Werden wir Helden für einen Tag

Home | About | Archive

Advent of emacs #1: How I do package management in emacs

Posted on Dec 1, 2022 by Chung-hong Chan

While the programmers (surrounding me) are crazy about Advent of Code, I wanted to try something else. I really like the “Advent of X” format, but I don’t want to solve some artificial puzzles created by a game master. I have enough puzzles to solve in my real life.

Skippable introduction

In Taiwan, there is a campaign called “Ironman”. The idea is to write one technical blog post a day for 30 days. The campaign is brutal because it usually happens in September and there are usually two important holidays in-between. Maybe I can import this campaign from Taiwan. Instead of writing a technical blog post a day for 30 days, maybe I can write a short technical blog post a day for 25 days. So that it is also similar to the “Advent of X” format.

Then it came the question of write about what. My original plan was to write about computational reproducibility and use the 25 days to write 25 blog posts about it. But to be honest, I am not a subject matter expert. It can be a good thing because I can see things and learn things from a fresh perspective. But I can also see that my December is gonna be a bit chaotic and the project is a bit too ambitious. Maybe it is better to scale it down a bit.

So, I decided to write about the next thing on the list: emacs. So, here is the plan: I am going to write a series of blog posts called “How I do x in emacs.” It’s suitable because I have an emacs.ch mastodon account. Also, these blog posts will be not useful for >95% of the programmers. Even much less useful for the people surrounding me, mostly communication researchers who won’t program.

I hope these blog posts would be useful for novice emacs users. I will cover topics that are super basic. Admittedly, I am also a novice, despite the fact that I have used emacs almost daily and exclusively for almost 2 decades. I think I can only “get” what emacs is recently.

Keep in mind also that I am talking about “How I do” thing. It’s opinionated. I know, I know. I am always wrong.

Day 1: How I do package management in emacs

emacs is incredibly extensible. There are also many contributed packages for emacs. Using the blank-state emacs won’t take one very far 1. The same way a blank-state computer is usable, but not very useful. One will need more software to make it useful. And also more fun.

Traditionally, one have to install package using the now built-in package. On a blank-state emacs, one can type M-x list-packages to list out all the available contributed package that can be installed. Select the ones you want to install, click the “install” button, and boom. It’s easy.

But the problem with this approach is that it is tedious. Suppose one has two computers and one wants to install the same package on these two computers. One will need to do it manually twice. Suppose one has formatted the computer, it’s needed to do manually again.

The solution to this is very similar to package.json (npm), requirements.txt (pip), or Gemfile (gem). The idea is to document all the emacs packages that one needs in a text file. Then, emacs looks into that file and install all the packages automatically. That file, for many users, is the configuration file. If you haven’t had your own, maybe it is a good time to have one now. The simplest way to have one is to create an empty text file called .emacs in your user directory.

So, what should be in a configuration file? You need to write emacs lisp there. Before you close this browser tab, I can assure you that it is easy. It is incredibly easy now. Don’t close this tab!

The idea is to use use-package macro (Github) by John Wiegley et al. One can install use-package by M-x list-packages. But the very idea is to make the configuration repeatable. So I put the following at the very beginning of my emacs configuration.

(require 'package)
(add-to-list 'package-archives
			 '("melpa" . "https://melpa.org/packages/"))
(when (< emacs-major-version 24)
  ;; For important compatibility libraries like cl-lib
  (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
(package-initialize)

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

(require 'use-package)
(setq use-package-always-ensure t)

The above code snippet does two things: 1) it enables melpa, another emacs package repository; 2) install and activate use-package automatically if it is not yet installed. Punkt.

Now, restart emacs, use-package should have been installed. The very idea of use-package is actually very similar to the point 2) above. If one has (use-package all-the-icons) in the configuration file, it means: install all-the-icons and activate it if it is not yet installed; otherwise, activate it.

For example, if you really like magit (I really like magit, I will certainly write about it in this series), quarto-mode and rust-mode and want to install them, you can simply put this in your configuration file.

(use-package magit)
(use-package quarto-mode)
(use-package rust-mode)

Restart your emacs and boom, you have all 3 installed and activated (try: M-x magit).

As this post is only about “package management”, I can stop from here. But you can also do configuration with use-package. Let’s say:

(use-package rust-mode
  :config
  (add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode)))

(use-package magit
  :init
  (global-set-key (kbd "C-c g") 'magit-status))

So that you open .rs, it will use rust-mode. And press C-c g will activate magit. For more information, please refer to the README.


  1. Well, one can now download some emacs distributions such as Doom Emacs, which can take you very, VERY, far. But I am talk about the blank-state emacs one would get by, say: sudo apt install emacs


Powered by Jekyll and profdr theme