繁体   English   中英

emacs dired和openwith

[英]emacs dired and openwith

我想在从dired模式打开图像文件时配置emacs以使用外部应用程序。

另一方面,我也想在emacs缓冲区中使用内联图像。

要在外部应用程序中打开文件,我使用openwith.elhttp://www.emacswiki.org/emacs/OpenWith

openwith minor模式的问题在于它是全局的,并且当它由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只使用带有dired缓冲区的openwith minor模式而不是其他地方?

谢谢。

openwith-mode的工作方式有点奇怪:它确实假设您全局使用或根本不使用它。 但是,你想要的是在本地使用它,即只能在一个直接缓冲区中使用它。

这不可能很容易实现,但这是一种方式。

打开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的一个函数中使用,该函数决定是否使用外部应用程序。 通常,当您定义次要模式时,Emacs会自动提供这样的变量 - 但是由于我们刚刚注释掉了上面实际次要模式的定义,我们在这里明确地重新引入了这个变量。

变量的目的是作为一种开关工作,通过它我们可以控制图像文件是否应该内联或传递给外部查看器。

接下来我们有(mapc ...)表达式。 我们在这里做的是迭代五个函数的列表:

  • dired - 查找 - 备用文件
  • dired找到的文件
  • dired找到的文件,其他窗口
  • dired鼠标找到的文件,其他窗口
  • dired - 视图 - 文件

函数dired用于打开文件。 为了这些功能,我们添加的少量代码在一个名为技术建议 :什么(ad-add-advice...)所做的就是设置变量openwith-modet ,只要这五个函数之一被调用。 在函数调用之外,变量保持设置为nil

这样做的结果是,无论何时使用dired函数之一打开文件,负责调用外部应用程序的openwith-mode函数都会将变量设置为t ,如果知道一个,则立即尝试打开外部应用程序。 我们必须跳过这样的环节的原因是,无论何时使用Cx Cf打开图像文件,都会调用相同的openwith-mode函数 - 这就是openwith-mode的实现方式。

(注意:遗憾的是,我们不能只使用当前的主模式作为开关,因为这将是已经为文件打开创建的新缓冲区的主要模式。它始终是fundamental-mode 。)

最后,最后三行只是我们之前评论过的次模式定义的复制和粘贴。 他们说我已经提到了很多函数,并且负责调用外部应用程序 - 称为open-with-filehandler - 是一个所谓的文件处理程序。 它实际上并没有对文件的实际访问做任何特殊操作,因此我们将该函数的safe-magic设置为t 此外,我们声明操作insert-file-contents由我们的函数以非平凡的方式处理。 (有关这些属性的更多信息,请参见此处 。)

最后,我们实际安装了文件处理程序。


重要提示 :openwith-mode文档建议您将以下两行放入.emacs文件中:

(require 'openwith)
(openwith-mode t)

现在不再有小模式openwith-mode (在我们对其定义进行评论之后),请确保删除第二行,例如通过注释掉:

;; (openwith-mode t)

重新启动Emacs后,如果用dired打开图像文件,它应该在外部应用程序中打开; 如果你通过Cx Cf打开它,它将在缓冲区中内联。

我不使用openwith 我使用定义的函数

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

一种方法是将emacsclient设置为openwith-associationsopenwith-associations中喜欢的文件类型的首选程序,并开始使用emacsclient。

你可以每次都开始新的emacs会话,但这听起来比之前的建议更加丑陋。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM