Skip to content

Commit c29e528

Browse files
authored
Merge pull request #1035 from julia-vscode/sp/fix-multibyte-partial-completions
Fix completions with multibyte chars in partial
2 parents 50d7a09 + 2d9f942 commit c29e528

File tree

3 files changed

+32
-21
lines changed

3 files changed

+32
-21
lines changed

src/document.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ get_offset(doc, p::Position) = get_offset(doc, p.line, p.character)
102102
get_offset(doc, r::Range) = get_offset(doc, r.start):get_offset(doc, r.stop)
103103

104104
# 1-based. Basically the index at which (line, character) can be found in the document.
105+
get_offset2(doc::Document, p::Position, forgiving_mode=false) = get_offset2(doc, p.line, p.character, forgiving_mode)
105106
function get_offset2(doc::Document, line::Integer, character::Integer, forgiving_mode=false)
106107
line_offsets = get_line_offsets2!(doc)
107108
text = get_text(doc)
@@ -134,9 +135,12 @@ function get_offset2(doc::Document, line::Integer, character::Integer, forgiving
134135
pos = nextind(text, pos)
135136
end
136137

137-
return pos
138+
return pos
138139
end
139140

141+
# get_offset, but correct
142+
get_offset3(args...) = get_offset2(args...) - 1
143+
140144
# Note: to be removed
141145
function obscure_text(s)
142146
i = 1

src/requests/completions.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ end
4141
function textDocument_completion_request(params::CompletionParams, server::LanguageServerInstance, conn)
4242
state = let
4343
doc = getdocument(server, URI2(params.textDocument.uri))
44-
offset = get_offset(doc, params.position)
44+
offset = get_offset3(doc, params.position)
4545
rng = Range(doc, offset:offset)
4646
x = get_expr(getcst(doc), offset)
4747
using_stmts = server.completion_mode == :import ? get_preexisting_using_stmts(x, doc) : Dict()
@@ -100,7 +100,7 @@ end
100100

101101

102102
function get_partial_completion(state::CompletionState)
103-
ppt, pt, t = toks = get_toks(state.doc, state.offset)
103+
ppt, pt, t = get_toks(state.doc, state.offset)
104104
is_at_end = state.offset == t.endbyte + 1
105105
return ppt, pt, t, is_at_end
106106
end
@@ -161,7 +161,7 @@ const snippet_completions = Dict{String,String}(
161161

162162

163163
function texteditfor(state::CompletionState, partial, n)
164-
TextEdit(Range(Position(state.range.start.line, state.range.start.character - sizeof(partial)), state.range.stop), n)
164+
TextEdit(Range(Position(state.range.start.line, max(state.range.start.character - length(partial), 0)), state.range.stop), n)
165165
end
166166

167167
function collect_completions(m::SymbolServer.ModuleStore, spartial, state::CompletionState, inclexported=false, dotcomps=false)
@@ -319,14 +319,15 @@ function string_completion(t, state::CompletionState)
319319
path_completion(t, state)
320320
# Need to adjust things for quotation marks
321321
if t.kind in (CSTParser.Tokenize.Tokens.STRING,CSTParser.Tokenize.Tokens.CMD)
322-
t.startbyte < state.offset <= t.endbyte || return
322+
t.startbyte + 1 < state.offset <= t.endbyte || return
323323
relative_offset = state.offset - t.startbyte - 1
324324
content = t.val[2:prevind(t.val, lastindex(t.val))]
325325
else
326-
t.startbyte < state.offset <= t.endbyte - 2 || return
326+
t.startbyte + 3 < state.offset <= t.endbyte - 2 || return
327327
relative_offset = state.offset - t.startbyte - 3
328328
content = t.val[4:prevind(t.val, lastindex(t.val), 3)]
329329
end
330+
relative_offset = clamp(relative_offset, firstindex(content), lastindex(content))
330331
partial = is_latex_comp(content, relative_offset)
331332
!isempty(partial) && latex_completions(partial, state)
332333
end

test/requests/completions.jl

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ completion_test(line, char) = LanguageServer.textDocument_completion_request(Lan
1212
""")
1313
@test completion_test(0, 9).items[1].textEdit.newText == ""
1414
@test completion_test(0, 9).items[1].textEdit.range == LanguageServer.Range(0, 0, 0, 9)
15-
15+
1616
@test completion_test(1, 10).items[1].textEdit.newText == ""
1717
@test completion_test(1, 10).items[1].textEdit.range == LanguageServer.Range(1, 1, 1, 10)
18-
18+
1919
@test completion_test(2, 10).items[1].textEdit.newText == ""
2020
@test completion_test(2, 10).items[1].textEdit.range == LanguageServer.Range(2, 1, 2, 10)
21-
21+
2222
@test completion_test(3, 10).items[1].textEdit.newText == ""
2323
@test completion_test(3, 10).items[1].textEdit.range == LanguageServer.Range(3, 1, 3, 10)
24-
24+
2525
@test completion_test(4, 12).items[1].textEdit.newText == ""
2626
@test completion_test(4, 12).items[1].textEdit.range == LanguageServer.Range(4, 3, 4, 12)
2727

@@ -41,7 +41,7 @@ end
4141

4242
settestdoc("import ")
4343
@test all(item.label in ("Main", "Base", "Core") for item in completion_test(0, 7).items)
44-
44+
4545
settestdoc("""module M end
4646
import .""")
4747
@test_broken completion_test(1, 8).items[1].label == "M"
@@ -70,7 +70,7 @@ end
7070
@test any(item.label == "quot" for item in completion_test(1, 10).items)
7171

7272
settestdoc("""
73-
module M
73+
module M
7474
inner = 1
7575
end
7676
M.
@@ -94,8 +94,6 @@ end
9494
@test all(item.label in ("f1", "f2") for item in completion_test(1, 2).items)
9595
end
9696

97-
98-
9997
@testset "token completions" begin
10098
settestdoc("B")
10199
@test any(item.label == "Base" for item in completion_test(0, 1).items)
@@ -105,25 +103,33 @@ end
105103

106104
settestdoc("@t")
107105
@test any(item.label == "@time" for item in completion_test(0, 2).items)
108-
106+
109107
settestdoc("i")
110108
@test any(item.label == "if" for item in completion_test(0, 1).items)
111-
109+
112110
settestdoc("i")
113111
@test any(item.label == "in" for item in completion_test(0, 1).items)
114-
112+
115113
settestdoc("for")
116114
@test any(item.label == "for" for item in completion_test(0, 3).items)
117115

118116
settestdoc("in")
119117
@test any(item.label == "in" for item in completion_test(0, 2).items)
120-
118+
121119
settestdoc("isa")
122120
@test any(item.label == "isa" for item in completion_test(0, 3).items)
123121
end
124122

125123
@testset "scope var completions" begin
126-
settestdoc("""myvar = 1
127-
myv""")
128-
@test any(item.label == "myvar" for item in completion_test(1, 3).items)
124+
settestdoc("""
125+
myvar = 1
126+
βbb = 2
127+
bβb = 3
128+
myv
129+
βb
130+
131+
""")
132+
@test any(item.label == "myvar" for item in completion_test(3, 3).items)
133+
@test any(item.label == "βbb" for item in completion_test(4, 2).items)
134+
@test any(item.label == "bβb" for item in completion_test(5, 2).items)
129135
end

0 commit comments

Comments
 (0)