snippet.l をごにょごにょしてみた
とりあえず snippet てのはテンプレートを展開した後で部分的に書き換えたりできるような、そんな感じ。
なんともタイムリーに中の人が ScreenCast なぞしてくれてる。
http://white.s151.xrea.com/wiki/index.php?diary%2F2007-01-18%2Fsnippet%20screencast
url のリンクじゃなくて、その下にある「ここからどうぞ」ってやつ。
んで、~/.abbrev_defs に
("function" "function${1/./ }${1:name}(${2:arg}){ $0; };" nil 0)
なんてのを書いとけばその通り展開して ${n:hoge} んとこを書き換えたりできるのだが
var myObj = { method: func! //<-ここで展開 };
とかしたときは
var myObj = { method: function(arg){ //<-まずは name を入力できるんで消して、その次 arg ! //<-展開終わったらここへ }; };
となって欲しいのだが
var myObj = { method: function(arg){ ! //<-インデントがそのまま }; };
とインデントが ~/.abbrev_defs に書いてあるままになっちゃうんで
ごにょごにょしてみた
改行+なにか*1で mode-specific-indent-command するように。
; snippet.l の 410 行目くらい(コメント入れすぎて元のがわからん ; (defun snippet-expand () の割と頭付近 (setf *snippet-end* (point)) ;*snippet-end* にカーソル位置を代入 (goto-char *snippet-begin*) ;*snippet-begin* へカーソルを移動 ;;+ \n の後は mode-specific-indent-command でインデント (while (scan-buffer "[^\\]\\(\n\\).+" :regexp t :limit *snippet-end*) (let ((head (match-end 1)) indent-end) (goto-char head) (funcall mode-specific-indent-command) (setf indent-end (point)) (setf *snippet-end* (+ *snippet-end* (- indent-end head))) )) (clear-undo-boundary) (goto-char *snippet-begin*) ;ここまでインデントの (while (scan-buffer "\\(?:[^\\]\\|^\\)\\($\\(?:\\([0-9]\\)\\|{\\([0-9]\\)\\(?::\\([^}]+\\)\\)?}\\)\\)"
problems
javascript-mode では '$0' が書いてある状態でそれ以降のインデントがずれる。$0${0/./;}って書いといたらだいじょぶっぽい。
py-mode は mode-specific-indent-command が定義されてないんでエラーになる。定義して py-indent-line にしといたら今んとこ動いてる。
; py-mode.l の 560 行目あたり ; (defun py-mode () の中 (setq keyword-hash-table *py-keyword-hash-table*)) (make-local-variable 'indent-tabs-mode) ;;+ mode-specific-indent-command に py-indent-line を設定 (make-local-variable 'mode-specific-indent-command) (setq mode-specific-indent-command 'py-indent-line) (setq indent-tabs-mode *py-indent-tabs-mode*)
javascript-mode と py-mode しか見てなくて他のモードはテストもしてない。きっとエラー出るんだ。そうに決まってる。
感想
とりあえずがーっとソース読んでみたら、今んとこなんとか理解はできてる。半分くらいしか読めてないけど。何してるかはっきりわかってないんで *snippet-end* いぢってるのがちょっと怖い。
${n:hoge} の hoge を全部消したときがなんかおかしいんだが、中の人も苦労してるようだ。ガンバレ。
lisp はなんかおっかないイメージあったけど javascript とか python とかと比べて思ってたほど違うもんではないようだ。熱帯魚と秋刀魚くらいの違い。どっちもよくわかってないが。
html+-mode で "<div>!" から "<div id='[id]' class='[class]'>" とか展開できればなーと思うのだが、"<" がダメっぽい。これは abbrev の方をいぢらなきゃならなそう。
追記 21/jan/2007 12:50
中の人が実装してくれた!
http://white.s151.xrea.com/wiki/index.php?diary%2F2007-01-20%2Fsnippet4
ありがたく使わせて頂きます。
*1:空行は放置