This file contains my Emacs config. All code snippets present in this
file are exported to a config.el
file, and loaded by Emacs, thanks
to the following code snippet in init.el:
(setq my/org-config
(expand-file-name "config.org" user-emacs-directory))
(org-babel-load-file my/org-config)
This allows me to have a nice, always up-to-date documentation of my configuration.
Note that this does increase startup time, as Org needs to build the
config.el
file everytime Emacs is started, however I like to use
Emacs in daemon mode, so this isn’t a problem for me.
The alternative would be to tangle this file before starting emacs, but that would require to generate it again whenever I change something.
First of all, enable lexical binding.
;;; -*- lexical-binding: t; -*-
If we’re in GUI mode, we hide useless GUI elements.
(if (fboundp 'menu-bar-mode) (menu-bar-mode -1))
(if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(if (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
Store custom variables in another file, we don’t want our config to be
polluted with those. Also allows us to gitignore
this file.
(setq custom-file
(expand-file-name "custom.el" user-emacs-directory))
(unless (file-exists-p custom-file)
(write-region "" nil custom-file))
(load custom-file)
We don’t need the startup screen, this starts us directly in a
*scratch*
buffer.
(setq inhibit-startup-screen t)
By default, Emacs generates ~backup
and #autosave#
files. I don’t
like them because they pollute my working directory.
(setq make-backup-files nil
auto-save-default nil)
For package management, we’ll use straight.el, and use-package.
This variable tells use-package
to fetch packages via straight.el
by default.
(setq straight-use-package-by-default t)
Here’s the bootstrap code to install straight.el
, copied straight
from https://github.com/raxod502/straight.el#getting-started
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el"
user-emacs-directory))
(bootstrap-version 5))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
Here we install the main packages of our system, namely:
doom-themes | Loaded early so that our dark theme is displayed quickly |
projectile | For project navigation |
evil | For Vim bindings |
which-key | To display binding hints |
general | To setup our SPC leader key and related functionality |
(straight-use-package 'use-package)
(use-package doom-themes
:config
;; defaults
(setq doom-themes-enable-bold t
doom-themes-enable-italic t)
(load-theme 'doom-one t))
(use-package projectile
:config
(projectile-mode 1))
(use-package evil
:config
(evil-mode 1))
(use-package which-key
:config
(which-key-mode 1))
(use-package general)
This is why I’m using Emacs. Magit is THE best git plugin I’ve ever used.
(use-package magit)
And the Vim bindings to make it usable…
(use-package evil-magit)
Ivy is a completion system, replacing the default one.
(use-package ivy
:config
(ivy-mode 1)
(setq ivy-use-virtual-buffers t)
(setq enable-recursive-minibuffers t))
Counsel replaces many of Emacs’s prompts to use Ivy instead…
(use-package counsel
:config
(counsel-mode 1))
and can also integrate with Projectile!
(use-package counsel-projectile)
Now that we have fancy search, we want fancy style and icons to go with it.
(use-package ivy-rich
:config
(ivy-rich-mode 1))
Don’t forget to run M-x all-the-icons-install-fonts
when you set
everything up.
(use-package all-the-icons-ivy-rich
:config (all-the-icons-ivy-rich-mode 1))
(setq-default indent-tabs-mode nil)
First we need lsp-mode
, to support Language Server Protocol in any
language package.
lsp-mode
can be used standalone, but the user experience can be
improved by other plugins, such as company
for autocompletion, or
flycheck
for error reporting.
(use-package company)
(use-package flycheck)
(use-package lsp-mode)
(use-package lsp-ui)
(use-package lsp-ivy)
(use-package company-lsp)
For Rust, rustic-mode
can handle everything for us. We just need to
enable format-on-save by setting rustic-lsp-format
to t
.
(use-package rustic
:config
(setq rustic-lsp-format t))
Org mode comes with Emacs already, but I want to get the latest version directly from the repository.
(use-package org)
(defconst my-leader "SPC")
(defconst my-alt-leader "M-SPC")
(general-create-definer my-leader-def
:keymaps 'override
:states '(insert emacs normal hybrid motion visual operator)
:prefix my-leader
:non-normal-prefix my-alt-leader)
;; root leader shortcuts
(my-leader-def
"SPC" #'find-file
":" #'counsel-M-x
"f" #'find-file
"g" #'magit
"p" '(counsel-projectile-switch-project :which-key "switch project"))
;; search subsection
(general-create-definer my-global-search
:wrapping my-leader-def
:infix "s"
:wk-full-keys nil
"" '(:ignore t :which-key "search"))
(my-global-search
"s" #'swiper
"p" #'counsel-projectile-rg)
;; window subsection
(general-create-definer my-global-window
:wrapping my-leader-def
:infix "w"
:wk-full-keys nil
"" '(:ignore t :which-key "window"))
(my-global-window
"h" #'evil-window-left
"j" #'evil-window-down
"k" #'evil-window-up
"l" #'evil-window-right
"q" #'evil-quit
"s" #'evil-window-split
"v" #'evil-window-vsplit)