Skip to content

Commit 2e37993

Browse files
committed
fix: convert to utf-8 encoding on text edits
closes #188 closes #200
1 parent 1ce30c9 commit 2e37993

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

lua/blink/cmp/accept/init.lua

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ local function accept(item)
3434
local temp_text_edit = vim.deepcopy(item.textEdit)
3535
temp_text_edit.newText = ''
3636
table.insert(all_text_edits, temp_text_edit)
37-
text_edits_lib.apply_text_edits(item.client_id, all_text_edits)
37+
text_edits_lib.apply_text_edits(all_text_edits)
3838

3939
-- Expand the snippet
4040
vim.snippet.expand(item.textEdit.newText)
4141

4242
-- OR Normal: Apply the text edit and move the cursor
4343
else
4444
table.insert(all_text_edits, item.textEdit)
45-
text_edits_lib.apply_text_edits(item.client_id, all_text_edits)
45+
text_edits_lib.apply_text_edits(all_text_edits)
4646
-- TODO: should move the cursor only by the offset since text edit handles everything else?
4747
vim.api.nvim_win_set_cursor(0, {
4848
vim.api.nvim_win_get_cursor(0)[1],

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

+33-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
local config = require('blink.cmp.config')
22
local text_edits = {}
33

4+
--- Position is a https://microsoft.github.io/language-server-protocol/specifications/specification-current/#position
5+
--- @param position lsp.Position
6+
--- @param offset_encoding string|nil utf-8|utf-16|utf-32
7+
--- @return integer
8+
local function get_line_byte_from_position(position, offset_encoding)
9+
local bufnr = vim.api.nvim_get_current_buf()
10+
-- LSP's line and characters are 0-indexed
11+
-- Vim's line and columns are 1-indexed
12+
local col = position.character
13+
-- When on the first character, we can ignore the difference between byte and
14+
-- character
15+
if col > 0 then
16+
local line = vim.api.nvim_buf_get_lines(bufnr, position.line, position.line + 1, true)[1] or ''
17+
return vim.lsp.util._str_byteindex_enc(line, col, offset_encoding or 'utf-16')
18+
end
19+
return col
20+
end
21+
422
--- @param item blink.cmp.CompletionItem
523
--- @return lsp.TextEdit
624
function text_edits.get_from_item(item)
@@ -17,6 +35,15 @@ function text_edits.get_from_item(item)
1735
end
1836

1937
local text_edit = vim.deepcopy(item.textEdit)
38+
39+
local client = vim.lsp.get_client_by_id(client_id)
40+
local offset_encoding = client ~= nil and client.offset_encoding or 'utf-8'
41+
42+
if offset_encoding ~= 'utf-8' then
43+
text_edit.range.start.character = get_line_byte_from_position(text_edit.range.start, offset_encoding)
44+
text_edit.range['end'].character = get_line_byte_from_position(text_edit.range['end'], offset_encoding)
45+
end
46+
2047
local offset = vim.api.nvim_win_get_cursor(0)[2] - item.cursor_column
2148
text_edit.range['end'].character = text_edit.range['end'].character + offset
2249
return text_edit
@@ -26,12 +53,9 @@ function text_edits.get_from_item(item)
2653
return text_edits.guess_text_edit(item)
2754
end
2855

29-
--- @param client_id number
3056
--- @param edits lsp.TextEdit[]
31-
function text_edits.apply_text_edits(client_id, edits)
32-
local client = vim.lsp.get_client_by_id(client_id)
33-
local offset_encoding = client ~= nil and client.offset_encoding or 'utf-16'
34-
vim.lsp.util.apply_text_edits(edits, vim.api.nvim_get_current_buf(), offset_encoding)
57+
function text_edits.apply_text_edits(edits)
58+
vim.lsp.util.apply_text_edits(edits, vim.api.nvim_get_current_buf(), 'utf-8')
3559
end
3660

3761
--- @param text_edit lsp.TextEdit
@@ -52,7 +76,7 @@ function text_edits.undo_text_edit(text_edit)
5276
text_edit.range = text_edits.get_undo_text_edit_range(text_edit)
5377
text_edit.newText = ''
5478

55-
vim.lsp.util.apply_text_edits({ text_edit }, vim.api.nvim_get_current_buf(), 'utf-16')
79+
text_edits.apply_text_edits({ text_edit })
5680
end
5781

5882
--- @param item blink.cmp.CompletionItem
@@ -69,13 +93,15 @@ function text_edits.guess_text_edit(item)
6993
local current_line = vim.api.nvim_win_get_cursor(0)[1]
7094

7195
-- convert to 0-index
72-
return {
96+
local text_edit = {
7397
range = {
7498
start = { line = current_line - 1, character = range.start_col - 1 },
7599
['end'] = { line = current_line - 1, character = range.start_col - 1 + range.length },
76100
},
77101
newText = word,
78102
}
103+
104+
return text_edit
79105
end
80106

81107
return text_edits

0 commit comments

Comments
 (0)