9

In my setup, I have several (GNU) Emacs instances running simultaneously on my local machine, one for each project or task that I'm currently working on.

I would like to be able to open buffers in an already running Emacs instance, for example by a command like

$ emacs file.txt

The typically suggested solution to this is to run Emacs in server mode. However, this conflicts with my use of multiple Emacs instances, as I understand that by default only a single emacsclient can be active at any time.

How can I open files as buffers in existing (possibly multiple) Emacs instances? The final goal is to open the file in the Emacs instance that is in the current workspace (Compiz), or to create such an instance if it doesn't already exist.

4
  • I edited the title a bit. It seems you're asking about how to have multiple Emacs severs running simultaneously. Please correct me if I got it wrong.
    – Malabarba
    Sep 30, 2014 at 10:29
  • 1
    The answers here are likely to be of interest: emacs.stackexchange.com/q/41/93
    – nispio
    Sep 30, 2014 at 10:31
  • If that's the case I'll remove my answer, because I thought he was asking for different clients in different workspaces. Sep 30, 2014 at 10:31
  • @Malabarba I'm honestly not sure! The reason I put the question more broadly is because I don't know whether answering the question "How can I have multiple Emacs servers?" is the right approach to answer my problem "How can I having multiple Emacs instances and open files as buffers in one of them from the command line?". I do see however, that achieving to have multiple servers running could be a potential way of solving my problem. Sep 30, 2014 at 12:13

3 Answers 3

6

This answer has the general method, though the question was different than yours.

You can use emacs --daemon=workspaceN combined with emacsclient -s workspaceN to have an emacs daemon on workspace N. If you need multiple, simply do workspace1, workspace2, etc. Note that the daemon name is entirely arbitrary and you can use whatever naming scheme you like.

Determining which workspace you're in will likely be more difficult, and I do not know how to determine it. If you have an environment variable then a shell alias or function will likely do the trick (if you only want to open things via shell).

3
  • 1
    To add to your answer, server-name enables doing the same thing without having to use an Emacs daemon. Just set it before running (server-start). It's possible to set it to a value depending on the value of command-line-args, to simulate something similar to the --daemon invocation
    – Sigma
    Sep 30, 2014 at 15:18
  • 1
    @Sigma Thanks! While the --daemon solution does work in principle, I'm now running into some trouble with the last part of my question, "... or to create such an instance if it doesn't already exist." I can either pass -c to emacsclient or not, but there doesn't seem to be something in between (which I would need). Could you elobarte on your solution? How can I set server-name before running server-start (set-variable doesn't do the trick as the variable doesn't yet exist). An init.el solution, setting server-name depeding on command line args, would be just what I'm looking for. Sep 30, 2014 at 16:06
  • (set-variable 'server-name "foo") worked for me. Did you remember to quote server-name? Also: you can use server-running-p to check if the server is already running. Oct 1, 2014 at 13:42
0

As far as I know, you can use Emacs in server mode to get what you are looking for. I often have multiple emacsclient instances in different workspaces, which, for instance, enables me to easily share buffers between them.

Here's what I do:

  • start emacs --daemon in my .xinitrc
  • run emacsclient -c in workspace 2
  • run emacsclient -t in workspace 1 (when I usually keep a fullscreen tmux)

I can edit buffers in each instance, moving quickly from term to GUI and viceversa.

You can find more approaches in Start two separate emacs daemons for console and GUI

2
  • This answers a different question: accessing the same Emacs instance from different locations. But the question is about having multiple Emacs instances. Sep 30, 2014 at 13:01
  • 1
    Yes, topic title was changed after my answer so I thought the question was about multiple emacsclient. Sorry. Sep 30, 2014 at 13:04
0

Top answer is right; the way I do it is somewhat more involved and uses systemd, if don't mind that then you can use my implementation. I use two daemons, one with a minimal configuration to only use in the terminal, and a fully configured PDE for development.

My .service files are as follows (place these in ~/.config/systemd/user

emacsq.service


[Unit]
Description=Emacs: the extensible, self-documenting text editor
Documentation=man:emacs(1) info:Emacs

[Service]
Type=forking
ExecStart=/usr/local/bin/emacs -nw --no-splash --init-directory=~/.q.emacs --daemon="shell"
ExecStop=/usr/local/bin/emacsclient --eval "(progn (setq kill-emacs-hook nil) (kill-emacs))"
Restart=on-failure
Environment=DISPLAY=:%i
TimeoutStartSec=0

[Install]
WantedBy=default.target[Unit]
Description=Emacs: the extensible, self-documenting text editor
Documentation=man:emacs(1) info:Emacs
After=graphical-session.target

Notice that here i pass the argument

--init-directory=/path/to/other/emacsdir/ 

this is the directory where my minimal configuration is, this may or may not be what you want.

emacsd.service

[Service]
Type=forking
ExecStart=/usr/local/bin/emacs --daemon=gui
ExecStop=/usr/local/bin/emacsclient --eval "(progn (setq kill-emacs-hook nil) (kill-emacs))"
Restart=on-failure
Environment=DISPLAY=:%i
TimeoutStartSec=0

[Install]
WantedBy=default.target

then, i use the following bash functions to call them as i need them

vic(){ # use the gui, but open the file in a new window
    emacsclient -c $1 -s "gui" &
}

vis(){ # use the gui, but use an existing window if it exists
    emacsclient -r -c $1 -s "gui" &
}

fis(){ # open the target file on the terminal where am at
    emacsclient -nw -s "shell" $1
}

vzf(){ # save as vis, but first use fuzzy finder to search for a file (requires fzf)
    vis $( fzf )
}

then enable and start the services

systemctl --user enable --now emacsq.service

and

systemctl --user enable --now emacsd.service

this answer builds on the top selected answer. I hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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