From 3f33c47e0f9cc976ce14e52865b7ee3a8462a941 Mon Sep 17 00:00:00 2001 From: linrongbin16 Date: Tue, 23 Apr 2024 09:46:21 +0800 Subject: [PATCH] feat(command): add 'file' and 'rev' parameters (#238) --- .github/PULL_REQUEST_TEMPLATE.md | 1 + .github/workflows/ci.yml | 6 ++---- .gitignore | 4 ++++ README.md | 22 +++++++++++++++++++--- lua/gitlinker.lua | 30 ++++++++++++++++++++++++------ lua/gitlinker/commons/_system.lua | 3 +++ 6 files changed, 53 insertions(+), 13 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 8c36c6ee..3b7f5b0c 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -23,3 +23,4 @@ - [ ] Copy git link in a symlink directory of git repo. - [ ] Copy git link in an un-pushed git branch, and receive an expected error. - [ ] Copy git link in a pushed git branch but edited file, and receive a warning says the git link could be wrong. +- [ ] Copy git link with 'file' and 'rev' parameters. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2d913a7..ab4565df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,12 +29,10 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} version: latest args: --config-path .stylua.toml ./lua ./spec - - uses: stevearc/nvim-typecheck-action@v1 + - uses: mrcjkb/lua-typecheck-action@v0 with: - path: lua - level: Warning + directories: lua configpath: ".luarc.json" - neodev-version: stable - uses: cargo-bins/cargo-binstall@main - name: Selene run: | diff --git a/.gitignore b/.gitignore index 748eabfd..b85af1ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ .luacheckcache +service.log +stderr.txt +stdout.txt +*nvim_gitlinker.nvim_lua.log diff --git a/README.md b/README.md index 1000a5e3..b32ead37 100644 --- a/README.md +++ b/README.md @@ -134,11 +134,25 @@ There're several **router types**: To specify the remote when there're multiple git remotes, add `remote=xxx` parameter, for example: -- `GitLink remote=upstream`: copy `blob` url to clipboard for the `upstream` remote. -- `GitLink! blame remote=upstream`: open `blame` url in browser for the `upstream` remote. +- `GitLink remote=upstream`: copy url for the `upstream` remote. +- `GitLink! blame remote=upstream`: open blame url for the `upstream` remote. > By default `GitLink` will use the first detected remote (usually it's `origin`). +To specify the relative file path when current buffer's file path is not a normal file name, add `file=xxx` parameter, for example: + +- `GitLink file=lua/gitlinker.lua`: copy url for the `lua/gitlinker.lua` file. +- `GitLink! blame file=README.md`: open blame url for the `README.md` file. + +> By default `GitLink` will use the current buffer's file name. + +To specify the git commit ID when current repository's commit ID is not on your needs, add `rev=xxx` parameter, for example: + +- `GitLink rev=00b3f9a1`: copy url for the `00b3f9a1` commit ID. +- `GitLink! blame rev=00b3f9a1`: open blame url for the `00b3f9a1` commit ID. + +> By default `GitLink` will use the current repository's commit ID. + ### API > [!NOTE] @@ -155,7 +169,7 @@ You can also use the `link` API to generate git permlink: --- @alias gitlinker.Linker {remote_url:string,protocol:string?,username:string?,password:string?,host:string,port:string?,org:string?,user:string?,repo:string,rev:string,file:string,lstart:integer,lend:integer,file_changed:boolean,default_branch:string?,current_branch:string?} --- @alias gitlinker.Router fun(lk:gitlinker.Linker):string? --- @alias gitlinker.Action fun(url:string):any ---- @param opts {router_type:string?,router:gitlinker.Router?,action:gitlinker.Action?,lstart:integer?,lend:integer?,message:boolean?,highlight_duration:integer?,remote:string?}? +--- @param opts {router_type:string?,router:gitlinker.Router?,action:gitlinker.Action?,lstart:integer?,lend:integer?,message:boolean?,highlight_duration:integer?,remote:string?,file:string?,rev:string?}? require("gitlinker").link(opts) ``` @@ -187,6 +201,8 @@ require("gitlinker").link(opts) - `message`: Whether print message in nvim command line. By default it uses the configured value while this plugin is been setup (see [Configuration](#configuration)). You can also overwrite this field to change the configured behavior. - `highlight_duration`: How long (milliseconds) to highlight the line range. By default it uses the configured value while this plugin is been setup (see [Configuration](#configuration)). You can also overwrite this field to change the configured behavior. - `remote`: Specify the git remote. By default is `nil`, it uses the first detected git remote (usually it's `origin`). + - `file`: Specify the relative file path. By default is `nil`, it uses the current buffer's file name. + - `rev`: Specify the git commit ID. By default is `nil`, it uses the current repository's git commit ID. ##### `gitlinker.Router` diff --git a/lua/gitlinker.lua b/lua/gitlinker.lua index 2625394d..977c689d 100644 --- a/lua/gitlinker.lua +++ b/lua/gitlinker.lua @@ -200,7 +200,7 @@ local function _blame(lk) return _router("blame", lk) end ---- @param opts {action:gitlinker.Action|boolean,router:gitlinker.Router,lstart:integer,lend:integer,message:boolean?,highlight_duration:integer?,remote:string?} +--- @param opts {action:gitlinker.Action|boolean,router:gitlinker.Router,lstart:integer,lend:integer,message:boolean?,highlight_duration:integer?,remote:string?,file:string?,rev:string?} local _link = function(opts) local confs = configs.get() local logger = logging.get("gitlinker") @@ -213,6 +213,14 @@ local _link = function(opts) lk.lstart = opts.lstart lk.lend = opts.lend + if str.not_empty(opts.file) then + lk.file = opts.file + lk.file_changed = false + end + if str.not_empty(opts.rev) then + lk.rev = opts.rev + end + async.scheduler() local ok, url = pcall(opts.router, lk, true) -- logger:debug( @@ -264,30 +272,36 @@ local _link = function(opts) return url end ---- @type fun(opts:{action:gitlinker.Action?,router:gitlinker.Router,lstart:integer,lend:integer,remote:string?}):string? +--- @type fun(opts:{action:gitlinker.Action?,router:gitlinker.Router,lstart:integer,lend:integer,remote:string?,file:string?,rev:string?}):string? local _void_link = async.void(_link) --- @param args string? ---- @return {router_type:string,remote:string?} +--- @return {router_type:string,remote:string?,file:string?,rev:string?} local function _parse_args(args) args = args or "" local router_type = "browse" local remote = nil + local file = nil + local rev = nil if string.len(args) == 0 then - return { router_type = router_type, remote = remote } + return { router_type = router_type, remote = remote, file = file, rev = rev } 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 str.startswith(a, "remote=") then remote = a:sub(8) + elseif str.startswith(a, "file=") then + file = a:sub(6) + elseif str.startswith(a, "rev=") then + rev = a:sub(5) else router_type = a end end end - return { router_type = router_type, remote = remote } + return { router_type = router_type, remote = remote, file = file, rev = rev } end --- @param opts gitlinker.Options? @@ -327,6 +341,8 @@ local function setup(opts) lstart = lstart, lend = lend, remote = parsed.remote, + file = parsed.file, + rev = parsed.rev, }) end, { nargs = "*", @@ -354,7 +370,7 @@ local function setup(opts) end end ---- @param opts {router_type:string?,router:gitlinker.Router?,action:gitlinker.Action?,lstart:integer?,lend:integer?,message:boolean?,highlight_duration:integer?,remote:string?}? +--- @param opts {router_type:string?,router:gitlinker.Router?,action:gitlinker.Action?,lstart:integer?,lend:integer?,message:boolean?,highlight_duration:integer?,remote:string?,file:string?,rev:string?}? local function link_api(opts) opts = opts or { @@ -384,6 +400,8 @@ local function link_api(opts) message = opts.message, highlight_duration = opts.highlight_duration, remote = opts.remote, + file = opts.file, + rev = opts.rev, }) end diff --git a/lua/gitlinker/commons/_system.lua b/lua/gitlinker/commons/_system.lua index acf7214c..684bc90e 100644 --- a/lua/gitlinker/commons/_system.lua +++ b/lua/gitlinker/commons/_system.lua @@ -19,6 +19,7 @@ local uv = vim.uv or vim.loop --- @field stderr? string --- @class vim.SystemState +--- @field cmd string[] --- @field handle? uv.uv_process_t --- @field timer? uv.uv_timer_t --- @field pid? integer @@ -57,6 +58,7 @@ local function close_handles(state) end --- @class vim.SystemObj +--- @field cmd string[] --- @field pid integer --- @field private _state vim.SystemState --- @field wait fun(self: vim.SystemObj, timeout?: integer): vim.SystemCompleted @@ -69,6 +71,7 @@ local SystemObj = {} --- @return vim.SystemObj local function new_systemobj(state) return setmetatable({ + cmd = state.cmd, pid = state.pid, _state = state, }, { __index = SystemObj })