Package Manager

Repositories

By default, only GNU’s repositories are available to the package managers of Emacs. I also want to use Melpa and org-mode’s repository, so let’s add them! Note that the stock elpa repository is renamed to gnu due to the addition of another Elpa repository, nongnu, which will hosts packages that do not conform to the FSF’s copyright assignment. Both the gnu and the nonfree repositories are Elpa repositories now, and they are renamed here in order to avoid any confusion between the two of them. Melpa is a community-maintained repository which contains an absurd amount of Emacs packages.

(setq package-archives '(("melpa"  . "https://melpa.org/packages/")
                         ("gnu"    . "https://elpa.gnu.org/packages/")
                         ("nongnu" . "https://elpa.nongnu.org/nongnu/")))

Straight

For my package management, I prefer to use straight (GitHubopen in new window). This is due to its capacity of integrating nicely with use-package, which also supports general which I use for my keybindings (see below), but also because with it, I can specify where to retrieve packages that are not on MELPA or ELPA but on GitHub and other online Git repositories too. First, let’s bootstrap straight.

(defvar bootstrap-version)
(defvar comp-deferred-compilation-deny-list ()) ; workaround, otherwise straight shits itself
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

Now, we can refresh our package list in order to be able to install stuff.

(package-initialize)
(unless package-archive-contents
  (package-refresh-contents))

From time to time, I fork some packages either because I’m trying to implement something new in said package, or because the package is unmaintained, and I want to continue developing it a bit more. Straight provides a nice feature for using forks of a package with its :fork option. If set to t, then straight will attempt to retrieve the package with the same name but with a different username on the same host. This username is retrieved through the following variable:

(setq straight-host-usernames
      '((github . "Phundrak")
        (gitlab . "Phundrak")))

The huge advantage of straight is it clones through git the packages it installs. This means development can be done directly on the downloaded package. However, Forge (a Magit extension for interacting with websites such as GitHub, GitLab, and such) interacts by default with the forge described by the origin remote, which isn’t necessarily the one I want Forge to interact with by default. Therefore, straight.el will name all default remotes straight to avoid any name collision with my regular development flow.

(setq straight-vc-git-default-remote-name "straight")

We finally come to the use-package installation. This is done like so:

(straight-use-package '(use-package :build t))
(setq use-package-always-ensure t)