From e0276bb32e9b33ece11fef2a5cfc8fb2108df0df Mon Sep 17 00:00:00 2001 From: Bronson Jordan <80419011+bpjordan@users.noreply.github.com> Date: Mon, 15 Jan 2024 21:48:26 -0600 Subject: feat: Add dry_run option and report if buffer was/would be changed by formatters (#273) * feat: add dry_run option and pass return values for if buffer would be modified * fix: implement dry_run for blocking calls to lsp formatter * refactor: change `changed` variable to `did_edit` * docs: Update README * fix: address PR comments * fix: small cleanups --------- Co-authored-by: Steven Arcangeli --- lua/conform/lsp_format.lua | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) (limited to 'lua/conform/lsp_format.lua') diff --git a/lua/conform/lsp_format.lua b/lua/conform/lsp_format.lua index cd6e429..f49e15f 100644 --- a/lua/conform/lsp_format.lua +++ b/lua/conform/lsp_format.lua @@ -4,7 +4,7 @@ local util = require("vim.lsp.util") local M = {} -local function apply_text_edits(text_edits, bufnr, offset_encoding) +local function apply_text_edits(text_edits, bufnr, offset_encoding, dry_run) if #text_edits == 1 and text_edits[1].range.start.line == 0 @@ -19,9 +19,19 @@ local function apply_text_edits(text_edits, bufnr, offset_encoding) table.remove(new_lines) end log.debug("Converting full-file LSP format to piecewise format") - require("conform.runner").apply_format(bufnr, original_lines, new_lines, nil, false) + return require("conform.runner").apply_format( + bufnr, + original_lines, + new_lines, + nil, + false, + dry_run + ) + elseif dry_run then + return #text_edits > 0 else vim.lsp.util.apply_text_edits(text_edits, bufnr, offset_encoding) + return #text_edits > 0 end end @@ -56,7 +66,7 @@ function M.get_format_clients(options) end ---@param options table ----@param callback fun(err?: string) +---@param callback fun(err?: string, did_edit?: boolean) function M.format(options, callback) options = options or {} if not options.bufnr or options.bufnr == 0 then @@ -84,9 +94,10 @@ function M.format(options, callback) if options.async then local changedtick = vim.b[bufnr].changedtick local do_format + local did_edit = false do_format = function(idx, client) if not client then - return callback() + return callback(nil, did_edit) end local params = set_range(client, util.make_formatting_params(options.formatting_options)) local auto_id = vim.api.nvim_create_autocmd("LspDetach", { @@ -112,21 +123,35 @@ function M.format(options, callback) ) ) else - apply_text_edits(result, ctx.bufnr, client.offset_encoding) + local this_did_edit = + apply_text_edits(result, ctx.bufnr, client.offset_encoding, options.dry_run) changedtick = vim.b[bufnr].changedtick - do_format(next(clients, idx)) + if options.dry_run and this_did_edit then + callback(nil, true) + else + did_edit = did_edit or this_did_edit + do_format(next(clients, idx)) + end end end, bufnr) end do_format(next(clients)) else local timeout_ms = options.timeout_ms or 1000 + local did_edit = false for _, client in pairs(clients) do local params = set_range(client, util.make_formatting_params(options.formatting_options)) local result, err = client.request_sync(method, params, timeout_ms, bufnr) if result and result.result then - apply_text_edits(result.result, bufnr, client.offset_encoding) + local this_did_edit = + apply_text_edits(result.result, bufnr, client.offset_encoding, options.dry_run) + did_edit = did_edit or this_did_edit + + if options.dry_run and did_edit then + callback(nil, true) + return true + end elseif err then if not options.quiet then vim.notify(string.format("[LSP][%s] %s", client.name, err), vim.log.levels.WARN) @@ -134,7 +159,7 @@ function M.format(options, callback) return callback(string.format("[LSP][%s] %s", client.name, err)) end end - callback() + callback(nil, did_edit) end end -- cgit v1.2.3-70-g09d2