インクリメンタルに行を移動する

 秀丸のマクロに、便利そうなのがないか見ていたら、そういうのがあったので、何となく作ってみた。ただし、自分は行移動ってあんまり使わないけど。

■具体的に何をするか。

  • インクリメンタルに行を移動する。そのまま。M-gのインクリメンタル版と言う感じ。
  • 数字とC-h以外はキーが聞かないけど、まあ良いかなぁと。他のキーは打つと直ぐ移動から抜けてしまう。個人的には、逆に移動した後直ぐに入力できて便利じゃないかと思ってそうした。Enterいらない分多少いい。
(defun igoto-line()
  (interactive)
  (toggle-ime nil)
  (let ((input-number 0))
	(loop
	  (minibuffer-prompt "iline to go:~A"
						 (if (= input-number 0)
							 ""
						   input-number))
	  (refresh-screen)
	  (let ((key (read-char *keyboard*)))
		(cond ((eq key #\C-h)
			   (if (<= 10 input-number)
				   (setq input-number (truncate (/ input-number 10)))
				 (setq input-number 0)))
			  ((digit-char-p key)
			   (setq input-number (+ (* input-number 10) (digit-char-p key))))
			  (t
			   (unread-char key)
			   (return))))
	  (goto-line input-number))
	))

秀丸奥義書 - お勧めマクロ一覧
http://homepage2.nifty.com/masema/hide/hide-ougi-macros.html#cursor
 ここを見て、他にも便利そうなのがないか見たけど、殆ど既にxyzzyにありそうなのでやめた。

■関係ないこと
 作ってて気づいたけどlispの変数って型が一応あるらしい(今まで気にもしてなかったのは秘密)。適当にやったら、型のエラーが色々出た。isearchの中身を真似しようかと見てみたらキーマップとか作って意外と色々つけてて大変そうだったので、(read-char *keyboard*)したときに何が入るかだけ見て判別してみた。(read-char *keyboard*)がこんな風にキーを受けているのにはじめて気づいた。

■追記
二桁かいて10の位だけ編集とかというのも出来るといいかもしれない。まあ、C-vやPageDownがC-gなしにも動くのでいらないかもしれないけど、100の位とかだったらやってみたいかもしれないし、後から試してみよう。

更に追記。少し考えてみたけど、10の位だけ消す方法とかがよく分からなかったので諦めた。

■更に更に追記
 入力したのをリストに入れてとかやってみたけど、リストの中身がどうやったら書き換えれるのかよく分からず断念。hoge[2]とかに代入したら出来るくらいに思っていたのが間違いだった、というか、リストと配列が同じものだと思っていたけど、全く違った。良く見たら配列も別に存在していて('A`)・・・
一応作ったゴミのようなもの。

(defun igoto-line()
  (interactive)
  (toggle-ime nil)
  (let ((input-number 0)
		(rank 1)
		number-list
		tmp-list)
	(loop
	  (minibuffer-prompt "iline to go:~A"
						 (if (zerop input-number)
							 ""
						   input-number))
	  (refresh-screen)
	  (let ((key (read-char *keyboard*)))
		(cond ((eq key #\C-h)
			   (if (<= 10 input-number)
				   (setq input-number (truncate (/ input-number 10)))
				 (setq input-number 0))
			   (setq number-list (cdr number-list)))
			  ((eq key #\C-b)
			   (setq rank (1+ rank)))
			  ((and (eq key #\C-f) (< 1 rank))
			   (setq rank (1- rank)))
			  ((digit-char-p key)
			   (if (= rank 1)
				   (push (digit-char-p key) number-list))
			   ;リストの書き換え方がよく分からない。
			   (setq tmp-list number-list)
			   (setq input-number 0)
			   (dotimes (i (list-length number-list) t)
				 (setq input-number
					   (+ input-number (* (car tmp-list) (expt 10 i))))
				 (setq tmp-list (cdr tmp-list)))
			   )
			  (t
			   (unread-char key)
			   (return))))
	  (goto-line input-number))
	))