Skip to content

Latest commit

 

History

History
1041 lines (741 loc) · 24.3 KB

config.org

File metadata and controls

1041 lines (741 loc) · 24.3 KB

Zach Heeylmu Emacs Config

Emacs Config

Emacs is a neat text editor

Auto-Package-Update

Automagically update packages weekly if updates are available.

 ;; Automatically pull updates weekly and hide results
 (use-package auto-package-update
	:straight t
	:custom
	(auto-package-update-interval 7)
	(auto-package-update-hide-results t)
	:config
	(auto-package-update-maybe))

Garbage Collection

Gcmh uses some clever trickery to perform garbage collections in when idle, minimizing the impact. It’s enabled last thing in init.el, allowing initialization without gc, but enabling it before user input.

 (use-package gcmh
	:straight t)

UI Configuration

The following section configures the basics of the stock Emacs UI. Inint.el also disables several UI elements as well as the startup message. Here we configure default buffer rendering and UI behavior.

Basic UI elements

 (set-fringe-mode 0)

 ;; Show column numbers in the modeline
 (column-number-mode)

 ;; Enable line numbers for some modes
 (dolist (mode '(text-mode-hook
				  prog-mode-hook
				  conf-mode-hook))
	(add-hook mode (lambda () (display-line-numbers-mode 1))))

 ;; 8 character tabs are too damn large
 (setq-default tab-width 4)

 ;; Default behavior is case sensitive for sorting.
 ;; Just sort alphabetically
 (setq sort-fold-case t)

File backup behavior

Default file backup behavior is awful. Make it less awful:

 (setq user-emacs-directory "~/.cache/emacs")

 (use-package no-littering
	:straight t)

 ;; no-littering doesn't set this by default so we must place
 ;; auto save files in the same path as it uses for sessions
 (setq auto-save-file-name-transforms
		`((".*" ,(no-littering-expand-var-file-name "auto-save/") t)))

Evil first, Evil Always

Load evil super early so my key bindings don’t change when I goof my config

EVIL

Evil mode brings Vim keybindings to Emacs.

 (defun void/evil-hook ()
	(dolist (mode '(custom-mode
					eshell-mode
					git-rebase-mode
					erc-mode
					circe-server-mode
					circe-chat-mode
					circe-query-mode
					sauron-mode
					term-mode))
	  (add-to-list 'evil-emacs-state-modes mode)))

 (use-package evil
	:straight t
	:init
	(setq evil-want-integration t)
	(setq evil-want-keybinding nil)
	(setq evil-want-C-u-scroll t)
	(setq evil-want-C-i-jump nil)
	:hook (evil-mode . void/evil-hook)
	: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 everywhere
	(evil-global-set-key 'motion "j" 'evil-next-visual-line)
	(evil-global-set-key 'motion "k" 'evil-previous-visual-line)
	(evil-set-initial-state 'messages-buffer-mode 'normal)
	(evil-set-initial-state 'dashboard-mode 'normal))

Evil Collection

Evil Collection Provides a sensible set of file types and automatically configures Evil mode for them

 (use-package evil-collection
	:straight t
	:init
	(evil-collection-init))

Fonts

Fira Code is a beautiful, open source font for programming. It has very pretty ligatures for common programming symbol combinations.

 ;; Used as default font for most things
 (set-face-attribute 'default nil :font "Fira Code Retina" :height 120)

 (use-package fira-code-mode
	:straight t
	:hook prog-mode)     ; mode to enable fira-code-mode in

 ;;Fira Code Mode requires that the fonts be installed to the system before use.
 ;; Check for them and install if unavailable
 (if(not(find-font(font-spec :name "Fira Code Symbol")))
	  (fira-code-mode-install-fonts))

 (use-package all-the-icons
	:straight t)

 ;; All the icons requires that the fonts be installed to the system before use.
 ;; Check for them and install if unavailable, silencing the confirmation
 (if(not(find-font(font-spec :name "all-the-icons")))
	  (all-the-icons-install-fonts 0))

UI Packages

Set of packages to improve the look and functionality of the UI

Beacon

Beacon makes it easy to find your cursor when the screen moves

(use-package beacon
:straight t
:config
(beacon-mode 1))

Doom Modeline

The Doom modeline provides a concise view of current mode functionality

 (use-package doom-modeline
	:straight t
	:init (doom-modeline-mode 1)
	:custom ((doom-modeline-height 16)))

Doom Themes

 (use-package doom-themes
	:straight t
	:config
	(doom-themes-visual-bell-config)
	(doom-themes-treemacs-config)
	:init
	(load-theme 'doom-gruvbox t))

Multiple Cursors

Add friendly mulit-editing

 (use-package multiple-cursors
	:straight t
	:config
	(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines))

Rainbow Delimiters

Rainbow delimiters makes it much easier to match up scope delimiters such as parenthesis

 (use-package rainbow-delimiters
	:straight t
	:hook (prog-mode . rainbow-delimiters-mode))

Solaire

 (use-package solaire-mode
	:straight t
	:config
	(solaire-global-mode +1))

Treemacs

Treemacs provides a file and project explorer. It gives a nice outline similar to many IDEs.

 (use-package treemacs
	:straight t
	:ensure t
	:defer t
	:init(with-eval-after-load 'winum
		   (define-key winum-keymap (kbd "M-0") #'treemacs-select-window)))

 (use-package treemacs-evil
	:straight t
	:after evil treemacs)

 (use-package treemacs-magit
	:straight t
	:after magit treemacs)

 (use-package treemacs-projectile
	:straight t
	:after projectile treemacs)

Undo-Tree

Undo-Tree provides a powerful visualization of the undo tree structure

 (use-package undo-tree
	:straight t
	:config
	(global-undo-tree-mode 1))

Help and navigation

Vertico

	(use-package vertico
	  :straight t
	  :bind (:map vertico-map
				  ("C-j" . vertico-next)
				  ("C-k" . vertico-previous)
				  ("C-f" . vertico-exit)
				  :map minibuffer-local-map
				  ("M-h" . backward-kill-word))
	  :custom
	  (vertico-cycle t)
	  :init
	  (vertico-mode))

	(use-package savehist
	  :straight t
	  :init
	  (savehist-mode))

	(use-package marginalia
	  :straight t
	  :after vertico
	  :ensure t
	  :custom
	  (marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil))
	  :init
	  (marginalia-mode))

 (use-package ctrlf
	:straight t
	:config
	(ctrlf-mode +1))

 (use-package orderless
	:straight t)

 (setq completion-styles '(orderless)
		completion-category-defaults nil
		completion-category-overrides '((file (styles . (partial-completion)))))


Prescient

Prescient is a sorting and filtering extension which improves the usability of suggestions by from vertico, Company

 (use-package prescient
	:straight t)
 (use-package company-prescient
	:straight t
	:after company prescient)

Helpful

Helpful is an alternative to the built-in emacs help functionality that provides considerably more contextual information.

	 (use-package helpful
	   :straight t
	   :bind
	   ([remap describe-command] . helpful-command)
	   ([remap describe-key] . helpful-key))

Which-key

Which-key provides helpful command completion for partial command prefixes. It’s configured with an idle delay, so that it doesn’t pop up when commands are entered quickly, but shows the help after a short delay.

	 (use-package which-key
	   :straight t
	   :init (which-key-mode)
	   :diminish(which-key-mode)
	   :config
	   (setq which-key-idle-delay 0.3))

Key Bindings

Packages and configuration related to key bindings

General

General provides a convenient key binding method for key bindings. Set up custom leader key with space bar.

	 (setq mac-command-modifier 'meta)

	 (use-package general
	   :straight t
	   :config (general-create-definer void/leader-keys
	   :keymaps '(normal insert visual emacs) :prefix "SPC" :global-prefix
	   "C-SPC") (void/leader-keys "to" '(:ignore t :which-key "toggles")
	   "tt" '(counsel-load-theme :which-key "chose theme")))

	 (general-define-key "C-M-j" 'counsel-switch-buffer)

Hydra

Hydra provides a utility for creating modal clusters of bindings which dismiss automatically after a specified timeout. This is used to create a custom mode for quickly scaling text.

		  (use-package hydra
			:straight t)

		  (defhydra hydra-text-scale (:timeout 4)
			"scale text"
			("j" text-scale-increase "in")
			("k" text-scale-decrease "out")
			("f" nil "finished" :exit t))

		  (void/leader-keys
			"ts" '(hydra-text-scale/body :which-key "scale-text" ))

Org Mode

Org Mode Font Setup

 ;; Replace list hyphen with dot
 (font-lock-add-keywords 'org-mode
						  '(("^ *\\([-]\\) "
							 (0 (prog1 () (compose-region (match-beginning 1) (match-end 1) ""))))))

 ;; Set faces for heading levels
 (dolist (face '((org-level-1 . 1.2)
				  (org-level-2 . 1.1)
				  (org-level-3 . 1.05)
				  (org-level-4 . 1.0)
				  (org-level-5 . 1.1)
				  (org-level-6 . 1.1)
				  (org-level-7 . 1.1)
				  (org-level-8 . 1.1)))
	(set-face-attribute (car face) nil :font "Cantarell" :weight 'regular :height (cdr face)))

 ;; Ensure that anything that should be fixed-pitch in Org files appears that way
 (set-face-attribute 'org-block nil    :foreground nil :inherit 'fixed-pitch)
 (set-face-attribute 'org-table nil    :inherit 'fixed-pitch)
 (set-face-attribute 'org-formula nil  :inherit 'fixed-pitch)
 (set-face-attribute 'org-code nil     :inherit '(shadow fixed-pitch))
 (set-face-attribute 'org-table nil    :inherit '(shadow fixed-pitch))
 (set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
 (set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
 (set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
 (set-face-attribute 'org-checkbox nil  :inherit 'fixed-pitch)
 (set-face-attribute 'line-number nil :inherit 'fixed-pitch)
 (set-face-attribute 'line-number-current-line nil :inherit 'fixed-pitch)

Org Mode Config

Configure org-mode itself. Replace ellipsis in collapsed sections with a nice arrow indicating additional content.

(setq org-agenda-files
		'("~/.org/tasks.org"
		  "~/.org/birthdays.org"))
(setq org-ellipsis "")
(setq org-log-done t)

Org Babel Configuration

Org mode babel integration for emacs-lisp and python

	 (org-babel-do-load-languages
	  'org-babel-load-languages
	  '((emacs-lisp . t)
		(python . t)))

	 (setq org-confirm-babel-evaluate nil)

	 (push '("conf-unix" . conf-unix) org-src-lang-modes)
	 (require 'org-tempo )
	 (add-to-list 'org-structure-template-alist '("c99" . "src c"))
	 (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
	 (add-to-list 'org-structure-template-alist '("py" . "src python"))
	 (add-to-list 'org-structure-template-alist '("sh" . "src shell"))

Org Bullets

Nice bullets

 (use-package org-superstar
	:straight t
	:after org
	:hook( org-mode . org-superstar-mode )
	:custom
	(org-superstar-remove-leading-stars t)
	(org-superstar-headline-bullets-list '("" "" "" "" "" "" "")))

Org Mode Visuals

Configure org mode content to render in center of buffer

 (defun void/org-mode-visual-fill ()
	(setq visual-fill-column-width 120
		  visual-fill-column-center-text t)
	(visual-fill-column-mode 1)
	(visual-line-mode 1))

 (use-package visual-fill-column
	:straight t
	:after org
	:defer t
	:hook (org-mode . void/org-mode-visual-fill)
	(markdown-mode . void/org-mode-visual-fill))

Org Roam

I’ll probably have something to say here eventually

 (use-package org-roam
	:straight t
	:after org
	:init
	(setq org-roam-v2-ack t) ;; Never had a 1.0 database, don't worry about it
	:custom
	(org-roam-directory (file-truename "~/.roam/"))
	: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)
		   :map org-mode-map
		   ("C-M-i" . completion-at-point))
	:config
	(org-roam-db-autosync-mode)
	;; If using org-roam-protocol
	(require 'org-roam-protocol))

Development

Tools

Company

Company is a completion framework for Emacs. It includes backends for many common tasks.

 (use-package company
	:straight t
	:init
	(add-hook 'after-init-hook 'global-company-mode))

Flycheck

Flycheck provides on the fly syntax checking.

 (use-package flycheck
	:straight t
	:init (global-flycheck-mode))

Forge

Forge provides integration to advanced git hosting features from providers such as GitHub and GitLab.

 (use-package forge
	:straight t)

Indent Guides

 (use-package highlight-indent-guides
	:straight t
	:config
	(setq highlight-indent-guides-method 'character))

LSP

lsp-mode provides advanced language server based features to Emacs.

		(defun void/lsp-mode-setup ()
		  (setq lsp-headerline-breadcrumb-segments '(path-up-to-project file symbols))
		  (lsp-headerline-breadcrumb-mode))

		(use-package lsp-mode
		  :straight t
		  :init
		  ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
		  (setq lsp-keymap-prefix "C-c l")
		  :config
		  (setq read-process-output-max (* 5 1024 1024))
		  (lsp-enable-which-key-integration))

		(use-package lsp-ui
		  :straight t
		  :after lsp-mode
		  :hook (lsp-mode . lsp-ui-mode)
		  :custom
		  (lsp-ui-doc-position 'atpoint))

		(use-package dap-mode
		  :straight t
		  :after lsp-mode
		  :config
		  (require 'dap-gdb-lldb)
		  (dap-register-debug-template "Rust::GDB Run Configuration"
                           (list :type "gdb"
                                 :request "launch"
                                 :name "GDB::Run"
                         :gdbpath "rust-gdb"
                                 :target nil
                                 :cwd nil)))

Magit

Magit is an incredible, text based git client. It has a beautiful, text based graph, and all of the power of the command line interface (+ some really nice convenience features).

	(use-package magit
		:straight t)

Projectile

Projectile is a project interaction library for Emacs that adds capabilities for quickly navigating around the files within a project.

 (use-package projectile
	:straight t
	:diminish projectile-mode
	:config (projectile-mode)
	:bind-keymap
	("C-c p" . projectile-command-map)
	:init
	(setq projectile-enable-cmake-presets t)
	(setq projectile-switch-project-action #'projectile-dired))

RipGrep

Ripgrep provides blazing fast search capabilities. Integrated with Projectile via projectile-ripgrep

 (use-package ripgrep
	:straight t)

 (use-package projectile-ripgrep
	:straight t
	:after projectile ripgrep)

Yasnippet

Yasnippet expands templates

 (use-package yasnippet
	:straight t
	:config
	(yas-global-mode t))

Whitespace

Cleanup

 (require 'whitespace)

 (setq whitespace-style
		'(face trailing indentation::tab space-before-tab::tab space-after-tab))

 (use-package ws-butler
	:straight t
	:config
	(ws-butler-global-mode))

 (add-hook 'prog-mode-hook ; turn on whitespace-mode in any 'programming mode'
			(lambda ()
			  (whitespace-mode t)))

Language Support

C/C++

CCLS is a C/C++ indexer which uses the compilation commands and clang frontend to ensure that the indexing is accurate.

 (use-package ccls
	:straight t
	:after lsp
	:hook ((c-mode c++-mode objc-mode cuda-mode) .
		   (lambda ()
			 (require 'ccls)
			 (lsp)))
	:init
	(with-eval-after-load "lsp-mode"
	  (add-to-list 'lsp-enabled-clients 'ccls))
	(setq ccls-executable "ccls")
	(setq ccls-initialization-options '(:cache (:directory "build/.ccls-cache")
											   :clang ( :excludeArgs ["-working-directory"] ))))
 (use-package clang-format+
	:straight t
	:hook ((c-mode c++-mode) .
		   (lambda ()
			 (require clang-format+)
			 (clang-format+-mode) )))

C#

 (use-package omnisharp
	:straight t
	:hook
	(csharp-mode . (lambda ()
					 (omnisharp-mode)
					 (add-to-list 'company-backends 'company-omnisharp))))
 ;; add support for xaml and cshtml
 (add-to-list 'auto-mode-alist '("\\.xaml\\'" . xml-mode))
 (add-to-list 'auto-mode-alist '("\\.cshtml\\'" . html-mode))
 (add-to-list 'auto-mode-alist '("\\.razor\\'" . html-mode))

CMake

Add support for CMake files.

 (use-package cmake-mode
	:straight t)

Dart

Add support for Dart and Flutter development.

 (use-package dart-mode
	:straight t)

 (use-package lsp-dart
	:straight t
	:after lsp-mode
	:hook
	(dart-mode-hook . lsp))

Jenkins

Add support for Jenkinsfiles

 (use-package jenkinsfile-mode
	:straight t)

Make

 (use-package make-mode
	:straight t
	:mode (( "\\Doxyfile\\'" . makefile-mode)))

Markdown

Markdown-mode is a major mode for editing markdown files.

 (use-package markdown-mode
	:straight t
	:commands
	(markdown-mode gfm-mode)
	:mode (("README\\.md\\'" . gfm-mode)
		   ("\\.md\\'" . markdown-mode)
		   ("\\.markdown\\'" . markdown-mode))
	:init (setq markdown-command "pandoc"))

Meson

 (use-package meson-mode
	:straight t)

PlantUML

PlantUML is an excellent uml and diagram markup language. It allows you to create pretty diagrams with very little effort. Plantuml-mode adds a major mode for editing PlantUML diagrams.

 (use-package plantuml-mode
	:straight t
	:config
	(setq plantuml-default-exec-mode 'executable))

Python

 (use-package lsp-jedi
	:straight t
	:ensure t
	:config
	(with-eval-after-load "lsp-mode"
	  (add-to-list 'lsp-enabled-clients 'jedi)))

 (use-package python-black
	:demand t
	:straight t
	:after python lsp-mode
	:hook (python-mode . (lambda ()
					   (python-black-on-save-mode-enable-dwim)
					   (lsp))))

Rust

	(use-package rustic
	  :ensure t
	  :straight t
	  :init
	  (with-eval-after-load "lsp-mode"
		(add-to-list 'lsp-enabled-clients 'rust-analyzer)
		(require 'dap-cpptools))
	  :after lsp-mode)

Swift

Swift language support is added with the swift-mode package. Language server features are added with lsp-sourcekit. Finally, syntax checking is provided by

flycheck-integration

 (use-package lsp-sourcekit
	:straight t
	:after lsp-mode
	:config
	(setq lsp-sourcekit-executable "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp"))


 (use-package swift-mode
	:straight t
	:hook (swift-mode . (lambda () (lsp))))

Typescript

 (require 'ansi-color)

 (defun colorize-compilation-buffer ()
	(ansi-color-apply-on-region compilation-filter-start (point-max)))
 (add-hook 'compilation-filter-hook 'colorize-compilation-buffer)

 (use-package typescript-mode
	:ensure t
	:straight t
	:init
	(with-eval-after-load "lsp-mode"
	  (add-to-list 'lsp-enabled-clients 'ts-ls))
	:mode "\\.ts\\'"
	:hook (typescript-mode . lsp-deferred))

Yaml

	  (use-package yaml-mode
		:straight t)

Terminals and Shells

All Terminals

Configuration for terminals which all use

(setq explicit-shell-file-name "zsh")
(setq term-prompt-regexp "^#$%>\n]*[#$%>] *")

VTerm

	 (use-package vterm
	   :straight t
	   :commands vterm
	   :config
	   (setq vterm-max-scrollback 10000))

EShell

Emacs is frequently started from the UI instead of terminal. Make sure the path still works.

 (defun void/configure-eshell ()
	;; Save a command history
	(add-hook 'eshell-pre-command-hook 'eshell-save-some-history)

	;; Truncate buffer for performance
	(add-to-list 'eshell-output-filter-functions 'eshell-truncate-buffer)
	;; Bind C-r to pull up history buffer
	(evil-define-key '(normal insert visual) eshell-mode-map (kbd "C-r") 'counsel-esh-history)

	;; Renormalize keymaps
	(evil-normalize-keymaps)

	(setq eshell-history-size 10000
		  eshell-buffer-maximum-lines 10000
		  eshell-hist-ignoredups t
		  eshell-scroll-to-bottom-on-input t))

 (use-package exec-path-from-shell
	:straight t)

 (when (memq window-system '(mac ns x))
	(exec-path-from-shell-initialize))
 (use-package eshell-git-prompt
	:straight t)

 (use-package eshell
	:straight t
	:hook (eshell-first-time-mode . void/configure-eshell)
	:config
	(eshell-git-prompt-use-theme 'powerline))

Color Support

	 (use-package eterm-256color
	   :straight t
	   :hook (term-mdode . eterm-256color-mode))

Email

(use-package mu4e
:config
(require 'org-mu4e)
;; Refresh mail using isync every 10 minutes
(setq mu4e-update-interval (* 10 60))
(setq mu4e-get-mail-command "mbsync -a")
(setq mu4e-maildir "~/mail")

;; Set up vertico for completions
(setq mu4e-completing-read-function #'vertico--advice)
;; Force Mu4e to change filenames when moving messages to different folders
(setq mu4e-change-filenames-when-moving t)
(setq mu4e-contexts
		'(,(make-mu4e-context
			:name "Voidstar"
			:match-func (lambda (msg)
						  (when msg
							(string-prefix-p "/voidstar"
											 (mu4e-message-field msg :maildir))))
			:vars '(
					(user-full-name . "Zach Heylmun")
					(user-mail-address . "zach@voidstarsolutions.com")
					(mu4e-sent-folder . "/voidstar/Sent Items")
					(mu4e-trash-folder . "/voidstar/Trash")
					(mu4e-drafts-folder . "/voidstar/Drafts")
					(mu4e-refile-folder . "/voidstar/Archive")
					(mu4e-sent-messages-behavior . sent)
					))
		  ,(make-mu4e-context
			:name "Personal"
			:match-func (lambda (msg) (when msg
										(string-prefix-p "/Personal" (mu4e-message-field msg :maildir))))
			:vars '
					(mu4e-sent-folder . "/Personal/Sent")
					(mu4e-trash-folder . "/Personal/Deleted")
					(mu4e-refile-folder . "/Personal/Archive")
					))
		  ))
(setq mu4e-context-policy 'pick-first)
)