tags:

views:

1265

answers:

5

How can I get emacs 23 working nicely in multi-tty mode on OS X?

I've added (server-start) to my .emacs, and have discovered that running /Applications/Emacs.app/Contents/MacOS/bin/emacsclient -n ~/myfile.txt will open it in my emacs.app, but it doesn't bring emacs to the front.

So, how can I get emacs.app to come to the front when I run emacsclient? (I've considered writing a function that puts the current frame to the front every time a file is opened, or maybe writing an Applescript to do a similar job that could be called at the same time as emacsclient)

Is the emacsclient within emacs.app the best one to use? I assume I'll write an alias to it if so, but it seems weird to be using that rather than something in /usr/local/bin

Has anyone got any other tips or examples of getting this working?

+1  A: 

The AppleScript would be simple:

tell app "Emacs" to activate
Graham Lee
Thanks, this works great. Just to expand. I've aliased emacs to:'osascript -e '\''tell app "Emacs" to activate'\'';/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -n'
Singletoned
+5  A: 

Perhaps this would work, just calling raise-frame when the client attaches:

(add-hook 'server-visit-hook 'call-raise-frame)
(defun call-raise-frame ()
  (raise-frame))

(It happens to be redundant on my Linux machine.)

Trey Jackson
This doesn't work for me. I put it in .emacs and evaluated it but it doesn't appear to have any effect.
Singletoned
If you're up for it, you can try debugging this. Step one, in Emacs, move the point inside the 'call-raise-frame defun and do M-x edebug-defun. Then connect using emacsclient. Emacs should enter the debugger - which should show your .emacs (or whatever buffer contains the 'call-raise-frame) with a little arrow next to the (raise-frame) line. And the mode line should have [] around it (indicating you're in debugging). At which point you should be able to do M-x raise-frame. Of course, in Linux every action in the debugger raises the frame, reducing the usefulness of debugging.
Trey Jackson
I can confirm that this does work with 23.0.92 on OS X
Hamza Yerlikaya
@Hamza, thanks.
Trey Jackson
I've had a play with this and tried to debug it. It appears that raise-frame doesn't work at all on my version of Emacs 23 (next-step compiled from source about 20 minutes ago). I can't work out why it doesn't work. I even have server-raise-frame set to t.
Singletoned
Doesn't work for me with Emacs.app 23 compiled yesterday on Mac OSX :|
simao
Works for me (current build of CocoaEmacs). Make sure you're using the emacsclient binary from inside the application bundle.
jkp
A: 

I have an alias from emacs to

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

If you are annoyed by the fact that it opens a new frame (window) for each file -- add

(setq ns-pop-up-frames nil)

to your .emacs and fixed.

mrflip
A: 

I define this function in my .emacs

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

Then use this to raise the frame:

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

I recommend doing it this way instead of calling osascript. It seems to respond faster (significantly faster sometimes) than using osascript.

pheaver
A: 

To expand on the answers given by Trey Jackson and the comment by Singletoned: I have the following in my .emacs file

;;;
;;; 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)

And in my shell init file I have the following aliases:

alias e='emacsclient'      # edit
alias enw='emacsclient -n' #edit (no wait)

Now I can have a shell open side-by-side with my CocoaEmacs instance and use the two seamlessly together. I can call the editor "inline" with my current terminal flow by using the e alias and once I finish editing in emacs focus will be returned to the calling terminal.

jkp