summaryrefslogtreecommitdiffstats
path: root/.config/nvim/plugin/50-format.lua
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-06-11 19:53:59 +0200
committerThomas Vanbesien <tvanbesi@proton.me>2026-06-11 20:08:37 +0200
commitb62430bb2610198bffb076a59755ad74b4a3d50a (patch)
tree1fd55be01a1e31b35440b56bb5c6176dc59c0eb4 /.config/nvim/plugin/50-format.lua
parent796b523aa141dd6aff2d100ddcc46f2895859ecd (diff)
downloaddotfiles-b62430bb2610198bffb076a59755ad74b4a3d50a.tar.gz
dotfiles-b62430bb2610198bffb076a59755ad74b4a3d50a.zip
refactor(nvim): rewrite the buffer formatting flow
Diffstat (limited to '.config/nvim/plugin/50-format.lua')
-rw-r--r--.config/nvim/plugin/50-format.lua67
1 files changed, 67 insertions, 0 deletions
diff --git a/.config/nvim/plugin/50-format.lua b/.config/nvim/plugin/50-format.lua
new file mode 100644
index 0000000..46a245c
--- /dev/null
+++ b/.config/nvim/plugin/50-format.lua
@@ -0,0 +1,67 @@
+--
+-- 50-format.lua
+--
+-- Specifies the formatters to use for different file types and sets up a global autocommand to trigger them.
+--
+-- User commands:
+-- FormatToggle: toggle formatting on save on/off for the current buffer
+
+local function toggle_format()
+ vim.b.format = not vim.b.format
+end
+
+local function format_impl(cmd, lines)
+ local r = vim.system(cmd, { stdin = lines, text = true }):wait()
+ if r.code ~= 0 then
+ vim.notify(cmd[1] .. " error:\n" .. r.stderr, vim.log.levels.WARN)
+ return nil
+ end
+ return vim.split(r.stdout, "\n", { trimempty = true })
+end
+
+local formatters = {
+ ["sh"] = function(lines)
+ return format_impl({ "shfmt", "-" }, lines)
+ end,
+ ["lua"] = function(lines)
+ return format_impl({ "stylua", "--search-parent-directories", "-" }, lines)
+ end,
+ ["markdown"] = function(lines)
+ return format_impl({ "mdformat", "-" }, lines)
+ end,
+ ["python"] = function(lines)
+ return format_impl({ "black", "-" }, lines)
+ end,
+}
+formatters.bash = formatters.sh
+
+--- Format the buffer `ev.buf` with the formatter for its filetype.
+--- This function is meant to be an event handler for `vim.api.nvim_create_autocmd()`
+--- @param ev table `ev` argument passed from `vim.api.nvim_create_autocmd()`
+local function on_format(ev)
+ if vim.b[ev.buf].format ~= true then
+ return
+ end
+ local ft = vim.bo[ev.buf].filetype
+ local format = formatters[ft]
+ if not format then
+ vim.notify("No formatter registered for " .. ft, vim.log.levels.ERROR)
+ return
+ end
+ local lines_in = vim.api.nvim_buf_get_lines(ev.buf, 0, -1, false)
+ local lines_out = format(lines_in)
+ if not lines_out or vim.deep_equal(lines_in, lines_out) then
+ return
+ end
+ local view = vim.fn.winsaveview()
+ vim.api.nvim_buf_set_lines(ev.buf, 0, -1, false, lines_out)
+ vim.fn.winrestview(view)
+end
+
+vim.api.nvim_create_autocmd("BufWritePre", {
+ desc = "Format buffer",
+ group = vim.g.dotfiles.augroup,
+ callback = on_format,
+})
+
+vim.api.nvim_create_user_command("FormatToggle", toggle_format, { desc = "Toggle format on save" })