当命令尝试以shell模式打开编辑器时,打开Emacs缓冲区

时间:2008-09-22 18:18:59

标签: unix shell emacs

我喜欢使用Emacs的shell模式,但它有一些不足之处。其中之一是,当shell命令试图调用编辑器时,打开新缓冲区并不够智能。例如,如果环境变量VISUAL设置为vim,我会从svn propedit获得以下内容:

$ svn propedit svn:externals . 
"svn-prop.tmp" 2L, 149C[1;1H
~                                                                               [4;1H~                                                                               [5;1H~                                                                               [6;1H~                                                                               [7;1H~            
...

(从表示中可能很难说,但这是一个可怕的,丑陋的混乱。)

VISUAL设置为"emacs -nw"后,我

$ svn propedit svn:externals .
emacs: Terminal type "dumb" is not powerful enough to run Emacs.
It lacks the ability to position the cursor.
If that is not the actual type of terminal you have,
use the Bourne shell command `TERM=... export TERM' (C-shell:
`setenv TERM ...') to specify the correct type.  It may be necessary
to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.svn: system('emacs -nw svn-prop.tmp') returned 256

(它适用于设置为VISUAL的{​​{1}},但仅限于Emacs X窗口内部,而不是终端会话内。)

有没有办法让shell模式在这里做正确的事情并代表命令行进程打开一个新的缓冲区?

6 个答案:

答案 0 :(得分:20)

您可以通过emacsclient附加到Emacs会话。首先,使用

启动emacs服务器
M-x server-start

或将(server-start)添加到您的.emacs。然后,

export VISUAL=emacsclient

编辑。

注意:

  • emacsemacsclient的版本必须同意。如果您安装了多个版本的Emacs,请确保调用与运行服务器的Emacs版本对应的emacsclient版本。
  • 如果您在多个Emacs进程/帧中启动服务器(例如,因为(server-start).emacs中),则将在最后一帧中创建缓冲区以启动服务器。

答案 1 :(得分:3)

有emacsclient,gnuserv,在Emacs 23中,multi-tty对此都很有用。实际上我认为在Emacs 23中,emacsclient具有gnuserv的所有有趣功能。

答案 2 :(得分:0)

不完全正确。 ansi-term可以运行emacs(虽然我通常运行mg作为提交日志,但在极少数情况下我不直接从emacs提交)。如果您先启动eshell并从那里开始运行,screen也可以运行emacs。

答案 3 :(得分:0)

除了使用emacs客户端/服务器之外,我还使用此脚本来调用emacs。

如果emacs尚未运行,它将启动emacs,或者只是在运行的emacs中打开一个新的emacs缓冲区(使用gnuclient)。它默认在后台运行,但可以在前台运行,以获得期望输入的进程。例如,在输入更改列表描述时,我将其用作源控件编辑器。我有“SVN_EDITOR = emacs sync”,所以我可以在emacs shell中执行“svn commit”,它会在同一个emacs中的新emacs缓冲区中打开svn编辑器。当我关闭缓冲区时,“svn commit”继续。很有用。

#!/bin/sh

if [ -z $EMACS_CMD ]; then
  EMACS_CMD="/usr/bin/emacs"
fi

if [ -z $GNUCLIENT_CMD ]; then
  GNUCLIENT_CMD="/usr/bin/gnuclient"
fi

if [ "$1" = "sync" ]; then
    shift 1
    sync=true
else
    sync=false
fi

cmd="${EMACS_CMD} $*"
lsof $EMACS_CMD | grep $USER >/dev/null 2>&1
if [ "$?" -ne "1" ]; then
    cmd="${GNUCLIENT_CMD} $*"
fi

if [ $sync = "true" ]; then
    $cmd
else
    $cmd &
fi

答案 4 :(得分:0)

我想通过mercurial在emacs shell中进行类似的操作。感谢这里的海报,我找到了方法。两步:

  1. 在.emacs文件中添加:(start-server)(记得在更改后加载文件)

  2. 你的hgrc中的
  3. [merge-tools]
    emacs.executable = emacsclient
    emacs.premerge = False
    emacs.args = --eval "(ediff-merge-with-ancestor \"$local\" \"$other\" \"$base\" nil \"$output\")"
    

答案 5 :(得分:0)

当我的.emacs中有(start-server)时,我收到此错误....

Debugger entered--Lisp error: (void-function start-server)
  (start-server)
  eval-buffer(#<buffer  *load*> nil "/Users/jarrold/.emacs" nil t)  ; Reading at buffer position 22768
  load-with-code-conversion("/Users/jarrold/.emacs" "/Users/jarrold/.emacs" t t)
  load("~/.emacs" t t)
  #[nil "^H\205\276^@   \306=\203^Q^@\307^H\310Q\202A^@ \311=\2033^@\312\307\313\314#\203#^@\315\202A^@\312\307\$
  command-line()
  normal-top-level()

....我正在使用GNU Emacs 22.1.1

这是我正在使用的Mac OS-X版本:

  

shandemo 511 $ uname -a Darwin Facilitys-MacBook-Pro.local 10.8.0

     

Darwin内核版本10.8.0:2011年6月7日星期二16:33:36;

     

root:xnu-1504.15.3~1 / RELEASE_I386 i386

请注意,m-x ansi-term似乎允许我在其shell中成功提交hg。但是,那个shell不允许我滚动缓冲区,例如c-p或c-n所以我更喜欢我们的m-x shell。