All notes tagged with emacs.

July 1, 2024

emacs macos

Install Emacs on the Mac - Part Two

Previously, I used to install Emacs on the Mac through a build script, but I recently switched to the Emacs Plus version, installed through homebrew.

First, you need to “tap” it and install dependencies before you can use it:

brew tap d12frosted/emacs-plus

# Install dependencies
brew install jq

And then you can install it. I pin it to a version and use minimal flags:

brew install emacs-plus@30 --with-memeplex-slim-icon --with-native-comp

And there you go, an Emacs version specifically tuned for the Mac.

June 30, 2024

emacs macos

Enhancing Font Rendering in Emacs on macOS

Recently, I stumbled upon a Reddit thread on font rendering in Emacs on macOS. I figured many users might be unaware of simple trick for crisper fonts:

defaults write org.gnu.Emacs AppleFontSmoothing -int 0

After running this command, restart Emacs to see the effect.

If you’re not satisfied with the result, you can easily revert to the default settings by running:

defaults delete org.gnu.Emacs AppleFontSmoothing

Remember to restart Emacs after making changes again.

June 29, 2024

linux emacs

Sync Fastmail with isync

As an Emacs enthusiast, I’ve found Mu4e to be an excellent email client. While Emacs can send emails, it can’t fetch and sync them efficiently. Enter isync, the perfect companion to fill this gap.

Setting up this duo took some digging, so I’m sharing my configuration to save you time and headaches.

Here’s what my setup accomplishes:

  1. Syncs all mailboxes, excluding junk and notes.
  2. Renames “Sent Items” to “Sent” for simplicity.
  3. Encrypts your password on disk using GPG.

First, I recommend to install the latest version of isync, if you are on the Mac, use brew install isync --HEAD. Then, you’ll need to create an encrypted password file. In Emacs, run the epa-encrypt-file command.

Now, let’s dive into the heart of the setup. Here’s my .mbsyncrc configuration file:

# Petar account on Fastmail.
IMAPAccount petar
Port 993
AuthMechs LOGIN
User [email protected]
PassCmd "gpg -q --for-your-eyes-only --no-tty -d ~/.mbsync-password-petar.gpg"
TLSVersions +1.2

IMAPStore petar-remote
Account petar

# Petar Local.
MaildirStore petar-local
Path ~/Mail/Petar/
Inbox ~/Mail/Petar/Inbox
Trash ~/Mail/Petar/Trash/
SubFolders Verbatim

# Sync everything besides sent and junk.
Channel sync-petar-all
Far :petar-remote:
Near :petar-local:
Patterns * !"Sent Items" !"Junk Mail" !"Notes"
Expunge None
CopyArrivalDate yes
Sync All
Create Near
SyncState *

# Sync and rename the sent items
Channel sync-petar-sent
Far :petar-remote:"Sent Items"
Near :petar-local:Sent
Expunge None
CopyArrivalDate yes
Sync All
Create Near
SyncState *

Group petar
Channel sync-petar-all
Channel sync-petar-sent

With this setup, you’ll have all your email on disk, ready to use it in Emacs and Mu4e.

June 28, 2024

emacs lisp

From Python to Emacs Lisp

Ever feel like your brilliant blog ideas evaporate faster than spilled coffee on a hot keyboard?

If you’re like me, the lower the barrier to creating a note for your blog, the better. I started with a Python script to streamline my blog writing process, but it wasn’t quite hitting the mark. It required me to open the terminal, run the command, and then open the file in Emacs. The experience felt clunky.

Then it hit me: I’m using Emacs, why the heck am I doing this in Python.

I decided to port my Python script to Emacs Lisp, and not only was it easier to write, but the overall experience also improved significantly. It prompts you with a few questions and opens a buffer for you to start writing.

For reference, here’s the code that I ended up writing.

(defun pet/write-blog ()
  "Create a new blog note or post."
  (let* ((is-note (y-or-n-p "Do you want to write a note? "))
         (title (read-string "What is the title? "))
         (tags (read-string "Do you want to tag it? "))
         (filename (concat (pet--slugify title) ".md"))
         (dir-type (if is-note "note" "post"))
         (path (expand-file-name
                 (concat "content/" dir-type "s") pet/blog-directory)))
         (date (format-time-string "%Y-%m-%d"))
          `(("${title}" . ,title)
            ("${date}" . ,date)
            ("${type}" . ,dir-type)
            ("${taxonomies}" . ,(format (if is-note "tags: [%s]" "categories: [%s]") tags))
            ("${tags}" . ,tags))))
    (find-file path)
    (insert pet/blog-frontmatter) ;; insert template for frontmatter
    (goto-char (point-min)) ;; beginning of buffer, so we can replace the title
    (pet--replace-strings replacements)
    (goto-char (point-max))))

(defun pet--slugify (s)
  "Create a slug from string S."
  (replace-regexp-in-string "^-\\|-$" ""
     "[^a-z0-9]+" "-" (downcase s))))

(defun pet--replace-strings (replacement-list)
  "Replace multiple strings in the current buffer.

REPLACEMENT-LIST is an alist where each element is a cons cell (SEARCH
. REPLACE).  For each pair, all occurrences of SEARCH are replaced with
    (dolist (rep replacement-list)
      (goto-char (point-min))
      (while (search-forward (car rep) nil t)
        (replace-match (cdr rep) t t)))))

Now it’s just one command pet/write-blog to start writing a new note, just like the one you are reading right now.

October 14, 2022

emacs macos

Install Emacs on the Mac

This note is outdated, I have since switched to Emacs Plus with Homebrew. See here: Install Emacs on the Mac - Part Two.

There are many ways to install Emacs on the Mac, from pre-build Applications, to Homebrew, to installing from source.

My current favorite way to get the latest Emacs which has some additional stuff for the Mac is by using a build script, which builds Emacs from its source.

It’s called build-emacs-macos and is on Github. The instructions to use it are here in the README.

October 12, 2022

emacs wsl

Emacs on Windows WSL2

So, it turns out that WSL2 is actually kind of neat, where it runs a Linux image at almost native speed, and also supports Wayland.

So, what’s the first thing you do in WSL2? Install Emacs of course!

Below is the script I use to install Emacs on an Ubuntu image.

To know what the latest stable version on master is, I look at this Github issue from Jim Myhrberg, who keeps track of those.

# Checkout Emacs
$ git clone git://

# Checkout latest stable version, see note above.
$ git checkout 8febda4

# Vanilla Emacs requirements
$ sudo apt install build-essential autoconf libgtk-3-dev libgnutls28-dev libtiff5-dev libgif-dev libjpeg-dev libpng-dev librsvg2-dev libxpm-dev libncurses-dev texinfo adwaita-icon-theme-full

# Native compilation requirements
$ sudo apt install libgccjit-11-dev

# Required for Native JSON
$ sudo apt install libjansson4 libjansson-dev

# Required for tree-sitter support
$ sudo apt install libtree-sitter-dev

$ cd emacs
$ export CC=/usr/bin/gcc-11 CXX=/usr/bin/gcc-11
$ ./
$ ./configure --with-pgtk --with-native-compilation --with-tree-sitter --with-json --without-pop
$ make -j$(nproc)
$ sudo make install

And, sometimes when you update the repository, it refuses to build. I usually fix that with running make bootstrap er make distclean.