Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support terminal hyperlinks to allow opening diff lines in editor when using delta pager #3817

Closed
dandavison opened this issue Aug 10, 2024 · 12 comments · Fixed by #3825
Closed
Labels
enhancement New feature or request

Comments

@dandavison
Copy link

dandavison commented Aug 10, 2024

Is your feature request related to a problem? Please describe.
I'd like to be able to click / use a keybinding on lines of a diff in lazygit and have my editor open at that line.

Describe the solution you'd like
delta can be used as a pager with lazygit. delta --hyperlinks formats all line numbers in the diff as terminal (OSC) hyperlinks; e.g. with --hyperlinks-file-link-format = "vscode://file/{path}:{line}" a click on a line number opens that line in VSCode. I'd like the hyperlinks emitted by delta to be clickable (and have a keybinding to open?) inside layzgit.

Describe alternatives you've considered

  • One alternative could be to construct customizable OSC hyperlinks for diff lines natively in lazygit.
  • Something could probably be done with custom commands but I think it would be less convenient than clicking on the line numbers

Additional context

  • lazygit was modified to ignore OSC hyperlinks at Ignore OSC sequence gocui#24 (previously it was incorrectly displaying raw escape sequences)
  • Clickable URL functionality was added to lazygit in Make URLs in confirmation panels clickable, and underline them #3446, but this PR opted not to use terminal hyperlink technology.
  • VSCode, JetBrains IDEs, and Zed all support custom URL protocols this. Alternatively users can use file://, or customize the URL to send a request to an arbitrary service of their choice.
  • OSC Hyperlinks are supported by many terminal emulators on any platforms today, as well as by tmux.
  • In addition to delta, GNU ls, ripgrep, fd, etc all emit OSC hyperlinks.
@stefanhaller
Copy link
Collaborator

@dandavison A draft PR is available for early testing here: #3825.

While testing I found two issues with this:

  • when command-clicking a link, iTerm2 also passes the click to lazygit, which means that when you are in the commit files panel, you'll go into custom patch staging mode. Very annoying. I filed this as an iTerm2 issue, but since the built-in terminal of VS Code behaves the same, I'm wondering if we are doing something wrong.
  • when using the vscode: URI scheme, VS Code always opens the file in the current workspace, even if the file's workspace is also open in another window. This is very annoying, the code command-line tool doesn't have this problem. I filed this as a VS Code issue here.

Apart from that, however, the feature is fantastic, and I'm wondering how I could live without it for so long.

@stefanhaller
Copy link
Collaborator

After testing various terminal emulators and seeing how varied their support for hyperlinks is, I came to the conclusion that OSC 8 hyperlinks and TUI apps don't mix well. Actually, thinking about it there's little reason for a TUI app to emit OSC 8 hyperlinks and rely on the terminal to handle them; we're better off doing this ourselves.

So I'm proposing a hybrid approach now, where we parse OSC 8 sequences coming from pagers, but then don't pass them on to the tcell layer. Instead, we remember the information in the gocui cell struct, and take care of underlining the links and handling clicks in them on our side (in gocui, that is).

I've modified the PR (#3825, still in draft mode) accordingly, and I'm very happy with the behavior now. It has several advantages:

  • allows simple non-modifier clicks to launch links, like in a web browser (good for people like me who don't like having to put down their coffee mug)
  • works in all terminal emulators, even those that don't support hyperlinks at all
  • consistent UI: the underline looks the same in all terminal emulators (for OSC 8 hyperlinks, some underline them solid, some dotted, some only on hover, etc.)

Possible downsides:

  • no mouse hover support. It would be nice to somehow highlight the URL as you hover over it; we could theoretically add this, but it's a bit of work, so I won't do that in the initial version.
  • possible security issues, as there's no way to see what link you are getting sent to. So it would be possible for a malicious pager to send you to a fishing website. Some terminal emulators solve this by a) showing the link target in a status bar as you hover over it, and/or b) showing a confirmation dialog the first time you click a link for a particular target. We could theoretically build these in to lazygit or gocui, but again it's a lot of work, and not for the initial version.

I have been using this version for the last two days, and it has already become a total game changer for me.

@dandavison Please try it out and let me know what you think!

@dandavison
Copy link
Author

Based on a quick try so far, this is working beautifully for me in Wezterm and Alacritty.

My biggest question (and it's not a very big one) is about double-click to copy. In particular I'm thinking of commit SHAs, which delta hyperlinks (configurably, but the idea is it links to the web hosting of the repo), and which it is common to want to copy to system clipboard. And this this might partly be a question about copying text in lazygit regardless of your PR.

In Alacritty, I see that I can do it by holding down shift and double-clicking on the commit SHA. The unexpected behavior I'm seeing is that if I then click without shift held, on a bit of "blank" screen in lazygit, then the element remains highlighted, whereas my expectation (from web browsers) is that the highlighting will disappear. To make it disappear I have to shift-click elsewhere. In contrast, in Wezterm, the highlighting goes away if the mouse moves away from the element (i.e. on blur). Sorry this is a rather unclear question -- could you just confirm that the behavior related to double-click highlighting on hyperlinked elements is all as you expect?

I think it makes sense to me that a TUI can have its own opinions about how UI elements are presented that may differ from the terminal's native presentation of analogous elements. Of course, it results in some discord if I split terminal panes with lazygit in one.

@stefanhaller
Copy link
Collaborator

I'm not really sure I can follow. When you say "double-click to copy", do you literally mean that, or do you mean "double click to select, and then press Cmd-C to copy"?

In iTerm2, I can hold the option key to select text (by dragging or double-clicking), which temporarily overrides mouse capturing. But of course, if I select a lazygit hyperlink this way and copy it, I copy the text and not the link target, which appears to be what you want.

@dandavison
Copy link
Author

When you say "double-click to copy", do you literally mean that, or do you mean "double click to select, and then press Cmd-C to copy"?

Yes, that's what I mean. In Alacritty:

  1. I hold down shift and double-click to select a commit SHA (I must hold down shift or else it would open the link)
  2. Now the commit SHA is highlighted
  3. Now, suppose I want the highlighting to go away. I was expecting a plain click in any blank region of the lazygit UI to have that effect, but it does not. A shift-click in a blank region does though.

I'm not saying this is wrong, I just want to check with you that it's as it should be.

@stefanhaller
Copy link
Collaborator

iTerm2 does remove the highlight when you plain-click somewhere else. But that's the behavior of the terminal emulator, lazygit doesn't have any influence on it. It also sounds unrelated to hyperlinks to me.

Still curious: if you select an OSC 8 hyperlink in Alacritty and then copy, does it copy the text or the link target?

@dandavison
Copy link
Author

if you select an OSC 8 hyperlink in Alacritty and then copy, does it copy the text or the link target?

It copied the text (as desired)

It also sounds unrelated to hyperlinks to me.

Ah yes you're right I think this isn unrelated to hyperlinks; I'm just new to shift-clicking to select. (Natively Alacritty removes the highlight with a plain click; in lazygit that doesn't happen, but that's not relevant to this issue and possibly intended.)

@stefanhaller
Copy link
Collaborator

It copied the text (as desired)

In that case I'd recommend to use ctrl-o in the commits panel to copy commit hashes, that should be faster than shift-double-clicking and copying manually. I do this all the time.

in lazygit that doesn't happen

Again, this has nothing to do with lazygit, but with Alacritty's handling of TUI apps. Whether it's intentional or not I have no idea, but after my recent (brief) interaction with the Alacritty devs I am not interested in finding out. 😄

@jesseduffield
Copy link
Owner

after my recent (brief) interaction with the Alacritty devs I am not interested in finding out. 😄

@stefanhaller if there's a link to that interaction I would love to read it

@stefanhaller
Copy link
Collaborator

Oh it's probably not as bad as I made it sound: alacritty/alacritty#8129

@jesseduffield
Copy link
Owner

Haha yeah not so bad. I saw how disagreeable alacritty's devs were about adding support for tabs/panes a while back and was wondering if you had accidentally revived that debate because that would be a spectacle to behold.

@stefanhaller
Copy link
Collaborator

Oh, and now you got the popcorn out already; sorry to disappoint...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants