Ruby に付いてくる ruby-electric.el では、たとえば class と打った後に空白を入れると end が挿入されます。僕が欲しいエレクトリックな機能は、これじゃありません。
end と押すと対応する単語に飛んでほしいのです。というわけで作ってみました。別ファイルにすると設定方法を説明するのが面倒なので、とりあえず以下を .emacs に入れて下さい。
(defvar ruby-elct-regex "def\\|if\\|class\\|module\\|unless\\|case\\|while\\|do\\|until\\|for\\|begin\\|end") (defun ruby-elect-end () (interactive) (insert "d") (when (and (char-equal (char-before (1- (point))) ?n) (char-equal (char-before (- (point) 2)) ?e)) (ruby-indent-command) (let ((orig (point)) open) (forward-char -3) (when (looking-at "\\bend\\b") (setq open (ruby-elect-begin)) (when open (goto-char open) (sit-for 0.3))) (goto-char orig)))) (defun ruby-elect-begin () (let ((level 0)) (catch 'loop (while (re-search-backward ruby-elct-regex nil t) (cond ((string= (match-string 0) "end") (setq level (1+ level))) (t (if (= level 0) (throw 'loop (match-beginning 0))) (setq level (1- level)))))))) (add-hook 'ruby-mode-hook (lambda () (define-key ruby-mode-map "d" 'ruby-elect-end)))
あんまりテストしていません。飛んで一瞬留まる方法も正しいのか調べていません。
こういう構想は、Pascal を使っていた学生時代に持っていたんですが、そのときの実力では実現できませんでした。
今日、書いてみたら 10 分ぐらいでできたので、成長したんだなぁと思います。。。(Pascal を使わなくなったとはいえ、構想の実現に 15 年以上もかかるとは。。。)