2023-06-08 08:20:14 +00:00
#+TITLE : My literate Emacs config
* Introduction
This is my personal Emacs config, using org mode to make it easier to structure things and comment what section is used for exactly.
* Initialization
** General settings
Set the author name
2023-06-08 07:42:38 +00:00
#+begin_src emacs-lisp
(setq user-full-name "Anthony Rodriguez")
2023-06-08 08:20:14 +00:00
#+end_src
2023-06-08 07:42:38 +00:00
2023-06-08 08:20:14 +00:00
Remove the startup message
#+begin_src emacs-lisp
(setq inhibit-startup-message t)
#+end_src
2023-06-08 07:42:38 +00:00
2023-06-08 08:20:14 +00:00
Disable some UI elements that I don't need
#+begin_src emacs-lisp
(scroll-bar-mode -1)
(tool-bar-mode -1)
(tooltip-mode -1)
(menu-bar-mode -1)
#+end_src
2023-06-08 07:42:38 +00:00
2023-06-08 08:20:14 +00:00
Add space on the sides
#+begin_src emacs-lisp
(set-fringe-mode 10)
#+end_src
2023-06-08 07:42:38 +00:00
2023-06-08 08:20:14 +00:00
Disable backup and auto save as I use git repositories a lot and I don't like having to ignore Emacs specific files
#+begin_src emacs-lisp
2023-06-08 07:42:38 +00:00
(setq backup-inhibited t)
(setq auto-save-default nil)
2023-06-08 08:20:14 +00:00
#+end_src
2023-06-08 07:42:38 +00:00
2023-06-08 08:20:14 +00:00
** Package management
I use [[https://github.com/radian-software/straight.el ][straight.el ]] for my package management, alongside [[https://github.com/jwiegley/use-package ][use-package ]] to make my configuration easier to maintain.
Initialize straight.el
#+begin_src emacs-lisp
2023-06-08 07:42:38 +00:00
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 6))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
2023-06-08 08:20:14 +00:00
#+end_src
2023-06-08 07:42:38 +00:00
2023-06-08 08:20:14 +00:00
Install use-package with straight.el
#+begin_src emacs-lisp
2023-06-08 07:42:38 +00:00
(straight-use-package 'use-package)
2023-06-08 08:20:14 +00:00
#+end_src
Set use-package to always ensure (makes sure all of our packages download automatically)
#+begin_src emacs-lisp
2023-06-08 07:42:38 +00:00
(setq use-package-always-ensure t)
2023-06-08 08:20:14 +00:00
#+end_src
2023-06-08 07:42:38 +00:00
2023-06-08 08:20:14 +00:00
Makes use-package use straight.el by default
#+begin_src emacs-lisp
2023-06-08 07:42:38 +00:00
(use-package straight
:custom
2023-06-08 08:20:14 +00:00
(straight-use-package-by-default t))
#+end_src
** Environment variables
One issue I had using Emacs was the fact that my environment variables were not available inside of the GUI version. This is because on some systems, mainly OS X, where graphical apps inherit a minimal set of environment variables, or setups running Emacs as a daemon, graphical apps may not have all of the available environment variables (mainly $PATH and ssh related variables). This is why we use [[https://github.com/purcell/exec-path-from-shell ][exec-path-from-shell ]], a handy library that will ensure we have access to the same stuff across Emacs and the terminal.
2023-06-08 07:42:38 +00:00
2023-06-08 08:20:14 +00:00
Here, we install the aforementioned package, and define a list of commonly needed variables to share with the Emacs instance.
#+begin_src emacs-lisp
2023-06-08 07:42:38 +00:00
(use-package exec-path-from-shell
:config
(dolist (var '("SSH_AUTH_SOCK" "SSH_AGENT_PID" "GPG_AGENT_INFO" "LANG" "LC_CTYPE" "NIX_SSL_CERT_FILE" "NIX_PATH"))
(add-to-list 'exec-path-from-shell-variables var)))
2023-06-08 08:20:14 +00:00
#+end_src
2023-06-08 07:42:38 +00:00
2023-06-08 08:20:14 +00:00
Share the path on OS X
#+begin_src emacs-lisp
2023-06-08 07:42:38 +00:00
(when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize))
2023-06-08 08:20:14 +00:00
#+end_src
2023-06-08 07:42:38 +00:00
2023-06-08 08:20:14 +00:00
Share the path on daemonized setups
#+begin_src emacs-lisp
2023-06-08 07:42:38 +00:00
(when (daemonp)
(exec-path-from-shell-initialize))
2023-06-08 08:20:14 +00:00
#+end_src
* Appearance
** Theme
I use [[https://github.com/catppuccin ][catppuccin ]] as my theme (the mocha flavor).
#+begin_src emacs-lisp
;; set theme
(use-package catppuccin-theme
:custom
(catppuccin-flavor 'mocha)
2023-06-08 07:42:38 +00:00
:init
2023-06-08 08:20:14 +00:00
(load-theme 'catppuccin t)
(catppuccin-reload))
#+end_src
2023-06-08 07:42:38 +00:00
2023-06-08 08:20:14 +00:00
** Font
I really like being able to use standard fonts, so I decided to set my Emacs font to my system monospace font.
#+begin_src emacs-lisp
(add-to-list 'default-frame-alist '(font . "Monospace 15"))
(add-hook 'text-mode-hook 'visual-line-mode)
#+end_src
** Mode-line
I use [[https://github.com/seagle0128/doom-modeline ][doom-modeline ]] as my mode-line, it's really slick and shows me all that I need to know at all times.
#+begin_src emacs-lisp
2023-06-08 07:42:38 +00:00
(use-package doom-modeline
:ensure t
:init (doom-modeline-mode 1)
:custom ((doom-modeline-height 15)))
2023-06-08 08:20:14 +00:00
#+end_src
doom-modeline requires nerd-icons to be able to display icons. Don't forget to run nerd-icons-install-fonts to make it available on your system.
#+begin_src emacs-lisp
(use-package nerd-icons)
#+end_src
#+begin_src emacs-lisp
(use-package vertico
:init
(vertico-mode))
2023-06-08 07:42:38 +00:00
2023-06-08 08:20:14 +00:00
2023-06-08 07:42:38 +00:00
(use-package which-key
:config
(which-key-mode))
;; magit
(use-package magit)
;; org setup
;; export to a4
(with-eval-after-load 'ox-latex (add-to-list 'org-latex-classes
'("article" "\\documentclass[11pt,a4paper]{article}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))
(use-package org-roam
:custom
(org-roam-directory "~/org/notes")
(org-roam-completion-everywhere t)
:config
(org-roam-setup)
:bind (("C-c n f" . org-roam-node-find)
(:map org-mode-map
(("C-c n i" . org-roam-node-insert)
("C-c n l" . org-roam-buffer-toggle)))))
(setq org-publish-project-alist
(list
'("notes"
:base-directory "~/org/notes"
:base-extension "org"
:publishing-directory "~/org/notes"
:publishing-function org-latex-publish-to-pdf
)))
;; spell checking for text modes
(dolist (hook '(text-mode-hook))
(add-hook hook (lambda () (flyspell-mode 1))))
(dolist (hook '(change-log-mode-hook log-edit-mode-hook))
(add-hook hook (lambda () (flyspell-mode -1))))
(add-hook 'prog-mode-hook
(lambda ()
(flyspell-prog-mode)))
;; avoid spell checking code regions in org mode
(add-to-list 'ispell-skip-region-alist '("^#+BEGIN_SRC" . "^#+END_SRC"))
;; add different dictionaries
(let ((langs '("american" "francais")))
(setq lang-ring (make-ring (length langs)))
(dolist (elem langs) (ring-insert lang-ring elem)))
;; cycle through languages
(defun cycle-ispell-languages ()
(interactive)
(let ((lang (ring-ref lang-ring -1)))
(ring-insert lang-ring lang)
(ispell-change-dictionary lang)))
(setq ispell-program-name "aspell")
(global-set-key [f6] 'cycle-ispell-languages)
;; automatic language detection
(use-package guess-language
:config
(setq guess-language-languages '(en fr))
(setq guess-language-min-paragraph-length 35)
:hook
(text-mode . guess-language-mode))
(use-package expand-region
:bind
("C-=" . er/expand-region))
;; enable syntax highlighting in org source blocks
(setq org-src-fontify-natively t)
;; disable latex subscript in org-mode
(setq org-export-with-sub-superscripts nil)
(use-package pdf-tools
:config
(pdf-tools-install)
(setq-default pdf-view-display-size 'fit-width))
(use-package rustic
:custom
(rustic-format-trigger 'on-save)
(rustic-analyzer-command '("rustup" "run" "stable" "rust-analyzer"))
:hook
(rustic-mode . display-line-numbers-mode))
;; lsp integration
(use-package lsp-mode
:ensure
:commands lsp
:custom
;; what to use when checking on-save. "check" is default, I prefer clippy
(lsp-rust-analyzer-cargo-watch-command "clippy")
(lsp-eldoc-render-all t)
(lsp-idle-delay 0.6))
(use-package lsp-ui
:after lsp-mode
:hook (lsp-mode . lsp-ui-mode))
;; code completion
(use-package company
:after lsp-mode)
(use-package company-box
:hook (company-mode . company-box-mode))
#+end_src