Emacs Configuration

If I am totally honest, this configuration has become, over the years, a succession of hacks found in various GitHub issues to solve surprising problems. That being said, I cannot help but be a little proud of the result.

Package Management

We use melpa, an Emacs Lisp Package Archive, to get use-package package which provides a macro to isolate package configuration.

Before going any further, we first make sure we have an up-to-date description of the packages archive available.

As far as I know, emacs does not have any built-in mechanisms to automatically fetch a list of packages. There are several way to achieve that, one is Cask. I mention it here because it looks like a pretty good tool, but it is not available in the Archlinux repositories I am using (if you exclude the AUR package). Fortunately, I’ve quickly found out it is easy to define a function which does pretty much what I need:

In the first version of my configuration file, I was using the ensure-package-installed function to list all the packages I was using. Now, as said before, I use the use-package macro.

As stated in the use-package README, the macro is not required to be available at runtime, so lets require it as they say:

Look & Feel


I use my homegrown collection of themes, based on colorless. It is not yet on Melpa, for no good reason. So instead I have to load it manually.

For a reason I do not fully understand, emacsclient does not work very well with changing the color of the cursor. I have found a solution on StackOverflow.


The default status line on Emacs does the job, but sometimes it is good to just be a bit fancy.

Keyboard Layout

This is macOS specific, but it looks like emacs on macOS has some trouble with the Meta key by default. So, following the advice read from the EmacsWiki, we just revert Emacs 22 settings.

I am a former vim user and I have switch to emacs mostly for Proof General. The only reason I ever consider making this move is because I ran into a blogpost which describes such a migration through the evil package, a way to get the vim bindings and modal functioning into emacs.

Note that, before loading evil, we need to tell it not to expand abbreviation on insert exit, see this Github issue if you want to know why.

Now, the think is I am a bépo happy user. It is quite different from qwerty and therefore I need to rebind a lot of things manually.

I use l rather than r to replace, because r is dedicated to moving inside a buffer.

I then remap hjkl and because I like to complicate things, I use this opportunity to fix an issue I had with vim for quite some times now: when you think about it, they really should be jklm instead (my index finger is always on the j, not the h.

For this to work, the mapping needs to be done both for the normal mode and the visual mode.

Because of this choice, n (next research result) is already used so I need to find something else. Its neighbor m is a perfect candidate.

I split my buffers a lot, so jumping from one buffer to another should be easy. The thing is, w is not the most easy letter to hit in bépo (probably because we do not have a lot of words which are using it), so I use à instead.

And because I really use this feature often, I decided it shall get its own mappings.

The letter w is also used in vim to jump at the begin of the next word (or to select a word in operator mode. Lets use é instead.

Lets M-c and M-v to copy and paste from X. To do that, we first need to define the following functions, found on one emacs configuration online.

The mapping can be made both in normal and insert mode.

Did I mention I am a former vim user? I need the escape key to work everywhere. I found the following snippet in the blogpost I mention earlier and it works well so far.

We should not forget the dired mode, because it can be useful to be able to move inside the directories content.

I want to be able to zoom and zoom at.

Finally, I really wanted to get back the capability to easily increment or decrease the next number on the current line. To do that, the evil-numbers package.

Minimal UI

First, lets simplify the look and feel of emacs. We do not need neither the scroll bar, nor the tool bar, nor the menu bar. Also, we can safely disable the startup screen.

In a similar manner, we do not need the cursor to blink. Lets keep the UI as simple as possible.

We can also change the way the scrolling works to get a behaviour a bit more smooth.

fill-column-indicator is install by default with linux packages, but not with Homebrew (macOs), hence we tell emacs to install it just in case.

I like to have vertical indicator of the indentation level, and the highlight-indent-guides appeared to be exactly what I was locking for.

The only fancy thing I want is to highlight the line on which my cursor is. It can be very useful when I am lost.

Line Numbers

Since its version 26, Emacs comes with a nice (and built-in) global-display-line-numbers-mode that I use in place of linum or nlinum.

Matching Parentheses

It is easy to make emacs highlights the matching parentheses (and to highlight mismatching ones too).

File Management

Rather than the built-in one, I use helm as my completion system. Especially, I really like the fuzzy match feature, even if sometimes it is annoying to hit space to specify two characters don’t have to be neighbors.

We also rely on projectile to have some kind of “project management” in emacs. The most useful feature of projectile is maybe to use the .gitignore file to filter the list of files available. And, it can be used with helm!

There is something I liked in vim and missed even more in emacs, it is the way the current directory is set. Basically, in vim, the current directory is the directory wherein vim has been started. In emacs, by default, it is the directory of the file of the current buffer! So it is quite different. Because I always start vim at the root of my projects, I can find something similar by using some feature of projectile so I can set the current directory to be the root directory of the project. Pretty useful!

And because I like binding, I now can search and open a file by hitting ~T— in normal mode.

Git integration

I have never taken the time to learn magit, so my emacs/git integration is pretty simple.

First, I rely on diff-hl to add in the fringe a diff indicator (is it a change? an addition? a deletion?). It is not always accurate, but it can be pretty convenient if like me you like to know what you did since your last commit in a glance.

Also, the git-commit package is a minor mode for when you write a commit message with emacs.

Parentheses Auto Pairing

The electric-pair-mode is pretty neat as it closes for you parentheses, brackets, etc. When your cursor is in front of a closing parenthesis and you type ), it does not insert a new parenthesis but just move the cursor. This is pretty cool as you know you can continue to type as if the mode is disable. From my point of view, it is the best of both worlds.

White Spaces

For now, I stick to 2-spaces over tabs when I can. But there are some folks out there who do not think the way I do and I want to be able to work with them. The dtrt-indent package provides a way for emacs to guess which indentation rules to follow based on the current file.

Following leading white spaces, we can deal quite easily with trailing ones. I never found myself in a situation where I wanted tailing white spaces. I know markdown relies on them to insert newlines within a paragraph, but I find this feature quite useless to say the least. So, I can safely delete them.

Now comes the funny part. It is probably one of the part on which I have worked the most. Basically, I wanted emacs to display spaces, tabs and newlines with dedicated symbols. I also wanted it to be discrete and I mostly succeeded for that last one.

Just for the record, you can do that pretty easily with vim:

set list
set listchars=eol:¬,tab:>,space:·

Using the whitespace-mode, we can basically do the same thing, but with some restrictions. First, do not change the background of any face, because it does not work very well with whitespace-* faces (basically, there is a good chance the default background will be applied to spaces…). Second, we cannot use global-whitespace-mode, because once again it does not play very well with space styling. There is a hack in this configuration file to disable whitespace-mode when the company tool tip appears (and enable it again when it disappears). It is similar to another hack to disable/enable fci-mode. Might as well say the way company handles the completion tool tip is broken.

Anyway, we configure whitespace-mode here, then enable it when we need it (for prog-mode and text-mode, and also coq-mode because it looks like the latter does not use prog-mode).

Core Modes

I’ve chosen to use company as my completion engine.

Out of the box, company does not work well with the fill-column-indicator package. Therefore, I had to find a workaround (yet another one, I would add). Basically, it makes company disables the fci when it needs to.

In addition, I use flycheck.

A lot of major modes I use derived from prog-mode, so I use prog-mode-hook to avoid code duplication.

In a similar manner, I use text-mode-hook.

Programming Languages


Irony is a pretty solid tool to work with C project. It needs additional packages to work with company and flycheck.

Common Lisp

I kinda like Common Lisp, and the slime mode for Emacs is awesome. The following code snippet assumes quicklisp (sort of package manager for CL) has been installed.


Until recently, I was using the archlinux package to get coq, but I had poor experiences with the coq-equations package. To fix that, I switch to an opam-based setup. It works well, and in particular I do not need to be root anymore to install packages. Unfortunately, this does not work out of the box with emacs + systemd.

We load proof general and we are ready to go.

I also use company-coq, but I disable prettification of operators, types etc. And, of course! The coq-mode is not using prog-mode. Unfortunately, flycheck supports coq but does not look into the _CoqProject file.

And that should be all for now.


The Elixir typical package is called alchemist.

Emacs Lisp

So would have guessed? I wrote at least one emacs package, in addition to this configuration. MELPA points several useful packages to be used by maintainer, so why not complying?


Cool kids use intero now. For this to work as expected, you will need:

  • hlint
  • apply-refact
  • stylish-haskell

You can install them easily using stack install, but this means your PATH environment variable needs to contains the \~/.local/bin directory.




The Ocaml typical package is called tuareg.


The ogmarkup is a markup language I have created for the ogma-project. It is intended to be used by storytellers to write their stories. I first define a major mode for ogmarkup.


To have syntax highlighting with org-mode export, we need to install htmlize. Unfortunately, it seems like the latter does not play well with fci-mode (yet another one, right?), but as usual, there is a hack somewhere in the internet.


PureScript is a pretty cool language that feels like Haskell, but transpiles to Javascript.


Cool kids use Rust too. Unfortunately, not all programming languages have there own intero and here the setup is a bit more complicated than Haskell or C, because we rely on more packages.

The major mode is rust-mode:

Then we need cargo to get an integration with the rust packages manager.

Racer is the completion engine of rust, lets configure that. The trick here is I have found a way to use rustup to decide which toolchain to use.

The package company-racer builds the bruige between racer and company.

And finally, flycheck-rust!


We use the ssass-mode to edit sass files.



Emacs as a RSS Reader

You know what vim users say. “Emacs is a great operating system, it only lacks a decent text editor.” Well, recently, I found myself willing to start using RSS again. lobsters is a great website and my primary source of blogposts to read, but not everything ends up there (and I like submitting links from time to time).

Temporary Files

And that is pretty much all!