Packages

Author

Marie-Hélène Burle

Emacs is a huge and endlessly customizable toolkit out of the box. In addition, countless external packages have been (and continue to be) developed to add yet more functionality. This section will cover the basics of package installation and customization.

Package manager

There are multiple ways to manage external Emacs packages. package.el is the built-in package manager. Several packages provide alternative package management systems. My favourite by far is straight. It allows to install packages from anywhere (MELPA, ELPA, Emacsmirror, local server, GitLab, GitHub…). Packages are cloned as Git repos instead of tarballs, making it easy to revert to an old version, edit, etc. Packages are also compiled natively for better efficiency.

To install straight, you need to put the following in your init file:

;; Install straight
(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 6))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

Then you need to evaluate this code. For this, you can close and re-open Emacs. Alternatively, you can select the paragraph and run M-x eval-region.

Package location

Except for the init file which, by default, lives directly in your home directory, all Emacs configuration files get created in a directory called .emacs.d located in your home directory. This is where Emacs will store your installed packages.

If you use straight to manage your packages, a straight directory will be created in ~/.emacs.d and in it, you will see two subdirectories:

  • repos which holds the cloned Git repos of the packages and
  • build which holds the built packages.

Package loading and configuration

Use-package is a modern package that allows lazy loading of packages for a speedy startup and a neat way to configure Emacs package by package.

Due to the huge popularity of this package, starting with Emacs 29, use-package ships with Emacs and doesn’t need to be installed. Prior to Emacs 29, it can be installed (using straight) with:

;; Install use-package (unnecessary for Emacs >= 29)
(straight-use-package 'use-package)

Installing packages

When you install a new package, the best thing to do is to read the README carefully and start with minimal configuration. A growing number of packages will give you configuration instructions using use-package.

With usage, you can add more configurations, either in your use-package declaration or using the easy customization interface.

Example: ESS package

First, let’s create a file called test.R with the following R code in it:

a <- c(1, 2, 3)

b <- 5L

Your turn:

  • What is the major mode used by Emacs?
  • Why do you think that is?

To get the proper major mode which will give us syntax highlighting and indentation for R, as well as a lot of additional functionality, we need to install the package ESS (Emacs Speaks Statistics).

To install it using straight, you can put the following in your init file:

(straight-use-package 'ess)

Or you can use the perfectly equivalent expression:

(use-package ess
    :straight t)

The advantage of this second syntax is that you can now add any customization you want to the use-package declaration.

Your turn:

After evaluating this snippet of code in your init file, re-open test.R.
- What is the major mode now?
- Notice that we now also have syntax highlighting for R.

Now that we have a proper mode for R, we can even use Emacs as an IDE.

First, of course, we will need to have R available. Send Emacs to the background with C-z and load the R module:

module load r/4.3.1

Then bring the test.R file back to the foreground by typing fg and Enter in the terminal.

Now, you can use the kbd C-c C-c, bound to ess-eval-region-or-function-or-paragraph-and-step, to send sections of code from the script to a buffer containing a running R console.

If you want to have two windows, one with your script on the left and one with your running R process on the right, you need to split windows, select the proper buffers to display in each window, and move the cursor to the script. This is easy to do, but a bit annoying to have to do each time you want to run R from script.

Instead, you could save a keyboard macro with all these commands and set a kbd for it. Or you can define a function doing all this and set a kbd. Let’s do it as an example of configuration using use-package:

(use-package ess-r-mode
    :straight (ess)
    :config
    (defun my-start-r ()
      (interactive)
      (split-window-right)
      (R)
      (other-window 1))
    :bind (:map ess-r-mode-map
                ;; start R process from script
                ("C-c r" . my-start-r)))

Note that we had to edit our use-package declaration a little because ESS provides modes for both R and Julia. This is a weird case. Usually, you don’t have to make any such change when you add configuration to the use-package declaration.

After evaluating this declaration, you can now launch an R process from any R script, in a window to the right, with the kbd C-c r (after which you can evaluate your R script chunk by chunk with C-c C-c).