interactive で任意の動作をさせる list について調べた
- selection があれば selection の
- region があれば region の
- C-u <数字> されてれば、現在行の前後の<数字>行の
- C-u されてればバッファ全体の
- それ以外なら現在行の
start と end を受け取る interactive なんてのがあれば便利かなぁ、という気がしたので作ってみる。
また、LISTにて指定子に依らない任意の動作をさせることもできます。
http://xyzzy.s53.xrea.com/reference/wiki.cgi?p=interactive
cmds.lのrepeat-complex-commandの定義などを参照。
で cmds.l の repeat-complex-command を見てみると
(defun repeat-complex-command (sexp) (interactive (list (let ((*minibuffer-default-history* *minibuffer-complex-command-history*)) (prog1 (read-from-string (read-string "Redo: " :default (car *minibuffer-complex-command-history*))) (setq *minibuffer-complex-command-history* *minibuffer-default-history*))))) (eval sexp))
ヨクワカラナイ。read-from-string で入力された S-Expression を sexp として eval するんだろう、程度しかわからない。
とりあえず試してみる。
(defun test-interactive (from to) (interactive (list 0 100)) (msgbox "from: ~S~%to: ~S" from to)) => test-interactive ;; M-x test-interactive from: 0 to: 100
なるほど。インタラクティブ指定子 - 日々ごちゃごちゃと考える のと同様に (list 引数とする値) を返せばいいようだ。しかもその list の各要素が関数の各引数に渡されるようだ。イメージ的にはこんな感じ
`(multiple-value-bind ,arg-list (values ,@<interactive-list の返す list>) ...)
んじゃ。
(defun test-interactive (from to) (interactive (multiple-value-call #'list (progn (msgbox "*prefix-args*: ~S~%*prefix-value*: ~S" *prefix-args* *prefix-value*) (cond ((pre-selection-p) (values (selection-mark) (selection-point))) ;; ホントはここで region があったら、としたいのだけど ;; region の有無だけだと mark ってあんまり消えないので ;; ほぼ常に region はある。 ;; ac-mode みたいに rv-region で、ならよさげ。だけど ;; めんどいので今回はパス ;;((mark) ;; (values (region-beginning) (region-end))) ((and *prefix-value* (eq *prefix-args* 'digit-argument)) (values (save-excursion (forward-line (- *prefix-value*)) (point)) (save-excursion (forward-line *prefix-value*) (goto-eol) (point)))) ((eq *prefix-args* 'universal-argument) (values (point-min) (point-max))) (t (save-excursion (values (progn (goto-bol) (point)) (progn (goto-eol) (point))))))))) (msgbox "from: ~S~%to: ~S~%~%~A" from to (buffer-substring from to))) => test-interactive
ちょっとハマったところとか
*prefix-args* が、C-u ... とか C-u <数字> ... とかのときにどうなるのかはっきり覚えてなかった。
(defun check-prefix-args () (interactive) (msgbox "*prefix-args*: ~S~%*prefix-value*: ~S" *prefix-args* *prefix-value*)) => check-prefix-args (define-key spec-map #\p 'check-prefix-args) => t ;; C-c p *prefix-args*: nil *prefix-value*: nil ;; C-u C-c p *prefix-args*: universal-argument *prefix-value*: 4 ;; C-u 3 C-c p *prefix-args*: digit-argument *prefix-value*: 3
いつまでも存在してる region って・・・
普段 region をまったく使わないせいか、region というか mark がずっと存在はしてるなんてことに気付かなかった。ac-mode の「rv-region で反転してたら」てのはそーゆーことだったのか。
(save-excursion (goto-bol) (point)) とか
めんどくね?この式しょっちゅう書いてる気がする。