[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

24. ファイル

Emacsでは、ファイルやディレクトリを 探したり、作成したり、眺めたり、保存したり、その他のことをできます。 本章では、Emacs Lispのファイル関連の関数のほとんどについて説明しますが、 他の一部は26. バッファで、バックアップや自動保存に関することは 25. バックアップと自動保存で説明します。

ファイル関数の多くは、ファイル名の引数を1つないし複数個取ります。 ファイル名は実際には文字列です。 これらのほとんどの関数では、expand-file-nameを呼び出して ファイル名引数を展開することで`~'や (`../'を含む)相対ファイル名を正しく処理します。 これらの関数は、`$HOME'などの環境変数置換は認識しません。 See section 24.8.4 ファイル名を展開する関数

24.1 ファイルの訪問  Reading files into Emacs buffers for editing.
24.2 バッファの保存  Writing changed buffers back into files.
24.3 ファイルの読み込み  Reading files into buffers without visiting.
24.4 ファイルへの書き出し  Writing new files from parts of buffers.
24.5 ファイルロック  Locking and unlocking files, to prevent simultaneous editing by two people.
24.6 ファイルに関する情報  Testing existence, accessibility, size of files.
24.7 ファイルの名前と属性の変更  Renaming files, changing protection, etc.
24.8 ファイル名  Decomposing and expanding file names.
24.9 ディレクトリの内容  Getting a list of the files in a directory.
24.10 ディレクトリの作成と削除  Creating and Deleting Directories.
24.11 ファイル名を『マジック』にする  Defining "magic" special handling for certain file names.
24.12 ファイル書式変換  Conversion to and from various file formats.


24.1 ファイルの訪問

ファイルを訪問するとは、ファイルをバッファに読み込むことです。 いったんこうすると、バッファはそのファイルを 訪問している(visiting)といい、 そのファイルをバッファの『訪問しているファイル』と呼びます。

ファイルとバッファは2つの異なるものです。 ファイルは、コンピュータ内に(読者が削除しない限り)恒久的に 記録されている情報です。 一方、バッファはEmacs内部にある情報であり、 編集セッションを終了する(あるいはバッファを削除する)と消えてしまいます。 通常、バッファにはファイルからコピーした情報があります。 つまり、バッファはそのファイルを訪問しているのです。 読者は、バッファ内のコピーを編集コマンドで修正するのです。 バッファに対するそのような変更では、ファイルは変更しません。 したがって、変更を恒久的なものにするには、 読者はバッファを保存(save)する、つまり、 バッファの変更した内容をファイルにコピーし戻す必要があります。

ファイルとバッファの区別にも関わらず、 バッファを意味してファイルといったり、その逆のいい方をしばしばします。 もちろん、『同じ名前のファイルにただちに保存するつもりでバッファを 編集している』とはいわずに『ファイルを編集している』といいます。 しばしば、人間は明確に区別する必要はありません。 しかし、コンピュータプログラムを扱ううえでは、 区別を心得ておくことがよいのです。

24.1.1 ファイルを訪問する関数  The usual interface functions for visiting.
24.1.2 訪問するためのサブルーティン  Lower-level subroutines that they use.


24.1.1 ファイルを訪問する関数

本節では、ファイルを訪問するために通常使う関数について述べます。 歴史的な理由で、これらの関数は`visit-'でなく`find-'という 名前で始まります。 バッファで訪問したファイルの名前を参照するための関数や変数、ならびに、 訪問したファイルの名前で既存バッファを探すための関数や変数については、 See section 26.4 バッファファイル名

Lispプログラムにおいて、ファイルの内容を変更せずにその内容を調べたいときには、 もっとも速い方法は一時的なバッファでinsert-file-contentsを 使うことです。 ファイルを訪問する必要はありませんし、それには余計に時間がかかります。 See section 24.3 ファイルの読み込み

コマンド: find-file filename
このコマンドはファイルfilenameを訪問したバッファを選択する。 そのようなバッファが既存ならば当該バッファを使う。 さもなければ、新たなバッファを作成してファイルを読み込む。 当該バッファを返す。

関数find-fileの本体は非常に簡単で、つぎのとおりである。

 
(switch-to-buffer (find-file-noselect filename))

27.7 ウィンドウへのバッファの表示switch-to-bufferを参照。)

find-fileが対話的に呼び出されると、 ミニバッファでfilenameを問い合わせる。

Function: find-file-noselect filename &optional nowarn rawfile
この関数は、ファイルを訪問するすべての関数の基である。 ファイルfilenameを訪問した/するバッファを探し/作成し、 当該バッファを返す。 そのようなバッファが既存ならば当該バッファを使う。 さもなければ、新たなバッファを作成してファイルを読み込む。 必要に応じて、バッファをカレントバッファにしたり ウィンドウに表示できるが、この関数はそこまでは行わない。

find-file-noselectが既存バッファを使うときには、 ファイルの内容が当該バッファに最後に訪問してから、あるいは、 当該バッファを最後に保存してから変更されたかどうかまず確認する。 ファイルが変更されていれば、この関数は変更されたファイルを 再度読み込むかどうかユーザーに問い合わせる。 ユーザーが`yes'と答えると、バッファ内の変更は破棄される。

省略可能な引数nowarnnilであると、 この関数はさまざまな場面で警告/助言メッセージを表示する。 たとえば、バッファを作成する必要があり、かつ、 指定したファイルfilenameがない場合には、 エコー領域にメッセージ`New file'を表示し、バッファは空にしておく。

関数find-file-noselectは、 ファイルを読み込み終えると通常after-find-fileを呼び出す (see section 24.1.2 訪問するためのサブルーティン)。 その関数は、バッファのメジャーモードを設定し、ローカル変数を解析し、 訪問したファイルより新しい自動保存ファイルが存在するとユーザーに警告を発し、 find-file-hooksの関数を実行して処理を終える。

省略可能な引数rawfilenil以外であると、 after-find-fileを呼び出さず、 失敗してもfind-file-not-found-hooksを実行しない。 さらに、rawfileの値がnil以外であると、 コーディングシステムの変換(see section 32.10 コーディングシステム)や 書式変換(see section 24.12 ファイル書式変換)も行わない。

関数find-file-noselectは、 ファイルfilenameを訪問したバッファを返す。

 
(find-file-noselect "/etc/fstab")
     => #<buffer fstab>

コマンド: find-file-other-window filename
このコマンドは、選択しているウィンドウ以外のウィンドウにおいて、 ファイルfilenameを訪問したバッファを選択する。 別の既存ウィンドウを使うか、ウィンドウを分割する。 27.7 ウィンドウへのバッファの表示を参照。

このコマンドが対話的に呼び出されると、 filenameを問い合わせる。

コマンド: find-file-read-only filename
このコマンドは、find-fileのようにファイルfilenameを訪問した バッファを選択するが、当該バッファは読み出し専用となる。 See section 26.7 読み出し専用バッファ

このコマンドが対話的に呼び出されると、 filenameを問い合わせる。

コマンド: view-file filename
このコマンドは、閲覧(view)モードでfilenameを訪問し、 閲覧(view)モードを抜けるとそれ以前のバッファに戻る。 閲覧(view)モードは、ファイルを素早く眺めるためのコマンドを与えるが テキストの変更は許さないマイナモードである。 閲覧(view)モードに入ると、ノーマルフックview-mode-hookを実行する。 see section 22.6 フック

view-fileが対話的に呼び出されると、 filenameを問い合わせる。

Variable: find-file-hooks
この変数の値は、ファイルを訪問後に呼び出される関数のリストである。 ファイルにローカル変数指定(があれば)は、 フックを実行するまえに処理される。 フック関数が実行されときには、 ファイルを訪問したバッファはカレントバッファになっている。

この変数はノーマルフックのように動作するが、 改名すべきではないと考えている。 see section 22.6 フック

Variable: find-file-not-found-hooks
この変数の値は、find-filefind-file-noselectに 存在しないファイルを与えたときに呼び出される関数のリストである。 find-file-noselectは、ファイルが存在しないことがわかると ただちにこれらの関数を呼び出す。 nil以外の値が返されるまで、リストに現れる順に呼び出す。 buffer-file-nameは設定済みである。

関数の値を使い、しかも、一部の関数だけを呼び出すので、 これはノーマルフックではない。


24.1.2 訪問するためのサブルーティン

関数find-file-noselectは、ユーザーのLispコードでも有用な 2つの重要なサブルーティン、create-file-bufferafter-find-fileを使います。 本節ではそれらの使い方を説明します。

Function: create-file-buffer filename
この関数は、filenameを訪問するのに適するように命名した バッファを作成しそれを返す。 (ディレクトリを除外した)filenameが使用中の名前でなければ、 それを名前とする。 さもなければ、未使用の名前を得るために`<2>'などの文字列を付加する。 26.9 バッファの作成も参照。

注意: create-file-bufferは、 新たなバッファをファイルに対応付けないし、 当該バッファを選択しない。 デフォルトのメジャーモードも使わない。

 
(create-file-buffer "foo")
     => #<buffer foo>
(create-file-buffer "foo")
     => #<buffer foo<2>>
(create-file-buffer "foo")
     => #<buffer foo<3>>

この関数はfind-file-noselectで使われる。 この関数はgenerate-new-buffer(see section 26.9 バッファの作成)を使う。

Function: after-find-file &optional error warn
この関数は、バッファのメジャーモードを設定し、 ローカル変数を解析する(see section 22.1.3 メジャーモードの選択方法)。 find-file-noselectや デフォルトの復元処理関数(see section 25.3 復元)から呼ばれる。

ディレクトリはあるのにファイルが存在しないために ファイルの読み込みがエラーになった場合には、 呼び出し側はerrorの値としてnil以外を渡すこと。 その場合、after-find-fileは警告`(New File)'を表示する。 より重大なエラーの場合には、after-find-fileを呼び出すべきでない。

warnnil以外であると、 自動保存ファイルが存在しそれが訪問したファイルより新しい場合には、 この関数は警告を発する。

after-find-fileが最後に行うことは、 リストfind-file-hooks内のすべての関数を呼び出すことである。


24.2 バッファの保存

Emacsでファイルを編集するときには、 ファイルを訪問したバッファを実際には扱っています。 つまり、ファイルの内容はバッファにコピーされ、 そのコピーを編集しているのです。 バッファを変更しても、当該バッファを保存(save)するまで、 つまり、バッファの内容をファイルへコピーするまでは、 ファイルを変更しません。

コマンド: save-buffer &optional backup-option
この関数は、最後に訪問/保存してからカレントバッファが変更されていれば、 カレントバッファの内容を訪問しているファイルへ保存する。

save-bufferは、バックアップの作成に責任がある。 通常、backup-optionnilであり、 save-bufferは、ファイルを訪問してから 最初に保存するときにのみバックアップファイルを作成する。 backup-optionが別の値であると、 別の場面でもバックアップファイルを作成することを指示する。

コマンド: save-some-buffers &optional save-silently-p exiting
このコマンドは、ファイルを訪問している変更されたバッファを保存する。 通常、各バッファについてユーザーに問い合わせる。 しかし、save-silently-pnil以外であると、 ユーザーに問い合わせずにファイルを訪問しているバッファをすべて保存する。

省略可能な引数exitingnil以外であると、 この関数は、ファイルを訪問していないある種のバッファを保存する機会も与える。 buffer-offer-saveのバッファローカルな値が nil以外のバッファが対象となる。 (ユーザーがこれらのバッファの1つを保存するように答えると、 ファイル名を指定するように聞いてくる。) 関数save-buffers-kill-emacsは、 この引数にnil以外の値を渡す。

コマンド: write-file filename
この関数は、カレントバッファをファイルfilenameに保存し、 当該ファイルを訪問しているバッファとし、さらに未変更という印を付ける。 続いて、バッファ名を一意にするために必要ならば`<2>'のような 文字列を付加して、バッファをfilenameに基づいた名前に改名する。 この処理のほとんどは、set-visited-file-name(see section 26.4 バッファファイル名) とsave-bufferを呼び出して行う。

バッファを保存すると、いくつかのフックを実行します。 また、書式変換(see section 24.12 ファイル書式変換)を行い、 テキスト属性を『注記』(annotations)(see section 31.19.7 テキスト属性をファイルへ保存する)に 保存することもあります。

Variable: write-file-hooks
この変数の値は、バッファを訪問しているファイルに書き出すまえに 呼ばれる関数のリストである。 それらの1つがnil以外を返すと、すでにファイルに書き出したとみなして 残りの関数を呼び出さず、ファイルに書き出すための通常のコードも実行しない。

write-file-hooksの関数がnil以外を返すときには、 その関数には(必要ならば)バックアップファイルを作成する責任がある。 そのためにはつぎのコードを実行する。

 
(or buffer-backed-up (backup-buffer))

backup-bufferが返したファイルモードの値を保存しておき、 読者が書くファイルのモードにその値を使いたい場合がある。 save-bufferは通常そのようにする。

write-file-hooksのフック関数は、 (必要ならば)データの符号化にも責任がある。 適切なコーディングシステム(see section 32.10.3 Lispにおけるコーディングシステム)を選び、 符号化(see section 32.10.7 明示的な符号化と復号化)を行い、 使用したコーディングシステムをlast-coding-system-usedに設定する (see section 32.10.2 符号化と入出力)。

この変数をバッファローカルにはしないこと。 バッファ固有のフック関数を指定するには、 かわりにwrite-contents-hooksを使う。

これはノーマルフックではないが、 add-hookremove-hookでリストを扱える。 see section 22.6 フック

Variable: local-write-file-hooks
これはwrite-file-hooksのように働くが、 特定のバッファにバッファローカルにするように意図してあり、 ファイル名に関するフックやバッファ内容を得た方法に関する フックとして使われる。

変数は恒久的にバッファローカルと印が付いているので、 メジャーモードを変更してもバッファローカルな値は変更されない。 これは、『ファイル』の内容を特別な方法で読み込み、 対応した方法でデータを保存するフックを設定するようなパッケージには便利である。

Variable: write-contents-hooks
この変数はwrite-file-hooksのように働くが、 ファイルの場所に関するフックではなく、 ファイルの内容に関するフックであると意図されている。 そのようなフックは、この変数のバッファローカルな束縛として メジャーモードが通常設定する。

この変数に設定すると自動的にバッファローカルになる。 このフックに要素を追加するためにadd-hooksを使うときには、 引数localnil以外を指定しないこと。 この変数はバッファローカルのみであるからである。

Variable: after-save-hook
このノーマルフックは、バッファを訪問したファイルに 保存し終えてから実行される。 このフックの用途の1つは高速ロック(fast-lock)モードである。 このフックを使って強調表示情報をキャッシュファイルに保存する。

Variable: file-precious-flag
この変数がnil以外ならば、 save-bufferは保存処理中の入出力エラーに備えて対処する。 つまり、目的の名前のファイルにではなく一時的な名前の新規ファイルに書き出し、 エラーがないことを確認してから目的の名前に改名する。 これにより、不正なファイルに起因する問題からディスク容量の不足といった 問題を回避できる。

副作用として、バックアップも必然的にコピーして行う。 see section 25.1.2 改名によるバックアップかコピーによるバックアップか。 それと同時に、大事な(precious)ファイルとして保存すると、 読者が保存したファイルと別のファイル名とのあいだの ハードリンクをつねに切ってしまう。

特定のバッファではこの変数にnil以外のバッファローカルな値を 指定するモードもある。

User Option: require-final-newline
この変数は、改行で終らないファイルを書き出すかどうかを決定する。 この変数の値がtであると、save-bufferは、 保存するバッファが改行で終っていないと黙ってファイルの末尾に改行を追加する。 この変数の値がtではないnil以外であると、 save-bufferは、必要な場面では 改行を追加するかどうかユーザーに問い合わせる。

この変数の値がnilであると、save-bufferは改行を追加しない。 デフォルト値はnilであるが、特定のバッファではtに 設定するメジャーモードもある。

関数set-visited-file-name(see section 26.4 バッファファイル名)も 参照してください。


24.3 ファイルの読み込み

関数insert-file-contentsを使って ディスクからファイルをバッファへコピーできます。 ユーザーレベルのコマンドinsert-fileはマークを設定するので Lispプログラムでは使わないでください。

Function: insert-file-contents filename &optional visit beg end replace
この関数は、ファイルfilenameの内容をカレントバッファの ポイントのうしろに挿入する。 絶対ファイル名と挿入したデータの長さから成るリストを返す。 filenameが読み込めるファイルの名前でないと、エラーを通知する。

関数insert-file-contentsは、 ファイルの内容を定義済みのファイルの書式と比較し、 必要ならばファイルの内容を変換する。 see section 24.12 ファイル書式変換。 リストafter-insert-file-functionsの関数も呼び出す。 31.19.7 テキスト属性をファイルへ保存するを参照。

visitnil以外であると、 この関数はバッファを未変更と印を付け、 ファイルfilenameを訪問しているバッファとなるように バッファのさまざまな部分を設定する。 これには、バッファが訪問しているファイルの名前、ファイル更新時刻を含む。 この機能はfind-file-noselectで使われており、 読者自身が使うことはないであろう。

begendnil以外であると、 それらは挿入すべきファイルの部分を指定する整数であること。 この場合、visitnilであること。 たとえば、

 
(insert-file-contents filename nil 0 500)

はファイルの最初の500文字を挿入する。

引数replacenil以外であると、 バッファの内容(実際には参照可能な部分のみ)を ファイルの内容で置き換えることを意味する。 これは、単純にバッファの内容を削除してからファイル全体を挿入するより 好ましい。 なぜなら、(1)マーカ位置を保存できる場合がある、 (2)アンドゥリストにほとんどデータを入れない、からである。

replacevisitnilである限り、 insert-file-contentsで(FIFOや入出力装置などの) 特別なファイルを読むことも可能である。

Function: insert-file-contents-literally filename &optional visit beg end replace
この関数はinsert-file-contentsのように動作するが、 書式を変換しない(see section 24.12 ファイル書式変換)、 文字コードを変換しない(see section 32.10 コーディングシステム)、 find-file-hooksを実行しない、自動的に解凍しないなどが異なる。

別のプログラムが読めるようにファイル名を別のプロセスに渡すには、 関数file-local-copyを使います。 24.11 ファイル名を『マジック』にするを参照してください。


24.4 ファイルへの書き出し

関数append-to-filewrite-regionを使って、 バッファの内容やその一部をディスク上のファイルへ直接書き出せます。 訪問しているファイルには、これらの関数で書き出さないでください。 訪問の機構に混乱をきたすことがあります。

コマンド: append-to-file start end filename
この関数は、カレントバッファのstartからendで 区切られる領域の内容をファイルfilenameの末尾に追加する。 当該ファイルが存在しなければ作成する。 この関数はnilを返す。

書き込めないファイルをfilenameに指定したり、 ファイルを作成できないディレクトリ上の存在しないファイルを filenameに指定するとエラーを通知する。

コマンド: write-region start end filename &optional append visit confirm
この関数は、カレントバッファのstartからendで 区切られる領域の内容をfilenameで指定したファイルに書き出す。

startが文字列であると、 write-regionはバッファのテキストではなく その文字列を書いたり追加する。

appendnil以外であると、 指定したテキストを既存ファイル(があれば)の内容に追加する。

confirmnil以外であると、 filenameが既存ファイルの名前であると write-regionは確認を求める。

visittであると、 Emacsはバッファとファイルの対応を確立する。 つまり、バッファはそのファイルを訪問していることになる。 さらに、カレントバッファの最終ファイル更新時刻を filenameの更新時刻にし、 バッファには未変更と印を付ける。 この機能はsave-bufferが使っているが、 読者自身が使うことはないであろう。

visitが文字列であると、訪問するファイルの名前を指定する。 このようにして、データを1つのファイル(filename)に書き出す一方で、 バッファは別のファイル(visit)を訪問していると設定できる。 引数visitはエコー領域のメッセージに使われ、 ファイルのロックにも使われる。 visitbuffer-file-nameに保存される。 この機能はfile-precious-flagの実装に使われているが、 読者は、なにをしているか理解できない限り、この機能を使わないこと。

関数write-regionは、書き出すデータを buffer-file-formatで指定される適切なファイル書式に変換する。 see section 24.12 ファイル書式変換。 さらに、リストwrite-region-annotate-functionsの関数も呼び出す。 31.19.7 テキスト属性をファイルへ保存するを参照。

通常、write-regionはエコー領域にメッセージ `Wrote filename'を表示する。 visittでもnilでも文字列でもないと、 このメッセージは表示しない。 この機能は、ユーザーが知る必要のない 内部目的にファイルを使うプログラムに有用である。

Macro: with-temp-file file body...
マクロwith-temp-fileは、一時的なバッファをカレントバッファとして フォームbodyを評価する。 そして最後にバッファの内容をファイルfileに書き出す。 終了すると一時的なバッファを削除し、 フォームwith-temp-fileのまえにカレントバッファであったバッファに戻る。 bodyの最後のフォームの値を返す。

throwやエラーによる異常終了(see section 9.5 非ローカル脱出)であっても カレントバッファに戻る。

26.2 カレントバッファwith-temp-bufferも参照。


24.5 ファイルロック

2人のユーザーが同時に同じファイルを編集すると、互いに干渉し合います。 Emacsは、ファイルが変更されるとファイルロック(file lock)を 記録することで、このような状況が発生しないように努めます。 すると、Emacsは別のEmacsがロックしているファイルを訪問した バッファを変更しようとする最初の試みを検出でき、 ユーザーにどうすべきかを問い合わせます。

複数の計算機がファイルシステムを共有している場合には、 ファイルロックには完全な信頼性はありません。 ファイルロックが働かないと、 2人のユーザーが同時に変更する可能性がありますが、 それでも、Emacsは2番目に保存したユーザーに警告できます。 また、ディスク上で変更されたファイルを訪問しているバッファの変更を 検出することで、同時編集のある場面を捕捉できます。 26.6 更新時刻の比較を参照してください。

Function: file-locked-p filename
ファイルfilenameがロックされていなければ、この関数はnilを返す。 このEmacsプロセスがロックしているときにはtを返す。 他のEmacsがロックしている場合には、ロックしているユーザーの名前を返す。

 
(file-locked-p "foo")
     => nil

Function: lock-buffer &optional filename
この関数は、カレントバッファが変更されていれば ファイルfilenameをロックする。 引数filenameのデフォルトは、 カレントバッファで訪問しているファイルである。 カレントバッファがファイルを訪問していなかったり、 未変更ならばなにもしない。

Function: unlock-buffer
この関数は、バッファが変更されていれば、 カレントバッファで訪問しているファイルのロックを解除する。 バッファが未変更ならばファイルをロックしていないはずであり、 この関数はなにもしない。 カレントバッファがファイルを訪問していなければ、 やはりなにもしない。

Function: ask-user-about-lock file other-user
この関数は、別のユーザーother-userがロックしている ファイルfileをユーザーが変更しようとしたときに呼び出される。 この関数のデフォルトの定義は、ユーザーになにをすべきか 問い合わせることである。 この関数の戻り値がEmacsのつぎの動作を決定する。

読者は、関数ask-user-about-lockを 別の方法で決定する読者独自のものに置き換えてもよい。 通常の定義に対応したコードは`userlock.el'にある。


24.6 ファイルに関する情報

本節に述べる関数はすべて、ファイル名を表す文字列に作用します。 すべての関数の名前は単語`file'で始まり、 それらの引数は、特に断らないかぎり、 既存のファイルやディレクトリである必要があります。

24.6.1 参照可能性の検査  Is a given file readable? Writable?
24.6.2 ファイルの種類の区別  Is it a directory? A symbolic link?
24.6.3 実名  Eliminating symbolic links from a file name.
24.6.4 ファイルに関する他の情報  How large is it? Any other names? Etc.


24.6.1 参照可能性の検査

これらの関数は、特別な方法でファイル参照のパーミッションを検査します。

Function: file-exists-p filename
ファイルfilenameが存在すれば、この関数はtを返す。 これは必ずしもファイルを読めることは意味せず、 単にファイルの属性を調べられるだけである。 (UNIXでは、ファイルが存在し、かつ、 それを収めたディレクトリに対する実行パーミッションがあれば、 ファイル自体のパーミッションに関係なくこのようになる。)

ファイルが存在しなかったり、ファイルの属性を探す権限がなければ、 この関数はnilを返す。

Function: file-readable-p filename
ファイルfilenameが存在しそれを読むことができるならば、 この関数はtを返す。 さもなければnilを返す。

 
(file-readable-p "files.texi")
     => t
(file-exists-p "/usr/spool/mqueue")
     => t
(file-readable-p "/usr/spool/mqueue")
     => nil

Function: file-executable-p filename
ファイルfilenameが存在しそれを実行できるならば、 この関数はtを返す。 さもなければnilを返す。 ファイルがディレクトリである場合、実行パーミッションは、 ディレクトリ内のファイルの存在やその属性を検査でき、 それらのファイルのモードが許せばオープンできることを意味する。

Function: file-writable-p filename
ファイルfilenameに書き出したり作成できるならば、 この関数はtを返し、さもなければnilを返す。 ファイルに書き出せるのは、ファイルが存在し書ける場合である。 作成できるのは、ファイルは存在しないが 指定したディレクトリが存在しそのディレクトリに書ける場合である。

以下の3番目の例では、`foo'の親ディレクトリが存在しないので、 たとえディレクトリを作成できるとしても`foo'は書けない。

 
(file-writable-p "~/foo")
     => t
(file-writable-p "/foo")
     => nil
(file-writable-p "~/no-such-dir/foo")
     => nil

Function: file-accessible-directory-p dirname
ディレクトリdirnameの既存ファイルをオープンするパーミッションがあれば、 この関数はtを返す。 さもなければ(あるいは当該ディレクトリが存在しなければ)nilを返す。 dirnameの値はディレクトリ名である。

例: つぎの例では、

 
(file-accessible-directory-p "/foo")
     => nil

から、`/foo/'内のファイルを読もうとすると エラーになると推論できる。

Function: access-file filename string
この関数は、ファイルfilenameを読むためにオープンし、 クローズしてからnilを返す。 しかし、オープンに失敗するとstringをエラーメッセージのテキストとした エラーを通知する。

Function: file-ownership-preserved-p filename
もしファイルfilenameを削除して改めて作成しても ファイルの所有者が変更されなければ、この関数はtを返す。

Function: file-newer-than-file-p filename1 filename2
ファイルfilename1filename2より新しければ、 この関数はtを返す。 filename1が存在しなければnilを返す。 filename2が存在しなければtを返す。

以下の例で、ファイル`aug-19'は19日に書かれ、 ファイル`aug-20'は20日に書かれ、 ファイル`no-file'は存在しないと仮定する。

 
(file-newer-than-file-p "aug-19" "aug-20")
     => nil
(file-newer-than-file-p "aug-20" "aug-19")
     => t
(file-newer-than-file-p "aug-19" "no-file")
     => t
(file-newer-than-file-p "no-file" "aug-19")
     => nil

file-attributesを使って、 2つの数から成るリストとしてファイルの最終更新時刻を取得できる。 see section 24.6.4 ファイルに関する他の情報


24.6.2 ファイルの種類の区別

本節ではさまざまな種類のファイル、つまり、 ディレクトリ、シンボリックリンク、普通のファイルを区別する方法を 説明します。

Function: file-symlink-p filename
ファイルfilenameがシンボリックリンクであると、 関数file-symlink-pは当該リンクが指すファイルの名前を返す。 これは、テキストファイル、ディレクトリ、別のシンボリックリンク、 存在しないファイルの名前のいずれかである。

ファイルfilenameがシンボリックリンクでない (あるいは当該ファイルが存在しない)場合、 file-symlink-pnilを返す。

 
(file-symlink-p "foo")
     => nil
(file-symlink-p "sym-link")
     => "foo"
(file-symlink-p "sym-link2")
     => "sym-link"
(file-symlink-p "/bin")
     => "/pub/bin"

Function: file-directory-p filename
ファイルfilenameが既存ディレクトリの名前であるとtを返し、 さもなければnilを返す。

 
(file-directory-p "~rms")
     => t
(file-directory-p "~rms/lewis/files.texi")
     => nil
(file-directory-p "~rms/lewis/no-such-file")
     => nil
(file-directory-p "$HOME")
     => nil
(file-directory-p
 (substitute-in-file-name "$HOME"))
     => t

Function: file-regular-p filename
ファイルfilenameが存在しそれが普通のファイル (ディレクトリでもシンボリックリンクでも名前付きパイプでも 端末でもその他の入出力装置でもない)であれば、 この関数はtを返す。


24.6.3 実名

ファイルの実名(truename)とは、 シンボリックリンクをすべて辿り尽くしてから、 要素として現れる`.' や`..' を簡略化して得られる名前です。 厳密にいえば、ファイルが一意の実名を持つ必要はありません。 ファイルの異なる実名の個数は、当該ファイルに対するハードリンクの個数に 等しいのです。 それでも、実名はシンボリックリンクによる名前の変動を取り除くため、 実名は有用です。

Function: file-truename filename
関数file-truenameはファイルfilenameの実名を返す。 これはシンボリックリンクをすべて辿り尽くして得られる名前である。 引数は絶対ファイル名であること。

関連情報については、See section 26.4 バッファファイル名


24.6.4 ファイルに関する他の情報

本節では、ファイルの内容以外の詳しい情報を得るための関数を説明します。 この情報には、参照パーミッションを制御するモードビット、 所有者とグループの番号、名前の個数、iノード番号、サイズ、 参照時刻と更新時刻が含まれます。

Function: file-modes filename
この関数はfilenameのモードビットを整数で返す。 モードビットはファイルのパーミッションとも呼ばれ、 UNIX流の参照制御を指定する。 最下位ビットが1であると、当該ファイルはすべてのユーザーが実行でき、 2番目の下位ビットが1であると、当該ファイルはすべてのユーザーが書ける といった具合である。

戻り値の最大値は4095(8進数7777)であり、これは、 だれもが読み/書き/実行でき、 所有者とグループの両者にビットSUIDが設定してあり、 スティッキービットも設定されていることを意味する。

 
(file-modes "~/junk/diffs")
     => 492               ; 10進整数
(format "%o" 492)
     => "754"             ; 8進数に変換

(set-file-modes "~/junk/diffs" 438)
     => nil

(format "%o" 438)
     => "666"             ; 8進数に変換

% ls -l diffs
  -rw-rw-rw-  1 lewis 0 3063 Oct 30 16:00 diffs

Function: file-nlinks filename
この関数は、ファイルfilenameの 名前(つまりハードリンク)の個数を返す。 ファイルが存在しなければ、この関数はnilを返す。 シンボリックリンクはそれが指すファイルの名前とはみなさないので、 シンボリックリンクはこの関数には効果を持たない。

 
% ls -l foo*
-rw-rw-rw-  2 rms       4 Aug 19 01:27 foo
-rw-rw-rw-  2 rms       4 Aug 19 01:27 foo1

(file-nlinks "foo")
     => 2
(file-nlinks "doesnt-exist")
     => nil

Function: file-attributes filename
この関数はファイルfilenameの属性のリストを返す。 オープンできないファイルを指定するとnilを返す。

リストの要素は順につぎのとおりである。

  1. ディレクトリはt、 シンボリックリンクは(それが指す名前の)文字列、 テキストファイルはnilである。

  2. ファイルの名前の個数。 別の名前、つまり、 ハードリンクは関数add-name-to-file(see section 24.7 ファイルの名前と属性の変更) を使って作成する。

  3. ファイルのUID(所有者番号)。

  4. ファイルのGID(グループ番号)。

  5. 2つの整数から成るリストとしての最終参照時刻。 最初の整数は時刻の上位16ビットであり、2番目は下位16ビット。 (これはcurrent-timeの値と同様。 37.5 時刻を参照。)

  6. 2つの整数から成るリストとしての最終更新時刻(上記と同様)。

  7. 2つの整数から成るリストとしての最終状態更新時刻(上記と同様)。

  8. バイト単位でのファイルのサイズ。

  9. `ls -l'と同様のファイルのモードを表す10文字の文字列。

  10. もしファイルを削除して再度作成した場合に ファイルのGID(グループ番号)が変わる場合にはt。 さもなければnil

  11. ファイルのiノード番号。 可能ならばこれは整数である。 iノード番号がEmacs Lispの整数として表現できないほど大きな場合、 値は(high . low)の形である。 ただし、lowは下位16ビットである。

  12. ファイルが置いてあるファイルシステムのファイルシステム番号。 この要素とファイルのiノード番号により、 システム上の任意の2つのファイルを区別するために十分な情報を与える。 つまり、2つのファイルが同じ値のこれらの番号を持つことはない。

たとえば、`files.texi'のファイル属性はつぎのようである。

 
(file-attributes "files.texi")
     =>  (nil 1 2235 75 
          (8489 20284) 
          (8489 20284) 
          (8489 20285)
          14906 "-rw-rw-rw-" 
          nil 129500 -32252)

この意味はつぎのとおりである。

nil
ディレクトリでもシンボリックリンクでもない。

1
唯一の名前(カレントディレクトリで`files.texi')を持つ。

2235
UID(ユーザー番号)2235のユーザーが所有している。

75
GID(グループ番号)75のグループに属する。

(8489 20284)
最後に参照されたのは8月19日00時09分である。

(8489 20284)
最後に更新されたのは8月19日00時09分である。

(8489 20285)
最後にこのiノードを変更したのは8月19日00時09分である。

14906
長さは14906バイトである。

"-rw-rw-rw-"
モードは、所有者/グループ/その他は読み書きできる。

nil
再度作成してもGID(グループ番号)は保存される。

129500
iノード番号は129500。
-32252
ファイルシステム番号は-32252。


24.7 ファイルの名前と属性の変更

本節の関数は、ファイルを改名/コピー/削除/リンクしたり、 ファイルのモードを設定するためのものです。

引数newnameをとる関数では、 newnameで指定したファイルが既存の場合、 関数の動作は引数ok-if-already-existsの値に依存します。

Function: add-name-to-file oldname newname &optional ok-if-already-exists
この関数は、oldnameで指定したファイルに 追加の名前newnameを与える。 つまり、newnameoldnameへの新たな『ハードリンク』になる。

つぎの例では、2つのファイル`foo'と`foo3'がある。

 
% ls -li fo*
81908 -rw-rw-rw-  1 rms       29 Aug 18 20:32 foo
84302 -rw-rw-rw-  1 rms       24 Aug 18 20:31 foo3

add-name-to-fileを呼んでハードリンクを作成し、 ファイル一覧を表示し直す。 1つのファイルに2つの名前`foo'と`foo2'があることがわかる。

 
(add-name-to-file "foo" "foo2")
     => nil

% ls -li fo*
81908 -rw-rw-rw-  2 rms       29 Aug 18 20:32 foo
81908 -rw-rw-rw-  2 rms       29 Aug 18 20:32 foo2
84302 -rw-rw-rw-  1 rms       24 Aug 18 20:31 foo3

最後につぎの式を評価し

 
(add-name-to-file "foo" "foo3" t)

ファイル一覧を表示し直す。 今度は、1つのファイルに3つの名前`foo'、`foo2'、`foo3'がある。 古い`foo3'の内容は失われている。

 
(add-name-to-file "foo1" "foo3")
     => nil

% ls -li fo*
81908 -rw-rw-rw-  3 rms       29 Aug 18 20:32 foo
81908 -rw-rw-rw-  3 rms       29 Aug 18 20:32 foo2
81908 -rw-rw-rw-  3 rms       29 Aug 18 20:32 foo3

1つのファイルに複数の名前を許さないオペレーティングシステムでは、 この関数は意味がない。

24.6.4 ファイルに関する他の情報file-nlinksも参照。

コマンド: rename-file filename newname &optional ok-if-already-exists
このコマンドは、ファイルfilenamenewnameと改名する。

filenamefilename以外の名前があれば、 それらの名前は存在し続ける。 実際、add-name-to-fileで名前newnameを追加してから filenameを削除すると、一時的な中間状態があることを除けば、 改名と同じ効果がある。

対話的に呼び出されると、この関数は ミニバッファでfilenamenewnameを聞く。 また、newnameが既存であると確認を求める。

コマンド: copy-file oldname newname &optional ok-if-exists time
このコマンドはファイルoldnamenewnameへコピーする。 oldnameが存在しないとエラーを通知する。

timenil以外であると、 この関数は新たなファイルに古いファイルと同じ最終更新時刻を与える。 (これは特定のオペレーティングシステムでのみ動作する。) 時刻設定でエラーがあると、copy-fileは エラーfile-date-errorを通知する。

対話的に呼び出されると、この関数は ミニバッファでoldnamenewnameを聞く。 また、newnameが既存であると確認を求める。

コマンド: delete-file filename
このコマンドは、シェルコマンド`rm filename'と同様に ファイルfilenameを削除する。 ファイルに複数の名前があると、他の名前では存在し続ける。

ファイルが存在しなかったり削除できないと、 エラーfile-errorの適切な種類が通知される。 (UNIXでは、ファイルを収めたディレクトリに書けると 当該ファイルは削除可能である。)

24.10 ディレクトリの作成と削除delete-directoryも参照。

コマンド: make-symbolic-link filename newname &optional ok-if-exists
このコマンドは、filenameに対するシンボリックリンクnewnameを 作成する。 これはシェルコマンド`ln -s filename newname'と同じである。

対話的に呼び出されると、この関数は ミニバッファでfilenamenewnameを聞く。 また、newnameが既存であると確認を求める。

Function: define-logical-name name string
この関数は論理名nameに値stringを定義する。 VMSでのみ使える。

Function: set-file-modes filename mode
この関数はfilenameのモードビットを mode(整数であること)と設定する。 modeの下位12ビットのみを使う。

Function: set-default-file-modes mode
この関数は、Emacsやそのサブプロセスが作成する新規ファイルの デフォルトのファイルモードを設定する。 Emacsが作成する各ファイルは最初このモードになる。 UNIXでは、デフォルトのモードは『umask』の値の1の補数である。

引数modeは整数であること。 ほとんどのシステムでは、modeの下位9ビットのみが意味を持つ。

既存ファイルの変更を保存することはファイルの作成とはみなさないため、 ファイルのモードは変わらず、デフォルトのファイルモードを使わない。

Function: default-file-modes
この関数は、現在のデフォルトのファイルモードの値を返す。

MS-DOSでは、『実行可能』ファイルモードビットのようなものはありません。 そのためEmacsは、`.com'、`.bat'、`.exe'のいずれかで 終る名前のファイルを実行可能であるとみなします。 これは、file-modesfile-attributesが返す値に反映されます。


24.8 ファイル名

他の場面と同様にEmacsでは、一般にファイルはその名前で参照します。 Emacsではファイル名は文字列で表します。 ファイルを操作する関数はすべてファイル名引数を仮定します。

ファイル自体の操作に加えて、Emacs Lispプログラムは ファイルの名前そのものを操作する必要があります。 つまり、ファイル名を分解したり、関連するファイル名を作成するために その一部を使います。 本節ではファイル名を操作する方法を説明します。

本節の関数は実際にはファイルを参照しませんから、 既存のファイルやディレクトリを表さないファイル名を操作できます。

VMSでは、これらの関数はすべて、VMSのファイル名構文と UNIXの構文の両方を理解します。 つまり、標準LispライブラリはUNIX構文でファイル名を指定でき、 変更せずにVMS上で正しく動作します。 MS-DOSやMS-Windowsでは、これらの関数は、 UNIX構文に加えてMS-DOSやMS-Windowsのファイル名構文を理解します。

24.8.1 ファイル名の構成要素  The directory part of a file name, and the rest.
24.8.2 ディレクトリ名  A directory's name as a directory is different from its name as a file.
24.8.3 ファイルの絶対名と相対名  Some file names are relative to a current directory.
24.8.4 ファイル名を展開する関数  Converting relative file names to absolute ones.
24.8.5 一意なファイル名の生成  Generating names for temporary files.
24.8.6 ファイル名の補完  Finding the completions for a given file name.
24.8.7 標準ファイル名  If your package uses a fixed file name, how to handle various operating systems simply.


24.8.1 ファイル名の構成要素

オペレーティングシステムは、一連のファイルをディレクトリにまとめます。 ファイルを指定するには、ディレクトリと当該ディレクトリ内のファイルの名前を 指定する必要があります。 そのためEmacsは、ファイル名には2つの部分、 ディレクトリ名(directory name)部分と 非ディレクトリ名(nondirectory name)部分 (つまりディレクトリ内のファイル名)があるとみなします。 どちらかの部分は空でもかまいません。 これらの2つの部分を連結するともとのファイル名になります。

UNIXでは、ディレクトリ部分は最後のスラッシュまでを含んだ部分であり、 非ディレクトリ部分は残りの部分です。 VMSの構文規則は複雑です。

ある種の目的のために、非ディレクトリ部分をさらに 名前だけの部分と版番号(version number)に分けます。 UNIXでは、バックアップファイルだけにそれらの名前に版番号があります。 VMSでは各ファイルに版番号がありますが、 ほとんどの場合、Emacsで実際に使うファイル名では版番号を省略します。 そのため、Emacsで版番号が見えるのは多くの場合ディレクトリ一覧です。

Function: file-name-directory filename
この関数はfilenameのディレクトリ部分 (ディレクトリ部分がなければnil)を返す。 UNIXでは、この関数はスラッシュで終る文字列を返す。 VMSでは、`:'、`]'、`>'のいずれかで終る文字列を返す。

 
(file-name-directory "lewis/foo")  ; UNIXの例
     => "lewis/"
(file-name-directory "foo")        ; UNIXの例
     => nil
(file-name-directory "[X]FOO.TMP") ; VMSの例
     => "[X]"

Function: file-name-nondirectory filename
この関数はfilenameの非ディレクトリ部分を返す。

 
(file-name-nondirectory "lewis/foo")
     => "foo"
(file-name-nondirectory "foo")
     => "foo"
;; つぎの例はVMSでのみ正確である
(file-name-nondirectory "[X]FOO.TMP")
     => "FOO.TMP"

Function: file-name-sans-versions filename
この関数は、filenameから版番号、バックアップ版番号、 末尾のティルダをすべて削除したものを返す。

 
(file-name-sans-versions "~rms/foo.~1~")
     => "~rms/foo"
(file-name-sans-versions "~rms/foo~")
     => "~rms/foo"
(file-name-sans-versions "~rms/foo")
     => "~rms/foo"
;; つぎの例はVMSでのみ正確である
(file-name-sans-versions "foo;23")
     => "foo"

Function: file-name-sans-extension filename
この関数は、filenameからあれば『拡張子』を除いたものを返す。 ファイル名の拡張子とは、 名前の最後の部分にある`.'で始まる部分である。 たとえばつぎのとおりである。

 
(file-name-sans-extension "foo.lose.c")
     => "foo.lose"
(file-name-sans-extension "big.hack/foo")
     => "big.hack/foo"


24.8.2 ディレクトリ名

ディレクトリ名(directory name)とはディレクトリの名前です。 ディレクトリはファイルの一種であり、ファイル名を持ちますが、 それはディレクトリ名に関連付けられますが同一ではありません。 (これはUNIXの通常の用語と同じではない。) 同じものに対するこれらの異なる2つの名前は、構文の変換で関連付けます。 UNIXではこれは簡単であり、ディレクトリ名はスラッシュで終りますが、 ファイルとしてのディレクトリの名前にはスラッシュはありません。 VMSでは、関係はより複雑です。

ディレクトリ名とそのファイルとしての名前との違いはわずかですが重大です。 Emacsの変数や関数引数がディレクトリ名と記述されているときには、 ディレクトリのファイルとしての名前は受け付けません。

つぎの2つの関数はディレクトリ名とファイルとしての名前を相互に変換します。 これらは、`$HOME'などの環境変数置換や `~'や`..'などの構造にはなにも特別なことはしません。

Function: file-name-as-directory filename
この関数は、オペレーティングシステムが ディレクトリ名と解釈する表現で表したfilenameの文字列を返す。 UNIXでは、文字列に(最後にスラッシュがなければ)スラッシュを 付加することを意味する。 VMSでは、`[X]Y.DIR.1'の形の文字列を`[X.Y]'の形に変換する。

 
(file-name-as-directory "~rms/lewis")
     => "~rms/lewis/"

Function: directory-file-name dirname
この関数は、オペレーティングシステムが ファイルの名前と解釈する表現で表したdirnameの文字列を返す。 UNIXでは、文字列の最後のスラッシュを取り除くことを意味する。 VMSでは、`[X.Y]'の形の文字列を`[X]Y.DIR.1'の形に変換する。

 
(directory-file-name "~lewis/")
     => "~lewis"

シンボリックリンクを介して通常参照されるディレクトリには ディレクトリ名の省略形が有用です。 ユーザーはリンクの名前をディレクトリの『名前』としばしばみなし、 ディレクトリの『本当の』名前を見るのをわずらわしく思うことがあります。 リンク名を『本当の』名前の省略形と定義しておくと、 Emacsはユーザーに省略形を表示します。

Variable: directory-abbrev-alist
変数directory-abbrev-alistは、 ディレクトリに使う省略形の連想リストを保持する。 各要素は(from . to)の形であり、 ディレクトリ名にfromが現れるとこれをtoに置き換えることを指示する。 文字列fromは実際には正規表現であり、つねに`^'で始まること。 関数abbreviate-file-nameがこれらの置換を行う。

ファイル`site-init.el'でこの変数に設定し、 読者のサイトに適した省略形を記述できる。

ファイルシステム`/home/fsf'などをシンボリック名`/fsf'で通常参照する システムの例をつぎに示す。

 
(("^/home/fsf" . "/fsf")
 ("^/home/gp" . "/gp")
 ("^/home/gd" . "/gd"))

ディレクトリ名をその省略形に変換するには、つぎの関数を使います。

Function: abbreviate-file-name dirname
この関数は、directory-abbrev-alistの省略形を引数に適用し、 ユーザーのホームディレクトリを`~'に置き換える。


24.8.3 ファイルの絶対名と相対名

ファイルシステム内のすべてのディレクトリは、 ルートディレクトリから始まる木を形作ります。 ファイル名では、木のルートから始まるすべてのディレクトリ名を指定できて、 これを絶対(absolute)ファイル名と呼びます。 あるいは、デフォルトディレクトリを基準に 木の中でのファイルの位置を指定することもでき、 これを相対(relative)ファイル名と呼びます。 UNIXでは、絶対ファイル名はスラッシュかティルダ(`~')で始まり、 相対ファイル名はそれらでは始まりません。 VMSでの規則は複雑です。

Function: file-name-absolute-p filename
この関数は、ファイルfilenameが絶対ファイル名であればtを返し、 さもなければnilを返す。 VMS上では、この関数はUNIXの構文とVMSの構文の両方を理解する。

 
(file-name-absolute-p "~rms/foo")
     => t
(file-name-absolute-p "rms/foo")
     => nil
(file-name-absolute-p "/user/rms/foo")
     => t


24.8.4 ファイル名を展開する関数

ファイル名の展開(expansion)とは、 相対ファイル名を絶対ファイル名に変換することです。 これはデフォルトディレクトリを基準に行うので、 展開すべきファイル名に加えて、デフォルトディレクトリの名前も 指定する必要があります。 また、展開では、`./'や`name/../'のような冗長部分を 取り除いてファイル名を単純にします。

Function: expand-file-name filename &optional directory
この関数はfilenameを絶対ファイル名に変換する。 directoryが与えられると、 filenameが相対ファイル名であれば、 デフォルトディレクトリを基準にする。 (directoryの値そのものは絶対ディレクトリ名であること。 `~'で始まってもよい。) さもなければ、バッファのdefault-directoryの値を使う。 たとえばつぎのとおり。

 
(expand-file-name "foo")
     => "/xcssun/users/rms/lewis/foo"
(expand-file-name "../foo")
     => "/xcssun/users/rms/foo"
(expand-file-name "foo" "/usr/spool/")
     => "/usr/spool/foo"
(expand-file-name "$HOME/foo")
     => "/xcssun/users/rms/lewis/$HOME/foo"

`.'や`..'を含むファイル名は、それらの正則な形に単純化する。

 
(expand-file-name "bar/../foo")
     => "/xcssun/users/rms/lewis/foo"

expand-file-nameは環境変数を展開しないことに注意。 substitute-in-file-nameだけがそれを行う。

Function: file-relative-name filename directory
この関数は展開の逆操作を行う。 つまり、directoryを基準に解釈すると filenameと等価になる相対名を返す。

絶対ファイル名が装置名で始まるシステムもある。 そのようなシステムでは、directoryfilenameが 2つの異なる装置名で始まると、 filenameに等価なdirectoryを基準にした相対名はない。 そのような場合、file-relative-nameは 絶対名の形でfilenameを返す。

 
(file-relative-name "/foo/bar" "/foo/")
     => "bar"
(file-relative-name "/foo/bar" "/hack/")
     => "/foo/bar"

Variable: default-directory
このバッファローカルな変数の値は、 カレントバッファのデフォルトディレクトリである。 これは絶対ディレクトリ名であること。 `~'で始まってもよい。 この変数は各バッファにおいてバッファローカルである。

expand-file-nameは、その第2引数がnilであると デフォルトディレクトリを使う。

UNIXでは、この値はつねにスラッシュで終る文字列である。

 
default-directory
     => "/user/lewis/manual/"

Function: substitute-in-file-name filename
この関数は、filename内の環境変数の参照を 環境変数の値で置き換える。 UNIXのシェルの構文規則に従って、 `$'は環境変数の値に置換するための接頭辞である。

環境変数名は、`$'に続く(下線を含む)英数字の列である。 `$'のつぎの文字が`{'であると、 対応する`}'までが変数名である。

ここでは、環境変数HOMEはユーザーのホームディレクトリ名 `/xcssun/users/rms'を保持していると仮定する。

 
(substitute-in-file-name "$HOME/foo")
     => "/xcssun/users/rms/foo"

置換後、`/'のつぎに`~'か`/'が現れると、 `/'までの部分をすべて取り除く。

 
(substitute-in-file-name "bar/~/foo")
     => "~/foo"
(substitute-in-file-name "/usr/local/$HOME/foo")
     => "/xcssun/users/rms/foo"
     ;; `/usr/local/' has been discarded.

VMSでは、`$'による置換は行わないため、 この関数は冗長部分を取り除く以外にはなにも行わない。


24.8.5 一意なファイル名の生成

一時的なファイルに書く必要があるプログラムもあります。 そのようなファイル向けの名前を作る通常の方法はつぎのとおりです。

 
(make-temp-name
 (expand-file-name name-of-application
                   temporary-file-directory))

make-temp-nameの仕事は、 異なる2人のユーザーや異なる2つのジョブがまったく同じファイル名を 使わないようにすることです。 この例では、変数temporary-file-directoryを使って 一時的なファイルを置く場所を決めています。 すべてのEmacs Lispプログラムでは、 すべての一時的なファイル向けのディレクトリを指定する 一意な方法をユーザーに提供するために、 この目的にはtemporary-file-directoryを使うべきです。

Function: make-temp-name string
この関数は、一意なファイル名として使える文字列を生成する。 名前はstringで始まり、各Emacsジョブごとに異なる数を含む。

 
(make-temp-name "/tmp/foo")
     => "/tmp/foo232J6v"

同じEmacsで動作している異なるライブラリのあいだで衝突しないように、 make-temp-nameを使う各Lispプログラムでは、 独自のstringを使うべきである。 stringの末尾に付加される数は、 異なるEmacsジョブで動いている同じアプリケーションを区別する。 文字を余計に追加することで、1つのEmacsジョブであっても 異なる名前の個数を非常に多くできる。

Variable: temporary-file-directory
この変数は、一時的なファイルを作成するためのディレクトリ名を指定する。 その値はディレクトリ名(see section 24.8.2 ディレクトリ名)であるべきだが、 Lispプログラムにとっては、 その値がディレクトリのファイルとしての名前であっても処理できるほうがよい。 この値をexpand-file-nameの第2引数に使うと、 そのようにできる。

デフォルト値は、読者のオペレーティングシステムにおいて 合理的な方法で決定される。 GNUとUNIXシステムでは、環境変数TMPTMPDIRを基にする。

読者が一時的なファイル名を選ぶためにmake-temp-nameを 使わない場合であっても、 一時的なファイル名を置くディレクトリを決めるために この変数を使うべきである。


24.8.6 ファイル名の補完

本節では、ファイル名の補完向けの低レベルのサブルーティンについて述べます。 他の補完関数については、19.5 補完を参照してください。

Function: file-name-all-completions partial-filename directory
この関数は、ディレクトリdirectoryにおいて partial-filenameで始まる名前のファイルに対する すべての補完候補から成るリストを返す。 候補の順番はディレクトリ内でのファイルの順番であり、 それは予測できず有用な情報はなにもない。

引数partial-filenameは、ディレクトリ部分やスラッシュを いっさい含まないファイル名であること。 directoryが絶対名でないと、 カレントバッファのデフォルトディレクトリをdirectoryのまえに補う。

つぎの例で、カレントデフォルトディレクトリは`~rms/lewis'であり、 `f'で始まる名前のファイルは、 `foo'、`file~'、`file.c'、`file.c.~1~'、 `file.c.~2~'の5つであると仮定する。

 
(file-name-all-completions "f" "")
     => ("foo" "file~" "file.c.~2~" 
                "file.c.~1~" "file.c")

(file-name-all-completions "fo" "")  
     => ("foo")

Function: file-name-completion filename directory
この関数は、ディレクトリdirectoryにおいてファイル名filenameを 補完する。 ディレクトリdirectoryにおいてfilenameで始まる すべてのファイル名に共通な最長の文字列を返す。

filenameで始まるものがたった1つであり完全に一致すると、 この関数はtを返す。 ディレクトリdirectoryfilenameで始まる名前がないと nilを返す。

つぎの例で、カレントデフォルトディレクトリには `f'で始まる名前のファイルは、 `foo'、`file~'、`file.c'、`file.c.~1~'、 `file.c.~2~'の5つであると仮定する。

 
(file-name-completion "fi" "")
     => "file"

(file-name-completion "file.c.~1" "")
     => "file.c.~1~"

(file-name-completion "file.c.~1~" "")
     => t

(file-name-completion "file.c.~3" "")
     => nil

User Option: completion-ignored-extensions
file-name-completionは、このリスト内のいずれかの文字列で終る 名前のファイルを通常無視する。 補完候補すべてがこれらの接頭辞の1つで終る場合や、 補完候補すべてを含んだバッファが表示されている場合には無視しない。

典型的な値はつぎのとおりである。

 
completion-ignored-extensions
     => (".o" ".elc" "~" ".dvi")


24.8.7 標準ファイル名

Lispプログラムで使われるほとんどのファイル名は、 ユーザーが入力したものです。 しかし、Lispプログラムでは、 特定目的の標準ファイル名を指定する必要がある場合があります。 典型的には、各ユーザーごとのカスタマイズ情報を保持するものです。 たとえば、省略形の定義は(デフォルトでは) ファイル`~/.abbrev_defs'に保存されます。 パッケージcompletionは、 補完情報をファイル`~/.completions'に保存します。 これらは、Emacsで特定目的に使われる多くの標準ファイル名のうちの2つです。

さまざまなのオペレーティングシステムには、 正しいファイル名やユーザーのプロフィールデータに使うファイル名に 独自の慣習があります。 標準ファイル名を使用するファイルを読み込むLispプログラムでは、 各システムごとに当該システムに適したファイル名を使うべきです。 関数convert-standard-filenameは、これを簡単にします。

Function: convert-standard-filename filename
この関数は、ファイル名filenameを使用しているオペレーティングシステム の慣習に従うように変換し、新たな文字列として結果を返す。

Lispプログラムにおいて標準ファイル名を指定する推奨方法は、 GNUとUNIXシステムの慣習に従った名前を選ぶことです。 つまり、ピリオドで始まる非ディレクトリ部分を選び、 それを直接使うかわりにconvert-standard-filenameに渡します。 パッケージcompletionからの例をつぎに示します。

 
(defvar save-completions-file-name
        (convert-standard-filename "~/.completions")
  "*The file name to save completions to.")

GNUとUNIXシステム、および、他のいくつかのシステムでは、 convert-standard-filenameは引数を未変更で返します。 別のシステムでは、システムの慣習に従うように名前を変更します。

たとえば、MS-DOSではこの関数は、先頭の`.'を`_'に、 `.'がどこにもなければ名前の途中の`_'を`.'に、 8文字目のうしろに`.'がなければ`.'を挿入し、 `.'以降の3文字よりうしろを切り詰めるなどを行います。 (これ以外にも変更する。) したがって、`.abbrev_defs'は`_abbrev.def'となり、 `.completions'は`_complet.ion'となります。


24.9 ディレクトリの内容

ディレクトリは、さまざまな名前で入れた別のファイルを 収めているファイルの一種です。 ディレクトリは、ファイルシステムの機能です。

Emacsは、ディレクトリ内のファイル名をLispのリストとして一覧にしたり、 シェルコマンドlsを使ってバッファに名前を表示できます。 後者の場合、コマンドlsに渡したオプションに応じて、 各ファイルに関する情報も表示できます。

Function: directory-files directory &optional full-name match-regexp nosort
この関数は、ディレクトリdirectory内の ファイルの名前から成るリストを返す。 デフォルトでは、リストはアルファベット順になる。

full-namenil以外であると、 関数はファイルの絶対ファイル名を返す。 さもなければ、指定したディレクトリに対する相対名を返す。

match-regexpnil以外であると、 この関数は正規表現match-regexpに一致するファイル名のみを返す。 つまり、他の名前のファイルはリストから除かれる。

nosortnil以外であると、 directory-filesはリストをソートしないので、 ファイル名の順番に規則はない。 処理速度を最大にしてファイルの処理順序に拘らないならば、これを用いる。 処理順序がユーザーに見える場合には、 ソートしたほうがユーザーは幸せであろう。

 
(directory-files "~lewis")
     => ("#foo#" "#foo.el#" "." ".."
         "dired-mods.el" "files.texi" 
         "files.texi.~1~")

directoryが読めないディレクトリの名前であるとエラーを通知する。

Function: file-name-all-versions file dirname
この関数は、ディレクトリdirname内のfileという名前の ファイルのすべての版から成るリストを返す。

Function: insert-directory file switches &optional wildcard full-directory-p
この関数は、lsswitchesを渡して表示した ディレクトリfileの一覧を(カレントバッファに)挿入する。 ポイントは挿入したテキストのうしろに置かれる。

引数fileは、ディレクトリ名であるか ワイルドカードを含んだファイル指定である。 wildcardnil以外であると、 fileをワイルドカードを含むファイル指定として扱う。

full-directory-pnil以外であると、 ディレクトリ一覧はディレクトリの全内容を表すと仮定することを意味する。 fileがディレクトリでありswitchesに`-d'を含まない場合には、 tを指定すべきである。 (lsのオプション`-d'は、 ディレクトリの内容ではなく、ファイルとしてのディレクトリ自身を 表示することを意味する。)

この関数は、変数insert-directory-programで指定される 名前のディレクトリ表示プログラムを実行して動作する。 wildcardnil以外であると、 ワイルドカードを展開するためにshell-file-nameで指定される シェルを実行する。

Variable: insert-directory-program
この変数の値は、関数insert-directoryで ディレクトリ一覧を生成するために実行するプログラムである。


24.10 ディレクトリの作成と削除

Emacs Lispのほとんどのファイル操作関数は、 ディレクトリであるファイルに使うとエラーになります。 たとえば、delete-fileではディレクトリを削除できません。 これらの特別な関数はディレクトリを作成したり削除するためのものです。

Function: make-directory dirname
この関数はdirnameという名前のディレクトリを作る。

Function: delete-directory dirname
この関数は、ディレクトリdirnameを削除する。 関数delete-fileは、ディレクトリであるファイルには使えない。 ディレクトリにはdelete-directoryを使う必要がある。 ディレクトリ内にファイルがあると、delete-directoryは エラーを通知する。


24.11 ファイル名を『マジック』にする

特定のファイル名を特別に扱うことができます。 これをそれらの名前をマジック(magic)にするといいます。 この機能の主な用途はリモートファイル名 (see section `リモートファイル' in GNU Emacs マニュアル) を実装することです。

マジックファイル名の種類を定義するには、 名前のクラス(正規表現に一致するものすべて)を定義する正規表現と、 それに一致するファイルに対する Emacsの基本ファイル操作を実装するハンドラを指定する必要があります。

変数file-name-handler-alistは、 ハンドラと当該ハンドラの適用を決定する正規表現からなるリストを保持します。 各要素の形はつぎのとおりです。

 
(regexp . handler)

Emacsのすべてのファイル操作基本関数とファイル名変換基本関数は、 指定された名前をfile-name-handler-alistに対して検査します。 ファイル名がregexpに一致すると、 基本関数はhandlerを呼び出して当該ファイルを処理します。

handlerに与える最初の引数は基本関数の名前です。 残りの引数は当該操作に渡されるべき引数です。 (それらの引数の最初のものは典型的にはファイル名自身である。) たとえば、つぎのようにした場合、

 
(file-exists-p filename)

filenameにハンドラhandlerがあると、 handlerはつぎのように呼び出されます。

 
(funcall handler 'file-exists-p filename)

つぎは、マジックファイル名のハンドラが処理すべき操作です。

add-name-to-filecopy-filedelete-directorydelete-filediff-latest-backup-filedirectory-file-namedirectory-filesdired-call-processdired-compress-filedired-uncacheexpand-file-namefile-accessible-directory-p
file-attributesfile-directory-pfile-executable-pfile-exists-p
file-local-copyfile-modesfile-name-all-completions
file-name-as-directoryfile-name-completionfile-name-directoryfile-name-nondirectoryfile-name-sans-versionsfile-newer-than-file-pfile-ownership-preserved-pfile-readable-pfile-regular-pfile-symlink-pfile-truenamefile-writable-pfind-backup-file-nameget-file-buffer
insert-directoryinsert-file-contentsload, make-directorymake-symbolic-linkrename-fileset-file-modesset-visited-file-modtimeshell-command
unhandled-file-name-directoryvc-registeredverify-visited-file-modtime
write-region

insert-file-contentsに対するハンドラは、 引数visitnil以外であるときには (set-buffer-modified-p nil)を使って バッファの変更フラグをクリアする必要が典型的にはあります。

ハンドラ関数は、上のすべての操作、ならびに、 将来追加されるものを扱える必要があります。 これらの操作すべてをハンドラ自身で実装する必要はありません。 特定の操作について特別なことを行う必要がなければ、 『通常どおりに』操作を処理するために基本関数を再起動できます。 ハンドラが認識できない操作については、 基本関数を再起動するべきです。 1つの方法はつぎのとおりです。

 
(defun my-file-handler (operation &rest args)
  ;; まず、特別に扱う必要がある操作かどうか検査する
  (cond ((eq operation 'insert-file-contents) ...)
        ((eq operation 'write-region) ...)
        ...
        ;; 知らない操作を扱う
        (t (let ((inhibit-file-name-handlers
                  (cons 'my-file-handler 
                        (and (eq inhibit-file-name-operation operation)
                             inhibit-file-name-handlers)))
                 (inhibit-file-name-operation operation))
             (apply operation args)))))

ハンドラ関数で、指定された操作についてはEmacsの通常の基本関数を呼び出すと 決定したときには、基本関数から同じハンドラが再度呼ばれて 無限再帰になることを防ぐ必要があります。 上の例は、変数inhibit-file-name-handlersinhibit-file-name-operationを使ってこれを行う方法を示すものです。 それらを上に示したとおりに使うように注意してください。 複数のハンドラがあったり、 2つのファイルを扱う操作において各ファイルにハンドラがある場合には、 この詳細は重要です。

Variable: inhibit-file-name-handlers
この変数は、特定操作については 現在適用を禁止されているハンドラのリストを保持する。

Variable: inhibit-file-name-operation
特定のハンドラにおいて現在禁止されている操作。

Function: find-file-name-handler file operation
この関数はファイル名fileに対するハンドラ関数を返す。 ハンドラがなければnilを返す。 引数operationは、ファイルに対して適用する操作であること。 つまり、ハンドラを呼び出すときに第1引数として渡される値。 当該操作はinhibit-file-name-operationと比較する必要がある。

Function: file-local-copy filename
この関数は、ファイルfilenameがマジックでない普通のファイルでなければ、 filenameをマジックでない普通のファイルにコピーする。

filenameが、 Emacsの外側のプログラムからは直接読んだり書けないマジックファイル名であると、 この関数は普通のファイルにコピーしてそのファイルの名前を返す。

filenameが普通のファイル名でマジックでなければ、 この関数はなにもせずにnilを返す。

Function: unhandled-file-name-directory filename
この関数は、マジックではないディレクトリの名前を返す。 filenameがマジックでなければ、 filenameのディレクトリ部分を使う。 マジックファイル名であると、ファイル名ハンドラを起動し、 当該ハンドラがどんな値を返すか決定する。

これは実行中のサブプロセスに有用である。 各サブプロセスには、カレントディレクトリとしてマジックでないディレクトリが 必要であり、この関数はそれを扱うのによい方法である。


24.12 ファイル書式変換

変数format-alistは、 Emacsバッファ内のデータ(テキスト、テキスト属性、その他の情報)を ファイル内でテキスト表現する方法を記述した ファイル書式(file format)のリストを定義します。 Emacsはファイルを読み書きするときに必要ならば書式変換を行います。

Variable: format-alist
このリストは、各ファイル書式の定義を含んだリストである。

各書式定義はつぎの形のリストです。

 
(name doc-string regexp from-fn to-fn modify mode-fn)

書式定義の各要素の意味はつぎのとおりです。

name
当該書式の名前。

doc-string
当該書式の説明文字列。

regexp
当該書式で表現されたファイルを認識するために使用する正規表現。

from-fn
当該書式のデータを復号化(ファイル内のデータをEmacsの通常のデータ表現へ 変換)するためのシェルコマンドか関数。

シェルコマンドは文字列で表現し、 Emacsは変換を行うために当該コマンドをフィルタとして実行する。

from-fnが関数であると、 バッファの変換すべき部分を指定するbeginendの2つの引数で 呼ばれる。 当該関数はその場で編集してテキストを変換すること。 これによりテキストの長さが変わる可能性があるので、 from-fnは変更部分の末尾位置を返すこと。

from-fnの責任の1つは、 ファイルの先頭がregexpで始まらないように保証することである。 さもないと、再度呼び出される可能性がある。

to-fn
当該書式にデータを符号化するためのシェルコマンドか関数。 つまり、Emacsの通常のデータ表現を当該書式に変換する。

to-fnが文字列であるとそれはシェルコマンドであり、 Emacsは変換を行うために当該コマンドをフィルタとして実行する。

to-fnが関数であると、 バッファの変換すべき部分を指定するbeginendの2つの引数で 呼ばれる。 変換を行うには2つの方法がある。

modify
フラグであり、 符号化関数がバッファを変更する場合にはt、 注記のリストを返す場合にはnilである。

mode
当該書式から変換されたファイルを訪問後に呼び出されるモード関数。

関数insert-file-contentsは、指定されたファイルを読み込むときに ファイル書式を自動的に認識します。 ファイルの先頭のテキストを書式定義の正規表現に対して検査して、 一致がみつかれば当該書式の復号化関数を呼び出します。 そして、既知の書式について再度調べ直します。 適用できる書式がなくなるまで検査し続けます。

関数find-file-noselectやこれを使うコマンドでファイルを訪問すると、 (insert-file-contentsを呼び出すので)同様に変換を行います。 さらに、この関数は、復号した各書式についてモード関数を呼び出します。 バッファローカルな変数buffer-file-formatに 書式名のリストを保存します。

Variable: buffer-file-format
この変数は、訪問したファイルの書式を記述している。 より正確には、カレントバッファのファイルを訪問する過程で 復号したファイル書式名のリストである。 この変数は、すべてのバッファにおいてつねにバッファローカルである。

write-regionがデータをファイルに書き出すときには、まず、 buffer-file-formatで指定された書式の符号化関数を リストに現れる順に呼び出します。

コマンド: format-write-file file format
このコマンドは、カレントバッファの内容を書式formatにて ファイルfileに書き出す。 さらに、当該書式をバッファを将来保存するときのデフォルトとする。 引数formatは、書式名のリストである。

コマンド: format-find-file file format
このコマンドは、ファイルfileを探し、 それを書式formatに従って変換する。 さらに、当該書式をバッファをのちに保存するときのデフォルトとする。

引数formatは、書式名のリストである。 formatnilであると、変換を行わない。 対話的に呼び出した場合、 formatnilを指定するにはRETのみを打つ。

コマンド: format-insert-file file format &optional beg end
このコマンドは、ファイルfileの内容を書式formatに従って 変換して挿入する。 begendnil以外であると、 それらは、insert-file-contents(see section 24.3 ファイルの読み込み)と同様に、 読み込むべきファイルの部分を指定する。

戻り値は、insert-file-contentsが返す値に似ており、 絶対ファイル名と挿入データの(変換後の)長さのリストである。

引数formatは、書式名のリストである。 formatnilであると、変換を行わない。 対話的に呼び出した場合、 formatnilを指定するにはRETのみを打つ。

Variable: auto-save-file-format
この変数は、自動保存に対して使用する書式を指定する。 その値は、buffer-file-formatの値のように、書式名のリストであるが、 buffer-file-formatのかわりに 自動保存ファイルを書くために使われる。 この変数は、すべてのバッファにおいてつねにバッファローカルである。


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Akihiro Sagawa on January, 21 2003 using texi2html