10

Since emacsclient can handle long package loading time proerly, I really want to keep at least one emacs process, and most of the time only one emacs process, open as a background process and better hide GUI.

Right now I defined the following function in .bashrc:

emc () 
{ 
    if [[ $# -eq 0 ]]; then
        emacs --eval "(suspend-frame)" &
        return
    fi
    args=($*);
    setsid emacsclient -c -e "(find-file \"${args[*]}\")"
}

And also have the following line in .bashrc:

emc

So everytime I open up a shell, I will end up having a new emacs process.

The problem is I will have many additional unnecessary emacs process after opening up many shells. However, I only want to maintain one single emacs process all the time from startup better hide GUI.

  • 5
    I'm not familiar with the practice of `emacs --eval "(suspend-frame)"` rather than `emacs --daemon` (https://www.emacswiki.org/emacs/EmacsAsDaemon). Is there a reason you choose not to invoke emacs as a daemon? You could use something like `pgrep -U \`whoami\` emacs || emacs --daemon &` to ensure that it is running. – ebpa Jan 16 '17 at 06:22
  • Check out [MJ Wall's scripts](http://mjwall.com/blog/2013/10/04/how-i-use-emacs/) for using Emacs client. – Tianxiang Xiong Jan 19 '17 at 21:26

3 Answers3

14

I do this by starting an emacs daemon when I login. Where you put this command depends on your desktop manager. I use i3, which is configured to run a script on login that includes the following:

emacs --daemon &

With that, emacs is always running in the background, and I open a new client with emacsclient -c -n, bound to a convenient keybinding in the window manager. If you're working in a terminal, you only need a simple alias like alias emc='emacsclient', possibly with -n, -c or -t arguments, depending on how you use it.

Do check out the options for emacsclient in the manual: ((emacs) emacsclient Options, accessible from Emacs by C-h r m emacsclient options <enter>). You can use the -a flag to automatically start an emacs daemon if it isn't running already, and -c or -t to open a new frame or terminal client, rather than reusing an existing one (in the same session):

‘-a COMMAND’
‘--alternate-editor=COMMAND’
     Specify a command to run if ‘emacsclient’ fails to contact Emacs.
     This is useful when running ‘emacsclient’ in a script.

     As a special exception, if COMMAND is the empty string, then
     ‘emacsclient’ starts Emacs in daemon mode (as ‘emacs --daemon’) and
     then tries connecting again.

‘-c’
‘--create-frame’
     Create a new graphical “client frame”, instead of using an existing
     Emacs frame.  See below for the special behavior of ‘C-x C-c’ in a
     client frame.  If Emacs cannot create a new graphical frame (e.g.,
     if it cannot connect to the X server), it tries to create a text
     terminal client frame, as though you had supplied the ‘-t’ option
     instead.

‘-t’
‘--tty’
‘-nw’
     Create a new client frame on the current text terminal, instead of
     using an existing Emacs frame.  This behaves just like the ‘-c’
     option, described above, except that it creates a text terminal
     frame (*note Non-Window Terminals::).
Tyler
  • 21,719
  • 1
  • 52
  • 92
4

If you are using an operating system that uses the systemd service manager (which nowadays includes most GNU/Linux distributions), then the best solution might be to use systemd to start your Emacs daemon on boot. You can do this by creating a file $HOME/.config/systemd/user/emacs.service with the following contents:

[Unit]
Description=Emacs text editor
Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/

[Service]
Type=simple
ExecStart=/usr/bin/emacs --fg-daemon
ExecStop=/usr/bin/emacsclient --eval "(kill-emacs)"
Environment=SSH_AUTH_SOCK=%t/keyring/ssh
Restart=on-failure

[Install]
WantedBy=default.target

Then you should start the service and set it to automatically start for all future boots:

$ systemctl enable --user emacs
$ systemctl start --user emacs

You can now use emacsclient as usual. If you normally run it with the -n, -c, or -t options, you can set an alias in your shell. You might also want to set the EDITOR and/or VISUAL environment variables to run emacsclient the way you like it. For example, in Bash, you might add the following to your .bashrc file:

alias emc="emacsclient -c"
export VISUAL="emacsclient -c"
export EDITOR="emacsclient -t"

If you ever need to stop the Emacs daemon, you can do this as follows:

$ systemctl stop --user emacs

And if you want to permanently stop it from running on boot:

$ systemctl disable --user emacs
Psychonaut
  • 141
  • 3
  • 1
    perhaps this link to EmacsWiki should be acknowledged: [EmacsAsDaemon](https://www.emacswiki.org/emacs/EmacsAsDaemon) – HongboZhu Feb 26 '19 at 11:29
  • @psychonaut - can you please advise why you choose to use `--fg-daemon` instead of background daemon? Thanks! – malcook Jun 30 '20 at 23:56
  • @malcook: The [systemd documentation](https://www.freedesktop.org/software/systemd/man/systemd.service.html) indicates that `Type=simple` is generally preferred over `Type=forking` for long-running services. I've been using this setup for emacs for years and so if there's any disadvantage to it, it's not been apparent to me. – Psychonaut Jul 01 '20 at 07:23
0

The way I do it is pretty similar to a previous answer, by having an alias defined in my .bashrc for emacs --daemon

alias ds="emacs --daemon"

Apart from this, I have a key-board shortcut ctrl-alt-E set to emacsclient -c. When I want to start working on emacs I open a terminal and type ds and call up each emacsclient instance with my shortcut.

Hope this helps someone.