Category Archives: emacs

Reading these posts, you can probably tell that I really, really like the Emacs text editor.

View my Emacs configuration.

Check out Planet Emacsen to read other Emacs geeks’ blogs. For all things Emacs, check out the EmacsWiki.

New to Emacs? Start here:

2016-05-23 Emacs News

Links from reddit.com/r/emacs, /r/orgmode, Hacker News, planet.emacsen.org, Youtube, the changes to the Emacs NEWS file, and emacs-devel.

Past Emacs News round-ups

2016-05-16 Emacs News

Links from reddit.com/r/emacs, /r/orgmode, Hacker News, planet.emacsen.org, Youtube, the changes to the Emacs NEWS file, and emacs-devel.

Past Emacs News round-ups

2016-05-09 Emacs News

Links from reddit.com/r/emacs, /r/orgmode, Hacker News, planet.emacsen.org, Youtube, the changes to the Emacs NEWS file, and emacs-devel.

Past Emacs News round-ups

2016-05-02 Emacs News

Links from reddit.com/r/emacs, /r/orgmode, Hacker News, planet.emacsen.org, Youtube, the changes to the Emacs NEWS file, and emacs-devel.

Past Emacs News round-ups

2016-04-25 Emacs News

Links from reddit.com/r/emacs, /r/orgmode, Hacker News, planet.emacsen.org, Youtube, the changes to the Emacs NEWS file, and emacs-devel.

Past Emacs News round-ups

Keep Emacs alive through X crashes by running it in the background with –daemon

I periodically have to kill and restart my X server when it freezes. I probably have the wrong configuration, since it starts off in low-graphics mode until I manually restart the graphical login manager (I’m using sddm). Anyway, since it’s been hard to debug and fix that issue, I figured I’d address the part that really bugs me when I restart X: dealing with ungraceful Emacs exits. M-x recover-session does a decent job of restoring my modified files and I usually remember to call it from the scratch screen, but sometimes I forget, and then I end up losing changes.

I started taking advantage of the fact that I used (server-start) to enable other Emacs clients to connect to the same process. Whenever I needed to restart X, I’d first switch to a console, use emacsclient -c to connect to Emacs, and use M-x save-buffers-kill-emacs to close my Emacs neatly. Still, starting my Emacs from X meant that I had to restart Emacs each time I restarted X.

It turns out that you can run Emacs as a background process with emacs --daemon and then connect to it with emacsclient -c. When I did that, though, the emacsclient frame didn’t have my color theme applied. This after-make-frame-functions addition fixes that:

(defun my/setup-color-theme ()
  (interactive)
  (color-theme-solarized-dark)
  (set-face-foreground 'secondary-selection "darkblue")
  (set-face-background 'secondary-selection "lightblue")
  (set-face-background 'font-lock-doc-face "black")
  (set-face-foreground 'font-lock-doc-face "wheat")
  (set-face-background 'font-lock-string-face "black")
  (set-face-foreground 'org-todo "green")
  (set-face-background 'org-todo "black"))
(add-hook 'after-make-frame-functions
          (lambda (frame)
            (select-frame frame)
            (my/setup-color-theme)))

Once I got emacs --daemon and emacsclient -c working to my satisfaction, I decided to go one step further and get it to run automatically when I start my computer. I tried the init script at https://www.emacswiki.org/emacs/EmacsAsDaemon . My Linux install uses systemd, so enabling the init script resulted in a message about a missing service file. I removed the init script and created this ~/.config/systemd/user/emacs.service instead:

[Unit]
Description=Emacs: the extensible, self-documenting text editor

[Service]
Type=forking
ExecStart=/usr/local/bin/emacs --daemon
ExecStop=/usr/local/bin/emacsclient --eval "(progn (setq kill-emacs-hook 'nil) (kill-emacs))"
Restart=always
TimeoutStartSec=0

[Install]
WantedBy=default.target

and then I ran these commands as my regular user account:

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

Then I changed the emacs in my ~/.xsession to emacsclient -c, so that a new X session would connect to the existing session instead of starting a new one. That way, Emacs automatically started as my user whenever I restarted the computer, and I connected to that process when I started X.

Still, restarting X caused the Emacs daemon to crash. This is a GTK-related bug which emacs --daemon warns you about. I recompiled Emacs using ./configure --with-x-toolkit=lucid; make; make install. It seems to work fine now; I can ungracefully restart X, and my Emacs stays the same. Bonus: because Emacs gets initialized when I start my computer and all I need to do is connect to that process, when I log in, it feels like Emacs starts up really quickly.

Final touches: I noticed that TRAMP couldn’t find my SSH keyring, so it got stuck waiting for my passphrase when I tried running remote scripts in Org Babel like so:

#+begin_src sh :dir [email protected]:~
perl library-new.pl Business
#+end_src

Because my SSH socket looks like /tmp/ssh-BLAHBLAHBLAH/agent.PROCESSID, the SSH_AUTH_SOCK setting (Environment=SSH_AUTH_SOCK=%t/keyring/ssh) described on EmacsWiki didn’t work for me. This snippet from https://github.com/nhoffman/.emacs.d/blob/master/init.org worked, though.

(defun my/ssh-refresh ()
  "Reset the environment variable SSH_AUTH_SOCK"
  (interactive)
  (let (ssh-auth-sock-old (getenv "SSH_AUTH_SOCK"))
    (setenv "SSH_AUTH_SOCK"
            (car (split-string
                  (shell-command-to-string
                   "ls -t $(find /tmp/ssh-* -user $USER -name 'agent.*' 2> /dev/null)"))))
    (message
     (format "SSH_AUTH_SOCK %s --> %s"
             ssh-auth-sock-old (getenv "SSH_AUTH_SOCK")))))
(my/ssh-refresh)

Also, emacs --daemon didn’t pick up the default browser I’d configured in KDE. Opening URL links from Org Mode started a separate Chromium process instead of using Google Chrome. I fixed that by switching from browse-url-default-browser to browse-url-generic, like so:

(setq browse-url-generic-program "google-chrome")
(setq browse-url-browser-function 'browse-url-generic)

Let’s see how this works!