#+TITLE: Michael's GNU Emacs Config #+AUTHOR: Michael Thomson #+DESCRIPTION: Michael's personal Emacs config #+STARTUP: showeverything #+OPTIONS: toc:2 * TABLE OF CONTENTS :toc: - [[#important-programs-to-load-first][IMPORTANT PROGRAMS TO LOAD FIRST]] - [[#elpaca-package-manager][Elpaca Package Manager]] - [[#evil-mode][Evil Mode]] - [[#general-keybindings][General Keybindings]] - [[#fonts][FONTS]] - [[#gui-tweaks][GUI TWEAKS]] - [[#org-mode][ORG MODE]] - [[#general-settings][General Settings]] - [[#enable-table-of-contents][Enable Table of Contents]] - [[#enable-org-bullets][Enable org bullets]] - [[#block-expansion][Block expansion]] - [[#org-roam][Org Roam]] - [[#completion-framework][Completion Framework]] - [[#completion-at-point][COMPLETION AT POINT]] - [[#lsp][LSP]] - [[#eglot][Eglot]] - [[#language-support][LANGUAGE SUPPORT]] - [[#treesitter][Treesitter]] * IMPORTANT PROGRAMS TO LOAD FIRST ** Elpaca Package Manager #+begin_src emacs-lisp (defvar elpaca-installer-version 0.9) (defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory)) (defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory)) (defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory)) (defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git" :ref nil :depth 1 :inherit ignore :files (:defaults "elpaca-test.el" (:exclude "extensions")) :build (:not elpaca--activate-package))) (let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory)) (build (expand-file-name "elpaca/" elpaca-builds-directory)) (order (cdr elpaca-order)) (default-directory repo)) (add-to-list 'load-path (if (file-exists-p build) build repo)) (unless (file-exists-p repo) (make-directory repo t) (when (< emacs-major-version 28) (require 'subr-x)) (condition-case-unless-debug err (if-let* ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*")) ((zerop (apply #'call-process `("git" nil ,buffer t "clone" ,@(when-let* ((depth (plist-get order :depth))) (list (format "--depth=%d" depth) "--no-single-branch")) ,(plist-get order :repo) ,repo)))) ((zerop (call-process "git" nil buffer t "checkout" (or (plist-get order :ref) "--")))) (emacs (concat invocation-directory invocation-name)) ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch" "--eval" "(byte-recompile-directory \".\" 0 'force)"))) ((require 'elpaca)) ((elpaca-generate-autoloads "elpaca" repo))) (progn (message "%s" (buffer-string)) (kill-buffer buffer)) (error "%s" (with-current-buffer buffer (buffer-string)))) ((error) (warn "%s" err) (delete-directory repo 'recursive)))) (unless (require 'elpaca-autoloads nil t) (require 'elpaca) (elpaca-generate-autoloads "elpaca" repo) (load "./elpaca-autoloads"))) (add-hook 'after-init-hook #'elpaca-process-queues) (elpaca `(,@elpaca-order)) (elpaca elpaca-use-package (elpaca-use-package-mode)) #+end_src ** Evil Mode #+begin_src emacs-lisp (use-package evil :ensure t :init (setq evil-want-integration t) (setq evil-want-keybinding nil) (setq evil-vsplit-window-right t) (setq evil-split-window-below t) :config (evil-mode 1)) (use-package evil-collection :ensure t :after evil :config (evil-collection-init)) #+end_src ** General Keybindings #+begin_src emacs-lisp (use-package general :ensure t :config (general-create-definer mt/leader-def :states '(normal visual) :keymaps 'override :prefix "SPC") (mt/leader-def "f f" 'find-file "f c" (lambda () (interactive) (find-file "~/.emacs.d/config.org"))) (mt/leader-def "e b" 'eval-buffer "e r" 'eval-region)) #+end_src * FONTS #+begin_src emacs-lisp (set-face-attribute 'default nil :font "JetBrainsMono Nerd Font Mono" :height 110 :weight 'medium) #+end_src * GUI TWEAKS #+begin_src emacs-lisp (tool-bar-mode -1) (scroll-bar-mode -1) (menu-bar-mode -1) (setq inhibit-splash-screen t) (setq use-file-dialog nil) (global-display-line-numbers-mode 1) (setq display-line-numbers-type 'relative) (global-visual-line-mode t) (setq gc-cons-threshold 100000000) ; 100 mb (setq read-process-output-max (* 1024 1024)) ; 1mb (setq backup-directory-alist `((".*" . ,temporary-file-directory))) (setq auto-save-file-name-transforms `((".*" ,temporary-file-directory t))) (use-package gruvbox-theme :ensure t :config (load-theme 'gruvbox-dark-hard)) #+end_src * ORG MODE ** General Settings #+begin_src emacs-lisp (add-hook 'org-mode-hook 'org-indent-mode) #+end_src ** Enable Table of Contents #+begin_src emacs-lisp (use-package toc-org :ensure t :init (add-hook 'org-mode-hook 'toc-org-mode)) #+end_src ** Enable org bullets #+begin_src emacs-lisp (use-package org-superstar :ensure t :init (add-hook 'org-mode-hook (lambda () (org-superstar-mode 1)))) #+end_src ** Block expansion #+begin_src emacs-lisp (require 'org-tempo) #+end_src ** Org Roam #+begin_src emacs-lisp (use-package org-roam :ensure t :custom (org-roam-directory "~/everything") (org-roam-completion-everywhere t) (org-roam-dailies-capture-templates '(("d" "default" entry "* %<%I:%M %p>: %?" :if-new (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")))) :bind (("C-c n l" . org-roam-buffer-toggle) ("C-c n f" . org-roam-node-find) ("C-c n g" . org-roam-graph) ("C-c n i" . org-roam-node-insert) ("C-c n c" . org-roam-capture) ;; Dailies ("C-c n j" . org-roam-dailies-capture-today)) :config (setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag))) (org-roam-db-autosync-mode)) #+end_src * Completion Framework #+begin_src emacs-lisp (use-package vertico :ensure t :init (vertico-mode)) (use-package marginalia :ensure t :init (marginalia-mode)) (use-package savehist :ensure nil :init (savehist-mode)) (use-package orderless :ensure t :custom (completion-styles '(orderless basic)) (completion-category-defaults nil) (completion-category-overrides nil)) #+end_src * COMPLETION AT POINT #+begin_src emacs-lisp (use-package corfu :ensure t :config (setq tab-always-indent 'complete) (setq corfu-popupinfo-delay '(1.25 . 0.5)) (corfu-popupinfo-mode 1) (setq corfu-auto t) (setq corfu-auto-delay 0) (setq corfu-auto-prefix 0) :init (global-corfu-mode)) #+end_src * LSP ** Eglot #+begin_src emacs-lisp (use-package direnv :ensure t :config (direnv-mode)) (use-package exec-path-from-shell :ensure t :config (exec-path-from-shell-initialize)) (use-package eglot :ensure nil :hook (go-ts-mode . eglot-ensure) (typescript-ts-mode . eglot-ensure) (css-ts-mode . eglot-ensure) (vue-ts-mode . eglot-ensure)) #+end_src * LANGUAGE SUPPORT ** Treesitter #+begin_src emacs-lisp (use-package treesit-auto :ensure t :custom (treesit-auto-install 'prompt) :config (treesit-auto-add-to-auto-mode-alist 'all) (global-treesit-auto-mode)) #+end_src