Hacking Emacs
Hacking Emacs
Jethro Kuan
August 8, 2016
Contents
1 Preface
2 Introduction
2.1 Installing Emacs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
4
4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
12
12
12
12
13
14
14
6 Thought-speed Editing
6.1 Moving Text Around
6.2 Selecting Regions . .
6.3 Zap-to-char . . . . .
6.4 Multiple-cursors . .
6.5 Templating . . . . .
6.6 Autocompletion . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
16
16
17
18
19
19
19
7 Project Management
7.1 FFIP . . . . . . . .
7.2 Projectile . . . . .
7.3 Using Ag or Grep .
7.4 Magit . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
21
21
21
23
23
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
24
24
24
24
24
25
25
25
9 Miscellaneous Goodies
9.1 Minimizing Startup Time . . . .
9.2 Micro-optimizations with keyfreq
9.3 Remapping Capslock . . . . . . .
9.4 Ergonomic Keybindings . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
26
26
27
27
27
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1 Preface
Emacs is a nice operating system, but what it lacks, in order to compete with Linux,
is a good text editor. Thomer M. Gil
Today, you begin your journey with Emacs, the extensible, customizable, self-documenting real-time
display editor.
Because of its complexity, Emacs will seem difficult to grok. Rest assured that learning a select
few features and packages more than suffices. This material is titled Hacking Emacs, not only
because a great deal of customization will be made, but also because youll be learning packages
that have been handpicked, to greatly boost your productivity with the least amount of learning
time.
The tinkerer will marvel at the masterpiece which is Emacs. We hack on Emacs because we can;
every facet of Emacs is extensible and customizable. Emacs is not for the faint of heart. Embrace
the challenge, but most importantly enjoy the ride. I encourage you to be curious and playful
throughout this course.
Atom users, go grab yourselves another cup of coffee while you wait for it to load up :P.
Jethro Kuan
2 Introduction
2.1 Installing Emacs
If on a Linux distribution, Emacs should be available through your respective package managers.
For OSX users, I recommend Emacs for OSX.
Refer here if you have further doubts.
This course assumes a recent Emacs version (of version >24.0) has been installed. You can check
your Emacs version from the command line with emacs --version.
2.2 Terminology
2.2.1 Windows, Frames and Buffers
The text you are editing in Emacs resides in an object called the buffer.
A window is a container for a buffer. A window can contain one and only one buffer.
A frame is a container for windows. While inaccurate, one can think of it as the window configuration for Emacs.
Figure 1: A pictorial representation of windows, frames and buffers. In this picture, there are 1
frame, 3 windows and 3 buffers.
Modern
Emacs
Cut
Paste
Copy
Kill
Yank
Save To Kill Ring
The Emacs terminology had been set in stone decades ago, long before the terms cut, copy and
paste (derived from the CUA, or Common User Access) were formed.
I will demonstrate in a later chapter why the Emacs way is better for text-editing.
2.2.4 Modeline
The bottom bar in Emacs is called the modeline. Each window has a modeline, which presents
useful information about the buffer it displays. The first item in brackets is the major mode, and
the others are all minor modes.
Note that some minor modes can be configured to not appear on the modeline (a.k.a diminished).
To see the full list of modes activated, run M-x describe-mode, or C-h m.
or be self-written.
These functions are defined in a language called Emacs Lisp, also referred to in short as Elisp.
Emacs Lisp files have the file extension .el.
The full list of functions are browsable and invokable with M-x.
1
2
3
4
5
1
2
3.1.3 UI Cruft
All these UI cruft take up precious screen estate, and should be removed.
1
2
3
4
5
6
(tooltip-mode -1)
(tool-bar-mode -1)
(menu-bar-mode -1)
(scroll-bar-mode -1)
(setq inhibit-splash-screen t)
(setq inhibit-startup-message t)
3.1.4 Use-package
use-package is a macro which allows you to isolate package configuration in an organized and
performant fashion. It was created by John Wiegley, the current Emacs maintainer.
1
2
3
4
5
6
7
8
9
10
11
(eval-and-compile
(defvar use-package-verbose t)
(require 'cl)
(require 'use-package)
(require 'bind-key)
(require 'diminish)
(setq use-package-always-ensure t))
Here, we set use-package-always-ensure to true, so if a package is found missing, it will be
installed automatically.
3.1.5 y/n
It is easier to type y/n than to type yes/no.
1
2
1
2
3
4
(setq backup-directory-alist
`((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
`((".*" ,temporary-file-directory t)))
When added to your init.el, Emacs will scan the temp directory and purge old backup files on
startup.
1
2
3
4
5
6
7
8
(delete-selection-mode +1)
1
2
(add-to-list 'default-frame-alist
'(font . "Fira Code-12"))
1
2
(setq-default tab-width 2)
(setq-default indent-tabs-mode nil)
3.2 Theming
There are a myriad of themes available for your picking. Here I list the better ones:
1.
2.
3.
4.
5.
6.
Zenburn
Solarized
Leuven (has an impressive org-mode theme)
Monokai
Tomorrow by Sanityinc
Darkorai
Im currently using tao, a monochrome theme, with personal customizations for org-mode.
To enable a theme, find the relevant name of the theme on MELPA and add in the following snippet
of code:
1
2
3
(use-package tao-theme
:init
(load-theme 'tao-yang t))
At this point you should have quite a hefty amount of modification done. Remember to save your
configuration directory into version control.
Window
0
1
2
3
4.1 Winner-mode
Winner-mode is a global minor mode. When activated, it allows you to undo and redo changes
in the window configuration.
Key
Action
C-c left
C-c right
winner-undo
winner-redo
The keybinding for switching between windows is C-x o, which I find overly complex for such an
essential key.
4.2 WindMove
WindMove is a library included in Emacs starting with version 21. It lets you switch between
windows using Shift + arrow keys. To activate it on startup, add the following piece of code in
your init.el.
1
2
4.3 Ace-window
ace-window lets you quickly switch between windows. Its the one Im currently using, and Im
very happy with it.
1
2
(use-package ace-window
:bind (("M-q" . ace-window)))
Id bind it to M-q, or anything else you find convenient.
5 Thought-speed Motion
With a more usable Emacs configuration, well begin navigating around Emacs, installing helper
libraries where relevant.
I recommend printing this refcard, and refer to it when necessary.
The first rule to moving around quickly is to never leave the keyboard. This concept is pervalent
across all efficient text editors, be it Vim or Emacs. In Emacs, key combinations are the gateway
to text-editing nirvana.
Movement
Emacs Function
C-e
C-a
M-m
End of line
Start of line
first non-whitespace of line
(end-of-line)
(beginning-of-line)
(back-to-indentation)
PROTIP: To check what a key combination is bound to, press C-h k kbd. Alternatively, M-x describe-keybindings lists all defined keys and their definitions in order
of precedence.
1
2
3
Within three
(use-package avy
:bind* (("C-'" . avy-goto-char)
("C-," . avy-goto-char-2)))
PROTIP: To jump back to your previous location, use C-u C-space.
5.3.2 moccur
moccur is short for multi-occur. Some find this useful, but I personally feel like Swiper (introduced
below) is sufficient for my day to day operations. The key benefit of moccur is that a buffer for
search result matches is created, and this can be used to move to the matched locations again.
5.3.3 imenu
imenu is short for interactive menu. Imenu offers a way to find the major definitions in a file by
name. For example, in an Emacs Lisp (.el) file, you can navigate around with imenu to variables,
and function definitions. In org-mode, you can navigate to title headers with imenu. Because of its
utility, I bind it to M-i.
5.4 Registers
NOTE: Before I begin, note that while I introduce registers here, registers are not just
for moving around the buffer.
Registers are compartments where text, rectangles, positions, window configurations and many
more can be stored. Think of it as a temporal bookmarking system; these registers get wiped at
the end of the Emacs process. Each register is denoted by a single character (eg. ?r or ?1). The
register ?a is different from the register ?A.
Whatever you store inside a register persists until it is overwritten by something else, or until the
Emacs process is killed.
Store a file in a register is simple:
5.5 Bookmarks
Bookmarks are similar to registers, but they are persisted in a file.
To create a bookmark, type C-x r m bookmark-name. Similarly, bind bookmark-jump to a more
accessible key:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
(use-package counsel)
(use-package swiper
:bind*
(("C-s" . swiper)
("C-c C-r" . ivy-resume)
("M-a" . counsel-M-x)
("C-x C-f" . counsel-find-file)
("C-c h f" . counsel-describe-function)
("C-c h v" . counsel-describe-variable)
("C-c i u" . counsel-unicode-char)
("M-i" . counsel-imenu)
("C-c g" . counsel-git)
("C-c j" . counsel-git-grep)
("C-c k" . counsel-ag)
("C-c l" . counsel-locate))
:config
(progn
(ivy-mode 1)
(setq ivy-use-virtual-buffers t)
(define-key read-expression-map (kbd "C-r") #'counsel-expression-history)
(ivy-set-actions
'counsel-find-file
'(("d" (lambda (x) (delete-file (expand-file-name x)))
"delete"
)))
(ivy-set-actions
'ivy-switch-buffer
'(("k"
29
30
31
32
33
34
35
(lambda (x)
(kill-buffer x)
(ivy--reset-state ivy-last))
"kill")
("j"
ivy--switch-buffer-other-window-action
"other window")))))
For a powerful preconfigured alternative, consider helm and its companion tutorial here. For
something like Swiper, look at helm-swoop.
For a simpler in-built alternative, look at ido-mode, Mickey Petersen has a great write-up about
it here.
6 Thought-speed Editing
6.1 Moving Text Around
Earlier, I introduced the terminology Emacs uses for its clipboard system. I missed one vital piece,
because I felt it was more appropriate to introduce here to keep things fresh.
Text that gets killed is erased, and then stored inside the kill ring. This stored text is then
retrievable by yanking. There is only one kill ring, global to Emacs.
A clear distinction has to be made between killing and deleting. Deleting text removes it from
the buffer, but does not store it in the kill ring. Therefore extra caution has to be made when
performing deletions.
Action
Function
M-\
M-SPC
(delete-horizontal-space)
(just-one-space)
C-x C-o
M-^
(delete-blank-lines)
(delete-indentation)
Action
Function
C-k
C-w
C-x DEL
M-k
Kill
Kill
Kill
Kill
(kill-line)
(kill-region)
(backward-kill-sentence)
(kill-sentence)
line
region
back to beginning of sentence
to end of sentence
Key
Action
Function
C-y
M-y
M-w
C-M-w
(yank)
(yank-pop)
(kill-ring-save)
(append-next-kill)
You can think of the kill ring as a stack, so you could continuously pop the kill ring to obtain earlier
batches of killed text.
6.1.4 browse-kill-ring
I often defer to browse-kill-ring to access my kill-ring history. I bind it to M-y, replacing (yankpop). Try it out, and see if it suits your workflow.
1
2
(use-package browse-kill-ring
:bind ("M-y" . browse-kill-ring))
Key
Action
Function
C-x r k
(kill-rectangle)
C-x
C-x
C-x
C-x
C-x
r
r
r
r
r
M-w
d
y
c
t string RET
(copy-rectangle-as-kill)
(delete-rectangle)
(yank-rectangle)
(clear-rectangle)
(string-rectangle)
1
2
(use-package expand-region
:bind (("C-=" . er/expand-region)))
6.3 Zap-to-char
As an ex-vim user, I miss the ct and dt key dearly. Fret not, for what vim can do, emacs can do
better.
zap-up-to-char does exactly what it says it does: it kills up to, but not including the ARGth
occurrence of CHAR.
1
2
3
4
5
(use-package zzz-to-char
6.4 Multiple-cursors
Multiple cursors would be familiar functionality to Sublime Text users. Its the perfect tool for
many things, including editing variable names with visual feedback.
1
2
3
4
(use-package multiple-cursors
:bind (("C->" . mc/mark-next-like-this)
("C-<" . mc/mark-previous-like-this)
("C-c C-<" . mc/mark-all-like-this)))
I use it in conjunction with expand-region: expand-region to select the keyword (variable names,
for example), and use C-c C-< to select all instances of the variable, and simply type over it.
6.5 Templating
yasnippet is a templating system, allowing you to type an abbrieviation and automatically expand
it into function templates with <TAB>. This feature is similar to the one offered by Textmate; in
fact, the templating language is inherited from it.
1
2
3
4
5
(use-package yasnippet
:diminish yas-global-mode yas-minor-mode
:defer 5
:init (add-hook 'after-init-hook 'yas-global-mode)
:config (setq yas-snippet-dirs '("~/.emacs.d/snippets/")))
Andrea Crotti maintains an official repo for yasnippet templates. It supports many languages and
major-modes. I recommend forking the repository as I did and cloning it as a git submodule
under ~/.emacs.d: this way you can add your own templates and version control them. I had set
the yas-snippet-dirs to ~/.emacs.d/snippets, so following that configuration:
6.6 Autocompletion
Text completion in Emacs has Emacs users split between two major factions: autocomplete and
company-mode. Both have similar feature sets, but it is generally argued that company-mode is
more feature-rich.
The following snippet installs company-mode.
1
2
(use-package company
:defer 5
3
4
5
6
7
8
9
10
11
12
13
:diminish company-mode
:init (progn
(add-hook 'after-init-hook 'global-company-mode)
(setq company-dabbrev-ignore-case nil
company-dabbrev-code-ignore-case nil
company-dabbrev-downcase nil
company-idle-delay 0
company-begin-commands '(self-insert-command)
company-transformers '(company-sort-by-occurrence))
(use-package company-quickhelp
:config (company-quickhelp-mode 1))))
One thing that people miss from autocomplete is documentation popups. We add that functionality
with company-quickhelp. Another notable setting made was to set the delay for autocomplete to
0. Play around with the numbers and see what youre comfortable with.
Note that company-mode is merely a framework for autocompletion. To enable autocompletion for
various languages, youd need to install various company backends.
7 Project Management
In most cases, your work is not limited to a single file. Instead, its comprised of multiple files
residing in a parent directory, or perhaps even version-controlled with Git or the likes.
While Emacs does not ship with project management tooling, there are a few quality libraries that
help you with that.
7.1 FFIP
find-file-in-project, or ffip in short, provides quick access to files in a directory managed by versioncontrol (git/svn/mercurial). Its intentionally kept simple. It uses GNU find under the hood, which
makes it suitable even for large codebases. The default interface has been recently changed to ivy
(introduced earlier). Look no further than ffip for a simple project-management tool.
1
2
3
4
(use-package find-file-in-project
:bind (("s-f" . find-file-in-project)
("s-F". find-file-in-current-directory)
("M-s-f" . find-file-in-project-by-selected)))
The functions are so useful they deserve a short keybinding: s-f is what Id go with.
7.2 Projectile
Projectile is a different beast, leveraging a variety of tools to be a performant project interaction
library. While ffip aims to be a minimalistic and fast file-switcher for projects, projectile aims to
be the all-encompassing project-management tool. It has certainly proved to be the only one youll
need.
Here are some handpicked features Projectile has to offer, as seen on the Github page:
I bind the projectile keymap to C-x p. If you use ivy, set the projectile-completion-system to
ivy, and install counsel-projectile, which adds more ivy-friendly functions for projectile.
1
2
3
(use-package projectile
:demand t
:init (projectile-global-mode 1)
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
(def-projectile-commander-method ?s
"Open a *eshell* buffer for the project."
(projectile-run-eshell))
(def-projectile-commander-method ?c
"Run `compile' in the project."
(projectile-compile-project nil))
(def-projectile-commander-method ?\C-?
"Go back to project selection."
(projectile-switch-project))
(def-projectile-commander-method ?d
"Open project root in dired."
(projectile-dired))
(def-projectile-commander-method ?F
"Git fetch."
(magit-status)
(call-interactively #'magit-fetch-current))
(def-projectile-commander-method ?j
"Jack-in."
(let* ((opts (projectile-current-project-files))
(file (ido-completing-read
"Find file: "
opts
nil nil nil nil
(car (cl-member-if
(lambda (f)
(string-match "core\\.clj\\'" f))
opts)))))
(find-file (expand-file-name
file (projectile-project-root)))
(run-hooks 'projectile-find-file-hook)
(cider-jack-in))))
Append all these code into :config for the projectile package.
7.4 Magit
Magit is an interface for Git. It is an absolute joy to use, and is one of the main reasons I stuck
with Emacs after a period with Vim.
1
2
3
4
5
(use-package magit
:bind (("C-x g" . magit-status)
("C-x M-g" . magit-blame))
:init (setq magit-auto-revert-mode nil)
:config (add-hook 'magit-mode-hook 'hl-line-mode))
Surely you can figure out the basics like adding remotes, fetching, and committing with such a
simplified interface. Heres a great tutorial on how to perform rebases, squashes and the like easily
with Magit.
8.1
golden-ratio
1
2
3
4
5
(use-package golden-ratio
:diminish golden-ratio-mode
:config (progn
;;(add-to-list 'golden-ratio-extra-commands 'ace-window)
(golden-ratio-mode 1)))
If youre using ace-window, uncomment the line for golden-ratio to function properly.
8.2
aggressive-indent
Keep your code nicely aligned while you hack away at more important stuff. Remember to disable
this for languages that depend on indentation for syntax, like Python.
1
2
3
(use-package aggressive-indent
:diminish aggressive-indent-mode
:config (add-hook 'prog-mode-hook 'aggressive-indent-mode))
8.3
which-key
Which-key is a godsend when youre first starting out using Emacs. I still refer to the list of
keybindings it shows from time to time.
1
2
3
(use-package which-key
:diminish which-key-mode
:config (add-hook 'after-init-hook 'which-key-mode))
8.4
volatile-highlights
Volatile-highlights provides visual feedback for operations such as yanking by highlighting the
relevant regions.
1
2
3
(use-package volatile-highlights
:diminish volatile-highlights-mode
:config (volatile-highlights-mode t))
8.5
firestarter
firestarter lets you execute commands (including shell commands) on save. Example use cases
include compiling SASS files, and compiling a program.
1
2
3
(use-package firestarter
:bind ("C-c m s" . firestarter-mode)
:init (put 'firestarter 'safe-local-variable 'identity))
8.6
git-gutter+
I use git-gutter+ primarily for showing on the left side what parts of my files have changed. It also
has additional features like staging hunks for commits, but I use Magit for that. You can take a
look at the Github page for more details.
1
2
3
4
5
6
7
8
(use-package git-gutter+
:init (global-git-gutter+-mode)
:diminish git-gutter+-mode
:defer 5
:config (progn
(setq git-gutter+-modified-sign "==")
(setq git-gutter+-added-sign "++")
(setq git-gutter+-deleted-sign "--")))
9 Miscellaneous Goodies
9.1 Minimizing Startup Time
9.1.1 Emacs Daemon
One way to avoid all perceived boot time, is to start emacs during the system boot as a daemon.
This is the option I have gone with.
All you need to do add the Emacs daemon to auto-start:
emacs --daemon
I use systemd instead. For this option, create a user systemd service file with the following content:
To enable the service on startup, just do systemd enable --user emacsd.service.
1
2
(use-package esup
:defer t)
Next, just execute esup with M-x esup. A separate emacs process will start, and the profiling
results will be returned in a separate window, which would look like this:
1
2
3
4
(use-package keyfreq
:config
(keyfreq-mode 1)
(keyfreq-autosave-mode 1))
After a period of Emacs usage, run M-x keyfreq-show. Perform micro-optimizations based on the
results. After which, M-x keyfreq-reset to rinse and repeat.
9.4.1 M-x
Lets face it. M-x is actually pretty damn hard to hit. x is highly inaccessible, not even on alternative
keyboard layouts like Dvorak.
In prelude, M-x is bound to C-x C-m. I bind M-x to M-a, which is originally bound to backwardsentence, which I dont use much at all. Both are viable options.
9.4.2 ergoemacs
ergoemacs was developed to bring familiar keys to Emacs, as well as to reduce risk of RSI. While
you could follow the instructions on the webpage to have it installed, I recommend studying their
keybindings and adopting the ones you think youll like.