如何从 OSX 的命令行启动 GUI Emacs?

Posted

技术标签:

【中文标题】如何从 OSX 的命令行启动 GUI Emacs?【英文标题】:How to launch GUI Emacs from command line in OSX? 【发布时间】:2012-04-27 14:45:36 【问题描述】:

如何在 OSX 中从命令行启动 GUI Emacs?

我已经从http://emacsformacosx.com/ 下载并安装了 Emacs。

我会接受满足以下所有条件的答案:

    emacs 窗口在我的终端窗口前面打开。 键入“emacs”会启动一个 GUI Emacs 窗口。在该窗口中查找文件将默认在我启动 Emacs 的目录中查找。 当 foo.txt 存在时键入“emacs foo.txt”会启动一个加载了 foo.txt 的 GUI Emacs 窗口。 当 foo.txtnot 存在时键入“emacs foo.txt”会启动一个 GUI Emacs 窗口,其中包含一个名为“foo.txt”的空文本缓冲区。在该缓冲区中执行 ^X^S 会将 foo.txt 保存在我启动 Emacs 的目录中。

【问题讨论】:

在终端提示符下输入“emacs”不满足哪些条件?您的要求描述了 Linux 上的默认行为。我有一段时间没用过 Mac,但我认为诀窍就是找到合适的程序来执行 - 也许是 emacs.app? Tyler,Linux 出身,我一直陪着你;只需在提示符下输入“emacs”就可以了。但是,在 OSX 上这样做会在终端窗口中启动文本模式 Emacs(因此不符合标准 1),这不是我想要的。 Johan - 在此期间您找到解决方案了吗?我正在努力解决同样的问题,并考虑开始赏金。特别烦人的是,从命令行调用 emacs(而不是 Emacs.app)会在后台打开一个窗口... @DougHarris 我的要求在任何 Linux 发行版上都符合现实,这就是它们的来源。我很高兴您找到了适合您的工作流程。干杯! 我不知道它是否适用于 OSX,但您可以尝试:emacsclient -c -a "" "$@" command 【参考方案1】:
open_emacs() 
    num=$(ps aux | grep -E "[E]macs-x86_64-10_14 --|[e]macs --" | wc -l)
    if [ $num -eq 0 ]; then
        echo "## starting emacs"
        # Run in a subshell to remove notifications and close STDOUT and STDERR:
        (&>/dev/null emacsclient -t -q &)
    fi


alias e="open_emacs"

如果 emacs 守护程序不在后台运行,下面的行 (&>/dev/null emacsclient -t -q &) 将启动它。

macOS 可能已经定义了以E 开头的应用名称(例如:Emacs-x86_64-10_14.app),基于此您可以检查emacs 守护进程是否在后台运行。

【讨论】:

【参考方案2】:

top answer 很好,但我希望 emacs 进程在后台运行,这样我仍然可以使用我的 shell。 This answer 似乎做了我想做的事,但没有在正确的目录中启动 emacs,这意味着需要绝对路径(或者将pwd 附加到在所有情况下都不起作用的路径上)。此外,简单地使用& 意味着如果我杀死终端,emacs 也会被杀死。

我决定使用screen 和 bash 函数,以下解决方案适用于安装了brew 的 macOS 10.15.6 和 emacs 26.2:

function emacs() 
    screen -d -m /Applications/Emacs.app/Contents/MacOS/Emacs "$@"

对于-d -m 命令行标志的含义,它们一起使用时具有特殊含义,因此基本上可以将其视为一个命令行标志。解释在手册页中:

以“分离”模式启动屏幕。这会创建一个新会话,但不会附加到它。这对于系统启动脚本很有用。

【讨论】:

问题在 GUI 窗口中明确要求 Emacs,这会在终端会话中打开 Emacs。 @JohanWalles,这会在 GUI 窗口中打开 Emacs。 screen 让我失望,现在我更仔细地阅读,我意识到你是对的。我很抱歉@gsingh2011。 您能否编辑或评论以解释screen -d -m对这种情况的影响? @JoshuaGoldberg,我想我在答案中回答了这个问题。我想在后台运行 emacs 并继续使用我的终端。还有其他提供类似功能的答案,但它们有一些缺点,例如从错误的目录开始或将 emacs 进程生命周期与终端进程生命周期联系起来。我的回答(使用屏幕)避免了这些缺点。【参考方案3】:

在使用“open”时,请确保使用“--args”选项

不要这样做:

alias emacs='open -a /Applications/Emacs.app $1'

改为:

alias emacs='open -a /Applications/Emacs.app --args $1'

--args 选项可防止“打开”使用用于 Emacs 的各种选项。

【讨论】:

出于某种原因,当我在 macOS 10.15.6 和 Emacs 26.2 上进行测试时,emacs 工作目录设置为我的主目录,这意味着我无法使用相对路径打开文件。不过,这确实解决了打开不存在文件的问题。【参考方案4】:

简单的解决方案...

这里发布了很多非常复杂的解决方案。这很公平,因为它看起来很重要。

但是,这个解决方案对我来说非常有效。

ec() 
  emacsclient -n $@ 2> /dev/null
  if [[ $? == 1 ]]; then
    open -a Emacs.app  -- $@
  fi

用法

ec file [...]

让我们解开正在发生的事情:

    将所有ec 参数传递给emacsclient,不要(-n)在继续之前等待emacs。
      如果 Emacs 已经在运行,我们就完成了,您正在编辑。
    在没有运行 emacs 时吞下 emacsclient 发布的错误消息。 (2> /dev/null) 手动处理退出码1([[ $? == 1 ]])
      打开 Emacs.app 并将文件参数传递给它(路径将被正确打开。) 大功告成,Emacs 已打开您的文件。

【讨论】:

【参考方案5】:

这是我在 osx 上打开 emacs/emacsclient 的脚本。

#!/bin/bash

# Ensure (server-start) is added in your emacs init script.

EMACS=/Applications/MacPorts/Emacs.app/Contents/MacOS/Emacs
EMACSCLIENT=/Applications/Macports/Emacs.app/\
Contents/MacOS/bin/emacsclient

# test if client already exsit.
$EMACSCLIENT -e "(frames-on-display-list)" &>/dev/null

# use emacsclient to connect existing server.
if [ $? -eq 0 ]; then
    $EMACSCLIENT -n "$@"
# open emacs.app instead.
else
    `$EMACS "$@"` &
fi

【讨论】:

【参考方案6】:

我假设你是:

登录时启动 emacs 守护进程 在您的 .emacs 中有(服务器启动) 不介意运行多个单独的 emacs 副本

如果是这样,那么我认为这满足了原来的四个标准,再加上一个:

    emacs 窗口在我的终端窗口前面打开。

它将始终向前景打开(带有 x-focus-frame)。

    键入“emacs”会启动一个 GUI Emacs 窗口。在该窗口中查找文件将默认在我启动 Emacs 的目录中查找。

它将以 dired 模式打开现有的 emacs 窗口。

    当 foo.txt 存在时键入“emacs foo.txt”会启动一个加载了 foo.txt 的 GUI Emacs 窗口。

如果 emacs 已经在运行并且有服务器,那么它将在现有窗口中打开并进入前台。

    当 foo.txt 不存在时键入“emacs foo.txt”会启动一个带有名为“foo.txt”的空文本缓冲区的 GUI Emacs 窗口。在该缓冲区中执行 ^X^S 会将 foo.txt 保存在我启动 Emacs 的目录中。

正确。

一个额外的:

输入命令后控制立即返回终端会话。

~/bin/emacs

#!/bin/bash
EMACSPATH=/Applications/Emacs.app/Contents/MacOS

# Check if an emacs server is available 
# (by checking to see if it will evaluate a lisp statement)

if ! ($EMACSPATH/bin/emacsclient --eval "t"  2> /dev/null > /dev/null )
then
    # There is no server available so,
    # Start Emacs.app detached from the terminal 
    # and change Emac's directory to PWD

    nohup $EMACSPATH/Emacs --chdir "$PWD" "$@" 2>&1 > /dev/null &
else
    # The emacs server is available so use emacsclient

    if [ -z "$@" ]
    then
        # There are no arguments, so
        # tell emacs to open a new window

        $EMACSPATH/bin/emacsclient --eval "(list-directory \"$PWD\")"
    else    
        # There are arguments, so
        # tell emacs to open them

        $EMACSPATH/bin/emacsclient --no-wait "$@"
    fi

    # Bring emacs to the foreground

    $EMACSPATH/bin/emacsclient --eval "(x-focus-frame nil)"
fi

【讨论】:

太棒了!不过,您的 args 和 no-args 腿似乎已互换。【参考方案7】:

这里的其他答案对我来说不太适用。特别是在我的机器上,bash 脚本

#!/bin/sh
/Applications/Emacs.app/Contents/MacOS/Emacs "$@" 

总是在主目录中打开 emacs。为了让它在当前工作目录中打开,我必须这样做

#!/bin/sh
/Applications/Emacs.app/Contents/MacOS/Emacs "$PWD/$@"

改为。

【讨论】:

我的特定构建/安装没有该问题,但您的解决方案存在问题。如果您尝试打开多个文件,则只有第一个文件会扩展至 PWD 目录。其余的将没有 $PWD 路径前缀。【参考方案8】:

进一步改进大卫詹姆斯的回应,以下对我有用:

按照从位于http://www.emacswiki.org/emacs/EmacsForMacOS#toc20 的终端打开文件的说明

open -a /Applications/Emacs.app <file-name>

结合 David Jame 的回复,我创建了以下 emax bash 脚本并将其放置在我的路径中 ~/bin

#!/bin/bash
(open -a /Applications/Emacs.app "$@") &

警告:为了让emacs以Dired by name模式打开当前目录,你需要使用

emax .

环境:

OS X Yosemite 版本 10.10.2 GNU Emacs 24.4.2 (x86_64-apple-darwin14.0.0, NS apple-appkit-1343.14) 2014 年 11 月 13 日

【讨论】:

这仅适用于现有文件,如果不存在则不会创建一个 我使用的是 macOS 10.15 (Catalina),这似乎第一次有效(当 Emacs 尚未打开时),但第二次无效(当 Emacs 窗口已经打开)。你知道如何解决这个问题吗?【参考方案9】:

通过在后台启动 Emacs,这对 David Caldwell's answer 进行了改进:

#!/bin/sh
$(/Applications/Emacs.app/Contents/MacOS/Emacs "$@") &

如另一个答案中所述,这包括#2、#3 和#4。对于 #1,将其放在 .emacs 文件中的某个位置:(x-focus-frame nil)

请注意,以下内容对我有用——它不会在命令行指定的目录中启动 Emacs(例如 emacs .

# NOT RECOMMENDED
#!/bin/sh
/Applications/Emacs.app/Contents/MacOS/Emacs "$@" &

【讨论】:

这修复了 OSX 的一个问题(可能从 10.9 Mavericks 开始)。从 10.9 开始,“不推荐”的方法会失败,而在 10.6 之前,不推荐的方法确实同步了 shell $PWD 和 Emacs (pwd)。大卫的答案可能在别处,但你如何让搜索引擎理解:“pwd not pwd”? 当我在 macOS 10.15.6 和 Emacs 26.2 上测试时,这个答案中的两个 sn-ps 都没有在正确的目录中启动 emacs。【参考方案10】:

在您的 shell 中,将命令“emacs”别名为指向 OSX emacs 应用程序

在我的 shell(运行默认 bash)中,我有以下内容(在我的 .bashrc 中)

alias emacs='open -a /Applications/Emacs.app $1'

然后,在命令行输入 emacs 启动 emacs 应用程序。

不过,我建议您打开一份 emacs 副本并保持其正常运行。如果是这种情况,并且您想将文件加载到现有的 emacs 副本中,则可以通过在 .bashrc 中放置以下内容来使用 emacsclient:

alias ec='/Applications/Emacs.app/Contents/MacOS/bin/emacsclient'

然后将以下内容添加到您的 .emacs 文件中以启动 emacs 服务器(它接收 emacsclient 调用)

;;========================================
;; start the emacsserver that listens to emacsclient
(server-start)

然后你可以输入

ec .bashrc

将 .bashrc 的副本加载到现有的 emacs 会话中!

【讨论】:

嗨,克里斯!您的第一个答案不符合标准 2 和 4。您的第二个答案不符合标准 2。我正在寻找满足所有编号标准的解决方案。问候/约翰 如果你只使用emacs本身来加载文件,而不是每次都依赖命令行启动一个新实例,似乎你所有的问题都可以解决。我通常在一天开始时启动 emacs(如果它还没有运行),并使用它来加载文件、更改目录、创建新文件以及我想要的任何其他内容,而无需触摸终端窗口。 不得不说,本站有几个这样的问题是处理这个问题的,但这是唯一一个完全解决了也打开文件的问题,用短小精悍的方式. @tylerthemiler,完全解决问题的答案在哪里?此答案中的两个答案均未通过标准 2,第一个答案也未通过标准 4。 一点点机智可以让问题得到解答。谷歌搜索也是如此。【参考方案11】:

刚刚根据本指南使用自制软件包管理器构建了 emacs: http://www.emacswiki.org/emacs/EmacsForMacOS 用 brew install --cocoa emacs 之后应该启动 .app 版本来获取 gui,在我的例子中是 /usr/local/Cellar/emacs/24.3/Emacs.app/Contents/MacOS/Emacs

【讨论】:

--可可已被弃用;使用 --with-cocoa 代替!【参考方案12】:

按照以下步骤编译 Emacs:

./configure --with-x --prefix=/usr
make
sudo make install

你完成了!下载和安装 XQuartz 可能会有所帮助,但这只是我的看法。

【讨论】:

【参考方案13】:

调用以下脚本“emacs”并将其放在您的PATH 某处:

#!/bin/sh
/Applications/Emacs.app/Contents/MacOS/Emacs "$@"

这包括 #2、#3 和 #4。

对于 #1,将其放在 .emacs 文件中的某个位置:

(x-focus-frame nil)

emacsformacosx.com 站点现在有一个How-To page,这是*** sn-p 的来源。那里有更多关于运行 emacsclient 和将 Emacs 连接到 git mergetool 的信息。

【讨论】:

效果很好。赏金即将到来。 谢谢 - 也为我工作! 如果我在文件夹 ~/foo 中并且想要打开 bar.txt 在 Mavericks 上,我输入 gmacs bar.txt 但它会在 ~/bar.txt 创建一个新文件,而不是打开 ~foo/bar.txt。我做错了吗? .emacs 文件在哪里? 你不能在任何地方添加 (x-focus-frame nil),它必须在 (custom-set-variables) 表达式中,一旦你通过设置任何东西,emacs 将为你创建定制。只需从菜单栏中自定义某些内容,例如将“闪烁光标”设置为打开(如果您不喜欢则关闭),该部分将在您的 .emacs 中创建。另外,这是否经过测试?我不确定 Cocoa 上的 emacs 是否会尊重这个设置。【参考方案14】:

在 Mountain Lion 上,我使用 Yamamoto Mitsuharu 的端口 https://github.com/railwaycat/emacs-mac-port,别名如下:

alias emacs=/Applications/Emacs.app/Contents/MacOS/Emacs

它满足您的所有条件。

【讨论】:

以上是关于如何从 OSX 的命令行启动 GUI Emacs?的主要内容,如果未能解决你的问题,请参考以下文章

markdown 从OSX上的命令行启动Sublime Text

text 从命令行启动Sublime Text(在OSX上)

如何从命令行打开 DbVisualizer 连接(GUI)?

sh 从命令行macOS,OSX,Linux重启,启动,停止MySQL

Emacs服务器模式以及emacsclient配置

Mac OSX、Emacs 24.2 和 nrepl.el 不工作