Emacs Reference
Kip Landergren
(Updated: )
My cheat sheet for emacs covering macOS installation, common keyboard shortcuts, and usage of dired, web-mode, and magit.
Contents
- Installation
- Configuration
- General
- Documentation Lookup / Getting Help
-
Common Operations
- n Column Layout
- Frame Management
- Figuring Out What Went Wrong
- ansi-term
- Reload init.el and apply changes to open buffers
- Remove Carriage Returns (^M) / Set file-coding-system
- edit file as root
- Record Keyboard Macro / Run Keyboard Macro
- Byte Recompile / Rebuild Packages for Emacs 28.4
- Scroll / Advance by Half a Page
- Internal Packages
- External Packages
- Custom Behavior
- Emacs Lisp (elisp)
- Frequently Asked Questions (FAQs)
- Emacs Terminology
- Resources
Installation
For macOS, using d12frosted/homebrew-emacs-plus:
$ brew tap d12frosted/emacs-plus
$ brew install emacs-plus@30 --with-native-comp
And follow the instructions after install to create an alias.
Previously, I have downloaded the appropriate build from Emacs For Mac OS X: Releases, Pretests & Nightlies. Builds are also available from jimeh/emacs-builds.
Configuration
Organization Within use-package
Declarations
For a major mode major
and minor mode minor
:
(use-package minor ...)
should contain:- configuration for its behavior in all modes
(use-package major ...)
should contain:- configuration for
major
’s behavior - configuration for
minor
’s behavior inmajor
- configuration for
Think carefully before using :hook
to add functions to other modes / packages.
Especially do not fall into the trap of:
(use-package bar
:defer t)
(use-package foo
;; adds `bar-mode` to `foo-mode-hook`
:hook (foo-mode . bar-mode))
As :hook
will, as I understand it, ensure an autoload is set up for bar-mode
thinking it is provided by foo
.
The correct use of :hook
, and valid alternative, but not organizationally aligned with how I think, is:
(use-package bar
;; adds `bar-mode` to `foo-mode-hook`, but
;; is within the `bar` declaration, which
;; for me is confusing
:hook foo-mode)
(use-package foo
:defer t)
Instead, my preference is:
- if not autoloaded, declare the function within
:commands
- use
add-hook
within the other package’s:config
declaration (or wherever appropriate)- additionally, using
add-hook
also allows you to control whether to modify the hook’s buffer-local or global value
- additionally, using
An example preferred configuration:
(use-package bar
;; only necessary if not autoloaded
:commands bar-mode)
(use-package foo
:defer t
:config
(add-hook ‘foo-mode-hook #'bar-mode))
EmacsLisp
- turn on / off modes with explicit
(foo-mode +1)
or(foo-mode -1)
- wrap any
:init
or:config
in(progn ...)
to allow easier invocation - prefer named functions over lambdas in hooks; this allows for easier debugging and reevaluation when its contents change
Globally Enabled Minor Modes
Prefer:
(use-package minor
:demand t
:config
(progn
(minor-mode +1)))
over:
(use-package minor
:init
(minor-mode))
Because 1) I can understand this code without knowing how autoload
works and 2) the former reads more how I think:
:demand
to explicitly load the package:config
to invoke it once loading is completed
Vs. the latter:
:init
to execute code before the package is loaded- hope that
autoload
onminor-mode
is configured correctly - invoke
minor-mode
, forcing an immediate load (possibly of the entire package?)
I do not yet know Emacs Lisp well enough to determine how autoload
affects package loading. Possibly the entire package is loaded? or just the autoloaded function implementation?
For example, radian-software/apheleia’s User guide indicates that:
The autoloading has been configured so that this will not cause Apheleia to be loaded until you save a file.
Which is contrary to my understanding that the entire package would be loaded once an autoloaded function is invoked. Therefore, for now, I am willing to trade the performance hit of :demand
for the understanding of configuration behavior.
General
Note: this document’s key chords are represented in emacs’ short-form style where a modifier key starts and a normal key follows. When a normal key is capitalized it implies using ⇧ Shift.
Modifier key / abbreviations legend:
C- | ⌃ Control + |
M- | ⌥ Option + |
s- | ⌘ Command + |
S- | ⇧ Shift + |
DOWN | ↓ |
UP | ↑ |
LEFT | ← |
RIGHT | → |
DEL | ⌫ Backspace |
ESC | ⎋ Esc |
TAB | ↹ Tab |
Default Prefix Keys
C-c |
C-h |
C-x |
C-x RET |
C-x @ |
C-x a |
C-x n |
C-x r |
C-x t |
C-x v |
C-x 4 |
C-x 5 |
C-x 6 |
ESC |
M-g |
Commands
C-f | forward one character |
C-b | backward one character |
M-f | forward one word |
M-b | backward one word |
M-e | forward one sentence |
M-a | backward one sentence |
C-x ] | forward-page |
C-x [ | backward-page |
C-e | move to end of line |
C-a | move to beginning of line |
M-m | back-to-indentation |
C-_ | undo |
C-d | delete one character |
M-d | delete one word |
C-x o | other-window |
C-x ^ | enlarge-window (make taller) |
C-x { | shrink-window-horizontally (make narrower) |
C-x } | enlarge-window-horizontally (make wider) |
C-x 0 | delete-window |
C-x 1 | delete-other-windows |
C-x + | balance-windows (distribute width and height to fit) |
C-l | scroll window so that current line is at middle, top, or bottom |
M-r | position cursor according to recenter-positions |
C-k | kill-line from point to end of line |
C-S-DEL | kill-whole-line |
C-y | yank (aka paste) |
M-y | yank-pop to select different killed text from kill ring |
M-g g | goto line |
C-c C-w | toggle whitespace (web-mode only! web-mode-whitespaces-show ) |
s-=, and then follow prompts | adjust text scale (zoom in / zoom out / zoom text / increase font size) |
M-; | comment / uncomment |
M-x load-file | load file (use to reload configuration) |
C-x C-e | evaluate expression |
M-| | execute shell command |
C-g | quit; toggle undo / redo |
C-h l | display last lossage-size characters typed ( view-lossage ) |
C-n | move down one screen line (next-line ) |
C-p | move up one screen line (previous-line ) |
C-v | scroll forward; page down |
M-v | scroll backward; page up |
C-SPC | set mark and activate region ( set-mark-command ) |
C-u C-SPC | move to previous mark (jump back to previous position) |
C-x C-x | exchange-point-and-mark |
M-= | count-words-region |
C-q C-j | newline (useful in minibuffer) |
M-x rename-buffer | rename buffer |
M-x rename-uniquely | rename buffer uniquely (appends digit) |
s-+ | zoom in / increase font size |
s-- | zoom out / increase font size |
C-x C-v | find alternate file |
C-x x t | toggle-truncate-lines ; toggle line wrap / disable line wrap |
C-u 1 M-x FUNCTION | add a prefix argument to FUNCTION |
C-q CHARACTER | quote CHARACTER |
C-o | insert a blank line after the cursor (open-line ) |
C-x C-o | delete all but one of many consecutive blank lines (delete-blank-lines ) |
C-x n n | narrow-to-region |
C-x n w | widen |
s-u | revert-buffer |
C-x z | repeat |
Documentation Lookup / Getting Help
Commands
Tip:
- type C-h after any prefix key to view what other keys may be completed
C-h k | describe-key ; displays documentation for the function invoked by the key presses (defaults to current buffer) |
C-h f | describe-function ; displays documentation for the passed function |
C-h v | describe-variable ; displays documentation for the passed variable |
C-h e | view-echo-area-messages ; displays the *Messages* buffer |
C-h a | apropos-command PATTERN ; shows commands that match PATTERN |
C-h i | info ; enter Info, the documentation browser |
C-h r | info-emacs-manual ; displays the Emacs manual in Info |
C-h R | (info-display-manual MANUAL) ; displays an Info buffer displaying MANUAL |
C-h m | describe-mode ; displays documentation of current major and minor modes |
C-h b | describe-bindings ; displays a buffer showing a list of all defined keys, and their definitions |
C-h t | help-with-tutorial |
C-h C-f | view-emacs-FAQ |
C-h n | view-emacs-news |
C-h w COMMAND | where-is ; show which keys run COMMAND |
C-h o | describe-symbol ; displays documentation for the passed symbol |
C-h P | describe-package ; displays documentation for the passed package |
C-h . | display-local-help |
M-x man | runs the man program, prompting for a topic to search for |
M-x describe-keymap | describes the key bindings in KEYMAP |
Help Mode
SPC | scroll down; navigate to next node if at bottom (regardless of level) |
DEL | scroll up; navigate to previous node if at top (regardless of level) |
PageDown | scroll down |
PageUp | scroll up |
TAB | move cursor to next cross reference or menu item |
Info
General
q | quit |
? | show Info Help |
h | invoke the Info tutorial |
Navigating Node Trees
n | next node (at level) |
p | previous node (at level) |
] | next node (regardless of level) |
[ | previous node (regardless of level) |
u | up |
t | top |
m | pick menu item |
l | last node in history (i.e. browser back button) |
r | revisit node in history (i.e. browser forward button) |
L | view history |
d | directory |
f | follow a cross reference |
TAB | move cursor to next cross reference or menu item |
1...9 | navigate to the ith menu item |
g | go to node by name |
s | search |
i | pick index item |
I | search virtual index item |
M-n | create a new independent Info buffer |
C-u m or C-u g | create a new independent Info buffer |
Scrolling Nodes
SPC | scroll down; navigate to next node if at bottom (regardless of level) |
DEL | scroll up; navigate to previous node if at top (regardless of level) |
PageDown | scroll down |
PageUp | scroll up |
e | scroll to end |
b | scroll to beginning |
Frequently Asked Questions (FAQ)
Why are some asterisks in menu items colored differently than their peers?
These are the 3rd, 6th, and 9th items of a menu list and allow for visual distinction for easy access via their corresponding numeric keys.
From 2.4 ‘1’–‘9’ choose a menu subtopic by its number of the Info manual:
If your display supports multiple fonts, colors or underlining, and you are using Emacs’s Info mode to read Info files, the third, sixth and ninth menu items have a ‘*’ that stands out, either in color or in some other attribute, such as underline; this makes it easy to see at a glance which number to use for an item.
Common Operations
n Column Layout
C-x 3 | split vertically (repeat n - 1 times) |
C-x + | balance-windows (distribute width and height to fit) |
Frame Management
On Mac OS, a new frame will be created using native windowing.
C-x 5 2 | create new frame |
C-x 5 0 | delete selected frame |
Figuring Out What Went Wrong
Sometimes mistyped key combinations result in unexpected behavior. To help figure out what went wrong, consider:
- C-h l, or
view-lossage
, which shows the last 300 characters typed list-command-history
, which shows every command involving the minibuffer- an add-on like
command-log-mode
ansi-term
ansi-term
runs in character mode
by default, making the buffer read-only. Switching to line mode allows copy and pasting to work more naturally.
C-c C-j | enter line mode |
C-c C-k | enter character mode |
C-x x r | rename-buffer |
Reload init.el and apply changes to open buffers
make modifications to init.el | |
M-x load-file | reload file |
M-x ibuffer | open ibuffer |
/ f | (optional) filter buffers by filename regexp |
m with cursor on [ Default ] | (optional) mark all filtered buffers |
V | revert all buffers (ensure saved!) |
Remove Carriage Returns (^M) / Set file-coding-system
open buffer | |
C-x-RET-f | set-buffer-file-coding-system |
select utf-8-unix or other appropriate value | |
save buffer |
This emacs.stackexchange.com answer explaining line endings is very helpful.
edit file as root
Prepend /sudo::
before a path, like when finding a file.
Record Keyboard Macro / Run Keyboard Macro
C-x ( | start recording |
perform the keystrokes / operations | |
C-x ) | end recording |
M-0 C-x e | repeat macro until an error |
C-x C-k n | name the macro / save the macro |
C-u 3 M-x NAME | repeatedly execute macro NAME 3 times |
open init.el and run: M-x insert-kbd-macro | save the macro for the future |
C-x C-k e | edit macro kbd-edit-macro |
Notes:
- macros are not scoped to a specific buffer—they perform keystrokes just as you would
- error “terminated by a command ringing the bell” likely means a command went wrong during the running of the macro
Byte Recompile / Rebuild Packages for Emacs 28.4
find . -name "*.elc" -type f -delete |
delete all compiled elisp files |
M-: | eval |
(byte-recompile-directory package-user-dir 0 'force) |
byte recompile all packages |
Scroll / Advance by Half a Page
M-r (repeat as needed) | position point cycling through recenter-positions |
C-l (repeat as needed) | scroll window |
Internal Packages
autorevert.el
auto-revert-mode |
function | Toggle reverting buffer when the file changes |
auto-revert-verbose |
variable | controls messages when a buffer is reverted |
Frequently Asked Questions (FAQs)
How do I get emacs to follow a file? How do I get emacs to tail a file?
Toggle auto-revert-mode.
dired
Summary
dired
is a mode for editing directory listings. It takes the output of the system’s GNU ls
command (or, if not available, emulation through ls-lisp.el) and presents it in a read-only buffer for interaction. Customization is available through hooks listed in its *Help* buffer.
Commands
C-x d | enter dired buffer |
h | help |
? | summary |
a | visit selection, killing the dired buffer; directories are visited in a new dired buffer |
f | visit selection, keeping the dired buffer; directories are visited in a new dired buffer |
g | read all currently expanded directories again; refresh |
m | mark |
u | unmark |
U | unmark all |
Q | dired-do-find-regexp-and-replace |
C | copy |
R | rename |
d | mark for deletion |
D | delete |
S | symlink |
M | dired-do-chmod ; accepts input like +x or 644; make executable |
% m | dired-mark-files-regexp ; mark by pattern; filter |
( | dired-hide-details-mode ; a minor mode which is toggled on invocation |
Common Operations
Bulk Edit Directoy
C-x d | dired (enter dired buffer) |
C-x C-q | dired-toggle-read-only (enter editing mode) |
perform edits | |
C-c C-c | apply changes |
C-c ESC | or cancel |
Find and Replace Text
C-x d | enter dired buffer |
m | mark files to search |
Q | run find and replace on marked files |
entire regexp and replacement | |
? | choose whether to replace / exit / do something else |
Resources
- GNU Emacs Manual, Dired (single page)
- Dired Reference Card (PDF)
eglot (eglot.el)
Variables
eglot-server-programs |
association list of (MAJOR-MODE . CONTACT) where CONTACT specifies how to connect to a language server |
eglot-autoshutdown |
when non-nil, will automatically shut down |
eglot-workspace-configuration |
Hooks
eglot-connect-hook |
run after eglot connects to a language server for the first time |
eglot-managed-mode-hook |
Functions
eglot-ensure |
|
eglot-shutdown |
|
eglot-rename |
|
eglot-format |
|
eglot-code-actions |
|
eglot-code-action-organize-imports |
|
eglot-code-action-quickfix |
|
eglot-code-action-extract |
|
eglot-code-action-inline |
|
eglot-code-action-rewrite |
|
eglot-inlay-hints-mode |
|
eglot-show-workspace-configuration |
|
eglot-signal-didChangeConfiguration |
Common Operations
Iterating on LSP Workspace Configuration
- edit .dir-locals.el per 5.1 Project-specific configuration
- M-x eglot-show-workspace-configuration
- not what you wanted? go back to step 1. otherwise continue.
- M-x eglot-signal-didChangeConfiguration to notify the language server of the new configuration
Getting completions.completeFuncCalls=true to Work With typescript-language-server
Create a .dir-locals.el at the root of your project:
((tsx-ts-mode
. ((eglot-workspace-configuration
. (:completions
(:completeFunctionCalls t))))))
It seems like typescript-language-server appears to not want completions.completeFuncCalls to be scoped to typescript-language-server. I do not know if this is expected behavior or a bug.
Getting usePlaceHolders to Work With gopls in go-ts-mode
Create a .dir-locals.el at the root of your project:
;; intentionally use `go-mode` rather than `go-ts-mode` because otherwise
;; eglot fails to find the workspace configuration
((go-mode
. ((eglot-workspace-configuration
. (:gopls (:usePlaceholders t))))))
files.el
C-x C-v | find-alternate-file |
Frequently Asked Questions (FAQs)
How do I reload a buffer/file to pick up changes I made in my init.el file?
Use find-alternate-file
and specify the same filename.
Flymake
flymake-show-buffer-diagnostics |
|
flymake-show-project-diagnostics |
Flyspell (flyspell.el)
C-, | flyspell-goto-next-error |
C-c $ | flyspell-correct-word-before-point |
ibuffer
Mode for listing, sorting, filtering, and managing open buffers:
M-x ibuffer | enter ibuffer |
? | display help |
m | mark buffer at point |
u | unmark buffer at point |
V | revert all marked buffers |
U | unmark all marked buffers |
/ f | filter buffers by filename regexp |
/ / | remove all filtering currently in effect (remove all filters) |
ido
Frequently Asked Questions (FAQs)
How do I use ido to open multiple files at once?
I have not found a way to do so using just ido
. Here is what I have found to work, using helm
and helm-projectile
:
- M-x helm-projectile
- typed some-string-to-match-on
- selected all via M-a
- opened via ↵ Enter
Ispell (ispell.el)
ispell-buffer ; spell check the buffer |
package.el
For use with MELPA or others.
Commands
M-x list-packages | list packages |
M-x package-refresh-contents | refresh contents |
project.el
Commands
M-x project-forget-project | remove directory PROJECT-ROOT from the project list |
Rectangles
C-x SPC | rectangle-mark-mode |
C-x r k | kill-rectangle |
C-x r M-w | copy-rectangle-as-kill |
C-x r d | delete-rectangle |
C-x r y | yank-rectangle |
C-x r o | open-rectangle (moves contents to the right) |
C-x r c | clear-rectangle |
C-x C-x | rectangle-exchange-point-and-mark |
regexes
For use with replace-regexp
.
Replace blank lines:
^[[:space:]]*^J
Themes
Frequently Asked Questions (FAQs)
How do I tell what the current theme is?
C-h o | describe-symbol |
custom-enabled-themes RET | the variable custom-enabled-themes |
treesit.el
treesit-install-language-grammar |
build and install treesit grammar for LANG, based on values in treesit-language-source-alist |
treesit-language-source-alist |
configuration for downloading and installing tree-sitter language grammars |
use-package
Gotchas
:mode
is forauto-mode-alist
, which is for major modes; minor mode configuration should be handled elsewhere
window.el
(setq display-buffer-alist '(
("\\*Help\\*"
(display-buffer-reuse-window
display-buffer-in-side-window)
(side . right)
(slot . -1)
(window-parameters . ((no-other-window . t)
(no-delete-other-windows . t))))
("\\*eldoc.*\\*"
(display-buffer-reuse-window
display-buffer-in-side-window)
(side . right)
(slot . 1)
(window-height . .5))
("\\*info\\*"
(display-buffer-reuse-window
display-buffer-in-side-window)
(side . right)
(window-height . .5)
(window-width . 80))
((derived-mode . magit-diff-mode)
(display-buffer-reuse-window
display-buffer-in-side-window)
(side . right)
(slot . 1))
((derived-mode . magit-mode)
(display-buffer-reuse-window
display-buffer-in-side-window)
(side . right))
))
External Packages
apheleia
Useful Variables
apheleia-inhibit-functions |
|
apheleia-formatters |
Gotchas
- apheleia checks whether
indent-tabs-mode
is enabled to determine whether tabs or spaces should be used
command-log-mode
command-log-mode is an add-on that makes it easy to show command and event history.
Commands
C-c o | toggle the log window |
geiser-guile
C-c C-z | start REPL |
M-x geiser-restart-repl | restart REPL |
,q | quit REPL |
C-x C-e | geiser-eval-last-sexp |
C-u C-x C-e | evaluate last sexp and insert result at point |
C-M-x | geiser-eval-definition |
C-c M-e | geiser-eval-definition-and-go |
C-c C-r | geiser-eval-region |
C-c M-r | geiser-eval-region-and-go |
C-c C-b | geiser-eval-buffer |
C-c M-b | geiser-eval-buffer-and-go |
Helpful links:
helm
Helpful links
- Recursive grep in directory with helm and/or projectile?
- helm GitHub repo
- helm-projectile GitHub repo
- Exploring large projects with Projectile and Helm Projectile
js-mode
M-x js-jsx-enable | enable JSX support |
More JSX info in this StackExchange answer.
lsp-mode
LSP Mode - LSP support for Emacs
Commands
s-l r r | Rename the symbol (and all references to it). |
s-l g g | Find definitions of the symbol under point. Jump to definition. |
s-l g r | Find references of the symbol under point. |
s-l r o | Perform the source.organizeImports code action, if available. |
s-l w r | lsp-workspace-restart - restart the workspace WORKSPACE and the language server associated with it |
M-x lsp-describe-session | Describe session; shows project roots |
s-l F r | lsp-workspace-folders-remove - remove folders from workspace |
M-x lsp-workspace-folders-add | Add folders to workspace |
Troubleshooting
lsp-mode not reading tsconfig.json
- check if M-x lsp-describe-session makes sense
- remove folders via M-x lsp-workspace-folders-remove
- close all project files
- reopen file and input I to interactively choose project root
gopls errors
Try upgrading to the latest gopls:
go install golang.org/x/tools/gopls@latest
Configuration
GitHub code search results for Go configuration
magit (magit.el)
Official magit documentation
Commands
General
C-x g | open magit-popup |
C-c M-g | magit-file-dispatch ; giving access to blame |
M-x magit-init | Initialize a new repository |
C-u C-x g | Choose repository |
Within magit-popup
b | branch ( magit-branch ) |
f | fetch ( magit-fetch ) |
m | merge ( magit-merge ) |
F | pull ( magit-pull ) |
P | push ( magit-push ) |
o | submodule ( magit-submodule) |
y | list branches ( magit-show-refs ) |
TAB | magit-section-toggle |
S-TAB | magit-section-cycle-global |
M-TAB | magit-section-cycle-diffs |
Common Operations
Add Remote Origin
C-x g | open magit-popup |
M | open magit-remote-popup |
a | select ‘add’ |
origin | add name |
git@example.com:path/to/repo.git | add repository address |
Cloning a Repository
C-x g | open magit-popup |
C | invoke magit-clone |
Commit Message Editing
C-c C-c | Finish editing session and create commit |
C-c C-k | Cancel editing session and cancel commit |
Tagging
t | run magit-tag |
t r | create a new release tag |
P t | push all tags |
Cloning a Repository at Tag
clone the repository | |
open a file | |
C-x g | open magit-popup |
b b | use magit-checkout |
enter tag name |
Diffing Between Two Commits
l l | get the sha values you wish to diff (e.g. through inspecting the log) |
d | open magit-diff |
specify options, like limiting to specific file | |
r | specify range (e.g. HEAD..8637c28) |
Restoring file(s) from a commit
Note: I do not yet know how to restore an entire directory at once—workaround is just to restore each file one by one.
gather the SHA1 or ref you wish to restore from | |
X | open magit-reset |
f | select a file |
enter commit SHA1 or tag, followed by filepath |
Check Out a Specific Tag / Check Out a Specific Version
C-x g | open magit-popup |
b b | magit-checkout |
enter tag name |
Frequently Asked Questions (FAQs)
What is the difference between upstream and pushRemote?
Assuming:
- a local branch topic tracking origin/topic
- topic was branched from origin/main
- topic is planned to be merged into origin/main when work is complete
we use the following terminology:
- upstream is where topic will eventually end up: origin/main
- pushRemote is where in-progress work on topic should go: origin/topic
This is a semantic distinction that helps organize development: if upstream and pushRemote are always the same there is no need to set both. My personal preference is to always configure pushRemote because the keybindings feel more natural.
Read The Two Remotes from the official documentation.
What is a release tag?
I do not exactly know, but reading the tagging docs indicates that it is a normal tag that magit runs through magit-release-tag-regexp to ensure a consistent numbering scheme.
markdown-mode
Commands
C-c S-UP | markdown-table-delete-row |
C-c S-DOWN | markdown-table-insert-row (at point, moving current row “down”) |
C-c S-LEFT | markdown-table-delete-column |
C-c S-RIGHT | markdown-table-insert-column |
C-c C-c ^ | markdown-table-sort-lines (based on column at point) |
C-c C-u | markdown-outline-up |
C-c C-n | markdown-outline-next |
C-c C-p | markdown-outline-previous |
C-c C-b | markdown-outline-previous-same-level |
C-c C-f | markdown-outline-next-same-level |
markdown-table-move-column-right |
|
markdown-table-move-column-left |
Official markdown-mode
Documentation
multiple-cursors.el
M-x mc/mark-all-in-region | prompt for a string to match in region |
Org
Resources
- Official site
- org-mode codebase
- org-mode mailing list
- Questions tagged with
org-mode
on Emacs Stack Exchange
prettier-js
Notes
- displays as Prettier despite being named prettier-js
- is a minor-mode
Commands
M-x prettier-js | run prettier on current file |
Resources
projectile (projectile.el)
Commands
s-p p | open project |
s-p q | switch project |
s-f | find file in project |
M-x projectile-discover-projects-in-directory | discover projects in directory |
M-x projectile-discover-projects-in-search-path | discover projects in search path (path specified via config) |
M-x projectile-cleanup-known-projects | remove known projects that don’t exist anymore |
M-x projectile-clear-known-projects | clear known projects |
M-x projectile-invalidate-cache | clear cache |
M-x projectile-kill-buffers | close all buffers associated with a project |
Problems and Solutions
problem | solution |
---|---|
deleted / removed file still being found | M-x projectile-invalidate-cache |
grepped-for string not being found | ensure that all files are tracked by git |
deleted project still showing up in project switcher | M-x projectile-cleanup-known-projects |
old / irrelevant / no longer needed project still showing up in the project switcher | option 1: (completely removes all projects and starts again from scratch) M-x projectile-clear-known-projects |
option 2: M-x projectile-remove-known-project | |
option 3: (if you are currently visiting a buffer within the project) M-x projectile-remove-current-project-from-known-projects |
Resources
scheme-mode
C-x C-e | evaluate expression |
C-c C-l | load file |
sqlformat
Official purcell/sqlformat GitHub repo.
Commands
M-x sqlformat-on-save-mode | disable / enable automatic format on save |
vertico
Frequently Asked Questions (FAQs)
How Do I Override Completion? How do I Insert Literal Input?
M-RET
web-mode
Commands
C-c C-e i | insert HTML element |
C-c C-s | insert snippet |
C-c C-f | fold or unfold |
M-; | insert HTML comment |
Resources
wgrep
Usage
enter *grep* buffer | |
C-c C-p | wgrep-change-to-wgrep-mode |
make your changes | |
C-c C-e | wgrep-finish-edit ; apply and save your changes |
C-c C-k | wgrep-abort-changes ; discard all changes and exit |
C-x C-q | wgrep-exit |
Resources
- mhayashi1120/Emacs-wgrep GitHub repository
yasnippet
Commands
M-x yas-new-snippet | create new snippet |
M-x yas-recompile-all | recompile all snippets |
M-x yas-reload-all | reload all snippets |
Selected Authoring Functions
yas-choose-value (&rest possibilities) |
allows you to choose from a predefined list |
yas-auto-next |
automatically moves to the next input after entry |
Selected Interactive Functions
yas-reload-all |
reloads all snippets and clears any incorrectly created snippets |
Examples
A snippet file named now
that returns a double-quoted and formatted time:
# -*- mode: snippet -*-
# name: now
# key: now
# --
"`(format-time-string "%F @ %R %z")`"
Frequently Asked Questions (FAQs)
I restarted emacs and snippets no longer reflect the changes I made last session but are present in the snippet file—what gives?
It is possible yasnippet is reading a stale compiled snippets file. These files exist at the top level of a snippet template directory.
Example:
./snippets/markdown-mode/.yas-compiled-snippets.el
./snippets/conf-mode/.yas-compiled-snippets.el
./snippets/yaml-mode/.yas-compiled-snippets.el
To fix:
M-x yas-recompile-all | |
M-x yas-reload-all |
Resources
xref
Commands
M-. | xref-find-definitions ; prefix argument will prompt for identifier name |
C-M-. | xref-find-apropos |
M-, | xref-go-back |
C-M-, | xref-go-forward |
M-? | xref-find-references |
C-M-i | complete at point |
Custom Behavior
Specific to my init.el:
escape-html |
HTML escapes the text in region |
unescape-html |
HTML unescapes the text in region |
M-p | move line of text up / move text up / move line up |
M-n | move line of text down / move text down / move line down |
C-c t | toggle typopunct-mode (for curly quotes and apostrophes) |
Emacs Lisp (elisp)
elisp Formatting
Times and Dates
Format strings, for use with format-time-string
:
%F |
the ISO 8601 date format: 2006-01-02 |
%R |
synonym for %H:%M (e.g. 15:04) |
Examples:
(format-time-string "%F @ %R %z" (date-to-time "02 Jan 06 15:04 MST") "MST")
"2006-01-02 @ 15:04 -0700"
(format-time-string "%Y-W%W %a %b %d" (date-to-time "02 Jan 06 15:04 MST") "MST")
"2006-W01 Mon Jan 02"
- GNU Emacs Manual 40.8 Parsing and Formatting Times
Frequently Asked Questions (FAQs)
How do I add emacs to Automation permissions under Privacy & Security?
Use osascript
from within emacs to request the permission:
- M-x shell-command
- osascript -e 'tell application "System Events" to tell appearance preferences to return dark mode'
- allow the permission
- restart emacs
What is the ^L character?
From the GNU Emacs Manual on Pages:
Within some text files, text is divided into “pages” delimited by the “formfeed character” (ASCII code 12, also denoted as ‘control-L’), which is displayed in Emacs as the escape sequence ‘^L’ (see How Text Is Displayed). Traditionally, when such text files are printed to hardcopy, each formfeed character forces a page break. Most Emacs commands treat it just like any other character, so you can insert it with ‘C-q C-l’, delete it with
<DEL>
, etc. In addition, Emacs provides commands to move over pages and operate on them.
Emacs Terminology
- abbrev
- a word which expands to a specified expansion if you insert it
- binding
- mapping a key to a command
- buffer
- the text or other graphics you are editing or viewing
- buffer, current buffer
- buffer displayed in the selected window
- buffer, indirect buffer
- a buffer that shares the contents of another base buffer
- control characters
- definition todo. such as RET, TAB, DEL, ESC, F1, Home, and LEFT
- cursor
- the blinking block over an area of a single character’s dimensions
- defun
- a major definition at the top level in the buffer, such as a function
- delete / deleting / deletion
- erasing text and not saving it in the kill ring
- dispatch menu
- ?? menu in the mini buffer that allows further actions ??
- echo area
- (area at the bottom of the frame) where informative messages are displayed and where you enter information when Emacs asks for it
- echoing
- displaying the characters of a multi-character command as you type
- face
- how text is displayed
- follow-mode
- minor mode that makes two windows, both sharing the same buffer, scroll as a single tall virtual window
- font lock mode
- a minor mode which assigns faces to the text in the buffer; the buffer’s major mode tells Font Lock mode which text to fontify (e.g. a programming language mode telling which text are comments or function names).
- frame
- a graphical window or terminal screen occupied by Emacs
-
refers to the macOS window that emacs is running in
- graphic character
- a character that can be typed by pressing the associated key
- hook
- a Lisp variable which holds a list of functions, to be called on some well-defined occasion
- input events
- keyboard and mouse presses
- key (key sequence; key chord)
- a sequence of input events that is meaningful as a unit
- key, complete key
- a key sequence that invokes a command
- key, prefix key
- a key sequence that does not itself invoke a command
- keymap
- the bindings between keys and commands
- kill / killing
- erasing text and copying it into the kill ring; aka cutting
- library
- a collection of Emacs Lisp code in a single file; sometimes used interchangeably with package
- mark
- a saved location in the buffer (for the user’s convenience); can be thought of as a second, stationary cursor
- minibuffer
- special-purpose buffer where emacs reads compilicated arguments (file names, buffer names, command names, lisp expressions, etc)
- mode line
- the last line of the window ... (that) displays various information about what is going on in the buffer, such as whether there are unsaved changes, the editing modes that are in use, the current line number, and so forth
- modifier keys
- keys like Control and Meta that change the bahvior of other keys
- narrowing
- editing a buffer is restricted to only a portion of its text; focusing in on some portion of the buffer, making the rest temporarily inaccessible
- numeric argument / prefix argument
- typed before a command
- package
- a collection containing at least one Emacs Lisp library, zero or more Info manuals, and possibly other components; sometimes used interchangeably with library
- package archive
- collections of Emacs Lisp packages
- point
- the cursor in the selected window (which) shows the location where most editing commands take effect
- point
- the location of the cursor
- regexp
- regular expression
- region
- the text between point and the mark
- register
- compartments where you can save text, rectangles, positions, and other things for later use
- ring, kill ring
- cyclical area that stores killed text; visualizable as blocks of text arranged into a ring, accessible in cyclic order
- scrollbar
- UI element within the window on graphical displays that allows scrolling of the buffer
- tag
- an identifier within a program
- tool bar
- a row of icons (below the menu bar) that perform editing commands when you click on them
- variable
- a Lisp symbol which has a value
- visit
- read a file and prepare a buffer containing a copy of the file’s contents
- widening
- canceling narrowing, making the entire buffer once again accessible
- window
- the main area of the frame, below the tool bar (if one exists) and above the echo area
- window, side window
- special windows that are placed on the edges of the frame’s root window
- xref
- the unified interface for dealing with program identifiers (also known as tags)
- yank / yanking
- bringing text from the kill ring back into the buffer; aka pasting; reinserting text previously killed