Trying GNU Emacs part 1

22 Jul 2025

emacs

This is my attempt to learn to use the glorious GNU program, that is GNU Emacs.

I am a vim enthusiast, so I definitely have a bias towards it and will compare Emacs with vim in my subconscious.

Installation

At the time of writing this document, I'm using macOS Sequoia 15.5 on a Macbook Pro M4 and Emacs version 30.1, so here is some installation step specifically for this machine.

There are several options that we can choose to use Emacs on macOS:

  • https://emacsformacosx.com/ - This is the simplest way to install Emacs on macOS system, just regular drag and drop to Applications folder and it's done.
  • Homebrew emacs - Install Emacs using homebrew.
  • emacs-plus - This is another homebrew package but I noticed a lot of people recommended this if we want a more feature complete Emacs on macOS.

I tried all of them but I don't see any major difference because I'm just getting started and have no idea of what I'm missing or not. So if we're just getting started, I believe it is safe to use any of them.

NOTE: when I install emacs-plus, it builds emacs from source and I noticed the spike of CPU usage on my machine, it was so intense it is the first time (the only time?) since I bought the machine that the fan start to spin real hard I started to worry. The build finished about 30 minutes or so.

Getting Started

Emacs provide a quick guided tutorial similar to vimtutor that we can access by pressing C-h t (that is Control + h then t).

And it has a very extensive built-in user manual that we can access by pressing C-h r.

For a quick reference there is also C-h ?.

Most (all?) of the keybinding on emacs are translated to Emacs Lisp function calls. For example pressing C-f and C-b will invoke forward-char and backward-char function respectively. We can also run the functions manually by using M-x (that is Meta + x or Alt + x) from which we can enter the function name to call.

M-x is different than vim command mode, because we cannot call command/function along with its arguments in one go but instead do it in a more interactive way, i.e. enter function name, then prompt us with arguments if needed.

For example, to change the theme, the expession in Emacs Lisp is (load-theme 'theme-name). Using M-x it is two step, first enter M-x load-theme RET then theme-name RET.

Emacs provide a way to directly evaluate any expression using M-:. Again, this is also different than vim command mode because it is more like a REPL or lisp expression evaluator.

Configuration

Emacs read configuration from multiple places.

Some that I know are ~/.emacs, ~/.emacs.d/init.el, ~/.config/emacs/init.el.

The configuration is written in Emacs Lisp.

To set an option variable we use setq.

; Allow scroll to top/bottom of a buffer
(setq scroll-error-top-bottom t)

To check out help file of a variable we can use C-h v then enter the variable name, or if the cursor is on top of a variable we can press C-h v RET.

Some of the configuration can be set by calling functions.

(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(global-hl-line-mode 1)

Similarly, to check out help file of a function we can use C-h f then enter the variable name, or if the cursor is on top of a variable we can press C-h f RET.

Packages

Emacs provide a package manager called package.el. This module provide functions to manage Emacs packages interactively.

By default Emacs will try to download packages from gnu and nongnu repository, specified in package-archives variable.

We can add more repository to download packages from, for example MELPA is a popular one.

(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)

We call call package-refresh-contents to re-index available packages.

Installing Package

To install a package, we can browse available packages using list-packages then use the interactive menu from there to install each package.

We can also specify it in our config file by calling the package-install manually. But we also need to check if they're not installed already, using package-installed-p function.

(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)

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

(dolist (pkg '(spacemacs-theme evil magit))
  (unless (package-installed-p pkg)
    (package-install pkg)))

;; theme
(load-theme 'spacemacs-dark t)

;; evil mode
(setq evil-want-C-u-scroll t)
(require 'evil)
(evil-mode 1)

;; magit
(require 'magit)

;; org
(require 'org)
(setq org-agenda-files (directory-files-recursively "~/org" "\\.org$"))
(global-set-key (kbd "C-c a") #'org-agenda)
(global-set-key (kbd "C-c c") #'org-capture)

We can also use the use-package macro to make it tidy.

;; setup packages
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)

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

;; bootstrap use-package
(unless (package-installed-p 'use-package)
  (package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t)

;; themes and packages
(use-package spacemacs-theme
  :config
  (load-theme 'spacemacs-dark t))

(use-package evil
  :init
  (setq evil-want-C-u-scroll t)
  :config
  (evil-mode 1))

(use-package magit)

(use-package org
  :init
  (setq org-agenda-files (directory-files-recursively "~/org" "\\.org$"))
  :bind (("C-c a" . org-agenda)
         ("C-c c" . org-capture)))

Packages Quirks

When we install a package, Emacs will modify and add at the end of config file with some "custom" section.

To avoid this, we can set custom-file variable to let emacs modify that file instead.

(setq custom-file "~/.emacs-custom.el")

Other Package Manager

There are other package manager available but I haven't tried any of them.

Appendix

There are also Emacs distro which configure Emacs for us, only two that I'm aware of (there are others) so far.

I have tried to install spacemacs long time ago, but the only thing I can remember is that it was slow as hell, but I'm sure it has changed since then (or not, who knows?).

I have also recently tried to install doom emacs. While it mostly works, I don't like the fact that I don't get the experience of using Emacs because most of the feature feels like magic. This is of course because my lack of experience, and that is why I want to have the real experience.

← View all posts