Files
config.phundrak.com/docs/emacs/keybindings.org
T

547 lines
27 KiB
Org Mode
Raw Normal View History

2023-09-18 18:45:14 +02:00
#+title: Emacs — Keybindings
#+setupfile: ../headers
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/keybindings.el
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
* Keybindings
Undefining some stuff to make keybind prefixes work correctly.
#+name: general-keybindings-gen
#+header: :tangle no :exports none :results value :cache yes
#+begin_src emacs-lisp :var table=keybindings-apps prefix="a"
(mapconcat
(lambda (line)
(let* ((key (format "%s" (nth 0 line)))
(function (nth 1 line))
(fn-nil-p (member function '("" "nil")))
(comment (or (nth 2 line) ""))
(comment-p (not (string= "" comment)))
(comment (cond ((nth 2 line) (concat " :wk \"" (nth 2 line) "\""))
(fn-nil-p " :wk t")
(t "")))
(package (or (nth 3 line) ""))
(package-p (not (string= "" (nth 3 line))))
(package (if package-p (concat " :package " (nth 3 line)) "")))
(format "\"%s\" %s"
(concat prefix key)
(if (or comment-p package-p)
(format "'(%s%s%s)"
(if (member function '("" "nil"))
":ignore t"
function)
(if comment-p comment "")
(if package-p package ""))
(concat "#'" function)))))
table
"\n")
2023-09-18 18:45:14 +02:00
#+end_src
#+begin_src emacs-lisp
(general-define-key
:keymaps 'global-map
"<mouse-2>" nil
"<mouse-3>" nil)
(phundrak/evil
:packages '(counsel)
"U" '(evil-redo :package evil)
2023-09-18 18:45:14 +02:00
"C-a" #'beginning-of-line
"C-e" #'end-of-line
"C-y" #'yank
"M-y" '(counsel-yank-pop :package counsel))
2023-09-18 18:45:14 +02:00
#+end_src
#+begin_src emacs-lisp :results none
2023-09-18 18:45:14 +02:00
(general-define-key
"<f5>" #'compile
"<f6>" #'recompile)
(phundrak/leader-key
"SPC" '(counsel-M-x :wk "M-x")
"'" '(shell-pop :package shell-pop)
"R" #'recompile
2023-09-18 18:45:14 +02:00
"u" #'universal-argument
<<general-keybindings-gen(table=keybindings-tabs, prefix="TAB ")>>
<<general-keybindings-gen(table=keybindings-apps, prefix="a")>>
<<general-keybindings-gen(table=keybindings-apps-shell, prefix="as")>>
<<general-keybindings-gen(table=keybindings-treemacs, prefix="at")>>
<<general-keybindings-gen(table=keybindings-buffers, prefix="b")>>
<<general-keybindings-gen(table=keybindings-code, prefix="c")>>
<<general-keybindings-gen(table=keybindings-errors, prefix="e")>>
<<keybindings-errors-extra>>
<<general-keybindings-gen(table=keybindings-files, prefix="f")>>
<<keybindings-files-extras>>
<<general-keybindings-gen(table=keybindings-git, prefix="g")>>
<<general-keybindings-gen(table=keybindings-help, prefix="h")>>
<<general-keybindings-gen(table=keybindings-insert, prefix="i")>>
<<general-keybindings-gen(table=keybindings-jump, prefix="j")>>
<<general-keybindings-gen(table=keybindings-language, prefix="l")>>
<<general-keybindings-gen(table=keybindings-media, prefix="m")>>
<<general-keybindings-gen(table=keybindings-org, prefix="o")>>
<<general-keybindings-gen(table=keybindings-refactor, prefix="r")>>
<<general-keybindings-gen(table=keybindings-toggle, prefix="t ")>>
<<general-keybindings-gen(table=keybindings-text, prefix="T")>>
<<general-keybindings-gen(table=keybindings-windows, prefix="w")>>
<<general-keybindings-gen(table=keybindings-quit, prefix="q")>>)
2023-09-18 18:45:14 +02:00
#+end_src
** Apps
Here are my apps keybindings. Each one of them is prefixed by ~a~.
#+name: keybindings-apps
2025-11-19 11:30:34 +01:00
| Key | Function | Description | Package |
|-----+----------------------------+-------------+-----------------|
| | | apps | |
| a | | AI | |
| ae | eca | | eca |
| aC | claude-code-ide | | claude-code-ide |
| ac | claude-code-ide-menu | | claude-code-ide |
| c | calc | | |
| C | | calendar | |
| CC | calendar | | |
| Co | org-agenda | | org |
| Cs | org-caldav-sync | | org-caldav |
| d | docker | | docker |
| E | elfeed | | elfeed |
| e | | email | |
| ec | mu4e-compose-new | | mu4e |
| em | mu4e | | mu4e |
| k | keycast-mode | | keycast |
| K | keycast-log-mode | | keycast |
| m | | mastodon | |
| mm | mastodon | | mastodon |
| mn | mastodon-notifications-get | | mastodon |
| mt | mastodon-toot | | mastodon |
| T | tetris | | |
| S | screenshot | | screenshot |
| w | wttrin | | wttrin |
2023-09-18 18:45:14 +02:00
*** Shell apps
2023-09-18 18:45:14 +02:00
I also have two main shell-related functions, prefixed with ~as~.
#+name: keybindings-apps-shell
2025-06-08 14:51:25 +02:00
| Key | Function | Description | Package |
|-----+------------+-------------+---------|
| | | shells | |
| e | eshell-new | | |
| t | eat | | eat |
2023-09-18 18:45:14 +02:00
*** Treemacs
#+name: keybindings-treemacs
| Key | Function | Description | Package |
|-----+----------------------------------------+-------------+----------|
| | | treemacs | |
2025-05-24 21:24:14 +02:00
| c | | create | |
| cd | treemacs-create-dir | | treemacs |
| cf | treemacs-create-file | | treemacs |
| ci | treemacs-create-icon | | treemacs |
| ct | treemacs-create-theme | | treemacs |
| cw | treemacs-create-workspace | | treemacs |
| d | treemacs-delete-file | | treemacs |
| f | | files | |
| ff | treemacs-find-file | | treemacs |
| ft | treemacs-find-tag | | treemacs |
| l | | lsp | |
| ls | treemacs-expand-lsp-symbol | | treemacs |
| ld | treemacs-expand-lsp-treemacs-deps | | treemacs |
| lD | treemacs-collapse-lsp-treemacs-deps | | treemacs |
| lS | treemacs-collapse-lsp-symbol | | treemacs |
| p | | projects | |
| pa | treemacs-add-project-to-workspace | | treemacs |
| pf | treemacs-project-follow-mode | | treemacs |
| pn | treemacs-project-of-node | | treemacs |
| pp | treemacs-project-at-point | | treemacs |
| pr | treemacs-remove-project-from-workspace | | treemacs |
| pt | treemacs-move-project-down | | treemacs |
| ps | treemacs-move-project-up | | treemacs |
| r | | rename | |
| rf | treemacs-rename-file | | treemacs |
| rp | treemacs-rename-project | | treemacs |
| rr | treemacs-rename | | treemacs |
| rw | treemacs-rename-workspace | | treemacs |
| t | treemacs | | treemacs |
| T | | toggles | |
| Td | treemacs-toggle-show-dotfiles | | treemacs |
| Tn | treemacs-toggle-node | | treemacs |
| v | | visit node | |
| va | treemacs-visit-node-ace | | treemacs |
| vc | treemacs-visit-node-close-treemacs | | treemacs |
| vn | treemacs-visit-node-default | | treemacs |
| y | | yank | |
| ya | treemacs-copy-absolute-path-at-point | | treemacs |
| yp | treemacs-copy-project-path-at-point | | treemacs |
| yr | treemacs-copy-relative-path-at-point | | treemacs |
| yf | treemacs-copy-file | | treemacs |
2023-09-18 18:45:14 +02:00
** Buffers
My buffer-related keybindings are all prefixed by ~b~.
#+name: keybindings-buffers
| Key | Function | Description | Package |
|-----+------------------------------------+-------------+-----------|
| | | buffers | |
| b | bufler-switch-buffer | | bufler |
| B | bury-buffer | | |
| c | clone-indirect-buffer | | |
| C | clone-indirect-buffer-other-window | | |
| l | bufler | | bufler |
| d | kill-current-buffer | | |
| D | kill-buffer | | |
| h | dashboard-refresh-buffer | | dashboard |
| m | switch-to-messages-buffer | | |
| n | next-buffer | | |
| p | previous-buffer | | |
| r | counsel-buffer-or-recentf | | counsel |
| R | rename-uniquely | | |
| s | switch-to-scratch-buffer | | |
** Code
#+name: keybindings-code
| Key | Function | Description | Package |
|-----+-----------------------------------+-------------+---------------------|
| | | code | |
| l | evilnc-comment-or-uncomment-lines | | evil-nerd-commenter |
| n | hl-todo-next | | hl-todo |
| p | hl-todo-previous | | hl-todo |
2023-09-18 18:45:14 +02:00
** Errors
#+begin_src emacs-lisp
(defhydra hydra-flycheck
(:pre (flycheck-list-errors)
:post (quit-windows-on "*Flycheck errors*")
:hint nil)
("f" flycheck-error-list-set-filter "Filter")
("t" flycheck-next-error "Next")
("s" flycheck-previous-error "Previous")
("gg" flycheck-first-error "First")
("G" (progn (goto-char (point-max)) (flycheck-previous-error)) "Last")
("q" nil))
#+end_src
#+name: keybindings-errors
| Key | Function | Description | Package |
|-----+---------------------+----------------+---------|
| | | errors | |
| . | hydra-flycheck/body | hydra-flycheck | |
| l | counsel-flycheck | | counsel |
| F | flyspell-hydra/body | flyspell-hydra | |
#+name: keybindings-errors-extra
2023-09-18 18:45:14 +02:00
#+begin_src emacs-lisp :tangle no
"ee" '(:keymap flycheck-command-map :package 'flycheck :wk "flycheck")
"ef" '(:keymap flyspell-mode-map :package 'flyspell :wk "flyspell")
#+end_src
** Files
My keybindings for file manipulation are prefixed by ~f~.
#+name: keybindings-files
| Key | Function | Description | Package |
|-----+-------------------+-------------+------------------|
| | | files | |
| f | counsel-find-file | | counsel |
| F | quick-find-files | | quick-find-files |
| h | hexl-find-file | | |
| r | counsel-recentf | | counsel |
| s | save-buffer | | |
I also have some keybindings dedicated to opening specific files.
#+name: keybindings-files-extras
2023-09-18 18:45:14 +02:00
#+begin_src emacs-lisp :tangle no
"fc" '((lambda ()
(interactive)
(quick-find-files nil "~/org/config/docs/emacs" "org"))
:wk "emacs config"
:package quick-find-files)
"fC" '((lambda ()
(interactive)
(quick-find-files nil "~/org/config/docs" "org"))
:wk "general config"
:package quick-find-files)
2023-09-18 18:45:14 +02:00
"fi" '((lambda ()
(interactive)
(find-file (concat user-emacs-directory "init.el")))
:which-key "init.el")
"fI" '((lambda ()
(interactive)
(quick-find-files nil
(expand-file-name "lisp" user-emacs-directory)
"el"))
:which-key "elisp config"
:package quick-find-files)
2023-09-18 18:45:14 +02:00
"fR" '((lambda ()
(interactive)
(counsel-find-file ""
(concat user-emacs-directory
(file-name-as-directory "straight")
(file-name-as-directory "repos"))))
:which-key "straight package"
:package counsel)
2023-09-18 18:45:14 +02:00
"fS" '((lambda ()
(interactive)
(find-file "~/org/config/stumpwm.org"))
:which-key "stumpwm.org")
#+end_src
** Git
#+name: keybindings-git
| Key | Function | Description | Package |
|-----+---------------------+-------------+---------|
| | | git | |
| b | magit-blame | | magit |
| c | magit-clone | | magit |
| d | magit-dispatch | | magit |
| i | magit-init | | magit |
| s | magit-status | | magit |
| l | magit-log | | magit |
| y | my/yadm | | magit |
| S | magit-stage-file | | magit |
| U | magit-unstage-file | | magit |
| f | | file | |
| fd | magit-diff | | magit |
| fc | magit-file-checkout | | magit |
| fl | magit-file-dispatch | | magit |
| fF | magit-find-file | | magit |
2023-09-18 18:45:14 +02:00
** Help
My keybindings for help are prefixed by ~h~.
#+name: keybindings-help
2023-09-18 18:45:14 +02:00
| Key | Function | Description |
|-----+--------------------------+-------------|
| | | help |
| k | which-key-show-top-level | which-key |
2023-09-18 18:45:14 +02:00
| i | info | |
| I | info-display-manual | |
| d | | describe |
| dc | describe-char | |
| dC | helpful-command | |
| df | helpful-callable | |
| di | describe-input-method | |
| dk | helpful-key | |
| dm | helpful-macro | |
| dM | helpful-mode | |
| dp | describe-package | |
| ds | helpful-symbol | |
| dv | helpful-variable | |
** Insert
#+name: keybindings-insert
| Key | Function | Description | Package |
|-----+----------------------+-------------+-----------|
| | | insert | |
| u | counsel-unicode-char | | counsel |
| y | ivy-yasnippet | | yasnippet |
2023-09-18 18:45:14 +02:00
** Jump
My keybindings for jumping around are prefixed by ~j~.
#+name: keybindings-jump
| Key | Function | Description | Package |
|-----+-------------------------------+-------------+---------|
| | | jump | |
| C | | avy copy | |
| Cl | avy-copy-line | | avy |
| Cr | avy-copy-region | | avy |
| D | dired-jump-other-window | | |
| U | my/avy-open-url | open-url | avy |
| b | avy-pop-mark | | avy |
| c | evil-avy-goto-char-timer | | avy |
| d | dirvish-dwim | | dirvish |
| f | counsel-file-jump | | counsel |
| k | | avy kill | |
| kL | avy-kill-ring-save-whole-line | | avy |
| kR | avy-kill-ring-save-region | | avy |
| kl | avy-kill-whole-line | | avy |
| kr | avy-kill-region | | avy |
| l | avy-goto-line | | avy |
| m | | move | |
| ml | avy-move-line | | avy |
| mr | avy-move-region | | avy |
| mt | avy-transpose-lines-in-region | | avy |
| n | avy-next | | avy |
| p | avy-prev | | avy |
| u | my/avy-goto-url | goto-url | avy |
** Language
#+name: keybindings-language
| Key | Function | Description | Package |
|-----+----------------------------------+-------------+----------|
| | | language | |
| . | langtool-correct-at-point | | langtool |
| B | langtool-correct-buffer | | langtool |
| b | langtool-check-buffer | | langtool |
| c | langtool-check | | langtool |
| d | langtool-check-done | | langtool |
| l | langtool-switch-default-language | | langtool |
| p | langtool-show-message-at-point | | langtool |
| r | langtool-correct-region | | langtool |
** Media
#+name: keybindings-media
| Key | Function | Description | Package |
|-----+-----------------------------+----------------+---------|
| | | media | |
| . | hydra-media/body | hydra-media | emms |
| « | emms-player-mpd-previous | | emms |
| » | emms-player-mpd-next | | emms |
| c | emms-player-mpd-clear | | emms |
| e | | emms | |
| eb | emms-browser | | emms |
| ep | emms-playlist-mode-go | | emms |
| es | emms-player-mpd-show | | emms |
| p | my/mpc-toggle | mpd-play-pause | |
| s | emms-stop | | emms |
| u | | update | |
| um | emms-player-mpd-update-all | | emms |
| uc | emms-cache-set-from-mpd-all | | emm s |
2023-09-18 18:45:14 +02:00
** Project
My keybindings for my projects are prefixed by ~p~.
#+name: keybindings-project
| Key | Function | Description | Package |
|-----+--------------------------------------------+-------------+------------|
| | | project | |
| ! | projectile-run-shell-command-in-root | | projectile |
| & | projectile-run-async-shell-command-in-root | | projectile |
| b | counsel-projectile-switch-to-buffer | | counsel |
| c | counsel-projectile | | counsel |
| d | counsel-projectile-find-dir | | counsel |
| e | projectile-edit-dir-locals | | projectile |
| f | counsel-projectile-find-file | | counsel |
| g | projectile-find-tag | | projectile |
| k | project-kill-buffers | | |
| p | counsel-projectile-switch-project | | cousel |
| v | projectile-vc | | projectile |
** Refactor
#+name: keybindings-refactor
| Key | Function | Description | Package |
|-----+----------------------------------+-----------------+------------------|
| | | refactor | |
| i | evil-iedit-state/iedit-mode | iedit-mode | evil-iedit-state |
| q | evil-iedit-state/quit-iedit-mode | quit-iedit-mode | evil-iedit-state |
** Org
#+name: keybindings-org
| Key | Function | Description | Package |
|-----+--------------------------------+-------------+----------|
| | | org | |
2025-11-01 11:38:58 +01:00
| c | | clock | |
| cc | org-clock-cancel | | org |
| cd | org-clock-display | | org |
| cg | org-clock-goto | | org |
| ci | org-clock-in | | org |
| co | org-clock-out | | org |
| C | org-capture | | org |
| r | | roam | |
| rb | org-mark-ring-goto | back | org-roam |
| rB | org-roam-buffer-toggle | | org-roam |
| rn | | nodes | |
| rnf | org-roam-node-find | | org-roam |
| rni | org-roam-node-insert | | org-roam |
| rno | org-roam-node-open | | org-roam |
| rnr | org-roam-node-random | | org-roam |
| rnv | org-roam-node-visit | | org-roam |
| rs | | sync | |
| rsa | org-roam-db-autosync-mode | | org-roam |
| rsc | org-roam-db-clear-all | | org-roam |
| rsd | org-roam-db-diagnose-node | | org-roam |
| rss | org-roam-db-sync | | org-roam |
| ru | | ui | |
| rua | org-roam-ui-add-to-local-graph | | org-roam |
| ruo | org-roam-ui-open | | org-roam |
2023-09-18 18:45:14 +02:00
** Tabs
Emacs has native tabs available, which can be interesting when working
on multiple projects at once between which we may want to switch. Tabs
allow the user not to have multiple frames while keeping the
advantages of having multiple frames.
My keybindings are prefixed by ~SPC TAB~.
#+name: keybindings-tabs
2023-09-18 18:45:14 +02:00
| Key | Function | Description |
|-----+--------------+-------------|
| | | tabs |
| TAB | tab-switch | |
| » | tab-next | |
| « | tab-previous | |
| c | tab-new | |
| C | tab-new-to | |
| d | tab-close | |
| n | tab-next | |
| p | tab-previous | |
| r | tab-rename | |
** Text
The prefix here is ~T~.
#+name: keybindings-text
| Key | Function | Description | Package |
|-----+----------------------+-------------+----------------------|
| | | text | |
| e | string-edit-at-point | | string-edit-at-point |
| u | downcase-region | | |
| U | upcase-region | | |
| z | hydra-zoom/body | | |
*** TODO Rewrite hydra-zoom :noexport:
2023-09-18 18:45:14 +02:00
** Toggles
My toggle keybindings are prefixed by ~t~.
#+name: keybindings-toggle
2023-09-18 18:45:14 +02:00
| Key | Function | Description |
|-----+---------------------------------------+--------------|
| | | toggles |
| TAB | tab-bar-mode | |
| t | my/modify-frame-alpha-background/body | |
| T | counsel-load-theme | |
| d | | debug |
| de | toggle-debug-on-error | |
| dq | toggle-debug-on-quit | |
| i | | input method |
| it | toggle-input-method | |
| is | set-input-method | |
*** TODO Rewrite =my/modify-frame-alpha-background/body= :noexport:
2023-09-18 18:45:14 +02:00
** Windows
A couple of keybindings are hidden from which-key, otherwise theres not
2023-09-18 18:45:14 +02:00
much to say. The prefix here is ~w~.
#+name: keybindings-windows
| Key | Function | Description | Package |
|-----+-------------------------------+----------------+----------------|
| | | windows | |
| c | evil-window-left | | evil |
| t | evil-window-down | | evil |
| s | evil-window-up | | evil |
| r | evil-window-right | | evil |
| . | windows-adjust-size/body | | |
| - | split-window-below-and-focus | | |
| / | split-window-right-and-focus | | |
| $ | winum-select-window-by-number | | winum |
| 0 | winum-select-window-0-or-10 | none | winum |
| 1 | winum-select-window-1 | none | winum |
| 2 | winum-select-window-2 | none | winum |
| 3 | winum-select-window-3 | none | winum |
| 4 | winum-select-window-4 | none | winum |
| 5 | winum-select-window-5 | none | winum |
| 6 | winum-select-window-6 | none | winum |
| 7 | winum-select-window-7 | none | winum |
| 8 | winum-select-window-8 | none | winum |
| 9 | winum-select-window-9 | none | winum |
| b | kill-buffer-and-window | | |
| d | delete-window | | |
| o | other-window | | |
| D | delete-other-windows | | |
| w | | writeroom | |
| w. | my/writeroom-transient | adapt width | |
| w= | my/writeroom-reset | reset width | |
| wf | my/writeroom-fit-buffer | fit to content | |
| ww | writeroom-mode | | writeroom-mode |
2023-09-18 18:45:14 +02:00
** Quit
Why would I ever use any of these keybindings? They are prefixed with ~q~.
#+name: keybindings-quit
2023-09-18 18:45:14 +02:00
| Key | Function | Description |
|-----+----------------------------+-------------|
| | | quit |
| f | delete-frame | |
| q | save-buffers-kill-terminal | |
| Q | kill-emacs | |