11

How can I make emacsclient -a '' -n create a new frame only if there isn't one already?

The problem with the -c flag is that it creates a new frame every time. The problem without it is that if there is no frame open it will open in the command line.

If I can check if there is an open Emacs frame from the shell, I can call with or without -c depending on that to get the behavior I want. I tried:

$ emacsclient -a '' --eval '(frames-on-display-list)'
(#<frame F1 0xba2740>)

I always get the same result.

I could use temporary files or pgrep, but those approaches are very error prone.

This is similar to this question, but it is not a duplicate, since the OP there was satisfied with having to have a frame open before calling emacsclient.

3

I ended up making this script based on this

#!/bin/bash -e

if [[ "$DISPLAY" ]]; then
        frame=`emacsclient -a '' -e "(member \"$DISPLAY\" (mapcar 'terminal-name (frames-on-display-list)))" 2>/dev/null`
        [[ "$frame" == "nil" ]] && opts='-c' # if there is no frame open create one
        [[ "${@/#-nw/}" == "$@" ]] && opts="$opts -n" # don't wait unless we've asked to run in a terminal
else
        opts='-nw'
fi

exec emacsclient -a '' $opts "$@"

If there is no display it opens with -nw. If $DISPLAY is set it looks for frames in that display to see if it needs to make a new one.

Edit: I've modified it so that you can manually specify -nw if you want to open in a terminal even if there is a display.

0

You can use:

emacsclient -s server_name -e '(+ 1 0)' >/dev/null 2>&1

to check if the Emacs server "server_name" is already running. If the command returns exit code 0, it is running. If so, just use the emacsclient command:

emacsclient -s server_name -n file_name.txt

If it is not running, you can open a new Emacs server with for example:

emacs --eval '(setq server-name "server_name")' --eval '(server-start)' file_name.txt &
  • But that way once you close the shell you'll kill the server, right? The emacsclient -a '' starts emacs --daemon if necessary, which persists even if you close the shell. – spelufo Jun 4 '15 at 15:18
  • @spelufo The server is not killed by killing the shell. Note the & at the end of the command; it means to run the server as a background process.. – Håkon Hægland Jun 4 '15 at 15:56
  • Which forks it to the background of the current shell. It is not killed when you get back your shell, but it IS killed when you close that shell completely (C-d). – spelufo Jun 4 '15 at 16:09
  • The daemon keeps running even if you close all your terminals. It would only keep on running if server-start starts the server as daemon process. What do you get if you start emacs that way and then close all emacs and terminals, then open a new terminal and run pgrep emacs? – spelufo Jun 4 '15 at 16:10
  • @spelufo Actually it is still running after C-d. I tried this now using gnome-terminal on Ubuntu 14.10.. I think your are referring to a running instance after closing all Emacs frames? Then, that would require a daemon process yes.. – Håkon Hægland Jun 4 '15 at 16:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.