#+TITLE: Venomade's Emacs Config #+AUTHOR: Venomade #+STARTUP: showeverything * Table of Contents :toc_2: - [[#straight-package-manager][Straight Package Manager]] - [[#configs][Configs]] - [[#custom-functions][Custom Functions]] - [[#fix-annoyances][Fix Annoyances]] - [[#setup-line-numbers][Setup Line Numbers]] - [[#general][General]] - [[#beacon][Beacon]] - [[#colors][Colors]] - [[#diminish][Diminish]] - [[#evil-mode][Evil Mode]] - [[#general-keybindings][General Keybindings]] - [[#magit][Magit]] - [[#ivy-counsel][Ivy (Counsel)]] - [[#pdf-tools][PDF Tools]] - [[#simple-modeline][Simple Modeline]] - [[#smart-parentheses-pairing][Smart Parentheses Pairing]] - [[#undo-tree][Undo Tree]] - [[#which-key][Which Key]] - [[#dashboard][Dashboard]] - [[#dashboard-config][Dashboard Config]] - [[#clean-up][Clean Up]] - [[#org-mode][Org Mode]] - [[#table-of-contents][Table of Contents]] - [[#bullet-headers][Bullet Headers]] - [[#org-agenda][Org Agenda]] - [[#org-babel][Org Babel]] - [[#org-tempo][Org Tempo]] - [[#mixed-pitch][Mixed Pitch]] - [[#styling][Styling]] - [[#programming][Programming]] - [[#lsp-mode][LSP Mode]] - [[#corfu][Corfu]] - [[#utilities][Utilities]] - [[#terminal][Terminal]] - [[#vterm][VTerm]] - [[#user-interface][User Interface]] - [[#add-nerd-icons][Add Nerd Icons]] - [[#kind-icons][Kind Icons]] - [[#fonts][Fonts]] - [[#theme][Theme]] - [[#niceties][Niceties]] * Straight Package Manager I'm using the Straight package manager instead of use-package because it is only available in Emacs 29 and above. #+begin_src emacs-lisp (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)) (setq straight-use-package-by-default t) #+end_src * Configs ** Custom Functions *** Cursor follow on split This is so that action can be taken as soon as a split takes place, to either close/move the window or perform an action inside of it. #+begin_src emacs-lisp (defun split-and-follow-horizontally() (interactive) (split-window-below) (balance-windows) (other-window 1)) (defun split-and-follow-vertically() (interactive) (split-window-right) (balance-windows) (other-window 1)) #+end_src ** Fix Annoyances *** Disable Backups Living on the edge. #+begin_src emacs-lisp (setq make-backup-files nil) (setq auto-save-default nil) #+end_src *** Disable Bell Only flash, no sound, it gets annoying. #+begin_src emacs-lisp (setq ring-bell-function 'ignore) #+end_src *** Hide Warnings Fixing warnings is for nerds. This is basically necessary after more than 5 packages. #+begin_src emacs-lisp (setq warning-minimum-level :emergency) #+end_src *** Add Scroll Margin This adds a scroll margin at the top and bottom of 12 lines to make it easier to scroll through the buffer. #+begin_src emacs-lisp (setq scroll-margin 12) #+end_src ** Setup Line Numbers Vim style line numbers. #+begin_src emacs-lisp (add-hook 'prog-mode-hook 'display-line-numbers-mode) (setq display-line-numbers-type 'relative) (global-visual-line-mode t) #+end_src *** Generally use spaces instead of tabs Generally, as in everywhere but Go. #+begin_src emacs-lisp (setq-default indent-tabs-mode nil) (setq tab-width 4) (setq tab-stop-list (number-sequence 4 200 4)) #+end_src * General ** Beacon Highlight the cursor's position to make it's position clear on cursor jump. #+begin_src emacs-lisp (use-package beacon :diminish beacon-mode :init (beacon-mode 1)) #+end_src ** Colors *** Highlight Todo Highlight TODO items so they can be reviewed later. #+begin_src emacs-lisp (use-package hl-todo :diminish hl-todo-mode :hook ((org-mode . hl-todo-mode) (prog-mode . hl-todo-mode)) :config (setq hl-todo-highlight-punctuation ":" hl-todo-highlight-faces `(("TODO" warning bold) ("FIXME" error bold) ("HACK" font-lock-constant-face bold) ("REVIEW" font-lock-doc-face bold) ("NOTE" success bold) ("DEPRECATED" font-lock-doc-face bold)))) #+end_src *** Rainbow Mode Highlights color hex codes with their color #+begin_src emacs-lisp (use-package rainbow-mode :diminish rainbow-mode :hook ((org-mode . rainbow-mode) (prog-mode . rainbow-mode))) #+end_src *** Rainbow Delimiters Makes different brackets and other delimeters levels different colors so they can be quickly distinguished. #+begin_src emacs-lisp (use-package rainbow-delimiters :diminish rainbow-delimiters-mode :hook (prog-mode . rainbow-delimiters-mode)) #+end_src ** Diminish Hides modes from the modeline to make it cleaner #+begin_src emacs-lisp (use-package diminish) #+end_src ** Evil Mode *** Evil Mode Package Adds Vim motions to Emacs, I was a vim user and have no interest in getting carpal tunnel, sue me. #+begin_src emacs-lisp (use-package evil :diminish evil-mode :init (setq evil-want-integration t) (setq evil-want-keybinding nil) (setq evil-vsplit-window-right t) (setq evil-split-window-below t) (evil-mode)) #+end_src *** Evil Collection Adds Vim motions to even more Emacs packages. #+begin_src emacs-lisp (use-package evil-collection :after evil :config (setq evil-collection-mode-list '(dashboard dired ibuffer magit)) (evil-collection-init)) #+end_src ** General Keybindings Keybindings for my most common actions. #+begin_src emacs-lisp (use-package general :diminish general-override-mode :config (general-evil-setup) ;; Set 'SPC' as the leader key (general-create-definer vnmd/leader-keys :states '(normal insert visual emacs) :keymaps 'override :prefix "SPC" :global-prefix "M-SPC") ;; For insert mode ;; FIXME Alt-Space is a common keybind for the application menu. (vnmd/leader-keys "/" '(swiper t :wk "Search") "r" '(:ignore t :wk "Reload") "r c" '((lambda () (interactive) (load-file "~/.emacs.d/init.el")) :wk "Reload Config")) (vnmd/leader-keys "b" '(:ignore t :wk "Buffer") "b b" '(switch-to-buffer :wk "Switch buffer") "b k" '(kill-this-buffer :wk "Kill this buffer") "b n" '(next-buffer :wk "Next buffer") "b p" '(previous-buffer :wk "Previous buffer") "b r" '(revert-buffer :wk "Reload buffer")) (vnmd/leader-keys "e" '(:ignore t :wk "Evaluate / Eshell") "e b" '(eval-buffer :wk "Evaluate Elisp buffer") "e d" '(eval-defun :wk "Evaluate Elisp defun") "e e" '(eval-expression :wk "Evaluate Elisp expression") "e l" '(eval-last-sexp :wk "Evaluate Elisp expression before point") "e r" '(eval-region :wk "Evaluate Elisp region") "e s" '(eshell :wk "Eshell")) (vnmd/leader-keys "f" '(:ignore t :wk "Open File") "f c" '((lambda () (interactive) (find-file "~/.emacs.d/config.org")) :wk "Open Emacs config") "f f" '(counsel-fzf :wk "Find (File) Fuzzy") "f g" '(counsel-rg :wk "Find (Rip)Grep") "f p" '(find-file :wk "Find (File) Path") "f r" '(counsel-recentf :wk "Recent file")) (vnmd/leader-keys "g" '(:ignore t :wk "Git") "g s" '(magit-status :wk "Git Status")) (vnmd/leader-keys "l" '(:ignore t :wk "LSP") "l a" '(lsp-execute-code-action :wk "Execute code action") "l d" '(lsp-describe-thing-at-point :wk "Describe at point") "l f" '(lsp-format-buffer :wk "Format buffer") "l m" '(lsp-command-map :wk "LSP Command Map") "l w" '(flycheck-list-errors :wk "Show Diagnostics")) (vnmd/leader-keys "m" '(:ignore t :wk "Make") "m c" '(compile :wk "Compile") "m r" '(recompile :wk "Recompile")) (vnmd/leader-keys "o" '(:ignore t :wk "Org Mode") "o a" '(org-agenda :wk "Open Agenda") "o A" '((lambda () (interactive) (find-file "~/Documents/Org/agenda.org")) :wk "Edit Agenda") "o d" '(:ignore t :wk "Date") "o d n" '(org-timestamp-up :wk "Next Date") "o d p" '(org-timestamp-down :wk "Previous Date") "o d d" '(org-time-stamp :wk "Insert Date") "o e" '(:ignore t :wk "Org Export") "o e h" '(org-html-export-to-html :wk "Export to HTML")) (vnmd/leader-keys "t" '(:ignore t :wk "Terminal") "t t" '(vterm-toggle :wk "Toggle Terminal")) (vnmd/leader-keys "u" '(undo-tree-visualize :wk "Undo Tree")) (vnmd/leader-keys "w" '(:ignore t :wk "Windows") "w h" '(evil-window-left :wk "Window Left") "w " '(evil-window-left :wk "Window Left") "w j" '(evil-window-down :wk "Window Down") "w " '(evil-window-down :wk "Window Down") "w k" '(evil-window-up :wk "Window Up") "w " '(evil-window-up :wk "Window Up") "w l" '(evil-window-right :wk "Window Right") "w " '(evil-window-right :wk "Window Right") "w u" '(winner-undo :wk "Undo Movement") "w r" '(winner-redo :wk "Redo Movement") "w c" '(evil-window-delete :wk "Close Window") "w n" '(evil-window-new :wk "New Window") "w v" '(evil-window-vsplit :wk "Split Window (Vertical)") "w s" '(evil-window-split :wk "Split Window (Horizontal)")) (vnmd/leader-keys :keymaps 'org-mode-map "c" '(:ignore t :wk "Org-Src") "c '" '(org-edit-src-code :wk "Edit Source Block")) (vnmd/leader-keys :keymaps 'org-src-mode-map "c" '(:ignore t :wk "Org-Src") "c '" '(org-edit-src-exit :wk "Exit Source Block")) ) #+end_src ** Magit A very extensive Git GUI for Emacs. #+begin_src emacs-lisp (use-package magit :after evil-collection) #+end_src ** Ivy (Counsel) *** Counsel Adds better fuzzy completion to many Emacs commands. #+begin_src emacs-lisp (use-package counsel :diminish counsel-mode :after ivy :config (counsel-mode)) #+end_src *** Counsel Web Adds an interactible web search into emacs. #+begin_src emacs-lisp (use-package counsel-web) (setq counsel-web-search-action 'browse-url) #+end_src *** Ivy Adds fuzzy completion to basic Emacs commands. #+begin_src emacs-lisp (use-package ivy :diminish ivy-mode :custom (setq ivy-use-virtual-buffers t) (setq ivy-count-format "(%d/%d) ") (setq enable-recursive-minibuffers t) :config (ivy-mode)) #+end_src *** Ivy Rich Adds Icons to all the new fuzzy completed Emacs commands. #+begin_src emacs-lisp (use-package ivy-rich :diminish ivy-rich-mode :after ivy :init (ivy-rich-mode 1) :custom (ivy-virtual-abbreviate 'full ivy-rich-switch-buffer-align-virtual-buffer t ivy-rich-path-style 'abbrev)) #+end_src ** PDF Tools View PDFs within Emacs and have their colours match the theme. *** Install and Theme #+begin_src emacs-lisp (use-package pdf-tools :init (pdf-tools-install) :config (pdf-tools-install) :hook (pdf-view-mode . pdf-view-themed-minor-mode)) #+end_src *** Evil mode compatibility fix Fix an evil-mode pdf-view-mode compatibility bug that draws a flashing border around the PDF. #+begin_src emacs-lisp (evil-set-initial-state 'pdf-view-mode 'emacs) (add-hook 'pdf-view-mode-hook (lambda () (set (make-local-variable 'evil-emacs-state-cursor) (list nil)))) #+end_src ** Simple Modeline Make the modeline simple, yet still display helpful information. #+begin_src emacs-lisp (use-package simple-modeline :diminish simple-modeline-mode :custom (simple-modeline-segments '((simple-modeline-segment-modified simple-modeline-segment-buffer-name simple-modeline-segment-position) (simple-modeline-segment-vc ;;simple-modeline-segment-minor-modes ;;simple-modeline-segment-misc-info ;;simple-modeline-segment-process simple-modeline-segment-major-mode))) :hook (after-init . simple-modeline-mode)) #+end_src ** Smart Parentheses Pairing Automatically deals with parentheses in pairs. #+begin_src emacs-lisp (use-package smartparens :diminish smartparens-mode :hook (prog-mode text-mode markdown-mode) :config (require 'smartparens-config)) #+end_src ** Undo Tree Makes undo history like a Git commit tree, very powerful. #+begin_src emacs-lisp (use-package undo-tree :diminish undo-tree-mode :config (setq undo-tree-auto-save-history nil) (evil-set-undo-system 'undo-tree) (add-hook 'evil-local-mode-hook 'turn-on-undo-tree-mode)) #+end_src ** Which Key After pressing a key and a half-second delay, list out the possible next keys to perform a shortcut. #+begin_src emacs-lisp (use-package which-key :diminish which-key-mode :init (which-key-mode 1) :config (setq which-key-side-window-location 'bottom which-key-sort-order #'which-key-key-order-alpha which-key-sort-uppercase-first nil which-key-add-column-padding 1 which-key-max-display-columns nil which-key-min-display-lines 6 which-key-side-window-slot -10 which-key-side-window-max-height 0.25 which-key-idle-delay 0.4 which-key-max-description-length 25 which-key-allow-imprecise-window-fit t which-key-separator " -> " )) #+end_src * Dashboard ** Dashboard Config A dashboard for quick actions after entering Emacs. #+begin_src emacs-lisp (use-package welcome-dashboard :diminish welcome-dashboard-mode :straight '(:type git :host github :repo "konrad1977/welcome-dashboard") :config (setq welcome-dashboard-latitude 52.0848 welcome-dashboard-longitude 0.4368 ;; latitude and longitude must be set to show weather information welcome-dashboard-path-max-length 75 welcome-dashboard-use-fahrenheit nil ;; show in celcius or fahrenheit. welcome-dashboard-min-left-padding 10 welcome-dashboard-image-file "~/.emacs.d/EmacsLogo.png" welcome-dashboard-image-width 261 welcome-dashboard-image-height 220 welcome-dashboard-title "Welcome Venomade. Time to Emacs!") (welcome-dashboard-create-welcome-hook)) #+end_src ** Clean Up *** Hide Mode Line Hide the modeline in the dashboard. #+begin_src emacs-lisp (use-package hide-mode-line :hook (welcome-dashboard-mode . hide-mode-line-mode)) #+end_src *** Hide messages Hide startup messages, like 'hide warnings' but for information tooltips. #+begin_src emacs-lisp (defun display-startup-echo-area-message () (message "")) (setq inhibit-startup-message t) (setq inhibit-startup-echo-area-message t) (defun dashboard-quiet() "Shut up those messages" (message nil)) (add-hook 'dashboard-quiet 'welcome-dashboard-mode) #+end_src * Org Mode ** Table of Contents Automatically generate a table of contents for an Org file. #+begin_src emacs-lisp (use-package toc-org :diminish toc-org-mode :commands toc-org-enable :init (add-hook 'org-mode-hook 'toc-org-enable) :config (setq org-src-window-setup 'current-window)) (add-hook 'org-mode-hook 'org-indent-mode) #+end_src ** Bullet Headers Stylize Org Mode headers with Nerd Icons. #+begin_src emacs-lisp (use-package org-bullets :diminish org-bullets-mode :config (setq org-bullets-bullet-list '( "" "" "" "" ""))) (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))) #+end_src ** Org Agenda Manage a Todo list, a Calendar, and other organization tools with Org. #+begin_src emacs-lisp (setq org-agenda-files '("~/Documents/Org/agenda.org")) (setq org-fancy-priorities-list '("[A]" "[B]" "[C]") org-priority-faces '((?A :foreground "#ff6c6b" :weight bold) (?B :foreground "#ffff91" :weight bold) (?C :foreground "#aaffaa" :weight bold))) (setq org-agenda-custom-commands '(("v" "View Agenda" ((tags "PRIORITY=\"A\"" ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done)) (org-agenda-overriding-header "HIGH PRIORITY:"))) (tags "PRIORITY=\"B\"" ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done)) (org-agenda-overriding-header "Medium Priority:"))) (tags "PRIORITY=\"C\"" ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done)) (org-agenda-overriding-header "low priority:"))) (agenda "") (alltodo ""))))) #+end_src ** Org Babel Setup literate progamming in Org Mode. *** Config Don't ask for conformation when evaluating source blocks. #+begin_src emacs-lisp (setq org-confirm-babel-evaluate nil) #+end_src *** Load Languages #+begin_src emacs-lisp (org-babel-do-load-languages 'org-babel-load-languages '((python . t) (scheme . t))) #+end_src ** Org Tempo This provides shorthands for Org functions. #+begin_src emacs-lisp (require 'org-tempo) #+end_src ** Mixed Pitch Allow Monospace fonts and Proportional fonts in the same buffer, enabling it for Org Mode. #+begin_src emacs-lisp (use-package mixed-pitch :diminish mixed-pitch-mode :hook (org-mode . mixed-pitch-mode)) #+end_src ** Styling Hide markers for bold, italic and other types of text styling. #+begin_src emacs-lisp (setq org-hide-emphasis-markers t) #+end_src * Programming ** LSP Mode Use language servers to provide info and completion #+begin_src emacs-lisp (use-package lsp-mode :init (setq lsp-completion-provider :none) :commands lsp lsp-deferred :config (lsp-enable-snippet nil) (lsp-enable-which-key-integration t) :hook (prog-mode . lsp-deferred)) (use-package lsp-ui :commands lsp-ui-mode :hook (prog-mode . lsp-ui-mode)) (define-key evil-normal-state-map (kbd "K") 'lsp-ui-doc-show) #+end_src ** Corfu A lightweight auto-completion utility #+begin_src emacs-lisp (use-package corfu :diminish corfu-mode :custom (corfu-auto t) (corfu-auto-delay 0.1) (corfu-auto-prefix 2) (corfu-quit-no-match t) (corfu-cycle t) (corfu-preselect 'prompt) :bind (:map corfu-map ("RET" . nil) ("TAB" . corfu-next) ([tab] . corfu-next) ("S-TAB" . corfu-previous) ([backtab] . corfu-previous)) :init (global-corfu-mode) (corfu-popupinfo-mode)) (use-package emacs :init (setq completion-cycle-threshold 3) (setq corfu-popupinfo-delay 0) (setq tab-always-indent 'complete)) #+end_src ** Utilities *** Flycheck Syntax checking for Emacs. #+begin_src emacs-lisp (use-package flycheck :diminish flycheck-mode :defer t :init (global-flycheck-mode)) #+end_src *** Tree Sitter Insane syntax highlighting. #+begin_src emacs-lisp (use-package tree-sitter) (use-package tree-sitter-langs) (global-tree-sitter-mode) (add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode) #+end_src *** Languages Specific language packages **** Rust #+begin_src emacs-lisp (use-package rust-mode :init (setq rust-mode-treesitter-derive t)) (setenv "PATH" (concat (concat (concat (expand-file-name "~/.cargo/bin") ":") (getenv "PATH")))) (setq exec-path (append exec-path (list (expand-file-name "~/.cargo/bin")))) #+end_src * Terminal ** VTerm Add a more traditional terminal to Emacs. *** VTerm Package #+begin_src emacs-lisp (use-package vterm :config (setq shell-file-name "/bin/bash" vterm-max-scrollback 5000)) #+end_src *** VTerm Toggle Toggle VTerm with 'SPC-t-t' #+begin_src emacs-lisp (use-package vterm-toggle :after vterm :config (setq vterm-toggle-fullscreen-p nil) (setq vterm-toggle-scope 'project) (add-to-list 'display-buffer-alist '((lambda (buffer-or-name _) (let ((buffer (get-buffer buffer-or-name))) (with-current-buffer buffer (or (equal major-mode 'vterm-mode) (string-prefix-p vterm-buffer-name (buffer-name buffer)))))) (display-buffer-reuse-window display-buffer-at-bottom) (reusable-frames . visible) (window-height . 0.3)))) #+end_src * User Interface ** Add Nerd Icons Use Icons from Nerd Font to add a little modern spice to Emacs. #+begin_src emacs-lisp (use-package nerd-icons :if (display-graphic-p)) (use-package nerd-icons-dired :hook (dired-mode . nerd-icons-dired-mode)) (use-package nerd-icons-ivy-rich :init (nerd-icons-ivy-rich-mode 1)) (setq welcome-dashboard-use-nerd-icons t) #+end_src ** Kind Icons #+begin_src emacs-lisp (use-package kind-icon :after corfu :custom (kind-icon-default-face 'corfu-default) :config (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter)) #+end_src ** Fonts *** Set Font Set fonts for both Monospace and Proportional text. #+begin_src emacs-lisp (set-face-attribute 'variable-pitch nil :font "ZedMono Nerd Font" :height 160 :weight 'regular) (add-to-list 'default-frame-alist '(font . "ZedMono Nerd Font-16")) (set-face-attribute 'font-lock-comment-face nil :slant 'italic) (set-face-attribute 'font-lock-keyword-face nil :slant 'italic) #+end_src *** Ligatures Make ligature symbols out of common function symbols. #+begin_src emacs-lisp (dolist (char/ligature-re `((?- . ,(rx (or (or "-->" "-<<" "->>" "-|" "-~" "-<" "->") (+ "-")))) (?/ . ,(rx (or (or "/==" "/=" "/>" "/**" "/*") (+ "/")))) (?* . ,(rx (or (or "*>" "*/") (+ "*")))) (?< . ,(rx (or (or "<<=" "<<-" "<|||" "<==>" "