Hello and welcome everyone at EmacsConf 2022.
I'm Andrew Tropin, and today
we will talk about my Emacs setup.
I will tell you the story behind it.
We will discuss what rde and rde Emacs are,
and we'll make a small Emacs configuration.
My original motivation was to have
a ready for work development environment
which is reliable and guaranteed to work
every time I need it,
preferably performant and consistent.
I say development environment,
but it actually applies to
many other working environment,
especially text-heavy.
An easy and obvious solution is to
pick one of existing configuration frameworks
like Spacemacs, Doom Emacs, Prelude,
or something else,
and to get a pre-configured Emacs
in a minute with all bells and whistles.
But the problem is: only Emacs.
In reality, your working environment consists
not only from elisp packages,
but also from system packages
and their configurations, project libraries,
compilers, building tools, etc.,
and thus you already have at least
three, or more likely, five things
for managing your environment:
configuration, Emacs configuration framework,
Emacs package manager, system package manager,
system/dot files configuration manager,
project/language package manager
and maybe something else.
Even having our Emacs configuration
and package manager covered by framework
we still have a lot of things
which we have to interact with,
keep in sync, and more importantly,
each of them can break.
But by "works every time," I mean
even if I updated my system packages,
configurations, I migrated to a different machine,
someone on my team updated project dependencies,
I can get back to work in a matter of seconds,
or maybe in some cases, minutes.
If I have multiple tools
for managing my environment
and even one of them is broken,
the whole setup is broken.
Also, if one of them doesn't support
deterministic rollback,
I can't guarantee the reliability
of my working environment.
I can't be sure that I will be able to
rescue or revive it.
The less points of failure we have,
the easier to stay sane.
Imagine some late breakage notice
when you did update a few hours or days ago
and found it later, and you have
a few different tools involved.
It will be really hard to find the cause
and to make everything work again.
Is it possible to have one tool
to cover all the needs I described above?
Yes, almost. With this tool,
you can get a reliable setup.
Now, I talk about functional package managers.
Functional package managers allow us to
manage systems, users, Emacs, project/
language packages, and their configurations.
But more importantly, it allows to do it
in a declarative and reproducible manner.
That means you just define what you need,
and those tools build it for you.
No matter what was before, you get what you asked for.
It doesn't matter what time of day,
what you did before, what other packages
you have installed previously.
You just ask for something, and you get it.
Two years ago, I did a talk at EmacsConf 2020
where I demonstrated a prototype of
Emacs configuration managed by Nix.
Originally, I wanted to base my work on
an already existing Emacs configuration framework.
But later, I decided that it will be easier
and a little more flexible
to start from ground up.
After the first prototype in Nix,
I decided to switch to Guix. To make it short,
Guix is another functional package manager,
but more freedom- and reproducibility-oriented,
and written in only one language (Guile Scheme)
instead of few custom-made Nix DSL, Bash, and C++.
So now I can write Lisp code, while this code
writes another Lisp code. Very neat indeed.
Unfortunately, at the moment, there was no tool
to manage user configurations,
also known as dotfiles, with Guix.
So I wrote one. And now it's a part of GNU Guix
and called Guix Home.
What do we get from this one tool?
We can use one language to describe the whole system,
the home environment, the project environment,
and everything else.
We don't need to worry about
to keep different tools in sync
and to integrate them between each other.
Also, using one language to describe
the whole configuration makes it possible
to share values between different parts of the system.
For example, color scheme, fonts, and much more.
To sum up the first part of the talk:
I want a working environment which is ready for work,
configured in minutes to almost what I want.
That means it should have some batteries included.
It should be reliable.
I want to get back to work in seconds
even if I broke something
or someone else broke something.
For example, using rollbacks.
It would be nice if it will be performant.
It's a little subjective thing,
but it's nice when things are snappy.
And it's cool when things are consistent.
Different interfaces have
the same way of interactions with them.
Let's get to the next part,
and let's discuss what rde is.
Originally it was my dotfiles repo,
but it grew into something bigger.
Now, it's a set of tools on top of
GNU Guix, Guix System, and Guix Home.
You can treat it as a GNU/Linux distribution,
system and home environment manager
or configuration framework,
project environment manager
(like virtualenv, but on steroids),
and Emacs distribution.
Usually, you just pick a few features,
parameterize them and ask the tool
to create an operating system for you,
a home environment, project environment,
or Emacs configuration.
That's it. That's simple.
And what rde Emacs is and how it tastes...
It's like an ice cream, vanilla-flavored.
No fancy macros for configuration, just plain Elisp.
You can find in almost every
personal Emacs configuration,
built-in or vanilla-flavored packages
are in priority over external
or very fancy packages.
There is practical reason for this.
Maybe sometimes you don't get the things
you're used to in other text editors,
or maybe even in other Emacs frameworks,
but we want to keep the final result consistent,
so you can apply the same interaction patterns
in different situations and extend your expectations
from one tool to another,
from one package to another.
For example, we encourage people
to use the minibuffer completion
with orderless and vertico for many tasks:
code navigation, file navigation,
looking through your emails,
or just for jumping around.
Let's see.
First, create a new Emacs instance
and open a repository with my configuration.
You can see the source code.
Let's open another file which contains
Emacs-related features.
You can see I use imenu,
and I can filter the list using minibuffer.
Now let's open the Magit interface,
and now I want to navigate through
this long list of things here.
Some of them staged. Some of them are recent commits.
Some of them are untracked at all.
I can open imenu: the same interface,
but for now, I can navigate around
the Magit sections and files which are present here.
If I want to navigate project files,
I use almost the same interface.
I can use the same patterns to filter out
files in my project or items in magit-imenu.
Very similar and very consistent.
Also, we try to have hotkeys consistent
across different packages and parts of Emacs.
We usually don't provide alternatives on what to use.
We provide only one package for one task.
But of course this is
a configuration framework after all.
You can declare your own features,
implement them yourself,
and use whatever you want.
Let's get to some real-world examples.
It's always easy to show
how things get appended,
how things get installed,
but usually people don't show
how they remove things,
because it's usually painful.
But in our case, it's not.
Let's take my configuration,
let's find feature-emacs-vertico.
Vertico's just used to show
this fancy completion UI
that you can see here.
If I disable this feature
and rebuild my home environment,
Emacs will lack this feature.
It may take some time. It was quite fast,
I didn't expect it.
I have Emacs. As you can see here,
now it doesn't have this completion UI anymore.
I just commented it out,
rebuilt my home environment,
and this thing disappeared from Emacs.
But what if I broke something?
I just call guix home roll-back command
and launch Emacs again, and you see
now we have vertico back.
Very good.
Reliability is one of the most important qualities
of working environment.
We can always get back to
the working state of our environment
and be sure that we do the things we want.
Now let's see another example.
Here I have a mastodon,
a post which contains a gemini link.
I can click it, and you see it opens emacsclient,
it renders this gemini capsule,
and we can read all the posts of this guy.
Very cool.
But what if I go back to my configuration,
we'll find a feature related to elpher,
the application which handles gemini links,
we'll comment it out,
and we'll rebuild my home environment.
What I expect here is that
when I will be clicking the link,
emacsclient won't pop up anymore.
Cool.
We rebuilt it and let's click the link.
Now you see, it just opens another tab
which doesn't do anything useful.
Cool.
Why it is important?
It is important because every time
you install something and you want to remove it,
some parts depending on it can be broken.
And also important in the other way around.
Sometimes you want to install something,
and it requires a few steps.
For example, if you want to have
a docker.el in your Emacs,
you need not only docker.el itself
and configuration for it,
you also need to add your user to the docker group.
But before it, you need to create this group,
and you also need to
define a system service and run it.
Also you need to install docker package,
docker-cli package, and containerd package.
You can forget every of this small step,
but if it in your declarative configuration
in one place, and you just ask
to enable this feature, each of those steps
will be performed automatically.
If you don't need docker anymore,
you just disable the feature,
and all the effect of all those steps
will be removed from your system.
I won't be showing it because it probably will
take more time for reconfiguring,
but you can experiment with it on your own.
Let's do another interesting thing.
Let's construct a small
Emacs configuration from scratch.
Who's this?
I will open a file which contains only
emacs-portable feature and feature-user-info.
Now I will build an environment,
and inside this environment,
I will launch a new Emacs instance.
As you see, it's very different
from what you saw previously.
And it's almost barebones.
It doesn't contain anything
except user-mail-address
which is set to my mail address,
and user-full-name.
How it works:
In feature-user-info, I define a few values.
Those values are obtained by Emacs
feature-emacs-portable
and set inside Emacs configuration.
But let's enable a few more features.
I will do it in one go
because we already saw how it works overall.
Let's build another Emacs with Emacs configuration.
The interesting thing about this Emacs instance
is that it doesn't contain anything
that I have in my usual Emacs.
For example, I don't have much here.
I don't have make installed, and so on.
But we have feature-loader-portable package
which just requires a few configure packages.
Let's move it to a separate workspace.
First of all, configure-rde-emacs-portable
which just sets a few variables.
rde configure-keycast which just shows
something on the modeline
which demonstrates the last hotkey pressed
and the command which was invoked.
We can enable which-key,
and now when I type a prefix,
I can see all the possible continuations
for this prefix.
I can enable vertico,
and you can see, now we have nice completion UI.
We can enable completion-related improvements
and now I have not only UI itself, but also
some notes here near each command,
and ability to use regular expressions
or some orderless matching.
We can enable eshell,
and now I have a hotkey for invoking Emacs shell.
I don't have hotkey for vterm yet,
but I can enable it,
and now I have a terminal inside my Emacs.
As you can see my usual shell is Zsh,
but here I have a plain bash.
Let's enable feature-git,
and now I will be able to open my project.
And inside this project,
I will be able to open Magit
and navigate around using imenu.
Let's do few more things.
Let's enable Org Roam
so I will be able to open my EmacsConf notes.
Let's enable configure-emacs.
As you can see, the way it displayed updated.
Let's enable configure-appearance,
and you see the appearance of Emacs changed radically.
And also, let's change the faces.
And now you see almost my setup
that you saw previously,
but we build it from small tiny pieces.
A little summary:
rde is the one tool that you can use
to manage the whole computing experience.
It consists of composable components,
and actually, it provides
a reliable configuration framework.
You always have a rollback.
You always can switch to a generation
you used a week ago.
And of course, it's reproducible and declarative
which is also very cool.
rde Emacs is a part of rde
but it can be used separately.
You can think of it as an Emacs distribution
which is vanilla-flavored, consistent,
well-integrated, and self-contained.
That's it for today.
Don't hesitate to contact me
via email or any other way.
Thank you everyone for your attention
and see you in a bit.