Making a Multiplatform Emacs Configuration
For Linux, macOS, and MS Windows
These days, I use three different operating systems at work and home: Ubuntu Linux (Dell Latitude 7490 13" laptop), Microsoft Windows (Dell Latitude 7400 13" laptop), and macOS (27" iMac). My primary tool across these platforms is Emacs, which I use for nearly everything—coding (C++, Python), blogging (Hugo), reading (Elfeed), note-taking (Org Mode, org-roam), diary, and agenda management (beorg on iPhone, synchronized via Dropbox across all computers), among other tasks.
Naturally, I want a single Emacs configuration file—.emacs
or, if you
prefer, init.el
—to work seamlessly across all these platforms.
Emacs is arguably the most platform-agnostic software available. However, some OS-specific differences must be addressed. These can be grouped into several categories:
- Paths for external executables, particularly on Windows.
- OS-specific key bindings, especially on macOS.
- Various OS-specific tweaks, particularly for Windows.
- Font sizes, which depend on screen size and resolution.
Below, I explore these issues in greater detail.
Introduction
First, we need to determine the operating system type.
;;;; OS Detection
(defvar os-windows (string-equal system-type "windows-nt") "Running on Windows.")
(defvar os-linux (string-equal system-type "gnu/linux") "Running on Linux.")
(defvar os-macos (string-equal system-type "darwin") "Running on macOS.")
Paths
;;; Environment Variables.
(defvar my/home (getenv "HOME"))
(when os-linux
(setenv "PATH"
(concat
my/home "/lib/grpc/bin" path-separator ; gRPC binaries
(getenv "PATH")))
(setenv "PKG_CONFIG_PATH"
(concat
my/home "/lib/grpc/lib/pkgconfig")))
;; Add Cygwin path on Windows.
(when os-windows
(setq exec-path (cons "C:/cygwin64/bin" exec-path)))
;; Clang/clangd compiler on Windows.
(when os-windows
(setq exec-path (append exec-path '("C:/bin/LLVM/9.0.0/bin"))))
;; Clang/clangd compiler on macOS.
(when os-macos
(setq exec-path (append exec-path '("/usr/local/Cellar/llvm/11.0.0_1/bin"))))
The exec-path
built-in variable contains a list of directories Emacs
searches to run programs in subprocesses. Each element is either a
string (directory name) or nil (indicating the default directory).
OS-Specific Key Bindings
macOS
Disable the Command key as Meta and enable Option as Meta (Alt).
;;;; `macOS' keyboard
(when os-macos
(setq mac-command-key-is-meta nil
mac-command-modifier 'super
mac-option-key-is-meta t
mac-option-modifier 'meta))
Prevent accidentally closing the frame or Emacs app by disabling ⌘-w and ⌘-q.
(when os-macos
(global-unset-key (kbd "s-w"))
(global-unset-key (kbd "s-q")))
OS-Specific Tweaks
Microsoft Windows
Increase the default Windows pipe buffer size. (Note: This may no longer be necessary, but I include it for compatibility.)
(when os-windows
(setq w32-pipe-read-delay 0)
(setq irony-server-w32-pipe-buffer-size (* 64 1024)))
Configure Dired
to resemble its appearance on Linux/macOS.
(if os-windows
(setq dired-listing-switches "/A:H /O:NG")
;; Linux/macOS
(setq dired-listing-switches "-laGgh1v --group-directories-first --time-style=long-iso"))
Linux
Set the default browser on Linux.
(when os-linux
(setq browse-url-browser-function 'browse-url-firefox))
Font Size
I use the same .emacs
configuration on both a 13" laptop and a 27"
desktop, which have significantly different screen sizes and
resolutions. This requires font size adjustments.
(cond
(os-linux (defvar my/font-height 140 "The default font height for Emacs on Linux (in 1/10th points)."))
(os-macos (defvar my/font-height 180 "The default font height for Emacs on macOS (in 1/10th points)."))
(t (defvar my/font-height 140 "The default font height for Emacs on Windows and other systems (in 1/10th points).")))
Set the default font size based on the OS type.
(custom-set-faces
`(default ((t (:height ,my/font-height :width normal :family "Aporetic Sans Mono"))))
)
Note the use of the backquote macro for dynamic font height.
Summary
With these configurations, I can use a single .emacs
file across all
my machines, ensuring a consistent Emacs experience regardless of the
operating system.
Happy emacsing!
— The Emacs Cat.