nvim-telescope/telescope.nvim

handling fugitive links in quickfix

name-snrl opened this issue · 12 comments

Is your feature request related to a problem? Please describe.
Yes, for the fugitive:// files, preview and path_display don't work. You can check it bv running :G difftool <hash> <hash>.

Describe the solution you'd like
The vim-fugitive provides the FugitiveParse() function, which returns a list that containing commit_hash:relative_path and git_dir strings. We can use this to display a more informative entries.

It also has fugitive#BufReadCmd(), this function is run by autocmd when you open a buffer to fill it with a file from a particular commit. I'm not very familiar with vimL, but as I understand it, it just calls git cat-file or git show under the hood. I also don't know much about both, fugitive and telescope, to say which is a better way to fix the preview using this function, or write our own that will call git commands.

Is this a bug?
And which telescope picker are you using for this interaction with fugitive?

For path_display, we explicitly don't handle URIs like fugitive:// and I don't think we would change this. I'd have to think about previews a bit.

Is this a bug?

No, I create issue about feature request.

And which telescope picker are you using for this interaction with fugitive?

Quickfix. G difftool loads the diff files into quickfix, and then when I open telescope quickfix, I see this:

image

without preview

image

instead of something like this

image

My cfg:

    defaults = {
      scroll_strategy = 'limit',
      layout_strategy = 'bottom_pane',
      layout_config = {
        bottom_pane = {
          height = 15, -- TODO
          prompt_position = 'bottom',
        },
      },
      border = false,
      path_display = { truncate = 5 }, --TODO
      borderchars = { '', '', '', '', '', '', '', '' }, -- TODO
      dynamic_preview_title = true,
    }

For path_display, we explicitly don't handle URIs like fugitive:// and I don't think we would change this

Bad news for me. That's the main reason I created this issue. Without I just can't see which file I choose, It makes telescope unusable in this case.

I'm honestly surprised support for this wasn't added earlier, I seemed vim-fugitive is very popular.

What if I implement this on my own in my spare time, can it be combined?

Problem is, URIs come in variety of types and figuring out which are usable as path (ideally for a local file - we probably won't support fetching non-local files for preview purposes) could be tricky.

      https://www.example.com/index.html
      ftp://ftp.example.com/files/document.pdf
      mailto:user@example.com
      tel:+1234567890
      file:///home/user/documents/report.docx
      news:comp.lang.python
      ldap://ldap.example.com:389/dc=example,dc=com
      git://github.com/user/repo.git
      steam://run/123456
      magnet:?xt=urn:btih:6B4C3343E1C63A1BC36AEB8A3D1F52C4EDEEB096

Probably obviously the file:// prefix should work. But I'd need to study the URI spec more if any URI starting with <word>:/// is a valid file path we can use.
If so, I think we can utilize this to handle path_display and previews.

If you or anyone else has thoughts, I'm open to them.

Oh I just had a quick idea, I think there's something like vim.uri_to_fname. Could probably use that.

figuring out which are usable as path

As I said, we can use vim.fn.FugitiveParse() to do this. For example, I have something like this on my quickfix list.

fugitive:///home/name_snrl/nixos-configuration/.git//4f3ae7ef3c36f06ecf1c9c467de8e0e7ca117031/hosts/liveCD/default.nix:21:0:

this output of :lua lua =vim.fn.FugitiveParse('fugitive:///home/name_snrl/nixos-configuration/.git//4f3ae7ef3c36f06ecf1c9c467de8e0e7ca117031/hosts/liveCD/default.nix')

{ "4f3ae7ef3c36f06ecf1c9c467de8e0e7ca117031:hosts/liveCD/default.nix", "/home/name_snrl/nixos-configuration/.git" }

Now we just need to truncate the hash to 7 characters and show it to the user:

4f3ae7e:hosts/liveCD/default.nix

ideally for a local file - we probably won't support fetching non-local files

We are talking about files in git, I don't think they are stored as plain files in the git directory, but we can easily use the output of FugitiveParse as arguments to git show:

git --git-dir=/home/name_snrl/nixos-configuration/.git show 4f3ae7ef3c36f06ecf1c9c467de8e0e7ca117031:hosts/liveCD/default.nix

The only thing I'm not sure about is that we should use git show or git cat-file to preview. How exactly vim-fugitive does this we can find in this function, if my understanding of the codebase is correct

https://github.com/tpope/vim-fugitive/blob/c0b03f1cac242d96837326d300f42a660306fc1a/autoload/fugitive.vim#L3115-L3245

or ask @tpope

This isn't exclusively a fugitive issue though. It's a general issue with how telescope handles file path type URIs. So I don't really want a fugitive specific solution.

This isn't exclusively a fugitive issue though

I apologize, I misunderstood you. In any case, I don't think there can be one single solution that will also cover fugitive URI.

Going back to the previous question, if I implement what I described above through a matching for a fugitive URI, will it merge?

This isn't exclusively a fugitive issue though. It's a general issue with how telescope handles file path type URIs. So I don't really want a fugitive specific solution.

Fugitive does offer an API that attempts to fulfill these requirements. Take the scheme of the URL (fugitive), look for a Vim global variable named like g:<scheme>_io (g:fugitive_io), and confirm it's a dictionary. The keys of the dictionary are built-in Vim IO functions (getftype, readfile, etc.) and the values are functions that implement that behavior for the URLs.

So preview could conceivably be backed by g:fugitive_io.readfile(bufname), but without fugitive needing to appear anywhere in the implementation.

Wouldn't this still require all plugins telescope interacts with that uses file URIs support a similar io_<scheme> API?
I'm not aware of this being some sort of common API protocol. I just recently had a similar issue with oil.nvim using oil as the scheme and io_<scheme> would not help for this particular case.

Reason why vim.uri_to_fname doesn't work is that it expects the scheme to be file according to rfc8089 I believe.

Wouldn't this still require all plugins telescope interacts with that uses file URIs support a similar io_<scheme> API? I'm not aware of this being some sort of common API protocol.

Yes, any solution would require some sort of common API. This is the only one I'm aware of that's been designed. Mirroring the Vim API means it's not designed with Fugitive's needs in mind; it covers everything Vim can do (Neovim specific APIs not withstanding).

I just recently had a similar issue with oil.nvim using oil as the scheme and io_<scheme> would not help for this particular case.

oil.nvim is free to implement it. Might make sense to extend it to readdir().