33# - fuzzy completions
44# - (maybe) export latex completions into a separate package
55
6+ using REPL
7+
8+ """
9+ is_completion_match(s::AbstractString, prefix::AbstractString, cutoff=3)
10+
11+ Returns true if `s` starts with `prefix` or has a sufficiently high fuzzy score.
12+ """
13+ function is_completion_match (s:: AbstractString , prefix:: AbstractString , cutoff= 3 )
14+ starter = if all (islowercase, prefix)
15+ startswith (lowercase (s), prefix)
16+ else
17+ startswith (s, prefix)
18+ end
19+ starter || REPL. fuzzyscore (prefix, s) >= cutoff
20+ end
21+
622function textDocument_completion_request (params:: CompletionParams , server:: LanguageServerInstance , conn)
723 CIs = CompletionItem[]
824 doc = getdocument (server, URI2 (params. textDocument. uri))
6884
6985function latex_completions (doc, offset, partial, CIs)
7086 for (k, v) in REPL. REPLCompletions. latex_symbols
71- if startswith (string (k), partial)
87+ if is_completion_match (string (k), partial)
7288 t1 = TextEdit (Range (doc, (offset - sizeof (partial)): offset), v)
7389 push! (CIs, CompletionItem (k, 11 , missing , v, v, missing , missing , missing , missing , missing , missing , t1, missing , missing , missing , missing ))
7490 end
@@ -123,13 +139,14 @@ function collect_completions(m::SymbolServer.ModuleStore, spartial, rng, CIs, se
123139 for val in m. vals
124140 n, v = String (val[1 ]), val[2 ]
125141 (startswith (n, " ." ) || startswith (n, " #" )) && continue
126- ! startswith (n, spartial) && continue
142+ ! is_completion_match (n, spartial) && continue
127143 if v isa SymbolServer. VarRef
128144 v = SymbolServer. _lookup (v, getsymbolserver (server), true )
129145 v === nothing && return
130146 end
131147 if StaticLint. isexportedby (n, m) || inclexported
132- push! (CIs, CompletionItem (n, _completion_kind (v, server), MarkupContent (sanitize_docstring (v. doc)), TextEdit (rng, n[nextind (n, sizeof (spartial)): end ])))
148+ rng1 = Range (Position (rng. start. line, rng. start. character - sizeof (spartial)), rng. stop)
149+ push! (CIs, CompletionItem (n, _completion_kind (v, server), MarkupContent (sanitize_docstring (v. doc)), TextEdit (rng1, n)))
133150 elseif dotcomps
134151 rng1 = Range (Position (rng. start. line, rng. start. character - sizeof (spartial)), rng. stop)
135152 push! (CIs, CompletionItem (n, _completion_kind (v, server), MarkupContent (sanitize_docstring (v. doc)), TextEdit (rng1, string (m. name, " ." , n))))
@@ -156,13 +173,14 @@ end
156173function collect_completions (x:: StaticLint.Scope , spartial, rng, CIs, server, inclexported= false , dotcomps= false )
157174 if x. names != = nothing
158175 for n in x. names
159- if startswith (n[1 ], spartial)
176+ if is_completion_match (n[1 ], spartial)
160177 documentation = " "
161178 if n[2 ] isa StaticLint. Binding
162179 documentation = get_hover (n[2 ], documentation, server)
163180 sanitize_docstring (documentation)
164181 end
165- push! (CIs, CompletionItem (n[1 ], _completion_kind (n[2 ], server), MarkupContent (documentation), TextEdit (rng, n[1 ][nextind (n[1 ], sizeof (spartial)): end ])))
182+ rng1 = Range (Position (rng. start. line, rng. start. character - sizeof (spartial)), rng. stop)
183+ push! (CIs, CompletionItem (n[1 ], _completion_kind (n[2 ], server), MarkupContent (documentation), TextEdit (rng1, n[1 ])))
166184 end
167185 end
168186 end
@@ -189,15 +207,17 @@ function _get_dot_completion(px::EXPR, spartial, rng, CIs, server)
189207 elseif refof (px). type isa SymbolServer. DataTypeStore
190208 for a in refof (px). type. fieldnames
191209 a = String (a)
192- if startswith (a, spartial)
193- push! (CIs, CompletionItem (a, 2 , MarkupContent (a), TextEdit (rng, a[nextind (a, sizeof (spartial)): end ])))
210+ if is_completion_match (a, spartial)
211+ rng1 = Range (Position (rng. start. line, rng. start. character - sizeof (spartial)), rng. stop)
212+ push! (CIs, CompletionItem (a, 2 , MarkupContent (a), TextEdit (rng1, a)))
194213 end
195214 end
196215 elseif refof (px). type isa StaticLint. Binding && refof (px). type. val isa SymbolServer. DataTypeStore
197216 for a in refof (px). type. val. fieldnames
198217 a = String (a)
199- if startswith (a, spartial)
200- push! (CIs, CompletionItem (a, 2 , MarkupContent (a), TextEdit (rng, a[nextind (a, sizeof (spartial)): end ])))
218+ if is_completion_match (a, spartial)
219+ rng1 = Range (Position (rng. start. line, rng. start. character - sizeof (spartial)), rng. stop)
220+ push! (CIs, CompletionItem (a, 2 , MarkupContent (a), TextEdit (rng1, a)))
201221 end
202222 end
203223 elseif refof (px). type isa StaticLint. Binding && refof (px). type. val isa EXPR && CSTParser. defines_struct (refof (px). type. val) && scopeof (refof (px). type. val) isa StaticLint. Scope
247267function string_completion (doc, offset, rng, t, CIs)
248268 path_completion (doc, offset, rng, t, CIs)
249269 # Need to adjust things for quotation marks
250- if t. kind in (CSTParser. Tokenize. Tokens. STRING,CSTParser. Tokenize. Tokens. CMD)
270+ if t. kind in (CSTParser. Tokenize. Tokens. STRING, CSTParser. Tokenize. Tokens. CMD)
251271 t. startbyte < offset <= t. endbyte || return
252272 relative_offset = offset - t. startbyte - 1
253273 content = t. val[2 : prevind (t. val, lastindex (t. val))]
@@ -326,17 +346,18 @@ is_in_import_statement(x::EXPR) = is_in_fexpr(x, x -> headof(x) in (:using, :imp
326346
327347function import_completions (doc, offset, rng, ppt, pt, t, is_at_end, x, CIs, server)
328348 import_statement = StaticLint. get_parent_fexpr (x, x -> headof (x) === :using || headof (x) === :import )
329-
349+
330350 import_root = get_import_root (import_statement)
331-
351+
332352 if (t. kind == CSTParser. Tokens. WHITESPACE && pt. kind ∈ (CSTParser. Tokens. USING, CSTParser. Tokens. IMPORT, CSTParser. Tokens. IMPORTALL, CSTParser. Tokens. COMMA, CSTParser. Tokens. COLON)) ||
333353 (t. kind in (CSTParser. Tokens. COMMA, CSTParser. Tokens. COLON))
334354 # no partial, no dot
335355 if import_root != = nothing && refof (import_root) isa SymbolServer. ModuleStore
336356 for (n, m) in refof (import_root). vals
337357 n = String (n)
338- if startswith (n, t. val) && ! startswith (n, " #" )
339- push! (CIs, CompletionItem (n, _completion_kind (m, server), MarkupContent (m isa SymbolServer. SymStore ? sanitize_docstring (m. doc) : n), TextEdit (rng, n[length (t. val) + 1 : end ])))
358+ if is_completion_match (n, t. val) && ! startswith (n, " #" )
359+ rng1 = Range (doc, offset - sizeof (t. val): offset)
360+ push! (CIs, CompletionItem (n, _completion_kind (m, server), MarkupContent (m isa SymbolServer. SymStore ? sanitize_docstring (m. doc) : n), TextEdit (rng1, n)))
340361 end
341362 end
342363 else
@@ -358,24 +379,27 @@ function import_completions(doc, offset, rng, ppt, pt, t, is_at_end, x, CIs, ser
358379 rootmod = StaticLint. getsymbolserver (server)[Symbol (ppt. val)]
359380 for (n, m) in rootmod. vals
360381 n = String (n)
361- if startswith (n, t. val) && ! startswith (n, " #" )
362- push! (CIs, CompletionItem (n, _completion_kind (m, server), MarkupContent (m isa SymbolServer. SymStore ? sanitize_docstring (m. doc) : n), TextEdit (rng, n[length (t. val) + 1 : end ])))
382+ if is_completion_match (n, t. val) && ! startswith (n, " #" )
383+ rng1 = Range (doc, offset - sizeof (t. val): offset)
384+ push! (CIs, CompletionItem (n, _completion_kind (m, server), MarkupContent (m isa SymbolServer. SymStore ? sanitize_docstring (m. doc) : n), TextEdit (rng1, n)))
363385 end
364386 end
365387 end
366388 else
367389 if import_root != = nothing && refof (import_root) isa SymbolServer. ModuleStore
368390 for (n, m) in refof (import_root). vals
369391 n = String (n)
370- if startswith (n, t. val) && ! startswith (n, " #" )
371- push! (CIs, CompletionItem (n, _completion_kind (m, server), MarkupContent (m isa SymbolServer. SymStore ? sanitize_docstring (m. doc) : n), TextEdit (rng, n[length (t. val) + 1 : end ])))
392+ if is_completion_match (n, t. val) && ! startswith (n, " #" )
393+ rng1 = Range (doc, offset - sizeof (t. val): offset)
394+ push! (CIs, CompletionItem (n, _completion_kind (m, server), MarkupContent (m isa SymbolServer. SymStore ? sanitize_docstring (m. doc) : n), TextEdit (rng1, n)))
372395 end
373396 end
374397 else
375398 for (n, m) in StaticLint. getsymbolserver (server)
376399 n = String (n)
377- if startswith (n, t. val)
378- push! (CIs, CompletionItem (n, 9 , MarkupContent (m isa SymbolServer. SymStore ? m. doc : n), TextEdit (rng, n[nextind (n, sizeof (t. val)): end ])))
400+ if is_completion_match (n, t. val)
401+ rng1 = Range (doc, offset - sizeof (t. val): offset)
402+ push! (CIs, CompletionItem (n, 9 , MarkupContent (m isa SymbolServer. SymStore ? m. doc : n), TextEdit (rng1, n)))
379403 end
380404 end
381405 end
0 commit comments