tags:

views:

1398

answers:

5

I like to use Emacs' shell mode, but it has a few deficiencies. One of those is that it's not smart enough to open a new buffer when a shell command tries to invoke an editor. For example with the environment variable VISUAL set to vim I get the following from svn propedit:

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

(It may be hard to tell from the representation, but it's a horrible, ugly mess.)

With VISUAL set to "emacs -nw", I get

$ 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

(It works with VISUAL set to just emacs, but only from inside an Emacs X window, not inside a terminal session.)

Is there a way to get shell mode to do the right thing here and open up a new buffer on behalf of the command line process?

+13  A: 

You can attach to an Emacs session through emacsclient. First, start the emacs server with

M-x server-start

or add (server-start) to your .emacs. Then,

export VISUAL=emacsclient

Edit away.

Note:

  • The versions of emacs and emacsclient must agree. If you have multiple versions of Emacs installed, make sure you invoke the version of emacsclient corresponding to the version of Emacs running the server.
  • If you start the server in multiple Emacs processes/frames (e.g., because (server-start) is in your .emacs), the buffer will be created in the last frame to start the server.
Rich
Chris Conway
Oops. I have /etc/alternatives pointing to different versions for emacs and emacsclient. Updating the alternative for emacsclient fixed the above.
Chris Conway
`export EDITOR="emacsclient --alternate-editor=emacs --no-wait +%l %f"` is worth mentioning.
J.F. Sebastian
+3  A: 

There's emacsclient, gnuserv, and in Emacs 23, multi-tty that are all useful for this. Actually I think in Emacs 23, emacsclient has all of the interesting functionality of gnuserv.

jfm3
A: 

Not entirely true. ansi-term can run an emacs fine (although I usually run mg for commit logs, in the rare event I don't commit from emacs directly). eshell can also run an emacs if you start a screen first and run it from within there.

jrockway
A: 
killdash10
A: 

I wanted to do something similar for merging in an emacs shell via mercurial. Thanks to the posters here, i found the way. two steps:

  1. add: (start-server) in your .emacs file (remember to load-file after your change)

  2. in your hgrc:

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

T Collins