diff --git a/CUSTOMIZE.md b/CUSTOMIZE.md index c4cf5ab..574a103 100644 --- a/CUSTOMIZE.md +++ b/CUSTOMIZE.md @@ -6,7 +6,7 @@ A tool is specified as follows: { -- specify an executable cmd -- string: tool command - args -- string[]: command arguments + args -- string[] | fun(number): string[]: command arguments fname -- boolean: insert filename to args tail stdin -- boolean: pass buffer contents into stdin @@ -14,9 +14,9 @@ A tool is specified as follows: fn -- function: write your own logic for formatting / linting, more in ADVANCED.md -- running condition - ignore_patterns -- string|string[]: don't run formatter when pattern match against file name + ignore_patterns -- string | string[]: don't run formatter when pattern match against file name ignore_error -- boolean: when has lsp error ignore format - find -- string|string[]: format if the file is found in the lsp root dir + find -- string | string[]: format if the file is found in the lsp root dir -- misc env -- table?: environment variables passed to cmd (key value pair) @@ -29,7 +29,7 @@ A tool is specified as follows: } ``` -guard also tries to require them if you have `guard-collection`. +guard also tries to require them by name if you have `guard-collection`. You can also pass in a function that evaluates to the table above, it will be evaluated every time you call format. See more [here](https://github.com/nvimdev/guard.nvim/blob/main/ADVANCED.md#dynamic-formatters) diff --git a/doc/guard.nvim.txt b/doc/guard.nvim.txt index ec00cb5..29a3473 100644 --- a/doc/guard.nvim.txt +++ b/doc/guard.nvim.txt @@ -1,4 +1,4 @@ -*guard.nvim.txt* For NVIM v0.8.0 Last change: 2025 June 11 +*guard.nvim.txt* For NVIM v0.8.0 Last change: 2025 August 05 ============================================================================== Table of Contents *guard.nvim-table-of-contents* @@ -175,7 +175,7 @@ A tool is specified as follows: { -- specify an executable cmd -- string: tool command - args -- string[]: command arguments + args -- string[] | fun(number): string[]: command arguments fname -- boolean: insert filename to args tail stdin -- boolean: pass buffer contents into stdin @@ -183,9 +183,9 @@ A tool is specified as follows: fn -- function: write your own logic for formatting / linting, more in ADVANCED.md -- running condition - ignore_patterns -- string|string[]: don't run formatter when pattern match against file name + ignore_patterns -- string | string[]: don't run formatter when pattern match against file name ignore_error -- boolean: when has lsp error ignore format - find -- string|string[]: format if the file is found in the lsp root dir + find -- string | string[]: format if the file is found in the lsp root dir -- misc env -- table?: environment variables passed to cmd (key value pair) @@ -198,7 +198,7 @@ A tool is specified as follows: } < -guard also tries to require them if you have `guard-collection`. +guard also tries to require them by name if you have `guard-collection`. You can also pass in a function that evaluates to the table above, it will be evaluated every time you call format. See more here diff --git a/lua/guard/_meta.lua b/lua/guard/_meta.lua index 1447505..5c75c6d 100644 --- a/lua/guard/_meta.lua +++ b/lua/guard/_meta.lua @@ -1,6 +1,6 @@ ---@class FmtConfigTable ---@field cmd string? ----@field args string[]? +---@field args (string[]|fun(number):string[])? ---@field fname boolean? ---@field stdin boolean? ---@field fn function? @@ -10,12 +10,13 @@ ---@field find string|string[]? ---@field env table? ---@field timeout integer? +---@field health function? ---@alias FmtConfig FmtConfigTable|fun(): FmtConfigTable ---@class LintConfigTable ---@field cmd string? ----@field args string[]? +---@field args (string[]|fun(number):string[])? ---@field fname boolean? ---@field stdin boolean? ---@field fn function? @@ -26,6 +27,7 @@ ---@field find string|string[]? ---@field env table? ---@field timeout integer? +---@field health function? ---@alias LintConfig LintConfigTable|fun(): LintConfigTable diff --git a/lua/guard/format.lua b/lua/guard/format.lua index e6042af..e116620 100644 --- a/lua/guard/format.lua +++ b/lua/guard/format.lua @@ -135,7 +135,7 @@ local function do_fmt(buf) vim.schedule(function() changedtick = api.nvim_buf_get_changedtick(buf) end) - new_lines = pure:fold(new_lines, function(acc, config, _) + new_lines = pure:fold(new_lines, function(acc, config) -- check if we are in a valid state vim.schedule(function() if api.nvim_buf_get_changedtick(buf) ~= changedtick then @@ -150,7 +150,7 @@ local function do_fmt(buf) if config.fn then return config.fn(buf, range, acc) else - local result = spawn.transform(util.get_cmd(config, fname), cwd, config, acc) + local result = spawn.transform(util.get_cmd(config, fname, buf), cwd, config, acc) if type(result) == 'table' then -- indicates error errno = result @@ -193,12 +193,12 @@ local function do_fmt(buf) -- wait until substitution is finished coroutine.yield() - impure:fold(nil, function(_, config, _) + impure:each(function(config) if errno then return end - vim.system(util.get_cmd(config, fname), { + vim.system(util.get_cmd(config, fname, buf), { text = true, cwd = cwd, env = config.env or {}, diff --git a/lua/guard/util.lua b/lua/guard/util.lua index 603fd76..ac195f2 100644 --- a/lua/guard/util.lua +++ b/lua/guard/util.lua @@ -25,8 +25,8 @@ end ---@param mode "v"|"V" ---@return table {start={row,col}, end={row,col}} using (1, 0) indexing function M.range_from_selection(bufnr, mode) - local start = vim.fn.getpos('v') - local end_ = vim.fn.getpos('.') + local start = assert(vim.fn.getpos('v')) + local end_ = assert(vim.fn.getpos('.')) local start_row = start[2] local start_col = start[3] local end_row = end_[2] @@ -70,9 +70,17 @@ end ---@param config FmtConfig|LintConfig ---@param fname string +---@param buf number ---@return string[] -function M.get_cmd(config, fname) - local cmd = config.args and vim.deepcopy(config.args) or {} +function M.get_cmd(config, fname, buf) + local args + if type(config.args) == 'function' then + args = config.args(buf) + elseif type(config.args) == 'table' then + args = vim.deepcopy(config.args) + end + + local cmd = args or {} if config.fname then table.insert(cmd, fname) end diff --git a/spec/format_spec.lua b/spec/format_spec.lua index 616780d..17c52d9 100644 --- a/spec/format_spec.lua +++ b/spec/format_spec.lua @@ -109,6 +109,40 @@ describe('format module', function() assert.are.same({ 'def' }, lines) end) + it('can format with dynamic arguments', function() + ft('lua'):fmt({ + cmd = 'cat', + args = function(_) + if vim.g.blah then + return { '-E' } + else + return nil + end + end, + stdin = true, + }) + + setlines({ 'foo', 'bar' }) + gapi.fmt() + vim.wait(500) + local lines = getlines() + assert.are.same({ 'foo', 'bar' }, lines) + + vim.g.blah = true + + gapi.fmt() + vim.wait(500) + lines = getlines() + assert.are.same({ 'foo$', 'bar' }, lines) + + vim.g.blah = false + + gapi.fmt() + vim.wait(500) + lines = getlines() + assert.are.same({ 'foo$', 'bar' }, lines) + end) + it('can format on custom user events', function() ft('lua'):fmt({ fn = function() diff --git a/spec/lint_spec.lua b/spec/lint_spec.lua index 714d5f1..2f6516d 100644 --- a/spec/lint_spec.lua +++ b/spec/lint_spec.lua @@ -160,19 +160,7 @@ describe('lint module', function() gapi.lint() vim.wait(100) - same({ - { - bufnr = bufnr, - col = 1, - end_col = 1, - lnum = 1, - end_lnum = 1, - message = 'foo', - namespace = ns, - severity = vd.severity.HINT, - source = 'bar', - }, - }, vd.get()) + same('foo', vd.get()[1].message) end) it('can lint on custom user events', function() @@ -194,18 +182,6 @@ describe('lint module', function() vim.cmd('colorscheme blue') vim.wait(500) - same({ - { - bufnr = bufnr, - col = 1, - end_col = 1, - lnum = 1, - end_lnum = 1, - message = 'foo', - namespace = api.nvim_get_namespaces()[tostring(mock_linter_custom)], - severity = vd.severity.HINT, - source = 'bar', - }, - }, vd.get()) + same('foo', vd.get()[1].message) end) end) diff --git a/spec/settings_spec.lua b/spec/settings_spec.lua index a75802f..b41139f 100644 --- a/spec/settings_spec.lua +++ b/spec/settings_spec.lua @@ -150,19 +150,7 @@ describe('settings', function() same(true, util.getopt('auto_lint')) vim.cmd('silent! write!') vim.wait(500) - same({ - { - source = 'mock_linter_regex', - bufnr = bufnr, - col = 1, - end_col = 1, - lnum = 1, - end_lnum = 1, - message = 'Very important error message[error code 114514]', - namespace = ns, - severity = 2, - }, - }, vd.get()) + same('Very important error message[error code 114514]', vd.get()[1].message) vim.g.guard_config = { auto_lint = false } same(false, util.getopt('auto_lint'))