The Way of Emacs

Why learn and use Emacs? This article covers two aspects:

  1. As a tool - guidance for new and experienced users of what is made possible by the packages and environment
  2. As a philosophy of freedom, minimalism, and longevity (yes, you read that right, minimalism)


1. Intro   ATTACH

I was an unbeliever once. Emacs? It is slow, kludgy, and does everything but edit text. This was indeed true in 1995. I couldn’t even open Emacs (Eight Megs and Constantly Swapping) on my Pentium with a massive 4MB of RAM. So for 20 years, I just didn’t understand what people saw.

Given the circumstances, I had a very simple text / console setup:

  • vim - with a slew of plugins to manage buffers, tiling, etc.
  • tmux or screen - to manage terminal multiplexing
  • tiling window manager - ion, xmonad, and finally awesomewm.
  • mail - used pine, alpine, and then sup
  • file management - terminal commands or midnight commander (clone of the venerable Norton Commander)
  • pdf - evince
  • note management - texts, zotero, polar bookshelf
  • messenger - weechat, pidgin, etc, etc.
  • video - vlc, mplayer
  • music - audacious
  • shell - bash and zsh
  • reading - calibre

But emacs had a killer app found nowhere else. In my desire to use org-mode, I got sucked into the abyss and have come out a believer. It started by finding an emacs configuration that had with vi keys. Now, 5 years later, I never leave Emacs. I finally understand why people have loved Emacs, and it’s endless customizability, (relevant xkcd) for over 40 years.

So why is it that good? Well, it has an embedded lisp-machine and a design that separates the content and presentation layers that enables it to modify all information that flows through while maintaining extensibility. Given that design, there’s a large community which has made world-class software to integrate/interface with all types of workflows with different programs. Additionally, operating on text gives massive benefit with regards to data ownership, simple modification, search, parsing, copying, scrolling, and various integrations. A music playlist is just a text file that can managed the same way as your mail and both can be linked to an agenda file which is put in your schedule. The whole is greater than the sum of the parts. This might appear contrary to the Unix philosophy of doing one thing and doing it well, but I consider Vim being a text editor while Emacs more like a unix pipe which operates on buffers/information instead of streams.

Now, if you’re a regular person, firstly, that last paragraph probably sounded like complete nonsense, and secondly, you probably just want something that works without endless fiddling. The unreasonable power of customizability is both a blessing and a curse, but I’ve actually only used mostly the defaults from other’s configurations. My Emacs journey started off with Spacemacs which has a fantastic UI, but on the slower side. But I needed more speed being on an older laptop. Now I use Doom Emacs because of the simplicity, stability, and, of course, the speed. It also supports non-vi keys. In fact, chances are that I’ve probably spent more time writing this post out than I’ve ever spent customizing Emacs.

But why bother learning anyway?

There are two aspects to this:

  1. As a tool - what is made possible by the packages and environment which will likely cover what most people do on a regular basis.
  2. As a philosophy of freedom, minimalism, and longevity (yes, you read that right, minimalism)

Here are a few screenshots of my Emacs setup running on a 43 monitor in 4k resolution powered by an X230. Essentially, Emacs is powering 6 normal screens of 1280x1080. It’s absurdly awesome.


And another one…


2. General guide to Emacs tooling for new users

There were a few things that were on my wishlist as an emacs newbie.

  1. A working configuration with vi-keys - this is delivered by Doom and probably others.
  2. A general walkthough of the best parts of Emacs with basic keybindings - provided by this guide.
  3. Understanding how to figure things out - the last section.

In the rest of this guide, we’ll follow the following keybinding notation:

C-x x     ; Hit Ctrl and x together and then x again
M-x       ; On most systems, this is the Alt key. This command is Alt-x
SPC x     ; For Doom or spacemacs, this is spacebar is called the leader key. This is hitting space followed by hitting x

2.1. Org-mode - your life in plain text   ATTACH

Org-Mode is what got me into Emacs. It’s one of the first Emacs killer apps. What most people miss is that org-mode is an outliner - not a word processor - which is extremely important for organization. This means that you get structured editing with folding via the headings, sub-headings, etc. It’s also an excellent markup language which allows you to do things that aren’t possible otherwise.

Writing is a way to make sure your thinking is clear and org-mode makes it even easier.

I’ve used it to make grocery lists and to build software that spans hundreds of engineers. It enables you to see the flow of projects, writing, and almost anything else.

Some features:

There are a plethora of org-mode resources out there.

Also, don’t worry about getting a perfect setup. Just start using it with a single file, things will evolve.

Basic org-mode setup

I organize by quarters since I’ve been inculcated by the vast financial machinery of Silicon Valley for far too long. I have a file for each major area I’m trying to cover, but my quarterly file is my catch-all. Here’s an example org-file.

 * DONE Task1 :tag1:
  Some description of a task
  Could take multiple lines
 * WAIT Task2 :tag2:
  Paragraphs of writing
 * TODO Outside :outside:
 ** TODO Pick up milk :grocery:
 ** TODO Look for flooring :grocery:

 * Arg :bureaucracy:
 ** Pay bills
 *** Credit card
 SCHEDULED: <2020-11-01 Sun>
 *** Electricity
 *** Phone

The number of stars in a headline indicates the indentation level and what can be folded/hidden. The title and tags are self-explanatory.

SPC o A           ; opens the generic agenda menu selection
SPC o A a         ; opens the scheduled items
SPC o A < a       ; opens the scheduled items for the current buffer
SPC o A M         ; filter the agenda based on tag for which you want the TODO's. I use this to schedule things.
Attaching and linking files to agenda

While in a heading, you can attach files.

M-x org-attach      ; opens up large number of ways to attach. pick move or copy
M-x org-attach-open ; opens up the attachment

You can also make a link to it the file instead of full attachment. This works for points in a file, mail, etc.

M-x org-store-link     ; stores a pointer to whatever you're looking at
M-x org-insert-link    ; inserts said link - clicking navigates to it.

2.2. Org-Roam - a personal knowledge management system

Although, this is technically under org-mode, org-roam deserves it’s own heading since it’s an extremely recent development.

This is a combination of One Note, Evernote, and Roam Research. Except, well, it’s fully free / open and you own all your data.

With a tiny bit of configuration, you can capture screenshots and embed them directly into org-mode files with your notes. With backlinks and various graphing capabilities, it is something I wish I had 20 years ago as I now pore and grep through un-organized text files.

It is incredible.

SPC m m f   ; find a note
SPC m m i   ; open up a window to capture notes
SPC m m d   ; use the date facilities - you'll have to try it

2.3. PDF - viewing, markup, and annotate

So can you imagine being able to go into a pdf and mark it up with various notes in Emacs? Well…you can in pdf-mode. It will open up several different window panes, each with their own functionality. Provided by pdf-tools

Simply open a pdf and use the following annotation commands:

M-x pdf-annot-add-highlight-markup-annotation
M-x pdf-annot-list-annotations
M-x pdf-annot-list-follow-mode

2.4. Nov.el - reading epubs in Emacs

No, you don’t even need an e-book reader if you have the power of nov-mode on your side. And a clarification for the newcomers, Emacs has a ton of modes to deal with different files and situations. If you open an epub and just see a listing of files, that means you need to execute M-x nov-mode given by the package Nov.el or add the following to your config to enable it automatically.

;; config.el
;; https://depp.brause.cc/nov.el/ - has setup instructions

(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))

;; set a custom font if desired
(defun my-nov-font-setup ()
  (face-remap-add-relative 'variable-pitch :family "Liberation Serif" :height 1.0))
(add-hook 'nov-mode-hook 'my-nov-font-setup)

M-x nov-mode           ; activates nov-mode
C-u                    ; navigates page up
C-d                    ; navigates page down
j                      ; moves cursor down
k                      ; moves cursor up
C+                     ; increase font
C-                     ; decrease font
C-j                    ; next chapter
C-k                    ; previous chapter

2.5. Window and buffer management

Emacs has by far the best window and buffer management that I’ve used. You can have hundreds of buffers, search over them, split/resize windows in any direction, move buffers back and forth between windows - all with autocompletion and fuzzy matching. With tmux, vim, and others, it’s not quite so easy to search and find buffers. I used to spend a lot of time context switching in trying to find the right windows, but now it is instantaneous.

Emacs has the following terminology:

  • Frame - every time you open up the emacs editor - it creates a new frame.
  • Window - some portion of the frame
  • Buffer - analogous to tabs in a browser window which contain the content. You can move any buffer to any window or frame.

For instance, you can setup a frame in each workspace of your VM and setup each frame with a different window layout. Then you can also move buffers back and forth across all the frames. More details below and window and buffer movement.

2.5.1. Splitting/unsplitting a frame into multiple windows:

C-x 3 ; splits vertically
C-x 2 ; splits horizontally
C-x 1 ; makes that buffer full screen and removes all other window splits
C-x 0 ; gets rid of the current window in a split
C-x + ; balances the sizing of all the windows

2.5.2. Selecting the active window

Doom also includes ace-window which is a popular way to select which part of the screen you want to be active. For instance, if you have the emacs frame split into 6 windows, you can select which window you would like to work on. Alternatively, if you didn’t want the native emacs functionality, you could also open up 6 frames with a single window each and have the window manager handle all the movement.

C-x o ; highlights each window with a letter which you can press to activate it
      ; for my 6 split setup the keys to pick each section are along the home row
      ; | a | d | g |
      ; |-----------|
      ; | s | f | h |

2.5.3. Selecting buffers for the current window

Finally, let’s say you have 50 different buffers open (which could consist of different types of files, modes, repl, messages, etc.)

C-x b   ; lists all available buffers in a popup window. After you select a buffer, it replaces the existing buffer in the window.
C-x C-b ; pops up all available buffers in another window for management. By manage I mean, can select for deletion/closure, etc. using the standard dired keys (more on that later)

This can be done in several different ways - either frame based or otherwise.

I have exwm (more on that later) setup workspaces accessible via s-1, s-2, s-3 and have custom window setting for each desktop based on what I’m working on at the time.

Doom by default sets up workspaces via combinations that are prefixed with:

SPC tab   ; workspace menu
SPC tab n ; new workspace
SPC tab d ; delete workspace
SPC tab 1 ; move to workspace 1

2.6. Daemon-mode - for extra startup speed

Daemon-mode speeds the startup to near instantaneous. By starting emacs up as a daemon, you connect to the running instance with emacsclient. Here’s an example systemd unit file.

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

ExecStart=/usr/bin/emacs --fg-daemon
ExecStop=/usr/bin/emacsclient --eval "(kill-emacs)"
# The location of the SSH auth socket varies by distribution, and some
# set it from PAM, so don't override by default.
# Environment=SSH_AUTH_SOCK=%t/keyring/ssh


This way, if you’re in a tiling VM you can bring up multiple emacsclient frames and manage all the buffers in the same context.

2.7. Password management

There are a lot of password managers out there and I don’t trust a single one of them. Lastpass, keepassxc, bitwarden, etc.

For years, I’ve just used gpg and stored my passwords individually in text files and had a few shell functions to select the file and kick off the gpg decryption. Well, it turns out the Wireguard author does the same thing and made a pretty slick cli interface. Now there’s an entire community formed around that concept.

And where there’s community, well, there’s an emacs major mode that integrates with it.

So to manage your passwords directly from emacs:

M-x password-store-generate ; creates a random password for use
M-x password-store-copy     ; copies the first line of the file for copy and paste for 45 seconds
M-x password-store-edit     ; opens the gpg file for editing and you can select other content from that file.

;; in a configuration file
(setq password-store-password-length 18) ;; would set the max length of the password to 18

Just remember to set your pinentry to something graphical (gnome, gtk, etc) as sometimes having a console pop up in a shell in emacs doesn’t work so well.

2.8. Magit - Making git friendly and usable

Perhaps another killer app.

So if you’ve made it this far, you probably have used git. And after you’ve used magit, you may actually enjoy using git. But let’s say you already liked using git, then suddenly you’ll start loving it! It completely changes how you can visualize what goes in/out of a commit.

There are a ton of videos and tutorials on the web describing all the things you can do to improve your git workflow.

There’s also vc-mode for all the other version control systems, certainly not as slick, but it is decent none the less for quick work.

2.9. Development tools

The development tools / IDE section could be an entire post by itself. There’s treemacs, autocomplete, projectile, multiline comments (visual select followed by M-;), different types of search, jumping, folding (za, zo, zc) and countless other tools. Below are just two examples.

2.9.1. Rest client

Words simply cannot do justice to literate programming with rest client.

Go watch this 2 minute video of EmacsRocks Episode 15 instead.

2.9.2. REPL modes

This is far too complicated to get into at this point, but most languages have a REPL implementation that can be used. This means that you can run code and get the response back in your current buffer (or a popup) and not have to context switch.

2.9.3. Literate programming

Literate programming was introduced by Knuth - as the ideas behind a design are more important than the code in most cases. The best example I could find of literate programming for this post was, naturally, a literate emacs config file .

2.9.4. Plantuml integration

And if you’re going to be writing any sort of documentation, you might as well embed diagrams.

;; config.el
(setq plantuml-default-exec-mode 'jar)
(require 'ob-plantuml)
(setq org-babel-load-languages
  ((shell . t)
    (plantuml . t)
    (python . t)
    (emacs-lisp . t))))
(add-to-list 'org-src-lang-modes '("plantuml" . plantuml) )
(org-babel-do-load-languages 'org-babel-load-languages '((plantuml . t)))

2.10. Email

Yes, you can and should read your mail in emacs. Since I have my own mail server my setup is fairly straight forward.

I’ve migrated from Pine -> Alpine -> Sup -> Notmuch to mu4e.

mu4e manages over 40,000 messages from 1997. It works. On top of that, you can link anything to anything in emacs. You can have pointers to files, emails, images all embedded in different org-mode files.

Although you can search through emails, with this method, you won’t need to.

M-x org-store-link     ; stores a pointer to whatever you're looking at
M-x org-insert-link    ; inserts said link - clicking navigates to it.

I use the following combination to provide mail:

  • Mu - this is a system package which provides indexes and search
  • mu4e - the actual emacs client
  • OfflineIMAP and MSMTP - to fetch and send mail

Doom includes a configuration for mu4e out of the box and decent installation instructions.

Although there are tons of ways to configure mu4e, the only minor adjustment I’ve made is to handle HTML email links better to make them viewable/clickable at the bottom of a msg:

(setq mu4e-view-prefer-html t
    mu4e-html2text-command "w3m -dump -T text/html -cols 72 -o display_link_number=true -o auto_image=false -o display_image=false -o ignore_null_img_alt=true" )

2.11. Dired - for file management

If you see an emacs buffer giving a file listing, that is dired. Dired allows you to manage files/directories. Once you know the keys, dare I say it, it’s even better than Norton Commander.

I’ve listed the doom keys for convenience.

j     ; next item or move down
k     ; previous item or move up
-     ; move to the parent directory
enter ; if you're on a directory, it will enter it.
m     ; mark a set of files
R     ; rename or move. If you have dual panes, it will default move to the other pane.
C     ; copy file. If you have dual panes, it will default move to the other pane.
+     ; create a directory
d     ; mark a file for deletion
x     ; execute the mark/deletion

Now you can also press enter on a file. This will open the file based on what modes you have installed. For instance, an mp3/mp4 could open in emms / mpv / vlc. A pdf will open in a new buffer directly in emacs. And, of course, text files will open in emacs. Neat, eh?

There’s also the ability to set bookmarks for common locations:

M-x list-bookmarks           ; list-bookmarks
M-x bookmark-set             ; set the bookmark

I do customize dired a bit to keep a single buffer.

(package! dired-quick-sort)
(package! dired-open)
(package! dired-single)

;; dired-single buffer
(defun my-dired-init ()
  "Bunch of stuff to run for dired, either immediately or when it's loaded."
  ;; <add other stuff here>
  (define-key dired-mode-map [remap dired-find-file]
  (define-key dired-mode-map [remap dired-mouse-find-file-other-window]
  (define-key dired-mode-map [remap dired-up-directory]

;; if dired's already loaded, then the keymap will be bound
(if (boundp 'dired-mode-map)
    ;; we're good to go; just add our bindings
  ;; it's not loaded yet, so add our bindings to the load-hook
  (add-hook 'dired-load-hook 'my-dired-init))

2.12. Tramp - remote files and sudo

Tramp stands for “Transparent Remote (file) Access, Multiple Protocol” and is used for the time when you need to edit files on remote machines or sudo. Are you going to ssh? scp? sftp? Of course not. No, you’re going to use TRAMP. It has definitely grown on me. I’ve only used the sudo and ssh protocols, but there is also sftp, afp, samba, davs, gdrive, adb, and rclone as protocols.

Above that, there is integration with the other emacs processes. You can set bookmarks and browse and manage the remote system using dired in the same way that you do locally! In fact, if you open a shell while in tramp mode buffer in dired, it will drop you in a shell in the correct directory on the remote machine!

I haven’t figured out how to sudo+edit on a remote system yet, but I’m sure there’s some way. And if your remote shell is a bit weird, use /sshx instead or check out the info docs for tramp.

SPC .                                 ; opens up find-file with doom keys
C-x C-f                               ; find-file with regular keys
C-x C-f /ssh:user@host:/path/to/file  ; edit a file on a remote host
C-x C-f /sshx:user@host:/path/to/file ; if ssh hangs or weird shell issues
C-x C-f /sudo::/path/to/file          ; sudo with emacs to edit a file

2.13. Exporting org content to other formats

I’ve already mentioned this under org-mode and the markup language section, but org-export (ox) is certainly worth another pass. Org-mode ships with quite a few default exporters. Depending on your inclination (or disinclination) towards visual complexity, you might actually be able to do everything in org.

Personally, I think having everything in org and converting it is a bit overkill. It’s pretty easy to write reveal or markdown after all, but org-markup is pretty fast and easy to manipulate for large bodies of text because it’s an outliner. I wouldn’t have wanted to write this post straight in markdown, but I have done other writing directly in those formats to get some better control.

So let’s say you want to write something that has some math and maybe some images and publish it to HTML. Org-export supports mathjax by default.

For instance, this post is has approximately:

\(2^{10} < word count < 2^{13}\) total words.

And, for the matter of publishing, there are a few outputs:

I’ve used ox-hugo and ox-reveal so far and they worked just fine. I’ve also made content directly in markdown and reveal. Either way works.

C-c C-e    ; open up the export window that has a ton of output options

2.14. Static websites

It wouldn’t really be complete if this website wasn’t published from emacs, would it? I’m both irritated and impressed with org-publish.

I’m impressed because if you have generated images or other attachments in org, it will also correctly publish everything to a remote host via TRAMP.

I’m irritated because I never knew about this before and suffered with the tooling for image generation and maintenance with my other setups.

; https://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.html
; https://www.baty.net/2015/publishing-my-notes-using-org-mode/
; https://www.john2x.com/blog/blogging-with-orgmode.html
; https://pavpanchekha.com/blog/org-mode-publish.html
; https://nicolas.petton.fr/blog/blogging-with-org-mode.html
; https://justin.abrah.ms/emacs/orgmode_static_site_generator.html

(require 'ox-publish)
(setq org-babel-temporary-directory "~/current/sheer.tj/plantuml")

(setq org-publish-project-alist
 :base-directory "~/current/sheer.tj/"
 :base-extension "org"
 :exclude "noexport"            ; any file matching regexp noexport
 :exclude-tags ("noexport" "todo")
 :publishing-directory "/ssh:"
 :recursive t
 :publishing-function org-html-publish-to-html
 :headline-levels 4             ; Just the default for this project.
 :auto-preamble t
 ;:makeindex t                   ; https://orgmode.org/manual/Generating-an-index.html
 :sitemap-title "Blog Index"
 ;:sitemap-filename "index.org"
 :sitemap-style list
 :html-head "<link rel='stylesheet' href='css/org.css' type='text/css'/>"

 :base-directory "~/current/sheer.tj"
 :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf"
 :publishing-directory "/ssh:"
 :recursive t
 :publishing-function org-publish-attachment
 ("prod" :components ("prod-notes" "prod-static"))

2.15. Music

I’ve started playing music more once I figured out how to use EMMS. I used audacious previously, but EMMS is the least irritating music player I’ve used so far. You could make custom keymaps, but I haven’t really bothered.

Some basic commands:

M-x emms-playlist-play
M-x emms-pause
M-x emms-next
M-x emms-playlist-go            ; shows currently what's on the playlist
M-x emms-play-dired             ; can play directories, files, etc.
M-x emms-add-dired              ; add all marked files or directories into dired
M-x emms-playlist-save
M-x emms-playlist-shuffle
M-x emms-seek-forward           ; seek forward 10s
M-x emms-seek-backward          ; seek backward 10s

There’s Bongo also, but I haven’t really compared the two.

2.16. Calendar integration

M-x calendar pulls up the same interface as cal -3 on the cli. There’s a diary mode which I believe has been mostly superseded by org-mode. However, there are some neat features. For instance, I like to know the sunrise/sunset times, which are provided by M-x calendar-sunrise-sunset.

Now for more serious business, you can also integrate with outlook and gmail with:

I use neither of these, but it’s nice to know they’re there.

2.17. Vterm

We can go on about the applications - there’s a RPN calculator, several newsreaders, proced (a replacement for top) and so on and so forth. But what if you just want to use a terminal? The regular terminal applications are fairly slow for long wrapping text. So doing “top” inside a regular one on a wide screen can take quite a bit of cpu.

However, vterm is a full fledged c-application inside of Emacs and it is fast. If you do have applications that require curses, vterm is the way to go. On top of that, it makes the general copy and paste much easier.

There’s pretty good completion and integration for fish, bash, and zsh. I’m using bash for compatibility and the fact I’m not really in the terminal very much anymore. If I was, perhaps I would opt for zsh or fish.

Beware though - on some distributions this is very tricky to install.

2.18. As an OS or init system

Just in case what I’ve written isn’t enough and you want to really take it to the next level you can also:

2.19. As an editor

No joke, Emacs also serves as an excellent text editor when you enable vi-keys. I thought I’d throw it in there.

Despite my personal preference for vi-keys, I have heard that people can actually edit text without those keybindings. Vi-keys are optional in Emacs. Also, I find WYSIWYG detracts from the writing experience, so I strongly prefer to have the presentation (formatting and typesetting) be a separate step from the content.

Distraction free editing is a thing and Emacs can easily do that with writeroom-mode (SPC t z), which clears off the entire frame, can be made full-screen, and uses a slightly larger font.

It also supports multiple fonts with mixed pitch mode, word counts (M-x count-words), synonym lookup (M-X +lookup/synonyms), and spell-check.

And I said before, it’s an outliner which allows you to structure your thoughts in a tree format and makes working on long texts much easier.

z c  ; close a heading via folding
z o  ; open a heading via folding
z M  ; close all folds
z R  ; open all folds
z O  ; open everything in the subtree
z B  ; show only the structure of the headers
C-j  ; navigate to the next header
C-k  ; navigate to the previous header

V    ; enable visual selection of lines
M-;  ; comment a line

2.20. Syncing and working with mobile

I’m not a big fan of mobile philosophically, but there are some projects that provide that experience.

TODO - publish org mode multi-device tooling :someday:

2.21. Text web browser

Why would you want to browse the web in text mode? I have a few reasons:

  • The text-mode web isn’t actively trying to make you stay online and click on things.
  • No ads. Less tracking. Fast.
  • Any sites that have useful or relevant content will be readable in text-mode anyway. For instance, Reuters has perfectly readable news articles. If you like Medium, it also works satisfactorily, and so does Hacker News

There are only a few options for text mode browsing:

  • EWW - browser that comes by default (images, no js)
  • W3M - uses w3m as a backend pager to render pages (images, no js)
  • Links - needs to be run inside ncurses terminal
  • Lynx - also, needs to be run inside ncurses terminal
  • Brow.sh - the most modern - uses a firefox backend to render to text

There’s also projects that open up browsers inside of emacs:

My personal preference is W3M because it has very robust emacs interface. It supports tabs, images, and is very fast.

You do have to be careful in knowing what mode that you’re in though because the movement keys are close to identical when the evil-collection is installed.

;; config.el
; http://emacs-w3m.namazu.org/
; http://beatofthegeek.com/2014/02/my-setup-for-using-emacs-as-web-browser.html

(setq w3m-search-default-engine "duckduckgo")
(setq browse-url-browser-function 'w3m-goto-url)
; having a million tabs open is silly but possible
;(setq browse-url-browser-function ‘w3m-goto-url-new-session)

; emacs-mode
z i          ; toggle inline image
z I          ; toggle inline images for the buffer

;; w3m-mode
C-c C-s                ; open up the tab list. This updates the main buffer
g                      ; open url
G                      ; open url in new buffer
s                      ; send query to search in current buffer
S                      ; send query to search in new buffer
o                      ; open url in current buffer
O                      ; open url in new buffer
j/k                    ; up / down
b/SPC                  ; page up / page down
[ or ]                 ; previous / next form
tab or s-tab           ; previous / next link
M-x w3m-history        ; open up a buffer with all history
B/L                    ; go back/forward in history
M-x w3m-delete-buffer  ; delete buffer
M-x w3m-browse-url     ; open up links in w3m

Note that you can also embed webkit inside of emacs. I haven’t done this myself as I use exwm, which we will be getting to next.

2.22. Exwm - an emacs window manager

Emacs has a lot of packages, but some of them aren’t good enough for effective use. For instance, slack or telegram could be setup in emacs with various plugins, but they are iffy at best. And there’s no equivalent for zoom or firefox, etc.

I was using awesome wm over with multiple monitors and despite my efforts, when I undocked, all my windows would end up either collapsing on a single workspace or disappearing. Although awesomewm lets you move windows into different locations on the screen or different monitors, it is nowhere as near as convenient as the emacs window management, so I ended up putting things in fixed locations or using the monitors less efficiently.

I’ve gone through the buffer and window management section earlier. To have browser windows and other graphical applications inside emacs, there are two options:

I heard about exwm, but I never tried it because I thought it would be too difficult to get working.

I was dead wrong.

Since switching, I have no idea how I managed before. Everything is using the same native keys and window management. Docking and undocking worked with my existing docking scripts, and now, I don’t suddenly lose my workspace state. And I mentioned it already, but it’s really nice to manage all applications and windows in the exact same way. Being able to split your monitor exactly how you want it and then placing the windows in those locations makes incredibly effective use of real-estate. In fact, some people use exwm to manage firefox windows rather than deal with all the tabs.

When I switched to a 43 inch monitor, it got even better. The only issue was, well, my laptop doesn’t really have the graphical horsepower. What was smooth and rendering fine on 2000x2000 pixels, didn’t do so well 4000x2000. Typing had a noticable lag of between 80-150ms and cpu would be up at 50% just doing that. I had to switch back to awesome, which didn’t have that problem.

Unfortunately, after having the window management awesomeness of exwm, switching back really sucked. I struggled making effective use of the monitor. So then I installed a development branch of native compilation (EmacsGcc) which took the typing latency to something that I can’t notice with low cpu usage. Note that this is likely completely unnecessary unless you have a giant monitor and an old laptop.

2.22.1. Single-threading and pauses

The only time I’ve noticed pauses regarding the single-threadedness is waiting on a network request or user input. For instance, launching something that requires ssh on another machine requires waiting for that connection to establish in Tramp (note that ssh via vterm doesn’t have this effect). Sometimes a window pops up somewhere that can’t be accessed that is waiting for input. Other than that, I haven’t noticed any Emacs related freeze due to single-threadedness at this time. However, if you do run into a freeze, there are two options.

C-g                      ; This cancels the network command from within emacs
$ killall -USR2 emacs    ; Outside of emacs, you can send a USR2 to the process

2.22.2. Exwm configuration

(setq mouse-autoselect-window t
      focus-follows-mouse t)
(require 'exwm)
(require 'exwm-config)
(require 'exwm-randr)

; Three monitor workspace assignment (deprecated)
;(setq exwm-randr-workspace-monitor-plist '(0 "LVDS-1" 9 "LVDS-1"
;                                             1 "VGA-1" 2 "VGA-1" 3 "VGA-1"
;                                             4 "HDMI-3" 5 "HDMI-3" 6 "HDMI-3"))

; The undock hook is called by udev on undock event
(add-hook 'exwm-randr-screen-change-hook
          (lambda ()
             "xrandr" nil "~/bin/thinkpad-dock/dock-lg.sh")))

;; https://github.com/technomancy/dotfiles/blob/master/.emacs.d/phil/wm.el
(setq exwm-workspace-number 9
        exwm-workspace-show-all-buffers t
        exwm-layout-show-all-buffers t
        exwm-manage-force-tiling nil)

(require 'exwm-systemtray)
  (display-time-mode 1)
  (display-battery-mode 1)
  (setq display-time-string-forms '((format-time-string "%H:%M " now)))

2.22.3. ewwm startup - xinit and startx / xesession.desktop config

There are several options to startup exwm.

The easiest is to configure .xinitrc and startup with startx.

# ~/.xinitrc called with startx

# Disable access control for the current user.
xhost +SI:localuser:$USER

# Make Java applications aware this is a non-reparenting window manager.

# Set default cursor.
xsetroot -cursor_name left_ptr

# Set keyboard repeat rate.
xset r rate 200 60

# Start ssh-agent
eval `ssh-agent`

# Uncomment the following block to use the exwm-xim module.
#export XMODIFIERS=@im=exwm-xim
#export GTK_IM_MODULE=xim
#export QT_IM_MODULE=xim

# Finally start Emacs (may need full path)
exec emacs

If you want exwm to startup on your login screen, for lightdm, you can configure /usr/share/xessions/exwm.desktop

[Desktop Entry]
Comment=Emacs Window Manager
Keywords=Window manager

2.23. Learning curve - discoverability, introspectability, and customization

Did you know that almost everything in Emacs is discoverable or introspectable? Well, now you do.

And with Doom, here are the easiest ways to find out what is possible or not:

M-x enter some words            ; There's a fuzzy match on the words. "play emms" could return emms-play-dired.
SPC h v                         ; describe variable - if you're looking to understand how something is configured. Again fuzzy-matching
M-x toggle-debug-mode           ; If there's an error, this will show the trace
M-x edebug*                     ; You can actually debug everything in emacs.

Also, if you’re looking to understand how a module works, everything is in the code of the modules: https://github.com/hlissner/doom-emacs/tree/develop/modules

And finally, if you’re looking for how something works, you can always refer to the info pages. They are accessed from

SPC h i     ; opens info
C-h i       ; opens info

And one last thing, there’s an embedded lisp machine. Elisp gives Emacs an unreasonable amount of power. Unlike myself, before you start using this power, I would highly recommend going through some elisp tutorials for an hour or two. I haven’t really customized Emacs yet though.

2.24. Community

There are a ton of writing on emacs scattered across the web. Here are just a few:

3. Philosophy on technology

Technology should be evaluated on its merits and benefit to society, not just novelty and newness. It seems pretty obvious, but the only community that I am aware of that evaluates technology before adoptation are the Amish.

Technical progress, by its very nature, allows a smaller subset of people to exert influence over a larger set of objects/population than ever before. And so, more money and power are concentrated into the hands of fewer, and the earning power of the average person decreases. And newer advances, such as social networks and online advertising, are of dubious merit for society at large and certainly don’t create food or wealth for the masses.

And with the aim of rapid progress, we’ve disregarded maintainability - which causes predictable obsolescence. Computers get faster and software eats that away by providing glittery transitions and rounded corners. But the fact of the matter is, the software that an average person uses has been good enough for a long time. For instance, most spreadsheets are rather simple and can be imported into org-mode. The largest spreadsheet I ever worked on was in Google Sheets, and it involved a thousand person re-org with over 10k cells and had custom scripts to calculate various conditions close to recursively.

It also broke Google Sheets.

There is certainly room for software for custom / professional tasks, but that’s not the 99th percentile case. Some people still use and consider WordPerfect 5.1 as the best word processor ever made.

So, as software is mostly feature complete for all but the most complex cases, companies need to ensure they make money. Adobe started with the transition to cloud and then disabled access to desktop products. Now even Apple is getting into the services game to turn customers into sources of recurring revenue.

However, if you don’t mind being food for Google, Microsoft, Facebook, Adobe, Amazon, etc, you can stop reading here.

But for us to not be food, we need to optimize for freedom, longevity, minimalism, and data ownership.

3.0.1. Freedom and ownership

Proprietary software has a place in the world. It provides useful functionality which open-source cannot tackle because the open source funding problem isn’t adequately solved. However, by using closed and cloud software, we leave ourselves open to a lot of problems.

There are a few trends happenning right now:

  1. Software is no longer being sold with a perpetual license, but with a subscription.
  2. Hardware is also being bundled with software/firmware and goes EOL with software / account / firmware rather than the lifetime of the product.
  3. Content is being licensed for limited time rather than purchased.
  4. Your data is not yours

These trends are disturbing and will likely get worse over time. It’s best to make the switch for personal data sooner than later.

3.0.2. Longevity

Assuming that we’re going to build a library of free software, we want to have software with longevity. Emacs’ design has shown empirically over 40 years that it is durable and extensible. We have seen it being ported through multiple hardware architecture shifts and platforms. If we were going to make a bet on a programming language vs Emacs on longevity for the next 50 years, there are only a few languages that I would want to pick in that fight.

And despite evidence to the contrary, I don’t like spending time screwing around with computers. I like my software to work and stay working.

So given all we know about Emacs, this means all the basic tasks that I outlined in the first section will likely still work. And if you customized Emacs to make it work for your workflows, that means those should also be intact if they were built-in. Even if they relied on an external program which no longer worked, it’s likely that Emacs would be able to interface with a new program that has the same functionality.

I would postulate that an Emacs based workflow is likely going to outlast most software programs.

3.0.3. Minimalism

Minimalism can be examined on a few levels.


Emacs is certainly not the best tool for every task. It has a reduced subset of functionality and graphics for most tasks. However, if we’re trying to optimize for longevity and the least amount of workflow changes, Emacs maximizes the total amount of utility with the least amount of free software that you can use.


Compared to modern software, Emacs can no longer be considered bloated. In fact, Emacs is getting faster as it ages. There are massive speed improvements in the development branch which should be available in the Emacs 28 release. At the high end, it may take 700MB. At the low-end, it can take 16-32MB. It can work on all sorts of hardware and platforms.


Can you eschew the fancy graphics and transitions? What’s good enough?

3.0.4. Own your data

Let’s say you use Google and one of their algorithms decide to ban you because you posted a picture of your apple pie on Youtube. Well, then at the very least, you have:

  1. All your email and google drive documents locally if you’ve used offlineimap/mu4e and tramp.
  2. A delicious apple pie to eat.

We’re actually moving into a world where the next generation may not actually know what a file is. I’ve worked on designing systems which extracted data out of large files/designs to be able to interact with other components. On the one hand, this is extremely beneficial for integration and making workflows, but this will eventually cause user data lock in. What is convenient in the short-term is quite dangerous for the user in the long-term.

Emacs can’t really help manage photos and videos (which need non-cloud or multi-cloud backups), but chances are, the rest of your generated data will be in plain text files. Other formats may become unreadable over time, but plain text is everlasting and timeless. It’s tough to go wrong with that.

4. Conclusion

In haiku form, it’s more important than ever to:

purchase dumb hardware
use software without lock-in
own all your data.

At the end of the day, you want to own your house, not rent it. There are many paths up the mountain - the Way of Emacs - is but one.

I choose this path because I cannot think of any other software that provides so much rich functionality and customizability as Emacs with such a low learning curve. Coming in with a solid vim background, I spent probably 50 hours to achieve my setup over the past 5 years. With Doom and this guide, my guess is future users will spend less than I did.

But on top of functionality, I also want my software to be long lasting, minimal, and have a readable data format. Once I’ve set something up, I dislike it when it suddenly stops working. Emacs checks all those boxes, too.

  • Longevity - it has lasted 40 years and gone through many platform changes. There’s no reason to assume that it won’t be functioning in another 40.
  • Minimalistic - it’s the least amount of software that you can use to accomplish many tasks.
  • Data - the data it generates is mostly plain text and will be readable by any program in the future Dealing with images, videos, and music would probably be a good subject for another guide in the future. .

Learning emacs is no longer a dark and arcane art anymore like it was in the 90’s or the 00’s. In fact, it gives an unreasonable amount of power in a very small amount of time. I would suggest for anyone that enjoyed this article, download Doom and Emacs 27.1 and give it a shot. Let me know what works (or doesn’t work) by mailing contact at sheer.tj and I’ll update this post.



Dealing with images, videos, and music would probably be a good subject for another guide in the future.

Date: 2020-11-12