9.7 KiB
Editor
Configuration and imrpovements to the editor experience within Emacs. Vim1 user? This module extends the keybindings by implementing Evil2. Doom3, Spacemacs4? The all powerful leader key is also implemented right here!
Keys
Offer ESC
as an alternative to quit (most) prompts, instead of the default C-g
.
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
Completions
Emacs has a lot of keybindings, sometimes it's useful to just start mashing keys and see what happens. This behaviour exists in a third-party package called which-key5. It displays the current incomplete keybinding input in a mini-buffer, showing available completion options with their corresponding keybindings.
(use-package which-key :diminish which-key-mode :custom (which-key-idle-delay dotfiles/idle) :config (which-key-mode))
Turn Emacs into Vim
Emacs has some strange default keybindings, they're not like any other editor you've likely ever used. To overcome this nearly show-stopping hurdle, we turn Emacs into Vim1 with Evil Mode - The Extensible VI Layer for Emacs2.
-
Enable visual line motions outside of
visual-line-mode
buffers
(use-package evil :custom (evil-want-integration t) ;; Required for `evil-collection'. (evil-want-keybinding nil) ;; Same as above :config (evil-global-set-key 'motion "j" 'evil-next-visual-line) (evil-global-set-key 'motion "k" 'evil-previous-visual-line) (evil-mode +1))
While covering substantial ground towards our goal, the default keybindings implemented in Evil2 alone are lacking compared to what you would expect from Vim1. There's, of course, a communicated curated package evil-collection6 that does a much better job implementing the proper keybindings.
(use-package evil-collection :after evil :config (evil-collection-init))
Surround text
Whether it's on purpose, or more likely, you forgot an opening brace; evil-surround7 surrounds highlighted blocks of text with functions, quotations, and any symbol you can input.
(use-package evil-surround :after evil :config (global-evil-surround-mode 1))
Toggle comments
When you're in deep with errors, or just trying some new code, it's useful to be able to toggle large comment sections in a language agnostic manner. In comes evil-nerd-commentor8, with a custom binding to M-;
. What is M-
? Typically that refers to the Alt
key, called the Meta
key in Emacs.
(use-package evil-nerd-commenter :after evil :bind ("M-;" . evilnc-comment-or-uncomment-lines))
Implementing the leader key
If you're like me and started with Emacs using a framework like Doom3 or Spacemacs4, you probably have a lot of muscle memory for using SPC
as a leader key. This behaviour is actually not difficult to implement, especially when using general.el9.
-
SPC
in most situations as a prefix key -
C-SPC
when using the Desktop module within anX
buffer
(use-package general :after evil :config (general-create-definer dotfiles/leader :states '(normal motion) :keymaps 'override :prefix dotfiles/leader-key :global-prefix dotfiles/leader-key-global))
Transient bindings
Create transient keybindings with a shared prefix through Hydra10. This is also used by a number of third-party packages as a completion system. An implementation example is available in the Font section of the Interface module.
-
Defer loading for performance
(use-package hydra :defer t)
Place runtime tweaks behind SPC t
(dotfiles/leader "t" '(:ignore t :which-key "Tweaks"))
Cherry picked shortcuts
Implement shortcut bindings, cherry picked from Doom3.
-
Close buffers with
SPC c
-
Find files with
SPC , (comma)
(dotfiles/leader "." '(find-file :which-key "Files") "c" '(kill-buffer-and-window :which-key "Close"))
Managing windows
Window management with SPC w
-
Swap with
w
-
Close with
c
-
Move with
h,j,k,l
-
Split with
s - <motion>
(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"))
Quitting Emacs
Quit Emacs with SPC q
-
Save and quit
q
-
Quit without saving
w
-
Exit the Frame (daemon)
f
(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"))
Help
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
-
(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"))
Files
Emacs has some really cool built-in packages, Dired11 is one of them. It's not perfect out of the box though, there's work to do.
Navigating to the current directory
I don't want to have to press RET
twice to navigate to the current directory. Avoid this behaviour with jump
, included in the dired-x
package that ships with Dired11.
-
Open a new dired buffer with
SPC d
.
(require 'dired-x) (dotfiles/leader "d" '(dired-jump :which-key "Dired"))
Reusing the same buffer
By default Dired11 will create a new buffer every time you press RET
over a directory. This leads to unwanted buffers all over the place. Avoid this behaviour with Dired Single12, reusing the same dired buffer.
-
Move up a directory with
h
-
Open a single buffer with
l
(use-package dired-single :config (evil-collection-define-key 'normal 'dired-mode-map "h" 'dired-single-up-directory "l" 'dired-single-buffer))
Shell
Another really incredible piece of kit, shipped with Emacs. Eshell13 is a fully POSIX compliant shell written entirely in Emacs Lisp. While not a traditional terminal emulator, it provides me with all of the functionality I expect and require from one. The infamous lambda prompt implemented with the Eshell Prompt Extras14 package.
(use-package eshell-prompt-extras :custom (eshell-highlight-prompt nil) (eshell-prefer-lisp-functions nil) (eshell-prompt-function 'epe-theme-lambda))
Open an eshell
buffer with SPC e
.
(dotfiles/leader "e" '(eshell :which-key "Shell"))
Magit
Yet another hallmark feature of Emacs: Magit15 with the darling name, the developer stresses it's supposed to be Magic but with Git16. It's a complete Git16 porcelain within Emacs.
(use-package magit :commands magit-status :custom (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1))
Open the status page for the current repository with SPC g
.
(dotfiles/leader "g" '(magit-status :which-key "Magit"))
GitHub integration
Deploying the global config
Git16 reads its global config from $HOME/.gitconfig
, create a link to the custom configuration.
(dotfiles/symlink "~/.emacs.d/config/git" "~/.gitconfig")