Emacs Mac Port 能自动从 ~/.profile 继承环境变量

看到了。

所以大家也可以自己改造 GNU Emacs 的 bundle。如果不想破坏,也可以另外制作一个 bundle,然后可以直接在 spotlight 启动。我以主用 GUI 的时候其实一直就是这样用的:

不太懂 applescript,加上当时的一些奇怪想法,所以写得很乱,其实把逻辑全部写在 Emacs.sh,然后在 Applescript 只需 do shell script 调用就好了。

@railwaycat 搜索了下 Emacs Mac Port 的代码,发现是用 C 实现的

https://bitbucket.org/mituharu/emacs-mac/src/df85af37ecb76855ffb9f85285e2111c612775af/src/mac.c?at=master&fileviewer=file-view-default#mac.c-3168

@twlz0ne Emacs Mac Port 的做法是在二进制 Emacs 中(或者说 main())调用 Emacs.sh,原因好像在上面链接中的注释有解释。

不需要的,看我下边用 applescript 启动:

其实直接 bash 也可以传环境变量,只不过 applescript 可以编译成 bundle,加个图标就是 “app” 了 (右边的 UTF-8 是因为之前我在 bash 里临时修改过环境变量,而 ~/.bash_profile 里还是 zh_CN.UTF-8)


自制 bundle 很简单,我这有个简陋的脚本,可以把 shell 转换成 bundle,不过废弃很久了😅

还有个更强大的工具叫做 Platypus

2 个赞

Script Editor 可以把 AppleScript 导出(File -> Export...)成 App,不知道是不是这个意思。

是的,Script Editor 可以导出 App。

不过我更习惯用 Emacs 来写 applescript / shellscript,然后用转换脚本转。如果直接用 Script Editor 写,默认保存的源文件不是纯文本,并且编辑体验也不好。

Apple Script 看起来是纯文本,其实是编译过的。

多谢指出!看来我之前的印象还停留在最早的已经被废弃的实现上。

并没有废弃 Emacs.sh,只是从 c 调用它,效果跟从 applescript 调用是一样的。既然都 port 了,用 c 是顺理成章,构建编译一步到位,没必要再转手使用其它方式。

的确,需要纯文本的话,保存的时候需要改一下类型(很容易做到)。

Script Editor 默认的命名规则:foo.scpt 不是存文本,foo.applescript 是纯文本。

呃,好像我说的太歧义了…我指的“废弃”是指之前有段时间 Emacs.sh 是作为 Emacs.app 的入口用的壳,而现在放弃了这个做法改成从 Emacs 程序里再调用。

很是蛋疼,exec-path-from-shell提供的默认arguement 是-l -i,但是zsh -l -i -c 'echo $PATH'并不从.zshenv读取环境变量,然而官方默认却说要写在.zshenv里面...zsh -i -c 'echo $PATH'倒是能读取到zshenv,但是.zshrc 的也一并读取了...求教解决方案:sweat_smile:

(use-package exec-path-from-shell
  :defer t
  :init
  (setq exec-path-from-shell-check-startup-files nil) ;; only from .zshenv
  (setq exec-path-from-shell-arguments '("-l"))  ;; remove -i read form .zshenv
  (setq exec-path-from-shell-variables '("PATH"))
  (exec-path-from-shell-initialize))

这是参考论坛某个帖子的,据我观察,每次启动并不读.zshrc

其实让他读.zshrc启动时间也没有差多少,我觉得主要是package-initialize太慢了

你没有用 export PATH=$PATH:xxxx吧?

我在.zshenv里面添加了

export PATH=/usr/local/sbin:/usr/local/bin:/usr/bin

terminal中执行

$ zsh -l  -c 'echo $PATH' 
/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl

也就是使用login shell并不会读取.zshenv,很奇怪,官方文档明明写了大多zsh都会run.A User's Guide to the Z-Shell 实际测试下来,只有interactive shellzsh -i -c 'echo $PATH'才会load .zshenv中定义的path...

你在 zshrc 或者别的地方覆盖了吗……

我的问题跟这个一样...就是使用login shell会在run .zshenv后会调用/etc/zsh/profile,然后path就被覆盖了. https://bbs.archlinux.org/viewtopic.php?id=180845

解决方法应该是使用.zprofile而不用.zshenv :boom: https://bugs.gentoo.org/show_bug.cgi?id=19924#c50

升级了10.15之后貌似没有继承了?

我还没升级 macOS,不过我没依赖 Mac Port 的这个特性,而是自己手动设置的

;; [[https://emacs-china.org/t/topic/5507][Mac 下给 Emacs 设置 PATH 和 exec-path - Emacs-general - Emacs China]]
;; NOTE: When PATH is changed, run the following command
;; $ sh -c 'printf "%s" "$PATH"' > .path
(when *is-mac*
  (condition-case err
      (let ((path (with-temp-buffer
                    (insert-file-contents-literally "~/.path")
                    (buffer-string))))
        (setenv "PATH" path)
        (setq exec-path (append (parse-colon-path path) (list exec-directory))))
    (error (warn "%s" (error-message-string err)))))

这样完全不用运行个 Shell 来获得 PATH。

我用的也是类似手动储存PATH和其他几个环境变量到一个文件里,Emacs再导入的方法。之前尝试改变launchd的环境变量但没有作用:launchd的变量是改变了,但是从spotlight/dock开启的Emacs并没有继承这些环境变量,不知道是什么问题。 忘了这么打开Emacs不是从launchd继承环境变量,我回去重启spotlight再试试 重启了也不行。


我所有环境设置都在~/.profile里,然后再在其他shell的配置文件里source ~/.profile。这样只用维护一份环境配置,所有shell都能用。


写:

echo "(setenv \"PATH\" \"$PATH\") (setenv \"CPATH\" \"$CPATH\") (setenv \"MANPATH\" \"$MANPATH\")" > ~/.emacsenv

读:

(defun luna-load-env ()
  "Load PATH and CPATH from a file."
  (interactive)
  (condition-case err
      (progn (load "~/.emacsenv")
             (setq exec-path (split-string (getenv "PATH") ":")))
    (error (message (error-message-string err)))))