From b62430bb2610198bffb076a59755ad74b4a3d50a Mon Sep 17 00:00:00 2001 From: Thomas Vanbesien Date: Thu, 11 Jun 2026 19:53:59 +0200 Subject: refactor(nvim): rewrite the buffer formatting flow --- .config/nvim/plugin/50-format.lua | 67 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .config/nvim/plugin/50-format.lua (limited to '.config/nvim/plugin/50-format.lua') 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" }) -- cgit v1.3.1