Emacs Config From Scratch, Part Two: Projects and Keybindings
In this second post in my Emacs from Scratch series, we’ll set up a way to manage projects, quickly find files, set up custom keybindings, interact with Git and open a terminal inside Emacs. · Frankfurt, GermanyThis is the second post in my Emacs From Scratch series.
In Part 1, we’ve set up the UI and evil mode. Today we’ll set up a way to manage projects, quickly find files, set up custom keybindings, interact with Git and open a terminal inside Emacs.
Table of Contents
Project manager
Vim is usually terminal-first; you navigate to a directory and open Vim. Emacs is the other way around; you start Emacs, open a project and maybe a terminal buffer (see Terminal further down).
Let’s set up Projectile to manage our projects and quickly find files.
You can now run M-x
(a.k.a. Opt-x
on macOS) and type
projectile-add-known-project
to add a project as well as
projectile-switch-project
to open a project.
This is neither fast, nor discoverable. Let’s set up some custom keybindings.
Custom keybindings
Before we define our own keybindings, we need to do something to improve discoverability. which-key will show available commands as you start a keybinding sequence:
We’ll use general.el because it makes
it super easy to define keybindings and allows us to define them in a
use-package
function.
We’ll have SPC
as our leader key, which allows us to press SPC
and have all our custom keybindings show up.
We’re using :which-key
to add a description that will show up next to the
command.
To add custom keybindings to Projectile, we need to edit the use-package
definition and move it after the use-package general
function:
Now we can press SPC
and get suggestions that we can navigate along.
SPC SPC
lets you open a file in the current project (or a project if none is open),
SPC b
opens buffer options, SPC p
project options, etc.
This is what it looks like:
But when you try to find a file, or add a project, you’ll notice that this is clunky as you need to type the exact path for it to work. Let’s fix that.
Fuzzy finding
We’ll be using ivy as our generic completion frontend. This will make choosing files and projects a lot more ergonomic:
Now we get a list of possible entries and live-search.
Git integration
To manage source control, we’ll use Magit, which is–rightfully–widely considered to be the best Git client ever:
To make Magit work nicely with Evil, let’s add evil-collection:
In addition we need to add this to the :init
block of use-package evil
to
prevent evil and evil-collection interfering:
Now SPC g g
will open up the current Git status.
You can stage single files with s
, all files with S
and commit by pressing cc
.
Finally, we want to highlight uncommited changes in the gutter:
Terminal
Even though we’ll try to make everything work from inside Emacs, sometimes it’s just quicker and easier to have a shell.
We’ll use vterm as a terminal emulator we can use inside emacs.
We’ll also install vterm-toggle, a package that allows us to toggle between the active buffer and a vterm buffer:
Pressing SPC '
will open a terminal. Pressing it again will hide it, but keep any processes running.
Small tweaks
As every time, we’ll do a few small tweaks:
Ctrl-u
work like in Vim
Make Add the following to the :init
block of use-package evil
:
Comment lines
We want similar behaviour to commentary.vim and comment objects in/out with gc
:
Optimizing the garbage collector
We’ll use GCMH, “the Garbage Collector Magic Hack”, to minimize GC interference with user activity:
Move this up to be the first package loaded after configuring use-package
, to improve start-up time.
Don’t use ESC as a modifier
If you want to exit a menu, <escape>
is the key of choice, esp. coming from Vim. Let’s match that behaviour:
Conclusion
We now have everything we need to manage projects, navigate to files, run terminal commands and manage Git. Starting with this post, I’m using this very setup to edit this series.
In part 3, we’ll set up Tree-sitter and, if available, LSP for Rust, Go, TypeScript and Markdown.
Subscribe to the RSS Feed so you don’t miss the following parts, and let me know what you think!