あどけない話

インターネットに関する技術的な話など

Electric な Ruby の end (2)

Electric な Ruby の endですが、ブックマークのコメントにバグが指摘してあったので、直してみました。

バグの報告は、ブログのコメントに書き込んで頂けると嬉しいです。(_ _)

(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) pos)
    (catch 'loop
      (while (re-search-backward ruby-elct-regex nil t)
	(setq pos (match-beginning 0))
	(cond
	 ((string= (match-string 0) "end")
	  (setq level (1+ level)))
	 ((string= (match-string 0) "if")
	  (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))))))))

(defun ruby-elect-if (pos)
  (save-excursion
    (beginning-of-line)
    (and (looking-at "^[ \t]*\\(if\\)")
	 (= (match-beginning 1) pos))))

(add-hook 'ruby-mode-hook
	  (lambda ()
	    (define-key ruby-mode-map "d" 'ruby-elect-end)))