On first boot you can run emacs --batch --eval "(require 'org)" --eval '(org-babel-tangle-file "init.org")' to create the init file.
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(load custom-file :no-error-if-file-is-missing)Standardize the location of all backup files, rather than polluting the working directory
(setq backup-directory-alist
'((".*" . "~/.emacs.d/backups/")))(use-package savehist
:config
(savehist-mode))
(recentf-mode 1)Setup straight.el as the package manager
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name
"straight/repos/straight.el/bootstrap.el"
(or (bound-and-true-p straight-base-dir)
user-emacs-directory)))
(bootstrap-version 7))
(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))
(straight-use-package 'use-package)Disable the tool bar, menu bar, scroll bar, and splash screen
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(setq-default inhibit-splash-screen t)
(setq-default cursor-type 'bar)The warnings buffer is super nice but it can be annoying that it pops up into view. I prefer to just open the buffer when I want to deal with it
(add-to-list 'display-buffer-alist
'("\\`\\*\\(Warnings\\|Compile-Log\\)\\*\\'"
(display-buffer-no-window)
(allow-no-window . t)))(set-face-attribute 'default nil :font "ComicShannsMono Nerd Font Mono" :height 120)Set a scrolling offset and disable the ensure emacs does not recenter the view when scrolling
(pixel-scroll-precision-mode 1)
(setq scroll-margin 5
scroll-step 1
scroll-conservatively 10000
scroll-preserve-screen-position 1)(setq display-line-numbers-type 'relative)(use-package doom-modeline
:straight t
:after nerd-icons
:init
(doom-modeline-mode 1)
(display-time-mode t)
:config
(setq doom-modeline-project-detection 'auto
doom-modeline-icon t
doom-modeline-analogue-clock nil
doom-modeline-lsp-icon t
doom-modeline-modal t
doom-modeline-modal-modern-icon t))I only really use ef-themes, but it doesn’t hurt to have a few more options for a little change of pace
Truly amazing themes. ef-autumn is my all-time favorite theme
(use-package ef-themes
:straight t
:config
(load-theme 'ef-autumn t)
(setq ef-themes-to-toggle '(ef-autumn ef-melissa-light)))Another of prot’s great themes, these are built-in
(use-package modus-themes
:straight t)Also from Prot, a more minimal set of themes
(use-package doric-themes
:straight (:type git :host github :repo "protesilaos/doric-themes"))(use-package catppuccin-theme
:straight t
:defer t)(use-package cyberpunk-theme
:straight t
:defer t)(use-package doom-themes
:straight t
:defer t)(use-package gruber-darker-theme
:straight t
:defer t)(use-package nerd-icons
:straight t
:config
(setq nerd-icons-scale-factor 1.1
nerd-icons-font-family "ComicShannsMono Nerd Font Mono"))(use-package nerd-icons-completion
:straight t
:after (nerd-icons marginalia)
:config
(add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup))(use-package nerd-icons-dired
:straight t
:after nerd-icons
:hook
(dired-mode . nerd-icons-dired-mode))(use-package olivetti
:straight t)Customize dired. Allow
(use-package dired
:config
(setq dired-auto-revert-buffer #'dired-directory-changed-p
dired-free-space nil
dired-listing-switches "-AGFhlv --group-directories-first --time-style=long-iso"))Allows for opening certain file extensions in programs other than emacs 😱–mainly pdfs
(use-package openwith
:straight t
:after dired
:config
(setq openwith-associations '(
("\\.pdf\\'" "zathura" (file))))
:hook
(dired-mode . openwith-mode)
)(use-package denote
:straight t
:hook
(dired-mode . denote-dired-mode)
:config
(setq denote-directory (expand-file-name "~/Notes/denote"))
(denote-rename-buffer-mode 1))(use-package denote-org
:straight t)(use-package denote-journal
:straight t
:after (denote org)
:config
(setq denote-journal-directory
(expand-file-name "~/Notes/journal"))
(setq denote-journal-keyword "journal")
(setq denote-journal-title-format 'day-date-month-year)
(setq org-agenda-files `(,denote-journal-directory))
)(use-package denote-silo
:straight t
;; Bind these commands to key bindings of your choice.
;; :commands ( denote-silo-create-note
;; denote-silo-open-or-create
;; denote-silo-select-silo-then-command
;; denote-silo-dired
;; denote-silo-cd )
:config
;; Add your silos to this list. By default, it only includes the
;; value of the variable `denote-directory'.
(setq denote-silo-directories
(list denote-directory
(expand-file-name "~/Notes/TheIronreachAccord")
)))(use-package calendar
:commands calendar
;; For some reason :after denote-journal is not sufficient here, and results
; in M-x calendar not autoloading denote-journal
:init
(require 'denote-journal)
:config
(defun my/denote-journal-calendar-action ()
"Create or open a journal entry and close the calendar."
(interactive)
(denote-journal-calendar-new-or-existing)
(calendar-exit))
(defun my/calendar-custom-setup ()
"Enable denote-journal-calendar-mode and bind RET in evil normal mode."
;; Bind RET only in evil normal state
(denote-journal-calendar-mode 1)
(when (bound-and-true-p evil-mode)
(evil-define-key 'normal calendar-mode-map (kbd "RET") #'my/denote-journal-calendar-action)
(evil-define-key 'normal calendar-mode-map (kbd "l") 'calendar-forward-day)
(evil-define-key 'normal calendar-mode-map (kbd "h") 'calendar-backward-day)
(evil-define-key 'normal calendar-mode-map (kbd "j") 'calendar-forward-week)
(evil-define-key 'normal calendar-mode-map (kbd "k") 'calendar-backward-week)
))
(add-hook 'calendar-mode-hook #'my/calendar-custom-setup)
)Evil editing–accept no substitute
(use-package evil
:straight t
:init
(setq evil-want-keybinding nil)
:config
(setq evil-want-integration t
evil-vsplit-window-right t
evil-auto-indent t
evil-split-window-below t)
(evil-mode)
(define-key evil-normal-state-map (kbd "C-u") 'evil-scroll-up)
(evil-set-undo-system 'undo-redo))Adds evil-style keybindings for a bunch of major-modes
(use-package evil-collection
:straight t
:after evil
:config
(evil-collection-init))Allows for simple selection-based commenting/uncommenting
(use-package evil-nerd-commenter
:straight t
:after evil)Allows for the creation of multiple cursors for editing
(use-package evil-mc
:straight t
:after evil
:config
(setq evil-mc-mode-line-text-cursor-color t)
(global-evil-mc-mode 1))Adds the ability to add delimiters to the outside of a selection
I customize this because the default behavior is to have a space between the delimiters if you use the opening version of the paren, and no-space if you use the closing paren. I prefer the opposite behavior
(use-package evil-surround
:straight t
:after evil
:config
(global-evil-surround-mode 1)
(setq-default evil-surround-pairs-alist
'(
(?\( . ("(" . ")"))
(?\< . ("<" . ">"))
(?\[ . ("[" . "]"))
(?\{ . ("{" . "}"))
(?\) . ("( " . " )"))
(?\> . ("< " . " >"))
(?\] . ("[ " . " ]"))
(?\} . ("{ " . " }"))
(?\` . ("`" . "`"))
))
)(use-package avy
:straight t
:config
(setq avy-all-windows t))(use-package vertico
:straight t
:hook (after-init . vertico-mode)
:config
(setq vertico-cycle t
vertico-count 10))Allows filtering on fuzzy matches “foo baz” will find “foo-bar-baz”
(use-package orderless
:straight t
:config
(setq completion-styles '(orderless basic)
completion-category-defaults nil
read-buffer-completion-ignore-case t))Adds additional information to minibuffer results
(use-package marginalia
:straight t
:hook
(after-init . marginalia-mode))For completion-at-point I like company mode. I tried very hard to use corfu, it just seemed to cause emacs to crash occasionally in conjunction with lsp-mode and so I went back to company.
(use-package company
:straight t
:config
(setq company-idle-delay 0.2
company-minimum-prefix-length 2
company-tooltip-align-annotations t
company-tooltip-limit 5
company-tooltip-minimum 5
company-tooltip-offset-display 'lines
company-format-margin-function 'company-vscode-dark-icons-margin)
:bind
(:map company-active-map
("<tab>" . company-complete-selection)
("C-n" . company-select-next)
("C-p" . company-select-previous)
("M-<" . company-select-first)
("M->" . company-select-last))
:hook (after-init . global-company-mode)
)Adds additional collections to the completion at point like file paths and emojis
(use-package cape
:straight t
:bind ("C-c f" . cape-file)
:init
(add-hook 'completion-at-point-functions #'cape-file)
(add-hook 'completion-at-point-functions #'cape-emoji)
:config
;; Silence then pcomplete capf, no errors or messages!
(advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent)
;; Ensure that pcomplete does not write to the buffer
;; and behaves as a pure `completion-at-point-function'.
(advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify))Consult adds a ton of useful commands that improve on existing emacs functionality like consult-buffer which shows a live preview of the buffer as you move through the options, or consult-theme which does a similar thing. Must-have
(use-package consult
:straight t)(use-package consult-denote
:straight t
:after denote)(use-package consult-lsp
:straight t
:after lsp-mode)(use-package consult-flycheck
:straight t
:after flycheck)(use-package consult-todo
:straight t
:after hl-todo)Highlights terms like NOTE and TODO
(use-package hl-todo
:straight t
:hook (after-init . global-hl-todo-mode))(use-package rg
:straight t)(use-package affe
:straight t
:after orderless
:config
;; Manual preview key for `affe-grep'
(consult-customize affe-grep :preview-key "M-.")
(defun affe-orderless-regexp-compiler (input _type _ignorecase)
(setq input (cdr (orderless-compile input)))
(cons input (apply-partially #'orderless--highlight input t)))
(setq affe-regexp-compiler #'affe-orderless-regexp-compiler))(use-package prog-mode
:hook
(prog-mode . (lambda ()
(setq-local truncate-lines t)
(flyspell-prog-mode)
(display-line-numbers-mode)
(display-fill-column-indicator-mode)
(electric-indent-mode)
(electric-pair-mode))))(use-package lsp-mode
:straight t
:commands lsp
:config
(setq lsp-diagnostics-flycheck-enable t
lsp-keymap-prefix "C-l"
lsp-headerline-breadcrumb-enable nil
lsp-idle-delay 0.5))(use-package flycheck
:straight t
:config
(add-hook 'after-init-hook #'global-flycheck-mode))(use-package tree-sitter
:straight t
:config (global-tree-sitter-mode))(use-package tree-sitter-langs
:straight t)(use-package colorful-mode
:straight t
:hook (prog-mode text-mode))Direnv integration, automatically reads .envrc files and loads the proper environment for a given buffer. Great for Nix and python
(use-package direnv
:straight t
:config
(direnv-mode)) Useful for browsing documentation within emacs
(use-package devdocs
:straight t)Great asynchronous code formatter
(use-package apheleia
:straight t
:config
(add-to-list 'apheleia-formatters '(rustfmt . ("rustfmt" "--quiet" "--emit" "stdout" "--edition" "2024")))
:hook (prog-mode . apheleia-mode))(use-package rainbow-delimiters
:straight t
:defer t)Customizations to the default compile mode in emacs
(use-package compile
:config
(setq compilation-scroll-output t))fancy-compilation adds color support
(use-package fancy-compilation
:straight t
:after compile
:commands (fancy-compilation-mode)
:config
(setq fancy-compilation-override-colors nil)
:init
(with-eval-after-load 'compile
(fancy-compilation-mode)))(use-package vterm
:straight t
:config
(setq vterm-shell "nu"))Allows creating multiple vterm windows easily
(use-package multi-vterm
:straight t
:after vterm)(use-package magit
:straight t
:after seq
:config
(with-eval-after-load 'magit-mode
(add-hook 'after-save-hook 'magit-after-save-refresh-status t))
(setopt magit-format-file-function #'magit-format-file-nerd-icons)
(setq magit-show-long-lines-warning nil))Highlight todos in the project in the magit-status buffer
(use-package magit-todos
:straight t
:after magit
:config
(magit-todos-mode 1))(use-package git-modes
:straight t)The default ediff settings are kind of annoying, these improve them
(use-package ediff
:config
(setq ediff-split-window-function 'split-window-horizontally)
(setq ediff-window-setup-function 'ediff-setup-windows-plain))Shows highlights in the gutter for whether changes have been committed to VC files
(use-package diff-hl
:straight t
:config
(diff-hl-dired-mode t)
:hook
(prog-mode . diff-hl-mode)
(magit-pre-refresh . diff-hl-magit-pre-refresh)
(magit-post-refresh . diff-hl-magit-post-refresh))Adds git-blame to the buffer. In general this is too noisy for my taste but I like to be able to toggle it on for the times where I do want it
(use-package blamer
:straight t
:defer t
:config
(setq blamer-idle-time 0.3
blamer-view 'overlay-right)
:custom-face
(blamer-face ((t :foreground "#484741"
:background unspecified
:height 120
:italic t))))(use-package csv-mode
:straight t
:mode ("\\.csv\\'"))(use-package dockerfile-mode
:straight t
:mode ("\\.Dockerfile\\'" "Dockerfile")
:hook
(dockerfile-mode . (lambda () (setq-local devdocs-current-docs '("docker")))))(use-package groovy-mode
:straight t
:config
(setq groovy-indent-offset 2))(use-package odin-mode
:straight (:type git :repo "https://git.sr.ht/~mgmarlow/odin-mode"))(use-package protobuf-mode
:straight t)(use-package lsp-java
:straight t)
(use-package java-ts-mode
:mode ("\\.java\\'")
:after lsp-java
:config
(setq lombok-library-path (concat user-emacs-directory "lombok.jar"))
(unless (file-exists-p lombok-library-path)
(url-copy-file "https://projectlombok.org/downloads/lombok.jar" lombok-library-path))
(setq lsp-java-vmargs '(
"-XX:+UseParallelGC"
"-XX:GCTimeRatio=4"
"-XX:AdaptiveSizePolicyWeight=90"
"-Dsun.zip.disableMemoryMapping=true"
"-Xmx4G"
"-Xms100m"
))
(push (concat "-javaagent:"
(expand-file-name lombok-library-path))
lsp-java-vmargs)
:hook
(
(java-ts-mode . (lambda () (setq-local devdocs-current-docs '("openjdk~21")))))
(java-ts-mode . lsp-deferred)
)(use-package json-ts-mode
:mode ("\\.json\\'" . json-ts-mode))(use-package just-mode
:straight t);; (use-package makefile-mode
;; :straight t
;; :hook
;; (makefile-mode . (lambda () (setq-local devdocs-current-docs '("gnu_make")))))(use-package markdown-mode
:config
(setq indent-tabs-mode nil)
:hook
(markdown-mode . (lambda () (setq-local devdocs-current-docs '("markdown")))))(use-package nix-mode
:straight t
:mode "\\.nix\\'"
:hook
(nix-mode . (lambda () (setq-local devdocs-current-docs '("nix")))))(use-package nushell-mode
:straight t
:hook
(nushell-mode . (lambda () (setq-local devdocs-current-docs '("nushell")))))(use-package python-mode
:straight t
:hook
(python-mode . (lambda () (setq-local devdocs-current-docs '("python~3.13")))))(use-package rst
:hook ((rst-mode . display-line-numbers-mode)
(rst-mode . display-fill-column-indicator-mode)
(rst-mode . (lambda () (set-fill-column 80))))
:config
(setq-local compilation-ask-about-save nil)
(setq compile-command "make -k")
)(use-package rust-mode
:straight t
:init
(setq rust-mode-treesitter-derive t)
:hook ((rust-mode . lsp-deferred)
(rust-mode . (lambda () (set-fill-column 100)))
(rust-mode . (lambda () (setq-local devdocs-current-docs '("rust")))))
:config
(setq rust-indent-offset 4)
(setq compile-command "cargo b --all-features")
(setq lsp-rust-analyzer-cargo-watch-command "clippy")
(setq lsp-rust-features "all")
(setq rust-format-on-save nil)
)(use-package cargo
:config
(setq cargo-process--command-test "nextest run --all-features --color always --lib")
(setq cargo-process--command-build "build --all-features")
:straight t)(use-package toml-ts-mode
:mode ("\\.toml\\'" "Cargo\\.lock\\'"))(use-package yaml-ts-mode
:mode ("\\.yml\\'" "\\.yaml\\'"))(use-package zig-mode
:straight t
:hook
(zig-mode . (lambda () (setq-local devdocs-current-docs '("zig")))))(defun leinz/affe-home ()
"Invoke affe-find with the argument \"~/\". "
(interactive)
(affe-find "~/"))(use-package org
:straight t
:hook
(org-mode . (lambda ()
(visual-line-mode)
(flyspell-mode)
(display-line-numbers-mode)
(org-superstar-mode)
(org-indent-mode)))
:config
(setq org-todo-keywords
'((sequence "TODO(t)" "PROG(p)" "PROJ(j)" "SENT(s)" "|" "DONE(d)" "CANC(c)" "PASS(a)")))
(setq org-todo-keyword-faces
'(("TODO" . "#ff5555") ("PROG" . "#ffb86c") ("PROJ" . "#8be9fd") ("SENT" . "#ff79c6")
("DONE" . "#50fa7b") ("CANC" . "#a4fcba") ("PASS" . "#44475a")))
;; Add these files to the agenda
(setq org-clock-sound (expand-file-name "timer.wav" user-emacs-directory)
org-src-fontify-natively t)
;; Save Org buffers after refiling!
(advice-add 'org-refile :after 'org-save-all-org-buffers))(use-package ox-latex
:config
(add-to-list 'org-latex-classes
'("dndbook"
"\\documentclass{dndbook}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
))
)Eye-candy for org-mode
(use-package org-superstar
:straight t
:after org
:config
(setq org-hide-leading-stars nil)
;; This line is necessary.
(setq org-superstar-leading-bullet ?\s)
;; If you use Org Indent you also need to add this, otherwise the
;; above has no effect while Indent is enabled.
(setq org-indent-mode-turns-on-hiding-stars nil))Helpful popups with descriptions of what each key in the map does
(use-package which-key
:straight t
:defer t
:config
(setq which-key-idle-delay 0.5)
(which-key-mode))(use-package general
:straight t
:after evil
:config
(general-evil-setup t)
(general-override-mode)
;; EViL bindings
(general-define-key
:states '(normal visual emacs)
:keymaps 'override
"U" 'evil-redo
"C" 'evil-mc-make-cursor-move-next-line
"%" 'mark-whole-buffer
"_" 'expreg-expand
"-" 'expreg-contract
)
(general-define-key
:states '(normal visual emacs)
:keymaps '(normal prog-mode-map)
"s" 'avy-goto-char-2
)
(general-define-key
:states '(normal visual emacs)
:keymaps 'override
:prefix "g"
"a" 'evil-switch-to-windows-last-buffer
"h" 'evil-beginning-of-line
"l" 'evil-end-of-line
"g" 'beginning-of-buffer
"e" 'end-of-buffer
"d" 'xref-find-definitions
"r" 'lsp-find-references
"s" 'avy-goto-char-2
)
(general-define-key
:states '(normal)
:keymaps '(dired-mode-map)
"h" 'dired-up-directory
"l" 'dired-find-file
)
(general-define-key
:states 'visual
:keymaps 'override
:prefix "m"
"s" 'evil-surround-region
"r" 'evil-surround-change
"d" 'evil-surround-delete
)
(general-define-key
:states '(normal visual insert emacs)
:keymaps 'override
:prefix "SPC"
:non-normal-prefix "C-SPC"
"y" 'consult-yank-from-kill-ring
"j" 'evil-collection-consult-jump-list
"e" 'vterm
"/" 'evilnc-comment-or-uncomment-lines
"x" 'execute-extended-command
"D" '(:ignore t :which-key "Diagnostics")
"Dd" 'flymake-show-buffer-diagnostics
"DD" 'flymake-show-project-diagnostics
"Dc" 'consult-flycheck
"s" 'consult-lsp-file-symbols
"S" 'consult-lsp-symbols
"l" 'consult-line
"L" 'consult-line-multi
"d" '(:ignore t :which-key "Denote")
"dd" 'denote-open-or-create
"dc" 'calendar
"dn" 'denote
"dl" 'denote-link
"dt" 'denote-journal-new-or-existing-entry
"df" 'consult-denote-find
"dg" 'consult-denote-grep
"dss" 'denote-silo-open-or-create
"dsn" 'denote-silo-create-note
"dsd" 'denote-silo-dired
"b" '(:ignore t :which-key "Buffers")
"br" 'rename-buffer
"bi" 'ibuffer
"bR" 'revert-buffer
"bw" 'toggle-truncate-lines
"bb" 'consult-buffer
"bn" 'evil-next-buffer
"bp" 'evil-prev-buffer
"bk" 'kill-buffer
"f" '(:ignore t :which-key "Files")
"fn" 'consult-notes
"fd" 'dired-jump
"fs" 'save-buffer
"ff" 'find-file
"fF" 'leinz/affe-home
"fr" 'consult-recent-file
"fD" '((lambda () (interactive) (find-file "~/Notes/day-book.org")) :which-key "Open daybook")
"w" '(:ignore t :which-key "Window")
"ws" 'evil-window-split
"wv" 'evil-window-vsplit
"wq" 'evil-window-delete
"wo" 'delete-other-windows
"wj" 'evil-window-down
"wk" 'evil-window-up
"wh" 'evil-window-left
"wl" 'evil-window-right
"wJ" 'evil-window-move-very-bottom
"wK" 'evil-window-move-very-top
"wH" 'evil-window-move-far-left
"wL" 'evil-window-move-far-right
"C" '(:ignore t :which-key "Coding")
"Ct" 'cargo-process-test
"Cb" 'cargo-process-build
;; LSP Mode bindings
"c" '(:ignore t :which-key "Code")
"cg" '(:ignore t :which-key "goto")
"cC" 'recompile
"cc" 'compile
"ce" 'flycheck-list-errors
"ck" 'lsp-describe-thing-at-point
"cK" 'lsp-rust-analyzer-open-external-docs
"ca" 'lsp-execute-code-action
"cr" 'lsp-rename
"cs" 'consult-imenu
"cS" 'consult-imenu-multi
"cd" 'consult-lsp-diagnostics
"ct" 'consult-todo-dir
"p" '(:ignore t :which-key "Project")
"pe" 'multi-vterm-project
"pc" 'project-compile
"pi" 'consult-imenu-multi
"pf" 'project-find-file
"pd" 'project-find-dir
"pp" 'project-switch-project
"pb" 'consult-project-buffer
"pg" 'consult-ripgrep
"pt" 'consult-todo-project
"p!" 'project-shell-command
"h" '(:ignore t :which-key "Helper")
"he" 'emoji-search
"hd" 'devdocs-lookup
"ht" 'consult-theme
"hk" 'describe-key
"hv" 'describe-variable
"hf" 'describe-function
"g" '(:ignore t :which-key "Magit")
"gg" 'magit-status
"gi" 'blamer-show-posframe-commit-info
"gb" 'global-blamer-mode
"gf" 'magit-fetch
"gF" 'magit-fetch-all
"gp" 'magit-push-to-remote
"gs" 'magit-stage-modified
"gc" 'magit-commit
"t" '(:ignore t :which-key "Text Manipulation")
"tf" 'fill-region
"r" '(:ignore t :which-key "Configuration changes")
"rr" '((lambda () (interactive) (load-file (expand-file-name "init.el" user-emacs-directory))) :which-key "Reload init.el")
"re" 'eval-buffer
"!" 'shell-command
"o" '(:ignore t :which-key "Org")
"oa" 'org-agenda
"oc" 'org-clock-in
"oC" 'org-clock-out
"os" 'org-schedule
"od" 'org-deadline
"oy" 'org-store-link
)
;; Org-mode specific bindings
(general-define-key
:states '(normal visual emacs)
:keymaps '(org-mode-map)
:prefix "SPC"
"ob" 'org-babel-tangle
"oe" 'org-export-dispatch
"of" 'org-open-at-point
"oh" 'consult-org-heading
"oi" 'org-insert-link
"ot" 'org-todo
"oT" 'org-set-tags-command
)
)
(use-package which-key
:straight t
:defer 5
:config
(setq which-key-idle-delay 0.5)
(which-key-mode))