* General Config ** Disable Annoying Features Disable the useless features that make Emacs bloated. #+begin_src elisp (setq ring-bell-function 'ignore visual-bell nil use-dialog-box nil inhibit-startup-message t scroll-margin 4) ; Scroll as cursor reaches bottom/top of page. (scroll-bar-mode -1) ; Disable scrollbar (tool-bar-mode -1) ; Disable toolbar (tooltip-mode -1) ; Disable tooltips (menu-bar-mode -1) ; Disable menu-bar (set-fringe-mode 10) ; Add gaps on left and right #+end_src ** Global Auto Revert Enabling global auto revert in Emacs so that changes across a shared file system are synced with emacs buffers. #+begin_src elisp (global-auto-revert-mode 1) (setq auto-revert-use-notify nil) (setq auto-revert-verbose 1) #+end_src ** Relocate Emacs Files Change location of custom file. This will stop *custom* from appending to the config file. #+begin_src elisp (setq custom-file "~/.emacs.d/custom.el") (unless (file-exists-p custom-file) (make-empty-file custom-file)) (load custom-file) #+end_src This moves the backup files so that Emacs doesn't clutter up directories with backup files. #+begin_src elisp (setq backup-directory-alist '(("." . "~/.emacs.d/backups/"))) #+end_src ** Remap Quit Key Remap quit command to make it easier to rescue a buffer. With this function, escape will be used instead of ~C-g~. #+begin_src elisp (global-set-key (kbd "") 'keyboard-escape-quit) #+end_src ** White Space Use spaces instead of tabs and set tab-width. #+begin_src elisp (setq-default indent-tabs-mode nil) (setq-default tab-width 4) (setq-default evil-shift-width tab-width) #+end_src Add a nice visualization for tabs and spaces. This can be helpful to identify which is which quickly to avoid submitting poorly spaced code. #+begin_src elisp (global-whitespace-mode) (setq whitespace-global-modes '(not org-mode dired-mode erc-mode)) (setq whitespace-style '(face tabs spaces tab-mark space-mark trailing)) (custom-set-faces '(whitespace-tab ((t (:foreground "#384551")))) '(whitespace-space ((t (:foreground "#384551"))))) (setq whitespace-display-mappings '((tab-mark 9 [187 9] [92 9]) (space-mark 32 [183] [46]))) #+end_src ** Line Numbers This adds relative line numbers while excluding certain modes. #+begin_src elisp ; Disable line numbers for certain modes (dolist (mode '(org-mode-hook erc-mode-hook mu4e-main-mode-hook term-mode-hook vterm-mode-hook shell-mode-hook eshell-mode-hook)) (add-hook mode (lambda () (display-line-numbers-mode 0)))) ; Enable relative line numbers (setq-default display-line-numbers-type 'visual) (global-display-line-numbers-mode t) #+end_src ** Package Manager Setup Setting up package archives: #+begin_src elisp (require 'package) (setq package-archives '(("melpa" . "https://melpa.org/packages/") ("org" . "https://orgmode.org/elpa/") ("elpa" . "https://elpa.gnu.org/packages/"))) (package-initialize) (unless package-archive-contents (package-refresh-contents)) #+end_src Installing ~use-package~ macros: #+begin_src elisp (unless (package-installed-p 'use-package) (package-install 'use-package)) (require 'use-package) (setq use-package-always-ensure t) (setq use-package-compute-statistics t) #+end_src * Cosmetics ** Update Font #+begin_src elisp (defun jm/set-font-faces () (set-face-attribute 'default nil :font "Maple Mono" :height 140)) ; Fix for fonts when running Emacs as a daemon. (if (daemonp) (add-hook 'after-make-frame-functions (lambda (frame) (with-selected-frame frame (jm/set-font-faces)))) (jm/set-font-faces)) #+end_src ** Doom Packages #+begin_src elisp (use-package all-the-icons) (use-package doom-modeline :init (doom-modeline-mode 1) :config (setq doom-modeline-height 45) (display-time)) (use-package doom-themes :init (load-theme 'doom-city-lights t)) #+end_src ** Rainbow Delimiters Colors parenthesis for better lisp syntax highlighting. #+begin_src emacs-lisp (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode)) #+end_src * Keybindings ** General General allows you to setup a prefix key easily. This makes it really easy to setup a bunch of keybindings with ease. #+begin_src elisp (use-package general :config (general-create-definer jm/leader-keys :keymaps '(normal insert visual emacs) :prefix "SPC" :global-prefix "C-SPC")) #+end_src Emacs related keybindings: #+begin_src elisp (jm/leader-keys "r" '(rename-buffer :which-key "Rename buffer") "er" '((lambda () (interactive) (load-file "~/.emacs")) :which-key "Reload emacs config") "es" '(eshell :which-key "Open eshell terminal")) #+end_src ** Which-Key #+begin_src elisp (use-package which-key :init (which-key-mode) :diminish which-key-mode) #+end_src ** Evil ~evil~ is a package that adds vim keybindings to Emacs. #+begin_src elisp (use-package evil :init (setq evil-want-keybinding nil) :config (evil-mode 1)) #+end_src *** Evil Collection Collection of ~evil~ keybindings for parts of emacs that are not properly covered by default (eg. ~help-mode~ and ~M-x calendar~). #+begin_src elisp (use-package evil-collection :after evil :config (evil-collection-init)) #+end_src *** Undo-Tree Undo tree's use is self explanatory. While the built-in Emacs undo system is fine for me, *undo-tree* is required as it fixes an issue with evil where you can't redo. #+begin_src elisp (use-package undo-tree :after evil :config (setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo"))) (evil-set-undo-system 'undo-tree) (global-undo-tree-mode 1)) #+end_src * Programming ** Auto-completion *** Corfu ~corfu~ is a package that allows for in-buffer completion. #+begin_src elisp (use-package corfu :custom (corfu-cycle t) (tab-always-indent 'complete) (text-mode-ispell-word-completion nil) :init (global-corfu-mode) (corfu-history-mode)) (use-package dabbrev :bind (("M-/" . dabbrev-completion) ("C-M-/" . dabbrev-expand)) :config (add-to-list 'dabbrev-ignored-buffer-regexps "\\` ") (add-to-list 'dabbrev-ignored-buffer-modes 'authinfo-mode) (add-to-list 'dabbrev-ignored-buffer-modes 'doc-view-mode) (add-to-list 'dabbrev-ignored-buffer-modes 'pdf-view-mode) (add-to-list 'dabbrev-ignored-buffer-modes 'tags-table-mode)) (use-package cape :defer 10 :init (add-to-list 'completion-at-point-functions #'cape-file) (add-to-list 'completion-at-point-functions #'cape-dabbrev)) #+end_src *** Vertico ~vertico~ is a package that implements a drop-down like menu in the mini buffer allowing for much better searching. #+begin_src elisp (use-package vertico :init (vertico-mode)) #+end_src When installing Vertico, the documentation mentions a few other packages that add some nice features that would come by default with something like /ivy/. I've added some descriptions of these below: - ~savehist~ - One feature of Vertico that is really helpful is it's seamless integration with the built-in emacs package, ~savehist~, to save command history when navigating. - ~marginalia~ - Similar to the definition of /marginalia/, this emacs package implements descriptions besides each option in Vertico completion. Some eamples of this would be definitions for Elisp functions, more verbose file information, etc. - ~orderless~ - By default, Vertico starts its completion from the start of the search the same way as default emacs completion. The ~orderless~ package changes this by implementing a nicer completion that searches for any similar options based on the provided search terms. - ~consult~ - Adds a bunch of helpful search and navigation commands such as recursive file grepping, etc. #+begin_src elisp (use-package savehist :init (savehist-mode)) (use-package marginalia :after vertico :init (marginalia-mode)) (use-package orderless :custom (completion-styles '(orderless basic)) (completion-category-defaults nil) (completion-category-overrides '((file (styles partial-completion))))) (use-package consult :after vertico :config (jm/leader-keys "pg" 'consult-git-grep "pf" 'consult-find)) #+end_src ** Projectile Projectile is a package for managing various /projects/ in emacs. It adds functionality to let you interact with various /projects/ such as quickly searching filenames, switching between all projects, grepping all files, etc. #+begin_src elisp (use-package projectile :bind-keymap ("C-x p" . projectile-command-map) :config (projectile-mode +1) :init (when (file-directory-p "~/Developer") (setq projectile-project-search-path '("~/Developer")))) #+end_src ** Magit ~magit~ adds several features to Emacs that make using git easier. #+begin_src elisp (use-package magit :bind (("C-x g" . magit-status) ("C-x C-g" . magit-status))) #+end_src * Other Packages ** Dashboard The ~dashboard~ package provides a nice dashboard when first starting up emacs. #+begin_src elisp (use-package dashboard :init (setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*")) dashboard-startup-banner 'logo dashboard-icon-type 'nerd-icons dashboard-set-file-icons t dashboard-set-heading-icons t dashboard-items '((projects . 5) (recents . 5) (agenda . 5))) :config (set-face-attribute 'dashboard-items-face nil :font "Maple Mono" :height 140) (dashboard-setup-startup-hook)) #+end_src * Import Other Files Function to include other config files. #+begin_src elisp (defun jm/load-config-if-exists (file-path) (if (file-exists-p file-path) (org-babel-load-file file-path) (warn (concat "Failed to load config: " file-path)))) #+end_src Load other files: #+begin_src elisp (jm/load-config-if-exists "~/.emacs.d/functions.org") ; Personal Elisp Functions (jm/load-config-if-exists "~/.emacs.d/org.org") ; Org-mode (jm/load-config-if-exists "~/.emacs.d/dired.org") ; Dired Config (jm/load-config-if-exists "~/.emacs.d/lsp.org") ; Language Server Protocol (jm/load-config-if-exists "~/.emacs.d/erc.org") ; Emacs IRC Client Config #+end_src