Skip to content

Improve clicking in diff view to enter staging/patch building #3986

Open
@stefanhaller

Description

@stefanhaller

When a single file (not a directory) is selected in the files panel, you can click in the diff on the right to enter staging, with the clicked line selected. This is very convenient, but there are several problem with this:

  • if you are using a custom pager that does more than just coloring the diff (e.g. delta), you usually end up with the wrong line selected; it's not very far away, but still annoying. This is because the line numbers in the pager's diff view don't exactly line up with the line numbers in the staging view.
  • it's only available when a file is selected. When a directory is selected, clicking in the diff collapses or expands the directory, which I suppose was not intentional.
  • it's not available when looking at a diff of a commit.

This last one is really a bummer. It is a very common use case for me to review my branch in the commits panel, and then I notice something that I want to improve; for example, I realize that a certain diff hunk should be extracted into a separate commit. To do that, I have to hit enter to go into the commit files view, then find the file again that I was just looking at, hit enter again to go into patch building mode, and then find the hunk again that I was just looking at. This is very cumbersome if there are many changed files in the commit, or many diff hunks in the file in question. It would be so much easier to just click in the diff view of the commit and go straight into patch building mode, with the clicked line selected.

(Side note: for editing a given line in the diff we recently improved this by using delta's hyperlink feature, so you can now jump straight to the editor by clicking on a line number. This is great, and I use it all the time; and this is a workaround for cases where you don't absolutely need a custom patch. For example, when I see a left-over printf statement from debugging that I want to drop from a commit, I now jump to the editor, delete it there, and amend the change into the commit I'm looking at. It should be as easy to make a custom patch and drop it, though.)

To implement all this, we can use delta's hyperlinks again, but it's a bit of a hacky solution. When clicking on a line in the diff (but not on a hyperlinked line number) we can examine the rest of the line to see if there are any lazygit-edit: URLs in it; if so, we use it to determine which file and line we're on. We can then select that file in the tree view on the left, and work out the line number in the patch that corresponds to the line number in the file.

I made a draft PR that implements this, and it works reasonably well. The main problem is that not all lines in the diff have a hyperlink; the ones between hunks don't, and deleted lines don't, either. As a user you need to learn to click on a line that has an underlined line number, which is not intuitive.

@dandavison I wonder if we can improve this by adding a mode to delta where it adds "invisible" hyperlinks to all lines in the diff, not just added or context lines. One way to do this could be to add a space at the beginning or end of the line and attach the hyperlink to that, and follow it with a \b character so that it's invisible. Very hacky, yes, but should improve things a bit.

Alternatively, we could use custom, private OSC messages to annotate all lines with file/lineNo information in some custom format. Probably a bit cleaner. Let me know if you'd be interested in exploring this more, or if you have other ideas how to solve this.

@jesseduffield Keen to hear your thoughts on all this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions