Emacs 23, OS X, multi-tty and emacsclient

让人想犯罪 __ 提交于 2019-11-30 21:24:26

The AppleScript would be simple:

tell app "Emacs" to activate

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.

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

Some of the proposed solutions suggest using 'raise-frame'. That will raise the emacs frame, but it will not give it focus. When you start emacs from a terminal window, emacs will still be beneath the terminal window because the terminal window retains the focus. I use 'select-frame-set-input-focus' to raise and give focus.

Examples:

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

I prefer to run separate instance of emacs, so when I exit with "^X^C" I don't lose all windows. To accomplish this I have a shell script:

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

I use something like this in my .emacs to only call server-start if the server isn't already running:

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

Then a couple of changes to my .zshrc so that I can mindlessly run ec as my editor command from the shell:

# 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'

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.

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.

fwiw, here's my solution:
step 1: create a script at /usr/local/bin/emacs with the following contents:

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

step 2. make it executable via: chmod +x /usr/local/bin/emacs

step 3. in your ~/.emacs file add the following:

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

explanation:

If the emacs script at /usr/local/bin/emacs is invoked and there's no emacs server currently running, the emacsclient will invoke the alternate editor, which in this case is the Emacs editor (/Applications/Emacs.app/Contents/MacOS/Emacs).

In step 3, the initial call to (ns-raise-emacs) seems to be necessary for the initial Emacs window to show in front of everything else.

The (add-hook 'server-visit-hook 'raise-frame) is so that subsequent frames show up in front of everything else.

Alternatively, if you prefer that all Emacs frames show up in front of everything else each time you invoke emacs from the command line, you can uncomment the (add-hook 'server-visit-hook 'ns-raise-emacs) line.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!