#+TITLE: Keys #+AUTHOR: Christopher James Hayward #+EMAIL: chris@chrishayward.xyz #+PROPERTY: header-args:emacs-lisp :tangle keys.el :comments org #+PROPERTY: header-args :results silent :eval no-export :comments org #+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil #+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil Improve the keyboard experience within Emacs. * Config Some of the default keybindings in Emacs really do leave you wondering, for example, when you want to exit a prompt you have to use =C-g=. Offer =ESC= as an alternative to quit (most) prompts, which I have muscle memory for already from literally every program created since 1990. #+begin_src emacs-lisp (global-set-key (kbd "") 'keyboard-escape-quit) #+end_src ** Hints Since Emacs is keyboard driven software, there are a lot of keybindings. Sometimes it's useful to start pressing well-known key combinations, and view the available completions. This behaviour is implemented in the third-party package ~which-key~[fn:1]. It displays the current incomplete keybinding input in a mini-buffer. It also works in the other direction, showing the corresponding keybindings for each command when you run =M-x=. #+begin_src emacs-lisp (use-package which-key :diminish which-key-mode :custom (which-key-idle-delay dotfiles/idle) :config (which-key-mode)) #+end_src ** Leader If like myself, you started using Emacs using a framework such as ~doom~[fn:2] or ~spacemacs~[fn:3], you probably have a considerable amount of muscle memory developed for using =SPC= as a leader key. In both of the previously mentioned frameworks, the package ~general.el~[fn:4] is used to implement this behaviour. It's a major improvement to the default way of creating custom keybindings in Emacs. #+begin_src emacs-lisp (use-package general :config (general-create-definer dotfiles/leader :states '(normal motion) :keymaps 'override :prefix dotfiles/leader-key :global-prefix dotfiles/leader-key-global)) #+end_src ** Transient Create transient keybindings with a shared prefix through ~hydra~[fn:5]. This is also used by a number of third-party packages as a completion system. An implementation example is used to scale the font size. #+begin_src emacs-lisp (use-package hydra :defer t) #+end_src * Shortcuts Implement some shortcut bindings, with a significant portion of them cherry picked from ~doom~[fn:2]: + Close buffers with =SPC c= + Find files with =SPC . (period)= + Switch buffers with =SPC , (comma)= + Kill buffers with =SPC / (slash)= #+begin_src emacs-lisp (dotfiles/leader "." '(find-file :which-key "Files") "," '(switch-to-buffer :which-key "Buffers") "c" '(kill-buffer-and-window :which-key "Close")) #+end_src ** Quitting Emacs Customize the behaviour of exiting emacs, with keybindings behind =SPC q=: + Save and quit =q= + Quit without saving =w= + Exit the Frame (daemon) =f= #+begin_src emacs-lisp (dotfiles/leader "q" '(:ignore t :which-key "Quit") "qq" '(save-buffers-kill-emacs :which-key "Save") "qw" '(kill-emacs :which-key "Now") "qf" '(delete-frame :which-key "Frame")) #+end_src ** Managing windows Screen space is divided into Frames inside of Emacs, manage them behind =SPC w=: + Swap with =w= + Close with =c= + Delete with =d= + Move with =h,j,k,l= + Split with =s - = #+begin_src emacs-lisp (dotfiles/leader "w" '(:ignore t :which-key "Window") "ww" '(window-swap-states :which-key "Swap") "wc" '(delete-window :which-key "Close") "wh" '(windmove-left :which-key "Left") "wj" '(windmove-down :which-key "Down") "wk" '(windmove-up :which-key "Up") "wl" '(windmove-right :which-key "Right") "ws" '(:ignore t :which-key "Split") "wsj" '(split-window-below :which-key "Down") "wsl" '(split-window-right :which-key "Right")) #+end_src ** Helper Functions Use the built-in ~describe-*~ functionality of Emacs to quickly access documentation for packages, variables, and functions. Run helper functions with =SPC h=: + Packages =p= + Variables =v= + Functions =f= #+begin_src emacs-lisp (dotfiles/leader "h" '(:ignore t :which-key "Help") "hp" '(describe-package :which-key "Package") "hv" '(describe-variable :which-key "Variable") "hf" '(describe-function :which-key "Function")) #+end_src * Footnotes [fn:1] https://github.com/justbur/emacs-which-key/ [fn:2] https://github.com/hlissner/doom-emacs/ [fn:3] https://spacemacs.org [fn:4] https://github.com/noctuid/general.el [fn:5] https://github.com/abo-abo/hydra