もう少し自由に歩く。
もっと自由にカーソルを移動したり、いくつかの場所をマークして同時に編集するモードを考えているのだけど、完成するまでは不便なので、もっと簡単に実装できるものを取り敢えず作ってみた。
とはいっても、前に作ったものの改良だけど。
関数の説明を表示してくれるモード*1を見つけたので、それに合わせて説明を入れたのと、universal-argumentの使い方が何となく分かったので、それを使うようにした。
forward-lineなどの移動量を指定できても使い道がないので、別の数値を使う移動を割り当ててある。
これでgoto-charとかgoto-lineに割り当てるキーを節約できた。
コードは畳んでおいた。
(defun walk-up (&optional N) "上にループ動作で移動。オプションでgoto-lineする。" (interactive "p") (or (if N (universal-walk N #'goto-line (buffer-lines))) (if (< (get-window-line) (/ (window-lines) 2)) (scroll-window -1)) (previous-virtual-line 1) (goto-line (buffer-lines)))) (defun walk-down (&optional N) "下にループ動作で移動。オプションでgoto-virtual-lineする。" (interactive "p") (let ((goal (goal-column)) (test (save-window-excursion (scroll-window (window-lines))))) (set-goal-column goal) (or (if N (universal-walk N #'goto-virtual-line (save-excursion (goto-char (buffer-size)) (current-virtual-line-number)))) (and test (> (get-window-line) (/ (window-lines) 2)) (scroll-window 1)) (next-virtual-line 1) (goto-line 0)))) (defun walk-left (&optional N) "左にループ動作で移動。オプションでgoto-charする。" (interactive "p") (if N (universal-walk N #'goto-char (buffer-size)) (if (backward-char 1) nil (goto-char (buffer-size)))) (let ((goal (goal-column)) (here (current-column))) (set-goal-column (cond ((= here (save-excursion (goto-eol) (current-column))) (window-columns)) ((zerop here) 0) (t goal))))) (defun walk-right (&optional N) "右にループ動作で移動。オプションでgoto-columnする。" (interactive "p") (if N (universal-walk N #'goto-column #1=(save-excursion (goto-eol) (current-column))) (if (forward-char 1) nil (goto-char 0))) (let ((goal (goal-column)) (here (current-column))) (set-goal-column (cond ((zerop here) 0) ((= here #1#) (window-columns)) (t goal))))) (defun universal-walk (N func limit) (funcall func (mod N (1+ limit))))
*1:shiroのdescribe-bindings-mode