openwith-mode の動作方法は少し独特です。実際には、それをグローバルに使用するか、まったく使用しないことを前提としています。ただし、ここで必要なのは、ローカルで、つまり dired バッファー内からのみ使用することです。
これは簡単には達成できませんが、ここに方法があります。
openwith-mode のソース ファイル openwith.el を開きます。次に、実際のマイナー モードの定義に到達するまで下にスクロールします。次に、各行の先頭にセミコロンを配置して、その定義をコメントアウトします。
;;;###autoload
; (define-minor-mode openwith-mode
; "Automatically open files with external programs."
; :lighter ""
; :global t
; (if openwith-mode
; (progn
; ;; register `openwith-file-handler' for all files
; (put 'openwith-file-handler 'safe-magic t)
; (put 'openwith-file-handler 'operations '(insert-file-contents))
; (add-to-list 'file-name-handler-alist '("" . openwith-file-handler)))
; (setq file-name-handler-alist
; (delete '("" . openwith-file-handler) file-name-handler-alist))))
次に、このコードの下 (ただし の前(provide 'openwith)
) に、次のコードを挿入します。
(defvar openwith-mode nil)
(mapc (lambda (function)
(ad-add-advice function
'(dired-openwith nil t (advice . (lambda () (let ((openwith-mode t)) ad-do-it))))
'around 0))
'(dired-find-alternate-file
dired-find-file
dired-find-file-other-window
dired-mouse-find-file-other-window
dired-view-file))
(put 'openwith-file-handler 'safe-magic t)
(put 'openwith-file-handler 'operations '(insert-file-contents))
(add-to-list 'file-name-handler-alist '("" . openwith-file-handler))
このコードはいくつかのことを行います。
まず、openwith-mode という変数を定義します。この変数は、外部アプリケーションを使用するかどうかを決定する openwith-mode の関数の 1 つの内部で使用されます。通常、そのような変数は、マイナー モードを定義するときに Emacs によって自動的に提供されますが、上記の実際のマイナー モードの定義をコメントアウトしたばかりなので、ここでこの変数を明示的に再導入します。
変数の目的は、画像ファイルをインライン化するか、外部ビューアに渡すかを制御できる一種のスイッチとして機能することです。
次に(mapc ...)
表現です。ここで行っているのは、5 つの関数のリストを反復処理することです。
- dired-find-alternate-file
- dired 検索ファイル
- dired-find-file-other-window
- dired-mouse-find-file-other-window
- dired ビュー ファイル
これらは dired がファイルを開くために提供する関数です。これらの関数のそれぞれに、 Advisingと呼ばれる手法で少量のコードを追加します。これにより、これら 5 つの関数のいずれかが呼び出されるたび(ad-add-advice...)
に変数が設定されます。関数呼び出しの外では、変数は に設定されたままです。openwith-mode
t
nil
これには、dired の関数の 1 つを使用してファイルを開くたびに、外部アプリケーションの呼び出しを担当する openwith-mode の関数が、変数が設定されてt
いることを認識し、外部アプリケーションがわかっている場合はすぐにそれを開こうとするという効果があります。このようなフープを飛び越えなければならない理由は、openwith-mode を使用して画像ファイルを開くたびに、同じ openwith-mode 関数も呼び出されるC-x C-fためです。これが openwith-mode の実装方法です。
(注意: 残念ながら、現在のメジャーモードをスイッチとして使用することはできません。これは、ファイルを開くために既に作成されている新しいバッファーのメジャーモードになるためです。常にfundamental-mode
です。)
最後に、最後の 3 行は、前にコメントアウトしたマイナーモードの定義からコピー & ペーストしただけです。彼らは、私がすでに何度も言及してきた、外部アプリケーションの呼び出しを担当する関数 (呼び出されopen-with-filehandler
た) は、いわゆるファイルハンドラーであると言います。ファイルへの実際のアクセスに対して特別なことを実際に行うわけではないsafe-magic
ため、その関数を に設定していますt
。また、操作insert-file-contents
が重要な方法で関数によって処理されることを宣言します。(これらのプロパティの詳細については、こちらを参照してください。)
そして最後に、実際にファイル ハンドラーをインストールします。
重要: openwith-mode のドキュメントでは、次の 2 行を .emacs ファイルに追加することを推奨しています。
(require 'openwith)
(openwith-mode t)
マイナー モードがなくなったのでopenwith-mode
(その定義をコメント アウトした後)、2 行目もコメント アウトするなどして、必ず削除してください。
;; (openwith-mode t)
Emacs を再起動した後、dired で画像ファイルを開くと、外部アプリケーションで開く必要があります。経由で開くとC-x C-f、バッファにインライン化されます。