Install Emacs

2025-02-08, Sat

Install Emacs tends out to be more complicated than I thought. This log file intends to record hiccups I've encountered.

1. on Debian GNU/Linux

Debian packages are provided in separate sections1, and emacs is available in the main section. However, this package lacks all the built-in documentation, which is somehow provided in the non-free section through package emacs-common-non-dfsg. Without documentation, the claim of "self-documenting editor" doesn't stand, so a bit tweak is needed.

  1. Open /etc/apt/sources.list and add "non-free" section after "main"
  2. Run "apt-get update", as usual
  3. Run "apt-get install emacs emacs-common-non-dfsg"

2. on macOS

The GNU site already provides instructions to install pre-built binaries of Emacs on macOS 2, 3. Follow any one would be sufficient.

However, things became tricker when I tried to compile from source.

First, install libraries required, in reverse order:

  • gnutls
  • nettle
  • gmp
  • libtasn1
  • help2man

The process was straightforward when I compiled these libraries from source one by one, …until gnutls-3.7.11, which is the current stable version provided on the official site4. When compiling from the source file downloaded, there was error thrown for file lib/system/certs.c. Turns out there is a one line change needed in the declaration of osstatus_error, like this:

static int osstatus_error(OSStatus status)

This problem was resolved long time ago in the master branch5. So it's not like a big issue anymore. Nevertheless, the experience worths a note.

Key Takeways

  • When there is error thrown while compiling source code from renowned resource, take a closer look at the error message. No need to get panic, upset, or scared.
  • If a solution is found for the error, consider to submit a patch to the source repo in order to give something back to the community.

3. Notes on Common Commands

This section records common commands & keybindings for some modes, major or minor.

3.1. Global Map

Key Binding Description
C-/, C-_, C-x u undo Undo some previous changes
C-?, C-M-_ undo-redo Undo the last ARG undos, i.e., redo the last ARG changes, ARGS default to 1

3.2. Major mode c-mode

Key Binding Description
C-c C-e c-macro-expand Expand C macros in the region, using the C preprocessor

3.3. Major mode org-mode

Key Binding Description
C-c C-c org-ctrl-c-ctrl-c Multi-purpose command that does things depending on context

3.4. Major mode emacs-lisp-mode

Key Binding Description
C-c C-e elisp-eval-region-or-buffer Evaluate forms in the active region or whole buffer
C-M-i completion-at-point Perform completion on the text around point

3.5. Major mode lisp-interaction-mode (for *scratch*)

Key Binding Description
C-j eval-print-last-sexp Evalute sexp before point

4. Notes on Common Practices

4.1. sudo edit file

Use TRAMP mode6 to sudo open and edit file by adding /sudo:: at the beginning of file name, e.g.

find-file (C-x C-f)
/sudo::/path/to-file

4.2. Sample Init Config

Sample init config could be found in the Emacs manual7 or online8. Nevertheless, I'll put another snippet below for reference:

;; ref: ~/.emacs.d/init.el
;;
;; save & restore desktop-session
(desktop-save-mode 1)
;; enable display of line number across all windows
(global-display-line-numbers-mode)

;; show column number in the mode line
(column-number-mode)
;; disable tool-bar
(tool-bar-mode 0)

;; ============================================================
;; configs that applies to speicifc mode or
;; depends on external program
;; ============================================================
;; running external lisp from within Emacs
;; in this case, it is SBCL that is being used
(setq inferior-lisp-program "/usr/local/bin/sbcl --noinform")

;; unlock the treemacs window width
(setq treemacs-width-is-initially-locked nil)

;; MELPA
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
;; Comment/uncomment this line to enable MELPA Stable if desired.  See `package-archive-priorities`
;; and `package-pinned-packages`. Most users will not need or want to do this.
;;(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)
(package-initialize)


;; Config LSP Servers
(require 'eglot)
(add-to-list 'eglot-server-programs '((c++-mode c-mode) "clangd"))
(add-hook 'c-mode-hook 'eglot-ensure)
(add-hook 'c++-mode-hook 'eglot-ensure)
(add-hook 'gdscript-mode-hook 'eglot-ensure)
(add-hook 'gdscript-mode-hook 'company-mode)

4.3. Correct PATH in shell

Aside from .bashrc and .bash_profile, macOS also updates $PATH based on content from /etc/paths.d/, which isn't recognized by inferior shell in Emacs. This could be corrected in init.el either through setting exec-path manually, or install package exec-path-from-shell9 from NonGNU ELPA or MELPA10 and introduce following content there:

;; ref: ~/.emacs.d/init.el
;; correct exec-path in inferior shell
(use-package exec-path-from-shell
  :ensure t
  :init
  (exec-path-from-shell-initialize))

Although this package is already available through the default nongnu archive, it is also provided on MELPA, which could be enabled like this:

;; ref: ~/.emacs.d/init.el
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
;; Or use the melpa-stable version instead
;;(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)
(package-initialize)

4.4. Connect to Database

Although we could connect to database in inferior shell, there is SqlMode provided by sql.el11 to offer a dedicated experience. Run command sql-help to see databases supported, e.g.

Use the following commands to start a specific SQL interpreter:

    MariaDB:	M-x sql-mariadb
    MySQL:	M-x sql-mysql
    Postgres:	M-x sql-postgres
    SQLite:	M-x sql-sqlite

Take PostgreSQL as an example, run sql-postgres and input connection info (i.e. username, database, host, password, etc.) and you will end up with a *SQL: Postgres* buffer within sql-interactive-mode.

4.5. Use LSP Server

Between Eglot12 and LSP Mode13, Eglot takes a minimal approach and works well with features already integrated into Emacs.

4.6. clangd for C

clangd is a language server for C, and its official site provides detailed guide on how to config it with eglot in Emacs14:

(require 'eglot)
(add-to-list 'eglot-server-programs '((c++-mode c-mode) "clangd"))
(add-hook 'c-mode-hook 'eglot-ensure)
(add-hook 'c++-mode-hook 'eglot-ensure)

Now we have almost real-time error message showing up along with code:

clangd-with-eglot.jpg

Figure 1: clangd with eglot

If the company-mode15 is also enabled for current file, we could have code completion as well:

clangd-with-company.jpg

Figure 2: with company-mode enabled

4.7. gdscript-mode error

The gdscript-mode16 installed from MELPA has the following error popped up while editing any function in the .gd file:

self-insert-command: Symbol’s value as variable is void: electric-pair-mode

This could be resolved by giving electric-pair-mode a value manually (or getting it into init.el):

;; turn on electric-pair-mode
(electric-pair-mode 1)
;; or turn off electric-pair-mode
(electric-pair-mode 0)

Also note that this problem seems to have been resolved in the latest source repo.

As for the GDScript LSP Server, it is integrated with the Godot engine. So add following config into init.el:

(add-hook 'gdscript-mode-hook 'eglot-ensure)

and ensure that the Godot Engine is running before opening any .gd file, then we should have automatic error reporting. Remember to enable company-mode if code completion is also needed.

4.8. Set Up Common Lisp development environment

There is this online post17 that details how to set up an SBCL Common Lisp dev environment in Emacs, which could be summarized as:

  • Install SBCL18 (Steel and Bank Common Lisp) as interpreter
  • Install and config Quicklisp19 for package management
  • Install SLIME20 for, well, slime mode.

Now we have *scratch* buffer, ielm (inferior Emacs Lisp mode), lisp-mode and scheme-mode all co-exist with slime, serving different purposes.

Footnotes:

1

About Debian package sections https://www.debian.org/distrib/packages

3

Unofficial Emacs build for macOS https://emacsformacosx.com

13

LSP Mode - LSP support for Emacs https://emacs-lsp.github.io/lsp-mode/

14

Config clangd with Emacs https://clangd.llvm.org/installation

15

Company mode home page: https://company-mode.github.io/, Company mode user manual: https://elpa.gnu.org/devel/doc/company.html

18

Steel Bank Common Lisp https://www.sbcl.org

20

SLIME https://github.com/slime/slime, along with some other links: