I am a C++ dev. I am now able to follow up symbols or files using LSP,/projectile/ivy/transient aso… but inside one file, I have difficulties going quickly up function by function, or by if/for statement. Do you know a convenient way to do this ? I am interested in any navigation tips as well ! Thanks for your help !
You can go to the next/previous function with C-M-a and C-M-e. With evil mode it’s ] m and [ m. You can use imenu. You can make keybindings to scroll forwards/backwards several lines at a time.
That one is great !!! What if I want to navigate through statements of the same type ? Like if instructions?
I don’t know any good way to do that.
Feels like this would be something cool to add to a treesitter mode.
Meanwhile I just C-s if
See my reply above. You can use either
thing-cmd.el
orfind-where.el
for that. You just need to define “statements of a given type” as a THING or define a predicate that is true for them. Or if their text has some property (even justface
from font-locking) thenisearch-prop.el
will help.
I’m not sure what that means, but
forward-sexp
,backward-sexp
, andbackward-up-list
are good for navigating across and within balanced expressions.
forward-sexp
C-s
consult-line
And I’m using outline-minor-mode
(setq-local outline-regexp " *//\\(-+\\)")
(outline-minor-mode 1)
Now every comment starting with // followed by one or more - like
//- Function this
//-- Function that
//--- Some important code
is treated like a heading by outline. So, you can use all the outline functions for navigating and folding.
Also you can use consult-outline (if installed) to jump quickly to a heading.
To make it even more convenient I recommend the packages bicycle and logos.
consult-line
And I’m using outline-minor-mode
(setq-local outline-regexp " *//\\(-+\\)")
(outline-minor-mode 1)
Now every comment starting with // followed by one or more - like
//- Function this
//-- Function that
//--- Some important code
is treated like a heading by outline. So, you can use all the outline functions for navigating and folding.
Also you can use consult-outline (if installed) to jump quickly to a heading.
To make it even more convenient I recommend the packages bicycle and logos.
avy
is good for quickly jumping between what’s visible. Occur is brilliant, it might also be worth mentioning consult and embark.Here are some ways to move around. The first two are in vanilla Emacs. (There are
previous
functions corresponding to thenext
functions mentioned.)-
C-M-e
andC-M-a
: Move to next “defun” (function definition). -
Imenu, if you know the name of the thing (e.g. a definition) you`re looking for. (Various libraries let you complete/filter and cycle among candidates.)
-
next-visible-thing
. Moves to end of next THING. First nonconsecutive use prompts for THING type. Or usenext-visible-thing
to define such a command for a specific kind of THING (so no prompt needed for the kind).Requires library
thing-cmds.el
, which requireshide-comnt.el
.Predefined THINGS (library
thingatpt+.el
needed for some):sexp, button, char, char-same-line, color, comment, decimal-number, defun, email, filename, hex-number, line, list, list-contents, non-nil-symbol-name, number, overlay, page, paragraph, region-or-word, sentence, string, string-contents, symbol, symbol-name, unquoted-list, url, whitespace, whitespace-&-newlines, word
“Visible” means invisible text is skipped. Option
ignore-comments-flag
controls whether to also ignore text in comments. -
Command
fw-to-next-thing
. Moves to the start of the next THING (unlikenext-visible-thing
, which moves to its end).Requires libraries
find-where.el
andthingatpt+.el
needed for some).Library
find-where.el
lets you get something at a position where an arbitrary predicate is true (not just a position at the start of a text THING), or move to such a position.E.g., function
fw-next-thing
returns the next THING and its position, and commandfw-to-next-thing
goes there.E.g., this defines a command to move to the beginning of the next sexp:
(defun to-next-sexp (n) "Go to next start of a sexp." (interactive "p") (fw-to-next-thing 'sexp nil n))
Likewise, for
fw-next-where
andfw-to-next-where
, which look for the next place and some data where some predicate is satisfied.See the Commentary in
find-where.el
. -
Commands in library
isearch-prop.el
to search within the text of certain things.E.g.,
isearchp-imenu-non-interactive-function
searches only within (or only outside of) definitions of functions that are not commands.isearch-property-forward
searches only within text that has (or doesn’t have) a given text or overlay property.isearchp-zones-forward
searches only within (or only outside) the text of a given set of zones (i.e., within a noncontiguous region). -
The old library
hideif.el
lets you hide text that’s withinifdef
s.
https://www.emacswiki.org/emacs/download/thing-cmds.el
https://www.emacswiki.org/emacs/download/hide-comnt.el
https://www.emacswiki.org/emacs/download/find-where.el
Awesome compilation!! I already start using C-M e/a already mentioned in this post. It’s simple and effective. I need to finish reading everything to get a way to move inside one function.
-
Ivy with Swiper is the best way to navigate large files or groups of files IMO.
I use it a lot yes. But some times you just want to look up or down along functions or statements. Scrolling is painful…
Ah yes. Do you use
C-M-a
andC-M-e
?They jump to the beginning or end of a function and can make scrolling much less painful. I know Evil mode has something similar.
I usually do screenwriting, and fountain-mode uses
M-n
andM-p
to jump between dialogue. I love that and feel likeC-M-a
andC-M-e
are really the closest comparisons to that I know of for code.
I like imenu-list a lot for showing the classes, methods, functions, etc in the file in a side buffer.
For functions, use
M-x imenu
orconsult-imenu
for flattened results. Forif
/for
statements, justisearch
. If you’re an evil user, mark the point (mx
means the point is stored inx
) then jump back ('x
).I think the “hide-show” package is invaluable in navigating large files. You can see all functions collapsed in a file. Or, within a function, you can see all blocks of code
{}
collapsed.inside one file, I have difficulties going quickly up function by function
helm-occur
Just start typing and it will show you occurrences in a file; you can use C-n/C-p (or whatever you bind it to), and it will move the point in the buffer and show you the occurrence so you can see the surrounding text. If you C-g the point is left where you were, and if you just press enter your point will be placed at the occurence.
inside one file, I have difficulties going quickly up function by function
helm-occur
Just start typing and it will show you occurrences in a file; you can use C-n/C-p (or whatever you bind it to), and it will move the point in the buffer and show you the occurrence so you can see the surrounding text. If you C-g the point is left where you were, and if you just press enter your point will be placed at the occurence.
Using treesitter you can have text objects that are if statements or functions or whatever. From there it is just a key binding away
Using treesitter you can have text objects that are if statements or functions or whatever. From there it is just a key binding away
https://github.com/abo-abo/avy#avy-goto-char-timer is excellent for jumping to any text you can see on screen.
isearch and occur are excellent for jumping to specified text anywhere in the buffer.
imenu and xref-find-* are excellent for jumping to specific definitions in the buffer.