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

Add hyperlinks #2322

Closed
wants to merge 11 commits into from
Closed

Conversation

ltrzesniewski
Copy link
Contributor

@ltrzesniewski ltrzesniewski commented Oct 2, 2022

This PR adds hyperlinks to the file paths for terminals which support it:

image

It's just a draft for now, there's still work to do, but I'm opening this in case anyone would like to provide some early feedback. I'm still new to Rust, so this surely looks like garbage right now, but I'd like to make the code more idiomatic, bring it to the adequate speed and quality level, and learn in the process.

I still need to add added hostnames on Unix for better SSH support, but that requires approval from @BurntSushi.

This depends on BurntSushi/termcolor#65, which will certainly need to be rewritten (because of the clunky API it currently introduces), or at the very least enhanced with stuff like supports_hyperlinks().

Fixes #665


This is what I have in mind for this PR:

  • On Unix: file://hostname/path/file.txt
  • On Windows: file:///C:/path/file.txt
  • On WSL: file://wsl$/distribution/path/file.txt

Hostnames on Unix would be useful for using ripgrep through SSH (SSH is mostly used to connect to Unix destinations). They could also be added on Windows after microsoft/terminal#14116 is fixed.


Preview builds can be found here.

@ltrzesniewski ltrzesniewski marked this pull request as draft October 2, 2022 21:14
@kovidgoyal
Copy link

I suggest you look at https://sw.kovidgoyal.net/kitty/kittens/hyperlinked_grep/ In particular

By default, this kitten adds hyperlinks for several parts of ripgrep output: the per-file header, match context lines, and match lines. You can control which items are linked with a --kitten hyperlink flag. For example, --kitten hyperlink=matching_lines will only add hyperlinks to the match lines. --kitten hyperlink=file_headers,context_lines will link file headers and context lines but not match lines. --kitten hyperlink=none will cause the command line to be passed to directly to rg so no hyperlinking will be performed. --kitten hyperlink may be specified multiple times.

I am pretty sure users will want to customize what parts of the output are hyperlinked.

@ltrzesniewski
Copy link
Contributor Author

ltrzesniewski commented Oct 3, 2022

I thought about adding a --hyperlink command line option, but wasn't sure exactly what options I should put there. That's something that should be discussed I guess.

It looks like hyperlinked_grep is able to point the editor directly at the matched line, which is awesome. Unfortunately, that doesn't seem to be possible to achieve in a standard way with just the file:// protocol alone. I took a quick glance at your code, and you're adding the line number in the fragment part of the URI (file://host/file#line), which, you guessed it... doesn't work on Windows (the file won't even open). 😭

@kovidgoyal
Copy link

kovidgoyal commented Oct 3, 2022 via email

@ltrzesniewski
Copy link
Contributor Author

ltrzesniewski commented Oct 3, 2022

I feel for you, maybe come over to the dark side :))

I have WSL on Windows, so I'm getting the best of both worlds. 😜

On a serious note, there is nothing preventing a windows based terminal from parsing the fragment part of the URL and either discarding it or using it, as it sees fit.

That's not really how things work on Windows, and I don't think Microsoft would change their terminal that way. This would need special-casing the file:// protocol in the terminal, enhancing it with #line support, then adding configurable apps by file types with custom command line argument patterns. They won't do such a thing.

Let me explain: URIs are handled by the shell (a system component), and applications can be associated with URI schemes. For instance, https:// would be associated with the web browser. So, the shell decides how to handle a particular URI, not the terminal app. That way, you get an integrated UI experience which is consistent across applications. I'm not sure how exactly file:// is set up, but it must be tied to something that decodes the URI to a file path, and chooses the application to open based on the file extension, which is configurable in the system settings. But this configuration doesn't let you specify additional parameters to pass to the target application, such as the file line.

This could be worked around with a custom URI scheme such as ripgrep://, but I'm pretty sure that wouldn't be accepted. 🙂

@kovidgoyal
Copy link

kovidgoyal commented Oct 3, 2022 via email

@ltrzesniewski
Copy link
Contributor Author

I don't see why the rest of the world should suffer for it.

Like I said before, the behavior can be slightly different on Windows and Linux. You don't need to suffer anything.

Do you know if other terminals can interpret the fragment part of the URI as a line number, and act accordingly?

I dont see why the shell cant pass file:// urls with fragments to applications, all it requires is an extra check box in their configuration UI, to indicate to the shell not to modify file urls when passed to the specified application.

Because of the intermediate step in the Windows shell which translates the URI to a file path, which apparently cannot handle it. The target appliction is passed the file path, not the URI.

"all it requires" is an obscure change at the OS level. That won't happen.

Or just use a non-Microsoft terminal if you must use windows.

I want this feature to work by default. Otherwise, there's no point. It also happens I want it to work with the terminal I use every day.

And finally, please stop being aggressive. I'm just trying to add a feature here, in good faith. I'm not trying to cripple anything. It doesn't need to be perfect right from the start. Remember it can always be enhanced afterwards. In the meantime, your kitten can continue to fill the gaps.

@kovidgoyal
Copy link

kovidgoyal commented Oct 3, 2022 via email

@ltrzesniewski
Copy link
Contributor Author

Sigh. Looks like you don't understand what I've been saying in the issue thread.

It can be running over ssh on a linux machine but its output can be interpreted on a windows machine.

Yes. And SSH support will work fine if I include the hostname on Linux. Because there's no Linux to Windows SSH.

No clue. Probably not, if I had to guess.

So, in other words, you're trying to change the default behavior of ripgrep to nonstandard links just for kitty support.

You want it to work by default on your terminal in your use case, breaking it by default for other people and other usecases.

Well, of course I want to make it work for myself. But I won't be breaking anyone else. On the contrary, I want this to work for most people out of the box.

You're trying to make me generate nonstandard links which only your terminal understands. Now that is breaking it by default for other people, like me.

And you picked the terminal and usecase that is the most limited.

Yes. That's the lowest common denominator which works for everyone.

No remote hosts and no line numbers.

  • Remote hosts will be supported if I include the hostname on Linux.
  • Line numbers are only supported by kitty, and can be handled by hyperlinked_grep just fine.

ripgrep must produce crippled output

ripgrep must produce standard output.

I don't consider clicking on a search result and being taken to a random point in the file (as will happen if the editor remembers last opened position) or the top of the file working by default.

Then, as you're fond of saying, change your settings. Or continue to use hyperlinked_grep. Just don't break it for other people.

You are adding the feature wrong.

This is your opinion. I've heard it. I just don't agree with it.

Thanks for your feedback.

@kovidgoyal
Copy link

Sigh. Looks like you don't understand what I've been saying in the issue thread.

Sigh. Looks like you dont have a clue what you are doing.

It can be running over ssh on a linux machine but its output can be interpreted on a windows machine.

Yes. And SSH support will work fine if I include the hostname on Linux. Because there's no Linux to Windows SSH.

Yes there is. Google is your friend.

No clue. Probably not, if I had to guess.

So, in other words, you're trying to change the default behavior of ripgrep to nonstandard links just for kitty support.

No, I am trying to make the output of ripgrep fit for purpose. The purpose here being, clicking on a search result and navigating to that result in an editor.

You want it to work by default on your terminal in your use case, breaking it by default for other people and other usecases.

It breaks only on terminals that pass file URLs without removing hostnames, fragments, queries etc from them onto systems which cant handle those. AKA terminals that dont sanitize untrusted input before passing it on. I feel for you that you are wedded to such a terminal.

Well, of course I want to make it work for myself. But I won't be breaking anyone else. On the contrary, I want this to work for most people out of the box.

Yes, you will. You have conveniently ignored the fact that output from a search tool when clicked should go to the search result inside the file, not just the file. By leaving off line numbers you are breaking that extremely reasonable expectation for everybody, forcing them to use wrappers to work around your lack.

You're trying to make me generate nonstandard links which only your terminal understands. Now that is breaking it by default for other people, like me.

Non standard? Which standard are you referring to? Last I checked fragments are a part of every standard that determines what constitutes a valid URL.

And you picked the terminal and usecase that is the most limited.

Yes. That's the lowest common denominator which works for everyone.

Except, it doesn't actually work.

No remote hosts and no line numbers.

  • Remote hosts will be supported if I include the hostname on Linux.
  • Line numbers are only supported by kitty, and can be handled by hyperlinked_grep just fine.

Is it really your position that you think clicking on search results should take you to random positions in a file?

ripgrep must produce crippled output

ripgrep must produce standard output.

Again, what standard?

I don't consider clicking on a search result and being taken to a random point in the file (as will happen if the editor remembers last opened position) or the top of the file working by default.

Then, as you're fond of saying, change your settings. Or continue to use hyperlinked_grep. Just don't break it for other people.

You mean you and your input unsanitizing, crippled terminal.

You are adding the feature wrong.

This is your opinion. I've heard it. I just don't agree with it.

Thanks for your feedback.

You are most welcome.

@ltrzesniewski
Copy link
Contributor Author

That discussion leads to nowhere. Now please stop insulting me and stick to your word:

You wont be hearing from me again.

@BurntSushi
Copy link
Owner

@kovidgoyal You are coming across as pretty agressive and it is a VERY POOR way to get your point across. Stop it or you will no longer be welcome here.

The overall temperature of this conversation should be reduced considerably. There is no reason for it to be heated.

@kovidgoyal
Copy link

Sure, happy to leave. I dont know why I bothered. Good luck.

@ltrzesniewski
Copy link
Contributor Author

ltrzesniewski commented Oct 29, 2022

I think this should now be ready for a first review, but I'm keeping the PR marked as draft as it can't be merged yet:

  • The termcolor feature needs to be approved/merged/released first.
  • I commented out a regression test temporarily until you decide if you'd like to add a --hyperlinks switch or similar.

Also, sorry for the drama in this thread.

# Conflicts:
#	Cargo.lock
#	crates/printer/Cargo.toml
This ensures the termcolor version from my other PR is available.

BurntSushi/termcolor#65
@ltrzesniewski
Copy link
Contributor Author

Superseded by #2483

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

Successfully merging this pull request may close these issues.

Option to print file paths as file URLs
3 participants