Electric な Ruby の end (2)で気付いたことを直しただけで、公開していませんでしたが、これが現在のバージョンです。コメントが付いたので、思い出しました。(_ _)
(defvar ruby-elect-keyword '("def" "if" "class" "module" "unless" "case" "while" "do" "until" "for" "begin" "end")) (defvar ruby-elect-regex (mapconcat (lambda (x) (format "\\<%s\\>" x)) ruby-elect-keyword "\\|")) (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 "\\<end\\>") (setq open (ruby-elect-begin)) (when open (goto-char open) (sit-for 0.3))) (goto-char orig)))) (defun ruby-elect-begin () (let ((level 0) pos) (catch 'loop (while (re-search-backward ruby-elect-regex nil t) (setq pos (match-beginning 0)) (cond ((string= (match-string 0) "end") (setq level (1+ level))) ((member (match-string 0) '("if" "unless" "while" "until")) (when (ruby-elect-if pos) (if (= level 0) (throw 'loop pos)) (setq level (1- level)))) (t (if (= level 0) (throw 'loop pos)) (setq level (1- level)))) (if (< level 0) (throw 'loop nil)))))) (defun ruby-elect-if (pos) (save-excursion (beginning-of-line) (and (looking-at "^[ \t]*") (= (match-end 0) pos)))) (add-hook 'ruby-mode-hook (lambda () (define-key ruby-mode-map "d" 'ruby-elect-end)))