Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: How Do You Navigate Code?
29 points by Davertron on Aug 23, 2022 | hide | past | favorite | 36 comments
I've been working in a new codebase recently, and I've been struggling to navigate code. I don't think this code is organized particularly poorly, but I still find myself jumping around and having quite a few files/tabs open trying to follow the thread. In this case some of this code is object oriented and so there's lots of jumping between class and base classes (often multiple base classes deep...) to see where anything happens. I've used VIM marks in the past, I'm trying a bookmarking extension for VS Code, and sometimes I open multiple files in splits to keep things "in context", but I still feel like these are all less than ideal and it's very easy if I step away from my computer for a few minutes for it all to leak out of my brain and then I spend the next 30 minutes trying to get it all back before I can work on the problem.

Looking for any tips you all might have for making this easier.




I use VSCode and mostly navigate via:

F12: Go to definition

Shift+F12: Go to usages

Ctrl+-: Go back

Ctrl+Shift+-: Go forward

Once you get used to it, it's as easy as browsing the web.

Since I started using VSCode I did not have to work with codebases that were complex enough to make these features valuable but some VSCode language extensions support tree views of call hierarchies and type hierarchies. Here's the documentation for the Java extension.

https://code.visualstudio.com/docs/java/java-editing#_call-h...

https://code.visualstudio.com/docs/java/java-editing#_type-h...

You can set keybindings for them too.


I use these as well, but maybe something I didn't articulate well is that it's often useful to remember where I've been. One thing that I haven't played with in VS Code but that bites me a lot (and sorry, I don't know the proper name for this setting/feature) is that often when you're navigating you're doing so in the same vs code tab. If I remember to double-click the tab it'll hang around, but that's a pretty janky workflow, and I don't ALWAYS want to do that. Ctrl+- works if I hop into a method/function and want to look at it briefly and hop out, but I find if I go more than a couple levels deep it would be nice to mark certain areas as I go so I can easily get back to them.

Sometimes I do this by just adding a comment, and now that file will at least show up in version control as changed and I can get back to it if I need to, but that's also a little bit janky and I have to be careful I don't leave that cruft around on accident when I commit.

I'm trying out a bookmark extension in VS code and we'll see how it goes, I'm already a little bit annoyed by it in that it doesn't seem to let me organize the bookmarks in any way, so it might be somewhat useful for temporary spelunking, but I won't for example be able to save these bookmarks to refer to them later, which seems like it could be useful.

Sourcegraph has this concept of "Notebooks" which allows you to add files and intermix markdown, which feels like a pretty cool idea, and if I'm just reading code in Sourcegraph it's great, but when I'm in my code editor and making changes I don't want to bounce over to another tool. Maybe it's as simple as keeping some sort of Markdown file open that I write into and then add links to file line numbers as I go, I haven't tried that but I suppose it wouldn't be the worst, and allows me to organize the links in any fashion I see fit.


Sourcegraph Notebooks PM here. We have a notepad feature you can enable that basically does what you're describing and allows you to create a notebook from the saved content in one click. There's a button to enable the notepad on the notebooks page (https://sourcegraph.com/notebooks or https://<your-sg-url.com>/notebooks).

It follows you around as you navigate search results and files and you can add searches, files, and file ranges to it, as well as notes for each item. Quick demo video: https://storage.googleapis.com/sourcegraph-assets/docs/image...


I just discovered this feature so I haven't played with it enough yet but it seems to tick all my boxes. One thing that I found confusing about the UX though was that I didn't realize at first I could continue searching around and adding content, so when I added my first bit of content and clicked "Create Notebook" and then subsequently navigated somewhere else and wanted to add content I ended up creating another notebook instead of adding it to a pre-existing one. Or sometimes I come back and want to add more content to an existing notebook, but I don't see how to do that.


That’s great feedback, thanks. We deliberately kept adding to existing notebooks out of scope for the first Notebooks release but had a feeling it would be requested pretty quickly.

It might also be more intuitive to clear out the notepad after a notebook is created but curious what you think.

Thanks again for the feedback, feel free to reply here if you have any other thoughts.


I find the Peek windows handy (the default experience for Find All References and the difference between Go to Definition and Peek Definition).

I find VS Code's Outline tool quite handy. By default it's hidden away at the bottom of the main Explorer tab, but you can turn on the Secondary Sidebar (now with a button at the top of the window) and drag it over on to the Secondary Sidebar to really give it room to grow and not fight your file explorer view for space. (Timeline I also like to move into the Secondary Sidebar as a good place for it.)

Outline resembles the Breadcrumbs at the top of an editor and even if you don't have great bookmarks, being able to quickly expand to a specific symbol in a file is handy.

Also Back/Forward mostly work pretty well in VS Code. If you've got the extra mouse buttons that can be used for Back/Forward in a browser those work well, as does the most common browser shortcut Alt+Left and Alt+Right. In very recent versions you can right click the Title Bar and turn on the Command Center and it gives you Back and Forward buttons there in the title bar, even more like a browser.

(ETA: holding Ctrl+Tab gives you a History menu in the order of Back/Forward sort order.)

> One thing that I haven't played with in VS Code but that bites me a lot (and sorry, I don't know the proper name for this setting/feature) is that often when you're navigating you're doing so in the same vs code tab. If I remember to double-click the tab it'll hang around, but that's a pretty janky workflow, and I don't ALWAYS want to do that.

This is called "Preview". If you don't double click to open the file, you can double-click the tab itself later if you decide to want to keep it open. (There's also Keep Open on the context menus and it has a keyboard shortcut of Ctrl+K Enter.)

You can entirely disable Preview with the Settings key "workbench.editor.enablePreview". (Set it to false. Or uncheck it in the UI.) You could make it apply to only a specific workspace while you are trying to navigate it by adding that to a .vscode/settings.json file in the project (though this specific Setting, I probably would try to avoid checking in to your project repo to avoid annoying other users).


OOP is annoying because if people are using interfaces, "Go to Definition" takes you to the interface instead of what I'm looking tor which is the implementation.


Ctrl+- is reduce font size Ctrl+Shift+- is a no-op

What version of VScode are you using?


I am on macOS. Keybindings are probably different for Windows and Linux.


Ctrl+Alt+-

I guess Ctrl+Shift+- is a no op if you haven't first gone back.


I think by default go back is Ctrl+Alt+-


Depends on what I am trying to achieve.

Most code (especially legacy code) has more branches than typically matter: the majority of branches is error handling or special cases and can be ignored when investigating core functionality. Executing the happy path test case for the functionality I want to extend or bug fix and then stepping through the code with a debugger or manually is my usual mode.

I use IntelliJ myself. Being able to step through with a debugger can be a huge help to show actual implementations used in polymorphic code but few test suites are sophisticated enough to guarantee the possibility. Sometimes I will refactor code simultaneously in order to make it more comprehensible; that obviously requires some tests and experience but if you have the tests take the time to gain the experience and otherwise write the tests! Especially BDD style tests, the kind that survive refactoring.


IntellIJ IDEA Ctrl-click, Ctrl-Shift-F, Ctrl-U, etc, Sourcegraph when I don't know which repo or do a company-wide code search or examples. Having a lot of tabs open for a single flow of data makes my brain forget about the start of the flow, so I put named bookmarks as I go when doing this. When debugging, the same kind of flow debugging, I use conditionnal non-suspend logging breakpoints that print out relevant stuff from variables in scope. One of the most important parts in this is closing all tabs from time to time, and putting 2 open files side-by-side, 1440p monitor helps, or splitting part of the IDE instance into a separate window on another monitor.


This is pretty much exactly what I do now, but since I'm unfamiliar with the codebase I often find myself thinking "where was that spot where this particular data came from?" or "where was that function defined again?" and I just waste a bunch of time & mental energy trying to track it down. Couple that with the fact that this particular codebase uses JavaScript with a custom / modified module system so you can't just cmd+click to go to definition and it's a real headache. It's also exacerbated here by having LOTS of files that have very similar names (Page, PageView, BaseView, BaseViewModel, config.model, config.view are a few examples...) and these are all just under one directory for a given component, if you look there are tons of components all with the same file names, which is a pet peeve of mine, but we all have our preferences I guess. Plus go to definition is great, but sometimes you go down a path that isn't fruitful and it takes a bit to get back to where you wanted to be, and often while I'm going down a path I want to annotate parts of it so it's easier to remember what each piece is doing. Anyway, it seems like bookmarks are a pretty good solution for this in vs code (https://marketplace.visualstudio.com/items?itemName=alefragn...), I just wish I could organize the bookmarks a little bit better than just "show me them by file" or "show me then in an unordered random list".

Edit: Oh and I would normally use the debugger A LOT to trace through the code and understand the call stack and params, but another crappy thing about this project is that it generates a massive JS bundle and it crashes the app I'm testing if I try to put debugger statements in...JS ftw


FWIW we (Sourcegraph) have updated our IntellIJ IDEA plugin: https://plugins.jetbrains.com/plugin/9682-sourcegraph


If my code's jumping around a lot I throw some keywords in the comments with unique numbers like verificationworkflow13 so with ctrl-f I can easily jump through the entire chain, or I can go straight to a specific step. Same concept as bookmarking but more flexible and it solves my problem of having a disorganized mess of too many bookmarks. It also helps for keeping things organized in my head ("this is part of the verification workflow between parts 12 and 14").


NeoVim + language servers + global search with rg + a bunch of keyboard shortcuts:

- <spc>gd = go to definition

- <spc>gr = open a hovering window filled with references to symbol

This is enough to get through every codebase I've yet encountered (Go, Typescript, Python, Java, C++). I also like to use <C-I> and <C-O> in vim which allows you to jump between the most recently viewed locations.

For keeping context, I just write everything down! Either in a scratch file or on a digital notetaking app on my iPad.


Are those keyboard shortcuts part of the LSP server?


Nope, you have to map them but they are very easy to do. You can use the suggested keymaps from nvim-lsp GitHub too (still need to copy pasta).


No, but defining one is as easy as one magic incantation in your .vimrc:

  nnore <leader>gd :LspGoToDefinition<CR> 
...or something like that. I haven't touched the config in a few months.


I had a similar requirements some time ago - I thought one nice way would be to write a Markdown file to be read inside VSCode with links to the files' lines/positions, but couldn't find an extension that worked like this. Settled for "Bookmarks" at the time. The "Code Tour" extension can also be used for this.


Ha, that's kind of where I'm leaning now, I thought of the same thing in another response in this thread. It seems like it's lightweight enough to stay out of my way but flexible enough that I can have some control over how I organize things, and being able to quickly add some prose to describe why that particular link is relevant would be great.


I have a weird workflow I think. I use ripgrep in the terminal to find relevant files and then run `subl $FILE` to open the file in Sublime Text in the foreground. Sublime knows to open the file in the window where the directory is already opened as a project.

I should probably use an IDE but I just don't like them. Sublime is insanely fast and lightweight. I don't want to wait for anything to happen and I find my current workflow allows me to navigate codebases quickly anyway.


I would just remember some keywords in either code or the file name and do global search, I barely use splits though bc I think it’s kinda distracting.


Yeah, I also don't really like splits, they just don't feel very scalable. If I just need to open one or two other files they're fine temporarily, but more than that and everything becomes too small. Maybe if there were something that let you zoom in and out, like a Figma canvas, so that you could organize the files spatially in some order that makes sense to you (this is another thing that annoys me about just opening tabs in my editor, they're never really ordered in any meaningful way). If you could do this not just for files but for selected lines / ranges / functions / classes to keep things tightly scoped that would be awesome. I believe this sort of thing was something the original LightTable video explored, but I don't believe it was ever actually implemented.


I’ll follow a lot of the vscode tips in this thread plus a helping of running Doxygen on the project. Even without the specific Doxygen markup in the headers, running Doxygen can help with the call graphs and object hierarchies with a browsable interface.


This is basically how I do it in Vim: https://vimways.org/2018/death-by-a-thousand-files/


If the computation jumps around between multiple files/classes, I document that on paper. Often when working on a new codebase, I end up surrounded by many pieces of paper documenting flows and type hierarchies.


grep -ri and then vim the interesting files. that's mostly web dev and scripting languages.

In the old days when I did more Java dev, I used Eclipse to view where things are defined and find usages.


Larger the code base, more likely I am to bookmark files and folders.

Otherwise, searches for file names and contextual links, usages etc.


I send my CTO 300 messages a day then cry when he doesn't reply and pay my friend $20/hr for an extra set of eyes.


step through it in a debugger;

run strace or ltrace on it;

grep: works better with editor assistance, such as emacs M-x grep;

write documentation for it;

factor out parts of it;


A good book on this topic is "Code Reading", by Diomidis Spinellis (2003)


vim + cscope

opengrok is nice if you want code search and navigation in a web interface


grep or vscode search / definitions.

Take some rough notes on a google doc / gedit so that I don't forget paths that I've explored previously


git grep, vim




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: