【问题标题】:emacs dired and openwithemacs dired 和 openwith
【发布时间】:2012-06-27 01:47:11
【问题描述】:

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

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

要在外部应用程序中打开文件,我使用openwith.elhttp://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 minor 模式 使用干缓冲区而不是其他任何地方?

谢谢。

【问题讨论】:

    标签: emacs elisp dired


    【解决方案1】:

    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 函数之一。通常,当您定义次要模式时,Emacs 会自动提供类似的变量——但是由于我们刚刚注释掉了上面实际次要模式的定义,所以我们在这里明确地重新引入了这个变量。

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

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

    • dired-find-alternate-file
    • 目录查找文件
    • dired-find-file-other-window
    • dired-mouse-find-file-other-window
    • 目录视图文件

    dired 提供的用于打开文件的函数。对于这些函数中的每一个,我们在称为advising 的技术中添加了少量代码:(ad-add-advice...) 所做的是在调用这五个函数之一时将变量openwith-mode 设置为t。在函数调用之外,变量仍然设置为nil

    这样的效果是,每当您使用 dired 的函数之一打开文件时,负责调用外部应用程序的 openwith-mode 函数看到变量设置为 t 并立即尝试打开外部应用程序,如果它知道一个。 我们必须跳过这些环节的原因是,每当您使用 C-x C-f 打开图像文件时,也会调用相同的 openwith-mode 函数——这正是 openwith-mode 的实现方式。

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

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

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


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

    (require 'openwith)
    (openwith-mode t)
    

    现在没有次要模式openwith-mode(在我们注释掉它的定义之后),请确保删除第二行,例如也将其注释掉:

    ;; (openwith-mode t)
    

    重新启动 Emacs 后,如果你用 dired 打开一个图像文件,它应该在外部应用程序中打开;如果您通过 C-x C-f 打开它,它将被内联在缓冲区中。

    【讨论】:

    • 赞成,但您还没有解释为什么需要注释掉模式定义(或直接修改库——eval-after-load 将是添加额外代码的更正常方法) .
    • @phils 好点 - 我只对此做了一个小评论,但不是很清楚:openwith-mode 的设计方式,它意味着在 全局上:它添加了一个全局文件处理程序,当模式打开时,该文件处理程序检查外部应用程序,如果它关闭,它什么也不做。
    • 但是你会不会通过使用eval-after-load 包装(fmakunbound 'openwith-mode) 和你的其余代码来获得相同的结果,而不是真正接触原始库?
    • @phils 哦,我明白你的意思了。是的,你是对的,这应该有效。 (不过,我可以看到这两种方法的优缺点。)
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      您可以每次都启动新的 emacs 会话,但这听起来比以前的建议更难看。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        • 2011-05-11
        • 2011-01-22
        • 2013-03-29
        • 1970-01-01
        相关资源
        最近更新 更多