Skip to content

Commit

Permalink
Apply format TextEdits in reverse order
Browse files Browse the repository at this point in the history
The `TextEdit` ranges don't consider the intermediate doc states, so applying them in reverse order (from bottom to top) should result in edits occurring at the intended locations.
  • Loading branch information
Guldoman committed Feb 25, 2024
1 parent 35880ac commit b11b930
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,9 @@ end
---@param doc core.doc
---@param text_edit table
---@param is_snippet boolean
---@param update_cursor_position boolean
---@return boolean True on success
local function apply_edit(server, doc, text_edit, is_snippet)
local function apply_edit(server, doc, text_edit, is_snippet, update_cursor_position)
local range = nil

if text_edit.range then
Expand Down Expand Up @@ -433,7 +434,9 @@ local function apply_edit(server, doc, text_edit, is_snippet)
end

doc:insert(line1, col1, text)
doc:set_selection(line2, col1+#text, line2, col1+#text)
if update_cursor_position then
doc:set_selection(line2, col1+#text, line2, col1+#text)
end

return true
end
Expand Down Expand Up @@ -513,7 +516,7 @@ local function autocomplete_onselect(index, item)
if dv then
local is_snippet = completion.insertTextFormat
and completion.insertTextFormat == Server.insert_text_format.Snippet
local edit_applied = apply_edit(item.data.server, dv.doc, completion.textEdit, is_snippet)
local edit_applied = apply_edit(item.data.server, dv.doc, completion.textEdit, is_snippet, true)
if edit_applied then
-- Retrigger code completion if last char is a trigger
-- this is useful for example with clangd when autocompleting
Expand Down Expand Up @@ -1947,8 +1950,13 @@ function lsp.request_document_format(doc)
if response.error and response.error.message then
log(server, "Error formatting: " .. response.error.message)
elseif response.result and #response.result > 0 then
for _, result in pairs(response.result) do
apply_edit(server, doc, result)
-- Apply edits in reverse, as the ranges don't consider
-- the intermediate states.
-- Consider the TextEdits as already sorted.
-- If there are servers that don't sort their TextEdits,
-- we'll add sorting code.
for i=#response.result,1,-1 do
apply_edit(server, doc, response.result[i], false, false)
end
log(server, "Formatted document")
else
Expand Down

0 comments on commit b11b930

Please sign in to comment.