* 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 Retina" :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) #+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 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 ** 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. ** 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. #+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))))) #+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 'all-the-icons dashboard-set-file-icons t dashboard-set-heading-icons t dashboard-items '((projects . 5) (recents . 5) (agenda . 5))) :config (add-hook 'after-init-hook 'dashboard-refresh-buffer) (dashboard-setup-startup-hook)) #+end_src ** 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 (exec-path-from-shell-initialize)) #+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)) #+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) #+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 :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 :config (setq erc-nick "random936" erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "353") 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) ;; 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 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 * 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/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/functions.org") ; Personal Elisp Functions (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