This is a collection of dotfiles and scripts for my bspwm setup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

42 KiB

Ricemacs, an Emacs Configuration

Global Variables

Variables for directories, leader keys, etc.

(defvar dot-emacs-dir (directory-file-name (file-truename user-emacs-directory))
  "Directory base.") ; ~/.config/emacs

(defvar dot-etc-dir (concat dot-emacs-dir "/etc")
  "Directory for non-volatile storage.") ; ~/.config/emacs/etc

(defvar dot-cache-dir (concat (getenv "XDG_CACHE_HOME") "/emacs")
  "Directory for cache data.") ; ~/.cache/emacs

(defvar dot/leader-key "SPC"
  "Leader prefix key.")

(defvar dot/leader-alt-key "M-SPC"
  "Alternative leader prefix key, used for Insert and Emacs states.")

(defvar dot/localleader-key "SPC m"
  "Local leader prefix key, for 'major-mode' specific commands.")

(defvar dot/localleader-alt-key "M-SPC m"
  "Alternative local leader prefix key, used for Insert and Emacs states.")

(defvar dot/shell "/bin/zsh"
  "Command interpreter binary path.")

(defvar dot/hidpi (getenv "HIDPI")
  "Whether the primary screen is HiDPI.")

;; Create cache directory
(unless (file-directory-p dot-cache-dir)
  (make-directory dot-cache-dir t))

Customizations

Store customize file separately, don't freak out when it's not found.

(setq custom-file (concat dot-etc-dir "/custom.el"))
(load custom-file 'noerror)

Set font.

(set-face-attribute 'default nil :height 90 :family "DejaVu Sans Mono")
(set-face-attribute 'fixed-pitch-serif nil :height 100)

Package Management

Ensure

Ensures packages are installed by default.

(require 'use-package-ensure)
(setq use-package-always-ensure t)

Auto Update

Update pending updates of installed packages at startup. https://github.com/rranelli/auto-package-update.el

(use-package auto-package-update
  :config
  (setq auto-package-update-delete-old-versions t)
  (setq auto-package-update-hide-results t)
  (setq auto-package-update-last-update-day-path (concat dot-cache-dir "/last-package-update-day"))

  (defun dot/update-packages ()
	"Update all packages."
	(interactive)
	(package-refresh-contents)
	(auto-package-update-now)
	(package-quickstart-refresh))

  (auto-package-update-maybe))

Compile

Automatically compile all packages. https://github.com/emacscollective/auto-compile

(use-package auto-compile
  :config
  (auto-compile-on-load-mode)
  (auto-compile-on-save-mode))

Packages

Install and configure packages.

Load Modules

(defun dot/load-org (file)
  "Tangle then load org FILE."
  (if (file-readable-p file)
	  (org-babel-load-file file)
	(user-error (format "Init: could not load module '%s'" (file-name-base file)))))

(dot/load-org (concat dot-emacs-dir "/config/ui.org"))
(dot/load-org (concat dot-emacs-dir "/config/evil.org"))
(dot/load-org (concat dot-emacs-dir "/config/development.org"))
(dot/load-org (concat dot-emacs-dir "/config/selection.org"))
(dot/load-org (concat dot-emacs-dir "/config/org-mode.org"))
(dot/load-org (concat dot-emacs-dir "/config/mail.org"))

General Packages

(use-package general)

(use-package avy
  :defer t)

(use-package hungry-delete
  :config (global-hungry-delete-mode))

(use-package smart-tabs-mode
  :config
  (smart-tabs-add-language-support latex latex-mode-hook
	((latex-indent-line . 4)
	 (latex-indent-region . 4)))
  (smart-tabs-insinuate 'c 'c++ 'java 'python 'latex))

(use-package super-save
  :config
  (setq super-save-auto-save-when-idle t)
  (super-save-mode))

RSS

(use-package elfeed
  :hook (elfeed-search-mode . dot/hook-disable-line-numbers)
  :hook (elfeed-show-mode   . dot/hook-disable-line-numbers)
  :config
  (setq elfeed-db-directory (concat dot-cache-dir "/elfeed"))
  (setq elfeed-enclosure-default-dir "~/downloads/")
  (setq elfeed-search-filter "@6-months-ago +unread")
  (setq elfeed-search-clipboard-type 'CLIPBOARD)
  (setq elfeed-search-title-max-width 100)
  (setq elfeed-search-title-min-width 30)
  (setq elfeed-search-trailing-width 55)
  (setq elfeed-show-unique-buffers t)
  (load (concat dot-etc-dir "/elfeed-feeds")))

General

;; Columns start at 1
(setq column-number-indicator-zero-based nil)

;; Dont confirm on quitting Emacs
(setq confirm-kill-processes nil)

;; Custom thems, do not ask if safe
(setq custom-safe-themes t)

;; Dired move to trash
(setq delete-by-moving-to-trash t)

;; Column indicator character
(setq display-fill-column-indicator-character ?\N{U+2503})

;; Scrolling
(setq scroll-conservatively 1)
(setq mouse-wheel-scroll-amount '(5))
(setq mouse-wheel-progressive-speed nil)

;; Parenthesis, set behavior
(setq show-paren-delay 0)
(setq show-paren-style 'mixed)

;; Tramp default protocol
(setq tramp-default-method "ssh")

;; Set undo limit, measured in bytes
(setq-default undo-limit 400000)
(setq-default undo-strong-limit 3000000)
(setq-default undo-outer-limit 12000000)

;; Enable line numbers
(global-display-line-numbers-mode)

;; C++ syntax highlighting for .h files
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))

;; Set the frame title
(setq frame-title-format
	  `("%b"
		(:eval
		 (if (buffer-file-name)
			 (concat
			  (if (buffer-modified-p) " •" nil)
			  " ("
			  (abbreviate-file-name
			   (directory-file-name
				(file-name-directory (buffer-file-name))))
			  ")")
		   nil))
		,(format " - GNU Emacs %s" emacs-version)
		))
(setq icon-title-format frame-title-format)

Buffers

(setq confirm-nonexistent-file-or-buffer nil)
(setq ibuffer-expert t)

Dired

(setq wdired-allow-to-change-permissions t)

Electric

;; Make return key also do indent of previous line
(electric-indent-mode 1)
(setq electric-pair-pairs '(
							(?\( . ?\))
							(?\[ . ?\])
							))
(electric-pair-mode 1)

File Paths

Set file paths for built-in features like: auto-saves, backups, etc.

;; Set Directory locations
(setq auto-save-list-file-prefix      (concat dot-cache-dir "/auto-save/"))
(setq auto-save-file-name-transforms `((".*" ,auto-save-list-file-prefix t)))
(setq backup-directory-alist         `((".*" . ,(concat dot-cache-dir "/backup/"))))
(setq eshell-directory-name           (concat dot-cache-dir "/eshell/"))
(setq org-id-locations-file           (concat dot-cache-dir "/org-id-locations"))
(setq tramp-auto-save-directory       (concat dot-cache-dir "/tramp-auto-save/"))
(setq tramp-backup-directory-alist    backup-directory-alist)
(setq url-configuration-directory     (concat dot-cache-dir "/url/"))

;; Set file locations
(setq bookmark-default-file           (concat dot-etc-dir "/bookmarks"))
(setq nsm-settings-file               (concat dot-cache-dir "/network-security.data"))
(setq tramp-persistency-file-name     (concat dot-cache-dir "/tramp"))

File Backups Versioning

Setup file backups versioning.

(setq backup-by-copying t)    ; Don't cobbler symlinks
(setq create-lockfiles nil)   ; Disable lockfiles (.#)
(setq delete-old-versions t)  ; Cleanup backups
(setq kept-new-versions 5)    ; Newest backups to keep
(setq kept-old-versions 2)    ; Oldest backups to keep
(setq version-control t)      ; Use version numbers on backups

Formatting

;; Columnn after line-wrapping happens
(setq-default fill-column 80)

;; Automatically add newline on save at the end of the file
(setq require-final-newline t)

;; End sentences with a single space
(setq sentence-end-double-space nil)

;; `tabify' and `untabify' should only affect indentation
(setq tabify-regexp "^\t* [ \t]+")

;; Do not wrap lines
(setq-default truncate-lines t)

;; Wrap lines in the middle of words, gives a \ indicator
(setq-default word-wrap nil)

Hide Elements

(menu-bar-mode 0)
(scroll-bar-mode 0)
(tool-bar-mode 0)
(tooltip-mode 0)
(fringe-mode 0)
(blink-cursor-mode 0)

(setq inhibit-startup-message t)
(setq initial-scratch-message nil)
(setq ring-bell-function 'ignore)

Native Compilation

(setq native-comp-async-report-warnings-errors nil)

Recentf

(use-package recentf
  :ensure nil ; built-in
  :config
  (setq recentf-auto-cleanup 'never)
  (setq recentf-exclude '("~$" "/ssh:" "/sudo:"))
  (setq recentf-filename-handlers '(abbreviate-file-name))
  (setq recentf-max-menu-items 0)
  (setq recentf-max-saved-items 200)
  (setq recentf-save-file (concat dot-cache-dir "/recentf"))
  (recentf-mode))

Tabs

;; Tabs
(setq-default tab-width 4
			  indent-tabs-mode t)

;; C/C++-like languages formatting style
;; https://www.emacswiki.org/emacs/IndentingC
(setq-default c-basic-offset 4
			  sgml-basic-offset 4
			  c-default-style "linux")

UTF-8

Set UTF-8 encoding as default.

(prefer-coding-system 'utf-8-unix)
(setq locale-coding-system 'utf-8-unix)
;; Default also sets file-name, keyboard and terminal coding system
(set-default-coding-systems 'utf-8-unix)
(set-buffer-file-coding-system 'utf-8-unix)
(set-selection-coding-system 'utf-8-unix)

Window

;; Set `switch-to-buffer' to respect the window rules
(setq switch-to-buffer-obey-display-actions t)

;; Window rules
(setq display-buffer-alist
	  '(
		;; ^\*(e?shell|(ansi-|v)?term).*
		("^\\*\\(e?shell\\|\\(ansi-\\|v\\)?term\\).*"
		 (display-buffer-in-side-window)
		 (window-height . 0.25)
		 (side . bottom)
		 (slot . -1))
		("\\*Faces\\*"
		 (display-buffer-in-side-window)
		 (window-height . 0.25)
		 (side . bottom)
		 (slot . 1))
		("\\*Help.*"
		 (display-buffer-in-side-window)
		 (window-height . 0.25)
		 (side . bottom)
		 (slot . 0))
		))

Functions

General Functions

Functions that only use built-in Emacs functionality.

(defun display-startup-echo-area-message ()
  "Hide default startup message."
  (message nil))

(defun dot/config-visit ()
  "Edit config file."
  (interactive)
  (find-file (concat dot-emacs-dir "/config.org")))

(defun dot/config-reload ()
  "Reload config file."
  (interactive)
  (org-babel-load-file (concat dot-emacs-dir "/config.org")))

;; Reference: http://turingmachine.org/bl/2013-05-29-recursively-listing-directories-in-elisp.html
(defun dot/directory-files-recursively-depth (dir regexp include-directories maxdepth)
  "Depth limited variant of the built-in `directory-files-recursively'."
  (let ((result '())
		(current-directory-list (directory-files dir t)))
	(dolist (path current-directory-list)
	  (cond
	   ((and (file-regular-p path)
			 (file-readable-p path)
			 (string-match regexp path))
		(setq result (cons path result)))
	   ((and (file-directory-p path)
			 (file-readable-p path)
			 (not (string-equal "/.." (substring path -3)))
			 (not (string-equal "/." (substring path -2))))
		(when (and include-directories
				   (string-match regexp path))
		  (setq result (cons path result)))
		(when (> maxdepth 1)
          (setq result (append (nreverse (dot/directory-files-recursively-depth
										  path regexp include-directories (- maxdepth 1)))
							   result))))
	   (t)))
	(reverse result)))

(defun dot/dired-find-file ()
  "In Dired, visit the file or directory named on this line."
  (interactive)
  (if (file-directory-p (dired-file-name-at-point))
      (dired-find-alternate-file)
    (dired-find-file)))

(defun dot/dired-up-directory ()
  "Run Dired on parent directory of current directory."
  (interactive)
  (find-alternate-file ".."))

(defun dot/find-file-emacsd ()
  "Find file under `dot-emacs-dir', recursively."
  (interactive)
  (let ((files (mapcar 'abbreviate-file-name
					   (directory-files-recursively dot-emacs-dir ""))))
	(find-file (completing-read "Find file (emacs): " files nil t))))

(defun dot/indent-buffer ()
  "Indent each nonblank line in the buffer."
  (interactive)
  (save-excursion
	(indent-region (point-min) (point-max) nil)))

(defun dot/insert-spaces-until-column (until-column)
  "Insert spaces from point to UNTIL-COLUMN."
  (interactive "nInsert spaces until column: ")
  (let ((current-column (current-column)))
	;; Increment column if the index is 1 based
	(when (not column-number-indicator-zero-based)
	  (setq current-column (+ current-column 1)))
	;; Insert spaces
	(let ((diff (- until-column current-column)))
	  (if (> diff 0)
		  (save-excursion (insert (make-string diff ?\ )))
		(user-error "Column should be higher than point")))))

(defun dot/reload-theme ()
  "Reload custom theme."
  (interactive)
  (mapc 'load (file-expand-wildcards
			   (concat (car custom-theme-load-path) "*.el")))
  (load-theme (car custom-enabled-themes) t))

(defun dot/sudo-find-file (filename)
  "Edit file FILENAME as root."
  (interactive "FOpen file (as root): ")
  (find-file (concat "/sudo:root@localhost:" filename)))

(defun dot/sudo-this-file ()
  "Edit the current file as root."
  (interactive)
  (if buffer-file-name
	  (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name))
	(princ "Current buffer isn't a file")))

(defun dot/toggle-fringe (&optional arg)
  "Toggle left-only fringe, or set state with ARG."
  (interactive)
  (if (or (and (eq fringe-mode 0) (eq arg nil))
		  (eq arg 1))
	  (set-fringe-mode '(nil . 0))
	(set-fringe-mode 0)))

(defun dot/M-x (command)
  "Prompt and execute COMMAND."
  (interactive "CCommand: ")
  (command-execute command))

(defun split-follow-horizontally ()
  "Split and follow window."
  (interactive)
  (split-window-below)
  (other-window 1))
(defun split-follow-vertically ()
  "Split and follow window."
  (interactive)
  (split-window-right)
  (other-window 1))

;; https://emacsredux.com/blog/2013/05/04/rename-file-and-buffer/
(defun rename-file-and-buffer ()
  "Rename the current buffer and file it is visiting."
  (interactive)
  (let ((filename (buffer-file-name)))
	(if (not (and filename (file-exists-p filename)))
		(message "Buffer is not visiting a file!")
	  (let ((new-name (read-file-name "New name: " filename)))
		(cond
		 ((vc-backend filename) (vc-rename-file filename new-name))
		 (t
		  (rename-file filename new-name t)
		  (set-visited-file-name new-name t t)))))))

Functions that are only used for hook calls.

(defun dot/hook-disable-line-numbers ()
  "Disable the line numbers."
  (display-line-numbers-mode 0))

(defun dot/hook-disable-mode-line ()
  "Disable the mode line."
  (setq-local mode-line-format nil))

Advice and Aliases

Advice

Define default terminal option.

(defun dot/ansi-term (program &optional new-buffer-name)
  (interactive (list dot/shell)))
(advice-add 'ansi-term :before #'dot/ansi-term)

Aliases

Make confirm easier, by just pressing y/n.

(defalias 'yes-or-no-p 'y-or-n-p)

Hooks

;; Delete trailing whitespace
(add-hook 'before-save-hook 'delete-trailing-whitespace)

;; Display fill column indicator
(add-hook 'prog-mode-hook 'display-fill-column-indicator-mode)
(add-hook 'text-mode-hook 'display-fill-column-indicator-mode)

;; Highlight parenthesis
(add-hook 'prog-mode-hook 'show-paren-mode)

;; Disable line numbers
(add-hook 'Custom-mode-hook 'dot/hook-disable-line-numbers)
(add-hook 'dired-mode-hook 'dot/hook-disable-line-numbers)
(add-hook 'Info-mode-hook 'dot/hook-disable-line-numbers)
(add-hook 'term-mode-hook 'dot/hook-disable-line-numbers)

;; Wrap lines in the middle of words, gives a \ indicator
(add-hook 'visual-line-mode-hook (lambda () (setq word-wrap nil)))

Key Bindings

Useful links:
Mastering Emacs key bindings
use-package bind key
GNU remapping commands
GNU binding combinations of modifiers
Doom Emacs bindings

Disable Native

Disable keybinds of native modes that clash with other custom keybinds.

(with-eval-after-load 'org
  (define-key org-mode-map (kbd "M-h") nil)
  (define-key org-mode-map (kbd "C-M-h") nil))

(with-eval-after-load 'cc-mode
  (define-key c-mode-base-map (kbd "M-j") nil)
  (define-key c-mode-base-map (kbd "C-M-h") nil))

(with-eval-after-load 'nxml-mode
  (define-key nxml-mode-map (kbd "M-h") nil))

Disable Package

Disable keybinds of installed packages that clash with other custom keybinds.

(with-eval-after-load 'evil-states
  (define-key evil-motion-state-map (kbd dot/leader-key) nil))

(with-eval-after-load 'magit
  (general-def 'normal magit-mode-map
    ;; Do not close magit when pressing escape
	"<escape>" nil))

(with-eval-after-load 'php-mode
  (define-key php-mode-map (kbd "M-j") nil)
  (define-key php-mode-map (kbd "C-M-h") nil))

Set Native

Set keybinds to native functionality.

Set Native Global Keybinds

;; Buffers
(global-set-key (kbd "C-x C-b") 'ibuffer)
(global-set-key (kbd "M-w") 'kill-buffer-and-window)

;; Config edit/reload
(global-set-key (kbd "C-c r") 'config-reload)
(global-set-key (kbd "C-c v") 'config-visit)

;; Find file
(global-set-key (kbd "C-x C-f") #'dot/find-file-in-project-root)

;; Split and follow window
(global-set-key (kbd "C-x 2") 'split-follow-horizontally)
(global-set-key (kbd "C-x 3") 'split-follow-vertically)

;; Terminal
(global-set-key (kbd "<s-backspace>") 'ansi-term)

Set Native Mode Keybinds

;; Dired
(with-eval-after-load 'dired
  (define-key dired-mode-map [remap dired-find-file] #'dot/dired-find-file)
  (define-key dired-mode-map [remap dired-up-directory] #'dot/dired-up-directory))

;; Org-mode
(with-eval-after-load 'org-capture
  (define-key org-capture-mode-map (kbd "M-c") #'org-capture-finalize)
  (define-key org-capture-mode-map (kbd "M-w") #'org-capture-refile)
  (define-key org-capture-mode-map (kbd "M-k") #'org-capture-kill))
(define-key org-mode-map           (kbd "M-c") #'org-edit-special)
(define-key org-src-mode-map       (kbd "M-c") #'org-edit-src-exit)
(define-key org-src-mode-map       (kbd "M-k") #'org-edit-src-abort)

Set Package

Set keybinds to functionality of installed packages.

;; Buffers
(global-set-key (kbd "M-h") #'centaur-tabs-backward-tab)
(global-set-key (kbd "M-j") #'centaur-tabs-forward-group)
(global-set-key (kbd "M-k") #'centaur-tabs-backward-group)
(global-set-key (kbd "M-l") #'centaur-tabs-forward-tab)
(global-set-key (kbd "M-H") #'centaur-tabs-move-current-tab-to-left)
(global-set-key (kbd "M-L") #'centaur-tabs-move-current-tab-to-right)
(global-set-key (kbd "M-\`") #'evil-switch-to-windows-last-buffer)

(global-set-key (kbd "M-s") #'avy-goto-char-timer)
(global-set-key (kbd "M-x") #'dot/M-x)

;; Company completion selection
(with-eval-after-load 'company
  (define-key company-active-map (kbd "M-n") nil)
  (define-key company-active-map (kbd "M-p") nil)
  (define-key company-active-map (kbd "M-h") #'company-abort)
  (define-key company-active-map (kbd "M-j") #'company-select-next)
  (define-key company-active-map (kbd "M-k") #'company-select-previous)
  (define-key company-active-map (kbd "M-l") #'company-complete-selection)
  (define-key company-active-map (kbd "<escape>") #'company-abort))

;; Evil command history selection
(with-eval-after-load 'evil-ex
  (define-key evil-ex-completion-map (kbd "M-h") #'abort-recursive-edit)
  (define-key evil-ex-completion-map (kbd "M-j") #'next-complete-history-element)
  (define-key evil-ex-completion-map (kbd "M-k") #'previous-complete-history-element)
  (define-key evil-ex-completion-map (kbd "M-l") #'exit-minibuffer))

;; flyspell-correct
(with-eval-after-load 'flyspell-correct
  (global-set-key [remap ispell-word] #'flyspell-correct-at-point)) ; z=

;; Helpful overwrite default help functions
(global-set-key [remap describe-command]  #'helpful-command)
(global-set-key [remap describe-function] #'helpful-callable)
(global-set-key [remap describe-key]      #'helpful-key)
(global-set-key [remap describe-symbol]   #'helpful-at-point)
(global-set-key [remap describe-variable] #'helpful-variable)
(which-key-add-key-based-replacements "C-h o" "describe-symbol-at-point")

;; Magit
(with-eval-after-load 'magit
  (define-key magit-log-select-mode-map (kbd "M-c") #'magit-log-select-pick)
  (define-key magit-log-select-mode-map (kbd "M-k") #'magit-log-select-quit))

;; Org-roam
(with-eval-after-load 'org-roam
  (define-key org-roam-mode-map [down-mouse-1] #'org-roam-visit-thing))

;; Minibuffer completion selection
(general-def minibuffer-local-map
  "M-h" #'abort-recursive-edit
  "M-j" #'selectrum-next-candidate
  "M-k" #'selectrum-previous-candidate
  "M-l" #'selectrum-select-current-candidate
  "M-J" #'next-history-element
  "M-K" #'previous-history-element
  "<backspace>"   #'dot/selectrum-backspace
  "<S-backspace>" #'evil-delete-backward-char-and-join)

;; with-editor
(with-eval-after-load 'with-editor
  (define-key with-editor-mode-map (kbd "M-c") 'with-editor-finish)
  (define-key with-editor-mode-map (kbd "M-k") 'with-editor-cancel))

(with-eval-after-load 'evil-states

  ;; Global evil keymap

  (general-def evil-normal-state-map
	"C-n" #'neotree-toggle-in-project-root
	"C-S-p" #'evil-paste-pop-next
    )

  (general-def evil-insert-state-map
	"<backtab>" #'dot/evil-insert-shift-left  ; <S-Tab>
	"TAB"       #'dot/evil-insert-shift-right ; <Tab>
    )

  (general-def evil-visual-state-map
	"<" #'dot/evil-visual-shift-left   ; <gv
	">" #'dot/evil-visual-shift-right  ; >gv
    )

  ;; Custom (M-x customize)
  (general-def 'normal custom-mode-map
	[down-mouse-1] #'widget-button-click
	)

  ;; Dashboard
  (general-def 'normal dashboard-mode-map
	[down-mouse-1] 'widget-button-click
	"g" #'dashboard-refresh-buffer
	"m" #'dot/dashboard-goto-bookmarks
	"p" #'dot/dashboard-goto-projects
	"r" #'dot/dashboard-goto-recent-files
	)

  ;; Dap
  (general-def 'normal dap-ui-session-mode-map
	"D" #'dap-ui-delete-session
	)

  ;; Deft
  (general-def 'normal deft-mode-map
	[down-mouse-1] #'widget-button-click
	"+"  #'deft-new-file-named
	"-"  #'deft-new-file
	"a"  #'deft-archive-file
	"c"  #'deft-filter-clear
	"d"  #'deft-delete-file
	"f"  #'deft-find-file
	"g"  #'deft-refresh
	"q"  #'kill-this-buffer
	"R"  #'deft-rename-file
	"s"  #'deft-filter
	"ts" #'deft-toggle-incremental-search :which-key "Toggle search"
	"tt" #'deft-toggle-sort-method        :which-key "Toggle sort"
	)

  ;; Elfeed
  (general-def 'normal elfeed-search-mode-map
	"b"  'elfeed-search-browse-url
	"c"  'elfeed-search-clear-filter
	"gr" '(elfeed-search-update--force  :which-key "Refresh buffer")
	"gR" '(elfeed-search-fetch          :which-key "Update feeds")
	"q"  'elfeed-search-quit-window
	"u"  'elfeed-search-tag-all-unread
	"U"  nil
	"r"  'elfeed-search-untag-all-unread
	)

  (general-def 'normal elfeed-show-mode-map
	"b" #'elfeed-show-visit
	"g" #'elfeed-show-refresh
	"q" #'elfeed-kill-buffer
	"u" #'elfeed-show-tag--unread
	"y" #'elfeed-show-yank
	)

  ;; Magit
  (general-def '(normal visual) magit-mode-map
	"{" #'magit-section-backward-sibling
	"}" #'magit-section-forward-sibling
	)

  ;; Minibuffer
  (general-def 'normal minibuffer-local-map
	"TAB"    #'selectrum-insert-current-candidate
	"j"      #'selectrum-next-candidate
	"k"      #'selectrum-previous-candidate
	"<up>"   #'selectrum-previous-candidate
	"<down>" #'selectrum-next-candidate
	)
  (general-def 'insert minibuffer-local-map
	"TAB"    #'selectrum-insert-current-candidate
	)

  ;; Mu4e
  (general-def 'normal mu4e-compose-mode-map
    "q"   #'mu4e-message-kill-buffer
	"M-c" #'message-send-and-exit
	"M-k" #'mu4e-message-kill-buffer
	)

  ;; Neotree
  (general-def 'normal neotree-mode-map
	"RET"       'neotree-enter
	"<backtab>" 'neotree-collapse-all ; <S-tab>
	"c"         'neotree-create-node
	"r"         'neotree-rename-node
	"d"         'neotree-delete-node
	"h"         'neotree-select-previous-sibling-node
	"g"         'neotree-refresh
	"j"         'neotree-next-line
	"k"         'neotree-previous-line
	"l"         'neotree-enter
	"C"         'neotree-change-root
	"H"         'neotree-hidden-file-toggle
	"q"         'neotree-hide
	)

  ;; Org
  (general-def 'normal org-mode-map
	"RET" #'dot/org-ret-at-point)
  (general-def 'insert org-mode-map
	"RET" #'evil-ret)
  (general-def 'motion org-agenda-mode-map
	"RET" #'org-agenda-switch-to)

  ;; Wdired
  (with-eval-after-load 'wdired
	(general-def '(normal insert) wdired-mode-map
	  "M-c" #'wdired-finish-edit
	  "M-k" #'wdired-abort-changes
	  ))
  )

Leader

General.el ~leader key binds.

Global Leader

(general-create-definer space-leader
  :prefix dot/leader-key
  :non-normal-prefix dot/leader-alt-key
  :global-prefix dot/leader-alt-key
  :states '(normal visual insert motion emacs)
  :keymaps 'override) ; prevent leader keybindings from ever being overridden

(space-leader
  "SPC"       '(dot/M-x                    :which-key "Execute command")
  "RET"       '(consult-bookmark           :which-key "Go to bookmark")

  ;; Apps
  "a"     '(:ignore t                      :which-key "apps")
  "a d"   '(deft                           :which-key "Deft")
  "a e"   '(elfeed                         :which-key "Elfeed")

  ;; Buffer / bookmark
  "b"         '(:ignore t                         :which-key "buffer/bookmark")
  "b a"       '(auto-revert-mode                  :which-key "Auto revert buffer")
  "b b"       '(consult-buffer                    :which-key "Switch buffer")
  "b d"       '(dot/dashboard-goto                :which-key "Dashboard")
  "b k"       '(kill-current-buffer               :which-key "Kill buffer")
  "b m"       '(bookmark-set                      :which-key "Make bookmark")
  "b n"       '(evil-buffer-new                   :which-key "New empty buffer")
  "b r"       '(revert-buffer                     :which-key "Revert buffer")
  "b s"       '(basic-save-buffer                 :which-key "Save buffer")
  "b B"       '(ibuffer                           :which-key "List buffers")
  "b C"       '(dot/centaur-tabs-buffer-cleanup   :which-key "Cleanup buffers")
  "b M"       '(bookmark-delete                   :which-key "Delete bookmark")
  "b S"       '(evil-write-all                    :which-key "Save all buffers")
  "b <left>"  '(previous-buffer                   :which-key "Previous buffer")
  "b <right>" '(next-buffer                       :which-key "Next buffer")

  ;; Comments
  "c"   '(:ignore t                               :which-key "comment/config")
  "c c" '(evilnc-comment-or-uncomment-lines       :which-key "Toggle comment")
  "c p" '(evilnc-comment-or-uncomment-paragraphs  :which-key "Toggle comment paragraph")
  "c y" '(evilnc-comment-and-kill-ring-save       :which-key "Comment and copy")

  ;; Elisp
  "e"   '(:ignore t                        :which-key "elisp")
  "e ;" '(eval-expression                  :which-key "Evaluate expression")
  "e b" '(eval-buffer                      :which-key "Evaluate buffer")
  "e e" '(eval-last-sexp                   :which-key "Evaluate last sexp")
  "e r" '(eval-region                      :which-key "Evaluate region")
  "e t" '(dot/reload-theme                 :which-key "Reload theme")

  ;; File
  "f"     '(:ignore t                      :which-key "file")
  "f d"   '(dired                          :which-key "Find directory")
  "f f"   '(dot/find-file-in-project-root  :which-key "Find file")
  "f o"   '(ff-find-other-file             :which-key "Find header/source file")
  "f r"   '(consult-recent-file            :which-key "Find recent file")
  "f R"   '(rename-file-and-buffer         :which-key "Rename file")
  "f s"   '(basic-save-buffer              :which-key "Save file")
  "f S"   '(write-file                     :which-key "Save file as...")
  "f u"   '(dot/sudo-find-file             :which-key "Sudo find file")
  "f U"   '(dot/sudo-this-file             :which-key "Sudo this file")
  "f e"   '(:ignore t                      :which-key "emacs")
  "f e c" '(dot/config-visit               :which-key "Config visit")
  "f e f" '(dot/find-file-emacsd           :which-key "Find emacs file")
  "f e r" '(dot/config-reload              :which-key "Config reload")

  ;; Go to
  "g"     '(:ignore t                      :which-key "goto")
  "g b"   '(consult-bookmark               :which-key "Go to bookmark")
  "g f"   '(consult-flycheck               :which-key "Go to flycheck error")
  "g m"   '(consult-mark                   :which-key "Go to marker")

  ;; Help
  "h"   '(:keymap help-map                 :which-key "help")
  "h o" '(:ignore t                        :which-key "describe-symbol-at-point")

  ;; Insert
  "i"   '(:ignore t                        :which-key "insert")
  "i b" '(dot/indent-buffer                :which-key "Indent buffer")
  "i f" '(fill-region                      :which-key "Reflow region")
  "i F" '(fill-paragraph                   :which-key "Reflow paragraph")
  "i r" '(indent-region                    :which-key "Indent region")
  "i s" '(dot/evil-normal-sort-paragraph   :which-key "Sort paragraph")
  "i S" '(dot/insert-spaces-until-column   :which-key "Insert spaces")
  "i y" '(yas-insert-snippet               :which-key "Insert yasnippet")

  ;; Notes
  "n"     '(:ignore t                           :which-key "notes")
  "n a"   '(org-agenda                          :which-key "Org agenda")
  "n r"   '(:ignore t                           :which-key "org-roam")
  "n r c" '(org-roam-capture                    :which-key "Capture")
  "n r C" '(org-roam-db-sync                    :which-key "Build cache")
  "n r f" '(org-roam-node-find                  :which-key "Find node")
  "n r g" '(org-roam-graph                      :which-key "Show graph")
  "n r i" '(org-roam-node-insert                :which-key "Insert")
  "n r I" '(dot/org-roam-node-insert-immediate  :which-key "Insert (without capture)")
  "n r r" '(org-roam-buffer-toggle              :which-key "Toggle buffer")
  "n r s" '(org-roam-ui-mode                    :which-key "Toggle server")

  ;; Project
  "p"   '(:keymap project-prefix-map       :which-key "project")
  "p b" '(consult-project-buffer           :which-key "project-switch-buffer")
  "p f" '(consult-project-extra-find       :which-key "project-find-file")
  "p g" '(consult-grep                     :which-key "project-find-regexp")

  ;; Quit
  "q"   '(:ignore t                        :which-key "quit")
  "q q" '(save-buffers-kill-terminal       :which-key "Quit Emacs")
  "q Q" '(save-buffers-kill-emacs          :which-key "Quit Emacs (and daemon)")
  "q f" '(delete-frame                     :which-key "Close frame")
  "q o" '(delete-other-frames              :which-key "Close other frames")

  ;; Search
  "s"   '(:ignore t                        :which-key "search")
  "s a" '(avy-goto-char-timer              :which-key "Avy goto char")
  "s f" '(consult-find                     :which-key "Search file")
  "s l" '(avy-goto-line                    :which-key "Avy goto line")
  "s p" '(consult-grep                     :which-key "Search project")
  "s q" '(evil-ex-nohighlight              :which-key "Stop search")
  "s s" '(consult-line                     :which-key "Search buffer")

  ;; Tabs / toggle
  "t"   '(:ignore t                                 :which-key "tabs/toggle")
  "t f" '(dot/toggle-fringe                         :which-key "Toggle fringe")
  "t g" '(centaur-tabs-switch-group                 :which-key "Switch tab group")
  "t h" '(centaur-tabs-backward-group               :which-key "Tab backward group")
  "t j" '(centaur-tabs-select-end-tab               :which-key "Tab select first")
  "t k" '(centaur-tabs-select-beg-tab               :which-key "Tab select last")
  "t l" '(centaur-tabs-forward-group                :which-key "Tab forward group")
  "t n" '(neotree-toggle-in-project-root            :which-key "Toggle Neotree")
  "t w" '(visual-line-mode                          :which-key "Toggle line wrapping")

  ;; Update packages
  "U"   '(dot/update-packages                       :which-key "Update packages")

  ;; Version control
  "v"     '(:ignore t                      :which-key "git")
  "v b"   '(magit-branch-checkout          :which-key "Magit switch branch")
  "v B"   '(magit-blame-addition           :which-key "Magit blame")
  "v C"   '(magit-clone                    :which-key "Magit clone")
  "v F"   '(magit-fetch                    :which-key "Magit fetch")
  "v L"   '(magit-log                      :which-key "Magit log")
  "v s"   '(magit-show-commit              :which-key "Magit show commit")
  "v S"   '(magit-stage-file               :which-key "Stage file")
  "v U"   '(magit-unstage-file             :which-key "Unstage file")
  "v v"   '(magit-status                   :which-key "Magit status")
  "v V"   '(magit-status-here              :which-key "Magit status here")
  "v c"   '(:ignore t                      :which-key "create")
  "v c c" '(magit-commit-create            :which-key "Commit")
  "v c b" '(magit-branch-and-checkout      :which-key "Branch")
  "v c r" '(magit-init                     :which-key "Initialize repo")
  "v f"   '(:ignore t                      :which-key "file")
  "v f c" '(magit-find-git-config-file     :which-key "Find gitconfig file")
  "v f D" '(magit-file-delete              :which-key "Delete file")
  "v f f" '(magit-find-file                :which-key "Find file")
  "v f R" '(magit-file-rename              :which-key "Rename file")
  "v l"   '(:ignore t                      :which-key "list")
  "v l r" '(magit-list-repositories        :which-key "List repositories")
  "v l s" '(magit-list-submodules          :which-key "List submodules")

  ;; Window
  "w"         '(:ignore t                               :which-key "window")
  "w +"       '(evil-window-increase-height             :which-key "Increase window height")
  "w -"       '(evil-window-decrease-height             :which-key "Decrease window height")
  "w <"       '(evil-window-decrease-width              :which-key "Decrease window width")
  "w ="       '(balance-windows                         :which-key "Balance windows")
  "w >"       '(evil-window-increase-width              :which-key "Increase window width")
  "w _"       '(evil-window-set-height                  :which-key "Maximize window height")
  "w h"       '(windmove-left                           :which-key "Focus window left")
  "w j"       '(windmove-down                           :which-key "Focus window down")
  "w k"       '(windmove-up                             :which-key "Focus window up")
  "w l"       '(windmove-right                          :which-key "Focus window right")
  "w o"       '(delete-other-windows                    :which-key "Close other windows")
  "w s"       '(split-follow-horizontally               :which-key "Split horizontal")
  "w v"       '(split-follow-vertically                 :which-key "Split vertical")
  "w w"       '(other-window                            :which-key "Focus other window")
  "w q"       '(dot/centaur-tabs-kill-buffer-or-window  :which-key "Close window")
  "w <left>"  '(windmove-left                           :which-key "Focus window left")
  "w <right>" '(windmove-right                          :which-key "Focus window right")
  "w <up>"    '(windmove-up                             :which-key "Focus window up")
  "w <down>"  '(windmove-down                           :which-key "Focus window down")
  ;; winner-redo (built-in window history)
  ;; winner-undo
  )

Evaluated keybinds.

(with-eval-after-load 'lsp-mode
  (space-leader lsp-mode-map
	"l" lsp-command-map
	"l = f" '(dot/lsp-format-buffer-or-region :which-key "format buffer or region")
	))

(with-eval-after-load 'dap-mode
  (space-leader lsp-mode-map
	"l d" '(dap-hydra :which-key "DAP hydra")
    ))

Source: https://github.com/redguardtoo/emacs.d/blob/master/lisp/init-evil.el#L712 https://github.com/suyashbire1/emacs.d/blob/master/init.el

Local Leader

(general-create-definer local-leader
  :prefix dot/localleader-key
  :non-normal-prefix dot/localleader-alt-key
  :global-prefix dot/localleader-alt-key
  :states '(normal visual insert motion emacs)
  :keymaps 'override ; prevent leader keybindings from ever being overridden

  ""    '(:ignore t                            :which-key "<localleader>")
  )

(local-leader org-mode-map
  "'"         '(org-edit-special               :which-key "Org edit")
  "e"         '(org-export-dispatch            :which-key "Org export")
  "o"         '(org-open-at-point              :which-key "Org open at point")
  "q"         '(org-set-tags-command           :which-key "Org tags")

  "g"         '(:ignore t                      :which-key "goto")
  "g o"       '(consult-outline                :which-key "Org go to heading")

  "i"         '(:ignore t                      :which-key "insert")
  "i c"       '(org-table-insert-column        :which-key "Insert table column")
  "i h"       '(org-table-insert-hline         :which-key "Insert table hline")
  "i H"       '(org-table-hline-and-move       :which-key "Insert table hline and move")
  "i r"       '(org-table-insert-row           :which-key "Insert table row")
  "i t"       '(org-insert-structure-template  :which-key "Insert template")

  "l"         '(:ignore t                      :which-key "links")
  "l i"       '(org-id-store-link              :which-key "Store ID link")
  "l l"       '(org-insert-link                :which-key "Insert link")
  "l s"       '(org-store-link                 :which-key "Store link")
  "l S"       '(org-insert-last-stored-link    :which-key "Insert stored link")

  "s"         '(:ignore t                      :which-key "tree/subtree")
  "s h"       '(org-promote-subtree            :which-key "Org promote subtree")
  "s j"       '(org-metadown                   :which-key "Org move subtree down")
  "s k"       '(org-metaup                     :which-key "Org move subtree up")
  "s l"       '(org-demote-subtree             :which-key "Org demote subtree")
  "s <left>"  '(org-promote-subtree            :which-key "Org promote subtree")
  "s <right>" '(org-demote-subtree             :which-key "Org demote subtree")
  "s <up>"    '(org-move-subree-up             :which-key "Org move subtree up")
  "s <down>"  '(org-move-subtree-down          :which-key "Org move subtree down")

  "t"         '(:ignore t                      :which-key "toggle")
  "t t"       '(org-todo                       :which-key "Org todo state")
  "t l"       '(org-toggle-link-display        :which-key "Org link display")
  )

(local-leader org-src-mode-map
  "k"         '(org-edit-src-abort             :which-key "Org Edit abort"))

(local-leader elfeed-search-mode-map
  "g"         '(elfeed-search-update--force    :which-key "Elfeed refresh buffer")
  "G"         '(elfeed-search-fetch            :which-key "Elfeed update feeds")
  )

(local-leader elfeed-show-mode-map
  "g"         '(elfeed-show-refresh            :which-key "Elfeed refresh buffer")
  )

;; c-fill-paragraph Reflow comment
;; https://youtu.be/hbmV1bnQ-i0?t=1910

Notes

Org mode keybinds:

Keystroke Description Function
<C-c C-c> Update tags/headline (org-ctrl-c-ctrl-c)
<C-return> Insert heading (org-insert-heading-respect-content)
<C-x n s> ? (org-narrow-to-subtree)
<C-x n w> ? (widen)
<M-return> Insert heading (org-meta-return)
<M-S-return> Insert todo heading (org-insert-todo-heading)
<M-down> Move subtree down (org-metadown)
<M-left> Promote heading (org-metaleft)
<M-right> Demote heading (org-metaright)
<M-up> Move subtree up (org-metaup)
<S-left/right> Cycle to next todo keyword (org-shiftleft/org-shiftright)
<S-up/down> Cycle todo priority (org-shiftup/org-shiftdown)