Skip to content

Commit cd75be8

Browse files
authored
feat(shfmt): add automatic indentation detection (nvim-lua#481)
* feat(shfmt): automatically detect indentation * fix(markdown-toc): improve correctness of indentation size calculation * fix(djlint): improve correctness of indentation size calculation * feat: add effective `shiftwidth` to `conform.Context` this also refactors formatters that automatically set indentation level to use the new shiftwidth context
1 parent fc19dfc commit cd75be8

File tree

6 files changed

+47
-10
lines changed

6 files changed

+47
-10
lines changed

lua/conform/formatters/djlint.lua

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ return {
77
},
88
command = "djlint",
99
args = function(_, ctx)
10-
local indent = vim.bo[ctx.buf].tabstop or 4 -- default is 4
11-
return { "--reformat", "--indent", indent, "-" }
10+
return { "--reformat", "--indent", ctx.shiftwidth, "-" }
1211
end,
1312
cwd = util.root_file({
1413
".djlintrc",

lua/conform/formatters/markdown-toc.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ return {
66
},
77
command = "markdown-toc",
88
stdin = false,
9-
args = function(self, ctx)
9+
args = function(_, ctx)
1010
-- use the indentation set in the current buffer, effectively allowing us to
1111
-- use values from .editorconfig
12-
local indent = vim.bo[ctx.buf].expandtab and (" "):rep(vim.bo[ctx.buf].tabstop) or "\t"
12+
local indent = vim.bo[ctx.buf].expandtab and (" "):rep(ctx.shiftwidth) or "\t"
1313
return { "--indent=" .. indent, "-i", "$FILENAME" }
1414
end,
1515
}

lua/conform/formatters/shfmt.lua

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,11 @@ return {
55
description = "A shell parser, formatter, and interpreter with `bash` support.",
66
},
77
command = "shfmt",
8-
args = { "-filename", "$FILENAME" },
8+
args = function(_, ctx)
9+
local args = { "-filename", "$FILENAME" }
10+
if vim.bo[ctx.buf].expandtab then
11+
vim.list_extend(args, { "-i", ctx.shiftwidth })
12+
end
13+
return args
14+
end,
915
}

lua/conform/runner.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,11 @@ M.build_context = function(bufnr, config, range)
450450
end
451451
local filename = vim.api.nvim_buf_get_name(bufnr)
452452

453+
local shiftwidth = vim.bo[bufnr].shiftwidth
454+
if shiftwidth == 0 then
455+
shiftwidth = vim.bo[bufnr].tabstop
456+
end
457+
453458
-- Hack around checkhealth. For buffers that are not files, we need to fabricate a filename
454459
if vim.bo[bufnr].buftype ~= "" then
455460
filename = ""
@@ -482,6 +487,7 @@ M.build_context = function(bufnr, config, range)
482487
filename = filename,
483488
dirname = dirname,
484489
range = range,
490+
shiftwidth = shiftwidth,
485491
}
486492
end
487493

lua/conform/types.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
---@field filename string
5050
---@field dirname string
5151
---@field range? conform.Range
52+
---@field shiftwidth integer
5253

5354
---@class (exact) conform.RangeContext : conform.Context
5455
---@field range conform.Range

tests/runner_spec.lua

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,36 @@ describe("runner", function()
5959
local config = assert(conform.get_formatter_config("test"))
6060
local ctx = runner.build_context(0, config)
6161
local filename = vim.api.nvim_buf_get_name(bufnr)
62-
assert.are.same({
63-
buf = bufnr,
64-
filename = filename,
65-
dirname = vim.fs.dirname(filename),
66-
}, ctx)
62+
assert.equal(bufnr, ctx.buf)
63+
assert.equal(filename, ctx.filename)
64+
assert.equal(vim.fs.dirname(filename), ctx.dirname)
65+
end)
66+
67+
it("sets the shiftwidth to shiftwidth", function()
68+
vim.cmd.edit({ args = { "README.md" } })
69+
local bufnr = vim.api.nvim_get_current_buf()
70+
vim.bo[bufnr].shiftwidth = 7
71+
conform.formatters.test = {
72+
meta = { url = "", description = "" },
73+
command = "echo",
74+
}
75+
local config = assert(conform.get_formatter_config("test"))
76+
local ctx = runner.build_context(0, config)
77+
assert.equal(7, ctx.shiftwidth)
78+
end)
79+
80+
it("sets the shiftwidth to tabstop as fallback", function()
81+
vim.cmd.edit({ args = { "README.md" } })
82+
local bufnr = vim.api.nvim_get_current_buf()
83+
vim.bo[bufnr].shiftwidth = 0
84+
vim.bo[bufnr].tabstop = 3
85+
conform.formatters.test = {
86+
meta = { url = "", description = "" },
87+
command = "echo",
88+
}
89+
local config = assert(conform.get_formatter_config("test"))
90+
local ctx = runner.build_context(0, config)
91+
assert.equal(3, ctx.shiftwidth)
6792
end)
6893

6994
it("sets temp file when stdin = false", function()

0 commit comments

Comments
 (0)