This is my working document for my emacs configuration. What follows is notes, annotations, and context for code I’ve found, or written, to better my experience in emacs. Minimum version is emacs 29
(let ((minver "29"))
(when (version< emacs-version minver)
(error "Your Emacs is too old -- this config requires v%s or higher" minver)))
Uncomment this for any debugging needs.
(setq debug-on-error t)
Order matters, so we always refer to MELPA first. We also add Org, to make sure we get the most updated version of Org.
(require 'package)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("org" . "https://orgmode.org/elpa/")
("elpa" . "http://elpa.gnu.org/packages/")))
(setq use-package-always-ensure t)
We always want to make sure use-package
is available. We also refresh our package list from the above archives.
(when (not (package-installed-p 'use-package))
(package-refresh-contents)
(package-install 'use-package))
Experience / Nuisance Killers
First we want anything done with emacs customize to go in some other file, instead of cluttering our init.el
(setq custom-file "~/.emacs.d/custom.el")
(load-file custom-file)
The startup message and the bell noise are both inhibitors of concentration, so we kill them. We also can remove some unnecessary bars around the screen, ensuring we have a minimalist view
(scroll-bar-mode -1)
(tool-bar-mode -1)
(set-fringe-mode 10)
(menu-bar-mode -1)
(setq visible-bell t)
(setq inhibit-startup-message t)
Referencing This Blog for the basis of setting fonts. I tried Dracula at first, but I need something that has both light and dark mode depending on the computer I have setup, and where I am. Solarized seems fine for this?
(use-package solarized-theme :ensure t)
(load-theme 'solarized-selenized-black t)
(set-face-attribute 'default nil :font "Fira Code")
(use-package all-the-icons
:if (display-graphic-p))
(setq x-underline-at-descent-line t)
(use-package doom-modeline
:ensure t
:hook (after-init . doom-modeline-mode)
:custom ((doom-modeline-height 10)))
Using a hook here so everytime we load an org file, it will set these.
(defun ll/org-mode-setup ()
(org-indent-mode)
(variable-pitch-mode 1)
(auto-fill-mode 0)
(visual-line-mode 1)
(face-remap-add-relative 'default :family "ETBembo"))
(use-package org
:hook (org-mode . ll/org-mode-setup)
:config
(setq org-ellipsis " [x]"))
(use-package org-bullets
:config
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))
(use-package org-novelist
:ensure nil
:load-path "~/git/org-novelist")
(use-package rust-mode
:init
(add-hook 'rust-mode-hook #'lsp))
(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 nil)
(lsp-idle-delay 0.6)
;; enable / disable the hints as you prefer:
(lsp-inlay-hint-enable t)
;; These are optional configurations. See https://emacs-lsp.github.io/lsp-mode/page/lsp-rust-analyzer/#lsp-rust-analyzer-display-chaining-hints for a full list
(lsp-rust-analyzer-display-lifetime-elision-hints-enable "skip_trivial")
(lsp-rust-analyzer-display-chaining-hints t)
(lsp-rust-analyzer-display-lifetime-elision-hints-use-parameter-names nil)
(lsp-rust-analyzer-display-closure-return-type-hints t)
(lsp-rust-analyzer-display-parameter-hints nil)
(lsp-rust-analyzer-display-reborrow-hints nil)
:config
(add-hook 'lsp-mode-hook 'lsp-ui-mode))
(use-package lsp-ui
:ensure
:commands lsp-ui-mode
:custom
(lsp-ui-peek-always-show t)
(lsp-ui-sideline-show-hover t)
(lsp-ui-doc-enable nil))
lsp-ui is optional. It provides inline overlays over the symbol at point and enables code fixes at point. If you find it to flashy and prefer not activating it just remove :config (add-hook ‘lsp-mode-hook ‘lsp-ui-mode).
(use-package meow :ensure t)
(defun meow-setup ()
(setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty)
(meow-motion-overwrite-define-key
'("j" . meow-next)
'("k" . meow-prev)
'("<escape>" . ignore))
(meow-leader-define-key
;; SPC j/k will run the original command in MOTION state.
'("j" . "H-j")
'("k" . "H-k")
;; Use SPC (0-9) for digit arguments.
'("1" . meow-digit-argument)
'("2" . meow-digit-argument)
'("3" . meow-digit-argument)
'("4" . meow-digit-argument)
'("5" . meow-digit-argument)
'("6" . meow-digit-argument)
'("7" . meow-digit-argument)
'("8" . meow-digit-argument)
'("9" . meow-digit-argument)
'("0" . meow-digit-argument)
'("/" . meow-keypad-describe-key)
'("?" . meow-cheatsheet))
(meow-normal-define-key
'("0" . meow-expand-0)
'("9" . meow-expand-9)
'("8" . meow-expand-8)
'("7" . meow-expand-7)
'("6" . meow-expand-6)
'("5" . meow-expand-5)
'("4" . meow-expand-4)
'("3" . meow-expand-3)
'("2" . meow-expand-2)
'("1" . meow-expand-1)
'("-" . negative-argument)
'(";" . meow-reverse)
'("," . meow-inner-of-thing)
'("." . meow-bounds-of-thing)
'("[" . meow-beginning-of-thing)
'("]" . meow-end-of-thing)
'("a" . meow-append)
'("A" . meow-open-below)
'("b" . meow-back-word)
'("B" . meow-back-symbol)
'("c" . meow-change)
'("d" . meow-delete)
'("D" . meow-backward-delete)
'("e" . meow-next-word)
'("E" . meow-next-symbol)
'("f" . meow-find)
'("g" . meow-cancel-selection)
'("G" . meow-grab)
'("h" . meow-left)
'("H" . meow-left-expand)
'("i" . meow-insert)
'("I" . meow-open-above)
'("j" . meow-next)
'("J" . meow-next-expand)
'("k" . meow-prev)
'("K" . meow-prev-expand)
'("l" . meow-right)
'("L" . meow-right-expand)
'("m" . meow-join)
'("n" . meow-search)
'("o" . meow-block)
'("O" . meow-to-block)
'("p" . meow-yank)
'("q" . meow-quit)
'("Q" . meow-goto-line)
'("r" . meow-replace)
'("R" . meow-swap-grab)
'("s" . meow-kill)
'("t" . meow-till)
'("u" . meow-undo)
'("U" . meow-undo-in-selection)
'("v" . meow-visit)
'("w" . meow-mark-word)
'("W" . meow-mark-symbol)
'("x" . meow-line)
'("X" . meow-goto-line)
'("y" . meow-save)
'("Y" . meow-sync-grab)
'("z" . meow-pop-selection)
'("'" . repeat)
'("<escape>" . ignore)))
(require 'meow)
(meow-setup)
(meow-global-mode 1)
(use-package swiper)
(use-package counsel
:bind (("M-x" . counsel-M-x)
("C-x b" . counsel-ibuffer)
("C-x C-f" . counsel-find-file)
:map minibuffer-local-map
("C-r" . counsel-minibuffer-history)))
(global-set-key (kbd "C-M-j") 'counsel-switch-buffer)
(use-package ivy
:diminish
:bind (("C-s" . swiper))
:config
(ivy-mode 1))
(use-package ivy-rich
:init
(ivy-rich-mode 1))
;;ux
(use-package which-key
:defer 0
:diminish which-key-mode
:config
(which-key-mode)
(setq which-key-idle-delay 1))