【问题标题】:Opening files with default Windows application from within emacs在 emacs 中使用默认 Windows 应用程序打开文件
【发布时间】:2010-02-17 20:54:42
【问题描述】:

我正在尝试在 Windows XP 上的 emacs 中调整 dired-find-file 函数,以便当我从 dired 打开(例如)一个 pdf 文件时,它会启动 Acrobat Reader 的副本并用它打开该文件,而不是打开它在emacs中。但我不知道要使用shell-command/call-process 上的哪个变体。到目前为止,这是我所拥有的:

(defadvice dired-find-file (around dired-find-file-external (filename &optional wildcards))
  "Open non-text files with an appropriate external program."
  (if (string= ".pdf" (substring filename (- (length filename) 4))) ; obviously I'll replace this with something more general/robust
    (shell-command filename) ;; what should go here?
    (ad-do-it)))

(ad-activate 'dired-find-file)

我知道我可以通过为其提供 .exe 文件的位置来对其进行硬编码以启动 Acrobat Reader。但我宁愿有一些需要我进行较少搜索并且在默认应用程序移动/更改时不会中断的东西。我应该使用什么?

【问题讨论】:

    标签: windows emacs elisp


    【解决方案1】:

    扩展“org-open-file”提案:

    (defun my-dired-find-file (&optional prefix)
        (interactive "P")
        (if prefix
            (org-open-file (dired-get-file-for-visit) 'system)
          (dired-find-file)))
    
    (define-key dired-mode-map "\r" 'my-dired-find-file)
    

    会让你在外部使用 `C-u RET' 打开一个文件。

    发现于http://lists.gnu.org/archive/html/bug-gnu-emacs/2012-11/msg01069.html

    【讨论】:

      【解决方案2】:
      1. 评估以下省略号
      2. 运行 dired (M-x dired)
      3. 浏览到目录和文件
      4. 点在文件上,按 F3 将打开基于 windows 扩展名的文件。

        (defun w32-browser (doc) (w32-shell-execute 1 doc))

        (eval-after-load "dired" '(define-key dired-mode-map [f3] (lambda () (interactive) (w32-browser (dired-replace-in-string "/" "\\" (dired-get-filename))))))

      【讨论】:

      • 不热衷于 eval-after-load,但为 w32-shell-execute +1 - 这显然是正确的方法。
      • 为什么当我按 ``F3` 时它会显示 Defining kbd macro...
      【解决方案3】:

      使用Dired+w32-browser.el

      • C-RET 使用其 Windows 文件关联应用程序打开当前行的文件。

      • M-RET 将 Windows 资源管理器打开到文件或文件夹

      • ^,当位于根目录(例如C:\)时,向上移动到所有 Windows 驱动器(本地和远程)的 Dired 类列表。

      前两个命令可从w32-browser.el 获得。 (Dired+ 将它们绑定到这些键。)第三个命令来自 Dired+。

      【讨论】:

      • 但小缓冲区显示the M-Ret is not defined
      • @ZhaoGang:谢谢。已更正。忘了前两个命令是在 w32-browser.el 中定义的。
      【解决方案4】:

      我通过谷歌找到了this terrific web page,这让我了解了一种使用 RunDll 的技术。我把它放在这里以防其他人好奇。

      这是一段关键代码,它使用适当的应用程序打开filename

      (shell-command (concat "rundll32 shell32,ShellExec_RunDLL " (shell-quote-argument filename)))
      

      这是我的完整解决方案。 (请注意,dired-find-file 只是 find-file 的包装器,它不知道文件名,因此您必须建议find-file 而不是问题中的dired-find-file。如果您不希望这种行为find-file 你可能需要重写 dired-find-file 或者写更复杂的建议。)

      (defun open-externally (filename)
        (shell-command (concat "rundll32 shell32,ShellExec_RunDLL " (shell-quote-argument filename))))
      
      (defun is-file-type? (filename type)
        (string= type (substring filename (- (length filename) (length type)))))
      
      (defun should-open-externally? (filename)
        (let ((file-types '(".pdf" ".doc" ".xls")))
          (member t (mapcar #'(lambda (type) (is-file-type? filename type)) file-types))))
      
      (defadvice find-file (around find-file-external-file-advice (filename &optional wildcards))
        "Open non-emacs files with an appropriate external program"
        (if (should-open-externally? filename)
            (open-externally filename)
          ad-do-it))
      
      (ad-activate 'find-file)
      

      【讨论】:

        【解决方案5】:

        Tom Smith 的回答很好,但您也可以只运行程序“start”,并将文件名作为参数。

        (shell-command (concat "start " (shell-quote-argument filename)))
        

        【讨论】:

        • 你确定吗?当我尝试这个时它不起作用 - 我只是得到一个空的命令提示符窗口。
        • @Tom:这是有道理的,因为start 的第一个引用参数被用作窗口标题。
        【解决方案6】:

        我的 .emacs 中有这个:

        (setq dired-guess-shell-alist-user
          (list
            (list "\\.*$" "cmd /k")
          ))
        

        这将使用 cmd.exe 打开文件,该文件将使用与文件扩展名关联的任何程序。经测试可在 Windows 8 和 GNU Emacs 24.2.1 上运行。

        【讨论】:

        • 我目前正在测试(setq dired-guess-shell-alist-user '((".*" (concat "start " "\"" file "\""))))。 (我遇到了带空格的文件名。)
        【解决方案7】:

        我会使用(w32-shell-execute "open" file-name)

        事实上,在我的初始化文件中,我有:

        (defun open-externally (file-name)
          (interactive "fOpen externally: ")
          (let ((process-connection-type nil))
             (start-process "open-externally" nil
                            "xdg-open" file-name)))
        
        (when (eq window-system 'w32)
          (defun open-externally (file-name)
            (interactive "fOpen externally: ")
            (w32-shell-execute "open" file-name)))
        

        它定义了一个命令(可以交互使用并)根据xdg-open 使用默认应用程序打开一个文件,然后,如果我实际上在 Windows 上,则适当地重新定义该命令。

        【讨论】:

          【解决方案8】:

          org-open-file 是一个独立于系统的外部开启器。请参阅org-file-apps 了解如何进一步自定义。

          【讨论】:

            【解决方案9】:

            扩展@tom-smith 的答案,这是我验证过并且仅适用于 Windows 的内容(灵感来自 @Tom-smith 和 xahlee blogpost

            将此 sn-p 添加到您的 ~/.emacs.d/init.el:

            ;;; Open file types with default Windows apps
            ;;; -------------------------------------------------------------------
            (defun open-externally (filename)
              (shell-command (format "%s" (shell-quote-argument filename))))
            
            (defun is-file-type? (filename type)
              (string= type (substring filename (- (length filename) (length type)))))
            
            ;; => change this to include more file types <=
            (defun should-open-externally? (filename)
              (let ((file-types '(".pdf" ".doc" ".xls" ".html")))
                (member t (mapcar #'(lambda (type) (is-file-type? filename type)) file-types))))
            
            (defadvice find-file (around find-file-external-file-advice (filename &optional wildcards))
              "Open non-emacs files with an appropriate external program"
               (if (should-open-externally? filename)
                  (open-externally filename)
                 ad-do-it))
            
            (ad-activate 'find-file)
            ;;; -------------------------------------------------------------------
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-10-23
              • 2019-07-20
              • 1970-01-01
              相关资源
              最近更新 更多