aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Arcangeli <506791+stevearc@users.noreply.github.com>2023-09-15 08:35:28 -0700
committerGitHub <noreply@github.com>2023-09-15 08:35:28 -0700
commitfbb18a5b92e2f11aaaef379d74d4a1132a138cb3 (patch)
tree8a9193f0be376d9317f447790f23a5a0f1554a7c
parent3f855f3675a22cb52a6754f3ab073d13528ce0ca (diff)
feat: allow running commands in a shell (#49)
-rw-r--r--README.md1
-rw-r--r--doc/conform.txt1
-rw-r--r--lua/conform/init.lua4
-rw-r--r--lua/conform/runner.lua25
-rw-r--r--scripts/options_doc.lua1
-rw-r--r--tests/runner_spec.lua43
6 files changed, 64 insertions, 11 deletions
diff --git a/README.md b/README.md
index 3d312b8..e20dcc9 100644
--- a/README.md
+++ b/README.md
@@ -261,6 +261,7 @@ require("conform").setup({
command = "my_cmd",
-- OPTIONAL - all fields below this are optional
-- A list of strings, or a function that returns a list of strings
+ -- Return a single string instead to run the command in a shell
args = { "--stdin-from-filename", "$FILENAME" },
-- If the formatter supports range formatting, create the range arguments here
range_args = function(ctx)
diff --git a/doc/conform.txt b/doc/conform.txt
index e0dd9ff..1d29bdd 100644
--- a/doc/conform.txt
+++ b/doc/conform.txt
@@ -50,6 +50,7 @@ OPTIONS *conform-option
command = "my_cmd",
-- OPTIONAL - all fields below this are optional
-- A list of strings, or a function that returns a list of strings
+ -- Return a single string instead to run the command in a shell
args = { "--stdin-from-filename", "$FILENAME" },
-- If the formatter supports range formatting, create the range arguments here
range_args = function(ctx)
diff --git a/lua/conform/init.lua b/lua/conform/init.lua
index ff30686..a19813e 100644
--- a/lua/conform/init.lua
+++ b/lua/conform/init.lua
@@ -9,8 +9,8 @@ local M = {}
---@class (exact) conform.FormatterConfig
---@field command string|fun(ctx: conform.Context): string
----@field args? string[]|fun(ctx: conform.Context): string[]
----@field range_args? fun(ctx: conform.RangeContext): string[]
+---@field args? string|string[]|fun(ctx: conform.Context): string|string[]
+---@field range_args? fun(ctx: conform.RangeContext): string|string[]
---@field cwd? fun(ctx: conform.Context): nil|string
---@field require_cwd? boolean When cwd is not found, don't run the formatter (default false)
---@field stdin? boolean Send buffer contents to stdin (default true)
diff --git a/lua/conform/runner.lua b/lua/conform/runner.lua
index ff8fbef..fff638b 100644
--- a/lua/conform/runner.lua
+++ b/lua/conform/runner.lua
@@ -48,12 +48,13 @@ end
---@param ctx conform.Context
---@param config conform.FormatterConfig
+---@return string|string[]
M.build_cmd = function(ctx, config)
local command = config.command
if type(command) == "function" then
command = command(ctx)
end
- local cmd = { command }
+ ---@type string|string[]
local args = {}
if ctx.range and config.range_args then
---@cast ctx conform.RangeContext
@@ -67,16 +68,22 @@ M.build_cmd = function(ctx, config)
end
end
- ---@diagnostic disable-next-line: param-type-mismatch
- for _, v in ipairs(args) do
- if v == "$FILENAME" then
- v = ctx.filename
- elseif v == "$DIRNAME" then
- v = ctx.dirname
+ if type(args) == "string" then
+ local interpolated = args:gsub("$FILENAME", ctx.filename):gsub("$DIRNAME", ctx.dirname)
+ return command .. " " .. interpolated
+ else
+ local cmd = { command }
+ ---@diagnostic disable-next-line: param-type-mismatch
+ for _, v in ipairs(args) do
+ if v == "$FILENAME" then
+ v = ctx.filename
+ elseif v == "$DIRNAME" then
+ v = ctx.dirname
+ end
+ table.insert(cmd, v)
end
- table.insert(cmd, v)
+ return cmd
end
- return cmd
end
---@param range? conform.Range
diff --git a/scripts/options_doc.lua b/scripts/options_doc.lua
index 9073369..af7b10c 100644
--- a/scripts/options_doc.lua
+++ b/scripts/options_doc.lua
@@ -36,6 +36,7 @@ require("conform").setup({
command = "my_cmd",
-- OPTIONAL - all fields below this are optional
-- A list of strings, or a function that returns a list of strings
+ -- Return a single string instead to run the command in a shell
args = { "--stdin-from-filename", "$FILENAME" },
-- If the formatter supports range formatting, create the range arguments here
range_args = function(ctx)
diff --git a/tests/runner_spec.lua b/tests/runner_spec.lua
index 10ea075..56cf8e2 100644
--- a/tests/runner_spec.lua
+++ b/tests/runner_spec.lua
@@ -102,6 +102,49 @@ describe("runner", function()
local cmd = runner.build_cmd(ctx, config)
assert.are.same({ "echo", "--stdin" }, cmd)
end)
+
+ it("replaces $FILENAME in string args", function()
+ vim.cmd.edit({ args = { "README.md" } })
+ local bufnr = vim.api.nvim_get_current_buf()
+ conform.formatters.test = {
+ meta = { url = "", description = "" },
+ command = "echo",
+ args = "$FILENAME | patch",
+ }
+ local config = assert(conform.get_formatter_config("test"))
+ local ctx = runner.build_context(0, config)
+ local cmd = runner.build_cmd(ctx, config)
+ assert.equal("echo " .. vim.api.nvim_buf_get_name(bufnr) .. " | patch", cmd)
+ end)
+
+ it("replaces $DIRNAME in string args", function()
+ vim.cmd.edit({ args = { "README.md" } })
+ local bufnr = vim.api.nvim_get_current_buf()
+ conform.formatters.test = {
+ meta = { url = "", description = "" },
+ command = "echo",
+ args = "$DIRNAME | patch",
+ }
+ local config = assert(conform.get_formatter_config("test"))
+ local ctx = runner.build_context(0, config)
+ local cmd = runner.build_cmd(ctx, config)
+ assert.equal("echo " .. vim.fs.dirname(vim.api.nvim_buf_get_name(bufnr)) .. " | patch", cmd)
+ end)
+
+ it("resolves arg function with string results", function()
+ vim.cmd.edit({ args = { "README.md" } })
+ conform.formatters.test = {
+ meta = { url = "", description = "" },
+ command = "echo",
+ args = function()
+ return "| patch"
+ end,
+ }
+ local config = assert(conform.get_formatter_config("test"))
+ local ctx = runner.build_context(0, config)
+ local cmd = runner.build_cmd(ctx, config)
+ assert.equal("echo | patch", cmd)
+ end)
end)
describe("e2e", function()