ruby-modeが使いにくいので改造(その2)

昨日のままだと、onelinerの評価にはC-x C-e を、ブロックの評価にはruby-mode標準のキーバインドC-c C-xをと使い分けなければならない。どちらも同じように C-x C-eで評価できると便利なので、elispを書き直してみた。
(10/12 追記:ここに新しいバージョンが有る。endの自動補完機能が追加されている。)

;; ruby-mode customize
(defun ruby-send-exp ()
  "Send an exprssion to the inferior Ruby process.
Cursol must be after the 'end' symbol or at the end of a oneliner"
  (interactive)
  (let* *1
	    (point))))
    (ruby-send-region beginning (point))
    (scroll-down-irb)))

(defun scroll-down-irb ()
  (interactive)
  (setq curbuf (current-buffer))
  (if (get-buffer ruby-buffer)
      (pop-to-buffer ruby-buffer)
      (error "No current process buffer. See variable ruby-buffer."))
  (end-of-buffer)
  (pop-to-buffer curbuf))

(add-hook 'ruby-mode-hook
	  '(lambda ()
	     (define-key ruby-mode-map "\C-x\C-e" 'ruby-send-exp)))

これで、lisp-interaction-modeの様にRubyの式を評価できる。昨日のelisp.emacsに追加した人は、これと差し替えてください。
ブロックを評価したいときは、endの直後に、oneliner を評価したいときは、oneliner の最後にカーソルを移動してC-x C-eでどちらも評価できる。
ブロックの開始位置の判定には、ruby-modeで提供される式ruby-beginning-of-blockを使用しているが、この式はカーソル直前に有るendのインデントと同じ深さの開始シンボル*2をそれと見なしている様子。

ruby-beginning-of-blockで返される位置は、以下のキーバインドで調べる事ができるので、何度か試して自分で感覚をつかんで欲しい。

C-M-p		ruby-beginning-of-block

*1:last-three-chars (buffer-substring (- (point) 3) (point))) (beginning (save-excursion (if (string= last-three-chars "end") (ruby-beginning-of-block) (beginning-of-line

*2:"class\\|module\\|def\\|if\\|unless\\|case\\|while\\|until\\|for\\|begin\\|do"