Emacs 23、OS X、multi-tty 和 emacsclient

5
如何在 OS X 上使emacs 23 多tty模式正常工作?
我已经在我的.emacs中添加了(server-start),并发现运行/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -n ~/myfile.txt将在我的emacs.app中打开它,但它不会将emacs置于前台。
那么,当我运行emacsclient时,如何让emacs.app出现在前面?(我考虑编写一个函数,每次打开文件时都将当前框架放在前面,或者编写一个Applescript来执行类似的任务,该任务可以与emacsclient同时调用)
emacs.app中的emacsclient是最好使用的吗?如果是,我假设我将为其编写别名,但使用它似乎比使用/usr/local/bin中的某些内容更奇怪。
有没有人有任何其他提示或示例可以让这个工作?
8个回答

6

我在Emacs中设置了一个别名为

open -a /Applications/Emacs.app "$@"

如果您对每个文件都会打开一个新的框架(窗口)感到烦恼,请添加以下内容:
(setq ns-pop-up-frames nil)

将以下内容添加到你的 .emacs 文件中并保存。


5
也许这种方法可以行得通,当客户端连接时只需调用raise-frame:
(add-hook 'server-visit-hook 'call-raise-frame)
(defun call-raise-frame ()
  (raise-frame))

(这恰好是我Linux机器上的冗余部分。)

这对我没有用。我把它放在.emacs文件中并进行了评估,但似乎没有任何效果。 - Singletoned
1
如果你有兴趣,可以尝试调试这个程序。第一步,在Emacs中将光标移动到'call-raise-frame defun内部,然后执行M-x edebug-defun。接着使用emacsclient连接。Emacs应该会进入调试器,此时你的.emacs文件(或包含'call-raise-frame的任何缓冲区)旁边会出现一个小箭头指向(raise-frame)行。模式行周围应该有[]括号(表示你正在调试)。此时,你应该能够执行M-x raise-frame。当然,在Linux中,调试器中的每个操作都会提升框架,降低了调试的实用性。 - Trey Jackson
我已经尝试过这个并试图进行调试。看起来raise-frame在我的Emacs 23版本上根本不起作用(大约20分钟前从源代码编译的next-step)。我无法弄清楚为什么它不起作用。我甚至将server-raise-frame设置为t。 - Singletoned
在我的Mac OSX上,昨天编译的Emacs.app 23对我不起作用 :| - simao
我用的CocoaEmacs版本可以这样操作。请确保你正在使用应用程序包中的emacsclient二进制文件。 - jkp

4

一些提出的解决方案建议使用 'raise-frame'。 这将提高emacs框架,但不会使其获得焦点。 当您从终端窗口启动emacs时,emacs仍将位于终端窗口下方,因为终端窗口保留了焦点。 我使用'select-frame-set-input-focus'来提高并集中焦点。

示例:

/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -n ~/myfile.txt \
    --eval '(select-frame-set-input-focus (nth 0 (frame-list)))'

我更喜欢运行独立的emacs实例,这样当我使用"^X^C"退出时,不会失去所有窗口。为了实现这一点,我有一个shell脚本:

#!/bin/bash
/Applications/Emacs.app/Contents/MacOS/Emacs \
    --eval '(select-frame-set-input-focus (nth 0 (frame-list)))' \
    "$@"

2

我在我的.emacs文件中使用以下代码,仅在服务器未运行时才调用server-start:

(if (file-exists-p
 (concat (getenv "TMPDIR") "emacs"
         (number-to-string
          (user-real-uid)) "/server"))
nil (server-start))

我对我的.zshrc文件进行了一些更改,这样我就可以在shell中轻松地运行ec作为我的编辑器命令:

# I use the Emacs package from emacsformacosx.com
alias emacs='open -a emacs'
alias emacsclient='/Applications/Emacs.app/Contents/MacOS/bin/emacsclient'
alias ec='emacsclient -a /Applications/Emacs.app/Contents/MacOS/Emacs'
export EDITOR='ec'

2

这个AppleScript非常简单:

tell app "Emacs" to activate

谢谢,非常好用。只是想要扩展一下。我已经将Emacs命名为: 'osascript -e '''tell app "Emacs" to activate''';/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -n' - Singletoned

1
为了进一步阐述Trey Jackson的答案和Singletoned的评论:我在我的.emacs文件中有以下内容。
;;;
;;; Run in server-mode so other sessions can connet
;;;
(defun call-raise-frame ()
   (raise-frame))
(defun end-server-edit ()
   (shell-command "osascript -e \"tell application \\\"System Events\\\" to keystroke tab using command down\""))
(add-hook 'server-visit-hook 'call-raise-frame)
(add-hook 'server-done-hook 'end-server-edit)
(server-start)

在我的shell初始化文件中,我有以下别名:
alias e='emacsclient'      # edit
alias enw='emacsclient -n' #edit (no wait)

现在我可以在CocoaEmacs实例旁边打开一个shell,并且无缝地将两者一起使用。我可以通过使用“e”别名将编辑器“内联”到当前终端流中,一旦我在emacs中完成编辑,焦点将返回到调用终端。

0
我在我的 .emacs 中定义了这个函数。
(defun ns-raise-emacs ()
  (ns-do-applescript "tell application \"Emacs\" to activate"))

然后使用此代码来升起框架:

emacsclient -e '(ns-raise-emacs)'

我建议您使用这种方式而不是调用osascript。 与使用osascript相比,它似乎响应更快(有时显着更快)。


0

顺便提一下,这是我的解决方案:
步骤1:在 /usr/local/bin/emacs 创建一个脚本,并将以下内容放入其中:

#!/usr/bin/bash
emacsclient -c --alternate-editor='/Applications/Emacs.app/Contents/MacOS/Emacs'  "$@" 2>/dev/null

步骤2. 通过以下命令使其可执行:chmod +x /usr/local/bin/emacs

步骤3. 在您的~/.emacs文件中添加以下内容:

(server-start)  

(defun ns-raise-emacs ()  
(ns-do-applescript "tell application \"Emacs\" to activate"))  

(ns-raise-emacs)  

(add-hook 'server-visit-hook 'raise-frame)  
;;(add-hook 'server-visit-hook 'ns-raise-emacs)

说明:

如果在 /usr/local/bin/emacs 路径下调用 emacs 脚本时,没有正在运行的 emacs 服务器,emacsclient 将调用备选编辑器,在这种情况下是 Emacs 编辑器 (/Applications/Emacs.app/Contents/MacOS/Emacs)。

在第3步中,对 (ns-raise-emacs) 的初始调用似乎是必要的,以便初始的 Emacs 窗口显示在所有其他窗口前面。

(add-hook 'server-visit-hook 'raise-frame) 是为了让后续的窗口显示在所有其他窗口前面。

或者,如果你希望每次从命令行调用 emacs 时所有 Emacs 窗口都显示在所有其他窗口前面,可以取消注释 (add-hook 'server-visit-hook 'ns-raise-emacs) 这一行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接