Reputation: 315
It is so confusing that emacsclient said it can't find socket just after executing emacs --daemon
in bash:
$ ps aux | grep emacs
shiangro 1744 0.0 0.0 2432784 604 s000 S+ 1:03下午 0:00.00 grep emacs
$ /usr/local/bin/emacs --daemon
("emacs")
Starting Emacs daemon.
Restarting server
$ /usr/local/bin/emacsclient -t
emacsclient: can't find socket; have you started the server?
To start the server in Emacs, type "M-x server-start".
emacsclient: No socket or alternate editor. Please use:
--socket-name
--server-file (or environment variable EMACS_SERVER_FILE)
--alternate-editor (or environment variable ALTERNATE_EDITOR)
I have this settings in my .emacs:
(server-start)
(setq server-socket-dir "~/.emacs.d/server")
and it works,the server file ~/.emacs.d/server/server
was just there,but emacsclient say it can't find socket,so annoying that I have to tell him the socket file using the -s
option.
I find this thorny problem while I want let emacs runing as a daemon after everytime rebooting(start) systerm by using crontab's ◎reboot
special strings.
In this case ,cron successfully started the emacs server and the server file ~/.emacs.d/server/server
was also there, but later when I started a terminal and tried to emacsclient -t
,it failed and complained can't find socket file!
Although I can bypass this problem by using -s ~/.emacs.d/server/server
everytime I excute emacsclient,or alias emacsclient as emacsclient -s ~/.emacs.d/server/server
,but is ther a better way to comfort my heart?
Backgroud:
system: Mac OS X 10.9.2
emacs: GNU Emacs 24.3.1 installed by homebrew
Upvotes: 16
Views: 17013
Reputation: 2026
On macOS
, the emacs
socket name is calculated as follows:
export EMACS_SOCKET_NAME="${TMPDIR}/emacs$(id -u)/server"
According to
emacsclient
,
the environment variable EMACS_SOCKET_NAME
may be set to override the
default. However, this does not seem to work in a Homebrew environment. I
have this in my .bashrc
which works for me:
export EDITOR="emacsclient --tty"
export ALTERNATE_EDITOR="emacs --no-window-system"
case "$(uname -s)" in
# ...
Darwin*)
export EMACS_SOCKET_NAME="${TMPDIR}/emacs$(id -u)/server"
export EDITOR="${EDITOR} --socket-name ${EMACS_SOCKET_NAME}"
;;
esac
Upvotes: 2
Reputation: 1916
emacsclient only finds the emacs server if I run emacs
from the command line. If I run emacs from the Ubuntu launcher then emacsclient
fails to connect to the server.
If you want to use the Emacs daemon instead of the server, define the two environment variables
export ALTERNATE_EDITOR=""
export EDITOR=emacsclient
You can add these environment variables in either ~/.bashrc
or ~/.profile
.
If the ALTERNATE_EDITOR environment variable is empty, then Emacs will run its daemon and connect to it.
Upvotes: 3
Reputation: 30309
Finding the server socket file is the tricky bit, you can use lsof
to find it, and then a bit of grep
-ing to extract the socket path/filename.
lsof -c emacs | grep server | grep -E -o '[^[:blank:]]*$'
Or on OSX when you expect to be running /Application/Emacs
you'd change the command name lsof
is looking for with -c Emacs
. ie.
lsof -c Emacs | grep server | grep -E -o '[^[:blank:]]*$'
You could use cut
instead of the messy filtering grep
(searching for non-blanks until the line end [^[:blank:]]*$
)
lsof -c Emacs | grep server | cut -c70-
Better yet, squish the interspacing and use cut
's field chopping.
lsof -c Emacs | grep server | tr -s " " | cut -d' ' -f8
Now that you have the socket (or it's empty) you can do a conditional start on emacsclient
, ie.
#!/bin/bash
socket_file=$(lsof -c Emacs | grep server | tr -s " " | cut -d' ' -f8)
if [[ $socket_file == "" ]]; then
# Just run Emacs (with any arguments passed to the script)
# It would be a good idea to parse the arguments and clean/remove
# anything emacsclient specific.
# (ie. -e should be --eval for emacs)
# note that emacsclient doesn't fix these args for you either
# when using -a / --alternate-editor
emacs $@ &
# or on OSX
/Application/Emacs.app/Contents/MacOS/Emacs $@ &
else
emacsclient $@ -n -s $socket_file
fi
Upvotes: 17
Reputation: 493
Since you've done:
/usr/local/bin/emacs --daemon
the server is already started. So, you don't actually need the:
(server-start)
(setq server-socket-dir "~/.emacs.d/server")
in your .emacs. When you follow that approach, the server is placed in /tmp/emacs502 (or maybe some other number). On linux, emacsclient doesn't seem to have trouble finding it there (in that case I'm seeing /tmp/emacs1920), and so "emacsclient -nw" works. I'm trying it on OSX using HomeBrew, as you are, and I find I have to connect using:
emacsclient -nw -s /tmp/emacs502/server
(If you used --deamon=name, then you would use "name" instead of "server" in that last line.)
Upvotes: 11
Reputation: 2350
I think emacsclient
can look for special file server
in standard path only, e.g. in /tmp/emacs1000
. If you change this parameter server-socket-dir
, then you should tell about it to emacsclient
by key -s
.
Upvotes: 1