=============================================== 1999.7.05 発行 =========
         極私的 Emacs カスタマイズ紹介マガヂン
            Emacs をわたし色に染めて♪
------------------------------------------------------------------------
    第 6 回 便利なマクロ (1) yank の「正常」化とタブ幅【後編】
------------------------------------------------------------------------
※あなたのカスタマイズをぜひ教えてください。一般的なものから、他の人は
 絶対にしないような「外道」なものまで、何でも結構です。

※解除の方法は、このメールの末尾をごらんください。
========================================================================

	こんにちは。でるもんた・いいじま です。

	今回は「便利なマクロ(1)」の後編です。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
☆目次☆

	◇読者のおたよりから
	◇キーマクロの VZ 化 - if 文を使ったマクロ
	◇タブ幅の変更 - 引数をとるマクロ・while・計算
	◇C-u での回数指定を反映するマクロ
	◇下請けマクロ

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
☆読者のおたよりから☆

	○自動的にキーを記録してくれるマクロがあります。使ってみたら
	 便利でしたのでぜひどうぞ。

		ありがとうございます。私個人としては「記録してから使う」
		という方法になれているのですが、参考までにご紹介して
		おきます。何かの雑誌で紹介されていたそうです。

	http://www.csl.sony.co.jp/person/masui/papers/JSSSTDmacro/dmacro.el

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
☆キーマクロの VZ 化 - if 文を使ったマクロ☆

	さて、if 文の使い方は「第 2 回 デリイトキイは BS にあらず」で
	説明しましたが、マクロの定義にもこれは使用できます。

	具体的に使ってみましょう。これは、前回ご紹介したキーボード
	マクロの使い方で VZ 派には不満が残る(?)、「定義開始と定義
	終了が別キー」の対策です。

	同一のキーに割り当てるためにはひとつのコマンドとして呼び出せる
	ようにしなければいけませんから、それをつくりましょう、というのが
	ここの狙いです。

	まずは名前をきめましょう。オリジナルの C-x ( と C-x ) では
	start-kbd-macro、end-kbd-macro ですから、
	ここでは start/end-kbd-macro としてみましょう。
	(Emacs Lisp では、関数名に'/' が使えるのです!)
	まずは、ここまでの部分はお約束でしたね:

		(defun start/end-kbd-macro ()
			"キーボードマクロの記録開始・終了"
			(interactive)
		)

	続いて中身です。中身は、if 文を使って
		(if キーマクロを記録中
			(end-kbd-macro)
			(start-kbd-macro nil)
		)
	とすればいいことはわかります(start-kbd-macro の引数 nil に
	ついては M-x describe-function などを参考にしてください)が、
	この「キーマクロを記録中」はどうやって判別すべきでしょうか。

	apropos(第 4 回のワンポイント参照)によると、どうやらこれは
	defining-kbd-macro という変数の値を見ればよいようです。

	ということで、出来上がりは次のようになります。

		(defun start/end-kbd-macro ()
			"キーボードマクロの記録開始・終了"
			(interactive)
			(if defining-kbd-macro
				(end-kbd-macro)
				(start-kbd-macro nil)
			)
		)

	さらにこれをキーに割り当てておきましょう。

		(global-set-key "\C-_" 'start/end-kbd-macro)

				☆

	ついでですから、「キーマクロの実行」のほうも変えてしまいましょう。
	Canna の人は、
		(global-set-key "\C-\\" 'call-last-kbd-macro)
	でいいのですが、Wnn の場合は C-\ はかな漢の切り替えですので
	使えません。そこで、Wnn の人は M-\ にしましょう。
		(global-set-key "\M-\\" 'call-last-kbd-macro)

	【解説】\ は文字列中では特別な意味を持ちますので、\ という文字
		そのものを表したいときは \\ と書くことになっています。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
☆タブ幅の変更 - 引数をとるマクロ・while・計算☆

	さて、次は「タブ幅の変更」です。

	◇下調べ

		タブを設定するには、ふたつの変数をいじる必要がある
		ようです。ひとつは tab-stop-list、もうひとつは
		tab-width です。

		tab-stop-list は、「Tab キーを押したときにどこまで進むか」
		を表しており、初期状態では
			(8 16 24 32 40 48 56 64 72 80 88 96 104 112 120)
		となっています。ここでは 8 きざみですが、これは必ずしも
		一定間隔になっている必要はありません。たとえば、
			(setq tab-stop-list '(1 3 7 15 31))
		としてみるとそれがわかります。

		さて、8 桁ならこれでいいのですが、4 桁にするときには、
			(4 8 12 16 【後略】)
		としてやらなければなりません。

		一方、tab-width は「読んだテキスト中にタブ文字があったら、
		それを何文字で表すか」を示しています。

		なお、tab-stop-list に入っている値は、tab-width とは
		無関係に設定できるということに注意してください。
		たとえば、上の (1 3 7 15 31) の場合、
			○最初に Tab キーを押すと、スペースが 1 つ出る
			○次の Tab で、スペースが 2 つ増える
			○次の Tab で、スペースが 4 つ増える
			○次の Tab で、やっと「タブ文字+スペース 7 つ」
			 になる
			○さらに Tab を押すと、「タブ 3 つ+スペース
			 7 つ」になる
			○それ以上 Tab を押しても、何も出ない
		という挙動になります。

	◇マクロをつくる

		まず、お約束の形からはじまります。

			(defun delmonta-set-tab-width ()
				"タブ幅を指定します"
				(interactive)
			)

		今回の場合、タブ幅は、M-x delmonta-set-tab-width RET と
		入力したあとで、キーボードから入力させる必要があります。
		あるいは、他のマクロなどから
			(delmonta-set-tab-width 4)
		といった形でも呼び出せると便利です。

		そこで、つぎのように書きます。

			(defun delmonta-set-tab-width (num)
				"タブ幅を指定します"
				(interactive "nTab Width: ")
			)

		ここで、括弧の中に「num」という言葉が入りました。また、
		(interactive) の引数に "nTab Width: " が増えています。

		(delmonta-set-tab-width 4) といった形で呼び出すと、
		この 4 が num に入ることになります。キーボードから
		M-x delmonta-set-tab-width と入力すると、「Tab Width: 」
		と表示されて、数値を入力することができます。
		なお、"Tab Width: " の前の 'n' は、入力させるものが数値
		(number)であることを示すもので、画面には表示されません。

	◇マクロの中身

		マクロの中身は、次のように記述します。

			(setq tab-width num)

			(setq tab-stop-list ())
			(while (< num 256)
				(setq tab-stop-list
					(append tab-stop-list (list num))
				)
				(setq num (+ num tab-width))
			)

		さて、最初の (setq tab-width num) は、もう説明は要らない
		でしょう。

		続いて tab-stop-list ですが、これは、いちど空にして、
		ひとつずつ足していくということをしています。

		while は、英語の "while" という語義の通り、また、C 言語
		などの while 構文と同じく、「条件を満たしている間、
		ずっと繰り返す」です。(< num 256) というのは、普通の数式の
		「num < 256」と同じ意味です。

		(setq tab-stop-list ...) については、ここで説明すると
		長くなりますので省略しますが、tab-stop-list の末尾に
		num の値を追加するということをしています。

		(setq num (+ num tab-width)) は説明は要らないでしょう。
		これによって、while の中を一周するごとに num が増えて、
		それが一定値 256 以上になったときに、while loop から
		抜け出します。

	◇出来上がりは

		ということで、出来上がりは次のようになります。

			(defun delmonta-set-tab-width (num)
				"タブ幅を指定します"
				(interactive "nTab Width: ")

				(setq tab-width num)

				(setq tab-stop-list ())
				(while (< num 256)
					(setq tab-stop-list (append
						tab-stop-list (list num)
					))
					(setq num (+ num tab-width))
				)
			)

		【補足】(1)ここでは num は引数ですので、すでに他の場所で
			   使われている変数名と重複していても、それとは
			   別物として扱われます。ただし、引数として用意
			   したもの以外の変数は、書き換えると他の場所で
			   も書き換え結果は有効になりますの。この対策に
			    ついては後日また紹介します。

			(2)デフォルトでは tab-stop-list には 128 未満の
			   値しか入っていませんが、ここでは余裕を見て
			   256 以下としました。もし、もっと長い行を編集
			   することがあれば、この値を 1000 くらいに
			   増やしてみてください。

			(3)実は、こういう面倒なことをしなくても、
				(global-set-key "\C-i" 'self-insert-command)
			   とすれば、tab-width の書き換えだけで済みます。
			   (これは、C-i という文字自身、つまりタブ文字を
			   入力するという意味です。)実はこちらの方が
			   VZ その他の「通常の」エディタの挙動に近いの
			   ですが、私は tab-to-tab-stop コマンドの挙動が
			   気に入っているので、面倒な道を選びました。

			   なお、両者の挙動の違いは、C-i を self-insert-
			   command に設定してから、スペースを何文字か入力
			   し、C-i と M-i(こちらは初期状態で tab-to-tab-
			   stop になっています)をそれぞれ押してみると
			   わかるでしょう。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
☆C-u での回数指定を反映するマクロ☆

	Emacs では、C-u(第 4 回で書き換えた飯嶋式の場合は、M-o C-u)を
	つけることによって、いろいろなコマンドで回数指定ができます。
	これを自作のマクロでも実現するには、次のようにします。
	例題は、前回説明した insert-quotation です。

		(defun insert-quotation (n)
			(interactive "P")
			(while (> n 0)
				(beginning-of-line)
				(insert "> ")
				(next-line)
				(setq n (- n 1))
			)
		)

	このように、C-u で指定した回数は、(interactive "P") 指定によって、
	引数として受け取ることができます。C-u を使わなかった場合は、
	引数(この場合は n)は 1 になってくれます。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
☆下請けマクロ☆

	さて、マクロを組んでいると、下請けになるサブルーチンがほしい
	場合があります。

	こういったサブルーチンでは、(interactive) を書かないことが
	できます。そうすると、そのサブルーチンは、マクロや ~/.emacs
	のプログラムからは呼び出せても、キーボードから「M-x コマンド名」
	では呼び出せなくなります。

	身近なところでは、setq がそれにあたります。また、apropos
	(第 4 回のワンポイント参照)や describe-function で、
	「Command」 と書いてあるのが (interactive) のついたマクロ、
	「Function」と書いてあるのが (interactive) のつかないマクロです。

	この具体例は、また後日ご紹介したいと思います。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
☆次回予告☆

	次回は「第 7 回 禁断の VZ 化 (2) ファンクションキーと Alt・
	貴様はビル=ゲイツに魂を売ったかスペシャル」です。
	内容はご想像の通り(^^;)

	それでは、また来週♪


========================================================================
極私的 Emacs カスタマイズ紹介マガジン Emacs をわたし色に染めて♪

☆発行人☆

        でるもんた・いいじま <L94102@komaba.ecc.u-tokyo.ac.jp>
			http://user.ecc.u-tokyo.ac.jp/~l94102/emacs/

                ※このメールマガジンで取り上げてほしいテーマ、ご意見など
                 ありましたら、上のメールアドレスまでお気軽にどうぞ。

☆配信☆
        このメールマガジンは、「インターネットの本屋さん・まぐまぐ」を
        利用して配信しています。
                http://www.mag2.com     (マガジン ID=0000013484)

☆バックナンバー・登録解除・メールアドレス変更は☆

	上記のホームページまでどうぞ。
	なお、手動での登録解除は行っておりませんのでご了承下さい。
=========================================================================

Copyright © IIJIMA Hiromitsu aka Delmonta, 2016/03/10 15:09 JST
これは「古文書」です。 古くなった情報も原則未修正で保存していますのでご注意ください。

古文書本館トップ | 電脳外道学会