Neat behavior of M-x occur
Having used Emacs for several years now, I somehow hadn’t come across the prefix argument and active region behavior for one of the most well-known commands: occur.
Below is the docstring of occur reads, with the relevant portions preserved:
occur is an interactive native-comp-function in replace.el.
It is bound to M-s o.
(occur REGEXP &optional NLINES REGION)
Inferred type: (function (t &optional t t) t)
Show all lines in the current buffer containing a match for REGEXP.
If a match spreads across multiple lines, all those lines are shown.
[…]
Each line is displayed with NLINES lines before and after, or -NLINES
before if NLINES is negative.
NLINES defaults to list-matching-lines-default-context-lines.
Interactively it is the prefix arg.
Optional arg REGION, if non-nil, mean restrict search to the
specified region. Otherwise search the entire buffer.*
*REGION must be a list of (START . END) positions as returned by
region-bounds.
[…]
When NLINES is a string or when the function is called
interactively with prefix argument without a number (C-u alone
as prefix) the matching strings are collected into the ‘*Occur*’
buffer by using NLINES as a replacement regexp. NLINES may
contain \& and \N which convention follows replace-match.
For example, providing “defun\s +\(\S +\)” for REGEXP and
“\1” for NLINES collects all the function names in a lisp
program. When there is no parenthesized subexpressions in REGEXP
the entire match is collected. In any case the searched buffer
is not modified.
[…]
So:
- When called on a region, on that region is searched.
- When called with a numerical prefix argument, that many lines before and after every match is added to the search results. (This reminds me of next-screen-context-lines.) This functionality is particularly useful to me since added context is sometimes necessary.1
- When called with a universal argument, just the matching string (not the entire line) is inserted into a line in a read-only buffer.
- If called from elisp and NLINES is provided (as a regexp string), then the behavior is like
C-u
but matches can be modified like replace-match. (See(elisp) Replacing Match
for more information.)
Also, searching “NLINES” with apropos-documentation brings up a few other built-in commands that have similar functionality. isearch-occur, multi-occur, list-matching-lines, and occur-context-lines to name a few.
Pretty neat!
Further Reading
- Searching and Editing in Buffers with Occur Mode - Mastering Emacs
- What do you use for occur? - Reddit
- Emacs’ powerful OCCUR function in practice | Protesilaos Stavrou
- EmacsWiki: Occur Mode
I sometimes use occur-edit-mode (bound to
e
inoccur-mode
buffers), and the added context lines can be relevant to the edits I want to make to the matched text. ↩︎