* General Configuration General configuration is configuration of vanilla Emacs. This includes making Emacs more minimal. ** Disable Error Bell Disable error bell and visual bell. Visual bell would be nice on Linux, but on mac it is just annoying so I removed it temp. #+begin_src emacs-lisp (setq ring-bell-function 'ignore) (setq visual-bell nil) #+end_src ** Disable Dialog Box Disables the dialog prompting box and instead prompts the user in the minibuffer. #+begin_src emacs-lisp (setq use-dialog-box nil) #+end_src ** Relocate Custom File Change location of custom file. This will stop *custom* from appending to the config file. #+begin_src emacs-lisp (setq custom-file "~/.emacs.d/custom.el") (unless (file-exists-p custom-file) (make-empty-file custom-file)) (load custom-file) #+end_src ** Move Backup File This moves the backup files so that Emacs doesn't clutter up directories with backup files. #+begin_src emacs-lisp (setq backup-directory-alist '(("." . "~/.emacs.d/backups/"))) #+end_src ** White Space Various configuration relating to white-space. #+begin_src emacs-lisp (setq-default electric-ident-inhibit t) ; Stop indentation of the previous line. #+end_src *** Tabs/Spaces Disable tabs and replace them with a custom number of spaces. #+begin_src emacs-lisp (setq-default indent-tabs-mode nil) ; Use spaces instead of tabs. (setq-default tab-width 4) (setq-default evil-shift-width tab-width) ; C Indentation (setq-default c-basic-offset 4) ; Yara Indentation (setq-default yara-indent-offset 4) (setq-default yara-indent-section 4) #+end_src *** Visualizing White Space 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 emacs-lisp (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 ** SSH Remoting with Tramp Below are a few configuration changes to avoid TRAMP freezes when attempting to SSH into another system with more complex config files. #+begin_src emacs-lisp (setq tramp-remote-shell "/bin/sh") (setq tramp-remote-shell-login "-l") (setq tramp-remote-shell-args "-c") #+end_src * Package Manager Emacs and packages. Pretty much a requirement. ** Setup package Initialize *package* and setup package archives. This lets you install packages from other archives such as [[https://melpa.org/][melpa]]. #+begin_src emacs-lisp (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 ** Use-package Install use package for easier installation of other packages. #+begin_src emacs-lisp (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 * Cosmetic Packages that change the look of Emacs in some way. ** Cosmetic Configuration Disable the useless features that make Emacs bloated. #+begin_src emacs-lisp ; Disable startup message (setq inhibit-startup-message t) (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 (setq scroll-margin 4) ; Scroll as cursor reaches bottom/top of page. #+end_src *** Change font Pretty self explanatory. #+begin_src emacs-lisp (defun jm/set-font-faces () (set-face-attribute 'default nil :font "Fira Code Light" :height 140)) #+end_src Adding a fix for fonts when running Emacs as a daemon. #+begin_src emacs-lisp (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 Modeline Use doom modeline to make the modeline look nicer. #+begin_src emacs-lisp (use-package all-the-icons) ; requirement (use-package doom-modeline :init (doom-modeline-mode 1) :config (setq doom-modeline-height 45) (display-time)) #+end_src In order to avoid missing icons, you should also install the package ~all-the-icons-install-fonts~ through the Emacs command line. ** Doom Themes Install doom themes for better themes. #+begin_src emacs-lisp (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 ** Line Numbers This adds relative line numbers while excluding certain modes. #+begin_src emacs-lisp ; 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 * Keybindings Contains the configuration for any keybindings or packages relating to keybindings. ** General Configurations Remap quit command to make it easier to rescue a buffer. With this function, escape will be used instead of ~C-g~. #+begin_src emacs-lisp (global-set-key (kbd "") 'keyboard-escape-quit) #+end_src ** Which-key Lists all possible keybindings off of prefix. #+begin_src emacs-lisp (use-package which-key :init (which-key-mode) :diminish which-key-mode) #+end_src ** 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 emacs-lisp (use-package general :config (general-create-definer jm/leader-keys :keymaps '(normal insert visual emacs) :prefix "SPC" :global-prefix "C-SPC") (jm/leader-keys ; Emacs related keybindings "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 ** Evil Evil is a package that adds vim keybindings to Emacs. #+begin_src emacs-lisp ;; Setup vim keybindings with evil (use-package evil :init (setq evil-want-integration t) (setq evil-want-keybinding nil) ; replaced with evil collection (setq evil-want-C-u-scroll t) (setq evil-want-C-i-jump nil) :config (evil-mode 1) (define-key evil-insert-state-map (kbd "C-g") 'evil-normal-state) (define-key evil-insert-state-map (kbd "C-h") 'evil-delete-backward-char-and-join) ; Use visual line motions even outside of visual-line-mode buffers. (evil-global-set-key 'motion "j" 'evil-next-visual-line) (evil-global-set-key 'motion "k" 'evil-previous-visual-line) ; Modify which modes use vim keybindings. (evil-set-initial-state 'messages-buffer-mode 'normal) (evil-set-initial-state 'dashboard-mode 'normal)) #+end_src *** Evil Collection Evil collection is a package that replaces the bad ~evil-want-keybinding~ keybindings. #+begin_src emacs-lisp (use-package evil-collection :after evil :config (evil-collection-init)) #+end_src *** Evil Numbers The /Evil Numbers/ package implements the ability to increment or decrement numbers as you would with vim using ~C-a~ and ~C-x~. #+begin_src emacs-lisp (use-package evil-numbers :after evil :config (evil-define-key '(normal visual) 'global (kbd "C-c =") 'evil-numbers/inc-at-pt) (evil-define-key '(normal visual) 'global (kbd "C-c -") 'evil-numbers/dec-at-pt) (evil-define-key '(normal visual) 'global (kbd "C-c C-=") 'evil-numbers/inc-at-pt-incremental) (evil-define-key '(normal visual) 'global (kbd "C-c C--") 'evil-numbers/dec-at-pt-incremental)) #+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 emacs-lisp ; Fix vim redo with undo tree (use-package undo-tree :after evil :config (evil-set-undo-system 'undo-tree) (setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo"))) (global-undo-tree-mode 1)) #+end_src * Other Packages This is a list of installed packages not included in any other category. ** MacOS Environment Fix When using emacs on MacOS, the environment variables are not synced properly and therefore require a separate package to fix this. In this case, this package is the ~exec-path-from-shell~. #+begin_src emacs-lisp ;(use-package exec-path-from-shell ;:config ;(when (memq window-system '(mac ns x)) ;(exec-path-from-shell-initialize))) #+end_src ** Perspective *Perspective* is a package to help with managing buffers. It allows for multiple /workspaces/ or /perspectives/ which each contain their own sub list of buffers. #+begin_src emacs-lisp (use-package perspective :bind (("C-x b" . persp-switch-to-buffer*) ("C-x k" . persp-kill-buffer*)) :custom (persp-mode-prefix-key (kbd "C-x w")) :init (persp-mode)) #+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 emacs-lisp (use-package projectile :bind-keymap ("C-x p" . projectile-command-map) :config (projectile-mode +1) :init (when (file-directory-p "~/Projects") (setq projectile-project-search-path '("~/Projects")))) #+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 emacs-lisp (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 examples 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 emacs-lisp (use-package savehist :init (savehist-mode)) (use-package marginalia :after vertico :init (marginalia-mode)) (use-package orderless :custom (completion-styles '(orderless basic)) (completion-category-overrides '((file (styles basic partial-completion))))) (use-package consult :after vertico :config (jm/leader-keys "pg" 'consult-grep "pf" 'consult-find)) #+end_src ** Helpful *Helpful* is a package that improves the builtin Emacs help menus. The config below installs helpful and sets the keybindings to call helpful functions instead of the default emacs help. #+begin_src emacs-lisp (use-package helpful :bind (("C-h f" . #'helpful-callable) ("C-h v" . #'helpful-variable) ("C-h k" . #'helpful-key) ("C-h x" . #'helpful-command))) #+end_src ** Magit *Magit* adds several features to Emacs that make using git easier. #+begin_src emacs-lisp (use-package magit :config (jm/leader-keys "gc" 'magit-clone)) #+end_src ** Dashboard The Emacs dashboard package provides a nice dashboard when first starting up emacs. #+begin_src emacs-lisp (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 "Fira Code Light" :weight 'regular :height 140) (dashboard-setup-startup-hook)) #+end_src ** Ledger Ledger is a Unix program that implements a finance tracking system or /ledger/. To implement this into emacs, you can install the ~ledger-mode~ emacs package. #+begin_src emacs-lisp (use-package ledger-mode :mode ("\\.ledger\\'") :config (setq ledger-report-use-strict t ledger-master-file (file-truename "~/Nextcloud/Ledger/toc.ledger") ledger-accounts-file (file-truename "~/Nextcloud/Ledger/accounts.ledger")) (setq ledger-reports `(("bal" ,(format "%%(binary) -f %s bal" ledger-master-file)) ("budget" ,(format "%%(binary) -f %s --budget -p 'this month' bal Expenses" ledger-master-file)) ("account" ,(format "%%(binary) -f %s reg %%(account)" ledger-master-file)) ("monthly bal" ,(format "%%(binary) -f %s bal -p 'this month'" ledger-master-file)) ("daily bal" ,(format "%%(binary) -f %s bal -p 'today'" ledger-master-file))))) #+end_src ** Alert Alert is another library that better implements system notifications through emacs. As I use both MacOS and Linux, notifications don't work out of the box for both systems. Using alert, I can change this by selecting a working notify system for each OS. #+begin_src emacs-lisp (use-package alert :config (setq alert-default-style (if (eq system-type 'darwin) 'osx-notifier 'libnotify))) #+end_src * Builtin Package Config ** Dired Dired is a built-in package in Emacs that allows for basic file navigation. While it serves its purpose, vanilla dired is far from a good file navigator. With some basic customization however, this can be changed. #+begin_src emacs-lisp (use-package dired :ensure nil ; Melpa won't be able to find this package. :commands (dired dired-jump) :bind (("C-x C-j" . dired-jump)) :custom ((dired-listing-switches "-ahgo")) :config (evil-collection-define-key 'normal 'dired-mode-map "h" 'dired-single-up-directory "l" 'dired-single-buffer "T" 'dired-create-empty-file)) #+end_src *** Dired Single Vanilla dired opens a new buffer for every new directory it visits. When managing files, this will quickly fill up resulting in a ridiculous number of buffers. Though, single dired fixes this problem by instead modifying the current buffer when navigating through files. #+begin_src emacs-lisp (use-package dired-single :after dired) #+end_src *** All the Icons Dired ~all-the-icons-dired~ is a dired plugin that adds icons to each of the files. #+begin_src emacs-lisp (use-package all-the-icons-dired :after dired :hook (dired-mode . all-the-icons-dired-mode)) #+end_src *** Hide Dotfiles This hides all dotfiles in dired with the keybinding ~H~. #+begin_src emacs-lisp (use-package dired-hide-dotfiles :hook (dired-mode . dired-hide-dotfiles-mode) :config (evil-collection-define-key 'normal 'dired-mode-map "H" 'dired-hide-dotfiles-mode)) #+end_src ** ERC ERC is a builtin package that adds IRC chatting functionality to emacs. #+begin_src emacs-lisp ;; Shotcuts for general (jm/leader-keys "cc" '(erc-tls :which-key "Connect to IRC over TLS") "cb" '(erc-switch-to-buffer :which-key "Switch IRC buffers")) (use-package erc :ensure nil :defer t :custom (erc-nick "random936") (erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE" "353" "324" "329" "332" "333" "353" "477")) (erc-autojoin-channels-alist '((".*\.libera\.chat" "#emacs" "#gentoo" "#systemcrafters"))) (erc-fill-column 120) (erc-fill-function 'erc-fill-static) (erc-fill-static-center 20) (erc-kill-buffer-on-part t) (erc-kill-queries-on-quit t) (erc-kill-server-buffer-on-quit t) :config (add-to-list 'erc-modules 'notifications) ;; Fix for perspective.el not adding ERC buffers to active perspective. (add-hook 'erc-join-hook (lambda (&rest args) (persp-add-buffer (current-buffer))))) #+end_src *** ERC Extensions To highlight each nickname with a different color, I can use the ~erc-hl-nicks~ package. I can also use the ~erc-image~ package to render images sent by other users over IRC. #+begin_src emacs-lisp (use-package erc-hl-nicks :after erc :config (add-to-list 'erc-modules 'hl-nicks)) (use-package erc-image :after erc :config (setq erc-image-inline-rescale 300) (add-to-list 'erc-modules 'image)) #+end_src *** ERC Alert Integration Alert is a notification system that works with MacOS, however it is not integrated by default. To fix this, you need to create a function to hook with the ERC text matching. #+begin_src emacs-lisp (defun jm/erc-alert-integration (match-type nick message) (alert message :title (format "%s in %s" nick (buffer-name)) :category 'erc)) (add-hook 'erc-text-matched-hook 'jm/erc-alert-integration) #+end_src * Import Other Files This is the section to include imports from other files. #+begin_src emacs-lisp (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)))) (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/lsp.org") ; Language Server Protocol (jm/load-config-if-exists "~/.emacs.d/terminal.org") ; Emacs Terminal (jm/load-config-if-exists "~/.emacs.d/email.org") ; Mu4e/SMTP Config ;; Load EXWM configuration if environment variable set. (let ((exwm-org-file "~/.emacs.d/exwm.org")) (when (and (file-exists-p exwm-org-file) (getenv "USING_EXWM")) (org-babel-load-file exwm-org-file))) #+end_src