作者:winterTTr  转载请注明


无论我们在windows下或者在Linux下使用emacs,毫无疑问,我们都需要借助很多外部命令来完成相应的任务。

那么,在emacs中,是通过什么方式找到外部命令的呢?


我们都知道,无论在什么系统下,将某个可执行文件的目录加入PATH环境变量,就可以在命令行下使用这个命令,无论这个命令放在哪里。

所以,emacs启动时的PATH变量,是emacs中寻找外部命令的一个因素。


除此之外,emacs中还有一个主要的变量,那就是exec-path。


exec-path和PATH环境变量有什么区别?

exec-path是用来帮助emacs寻找可以*直接*使用的外部程序。所谓直接,表明是作为一个子进程存在的程序。这个子进程可以继承PATH环境变量,从而让子进程也可以找到对应的程序的执行路径。举个例子来说,如果你你指设置grep的执行路径给exec-path,你会发现,M-x grep执行不正确。那是因为,grep是通过一个sh子进程去执行的,所以,正确的办法是,更新PATH环境变量。


究竟应该何时设置exec-path和PATH环境变量?

当然,除非你可以很明确的区分emacs启动某些子进程的方式,否则,不必明显的区分exec-path和PATH,我得建议是同时将两者更新即可。

(defun wttr/prepend-to-exec-path (path)
  "prepand the path to the emacs intenral `exec-path' and \"PATH\" env variable.
Return the updated `exec-path'"
  (setenv "PATH" (concat (expand-file-name path)
                         path-separator
                         (getenv "PATH")))
  (setq exec-path
        (cons (expand-file-name path)
              exec-path)))

这里提供一个我使用的函数,可以比较方便的同时更新这两个变量。使用举例:

  (mapc #'wttr/prepend-to-exec-path
        (reverse 
         '("~/bin"
           "~/.emacs.d/extra-bin/unix-utils-bin"
           "~/.emacs.d/extra-bin/etc"
           "~/.emacs.d/extra-bin/PuTTY"
           "~/.emacs.d/extra-bin/clang"
           )))


为什么不选择将emacs使用的命令全加入系统的PATH?

就如同我上面的例子,emacs使用了很多linux下的命令,这些命令(例如:find)和windows系统的命令会有冲突。

如果全部加入系统PATH,可以会引起一些系统脚本不能正常运行。所以,比较安全的方式是,只更新emacs内部的状态,对外部不会有任何影响。


以上~



Logo

更多推荐