diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-06-24 21:24:54 +0200 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-06-24 21:24:54 +0200 |
| commit | d5887f31a416034300a8675d8883d615b31ced83 (patch) | |
| tree | 7c2b105a8a56ed4c2a9ca6b5d6e9b1b338934f77 /lua/dotfiles/format.lua | |
| parent | b0130288e93e00d5f37a5cf70bc8920216600aa7 (diff) | |
| download | nvim-config-d5887f31a416034300a8675d8883d615b31ced83.tar.gz nvim-config-d5887f31a416034300a8675d8883d615b31ced83.zip | |
refactor(nvim): rewrite formatter plugin
Diffstat (limited to 'lua/dotfiles/format.lua')
| -rw-r--r-- | lua/dotfiles/format.lua | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/lua/dotfiles/format.lua b/lua/dotfiles/format.lua new file mode 100644 index 0000000..72d0248 --- /dev/null +++ b/lua/dotfiles/format.lua @@ -0,0 +1,59 @@ +-- Format engine. Features register a stdin formatter command per filetype; the engine runs the +-- registered formatter over the buffer on write, when formatting is enabled for it (vim.b.format, +-- toggled by :FormatToggle). Formatters are registered in plugin/50-format.lua. +-- +-- API: +-- register(filetype, cmd) — `cmd` is a command list run with the buffer contents on stdin; its +-- stdout replaces the buffer. Call once per filetype to share a command. + +local M = {} + +-- Registered formatter commands, keyed by filetype. +M.formatters = {} + +-- Run `cmd` with `lines` piped on stdin; return its stdout as a list of lines, or nil on failure. +local function run(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 + +-- Register the stdin formatter command `cmd` for `filetype`. +function M.register(filetype, cmd) + assert(type(filetype) == "string", "format.register: filetype must be a string") + assert(type(cmd) == "table", "format.register: cmd must be a command list") + M.formatters[filetype] = cmd +end + +-- Format buffer `ev.buf` with its filetype's formatter when formatting is enabled for it. +-- Meant as a 'BufWritePre' handler; preserves the cursor/window view across the rewrite. +local function format_buffer(ev) + if vim.b[ev.buf].format ~= true then + return + end + local ft = vim.bo[ev.buf].filetype + local cmd = M.formatters[ft] + if not cmd 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 = run(cmd, 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 = format_buffer, +}) + +return M |
