Skip to content

Commit

Permalink
feat(remote): support multiple remotes (origin/upstream) (#166)
Browse files Browse the repository at this point in the history
feat(command): support command args complete suggestions
  • Loading branch information
linrongbin16 committed Dec 1, 2023
1 parent f0e4c6f commit bbab7ba
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 34 deletions.
4 changes: 4 additions & 0 deletions .nvim.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
vim.opt.tabstop = 2
vim.opt.softtabstop = 2
vim.opt.shiftwidth = 2

33 changes: 22 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ There're two **routers** provided:
- `browse`: generate the `/blob` urls (default router), also work for other git host websites, e.g. generate `/src` for bitbucket.org.
- `blame`: generate the `/blame` urls, also work for other git host websites, e.g. generate `/annotate` for bitbucket.org.

By default `GitLink` will use the first detected remote (`origin`), but if you need to specify other remotes with `remote=xxx` arguments. For example `upstream`, please use:

- `GitLink remote=upstream`: copy upstream url to clipboard.
- `GitLink! remote=upstream`: open upstream url in browser.

<details>
<summary><i>Click here to see recommended key mappings</i></summary>
<br/>
Expand Down Expand Up @@ -273,7 +278,11 @@ To create your own highlighting, please use below config before setup this plugi

```lua
-- lua
vim.api.nvim_set_hl( 0, "NvimGitLinkerHighlightTextObject", { link = "Constant" })
vim.api.nvim_set_hl(
0,
"NvimGitLinkerHighlightTextObject",
{ link = "Constant" }
)
```

```vim
Expand Down Expand Up @@ -306,11 +315,11 @@ require('gitlinker').setup({

You can directly use below builtin APIs:

- `github_browse`/`github_blame`: for [github.com](https://github.com/).
- `gitlab_browse`/`gitlab_blame`: for [gitlab.com](https://gitlab.com/).
- `bitbucket_browse`/`bitbucket_blame`: for [bitbucket.org](https://bitbucket.org/).
- `codeberg_browse`/`codeberg_blame`: for [codeberg.org](https://codeberg.org/).
- `samba_browse`: for [git.samba.org](https://git.samba.org/) (blame not support).
- `github_browse`/`github_blame`: for github.com.
- `gitlab_browse`/`gitlab_blame`: for gitlab.com.
- `bitbucket_browse`/`bitbucket_blame`: for bitbucket.org.
- `codeberg_browse`/`codeberg_blame`: for codeberg.org.
- `samba_browse`: for git.samba.org (blame not support).

### Fully Customize Urls

Expand Down Expand Up @@ -398,7 +407,7 @@ The available variables are the same with the `lk` parameter passing to hook fun
- `_A.HOST`: `github.com`, `gitlab.com`, `bitbucket.org`, etc.
- `_A.USER`: `linrongbin16` (for this plugin), `neovim` (for [neovim](https://github.com/neovim/neovim)), etc.
- `_A.REPO`: `gitlinker.nvim`, `neovim`, etc.
- **Note:** for easier writing, the `.git` suffix has been removed.
- **Note:** for easier writing, the `.git` suffix is been removed.
- `_A.REV`: git commit, e.g. `dbf3922382576391fbe50b36c55066c1768b08b6`.
- `_A.DEFAULT_BRANCH`: git default branch, `master`, `main`, etc, retrieved from `git rev-parse --abbrev-ref origin/HEAD`.
- `_A.CURRENT_BRANCH`: git current branch, `feat-router-types`, etc, retrieved from `git rev-parse --abbrev-ref HEAD`.
Expand Down Expand Up @@ -426,7 +435,7 @@ protocol host user repo file rev
The difference is: the main repo doesn't have the `user` component, it's just `https://git.samba.org/?p=samba.git`. To support such case, `user` and `repo` components have a little bit different when facing the main repo:

- `lk.user` (`_A.USER`): the value is `` (empty string).
- `lk.repo` (`_A.REPO`): the value is `samba.git`.
- `lk.repo` (`_A.REPO`): the value is `samba.git` (`_A.REPO` value is `samba`, the `.git` suffix is been removed for easier writing url template).

### More Router Types

Expand Down Expand Up @@ -465,8 +474,10 @@ require("gitlinker").setup({
Then use it just like `blame`:

```vim
GitLink default_branch
GitLink current_branch
GitLink default_branch " copy default branch to clipboard
GitLink! default_branch " open default branch in browser
GitLink current_branch " copy current branch to clipboard
GitLink! current_branch " open current branch in browser
```

## Highlight Group
Expand All @@ -492,7 +503,7 @@ Then test with `vusted ./test`.

## Contribute

Please also open [issue](https://github.com/linrongbin16/gitlinker.nvim/issues)/[PR](https://github.com/linrongbin16/gitlinker.nvim/pulls) for anything about gitlinker.nvim.
Please open [issue](https://github.com/linrongbin16/gitlinker.nvim/issues)/[PR](https://github.com/linrongbin16/gitlinker.nvim/pulls) for anything about gitlinker.nvim.

Like gitlinker.nvim? Consider

Expand Down
76 changes: 55 additions & 21 deletions lua/gitlinker.lua
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ local function _worker(lk, p, r)
end
end

--- @alias gitlinker.Router fun(lk:gitlinker.Linker):string
--- @alias gitlinker.Router fun(lk:gitlinker.Linker):string?
--- @param router_type string
--- @param lk gitlinker.Linker
--- @return string?
Expand Down Expand Up @@ -372,12 +372,12 @@ local function _blame(lk)
return _router("blame", lk)
end

--- @param opts {action:gitlinker.Action,router:gitlinker.Router,lstart:integer,lend:integer}
--- @param opts {action:gitlinker.Action?,router:gitlinker.Router,lstart:integer,lend:integer,remote:string?}
--- @return string?
local function link(opts)
-- logger.debug("[link] merged opts: %s", vim.inspect(opts))

local lk = linker.make_linker()
local lk = linker.make_linker(opts.remote)
if not lk then
return nil
end
Expand All @@ -391,11 +391,13 @@ local function link(opts)
vim.inspect(url),
vim.inspect(opts.router)
)
logger.ensure(
assert(
ok and type(url) == "string" and string.len(url) > 0,
"fatal: failed to generate permanent url from remote url (%s): %s",
vim.inspect(lk.remote_url),
vim.inspect(url)
string.format(
"fatal: failed to generate permanent url from remote (%s): %s",
vim.inspect(lk.remote_url),
vim.inspect(url)
)
)

if opts.action then
Expand Down Expand Up @@ -496,6 +498,29 @@ local function _merge_routers(opts)
return result
end

--- @param args string?
--- @return {router_type:string,remote:string?}
local function _parse_args(args)
args = args or ""

local router_type = "browse"
local remote = nil
if string.len(args) == 0 then
return { router_type = router_type, remote = remote }
end
local args_splits = vim.split(args, " ", { plain = true, trimempty = true })
for _, a in ipairs(args_splits) do
if string.len(a) > 0 then
if utils.string_startswith(a, "remote=") then
remote = a:sub(8)
else
router_type = a
end
end
end
return { router_type = router_type, remote = remote }
end

--- @param opts gitlinker.Options?
local function setup(opts)
local merged_routers = _merge_routers(opts or {})
Expand All @@ -514,7 +539,7 @@ local function setup(opts)
-- command
vim.api.nvim_create_user_command(Configs.command.name, function(command_opts)
local r = range.make_range()
local parsed_args = (
local args = (
type(command_opts.args) == "string"
and string.len(command_opts.args) > 0
)
Expand All @@ -523,30 +548,39 @@ local function setup(opts)
logger.debug(
"command opts:%s, parsed:%s, range:%s",
vim.inspect(command_opts),
vim.inspect(parsed_args),
vim.inspect(args),
vim.inspect(r)
)
local lstart =
math.min(r.lstart, r.lend, command_opts.line1, command_opts.line2)
local lend =
math.max(r.lstart, r.lend, command_opts.line1, command_opts.line2)
local router_type = type(parsed_args) == "string"
and string.len(parsed_args) > 0
and parsed_args
or "browse"
local router = function(lk)
return _router(router_type, lk)
end
local action = require("gitlinker.actions").clipboard
if command_opts.bang then
action = require("gitlinker.actions").system
end
link({ action = action, router = router, lstart = lstart, lend = lend })
local parsed = _parse_args(args)
link({
action = command_opts.bang and require("gitlinker.actions").system
or require("gitlinker.actions").clipboard,
router = function(lk)
return _router(parsed.router_type, lk)
end,
lstart = lstart,
lend = lend,
remote = parsed.remote,
})
end, {
nargs = "*",
range = true,
bang = true,
desc = Configs.command.desc,
complete = function()
local suggestions = {}
for router_type, _ in pairs(Configs._routers) do
table.insert(suggestions, router_type)
end
table.sort(suggestions, function(a, b)
return a < b
end)
return suggestions
end,
})

if type(Configs.mapping) == "table" then
Expand Down
6 changes: 4 additions & 2 deletions lua/gitlinker/linker.lua
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,16 @@ local function _parse_remote_url(remote_url)
end

--- @alias gitlinker.Linker {remote_url:string,protocol:string,host:string,host_delimiter:string,user:string,repo:string?,rev:string,file:string,lstart:integer,lend:integer,file_changed:boolean,default_branch:string?,current_branch:string?}
--- @param remote string?
--- @return gitlinker.Linker?
local function make_linker()
local function make_linker(remote)
local root = git.get_root()
if not root then
return nil
end

local remote = git.get_branch_remote()
remote = (type(remote) == "string" and string.len(remote) > 0) and remote
or git.get_branch_remote()
if not remote then
return nil
end
Expand Down

0 comments on commit bbab7ba

Please sign in to comment.