diff options
-rw-r--r-- | README.md | 41 | ||||
-rw-r--r-- | doc/conform.txt | 40 | ||||
-rw-r--r-- | lua/conform/init.lua | 54 | ||||
-rw-r--r-- | scripts/autoformat_doc.lua | 32 | ||||
-rw-r--r-- | scripts/options_doc.lua | 5 |
5 files changed, 130 insertions, 42 deletions
@@ -226,6 +226,11 @@ require("conform").setup({ lsp_fallback = true, timeout_ms = 500, }, + -- If this is set, Conform will run the formatter asynchronously after save. + -- It will pass the table to conform.format(). + format_after_save = { + lsp_fallback = true, + }, -- Set the log level. Use `:ConformInfo` to see the location of the log file. log_level = vim.log.levels.ERROR, -- Conform will notify you when a formatter errors @@ -301,7 +306,7 @@ require("conform").formatters.yamlfix = vim.tbl_deep_extend("force", require("co ## Autoformat on save If you want more complex logic than the `format_on_save` option allows, you can write it yourself -using your own autocmd. For example: +using an autocmd. For example: <!-- AUTOFORMAT --> @@ -328,17 +333,27 @@ vim.api.nvim_create_autocmd("BufWritePre", { end, }) --- Format asynchronously on save -vim.api.nvim_create_autocmd("BufWritePost", { - pattern = "*", - callback = function(args) - require("conform").format({ async = true, lsp_fallback = true, bufnr = args.buf }, function(err) - if not err then - vim.api.nvim_buf_call(args.buf, function() - vim.cmd.update() - end) - end - end) +-- To eliminate the boilerplate, you can pass a function to format_on_save +-- and it will be called during the BufWritePre callback. +require("conform").setup({ + format_on_save = function(bufnr) + if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then + return + end + -- ...additional logic... + return { timeout_ms = 500, lsp_fallback = true } + end, +}) + +-- There is a similar affordance for format_after_save, which uses BufWritePost. +-- This is good for formatters that are too slow to run synchronously. +require("conform").setup({ + format_after_save = function(bufnr) + if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then + return + end + -- ...additional logic... + return { lsp_fallback = true } end, }) ``` @@ -359,7 +374,7 @@ Format a buffer | opts | `nil\|table` | | | | | timeout_ms | `nil\|integer` | Time in milliseconds to block for formatting. Defaults to 1000. No effect if async = true. | | | bufnr | `nil\|integer` | Format this buffer (default 0) | -| | async | `nil\|boolean` | If true the method won't block. Defaults to false. | +| | async | `nil\|boolean` | If true the method won't block. Defaults to false. If the buffer is modified before the formatter completes, the formatting will be discarded. | | | formatters | `nil\|string[]` | List of formatters to run. Defaults to all formatters for the buffer filetype. | | | lsp_fallback | `nil\|boolean\|"always"` | Attempt LSP formatting if no formatters are available. Defaults to false. If "always", will attempt LSP formatting even if formatters are available (useful if you set formatters for the "*" filetype) | | | quiet | `nil\|boolean` | Don't show any notifications for warnings or failures. Defaults to false. | diff --git a/doc/conform.txt b/doc/conform.txt index 149db88..a62eca8 100644 --- a/doc/conform.txt +++ b/doc/conform.txt @@ -32,6 +32,11 @@ OPTIONS *conform-option lsp_fallback = true, timeout_ms = 500, }, + -- If this is set, Conform will run the formatter asynchronously after save. + -- It will pass the table to conform.format(). + format_after_save = { + lsp_fallback = true, + }, -- Set the log level. Use `:ConformInfo` to see the location of the log file. log_level = vim.log.levels.ERROR, -- Conform will notify you when a formatter errors @@ -96,7 +101,8 @@ format({opts}, {callback}): boolean *conform.forma true. {bufnr} `nil|integer` Format this buffer (default 0) {async} `nil|boolean` If true the method won't block. Defaults - to false. + to false. If the buffer is modified before the + formatter completes, the formatting will be discarded. {formatters} `nil|string[]` List of formatters to run. Defaults to all formatters for the buffer filetype. {lsp_fallback} `nil|boolean|"always"` Attempt LSP formatting if no @@ -232,17 +238,27 @@ write it yourself using your own autocmd. For example: end, }) - -- Format asynchronously on save - vim.api.nvim_create_autocmd("BufWritePost", { - pattern = "*", - callback = function(args) - require("conform").format({ async = true, lsp_fallback = true, bufnr = args.buf }, function(err) - if not err then - vim.api.nvim_buf_call(args.buf, function() - vim.cmd.update() - end) - end - end) + -- To eliminate the boilerplate, you can pass a function to format_on_save + -- and it will be called during the BufWritePre callback. + require("conform").setup({ + format_on_save = function(bufnr) + if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then + return + end + -- ...additional logic... + return { timeout_ms = 500, lsp_fallback = true } + end, + }) + + -- There is a similar affordance for format_after_save, which uses BufWritePost. + -- This is good for formatters that are too slow to run synchronously. + require("conform").setup({ + format_after_save = function(bufnr) + if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then + return + end + -- ...additional logic... + return { lsp_fallback = true } end, }) < diff --git a/lua/conform/init.lua b/lua/conform/init.lua index 9f844b1..3245020 100644 --- a/lua/conform/init.lua +++ b/lua/conform/init.lua @@ -75,19 +75,61 @@ M.setup = function(opts) end end + local aug = vim.api.nvim_create_augroup("Conform", { clear = true }) if opts.format_on_save then if type(opts.format_on_save) == "boolean" then opts.format_on_save = {} end - local aug = vim.api.nvim_create_augroup("Conform", { clear = true }) vim.api.nvim_create_autocmd("BufWritePre", { pattern = "*", group = aug, callback = function(args) - local format_opts = vim.tbl_deep_extend("keep", opts.format_on_save, { - buf = args.buf, - }) - M.format(format_opts) + local format_args = opts.format_on_save + if type(format_args) == "function" then + format_args = format_args(args.buf) + end + if format_args then + M.format(vim.tbl_deep_extend("force", format_args, { + buf = args.buf, + async = false, + })) + end + end, + }) + end + + if opts.format_after_save then + if type(opts.format_after_save) == "boolean" then + opts.format_after_save = {} + end + vim.api.nvim_create_autocmd("BufWritePost", { + pattern = "*", + group = aug, + callback = function(args) + if vim.b[args.buf].conform_applying_formatting then + return + end + local format_args = opts.format_after_save + if type(format_args) == "function" then + format_args = format_args(args.buf) + end + if format_args then + M.format( + vim.tbl_deep_extend("force", format_args, { + buf = args.buf, + async = true, + }), + function(err) + if not err and vim.api.nvim_buf_is_valid(args.buf) then + vim.api.nvim_buf_call(args.buf, function() + vim.b[args.buf].conform_applying_formatting = true + vim.cmd.update() + vim.b[args.buf].conform_applying_formatting = false + end) + end + end + ) + end end, }) end @@ -211,7 +253,7 @@ end ---@param opts? table --- timeout_ms nil|integer Time in milliseconds to block for formatting. Defaults to 1000. No effect if async = true. --- bufnr nil|integer Format this buffer (default 0) ---- async nil|boolean If true the method won't block. Defaults to false. +--- async nil|boolean If true the method won't block. Defaults to false. If the buffer is modified before the formatter completes, the formatting will be discarded. --- formatters nil|string[] List of formatters to run. Defaults to all formatters for the buffer filetype. --- lsp_fallback nil|boolean|"always" Attempt LSP formatting if no formatters are available. Defaults to false. If "always", will attempt LSP formatting even if formatters are available (useful if you set formatters for the "*" filetype) --- quiet nil|boolean Don't show any notifications for warnings or failures. Defaults to false. diff --git a/scripts/autoformat_doc.lua b/scripts/autoformat_doc.lua index 31cbec7..4880310 100644 --- a/scripts/autoformat_doc.lua +++ b/scripts/autoformat_doc.lua @@ -20,16 +20,26 @@ vim.api.nvim_create_autocmd("BufWritePre", { end, }) --- Format asynchronously on save -vim.api.nvim_create_autocmd("BufWritePost", { - pattern = "*", - callback = function(args) - require("conform").format({ async = true, lsp_fallback = true, bufnr = args.buf }, function(err) - if not err then - vim.api.nvim_buf_call(args.buf, function() - vim.cmd.update() - end) - end - end) +-- To eliminate the boilerplate, you can pass a function to format_on_save +-- and it will be called during the BufWritePre callback. +require("conform").setup({ + format_on_save = function(bufnr) + if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then + return + end + -- ...additional logic... + return { timeout_ms = 500, lsp_fallback = true } + end, +}) + +-- There is a similar affordance for format_after_save, which uses BufWritePost. +-- This is good for formatters that are too slow to run synchronously. +require("conform").setup({ + format_after_save = function(bufnr) + if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then + return + end + -- ...additional logic... + return { lsp_fallback = true } end, }) diff --git a/scripts/options_doc.lua b/scripts/options_doc.lua index 1a6921c..5dab627 100644 --- a/scripts/options_doc.lua +++ b/scripts/options_doc.lua @@ -18,6 +18,11 @@ require("conform").setup({ lsp_fallback = true, timeout_ms = 500, }, + -- If this is set, Conform will run the formatter asynchronously after save. + -- It will pass the table to conform.format(). + format_after_save = { + lsp_fallback = true, + }, -- Set the log level. Use `:ConformInfo` to see the location of the log file. log_level = vim.log.levels.ERROR, -- Conform will notify you when a formatter errors |