You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写Emacs插件:修改osascript -e显示的OS X原生通知图标方法

解决Emacs插件中通过osascript自定义OS X通知图标的方案

好问题!我之前在开发Emacs通知相关工具时也踩过terminal-notifier的坑——虽然它功能全,但依赖安装的要求对普通用户太不友好了。下面给你几个无需额外依赖、直接通过osascript实现自定义图标的实用方案:

方案1:直接引用本地.icns图标文件

OS X的display notification命令支持直接指定本地.icns格式的图标文件路径,完全不需要bundle包。

示例AppleScript代码

display notification "这是来自Emacs的通知内容" 
with title "Emacs通知" 
subtitle "自定义图标测试" 
with icon file "/Users/your-username/.emacs.d/assets/emacs-custom.icns"

在Emacs中集成的写法

你可以用Emacs的函数把相对路径转成系统能识别的绝对路径,同时处理路径中的空格问题:

(defun my-emacs-notify (title content icon-path)
  (let* ((abs-icon-path (expand-file-name icon-path user-emacs-directory))
         (escaped-icon (shell-quote-argument abs-icon-path))
         (cmd (format "osascript -e 'display notification \"%s\" with title \"%s\" with icon file %s'"
                      content title escaped-icon)))
    (shell-command cmd)))

;; 使用示例
(my-emacs-notify "编译完成" "你的代码已经编译成功!" "assets/emacs-custom.icns")

注意:图标文件必须是.icns格式,如果只有PNG/JPG,可以用系统自带的sips命令转换:

sips -s format icns your-icon.png --out your-icon.icns

方案2:直接调用系统应用的内置图标

如果不想额外携带图标文件,可以直接引用OS X系统中已安装应用的图标,比如Emacs自身的图标:

示例AppleScript代码

# 通过应用名称调用
display notification "内容" with title "标题" with icon application "Emacs"

# 或者通过Bundle ID调用(更稳定,避免重名应用冲突)
display notification "内容" with title "标题" with icon application id "org.gnu.Emacs"

在Emacs中集成的写法

这个方案更简洁,不需要处理文件路径:

(defun my-emacs-notify-simple (title content)
  (let ((cmd (format "osascript -e 'display notification \"%s\" with title \"%s\" with icon application id \"org.gnu.Emacs\"'"
                     content title)))
    (shell-command cmd)))

;; 使用示例
(my-emacs-notify-simple "任务完成" "你的Emacs插件已经加载完毕!")

方案3:临时嵌入图标(进阶,不推荐日常使用)

如果必须把图标嵌入到代码中(比如不想让用户看到额外文件),可以把.icns文件转成Base64字符串,在osascript中解码并临时保存为文件后使用。不过这个方法比较繁琐,性能也不如前两个方案,只适合特殊场景:

set iconBase64 to "这里替换成你的.icns文件的Base64字符串"
set tempIconPath to (path to temporary items as text) & "temp-icon.icns"
do shell script "echo " & quoted form of iconBase64 & " | base64 --decode > " & quoted form of POSIX path of tempIconPath
display notification "内容" with title "标题" with icon file tempIconPath
do shell script "rm " & quoted form of POSIX path of tempIconPath

内容的提问来源于stack exchange,提问作者Petrosyan Alexander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:49:21