OSX 下 Emacs 服务器的基本设置

OSX 下 Emacs 服务器的基本设置

我最近买了十年来的第一台 Mac,正在配置它。我是 Emacs 用户,我决定要只是普通的 Emacs不是 Aquamacs,这样我就可以使用其他操作系统的现有配置。我尝试按照网上找到的很多方法操作(例如这个这个这是我下载 Emacs 的网站),并尝试用多种方式组合各个部分,但从未使事情达到我习惯/希望的状态:

  1. Emacs 守护进程开始运行启动时或者我一需要它;两者都可以。任何新的 Emacs 框架都由同一服务器支持。
  2. 当我从 Finder 打开一个文本文件时,该文件会在 Emacs 中打开,如果可能的话,会在现有的图形框架中打开。
  3. 如果我运行 Emacs.app,系统将重用在后台运行的 emacs 守护程序,而不是启动新实例并在其上打开新窗口。(帽子提示
  4. 当我从终端运行 Emacs 时,终端会继续执行其任务,而不会等待我完成 Emacs(除非我使用“-nw”)
  5. 据我所知,在上述操作过程中,Emacs 不应处于等待我输入的状态(“服务器编辑模式?”)C-x #,尽管我对此没有深入的理解。
  6. (我认为这是个奖励)我可以通过某种方式从终端调用 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

相关内容