UP | HOME

Speeding up `M-x man` in Emacs on MacOS

Table of Contents

Problem Description

Running `M-x man` in Emacs on MacOS takes a significant amount of time compared to Linux. On my Macbook Pro M4 laptop, it takes ~0.673 seconds.

Understanding `man.el`

The `man` function comes with Emacs, and can be found in your Emacs' installation's `lisp/man.el` file. A quick summary of the flow of the function is as follows:

  1. The `man` lisp function is invoked, possibly with an argument.
  2. The position of the cursor is used to guess what the user is about to look up.
  3. The `Man-completion-cache` is set to nil. This variable is defined at the top level of the file via `defvar`.
  4. The function `Man-completion-table` is called. This function is responsible for the bulk of the logic of displaying the possible completions, and filtering down the list via user input. This is the function that sets the `Man-completion-cache` list via running `man -k ^` to get the full list of possible man pages. This call to the external `man` process is what takes so long.

So… why is `man -k ^` so slow on Mac?

It turns out that `man` on Mac is not a compiled binary like on Linux, but a shell script that greps pages in "$MANPATH". Also unlike Linux, `man` on Mac does not use mandb to index the search path ahead of time.

The solution

We can make use of Emacs' advice functionality to remember the value of the Man-completion-cache in between calls. See the example below:

(defvar my/Man-completion-cache nil)

(defun remember-man-completion-cache (man-function &rest args)
  (unless Man-completion-cache
    (setq Man-completion-cache my/Man-completion-cache))
  (let ((result (apply man-function args)))
    (setq my/Man-completion-cache Man-completion-cache)
    result))

(advice-add #'Man-completion-table :around #'remember-man-completion-cache)

Miscellaneous learnings/thoughts

  • `defvar` is very weird. A variable bound via `defvar` is globally redefined when defined in a `let` binding.
  • Implementing a faster `man` on Macos would make for an interesting side project.

Date: 2025-11-08 10:10:05

Emacs 30.2 (Org mode 9.7.11)