本章では、Emacs Lispの機能についてさらに述べることはしません。 かわりに、前章までに述べてきた機能を効率よく使うための助言や Emacs Lispプログラマが従うべき慣習について述べます。
ここでは、読者が広く使われることを意図した Emacs 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を使う。
(eval-when-compile (require 'bar))(さらに、
requireが働くように、
ライブラリbarには(provide 'bar)があること。)
この式により、fooをバイトコンパイルするときに
barをロードすることになる。
さもないと、必要なマクロをロードせずにfooをコンパイルする危険を侵し、
正しく動作しないコンパイル済みコードを生成することになる。
see section マクロとバイトコンパイル。
eval-when-compileを使うことで、
fooのコンパイル済みの版を使うときには
barをロードしない。
framepやframe-live-pである。
whatever-modeという
名前のコマンドを用意し、自動ロード(see section 自動ロード)するようにする。
パッケージをロードしただけでは見ためには効果がない、
つまり、その機能をオンにしないようにパッケージを設計すること。
ユーザーはコマンドを起動してその機能をオンにする。
next-lineやprevious-lineを使わないこと。
ほとんどの場合、forward-lineのほうがより便利であり、
予測可能で堅牢でもある。
see section テキスト行単位の移動。
beginning-of-buffer, end-of-buffer
replace-string, replace-regexp
princではなく関数messageを使うことである。
see section エコー領域。
error(あるいはsignal)を呼び出す。
関数errorは戻ってこない。
see section エラーの通知方法。
エラーを報告するために、
message、throw、sleep-for、beepは使わないこと。
...の周りに空白はなく、末尾にピリオドもない。
edit-optionsのようにする。
別のバッファに切り替え、戻るのはユーザーに任せる。
see section 再帰編集。
defvarの定義を追加して、
コンパイル時の未定義な自由変数に対する警告を避けるように努めること。
ある関数で変数を束縛しその変数を別の関数で使ったり設定すると、
その変数を定義しない限りコンパイラは後者の関数について警告を出す。
しかし、しばしばこれらの変数は短い名前で、
Lispパッケージでそのような変数名を定義すべきかどうか明らかでない。
したがって、そのような変数の名前は、
読者のパッケージの他の関数や変数に使っている接頭辞で
始まる名前に改名すべきである。
indent-sexp)で字下げすること。
;; 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プログラムの実行速度を改良する方法を示します。
memq、member、assq、assocのリスト探索基本関数を
使うほうが明示的な繰り返しよりも速い。
これらの探索基本関数の1つを使えるようにデータ構造を変更する価値はある。
byte-compileを調べる。
属性がnil以外であれば、その関数は特別に扱われる。
たとえば、つぎの入力は、arefが特別にコンパイルされることを示す
(see section 配列操作関数)。
(get 'aref 'byte-compile)
=> byte-compile-two-args
説明文字列を書くうえでのヒントや慣習を述べます。 コマンドM-x checkdoc-minor-modeを実行して、 これらの慣習の多くを確認できます。
nil以外の値はすべて同値であることを明らかにし、
nilとnil以外の意味を明確に示すこと。
/の説明文字列では、
その第2引数の名前はdivisorなので、`DIVISOR'と表す。
また、リストやベクトルを(その一部が変化するかもしれない)構成部分に
分解したものを示すときなどのメタ変数には、すべて大文字を使う。
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の説明文字列を指すハイパーリンクは作られない。
forward-charに現在バインドされているキーにEmacsが置き換える。
(普通は`C-f'であるが、ユーザーがキーバインディングを変更していれば、
別の文字になる。)
see section 説明文内のキーバインディングの置換。
コメントを置く場所とそれらの字下げ方法については以下のような慣習を推奨します。
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
(prog1 (setq auto-fill-function
...
...
;; update mode line
(force-mode-line-update)))
説明文字列を持たない各関数
(所属するパッケージで内部向けにのみ使用される関数)では、
関数が行うことと正しい呼び出し方を記述した
2つのセミコロンで始まるコメントを関数のまえに書くこと。
各引数の意味とその可能な値を関数がどのように解釈するかを正確に説明すること。
;;; 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))
;;;; 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: Ashwin Ram <Ram-Ashwin@cs.yale.edu> ;; Dave Sill <de5@ornl.gov> ;; Dave Brennan <brennan@hal.com> ;; Eric Raymond <esr@snark.thyrsus.com>
finder-by-keyword向けの
キーワードを書く。
意味のあるキーワードを理解するためにこのコマンドを試してほしい。
この部分は重要である。
人々が特定の話題で探して読者のパッケージをみつけるであろう。
キーワードは空白やカンマで区切る。
ほとんどのLispライブラリには、 `Author'と`Keywords'のヘッダコメント行が必要です。 残りのものは必要に応じて使います。 別の名前のヘッダ行があってもかまいません。 それらには標準的な意味はありませんが、害になることもありません。
ライブラリファイルの内容を分割するために形式を定めたコメントも使います。 それらを以下に示します。
Go to the first, previous, next, last section, table of contents.