From bc2770109977c0d95117e13113acf17a8aeb8aac Mon Sep 17 00:00:00 2001 From: linrongbin16 Date: Sun, 19 Jan 2025 05:16:43 +0800 Subject: [PATCH] fix(async): revert back to previous version 'async' module (#258) --- .github/ISSUE_TEMPLATE/bug.md | 5 + .github/PULL_REQUEST_TEMPLATE.md | 8 +- lua/gitlinker.lua | 12 +- lua/gitlinker/async.lua | 239 ++++++++++++++++++ lua/gitlinker/commons/{fileio.lua => fio.lua} | 21 +- lua/gitlinker/commons/platform.lua | 2 +- lua/gitlinker/commons/spawn.lua | 134 ++++++++-- lua/gitlinker/commons/version.txt | 2 +- lua/gitlinker/git.lua | 9 +- lua/gitlinker/linker.lua | 6 +- spec/gitlinker/git_spec.lua | 2 +- spec/gitlinker/linker_spec.lua | 2 +- spec/gitlinker_spec.lua | 6 +- 13 files changed, 389 insertions(+), 59 deletions(-) create mode 100644 lua/gitlinker/async.lua rename lua/gitlinker/commons/{fileio.lua => fio.lua} (95%) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 5d234b8a..263dbfc0 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -17,3 +17,8 @@ assignees: "" 3. how do you configure this plugin? It's ... + +4. What's your OS and Neovim version? + + The OS is: Windows 10 x86_64 (Intel/AMD chip), MacOS M1 chip, Ubuntu/Fedora/Arch x86_64 (Intel/AMD chip), ... + The Neovim version (`nvim --version`) is: ... diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3b7f5b0c..0c4ee03a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,12 +1,10 @@ -# Regression Test - -## Platforms +## Test Platforms - [ ] windows - [ ] macOS - [ ] linux -## Hosts +## Test Hosts - [ ] Test on [github.com](https://github.com). - [ ] Test on [gitlab.com](https://gitlab.com). @@ -14,7 +12,7 @@ - [ ] Test on [codeberg.org](https://codeberg.org). - [ ] Test on [git.samba.org](https://git.samba.org). -## Functions +## Test Functions - [ ] Use `GitLink(!)` to copy git link (or open in browser). - [ ] Use `GitLink(!) blame` to copy the `/blame` link (or open in browser). diff --git a/lua/gitlinker.lua b/lua/gitlinker.lua index e203ccc1..ed232f39 100644 --- a/lua/gitlinker.lua +++ b/lua/gitlinker.lua @@ -3,8 +3,8 @@ local str = require("gitlinker.commons.str") local num = require("gitlinker.commons.num") local LogLevels = require("gitlinker.commons.logging").LogLevels local logging = require("gitlinker.commons.logging") -local async = require("gitlinker.commons.async") +local async = require("gitlinker.async") local configs = require("gitlinker.configs") local range = require("gitlinker.range") local linker = require("gitlinker.linker") @@ -221,7 +221,7 @@ local _link = function(opts) lk.rev = opts.rev end - async.schedule() + async.scheduler() local ok, url = pcall(opts.router, lk, true) -- logger:debug( -- "|link| ok:%s, url:%s, router:%s", @@ -273,7 +273,7 @@ local _link = function(opts) end --- @type fun(opts:{action:gitlinker.Action?,router:gitlinker.Router,lstart:integer,lend:integer,remote:string?,file:string?,rev:string?}):string? -local _sync_link = async.sync(1, _link) +local _void_link = async.void(_link) --- @param args string? --- @return {router_type:string,remote:string?,file:string?,rev:string?} @@ -332,7 +332,7 @@ local function setup(opts) 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 parsed = _parse_args(args) - _sync_link({ + _void_link({ action = command_opts.bang and require("gitlinker.actions").system or require("gitlinker.actions").clipboard, router = function(lk) @@ -392,7 +392,7 @@ local function link_api(opts) opts.lend = math.max(r.lstart, r.lend) end - _sync_link({ + _void_link({ action = opts.action, router = opts.router, lstart = opts.lstart, @@ -408,7 +408,7 @@ end local M = { _url_template_engine = _url_template_engine, _worker = _worker, - _sync_link = _sync_link, + _void_link = _void_link, _router = _router, _browse = _browse, _blame = _blame, diff --git a/lua/gitlinker/async.lua b/lua/gitlinker/async.lua new file mode 100644 index 00000000..9f260998 --- /dev/null +++ b/lua/gitlinker/async.lua @@ -0,0 +1,239 @@ +---@diagnostic disable: luadoc-miss-module-name, undefined-doc-name +--- Small async library for Neovim plugins +--- @module async +-- Store all the async threads in a weak table so we don't prevent them from +-- being garbage collected +local handles = setmetatable({}, { __mode = "k" }) +local M = {} +-- Note: coroutine.running() was changed between Lua 5.1 and 5.2: +-- - 5.1: Returns the running coroutine, or nil when called by the main thread. +-- - 5.2: Returns the running coroutine plus a boolean, true when the running +-- coroutine is the main one. +-- +-- For LuaJIT, 5.2 behaviour is enabled with LUAJIT_ENABLE_LUA52COMPAT +-- +-- We need to handle both. +--- Returns whether the current execution context is async. +--- +--- @treturn boolean? +function M.running() + local current = coroutine.running() + if current and handles[current] then + return true + end +end +local function is_Async_T(handle) + if + handle + and type(handle) == "table" + and vim.is_callable(handle.cancel) + and vim.is_callable(handle.is_cancelled) + then + return true + end +end +local Async_T = {} +-- Analogous to uv.close +function Async_T:cancel(cb) + -- Cancel anything running on the event loop + if self._current and not self._current:is_cancelled() then + self._current:cancel(cb) + end +end +function Async_T.new(co) + local handle = setmetatable({}, { __index = Async_T }) + handles[co] = handle + return handle +end +-- Analogous to uv.is_closing +function Async_T:is_cancelled() + return self._current and self._current:is_cancelled() +end +--- Run a function in an async context. +--- @tparam function func +--- @tparam function callback +--- @tparam any ... Arguments for func +--- @treturn async_t Handle +function M.run(func, callback, ...) + vim.validate({ + func = { func, "function" }, + callback = { callback, "function", true }, + }) + local co = coroutine.create(func) + local handle = Async_T.new(co) + local function step(...) + local ret = { coroutine.resume(co, ...) } + local ok = ret[1] + if not ok then + local err = ret[2] + error( + string.format("The coroutine failed with this message:\n%s\n%s", err, debug.traceback(co)) + ) + end + if coroutine.status(co) == "dead" then + if callback then + callback(unpack(ret, 4, table.maxn(ret))) + end + return + end + local nargs, fn = ret[2], ret[3] + local args = { select(4, unpack(ret)) } + assert(type(fn) == "function", "type error :: expected func") + args[nargs] = step + local r = fn(unpack(args, 1, nargs)) + if is_Async_T(r) then + handle._current = r + end + end + step(...) + return handle +end +local function wait(argc, func, ...) + vim.validate({ + argc = { argc, "number" }, + func = { func, "function" }, + }) + -- Always run the wrapped functions in xpcall and re-raise the error in the + -- coroutine. This makes pcall work as normal. + local function pfunc(...) + local args = { ... } + local cb = args[argc] + args[argc] = function(...) + cb(true, ...) + end + xpcall(func, function(err) + cb(false, err, debug.traceback()) + end, unpack(args, 1, argc)) + end + local ret = { coroutine.yield(argc, pfunc, ...) } + local ok = ret[1] + if not ok then + local _, err, traceback = unpack(ret) + error(string.format("Wrapped function failed: %s\n%s", err, traceback)) + end + return unpack(ret, 2, table.maxn(ret)) +end +--- Wait on a callback style function +--- +--- @tparam integer? argc The number of arguments of func. +--- @tparam function func callback style function to execute +--- @tparam any ... Arguments for func +function M.wait(...) + if type(select(1, ...)) == "number" then + return wait(...) + end + -- Assume argc is equal to the number of passed arguments. + return wait(select("#", ...) - 1, ...) +end +--- Use this to create a function which executes in an async context but +--- called from a non-async context. Inherently this cannot return anything +--- since it is non-blocking +--- @tparam function func +--- @tparam number argc The number of arguments of func. Defaults to 0 +--- @tparam boolean strict Error when called in non-async context +--- @treturn function(...):async_t +function M.create(func, argc, strict) + vim.validate({ + func = { func, "function" }, + argc = { argc, "number", true }, + }) + argc = argc or 0 + return function(...) + if M.running() then + if strict then + error("This function must run in a non-async context") + end + return func(...) + end + local callback = select(argc + 1, ...) + return M.run(func, callback, unpack({ ... }, 1, argc)) + end +end +--- Create a function which executes in an async context but +--- called from a non-async context. +--- @tparam function func +--- @tparam boolean strict Error when called in non-async context +function M.void(func, strict) + vim.validate({ func = { func, "function" } }) + return function(...) + if M.running() then + if strict then + error("This function must run in a non-async context") + end + return func(...) + end + return M.run(func, nil, ...) + end +end +--- Creates an async function with a callback style function. +--- +--- @tparam function func A callback style function to be converted. The last argument must be the callback. +--- @tparam integer argc The number of arguments of func. Must be included. +--- @tparam boolean strict Error when called in non-async context +--- @treturn function Returns an async function +function M.wrap(func, argc, strict) + vim.validate({ + argc = { argc, "number" }, + }) + return function(...) + if not M.running() then + if strict then + error("This function must run in an async context") + end + return func(...) + end + return M.wait(argc, func, ...) + end +end +--- Run a collection of async functions (`thunks`) concurrently and return when +--- all have finished. +--- @tparam function[] thunks +--- @tparam integer n Max number of thunks to run concurrently +--- @tparam function interrupt_check Function to abort thunks between calls +function M.join(thunks, n, interrupt_check) + local function run(finish) + if #thunks == 0 then + return finish() + end + local remaining = { select(n + 1, unpack(thunks)) } + local to_go = #thunks + local ret = {} + local function cb(...) + ret[#ret + 1] = { ... } + to_go = to_go - 1 + if to_go == 0 then + finish(ret) + elseif not interrupt_check or not interrupt_check() then + if #remaining > 0 then + local next_task = table.remove(remaining) + next_task(cb) + end + end + end + for i = 1, math.min(n, #thunks) do + thunks[i](cb) + end + end + if not M.running() then + return run + end + return M.wait(1, false, run) +end +--- Partially applying arguments to an async function +--- @tparam function fn +--- @param ... arguments to apply to `fn` +function M.curry(fn, ...) + local args = { ... } + local nargs = select("#", ...) + return function(...) + local other = { ... } + for i = 1, select("#", ...) do + args[nargs + i] = other[i] + end + fn(unpack(args)) + end +end +--- An async function that when called will yield to the Neovim scheduler to be +--- able to call the neovim API. +M.scheduler = M.wrap(vim.schedule, 1, false) +return M diff --git a/lua/gitlinker/commons/fileio.lua b/lua/gitlinker/commons/fio.lua similarity index 95% rename from lua/gitlinker/commons/fileio.lua rename to lua/gitlinker/commons/fio.lua index f76e2a4a..1d2bf72a 100644 --- a/lua/gitlinker/commons/fileio.lua +++ b/lua/gitlinker/commons/fio.lua @@ -21,7 +21,7 @@ function FileLineReader:open(filename, batchsize) if type(handler) ~= "number" then error( string.format( - "|commons.fileio - FileLineReader:open| failed to fs_open file: %s", + "|commons.fio - FileLineReader:open| failed to fs_open file: %s", vim.inspect(filename) ) ) @@ -31,7 +31,7 @@ function FileLineReader:open(filename, batchsize) if type(fstat) ~= "table" then error( string.format( - "|commons.fileio - FileLineReader:open| failed to fs_fstat file: %s", + "|commons.fio - FileLineReader:open| failed to fs_fstat file: %s", vim.inspect(filename) ) ) @@ -67,7 +67,7 @@ function FileLineReader:_read_chunk() if read_err then error( string.format( - "|commons.fileio - FileLineReader:_read_chunk| failed to fs_read file: %s, read_error:%s, read_name:%s", + "|commons.fio - FileLineReader:_read_chunk| failed to fs_read file: %s, read_error:%s, read_name:%s", vim.inspect(self.filename), vim.inspect(read_err), vim.inspect(read_name) @@ -199,12 +199,12 @@ end --- @alias commons.AsyncReadFileOnComplete fun(data:string?):any --- @alias commons.AsyncReadFileOnError fun(step:string?,err:string?):any --- @param filename string ---- @param on_complete commons.AsyncReadFileOnComplete ---- @param opts {trim:boolean?,on_error:commons.AsyncReadFileOnError?}? -M.asyncreadfile = function(filename, on_complete, opts) - opts = opts or { trim = false } - opts.trim = type(opts.trim) == "boolean" and opts.trim or false +--- @param opts {on_complete:commons.AsyncReadFileOnComplete,on_error:commons.AsyncReadFileOnError?,trim:boolean?} +M.asyncreadfile = function(filename, opts) + assert(type(opts) == "table") + assert(type(opts.on_complete) == "function") + opts.trim = type(opts.trim) == "boolean" and opts.trim or false if type(opts.on_error) ~= "function" then opts.on_error = function(step1, err1) error( @@ -240,11 +240,10 @@ M.asyncreadfile = function(filename, on_complete, opts) uv.fs_close(fd --[[@as integer]], function(close_complete_err) if opts.trim and type(data) == "string" then local trimmed_data = vim.trim(data) - on_complete(trimmed_data) + opts.on_complete(trimmed_data) else - on_complete(data) + opts.on_complete(data) end - if close_complete_err then opts.on_error("fs_close complete", close_complete_err) end diff --git a/lua/gitlinker/commons/platform.lua b/lua/gitlinker/commons/platform.lua index 1887dcfc..8c2ca636 100644 --- a/lua/gitlinker/commons/platform.lua +++ b/lua/gitlinker/commons/platform.lua @@ -5,7 +5,7 @@ local os_name = uv.os_uname().sysname local os_name_valid = type(os_name) == "string" and string.len(os_name) > 0 M.OS_NAME = os_name -M.IS_WINDOWS = os_name_valid and os_name:gmatch("Windows") ~= nil +M.IS_WINDOWS = os_name_valid and os_name:match("Windows") ~= nil M.IS_MAC = os_name_valid and os_name:match("Darwin") ~= nil M.IS_BSD = vim.fn.has("bsd") > 0 M.IS_LINUX = os_name_valid and os_name:match("Linux") ~= nil diff --git a/lua/gitlinker/commons/spawn.lua b/lua/gitlinker/commons/spawn.lua index 60d10e3d..c8516f2e 100644 --- a/lua/gitlinker/commons/spawn.lua +++ b/lua/gitlinker/commons/spawn.lua @@ -1,22 +1,30 @@ ----@diagnostic disable local M = {} ---- @alias commons.SpawnLineProcessor fun(line:string):any ---- @alias commons.SpawnOpts {on_stdout:commons.SpawnLineProcessor, on_stderr:commons.SpawnLineProcessor, [string]:any} ---- @alias commons.SpawnOnExit fun(completed:vim.SystemCompleted):nil +--- @alias commons.SpawnOnLine fun(line:string):any +--- @alias commons.SpawnOnExit fun(result:{exitcode:integer?,signal:integer?}?):nil +--- @alias commons.SpawnOpts {on_stdout:commons.SpawnOnLine,on_stderr:commons.SpawnOnLine?,[string]:any} +--- @alias commons.SpawnJob {obj:vim.SystemObj,opts:commons.SpawnOpts,on_exit:commons.SpawnOnExit?} + --- @param cmd string[] ---- @param opts commons.SpawnOpts? by default {text = true} +--- @param opts commons.SpawnOpts? --- @param on_exit commons.SpawnOnExit? ---- @return vim.SystemObj -M.run = function(cmd, opts, on_exit) +--- @return commons.SpawnJob +local function _impl(cmd, opts, on_exit) opts = opts or {} - opts.text = type(opts.text) == "boolean" and opts.text or true - assert(type(opts.on_stdout) == "function") - assert(type(opts.on_stderr) == "function") + if opts.text == nil then + opts.text = true + end + if type(opts.on_stderr) ~= "function" then + opts.on_stderr = function() end + end + + assert(type(opts.on_stdout) == "function", "Spawn job must have 'on_stdout' function in 'opts'") + assert(type(opts.on_stderr) == "function", "Spawn job must have 'on_stderr' function in 'opts'") + assert(type(on_exit) == "function" or on_exit == nil) --- @param buffer string - --- @param fn_line_processor commons.SpawnLineProcessor + --- @param fn_line_processor commons.SpawnOnLine --- @return integer local function _process(buffer, fn_line_processor) local str = require("gitlinker.commons.str") @@ -98,18 +106,98 @@ M.run = function(cmd, opts, on_exit) end end - return vim.system(cmd, { - cwd = opts.cwd, - env = opts.env, - clear_env = opts.clear_env, - ---@diagnostic disable-next-line: assign-type-mismatch - stdin = opts.stdin, - stdout = _handle_stdout, - stderr = _handle_stderr, - text = opts.text, - timeout = opts.timeout, - detach = opts.detach, - }, on_exit) + --- @param completed vim.SystemCompleted + local function _handle_exit(completed) + assert(type(on_exit) == "function") + on_exit({ exitcode = completed.code, signal = completed.signal }) + end + + local obj + if type(on_exit) == "function" then + obj = vim.system(cmd, { + cwd = opts.cwd, + env = opts.env, + clear_env = opts.clear_env, + ---@diagnostic disable-next-line: assign-type-mismatch + stdin = opts.stdin, + stdout = _handle_stdout, + stderr = _handle_stderr, + text = opts.text, + timeout = opts.timeout, + detach = opts.detach, + }, _handle_exit) + else + obj = vim.system(cmd, { + cwd = opts.cwd, + env = opts.env, + clear_env = opts.clear_env, + ---@diagnostic disable-next-line: assign-type-mismatch + stdin = opts.stdin, + stdout = _handle_stdout, + stderr = _handle_stderr, + text = opts.text, + timeout = opts.timeout, + detach = opts.detach, + }) + end + + return { obj = obj, opts = opts, on_exit = on_exit } +end + +--- @param cmd string[] +--- @param opts commons.SpawnOpts? +--- @param on_exit commons.SpawnOnExit +--- @return commons.SpawnJob +M.detached = function(cmd, opts, on_exit) + opts = opts or {} + + assert( + type(opts.on_stdout) == "function", + "Detached spawn job must have 'on_stdout' function in 'opts'" + ) + assert(opts.on_exit == nil, "Detached spawn job cannot have 'on_exit' function in 'opts'") + assert( + type(on_exit) == "function", + "Detached spawn job must have 'on_exit' function in 3rd parameter" + ) + + return _impl(cmd, opts, on_exit) +end + +--- @param cmd string[] +--- @param opts commons.SpawnOpts? +--- @return commons.SpawnJob +M.waitable = function(cmd, opts) + opts = opts or {} + + assert( + type(opts.on_stdout) == "function", + "Waitable spawn job must have 'on_stdout' function in 'opts'" + ) + assert(opts.on_exit == nil, "Waitable spawn job cannot have 'on_exit' function in 'opts'") + + return _impl(cmd, opts) +end + +--- @param job commons.SpawnJob +--- @param timeout integer? +--- @return {exitcode:integer?,signal:integer?} +M.wait = function(job, timeout) + assert(type(job) == "table", "Spawn job must be a 'commons.SpawnJob' object") + assert(job.obj ~= nil, "Spawn job must be a 'commons.SpawnJob' object") + assert(type(job.opts) == "table", "Spawn job must be a 'commons.SpawnJob' object") + assert( + job.on_exit == nil, + "Detached spawn job cannot 'wait' for its exit, it already has 'on_exit' in 3rd parameter for its exit" + ) + + local completed + if type(timeout) == "number" and timeout >= 0 then + completed = job.obj:wait(timeout) --[[@as vim.SystemCompleted]] + else + completed = job.obj:wait() --[[@as vim.SystemCompleted]] + end + return { exitcode = completed.code, signal = completed.signal } end return M diff --git a/lua/gitlinker/commons/version.txt b/lua/gitlinker/commons/version.txt index e9dbbdad..1e212a91 100644 --- a/lua/gitlinker/commons/version.txt +++ b/lua/gitlinker/commons/version.txt @@ -1 +1 @@ -21.1.0 +26.0.0 diff --git a/lua/gitlinker/git.lua b/lua/gitlinker/git.lua index 2d7933a7..ab52db16 100644 --- a/lua/gitlinker/git.lua +++ b/lua/gitlinker/git.lua @@ -1,7 +1,8 @@ local logging = require("gitlinker.commons.logging") local spawn = require("gitlinker.commons.spawn") local uv = require("gitlinker.commons.uv") -local async = require("gitlinker.commons.async") + +local async = require("gitlinker.async") --- @class gitlinker.CmdResult --- @field stdout string[] @@ -42,12 +43,12 @@ function CmdResult:print_err(default) end --- NOTE: async functions can't have optional parameters so wrap it into another function without '_' -local _run_cmd = async.wrap(3, function(args, cwd, callback) +local _run_cmd = async.wrap(function(args, cwd, callback) local result = CmdResult:new() local logger = logging.get("gitlinker") logger:debug(string.format("|_run_cmd| args:%s, cwd:%s", vim.inspect(args), vim.inspect(cwd))) - spawn.run(args, { + spawn.detached(args, { cwd = cwd, on_stdout = function(line) if type(line) == "string" then @@ -63,7 +64,7 @@ local _run_cmd = async.wrap(3, function(args, cwd, callback) logger:debug(string.format("|_run_cmd| result:%s", vim.inspect(result))) callback(result) end) -end) +end, 3) -- wrap the git command to do the right thing always --- @package diff --git a/lua/gitlinker/linker.lua b/lua/gitlinker/linker.lua index c841a6b4..e5a4b81a 100644 --- a/lua/gitlinker/linker.lua +++ b/lua/gitlinker/linker.lua @@ -1,7 +1,7 @@ local logging = require("gitlinker.commons.logging") local str = require("gitlinker.commons.str") -local async = require("gitlinker.commons.async") +local async = require("gitlinker.async") local git = require("gitlinker.git") local path = require("gitlinker.path") local giturlparser = require("gitlinker.giturlparser") @@ -89,7 +89,7 @@ local function make_linker(remote, file, rev) end -- logger.debug("|linker - Linker:make| rev:%s", vim.inspect(rev)) - async.schedule() + async.scheduler() if not file_provided then local buf_path_on_root = path.buffer_relpath(root) --[[@as string]] @@ -114,7 +114,7 @@ local function make_linker(remote, file, rev) -- vim.inspect(file_in_rev_result) -- ) - async.schedule() + async.scheduler() local file_changed = false if not file_provided then diff --git a/spec/gitlinker/git_spec.lua b/spec/gitlinker/git_spec.lua index 6801ef09..e3da6ba1 100644 --- a/spec/gitlinker/git_spec.lua +++ b/spec/gitlinker/git_spec.lua @@ -11,7 +11,7 @@ describe("gitlinker.git", function() vim.cmd([[ edit lua/gitlinker.lua ]]) end) - local async = require("gitlinker.commons.async") + local async = require("gitlinker.async") local git = require("gitlinker.git") local path = require("gitlinker.path") local gitlinker = require("gitlinker") diff --git a/spec/gitlinker/linker_spec.lua b/spec/gitlinker/linker_spec.lua index e3a3cd61..240243eb 100644 --- a/spec/gitlinker/linker_spec.lua +++ b/spec/gitlinker/linker_spec.lua @@ -13,7 +13,7 @@ describe("gitlinker.linker", function() vim.cmd([[ edit lua/gitlinker.lua ]]) end) - local async = require("gitlinker.commons.async") + local async = require("gitlinker.async") local github_actions = os.getenv("GITHUB_ACTIONS") == "true" local linker = require("gitlinker.linker") describe("[make_linker]", function() diff --git a/spec/gitlinker_spec.lua b/spec/gitlinker_spec.lua index bd8e5ce1..ed72a84c 100644 --- a/spec/gitlinker_spec.lua +++ b/spec/gitlinker_spec.lua @@ -696,9 +696,9 @@ describe("gitlinker", function() end) end) - describe("[_sync_link]", function() + describe("[_void_link]", function() it("link browse", function() - gitlinker._sync_link({ + gitlinker._void_link({ action = require("gitlinker.actions").clipboard, router = function(lk) return require("gitlinker")._router("browse", lk) @@ -708,7 +708,7 @@ describe("gitlinker", function() }) end) it("link blame", function() - gitlinker._sync_link({ + gitlinker._void_link({ action = require("gitlinker.actions").clipboard, router = function(lk) return require("gitlinker")._router("blame", lk)