summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md8
-rw-r--r--lua/conform/init.lua37
2 files changed, 44 insertions, 1 deletions
diff --git a/README.md b/README.md
index 2e3c62e..6592bff 100644
--- a/README.md
+++ b/README.md
@@ -150,7 +150,13 @@ require("conform").setup({
See [conform.format()](#formatopts-callback) for more details about the parameters.
-To view configured and available formatters, as well as to see the path to the log file, run `:ConformInfo`
+Conform also provides a formatexpr, same as the LSP client:
+
+```lua
+vim.o.formatexpr = "v:lua.require'conform'.formatexpr()"
+```
+
+To view configured and available formatters, as well as to see the log file, run `:ConformInfo`
## Formatters
diff --git a/lua/conform/init.lua b/lua/conform/init.lua
index a19813e..07c46a3 100644
--- a/lua/conform/init.lua
+++ b/lua/conform/init.lua
@@ -343,6 +343,7 @@ M.format = function(opts, callback)
elseif opts.lsp_fallback and not vim.tbl_isempty(lsp_format.get_format_clients(opts)) then
log.debug("Running LSP formatter on %s", vim.api.nvim_buf_get_name(opts.bufnr))
lsp_format.format(opts, callback)
+ any_formatters = true
elseif any_formatters_configured and not opts.quiet then
vim.notify("No formatters found for buffer. See :ConformInfo", vim.log.levels.WARN)
callback("No formatters found for buffer")
@@ -480,4 +481,40 @@ M.get_formatter_info = function(formatter, bufnr)
}
end
+M.formatexpr = function(opts)
+ -- Change the defaults slightly from conform.format
+ opts = vim.tbl_deep_extend("keep", opts or {}, {
+ timeout_ms = 500,
+ lsp_fallback = true,
+ })
+ -- Force async = false
+ opts.async = false
+ if vim.tbl_contains({ "i", "R", "ic", "ix" }, vim.fn.mode()) then
+ -- `formatexpr` is also called when exceeding `textwidth` in insert mode
+ -- fall back to internal formatting
+ return 1
+ end
+
+ local start_lnum = vim.v.lnum
+ local end_lnum = start_lnum + vim.v.count - 1
+
+ if start_lnum <= 0 or end_lnum <= 0 then
+ return 0
+ end
+ local end_line = vim.fn.getline(end_lnum)
+ local end_col = end_line:len()
+ opts.range = {
+ start = { start_lnum, 0 },
+ ["end"] = { end_lnum, end_col },
+ }
+ if M.format(opts) then
+ return 0
+ elseif opts.lsp_fallback then
+ -- No formatters were available; fall back to lsp formatter
+ return vim.lsp.formatexpr({ timeout_ms = opts.timeout_ms })
+ else
+ return 1
+ end
+end
+
return M