Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Andrew Schwartzmeyer’s Emacs configurations

Utilizes jwiegley’s use-package macro to cleanly and quickly require, install via straight.el, and setup various extensions. Tries to get back to the basics.

These configurations work a lot better with at least Emacs 26, although Emacs 25 should be supported, and I tend to build from source so I can apply my patch.

This readme is currently going through a rewrite.

Using Emacs

Much of what I know about using Emacs I learned over a decade, but I highly recommend reading the book Mastering Emacs by Mickey Petersen. Xah Lee’s Practial Emacs Tutorial is also fantastic.

Syntactic movements

See Effective Editing Movement for more.

Characters and words

Moving forward a character is C-f, backward is C-b, and deleting is C-d. I mention this because the next syntactic movement is by word. The keys are symmetric to the character movements, just with meta instead of control: forward is M-f, backward is M-b, and deleting is M-d. You can also mark a word with M-@ (which explains why C-@ is another binding for set-mark-command). My configuration enables subword-mode, indicated by a comma in the mode line, which turns CamelCase into two words instead of one.


Now combine control and meta, and you can move by “s-expression,” or sexp: forward is C-M-f and backward is C-M-b. However, delete is different as it is C-M-k (for “kill”). This is because you can move through nested expressions with up C-M-u and down C-M-d. Marking should be familiar on C-M-SPC (and is also on C-M-@ for symmetry). Honestly, moving by sexp is usually much better than by word.

Lines and sentences

Similar to C-a to move to the beginning of the line, C-e to move to the end, and C-k to kill, sentence movement is M-a, M-e, and M-k. Marking a sentence is M-h. Sentences are more useful than they would seem, as modes are free to define a sentence how they see fit. For instance, in the C and C++ modes, a sentence is defined to be a language statement.

There is also a special command to move “back to indentation” on M-m. This places the point at the first non-whitespace text on the line, which is a nice shortcut.


Movement by function (or defun), is similar to lines and sentences, but with control and meta. Move to the beginning is C-M-a, end is C-M-e, and mark is C-M-h. In some modes, like that for Emacs Lisp, you can also evaluate a defun with C-M-x.


Buffer movement only has a commands: move to the beginning is bound to M-<, move to the end is M->, and mark the whole buffer is C-x h.

That last binding makes sense in the context of kill-buffer on C-x k, save-some-buffers on C-x s, switch-buffer on C-x b, and list-buffers on C-x C-b. See more.


Using C-s to incrementally search within a buffer must become second nature. This command is isearch. Using isearch to move within a buffer is probably the most powerful syntactic movement, as it is precise and easy to do. You can search in reverse with C-r.

After typing C-s or C-r, you can restart your last search by pressing it again, or you can yank successive words from the point onward with C-w. While searching for something, move forward through the matches with C-s and backward with C-r.

You can cancel a search with M-g, which will drop you back to your starting point, or you can finish a search with RET. Finishing a search will push your starting location onto the mark ring and drop you at the current match. You can jump right back with C-u C-SPC, which pops the mark ring.

Going places

Two bindings that are conspicuously missing are M-n and M-p, but in fact these are usually specific to the mode. In a Magit status buffer, for example, they move between sections; in an Occur buffer they move between occurrences; and in a compilation buffer they move between errors. They can be accessed from the original buffer with the prefix M-g, so M-g M-n will take you to the next occurrence without having to switch to the Occur buffer.

That last prefix mentioned, M-g, is actually a binding for the entire goto-map. Going to a specific line is done with M-g M-g, a specific character is M-g c, and a specific column (character on the current line) is M-g TAB.

As Mickey Petersen points out in Effective Editing Movement, a handy use of the universal argument for goto-line is to switch from a source buffer to some other buffer that has a line number corresponding to that source, then C-u M-g M-g will take the number at point and go to that line in the previous buffer. Considering how many tools emit line numbers (like compilers, linters, search tools, etc.), this can be quite useful.


When writing blocks of text, such as documentation or notes, paragraphs become a useful syntactic movement. Moving forward a paragraph is M-{ and backward is M-}. Wrapping a paragraph is done with fill-paragraph on M-q, which can also justify text when given a prefix argument. My configuration includes the package unfill which makes M-q undo itself when repeated.

Cut and paste

Or in Emacs parlance, kill and yank. In addition to the syntactic kill commands, you can also kill a region with C-w. Yanking text is done with C-y. Follow it up with M-y repeatedly to cycle through the kill ring until you have yanked what you want.

Before killing text, you can use C-M-w to append the next kill to the previous kill. This is useful when killing pieces of text throughout the buffer, to be yanked all at once elsewhere.

You can “zap” text with M-z [char]. This is equivalent to vi’s df[char]. It kills from the point to (and including) the next instance of the given character. I actually prefer the semantics of dt[char], which kills to (but excluding) the character. So my configuration remaps zap-to-char to zap-up-to-char.

Prefix arguments

Negative and numeric arguments can be prefixed to other commands in order to perform actions (similar to vi’s composable grammar). That is, 3dd in vi is equivalent to C-3 C-k, and 3k is C-3 C-p. I am not sure if vi has an equivalent to the negative argument: it is used to do things backwards, that is, M-- M-l will downcase the word before the point instead of after, and C-M-- C-M-SPC will mark the previous sexp instead of the next.

As you may have noticed, the negative and numeric arguments are bound to control, meta, and control-meta so that they can be easily combined with any other binding. You can type any number as a numeric argument. For example, C-SPC C-1 C-3 C-n marks the next 13 lines.

In my opinion, the only real difference between the two grammars is that in vi, you have to explicitly change modes with ESC, and with Emacs, you temporarily change modes with modifier key chords (control and alt/meta).

Universal argument

The negative and numeric argument bindings are truly just shortcuts for the “universal” argument C-u, which begins a numeric argument sequence (and remember, numbers can be negative). An example is the combined command M-- M-6 M-d, which kills the last six words, and is equivalent to C-u - 6 M-d.

More interesting is that C-u has a default numeric value of four. So if it is used alone as in C-u C-f it will move forward four characters. While this has some value, it is more useful in the context of alternative modes of operation for interactive functions. I will be honest, I usually use it after reading the documentation of a function, and then promptly forget it. One example I can think of is C-u C-SPC: a single prefix argument to set-mark-command causes it to pop the local mark ring (jump back to last marked spot in the buffer, like C-x C-SPC but not global).

Note that unlike the numeric and negative arguments, the universal argument is only on C-u. That is, M-u and C-M-u are bound to completely different commands.

See ErgoEmacs.

Repeating commands

While numeric arguments can repeat a command N times, you have to specify it before calling the command. Often you realize after calling a command that it needs to be repeated, which you can do with C-x z (bound to repeat). This is equivalent to vi’s . command. After the first invocation, z can be used for more repetitions. It also repeats the arguments used originally.

More complex commands are repeatable with repeat-complex-command, annoyingly bound to C-x M-:. Complex commands are those used in the minibuffer which take interactive input (like query-replace).

See Mastering Emacs.

Keyboard macros

When a more advanced action needs to be repeated, Emacs keyboard macros are awesome! To start recording a macro, use C-x (, to finish recording a macro, use C-x ), and to run the last recorded macro, use C-x e. That last command will also automatically finish recording a macro, and can be repeated with just e.

The rest of the useful kmacro functions are bound to the prefix C-x C-k. If C-x ( is annoying, C-x C-k s is also bound and is a bit more mnemonic (“execute kmacro start”).

When recording a macro, be careful not to quit by accident or with C-g, as this cancels the recording! I usually run into this when trying to cancel an isearch, and then have to start recording again. Instead, use RET to end (not quit) the search, and then use C-u C-SPC to pop the mark back to where you were. It is also a problem when deactivating a marked region. Instead of C-g, use C-SPC C-SPC to set and then deactivate the mark.

If a mistake is made when recording, use C-/ to undo. It will work just fine when applying the macro.

Writing useful macros means using syntactic movements instead of characters, so that the macro works regardless of textual differences. The most useful movements are C-s, C-a, and C-e, but also useful are word and expression commands.

To apply a macro to all lines in a region, use C-x C-k r. To repeatedly apply a macro until an error occurs (like reaching the end of the buffer, or no more search results), use C-0 C-x e.

Macros can be saved by naming them with C-x C-k n and then saved permanently by writing their lisp code with insert-kbd-macro (or just view the last macro with kmacro-view-macro).

See ErgoEmacs.

Mark rings

The mark rings are used for recording positions in buffers. The global mark ring records the latest mark for each buffer, and each buffer’s local mark ring records the marks for that buffer. So the global mark ring essentially records your buffer switching history (with the helpful context of where in the buffer you were), and the local mark ring records your position history in each buffer.

Setting the mark command is done with C-SPC (aptly named set-mark-command). This sets the mark at the point and pushes the last location onto the local mark ring.

Use C-u C-SPC (which internally calls pop-to-mark-command) to pop the local mark after jumping around in a buffer, such as when using C-s. Note that while typing text moves the point (or cursor) forward, it does not move the mark. Instead, this happens with commands that “jump,” or with C-SPC C-SPC to manually set and then deactivate the mark. Think of the mark as a bookmark of the point, but not the point itself.

Use C-x C-SPC (pop-global-mark) to go back after jumping into another buffer, such as when finding a definition with M-., although there is also a mark ring for xref which you can pop with =M-,=.

When set-mark-command-repeat-pop is enabled, the mark can be repeatedly popped by hitting C-SPC after first popping the global or local mark ring.

An obscure but useful command is C-x C-x, which exchanges the point and mark. When a region is marked, C-x C-x moves between the beginning and end of that region. If the region is not yet marked, it will mark the region between the point and previous mark. You can avoid marking the region and instead only move the point with the prefix argument, so C-u C-x C-x. This command is super useful when using the rectangle commands (on C-x r) as the exact region matters.

My configuration turns on transient-mark-mode and enables set-mark-command-repeat-pop.

Deleting whitespace

Delete all horizontal whitespace around the point on the current line with M-\. Use M-- M-\ to only delete the space backwards.

When a single space is desired (often the case after deleting some words), use M-SPC. The negative argument will delete newlines too, and numeric arguments keep N spaces. So M-- M-SPC is really useful to join text below the point separated by whitespace to the point on the same line after a space.

My configuration actually rebinds M-SPC to cycle-spacing, which is an enhanced version of just-one-space. On the first call it operates the same; on the second it deletes all spaces (like M-\); and on the third it restores the original whitespace.

You can delete blank lines (vertical whitespace) with C-x C-o, which is mnemonic since C-o inserts a newline. Use it on a non-blank line to join text below the point separated by whitespace, but with a newline in between instead of on the same line. Use it on a blank line to keep just one line (like M-SPC but for lines). Use it again on a single blank line to delete it.

You can join text at the point to the line above the point with M-^, which calls delete-indentation, so named because it also fixes up the whitespace at the join. The negative argument instead joins to the line below the point, essentially turning it into the commands above. I do not find this command as useful as the others.

Writing comments

Probably one of my most used commands is comment-dwim, or “comment Do What I Mean,” on M-;. Given a region, it comments it (or uncomments it). This is best combined with syntactic mark commands. Otherwise it starts a new comment, and with a prefix, kills a comment. To turn the current line into a comment, use C-x C-;.

Note that the key C-; is not a valid character in a terminal, so it is baffling that it is used as a default binding. Thus when using Emacs in a terminal typing C-x C-; translates to C-x ; which calls comment-set-column, a confusing situation indeed! Instead of finding a new mapping, I just select the line and use M-;.

While writing a multi-line comment, use M-j to insert a newline and comment syntax. This will also indent such as when you are writing to the side of a block of code. Its counterpart C-j inserts a newline and indents (without commenting). I should use these more.

Adjusting case

Words can be UPPERCASED with M-u, lowercased with M-l, and Capitalized with M-u. I find that I run these with the negative argument more often than not so that I can fix the case of a word just written.

My configuration remaps the Do What I Mean versions of the above so that they work on regions too. Otherwise the region versions are C-x C-u and C-x C-l, with capitalize-region conspicuously unbound. There is also an obscure version of the last one called upcase-initials-region, which specifically only alters the initial characters.


I did not use the transpose commands until Mickey explained that they “pull” characters (and words and sexps) to the right. I cannot explain this as well he did, so just go read Mastering Emacs. Transposing a character is C-t (useful after an immediate typo), a word is M-t, a sexp is C-M-t, and a line is C-x C-t.


The only help command you need to know is C-h h, which gets help for the help system. It brings up a buffer describing all the possible other help systems and shortcuts to get there. The other helpful commands are:

  • C-h e to view the messages buffers
  • C-h k to get help for a binding
  • C-h b to list and search bindings
  • C-h w to ask where-is a function bound
  • C-h f to get help for a function
  • C-h v to get help for a variable
  • C-h m to list help for the current modes
  • C-h l to view lossage (history of keystrokes)

That last one is for curious people to figure out what keys they are using too often.

Quoting characters

Sometimes you need to insert a character whose key usually triggers an action. An example is typing a lone open parenthesis or quotation mark when electric modes would otherwise type the whole pair. You can do this by “quoting” the character with C-q, such C-q (.

Another example is typing a newline in a query replacement, where hitting enter would accept the input instead of inserting a newline. However, C-q RET inserts ^M, which is a carriage return, not a newline. You actually want C-q C-j. But why is that?

Similarly, you often need to insert Unicode characters and Emacs has an amazing facility with the prefix C-x 8. For example, the copyright symbol © is C-x 8 C, and the Euro symbol € is C-x 8 * E. Smart quotes can be found on [ / ] for / , and { / } for / , but also see see electric-quote-mode. Use C-x 8 C-h to find the rest.

Emacs syntax explained

The answer goes all the way back to the ASCII table and the notion of Unix line endings. You might be familiar with line endings being “CRLF” on Windows and just “LF” on Linux. The “LF” is “line feed” (or ^J, read as “control J,” just like C-j) and the “CR” is “carriage return” (or ^M). The caret in those notations is for control (as in the key), because the ASCII standard represents these characters as the combination of control followed by a letter. The letter corresponds to the position of the character on the ASCII table. Since line feed is the tenth ASCII character, and “J” is the tenth letter, ^J is its notation. Hence Emacs literally interprets C-j as a line feed. Similarly, C-i is for horizontal tab, C-m is for carriage return, C-[ is for escape, etc. See ErgoEmacs for more.

This explains why setting flyspell-use-meta-tab to nil unbinds C-M-i because it is interpreted as M-TAB. This is because C-i is horizontal tab according to the ASCII standard. I mention this because this default binding is really annoying on Windows where M-TAB (or “alt-tab”) switches windows.

Arranging buffers

Emacs is old, so old that it existed before windowing systems. Because of this, it does not use the now commonplace terminology of “tabs” and “windows.” An operating system window is, to Emacs, a “frame,” and within a frame each portion is a “window” (Mickey Petersen likens it to window panes in a physical frame). These windows display buffers (usually an open file, but also any other set of text like *Messages* or *Help*), and they are similar to tabs in younger editors.

Switch buffers with C-x b, and list them with C-x C-b.

Splitting a window horizontally is bound to C-x 2, and splitting vertically is C-x 3. Closing a window is C-x 0, and closing all other windows is C-x 1 (kind of like “maximize this window”). The other window commands are on the C-x 4 keymap. What is handy is that most of these commands are reflective of the C-x commands, just applied to the “other” window. So while C-x b switches the current window’s buffer, C-x 4 b switches to the other window and then switches buffers (it will split the current frame to open the other window if it needs to). You can find a file with C-x 4 f, and open Dired with C-x 4 d.

I often find myself with windows split horizontally but I want them split vertically. Fixing this with vanilla Emacs is an annoying combination of closing and opening windows. With the transpose-frame.el package, it becomes a simple matter of calling transpose-frame, which I have bound to C-x 4 r. This package provides many other potentially useful functions depending on your windowing needs, so check it out.

Finally, if you need to deal with frames, all the bindings are under C-x 5, with the important ones being close on C-x 5 0, close others on C-x 5 1, and create on C-x 5 2 (these should be familiar now as they are symmetric to the basic frame bindings).

Advanced searching

As mentioned earlier, isearch is incredible incremental searching.

In isearch, switch to regular expression mode with M-s r. You can also initiate a regex search directly with C-M-s and C-M-r, but this introduces us to the isearch prefix binding, M-s.

Other useful bindings in this map are M-s _ which starts a search in symbol mode (use M-s . to start searching for the symbol at point), and M-s w which starts a word search (that is, search for a sequence without regard to the separating characters). If a search is already in progress, these same bindings toggle the search semantics, in addition to many other toggles available under M-s. Check them out the next time you need to narrow or expand your search.

Also handy is that calling query-replace with M-% while searching will use your current search string as the input. This lets you figure out your exact match string and then immediately replace it.


One of the neatest features of Emacs is the command occur, bound to M-s o. Essentially, it is grep within Emacs. Calling it alone prompts for a regular expression, but you can also call it during an isearch. It lists all the occurrences of the search in an overview buffer (in fact, list-matching-lines is an alias for occur). Selecting an occurrence with RET jumps you to it in the original buffer (C-o does the same but leaves the point in the Occur buffer), and typing e switches us to occur-edit-mode.

This last command is awesome. It makes the Occur buffer editable: any changes you make will be made to the original buffer when you finish with C-c C-c. In this way, you can edit matching lines (and additional context lines by customizing list-matching-lines-default-context-lines) in an overview. I find this to be a much friendlier way of making changes than slowly going through a query-replace.

Occur is made even better by the ability to run it across multiple buffers, with the interactive multi-occur, or the filtered multi-occur-in-matching-buffers.

Listing buffers

My configuration remaps C-x C-b to ibuffer, a much improved buffer listing. Frankly, I should use this more than I currently do, but usually I just switch buffers with C-x b. You can group and filter (with /) all your buffers, and once marked (individually with m or all with t), apply operations to them.

Instead of using multi-occur, you can select your buffers in ibuffer and hit O to run Occur across them as a group. You can also start a query replace with Q, and setup a multi-isearch with M-s a C-s. Hit h to see all the other options with ibuffer.

Common unbound commands

  • align
  • align-regexp
  • customize-group
  • desktop-clear
  • delete-matching-lines
  • delete-non-matching-lines
  • eval-buffer
  • eval-region
  • find-lisp-find-dired
  • revert-buffer
  • sort-lines
  • straight-pull-all
  • toggle-debug-on-error
  • toggle-theme
  • visual-line-mode
  • whitespace-cleanup
  • whitespace-mode

Future sections

  • ripgrep / wgrep
  • wgrep
  • compilation
  • eshell
  • rectangle
  • raise and surround


C-0 w runs dired-copy-filename-as-kill with full path

Notable packages

This is not an exhaustive list, just the ones I have found the most useful.

Emacs Lisp programming notes

Interactive Emacs Lisp Mode

Unsurprisingly, Emacs comes with an Emacs Lisp REPL, ielm, or the Interactive Emacs Lisp Mode. Use this when testing lots of Emacs Lisp.

The scratch buffer defaults to Emacs Lisp mode so that it is kind of a REPL. It can be used as such because C-M-x evaluates the current function, C-x C-e evaluates the last sexp, and C-j will evaluate and print the last sexp.

Use M-: to evaluate an expression queried from the minibuffer.

See Mastering Emacs for more.

Common functions

  • add-hook and eval-after-load for conditional execution
  • expand-file-name and f-expand for filename expansion
  • file-name-basename and file-name-nondirectory etc.
  • file-remote-p will return the connection prefix (remote root)
  • message and princ for printing
  • concat and format for strings
  • get-buffer-create for buffers
  • add-to-list and append for lists
  • mapcar with list of results
  • mapconcat for string of results
  • dolist for mapc with implicit bind
  • cadr for last item of pair, as in, (car (cdr foo))
  • cons to append without copying
  • remove to filter items from list
  • getenv, setenv, compilation-environment for env
  • executable-find for binaries
  • nth and elt for indexing a list
  • cond is better than if / else
  • let and let* for local variables
  • symbol-function to find an alias
  • where-is-internal to get bindings
  • save-excursion to restore point
  • replace-regexp-in-string
  • shell-command-to-string
  • thing-at-point to get things at point
  • dash.el modern list library
  • run-with-idle-timer to schedule functions to run when idle
  • list-timers to view (and use ‘c’ to cancel) existing timers

Custom faces

This was particularly annoying to get right, so here is how to set a custom face that varies with the background type.

(use-package ivy
   ((((class color) (background light))
     :background "#fdf6e3" :underline (:color "#859900"))
    (((class color) (background dark))
     :background "#002b36" :underline (:color "#859900")))))

Partially evaluate list elements

The backquote is like a normal quote except it evaluates elements marked with commas. See the manual.

(add-to-list 'somelist `(symbol . ,(expression to be evaluated)))

Capture all regexp matches

Captures all non-terminals in Bison grammar.

  (while (re-search-forward "^\\([a-z_]+\\):" nil t)
    (princ (format "%s " (match-string 1)) (get-buffer-create "matches"))))

Build regexps etc. with elisp

  • rx for building regexp from sexps
  • re-builder for interactively writing regexp
  • find-cmd for building find command from sexps

Building from source

  • Clone git clone -b emacs-27
  • See system-configuration-features for available features
  • See system-configuration-options for configure times
  • XFT is the X11 font system, and is required.
  • Sub-pixel rendering

macOS script


set -o errexit
set -o pipefail

brew install autoconf gnu-sed texinfo pkg-config gnutls libxml2 jansson

export PATH="/usr/local/opt/texinfo/bin:$PATH"
export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"
export PKG_CONFIG_PATH="/usr/local/opt/libxml2/lib/pkgconfig"

./configure --with-ns --without-x --with-gnutls --with-json --with-xml2 --without-dbus
make -j $(nproc) all info doc

./src/emacs -Q
make install
# Copy ‘nextstep/’ to /Applications

Ubuntu 19.10 script with X


set -o errexit
set -o pipefail

sudo apt install pkg-config texinfo libgtk-3-dev libncurses-dev libgnutls28-dev libjansson-dev libxpm-dev libxml2-dev

./configure --with-x-toolkit=gtk3 --with-gnutls --with-json --with-xml2
make -j $(nproc) all info doc

./src/emacs -Q
sudo make install install-info install-doc

Ubuntu 20.04 script without X


set -o errexit
set -o pipefail

sudo apt install pkg-config texinfo libncurses-dev libgnutls28-dev libjansson-dev libxpm-dev libxml2-dev libsystemd-dev libz-dev build-essential aspell
# Consider: git, ripgrep, sshguard, and htop

./configure --with-gnutls --with-json --with-xml2 --with-libsystemd --with-x-toolkit=no --with-jpeg=ifavailable --with-png=ifavailable --with-gif=ifavailable --with-tiff=ifavailable | less
make -j $(nproc) all info doc

./src/emacs -Q
sudo make install install-info install-doc


icomplete uses wrong default value

GNU Bug Report #42101 Disable this expression from icomplete--sorted-completions:

,(lambda (comp)
   (string-prefix-p minibuffer-default comp))

Buffer content invisible when tunneling X

GNU Bug Report #25474

(setq default-frame-alist
      (append default-frame-alist '((inhibit-double-buffering . t))))

derived-mode-p broken for aliased parents

GNU Bug Report #32795

(defun provided-mode-derived-p (mode &rest modes)
  "Non-nil if MODE is derived from one of MODES or their aliases.
Uses the `derived-mode-parent' property of the symbol to trace backwards.
If you just want to check `major-mode', use `derived-mode-p'."
       (not (memq mode modes))
       (let* ((parent (get mode 'derived-mode-parent))
              (parentfn (symbol-function parent)))
         (setq mode (if (and parentfn (symbolp parentfn)) parentfn parent)))))

Installing org-mode with straight.el

There is a known bug when installing org-mode with straight.el. I have not applied the workaround because the bug is pretty much just cosmetic.


Everything in this section is yet to be rewritten and refiled.

Install package fork with Quelpa

(quelpa '(eglot :repo "andschwa/eglot" :fetcher github :branch "fix-capf-use-from-minibuffer"))

Markdown dwim header C-c C-t h

Narrowing: C-x n region n defun d widen w

Selective display: <num> C-x $

Surround with parentheses: M-( on region or with numeric arg

The opposite of C-l is M-r recenter-positions

Reposition window to see comment/function: C-M-l

Set fill prefix: C-x .

Fill-Prefix with point after prefix

Set fill column: C-x f

Toggle read-only C-x C-q


(setq file-name-shadow-properties
      '(invisible t))

Writable modes

occur with e exit

wgrep with C-c C-p

wdired with C-x C-q

ivy occur with C-c C-o then follows wgrep

See =ivy-occur-mode=

Tricks and tips

Automatic alignment with align-current

Fall back to align-regexp. Prefix that for complex mode.

Replace uniq with delete-duplicate-lines

also flush-lines and keep-lines

Delete blank lines M-x flush-lines RET ^$ RET

Using quote marks within verbatim/code markup in org-mode

  • Unicode: <U200B> /xe2/x80/x8b ZERO WIDTH SPACE
  • Insert using: (C-x 8 RET 200b RET)

Quickly insert #+begin_src with <s <tab> and C-c C-, s

(require 'org-tempo)
(add-args-to-list 'org-structure-template-alist
                    '(("el" . "src emacs-lisp")
                      ("sh" . "src sh")))

Sudo mode using Tramp C-x C-f /ssh:you@host|sudo:host:/file

Replace in files

From StackOverflow:

  1. M-x find-name-dired: you will be prompted for a root directory and a filename pattern: =-name ”.py” -not -path “./.archive/”=
  2. Press t to “toggle mark” for all files found.
  3. Press Q for “Query-Replace in Files…”: you will be prompted for query/substitution regexps.
  4. Proceed as with query-replace-regexp: SPACE to replace and move to next match, n to skip a match, etc.
  5. Press Y to finish replacing in all buffers.
  6. C-x C-s ! to save all buffers.

Replace with capture regexp

  • use regex groups like ab\(c\) where the parentheses are escaped because Emacs
  • refer to prior capture groups by \N where N is 1-indexed on the captured groups (e.g. back reference)

Renumber with regexp

  • see Wiki; the comma indicates elisp code to evaluate
  • e.g. [0-9]+ -> \,(+ 257 \#)
  • or by 8 starting at 10 \,(+ 10 (* 8 \#))

Replace reStructuredText headers

  • Find ~~~ etc. ^\(~+\)$
  • Replace with ^^^ \,(make-string (length \1) ?^)

regexp-builder for replace

  • Use C-c C-i and choose the “string” syntax
  • Copy the regexp without the surrounding quotes
  • Use C-c C-q to close regexp-builder

Set directory local variable eval to execute arbitrary code

Use (hack-dir-local-variables-non-file-buffer) to re-evaluate dir local

See current faces list-faces-display


No releases published


No packages published