Skip to content

Commit a2f6cfb

Browse files
fix: make ghost-text extmark with pcall (#287)
* fix: make ghost-text extmark with pcall * fix: incorrect text edit end character at end of line --------- Co-authored-by: Liam Dyer <[email protected]>
1 parent 69a987b commit a2f6cfb

File tree

2 files changed

+22
-22
lines changed

2 files changed

+22
-22
lines changed

lua/blink/cmp/accept/text-edits.lua

+21-20
Original file line numberDiff line numberDiff line change
@@ -35,24 +35,22 @@ end
3535

3636
--- Grabbed from vim.lsp.utils. Converts an offset_encoding to byte offset
3737
--- @param position lsp.Position
38-
--- @param offset_encoding string|nil utf-8|utf-16|utf-32
38+
--- @param offset_encoding? 'utf-8'|'utf-16'|'utf-32'
3939
--- @return integer
4040
local function get_line_byte_from_position(position, offset_encoding)
4141
local bufnr = vim.api.nvim_get_current_buf()
42-
-- LSP's line and characters are 0-indexed
43-
-- Vim's line and columns are 1-indexed
4442
local col = position.character
45-
-- When on the first character, we can ignore the difference between byte and
46-
-- character
47-
if col > 0 then
48-
local line = vim.api.nvim_buf_get_lines(bufnr, position.line, position.line + 1, true)[1] or ''
49-
if vim.fn.has('nvim-0.11.0') == 1 then
50-
return vim.str_byteindex(line, offset_encoding or 'utf-16', col, false)
51-
else
52-
return vim.lsp.util._str_byteindex_enc(line, col, offset_encoding or 'utf-16')
53-
end
43+
44+
-- When on the first character, we can ignore the difference between byte and character
45+
if col == 0 then return 0 end
46+
47+
local line = vim.api.nvim_buf_get_lines(bufnr, position.line, position.line + 1, false)[1] or ''
48+
if vim.fn.has('nvim-0.11.0') == 1 then
49+
col = vim.str_byteindex(line, offset_encoding or 'utf-16', col, false)
50+
else
51+
col = vim.lsp.util._str_byteindex_enc(line, col, offset_encoding or 'utf-16')
5452
end
55-
return col
53+
return math.min(col, #line)
5654
end
5755

5856
--- Gets the text edit from an item, handling insert/replace ranges and converts
@@ -67,7 +65,7 @@ function text_edits.get_from_item(item)
6765
text_edit = {
6866
newText = item.textEditText or item.insertText or item.label,
6967
-- FIXME: temporarily convert insertReplaceEdit to regular textEdit
70-
range = item.editRange.insert or item.editRange.replace or item.editRange,
68+
range = vim.deepcopy(item.editRange.insert or item.editRange.replace or item.editRange),
7169
}
7270
end
7371

@@ -83,19 +81,22 @@ function text_edits.get_from_item(item)
8381
local client = vim.lsp.get_client_by_id(item.client_id)
8482
local offset_encoding = client ~= nil and client.offset_encoding or 'utf-8'
8583

86-
-- convert the offset encoding to utf-8 if necessary
87-
if offset_encoding ~= 'utf-8' then
88-
text_edit.range.start.character = get_line_byte_from_position(text_edit.range.start, offset_encoding)
89-
text_edit.range['end'].character = get_line_byte_from_position(text_edit.range['end'], offset_encoding)
90-
end
91-
9284
-- Adjust the position of the text edit to be the current cursor position
9385
-- since the data might be outdated. We compare the cursor column position
9486
-- from when the items were fetched versus the current.
9587
-- HACK: is there a better way?
9688
-- TODO: take into account the offset_encoding
9789
local offset = vim.api.nvim_win_get_cursor(0)[2] - item.cursor_column
9890
text_edit.range['end'].character = text_edit.range['end'].character + offset
91+
92+
-- convert the offset encoding to utf-8 if necessary
93+
-- TODO: we have to do this last because it applies a max on the position based on the length of the line
94+
-- so it would break the offset code when removing characters at the end of the line
95+
if offset_encoding ~= 'utf-8' then
96+
text_edit.range.start.character = get_line_byte_from_position(text_edit.range.start, offset_encoding)
97+
text_edit.range['end'].character = get_line_byte_from_position(text_edit.range['end'], offset_encoding)
98+
end
99+
99100
return text_edit
100101
end
101102

lua/blink/cmp/windows/ghost-text.lua

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ local ghost_text = {
1717
--- @param textEdit lsp.TextEdit
1818
local function get_still_untyped_text(textEdit)
1919
local type_text_length = textEdit.range['end'].character - textEdit.range.start.character
20-
local result = textEdit.newText:sub(type_text_length + 1)
21-
return result
20+
return textEdit.newText:sub(type_text_length + 1)
2221
end
2322

2423
function ghost_text.setup()

0 commit comments

Comments
 (0)