Skip to content

Commit

Permalink
feat: provide a formatexpr (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevearc committed Sep 15, 2023
1 parent 9e7d1d6 commit aa38b05
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
37 changes: 37 additions & 0 deletions lua/conform/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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

0 comments on commit aa38b05

Please sign in to comment.