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:
parent
88fbe2e531
commit
a929c0176d
48 changed files with 2096 additions and 376 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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})"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
39
src/Lean/Server/CompletionItemData.lean
Normal file
39
src/Lean/Server/CompletionItemData.lean
Normal 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
|
||||
|
|
@ -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 := {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -817,6 +817,7 @@ def mkLeanServerCapabilities : ServerCapabilities := {
|
|||
-- refine
|
||||
completionProvider? := some {
|
||||
triggerCharacters? := some #["."]
|
||||
resolveProvider := true
|
||||
}
|
||||
hoverProvider := true
|
||||
declarationProvider := true
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
8
tests/lean/interactive/completionCheck.lean
Normal file
8
tests/lean/interactive/completionCheck.lean
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
structure AVerySpecificStructureName where
|
||||
x : Nat
|
||||
|
||||
structure AVerySpecificStructureName2 where
|
||||
x : Nat
|
||||
|
||||
#check AVerySpecificStructureName
|
||||
--^ textDocument/completion
|
||||
20
tests/lean/interactive/completionCheck.lean.expected.out
Normal file
20
tests/lean/interactive/completionCheck.lean.expected.out
Normal 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}
|
||||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
5
tests/lean/interactive/completionFromExpectedType.lean
Normal file
5
tests/lean/interactive/completionFromExpectedType.lean
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
structure Foo where
|
||||
x : Nat
|
||||
|
||||
def foo : Foo := .
|
||||
--^ textDocument/completion
|
||||
|
|
@ -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}
|
||||
|
|
@ -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}
|
||||
|
|
|
|||
6
tests/lean/interactive/completionOpenNamespaces.lean
Normal file
6
tests/lean/interactive/completionOpenNamespaces.lean
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
def A.B1.verySpecificDefinitionNameOfCompletionOpenNamespaces := 1
|
||||
open A B1
|
||||
|
||||
namespace A
|
||||
def c2 : Nat := verySpecificDefinitionNameOfCompletionOpenNamespaces
|
||||
--^ textDocument/completion
|
||||
|
|
@ -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}
|
||||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
5
tests/lean/interactive/completionPrivateTypes.lean
Normal file
5
tests/lean/interactive/completionPrivateTypes.lean
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
private structure Foo where
|
||||
x : Nat
|
||||
|
||||
def foobar (f : Foo) := f.
|
||||
--^ textDocument/completion
|
||||
|
|
@ -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}
|
||||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue