Two Workflow Tips

An article about a couple of relatively recent additions to my workflow which I wish I knew about years ago.

Split And Go To Definition

Go to definition is super useful (in general, navigation is much more important than code completion). But often, when I use goto def I dont actually mean to permanently go there. Rather, I want to stay where I am, but I need a bit more context about a particular thing at point.

What Ive found works really great in this context is to split the screen in two, and issue go to def in the split. So that you see both the original context, and the definition at the same time, and can choose just how far you would like to go. Heres an example, where I want to understand how apply function works, and, to understand that, I want to quickly look up the definition of FuzzOp:

VS Code actually has a first-class UI for something like this, called Peek Definition but it is just not good it opens some kind of separate pop-up, with a completely custom UX. Its much more fruitful to compose two existing basic features splitting the screen and going to definition.

Note that in the example above I do move focus to the split. I also tried a version that keeps focus in the original split, but focusing new one turned out to be much better. You actually dont always know up front which split would become the main one, and moving the focus gives you flexibility of moving around, closing the split, or closing the other split.

I highly recommend adding a shortcut for this action. Its a good idea to make it a complementaryshortcut for the usual goto definition. I use , . for goto definition, and hence , > is the splitting version:

{ "key": ", .",       "command": "editor.action.revealDefinition" },
{ "key": ", shift+.", "command": "editor.action.revealDefinitionAside" },

, .

Yes, you are reading this right. , ., that is a comma followed by a full stop, is my goto definition shortcut. This is not some kind of evil vim mode. I use pedestrian non-modal editing, where I copy with ctrl + c, move to the beginning of line with Home and kill a word with ctrl + Backspace (though keys like Home, Backspace, or arrows are on my home row thanks to kanata).

And yet, I use , as a first keypress in a sequence for multiple shortcuts. That is, , . is not , + . pressed together, but rather a , followed by a separate .. So, when I press , my editor doesnt actually type a comma, but rather waits for me to complete the shortcut. I have many of them, with just a few being:

  • , . goes to definition,
  • , > goes to definition in a split,
  • , r runs a task,
  • , e s edits selection by sorting it, , e C converts to camelCase,
  • , o g opens magit for VS Code, , o k opens keybindings.
  • , w re-wraps selection at 80 (something I just did to format the previous bullet point), , p pretty-prints the whole file.

Ive used many different shortcut schemes, but this is by far the most convenient one for me. How do I type an comma? I bind , Space and , Enter to insert comma and a space/newline respectively, which handles most of the cases. And theres , , which types just a lone comma.

To remember longer sequences, I pair the comma with whichkey, such that, when I type , e, what I see is actually a menu of editing operations:

This horrible idea was born in the mind of Susam Pal, and is officially (and aptly I should say) named Devil Mode.

I highly recommend trying it out! It is the perfect interface for actions that you do once in a while. Where it doesnt work is for actions you want to repeat. For example, if you want to cycle through compilation errors, binding , e to the next error would probably be a bad idea, as typing , e , e , e to cycle three times is quite tiring.

This is actually a common theme, there are many things you might to cycle back and forward through:

  • completion suggestions
  • compiler errors
  • textual search results
  • reference search results
  • merge conflicts
  • working tree changes

It is mighty annoying to have to remember different shortcuts for all of them, isnt it? If only there was some way to have a universal pair of shortcuts for the next/prev generalized motion

The insight here is that youd rarely need to cycle through several different categories of things at the same time. So I bind the venerable ctrl+n and ctrl+p to repeating the last next/prev motion. So, if the last next thing was a worktree change, then ctrl+n moves me to the next worktree change. But if I then query the next compilation error, the subsequent ctrl+n would continue cycling through compilation errors. To kick-start the cycle, I have a , n hydra:

  • , n e next error
  • , n c next change
  • , n C next merge Conflict
  • , n r next reference
  • , n f next find
  • , n . previous edit

I dont know if theres some existing VS Code extension to do this, I implement this in my personal extension.

Hope this is useful! Now go and make a deal with the devil yourself!