this post was submitted on 12 Oct 2023
5 points (100.0% liked)

Emacs

311 readers
1 users here now

A community for the timeless and infinitely powerful editor. Want to see what Emacs is capable of?!

Get Emacs

Rules

  1. Posts should be emacs related
  2. Be kind please
  3. Yes, we already know: Google results for "emacs" and "vi" link to each other. We good.

Emacs Resources

Emacs Tutorials

Useful Emacs configuration files and distributions

Quick pain-saver tip

founded 1 year ago
MODERATORS
 

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 !

top 23 comments
sorted by: hot top controversial new old
[–] [email protected] 2 points 1 year ago (1 children)

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.

[–] [email protected] 1 points 1 year ago (2 children)

That one is great !!! What if I want to navigate through statements of the same type ? Like if instructions?

[–] [email protected] 1 points 1 year ago (2 children)

I don't know any good way to do that.

[–] [email protected] 1 points 1 year ago

See my reply above. You can use either thing-cmd.el or find-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 just face from font-locking) then isearch-prop.el will help.

[–] [email protected] 1 points 1 year ago

Feels like this would be something cool to add to a treesitter mode.

Meanwhile I just C-s if

[–] [email protected] 1 points 1 year ago

I'm not sure what that means, but forward-sexp, backward-sexp, and backward-up-list are good for navigating across and within balanced expressions.

[–] [email protected] 1 points 1 year ago

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.

[–] [email protected] 1 points 1 year ago

forward-sexp

C-s

[–] [email protected] 1 points 1 year ago (1 children)

Ivy with Swiper is the best way to navigate large files or groups of files IMO.

[–] [email protected] 1 points 1 year ago (1 children)

I use it a lot yes. But some times you just want to look up or down along functions or statements. Scrolling is painful...

[–] [email protected] 1 points 1 year ago

Ah yes. Do you use C-M-a and C-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 and M-p to jump between dialogue. I love that and feel like C-M-a and C-M-e are really the closest comparisons to that I know of for code.

[–] [email protected] 1 points 1 year ago (1 children)

Here are some ways to move around. The first two are in vanilla Emacs. (There are previous functions corresponding to the next functions mentioned.)

  • C-M-e and C-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 use next-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 requires hide-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 (unlike next-visible-thing, which moves to its end).

    Requires libraries find-where.el and thingatpt+.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 command fw-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 and fw-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 within ifdefs.

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

https://www.emacswiki.org/emacs/download/thingatpt%2b.el

https://www.emacswiki.org/emacs/download/isearch-prop.el

[–] [email protected] 1 points 1 year ago

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.

[–] [email protected] 1 points 1 year ago

avy is good for quickly jumping between what's visible. Occur is brilliant, it might also be worth mentioning consult and embark.

[–] [email protected] 1 points 1 year ago

Using treesitter you can have text objects that are if statements or functions or whatever. From there it is just a key binding away

[–] [email protected] 1 points 1 year ago

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.

[–] [email protected] 1 points 1 year ago

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.

[–] [email protected] 1 points 1 year ago

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.

[–] [email protected] 1 points 1 year ago

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.

[–] [email protected] 1 points 1 year ago

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.

[–] [email protected] 1 points 1 year ago

For functions, use M-x imenu or consult-imenu for flattened results. For if/for statements, just isearch. If you're an evil user, mark the point (mx means the point is stored in x ) then jump back ('x).

[–] [email protected] 1 points 1 year ago

Using treesitter you can have text objects that are if statements or functions or whatever. From there it is just a key binding away

[–] [email protected] 1 points 1 year ago

I like imenu-list a lot for showing the classes, methods, functions, etc in the file in a side buffer.