![OSX 下 Emacs 服务器的基本设置](https://linux22.com/image/1388742/OSX%20%E4%B8%8B%20Emacs%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%AE%BE%E7%BD%AE.png)
我最近买了十年来的第一台 Mac,正在配置它。我是 Emacs 用户,我决定要只是普通的 Emacs不是 Aquamacs,这样我就可以使用其他操作系统的现有配置。我尝试按照网上找到的很多方法操作(例如这个,这个和这是我下载 Emacs 的网站),并尝试用多种方式组合各个部分,但从未使事情达到我习惯/希望的状态:
- Emacs 守护进程开始运行启动时或者我一需要它;两者都可以。任何新的 Emacs 框架都由同一服务器支持。
- 当我从 Finder 打开一个文本文件时,该文件会在 Emacs 中打开,如果可能的话,会在现有的图形框架中打开。
- 如果我运行 Emacs.app,系统将重用在后台运行的 emacs 守护程序,而不是启动新实例并在其上打开新窗口。(帽子提示)
- 当我从终端运行 Emacs 时,终端会继续执行其任务,而不会等待我完成 Emacs(除非我使用“-nw”)
- 据我所知,在上述操作过程中,Emacs 不应处于等待我输入的状态(“服务器编辑模式?”)
C-x #
,尽管我对此没有深入的理解。 - (我认为这是个奖励)我可以通过某种方式从终端调用 Emacs,以便 Emacs 尽可能重用现有框架。
我怎样才能配置 Emacs 以实现这样的行为?
我特别困惑于如何让 Finder 按照我想要的方式在 Emacs 中打开东西(#2),因为我发现的指南通常会创建许多别名、Applescript、bash 脚本等等,而我不确定我要告诉 Finder 使用哪一个来打开文本文件。
谢谢!
A。@lawlist 问道:“从终端打开新文件时,是否会默认打开一个新框架,即使存在现有框架?”答案是,如果我在启动时按照所述启动服务器这里,打开一个框架,然后通过键入 打开一个文件/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -n <whatever>
,我可以让文件在现有框架中打开。如果当前没有打开框架,我必须使用“-nc”,否则当我尝试打开文件时什么也不会发生。
B.@lawlist 问道:“你想让守护进程在登录时运行,还是在登录后手动加载 Emacs 就足够了?”手动运行就可以了。
答案1
要使 Emacs.app 在现有框架而不是新框架中打开文件,请添加(setq ns-pop-up-frames nil)
到配置文件中,如~/.emacs
。
open -a emacs file
你可以用或从终端打开一个文件emacsclient -n file
。如果 Emacs.app 未打开但有一个Emacs --daemon
进程,则由于某种原因emacsclient -n file
不起作用emacsclient -nc file
。
确保您使用emacsclient
所用 Emacs 版本附带的二进制文件,例如/Applications/Emacs.app/Contents/MacOS/bin/emacsclient
,或者/usr/local/bin/emacsclient
如果您使用 Homebrew 安装了 Emacs。
要在登录时启动 Emacs 服务器,例如将此 plist 保存为~/Library/LaunchAgents/my.emacsdaemon.plist
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>my.emacsdaemon</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/Emacs.app/Contents/MacOS/Emacs</string>
<string>--daemon</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/> <!-- run the program again if it terminates -->
</dict>
</plist>
下次登录时,plist 会自动加载,但您可以通过运行立即加载它launchctl load ~/Library/LaunchAgents/my.emacsdaemon.plist
。
编辑:我仍然不知道为什么人们将文件类型与 AppleScript 应用程序而不是 Emacs.app 关联。不过,kuzzooroo 的答案中的脚本也可以编写为 shell 脚本:
macos=/Applications/Emacs.app/Contents/MacOS
if pgrep -qf 'Emacs.*--daemon'; then
[[ $($macos/bin/emacsclient -e '(<= 2 (length (visible-frame-list)))') = t ]] && args=-nc || args=-n
else
$macos/Emacs --daemon
args=-nc
fi
$macos/bin/emacsclient $args "$@"
open -a /Applications/Emacs.app
您可以使用鸭嘴兽将脚本保存为应用程序:
我刚开始使用 Emacs,但我有一个完全不同的设置。我通过复制 iTerm.app、更改 Info.plist 中的 CFBundleIdentifier 以便应用程序使用不同的首选项文件以及将默认命令设置为 来制作自己的 Emacs 应用程序/usr/local/bin/emacs
。我已添加(server-start)
到~/.emacs
并在登录时打开自定义 Emacs 应用程序。我使用 Platypus 创建了一个可运行的应用程序emacsclient -n "$@";open -b my.emacs
,并将其设为文本文件的默认应用程序。
答案2
Lauri 的解决方案与评论中的建议相结合,在很大程度上解决了我的问题。我在下面粘贴了一些 Applescript,这些脚本是我根据在线找到的内容拼凑起来的。该脚本有助于消除一些剩余的问题,例如,如果没有当前的 Emacs 框架,它的行为会更好一些。
编辑:该脚本的目的是与 Finder 中的 .txt 文件关联。
-- http://superuser.com/questions/457484/how-to-open-emacs-from-macs-finder
-- https://gist.github.com/ambethia/304964#comment-799519
on run {input}
set filepath to quoted form of POSIX path of input
tell application "Terminal"
try
-- we look for <= 2 because Emacs --daemon seems to always have an entry in visibile-frame-list even if there isn't
set frameVisible to do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -e '(<= 2 (length (visible-frame-list)))'"
if frameVisible is "t" then
do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -n " & filepath
else
-- there is a not a visible frame, launch one
do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -c -n " & filepath
end if
on error
-- daemon is not running, start the daemon and open a frame
do shell script "/Applications/Emacs.app/Contents/MacOS/Emacs --daemon"
do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -c -n"
end try
end tell
-- bring the visible frame to the front
tell application "Emacs" to activate
return input
end run