Emacs (Vimpulse)でtextobj-between

textobj-between 書いた - 永遠に未完成のtextobj-betweenをEmacs+Vimpulseでも使えるようにしてみた.

i"やa"がvimpulse-quote-rangeとして実装されていて, クォート文字を任意に指定できるようになっていたので, 1文字read-charしてそれをvimpulse-quote-rangeに渡すようにするだけでできた.

ただし, vimpulse-quote-rangeは内部でscan-sexpsを呼んでいて, どうやらこれがクォート文字が特定の記号の場合に動作を妨げるようなので, 一時的にadviceで無効化している点があまりイケてない.

.emacsに以下のように書いておくと, ciF,で「,」に挟まれた範囲を変更したり, viF|で「|」に挟まれた範囲を選択したりできる.

(defadvice scan-sexps (around ad-fake-scan-sexps (from count) disable)
  (setq ad-return-value (if (= from beg) end beg)))
(defun vimpulse-between-range (arg &optional include)
  (condition-case ()
      (let ((ch (read-char)))
        (when (string ch)
          (ad-enable-advice 'scan-sexps 'around 'ad-fake-scan-sexps)
          (ad-activate 'scan-sexps)
          (let ((ret (vimpulse-quote-range arg ch include)))
            (ad-disable-advice 'scan-sexps 'around 'ad-fake-scan-sexps)
            (ad-activate 'scan-sexps)
            ret)))
    (error nil)))
(vimpulse-define-text-object vimpulse-inner-between (arg)
  "Select inner range between a character by which the command is followed."
  :keys "iF"
  (vimpulse-between-range arg))
(vimpulse-define-text-object vimpulse-a-between (arg)
  "Select range between a character by which the command is followed."
  :keys "aF"
  (vimpulse-between-range arg t))