Go to the first, previous, next, last section, table of contents.
本章では、Emacs Lispの機能についてさらに述べることはしません。
かわりに、前章までに述べてきた機能を効率よく使うための助言や
Emacs Lispプログラマが従うべき慣習について述べます。
ここでは、読者が広く使われることを意図した
Emacs Lispコードを書く場合に従うべき慣習について述べます。
-
すべてのグローバル変数は同じ名前空間を共有し、
すべての関数も別の名前空間を共有するため、
読者のプログラムを別のLispプログラムと区別するための短い単語を選ぶべきである。
そして、すべてのグローバル変数、定数、関数の名前を
選んでおいた接頭辞で始めるように注意する。
Emacs Lispでは基本関数ではないがLispの伝統的な基本関数の名前にさえも
この勧告は適用される。
たとえ
copy-list
にさえもである。
信じるかどうかは別にして、
copy-list
のもっともらしい定義方法は複数ある。
安全であるためには、読者の接頭辞を付けて
foo-copy-list
やmylib-copy-list
のような名前にする。
読者が、twiddle-files
のような特定の名前でEmacsに
追加すべき関数を書いた場合には、読者のプログラムでは
その名前で呼ばないようにする。
読者のプログラムではmylib-twiddle-files
としておき、
Emacsに名前を追加するように提案するメイルを
`bug-gnu-emacs@gnu.org'へ送る。
われわれがそのようにすることを決定したときには、
名前をとても簡単に変更できる。
1つの接頭辞では不十分な場合には、
意味がある限りは、
2つか3つの共通する別の接頭辞を読者のパッケージで使ってもよい。
接頭辞とシンボル名の残りの部分とはハイフン`-'で分ける。
これはEmacs自身やほとんどのEmacs Lispプログラムと一貫性がある。
-
プログラムに少なくとも複数の入り口がある場合には、
各ライブラリプログラムに
provide
の呼び出しがあるとしばしば有用である。
-
別のライブラリプログラムをあらかじめロードしておく必要があるファイルでは、
ファイルの先頭のコマンドにそのように記述しておくこと。
さらに、必要なものが確実にロードされておくように
require
を使う。
-
別のファイルbarで定義されるマクロを
ファイルfooで使っている場合には、
fooでそのマクロを始めて使うまえにfooにつぎの式があること。
(eval-when-compile (require 'bar))
(さらに、require
が働くように、
ライブラリbarには(provide 'bar)
があること。)
この式により、fooをバイトコンパイルするときに
barをロードすることになる。
さもないと、必要なマクロをロードせずにfooをコンパイルする危険を侵し、
正しく動作しないコンパイル済みコードを生成することになる。
see section マクロとバイトコンパイル。
eval-when-compile
を使うことで、
fooのコンパイル済みの版を使うときには
barをロードしない。
-
メジャーモードを定義するときには、
メジャーモードの慣習に従うこと。
see section メジャーモードの慣習。
-
マイナモードを定義するときには、
マイナモードの慣習に従うこと。
see section マイナモードを書くための慣習。
-
関数の目的が特定の条件を満たすかどうかを報告するのであれば、
その関数には`p'で終る名前を付ける。
名前が1単語である場合には`p'だけを付加する。
複数の単語であれば`-p'を付加する。
たとえば、
framep
やframe-live-p
である。
-
真偽の条件を記録するユーザーオプション変数には、
`-flag'で終る名前を付ける。
-
読者のメジャーモードでは、
C-c letterをキーとして定義しないこと。
これらのキー列はユーザー向けに予約済みである。
それらだけがユーザー向けに予約されたキー列であり、
それらを禁止しないこと。
かわりに、C-cのあとにコントロール文字か数字文字か特定の句読点文字が続く
キー列を定義する。
これらのキー列は、メジャーモード用に予約してある。
Emacsのすべてのモードをこの慣習に従うように変換するのは
たいへんな作業量であった。
この慣習を捨てさるとその作業をむだにしてしまい、ユーザーにも不便である。
-
C-cのあとに{、}、<、>、:、;の
いずれかが続くキー列もメジャーモード用に予約してある。
-
C-cのあとにこれら以外の句読点文字が続くキー列は、
マイナモード用に割り当ててある。
これらをメジャーモードで使うことは絶対禁止ではないが、
これらを使うと、メジャーモードのバインディングが
マイナモードでときどき隠されてしまう。
-
修飾キーを使わないファンクションキーF5からF9は、
ユーザーが定義するように予約してある。
-
(C-cを含む)任意のプレフィックス文字に続く
C-hをバインドしないこと。
C-hをバインドしなければ、これは自動的に
プレフィックス文字のサブコマンド一覧を表示するヘルプ文字になる。
-
ESCに続くESC以外には、
ESCで終るキー列をバインドしないこと。
(つまり、ESC ESCで終るキー列をバインドするのはよい。)
この規則の理由は、任意の文脈において
ESCに対するプレフィックスでないバインディングがあることで、
エスケープシーケンスをその文脈におけるファンクションキーと
認識することを防げる。
-
ユーザーが出入りできる一時的なモードや状態のように働くものでは、
脱出手段としてESC ESCや
ESC ESC ESCを定義する。
Emacsの普通のコマンドを受け付ける状態、、あるいは、
より一般的にはESCに続けてファンクションキーや矢印キーが
意味を持つ可能性がある任意の状態では、
ESCに続くエスケープシーケンスの認識を妨げる
ESC ESCを定義するべきではない。
そのような状態では、脱出手段としてESC ESC ESCを
定義する。
さもなければ脱出手段としてESC ESCを定義する。
-
アプリケーションでは、シフトキーを押し下げたボタン1関連のマウスイベントを
バインドすべきではない。
これらのイベントには、S-mouse-1、M-S-mouse-1、
C-S-mouse-1などが含まれる。
これらはユーザー向けに予約してある。
-
読み出し専用のテキスト向けの特別なメジャーモードでは、普通、
mouse-2とRETをテキスト内のある種の参照を
辿るように再定義するべきである。
dired、info、コンパイル(compilation)、出現(occur)などのモードは
このように再定義している。
-
Emacsの普通のふるまいを変更するようなパッケージでは、
その機能をオン/オフするコマンドを含めるとよい。
その機能をオン/オフする
whatever-mode
という
名前のコマンドを用意し、自動ロード(see section 自動ロード)するようにする。
パッケージをロードしただけでは見ためには効果がない、
つまり、その機能をオンにしないようにパッケージを設計すること。
ユーザーはコマンドを起動してその機能をオンにする。
-
Emacsの基本関数の別名を定義することは悪い考えである。
そのかわりに標準の名前を使う。
-
Emacsの基本関数を再定義(あるいはアドバイス)することは謹むべきである。
特定のプログラムに対しては正しく動作するであろうが、
他のプログラムがその結果どうなるかはわからない。
-
Emacsの標準の関数やライブラリプログラムを置き換えるようなファイルでは、
そのファイルの先頭の目立つコメントに
どの関数を置き換え元のふるまいとの相違点を記述すること。
-
読者のEmacs Lispのソースファイルの名前は13文字以下にすること。
こうすると、ファイルをコンパイルしても、
コンパイル済みのファイル名は14文字以下になり、
どんな種類のUNIXシステムにも収まるだけの短さである。
-
プログラムでは
next-line
やprevious-line
を使わないこと。
ほとんどの場合、forward-line
のほうがより便利であり、
予測可能で堅牢でもある。
see section テキスト行単位の移動。
-
マークを設定することが読者のプログラムの意図した機能の一部でなければ、
マークを設定する関数は呼び出さないこと。
マークはユーザーレベルの機能であり、
ユーザーの便宜のために値を指定する以外には、
マークを変更するのは正しくない。
see section マーク。
特に、以下のいずれの関数も使わないこと。
-
beginning-of-buffer
, end-of-buffer
-
replace-string
, replace-regexp
対話的なユーザー向けの他の機能を必要とせずに
単にポイントを移動したり特定の文字列を置換するには、
これらの関数は1行か2行の単純なLispコードで置き換えられる。
-
ベクトルを使う特別な理由がない限りは、ベクトルではなくリストを使う。
Lispには、ベクトルに対するよりもリストを操作する機能のほうが多くあり、
リストを扱うほうが普通はより簡便である。
(リストだけが許す)要素を挿入したり削除する必要がないのであれば、
ある程度のサイズがあり
(先頭から末尾に向けての探索ではなく)ランダムに参照する表には
ベクトルのほうが適している。
-
エコー領域にメッセージを表示する推奨方法は、
princ
ではなく関数message
を使うことである。
see section エコー領域。
-
エラー条件に出会ったときには、
関数
error
(あるいはsignal
)を呼び出す。
関数error
は戻ってこない。
see section エラーの通知方法。
エラーを報告するために、
message
、throw
、sleep-for
、beep
は使わないこと。
-
エラーメッセージは大英文字で始め、ピリオドで終えないこと。
-
実行に時間を要する多くのコマンドでは、
開始時には`Operating...'のメッセージを表示し、
終了時にはそれを`Operating...done'と変える。
これらのメッセージの形を同じにしておくこと。
...
の周りに空白はなく、末尾にピリオドもない。
-
再帰編集の使用は避けるように努めること。
そのかわりにrmailのコマンドeのようにする。
つまり、古いローカルキーマップに戻るためのコマンドを収めた
新しいローカルキーマップを使う。
あるいは、コマンド
edit-options
のようにする。
別のバッファに切り替え、戻るのはユーザーに任せる。
see section 再帰編集。
-
変数名を`*'で始めたり終える慣習があるシステムもある。
Emacs Lispではこの慣習を使わないので、読者のプログラムでも使わないこと。
(Emacsでは、特別な目的のバッファにのみそのような名前を使う。)
すべてのライブラリで同じ慣習を使うと、
ユーザーにはEmacsがより整合して見える。
-
自由変数には
defvar
の定義を追加して、
コンパイル時の未定義な自由変数に対する警告を避けるように努めること。
ある関数で変数を束縛しその変数を別の関数で使ったり設定すると、
その変数を定義しない限りコンパイラは後者の関数について警告を出す。
しかし、しばしばこれらの変数は短い名前で、
Lispパッケージでそのような変数名を定義すべきかどうか明らかでない。
したがって、そのような変数の名前は、
読者のパッケージの他の関数や変数に使っている接頭辞で
始まる名前に改名すべきである。
-
デフォルトの字下げパラメータを使って、
各関数をC-M-q(
indent-sexp
)で字下げすること。
-
閉じ括弧だけの行にする癖をつけないこと。
Lispプログラマはこれに当惑する。
たまには、閉じ括弧が多数個連続するときに
それらを1つか2つの塊に分けることは意味がある。
-
コピーを配布する場合には、ファイルに著作権表示を入れること。
つぎのような文面を使う。
;; Copyright (C) year name
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of
;; the License, or (at your option) any later version.
;; This program is distributed in the hope that it will be
;; useful, but WITHOUT ANY WARRANTY; without even the implied
;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
;; PURPOSE. See the GNU General Public License for more details.
;; You should have received a copy of the GNU General Public
;; License along with this program; if not, write to the Free
;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
;; MA 02111-1307 USA
読者がフリーソフトウェアファウンデーションに著作権を委譲する契約を
結んでいるときには、
nameとして`Free Software Foundation, Inc.'を使う。
さもなければ読者自身の名前を使う。
バイトコンパイルしたLispプログラムの実行速度を改良する方法を示します。
説明文字列を書くうえでのヒントや慣習を述べます。
コマンドM-x checkdoc-minor-modeを実行して、
これらの慣習の多くを確認できます。
-
ユーザーが知っておくことを意図した各コマンド、関数、変数には、
説明文字列を付けること。
-
Lispプログラムの内部変数やサブルーティンにも説明文字列を付ける。
Emacsの初期の版では、説明文字列のかわりにコメントを使うと容量を節約できたが、
今はこれはあてはまらない。
-
説明文字列の最初の行は、1つか2つの完全な文であり、
それだけで概要を表していること。
M-x aproposは説明文字列の最初の行だけを表示するため、
それだけで十分に表せないと表示結果が悪くなる。
特に、最初の行は大文字で始め、ピリオドで終えること。
説明文字列には、関数や変数の使い方の詳細を述べる追加の行があってよい。
それらの行も完全な文から成るべきであるが、見ためをよくするために
適当に詰めてよい。
-
一貫性があるように、関数の説明文字列の最初の文の動詞は
『to』を省いた不定詞にする。
たとえば、『Returns the cons of A and B.』ではなく
『Return the cons of A and B.』とする。
最初の行の残りの文についても同様にするとよい。
以降の文節では適切な主語があるほうが一般にはよい。
-
説明文字列は受動態ではなく能動態で書き、未来形ではなく現在形で書く。
たとえば、『A list containing A and B will be returned.』ではなく
『Return a list containing A and B.』と書く。
-
不必要に単語『cause』(および同義語)を使わないこと。
『Cause Emacs to display text in boldface,』ではなく
単に『Display text in boldface.』と書く。
-
説明文字列は、白文字で始めたり終えないこと。
-
80コラムのスクリーン上のEmacsのウィンドウに収まるように
説明文字列を整形する。
ほとんどの行を60文字を越えないようにするとよい。
必要な情報を入れるためならば最初の行が長くなってもよい。
しかし、説明文字列全体を単純に整形するよりは、
注意深く行分けすると読みやすくなる。
説明文字列が長い場合には、話題ごとに空行で区切る。
-
ソースコード上で説明文字列の最初の行に揃えるために
説明文字列の残りの行を字下げしないこと。
ソースコード上では見ためがよくても、
ユーザーが説明文字を見るときには奇妙に見える。
文字列を始めるダブルクォートのまえにある字下げは
文字列の一部ではないことに注意!
-
ユーザーが禁止コマンドを実行しようとすると、
Emacsは当該コマンドの説明文字列の最初の文節、
つまり、最初の空行までを表示する。
必要ならば、最初の空行のまえに入れるべき情報を選んで、
このような表示が有用であるようにする。
-
ユーザーが対話的に設定したがるような変数では、
その変数の説明文字列は`*'で始める。
変数の値が、長いリストや関数であるとき、あるいは、
初期化ファイルでのみ設定するような変数であるときには、
その説明文字列を`*'で始めないこと。
see section グローバル変数を定義する。
-
yes/noのフラグを表す変数の説明文字列は『Non-nil means...』のような
単語で始めて、
nil
以外の値はすべて同値であることを明らかにし、
nil
とnil
以外の意味を明確に示すこと。
-
関数の説明文字列でその引数について述べるときには、
その引数の値を表す名前には大文字で書いた引数名を使う。
したがって、関数
/
の説明文字列では、
その第2引数の名前はdivisor
なので、`DIVISOR'と表す。
また、リストやベクトルを(その一部が変化するかもしれない)構成部分に
分解したものを示すときなどのメタ変数には、すべて大文字を使う。
-
説明文字列でLispシンボルを参照するときには、
それが表示されるとき(つまり普通はすべて小文字)のように
シングルクォートで囲って書く。
これには2つ例外があり、
t
とnil
は
シングルクォートで囲まない。
ヘルプモードでは、説明文字列でシングルクォートで囲ったシンボルを使うと、
そのシンボルに関数定義や変数定義があるときには自動的に
ハイパーリンクを作成する。
この機能を利用するために特別なことをする必要はない。
しかし、シンボルに関数定義と変数定義の両方があり、
どちらか一方のみを参照したい場合には、
シンボルの名前のまえに
`variable'、`option'、`function'、`command'の
いずれかの単語を書くだけでどちらであるかを指定できる。
(これらの単語を認識するときには大文字小文字は区別しない。)
たとえばつぎのように書くと、
This function sets the variable `buffer-file-name'.
ハイパーリンクは、変数buffer-file-name
の説明文字列を指し、
その関数の説明文字列は指さない。
シンボルに関数定義や変数定義があっても、
説明文字列でのシンボルの使い方には無関係な場合には、
シンボルの名前のまえに単語`symbol'を書けば、
ハイパーリンクを作らないようにできる。
たとえば、つぎのようにすると、
If the argument KIND-OF-RESULT is the symbol `list',
this function returns a list of all the objects
that satisfy the criterion.
ここではlist
の関数/変数定義は無関係なので、
関数list
の説明文字列を指すハイパーリンクは作られない。
-
説明文字列に直接キー列を書き込まないこと。
そのかわりに、それの標準的なキー列を作成する
`\\[...]'の書き方を使う。
たとえば、`C-f'と書くかわりに、`\\[forward-char]'と書く。
Emacsが説明文字列を表示するときに、
forward-char
に現在バインドされているキーにEmacsが置き換える。
(普通は`C-f'であるが、ユーザーがキーバインディングを変更していれば、
別の文字になる。)
see section 説明文内のキーバインディングの置換。
-
メジャーモードの説明文字列では、
グローバルなキーマップではなくそのモードのローカルなキーマップでの
キーバインディングを参照したいだろう。
それには、使用するキーマップを指定する構文`\\<...>'を
説明文字列の中に書く。
最初に`\\[...]'を使うまえにこうしておくこと。
`\\<...>'の内側のテキストは、
メジャーモード向けのローカルキーマップを保持する変数の名前であること。
説明文字列の表示を遅くしてしまうので、
`\\[...]'を何回も使うのは実用的ではない。
したがって、読者のメジャーモードのもっとも重要なコマンドの記述にこれを使い、
モードのキーマップの残りを表示するには`\\{...}'を使う。
コメントを置く場所とそれらの字下げ方法については以下のような慣習を推奨します。
- `;'
-
1つのセミコロン`;'で始まるコメントは、
ソースコードの右側で同じコラム位置に揃えること。
そのようなコメントは、その行のコードの動作を説明する。
lispモードやその関連するモードでは、
コマンドM-;(
indent-for-comment
)で
自動的に右側の正しい位置に`;'を挿入したり、
そのようなコメントが既存ならば整列できる。
つぎとその下の例は、Emacsのソースから持ってきたものである。
(setq base-version-list ; there was a base
(assoc (substring fn 0 start-vn) ; version to which
file-version-assoc-list)) ; this looks like
; a subversion
- `;;'
-
2つのセミコロン`;;'で始まるコメントは、
その部分のコードの字下げに揃えること。
そのようなコメントは、その後続の行の目的や
その箇所でのプログラムの状態を記述する。
(prog1 (setq auto-fill-function
...
...
;; update mode line
(force-mode-line-update)))
説明文字列を持たない各関数
(所属するパッケージで内部向けにのみ使用される関数)では、
関数が行うことと正しい呼び出し方を記述した
2つのセミコロンで始まるコメントを関数のまえに書くこと。
各引数の意味とその可能な値を関数がどのように解釈するかを正確に説明すること。
- `;;;'
-
3つのセミコロン`;;;'で始まるコメントは、左端に揃えること。
そのようなコメントは、関数定義の外側で使い、
プログラムの設計原理を説明する一般的な表明である。
たとえばつぎのとおり。
;;; This Lisp code is run in Emacs
;;; when it is to operate as a server
;;; for other processes.
3つのセミコロンで始まるコメントの別の使い方は、
関数内の行をコメントにする場合である。
そのような行が左端に留まるように3つのセミコロンを使うのである。
(defun foo (a)
;;; This is no longer necessary.
;;; (force-mode-line-update)
(message "Finished with %s" a))
- `;;;;'
-
4つのセミコロン`;;;;'で始まるコメントは、
左端に揃えて、プログラムの主要な部分のヘッダに使う。
たとえばつぎのとおり。
;;;; The kill ring
M-;(indent-for-comment
)や
TAB(lisp-indent-line
)などの
Emacsのlispモードの字下げコマンドは、
これらの慣習にしたがって自動的にコメントを字下げします。
See section `コメントの操作' in GNU Emacs マニュアル。
Emacsには、コメントをいくつかの部分に分けて作者などの情報を与えるために、
Lispライブラリの特別なコメントに対する慣習があります。
本節ではそれらの慣習について述べます。
まず、例を示します。
;;; lisp-mnt.el --- minor mode for Emacs Lisp maintainers
;; Copyright (C) 1992 Free Software Foundation, Inc.
;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
;; Maintainer: Eric S. Raymond <esr@snark.thyrsus.com>
;; Created: 14 Jul 1992
;; Version: 1.2
;; Keywords: docs
;; This file is part of GNU Emacs.
...
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
最初の行はつぎの形式であるべきです。
;;; filename --- description
この記述は1行で完全になるようにします。
著作権表示のあとには、`;; header-name:'で始まる
いくつかのヘッダコメント(header comment)行が続きます。
header-nameに使う可能性のある慣習の一覧を以下に示します。
- `Author'
-
この行では、少なくともライブラリの主作者の
氏名とネットワークアドレスを明記する。
複数の作者がいる場合には、以下のように、
;;
とタブ文字で始めた継続行に
その人達を列挙する。
;; Author: Ashwin Ram <Ram-Ashwin@cs.yale.edu>
;; Dave Sill <de5@ornl.gov>
;; Dave Brennan <brennan@hal.com>
;; Eric Raymond <esr@snark.thyrsus.com>
- `Maintainer'
-
この行には、作者行(`Author')のように1人の氏名とアドレス、
アドレスのみ、文字列`FSF'のいずれかを書く。
保守者行(`Maintainer')がない場合には、
作者行の人達が保守していると仮定する。
上の例は、保守者行が冗長であり、少々いんちきである。
作者行(`Author')と保守者行(`Maintainer')の考えは、
手作業で名前を探さずに『保守者にメイルを送る』ようなLisp関数を
作れるようにするためである。
ネットワークアドレスに加えて人の氏名も書く場合には、
ネットワークアドレスを`<...>'で必ず囲むこと。
- `Created'
-
この行は省略できるが、ファイルの作成日時を書く。
歴史的な意味だけである。
- `Version'
-
各Lispプログラムの版番号を記録しておきたい場合に、
この行に版番号を書く。
- `Adapted-By'
-
このヘッダ行では、(たとえば、スタイルの慣習に適合するように変更したなどの)
インストールのためにライブラリを受理した人の名前を書く。
- `Keywords'
-
この行には、ヘルプコマンド
finder-by-keyword
向けの
キーワードを書く。
意味のあるキーワードを理解するためにこのコマンドを試してほしい。
この部分は重要である。
人々が特定の話題で探して読者のパッケージをみつけるであろう。
キーワードは空白やカンマで区切る。
ほとんどのLispライブラリには、
`Author'と`Keywords'のヘッダコメント行が必要です。
残りのものは必要に応じて使います。
別の名前のヘッダ行があってもかまいません。
それらには標準的な意味はありませんが、害になることもありません。
ライブラリファイルの内容を分割するために形式を定めたコメントも使います。
それらを以下に示します。
- `;;; Commentary:'
-
ライブラリの動作を説明する入門的なコメントを始める。
著作権表示の直後にきて、
`Change Log'、`History'、`Code'のいずれかのコメント行で終る。
このテキストはパッケージfinderが使うので、
その文脈で意味があるようにすること。
- `;;; Documentation'
-
`;;; Commentary:'のかわりに使っているファイルもあるが、
`;;; Commentary:'のほうが好ましい。
- `;;; Change Log:'
-
(変更履歴をライブラリに収める場合の)
ライブラリファイルに収めた変更記録情報を始める。
Emacsで配布されるほとんどのLispファイルでは、
変更履歴はファイル`ChangeLog'に収めてあり、
ソースファイルには収めない。
それらのファイルには`;;; Change Log:'行はない。
- `;;; Code:'
-
プログラムの実際のコードを始める。
- `;;; filename ends here'
-
これは最終行(footer line)であり、ファイルの末尾に現れる。
その目的は、最終行が欠如していることでファイルが切り詰められていることが
わかるようにするのである。
Go to the first, previous, next, last section, table of contents.