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.
 
 
 
 
 
 

33 KiB

Ricemacs, an Emacs Configuration

Initial setup

These commands need to be run after the first startup.

Irony mode

M-x irony-install-server

All the icons

M-x all-the-icons-install-fonts

Customizations

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

  (setq custom-file (concat emacs-d "/custom.el"))
  (load custom-file 'noerror)

Set custom faces, without using customize.

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

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
	:custom
	(auto-package-update-delete-old-versions t)
	(auto-package-update-hide-results t)
	(auto-package-update-last-update-day-path (concat emacs-cache "/.last-package-update-day"))
	:config
	(auto-package-update-maybe))

Compile

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

  (use-package auto-compile
	:custom (load-prefer-newer t)
	:config
	(auto-compile-on-load-mode)
	(auto-compile-on-save-mode))

Packages

Install and configure packages.

General

  (use-package hybrid-reverse-theme
	:load-path "~/code/elisp/emacs-hybrid-reverse"
	:custom (load-theme 'hybrid-reverse t))

  (use-package which-key
	:defer 1
	:custom
	(which-key-add-column-padding 1)
	(which-key-max-display-columns nil)
	(which-key-min-display-lines 5)
	(which-key-sort-order 'which-key-prefix-then-key-order)
	(which-key-sort-uppercase-first nil)
	:config (which-key-mode))

  (use-package general)

  (use-package ido-vertical-mode
	:config (ido-vertical-mode))

  (use-package smex
	:defer t
	:custom (smex-prompt-string "Command: ")
	:config (smex-initialize))

  (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))

Evil

Evil mode and related packages.

  (use-package undo-tree)
  (use-package goto-chg)

  (use-package evil
 :after (undo-tree goto-chg)
 :custom
 (evil-search-module 'evil-search)
 (evil-ex-complete-emacs-commands nil)
 (evil-vsplit-window-right t)
 (evil-split-window-below t)
 (evil-shift-round nil)
 (evil-want-C-u-scroll t)
 ;; Do not set half cursor in operator mode
 (evil-operator-state-cursor '(box))
 ;; Needed by evil-collection
 (evil-want-integration t)
 (evil-want-keybinding nil)
 :config (evil-mode))

  (use-package evil-collection
 :after evil
 :custom
 (evil-collection-company-use-tng nil)
 (evil-collection-key-blacklist '("M-h" "M-j" "M-k" "M-l" "SPC"))
 (evil-collection-setup-minibuffer t)
 :config (evil-collection-init))

  (use-package evil-nerd-commenter
 :after evil)

Telephone Line

Emacs mode line replacement.

  (use-package telephone-line
	:custom
	(telephone-line-lhs
	 '((evil   . (telephone-line-evil-tag-segment))
	   (accent . (telephone-line-erc-modified-channels-segment
				  telephone-line-process-segment
				  telephone-line-buffer-segment))
	   (nil    . (telephone-line-projectile-segment))))
	:config (telephone-line-mode))

NeoTree

Collect icon fonts and propertize them within Emacs
(requires M-x all-the-icons-install-fonts).

  (use-package all-the-icons)

Provides Emacs with a file tree.

  (use-package neotree
	:after all-the-icons
	:custom
	(neo-theme (if (display-graphic-p) 'icons 'arrow))
	(neo-autorefresh nil)
	(neo-dont-be-alone t)
	(neo-mode-line-type 'none)
	(neo-show-hidden-files t)
	(neo-vc-integration '(face))
	:hook (neotree-mode . (lambda (&rest _) (display-line-numbers-mode 0))))

Centaur Tabs

Places buffers as tabs in a bar at the top.

  (use-package centaur-tabs
	:demand
	:custom
	(centaur-tabs-height 40)
	(centaur-tabs-set-icons t)
	(centaur-tabs-style "slant")
	;; (centaur-tabs-set-modified-marker t)
	;; (centaur-tabs-modified-marker "*")
	;; (centaur-tabs-height 29)
	;; (centaur-tabs-set-icons nil)
	:hook (neotree-mode . centaur-tabs-local-mode)
	:config
	(centaur-tabs-mode))

Projectile

Project manager.

  (use-package projectile
	:custom
	(projectile-enable-caching t)
	(projectile-indexing-method 'hybrid)
	(projectile-project-search-path '("~"))
	(projectile-sort-order 'recentf)
	:config (projectile-mode))

Org

  (use-package htmlize
	:custom (org-export-html-postamble nil))
  ;org-export-html-postamble-format @ToDo

  (use-package ox-gfm)

Completion

Autocomplete packages (includes code completion and snippets).

Company
  (use-package company
	:defer t
	:custom
	(company-idle-delay 0.2)
	(company-minimum-prefix-length 2)
	(company-tooltip-align-annotations 't)
	:hook
	((c-mode-common
	  emacs-lisp-mode
	  latex-mode
	  org-mode
	  php-mode
	  shell-mode
	  shell-script-mode)
	 . company-mode)
  )
Flycheck

On the fly syntax checking.

  (use-package flycheck
	:defer t
	:hook
	((c-mode-common
	  emacs-lisp-mode
	  latex-mode
	  org-mode
	  php-mode
	  shell-mode
	  shell-script-mode)
	 . flycheck-mode))
LSP
  (use-package lsp-mode
	:defer t
	:hook
	((c-mode         ; clangd
	  c++-mode       ; clangd
	  php-mode)      ; nodejs-intelephense
	 . lsp-deferred)
	:custom
	(lsp-auto-guess-root t)
	(lsp-clients-clangd-args '("-compile-commands-dir=build" "-j=2" "-background-index" "-log=error"))
	(lsp-enable-xref t)
	(lsp-keep-workspace-alive nil)
	(lsp-prefer-flymake nil)
	:commands lsp)

  (use-package company-lsp
	:after company lsp-mode
	:custom
	(company-transformers nil)
	(company-lsp-async t)
	(company-lsp-cache-candidates nil)
	(company-lsp-enable-snippet t)
	:commands company-lsp
	:config (push 'company-lsp company-backends))

  (use-package lsp-ui
	:after flycheck lsp-mode
	:hook (lsp-mode . lsp-ui-mode)
	:custom
	(lsp-ui-doc-border (face-foreground 'default))
	(lsp-ui-doc-enable nil)
	(lsp-ui-doc-header t)
	(lsp-ui-doc-include-signature t)
	(lsp-ui-doc-position 'top)
	(lsp-ui-doc-use-childframe t)
	(lsp-ui-sideline-enable nil)
	(lsp-ui-sideline-ignore-duplicate t)
	(lsp-ui-sideline-show-code-actions nil)
	(lsp-ui-flycheck-enable t)
	(lsp-ui-flycheck-list-position 'right)
	(lsp-ui-flycheck-live-reporting t)
	(lsp-ui-peek-enable nil)
	(lsp-ui-peek-list-width 60)
	(lsp-ui-peek-peek-height 25)
	:commands lsp-ui-mode)
YASnippet
  (use-package yasnippet
	:defer t
	:hook
	((org-mode
	  prog-mode
	  tex-mode)
	 . yas-minor-mode)
	:custom (yas-prompt-functions '(yas-ido-prompt
									yas-completing-prompt))
	:config (yas-reload-all))

  (use-package yasnippet-snippets
	:after yasnippet)
C/C++

Irony requires M-x irony-install-server.

  (use-package irony
	:defer t
	:hook
	((c-mode
	  c++-mode)
	 . irony-mode)
	(irony-mode . irony-cdb-autosetup-compile-options)
	:config (push 'glsl-mode irony-supported-major-modes))

  (use-package company-irony
	:after company irony
	:config (push 'company-irony company-backends))

  (use-package company-c-headers
	:after company
	:config (push 'company-c-headers company-backends))
  ;; company-irony-c-headers

Prettify

  (use-package dashboard
	:custom
	(initial-buffer-choice (lambda () (get-buffer "*dashboard*")))
	(dashboard-banner-logo-title "GNU Emacs master race!")
	(dashboard-center-content t)
	(dashboard-set-file-icons t)
	(dashboard-set-footer nil)
	(dashboard-set-heading-icons t)
	(dashboard-show-shortcuts t)
	(dashboard-startup-banner 'logo)
	(dashboard-items '((projects . 10)
					   (bookmarks . 5)
					   (recents . 5)))
	:hook (dashboard-mode . (lambda (&rest _) (display-line-numbers-mode 0)))
	:config (dashboard-setup-startup-hook))

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

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

  (use-package org-bullets
	:defer t
	:hook (org-mode . org-bullets-mode))

  ;; Cmake syntax highlighting
  (use-package cmake-mode
	:defer t)

  ;; Shader syntax highlighting
  (use-package glsl-mode
	:defer t)

  ;; Mark code after the 80 column range
  (use-package column-enforce-mode
	:defer t
	:custom (column-enforce-comments nil)
	:custom-face (column-enforce-face ((t (:background "#373b41" :foreground "#de935f"))))
	:hook (prog-mode . column-enforce-mode))

Possible modern replacement for column-enforce-mode: https://github.com/laishulu/hl-fill-column

RSS

	  (use-package elfeed
		:custom
		(elfeed-db-directory (concat emacs-d "/elfeed"))
		(elfeed-enclosure-default-dir "~/downloads/")
		(elfeed-search-filter "@6-months-ago +unread")
		(elfeed-search-clipboard-type 'CLIPBOARD)
		(elfeed-search-title-max-width 100)
		(elfeed-search-title-min-width 30)
		(elfeed-search-trailing-width 55)
		(elfeed-show-unique-buffers t)
		(elfeed-feeds
		 '(("https://www.youtube.com/feeds/videos.xml?user=linustechtips" comedy reviews youtube)
		   ("https://www.youtube.com/feeds/videos.xml?channel_id=UC2eYFnH61tmytImy1mTYvhA" boomer linux shell youtube)
		   ("https://phoronix.com/rss.php" linux news reviews)
		   ))
		:hook
		(elfeed-search-mode . (lambda (&rest _) (display-line-numbers-mode 0)))
		(elfeed-show-mode   . (lambda (&rest _) (display-line-numbers-mode 0))))

General

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

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

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

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

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

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

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

  ;; When in the GUI version of Emacs, enable pretty symbols
  (when window-system (global-prettify-symbols-mode t))

Buffers

  ;; Buffers
  (setq ido-create-new-buffer 'always)
  (setq ido-enable-flex-maching t)
  (setq ido-everywhere t)
  (setq ibuffer-expert t)
  ;; Enable ido
  (ido-mode 1)

Electric

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

File Backups

File auto-saves, backups, tramps.

  (unless (file-directory-p emacs-cache)
	(make-directory emacs-cache t))
  ;https://emacs.stackexchange.com/questions/33/put-all-backups-into-one-backup-folder
  (setq backup-directory-alist `((".*" . ,emacs-cache))
		auto-save-file-name-transforms `((".*" ,(concat emacs-cache "") t))
		auto-save-list-file-prefix (concat emacs-cache "/.saves-")
		tramp-backup-directory-alist `((".*" . ,emacs-cache))
		tramp-auto-save-directory emacs-cache)
  (setq create-lockfiles nil   ; Disable lockfiles (.#)
		backup-by-copying t    ; Don't cobber symlinks
		delete-old-versions t  ; Cleanup backups
		version-control t      ; Use version numbers on backups
		kept-new-versions 5    ; Backups to keep
		kept-old-versions 2)   ; ,,

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)

Org

  ;; Org
  (with-eval-after-load 'org
	(add-to-list 'org-structure-template-alist
				 '("el" "#+BEGIN_SRC emacs-lisp\n?\n#+END_SRC")))

  (setq org-ellipsis " ↴")
  (setq org-src-fontify-natively t)
  (setq org-src-window-setup 'current-window)
  (setq org-latex-toc-command "\\newpage \\tableofcontents \\newpage")
  ;; Enable syntax highlighting when exporting to .pdf
  ;; Include latex-exporter
  (with-eval-after-load 'ox-latex
	;; Add minted to the list of packages to insert in every LaTeX header
	(add-to-list 'org-latex-packages-alist '("" "minted"))
	;; Define how minted is added to source code
	(setq org-latex-listings 'minted)
	(setq org-latex-minted-options
		  '(("frame" "lines") ("linenos=true")))
	;; Append -shell-escape to every element in org-latex-pdf-process
	(setq org-latex-pdf-process
		  (mapcar
		   (lambda (s)
			 (if (not (string-match-p "-shell-escape" s))
				 (replace-regexp-in-string "%latex " "%latex -shell-escape " s)
			   s))
		   org-latex-pdf-process)))

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 keyboard and terminal coding system
  (set-default-coding-systems 'utf-8-unix)
  (set-buffer-file-coding-system 'utf-8-unix)
  (set-file-name-coding-system 'utf-8-unix)
  (set-selection-coding-system 'utf-8-unix)

Window

  ;; Window rules
  (setq display-buffer-alist
		'(
		  ("^\\(\\*e?shell\\|vterm\\).*"
		   (display-buffer-in-side-window)
		   (window-height . 0.25)
		   (side . bottom)
		   (slot . -1)
		   (centaur-tabs-local-mode 1))
		  ("\\*Help.*"
		   (display-buffer-in-side-window)
		   (window-height . 0.25)
		   (side . bottom)
		   (slot . 0)
		   (centaur-tabs-local-mode 1))
		  ("\\*Faces\\*"
		   (display-buffer-in-side-window)
		   (window-height . 0.25)
		   (side . bottom)
		   (slot . 1)
		   (centaur-tabs-local-mode 1))
		  ))

  (add-hook 'shell-mode-hook 'centaur-tabs-local-mode)
  (add-hook 'eshell-mode-hook 'centaur-tabs-local-mode)
  (add-hook 'help-mode-hook 'centaur-tabs-local-mode)

Functions

General

Functions that only use built-in Emacs functionality.

  (defun bookmark-jump-ido ()
	"Use ido to search for the bookmark."
	(interactive)
	(bookmark-jump
	 (bookmark-get-bookmark
	  (ido-completing-read "Jump to bookmark: " (bookmark-all-names)))))

  (defun bookmark-delete-ido ()
	"Use ido to search for the bookmark to delete."
	(interactive)
	(bookmark-delete
	 (bookmark-get-bookmark
	  (ido-completing-read "Delete bookmark: " (bookmark-all-names)))))

  (defun config-visit ()
	"Config edit."
	(interactive)
	(find-file (concat emacs-d "/config.org")))

  (defun config-reload ()
	"Config reload."
	(interactive)
	(org-babel-load-file (concat emacs-d "/config.org")))

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

  (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))

  (defun find-project-root ()
	"Return root of the project, determined by .git/, 'default-directory' otherwise."
	(let ((search-directory (locate-dominating-file "." ".git")))
	  (if search-directory
		  search-directory
		default-directory))
	)

  (defun find-file-in-project-root ()
	"Find file in project root."
	(interactive)
	(let ((default-directory (find-project-root)))
	  (call-interactively 'find-file)))


  ;; 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)))))))

  ;; https://emacsredux.com/blog/2013/04/21/edit-files-as-root/
  (defun sudo-edit (&optional arg)
	"Edit currently visited file as root.

  With a prefix ARG prompt for a file to visit.
  Will also prompt for a file to visit if current
  buffer is not visiting a file."
	(interactive "P")
	(if (or arg (not buffer-file-name))
		(find-file (concat "/sudo:root@localhost:"
						   (read-file-name "Find file(as root): ")))
	  (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name))))

Package

Functions that use package functionality.

  (defun centaur-tabs-buffer-groups ()
	"Organize tabs into groups."
	(list
	 (cond
	  ((string-equal "*" (substring (buffer-name) 0 1)) "Emacs")
	  ((derived-mode-p 'dired-mode) "Dired")
	  ((memq major-mode '(org-mode
						  org-agenda-mode
						  diary-mode
						  emacs-lisp-mode)) "OrgMode")
	  (t "User"))))

  (defun dashboard-goto-bookmarks ()
	"Go to bookmarks."
	(interactive)
	(funcall (local-key-binding "m")))

  (defun dashboard-goto-projects ()
	"Go to projects."
	(interactive)
	(funcall (local-key-binding "p")))

  (defun dashboard-goto-recent-files ()
	"Go to recent files."
	(interactive)
	(funcall (local-key-binding "r")))

  (defun lsp-format-region-or-buffer ()
	"Format the selection (or buffer) with LSP."
	(interactive)
	(unless (bound-and-true-p lsp-mode)
	  (user-error "Not in an LSP buffer"))
	(call-interactively
	 (if (use-region-p)
		 #'lsp-format-region
	   #'lsp-format-buffer)))

  (defun neotree-toggle-in-project-root ()
	"Toggle Neotree in project root."
	(interactive)
	(let ((default-directory (find-project-root)))
	  (call-interactively 'neotree-toggle)))

Advice and Aliases

Advice

Define default terminal option.

  (defvar terminal-shell "/bin/zsh")
  (defadvice ansi-term (before force-bash)
	(interactive (list terminal-shell)))
  (ad-activate 'ansi-term)

Aliases

General

Make confirm easier, by just pressing y/n.

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

Package

Evil command aliases.

  (with-eval-after-load 'evil-ex
    (evil-ex-define-cmd "W" "w")
    (evil-ex-define-cmd "Q" "q")
    (evil-ex-define-cmd "WQ" "wq")
    (evil-ex-define-cmd "Wq" "wq"))

Hooks

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

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

  ;; C++ // style comments in c-mode
  (add-hook 'c-mode-hook (lambda () (c-toggle-comment-style 0)))

  ;; PHP, set correct tab mode
  (add-hook 'php-mode-hook (lambda () (setq indent-tabs-mode t)))

  ;; LaTeX, set correct tab mode
  (add-hook 'latex-mode-hook (lambda () (setq indent-tabs-mode t)))

Key Bindings

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

Disable default

  (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 "C-M-h") nil))

Default

  ;; Buffers
  (global-set-key (kbd "C-x b") 'ido-switch-buffer)
  (global-set-key (kbd "C-x C-b") 'ibuffer)
  (global-set-key (kbd "M-w") 'kill-this-buffer)

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

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

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

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

Disable package

Disable spacebar in evil motion.

  (with-eval-after-load 'evil-states
	(define-key evil-motion-state-map (kbd "SPC") nil))

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

Package

  ;; 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 "C-M-h") 'centaur-tabs-move-current-tab-to-left)
  (global-set-key (kbd "C-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-x") 'smex)

  ;; 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))
  ; https://github.com/company-mode/company-mode/blob/master/company.el#L661

  ;; 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))

  ; Overwrite evil keymaps
  ;(evil-global-set-key 'motion (kbd "C-w") 'kill-this-buffer)
  ;(evil-define-key 'motion 'global (kbd "C-w") 'kill-this-buffer)
  ;(define-key evil-motion-state-map (kbd "C-w") 'kill-this-buffer) ; @Todo test this with nil
  ;https://github.com/noctuid/evil-guide#global-keybindings-and-evil-states

  (with-eval-after-load 'evil-states
	(general-define-key
	 :keymaps 'evil-normal-state-map

	 ;; Neotree
	 "C-n" 'neotree-toggle-in-project-root)

	(general-define-key
	 :states 'normal
	 :keymaps '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
	 "j"         'neotree-next-line
	 "k"         'neotree-previous-line
	 "l"         'neotree-enter
	 "R"         'neotree-refresh
	 "C"         'neotree-change-root
	 "H"         'neotree-hidden-file-toggle
	 "q"         'neotree-hide
	 )

	;; Dashboard
	(general-define-key
	 :states 'normal
	 :keymaps 'dashboard-mode-map
	 [down-mouse-1] 'widget-button-click
	 "g" 'dashboard-refresh-buffer
	 "m" 'dashboard-goto-bookmarks
	 "p" 'dashboard-goto-projects
	 "r" 'dashboard-goto-recent-files
	 )

	;; Elfeed
	(general-define-key
	 :states 'normal
	 :keymaps 'elfeed-search-mode-map
	 "b"  'elfeed-search-browse-url
	 "c"  'elfeed-search-clear-filter
	 "gr" 'elfeed-search-update--force
	 "gR" 'elfeed-search-fetch
	 "q"  'kill-this-buffer
	 "u"  'elfeed-search-tag-all-unread
	 "U"  nil
	 "r"  'elfeed-search-untag-all-unread
	 )

	(general-define-key
	 :states 'normal
	 :keymaps 'elfeed-show-mode-map
	 "b" #'elfeed-show-visit
	 "g" 'elfeed-show-refresh
	 "q" 'kill-this-buffer
	 "u" #'elfeed-show-tag--unread
	 "y" #'elfeed-show-yank
	 ))

Leader

General.el ~leader key binds.

Global

  (with-eval-after-load 'general
	(general-create-definer space-leader
	  :prefix "SPC"
	  :non-normal-prefix "M-SPC"
	  :global-prefix "M-SPC"
	  :states '(normal visual insert motion emacs))

	(space-leader
	  "SPC"       '(smex                       :which-key "Smex")
	  "RET"       '(bookmark-jump-ido          :which-key "Jump to bookmark")

	  ;; Buffer / bookmark
	  "b"         '(:ignore t                  :which-key "buffer/bookmark")
	  "b b"       '(ido-switch-buffer          :which-key "Switch buffer")
	  "b B"       '(ibuffer                    :which-key "List buffers")
	  "b d"       '(kill-current-buffer        :which-key "Kill buffer")
	  "b h"       '(previous-buffer            :which-key "Previous buffer")
	  "b k"       '(kill-current-buffer        :which-key "Kill buffer")
	  "b l"       '(next-buffer                :which-key "Next buffer")
	  "b m"       '(bookmark-set               :which-key "Make bookmark")
	  "b M"       '(bookmark-delete-ido        :which-key "Delete 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 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 / config
	  "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 r" '(config-reload                           :which-key "Config reload")
	  "c v" '(config-visit                            :which-key "Config visit")
	  "c y" '(evilnc-comment-and-kill-ring-save       :which-key "Comment and copy")

	  ;; LSP
	  "d"   '(:ignore t                        :which-key "lsp")
	  "d c" '(lsp-describe-thing-at-point      :which-key "LSP Describe under cursor")
	  "d d" '(lsp-find-definition              :which-key "LSP Find definition")
	  "d e" '(lsp-execute-code-action          :which-key "LSP Execute code action")
	  "d f" '(lsp-format-region-or-buffer      :which-key "LSP Format region/buffer")
	  "d r" '(lsp-find-references              :which-key "LSP Find references")
	  "d R" '(lsp-rename                       :which-key "LSP Rename")
	  "d s" '(lsp                              :which-key "Start LSP")

	  ;; Find file
	  "f"   '(:ignore t                        :which-key "file")
	  "f f" '(find-file-in-project-root        :which-key "Find file")
	  "f r" '(rename-file-and-buffer           :which-key "Rename file")
	  "f s" '(basic-save-buffer                :which-key "Save file")

	  ;; Help
	  "h"   '(help-command                     :which-key "help")

	  ;; Insert
	  "i"   '(:ignore t                        :which-key "insert")
	  "i s" '(yas-insert-snippet               :which-key "Snippet")

	  ;; Neotree
	  "n"   '(neotree-toggle-in-project-root   :which-key "Toggle Neotree")

	  ;; Projectile
	  "p"   '(:keymap projectile-command-map   :which-key "projectile")

	  ;; 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")

	  ;; Reformat region
	  "r"   '(:ignore t                        :which-key "region")
	  "r r" '(indent-region                    :which-key "Indent region")

	  ;; Search
	  "s"   '(:ignore t                        :which-key "search")
	  "s a" '(avy-goto-char-timer              :which-key "Avy goto char")
	  "s b" '(bookmark-jump-ido                :which-key "Jump to bookmark")

	  ;; Tabs
	  "t"   '(:ignore t                                 :which-key "tabs")
	  "t b" '(centaur-tabs-group-buffer-groups          :which-key "Group tabs by buffer")
	  "t p" '(centaur-tabs-group-by-projectile-project  :which-key "Group tabs by project")
	  "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")

	  ;; Update packages
	  "u"   '(auto-package-update-now          :which-key "Update packages")

	  ;; Window
	  ;; "w"         '(:keymap evil-window-map    :which-key "window")
	  "w"         '(:ignore t                  :which-key "window")
	  "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"       '(:ignore t                  :which-key "split")
	  "w s h"     '(split-follow-horizontally  :which-key "Split horizontal")
	  "w s v"     '(split-follow-vertically    :which-key "Split vertical")
	  "w w"       '(other-window               :which-key "Focus other window")
	  "w q"       '(delete-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

	  "x"         '(smex-major-mode-commands   :which-key "Smex major mode")
	  ))

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

Major mode

  (general-create-definer local-leader
	:prefix "SPC m"
	:non-normal-prefix "M-SPC m"
	:global-prefix "M-SPC m"
	:states '(normal visual insert motion emacs)
	)

  (which-key-add-key-based-replacements "SPC m" "<local leader>")
  (which-key-add-key-based-replacements "M-SPC m" "<local leader>")

  (local-leader org-mode-map
	"'"   '(org-edit-special                 :which-key "Org edit")
	)

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

  (define-key org-src-mode-map (kbd "C-c C-c") #'org-edit-src-exit)

  (local-leader elfeed-search-mode-map
	"g"   'elfeed-search-update--force
	"G"   'elfeed-search-fetch
	)

  (local-leader elfeed-show-mode-map
	"g"   'elfeed-show-refresh
	)

  ;; 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)