@@ -209,43 +209,43 @@ section IdCompletionUtils
209209 (Name.mkStr p (s.extract 0 ⟨newLen - optDot - len⟩), newLen)
210210 (go id).1
211211
212- def matchNamespace (ns : Name) (nsFragment : Name) (danglingDot : Bool) : Bool :=
213- if danglingDot then
214- if nsFragment != ns && nsFragment.isPrefixOf ns then
215- true
216- else
217- false
218- else
219- match ns, nsFragment with
220- | .str p₁ s₁, .str p₂ s₂ =>
221- if p₁ == p₂ then s₂.charactersIn s₁ else false
222- | _, _ => false
212+ def bestLabelForDecl? (ctx : ContextInfo) (declName : Name) (id : Name) (danglingDot : Bool) :
213+ M (Option Name) := Prod.snd <$> StateT.run (s := none) do
214+ let matchUsingNamespace (ns : Name) : StateT (Option Name) M Unit := do
215+ let some label ← matchDecl? ns id danglingDot declName
216+ | return
217+ modify fun
218+ | none =>
219+ some label
220+ | some bestLabel =>
221+ -- for open namespaces `A` and `A.B` and a decl `A.B.c`, pick the decl `c` over `B.c`
222+ if label.isSuffixOf bestLabel then
223+ some label
224+ else
225+ some bestLabel
226+ let rec visitNamespaces (ns : Name) : StateT (Option Name) M Unit := do
227+ let Name.str p .. := ns
228+ | return ()
229+ matchUsingNamespace ns
230+ visitNamespaces p
231+ -- use current namespace
232+ visitNamespaces ctx.currNamespace
233+ -- use open decls
234+ for openDecl in ctx.openDecls do
235+ let OpenDecl.simple ns exs := openDecl
236+ | pure ()
237+ if exs.contains declName then
238+ continue
239+ matchUsingNamespace ns
240+ matchUsingNamespace Name.anonymous
223241
224242 def completeNamespaces (ctx : ContextInfo) (id : Name) (danglingDot : Bool) : M Unit := do
225243 let env ← getEnv
226- let add (ns : Name) (ns' : Name) : M Unit :=
227- if danglingDot then
228- addNamespaceCompletionItem (ns.replacePrefix (ns' ++ id) Name.anonymous)
229- else
230- addNamespaceCompletionItem (ns.replacePrefix ns' Name.anonymous)
231244 env.getNamespaceSet |>.forM fun ns => do
232245 unless ns.isInternal || env.contains ns do -- Ignore internal and namespaces that are also declaration names
233- for openDecl in ctx.openDecls do
234- match openDecl with
235- | OpenDecl.simple ns' _ =>
236- if matchNamespace ns (ns' ++ id) danglingDot then
237- add ns ns'
238- return ()
239- | _ => pure ()
240- -- use current namespace
241- let rec visitNamespaces (ns' : Name) : M Unit := do
242- if matchNamespace ns (ns' ++ id) danglingDot then
243- add ns ns'
244- else
245- match ns' with
246- | Name.str p .. => visitNamespaces p
247- | _ => return ()
248- visitNamespaces ctx.currNamespace
246+ let label? ← bestLabelForDecl? ctx ns id danglingDot
247+ if let some bestLabel := label? then
248+ addNamespaceCompletionItem bestLabel
249249
250250end IdCompletionUtils
251251
@@ -258,7 +258,7 @@ section DotCompletionUtils
258258 | _ => false
259259 if isConstOf then
260260 return true
261- let some e ← unfoldeDefinitionGuarded ? e | return false
261+ let some e ← unfoldDefinitionGuarded ? e | return false
262262 isDefEqToAppOf e declName
263263
264264 private def isDotCompletionMethod (typeName : Name) (info : ConstantInfo) : MetaM Bool :=
@@ -356,34 +356,7 @@ private def idCompletionCore
356356 -- search for matches in the environment
357357 let env ← getEnv
358358 forEligibleDeclsWithCancellationM fun declName c => do
359- let bestMatch? ← (·.2 ) <$> StateT.run (s := none) do
360- let matchUsingNamespace (ns : Name) : StateT (Option Name) M Unit := do
361- let some label ← matchDecl? ns id danglingDot declName
362- | return
363- modify fun
364- | none =>
365- some label
366- | some bestLabel =>
367- -- for open namespaces `A` and `A.B` and a decl `A.B.c`, pick the decl `c` over `B.c`
368- if label.isSuffixOf bestLabel then
369- some label
370- else
371- some bestLabel
372- let rec visitNamespaces (ns : Name) : StateT (Option Name) M Unit := do
373- let Name.str p .. := ns
374- | return ()
375- matchUsingNamespace ns
376- visitNamespaces p
377- -- use current namespace
378- visitNamespaces ctx.currNamespace
379- -- use open decls
380- for openDecl in ctx.openDecls do
381- let OpenDecl.simple ns exs := openDecl
382- | pure ()
383- if exs.contains declName then
384- continue
385- matchUsingNamespace ns
386- matchUsingNamespace Name.anonymous
359+ let bestMatch? ← bestLabelForDecl? ctx declName id danglingDot
387360 if let some bestLabel := bestMatch? then
388361 addUnresolvedCompletionItem bestLabel (.const declName) (← getCompletionKindForDecl c)
389362 RequestCancellation.check
0 commit comments