すぎゃーんメモ

2015-05-04

ctagsでjsx(ES6 class)の定義にジャンプできるようにする

React を使うにあたって、最近は ES6 classes を使ってJSXを書くようにしているのだけど、Componentを色んなファイルに分けて書いてるとそれぞれの定義に移動するのがつらくなってきた。

そういえば普段PerlRubyを書くときctags -eでTAGSを作っておいて、Emacs内ではM-x heml-etags-select(helm-command-prefix-key + e にbindされている)を使ってメソッド定義に飛んでいるのだけど、そういえばJSX用にそれが使えてない、というのに気付いた。

適当にググったら https://github.com/jsx/jsx.vim/blob/master/ctags/jsx.conf っていうのが見つかって、まぁこれは違うJSXなのだけど、とりあえず探したいのはclassだし変わらないや、ということでコピペして

--langdef=JSX
--langmap=JSX:.jsx
--regex-JSX=/^[ \t]*([a-z]+[ \t]+)*class[ \t]+([A-Za-z0-9_]+)[ \t]*([^)])/\2/c,class,classes/

というのを~/.ctagsに書いておいたら無事にJSXのComponent定義もTAGSに入って定義ジャンプできるようになった。便利。

参照

2015-04-09

Java Day Tokyo 2015に行ってきた

最近またJavaを勉強し始めたし、ちょうどいいタイミングで開催されていたので、参加させていただきました。

Java Day Tokyo 2015

自分が聴きに行ったセッションは以下。

スーツの人たち多めで、午前中のキーノートからホールの席が埋まっていてすごいなーと思った。

「Lambdas and Streams」、「Date and Time」はJava8初心者として普通に勉強になった。Streamとかよくこういう書き方できるように考えて設計・機能追加したなーと感心。Date/Timeはとにかく色々なことができるようになっているけど覚えきれるかんじではなさそう。…と呟いていたら以下を紹介していただいたので困ったときに参照しようと思う。

アプリケーションサーバ運用とかチューニングの話はまぁしっかりログ取得して可視化したりしましょうねっていう聞いたことのあるような話もあったりしつつ、jstatやらJMCやらJVMのモニタリングツールについては全然知識が無かったのでそういうものについて話を聴けたので良かった。

最後は車に色んなセンサーを取り付けてタッチスクリーンに表示する、といった話 それほど興味なかったけど作るの楽しいだろうな〜と思いながら聴いた。

あとこれは聴きには行かなかったのだけど評判が良くて資料読むだけでも興味深かった

あとはサムライズムさんのブースでIntelliJ IDEAの実演デモが素晴らしくて、「うぉぉ、こんなことも出来るのか〜 使いこなしてるヒトすげぇ!」と感動でした。


まだまだ馴染みのないJava世界だけど、色々と見聞きして面白かったです。今週末は JJUG CCC 2015 Spring もあるので、それもちょっと行ってみようと思います。

2014-10-27

#perlcasual に参加してLTしてきた

PerlCasual #06に、参加してきました。なにげに5年前の第1回ときから参加しているし縁のあるイベント。@氏に感謝!

8月のYAPC::Asiaでは何も話せなかったけど、自分の開発環境についてアウトプットすることが全然なかったなーと思って、せっかくLTの機会をいただいたので自分のEmacs環境について話してきた。

たいして需要は無かったかもしれないけど とりあえずreveal.jsを使ってプレゼンを作ってみたいと思っていたのが実現したのと、デモ用のGIFアニメを作るにあたって 以前つくっていたttyrecからGIFアニメを生成するWebアプリをちょっと改良できたので だいぶ自己満足できました。

ありがとうございました。

2014-10-22

projectileをcache有効にして高速化

Emacs 24.4がリリースされました。

それとは(多分)関係ないのだけど、愛用しているhelm-projectileが、ファイル数の多いあるprojectでとても重くなってしまって困ったので、cacheを使うようにしてみた。

(require 'projectile)
(custom-set-variables
 '(projectile-enable-caching t))
(projectile-global-mode t)

projectile.elにはprojectile-enable-cachingというカスタム変数があって、これをtrueにすれば~/.emacs.d/projectile.cacheというファイルにキャッシュを作成しそれを使ってファイル一覧を得るようになるらしい。

ただそのキャッシュファイルの更新はprojectile-modeに関連するhookで行っているようなので、globalでprojectile-modeをtrueにしておくべき、っぽい。

こうしておくと、新たにファイルを追加したり削除したりしたときも自動的にキャッシュを更新してくれるのが確認できた。

2014-07-19

ターミナル操作の記録(ttyrec)からGIFアニメを生成するツールを作った

ttyrec で録画したデータを使ってターミナル上で再生しつつ、そのスクリーンキャプチャを使ってアニメーションGIFを生成するツールをGoで作ってみた。

Mac, Linux Desktopで動作。再生速度はオプションで変更可能。

f:id:sugyan:20140719013354g:image

f:id:sugyan:20140719013353g:image


背景

percolを使ってターミナル操作を早く、便利に。 - すぎゃーんメモ のような記事を書いたりする際に、ターミナル操作を録画してGIFアニメにしたい需要があり。

そういった用途に使える汎用のデスクトップ録画ツールとしてはLICEcapやGifzoなどがある。

これらはWindows, OSXあたりが対象で、Linuxの場合はまた他のツールがあるらしい(よく知らない)。

汎用的なキャプチャツールでも良いけれど、いちいち録画対象のターミナルのウィンドウを指定するのも面倒だし、ターミナル専用のツールがあっても良いのではないか。

ttyrec というツールが、古くから存在する。これを使うとコマンドからターミナルの操作を録画・再生することができる。

これで各コマを再生しつつターミナルのスクリーンショットを撮り、それらを繋げてGIFアニメにする、というツールも既に幾つか存在する。

これらは大抵 ImageMagick に依存しており、importコマンドを利用してスクリーンショットを撮ったり、convertコマンドでGIFを生成したりしている。言語はC/C++, Pythonで、対象はOSXとLinux両方だったり片方だけだったり。


ところで Go には標準パッケージとしてGIF画像を扱うものが用意されている。

これを使えばImageMagickに依存することなく前述のようなツールが作れるのでは? しかもPure Goで書けるはずだからクロスコンパイルして各環境用のバイナリを配布することも可能なはず!

ということで作ってみた次第。

(まぁターミナルの録画を撮りたい需要がある人なら各言語の実行環境用意したりImageMagickをインストールしたりするのに障壁は無いでしょうけども)


実装

ttyrecordの読み取り

ttyrecは自分でインストールしてもらうとして(RPMパッケージが用意されていたりhomebrewでも入るし そこは問題ないはず)。

それで撮って得られたバイナリデータは、

  • 各コマの時刻と、出力内容の長さを格納したヘッダ
  • それに続く出力内容の中身

がただ順番で書き込まれているだけなので、ひたすら順番に読み取っていく。


再生

読み取った内容を元に、各時刻の差分を計算したりしつつ ただターミナル上に出力していくだけで、再生できる。


キャプチャ

各コマを再生しつつ、TMPDIR以下にスクリーンショットを放り込んでいく。が、ここは結構面倒なところで。


OSXでは、

  • AppleScriptを使って対象アプリケーション(Terminal.appだったりiTerm.appだったり)のアクティブウィンドウのIDを取得
  • そのIDを指定してscreencaptureコマンドを実行する

という手順でスクリーンショットを撮る。実行中のターミナルアプリケーションがTerminal.appなのかiTerm.appなのか、はたまた別のアプリケーションなのか?は、とりあえずは$TERM_PROGRAM環境変数で二択の判別だけしているけれど 他に良い方法ないだろうか…

あと、Retina display上で撮ると高い解像度のデカい画像が作られてしまうので、そこからさらにsipsコマンドを使ってdpi情報を取得して調整したり。


Linux というかX Window Systemでは、xwdというコマンドで指定したWINDOWIDの画面をダンプできる、ということなのでそれを使うことにした。

ただこれはxwdフォーマットという独自のビットマップ形式で保存されるので、それを読み取って画像データとして得るためのdecoderは自分で書いた。


OSX/Linux各環境で分けられるかというとそうでもなく、Mac OS X上でも XQuartz を使ってX Window Systemを立ち上げてその上でターミナル動かしたりするので、出来る限りどちらにも対応できるようにした、つもり。

f:id:sugyan:20140719090422g:image

これはXQuartz上のxtermで撮ったもの。


xwdでは余計な部分が撮られることなくて済むのだけど、OSXのscreencaptureではどうしても「ウィンドウ全体」が撮られるため、タイトルバーなどが含まれてしまう。この部分が何故かコマによって白飛びしてしまったりするし、出来れば除外したいのだけど…

少し調べた限りでは良い方法は無さそうだった。決め打ちで上20pixelくらい削ったりしようにも アプリケーションによって または単一タブのときと複数タブのときとでバーの高さが変わったりするだろうし 逆にフルスクリーンモードのときは勝手に消えるからその場合も考慮しないといけないし…


キャプチャからのGIF生成

1コマずつ再生しつつ スクリーンショット取得->画像ファイル読み取り とやっていると再生終了まで時間がかかってしまうので、とりあえず撮るだけ撮って保存だけしておき、一通り再生し終わったらそれらを読み込んでGIF生成にとりかかる、というようにしている。

ここで早速 pipeline and cancellation並行性パターンの勉強 - すぎゃーんメモ で勉強した内容が役立った。CPU使う処理なので並行化でそこまで劇的に早くなるというわけでもないけど、runtime.GOMAXPROCS(runtime.NumCPU())指定してコア数ぶん動かすことで可能な限りの処理をしてくれるようになった、と思う。


TODO

Windowsのことは完全に無視して作った(確認できる環境も持ってないし…)けど、コマンドプロンプトのスクリーンショットを簡単に撮る方法はあるのだろうか?

Linux Desktopも自分では普段使ってないからあまり詳しく知らない、他にもサポートすべきものはあるのかな。

バイナリ配布するならttyrec自体もGoで再実装して使えるようにしておいた方がよかったりするのだろうか?

スピード調整はできるようにしたけど、「この前半3コマは削りたい」「このtypoの部分を削りたい」みたいな場面は出てくると思うので、一度各コマの時刻と出力内容概要をファイル出力して それを編集して使うことで各コマのタイミング調整や削除をできるようにしたいな、と思っている。