fix: auto-completion bugs and performance (#3460)

This PR addresses several performance issues in the auto-completion
implementation. It also fixes a number of smaller bugs related to
auto-completion.

In a file with `import Mathlib`, the performance of various kinds of
completions has improved as follows:
- Completing `C`: 49000ms -> 1400ms
- Completing `Cat`: 14300ms -> 1000ms
- Completing `x.` for `x : Nat`: 3700ms -> 220ms
- Completing `.` for an expected type of `Nat`: 11000ms -> 180ms

The following bugs have been fixed as well:
- VS Code never used our custom completion order. Now, the server fuzzy
completion score decides the order that completions appear in.
- Dot auto-completion for private types did not work at all. It does
now.
- Completing `.<identifier>` (where the expected type is used to infer
the namespace) did not filter by the expected type and instead displayed
all matching constants in the respective namespace. Now, it uses the
expected type for filtering. Note that this is not perfect because
sub-namespaces are technically correct completions as well (e.g.
`.Foo.foobar`). Implementing this is future work.
- Completing `.` was often not possible at all. Now, as long as the `.`
is not used in a bracket (where it may be used for the anonymous lambda
feature, e.g. `(. + 1)`), it triggers the correct completion.
-  Fixes #3228.
- The auto-completion in `#check` commands would always try to complete
identifiers using the full declaration name (including namespaces) if it
could be resolved. Now it simply uses the identifier itself in case
users want to complete this identifier to another identifier.

## Details

Regarding completion performance, I have more ideas on how to improve it
further in the future.

Other changes:
- The feature that completions with a matching expected type are sorted
to the top of the server-side ordering was removed. This was never
enabled in VS Code because it would use its own completion item order
and when testing it I found it to be more confusing than useful.
- In the server-side ordering, we would always display keywords at the
top of the list. They are now displayed according to their fuzzy match
score as well.

The following approaches have been used to improve performance:
- Pretty-printing the type for every single completion made up a
significant amount of the time needed to compute the completions. We now
do not pretty-print the type for every single completion that is offered
to the user anymore. Instead, the language server now supports
`completionItem/resolve` requests to compute the type lazily when the
user selects a completion item.
- Note that we need to keep the amount of properties that we compute in
a resolve request to a minimum. When the server receives the resolve
request, the document state may have changed from the state it was in
when the initial auto-completion request was received. LSP doesn't tell
us when it will stop sending resolve requests, so we cannot keep this
state around, as we would have to keep it around forever.
LSP's solution for this dilemma is to have servers send all the state
they need to compute a response to a resolve request to the client as
part of the initial auto completion response (which then sends it back
as part of the resolve request), but this is clearly infeasible for all
real language servers where the amount of state needed to resolve a
request is massive.
This means that the only practical solution is to use the current state
to compute a response to the resolve request, which may yield an
incorrect result. This scenario can especially occur when using
LiveShare where the document is edited by another person while cycling
through available completions.
- Request handlers can now specify a "header caching handler" that is
called after elaborating the header of a file. Request handlers can use
this caching handler to compute caches for information stored in the
header. The auto-completion uses this to pre-compute non-blacklisted
imported declarations, which in turn allow us to iterate only over
non-blacklisted imported declarations where we would before iterate over
all declarations in the environment. This is significant because
blacklisted declarations make up about 4/5 of all declarations.
- Dot completion now looks up names modulo private prefixes to figure
out whether a declaration is in the namespace of the type to the left of
the dot instead of first stripping the private prefix from the name and
then comparing it. This has the benefit that we do not need to scan the
full name in most cases.

This PR also adds a couple of regression tests for fixed bugs, but *no
benchmarks*. We will add these in the future when we add proper support
for benchmarking server interaction sessions to our benchmarking
architecture.

All tests that were broken by producing different completion output
(empty `detail` field, added `sortText?` and `data?` fields) have been
manually checked by me to be still correct before replacing their
expected output.
This commit is contained in:
Marc Huisinga 2024-02-26 10:43:19 +01:00 committed by GitHub
parent 88fbe2e531
commit a929c0176d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
48 changed files with 2096 additions and 376 deletions

View file

@ -47,19 +47,19 @@ structure CompletionItem where
documentation? : Option MarkupContent := none
kind? : Option CompletionItemKind := none
textEdit? : Option InsertReplaceEdit := none
sortText? : Option String := none
data? : Option Json := none
/-
tags? : CompletionItemTag[]
deprecated? : boolean
preselect? : boolean
sortText? : string
filterText? : string
insertText? : string
insertTextFormat? : InsertTextFormat
insertTextMode? : InsertTextMode
additionalTextEdits? : TextEdit[]
commitCharacters? : string[]
command? : Command
data? : any -/
command? : Command -/
deriving FromJson, ToJson, Inhabited
structure CompletionList where

View file

@ -534,10 +534,10 @@ open Meta
def elabCheckCore (ignoreStuckTC : Bool) : CommandElab
| `(#check%$tk $term) => withoutModifyingEnv <| runTermElabM fun _ => Term.withDeclName `_check do
-- show signature for `#check id`/`#check @id`
if let `($_:ident) := term then
if let `($id:ident) := term then
try
for c in (← resolveGlobalConstWithInfos term) do
addCompletionInfo <| .id term c (danglingDot := false) {} none
addCompletionInfo <| .id term id.getId (danglingDot := false) {} none
logInfoAt tk <| .ofPPFormat { pp := fun
| some ctx => ctx.runMetaM <| PrettyPrinter.ppSignature c
| none => return f!"{c}" -- should never happen

View file

@ -158,7 +158,10 @@ private def mkTacticMVar (type : Expr) (tacticCode : Syntax) : TermElabM Expr :=
@[builtin_term_elab noImplicitLambda] def elabNoImplicitLambda : TermElab := fun stx expectedType? =>
elabTerm stx[1] (mkNoImplicitLambdaAnnotation <$> expectedType?)
@[builtin_term_elab Lean.Parser.Term.cdot] def elabBadCDot : TermElab := fun _ _ =>
@[builtin_term_elab Lean.Parser.Term.cdot] def elabBadCDot : TermElab := fun stx expectedType? => do
if stx[0].getAtomVal == "." then
-- Users may input bad cdots because they are trying to auto-complete them using the expected type
addCompletionInfo <| CompletionInfo.dotId stx .anonymous (← getLCtx) expectedType?
throwError "invalid occurrence of `·` notation, it must be surrounded by parentheses (e.g. `(· + 1)`)"
@[builtin_term_elab str] def elabStrLit : TermElab := fun stx _ => do

View file

@ -49,14 +49,25 @@ def PartialContextInfo.mergeIntoOuter?
some { outer with parentDecl? := innerParentDecl }
def CompletionInfo.stx : CompletionInfo → Syntax
| dot i .. => i.stx
| id stx .. => stx
| dotId stx .. => stx
| fieldId stx .. => stx
| namespaceId stx => stx
| option stx => stx
| dot i .. => i.stx
| id stx .. => stx
| dotId stx .. => stx
| fieldId stx .. => stx
| namespaceId stx => stx
| option stx => stx
| endSection stx .. => stx
| tactic stx .. => stx
| tactic stx .. => stx
/--
Obtains the `LocalContext` from this `CompletionInfo` if available and yields an empty context
otherwise.
-/
def CompletionInfo.lctx : CompletionInfo → LocalContext
| dot i .. => i.lctx
| id _ _ _ lctx .. => lctx
| dotId _ _ lctx .. => lctx
| fieldId _ _ lctx .. => lctx
| _ => .empty
def CustomInfo.format : CustomInfo → Format
| i => f!"CustomInfo({i.value.typeName})"

View file

@ -29,11 +29,21 @@ builtin_initialize completionBlackListExt : TagDeclarationExtension ← mkTagDec
def addToCompletionBlackList (env : Environment) (declName : Name) : Environment :=
completionBlackListExt.tag env declName
/--
Checks whether a given name is internal due to something other than `_private`.
Correctly deals with names like `_private.<SomeNamespace>.0.<SomeType>._sizeOf_1` in a private type
`SomeType`, which `n.isInternal && !isPrivateName n` does not.
-/
private def isInternalNameModuloPrivate : Name → Bool
| n@(.str p s) => s.get 0 == '_' && n != privateHeader || isInternalNameModuloPrivate p
| .num p _ => isInternalNameModuloPrivate p
| _ => false
/--
Return true if name is blacklisted for completion purposes.
-/
private def isBlacklisted (env : Environment) (declName : Name) : Bool :=
declName.isInternal && !isPrivateName declName
isInternalNameModuloPrivate declName
|| isAuxRecursor env declName
|| isNoConfusion env declName
|| isRecCore env declName

View file

@ -47,7 +47,7 @@ def isPrivateNameExport (n : Name) : Bool :=
Return `true` if `n` is of the form `_private.<module_name>.0`
See comment above.
-/
private def isPrivatePrefix (n : Name) : Bool :=
def isPrivatePrefix (n : Name) : Bool :=
match n with
| .num p 0 => go p
| _ => false

View file

@ -15,6 +15,65 @@ import Lean.Meta.Tactic.Apply
import Lean.Meta.Match.MatcherInfo
import Lean.Server.InfoUtils
import Lean.Parser.Extension
import Lean.Server.FileSource
import Lean.Server.CompletionItemData
private partial def Lean.Server.Completion.consumeImplicitPrefix (e : Expr) (k : Expr → MetaM α) : MetaM α := do
match e with
| Expr.forallE n d b c =>
-- We do not consume instance implicit arguments because the user probably wants be aware of this dependency
if c == .implicit then
Meta.withLocalDecl n c d fun arg =>
consumeImplicitPrefix (b.instantiate1 arg) k
else
k e
| _ => k e
namespace Lean.Lsp
/--
Identifier that is sent from the server to the client as part of the `CompletionItem.data?` field.
Needed to resolve the `CompletionItem` when the client sends a `completionItem/resolve` request
for that item, again containing the `data?` field provided by the server.
-/
inductive CompletionIdentifier where
| const (declName : Name)
| fvar (id : FVarId)
deriving FromJson, ToJson
/--
`CompletionItemData` that also contains a `CompletionIdentifier`.
See the documentation of`CompletionItemData` and `CompletionIdentifier`.
-/
structure CompletionItemDataWithId extends CompletionItemData where
id? : Option CompletionIdentifier
deriving FromJson, ToJson
/--
Fills the `CompletionItem.detail?` field of `item` using the pretty-printed type identified by `id`.
-/
def CompletionItem.resolve
(item : CompletionItem)
(id : CompletionIdentifier)
: MetaM CompletionItem := do
let env ← getEnv
let lctx ← getLCtx
let mut item := item
if item.detail?.isNone then
let type? := match id with
| .const declName =>
env.find? declName |>.map ConstantInfo.type
| .fvar id =>
lctx.find? id |>.map LocalDecl.type
let detail? ← type?.mapM fun type =>
Lean.Server.Completion.consumeImplicitPrefix type fun typeWithoutImplicits =>
return toString (← Meta.ppExpr typeWithoutImplicits)
item := { item with detail? := detail? }
return item
end Lean.Lsp
namespace Lean.Server.Completion
open Lsp
@ -22,55 +81,93 @@ open Elab
open Meta
open FuzzyMatching
private partial def consumeImplicitPrefix (e : Expr) (k : Expr → MetaM α) : MetaM α := do
match e with
| Expr.forallE n d b c =>
-- We do not consume instance implicit arguments because the user probably wants be aware of this dependency
if c == .implicit then
withLocalDecl n c d fun arg =>
consumeImplicitPrefix (b.instantiate1 arg) k
else
k e
| _ => k e
/-- Cached header declarations for which `allowCompletion headerEnv decl` is true. -/
builtin_initialize eligibleHeaderDeclsRef : IO.Ref (HashMap Name ConstantInfo) ← IO.mkRef {}
private def isTypeApplicable (type : Expr) (expectedType? : Option Expr) : MetaM Bool :=
try
match expectedType? with
| none => return true
| some expectedType =>
let mut (numArgs, hasMVarHead) ← getExpectedNumArgsAux type
unless hasMVarHead do
let targetTypeNumArgs ← getExpectedNumArgs expectedType
numArgs := numArgs - targetTypeNumArgs
let (_, _, type) ← forallMetaTelescopeReducing type (some numArgs)
-- TODO take coercions into account
-- We use `withReducible` to make sure we don't spend too much time unfolding definitions
-- Alternative: use default and small number of heartbeats
withReducible <| withoutModifyingState <| isDefEq type expectedType
catch _ =>
return false
/-- Caches the declarations in the header for which `allowCompletion headerEnv decl` is true. -/
def fillEligibleHeaderDecls (headerEnv : Environment) : IO Unit := do
eligibleHeaderDeclsRef.modify fun startEligibleHeaderDecls =>
(·.2) <| StateT.run (m := Id) (s := startEligibleHeaderDecls) do
headerEnv.constants.forM fun declName c => do
modify fun eligibleHeaderDecls =>
if allowCompletion headerEnv declName then
eligibleHeaderDecls.insert declName c
else
eligibleHeaderDecls
/-- Iterate over all declarations that are allowed in completion results. -/
private def forEligibleDeclsM [Monad m] [MonadEnv m] [MonadLiftT (ST IO.RealWorld) m]
(f : Name → ConstantInfo → m PUnit) : m PUnit := do
let env ← getEnv
(← eligibleHeaderDeclsRef.get).forM f
-- map₂ are exactly the local decls
env.constants.map₂.forM fun name c => do
if allowCompletion env name then
f name c
/-- Checks whether this declaration can appear in completion results. -/
private def allowCompletion [Monad m] [MonadEnv m] [MonadLiftT (ST IO.RealWorld) m]
(declName : Name) : m Bool := do
let env ← getEnv
if (← eligibleHeaderDeclsRef.get).contains declName then
return true
if env.constants.map₂.contains declName && Lean.Meta.allowCompletion env declName then
return true
return false
/--
Sorts `items` descendingly according to their score and ascendingly according to their label
for equal scores.
-/
private def sortCompletionItems (items : Array (CompletionItem × Float)) : Array CompletionItem :=
items.qsort (fun (i1, s1) (i2, s2) => if s1 == s2 then i1.label < i2.label else s1 > s2) |>.map (·.1)
private def mkCompletionItem (label : Name) (type : Expr) (docString? : Option String) (kind : CompletionItemKind) : MetaM CompletionItem := do
let doc? := docString?.map fun docString => { value := docString, kind := MarkupKind.markdown : MarkupContent }
let detail ← consumeImplicitPrefix type fun type => return toString (← Meta.ppExpr type)
return { label := label.toString, detail? := detail, documentation? := doc?, kind? := kind }
let items := items.qsort fun (i1, s1) (i2, s2) =>
if s1 != s2 then
s1 > s2
else
i1.label.map (·.toLower) < i2.label.map (·.toLower)
items.map (·.1)
/-- Intermediate state while completions are being computed. -/
structure State where
itemsMain : Array (CompletionItem × Float) := #[]
itemsOther : Array (CompletionItem × Float) := #[]
/-- All completion items and their fuzzy match scores so far. -/
items : Array (CompletionItem × Float) := #[]
abbrev M := OptionT $ StateRefT State MetaM
/--
Monad used for completion computation that allows modifying a completion `State` and reading
`CompletionParams`.
-/
abbrev M := OptionT $ ReaderT CompletionParams $ StateRefT State MetaM
private def addCompletionItem (label : Name) (type : Expr) (expectedType? : Option Expr) (declName? : Option Name) (kind : CompletionItemKind) (score : Float) : M Unit := do
let docString? ← if let some declName := declName? then findDocString? (← getEnv) declName else pure none
let item ← mkCompletionItem label type docString? kind
if (← isTypeApplicable type expectedType?) then
modify fun s => { s with itemsMain := s.itemsMain.push (item, score) }
else
modify fun s => { s with itemsOther := s.itemsOther.push (item, score) }
/-- Adds a new completion item to the state in `M`. -/
private def addItem
(item : CompletionItem)
(score : Float)
(id? : Option CompletionIdentifier := none)
: M Unit := do
let params ← read
let data := { params, id? : CompletionItemDataWithId }
let item := { item with data? := toJson data }
modify fun s => { s with items := s.items.push (item, score) }
/--
Adds a new completion item with the given `label`, `id`, `kind` and `score` to the state in `M`.
Computes the doc string from the environment if available.
-/
private def addUnresolvedCompletionItem
(label : Name)
(id : CompletionIdentifier)
(kind : CompletionItemKind)
(score : Float)
: M Unit := do
let doc? ← do
match id with
| .const declName =>
let docString? ← findDocString? (← getEnv) declName
pure <| docString?.map fun docString =>
{ value := docString, kind := MarkupKind.markdown : MarkupContent }
| .fvar _ => pure none
let item := { label := label.toString, kind? := kind, documentation? := doc? }
addItem item score id
private def getCompletionKindForDecl (constInfo : ConstantInfo) : M CompletionItemKind := do
let env ← getEnv
@ -90,24 +187,25 @@ private def getCompletionKindForDecl (constInfo : ConstantInfo) : M CompletionIt
else
return CompletionItemKind.constant
private def addCompletionItemForDecl (label : Name) (declName : Name) (expectedType? : Option Expr) (score : Float) : M Unit := do
private def addUnresolvedCompletionItemForDecl (label : Name) (declName : Name) (score : Float) : M Unit := do
if let some c := (← getEnv).find? declName then
addCompletionItem label c.type expectedType? (some declName) (← getCompletionKindForDecl c) score
addUnresolvedCompletionItem label (.const declName) (← getCompletionKindForDecl c) score
private def addKeywordCompletionItem (keyword : String) : M Unit := do
private def addKeywordCompletionItem (keyword : String) (score : Float) : M Unit := do
let item := { label := keyword, detail? := "keyword", documentation? := none, kind? := CompletionItemKind.keyword }
modify fun s => { s with itemsMain := s.itemsMain.push (item, 1) }
addItem item score
private def addNamespaceCompletionItem (ns : Name) (score : Float) : M Unit := do
let item := { label := ns.toString, detail? := "namespace", documentation? := none, kind? := CompletionItemKind.module }
modify fun s => { s with itemsMain := s.itemsMain.push (item, score) }
addItem item score
private def runM (ctx : ContextInfo) (lctx : LocalContext) (x : M Unit) : IO (Option CompletionList) :=
private def runM (params : CompletionParams) (ctx : ContextInfo) (lctx : LocalContext) (x : M Unit)
: IO (Option CompletionList) :=
ctx.runMetaM lctx do
match (← x.run |>.run {}) with
match (← x.run |>.run params |>.run {}) with
| (none, _) => return none
| (some _, s) =>
return some { items := sortCompletionItems s.itemsMain ++ sortCompletionItems s.itemsOther, isIncomplete := true }
return some { items := sortCompletionItems s.items, isIncomplete := true }
private def matchAtomic (id : Name) (declName : Name) : Option Float :=
match id, declName with
@ -217,7 +315,12 @@ def completeNamespaces (ctx : ContextInfo) (id : Name) (danglingDot : Bool) : M
| _ => return ()
visitNamespaces ctx.currNamespace
private def idCompletionCore (ctx : ContextInfo) (id : Name) (hoverInfo : HoverInfo) (danglingDot : Bool) (expectedType? : Option Expr) : M Unit := do
private def idCompletionCore
(ctx : ContextInfo)
(id : Name)
(hoverInfo : HoverInfo)
(danglingDot : Bool)
: M Unit := do
let mut id := id.eraseMacroScopes
let mut danglingDot := danglingDot
if let HoverInfo.inside delta := hoverInfo then
@ -228,35 +331,40 @@ private def idCompletionCore (ctx : ContextInfo) (id : Name) (hoverInfo : HoverI
-- search for matches in the local context
for localDecl in (← getLCtx) do
if let some score := matchAtomic id localDecl.userName then
addCompletionItem localDecl.userName localDecl.type expectedType? none (kind := CompletionItemKind.variable) score
addUnresolvedCompletionItem localDecl.userName (.fvar localDecl.fvarId) (kind := CompletionItemKind.variable) score
-- search for matches in the environment
let env ← getEnv
env.constants.forM fun declName c => do
if allowCompletion env declName then
let matchUsingNamespace (ns : Name): M Bool := do
if let some (label, score) ← matchDecl? ns id danglingDot declName then
-- dbg_trace "matched with {id}, {declName}, {label}"
addCompletionItem label c.type expectedType? declName (← getCompletionKindForDecl c) score
return true
else
return false
forEligibleDeclsM fun declName c => do
let bestMatch? ← (·.2) <$> StateT.run (s := none) do
let matchUsingNamespace (ns : Name) : StateT (Option (Name × Float)) M Unit := do
let some (label, score) ← matchDecl? ns id danglingDot declName
| return
modify fun
| none =>
some (label, score)
| some (bestLabel, bestScore) =>
-- for open namespaces `A` and `A.B` and a decl `A.B.c`, pick the decl `c` over `B.c`
if label.isSuffixOf bestLabel then
some (label, score)
else
some (bestLabel, bestScore)
let rec visitNamespaces (ns : Name) : StateT (Option (Name × Float)) M Unit := do
let Name.str p .. := ns
| return ()
matchUsingNamespace ns
visitNamespaces p
-- use current namespace
let rec visitNamespaces (ns : Name) : M Bool := do
match ns with
| Name.str p .. => matchUsingNamespace ns <||> visitNamespaces p
| _ => return false
if (← visitNamespaces ctx.currNamespace) then
return ()
visitNamespaces ctx.currNamespace
-- use open decls
for openDecl in ctx.openDecls do
match openDecl with
| OpenDecl.simple ns exs =>
unless exs.contains declName do
if (← matchUsingNamespace ns) then
return ()
| _ => pure ()
if (← matchUsingNamespace Name.anonymous) then
return ()
let OpenDecl.simple ns exs := openDecl
| pure ()
if exs.contains declName then
continue
matchUsingNamespace ns
matchUsingNamespace Name.anonymous
if let some (bestLabel, bestScore) := bestMatch? then
addUnresolvedCompletionItem bestLabel (.const declName) (← getCompletionKindForDecl c) bestScore
-- Recall that aliases may not be atomic and include the namespace where they were created.
let matchAlias (ns : Name) (alias : Name) : Option Float :=
if ns.isPrefixOf alias then
@ -266,15 +374,15 @@ private def idCompletionCore (ctx : ContextInfo) (id : Name) (hoverInfo : HoverI
-- Auxiliary function for `alias`
let addAlias (alias : Name) (declNames : List Name) (score : Float) : M Unit := do
declNames.forM fun declName => do
if allowCompletion env declName then
addCompletionItemForDecl alias.getString! declName expectedType? score
if allowCompletion declName then
addUnresolvedCompletionItemForDecl alias.getString! declName score
-- search explicitly open `ids`
for openDecl in ctx.openDecls do
match openDecl with
| OpenDecl.explicit openedId resolvedId =>
if allowCompletion env resolvedId then
if allowCompletion resolvedId then
if let some score := matchAtomic id openedId then
addCompletionItemForDecl openedId.getString! resolvedId expectedType? score
addUnresolvedCompletionItemForDecl openedId.getString! resolvedId score
| OpenDecl.simple ns _ =>
getAliasState env |>.forM fun alias declNames => do
if let some score := matchAlias ns alias then
@ -294,20 +402,31 @@ private def idCompletionCore (ctx : ContextInfo) (id : Name) (hoverInfo : HoverI
if let .str .anonymous s := id then
let keywords := Parser.getTokenTable env
for keyword in keywords.findPrefix s do
addKeywordCompletionItem keyword
if let some score := fuzzyMatchScoreWithThreshold? s keyword then
addKeywordCompletionItem keyword score
-- Search namespaces
completeNamespaces ctx id danglingDot
private def idCompletion (ctx : ContextInfo) (lctx : LocalContext) (id : Name) (hoverInfo : HoverInfo) (danglingDot : Bool) (expectedType? : Option Expr) : IO (Option CompletionList) :=
runM ctx lctx do
idCompletionCore ctx id hoverInfo danglingDot expectedType?
private def idCompletion
(params : CompletionParams)
(ctx : ContextInfo)
(lctx : LocalContext)
(id : Name)
(hoverInfo : HoverInfo)
(danglingDot : Bool)
: IO (Option CompletionList) :=
runM params ctx lctx do
idCompletionCore ctx id hoverInfo danglingDot
private def unfoldeDefinitionGuarded? (e : Expr) : MetaM (Option Expr) :=
try unfoldDefinition? e catch _ => pure none
/-- Return `true` if `e` is a `declName`-application, or can be unfolded (delta-reduced) to one. -/
private partial def isDefEqToAppOf (e : Expr) (declName : Name) : MetaM Bool := do
if e.getAppFn.isConstOf declName then
let isConstOf := match e.getAppFn with
| .const name .. => (privateToUserName? name).getD name == declName
| _ => false
if isConstOf then
return true
let some e ← unfoldeDefinitionGuarded? e | return false
isDefEqToAppOf e declName
@ -321,14 +440,60 @@ private def isDotCompletionMethod (typeName : Name) (info : ConstantInfo) : Meta
return true
return false
/--
Checks whether the expected type of `info.type` can be reduced to an application of `typeName`.
-/
private def isDotIdCompletionMethod (typeName : Name) (info : ConstantInfo) : MetaM Bool := do
forallTelescopeReducing info.type fun _ type =>
isDefEqToAppOf type.consumeMData typeName
/--
Converts `n` to `Name.anonymous` if `n` is a private prefix (see `Lean.isPrivatePrefix`).
-/
private def stripPrivatePrefix (n : Name) : Name :=
match n with
| .num _ 0 => if isPrivatePrefix n then .anonymous else n
| _ => n
/--
Compares `n₁` and `n₂` modulo private prefixes. Similar to `Name.cmp` but ignores all
private prefixes in both names.
Necessary because the namespaces of private names do not contain private prefixes.
-/
partial def cmpModPrivate (n₁ n₂ : Name) : Ordering :=
let n₁ := stripPrivatePrefix n₁
let n₂ := stripPrivatePrefix n₂
match n₁, n₂ with
| .anonymous, .anonymous => Ordering.eq
| .anonymous, _ => Ordering.lt
| _, .anonymous => Ordering.gt
| .num p₁ i₁, .num p₂ i₂ =>
match compare i₁ i₂ with
| Ordering.eq => cmpModPrivate p₁ p₂
| ord => ord
| .num _ _, .str _ _ => Ordering.lt
| .str _ _, .num _ _ => Ordering.gt
| .str p₁ n₁, .str p₂ n₂ =>
match compare n₁ n₂ with
| Ordering.eq => cmpModPrivate p₁ p₂
| ord => ord
/--
`NameSet` where names are compared according to `cmpModPrivate`.
Helps speed up dot completion because it allows us to look up names without first having to
strip the private prefix from deep in the name, letting us reject most names without
having to scan the full name first.
-/
def NameSetModPrivate := RBTree Name cmpModPrivate
/--
Given a type, try to extract relevant type names for dot notation field completion.
We extract the type name, parent struct names, and unfold the type.
The process mimics the dot notation elaboration procedure at `App.lean` -/
private partial def getDotCompletionTypeNames (type : Expr) : MetaM NameSet :=
return (← visit type |>.run {}).2
private partial def getDotCompletionTypeNames (type : Expr) : MetaM NameSetModPrivate :=
return (← visit type |>.run RBTree.empty).2
where
visit (type : Expr) : StateRefT NameSet MetaM Unit := do
visit (type : Expr) : StateRefT NameSetModPrivate MetaM Unit := do
let .const typeName _ := type.getAppFn | return ()
modify fun s => s.insert typeName
if isStructure (← getEnv) typeName then
@ -337,49 +502,104 @@ where
let some type ← unfoldeDefinitionGuarded? type | return ()
visit type
private def dotCompletion (ctx : ContextInfo) (info : TermInfo) (hoverInfo : HoverInfo) (expectedType? : Option Expr) : IO (Option CompletionList) :=
runM ctx info.lctx do
private def dotCompletion
(params : CompletionParams)
(ctx : ContextInfo)
(info : TermInfo)
(hoverInfo : HoverInfo)
: IO (Option CompletionList) :=
runM params ctx info.lctx do
let nameSet ← try
getDotCompletionTypeNames (← instantiateMVars (← inferType info.expr))
catch _ =>
pure {}
pure RBTree.empty
if nameSet.isEmpty then
if info.stx.isIdent then
idCompletionCore ctx info.stx.getId hoverInfo (danglingDot := false) expectedType?
else if info.stx.getKind == ``Lean.Parser.Term.completion && info.stx[0].isIdent then
let stx := info.stx
if stx.isIdent then
idCompletionCore ctx stx.getId hoverInfo (danglingDot := false)
else if stx.getKind == ``Lean.Parser.Term.completion && stx[0].isIdent then
-- TODO: truncation when there is a dangling dot
idCompletionCore ctx info.stx[0].getId HoverInfo.after (danglingDot := true) expectedType?
idCompletionCore ctx stx[0].getId HoverInfo.after (danglingDot := true)
else
failure
else
(← getEnv).constants.forM fun declName c => do
let some declName ← normPrivateName? declName
| return
let typeName := declName.getPrefix
if nameSet.contains typeName then
if allowCompletion (←getEnv) c.name && (← isDotCompletionMethod typeName c) then
addCompletionItem c.name.getString! c.type expectedType? c.name (kind := (← getCompletionKindForDecl c)) 1
return
forEligibleDeclsM fun declName c => do
let unnormedTypeName := declName.getPrefix
if ! nameSet.contains unnormedTypeName then
return
let some declName ← normPrivateName? declName
| return
let typeName := declName.getPrefix
if ! (← isDotCompletionMethod typeName c) then
return
let completionKind ← getCompletionKindForDecl c
addUnresolvedCompletionItem c.name.getString! (.const c.name) (kind := completionKind) 1
private def dotIdCompletion
(params : CompletionParams)
(ctx : ContextInfo)
(lctx : LocalContext)
(id : Name)
(expectedType? : Option Expr)
: IO (Option CompletionList) :=
runM params ctx lctx do
let some expectedType := expectedType?
| return ()
let resultTypeFn := (← instantiateMVars expectedType).cleanupAnnotations.getAppFn.cleanupAnnotations
let .const .. := resultTypeFn
| return ()
let nameSet ← try
getDotCompletionTypeNames resultTypeFn
catch _ =>
pure RBTree.empty
forEligibleDeclsM fun declName c => do
let unnormedTypeName := declName.getPrefix
if ! nameSet.contains unnormedTypeName then
return
let some declName ← normPrivateName? declName
| return
let typeName := declName.getPrefix
if ! (← isDotIdCompletionMethod typeName c) then
return
let completionKind ← getCompletionKindForDecl c
if id.isAnonymous then
-- We're completing a lone dot => offer all decls of the type
addUnresolvedCompletionItem c.name.getString! (.const c.name) completionKind 1
return
private def dotIdCompletion (ctx : ContextInfo) (lctx : LocalContext) (id : Name) (expectedType? : Option Expr) : IO (Option CompletionList) :=
runM ctx lctx do
let some expectedType := expectedType? | return ()
let resultTypeFn := (← instantiateMVars expectedType).cleanupAnnotations.getAppFn
let .const typeName .. := resultTypeFn.cleanupAnnotations | return ()
(← getEnv).constants.forM fun declName c => do
let some (label, score) ← matchDecl? typeName id (danglingDot := false) declName | pure ()
addCompletionItem label c.type expectedType? declName (← getCompletionKindForDecl c) score
addUnresolvedCompletionItem label (.const c.name) completionKind score
private def fieldIdCompletion (ctx : ContextInfo) (lctx : LocalContext) (id : Name) (structName : Name) : IO (Option CompletionList) :=
runM ctx lctx do
private def fieldIdCompletion
(params : CompletionParams)
(ctx : ContextInfo)
(lctx : LocalContext)
(id : Name)
(structName : Name)
: IO (Option CompletionList) :=
runM params ctx lctx do
let idStr := id.toString
let fieldNames := getStructureFieldsFlattened (← getEnv) structName (includeSubobjectFields := false)
for fieldName in fieldNames do
let .str _ fieldName := fieldName | continue
let some score := fuzzyMatchScoreWithThreshold? idStr fieldName | continue
let item := { label := fieldName, detail? := "field", documentation? := none, kind? := CompletionItemKind.field }
modify fun s => { s with itemsMain := s.itemsMain.push (item, score) }
addItem item score
private def optionCompletion (ctx : ContextInfo) (stx : Syntax) (caps : ClientCapabilities) : IO (Option CompletionList) :=
private def optionCompletion
(params : CompletionParams)
(ctx : ContextInfo)
(stx : Syntax)
(caps : ClientCapabilities)
: IO (Option CompletionList) :=
ctx.runMetaM {} do
let (partialName, trailingDot) :=
-- `stx` is from `"set_option" >> ident`
@ -411,35 +631,44 @@ private def optionCompletion (ctx : ContextInfo) (stx : Syntax) (caps : ClientCa
detail? := s!"({opts.get name decl.defValue}), {decl.descr}"
documentation? := none,
kind? := CompletionItemKind.property -- TODO: investigate whether this is the best kind for options.
textEdit? := textEdit }, score)
textEdit? := textEdit
data? := toJson { params, id? := none : CompletionItemDataWithId } }, score)
return some { items := sortCompletionItems items, isIncomplete := true }
private def tacticCompletion (ctx : ContextInfo) : IO (Option CompletionList) :=
private def tacticCompletion (params : CompletionParams) (ctx : ContextInfo) : IO (Option CompletionList) :=
-- Just return the list of tactics for now.
ctx.runMetaM {} do
let table := Parser.getCategory (Parser.parserExtension.getState (← getEnv)).categories `tactic |>.get!.tables.leadingTable
let items : Array (CompletionItem × Float) := table.fold (init := #[]) fun items tk _ =>
-- TODO pretty print tactic syntax
items.push ({ label := tk.toString, detail? := none, documentation? := none, kind? := CompletionItemKind.keyword }, 1)
items.push ({
label := tk.toString
detail? := none
documentation? := none
kind? := CompletionItemKind.keyword
data? := toJson { params, id? := none : CompletionItemDataWithId }
}, 1)
return some { items := sortCompletionItems items, isIncomplete := true }
partial def find? (fileMap : FileMap) (hoverPos : String.Pos) (infoTree : InfoTree) (caps : ClientCapabilities) : IO (Option CompletionList) := do
private def findCompletionInfoAt?
(fileMap : FileMap)
(hoverPos : String.Pos)
(infoTree : InfoTree)
: Option (HoverInfo × ContextInfo × CompletionInfo) :=
let ⟨hoverLine, _⟩ := fileMap.toPosition hoverPos
match infoTree.foldInfo (init := none) (choose fileMap hoverLine) with
match infoTree.foldInfo (init := none) (choose hoverLine) with
| some (hoverInfo, ctx, Info.ofCompletionInfo info) =>
match info with
| .dot info (expectedType? := expectedType?) .. => dotCompletion ctx info hoverInfo expectedType?
| .id _ id danglingDot lctx expectedType? => idCompletion ctx lctx id hoverInfo danglingDot expectedType?
| .dotId _ id lctx expectedType? => dotIdCompletion ctx lctx id expectedType?
| .fieldId _ id lctx structName => fieldIdCompletion ctx lctx id structName
| .option stx => optionCompletion ctx stx caps
| .tactic .. => tacticCompletion ctx
| _ => return none
some (hoverInfo, ctx, info)
| _ =>
-- TODO try to extract id from `fileMap` and some `ContextInfo` from `InfoTree`
return none
none
where
choose (fileMap : FileMap) (hoverLine : Nat) (ctx : ContextInfo) (info : Info) (best? : Option (HoverInfo × ContextInfo × Info)) : Option (HoverInfo × ContextInfo × Info) :=
choose
(hoverLine : Nat)
(ctx : ContextInfo)
(info : Info)
(best? : Option (HoverInfo × ContextInfo × Info))
: Option (HoverInfo × ContextInfo × Info) :=
if !info.isCompletion then best?
else if info.occursInside? hoverPos |>.isSome then
let headPos := info.pos?.get!
@ -473,4 +702,62 @@ where
else
best?
/--
Assigns the `CompletionItem.sortText?` for all items in `completions` according to their order
in `completions`. This is necessary because clients will use their own sort order if the server
does not set it.
-/
private def assignSortTexts (completions : CompletionList) : CompletionList := Id.run do
if completions.items.isEmpty then
return completions
let items := completions.items.mapIdx fun i item =>
{ item with sortText? := toString i.val }
let maxDigits := items[items.size - 1]!.sortText?.get!.length
let items := items.map fun item =>
let sortText := item.sortText?.get!
let pad := List.replicate (maxDigits - sortText.length) '0' |>.asString
{ item with sortText? := pad ++ sortText }
{ completions with items := items }
partial def find?
(params : CompletionParams)
(fileMap : FileMap)
(hoverPos : String.Pos)
(infoTree : InfoTree)
(caps : ClientCapabilities)
: IO (Option CompletionList) := do
let some (hoverInfo, ctx, info) := findCompletionInfoAt? fileMap hoverPos infoTree
| return none
let completionList? ←
match info with
| .dot info .. =>
dotCompletion params ctx info hoverInfo
| .id _ id danglingDot lctx .. =>
idCompletion params ctx lctx id hoverInfo danglingDot
| .dotId _ id lctx expectedType? =>
dotIdCompletion params ctx lctx id expectedType?
| .fieldId _ id lctx structName =>
fieldIdCompletion params ctx lctx id structName
| .option stx =>
optionCompletion params ctx stx caps
| .tactic .. =>
tacticCompletion params ctx
| _ => return none
return completionList?.map assignSortTexts
/--
Fills the `CompletionItem.detail?` field of `item` using the pretty-printed type identified by `id`
in the context found at `hoverPos` in `infoTree`.
-/
def resolveCompletionItem?
(fileMap : FileMap)
(hoverPos : String.Pos)
(infoTree : InfoTree)
(item : CompletionItem)
(id : CompletionIdentifier)
: IO CompletionItem := do
let some (_, ctx, info) := findCompletionInfoAt? fileMap hoverPos infoTree
| return item
ctx.runMetaM info.lctx (item.resolve id)
end Lean.Server.Completion

View file

@ -0,0 +1,39 @@
/-
Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Marc Huisinga
-/
prelude
import Lean.Server.FileSource
namespace Lean.Lsp
/-- Used in `CompletionItem.data?`. -/
structure CompletionItemData where
params : CompletionParams
deriving FromJson, ToJson
/--
Yields the file source of `item` by attempting to parse `item.data?` to `CompletionItemData` and
obtaining the original file source from its `params` fields. Panics if `item.data?` is not present
or cannot be parsed to `CompletionItemData`.
Used when `completionItem/resolve` requests pass the watchdog to decide which file worker to forward
the request to.
Since this function can panic and clients typically send `completionItem/resolve` requests for every
selected completion item, all completion items returned by the server in `textDocument/completion`
requests must have a `data?` field that can be parsed to `CompletionItemData`.
-/
def CompletionItem.getFileSource! (item : CompletionItem) : DocumentUri :=
let r : Except String DocumentUri := do
let some data := item.data?
| throw s!"no data param on completion item {item.label}"
let data : CompletionItemData ← fromJson? data
return data.params.textDocument.uri
match r with
| Except.ok uri => uri
| Except.error e => panic! e
instance : FileSource CompletionItem where
fileSource := CompletionItem.getFileSource!
end Lean.Lsp

View file

@ -231,6 +231,8 @@ section Initialization
publishDiagnostics m #[progressDiagnostic] hOut
let fileSetupResult := fileSetupResult.addGlobalOptions globalOptions
let (headerEnv, envMsgLog) ← buildHeaderEnv m headerStx fileSetupResult
-- Prepare header-based caches that requests may use
runHeaderCachingHandlers headerEnv
let headerMsgLog := parseMsgLog.append envMsgLog
let cmdState := buildCommandState m headerStx headerEnv headerMsgLog fileSetupResult.fileOptions
let headerSnap := {

View file

@ -38,10 +38,32 @@ def handleCompletion (p : CompletionParams)
(notFoundX := pure { items := #[], isIncomplete := true })
(abortedX :=
-- work around https://github.com/microsoft/vscode/issues/155738
pure { items := #[{label := "-"}], isIncomplete := true }) fun snap => do
if let some r ← Completion.find? doc.meta.text pos snap.infoTree caps then
pure { items := #[{label := "-"}], isIncomplete := true })
(x := fun snap => do
if let some r ← Completion.find? p doc.meta.text pos snap.infoTree caps then
return r
return { items := #[ ], isIncomplete := true }
return { items := #[ ], isIncomplete := true })
/--
Handles `completionItem/resolve` requests that are sent by the client after the user selects
a completion item that was provided by `textDocument/completion`. Resolving the item fills the
`detail?` field of the item with the pretty-printed type.
This control flow is necessary because pretty-printing the type for every single completion item
(even those never selected by the user) is inefficient.
-/
def handleCompletionItemResolve (item : CompletionItem)
: RequestM (RequestTask CompletionItem) := do
let doc ← readDoc
let text := doc.meta.text
let some (data : CompletionItemDataWithId) := item.data?.bind fun data => (fromJson? data).toOption
| return .pure item
let some id := data.id?
| return .pure item
let pos := text.lspPosToUtf8Pos data.params.position
withWaitFindSnap doc (·.endPos + ' ' >= pos)
(notFoundX := pure item)
(abortedX := pure item)
(x := fun snap => Completion.resolveCompletionItem? text pos snap.infoTree item id)
open Elab in
def handleHover (p : HoverParams)
@ -609,18 +631,76 @@ partial def handleWaitForDiagnostics (p : WaitForDiagnosticsParams)
return t₁.map fun _ => pure WaitForDiagnostics.mk
builtin_initialize
registerLspRequestHandler "textDocument/waitForDiagnostics" WaitForDiagnosticsParams WaitForDiagnostics handleWaitForDiagnostics
registerLspRequestHandler "textDocument/completion" CompletionParams CompletionList handleCompletion
registerLspRequestHandler "textDocument/hover" HoverParams (Option Hover) handleHover
registerLspRequestHandler "textDocument/declaration" TextDocumentPositionParams (Array LocationLink) (handleDefinition GoToKind.declaration)
registerLspRequestHandler "textDocument/definition" TextDocumentPositionParams (Array LocationLink) (handleDefinition GoToKind.definition)
registerLspRequestHandler "textDocument/typeDefinition" TextDocumentPositionParams (Array LocationLink) (handleDefinition GoToKind.type)
registerLspRequestHandler "textDocument/documentHighlight" DocumentHighlightParams DocumentHighlightResult handleDocumentHighlight
registerLspRequestHandler "textDocument/documentSymbol" DocumentSymbolParams DocumentSymbolResult handleDocumentSymbol
registerLspRequestHandler "textDocument/semanticTokens/full" SemanticTokensParams SemanticTokens handleSemanticTokensFull
registerLspRequestHandler "textDocument/semanticTokens/range" SemanticTokensRangeParams SemanticTokens handleSemanticTokensRange
registerLspRequestHandler "textDocument/foldingRange" FoldingRangeParams (Array FoldingRange) handleFoldingRange
registerLspRequestHandler "$/lean/plainGoal" PlainGoalParams (Option PlainGoal) handlePlainGoal
registerLspRequestHandler "$/lean/plainTermGoal" PlainTermGoalParams (Option PlainTermGoal) handlePlainTermGoal
registerLspRequestHandler
"textDocument/waitForDiagnostics"
WaitForDiagnosticsParams
WaitForDiagnostics
handleWaitForDiagnostics
registerLspRequestHandler
"textDocument/completion"
CompletionParams
CompletionList
handleCompletion
Completion.fillEligibleHeaderDecls
registerLspRequestHandler
"completionItem/resolve"
CompletionItem
CompletionItem
handleCompletionItemResolve
registerLspRequestHandler
"textDocument/hover"
HoverParams
(Option Hover)
handleHover
registerLspRequestHandler
"textDocument/declaration"
TextDocumentPositionParams
(Array LocationLink)
(handleDefinition GoToKind.declaration)
registerLspRequestHandler
"textDocument/definition"
TextDocumentPositionParams
(Array LocationLink)
(handleDefinition GoToKind.definition)
registerLspRequestHandler
"textDocument/typeDefinition"
TextDocumentPositionParams
(Array LocationLink)
(handleDefinition GoToKind.type)
registerLspRequestHandler
"textDocument/documentHighlight"
DocumentHighlightParams
DocumentHighlightResult
handleDocumentHighlight
registerLspRequestHandler
"textDocument/documentSymbol"
DocumentSymbolParams
DocumentSymbolResult
handleDocumentSymbol
registerLspRequestHandler
"textDocument/semanticTokens/full"
SemanticTokensParams
SemanticTokens
handleSemanticTokensFull
registerLspRequestHandler
"textDocument/semanticTokens/range"
SemanticTokensRangeParams
SemanticTokens
handleSemanticTokensRange
registerLspRequestHandler
"textDocument/foldingRange"
FoldingRangeParams
(Array FoldingRange)
handleFoldingRange
registerLspRequestHandler
"$/lean/plainGoal"
PlainGoalParams
(Option PlainGoal)
handlePlainGoal
registerLspRequestHandler
"$/lean/plainTermGoal"
PlainTermGoalParams
(Option PlainTermGoal)
handlePlainTermGoal
end Lean.Server.FileWorker

View file

@ -10,6 +10,7 @@ import Lean.Data.Lsp.Utf16
import Lean.Data.Lsp.LanguageFeatures
import Lean.Util.Paths
import Lean.Util.LakePath
import Lean.Server.CompletionItemData
namespace ImportCompletion
@ -120,23 +121,35 @@ def collectAvailableImports : IO AvailableImports := do
ImportCompletion.collectAvailableImportsFromSrcSearchPath
| some availableImports => pure availableImports
/--
Sets the `data?` field of every `CompletionItem` in `completionList` using `params`. Ensures that
`completionItem/resolve` requests can be routed to the correct file worker even for
`CompletionItem`s produced by the import completion.
-/
def addCompletionItemData (completionList : CompletionList) (params : CompletionParams)
: CompletionList :=
let data := { params : Lean.Lsp.CompletionItemData }
{ completionList with items := completionList.items.map fun item =>
{ item with data? := some <| toJson data } }
def find (text : FileMap) (headerStx : Syntax) (params : CompletionParams) (availableImports : AvailableImports) : CompletionList :=
let availableImports := availableImports.toImportTrie
let completionPos := text.lspPosToUtf8Pos params.position
if isImportNameCompletionRequest headerStx completionPos then
let allAvailableImportNameCompletions := availableImports.toArray.map ({ label := toString · })
{ isIncomplete := false, items := allAvailableImportNameCompletions }
addCompletionItemData { isIncomplete := false, items := allAvailableImportNameCompletions } params
else if isImportCmdCompletionRequest headerStx completionPos then
let allAvailableFullImportCompletions := availableImports.toArray.map ({ label := s!"import {·}" })
{ isIncomplete := false, items := allAvailableFullImportCompletions }
addCompletionItemData { isIncomplete := false, items := allAvailableFullImportCompletions } params
else
let completionNames : Array Name := computePartialImportCompletions headerStx completionPos availableImports
let completions : Array CompletionItem := completionNames.map ({ label := toString · })
{ isIncomplete := false, items := completions }
addCompletionItemData { isIncomplete := false, items := completions } params
def computeCompletions (text : FileMap) (headerStx : Syntax) (params : CompletionParams)
: IO CompletionList := do
let availableImports ← collectAvailableImports
return find text headerStx params availableImports
let completionList := find text headerStx params availableImports
return addCompletionItemData completionList params
end ImportCompletion

View file

@ -182,8 +182,13 @@ section HandlerTable
open Lsp
structure RequestHandler where
fileSource : Json → Except RequestError Lsp.DocumentUri
handle : Json → RequestM (RequestTask Json)
fileSource : Json → Except RequestError Lsp.DocumentUri
handle : Json → RequestM (RequestTask Json)
/--
Handler that is called by the file worker after processing the header with the header environment.
Enables request handlers to cache data related to imports.
-/
handleHeaderCaching : Environment → IO Unit
builtin_initialize requestHandlers : IO.Ref (PersistentHashMap String RequestHandler) ←
IO.mkRef {}
@ -203,7 +208,9 @@ as LSP error responses. -/
def registerLspRequestHandler (method : String)
paramType [FromJson paramType] [FileSource paramType]
respType [ToJson respType]
(handler : paramType → RequestM (RequestTask respType)) : IO Unit := do
(handler : paramType → RequestM (RequestTask respType))
(headerCachingHandler : Environment → IO Unit := fun _ => pure ())
: IO Unit := do
if !(← Lean.initializing) then
throw <| IO.userError s!"Failed to register LSP request handler for '{method}': only possible during initialization"
if (← requestHandlers.get).contains method then
@ -214,8 +221,8 @@ def registerLspRequestHandler (method : String)
let params ← liftExcept <| parseRequestParams paramType j
let t ← handler params
pure <| t.map <| Except.map ToJson.toJson
requestHandlers.modify fun rhs => rhs.insert method { fileSource, handle }
let handleHeaderCaching := headerCachingHandler
requestHandlers.modify fun rhs => rhs.insert method { fileSource, handle, handleHeaderCaching }
def lookupLspRequestHandler (method : String) : IO (Option RequestHandler) :=
return (← requestHandlers.get).find? method
@ -246,6 +253,14 @@ def chainLspRequestHandler (method : String)
else
throw <| IO.userError s!"Failed to chain LSP request handler for '{method}': no initial handler registered"
/--
Runs the header caching handler for every single registered request handler using the given
`headerEnv`.
-/
def runHeaderCachingHandlers (headerEnv : Environment) : IO Unit := do
(← requestHandlers.get).forM fun _ handler =>
handler.handleHeaderCaching headerEnv
def routeLspRequest (method : String) (params : Json) : IO (Except RequestError DocumentUri) := do
match (← lookupLspRequestHandler method) with
| none => return Except.error <| RequestError.methodNotFound method

View file

@ -817,6 +817,7 @@ def mkLeanServerCapabilities : ServerCapabilities := {
-- refine
completionProvider? := some {
triggerCharacters? := some #["."]
resolveProvider := true
}
hoverProvider := true
declarationProvider := true

View file

@ -1,54 +1,172 @@
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}}
{"items":
[{"label": "getHygieneInfo",
[{"sortText": "0",
"label": "expandInterpolatedStr",
"kind": 3,
"detail": "Lean.HygieneInfo → Lean.Name"},
{"label": "getId", "kind": 3, "detail": "Lean.Ident → Lean.Name"},
{"label": "getName", "kind": 3, "detail": "Lean.NameLit → Lean.Name"},
{"label": "expandInterpolatedStr",
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.expandInterpolatedStr"}}}},
{"sortText": "1",
"label": "getChar",
"kind": 3,
"detail":
"Lean.TSyntax Lean.interpolatedStrKind → Lean.Term → Lean.Term → Lean.MacroM Lean.Term"},
{"label": "getChar", "kind": 3, "detail": "Lean.CharLit → Char"},
{"label": "getDocString",
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getChar"}}}},
{"sortText": "2",
"label": "getDocString",
"kind": 3,
"detail": "Lean.TSyntax `Lean.Parser.Command.docComment → String"},
{"label": "getNat", "kind": 3, "detail": "Lean.NumLit → Nat"},
{"label": "getScientific",
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getDocString"}}}},
{"sortText": "3",
"label": "getHygieneInfo",
"kind": 3,
"detail": "Lean.ScientificLit → Nat × Bool × Nat"},
{"label": "getString", "kind": 3, "detail": "Lean.StrLit → String"},
{"label": "raw",
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getHygieneInfo"}}}},
{"sortText": "4",
"label": "getId",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getId"}}}},
{"sortText": "5",
"label": "getName",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getName"}}}},
{"sortText": "6",
"label": "getNat",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getNat"}}}},
{"sortText": "7",
"label": "getScientific",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getScientific"}}}},
{"sortText": "8",
"label": "getString",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getString"}}}},
{"sortText": "9",
"label": "raw",
"kind": 5,
"documentation":
{"value": "The underlying `Syntax` value. ", "kind": "markdown"},
"detail": "Lean.TSyntax ks → Lean.Syntax"}],
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.raw"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}}
{"items":
[{"label": "getHygieneInfo",
[{"sortText": "0",
"label": "expandInterpolatedStr",
"kind": 3,
"detail": "Lean.HygieneInfo → Lean.Name"},
{"label": "getId", "kind": 3, "detail": "Lean.Ident → Lean.Name"},
{"label": "getName", "kind": 3, "detail": "Lean.NameLit → Lean.Name"},
{"label": "expandInterpolatedStr",
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.expandInterpolatedStr"}}}},
{"sortText": "1",
"label": "getChar",
"kind": 3,
"detail":
"Lean.TSyntax Lean.interpolatedStrKind → Lean.Term → Lean.Term → Lean.MacroM Lean.Term"},
{"label": "getChar", "kind": 3, "detail": "Lean.CharLit → Char"},
{"label": "getDocString",
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getChar"}}}},
{"sortText": "2",
"label": "getDocString",
"kind": 3,
"detail": "Lean.TSyntax `Lean.Parser.Command.docComment → String"},
{"label": "getNat", "kind": 3, "detail": "Lean.NumLit → Nat"},
{"label": "getScientific",
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getDocString"}}}},
{"sortText": "3",
"label": "getHygieneInfo",
"kind": 3,
"detail": "Lean.ScientificLit → Nat × Bool × Nat"},
{"label": "getString", "kind": 3, "detail": "Lean.StrLit → String"},
{"label": "raw",
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getHygieneInfo"}}}},
{"sortText": "4",
"label": "getId",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getId"}}}},
{"sortText": "5",
"label": "getName",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getName"}}}},
{"sortText": "6",
"label": "getNat",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getNat"}}}},
{"sortText": "7",
"label": "getScientific",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getScientific"}}}},
{"sortText": "8",
"label": "getString",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getString"}}}},
{"sortText": "9",
"label": "raw",
"kind": 5,
"documentation":
{"value": "The underlying `Syntax` value. ", "kind": "markdown"},
"detail": "Lean.TSyntax ks → Lean.Syntax"}],
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.raw"}}}}],
"isIncomplete": true}

View file

@ -1,47 +1,124 @@
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 9, "character": 23}}
{"items":
[{"label": "Lean.Elab.Tactic.elabTermEnsuringType",
[{"sortText": "0",
"label": "Lean.Elab.Tactic.elabTermEnsuringType",
"kind": 21,
"detail": "Type"},
{"label": "Lean.Elab.Term.elabTermEnsuringType",
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 9, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Tactic.elabTermEnsuringType"}}}},
{"sortText": "1",
"label": "Lean.Elab.Term.elabTermEnsuringType",
"kind": 21,
"detail": "Type"}],
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 9, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Term.elabTermEnsuringType"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 15, "character": 23}}
{"items":
[{"label": "Tactic.elabTermEnsuringType", "kind": 21, "detail": "Type"},
{"label": "Term.elabTermEnsuringType", "kind": 21, "detail": "Type"}],
[{"sortText": "0",
"label": "Tactic.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 15, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Tactic.elabTermEnsuringType"}}}},
{"sortText": "1",
"label": "Term.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 15, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Term.elabTermEnsuringType"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 21, "character": 23}}
{"items":
[{"label": "elabTermEnsuringType", "kind": 21, "detail": "Type"},
{"label": "Lean.Elab.Tactic.elabTermEnsuringType",
[{"sortText": "0",
"label": "elabTermEnsuringType",
"kind": 21,
"detail": "Type"}],
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 21, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Term.elabTermEnsuringType"}}}},
{"sortText": "1",
"label": "Lean.Elab.Tactic.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 21, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Tactic.elabTermEnsuringType"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 27, "character": 23}}
{"items":
[{"label": "elabTermEnsuringType", "kind": 21, "detail": "Type"},
{"label": "Lean.Elab.Tactic.elabTermEnsuringType",
[{"sortText": "0",
"label": "elabTermEnsuringType",
"kind": 21,
"detail": "Type"},
{"label": "Lean.Elab.Term.elabTermEnsuringType",
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 27, "character": 23}},
"id": {"const": {"declName": "elabTermEnsuringType"}}}},
{"sortText": "1",
"label": "Lean.Elab.Tactic.elabTermEnsuringType",
"kind": 21,
"detail": "Type"}],
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 27, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Tactic.elabTermEnsuringType"}}}},
{"sortText": "2",
"label": "Lean.Elab.Term.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 27, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Term.elabTermEnsuringType"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 33, "character": 23}}
{"items":
[{"label": "elabTermEnsuringType", "kind": 21, "detail": "Type"},
{"label": "Lean.Elab.elabTermEnsuringType", "kind": 21, "detail": "Type"},
{"label": "Lean.Elab.Tactic.elabTermEnsuringType",
[{"sortText": "0",
"label": "elabTermEnsuringType",
"kind": 21,
"detail": "Type"},
{"label": "Lean.Elab.Term.elabTermEnsuringType",
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 33, "character": 23}},
"id": {"const": {"declName": "elabTermEnsuringType"}}}},
{"sortText": "1",
"label": "Lean.Elab.elabTermEnsuringType",
"kind": 21,
"detail": "Type"}],
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 33, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.elabTermEnsuringType"}}}},
{"sortText": "2",
"label": "Lean.Elab.Tactic.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 33, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Tactic.elabTermEnsuringType"}}}},
{"sortText": "3",
"label": "Lean.Elab.Term.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 33, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Term.elabTermEnsuringType"}}}}],
"isIncomplete": true}

View file

@ -1,6 +1,20 @@
{"textDocument": {"uri": "file:///533.lean"},
"position": {"line": 4, "character": 10}}
{"items":
[{"label": "F", "kind": 6, "detail": "Sort ?u"},
{"label": "Foo", "kind": 6, "detail": "Sort ?u"}],
[{"sortText": "0",
"label": "F",
"kind": 6,
"data":
{"params":
{"textDocument": {"uri": "file:///533.lean"},
"position": {"line": 4, "character": 10}},
"id": {"fvar": {"id": "_uniq.6"}}}},
{"sortText": "1",
"label": "Foo",
"kind": 6,
"data":
{"params":
{"textDocument": {"uri": "file:///533.lean"},
"position": {"line": 4, "character": 10}},
"id": {"fvar": {"id": "_uniq.2"}}}}],
"isIncomplete": true}

View file

@ -1,16 +1,40 @@
{"textDocument": {"uri": "file:///863.lean"},
"position": {"line": 9, "character": 12}}
{"items":
[{"label": "getRef", "kind": 5, "detail": "[self : MonadRef] → Type"},
{"label": "MonadRef.getRef",
[{"sortText": "0",
"label": "getRef",
"kind": 5,
"detail": "[self : MonadRef] → Type"}],
"data":
{"params":
{"textDocument": {"uri": "file:///863.lean"},
"position": {"line": 9, "character": 12}},
"id": {"const": {"declName": "Lean.MonadRef.getRef"}}}},
{"sortText": "1",
"label": "MonadRef.getRef",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///863.lean"},
"position": {"line": 9, "character": 12}},
"id": {"const": {"declName": "Lean.MonadRef.getRef"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///863.lean"},
"position": {"line": 13, "character": 12}}
{"items":
[{"label": "getRef", "kind": 5, "detail": "[self : MonadRef] → Type"},
{"label": "MonadRef.getRef",
[{"sortText": "0",
"label": "getRef",
"kind": 5,
"detail": "[self : MonadRef] → Type"}],
"data":
{"params":
{"textDocument": {"uri": "file:///863.lean"},
"position": {"line": 13, "character": 12}},
"id": {"const": {"declName": "Lean.MonadRef.getRef"}}}},
{"sortText": "1",
"label": "MonadRef.getRef",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///863.lean"},
"position": {"line": 13, "character": 12}},
"id": {"const": {"declName": "Lean.MonadRef.getRef"}}}}],
"isIncomplete": true}

View file

@ -1,6 +1,20 @@
{"textDocument": {"uri": "file:///compHeader.lean"},
"position": {"line": 2, "character": 22}}
{"items":
[{"label": "veryLongNam", "kind": 6, "detail": "Sort u_1"},
{"label": "veryLongNameForCompletion", "kind": 21, "detail": "Type"}],
[{"sortText": "0",
"label": "veryLongNam",
"kind": 6,
"data":
{"params":
{"textDocument": {"uri": "file:///compHeader.lean"},
"position": {"line": 2, "character": 22}},
"id": {"fvar": {"id": "_uniq.7"}}}},
{"sortText": "1",
"label": "veryLongNameForCompletion",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///compHeader.lean"},
"position": {"line": 2, "character": 22}},
"id": {"const": {"declName": "veryLongNameForCompletion"}}}}],
"isIncomplete": true}

View file

@ -1,21 +1,60 @@
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 5, "character": 12}}
{"items": [{"label": "LongNamespaceExample", "kind": 9, "detail": "namespace"}],
{"items":
[{"sortText": "0",
"label": "LongNamespaceExample",
"kind": 9,
"detail": "namespace",
"data":
{"params":
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 5, "character": 12}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 9, "character": 12}}
{"items": [{"label": "LongNamespaceExample", "kind": 9, "detail": "namespace"}],
{"items":
[{"sortText": "0",
"label": "LongNamespaceExample",
"kind": 9,
"detail": "namespace",
"data":
{"params":
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 9, "character": 12}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 13, "character": 11}}
{"items": [{"label": "LongNamespaceExample", "kind": 9, "detail": "namespace"}],
{"items":
[{"sortText": "0",
"label": "LongNamespaceExample",
"kind": 9,
"detail": "namespace",
"data":
{"params":
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 13, "character": 11}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 16, "character": 16}}
{"items":
[{"label": "Foo.LongNamespaceExample", "kind": 9, "detail": "namespace"}],
[{"sortText": "0",
"label": "Foo.LongNamespaceExample",
"kind": 9,
"detail": "namespace",
"data":
{"params":
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 16, "character": 16}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 20, "character": 12}}
{"items": [{"label": "LongNamespaceExample", "kind": 9, "detail": "namespace"}],
{"items":
[{"sortText": "0",
"label": "LongNamespaceExample",
"kind": 9,
"detail": "namespace",
"data":
{"params":
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 20, "character": 12}}}}],
"isIncomplete": true}

View file

@ -1,16 +1,48 @@
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 3, "character": 22}}
{"items": [{"label": "foo", "kind": 5, "detail": "Foo → Nat"}],
{"items":
[{"sortText": "0",
"label": "foo",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 3, "character": 22}},
"id": {"const": {"declName": "Foo.foo"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 5, "character": 23}}
{"items": [{"label": "foo", "kind": 5, "detail": "Foo → Nat"}],
{"items":
[{"sortText": "0",
"label": "foo",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 5, "character": 23}},
"id": {"const": {"declName": "Foo.foo"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 7, "character": 28}}
{"items": [{"label": "foo", "kind": 5, "detail": "Foo → Nat"}],
{"items":
[{"sortText": "0",
"label": "foo",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 7, "character": 28}},
"id": {"const": {"declName": "Foo.foo"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 9, "character": 29}}
{"items": [{"label": "foo", "kind": 5, "detail": "Foo → Nat"}],
{"items":
[{"sortText": "0",
"label": "foo",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 9, "character": 29}},
"id": {"const": {"declName": "Foo.foo"}}}}],
"isIncomplete": true}

View file

@ -1,31 +1,136 @@
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 19, "character": 10}}
{"items":
[{"label": "ex2", "kind": 3, "detail": "a ≤ b → a + 2 ≤ b + 2"},
{"label": "ex3", "kind": 3, "detail": "a ≤ b → c ≤ d → a + c ≤ b + d"},
{"label": "ax1", "kind": 3, "detail": "a ≤ b → a - a ≤ b - b"},
{"label": "ex1", "kind": 3, "detail": "a ≤ b → a + a ≤ b + b"}],
[{"sortText": "0",
"label": "ax1",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 19, "character": 10}},
"id": {"const": {"declName": "Foo.Bla.ax1"}}}},
{"sortText": "1",
"label": "ex1",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 19, "character": 10}},
"id": {"const": {"declName": "Foo.Bla.ex1"}}}},
{"sortText": "2",
"label": "ex2",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 19, "character": 10}},
"id": {"const": {"declName": "Foo.Bla.ex2"}}}},
{"sortText": "3",
"label": "ex3",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 19, "character": 10}},
"id": {"const": {"declName": "Foo.Bla.ex3"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 25, "character": 6}}
{"items":
[{"label": "ex2", "kind": 3, "detail": "a ≤ b → a + 2 ≤ b + 2"},
{"label": "ex3", "kind": 3, "detail": "a ≤ b → c ≤ d → a + c ≤ b + d"},
{"label": "ax1", "kind": 3, "detail": "a ≤ b → a - a ≤ b - b"},
{"label": "ex1", "kind": 3, "detail": "a ≤ b → a + a ≤ b + b"}],
[{"sortText": "0",
"label": "ax1",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 25, "character": 6}},
"id": {"const": {"declName": "Foo.Bla.ax1"}}}},
{"sortText": "1",
"label": "ex1",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 25, "character": 6}},
"id": {"const": {"declName": "Foo.Bla.ex1"}}}},
{"sortText": "2",
"label": "ex2",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 25, "character": 6}},
"id": {"const": {"declName": "Foo.Bla.ex2"}}}},
{"sortText": "3",
"label": "ex3",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 25, "character": 6}},
"id": {"const": {"declName": "Foo.Bla.ex3"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 30, "character": 21}}
{"items":
[{"label": "ex2", "kind": 3, "detail": "a ≤ b → a + 2 ≤ b + 2"},
{"label": "ex3", "kind": 3, "detail": "a ≤ b → c ≤ d → a + c ≤ b + d"},
{"label": "ax1", "kind": 3, "detail": "a ≤ b → a - a ≤ b - b"},
{"label": "ex1", "kind": 3, "detail": "a ≤ b → a + a ≤ b + b"}],
[{"sortText": "0",
"label": "ax1",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 30, "character": 21}},
"id": {"const": {"declName": "Foo.Bla.ax1"}}}},
{"sortText": "1",
"label": "ex1",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 30, "character": 21}},
"id": {"const": {"declName": "Foo.Bla.ex1"}}}},
{"sortText": "2",
"label": "ex2",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 30, "character": 21}},
"id": {"const": {"declName": "Foo.Bla.ex2"}}}},
{"sortText": "3",
"label": "ex3",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 30, "character": 21}},
"id": {"const": {"declName": "Foo.Bla.ex3"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 37, "character": 22}}
{"items":
[{"label": "ex2", "kind": 3, "detail": "a ≤ b → a + 2 ≤ b + 2"},
{"label": "ex3", "kind": 3, "detail": "a ≤ b → c ≤ d → a + c ≤ b + d"},
{"label": "ex1", "kind": 3, "detail": "a ≤ b → a + a ≤ b + b"}],
[{"sortText": "0",
"label": "ex1",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 37, "character": 22}},
"id": {"const": {"declName": "Foo.Bla.ex1"}}}},
{"sortText": "1",
"label": "ex2",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 37, "character": 22}},
"id": {"const": {"declName": "Foo.Bla.ex2"}}}},
{"sortText": "2",
"label": "ex3",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 37, "character": 22}},
"id": {"const": {"declName": "Foo.Bla.ex3"}}}}],
"isIncomplete": true}

View file

@ -1,28 +1,112 @@
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 7, "character": 9}}
{"items":
[{"label": "b", "kind": 5, "detail": "S → Bool"},
{"label": "x", "kind": 5, "detail": "S → Nat"},
{"label": "y", "kind": 5, "detail": "S → String"}],
[{"sortText": "0",
"label": "b",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 7, "character": 9}},
"id": {"const": {"declName": "S.b"}}}},
{"sortText": "1",
"label": "x",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 7, "character": 9}},
"id": {"const": {"declName": "S.x"}}}},
{"sortText": "2",
"label": "y",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 7, "character": 9}},
"id": {"const": {"declName": "S.y"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 12, "character": 5}}
{"items":
[{"label": "b", "kind": 5, "detail": "S → Bool"},
{"label": "x", "kind": 5, "detail": "S → Nat"},
{"label": "y", "kind": 5, "detail": "S → String"}],
[{"sortText": "0",
"label": "b",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 12, "character": 5}},
"id": {"const": {"declName": "S.b"}}}},
{"sortText": "1",
"label": "x",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 12, "character": 5}},
"id": {"const": {"declName": "S.x"}}}},
{"sortText": "2",
"label": "y",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 12, "character": 5}},
"id": {"const": {"declName": "S.y"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 16, "character": 5}}
{"items":
[{"label": "b", "kind": 5, "detail": "S → Bool"},
{"label": "x", "kind": 5, "detail": "S → Nat"},
{"label": "y", "kind": 5, "detail": "S → String"}],
[{"sortText": "0",
"label": "b",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 16, "character": 5}},
"id": {"const": {"declName": "S.b"}}}},
{"sortText": "1",
"label": "x",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 16, "character": 5}},
"id": {"const": {"declName": "S.x"}}}},
{"sortText": "2",
"label": "y",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 16, "character": 5}},
"id": {"const": {"declName": "S.y"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 20, "character": 5}}
{"items":
[{"label": "x", "kind": 5, "detail": "S → Nat"},
{"label": "b", "kind": 5, "detail": "S → Bool"},
{"label": "y", "kind": 5, "detail": "S → String"}],
[{"sortText": "0",
"label": "b",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 20, "character": 5}},
"id": {"const": {"declName": "S.b"}}}},
{"sortText": "1",
"label": "x",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 20, "character": 5}},
"id": {"const": {"declName": "S.x"}}}},
{"sortText": "2",
"label": "y",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 20, "character": 5}},
"id": {"const": {"declName": "S.y"}}}}],
"isIncomplete": true}

View file

@ -1,28 +1,112 @@
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 7, "character": 4}}
{"items":
[{"label": "fn1", "kind": 5, "detail": "S → Nat → IO Unit"},
{"label": "fn2", "kind": 5, "detail": "S → Bool → IO Unit"},
{"label": "pred", "kind": 5, "detail": "S → String → Bool"}],
[{"sortText": "0",
"label": "fn1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 7, "character": 4}},
"id": {"const": {"declName": "S.fn1"}}}},
{"sortText": "1",
"label": "fn2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 7, "character": 4}},
"id": {"const": {"declName": "S.fn2"}}}},
{"sortText": "2",
"label": "pred",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 7, "character": 4}},
"id": {"const": {"declName": "S.pred"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 11, "character": 10}}
{"items":
[{"label": "fn1", "kind": 5, "detail": "S → Nat → IO Unit"},
{"label": "fn2", "kind": 5, "detail": "S → Bool → IO Unit"},
{"label": "pred", "kind": 5, "detail": "S → String → Bool"}],
[{"sortText": "0",
"label": "fn1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 11, "character": 10}},
"id": {"const": {"declName": "S.fn1"}}}},
{"sortText": "1",
"label": "fn2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 11, "character": 10}},
"id": {"const": {"declName": "S.fn2"}}}},
{"sortText": "2",
"label": "pred",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 11, "character": 10}},
"id": {"const": {"declName": "S.pred"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 16, "character": 11}}
{"items":
[{"label": "fn1", "kind": 5, "detail": "S → Nat → IO Unit"},
{"label": "fn2", "kind": 5, "detail": "S → Bool → IO Unit"},
{"label": "pred", "kind": 5, "detail": "S → String → Bool"}],
[{"sortText": "0",
"label": "fn1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 16, "character": 11}},
"id": {"const": {"declName": "S.fn1"}}}},
{"sortText": "1",
"label": "fn2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 16, "character": 11}},
"id": {"const": {"declName": "S.fn2"}}}},
{"sortText": "2",
"label": "pred",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 16, "character": 11}},
"id": {"const": {"declName": "S.pred"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 20, "character": 21}}
{"items":
[{"label": "fn1", "kind": 5, "detail": "S → Nat → IO Unit"},
{"label": "fn2", "kind": 5, "detail": "S → Bool → IO Unit"},
{"label": "pred", "kind": 5, "detail": "S → String → Bool"}],
[{"sortText": "0",
"label": "fn1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 20, "character": 21}},
"id": {"const": {"declName": "S.fn1"}}}},
{"sortText": "1",
"label": "fn2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 20, "character": 21}},
"id": {"const": {"declName": "S.fn2"}}}},
{"sortText": "2",
"label": "pred",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 20, "character": 21}},
"id": {"const": {"declName": "S.pred"}}}}],
"isIncomplete": true}

View file

@ -1,7 +1,28 @@
{"textDocument": {"uri": "file:///completion5.lean"},
"position": {"line": 9, "character": 15}}
{"items":
[{"label": "b1", "kind": 5, "detail": "C → String"},
{"label": "f1", "kind": 5, "detail": "C → Nat"},
{"label": "f2", "kind": 5, "detail": "C → Bool"}],
[{"sortText": "0",
"label": "b1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion5.lean"},
"position": {"line": 9, "character": 15}},
"id": {"const": {"declName": "C.b1"}}}},
{"sortText": "1",
"label": "f1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion5.lean"},
"position": {"line": 9, "character": 15}},
"id": {"const": {"declName": "C.f1"}}}},
{"sortText": "2",
"label": "f2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion5.lean"},
"position": {"line": 9, "character": 15}},
"id": {"const": {"declName": "C.f2"}}}}],
"isIncomplete": true}

View file

@ -1,19 +1,96 @@
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 12, "character": 15}}
{"items":
[{"label": "b1", "kind": 5, "detail": "C → String"},
{"label": "f1", "kind": 5, "detail": "C → Nat"},
{"label": "f2", "kind": 5, "detail": "C → Bool"},
{"label": "f3", "kind": 5, "detail": "D → Bool"},
{"label": "toC", "kind": 5, "detail": "D → C"}],
[{"sortText": "0",
"label": "b1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 12, "character": 15}},
"id": {"const": {"declName": "C.b1"}}}},
{"sortText": "1",
"label": "f1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 12, "character": 15}},
"id": {"const": {"declName": "C.f1"}}}},
{"sortText": "2",
"label": "f2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 12, "character": 15}},
"id": {"const": {"declName": "C.f2"}}}},
{"sortText": "3",
"label": "f3",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 12, "character": 15}},
"id": {"const": {"declName": "D.f3"}}}},
{"sortText": "4",
"label": "toC",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 12, "character": 15}},
"id": {"const": {"declName": "D.toC"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}}
{"items":
[{"label": "b1", "kind": 5, "detail": "C → String"},
{"label": "doubleF1", "kind": 3, "detail": "E → Nat"},
{"label": "f1", "kind": 5, "detail": "C → Nat"},
{"label": "f2", "kind": 5, "detail": "C → Bool"},
{"label": "f3", "kind": 5, "detail": "D → Bool"},
{"label": "toC", "kind": 5, "detail": "D → C"}],
[{"sortText": "0",
"label": "b1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}},
"id": {"const": {"declName": "C.b1"}}}},
{"sortText": "1",
"label": "doubleF1",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}},
"id": {"const": {"declName": "E.doubleF1"}}}},
{"sortText": "2",
"label": "f1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}},
"id": {"const": {"declName": "C.f1"}}}},
{"sortText": "3",
"label": "f2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}},
"id": {"const": {"declName": "C.f2"}}}},
{"sortText": "4",
"label": "f3",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}},
"id": {"const": {"declName": "D.f3"}}}},
{"sortText": "5",
"label": "toC",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}},
"id": {"const": {"declName": "D.toC"}}}}],
"isIncomplete": true}

View file

@ -1,11 +1,40 @@
{"textDocument": {"uri": "file:///completion7.lean"},
"position": {"line": 6, "character": 10}}
{"items": [{"label": "And", "kind": 22, "detail": "Type 1"}],
{"items":
[{"sortText": "0",
"label": "And",
"kind": 22,
"data":
{"params":
{"textDocument": {"uri": "file:///completion7.lean"},
"position": {"line": 6, "character": 10}},
"id": {"const": {"declName": "And"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completion7.lean"},
"position": {"line": 8, "character": 11}}
{"items":
[{"label": "left", "kind": 5, "detail": "And → Type"},
{"label": "mk", "kind": 4, "detail": "Type → Type → And"},
{"label": "right", "kind": 5, "detail": "And → Type"}],
[{"sortText": "0",
"label": "left",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion7.lean"},
"position": {"line": 8, "character": 11}},
"id": {"const": {"declName": "And.left"}}}},
{"sortText": "1",
"label": "mk",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///completion7.lean"},
"position": {"line": 8, "character": 11}},
"id": {"const": {"declName": "And.mk"}}}},
{"sortText": "2",
"label": "right",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion7.lean"},
"position": {"line": 8, "character": 11}},
"id": {"const": {"declName": "And.right"}}}}],
"isIncomplete": true}

View file

@ -1,14 +1,24 @@
{"textDocument": {"uri": "file:///completionAtPrint.lean"},
"position": {"line": 2, "character": 25}}
{"items":
[{"label": "find?",
[{"sortText": "0",
"label": "find?",
"kind": 3,
"detail": "Lean.Environment → Lean.Name → Option Lean.ConstantInfo"},
{"label": "freeRegions",
"data":
{"params":
{"textDocument": {"uri": "file:///completionAtPrint.lean"},
"position": {"line": 2, "character": 25}},
"id": {"const": {"declName": "Lean.Environment.find?"}}}},
{"sortText": "1",
"label": "freeRegions",
"kind": 3,
"documentation":
{"value":
"Free compacted regions of imports. No live references to imported objects may exist at the time of invocation; in\nparticular, `env` should be the last reference to any `Environment` derived from these imports. ",
"kind": "markdown"},
"detail": "Lean.Environment → IO Unit"}],
"data":
{"params":
{"textDocument": {"uri": "file:///completionAtPrint.lean"},
"position": {"line": 2, "character": 25}},
"id": {"const": {"declName": "Lean.Environment.freeRegions"}}}}],
"isIncomplete": true}

View file

@ -0,0 +1,8 @@
structure AVerySpecificStructureName where
x : Nat
structure AVerySpecificStructureName2 where
x : Nat
#check AVerySpecificStructureName
--^ textDocument/completion

View file

@ -0,0 +1,20 @@
{"textDocument": {"uri": "file:///completionCheck.lean"},
"position": {"line": 6, "character": 33}}
{"items":
[{"sortText": "0",
"label": "AVerySpecificStructureName",
"kind": 22,
"data":
{"params":
{"textDocument": {"uri": "file:///completionCheck.lean"},
"position": {"line": 6, "character": 33}},
"id": {"const": {"declName": "AVerySpecificStructureName"}}}},
{"sortText": "1",
"label": "AVerySpecificStructureName2",
"kind": 22,
"data":
{"params":
{"textDocument": {"uri": "file:///completionCheck.lean"},
"position": {"line": 6, "character": 33}},
"id": {"const": {"declName": "AVerySpecificStructureName2"}}}}],
"isIncomplete": true}

View file

@ -1,16 +1,26 @@
{"textDocument": {"uri": "file:///completionDocString.lean"},
"position": {"line": 0, "character": 20}}
{"items":
[{"label": "insertAt",
[{"sortText": "0",
"label": "insertAt",
"kind": 3,
"documentation":
{"value": "Insert element `a` at position `i`. ", "kind": "markdown"},
"detail": "(as : Array α) → Fin (Array.size as + 1) → α → Array α"},
{"label": "insertAt!",
"data":
{"params":
{"textDocument": {"uri": "file:///completionDocString.lean"},
"position": {"line": 0, "character": 20}},
"id": {"const": {"declName": "Array.insertAt"}}}},
{"sortText": "1",
"label": "insertAt!",
"kind": 3,
"documentation":
{"value":
"Insert element `a` at position `i`. Panics if `i` is not `i ≤ as.size`. ",
"kind": "markdown"},
"detail": "Array α → Nat → α → Array α"}],
"data":
{"params":
{"textDocument": {"uri": "file:///completionDocString.lean"},
"position": {"line": 0, "character": 20}},
"id": {"const": {"declName": "Array.insertAt!"}}}}],
"isIncomplete": true}

View file

@ -1,4 +1,12 @@
{"textDocument": {"uri": "file:///completionEOF.lean"},
"position": {"line": 8, "character": 9}}
{"items": [{"label": "And", "kind": 21, "detail": "Type"}],
{"items":
[{"sortText": "0",
"label": "And",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///completionEOF.lean"},
"position": {"line": 8, "character": 9}},
"id": {"const": {"declName": "And"}}}}],
"isIncomplete": true}

View file

@ -0,0 +1,5 @@
structure Foo where
x : Nat
def foo : Foo := .
--^ textDocument/completion

View file

@ -0,0 +1,12 @@
{"textDocument": {"uri": "file:///completionFromExpectedType.lean"},
"position": {"line": 3, "character": 18}}
{"items":
[{"sortText": "0",
"label": "mk",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///completionFromExpectedType.lean"},
"position": {"line": 3, "character": 18}},
"id": {"const": {"declName": "Foo.mk"}}}}],
"isIncomplete": true}

View file

@ -1,7 +1,28 @@
{"textDocument": {"uri": "file:///completionIStr.lean"},
"position": {"line": 5, "character": 34}}
{"items":
[{"label": "b1", "kind": 5, "detail": "C → String"},
{"label": "f1", "kind": 5, "detail": "C → Nat"},
{"label": "f2", "kind": 5, "detail": "C → Bool"}],
[{"sortText": "0",
"label": "b1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completionIStr.lean"},
"position": {"line": 5, "character": 34}},
"id": {"const": {"declName": "C.b1"}}}},
{"sortText": "1",
"label": "f1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completionIStr.lean"},
"position": {"line": 5, "character": 34}},
"id": {"const": {"declName": "C.f1"}}}},
{"sortText": "2",
"label": "f2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completionIStr.lean"},
"position": {"line": 5, "character": 34}},
"id": {"const": {"declName": "C.f2"}}}}],
"isIncomplete": true}

View file

@ -0,0 +1,6 @@
def A.B1.verySpecificDefinitionNameOfCompletionOpenNamespaces := 1
open A B1
namespace A
def c2 : Nat := verySpecificDefinitionNameOfCompletionOpenNamespaces
--^ textDocument/completion

View file

@ -0,0 +1,15 @@
{"textDocument": {"uri": "file:///completionOpenNamespaces.lean"},
"position": {"line": 4, "character": 68}}
{"items":
[{"sortText": "0",
"label": "verySpecificDefinitionNameOfCompletionOpenNamespaces",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///completionOpenNamespaces.lean"},
"position": {"line": 4, "character": 68}},
"id":
{"const":
{"declName":
"A.B1.verySpecificDefinitionNameOfCompletionOpenNamespaces"}}}}],
"isIncomplete": true}

View file

@ -9,10 +9,15 @@
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"sortText": "0",
"label": "trace.PrettyPrinter.format",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"},
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}}}},
{"textEdit":
{"replace":
{"start": {"line": 1, "character": 11},
@ -21,9 +26,14 @@
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"sortText": "1",
"label": "format.indent",
"kind": 10,
"detail": "(2), indentation"},
"detail": "(2), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}}}},
{"textEdit":
{"replace":
{"start": {"line": 1, "character": 11},
@ -32,9 +42,14 @@
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"sortText": "2",
"label": "format.inputWidth",
"kind": 10,
"detail": "(100), ideal input width"},
"detail": "(100), ideal input width",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}}}},
{"textEdit":
{"replace":
{"start": {"line": 1, "character": 11},
@ -43,9 +58,14 @@
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"sortText": "3",
"label": "format.unicode",
"kind": 10,
"detail": "(true), unicode characters"},
"detail": "(true), unicode characters",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}}}},
{"textEdit":
{"replace":
{"start": {"line": 1, "character": 11},
@ -54,9 +74,14 @@
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"sortText": "4",
"label": "format.width",
"kind": 10,
"detail": "(120), indentation"},
"detail": "(120), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}}}},
{"textEdit":
{"replace":
{"start": {"line": 1, "character": 11},
@ -65,10 +90,15 @@
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"sortText": "5",
"label": "trace.PrettyPrinter.format.backtrack",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"},
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}}}},
{"textEdit":
{"replace":
{"start": {"line": 1, "character": 11},
@ -77,10 +107,15 @@
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"sortText": "6",
"label": "trace.PrettyPrinter.format.input",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"}],
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 4, "character": 20}}
@ -93,9 +128,14 @@
"insert":
{"start": {"line": 4, "character": 11},
"end": {"line": 4, "character": 20}}},
"sortText": "0",
"label": "format.indent",
"kind": 10,
"detail": "(2), indentation"},
"detail": "(2), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 4, "character": 20}}}},
{"textEdit":
{"replace":
{"start": {"line": 4, "character": 11},
@ -104,9 +144,14 @@
"insert":
{"start": {"line": 4, "character": 11},
"end": {"line": 4, "character": 20}}},
"sortText": "1",
"label": "format.inputWidth",
"kind": 10,
"detail": "(100), ideal input width"},
"detail": "(100), ideal input width",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 4, "character": 20}}}},
{"textEdit":
{"replace":
{"start": {"line": 4, "character": 11},
@ -115,10 +160,15 @@
"insert":
{"start": {"line": 4, "character": 11},
"end": {"line": 4, "character": 20}}},
"sortText": "2",
"label": "trace.PrettyPrinter.format.input",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"}],
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 4, "character": 20}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 7, "character": 23}}
@ -131,10 +181,15 @@
"insert":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}}},
"sortText": "0",
"label": "trace.pp.analyze",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"},
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 7, "character": 23}}}},
{"textEdit":
{"replace":
{"start": {"line": 7, "character": 11},
@ -143,10 +198,15 @@
"insert":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}}},
"sortText": "1",
"label": "trace.pp.analyze.annotate",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"},
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 7, "character": 23}}}},
{"textEdit":
{"replace":
{"start": {"line": 7, "character": 11},
@ -155,10 +215,15 @@
"insert":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}}},
"sortText": "2",
"label": "trace.pp.analyze.error",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"},
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 7, "character": 23}}}},
{"textEdit":
{"replace":
{"start": {"line": 7, "character": 11},
@ -167,10 +232,15 @@
"insert":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}}},
"sortText": "3",
"label": "trace.pp.analyze.tryUnify",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"}],
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 7, "character": 23}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 10, "character": 27}}
@ -183,10 +253,15 @@
"insert":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}}},
"sortText": "0",
"label": "trace.pp.analyze",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"},
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 10, "character": 27}}}},
{"textEdit":
{"replace":
{"start": {"line": 10, "character": 11},
@ -195,10 +270,15 @@
"insert":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}}},
"sortText": "1",
"label": "trace.pp.analyze.annotate",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"},
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 10, "character": 27}}}},
{"textEdit":
{"replace":
{"start": {"line": 10, "character": 11},
@ -207,10 +287,15 @@
"insert":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}}},
"sortText": "2",
"label": "trace.pp.analyze.error",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"},
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 10, "character": 27}}}},
{"textEdit":
{"replace":
{"start": {"line": 10, "character": 11},
@ -219,10 +304,15 @@
"insert":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}}},
"sortText": "3",
"label": "trace.pp.analyze.tryUnify",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"}],
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 10, "character": 27}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}}
@ -235,10 +325,15 @@
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"sortText": "0",
"label": "trace.PrettyPrinter.format",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"},
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}}}},
{"textEdit":
{"replace":
{"start": {"line": 13, "character": 11},
@ -247,9 +342,14 @@
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"sortText": "1",
"label": "format.indent",
"kind": 10,
"detail": "(2), indentation"},
"detail": "(2), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}}}},
{"textEdit":
{"replace":
{"start": {"line": 13, "character": 11},
@ -258,9 +358,14 @@
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"sortText": "2",
"label": "format.inputWidth",
"kind": 10,
"detail": "(100), ideal input width"},
"detail": "(100), ideal input width",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}}}},
{"textEdit":
{"replace":
{"start": {"line": 13, "character": 11},
@ -269,9 +374,14 @@
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"sortText": "3",
"label": "format.unicode",
"kind": 10,
"detail": "(true), unicode characters"},
"detail": "(true), unicode characters",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}}}},
{"textEdit":
{"replace":
{"start": {"line": 13, "character": 11},
@ -280,9 +390,14 @@
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"sortText": "4",
"label": "format.width",
"kind": 10,
"detail": "(120), indentation"},
"detail": "(120), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}}}},
{"textEdit":
{"replace":
{"start": {"line": 13, "character": 11},
@ -291,10 +406,15 @@
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"sortText": "5",
"label": "trace.PrettyPrinter.format.backtrack",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"},
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}}}},
{"textEdit":
{"replace":
{"start": {"line": 13, "character": 11},
@ -303,10 +423,15 @@
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"sortText": "6",
"label": "trace.PrettyPrinter.format.input",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"}],
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}}
@ -319,9 +444,14 @@
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"sortText": "0",
"label": "format.indent",
"kind": 10,
"detail": "(2), indentation"},
"detail": "(2), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}}}},
{"textEdit":
{"replace":
{"start": {"line": 16, "character": 11},
@ -330,9 +460,14 @@
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"sortText": "1",
"label": "format.inputWidth",
"kind": 10,
"detail": "(100), ideal input width"},
"detail": "(100), ideal input width",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}}}},
{"textEdit":
{"replace":
{"start": {"line": 16, "character": 11},
@ -341,9 +476,14 @@
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"sortText": "2",
"label": "format.unicode",
"kind": 10,
"detail": "(true), unicode characters"},
"detail": "(true), unicode characters",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}}}},
{"textEdit":
{"replace":
{"start": {"line": 16, "character": 11},
@ -352,9 +492,14 @@
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"sortText": "3",
"label": "format.width",
"kind": 10,
"detail": "(120), indentation"},
"detail": "(120), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}}}},
{"textEdit":
{"replace":
{"start": {"line": 16, "character": 11},
@ -363,10 +508,15 @@
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"sortText": "4",
"label": "trace.PrettyPrinter.format.backtrack",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"},
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}}}},
{"textEdit":
{"replace":
{"start": {"line": 16, "character": 11},
@ -375,8 +525,13 @@
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"sortText": "5",
"label": "trace.PrettyPrinter.format.input",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules"}],
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}}}}],
"isIncomplete": true}

View file

@ -1,8 +1,21 @@
{"textDocument": {"uri": "file:///completionPrefixIssue.lean"},
"position": {"line": 1, "character": 64}}
{"items":
[{"label": "veryLongDefinitionName", "kind": 6, "detail": "Nat"},
{"label": "veryLongDefinitionNameVeryLongDefinitionName",
[{"sortText": "0",
"label": "veryLongDefinitionName",
"kind": 6,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrefixIssue.lean"},
"position": {"line": 1, "character": 64}},
"id": {"fvar": {"id": "_uniq.29"}}}},
{"sortText": "1",
"label": "veryLongDefinitionNameVeryLongDefinitionName",
"kind": 21,
"detail": "Nat"}],
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrefixIssue.lean"},
"position": {"line": 1, "character": 64}},
"id":
{"const": {"declName": "veryLongDefinitionNameVeryLongDefinitionName"}}}}],
"isIncomplete": true}

View file

@ -0,0 +1,5 @@
private structure Foo where
x : Nat
def foobar (f : Foo) := f.
--^ textDocument/completion

View file

@ -0,0 +1,12 @@
{"textDocument": {"uri": "file:///completionPrivateTypes.lean"},
"position": {"line": 3, "character": 26}}
{"items":
[{"sortText": "0",
"label": "x",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrivateTypes.lean"},
"position": {"line": 3, "character": 26}},
"id": {"const": {"declName": "_private.0.Foo.x"}}}}],
"isIncomplete": true}

View file

@ -1,22 +1,72 @@
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 2, "character": 11}}
{"items": [{"label": "blaBlaBoo", "kind": 21, "detail": "Nat"}],
{"items":
[{"sortText": "0",
"label": "blaBlaBoo",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 2, "character": 11}},
"id": {"const": {"declName": "_private.0.blaBlaBoo"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 9, "character": 11}}
{"items":
[{"label": "booBoo", "kind": 21, "detail": "Nat"},
{"label": "instToBoolBool", "kind": 21, "detail": "ToBool Bool"}],
[{"sortText": "0",
"label": "booBoo",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 9, "character": 11}},
"id": {"const": {"declName": "_private.0.Foo.booBoo"}}}},
{"sortText": "1",
"label": "instToBoolBool",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 9, "character": 11}},
"id": {"const": {"declName": "instToBoolBool"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 21, "character": 5}}
{"items":
[{"label": "field1", "kind": 5, "detail": "S → Nat"},
{"label": "getInc", "kind": 3, "detail": "S → Nat"}],
[{"sortText": "0",
"label": "field1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 21, "character": 5}},
"id": {"const": {"declName": "S.field1"}}}},
{"sortText": "1",
"label": "getInc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 21, "character": 5}},
"id": {"const": {"declName": "_private.0.S.getInc"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 25, "character": 4}}
{"items":
[{"label": "field1", "kind": 5, "detail": "S → Nat"},
{"label": "getInc", "kind": 3, "detail": "S → Nat"}],
[{"sortText": "0",
"label": "field1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 25, "character": 4}},
"id": {"const": {"declName": "S.field1"}}}},
{"sortText": "1",
"label": "getInc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 25, "character": 4}},
"id": {"const": {"declName": "_private.0.S.getInc"}}}}],
"isIncomplete": true}

View file

@ -1,6 +1,20 @@
{"textDocument": {"uri": "file:///dotIdCompletion.lean"},
"position": {"line": 4, "character": 5}}
{"items":
[{"label": "true", "kind": 4, "detail": "Boo"},
{"label": "truth", "kind": 4, "detail": "Boo"}],
[{"sortText": "0",
"label": "true",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///dotIdCompletion.lean"},
"position": {"line": 4, "character": 5}},
"id": {"const": {"declName": "Boo.true"}}}},
{"sortText": "1",
"label": "truth",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///dotIdCompletion.lean"},
"position": {"line": 4, "character": 5}},
"id": {"const": {"declName": "Boo.truth"}}}}],
"isIncomplete": true}

View file

@ -6,5 +6,13 @@
"end": {"line": 3, "character": 22}}}]}
{"textDocument": {"uri": "file:///editCompletion.lean"},
"position": {"line": 3, "character": 22}}
{"items": [{"label": "foo", "kind": 5, "detail": "Foo → Nat"}],
{"items":
[{"sortText": "0",
"label": "foo",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///editCompletion.lean"},
"position": {"line": 3, "character": 22}},
"id": {"const": {"declName": "Foo.foo"}}}}],
"isIncomplete": true}

View file

@ -1,14 +1,56 @@
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 4, "character": 11}}
{"items":
[{"label": "gfxabc", "kind": 3, "detail": "Nat → Nat"},
{"label": "gfxacc", "kind": 3, "detail": "Nat → Nat"},
{"label": "gfxadc", "kind": 3, "detail": "Nat → Nat"}],
[{"sortText": "0",
"label": "gfxabc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 4, "character": 11}},
"id": {"const": {"declName": "gfxabc"}}}},
{"sortText": "1",
"label": "gfxacc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 4, "character": 11}},
"id": {"const": {"declName": "gfxacc"}}}},
{"sortText": "2",
"label": "gfxadc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 4, "character": 11}},
"id": {"const": {"declName": "gfxadc"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 12, "character": 15}}
{"items":
[{"label": "gfxabc", "kind": 3, "detail": "Nat → Nat"},
{"label": "gfxacc", "kind": 3, "detail": "Nat → Nat"},
{"label": "gfxadc", "kind": 3, "detail": "Nat → Nat"}],
[{"sortText": "0",
"label": "gfxabc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 12, "character": 15}},
"id": {"const": {"declName": "Boo.gfxabc"}}}},
{"sortText": "1",
"label": "gfxacc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 12, "character": 15}},
"id": {"const": {"declName": "Boo.gfxacc"}}}},
{"sortText": "2",
"label": "gfxadc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 12, "character": 15}},
"id": {"const": {"declName": "Boo.gfxadc"}}}}],
"isIncomplete": true}

View file

@ -1,6 +1,20 @@
{"textDocument": {"uri": "file:///internalNamesIssue.lean"},
"position": {"line": 9, "character": 11}}
{"items":
[{"label": "bla", "kind": 3, "detail": "Nat → Nat"},
{"label": "foo", "kind": 3, "detail": "Nat → Nat"}],
[{"sortText": "0",
"label": "bla",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///internalNamesIssue.lean"},
"position": {"line": 9, "character": 11}},
"id": {"const": {"declName": "Foo.bla"}}}},
{"sortText": "1",
"label": "foo",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///internalNamesIssue.lean"},
"position": {"line": 9, "character": 11}},
"id": {"const": {"declName": "Foo.foo"}}}}],
"isIncomplete": true}

View file

@ -1,14 +1,64 @@
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}}
{"items":
[{"label": "bin", "kind": 21, "detail": "Type 1"},
{"label": "binder_predicate", "kind": 14, "detail": "keyword"},
{"label": "binop%", "kind": 14, "detail": "keyword"},
{"label": "binop_lazy%", "kind": 14, "detail": "keyword"},
{"label": "binrel%", "kind": 14, "detail": "keyword"},
{"label": "binrel_no_prop%", "kind": 14, "detail": "keyword"}],
[{"sortText": "0",
"label": "bin",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}},
"id": {"const": {"declName": "bin"}}}},
{"sortText": "1",
"label": "binder_predicate",
"kind": 14,
"detail": "keyword",
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}}}},
{"sortText": "2",
"label": "binop%",
"kind": 14,
"detail": "keyword",
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}}}},
{"sortText": "3",
"label": "binop_lazy%",
"kind": 14,
"detail": "keyword",
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}}}},
{"sortText": "4",
"label": "binrel%",
"kind": 14,
"detail": "keyword",
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}}}},
{"sortText": "5",
"label": "binrel_no_prop%",
"kind": 14,
"detail": "keyword",
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 13}}
{"items": [{"label": "binop_lazy%", "kind": 14, "detail": "keyword"}],
{"items":
[{"sortText": "0",
"label": "binop_lazy%",
"kind": 14,
"detail": "keyword",
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 13}}}}],
"isIncomplete": true}

View file

@ -1,16 +1,58 @@
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 6, "character": 11}}
{"items":
[{"label": "fn1", "kind": 5, "detail": "S → Nat"},
{"label": "name", "kind": 5, "detail": "S → String"},
{"label": "value", "kind": 5, "detail": "S → Bool"}],
[{"sortText": "0",
"label": "fn1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 6, "character": 11}},
"id": {"const": {"declName": "S.fn1"}}}},
{"sortText": "1",
"label": "name",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 6, "character": 11}},
"id": {"const": {"declName": "S.name"}}}},
{"sortText": "2",
"label": "value",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 6, "character": 11}},
"id": {"const": {"declName": "S.value"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 10, "character": 10}}
{"items":
[{"label": "fn1", "kind": 5, "detail": "S → Nat"},
{"label": "name", "kind": 5, "detail": "S → String"},
{"label": "value", "kind": 5, "detail": "S → Bool"}],
[{"sortText": "0",
"label": "fn1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 10, "character": 10}},
"id": {"const": {"declName": "S.fn1"}}}},
{"sortText": "1",
"label": "name",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 10, "character": 10}},
"id": {"const": {"declName": "S.name"}}}},
{"sortText": "2",
"label": "value",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 10, "character": 10}},
"id": {"const": {"declName": "S.value"}}}}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 14, "character": 2}}

View file

@ -1,7 +1,28 @@
{"textDocument": {"uri": "file:///matchStxCompletion.lean"},
"position": {"line": 8, "character": 9}}
{"items":
[{"label": "b1", "kind": 5, "detail": "C → String"},
{"label": "f1", "kind": 5, "detail": "C → Nat"},
{"label": "f2", "kind": 5, "detail": "C → Bool"}],
[{"sortText": "0",
"label": "b1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///matchStxCompletion.lean"},
"position": {"line": 8, "character": 9}},
"id": {"const": {"declName": "C.b1"}}}},
{"sortText": "1",
"label": "f1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///matchStxCompletion.lean"},
"position": {"line": 8, "character": 9}},
"id": {"const": {"declName": "C.f1"}}}},
{"sortText": "2",
"label": "f2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///matchStxCompletion.lean"},
"position": {"line": 8, "character": 9}},
"id": {"const": {"declName": "C.f2"}}}}],
"isIncomplete": true}