This is an account of my development environment overhaul.
I’ve recently made the following changes:
- Move from xfce to StumpWM
- Move from Qwerty to Norman
- Move from vanilla Emacs to Doom Emacs with Evil-mode (Vim bindings)
Instead of using the default window manager that I installed with Manjaro, I’m making the switch to a tiling window manager. I chose StumpWM because it was written in Common Lisp, a language I want more chances to use.
Changing window managers has the added benefit that I get to learn about how pieces of a desktop experience fit together. For example, I learned what a compositor is.
My understanding is that an operating system provides some area of memory onto which physical monitors, called “heads”, are mapped. A window manager detects the layout of these heads and draws the windows in certain locations of memory. Those locations in memory subsequently manifest as locations visually displayed by your monitor.
Neither the windows themselves nor the window manager are responsible for effects like shadows or transparency. That’s the responsibility of the compositor.
If I’m lucky enough to get to spend tens of thousands of more hours hacking away at code, investment in ergonomics and efficiency should pay well.
I have considered that training in things that are too outside the norm may be counter-productive; I don’t want to be useless when not at my own personal workstation.
But it would be irresponsible to never venture out.
For a long time, I valued being effective in a bare-minimum environment. I didn’t want to lean too heavily on custom configuration and tooling. I wanted to be proficient in the largest number of environments, such as my personal Mac/Windows/Linux workstations to SSHing into servers to pair programming on someone else's machine.
But why? Where does one stop? Why not use a more primitive editor, like Vim or even Ed. Why should it just apply to editors? I’m already reliant on so many tools and software for which I’m happy to let others have already worked out the most commonly accepted configs.
I don’t even have any quantification for how long it will take to learn Doom and Vim’s bindings to a level of proficiency equivalent to my current setup, so I’m not really qualified to know the cost/payoff and the easiest way to find it is to experience it.
The rest of this text will be reference notes to help me learn my new environment (and re-learn it if this silly idea gets back-burnered for another day).
I also hope it can serve as a helpful reference for others.
I’ll update this to track progress.
It will be hard to quantify the effect this has on my development speed in the long term. In the short term, it sure as hell has ground it to a halt. The cognitive overhead of what should be the simplest of actions is overwhelming and makes it very difficult to focus on any actual writing of code.
At least I’m enjoying the process.
The change to Norman can be tracked easily with a typing test.
A 1-minute sentence typing test at https://www.typingtest.com/ has me at 32 WPM using Norman. I immediately followed that with another test using Qwerty and got 62 WPM. It was extremely difficult to switch. I gave up trying to type Qwerty on my Ergodox and did the Qwerty test on my laptop’s keyboard. After a few more minutes re-familiarizing myself with Qwerty, I was up around 85 WPM.
The next section will be a reference for some config, shortcuts, and keybindings.
The number one thing I learned about learning Emacs, and this applies to many other things, is to not trust the documentation and tutorials and to not get frustrated when something you read doesn't work. Just go to the source. If an Emacs key binding that is mentioned in some docs doesn't work, just use
ctrl-h k to describe the key and see what it is bound to and
ctrl-h f to describe the function that you are trying to use.
You’ll first want to perform some config.
Locate and open Doom’s private config files with
SPC f p.
Set your name and email in
Enable some modules in
~./doom/d/init.el. Doom doesn’t enable a project tree viewer by default, so find and uncomment either
treemacs. Evil has its own multiple cursor functionality, but I’ve heard
multiple-cursorsbehaves more similarly to what one would expect from an editor like Sublime or Atom.
After enabling any new module, you’ll need to run
~./.emacs.d/bin/doom syncand then you might also be able to get away with a
SPC h r r to do a
doom/reload rather than restarting all of Emacs.
SPC. Press and wait for a minibuffer display of available sequences.
- Navigate forward one “section” (paragraph) in the buffer
- Backward to previous buffer
- Previous open paren
z. Commands vary by minor mode.
SPC mLocal leader. Bindings dependent on major mode.
Doom gives you isolated and persistent workspaces, collections of named windows and buffers. I think this is done through the persp-mode package.
These bindings aren’t specific to Doom. If you use vim, you’ll find them familiar. In Emacs, they come from evil-mode.
ESCCancel mode, move back up to normal mode.
IActivate insert at beginning of current line.
aAppend after cursor.
AInsert at end of current line.
oAppend blank line below.
OBlank line above.
ccReplace an entire line.
c <move command>change from cursor through move command (word, sentence, etc…)
CTRL-r *to insert the contents of the clipboard while in insert mode. (
CTRL-r "for the last yank)
vActivate visual mode. Used for highlighting/selecting.
CTRL-vVisual block mode
Vlinewise visual mode
y <move command>Yank (copy)
yyyank a line
xdelete character under cursor
Xdelete previous character
DDelete to end of line.
- Cursor movement
$start/end of line
^Goto first non-blank character of line.
CTRL-dMove down half a page.
CTRL-uMove up half a page.
sMove to the next 1 or 2 character match on the current line.
;Move to the previous/next match.
Nreapeat search in same/opposite direction
:%s/old/new/greplace all old with new
If you’re thinking about rebinding the movement keys, hjkl, for home-row use with a different keyboard layout, don’t do it. You’ll be faster in the long run by minimizing your use of navigating by row/column.
SPC RETCreate or jump to bookmark.
SPC :as the equivalent of
gsgives you many search options.
gs SPCand start typing a word to see choosable highlights.
SPC b d to kill the current buffer
SPC b [pn] next\/prev buffer
Might not be enabled by default. Uncomment the multiple-cursors line in
You have several options.
- Visually select some text and then press
Rto select all the rest in the current buffer. (This is a good chance to use narrowing.)
- Repeatedly press
M-dwith the cursor over a word.
gzzto create cursor at point.
gztwill temporarily pause the cursors. Move commands will cause all cursors to move in sync with the primary cursor if you don’t pause it.
gzmto create cursors at all matches for the word at point.
gzdto create a cursor at point and move to the next match (and gzD to create and move to the previous match).
K with the cursor over a word will open a mini-buffer asking where you would like to search for that term. If the word is an Emacs command, it will open a buffer to the docs.
gcc to comment or uncomment a line or selection.
SPC g g to launch Magit
SPC SPCto fuzzy find file in current project
SPC ,to fuzzy find buffer in current project
SPC f rto switch to a recently viewed file