cache-path-from-shell: 只加载环境变量一次

在Mac下用Emacs最悲伤的事就是, 所有插件都加载完毕以后, 插件一直抱怨找不到各种执行文件. 这些在Linux下都完全不用考虑的, 直接加载就可以用.

因为Mac默认只会让Emacs使用系统默认的环境变量, 而不会像在终端那样把所有的环境变量都加载进来. 这样就导致很多Emacs插件在执行外部命令时, 无法在 $PATH 环境变量中找到期望的二进制文件.

解决方案很简单, 使用 Steve Purcell 开发的 exec-path-from-shell 即可解决. 一般直接用下面的代码就可以了:

(when (featurep 'cocoa)
  (require 'exec-path-from-shell)
  (exec-path-from-shell-initialize))

因为 exec-path-from-shell 这个插件工作的非常好, 我开发的所有Emacs插件都会在插件开头写上这段代码保证能够正确调用外部命令.

Emacs作为一个永远都可以折腾下去的邪恶操作系统, exec-path-from-shell 又衍生出另外一个问题:

exec-path-from-shell-initialize 命令要从 shell rc 文件中读取环境变量
shell rc 文件越大, 读取越慢.

想象十几个Emacs插件启动的时候都需要执行一次
exec-path-from-shell-initialize 命令,
每次你都会感受到一种明显的顿挫感.

这样是不是很不爽? 其实 exec-path-from-shell-initialize 命令在最开始执行一次就行了, 不用每次都执行. 但是我们也不能控制其他Emacs插件的作者, 大家协调一致只调用一次, 他们可能想调用多少次都是他们的自由.

为了解决这个问题, 我写了一个新的插件 cache-path-from-shell 这个插件会针对 exec-path-from-shell-initialize 命令建立一个缓存机制, 确保 exec-path-from-shell-initialize 命令只能执行一次, 从而避免多个Emacs插件调用 exec-path-from-shell-initialize 命令而叠加的延时和不爽.

安装

先安装 exec-path-from-shell

再从 cache-path-from-shell 下载 cache-path-from-shell.el 然后在 ~/.emacs 的最开头的位置加上(注意一定是最开头的位置)

(require 'cache-path-from-shell)

That’s all.

8 个赞

@casouri 写一个神器送给你, 这样你就不用头疼多次加载的问题了.

除了点赞,我还能说啥呢

除了点赞,我还能说啥呢

卧槽,这神撩。除了点赞我还能说啥呢 :heart:

我看了你给 aweshell 发了一个 PR , 不忍心拒绝你的 PR , 但是我还是不喜欢那种变量的感觉.

干脆来一个一劳永逸的解决方案.

嗯嗯,你觉得不好其实可以拒绝,自己写的包混进去不喜欢的东西还是挺难受的。

没事, 多样化才好.

这个思路很好啊。

但是我觉得我们应该假设用户已经使用exec-path-from-shell,然后在README里给出说明。而不是写在程序里。

虽然编程应该避免假设……

说话有点冲,抱歉。

readme 已经给出说明了啊.

好吧……那你为什么会有exec-path-from-shell加载多次的问题?不都是只在配置最开头加载一次吗?

因为别的插件代码本身就会带 exec-path-from-shell 操作, 多个插件不就会有多个操作了吗?

如果插件本身不带 exec-path-from-shell 的操作, 没经验的用户遇到这种问题就懵逼了.

你先看懂问题再提出问题吧.

其实 spacemacs 的作者也意识到这个问题了。他的解决方案是使用一个 cache 文件存储环境变量。不过 Windows系统下读取的环境变量有不少问题,所以后来我弃用了,最后还是用的 purcell 的包,用起来没有太大问题,可能是调用的外部程序不多。

用这个是不是可以加速 magit 的启动?

好吧……我明白了……有这个操作不一定非要用exec-path-frome-shell这个package和命令。

我只是写出来給需要的朋友,不想抬杠

可以加速第二次以后调用 exec-path-from-shell 命令的所有插件

抱歉…………

magit在windows下的硬伤是每次开magit-status都会启动git,这个过程特别慢,当然本身git在windows里面就是慢。不像大多数gui client,git在后台一直跑着。我记得我之前在哪里看到的。

所以,感觉除非magit作者把机制改了,windows还是老慢。

有兴趣直接给purcell提pr么?感觉这个功能有益无害,应该很容易被接受。

我给上游 magit 和 magithub 贡献了两个补丁.

magithub https://github.com/vermiculus/magithub/pull/377 这个补丁和这位老兄折腾了一个多星期, 今天终于合并了 magit https://github.com/magit/magit/pull/3583 这个补丁和 magit 作者折腾了半个月, 一百行代码, 到现在 magit 作者都还没改对

不想和这帮国外开发者写补丁呢, 一个小时写第一版代码, 半个月时间倒时差扯皮, 累.