How to launch GUI Emacs from command line in OSX?
MacosEmacsCommand LineMacos Problem Overview
How do I launch GUI Emacs from the command line in OSX?
I have downloaded and installed Emacs from http://emacsformacosx.com/.
I'll accept an answer fulfilling all of the following criteria:
- The emacs window opens in front of my terminal window.
- Typing "emacs" launches a GUI Emacs window. Finding files in that window will default to looking in the directory from where I started Emacs.
- Typing "emacs foo.txt" when foo.txt exists launches a GUI Emacs window with foo.txt loaded.
- Typing "emacs foo.txt" when foo.txt does not exist launches a GUI Emacs window with an empty text buffer named "foo.txt". Doing ^X^S in that buffer will save foo.txt in the directory from where I started Emacs.
Macos Solutions
Solution 1 - Macos
Call the following script "emacs" and put it in your PATH
somewhere:
#!/bin/sh
/Applications/Emacs.app/Contents/MacOS/Emacs "$@"
That covers #2, #3, and #4.
For #1, put this somewhere in your .emacs file:
(x-focus-frame nil)
The emacsformacosx.com site now has a How-To page, which is where the top snippet came from. There's more info there about running emacsclient
and hooking Emacs up to git mergetool
.
Solution 2 - Macos
In your shell, alias the command 'emacs' to point to the OSX emacs application
In my shell (running the default bash), I have the following (in my .bashrc)
alias emacs='open -a /Applications/Emacs.app $1'
Then, typing emacs on the command line starts the emacs application.
I would, however, recommend that you open a copy of emacs and just keep it up and running. If that's the case, and you want to load a file into an existing copy of emacs, you can use the emacsclient by placing the following in your .bashrc:
alias ec='/Applications/Emacs.app/Contents/MacOS/bin/emacsclient'
Then add the following to your .emacs file to start the emacs server (which receives the emacsclient calls)
;;========================================
;; start the emacsserver that listens to emacsclient
(server-start)
Then you can type
ec .bashrc
to load a copy of .bashrc into an existing emacs session!
Solution 3 - Macos
This improves on David Caldwell's answer by starting Emacs in the background:
#!/bin/sh
$(/Applications/Emacs.app/Contents/MacOS/Emacs "$@") &
As stated in the other answer, this covers #2, #3, and #4. For #1, put this somewhere in your .emacs file: (x-focus-frame nil)
.
Note that the following does not work for me -- it does not start Emacs in a directory specified on the command line (e.g. emacs .
)
# NOT RECOMMENDED
#!/bin/sh
/Applications/Emacs.app/Contents/MacOS/Emacs "$@" &
Solution 4 - Macos
I assume you either:
- Start the emacs daemon on login
- Have (server-start) in your .emacs
- Don't mind having lots of separate copies of emacs running
If so, then I think this satisfies the original four criteria, plus one more:
> 1. The emacs window opens in front of my terminal window.
it will always open to the foreground (with x-focus-frame).
> 2. Typing "emacs" launches a GUI Emacs window. Finding files in that window will default to looking in the directory from where I started Emacs.
It will open an existing emacs window in dired mode.
> 3. Typing "emacs foo.txt" when foo.txt exists launches a GUI Emacs window with foo.txt loaded.
If emacs is already running and has a server, then it will open in the existing window and come to the foreground.
> 4. Typing "emacs foo.txt" when foo.txt does not exist launches a GUI Emacs window with an empty text buffer named "foo.txt". Doing ^X^S in that buffer will save foo.txt in the directory from where I started Emacs.
Correct.
One extra:
Control returns to the terminal session immediately after typing the command.
~/bin/emacs
#!/bin/bash
EMACSPATH=/Applications/Emacs.app/Contents/MacOS
# Check if an emacs server is available
# (by checking to see if it will evaluate a lisp statement)
if ! (${EMACSPATH}/bin/emacsclient --eval "t" 2> /dev/null > /dev/null )
then
# There is no server available so,
# Start Emacs.app detached from the terminal
# and change Emac's directory to PWD
nohup ${EMACSPATH}/Emacs --chdir "${PWD}" "${@}" 2>&1 > /dev/null &
else
# The emacs server is available so use emacsclient
if [ -z "${@}" ]
then
# There are no arguments, so
# tell emacs to open a new window
${EMACSPATH}/bin/emacsclient --eval "(list-directory \"${PWD}\")"
else
# There are arguments, so
# tell emacs to open them
${EMACSPATH}/bin/emacsclient --no-wait "${@}"
fi
# Bring emacs to the foreground
${EMACSPATH}/bin/emacsclient --eval "(x-focus-frame nil)"
fi
Solution 5 - Macos
On Mountain Lion, I am using Yamamoto Mitsuharu's port https://github.com/railwaycat/emacs-mac-port with the following alias:
alias emacs=/Applications/Emacs.app/Contents/MacOS/Emacs
and it satisfies all of your criteria.
Solution 6 - Macos
Just built emacs with homebrew package manager according to this guide: http://www.emacswiki.org/emacs/EmacsForMacOS with brew install --cocoa emacs After that one should launch the .app version to get gui, which in my case was /usr/local/Cellar/emacs/24.3/Emacs.app/Contents/MacOS/Emacs
Solution 7 - Macos
Further improving on David James' response the following works for me:
Per instructions to open a file from a terminal found at http://www.emacswiki.org/emacs/EmacsForMacOS#toc20
open -a /Applications/Emacs.app <file-name>
combining this with David Jame's response I've created the following emax bash script and placed it in my path at ~/bin
#!/bin/bash
(open -a /Applications/Emacs.app "$@") &
Caveat: in order to get emacs to open the current directory in Dired by name mode, you need to use
emax .
Environment:
- OS X Yosemite Version 10.10.2
- GNU Emacs 24.4.2 (x86_64-apple-darwin14.0.0, NS apple-appkit-1343.14) of 2014-11-13
Solution 8 - Macos
Simple solution...
A lot of very complex solutions to this problem are posted here. That's fair because it seems non-trivial.
However, this solution works really well for me.
ec() {
emacsclient -n $@ 2> /dev/null
if [[ $? == 1 ]]; then
open -a Emacs.app -- $@
fi
}
Usage
ec file [...]
Let's unpack what's happening:
- pass all the
ec
arguments to emacsclient and don't (-n
) wait for emacs before continuing.- If Emacs is already running, we're all done and you're editing.
- swallow up the error message posted by emacsclient when there's no emacs running. (
2> /dev/null
) - Manually handle the exit code
1
([[ $? == 1 ]]
)- open Emacs.app and pass file arguments to it (paths will be correctly opened.)
- You're all done, and Emacs has opened your files.
Solution 9 - Macos
The other answers here didn't quite work for me. In particular, on my machine, the bash script
#!/bin/sh
/Applications/Emacs.app/Contents/MacOS/Emacs "$@"
always opens emacs in the home directory. To get it to open in the current working directory, I had to do
#!/bin/sh
/Applications/Emacs.app/Contents/MacOS/Emacs "$PWD/$@"
instead.
Solution 10 - Macos
Compile Emacs according to the following steps:
./configure --with-x --prefix=/usr
make
sudo make install
And your done! It may help to download and install XQuartz, but that's just my opinion.
Solution 11 - Macos
This is my script for open emacs/emacsclient on osx.
#!/bin/bash
# Ensure (server-start) is added in your emacs init script.
EMACS=/Applications/MacPorts/Emacs.app/Contents/MacOS/Emacs
EMACSCLIENT=/Applications/Macports/Emacs.app/\
Contents/MacOS/bin/emacsclient
# test if client already exsit.
$EMACSCLIENT -e "(frames-on-display-list)" &>/dev/null
# use emacsclient to connect existing server.
if [ $? -eq 0 ]; then
$EMACSCLIENT -n "$@"
# open emacs.app instead.
else
`$EMACS "$@"` &
fi
Solution 12 - Macos
In all of the above when using "open" - make sure you use the "--args" option
Do not do this:
alias emacs='open -a /Applications/Emacs.app $1'
Instead this:
alias emacs='open -a /Applications/Emacs.app --args $1'
the --args
option prevents "open" from consuming various options intended for Emacs.
Solution 13 - Macos
The top answer is good, but I wanted the emacs process to run in the background so I could still use my shell. This answer appeared to do what I wanted, but didn't start emacs in the right directory, meaning absolute paths were required (or hacks to append pwd
to the paths which wouldn't work in all cases). Furthermore, simply using &
meant that if I killed the terminal, emacs would also be killed.
I decided to use screen
and a bash function, and the following solution works for me on macOS 10.15.6 and emacs 26.2 installed with brew
:
function emacs() {
screen -d -m /Applications/Emacs.app/Contents/MacOS/Emacs "$@"
}
For the meaning of the -d -m
command line flags, they have a special meaning when used together and so can essentially be thought of as one command line flag. The explanation is in the manpage:
> Start screen in "detached" mode. This creates a new session but doesn't attach to it. This is useful for system startup scripts.
Solution 14 - Macos
open_emacs() {
num=$(ps aux | grep -E "[E]macs-x86_64-10_14 --|[e]macs --" | wc -l)
if [ $num -eq 0 ]; then
echo "## starting emacs"
# Run in a subshell to remove notifications and close STDOUT and STDERR:
(&>/dev/null emacsclient -t -q &)
fi
}
alias e="open_emacs"
Following line (&>/dev/null emacsclient -t -q &)
will start the emacs daemon if it is not running on the background.
- macOS may have defined the app name starting with
E
(ex:Emacs-x86_64-10_14.app
), based on that you can check whether theemacs
daemon running on the background or not.