特定の動作時以外に解除されるモードのようなもの
xyzzy では (read-char ed:*keybodard*) を使えば入力を乗っ取れる。つまりこんなかんじ
(defun dabbrev-popup-loop () "連続して dabbrev-popup を実行する。" (interactive) ; おまじない (let (c) ; 変数 c を使います (loop ; 永久ループ (dabbrev-popup) ; dabbrev-popup を実行 (setq c (read-char ed:*keyboard*)) ;キーボードから一文字読み取る (unless (and (eq (lookup-key-command c) 'self-insert-command) ; もし、そのキーに割り当てられたコマンドが 'self-insert-command で (or (syntax-word-p c) ; word 文字か (syntax-symbol-p c))) ; symbol 文字でなかったら (unread-char c) ; キーボードを読んでないことにして (return)) ;dabbrev-popup-loop を終了 ;それ以外の場合は (insert c) ; c をインサートして (refresh-screen)))) ; 画面を再描写してループに戻る
これで、 davvrev-popup →候補がいっぱいあるので次の文字を入力→ もう一度davvrev-popup という動作をしなくてすみます。ってここにすでにあるやん…→ http://www-komo.ise.eng.osaka-u.ac.jp/~oka/xyzzy.html#dabbrev
まあそれはいいとして、これを使うことで、「特定の動作時以外に解除されるモードのようなもの」を作れる。VZ マクロでいうところの &p を使ったような。
とりあえずほかに作ったのは、UP/Down を乗っ取って行の入れ替えを行う transpose-line-loop とか。transpose-line-up / down ( http://www.uranus.dti.ne.jp/~shiro-/soft/xyzzy/edit.html#transposelines )よりも何が便利かというと、「そのために占有するキーが少なくてすむ」ということ。up/down で別々にコマンドを作っていた場合、M-Up M-Down などに割り当てたくなってくる。だが Up や Down +特殊キーで割り当てたいコマンドはかなり多く、transpose-line は、その利用頻度からそこまで使いやすくなくてもよい。かといってキー割り当てせずに M-x でわざわざコマンドを打つほどだと、「行選択してカット、移動、ペースト」したほうがましだ。また、連続して使用したい場合が多いので、2ストロークキーだと面倒に感じる。で、この「特定のキー以外では解除する」transpose-line-loop を用意する。たとえばそれを C-k C-t など割り当てる。使用の際、1行の移動であれば、この後、 UP か Down を押し成立。3ストロークとなる。だが2行下に移動したい場合、さらにもう一度、今度は C-k C-t なしで、 Down のみ押せば、4ストロークで成立する。その後「解除キーを押して解除」する必要はない。UPかDown以外のキーを押せば、解除された上にそのキーに割り当てられている元々の動作を行うからだ。
(defun transpose-line-loop () "transpose-line-loop" (interactive) (message "transpose-line-loop") (while (case (peek-char *standard-input* ed:*keyboard*) ((#\Up) (transpose-lines-up) t) ((#\Down) (transpose-lines-down) t) (t nil)) (read-char ed:*keyboard*) (refresh-screen)) (message ""))
こんなかんじ