Reputation: 7766
If I have emacs running as a daemon on my system, I can connect to it easily using emacsclient. This I know. However, what I would like to know is, is there a way to tell emacs (not emacsclient) to behave like emacsclient if a daemon is already running?
e.g.
# emacs daemon is not running
emacs # should start a new frame
# ...
# emacs daemon IS running
emacs # should actually behave like emacsclient, i.e. connect to my daemon
Is there anything I can do to my init.el to replicate this kind of behaviour?
Upvotes: 4
Views: 1803
Reputation: 6418
Here's what I do. It's like the solution by @philippe-carpin, in the sense that it's a script that does multiple steps:
In all cases you can pass filename(s) that will be opened.
In addition, my script only tries to run a piece of elisp just once and if there's no daemon it will not start an emacs process to run that elisp. So it should be slightly faster.
get_emacs_daemon_state () {
emacs_get_state_script='(if (> (length (frame-list)) 1) "daemon-with-frame" "daemon-no-frame")'
emacsclient -e "$emacs_get_state_script" -a "echo no-daemon" 2>/dev/null |
tr -d \" | cut -d' ' -f1
}
state=$(get_emacs_daemon_state)
create_frame_arg=""
if [[ $state = no-daemon ]]; then
emacs --daemon
fi
if [[ $state != daemon-with-frame ]]; then
create_frame_arg="--create-frame"
fi
client="emacsclient --no-wait $create_frame_arg"
if [[ $# -gt 0 ]]; then
# open files passed as arguments
$client "$@"
else
# if no file passed, we just focus the frame
$client --eval "(select-frame-set-input-focus (selected-frame))" >/dev/null
fi
Upvotes: 0
Reputation: 177
You can do the -a ''
thing with emacsclient
but what I do and a lot of people do is to have some kind of script that basically does what emacsclient ''
does in multiple steps.
My version is something like this BASH script: The part you are interested in is the ensure-server-is-running
function. This is the "main function" of the script, what follows is the ensure-server-is-running
function and the rest is there after that for your curiosity but does not contribute to answering the question.
#!/bin/bash
# ec.sh
#
# [function definitions]
#
ensure-server-is-running
ensure-frame-exists
focus-current-frame
Ensuring that the server is running
# ec.sh function definition
# From https://emacs.stackexchange.com/a/12896/19972
function server-is-running() {
emacsclient -e '(+ 1 0)' > /dev/null 2>&1
}
function ensure-server-is-running(){
if ! server-is-running ; then
echo "Need to start daemon, press enter to continue, C-c to abort"
read
emacs --daemon
fi
}
And the other two function:
# ec.sh function definition
# From https://superuser.com/a/862809
function frame-exists() {
emacsclient -n -e "(if (> (length (frame-list)) 1) 't)" 2>/dev/null | grep -v nil >/dev/null 2>&1
}
function ensure-frame-exists() {
if ! frame-exists ; then
emacsclient -c --no-wait
fi
}
# From https://emacs.stackexchange.com/a/54139/19972
function focus-current-frame() {
# Doesn't work a frame exists and is in a terminal
emacsclient --eval "(progn (select-frame-set-input-focus (selected-frame)))"
}
focus-current-frame
is something that will make the OS put you in the current Emacs Frame. This is the most important feature. For me I insert an adapted version of this into a MacOS Automator app. When there is an emacs GUI frame, doing Spotlight Search "EmacsC" (usually just typing the "e" is enough), puts me in my emacs window. It's a super fast way of switching to an emacs window.
Upvotes: 0
Reputation: 13422
I don't think so, but can you achieve a similar effect by using emacsclient
with an empty string as the the --alternate-editor
option? From http://www.gnu.org/s/libtool/manual/emacs/emacsclient-Options.html#emacsclient-Options:
-a command
--alternate-editor=command
. . . As a special exception, if command is the empty string, then emacsclient starts Emacs in daemon mode and then tries connecting again.
Upvotes: 11