6

dired モードから画像ファイルを開くときに、外部アプリケーションを使用するように emacs を構成したいと考えています。

一方で、emacs バッファーでインライン イメージも使用したいと考えています。

外部アプリケーションでファイルを開くには、openwith.el パッケージhttp://www.emacswiki.org/emacs/OpenWithを使用します

openwith マイナー モードの問題は、それがグローバルであり、dired-mode-hook によって有効にされている場合です。

(add-hook 'dired-mode-hook
          (lambda ()
            (setq truncate-lines t)
            (openwith-mode t)
            ))

どこでも機能し、emacs バッファー内のすべてのインライン画像が外部アプリケーションで開かれます。

変えてみた

:global t 

:global nil 

openwith.elで、しかしそれはどういうわけか openwith モードを完全に無効にします。

だから、私の質問は次のとおりです。どのようにemacsにopenwithマイナーモードをdiredバッファでのみ使用し、他の場所では使用しないように指示するのですか?

ありがとう。

4

3 に答える 3

4

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-modetnil

これには、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、バッファにインライン化されます。

于 2012-06-27T09:56:03.187 に答える
3

使いませんopenwith。で定義された関数を使用します

http://ergoemacs.org/emacs/emacs_dired_open_file_in_ext_apps.html

于 2012-06-27T12:49:59.440 に答える
0

1 つの方法は、openwith.el で好きなファイル タイプの優先プログラムとして emacsclient を設定しopenwith-associations、emacsclient の使用を開始することです。

毎回新しい emacs セッションを開始することもできますが、それは以前の提案よりも醜く聞こえます。

于 2012-06-27T02:17:20.060 に答える