« 今、「Emacsテクニックバイブル」を読んでいます(auto-complete.elをインストール) | メイン | AutoPagerizeのページ数を常に表示させるGreaseMonkey »

TextMateのsnippetから、YASnippetのsnippetを生成する方法(一部失敗)

Emacsテクニックバイブル(※1)を読んでYASnippetの存在を知る
Java用のsnippetを探すも見つからない
仕方がないので、YASnippetのsnippetの作り方を調べる(※2)
YASnippetのテンプレートの文法はTextMateのものにかなり似ていることを知る(※3)
TextMateのsnippetから、YASnippetのsnippetを生成できるかもと妄想する
TextMateのsnippetの書き方を真剣に調べ、かなり高機能なことに気付く(※4)
YASnippetのsnippetの書き方の英文を、変換方法を考えながらがんばって読む(※5)
もう少しで読み終えると喜んでいたら、snippetの書き方の最後にTextMate形式からの変換方法が書かれているのに気付く(※6) <=今ココ

丸一日かけて変換ツールの構想を練ってたのに...。
これだけ文法が似ていてたら、既に変換ツールがあると考えるべきだった。
※1 この本のおかげで変態的に便利なEmacsの環境が出来上がりつつあります。お勧めです。
※2 全て英語です。
※3 「snippetのテンプレートの文法はシンプルだけどもパワフルで、TextMateのものにとても似ている」と書いています。
※4 正規表現で置換できたり、Shellの実行結果を埋め込めたりできます。
※5 こちらもEmacs-lispの結果を使えたりして高機能です。
※6 しかもツールのダウンロード元は公式サイト。
textmate_import.rbをインストール
やったことは、textmate_import.rbをダウンロードしてヘルプの表示まで。
途中で、plistとchoiceのgemが足りなかったのでインストールしている。
% cd ~/dotfiles/emacs-config/download
% wget http://yasnippet.googlecode.com/svn/trunk/extras/textmate_import.rb
(略)
% ruby textmate_import.rb --help
textmate_import.rb:225: warning: parenthesize argument(s) for future version
textmate_import.rb:226: warning: parenthesize argument(s) for future version
textmate_import.rb:329: warning: parenthesize argument(s) for future version
textmate_import.rb:334: warning: parenthesize argument(s) for future version
/Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- plist (LoadError)
    from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
    from textmate_import.rb:18
% gem install plist
(略)
% ruby textmate_import.rb --help
textmate_import.rb:225: warning: parenthesize argument(s) for future version
textmate_import.rb:226: warning: parenthesize argument(s) for future version
textmate_import.rb:329: warning: parenthesize argument(s) for future version
textmate_import.rb:334: warning: parenthesize argument(s) for future version
/Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- choice (LoadError)
    from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
    from textmate_import.rb:19
% gem install choice
(略)
% ruby textmate_import.rb --help
textmate_import.rb:225: warning: parenthesize argument(s) for future version
textmate_import.rb:226: warning: parenthesize argument(s) for future version
textmate_import.rb:329: warning: parenthesize argument(s) for future version
textmate_import.rb:334: warning: parenthesize argument(s) for future version
Usage: textmate_import.rb [-dofpqbg]

Standard Options:
    -d, --bundle-dir=PATH            Tells the program the directory to find the TextMate bundle directory
    -o, --output-dir=PATH            What directory to write the new YASnippets to
    -f, --file=SNIPPET FILE NAME     A specific snippet that you want to copy or a glob for various files
    -p, --pretty-print               Pretty prints multiple snippets when printing to standard out
    -q, --quiet                      Be quiet.
    -b, --convert-bindings           TextMate "keyEquivalent" keys are translated to YASnippet "# binding :" directives
    -g, --info-plist=PLIST           Specify a plist file derive menu information from defaults to "bundle-dir"/info.plist

Common options: 
        --help                       Show this message
textmate_import.rbを使ってみる
TextMateの公式と思われるGitHubのページには、色々なbundleがupされている。
ここから、Java用のbundleをダウンロード。
java.tmbundleのページの右上の「Download Source」をクリックして、ファイル形式を選択する。
ここでは、「TAR」を選択。
そして解凍。
% tar zxvf textmate-java.tmbundle-83afc50.tar.gz 
(略)
textmate-java.tmbundle-83afc50/Snippets/
(略)
textmate-java.tmbundle-83afc50/info.plist
(略)
変換してみる。
% ruby textmate_import.rb -d textmate-java.tmbundle-83afc50/Snippets -o java-mode -g textmate-java.tmbundle-83afc50/info.plist 
textmate_import.rb:225: warning: parenthesize argument(s) for future version
textmate_import.rb:226: warning: parenthesize argument(s) for future version
textmate_import.rb:329: warning: parenthesize argument(s) for future version
textmate_import.rb:334: warning: parenthesize argument(s) for future version
Will try to convert 40 snippets...
(略)
textmate_import.rb:154:in `main_menu_to_lisp': undefined method `+' for nil:NilClass (NoMethodError)
    from textmate_import.rb:476
なんかエラーでた。
変換前の「.tmSnippet」と「.yasnippet」の数は共に40。
もしかして使えるかもしれないと思い、「java-mode」ディレクトリをYASnippetのsnippetディレクトリ内に移動。
% mv java-mode yasnippet-0.6.1c/snippets/text-mode/cc-mode/
念のため、Emacsを再起動し、javaファイルを開いた後、「cl」と入力し「M-x yas/expand」を実行してみる。
class TM_FILENAME/(.*?)(\..+)/TM_FILENAME/(.*?)(\..+)/// extends Parent implements Interface {
    
    }
うまく行っていない。
「TM_」で始まるのは、TextMateの環境変数のはず。
class.tmSnippetとclass.yasnippetの中身を見てみる。
% cat textmate-java.tmbundle-83afc50/Snippets/class.tmSnippet
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>content</key>
    <string>class ${1:${TM_FILENAME/(.*?)(\..+)/$1/}} ${2:extends ${3:Parent} }${4:implements ${5:Interface} }{
    $0
}</string>
    <key>name</key>
    <string>class</string>
    <key>scope</key>
    <string>source.java</string>
    <key>tabTrigger</key>
    <string>cl</string>
    <key>uuid</key>
    <string>E9ED01EA-E83B-4322-BD9D-39C88FB8C237</string>
</dict>
</plist>
% cat yasnippet-0.6.1c/snippets/text-mode/cc-mode/java-mode/class.yasnippet
# -*- mode: snippet -*-
# uuid: E9ED01EA-E83B-4322-BD9D-39C88FB8C237
# key: cl
# contributor: Translated from textmate snippet by PROGRAM_NAME
# name: class
## condition: "
# --
class ${1:${TM_FILENAME/(.*?)(\..+)/$1/}} ${2:extends ${3:Parent} }${4:implements ${5:Interface} }{
    $0
}% 
ファイル名の取得処理方法と、ファイル名から拡張子を外して既定値にする正規表現による変換処理方法が、TextMateの形式のままだった。
TM_FILENAMEは何ヵ所あるのかと調べてみたら、3ヵ所だけ。
% grep TM_FILENAME yasnippet-0.6.1c/snippets/text-mode/cc-mode/java-mode/*
yasnippet-0.6.1c/snippets/text-mode/cc-mode/java-mode/class.yasnippet:class ${1:${TM_FILENAME/(.*?)(\..+)/$1/}} ${2:extends ${3:Parent} }${4:implements ${5:Interface} }{
yasnippet-0.6.1c/snippets/text-mode/cc-mode/java-mode/interface.yasnippet:interface ${1:${TM_FILENAME/(.*?)(\..+)/$1/}} ${2:extends ${3:Parent} }{
yasnippet-0.6.1c/snippets/text-mode/cc-mode/java-mode/test case.yasnippet:public class ${1:${TM_FILENAME/(.*?)(\..+)/$1/}} extends ${2:TestCase} {
他の変数の変換はどうなっているのかと元のbundle内を調べてみたら同じく3ヵ所。
% grep TM textmate-java.tmbundle-83afc50/Snippets/*
textmate-java.tmbundle-83afc50/Snippets/class.tmSnippet:    <string>class ${1:${TM_FILENAME/(.*?)(\..+)/$1/}} ${2:extends ${3:Parent} }${4:implements ${5:Interface} }{
textmate-java.tmbundle-83afc50/Snippets/interface.tmSnippet:    <string>interface ${1:${TM_FILENAME/(.*?)(\..+)/$1/}} ${2:extends ${3:Parent} }{
textmate-java.tmbundle-83afc50/Snippets/test case.tmSnippet:    <string>public class ${1:${TM_FILENAME/(.*?)(\..+)/$1/}} extends ${2:TestCase} {
全然変換できてない。
環境変数には全く対応していないのかと思ったけど、codeの中には「TM_」の文字がいくつか見つかった。
それでも、正規表現にも対応していないのは結構致命的かも...。
elispの正規表現は独特な方言らしいし...。

ゼロからツールを作ろうにも、AppleのBundleの仕様を調べるのも大変だから、textmate_import.rbを読んで改造していくのが良いのかなぁ...。

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

Google

タグ クラウド