sharkdp / fd

A simple, fast and user-friendly alternative to 'find'
Apache License 2.0
33.61k stars 803 forks source link

Add hyperlink support to fd #1571

Closed tmccombs closed 2 months ago

tmccombs commented 3 months ago

Fixes: #1295 Fixes: #1563

sharkdp commented 3 months ago

Thank you! Should we maybe make this an option instead of a flag, to avoid future breaking changes in case we see the need for e.g. --color=never --hyperlink=always or potentially other ways of printing hyperlinks?

097115 commented 3 months ago

Something wrong happens if a filename contains non-latin characters.

097115 commented 3 months ago

@tmccombs This latest commit seems to fix the bug with non-latin chars, thanks :)

dandavison commented 2 months ago

Hi, this is a great development, but I think that it would be very valuable to allow more customization of the format of the hyperlink. For example, in my case I'd like to be able to specify the protocol (e.g. vscode://file/... instead of file://). I think that we could re-use a lot of the design work (and some code maybe?) that was done for ripgrep in https://github.com/BurntSushi/ripgrep/pull/2483.

Here's the current full text of the entry for --hyperlink-format=FORMAT in rg --help:

`rg --help` output
    --hyperlink-format=FORMAT
        Set the format of hyperlinks to use when printing results. Hyperlinks
        make certain elements of ripgrep's output, such as file paths,
        clickable. This generally only works in terminal emulators that support
        OSC-8 hyperlinks. For example, the format file://{host}{path} will emit
        an RFC 8089 hyperlink. To see the format that ripgrep is using, pass
        the --debug flag.

        Alternatively, a format string may correspond to one of the following
        aliases: default, none, file, grep+, kitty, macvim, textmate, vscode,
        vscode-insiders, vscodium. The alias will be replaced with a format
        string that is intended to work for the corresponding application.

        The following variables are available in the format string:

        {path}: Required. This is replaced with a path to a matching file. The
        path is guaranteed to be absolute and percent encoded such that it is
        valid to put into a URI. Note that a path is guaranteed to start with a
        /.

        {host}: Optional. This is replaced with your system's hostname. On
        Unix, this corresponds to calling gethostname. On Windows, this
        corresponds to calling GetComputerNameExW to fetch the system's
        "physical DNS hostname." Alternatively, if --hostname-bin was provided,
        then the hostname returned from the output of that program will be
        returned. If no hostname could be found, then this variable is replaced
        with the empty string.

        {line}: Optional. If appropriate, this is replaced with the line number
        of a match. If no line number is available (for example, if
        --no-line-number was given), then it is automatically replaced with the
        value 1.

        {column}: Optional, but requires the presence of {line}. If
        appropriate, this is replaced with the column number of a match. If no
        column number is available (for example, if --no-column was given),
        then it is automatically replaced with the value 1.

        {wslprefix}: Optional. This is a special value that is set to
        wsl$/WSL_DISTRO_NAME, where WSL_DISTRO_NAME corresponds to the value of
        the equivalent environment variable. If the system is not Unix or if
        the WSL_DISTRO_NAME environment variable is not set, then this is
        replaced with the empty string.

        A format string may be empty. An empty format string is equivalent to
        the none alias. In this case, hyperlinks will be disabled.

        At present, ripgrep does not enable hyperlinks by default. Users must
        opt into them. If you aren't sure what format to use, try default.

        Like colors, when ripgrep detects that stdout is not connected to a
        tty, then hyperlinks are automatically disabled, regardless of the
        value of this flag. Users can pass --color=always to forcefully emit
        hyperlinks.

        Note that hyperlinks are only written when a path is also in the output                                                                                                                    11:55:48 [409/3626]
        and colors are enabled. To write hyperlinks without colors, you'll need
        to configure ripgrep to not colorize anything without actually
        disabling all ANSI escape codes completely:

            --colors 'path:none' \
            --colors 'line:none' \
            --colors 'column:none' \
            --colors 'match:none'

        ripgrep works this way because it treats the --color flag as a proxy
        for whether ANSI escape codes should be used at all. This means that
        environment variables like NO_COLOR=1 and TERM=dumb not only disable
        colors, but hyperlinks as well. Similarly, colors and hyperlinks are
        disabled when ripgrep is not writing to a tty. (Unless one forces the
        issue by setting --color=always.)

        If you're searching a file directly, for example:

            rg foo path/to/file

        then hyperlinks will not be emitted since the path given does not
        appear in the output. To make the path appear, and thus also a
        hyperlink, use the -H/--with-filename flag.

        For more information on hyperlinks in terminal emulators, see:
        https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda        
tmccombs commented 2 months ago

It's sort of possible to do that today using the --format option. That is, you could do something like:

fd --absolute-path --format $'\e]8;;vscode://file/{}\e\\{}\e]8;;\e\\' ...

I'm not completely opposed to implement multiple formats, but I didn't want to add that level of complexity in the initial implementation.

dandavison commented 2 months ago

Thanks @tmccombs, I've moved this discussion to the issue: https://github.com/sharkdp/fd/issues/1563