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

Request: Opposite of :GBrowse #2223

Open
markis opened this issue Feb 10, 2022 · 8 comments
Open

Request: Opposite of :GBrowse #2223

markis opened this issue Feb 10, 2022 · 8 comments

Comments

@markis
Copy link

markis commented Feb 10, 2022

I would like to take a url and navigate to the file. Given a github url, then vim would open the file and potentially go the line that's being highlighted in the url.

For example, if I had this repo open and I executed a command such as :GBrowse https://github.com/tpope/vim-rhubarb/blob/master/autoload/rhubarb.vim#L2. Then vim would open autoload/rhubarb.vim and go to line 2.

@markis markis changed the title Opposite of :GBrowse Request: Opposite of :GBrowse Feb 10, 2022
@tpope
Copy link
Owner

tpope commented Feb 11, 2022

I too have wanted this, but it's a lot easier said than done. For starters, parsing the URL is nontrivial. Is the example you gave for autoload/rhubarb.vim on branch master, or is it for rhubarb.vim on branch master/autoload? If all we have is the URL, it's impossible to tell the difference. If we have the corresponding repository on disk, we can figure it out by looking at .git/refs/origin/master and checking if it's a file or directory, although that won't work if the branch is newer than the last time the repo was fetched, plus I imagine there are edge cases around packed refs. Alternatively, we could try talking to the repository directly, but we might not know how how to authenticate.

But even if we solve that, or just ignore nested refs, that's just the first challenge of many. How do we find the repository on disk? What's the user interface? What lives in Rhubarb, what lives in Fugitive, and what lives in a hypothetical new plugin? How do these plugins talk to each other?

I don't see working on this in the foreseeable future. And unfortunately, I don't really have much advice to give for someone attempting to tackle this themselves. I suppose one could start with the "find on disk" problem, as that will probably dictate much of the rest of the design.

@odnoletkov
Copy link
Sponsor Contributor

FWIW the workaround I use for this is navigating through some related commit. It is easy to grab hash for some commit touching the file on Github – i.e. last commit modified the file is displayed in the header. Then I :Gedit <commit> in Vim, find the file there, <CR> to jump to the file blob and :Gedit to finally jump to the actual file.

It's many steps and does not solve jumping to a specific line – but I find it easier and more reliable than manually extracting file path from URL

@brasic
Copy link

brasic commented Jun 10, 2022

@tpope @markis I came across this issue and wanted to let you know that there is an undocumented API for the ref/path disambiguation part (I work at GitHub but am not speaking on behalf of the company, just a happy fugitive/rhubarb user)

$ gh api repos/rails/rails/git/extract-ref/matthewd/inotify/tools/test.rb
{
  "name_with_owner": "rails/rails",
  "ref": "matthewd/inotify",
  "path": "tools/test.rb"
}

This could likely be promoted to a supported API if someone expressed interest. In terms of figuring out which repo to open, why not just assume the path is for the repo opened by the current buffer?

@tpope
Copy link
Owner

tpope commented Jun 11, 2022

This could likely be promoted to a supported API if someone expressed interest.

Color me interested. Ideally it would also include the commit SHA, to save us a second request, but even without that it's perfectly adequate to solve the problem at hand.

In terms of figuring out which repo to open, why not just assume the path is for the repo opened by the current buffer?

Verify, not assume, but this would be an adequate starting point, yes.

@tpope
Copy link
Owner

tpope commented Jun 11, 2022

Related, could someone save me the trouble and tell me the API for converting a ref to a commit SHA? We could get it from git ls-remote but an API would be easier as we're already set up to handle that.

@brasic
Copy link

brasic commented Jun 12, 2022

That would be this one.

@tpope
Copy link
Owner

tpope commented Jun 12, 2022

The git/refs endpoint expects a ref qualified with tags/ or heads/, while git/extract-ref gives a bare ref with no such qualification. How can we square this circle?

@tpope tpope transferred this issue from tpope/vim-rhubarb Oct 7, 2023
tpope added a commit that referenced this issue Oct 29, 2023
Use `:Gedit https://github.com/...` (or any other URL supported by an
installed :GBrowse provider) to edit the corresponding `fugitive://`
URL.  The dictionary g:fugitive_url_origins maps between homepage URLs
and local repositories:

	let g:fugitive_url_origins = {
	      'https://github.com/me/my-repo': '~/Projects/my-repo'}

It also checks the remotes of the repository that the currently edited
buffer belongs to.

This is an experimental prototype.  That means no documentation, and no
guarantees about behavior.  In particular, g:fugitive_url_origins and
the current contortions to leverage the existing :GBrowse API will
likely be dropped once a better API has been developed.

References: #2223
@tpope
Copy link
Owner

tpope commented Oct 29, 2023

Not long after my last comment I prototyped this, settling on git ls-remote to get around the aforementioned limitation of the GitHub API, which also has the advantage that it can live Fugitive side. In fact with the approach I took the whole thing can live Fugitive side, supporting all :GBrowse adapters in one fell swoop. But said approach is messy, basically brute forcing every possible URL variant out of every installed adapter, so I decided to sit on it until I could retool the API.

Over a year later, that hasn't happened, so I am shipping the prototype as is in df36d19. The interface is simply to pass the URL to one of Fugitive's edit commands, like :Gedit <url> or :Gdrop <url>. It targets the currently open repository or you can use the configuration mechanism (subject to change) explained in the commit message.

A big limitation of using edit commands as an interface is that if you give it an unrecognized URL, it silently falls back to using netrw to edit the raw HTML, which is annoying to say the least. This is something a new API could address, as that would allow the adapter to recognize arbitrary URLs from a provider without knowledge of the specific repository. (I don't want to throw out the netrw fallback entirely.)

I'll leave this issue open until it's officially supported and documented.

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

No branches or pull requests

4 participants