次: , 前: Create/Delete Dirs, 上: Files


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

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

マジックファイル名の種類を定義するには、 名前のクラス(正規表現に一致するものすべて)を定義する正規表現と、 それに一致するファイルに対する 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)

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

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つのファイルを扱う操作において各ファイルにハンドラがある場合には、 この詳細は重要です。

— 変数: inhibit-file-name-handlers

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

— 変数: inhibit-file-name-operation

特定のハンドラにおいて現在禁止されている操作。

— 機能: find-file-name-handler file operation

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

— 機能: file-local-copy filename

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

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

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

— 機能: unhandled-file-name-directory filename

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

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