feat: improve auto-completion performance (#10249)

This PR speeds up auto-completion by a factor of ~3.5x through various
performance improvements in the language server. On one machine, with
`import Mathlib`, completing `i` used to take 3200ms and now instead
yields a result in 920ms.

Specifically, the following improvements are made:
- The watchdog process no longer de-serializes and re-serializes most
messages from the file worker before passing them on to the user - a
fast partial de-serialization procedure is now used to determine whether
the message needs to be de-serialized in full or not.
- `escapePart` is optimized to perform better on ASCII strings that do
not need escaping.
- `Json.compress` is optimized to allocate fewer objects.
- A faster JSON compression specifically for completion responses is
implemented that skips allocating `Json` altogether.
- The JSON compression has been moved to the task where we convert a
request response to `Json` so that converting to a string won't block
the output task of the FileWorker and so the `Json` value is not marked
as multi-threaded when we compress is, which drastically increases the
cost of reference-counting.
- The JSON representation of the `data?` field of each completion item
is optimized.
- Both the completion kind and the set of completion tags for each
imported completion item is now cached.
- The filtering of duplicate completion items is optimized.

Other adjustments:
- `LT UInt8` and `LE UInt8` are moved to Prelude so that they can be
used in `Init.Meta` for the name part escaping fast path.
- `Array.usize` is exposed since it was marked as `@[simp]`.
This commit is contained in:
Marc Huisinga 2025-09-05 10:55:49 +02:00 committed by GitHub
parent 9923a8d9f8
commit 7ba0ae1f72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
61 changed files with 2249 additions and 3285 deletions

View file

@ -10,8 +10,6 @@ public import Init.WFTactics
public import Init.Data.Nat.Basic
public import Init.Data.Fin.Basic
public import Init.Data.UInt.BasicAux
public import Init.Data.Repr
public import Init.Data.ToString.Basic
public import Init.GetElem
public import Init.Data.List.ToArrayImpl
import all Init.Data.List.ToArrayImpl
@ -164,7 +162,7 @@ This is a low-level version of `Array.size` that directly queries the runtime sy
representation of arrays. While this is not provable, `Array.usize` always returns the exact size of
the array since the implementation only supports arrays of size less than `USize.size`.
-/
@[extern "lean_array_size", simp]
@[extern "lean_array_size", simp, expose]
def usize (xs : @& Array α) : USize := xs.size.toUSize
/--

View file

@ -6,7 +6,6 @@ Author: Leonardo de Moura
module
prelude
public import Init.Data.Array.Basic
public import Init.Data.Array.DecidableEq
public import Init.Data.UInt.Basic
public import Init.Data.UInt.BasicAux

View file

@ -139,16 +139,6 @@ This function is overridden at runtime with an efficient implementation.
-/
@[extern "lean_uint8_shift_right"]
protected def UInt8.shiftRight (a b : UInt8) : UInt8 := ⟨a.toBitVec >>> (UInt8.mod b 8).toBitVec⟩
/--
Strict inequality of 8-bit unsigned integers, defined as inequality of the corresponding
natural numbers. Usually accessed via the `<` operator.
-/
protected def UInt8.lt (a b : UInt8) : Prop := a.toBitVec < b.toBitVec
/--
Non-strict inequality of 8-bit unsigned integers, defined as inequality of the corresponding
natural numbers. Usually accessed via the `≤` operator.
-/
protected def UInt8.le (a b : UInt8) : Prop := a.toBitVec ≤ b.toBitVec
instance : Add UInt8 := ⟨UInt8.add⟩
instance : Sub UInt8 := ⟨UInt8.sub⟩
@ -160,8 +150,6 @@ set_option linter.deprecated false in
instance : HMod UInt8 Nat UInt8 := ⟨UInt8.modn⟩
instance : Div UInt8 := ⟨UInt8.div⟩
instance : LT UInt8 := ⟨UInt8.lt⟩
instance : LE UInt8 := ⟨UInt8.le⟩
/--
Bitwise complement, also known as bitwise negation, for 8-bit unsigned integers. Usually accessed
@ -197,39 +185,6 @@ Converts `true` to `1` and `false` to `0`.
@[extern "lean_bool_to_uint8"]
def Bool.toUInt8 (b : Bool) : UInt8 := if b then 1 else 0
/--
Decides whether one 8-bit unsigned integer is strictly less than another. Usually accessed via the
`DecidableLT UInt8` instance.
This function is overridden at runtime with an efficient implementation.
Examples:
* `(if (6 : UInt8) < 7 then "yes" else "no") = "yes"`
* `(if (5 : UInt8) < 5 then "yes" else "no") = "no"`
* `show ¬((7 : UInt8) < 7) by decide`
-/
@[extern "lean_uint8_dec_lt"]
def UInt8.decLt (a b : UInt8) : Decidable (a < b) :=
inferInstanceAs (Decidable (a.toBitVec < b.toBitVec))
/--
Decides whether one 8-bit unsigned integer is less than or equal to another. Usually accessed via the
`DecidableLE UInt8` instance.
This function is overridden at runtime with an efficient implementation.
Examples:
* `(if (15 : UInt8) ≤ 15 then "yes" else "no") = "yes"`
* `(if (15 : UInt8) ≤ 5 then "yes" else "no") = "no"`
* `(if (5 : UInt8) ≤ 15 then "yes" else "no") = "yes"`
* `show (7 : UInt8) ≤ 7 by decide`
-/
@[extern "lean_uint8_dec_le"]
def UInt8.decLe (a b : UInt8) : Decidable (a ≤ b) :=
inferInstanceAs (Decidable (a.toBitVec ≤ b.toBitVec))
attribute [instance] UInt8.decLt UInt8.decLe
instance : Max UInt8 := maxOfLe
instance : Min UInt8 := minOfLe

View file

@ -109,9 +109,22 @@ def isSubScriptAlnum (c : Char) : Bool :=
@[inline] def isIdFirst (c : Char) : Bool :=
c.isAlpha || c = '_' || isLetterLike c
@[inline] private def isAlphaAscii (c : UInt8) : Bool :=
'a'.toUInt8 ≤ c && c ≤ 'z'.toUInt8
|| 'A'.toUInt8 ≤ c && c ≤ 'Z'.toUInt8
@[inline] private def isIdFirstAscii (c : UInt8) : Bool :=
isAlphaAscii c || c = '_'.toUInt8
@[inline] private def isAlphanumAscii (c : UInt8) : Bool :=
isAlphaAscii c || '0'.toUInt8 ≤ c && c ≤ '9'.toUInt8
@[inline] def isIdRest (c : Char) : Bool :=
c.isAlphanum || c = '_' || c = '\'' || c == '!' || c == '?' || isLetterLike c || isSubScriptAlnum c
@[inline] private def isIdRestAscii (c : UInt8) : Bool :=
isAlphanumAscii c || c = '_'.toUInt8 || c = '\''.toUInt8 || c == '!'.toUInt8 || c == '?'.toUInt8
def idBeginEscape := '«'
def idEndEscape := '»'
@[inline] def isIdBeginEscape (c : Char) : Bool := c = idBeginEscape
@ -137,6 +150,23 @@ def isInaccessibleUserName : Name → Bool
@[extern "lean_string_get_byte_fast"]
private opaque getUtf8Byte' (s : @& String) (n : Nat) (h : n < s.utf8ByteSize) : UInt8
private partial def needsNoEscapeAsciiRest (s : String) (i : Nat) : Bool :=
if h : i < s.utf8ByteSize then
let c := getUtf8Byte' s i h
isIdRestAscii c && needsNoEscapeAsciiRest s (i + 1)
else
true
@[inline] private def needsNoEscapeAscii (s : String) (h : s.utf8ByteSize > 0) : Bool :=
let c := getUtf8Byte' s 0 h
isIdFirstAscii c && needsNoEscapeAsciiRest s 1
@[inline] private def needsNoEscape (s : String) (h : s.utf8ByteSize > 0) : Bool :=
needsNoEscapeAscii s h || isIdFirst (s.get 0) && (s.toSubstring.drop 1).all isIdRest
@[inline] private def escape (s : String) : String :=
idBeginEscape.toString ++ s ++ idEndEscape.toString
/--
Creates a round-trippable string name component if possible, otherwise returns `none`.
Names that are valid identifiers are not escaped, and otherwise, if they do not contain `»`, they are escaped.
@ -144,9 +174,15 @@ Names that are valid identifiers are not escaped, and otherwise, if they do not
-/
@[inline]
def escapePart (s : String) (force : Bool := false) : Option String :=
if s.length > 0 && !force && isIdFirst (s.get 0) && (s.toSubstring.drop 1).all isIdRest then some s
else if s.any isIdEndEscape then none
else some <| idBeginEscape.toString ++ s ++ idEndEscape.toString
if h : s.utf8ByteSize > 0 then
if !force && needsNoEscape s h then
some s
else if s.any isIdEndEscape then
none
else
some <| escape s
else
some <| escape s
variable (sep : String) (escape : Bool) in
/--

View file

@ -2199,6 +2199,52 @@ instance : DecidableEq UInt8 := UInt8.decEq
instance : Inhabited UInt8 where
default := UInt8.ofNatLT 0 (of_decide_eq_true rfl)
/--
Strict inequality of 8-bit unsigned integers, defined as inequality of the corresponding
natural numbers. Usually accessed via the `<` operator.
-/
protected def UInt8.lt (a b : UInt8) : Prop := LT.lt a.toBitVec b.toBitVec
/--
Non-strict inequality of 8-bit unsigned integers, defined as inequality of the corresponding
natural numbers. Usually accessed via the `≤` operator.
-/
protected def UInt8.le (a b : UInt8) : Prop := LE.le a.toBitVec b.toBitVec
instance : LT UInt8 := ⟨UInt8.lt⟩
instance : LE UInt8 := ⟨UInt8.le⟩
/--
Decides whether one 8-bit unsigned integer is strictly less than another. Usually accessed via the
`DecidableLT UInt8` instance.
This function is overridden at runtime with an efficient implementation.
Examples:
* `(if (6 : UInt8) < 7 then "yes" else "no") = "yes"`
* `(if (5 : UInt8) < 5 then "yes" else "no") = "no"`
* `show ¬((7 : UInt8) < 7) by decide`
-/
@[extern "lean_uint8_dec_lt"]
def UInt8.decLt (a b : UInt8) : Decidable (LT.lt a b) :=
inferInstanceAs (Decidable (LT.lt a.toBitVec b.toBitVec))
/--
Decides whether one 8-bit unsigned integer is less than or equal to another. Usually accessed via the
`DecidableLE UInt8` instance.
This function is overridden at runtime with an efficient implementation.
Examples:
* `(if (15 : UInt8) ≤ 15 then "yes" else "no") = "yes"`
* `(if (15 : UInt8) ≤ 5 then "yes" else "no") = "no"`
* `(if (5 : UInt8) ≤ 15 then "yes" else "no") = "yes"`
* `show (7 : UInt8) ≤ 7 by decide`
-/
@[extern "lean_uint8_dec_le"]
def UInt8.decLe (a b : UInt8) : Decidable (LE.le a b) :=
inferInstanceAs (Decidable (LE.le a.toBitVec b.toBitVec))
attribute [instance] UInt8.decLt UInt8.decLe
/-- The number of distinct values representable by `UInt16`, that is, `2^16 = 65536`. -/
abbrev UInt16.size : Nat := 65536

View file

@ -6,7 +6,6 @@ Authors: Leonardo de Moura
module
prelude
public import Init.Data.String.Basic
public import Init.Data.ToString.Basic
public section

View file

@ -22,7 +22,7 @@ This table contains for each UTF-8 byte whether we need to escape a string that
private def escapeTable : { xs : ByteArray // xs.size = 256 } :=
⟨ByteArray.mk #[
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
@ -74,6 +74,7 @@ where
else
false
@[inline]
def escape (s : String) (acc : String := "") : String :=
-- If we don't have any characters that need to be escaped we can just append right away.
if needEscape s then
@ -81,6 +82,7 @@ def escape (s : String) (acc : String := "") : String :=
else
acc ++ s
@[inline]
def renderString (s : String) (acc : String := "") : String :=
let acc := acc ++ "\""
let acc := escape s acc
@ -107,35 +109,123 @@ end
def pretty (j : Json) (lineWidth := 80) : String :=
Format.pretty (render j) lineWidth
protected inductive CompressWorkItem
| json (j : Json)
| arrayElem (j : Json)
private inductive CompressWorkItemKind where
| json
| arrayElem
| arrayEnd
| objectField (k : String) (j : Json)
| objectField
| objectEnd
| comma
open Json.CompressWorkItem in
private structure CompressWorkItemQueue where
kinds : Array CompressWorkItemKind
values : Array Json
objectFieldKeys : Array String
@[inline]
private def CompressWorkItemQueue.pushKind (q : CompressWorkItemQueue) (kind : CompressWorkItemKind) :
CompressWorkItemQueue := {
q with kinds := q.kinds.push kind
}
@[inline]
private def CompressWorkItemQueue.pushValue (q : CompressWorkItemQueue) (value : Json) :
CompressWorkItemQueue := {
q with values := q.values.push value
}
@[inline]
private def CompressWorkItemQueue.pushObjectFieldKey (q : CompressWorkItemQueue) (objectFieldKey : String) :
CompressWorkItemQueue := {
q with objectFieldKeys := q.objectFieldKeys.push objectFieldKey
}
@[inline]
private def CompressWorkItemQueue.popKind (q : CompressWorkItemQueue) (h : q.kinds.size ≠ 0) :
CompressWorkItemKind × CompressWorkItemQueue :=
let kind := q.kinds[q.kinds.size - 1]
let q := { q with kinds := q.kinds.pop }
(kind, q)
@[inline]
private def CompressWorkItemQueue.popValue! (q : CompressWorkItemQueue) :
Json × CompressWorkItemQueue :=
let value := q.values[q.values.size - 1]!
let q := { q with values := q.values.pop }
(value, q)
@[inline]
private def CompressWorkItemQueue.popObjectFieldKey! (q : CompressWorkItemQueue) :
String × CompressWorkItemQueue :=
let objectFieldKey := q.objectFieldKeys[q.objectFieldKeys.size - 1]!
let q := { q with objectFieldKeys := q.objectFieldKeys.pop }
(objectFieldKey, q)
partial def compress (j : Json) : String :=
go "" [json j]
where go (acc : String) : List Json.CompressWorkItem → String
| [] => acc
| json j :: is =>
match j with
| null => go (acc ++ "null") is
| bool true => go (acc ++ "true") is
| bool false => go (acc ++ "false") is
| num s => go (acc ++ s.toString) is
| str s => go (renderString s acc) is
| arr elems => go (acc ++ "[") ((elems.map arrayElem).toListAppend (arrayEnd :: is))
| obj kvs => go (acc ++ "{") (kvs.foldl (init := []) (fun acc k j => objectField k j :: acc) ++ [objectEnd] ++ is)
| arrayElem j :: arrayEnd :: is => go acc (json j :: arrayEnd :: is)
| arrayElem j :: is => go acc (json j :: comma :: is)
| arrayEnd :: is => go (acc ++ "]") is
| objectField k j :: objectEnd :: is => go (renderString k acc ++ ":") (json j :: objectEnd :: is)
| objectField k j :: is => go (renderString k acc ++ ":") (json j :: comma :: is)
| objectEnd :: is => go (acc ++ "}") is
| comma :: is => go (acc ++ ",") is
go "" {
kinds := #[.json]
values := #[j]
objectFieldKeys := #[]
}
where
go (acc : String) (q : CompressWorkItemQueue) : String :=
if h : q.kinds.size = 0 then
acc
else
let (kind, q) := q.popKind h
match kind with
| .json =>
let (j, q) := q.popValue!
match j with
| null =>
go (acc ++ "null") q
| bool b =>
go (acc ++ toString b) q
| num n =>
go (acc ++ toString n) q
| str s =>
go (renderString s acc) q
| arr elems =>
let q := q.pushKind .arrayEnd
go (acc ++ "[") (elems.foldr (init := q) fun e acc => acc.pushKind .arrayElem |>.pushValue e)
| obj kvs =>
let q := q.pushKind .objectEnd
go (acc ++ "{") (kvs.foldr (init := q) fun k j acc => acc.pushKind .objectField |>.pushObjectFieldKey k |>.pushValue j)
| .arrayElem =>
let (j, q) := q.popValue!
if h : q.kinds.size = 0 then
go acc {
kinds := #[.comma, .json]
values := #[j]
objectFieldKeys := #[]
}
else
let kind := q.kinds[q.kinds.size - 1]
if kind matches .arrayEnd then
go acc (q.pushKind .json |>.pushValue j)
else
go acc (q.pushKind .comma |>.pushKind .json |>.pushValue j)
| .arrayEnd =>
go (acc ++ "]") q
| .objectField =>
let (k, q) := q.popObjectFieldKey!
let (j, q) := q.popValue!
if h : q.kinds.size = 0 then
go (renderString k acc ++ ":") {
kinds := #[.comma, .json]
values := #[j]
objectFieldKeys := #[]
}
else
let kind := q.kinds[q.kinds.size - 1]
if kind matches .objectEnd then
go (renderString k acc ++ ":") (q.pushKind .json |>.pushValue j)
else
go (renderString k acc ++ ":") (q.pushKind .comma |>.pushKind .json |>.pushValue j)
| .objectEnd =>
go (acc ++ "}") q
| .comma =>
go (acc ++ ",") q
instance : ToFormat Json := ⟨render⟩
instance : ToString Json := ⟨pretty⟩

View file

@ -18,6 +18,11 @@ namespace IO.FS.Stream
open Lean
open IO
def readUTF8 (h : FS.Stream) (nBytes : Nat) : IO String := do
let bytes ← h.read (USize.ofNat nBytes)
let some s := String.fromUTF8? bytes | throw (IO.userError "invalid UTF-8")
return s
/-- Consumes `nBytes` bytes from the stream, interprets the bytes as a utf-8 string and the string as a valid JSON object. -/
def readJson (h : FS.Stream) (nBytes : Nat) : IO Json := do
let bytes ← h.read (USize.ofNat nBytes)

View file

@ -296,6 +296,105 @@ instance [FromJson α] : FromJson (Notification α) where
pure $ ⟨method, param⟩
else throw "not a notification"
/--
A variant of `Message` that has been parsed *partially*, without the payload.
This is useful when we want to process the metadata of a `Message` without parsing and converting
the whole thing.
-/
inductive MessageMetaData where
| request (id : RequestID) (method : String)
| notification (method : String)
| response (id : RequestID)
| responseError (id : RequestID) (code : ErrorCode) (message : String) (data? : Option Json)
deriving Inhabited
def MessageMetaData.toMessage : MessageMetaData → Message
| .request id method => .request id method none
| .notification method => .notification method none
| .response id => .response id .null
| .responseError id code message data? => .responseError id code message data?
open Std.Internal.Parsec in
open Std.Internal.Parsec.String in
open Json.Parser in
private def messageMetaDataParser (input : String) : Parser MessageMetaData := do
skip
let k ← parseStr
skip
match k with
| "id" =>
-- Request or response
let id ← parseRequestID
skip
-- Skip `jsonrpc` field
let _ ← parseStr
skip
let _ ← parseStr
skip
let k' ← parseStr
match k' with
| "method" =>
skip
let method ← parseStr
return .request id method
| "result" =>
-- Response
return .response id
| _ =>
fail "expected `method` or `result` field"
| "jsonrpc" =>
-- Notification
-- Skip `jsonrpc` version
let _ ← parseStr
skip
-- Skip `method` field name
let _ ← parseStr
skip
let method ← parseStr
return .notification method
| "error" =>
-- Response error
-- Response errors are usually small, so we just parse them normally.
match Json.parse input with
| .ok parsed =>
match fromJson? parsed with
| .ok (.responseError id code message data? : Message) =>
return .responseError id code message data?
| .ok _ =>
fail "expected response error message kind"
| .error err =>
fail err
| .error err =>
fail err
| _ =>
fail "expected `id`, `jsonrpc` or `error` field"
where
parseStr : Parser String := do
let c ← peek!
if c != '"' then
fail "expected \""
skip
str
parseRequestID : Parser RequestID := do
(do
let num ← Parser.num
return .num num) <|>
(do
let str ← parseStr
return .str str) <|>
(do
skipString "null"
return .null)
/--
Danger: For performance reasons, this function makes a number of fragile assumptions about `input`.
Namely:
- `input` is the output of `(toJson (v : Message)).compress`
- `compress` yields a lexicographic ordering of JSON object keys
-/
def parseMessageMetaData (input : String) : Except String MessageMetaData :=
messageMetaDataParser input |>.run input
end Lean.JsonRpc
namespace IO.FS.Stream

View file

@ -75,6 +75,13 @@ section
catch e =>
throw $ userError s!"Cannot read LSP message: {e}"
def readLspMessageAsString (h : FS.Stream) : IO String := do
try
let nBytes ← readLspHeader h
h.readUTF8 nBytes
catch e =>
throw $ userError s!"Cannot read LSP message: {e}"
def readLspRequestAs (h : FS.Stream) (expectedMethod : String) (α) [FromJson α] : IO (Request α) := do
try
let nBytes ← readLspHeader h
@ -100,14 +107,16 @@ end
section
variable [ToJson α]
def writeLspMessage (h : FS.Stream) (msg : Message) : IO Unit := do
def writeSerializedLspMessage (h : FS.Stream) (msg : String) : IO Unit := do
let header := s!"Content-Length: {toString msg.utf8ByteSize}\r\n\r\n"
-- inlined implementation instead of using jsonrpc's writeMessage
-- to maintain the atomicity of putStr
let j := (toJson msg).compress
let header := s!"Content-Length: {toString j.utf8ByteSize}\r\n\r\n"
h.putStr (header ++ j)
h.putStr (header ++ msg)
h.flush
def writeLspMessage (h : FS.Stream) (msg : Message) : IO Unit := do
h.writeSerializedLspMessage (toJson msg).compress
def writeLspRequest (h : FS.Stream) (r : Request α) : IO Unit :=
h.writeLspMessage r

View file

@ -10,6 +10,7 @@ prelude
public import Lean.Data.Json.FromToJson.Basic
public import Lean.Data.Lsp.Basic
meta import Lean.Data.Json
public import Lean.Expr
public section
@ -59,6 +60,10 @@ instance : FromJson CompletionItemTag where
return CompletionItemTag.ofNat (i-1)
structure CompletionItem where
-- When adjusting this type, make sure to adjust `ResolvableCompletionList.compressFast`
-- as well, which is our `(toJson l).compress` fast path.
-- (Completion downstream of Mathlib can output gigantic JSON,
-- so we want to avoid all redundant allocs)
label : String
detail? : Option String := none
documentation? : Option MarkupContent := none
@ -85,6 +90,112 @@ structure CompletionList where
items : Array CompletionItem
deriving FromJson, ToJson
/--
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 : Lean.FVarId)
deriving BEq, Hashable
instance : ToJson CompletionIdentifier where
toJson
| .const declName =>
.str s!"c{toString declName}"
| .fvar id =>
.str s!"f{toString id.name}"
instance : FromJson CompletionIdentifier where
fromJson?
| .str s =>
let c := s.get 0
if c == 'c' then
let declName := s.extract ⟨1⟩ s.endPos |>.toName
.ok <| .const declName
else if c == 'f' then
let id := ⟨s.extract ⟨1⟩ s.endPos |>.toName⟩
.ok <| .fvar id
else
.error "Expected string with prefix `c` or `f` in `FromJson` instance of `CompletionIdentifier`."
| _ => .error "Expected string in `FromJson` instance of `CompletionIdentifier`."
structure ResolvableCompletionItemData where
mod : Name
pos : Position
/-- Position of the completion info that this completion item was created from. -/
cPos? : Option Nat := none
id? : Option CompletionIdentifier := none
deriving BEq, Hashable
instance : ToJson ResolvableCompletionItemData where
toJson d := Id.run do
let mut arr : Array Json := #[
toJson d.mod,
d.pos.line,
d.pos.character,
]
if let some cPos := d.cPos? then
arr := arr.push <| toJson cPos
if let some id := d.id? then
arr := arr.push <| toJson id
Json.arr arr
instance : FromJson ResolvableCompletionItemData where
fromJson?
| .arr elems => do
if elems.size < 3 then
.error "Expected array of size 3 in `FromJson` instance of `ResolvableCompletionItemData"
let mod : Name ← fromJson? elems[0]!
let line : Nat ← fromJson? elems[1]!
let character : Nat ← fromJson? elems[2]!
let mut cPos? : Option Nat := none
let mut id? : Option CompletionIdentifier := none
if let .ok (some cPos) := elems[3]?.mapM fromJson? then
cPos? := some cPos
if let .ok (some id) := elems[3]?.mapM fromJson? then
id? := some id
if let .ok (some cPos) := elems[4]?.mapM fromJson? then
cPos? := some cPos
if let .ok (some id) := elems[4]?.mapM fromJson? then
id? := some id
let pos := { line, character }
return {
mod
pos
cPos?
id?
}
| _ => .error "Expected array in `FromJson` instance of `ResolvableCompletionItemData`"
structure ResolvableCompletionItem where
label : String
detail? : Option String := none
documentation? : Option MarkupContent := none
kind? : Option CompletionItemKind := none
textEdit? : Option InsertReplaceEdit := none
sortText? : Option String := none
data? : Option ResolvableCompletionItemData := none
tags? : Option (Array CompletionItemTag) := none
/-
deprecated? : boolean
preselect? : boolean
filterText? : string
insertText? : string
insertTextFormat? : InsertTextFormat
insertTextMode? : InsertTextMode
additionalTextEdits? : TextEdit[]
commitCharacters? : string[]
command? : Command
-/
deriving FromJson, ToJson, Inhabited, BEq, Hashable
structure ResolvableCompletionList where
isIncomplete : Bool
items : Array ResolvableCompletionItem
deriving FromJson, ToJson
structure CompletionParams extends TextDocumentPositionParams where
-- context? : CompletionContext
deriving FromJson, ToJson

View file

@ -37,12 +37,12 @@ structure CodeActionResolveData where
providerResultIndex : Nat
deriving ToJson, FromJson
def CodeAction.getFileSource! (ca : CodeAction) : DocumentUri :=
let r : Except String DocumentUri := do
def CodeAction.getFileSource! (ca : CodeAction) : FileIdent :=
let r : Except String FileIdent := do
let some data := ca.data?
| throw s!"no data param on code action {ca.title}"
let data : CodeActionResolveData ← fromJson? data
return data.params.textDocument.uri
return .uri data.params.textDocument.uri
match r with
| Except.ok uri => uri
| Except.error e => panic! e

View file

@ -17,27 +17,27 @@ open Lsp
open Elab
private def filterDuplicateCompletionItems
(items : Array CompletionItem)
: Array CompletionItem :=
let duplicationGroups := items.groupByKey fun i => (
i.label,
i.textEdit?,
i.detail?,
i.kind?,
i.tags?,
i.documentation?,
)
duplicationGroups.map (fun _ duplicateItems => duplicateItems[0]!)
|>.valuesArray
(items : Array ResolvableCompletionItem)
: Array ResolvableCompletionItem := Id.run do
let mut r : Array ResolvableCompletionItem := #[]
let mut index : Std.HashSet (String × Option InsertReplaceEdit) := ∅
for i in items do
let key := (i.label, i.textEdit?)
let (isDup, index') := index.containsThenInsert key
index := index'
if ! isDup then
r := r.push i
return r
partial def find?
(params : CompletionParams)
(mod : Name)
(pos : Lsp.Position)
(fileMap : FileMap)
(hoverPos : String.Pos)
(cmdStx : Syntax)
(infoTree : InfoTree)
(caps : ClientCapabilities)
: CancellableM CompletionList := do
: CancellableM ResolvableCompletionList := do
let (prioritizedPartitions, isComplete) := findPrioritizedCompletionPartitionsAt fileMap hoverPos cmdStx infoTree
let mut allCompletions := #[]
for partition in prioritizedPartitions do
@ -46,19 +46,19 @@ partial def find?
let completions : Array ScoredCompletionItem ←
match i.info with
| .id stx id danglingDot lctx .. =>
idCompletion params completionInfoPos i.ctx lctx stx id i.hoverInfo danglingDot
idCompletion mod pos completionInfoPos i.ctx lctx stx id i.hoverInfo danglingDot
| .dot info .. =>
dotCompletion params completionInfoPos i.ctx info
dotCompletion mod pos completionInfoPos i.ctx info
| .dotId _ id lctx expectedType? =>
dotIdCompletion params completionInfoPos i.ctx lctx id expectedType?
dotIdCompletion mod pos completionInfoPos i.ctx lctx id expectedType?
| .fieldId _ id lctx structName =>
fieldIdCompletion params completionInfoPos i.ctx lctx id structName
fieldIdCompletion mod pos completionInfoPos i.ctx lctx id structName
| .option stx =>
optionCompletion params completionInfoPos i.ctx stx caps
optionCompletion mod pos completionInfoPos i.ctx stx caps
| .errorName _ partialId =>
errorNameCompletion params completionInfoPos i.ctx partialId caps
errorNameCompletion mod pos completionInfoPos i.ctx partialId caps
| .tactic .. =>
tacticCompletion params completionInfoPos i.ctx
tacticCompletion mod pos completionInfoPos i.ctx
| _ =>
pure #[]
allCompletions := allCompletions ++ completions

View file

@ -24,14 +24,15 @@ open FuzzyMatching
section Infrastructure
private structure Context where
params : CompletionParams
mod : Name
pos : Lsp.Position
completionInfoPos : Nat
/-- Intermediate state while completions are being computed. -/
private structure State where
/-- All completion items and their fuzzy match scores so far. -/
items : Array CompletionItem := #[]
items : Array ResolvableCompletionItem := #[]
/--
Monad used for completion computation that allows modifying a completion `State` and reading
@ -46,12 +47,13 @@ section Infrastructure
: M Unit := do
let ctx ← read
let data := {
params := ctx.params,
cPos := ctx.completionInfoPos,
mod := ctx.mod,
pos := ctx.pos,
cPos? := ctx.completionInfoPos,
id?
: ResolvableCompletionItemData
}
let item := { item with data? := toJson data }
let item := { item with data? := data }
modify fun s => { s with items := s.items.push item }
/--
@ -62,42 +64,16 @@ section Infrastructure
(label : Name)
(id : CompletionIdentifier)
(kind : CompletionItemKind)
(tags : Array CompletionItemTag)
: M Unit := do
let env ← getEnv
let tags? := do
let .const declName := id
| none
guard <| Linter.isDeprecated env declName
some #[CompletionItemTag.deprecated]
let item := { label := label.toString, kind? := kind, tags? }
let item := { label := label.toString, kind? := kind, tags? := tags }
addItem item id
private def getCompletionKindForDecl (constInfo : ConstantInfo) : M CompletionItemKind := do
let env ← getEnv
if constInfo.isCtor then
return CompletionItemKind.constructor
else if constInfo.isInductive then
if isClass env constInfo.name then
return CompletionItemKind.class
else if (← isEnumType constInfo.name) then
return CompletionItemKind.enum
else
return CompletionItemKind.struct
else if wasOriginallyTheorem env constInfo.name then
return CompletionItemKind.event
else if (← isProjectionFn constInfo.name) then
return CompletionItemKind.field
else
let isFunction : Bool ← withTheReader Core.Context ({ · with maxHeartbeats := 0 }) do
return (← whnf constInfo.type).isForall
if isFunction then
return CompletionItemKind.function
else
return CompletionItemKind.constant
private def addUnresolvedCompletionItemForDecl (label : Name) (declName : Name) : M Unit := do
if let some c := (← getEnv).find? declName then
addUnresolvedCompletionItem label (.const declName) (← getCompletionKindForDecl c)
addUnresolvedCompletionItem label (.const declName)
(← getCompletionKindForDecl c)
(← getCompletionTagsForDecl declName)
private def addKeywordCompletionItem (keyword : String) : M Unit := do
let item := { label := keyword, detail? := "keyword", documentation? := none, kind? := CompletionItemKind.keyword }
@ -108,15 +84,16 @@ section Infrastructure
addItem item
private def runM
(params : CompletionParams)
(mod : Name)
(pos : Lsp.Position)
(completionInfoPos : Nat)
(ctx : ContextInfo)
(lctx : LocalContext)
(x : M Unit)
: CancellableM (Array CompletionItem) := do
: CancellableM (Array ResolvableCompletionItem) := do
let tk ← read
let r ← ctx.runMetaM lctx do
x.run ⟨params, completionInfoPos⟩ |>.run {} |>.run tk
x.run ⟨mod, pos, completionInfoPos⟩ |>.run {} |>.run tk
match r with
| .error _ => throw .requestCancelled
| .ok (_, s) => return s.items
@ -169,9 +146,8 @@ section Utils
return none
return none
private def forEligibleDeclsWithCancellationM [Monad m] [MonadEnv m]
[MonadLiftT (ST IO.RealWorld) m] [MonadCancellable m] [MonadLiftT IO m]
(f : Name → ConstantInfo → m PUnit) : m PUnit := do
private def forEligibleDeclsWithCancellationM [Monad m] [MonadEnv m] [MonadLiftT MetaM m]
[MonadCancellable m] (f : Name → EligibleDecl → m PUnit) : m PUnit := do
let _ ← StateT.run (s := 0) <| forEligibleDeclsM fun decl ci => do
modify (· + 1)
if (← get) >= 10000 then
@ -372,13 +348,14 @@ private def idCompletionCore
-- search for matches in the local context
for localDecl in (← getLCtx) do
if matchAtomic id localDecl.userName danglingDot then
addUnresolvedCompletionItem localDecl.userName (.fvar localDecl.fvarId) (kind := CompletionItemKind.variable)
addUnresolvedCompletionItem localDecl.userName (.fvar localDecl.fvarId)
(kind := CompletionItemKind.variable) (tags := #[])
-- search for matches in the environment
let env ← getEnv
forEligibleDeclsWithCancellationM fun declName c => do
forEligibleDeclsWithCancellationM fun declName decl => do
let bestMatch? ← bestLabelForDecl? ctx declName id danglingDot
if let some bestLabel := bestMatch? then
addUnresolvedCompletionItem bestLabel (.const declName) (← getCompletionKindForDecl c)
addUnresolvedCompletionItem bestLabel (.const declName) (← decl.kind) (← decl.tags)
RequestCancellation.check
let matchAlias (ns : Name) (alias : Name) : Bool :=
-- Recall that aliases may not be atomic and include the namespace where they were created.
@ -425,7 +402,8 @@ private def idCompletionCore
completeNamespaces ctx id danglingDot
def idCompletion
(params : CompletionParams)
(mod : Name)
(pos : Lsp.Position)
(completionInfoPos : Nat)
(ctx : ContextInfo)
(lctx : LocalContext)
@ -433,17 +411,18 @@ def idCompletion
(id : Name)
(hoverInfo : HoverInfo)
(danglingDot : Bool)
: CancellableM (Array CompletionItem) :=
runM params completionInfoPos ctx lctx do
: CancellableM (Array ResolvableCompletionItem) :=
runM mod pos completionInfoPos ctx lctx do
idCompletionCore ctx stx id hoverInfo danglingDot
def dotCompletion
(params : CompletionParams)
(mod : Name)
(pos : Lsp.Position)
(completionInfoPos : Nat)
(ctx : ContextInfo)
(info : TermInfo)
: CancellableM (Array CompletionItem) :=
runM params completionInfoPos ctx info.lctx do
: CancellableM (Array ResolvableCompletionItem) :=
runM mod pos completionInfoPos ctx info.lctx do
let nameSet ← try
getDotCompletionTypeNameSet (← instantiateMVars (← inferType info.expr))
catch _ =>
@ -451,27 +430,29 @@ def dotCompletion
if nameSet.isEmpty then
return
forEligibleDeclsWithCancellationM fun declName c => do
forEligibleDeclsWithCancellationM fun declName decl => do
let unnormedTypeName := declName.getPrefix
if ! nameSet.contains unnormedTypeName then
return
let some declName ← normPrivateName? declName
| return
let c := decl.info
let typeName := declName.getPrefix
if ! (← isDotCompletionMethod typeName c) then
return
let completionKind ← getCompletionKindForDecl c
addUnresolvedCompletionItem (.mkSimple c.name.getString!) (.const c.name) (kind := completionKind)
addUnresolvedCompletionItem (.mkSimple c.name.getString!) (.const c.name)
(← decl.kind) (← decl.tags)
def dotIdCompletion
(params : CompletionParams)
(mod : Name)
(pos : Lsp.Position)
(completionInfoPos : Nat)
(ctx : ContextInfo)
(lctx : LocalContext)
(id : Name)
(expectedType? : Option Expr)
: CancellableM (Array CompletionItem) :=
runM params completionInfoPos ctx lctx do
: CancellableM (Array ResolvableCompletionItem) :=
runM mod pos completionInfoPos ctx lctx do
let some expectedType := expectedType?
| return ()
@ -481,7 +462,7 @@ def dotIdCompletion
let nameSet := NameSetModPrivate.ofArray typeNames
forEligibleDeclsWithCancellationM fun declName c => do
forEligibleDeclsWithCancellationM fun declName decl => do
let unnormedTypeName := declName.getPrefix
if ! nameSet.contains unnormedTypeName then
return
@ -489,27 +470,30 @@ def dotIdCompletion
let some declName ← normPrivateName? declName
| return
let c := decl.info
if ! (← isDotIdCompletionMethod nameSet c) then
return
let completionKind ← getCompletionKindForDecl c
let kind ← decl.kind
let tags ← decl.tags
if id.isAnonymous then
-- We're completing a lone dot => offer all decls of the type
addUnresolvedCompletionItem (.mkSimple c.name.getString!) (.const c.name) completionKind
addUnresolvedCompletionItem (.mkSimple c.name.getString!) (.const c.name) kind tags
return
let some label ← matchDecl? declName.getPrefix id (danglingDot := false) declName | pure ()
addUnresolvedCompletionItem label (.const c.name) completionKind
addUnresolvedCompletionItem label (.const c.name) kind tags
def fieldIdCompletion
(params : CompletionParams)
(mod : Name)
(pos : Lsp.Position)
(completionInfoPos : Nat)
(ctx : ContextInfo)
(lctx : LocalContext)
(id : Option Name)
(structName : Name)
: CancellableM (Array CompletionItem) :=
runM params completionInfoPos ctx lctx do
: CancellableM (Array ResolvableCompletionItem) :=
runM mod pos completionInfoPos ctx lctx do
let idStr := id.map (·.toString) |>.getD ""
let fieldNames := getStructureFieldsFlattened (← getEnv) structName (includeSubobjectFields := false)
for fieldName in fieldNames do
@ -526,8 +510,8 @@ affect the set of eligible completion candidates.
-/
private def trailingDotCompletion [ForIn Id Coll (Name × α)]
(entries : Coll) (stx : Syntax) (caps : ClientCapabilities) (ctx : ContextInfo)
(mkItem : Name → α → Option InsertReplaceEdit → CompletionItem) :
Array CompletionItem := Id.run do
(mkItem : Name → α → Option InsertReplaceEdit → ResolvableCompletionItem) :
Array ResolvableCompletionItem := Id.run do
let (partialName, trailingDot) :=
match stx.getSubstring? (withLeading := false) (withTrailing := false) with
| none => ("", false) -- the `ident` is `missing`, list all options
@ -553,12 +537,13 @@ private def trailingDotCompletion [ForIn Id Coll (Name × α)]
return items
def optionCompletion
(params : CompletionParams)
(mod : Name)
(pos : Lsp.Position)
(completionInfoPos : Nat)
(ctx : ContextInfo)
(stx : Syntax)
(caps : ClientCapabilities)
: IO (Array CompletionItem) :=
: IO (Array ResolvableCompletionItem) :=
ctx.runMetaM {} do
-- HACK(WN): unfold the type so ForIn works
let (decls : Std.TreeMap _ _ _) ← getOptionDecls
@ -570,20 +555,22 @@ def optionCompletion
documentation? := none,
kind? := CompletionItemKind.property -- TODO: investigate whether this is the best kind for options.
textEdit?
data? := toJson {
params
cPos := completionInfoPos
data? := {
mod
pos
cPos? := completionInfoPos
id? := none : ResolvableCompletionItemData
}
}
def errorNameCompletion
(params : CompletionParams)
(mod : Name)
(pos : Lsp.Position)
(completionInfoPos : Nat)
(ctx : ContextInfo)
(partialId : Syntax)
(caps : ClientCapabilities)
: IO (Array CompletionItem) :=
: IO (Array ResolvableCompletionItem) :=
ctx.runMetaM {} do
let explanations := getErrorExplanationsRaw (← getEnv)
return trailingDotCompletion explanations partialId caps ctx fun name explan textEdit? => {
@ -597,26 +584,28 @@ def errorNameCompletion
kind? := CompletionItemKind.property
textEdit?
tags? := explan.metadata.removedVersion?.map fun _ => #[CompletionItemTag.deprecated]
data? := toJson {
params
cPos := completionInfoPos
data? := {
mod
pos
cPos? := completionInfoPos
id? := none : ResolvableCompletionItemData
}
}
def tacticCompletion
(params : CompletionParams)
(mod : Name)
(pos : Lsp.Position)
(completionInfoPos : Nat)
(ctx : ContextInfo)
: IO (Array CompletionItem) := ctx.runMetaM .empty do
: IO (Array ResolvableCompletionItem) := ctx.runMetaM .empty do
let allTacticDocs ← Tactic.Doc.allTacticDocs
let items : Array CompletionItem := allTacticDocs.map fun tacticDoc => {
let items : Array ResolvableCompletionItem := allTacticDocs.map fun tacticDoc => {
label := tacticDoc.userName
detail? := none
documentation? := tacticDoc.docString.map fun docString =>
{ value := docString, kind := MarkupKind.markdown : MarkupContent }
kind? := CompletionItemKind.keyword
data? := toJson { params, cPos := completionInfoPos, id? := none : ResolvableCompletionItemData }
data? := { mod, pos, cPos? := completionInfoPos, id? := none : ResolvableCompletionItemData }
}
return items

View file

@ -0,0 +1,128 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Marc Huisinga
-/
module
prelude
public import Lean.Data.Lsp.LanguageFeatures
namespace Lean.Lsp.ResolvableCompletionList
@[inline]
def compressItemDataFast (acc : String) (data : ResolvableCompletionItemData) :
String := Id.run do
let mut acc := acc ++ "["
acc := Json.renderString data.mod.toString acc
acc := acc ++ "," ++ data.pos.line.repr
acc := acc ++ "," ++ data.pos.character.repr
if let some cPos := data.cPos? then
acc := acc ++ "," ++ cPos.repr
if let some id := data.id? then
acc := acc ++ ","
match id with
| .const declName =>
acc := acc ++ "\"c"
acc := Json.escape declName.toString acc ++ "\""
| .fvar id =>
acc := acc ++ "\"f"
acc := Json.escape id.name.toString acc ++ "\""
acc ++ "]"
@[inline]
def compressMarkupContentFast (acc : String) (c : MarkupContent) : String :=
let kind := match c.kind with
| .plaintext => "plaintext"
| .markdown => "markdown"
let acc := acc ++ "{\"kind\":\"" ++ kind ++ "\",\"value\":"
let acc := Json.renderString c.value acc
acc ++ "}"
@[inline]
def compressPositionFast (acc : String) (p : Position) : String :=
acc ++ "{\"character\":" ++ p.character.repr ++ ",\"line\":" ++ p.line.repr ++ "}"
@[inline]
def compressRangeFast (acc : String) (range : Range) : String :=
let acc := acc ++ "{\"end\":"
let acc := compressPositionFast acc range.end
let acc := acc ++ ",\"start\":"
let acc := compressPositionFast acc range.start
acc ++ "}"
@[inline]
def compressEditFast (acc : String) (edit : InsertReplaceEdit) : String :=
let acc := acc ++ "{\"insert\":"
let acc := compressRangeFast acc edit.insert
let acc := acc ++ ",\"newText\":\"" ++ edit.newText ++ "\""
let acc := acc ++ ",\"replace\":"
let acc := compressRangeFast acc edit.replace
acc ++ "}"
def compressCompletionTagsFast (acc : String) (tags : Array CompletionItemTag) (i : Nat) :
String :=
if h : i < tags.size then
let acc := acc ++ (tags[i].ctorIdx + 1).repr
let acc :=
if i < tags.size - 1 then
acc ++ ","
else
acc
compressCompletionTagsFast acc tags (i + 1)
else
acc
@[inline]
def compressItemFast (acc : String) (item : ResolvableCompletionItem) : String := Id.run do
let mut acc := acc ++ "{\"label\":"
acc := Json.renderString item.label acc
if let some detail := item.detail? then
acc := acc ++ ",\"detail\":"
acc := Json.renderString detail acc
if let some documentation := item.documentation? then
acc := acc ++ ",\"documentation\":"
acc := compressMarkupContentFast acc documentation
if let some kind := item.kind? then
acc := acc ++ ",\"kind\":" ++ (kind.ctorIdx + 1).repr
if let some textEdit := item.textEdit? then
acc := acc ++ ",\"edit\":"
acc := compressEditFast acc textEdit
if let some sortText := item.sortText? then
acc := acc ++ ",\"sortText\":"
acc := Json.renderString sortText acc
if let some data := item.data? then
acc := acc ++ ",\"data\":"
acc := compressItemDataFast acc data
if let some tags := item.tags? then
if h : tags.size > 0 then
acc := acc ++ ",\"tags\":["
if tags.size == 1 then
acc := acc ++ (tags[0].ctorIdx + 1).repr
else
acc := compressCompletionTagsFast acc tags 0
acc := acc ++ "]"
return acc ++ "}"
def compressItemsFast
(acc : String) (items : Array ResolvableCompletionItem) (i : Nat) :
String :=
if h : i < items.size then
let acc := compressItemFast acc items[i]
let acc :=
if i < items.size - 1 then
acc ++ ","
else
acc
compressItemsFast acc items (i + 1)
else
acc
/--
Fast path for `(toJson l).compress` that skips the intermediate `Json` object.
Used in place of `(toJson l).compress` in the language server.
-/
public def compressFast (l : ResolvableCompletionList) : String :=
let acc := "{\"isIncomplete\":" ++ toString l.isIncomplete ++ ",\"items\":["
let acc := compressItemsFast acc l.items 0
acc ++ "]}"

View file

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

View file

@ -6,7 +6,7 @@ Authors: Leonardo de Moura, Marc Huisinga
module
prelude
public import Lean.Server.Completion.CompletionItemData
public import Lean.Data.Lsp
public import Lean.Server.Completion.CompletionInfoSelection
public import Lean.Linter.Deprecated
@ -14,26 +14,6 @@ public section
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 contains additional information to identify the item
in order to resolve it.
-/
structure ResolvableCompletionItemData extends CompletionItemData where
/-- Position of the completion info that this completion item was created from. -/
cPos : Nat
id? : Option CompletionIdentifier
deriving FromJson, ToJson
private partial def consumeImplicitPrefix (e : Expr) (k : Expr → MetaM α) : MetaM α := do
match e with
| Expr.forallE n d b c =>

View file

@ -7,46 +7,95 @@ module
prelude
public import Lean.Meta.CompletionName
public import Lean.Data.Lsp.LanguageFeatures
public import Lean.AddDecl
public import Lean.ProjFns
public import Std.Sync.Mutex
import Lean.Linter.Deprecated
public section
namespace Lean.Server.Completion
open Meta
abbrev EligibleHeaderDecls := Std.HashMap Name ConstantInfo
structure EligibleDecl where
info : ConstantInfo
kind : MetaM Lsp.CompletionItemKind
tags : MetaM (Array Lsp.CompletionItemTag)
abbrev EligibleHeaderDecls := Std.HashMap Name EligibleDecl
/-- Cached header declarations for which `allowCompletion headerEnv decl` is true. -/
builtin_initialize eligibleHeaderDeclsRef : IO.Ref (Option EligibleHeaderDecls) ←
IO.mkRef none
builtin_initialize eligibleHeaderDeclsMutex : Std.Mutex (Option EligibleHeaderDecls) ←
Std.Mutex.new none
def getCompletionKindForDecl (constInfo : ConstantInfo)
: MetaM Lsp.CompletionItemKind := do
let env ← getEnv
if constInfo.isCtor then
return .constructor
else if constInfo.isInductive then
if isClass env constInfo.name then
return .class
else if (← isEnumType constInfo.name) then
return .enum
else
return .struct
else if wasOriginallyTheorem env constInfo.name then
return .event
else if (← isProjectionFn constInfo.name) then
return .field
else
let isFunction : Bool ← withTheReader Core.Context ({ · with maxHeartbeats := 0 }) do
return (← whnf constInfo.type).isForall
if isFunction then
return .function
else
return .constant
def getCompletionTagsForDecl (declName : Name) : MetaM (Array Lsp.CompletionItemTag) := do
if Linter.isDeprecated (← getEnv) declName then
return #[.deprecated]
else
return #[]
/--
Returns the declarations in the header for which `allowCompletion env decl` is true, caching them
if not already cached.
-/
def getEligibleHeaderDecls (env : Environment) : IO EligibleHeaderDecls := do
eligibleHeaderDeclsRef.modifyGet fun
| some eligibleHeaderDecls => (eligibleHeaderDecls, some eligibleHeaderDecls)
def getEligibleHeaderDecls (env : Environment) : MetaM EligibleHeaderDecls := do
eligibleHeaderDeclsMutex.atomically do
match ← get with
| some eligibleHeaderDecls =>
return eligibleHeaderDecls
| none =>
let (_, eligibleHeaderDecls) := Id.run <|
StateT.run (s := {}) do
-- `map₁` are the header decls
env.constants.map₁.forM fun declName c => do
modify fun eligibleHeaderDecls =>
if allowCompletion env declName then
eligibleHeaderDecls.insert declName c
else
eligibleHeaderDecls
(eligibleHeaderDecls, some eligibleHeaderDecls)
let mut eligibleHeaderDecls : EligibleHeaderDecls := {}
-- map₁ are the header decls
for (declName, c) in env.constants.map₁ do
if allowCompletion env declName then
let kind ← getCompletionKindForDecl c
let tags ← getCompletionTagsForDecl declName
eligibleHeaderDecls := eligibleHeaderDecls.insert declName {
info := c
kind := pure kind
tags := pure tags
}
set <| some eligibleHeaderDecls
return eligibleHeaderDecls
/-- Iterate over all declarations that are allowed in completion results. -/
def forEligibleDeclsM [Monad m] [MonadEnv m] [MonadLiftT (ST IO.RealWorld) m]
[MonadLiftT IO m] (f : Name → ConstantInfo → m PUnit) : m PUnit := do
def forEligibleDeclsM [Monad m] [MonadEnv m] [MonadLiftT MetaM m]
(f : Name → EligibleDecl → m PUnit) : m PUnit := do
let env ← getEnv
(← getEligibleHeaderDecls env).forM f
-- map₂ are exactly the local decls
env.constants.map₂.forM fun name c => do
if allowCompletion env name then
f name c
f name {
info := c
-- Lazily compute the kind and the tags when needed.
kind := getCompletionKindForDecl c
tags := getCompletionTagsForDecl name
}
/-- Checks whether this declaration can appear in completion results. -/
def allowCompletion (eligibleHeaderDecls : EligibleHeaderDecls) (env : Environment)

View file

@ -8,14 +8,12 @@ module
prelude
public import Lean.Data.NameTrie
public import Lean.Util.LakePath
public import Lean.Server.Completion.CompletionItemData
public import Lean.Data.Lsp
public import Lean.Parser.Module
meta import Lean.Parser.Module
public section
public section
namespace ImportCompletion
open Lean Lsp
@ -130,30 +128,30 @@ Sets the `data?` field of every `CompletionItem` in `completionList` using `para
`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)
def addCompletionItemData (mod : Name) (pos : Lsp.Position) (completionList : CompletionList)
: CompletionList :=
let data := { params : Lean.Lsp.CompletionItemData }
let data := { mod, pos : Lean.Lsp.ResolvableCompletionItemData }
{ completionList with items := completionList.items.map fun item =>
{ item with data? := some <| toJson data } }
def find (text : FileMap) (headerStx : TSyntax ``Parser.Module.header) (params : CompletionParams) (availableImports : AvailableImports) : CompletionList :=
def find (mod : Name) (pos : Lsp.Position) (text : FileMap) (headerStx : TSyntax ``Parser.Module.header) (availableImports : AvailableImports) : CompletionList :=
let availableImports := availableImports.toImportTrie
let completionPos := text.lspPosToUtf8Pos params.position
let completionPos := text.lspPosToUtf8Pos pos
if isImportNameCompletionRequest headerStx completionPos then
let allAvailableImportNameCompletions := availableImports.toArray.map ({ label := toString · })
addCompletionItemData { isIncomplete := false, items := allAvailableImportNameCompletions } params
addCompletionItemData mod pos { isIncomplete := false, items := allAvailableImportNameCompletions }
else if isImportCmdCompletionRequest headerStx completionPos then
let allAvailableFullImportCompletions := availableImports.toArray.map ({ label := s!"import {·}" })
addCompletionItemData { isIncomplete := false, items := allAvailableFullImportCompletions } params
addCompletionItemData mod pos { isIncomplete := false, items := allAvailableFullImportCompletions }
else
let completionNames : Array Name := computePartialImportCompletions headerStx completionPos availableImports
let completions : Array CompletionItem := completionNames.map ({ label := toString · })
addCompletionItemData { isIncomplete := false, items := completions } params
addCompletionItemData mod pos { isIncomplete := false, items := completions }
def computeCompletions (text : FileMap) (headerStx : TSyntax ``Parser.Module.header) (params : CompletionParams)
def computeCompletions (mod : Name) (pos : Lsp.Position) (text : FileMap) (headerStx : TSyntax ``Parser.Module.header)
: IO CompletionList := do
let availableImports ← collectAvailableImports
let completionList := find text headerStx params availableImports
return addCompletionItemData completionList params
let completionList := find mod pos text headerStx availableImports
return addCompletionItemData mod pos completionList
end ImportCompletion

View file

@ -13,24 +13,34 @@ public section
namespace Lean.Lsp
inductive FileIdent where
| uri (uri : DocumentUri)
| mod (mod : Name)
deriving Inhabited
instance : ToString FileIdent where
toString
| .uri uri => toString uri
| .mod mod => toString mod
class FileSource (α : Type) where
fileSource : α → DocumentUri
fileSource : αFileIdent
export FileSource (fileSource)
instance : FileSource Location :=
⟨fun l => l.uri⟩
⟨fun l => .uri l.uri⟩
instance : FileSource TextDocumentIdentifier :=
⟨fun i => i.uri⟩
⟨fun i => .uri i.uri⟩
instance : FileSource VersionedTextDocumentIdentifier :=
⟨fun i => i.uri⟩
⟨fun i => .uri i.uri⟩
instance : FileSource TextDocumentEdit :=
⟨fun e => fileSource e.textDocument⟩
instance : FileSource TextDocumentItem :=
⟨fun i => i.uri⟩
⟨fun i => .uri i.uri⟩
instance : FileSource TextDocumentPositionParams :=
⟨fun p => fileSource p.textDocument⟩
@ -66,7 +76,7 @@ instance : FileSource ReferenceParams :=
⟨fun h => fileSource h.toTextDocumentPositionParams⟩
instance : FileSource WaitForDiagnosticsParams :=
⟨fun p => p.uri⟩
⟨fun p => .uri p.uri⟩
instance : FileSource DocumentHighlightParams :=
⟨fun h => fileSource h.toTextDocumentPositionParams⟩
@ -90,16 +100,16 @@ instance : FileSource PlainTermGoalParams where
fileSource p := fileSource p.textDocument
instance : FileSource RpcConnectParams where
fileSource p := p.uri
fileSource p := .uri p.uri
instance : FileSource RpcCallParams where
fileSource p := fileSource p.textDocument
instance : FileSource RpcReleaseParams where
fileSource p := p.uri
fileSource p := .uri p.uri
instance : FileSource RpcKeepAliveParams where
fileSource p := p.uri
fileSource p := .uri p.uri
instance : FileSource CodeActionParams where
fileSource p := fileSource p.textDocument
@ -110,4 +120,37 @@ instance : FileSource InlayHintParams where
instance : FileSource SignatureHelpParams where
fileSource p := fileSource p.textDocument
/--
Yields the file source of `item` by attempting to obtain `mod : Name` from `item.data?`. \
Panics if `item.data?` is not present or does not contain a `mod` field and the first element of a
`data?` array cannot be parsed to `Name`.
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 has a `mod` field.
-/
def CompletionItem.getFileSource! (item : CompletionItem) : FileIdent :=
let r : Except String FileIdent := do
let some data := item.data?
| throw s!"no data param on completion item {item.label}"
match data with
| .obj _ =>
-- In the language server, `data` is always an array,
-- but we also support having `mod` as an object field for
-- `chainLspRequestHandler` consumers.
let mod ← data.getObjValAs? Name "mod"
return .mod mod
| .arr _ =>
let mod ← fromJson? <| ← data.getArrVal? 0
return .mod mod
| _ =>
throw s!"unexpected completion item data: {data}"
match r with
| Except.ok id => id
| Except.error e => panic! e
instance : FileSource CompletionItem where
fileSource := CompletionItem.getFileSource!
end Lean.Lsp

View file

@ -72,12 +72,25 @@ structure PartialHandlerInfo where
pendingRefreshInfo? : Option RefreshInfo
deriving Inhabited
structure OutputMessage where
msg? : Option JsonRpc.Message
serialized : String
deriving Inhabited
def OutputMessage.ofLspResponse (id : RequestID) (r : SerializedLspResponse) : OutputMessage where
msg? := r.response?.map (.response id ·)
serialized := r.toSerializedMessage id
def OutputMessage.ofMsg (msg : JsonRpc.Message) : OutputMessage where
msg? := msg
serialized := toJson msg |>.compress
open Widget in
structure WorkerContext where
/-- Synchronized output channel for LSP messages. Notifications for outdated versions are
discarded on read. -/
chanOut : Std.Channel JsonRpc.Message
chanOut : Std.Channel OutputMessage
/--
Latest document version received by the client, used for filtering out notifications from
previous versions.
@ -213,7 +226,7 @@ This option can only be set on the command line, not in the lakefile or via `set
stickyInteractiveDiagnostics ++ docInteractiveDiagnostics
|>.map (·.toDiagnostic)
let notification := mkPublishDiagnosticsNotification doc.meta diagnostics
ctx.chanOut.sync.send notification
ctx.chanOut.sync.send <| .ofMsg notification
open Language in
/--
@ -238,14 +251,14 @@ This option can only be set on the command line, not in the lakefile or via `set
return ()
-- callback at the end of reporting
if st.hasFatal then
ctx.chanOut.send <| mkFileProgressAtPosNotification doc.meta 0 .fatalError
ctx.chanOut.send <| .ofMsg <| mkFileProgressAtPosNotification doc.meta 0 .fatalError
else
ctx.chanOut.send <| mkFileProgressDoneNotification doc.meta
ctx.chanOut.send <| .ofMsg <| mkFileProgressDoneNotification doc.meta
unless st.hasBlocked do -- "Debouncing 4."
publishDiagnostics ctx doc
-- This will overwrite existing ilean info for the file, in case something
-- went wrong during the incremental updates.
ctx.chanOut.sync.send (← mkIleanInfoFinalNotification doc.meta st.allInfoTrees)
ctx.chanOut.sync.send <| .ofMsg <| ← mkIleanInfoFinalNotification doc.meta st.allInfoTrees
return ()
where
/--
@ -322,7 +335,7 @@ This option can only be set on the command line, not in the lakefile or via `set
if let some itree := node.element.infoTree? then
let mut newInfoTrees := (← get).newInfoTrees.push itree
if (← get).hasBlocked then
ctx.chanOut.sync.send (← mkIleanInfoUpdateNotification doc.meta newInfoTrees)
ctx.chanOut.sync.send <| .ofMsg <| ← mkIleanInfoUpdateNotification doc.meta newInfoTrees
newInfoTrees := #[]
modify fun st => { st with newInfoTrees, allInfoTrees := st.allInfoTrees.push itree }
@ -341,7 +354,7 @@ This option can only be set on the command line, not in the lakefile or via `set
| none => rs.push r
let ranges := ranges.map (·.toLspRange doc.meta.text)
let notifs := ranges.map ({ range := ·, kind := .processing })
ctx.chanOut.sync.send <| mkFileProgressNotification doc.meta notifs
ctx.chanOut.sync.send <| .ofMsg <| mkFileProgressNotification doc.meta notifs
end Elab
@ -379,7 +392,7 @@ Lake for processing imports.
def setupImports
(doc : DocumentMeta)
(cmdlineOpts : Options)
(chanOut : Std.Channel JsonRpc.Message)
(chanOut : Std.Channel OutputMessage)
(stx : Elab.HeaderSyntax)
: Language.ProcessingT IO (Except Language.Lean.HeaderProcessedSnapshot SetupImportsResult) := do
let importsAlreadyLoaded ← importsLoadedRef.modifyGet ((·, true))
@ -393,7 +406,7 @@ def setupImports
return .error { diagnostics := .empty, result? := none, metaSnap := default }
let header := stx.toModuleHeader
chanOut.sync.send <| mkInitialIleanInfoUpdateNotification doc <| collectImports stx
chanOut.sync.send <| .ofMsg <| mkInitialIleanInfoUpdateNotification doc <| collectImports stx
let fileSetupResult ← setupFile doc header fun stderrLine => do
let progressDiagnostic := {
range := ⟨⟨0, 0⟩, ⟨1, 0⟩⟩
@ -402,9 +415,9 @@ def setupImports
severity? := DiagnosticSeverity.information
message := stderrLine
}
chanOut.sync.send <| mkPublishDiagnosticsNotification doc #[progressDiagnostic]
chanOut.sync.send <| .ofMsg <| mkPublishDiagnosticsNotification doc #[progressDiagnostic]
-- clear progress notifications in the end
chanOut.sync.send <| mkPublishDiagnosticsNotification doc #[]
chanOut.sync.send <| .ofMsg <| mkPublishDiagnosticsNotification doc #[]
match fileSetupResult.kind with
| .importsOutOfDate =>
return .error {
@ -466,7 +479,7 @@ section Initialization
let _ ← ServerTask.IO.asTask do
let importClosure ← IO.lazyPure fun _ => getImportClosure? initSnap
let importClosure ← importClosure.filterMapM (documentUriFromModule? ·)
chanOut.send <| mkImportClosureNotification importClosure
chanOut.send <| .ofMsg <| mkImportClosureNotification importClosure
let ctx := {
chanOut
hLog := e
@ -498,20 +511,21 @@ section Initialization
the output FS stream after discarding outdated notifications. This is the only component of
the worker with access to the output stream, so we can synchronize messages from parallel
elaboration tasks here. -/
mkLspOutputChannel maxDocVersion : IO (Std.Channel JsonRpc.Message) := do
mkLspOutputChannel maxDocVersion : IO (Std.Channel OutputMessage) := do
let chanOut ← Std.Channel.new
let _ ← chanOut.forAsync (prio := .dedicated) fun msg => do
let _ ← chanOut.forAsync (prio := .dedicated) fun msg?, serialized⟩ => do
-- discard outdated notifications; note that in contrast to responses, notifications can
-- always be silently discarded
let version? : Option Int := do match msg with
| .notification "textDocument/publishDiagnostics" (some params) =>
let version? : Option Int := do
match msg? with
| some (.notification "textDocument/publishDiagnostics" (some params)) =>
let params : PublishDiagnosticsParams ← fromJson? (toJson params) |>.toOption
params.version?
| .notification "$/lean/fileProgress" (some params) =>
| some (.notification "$/lean/fileProgress" (some params)) =>
let params : LeanFileProgressParams ← fromJson? (toJson params) |>.toOption
params.textDocument.version?
| .notification "$/lean/ileanInfoUpdate" (some params)
| .notification "$/lean/ileanInfoFinal" (some params) =>
| some (.notification "$/lean/ileanInfoUpdate" (some params))
| some (.notification "$/lean/ileanInfoFinal" (some params)) =>
let params : LeanIleanInfoParams ← fromJson? (toJson params) |>.toOption
some params.version
| _ => none
@ -521,7 +535,7 @@ section Initialization
-- note that because of `server.reportDelayMs`, we cannot simply set `maxDocVersion` here
-- as that would allow outdated messages to be reported until the delay is over
o.writeLspMessage msg |>.catchExceptions (fun _ => pure ())
o.writeSerializedLspMessage serialized |>.catchExceptions (fun _ => pure ())
return chanOut
getImportClosure? (snap : Language.Lean.InitialSnapshot) : Array Name := Id.run do
@ -545,7 +559,7 @@ section ServerRequests
(freshRequestId, freshRequestId + 1)
let responseTask ← ctx.initPendingServerRequest responseType freshRequestId
let r : JsonRpc.Request paramType := ⟨freshRequestId, method, param⟩
ctx.chanOut.sync.send r
ctx.chanOut.sync.send <| .ofMsg r
return responseTask
def sendUntypedServerRequest
@ -692,14 +706,15 @@ section MessageHandling
: WorkerM (ServerTask (Except Error AvailableImportsCache)) := do
let ctx ← read
let st ← get
let mod := st.doc.meta.mod
let text := st.doc.meta.text
match st.importCachingTask? with
| none => ServerTask.IO.asTask do
let availableImports ← ImportCompletion.collectAvailableImports
let lastRequestTimestampMs ← IO.monoMsNow
let completions := ImportCompletion.find text ⟨st.doc.initSnap.stx⟩ params availableImports
ctx.chanOut.sync.send <| .response id (toJson completions)
let completions := ImportCompletion.find mod params.position text ⟨st.doc.initSnap.stx⟩ availableImports
ctx.chanOut.sync.send <| .ofMsg <| .response id (toJson completions)
pure { availableImports, lastRequestTimestampMs : AvailableImportsCache }
| some task => ServerTask.IO.mapTaskCostly (t := task) fun (result : Except Error AvailableImportsCache) => do
@ -708,8 +723,8 @@ section MessageHandling
if timestampNowMs - lastRequestTimestampMs >= 10000 then
availableImports ← ImportCompletion.collectAvailableImports
lastRequestTimestampMs := timestampNowMs
let completions := ImportCompletion.find text ⟨st.doc.initSnap.stx⟩ params availableImports
ctx.chanOut.sync.send <| .response id (toJson completions)
let completions := ImportCompletion.find mod params.position text ⟨st.doc.initSnap.stx⟩ availableImports
ctx.chanOut.sync.send <| .ofMsg <| .response id (toJson completions)
pure { availableImports, lastRequestTimestampMs : AvailableImportsCache }
def handleStatefulPreRequestSpecialCases (id : RequestID) (method : String) (params : Json) : WorkerM Bool := do
@ -721,7 +736,7 @@ section MessageHandling
| "$/lean/rpc/connect" =>
let ps ← parseParams RpcConnectParams params
let resp ← handleRpcConnect ps
ctx.chanOut.sync.send <| .response id (toJson resp)
ctx.chanOut.sync.send <| .ofMsg <| .response id (toJson resp)
return true
| "textDocument/completion" =>
let params ← parseParams CompletionParams params
@ -734,7 +749,7 @@ section MessageHandling
| _ =>
return false
catch e =>
ctx.chanOut.sync.send <| .responseError id .internalError (toString e) none
ctx.chanOut.sync.send <| .ofMsg <| .responseError id .internalError (toString e) none
return true
open Widget RequestM Language in
@ -766,7 +781,7 @@ section MessageHandling
def handlePreRequestSpecialCases? (ctx : WorkerContext) (st : WorkerState)
(id : RequestID) (method : String) (params : Json)
: RequestM (Option (RequestTask (LspResponse Json))) := do
: RequestM (Option (RequestTask SerializedLspResponse)) := do
match method with
| "$/lean/rpc/call" =>
let params ← RequestM.parseRequestParams Lsp.RpcCallParams params
@ -778,7 +793,7 @@ section MessageHandling
let resp ← handleGetInteractiveDiagnosticsRequest ctx params
let resp ← seshRef.modifyGet fun st =>
rpcEncode resp st.objects |>.map (·) ({st with objects := ·})
return some <| .pure { response := resp, isComplete := true }
return some <| .pure { response? := resp, serialized := resp.compress, isComplete := true }
| "codeAction/resolve" =>
let params ← RequestM.parseRequestParams CodeAction params
let some data := params.data?
@ -789,36 +804,41 @@ section MessageHandling
return some <| ← RequestM.asTask do
let unknownIdentifierRanges ← waitAllUnknownIdentifierRanges st.doc
if unknownIdentifierRanges.isEmpty then
return { response := toJson params, isComplete := true }
let p := toJson params
return { response? := p, serialized := p.compress, isComplete := true }
let action? ← handleResolveImportAllUnknownIdentifiersCodeAction? id params unknownIdentifierRanges
let action := action?.getD params
return { response := toJson action, isComplete := true }
let action := toJson action
return { response? := action, serialized := action.compress, isComplete := true }
| _ =>
return none
def handlePostRequestSpecialCases (id : RequestID) (method : String) (params : Json)
(task : RequestTask (LspResponse Json)) : RequestM (RequestTask (LspResponse Json)) := do
(task : RequestTask SerializedLspResponse) : RequestM (RequestTask SerializedLspResponse) := do
let doc ← RequestM.readDoc
match method with
| "textDocument/codeAction" =>
let .ok (params : CodeActionParams) := fromJson? params
| return task
RequestM.mapRequestTaskCostly task fun r => do
let some response := r.response?
| return r
let isSourceAction := params.context.only?.any fun only =>
only.contains "source" || only.contains "source.organizeImports"
if isSourceAction then
let unknownIdentifierRanges ← waitAllUnknownIdentifierRanges doc
if unknownIdentifierRanges.isEmpty then
return r
let .ok (codeActions : Array CodeAction) := fromJson? r.response
let .ok (codeActions : Array CodeAction) := fromJson? response
| return r
return { r with response := toJson <| codeActions.push <| importAllUnknownIdentifiersCodeAction params "source.organizeImports" }
let response := toJson <| codeActions.push <| importAllUnknownIdentifiersCodeAction params "source.organizeImports"
return { r with response? := response, serialized := response.compress }
else
let requestedRange := doc.meta.text.lspRangeToUtf8Range params.range
let unknownIdentifierRanges ← waitUnknownIdentifierRanges doc requestedRange
if unknownIdentifierRanges.isEmpty then
return r
let .ok (codeActions : Array CodeAction) := fromJson? r.response
let .ok (codeActions : Array CodeAction) := fromJson? response
| return r
RequestM.checkCancelled
-- Since computing the unknown identifier code actions is *really* expensive,
@ -826,12 +846,13 @@ section MessageHandling
IO.sleep 1000
RequestM.checkCancelled
let unknownIdentifierCodeActions ← handleUnknownIdentifierCodeAction id params requestedRange
return { r with response := toJson <| codeActions ++ unknownIdentifierCodeActions }
let response := toJson <| codeActions ++ unknownIdentifierCodeActions
return { r with response? := response, serialized := response.compress }
| _ =>
return task
def emitRequestResponse
(requestTask? : Except RequestError (RequestTask (LspResponse Json)))
(requestTask? : Except RequestError (RequestTask SerializedLspResponse))
(cancelTk : RequestCancellationToken)
(id : RequestID)
(method : String)
@ -839,7 +860,7 @@ section MessageHandling
let ctx ← read
match requestTask? with
| Except.error e =>
emitResponse ctx (isComplete := false) <| e.toLspResponseError id
emitResponse ctx (isComplete := false) <| .ofMsg <| e.toLspResponseError id
return ServerTask.pure <| .ok ()
| Except.ok requestTask =>
ServerTask.IO.mapTaskCheap (t := requestTask) fun
@ -848,13 +869,13 @@ section MessageHandling
-- Try not to emit a partial response if this request was cancelled.
-- Clients usually discard responses for requests that they cancelled anyways,
-- but it's still good to send less over the wire in this case.
emitResponse ctx (isComplete := false) <| RequestError.requestCancelled.toLspResponseError id
emitResponse ctx (isComplete := false) <| .ofMsg <| RequestError.requestCancelled.toLspResponseError id
return
emitResponse ctx (isComplete := r.isComplete) <| .response id (toJson r.response)
emitResponse ctx (isComplete := r.isComplete) <| .ofLspResponse id r
| Except.error e =>
emitResponse ctx (isComplete := false) <| e.toLspResponseError id
emitResponse ctx (isComplete := false) <| .ofMsg <| e.toLspResponseError id
where
emitResponse (ctx : WorkerContext) (m : JsonRpc.Message) (isComplete : Bool) : IO Unit := do
emitResponse (ctx : WorkerContext) (m : OutputMessage) (isComplete : Bool) : IO Unit := do
ctx.chanOut.sync.send m
let timestamp ← IO.monoMsNow
ctx.modifyPartialHandler method fun h => { h with

View file

@ -13,6 +13,7 @@ public import Lean.Server.FileWorker.SemanticHighlighting
public import Lean.Server.FileWorker.SignatureHelp
public import Lean.Server.Completion
public import Lean.Server.References
public import Lean.Server.Completion.CompletionItemCompression
meta import Lean.Parser.Module
public import Lean.Widget.Diff
@ -40,7 +41,7 @@ def findCompletionCmdDataAtPos
findCmdDataAtPos doc pos (includeStop := true)
def handleCompletion (p : CompletionParams)
: RequestM (RequestTask CompletionList) := do
: RequestM (RequestTask ResolvableCompletionList) := do
let doc ← readDoc
let text := doc.meta.text
let pos := text.lspPosToUtf8Pos p.position
@ -48,7 +49,7 @@ def handleCompletion (p : CompletionParams)
mapTaskCostly (findCompletionCmdDataAtPos doc pos) fun cmdData? => do
let some (cmdStx, infoTree) := cmdData?
| return { items := #[], isIncomplete := true }
Completion.find? p doc.meta.text pos cmdStx infoTree caps
Completion.find? doc.meta.mod p.position doc.meta.text pos cmdStx infoTree caps
/--
Handles `completionItem/resolve` requests that are sent by the client after the user selects
@ -65,11 +66,13 @@ def handleCompletionItemResolve (item : CompletionItem)
| return .pure item
let some id := data.id?
| return .pure item
let pos := text.lspPosToUtf8Pos data.params.position
let some cPos := data.cPos?
| return .pure item
let pos := text.lspPosToUtf8Pos data.pos
mapTaskCostly (findCompletionCmdDataAtPos doc pos) fun cmdData? => do
let some (cmdStx, infoTree) := cmdData?
| return item
Completion.resolveCompletionItem? text pos cmdStx infoTree item id data.cPos
Completion.resolveCompletionItem? text pos cmdStx infoTree item id cPos
open Elab in
def handleHover (p : HoverParams)
@ -485,8 +488,9 @@ builtin_initialize
registerLspRequestHandler
"textDocument/completion"
CompletionParams
CompletionList
ResolvableCompletionList
handleCompletion
(serialize? := some (·.compressFast))
registerLspRequestHandler
"completionItem/resolve"
CompletionItem

View file

@ -451,9 +451,28 @@ For details of how to register one, see `registerLspRequestHandler`. -/
section HandlerTable
open Lsp
structure LspResponse (α : Type) where
response : α
isComplete : Bool
structure SerializedLspResponse where
response? : Option Json
serialized : String
isComplete : Bool
-- Custom serialization that uses `r.serialized` in place of `response`.
-- Identical to `Json.compress` for the JSON of `JsonRpc.Message.response ..`.
def SerializedLspResponse.toSerializedMessage
(id : JsonRpc.RequestID) (r : SerializedLspResponse) : String :=
"{" ++
s!"\"id\":{toJson id |>.compress}," ++
s!"\"jsonrpc\":\"2.0\"," ++
s!"\"result\":{r.serialized}"
++ "}"
structure RequestHandler where
fileSource : Json → Except RequestError Lsp.DocumentUri
handle : Json → RequestM (RequestTask Json)
fileSource : Json → Except RequestError FileIdent
handle : Json → RequestM (RequestTask SerializedLspResponse)
builtin_initialize requestHandlers : IO.Ref (PersistentHashMap String RequestHandler) ←
IO.mkRef {}
@ -466,6 +485,8 @@ A registration consists of:
- a type of JSON-serializable response data `respType`
- an actual `handler` which runs in the `RequestM` monad and is expected
to produce an asynchronous `RequestTask` which does any waiting/computation
- an optional `serialize` function which can be used to serialize `respType` directly to a string
for performance reasons, skipping `Json`
A handler task may be cancelled at any time, so it should check the cancellation token when possible
to handle this cooperatively. Any exceptions thrown in a request handler will be reported to the client
@ -473,7 +494,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))
(serialize? : Option (respType → String) := none) :
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
@ -483,7 +506,20 @@ def registerLspRequestHandler (method : String)
let handle := fun j => do
let params ← RequestM.parseRequestParams paramType j
let t ← handler params
pure <| t.mapCheap <| Except.map ToJson.toJson
pure <| t.mapCheap <| Except.map fun r =>
if let some serialize := serialize? then
{
response? := none
serialized := serialize r
isComplete := true
}
else
let j := toJson r
{
response? := some j
serialized := j.compress
isComplete := true
}
requestHandlers.modify fun rhs => rhs.insert method { fileSource, handle }
@ -506,11 +542,26 @@ def chainLspRequestHandler (method : String)
if let some oldHandler ← lookupLspRequestHandler method then
let handle := fun j => do
let t ← oldHandler.handle j
let t := t.mapCheap fun x => x.bind fun j => FromJson.fromJson? j |>.mapError fun e =>
.internalError s!"Failed to parse original LSP response for `{method}` when chaining: {e}"
let t := t.mapCheap fun x =>
x.bind fun j => do
let response ←
match j.response? with
| none =>
Json.parse j.serialized |>.mapError fun e =>
.internalError s!"Failed to parse original LSP response JSON for `{method}` when chaining: {e}"
| some response =>
pure response
FromJson.fromJson? response |>.mapError fun e =>
.internalError s!"Failed to parse original LSP response for `{method}` when chaining: {e}"
let params ← RequestM.parseRequestParams paramType j
let t ← handler params t
pure <| t.mapCheap <| Except.map ToJson.toJson
pure <| t.mapCheap <| Except.map fun r =>
let j := toJson r
{
response? := some j
serialized := j.compress
isComplete := true
}
requestHandlers.modify fun rhs => rhs.insert method {oldHandler with handle}
else
@ -531,18 +582,14 @@ inductive RequestHandlerCompleteness where
-/
| «partial» (refreshMethod : String) (refreshIntervalMs : Nat)
structure LspResponse (α : Type) where
response : α
isComplete : Bool
structure StatefulRequestHandler where
fileSource : Json → Except RequestError Lsp.DocumentUri
fileSource : Json → Except RequestError FileIdent
/--
`handle` with explicit state management for chaining request handlers.
This function is pure w.r.t. `lastTaskMutex` and `stateRef`, but not `RequestM`.
-/
pureHandle : Json → Dynamic → RequestM (LspResponse Json × Dynamic)
handle : Json → RequestM (RequestTask (LspResponse Json))
pureHandle : Json → Dynamic → RequestM (SerializedLspResponse × Dynamic)
handle : Json → RequestM (RequestTask SerializedLspResponse)
/--
`onDidChange` with explicit state management for chaining request handlers.
This function is pure w.r.t. `lastTaskMutex` and `stateRef`, but not `RequestM`.
@ -588,13 +635,14 @@ private def overrideStatefulLspRequestHandler
let initState := Dynamic.mk initState
let stateRef ← IO.mkRef initState
let pureHandle : Json → Dynamic → RequestM (LspResponse Json × Dynamic) := fun param state => do
let pureHandle : Json → Dynamic → RequestM (SerializedLspResponse × Dynamic) := fun param state => do
let param ← RequestM.parseRequestParams paramType param
let state ← getState! method state stateType
let (r, state') ← handler param state
return ({ r with response := toJson r.response }, Dynamic.mk state')
let response := toJson r.response
return ({ r with response? := some response, serialized := response.compress }, Dynamic.mk state')
let handle : Json → RequestM (RequestTask (LspResponse Json)) := fun param => lastTaskMutex.atomically do
let handle : Json → RequestM (RequestTask SerializedLspResponse) := fun param => lastTaskMutex.atomically do
let lastTask ← get
let requestTask ← RequestM.mapTaskCostly lastTask fun () => do
let state ← stateRef.get
@ -691,7 +739,12 @@ def chainStatefulLspRequestHandler (method : String)
let initState ← getIOState! method oldHandler.initState stateType
let handle (p : paramType) (s : stateType) : RequestM (LspResponse respType × stateType) := do
let (r, s) ← oldHandle (toJson p) (Dynamic.mk s)
let .ok response := fromJson? r.response
let .ok response :=
match r.response? with
| none => Json.parse r.serialized
| some response => .ok response
| throw <| RequestError.internalError "Failed to parse response of previous request handler when chaining stateful LSP request handlers"
let .ok response := fromJson? response
| throw <| RequestError.internalError "Failed to convert response of previous request handler when chaining stateful LSP request handlers"
let r := { r with response := response }
let s ← getState! method s stateType
@ -709,7 +762,7 @@ def handleOnDidChange (p : DidChangeTextDocumentParams) : RequestM Unit := do
(← statefulRequestHandlers.get).forM fun _ handler => do
handler.onDidChange p
def handleLspRequest (method : String) (params : Json) : RequestM (RequestTask (LspResponse Json)) := do
def handleLspRequest (method : String) (params : Json) : RequestM (RequestTask SerializedLspResponse) := do
if ← isStatefulLspRequestMethod method then
match ← lookupStatefulLspRequestHandler method with
| none =>
@ -721,11 +774,9 @@ def handleLspRequest (method : String) (params : Json) : RequestM (RequestTask (
| none =>
throw <| .internalError
s!"request '{method}' routed through watchdog but unknown in worker; are both using the same plugins?"
| some rh =>
let t ← rh.handle params
return t.mapCheap fun r => r.map ({response := ·, isComplete := true })
| some rh => rh.handle params
def routeLspRequest (method : String) (params : Json) : IO (Except RequestError DocumentUri) := do
def routeLspRequest (method : String) (params : Json) : IO (Except RequestError FileIdent) := do
if ← isStatefulLspRequestMethod method then
match ← lookupStatefulLspRequestHandler method with
| none => return Except.error <| RequestError.methodNotFound method

View file

@ -269,7 +269,31 @@ section FileWorker
end FileWorker
section ServerM
abbrev FileWorkerMap := Std.TreeMap DocumentUri FileWorker
structure FileWorkerMap where
fileWorkers : Std.TreeMap DocumentUri FileWorker := {}
uriByMod : Std.TreeMap Name DocumentUri Name.quickCmp := {}
def FileWorkerMap.getUri? (m : FileWorkerMap) (id : FileIdent) : Option DocumentUri :=
match id with
| .uri uri => uri
| .mod mod => m.uriByMod.get? mod
def FileWorkerMap.insert (m : FileWorkerMap) (uri : DocumentUri) (fw : FileWorker) :
FileWorkerMap where
fileWorkers := m.fileWorkers.insert uri fw
uriByMod := m.uriByMod.insert fw.doc.mod uri
def FileWorkerMap.erase (m : FileWorkerMap) (uri : DocumentUri) : FileWorkerMap := Id.run do
let some fw := m.fileWorkers.get? uri
| return m
return {
fileWorkers := m.fileWorkers.erase uri
uriByMod := m.uriByMod.erase fw.doc.mod
}
def FileWorkerMap.get? (m : FileWorkerMap) (uri : DocumentUri) : Option FileWorker := do
m.fileWorkers.get? uri
abbrev ImportMap := Std.TreeMap DocumentUri (Std.TreeSet DocumentUri)
/-- Global import data for all open files managed by this watchdog. -/
@ -416,9 +440,17 @@ section ServerM
let rd ← rd.modifyReferencesM (m := IO) f
set rd
def getFileWorkerUri? (id : FileIdent) : ServerM (Option DocumentUri) :=
return (← (← read).fileWorkersRef.get).getUri? id
def getFileWorker? (uri : DocumentUri) : ServerM (Option FileWorker) :=
return (← (←read).fileWorkersRef.get).get? uri
def fileWorkerExists (id : FileIdent) : ServerM Bool := do
let some uri ← getFileWorkerUri? id
| return false
return (← getFileWorker? uri).isSome
def getFileWorkerMod? (uri : DocumentUri) : ServerM (Option Name) := do
return (← getFileWorker? uri).map (·.doc.mod)
@ -654,40 +686,72 @@ section ServerM
definitions := definitions.push definitionLocation
return definitions
def handleResponseSpecialCases (req : JsonRpc.Request Json) (resp : JsonRpc.Response Json) :
ServerM (JsonRpc.Response Json) := do
def parseRequestParams? (α : Type) [FromJson α] (request : String) : Except String α := do
let j ← Json.parse request
let msg : JsonRpc.Message ← fromJson? j
match msg with
| .request _ _ params =>
fromJson? (toJson params)
| _ =>
Except.error "Got message that isn't a request in `parseRequestParams?`."
def parseNotificationParams? (α : Type) [FromJson α] (notification : String) : Except String α := do
let j ← Json.parse notification
let msg : JsonRpc.Message ← fromJson? j
match msg with
| .notification _ params =>
fromJson? (toJson params)
| _ =>
Except.error "Got message that isn't a notification in `parseNotificationParams?`."
def parseResponseResult? (α : Type) [FromJson α] (response : String) : Except String α := do
let j ← Json.parse response
let msg : JsonRpc.Message ← fromJson? j
match msg with
| .response _ result =>
fromJson? result
| _ =>
Except.error "Got message that isn't a response in `parseResponseResult?`."
def bendLocationLinks (req : JsonRpc.Request Json) (r : Array LeanLocationLink) :
ServerM Json := do
let refs ← getReferences
let r : Array LeanLocationLink := r.filterMap fun ll => Id.run do
let some ident := ll.ident?
| return ll
let ident : RefIdent := .const ident.module.toString ident.decl.toString
let some definitionInfo := refs.definitionOf? ident
| return ll
let newTargetRange := definitionInfo.location.range
return some {
ll with toLocationLink := {
originSelectionRange? := ll.originSelectionRange?
targetUri := definitionInfo.location.uri
targetRange := newTargetRange
targetSelectionRange := newTargetRange
}
}
if r.all (·.isDefault) then
-- The file worker produced fallback location links.
-- Let's see if we can obtain better ones using the .ileans, just to be safe.
let params' ← parseParams TextDocumentPositionParams req.param
let definitions ← findDefinitions params'
if ! definitions.isEmpty then
return toJson definitions
return toJson <| r.map (·.toLocationLink)
def handleResponseSpecialCases (req : JsonRpc.Request Json) (resp : String) :
ServerM String := do
match req.method with
| "textDocument/definition"
| "textDocument/declaration"
| "textDocument/typeDefinition" =>
let r : Array LeanLocationLink :=
match fromJson? resp.result with
| .ok r => r
| .error e => panic! s!"Expected `LeanLocationLink` in file worker response to definition request. Error: {e}. Got: {resp.result.compress}."
let refs ← getReferences
let r : Array LeanLocationLink := r.filterMap fun ll => Id.run do
let some ident := ll.ident?
| return ll
let ident : RefIdent := .const ident.module.toString ident.decl.toString
let some definitionInfo := refs.definitionOf? ident
| return ll
let newTargetRange := definitionInfo.location.range
return some {
ll with toLocationLink := {
originSelectionRange? := ll.originSelectionRange?
targetUri := definitionInfo.location.uri
targetRange := newTargetRange
targetSelectionRange := newTargetRange
}
}
if r.all (·.isDefault) then
-- The file worker produced fallback location links.
-- Let's see if we can obtain better ones using the .ileans, just to be safe.
let params' ← parseParams TextDocumentPositionParams req.param
let definitions ← findDefinitions params'
if ! definitions.isEmpty then
return { resp with result := toJson definitions }
return { resp with result := toJson <| r.map (·.toLocationLink) }
match parseResponseResult? (Array LeanLocationLink) resp with
| .ok r =>
let result ← bendLocationLinks req r
return JsonRpc.Message.response req.id result |> toJson |>.compress
| .error _ =>
return resp
| _ =>
return resp
@ -704,7 +768,7 @@ section ServerM
while true do
let msg ←
try
fw.stdout.readLspMessage
fw.stdout.readLspMessageAsString
catch _ =>
let exitCode ← fw.waitForProc
-- Remove surviving descendant processes, if any, such as from nested builds.
@ -715,18 +779,21 @@ section ServerM
| 0 => return .terminated
| 2 => return .importsChanged
| _ => return .crashed exitCode
let .ok metaData := parseMessageMetaData msg
| continue
let (_, pendingWorkerToWatchdogRequests') ←
StateT.run (s := pendingWorkerToWatchdogRequests) <| handleMessage msg
StateT.run (s := pendingWorkerToWatchdogRequests) <| handleMessage msg metaData
pendingWorkerToWatchdogRequests := ∅
for (id, task, cancelTk) in pendingWorkerToWatchdogRequests' do
if ← task.hasFinished then
continue
pendingWorkerToWatchdogRequests := pendingWorkerToWatchdogRequests.insert id (task, cancelTk)
return .terminated
handleMessage (msg : JsonRpc.Message)
handleMessage (msg : String) (metaData : MessageMetaData)
: StateT (Std.TreeMap RequestID (ServerTask Unit × CancelToken)) ServerM Unit :=
-- When the file worker is terminated by the main thread, the client can immediately launch
-- another file worker using `didOpen`. In this case, even when this task and the old file
@ -740,8 +807,8 @@ section ServerM
return
-- Re. `o.writeLspMessage msg`:
-- Writes to Lean I/O channels are atomic, so these won't trample on each other.
match msg with
| Message.response id result => do
match metaData with
| .response id => do
let req? ← eraseGetPendingRequest uri id
-- In the rare scenario that we detect a file worker crash on the main thread and this task
-- still has a response to process, it could theoretically happen that we restart the file
@ -749,44 +816,40 @@ section ServerM
-- This ensures that this scenario can't occur, and we only emit responses for requests
-- that were still pending.
if let some req := req? then
let resp ← handleResponseSpecialCases req { id, result }
o.writeLspMessage resp
| Message.responseError id code _ _ => do
let resp ← handleResponseSpecialCases req msg
o.writeSerializedLspMessage resp
| .responseError id code _ _ => do
let wasPending ← erasePendingRequest uri id
if code matches .requestCancelled then
let pendingWorkerToWatchdogRequests ← getThe (Std.TreeMap RequestID (ServerTask Unit × CancelToken))
if let some (_, cancelTk) := pendingWorkerToWatchdogRequests.get? id then
cancelTk.set
if wasPending then
o.writeLspMessage msg
| Message.request id method params? =>
o.writeSerializedLspMessage msg
| .request id method =>
if method == "$/lean/queryModule" then
if let some params := params? then
if let .ok (params : LeanQueryModuleParams) := fromJson? <| toJson params then
let (task, cancelTk) ← handleQueryModule fw id params
modifyThe (Std.TreeMap RequestID (ServerTask Unit × CancelToken)) (·.insert params.sourceRequestID (task, cancelTk))
if let .ok params := parseRequestParams? LeanQueryModuleParams msg then
let (task, cancelTk) ← handleQueryModule fw id params
modifyThe (Std.TreeMap RequestID (ServerTask Unit × CancelToken)) (·.insert params.sourceRequestID (task, cancelTk))
else
let globalID ← (← read).serverRequestData.modifyGet
(·.trackOutboundRequest fw.doc.uri id)
o.writeLspMessage (Message.request globalID method params?)
| Message.notification "$/lean/ileanHeaderInfo" params =>
if let some params := params then
if let Except.ok params := FromJson.fromJson? <| ToJson.toJson params then
handleILeanHeaderInfo fw params
| Message.notification "$/lean/ileanInfoUpdate" params =>
if let some params := params then
if let Except.ok params := FromJson.fromJson? <| ToJson.toJson params then
handleIleanInfoUpdate fw params
| Message.notification "$/lean/ileanInfoFinal" params =>
if let some params := params then
if let Except.ok params := FromJson.fromJson? <| ToJson.toJson params then
handleIleanInfoFinal fw params
| Message.notification "$/lean/importClosure" params =>
if let some params := params then
if let Except.ok params := FromJson.fromJson? <| ToJson.toJson params then
handleImportClosure fw params
if let .ok params? := parseRequestParams? (Option Json.Structured) msg then
let globalID ← (← read).serverRequestData.modifyGet
(·.trackOutboundRequest fw.doc.uri id)
o.writeLspMessage (Message.request globalID method params?)
| .notification "$/lean/ileanHeaderInfo" =>
if let .ok params := parseNotificationParams? LeanILeanHeaderInfoParams msg then
handleILeanHeaderInfo fw params
| .notification "$/lean/ileanInfoUpdate" =>
if let .ok params := parseNotificationParams? LeanIleanInfoParams msg then
handleIleanInfoUpdate fw params
| .notification "$/lean/ileanInfoFinal" =>
if let .ok params := parseNotificationParams? LeanIleanInfoParams msg then
handleIleanInfoFinal fw params
| .notification "$/lean/importClosure" =>
if let .ok params := parseNotificationParams? LeanImportClosureParams msg then
handleImportClosure fw params
| _ =>
o.writeLspMessage msg
o.writeSerializedLspMessage msg
def startFileWorker (m : DocumentMeta) : ServerM Unit := do
let st ← read
@ -861,9 +924,11 @@ section ServerM
pure ()
def tryWriteMessage
(uri : DocumentUri)
(id : FileIdent)
(msg : JsonRpc.Message)
: ServerM Unit := do
let some uri ← getFileWorkerUri? id
| return
let some fw ← getFileWorker? uri
| return
if let some req := JsonRpc.Request.ofMessage? msg then
@ -896,7 +961,7 @@ section ServerM
staleDependency := staleDependency
: LeanStaleDependencyParams
}
tryWriteMessage uri notification
tryWriteMessage (.uri uri) notification
end ServerM
section RequestHandling
@ -1202,7 +1267,7 @@ section NotificationHandling
}
updateFileWorkers { fw with doc := newDoc }
let notification := Notification.mk "textDocument/didChange" p
tryWriteMessage doc.uri notification
tryWriteMessage (.uri doc.uri) notification
/--
When a file is saved, notifies all file workers for files that depend on this file that this
@ -1211,11 +1276,11 @@ section NotificationHandling
-/
def handleDidSave (p : DidSaveTextDocumentParams) : ServerM Unit := do
let s ← read
let fileWorkers ← s.fileWorkersRef.get
let fws ← s.fileWorkersRef.get
let importData ← s.importData.get
let dependents := importData.importedBy.getD p.textDocument.uri ∅
for ⟨uri, _⟩ in fileWorkers do
for ⟨uri, _⟩ in fws.fileWorkers do
if ! dependents.contains uri then
continue
notifyAboutStaleDependency uri p.textDocument.uri
@ -1257,7 +1322,7 @@ section NotificationHandling
let ctx ← read
let some uri ← ctx.requestData.getUri? p.id
| return
tryWriteMessage uri (Notification.mk "$/cancelRequest" p)
tryWriteMessage (.uri uri) (Notification.mk "$/cancelRequest" p)
def forwardNotification {α : Type} [ToJson α] [FileSource α] (method : String) (params : α)
: ServerM Unit :=
@ -1266,7 +1331,7 @@ end NotificationHandling
section MessageHandling
def forwardRequestToWorker (id : RequestID) (method : String) (params : Json) : ServerM Unit := do
let uri: DocumentUri
let fileId : FileIdent
if method == "$/lean/rpc/connect" then
let ps ← parseParams Lsp.RpcConnectParams params
pure <| fileSource ps
@ -1276,7 +1341,7 @@ section MessageHandling
(←read).hOut.writeLspResponseError <| e.toLspResponseError id
return
| Except.ok uri => pure uri
if (← getFileWorker? uri).isNone then
if ! (← fileWorkerExists fileId) then
/- Clients may send requests to closed files, which we respond to with an error.
For example, VSCode sometimes sends requests just after closing a file,
and RPC clients may also do so, e.g. due to remaining timers. -/
@ -1285,16 +1350,16 @@ section MessageHandling
/- Some clients (VSCode) also send requests *before* opening a file. We reply
with `contentModified` as that does not display a "request failed" popup. -/
code := ErrorCode.contentModified
message := s!"Cannot process request to closed file '{uri}'" }
message := s!"Cannot process request to closed file '{toString fileId}'" }
return
let r := Request.mk id method params
tryWriteMessage uri r
tryWriteMessage fileId r
def handleReferenceRequest α β [FromJson α] [ToJson β] (id : RequestID) (params : Json)
(handler : α → ReaderT ReferenceRequestContext IO β) : ServerM Unit := do
let ctx ← read
let hOut := ctx.hOut
let fileWorkerMods := (← ctx.fileWorkersRef.get).map fun _ fw => fw.doc.mod
let fileWorkerMods := (← ctx.fileWorkersRef.get).fileWorkers.map fun _ fw => fw.doc.mod
let references ← getReferences
let _ ← ServerTask.IO.asTask do
try
@ -1396,7 +1461,7 @@ section MessageHandling
def handleResponse (id : RequestID) (result : Json) : ServerM Unit := do
let some translation ← (← read).serverRequestData.modifyGet (·.translateInboundResponse id)
| return
tryWriteMessage translation.sourceUri (Response.mk translation.localID result)
tryWriteMessage (.uri translation.sourceUri) (Response.mk translation.localID result)
def handleResponseError
(id : RequestID)
@ -1406,15 +1471,15 @@ section MessageHandling
: ServerM Unit := do
let some translation ← (← read).serverRequestData.modifyGet (·.translateInboundResponse id)
| return
tryWriteMessage translation.sourceUri (ResponseError.mk translation.localID code message data?)
tryWriteMessage (.uri translation.sourceUri) (ResponseError.mk translation.localID code message data?)
end MessageHandling
section MainLoop
def shutdown : ServerM Unit := do
let fileWorkers ← (←read).fileWorkersRef.get
for ⟨uri, _⟩ in fileWorkers do
for ⟨uri, _⟩ in fileWorkers.fileWorkers do
try terminateFileWorker uri catch _ => pure ()
for ⟨_, fw⟩ in fileWorkers do
for ⟨_, fw⟩ in fileWorkers.fileWorkers do
-- TODO: Wait for process group to finish instead
try let _ ← fw.killProcAndWait catch _ => pure ()
@ -1438,7 +1503,7 @@ section MainLoop
let st ← read
let workers ← st.fileWorkersRef.get
let mut workerTasks := #[]
for (_, fw) in workers do
for (_, fw) in workers.fileWorkers do
if !((← getWorkerState fw) matches WorkerState.crashed) then
workerTasks := workerTasks.push <| fw.commTask.mapCheap (ServerEvent.workerEvent fw)
@ -1626,7 +1691,7 @@ def initAndRunWatchdog (args : List String) (i o e : FS.Stream) : IO Unit := do
pendingWaitForILeanRequests := #[]
}
startLoadingReferences referenceData
let fileWorkersRef ← IO.mkRef (Std.TreeMap.empty : FileWorkerMap)
let fileWorkersRef ← IO.mkRef ({} : FileWorkerMap)
let serverRequestData ← IO.mkRef {
pendingServerRequests := Std.TreeMap.empty
freshServerRequestID := 0

View file

@ -1,168 +1,86 @@
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}}
{"items":
[{"label": "getDocString",
[{"label": "getScientific",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getDocString"}},
"cPos": 1}},
{"label": "expandInterpolatedStr",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.expandInterpolatedStr"}},
"cPos": 1}},
{"label": "getHygieneInfo",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getHygieneInfo"}},
"cPos": 1}},
["«external:file:///1265.lean»", 0, 51, 1, "cLean.TSyntax.getScientific"]},
{"label": "getString",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getString"}},
"cPos": 1}},
{"label": "getName",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getName"}},
"cPos": 1}},
{"label": "getChar",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getChar"}},
"cPos": 1}},
["«external:file:///1265.lean»", 0, 51, 1, "cLean.TSyntax.getString"]},
{"label": "getNat",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getNat"}},
"cPos": 1}},
{"label": "getScientific",
"data": ["«external:file:///1265.lean»", 0, 51, 1, "cLean.TSyntax.getNat"]},
{"label": "getName",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getScientific"}},
"cPos": 1}},
"data": ["«external:file:///1265.lean»", 0, 51, 1, "cLean.TSyntax.getName"]},
{"label": "getChar",
"kind": 3,
"data": ["«external:file:///1265.lean»", 0, 51, 1, "cLean.TSyntax.getChar"]},
{"label": "raw",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.raw"}},
"cPos": 1}},
{"label": "getId",
"data": ["«external:file:///1265.lean»", 0, 51, 1, "cLean.TSyntax.raw"]},
{"label": "getDocString",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 0, "character": 51}},
"id": {"const": {"declName": "Lean.TSyntax.getId"}},
"cPos": 1}}],
["«external:file:///1265.lean»", 0, 51, 1, "cLean.TSyntax.getDocString"]},
{"label": "expandInterpolatedStr",
"kind": 3,
"data":
["«external:file:///1265.lean»",
0,
51,
1,
"cLean.TSyntax.expandInterpolatedStr"]},
{"label": "getHygieneInfo",
"kind": 3,
"data":
["«external:file:///1265.lean»", 0, 51, 1, "cLean.TSyntax.getHygieneInfo"]},
{"label": "getId",
"kind": 3,
"data": ["«external:file:///1265.lean»", 0, 51, 1, "cLean.TSyntax.getId"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}}
{"items":
[{"label": "getDocString",
[{"label": "getScientific",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getDocString"}},
"cPos": 1}},
{"label": "expandInterpolatedStr",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.expandInterpolatedStr"}},
"cPos": 1}},
{"label": "getHygieneInfo",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getHygieneInfo"}},
"cPos": 1}},
["«external:file:///1265.lean»", 2, 53, 1, "cLean.TSyntax.getScientific"]},
{"label": "getString",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getString"}},
"cPos": 1}},
{"label": "getName",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getName"}},
"cPos": 1}},
{"label": "getChar",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getChar"}},
"cPos": 1}},
["«external:file:///1265.lean»", 2, 53, 1, "cLean.TSyntax.getString"]},
{"label": "getNat",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getNat"}},
"cPos": 1}},
{"label": "getScientific",
"data": ["«external:file:///1265.lean»", 2, 53, 1, "cLean.TSyntax.getNat"]},
{"label": "getName",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getScientific"}},
"cPos": 1}},
"data": ["«external:file:///1265.lean»", 2, 53, 1, "cLean.TSyntax.getName"]},
{"label": "getChar",
"kind": 3,
"data": ["«external:file:///1265.lean»", 2, 53, 1, "cLean.TSyntax.getChar"]},
{"label": "raw",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.raw"}},
"cPos": 1}},
{"label": "getId",
"data": ["«external:file:///1265.lean»", 2, 53, 1, "cLean.TSyntax.raw"]},
{"label": "getDocString",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///1265.lean"},
"position": {"line": 2, "character": 53}},
"id": {"const": {"declName": "Lean.TSyntax.getId"}},
"cPos": 1}}],
["«external:file:///1265.lean»", 2, 53, 1, "cLean.TSyntax.getDocString"]},
{"label": "expandInterpolatedStr",
"kind": 3,
"data":
["«external:file:///1265.lean»",
2,
53,
1,
"cLean.TSyntax.expandInterpolatedStr"]},
{"label": "getHygieneInfo",
"kind": 3,
"data":
["«external:file:///1265.lean»", 2, 53, 1, "cLean.TSyntax.getHygieneInfo"]},
{"label": "getId",
"kind": 3,
"data": ["«external:file:///1265.lean»", 2, 53, 1, "cLean.TSyntax.getId"]}],
"isIncomplete": false}

View file

@ -1,42 +1,42 @@
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 9, "character": 23}}
{"items":
[{"label": "Lean.Elab.Tactic.elabTermEnsuringType",
[{"label": "Lean.Elab.Term.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 9, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Tactic.elabTermEnsuringType"}},
"cPos": 0}},
{"label": "Lean.Elab.Term.elabTermEnsuringType",
["«external:file:///1659.lean»",
9,
23,
0,
"cLean.Elab.Term.elabTermEnsuringType"]},
{"label": "Lean.Elab.Tactic.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 9, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Term.elabTermEnsuringType"}},
"cPos": 0}}],
["«external:file:///1659.lean»",
9,
23,
0,
"cLean.Elab.Tactic.elabTermEnsuringType"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 15, "character": 23}}
{"items":
[{"label": "Tactic.elabTermEnsuringType",
[{"label": "Term.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 15, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Tactic.elabTermEnsuringType"}},
"cPos": 0}},
{"label": "Term.elabTermEnsuringType",
["«external:file:///1659.lean»",
15,
23,
0,
"cLean.Elab.Term.elabTermEnsuringType"]},
{"label": "Tactic.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 15, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Term.elabTermEnsuringType"}},
"cPos": 0}}],
["«external:file:///1659.lean»",
15,
23,
0,
"cLean.Elab.Tactic.elabTermEnsuringType"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 21, "character": 23}}
@ -44,81 +44,73 @@
[{"label": "elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 21, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Term.elabTermEnsuringType"}},
"cPos": 0}},
["«external:file:///1659.lean»",
21,
23,
0,
"cLean.Elab.Term.elabTermEnsuringType"]},
{"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"}},
"cPos": 0}}],
["«external:file:///1659.lean»",
21,
23,
0,
"cLean.Elab.Tactic.elabTermEnsuringType"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 27, "character": 23}}
{"items":
[{"label": "elabTermEnsuringType",
[{"label": "Lean.Elab.Term.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 27, "character": 23}},
"id": {"const": {"declName": "elabTermEnsuringType"}},
"cPos": 0}},
["«external:file:///1659.lean»",
27,
23,
0,
"cLean.Elab.Term.elabTermEnsuringType"]},
{"label": "elabTermEnsuringType",
"kind": 21,
"data":
["«external:file:///1659.lean»", 27, 23, 0, "celabTermEnsuringType"]},
{"label": "Lean.Elab.Tactic.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 27, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.Tactic.elabTermEnsuringType"}},
"cPos": 0}},
{"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"}},
"cPos": 0}}],
["«external:file:///1659.lean»",
27,
23,
0,
"cLean.Elab.Tactic.elabTermEnsuringType"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 33, "character": 23}}
{"items":
[{"label": "elabTermEnsuringType",
[{"label": "Lean.Elab.Term.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 33, "character": 23}},
"id": {"const": {"declName": "elabTermEnsuringType"}},
"cPos": 0}},
{"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"}},
"cPos": 0}},
{"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"}},
"cPos": 0}},
["«external:file:///1659.lean»",
33,
23,
0,
"cLean.Elab.Term.elabTermEnsuringType"]},
{"label": "Lean.Elab.elabTermEnsuringType",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///1659.lean"},
"position": {"line": 33, "character": 23}},
"id": {"const": {"declName": "Lean.Elab.elabTermEnsuringType"}},
"cPos": 0}}],
["«external:file:///1659.lean»",
33,
23,
0,
"cLean.Elab.elabTermEnsuringType"]},
{"label": "elabTermEnsuringType",
"kind": 21,
"data":
["«external:file:///1659.lean»", 33, 23, 0, "celabTermEnsuringType"]},
{"label": "Lean.Elab.Tactic.elabTermEnsuringType",
"kind": 21,
"data":
["«external:file:///1659.lean»",
33,
23,
0,
"cLean.Elab.Tactic.elabTermEnsuringType"]}],
"isIncomplete": false}

View file

@ -1,20 +1,10 @@
{"textDocument": {"uri": "file:///533.lean"},
"position": {"line": 4, "character": 10}}
{"items":
[{"label": "F",
[{"label": "Foo",
"kind": 6,
"data":
{"params":
{"textDocument": {"uri": "file:///533.lean"},
"position": {"line": 4, "character": 10}},
"id": {"fvar": {"id": "_uniq.7"}},
"cPos": 0}},
{"label": "Foo",
"data": ["«external:file:///533.lean»", 4, 10, 0, "f_uniq.3"]},
{"label": "F",
"kind": 6,
"data":
{"params":
{"textDocument": {"uri": "file:///533.lean"},
"position": {"line": 4, "character": 10}},
"id": {"fvar": {"id": "_uniq.3"}},
"cPos": 0}}],
"data": ["«external:file:///533.lean»", 4, 10, 0, "f_uniq.7"]}],
"isIncomplete": false}

View file

@ -1,40 +1,21 @@
{"textDocument": {"uri": "file:///863.lean"},
"position": {"line": 9, "character": 12}}
{"items":
[{"label": "getRef",
[{"label": "MonadRef.getRef",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///863.lean"},
"position": {"line": 9, "character": 12}},
"id": {"const": {"declName": "Lean.MonadRef.getRef"}},
"cPos": 0}},
{"label": "MonadRef.getRef",
"data": ["«external:file:///863.lean»", 9, 12, 0, "cLean.MonadRef.getRef"]},
{"label": "getRef",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///863.lean"},
"position": {"line": 9, "character": 12}},
"id": {"const": {"declName": "Lean.MonadRef.getRef"}},
"cPos": 0}}],
"data": ["«external:file:///863.lean»", 9, 12, 0, "cLean.MonadRef.getRef"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///863.lean"},
"position": {"line": 13, "character": 12}}
{"items":
[{"label": "getRef",
[{"label": "MonadRef.getRef",
"kind": 5,
"data": ["«external:file:///863.lean»", 13, 12, 0, "cLean.MonadRef.getRef"]},
{"label": "getRef",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///863.lean"},
"position": {"line": 13, "character": 12}},
"id": {"const": {"declName": "Lean.MonadRef.getRef"}},
"cPos": 0}},
{"label": "MonadRef.getRef",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///863.lean"},
"position": {"line": 13, "character": 12}},
"id": {"const": {"declName": "Lean.MonadRef.getRef"}},
"cPos": 0}}],
["«external:file:///863.lean»", 13, 12, 0, "cLean.MonadRef.getRef"]}],
"isIncomplete": false}

View file

@ -1,20 +1,15 @@
{"textDocument": {"uri": "file:///compHeader.lean"},
"position": {"line": 2, "character": 22}}
{"items":
[{"label": "veryLongNameForCompletion",
[{"label": "veryLongNam",
"kind": 6,
"data": ["«external:file:///compHeader.lean»", 2, 22, 0, "f_uniq.7"]},
{"label": "veryLongNameForCompletion",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///compHeader.lean"},
"position": {"line": 2, "character": 22}},
"id": {"const": {"declName": "veryLongNameForCompletion"}},
"cPos": 0}},
{"label": "veryLongNam",
"kind": 6,
"data":
{"params":
{"textDocument": {"uri": "file:///compHeader.lean"},
"position": {"line": 2, "character": 22}},
"id": {"fvar": {"id": "_uniq.7"}},
"cPos": 0}}],
["«external:file:///compHeader.lean»",
2,
22,
0,
"cveryLongNameForCompletion"]}],
"isIncomplete": false}

View file

@ -4,11 +4,7 @@
[{"label": "LongNamespaceExample",
"kind": 9,
"detail": "namespace",
"data":
{"params":
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 5, "character": 14}},
"cPos": 0}}],
"data": ["«external:file:///compNamespace.lean»", 5, 14, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 9, "character": 14}}
@ -16,11 +12,7 @@
[{"label": "LongNamespaceExample",
"kind": 9,
"detail": "namespace",
"data":
{"params":
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 9, "character": 14}},
"cPos": 0}}],
"data": ["«external:file:///compNamespace.lean»", 9, 14, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 13, "character": 11}}
@ -28,11 +20,7 @@
[{"label": "LongNamespaceExample",
"kind": 9,
"detail": "namespace",
"data":
{"params":
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 13, "character": 11}},
"cPos": 0}}],
"data": ["«external:file:///compNamespace.lean»", 13, 11, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 16, "character": 16}}
@ -40,11 +28,7 @@
[{"label": "LongNamespaceExample",
"kind": 9,
"detail": "namespace",
"data":
{"params":
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 16, "character": 16}},
"cPos": 0}}],
"data": ["«external:file:///compNamespace.lean»", 16, 16, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 20, "character": 14}}
@ -52,9 +36,5 @@
[{"label": "LongNamespaceExample",
"kind": 9,
"detail": "namespace",
"data":
{"params":
{"textDocument": {"uri": "file:///compNamespace.lean"},
"position": {"line": 20, "character": 14}},
"cPos": 0}}],
"data": ["«external:file:///compNamespace.lean»", 20, 14, 0]}],
"isIncomplete": false}

View file

@ -3,46 +3,26 @@
{"items":
[{"label": "foo",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 3, "character": 22}},
"id": {"const": {"declName": "Foo.foo"}},
"cPos": 1}}],
"data": ["«external:file:///completion.lean»", 3, 22, 1, "cFoo.foo"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 5, "character": 23}}
{"items":
[{"label": "foo",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 5, "character": 23}},
"id": {"const": {"declName": "Foo.foo"}},
"cPos": 1}}],
"data": ["«external:file:///completion.lean»", 5, 23, 1, "cFoo.foo"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 7, "character": 28}}
{"items":
[{"label": "foo",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 7, "character": 28}},
"id": {"const": {"declName": "Foo.foo"}},
"cPos": 0}}],
"data": ["«external:file:///completion.lean»", 7, 28, 0, "cFoo.foo"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 9, "character": 29}}
{"items":
[{"label": "foo",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion.lean"},
"position": {"line": 9, "character": 29}},
"id": {"const": {"declName": "Foo.foo"}},
"cPos": 0}}],
"data": ["«external:file:///completion.lean»", 9, 29, 0, "cFoo.foo"]}],
"isIncomplete": false}

View file

@ -1,136 +1,61 @@
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 19, "character": 10}}
{"items":
[{"label": "ex3",
[{"label": "ex2",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 19, "character": 10}},
"id": {"const": {"declName": "Foo.Bla.ex3"}},
"cPos": 0}},
{"label": "ex2",
"data": ["«external:file:///completion2.lean»", 19, 10, 0, "cFoo.Bla.ex2"]},
{"label": "ex3",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 19, "character": 10}},
"id": {"const": {"declName": "Foo.Bla.ex2"}},
"cPos": 0}},
{"label": "ax1",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 19, "character": 10}},
"id": {"const": {"declName": "Foo.Bla.ax1"}},
"cPos": 0}},
"data": ["«external:file:///completion2.lean»", 19, 10, 0, "cFoo.Bla.ex3"]},
{"label": "ex1",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 19, "character": 10}},
"id": {"const": {"declName": "Foo.Bla.ex1"}},
"cPos": 0}}],
"data": ["«external:file:///completion2.lean»", 19, 10, 0, "cFoo.Bla.ex1"]},
{"label": "ax1",
"kind": 23,
"data": ["«external:file:///completion2.lean»", 19, 10, 0, "cFoo.Bla.ax1"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 25, "character": 6}}
{"items":
[{"label": "ex3",
[{"label": "ex2",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 25, "character": 6}},
"id": {"const": {"declName": "Foo.Bla.ex3"}},
"cPos": 0}},
{"label": "ex2",
"data": ["«external:file:///completion2.lean»", 25, 6, 0, "cFoo.Bla.ex2"]},
{"label": "ex3",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 25, "character": 6}},
"id": {"const": {"declName": "Foo.Bla.ex2"}},
"cPos": 0}},
{"label": "ax1",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 25, "character": 6}},
"id": {"const": {"declName": "Foo.Bla.ax1"}},
"cPos": 0}},
"data": ["«external:file:///completion2.lean»", 25, 6, 0, "cFoo.Bla.ex3"]},
{"label": "ex1",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 25, "character": 6}},
"id": {"const": {"declName": "Foo.Bla.ex1"}},
"cPos": 0}}],
"data": ["«external:file:///completion2.lean»", 25, 6, 0, "cFoo.Bla.ex1"]},
{"label": "ax1",
"kind": 23,
"data": ["«external:file:///completion2.lean»", 25, 6, 0, "cFoo.Bla.ax1"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 30, "character": 21}}
{"items":
[{"label": "ex3",
[{"label": "ex2",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 30, "character": 21}},
"id": {"const": {"declName": "Foo.Bla.ex3"}},
"cPos": 0}},
{"label": "ex2",
"data": ["«external:file:///completion2.lean»", 30, 21, 0, "cFoo.Bla.ex2"]},
{"label": "ex3",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 30, "character": 21}},
"id": {"const": {"declName": "Foo.Bla.ex2"}},
"cPos": 0}},
{"label": "ax1",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 30, "character": 21}},
"id": {"const": {"declName": "Foo.Bla.ax1"}},
"cPos": 0}},
"data": ["«external:file:///completion2.lean»", 30, 21, 0, "cFoo.Bla.ex3"]},
{"label": "ex1",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 30, "character": 21}},
"id": {"const": {"declName": "Foo.Bla.ex1"}},
"cPos": 0}}],
"data": ["«external:file:///completion2.lean»", 30, 21, 0, "cFoo.Bla.ex1"]},
{"label": "ax1",
"kind": 23,
"data": ["«external:file:///completion2.lean»", 30, 21, 0, "cFoo.Bla.ax1"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 37, "character": 22}}
{"items":
[{"label": "ex3",
[{"label": "ex2",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 37, "character": 22}},
"id": {"const": {"declName": "Foo.Bla.ex3"}},
"cPos": 0}},
{"label": "ex2",
"data": ["«external:file:///completion2.lean»", 37, 22, 0, "cFoo.Bla.ex2"]},
{"label": "ex3",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 37, "character": 22}},
"id": {"const": {"declName": "Foo.Bla.ex2"}},
"cPos": 0}},
"data": ["«external:file:///completion2.lean»", 37, 22, 0, "cFoo.Bla.ex3"]},
{"label": "ex1",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completion2.lean"},
"position": {"line": 37, "character": 22}},
"id": {"const": {"declName": "Foo.Bla.ex1"}},
"cPos": 0}}],
"data": ["«external:file:///completion2.lean»", 37, 22, 0, "cFoo.Bla.ex1"]}],
"isIncomplete": false}

View file

@ -3,110 +3,50 @@
{"items":
[{"label": "x",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 7, "character": 9}},
"id": {"const": {"declName": "S.x"}},
"cPos": 1}},
{"label": "y",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 7, "character": 9}},
"id": {"const": {"declName": "S.y"}},
"cPos": 1}},
"data": ["«external:file:///completion3.lean»", 7, 9, 1, "cS.x"]},
{"label": "b",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 7, "character": 9}},
"id": {"const": {"declName": "S.b"}},
"cPos": 1}}],
"data": ["«external:file:///completion3.lean»", 7, 9, 1, "cS.b"]},
{"label": "y",
"kind": 5,
"data": ["«external:file:///completion3.lean»", 7, 9, 1, "cS.y"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 12, "character": 5}}
{"items":
[{"label": "x",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 12, "character": 5}},
"id": {"const": {"declName": "S.x"}},
"cPos": 1}},
{"label": "y",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 12, "character": 5}},
"id": {"const": {"declName": "S.y"}},
"cPos": 1}},
"data": ["«external:file:///completion3.lean»", 12, 5, 1, "cS.x"]},
{"label": "b",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 12, "character": 5}},
"id": {"const": {"declName": "S.b"}},
"cPos": 1}}],
"data": ["«external:file:///completion3.lean»", 12, 5, 1, "cS.b"]},
{"label": "y",
"kind": 5,
"data": ["«external:file:///completion3.lean»", 12, 5, 1, "cS.y"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 16, "character": 5}}
{"items":
[{"label": "x",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 16, "character": 5}},
"id": {"const": {"declName": "S.x"}},
"cPos": 1}},
{"label": "y",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 16, "character": 5}},
"id": {"const": {"declName": "S.y"}},
"cPos": 1}},
"data": ["«external:file:///completion3.lean»", 16, 5, 1, "cS.x"]},
{"label": "b",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 16, "character": 5}},
"id": {"const": {"declName": "S.b"}},
"cPos": 1}}],
"data": ["«external:file:///completion3.lean»", 16, 5, 1, "cS.b"]},
{"label": "y",
"kind": 5,
"data": ["«external:file:///completion3.lean»", 16, 5, 1, "cS.y"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 20, "character": 5}}
{"items":
[{"label": "x",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 20, "character": 5}},
"id": {"const": {"declName": "S.x"}},
"cPos": 1}},
{"label": "y",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 20, "character": 5}},
"id": {"const": {"declName": "S.y"}},
"cPos": 1}},
"data": ["«external:file:///completion3.lean»", 20, 5, 1, "cS.x"]},
{"label": "b",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion3.lean"},
"position": {"line": 20, "character": 5}},
"id": {"const": {"declName": "S.b"}},
"cPos": 1}}],
"data": ["«external:file:///completion3.lean»", 20, 5, 1, "cS.b"]},
{"label": "y",
"kind": 5,
"data": ["«external:file:///completion3.lean»", 20, 5, 1, "cS.y"]}],
"isIncomplete": false}

View file

@ -1,112 +1,52 @@
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 7, "character": 4}}
{"items":
[{"label": "pred",
[{"label": "fn2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 7, "character": 4}},
"id": {"const": {"declName": "S.pred"}},
"cPos": 1}},
"data": ["«external:file:///completion4.lean»", 7, 4, 1, "cS.fn2"]},
{"label": "fn1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 7, "character": 4}},
"id": {"const": {"declName": "S.fn1"}},
"cPos": 1}},
{"label": "fn2",
"data": ["«external:file:///completion4.lean»", 7, 4, 1, "cS.fn1"]},
{"label": "pred",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 7, "character": 4}},
"id": {"const": {"declName": "S.fn2"}},
"cPos": 1}}],
"data": ["«external:file:///completion4.lean»", 7, 4, 1, "cS.pred"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 11, "character": 10}}
{"items":
[{"label": "pred",
[{"label": "fn2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 11, "character": 10}},
"id": {"const": {"declName": "S.pred"}},
"cPos": 1}},
"data": ["«external:file:///completion4.lean»", 11, 10, 1, "cS.fn2"]},
{"label": "fn1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 11, "character": 10}},
"id": {"const": {"declName": "S.fn1"}},
"cPos": 1}},
{"label": "fn2",
"data": ["«external:file:///completion4.lean»", 11, 10, 1, "cS.fn1"]},
{"label": "pred",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 11, "character": 10}},
"id": {"const": {"declName": "S.fn2"}},
"cPos": 1}}],
"data": ["«external:file:///completion4.lean»", 11, 10, 1, "cS.pred"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 16, "character": 11}}
{"items":
[{"label": "pred",
[{"label": "fn2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 16, "character": 11}},
"id": {"const": {"declName": "S.pred"}},
"cPos": 1}},
"data": ["«external:file:///completion4.lean»", 16, 11, 1, "cS.fn2"]},
{"label": "fn1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 16, "character": 11}},
"id": {"const": {"declName": "S.fn1"}},
"cPos": 1}},
{"label": "fn2",
"data": ["«external:file:///completion4.lean»", 16, 11, 1, "cS.fn1"]},
{"label": "pred",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 16, "character": 11}},
"id": {"const": {"declName": "S.fn2"}},
"cPos": 1}}],
"data": ["«external:file:///completion4.lean»", 16, 11, 1, "cS.pred"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 20, "character": 21}}
{"items":
[{"label": "pred",
[{"label": "fn2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 20, "character": 21}},
"id": {"const": {"declName": "S.pred"}},
"cPos": 1}},
"data": ["«external:file:///completion4.lean»", 20, 21, 1, "cS.fn2"]},
{"label": "fn1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 20, "character": 21}},
"id": {"const": {"declName": "S.fn1"}},
"cPos": 1}},
{"label": "fn2",
"data": ["«external:file:///completion4.lean»", 20, 21, 1, "cS.fn1"]},
{"label": "pred",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion4.lean"},
"position": {"line": 20, "character": 21}},
"id": {"const": {"declName": "S.fn2"}},
"cPos": 1}}],
"data": ["«external:file:///completion4.lean»", 20, 21, 1, "cS.pred"]}],
"isIncomplete": false}

View file

@ -1,28 +1,13 @@
{"textDocument": {"uri": "file:///completion5.lean"},
"position": {"line": 9, "character": 15}}
{"items":
[{"label": "f2",
[{"label": "f1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion5.lean"},
"position": {"line": 9, "character": 15}},
"id": {"const": {"declName": "C.f2"}},
"cPos": 1}},
"data": ["«external:file:///completion5.lean»", 9, 15, 1, "cC.f1"]},
{"label": "b1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion5.lean"},
"position": {"line": 9, "character": 15}},
"id": {"const": {"declName": "C.b1"}},
"cPos": 1}},
{"label": "f1",
"data": ["«external:file:///completion5.lean»", 9, 15, 1, "cC.b1"]},
{"label": "f2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion5.lean"},
"position": {"line": 9, "character": 15}},
"id": {"const": {"declName": "C.f1"}},
"cPos": 1}}],
"data": ["«external:file:///completion5.lean»", 9, 15, 1, "cC.f2"]}],
"isIncomplete": false}

View file

@ -1,96 +1,41 @@
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 12, "character": 15}}
{"items":
[{"label": "f3",
[{"label": "f1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 12, "character": 15}},
"id": {"const": {"declName": "D.f3"}},
"cPos": 1}},
{"label": "f2",
"data": ["«external:file:///completion6.lean»", 12, 15, 1, "cC.f1"]},
{"label": "f3",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 12, "character": 15}},
"id": {"const": {"declName": "C.f2"}},
"cPos": 1}},
"data": ["«external:file:///completion6.lean»", 12, 15, 1, "cD.f3"]},
{"label": "toC",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 12, "character": 15}},
"id": {"const": {"declName": "D.toC"}},
"cPos": 1}},
"data": ["«external:file:///completion6.lean»", 12, 15, 1, "cD.toC"]},
{"label": "b1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 12, "character": 15}},
"id": {"const": {"declName": "C.b1"}},
"cPos": 1}},
{"label": "f1",
"data": ["«external:file:///completion6.lean»", 12, 15, 1, "cC.b1"]},
{"label": "f2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 12, "character": 15}},
"id": {"const": {"declName": "C.f1"}},
"cPos": 1}}],
"data": ["«external:file:///completion6.lean»", 12, 15, 1, "cC.f2"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}}
{"items":
[{"label": "f3",
[{"label": "f1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}},
"id": {"const": {"declName": "D.f3"}},
"cPos": 1}},
{"label": "f2",
"data": ["«external:file:///completion6.lean»", 21, 4, 1, "cC.f1"]},
{"label": "f3",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}},
"id": {"const": {"declName": "C.f2"}},
"cPos": 1}},
{"label": "doubleF1",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}},
"id": {"const": {"declName": "E.doubleF1"}},
"cPos": 1}},
"data": ["«external:file:///completion6.lean»", 21, 4, 1, "cD.f3"]},
{"label": "toC",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}},
"id": {"const": {"declName": "D.toC"}},
"cPos": 1}},
"data": ["«external:file:///completion6.lean»", 21, 4, 1, "cD.toC"]},
{"label": "b1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}},
"id": {"const": {"declName": "C.b1"}},
"cPos": 1}},
{"label": "f1",
"data": ["«external:file:///completion6.lean»", 21, 4, 1, "cC.b1"]},
{"label": "doubleF1",
"kind": 3,
"data": ["«external:file:///completion6.lean»", 21, 4, 1, "cE.doubleF1"]},
{"label": "f2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion6.lean"},
"position": {"line": 21, "character": 4}},
"id": {"const": {"declName": "C.f1"}},
"cPos": 1}}],
"data": ["«external:file:///completion6.lean»", 21, 4, 1, "cC.f2"]}],
"isIncomplete": false}

View file

@ -3,38 +3,18 @@
{"items":
[{"label": "And",
"kind": 22,
"data":
{"params":
{"textDocument": {"uri": "file:///completion7.lean"},
"position": {"line": 6, "character": 10}},
"id": {"const": {"declName": "And"}},
"cPos": 0}}],
"data": ["«external:file:///completion7.lean»", 6, 10, 0, "cAnd"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completion7.lean"},
"position": {"line": 8, "character": 11}}
{"items":
[{"label": "mk",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///completion7.lean"},
"position": {"line": 8, "character": 11}},
"id": {"const": {"declName": "And.mk"}},
"cPos": 0}},
{"label": "left",
[{"label": "left",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion7.lean"},
"position": {"line": 8, "character": 11}},
"id": {"const": {"declName": "And.left"}},
"cPos": 0}},
"data": ["«external:file:///completion7.lean»", 8, 11, 0, "cAnd.left"]},
{"label": "right",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completion7.lean"},
"position": {"line": 8, "character": 11}},
"id": {"const": {"declName": "And.right"}},
"cPos": 0}}],
"data": ["«external:file:///completion7.lean»", 8, 11, 0, "cAnd.right"]},
{"label": "mk",
"kind": 4,
"data": ["«external:file:///completion7.lean»", 8, 11, 0, "cAnd.mk"]}],
"isIncomplete": false}

View file

@ -3,10 +3,5 @@
{"items":
[{"label": "gg",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///completionAtPrint.lean"},
"position": {"line": 2, "character": 10}},
"id": {"const": {"declName": "f.gg"}},
"cPos": 0}}],
"data": ["«external:file:///completionAtPrint.lean»", 2, 10, 0, "cf.gg"]}],
"isIncomplete": false}

View file

@ -4,17 +4,17 @@
[{"label": "AVerySpecificStructureName2",
"kind": 22,
"data":
{"params":
{"textDocument": {"uri": "file:///completionCheck.lean"},
"position": {"line": 6, "character": 33}},
"id": {"const": {"declName": "AVerySpecificStructureName2"}},
"cPos": 0}},
["«external:file:///completionCheck.lean»",
6,
33,
0,
"cAVerySpecificStructureName2"]},
{"label": "AVerySpecificStructureName",
"kind": 22,
"data":
{"params":
{"textDocument": {"uri": "file:///completionCheck.lean"},
"position": {"line": 6, "character": 33}},
"id": {"const": {"declName": "AVerySpecificStructureName"}},
"cPos": 0}}],
["«external:file:///completionCheck.lean»",
6,
33,
0,
"cAVerySpecificStructureName"]}],
"isIncomplete": false}

View file

@ -2,73 +2,73 @@
"position": {"line": 25, "character": 28}}
{"items":
[{"tags": [1],
"label": "foo4",
"kind": 3,
"data":
["«external:file:///completionDeprecation.lean»",
25,
28,
0,
"cSomeStructure.foo4"]},
{"tags": [1],
"label": "foo8",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completionDeprecation.lean"},
"position": {"line": 25, "character": 28}},
"id": {"const": {"declName": "SomeStructure.foo8"}},
"cPos": 0}},
["«external:file:///completionDeprecation.lean»",
25,
28,
0,
"cSomeStructure.foo8"]},
{"tags": [1],
"label": "foo5",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completionDeprecation.lean"},
"position": {"line": 25, "character": 28}},
"id": {"const": {"declName": "SomeStructure.foo5"}},
"cPos": 0}},
{"tags": [1],
"label": "foo4",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completionDeprecation.lean"},
"position": {"line": 25, "character": 28}},
"id": {"const": {"declName": "SomeStructure.foo4"}},
"cPos": 0}},
{"tags": [1],
"label": "foo3",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completionDeprecation.lean"},
"position": {"line": 25, "character": 28}},
"id": {"const": {"declName": "SomeStructure.foo3"}},
"cPos": 0}},
{"label": "foo2",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completionDeprecation.lean"},
"position": {"line": 25, "character": 28}},
"id": {"const": {"declName": "SomeStructure.foo2"}},
"cPos": 0}},
["«external:file:///completionDeprecation.lean»",
25,
28,
0,
"cSomeStructure.foo5"]},
{"tags": [1],
"label": "foo7",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completionDeprecation.lean"},
"position": {"line": 25, "character": 28}},
"id": {"const": {"declName": "SomeStructure.foo7"}},
"cPos": 0}},
["«external:file:///completionDeprecation.lean»",
25,
28,
0,
"cSomeStructure.foo7"]},
{"label": "foo1",
"kind": 3,
"data":
["«external:file:///completionDeprecation.lean»",
25,
28,
0,
"cSomeStructure.foo1"]},
{"tags": [1],
"label": "foo6",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completionDeprecation.lean"},
"position": {"line": 25, "character": 28}},
"id": {"const": {"declName": "SomeStructure.foo6"}},
"cPos": 0}},
{"label": "foo1",
["«external:file:///completionDeprecation.lean»",
25,
28,
0,
"cSomeStructure.foo6"]},
{"tags": [1],
"label": "foo3",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completionDeprecation.lean"},
"position": {"line": 25, "character": 28}},
"id": {"const": {"declName": "SomeStructure.foo1"}},
"cPos": 0}}],
["«external:file:///completionDeprecation.lean»",
25,
28,
0,
"cSomeStructure.foo3"]},
{"label": "foo2",
"kind": 3,
"data":
["«external:file:///completionDeprecation.lean»",
25,
28,
0,
"cSomeStructure.foo2"]}],
"isIncomplete": false}

View file

@ -3,10 +3,5 @@
{"items":
[{"label": "And",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///completionEOF.lean"},
"position": {"line": 8, "character": 9}},
"id": {"const": {"declName": "And"}},
"cPos": 0}}],
"data": ["«external:file:///completionEOF.lean»", 8, 9, 0, "cAnd"]}],
"isIncomplete": false}

View file

@ -1,46 +1,42 @@
{"textDocument": {"uri": "file:///completionFallback.lean"},
"position": {"line": 14, "character": 14}}
{"items":
[{"label": "noConfusionType",
[{"label": "up",
"kind": 4,
"data":
["«external:file:///completionFallback.lean»", 14, 14, 0, "cDirection.up"]},
{"label": "noConfusionType",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completionFallback.lean"},
"position": {"line": 14, "character": 14}},
"id": {"const": {"declName": "Direction.noConfusionType"}},
"cPos": 0}},
["«external:file:///completionFallback.lean»",
14,
14,
0,
"cDirection.noConfusionType"]},
{"label": "left",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///completionFallback.lean"},
"position": {"line": 14, "character": 14}},
"id": {"const": {"declName": "Direction.left"}},
"cPos": 0}},
{"label": "right",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///completionFallback.lean"},
"position": {"line": 14, "character": 14}},
"id": {"const": {"declName": "Direction.right"}},
"cPos": 0}},
{"label": "up",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///completionFallback.lean"},
"position": {"line": 14, "character": 14}},
"id": {"const": {"declName": "Direction.up"}},
"cPos": 0}},
["«external:file:///completionFallback.lean»",
14,
14,
0,
"cDirection.left"]},
{"label": "down",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///completionFallback.lean"},
"position": {"line": 14, "character": 14}},
"id": {"const": {"declName": "Direction.down"}},
"cPos": 0}}],
["«external:file:///completionFallback.lean»",
14,
14,
0,
"cDirection.down"]},
{"label": "right",
"kind": 4,
"data":
["«external:file:///completionFallback.lean»",
14,
14,
0,
"cDirection.right"]}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionFallback.lean"},
"position": {"line": 28, "character": 30}}
@ -48,25 +44,13 @@
[{"label": "mk",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///completionFallback.lean"},
"position": {"line": 28, "character": 30}},
"id": {"const": {"declName": "CustomAnd.mk"}},
"cPos": 0}},
{"label": "hb",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completionFallback.lean"},
"position": {"line": 28, "character": 30}},
"id": {"const": {"declName": "CustomAnd.hb"}},
"cPos": 0}},
["«external:file:///completionFallback.lean»", 28, 30, 0, "cCustomAnd.mk"]},
{"label": "ha",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///completionFallback.lean"},
"position": {"line": 28, "character": 30}},
"id": {"const": {"declName": "CustomAnd.ha"}},
"cPos": 0}}],
["«external:file:///completionFallback.lean»", 28, 30, 0, "cCustomAnd.ha"]},
{"label": "hb",
"kind": 23,
"data":
["«external:file:///completionFallback.lean»", 28, 30, 0, "cCustomAnd.hb"]}],
"isIncomplete": false}

View file

@ -4,9 +4,9 @@
[{"label": "mk",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///completionFromExpectedType.lean"},
"position": {"line": 3, "character": 18}},
"id": {"const": {"declName": "Foo.mk"}},
"cPos": 0}}],
["«external:file:///completionFromExpectedType.lean»",
3,
18,
0,
"cFoo.mk"]}],
"isIncomplete": false}

View file

@ -1,28 +1,13 @@
{"textDocument": {"uri": "file:///completionIStr.lean"},
"position": {"line": 5, "character": 34}}
{"items":
[{"label": "f2",
[{"label": "f1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completionIStr.lean"},
"position": {"line": 5, "character": 34}},
"id": {"const": {"declName": "C.f2"}},
"cPos": 1}},
"data": ["«external:file:///completionIStr.lean»", 5, 34, 1, "cC.f1"]},
{"label": "b1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completionIStr.lean"},
"position": {"line": 5, "character": 34}},
"id": {"const": {"declName": "C.b1"}},
"cPos": 1}},
{"label": "f1",
"data": ["«external:file:///completionIStr.lean»", 5, 34, 1, "cC.b1"]},
{"label": "f2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completionIStr.lean"},
"position": {"line": 5, "character": 34}},
"id": {"const": {"declName": "C.f1"}},
"cPos": 1}}],
"data": ["«external:file:///completionIStr.lean»", 5, 34, 1, "cC.f2"]}],
"isIncomplete": false}

View file

@ -4,11 +4,9 @@
[{"label": "verySpecificDefinitionNameOfCompletionOpenNamespaces",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///completionOpenNamespaces.lean"},
"position": {"line": 4, "character": 68}},
"id":
{"const":
{"declName": "A.B1.verySpecificDefinitionNameOfCompletionOpenNamespaces"}},
"cPos": 0}}],
["«external:file:///completionOpenNamespaces.lean»",
4,
68,
0,
"cA.B1.verySpecificDefinitionNameOfCompletionOpenNamespaces"]}],
"isIncomplete": false}

View file

@ -1,89 +1,9 @@
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}}
{"items":
[{"textEdit":
{"replace":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}},
"newText": "trace.PrettyPrinter.format",
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"label": "trace.PrettyPrinter.format",
[{"label": "format.unicode",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}},
"cPos": 0}},
{"textEdit":
{"replace":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}},
"newText": "trace.PrettyPrinter.format.input",
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"label": "trace.PrettyPrinter.format.input",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}},
"cPos": 0}},
{"textEdit":
{"replace":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}},
"newText": "format.inputWidth",
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"label": "format.inputWidth",
"kind": 10,
"detail": "(100), ideal input width",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}},
"cPos": 0}},
{"textEdit":
{"replace":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}},
"newText": "format.width",
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"label": "format.width",
"kind": 10,
"detail": "(120), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}},
"cPos": 0}},
{"textEdit":
{"replace":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}},
"newText": "format.indent",
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"label": "format.indent",
"kind": 10,
"detail": "(2), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}},
"cPos": 0}},
{"textEdit":
"edit":
{"replace":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}},
@ -91,15 +11,73 @@
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"label": "format.unicode",
"kind": 10,
"detail": "(true), unicode characters",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}},
"cPos": 0}},
{"textEdit":
"data": ["«external:file:///completionOption.lean»", 1, 17, 0]},
{"label": "format.width",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}},
"newText": "format.width",
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"detail": "(120), indentation",
"data": ["«external:file:///completionOption.lean»", 1, 17, 0]},
{"label": "format.inputWidth",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}},
"newText": "format.inputWidth",
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"detail": "(100), ideal input width",
"data": ["«external:file:///completionOption.lean»", 1, 17, 0]},
{"label": "trace.PrettyPrinter.format.input",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}},
"newText": "trace.PrettyPrinter.format.input",
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data": ["«external:file:///completionOption.lean»", 1, 17, 0]},
{"label": "trace.PrettyPrinter.format",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}},
"newText": "trace.PrettyPrinter.format",
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data": ["«external:file:///completionOption.lean»", 1, 17, 0]},
{"label": "format.indent",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}},
"newText": "format.indent",
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"detail": "(2), indentation",
"data": ["«external:file:///completionOption.lean»", 1, 17, 0]},
{"label": "trace.PrettyPrinter.format.backtrack",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}},
@ -107,20 +85,16 @@
"insert":
{"start": {"line": 1, "character": 11},
"end": {"line": 1, "character": 17}}},
"label": "trace.PrettyPrinter.format.backtrack",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 1, "character": 17}},
"cPos": 0}}],
"data": ["«external:file:///completionOption.lean»", 1, 17, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 4, "character": 20}}
{"items":
[{"textEdit":
[{"label": "format.inputWidth",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 4, "character": 11},
"end": {"line": 4, "character": 20}},
@ -128,15 +102,11 @@
"insert":
{"start": {"line": 4, "character": 11},
"end": {"line": 4, "character": 20}}},
"label": "format.inputWidth",
"kind": 10,
"detail": "(100), ideal input width",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 4, "character": 20}},
"cPos": 0}},
{"textEdit":
"data": ["«external:file:///completionOption.lean»", 4, 20, 0]},
{"label": "trace.PrettyPrinter.format.input",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 4, "character": 11},
"end": {"line": 4, "character": 20}},
@ -144,16 +114,12 @@
"insert":
{"start": {"line": 4, "character": 11},
"end": {"line": 4, "character": 20}}},
"label": "trace.PrettyPrinter.format.input",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 4, "character": 20}},
"cPos": 0}},
{"textEdit":
"data": ["«external:file:///completionOption.lean»", 4, 20, 0]},
{"label": "format.indent",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 4, "character": 11},
"end": {"line": 4, "character": 20}},
@ -161,19 +127,15 @@
"insert":
{"start": {"line": 4, "character": 11},
"end": {"line": 4, "character": 20}}},
"label": "format.indent",
"kind": 10,
"detail": "(2), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 4, "character": 20}},
"cPos": 0}}],
"data": ["«external:file:///completionOption.lean»", 4, 20, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 7, "character": 23}}
{"items":
[{"textEdit":
[{"label": "trace.Compiler.specialize.candidate",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}},
@ -181,50 +143,12 @@
"insert":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}}},
"label": "trace.Compiler.specialize.candidate",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 7, "character": 23}},
"cPos": 0}},
{"textEdit":
{"replace":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}},
"newText": "trace.pp.analyze",
"insert":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}}},
"label": "trace.pp.analyze",
"data": ["«external:file:///completionOption.lean»", 7, 23, 0]},
{"label": "trace.pp.analyze.error",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 7, "character": 23}},
"cPos": 0}},
{"textEdit":
{"replace":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}},
"newText": "trace.pp.analyze.tryUnify",
"insert":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}}},
"label": "trace.pp.analyze.tryUnify",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 7, "character": 23}},
"cPos": 0}},
{"textEdit":
"edit":
{"replace":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}},
@ -232,16 +156,38 @@
"insert":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}}},
"label": "trace.pp.analyze.error",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 7, "character": 23}},
"cPos": 0}},
{"textEdit":
"data": ["«external:file:///completionOption.lean»", 7, 23, 0]},
{"label": "trace.pp.analyze",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}},
"newText": "trace.pp.analyze",
"insert":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}}},
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data": ["«external:file:///completionOption.lean»", 7, 23, 0]},
{"label": "trace.pp.analyze.tryUnify",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}},
"newText": "trace.pp.analyze.tryUnify",
"insert":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}}},
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data": ["«external:file:///completionOption.lean»", 7, 23, 0]},
{"label": "trace.pp.analyze.annotate",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}},
@ -249,37 +195,16 @@
"insert":
{"start": {"line": 7, "character": 11},
"end": {"line": 7, "character": 23}}},
"label": "trace.pp.analyze.annotate",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 7, "character": 23}},
"cPos": 0}}],
"data": ["«external:file:///completionOption.lean»", 7, 23, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 10, "character": 27}}
{"items":
[{"textEdit":
{"replace":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}},
"newText": "trace.pp.analyze.tryUnify",
"insert":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}}},
"label": "trace.pp.analyze.tryUnify",
[{"label": "trace.pp.analyze.error",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 10, "character": 27}},
"cPos": 0}},
{"textEdit":
"edit":
{"replace":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}},
@ -287,16 +212,12 @@
"insert":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}}},
"label": "trace.pp.analyze.error",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 10, "character": 27}},
"cPos": 0}},
{"textEdit":
"data": ["«external:file:///completionOption.lean»", 10, 27, 0]},
{"label": "trace.pp.analyze",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}},
@ -304,16 +225,25 @@
"insert":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}}},
"label": "trace.pp.analyze",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 10, "character": 27}},
"cPos": 0}},
{"textEdit":
"data": ["«external:file:///completionOption.lean»", 10, 27, 0]},
{"label": "trace.pp.analyze.tryUnify",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}},
"newText": "trace.pp.analyze.tryUnify",
"insert":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}}},
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data": ["«external:file:///completionOption.lean»", 10, 27, 0]},
{"label": "trace.pp.analyze.annotate",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}},
@ -321,36 +251,28 @@
"insert":
{"start": {"line": 10, "character": 11},
"end": {"line": 10, "character": 27}}},
"label": "trace.pp.analyze.annotate",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 10, "character": 27}},
"cPos": 0}}],
"data": ["«external:file:///completionOption.lean»", 10, 27, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}}
{"items":
[{"textEdit":
[{"label": "format.unicode",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}},
"newText": "format.indent",
"newText": "format.unicode",
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"label": "format.indent",
"detail": "(true), unicode characters",
"data": ["«external:file:///completionOption.lean»", 13, 17, 0]},
{"label": "format.width",
"kind": 10,
"detail": "(2), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}},
"cPos": 0}},
{"textEdit":
"edit":
{"replace":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}},
@ -358,49 +280,11 @@
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"label": "format.width",
"kind": 10,
"detail": "(120), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}},
"cPos": 0}},
{"textEdit":
{"replace":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}},
"newText": "trace.PrettyPrinter.format.input",
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"label": "trace.PrettyPrinter.format.input",
"data": ["«external:file:///completionOption.lean»", 13, 17, 0]},
{"label": "format.inputWidth",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}},
"cPos": 0}},
{"textEdit":
{"replace":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}},
"newText": "trace.PrettyPrinter.format.backtrack",
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"label": "trace.PrettyPrinter.format.backtrack",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}},
"cPos": 0}},
{"textEdit":
"edit":
{"replace":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}},
@ -408,15 +292,24 @@
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"label": "format.inputWidth",
"kind": 10,
"detail": "(100), ideal input width",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}},
"cPos": 0}},
{"textEdit":
"data": ["«external:file:///completionOption.lean»", 13, 17, 0]},
{"label": "trace.PrettyPrinter.format.input",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}},
"newText": "trace.PrettyPrinter.format.input",
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data": ["«external:file:///completionOption.lean»", 13, 17, 0]},
{"label": "trace.PrettyPrinter.format",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}},
@ -424,36 +317,41 @@
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"label": "trace.PrettyPrinter.format",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}},
"cPos": 0}},
{"textEdit":
"data": ["«external:file:///completionOption.lean»", 13, 17, 0]},
{"label": "format.indent",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}},
"newText": "format.unicode",
"newText": "format.indent",
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"label": "format.unicode",
"detail": "(2), indentation",
"data": ["«external:file:///completionOption.lean»", 13, 17, 0]},
{"label": "trace.PrettyPrinter.format.backtrack",
"kind": 10,
"detail": "(true), unicode characters",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 13, "character": 17}},
"cPos": 0}}],
"edit":
{"replace":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}},
"newText": "trace.PrettyPrinter.format.backtrack",
"insert":
{"start": {"line": 13, "character": 11},
"end": {"line": 13, "character": 17}}},
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data": ["«external:file:///completionOption.lean»", 13, 17, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}}
{"items":
[{"textEdit":
[{"label": "format.unicode",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}},
@ -461,31 +359,11 @@
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"label": "format.unicode",
"kind": 10,
"detail": "(true), unicode characters",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}},
"cPos": 0}},
{"textEdit":
{"replace":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}},
"newText": "format.inputWidth",
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"label": "format.inputWidth",
"data": ["«external:file:///completionOption.lean»", 16, 18, 0]},
{"label": "format.width",
"kind": 10,
"detail": "(100), ideal input width",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}},
"cPos": 0}},
{"textEdit":
"edit":
{"replace":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}},
@ -493,48 +371,23 @@
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"label": "format.width",
"kind": 10,
"detail": "(120), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}},
"cPos": 0}},
{"textEdit":
"data": ["«external:file:///completionOption.lean»", 16, 18, 0]},
{"label": "format.inputWidth",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}},
"newText": "format.indent",
"newText": "format.inputWidth",
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"label": "format.indent",
"detail": "(100), ideal input width",
"data": ["«external:file:///completionOption.lean»", 16, 18, 0]},
{"label": "trace.PrettyPrinter.format.input",
"kind": 10,
"detail": "(2), indentation",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}},
"cPos": 0}},
{"textEdit":
{"replace":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}},
"newText": "trace.PrettyPrinter.format.backtrack",
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"label": "trace.PrettyPrinter.format.backtrack",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}},
"cPos": 0}},
{"textEdit":
"edit":
{"replace":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}},
@ -542,13 +395,32 @@
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"label": "trace.PrettyPrinter.format.input",
"kind": 10,
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data":
{"params":
{"textDocument": {"uri": "file:///completionOption.lean"},
"position": {"line": 16, "character": 18}},
"cPos": 0}}],
"data": ["«external:file:///completionOption.lean»", 16, 18, 0]},
{"label": "format.indent",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}},
"newText": "format.indent",
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"detail": "(2), indentation",
"data": ["«external:file:///completionOption.lean»", 16, 18, 0]},
{"label": "trace.PrettyPrinter.format.backtrack",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}},
"newText": "trace.PrettyPrinter.format.backtrack",
"insert":
{"start": {"line": 16, "character": 11},
"end": {"line": 16, "character": 18}}},
"detail":
"(false), enable/disable tracing for the given module and submodules",
"data": ["«external:file:///completionOption.lean»", 16, 18, 0]}],
"isIncomplete": false}

View file

@ -4,18 +4,13 @@
[{"label": "veryLongDefinitionName",
"kind": 6,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrefixIssue.lean"},
"position": {"line": 1, "character": 64}},
"id": {"fvar": {"id": "_uniq.35"}},
"cPos": 0}},
["«external:file:///completionPrefixIssue.lean»", 1, 64, 0, "f_uniq.35"]},
{"label": "veryLongDefinitionNameVeryLongDefinitionName",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrefixIssue.lean"},
"position": {"line": 1, "character": 64}},
"id":
{"const": {"declName": "veryLongDefinitionNameVeryLongDefinitionName"}},
"cPos": 0}}],
["«external:file:///completionPrefixIssue.lean»",
1,
64,
0,
"cveryLongDefinitionNameVeryLongDefinitionName"]}],
"isIncomplete": false}

View file

@ -4,12 +4,9 @@
[{"label": "x",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrivateTypes.lean"},
"position": {"line": 3, "character": 26}},
"id":
{"const":
{"declName":
"_private.«external:file:///completionPrivateTypes.lean».0.Foo.x"}},
"cPos": 1}}],
["«external:file:///completionPrivateTypes.lean»",
3,
26,
1,
"c_private.«external:file:///completionPrivateTypes.lean».0.Foo.x"]}],
"isIncomplete": false}

View file

@ -4,14 +4,11 @@
[{"label": "longAndHopefullyUniqueBlaBlaBoo",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 2, "character": 33}},
"id":
{"const":
{"declName":
"_private.«external:file:///completionPrv.lean».0.longAndHopefullyUniqueBlaBlaBoo"}},
"cPos": 0}}],
["«external:file:///completionPrv.lean»",
2,
33,
0,
"c_private.«external:file:///completionPrv.lean».0.longAndHopefullyUniqueBlaBlaBoo"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 9, "character": 33}}
@ -19,14 +16,11 @@
[{"label": "longAndHopefullyUniqueBooBoo",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 9, "character": 33}},
"id":
{"const":
{"declName":
"_private.«external:file:///completionPrv.lean».0.Foo.longAndHopefullyUniqueBooBoo"}},
"cPos": 0}}],
["«external:file:///completionPrv.lean»",
9,
33,
0,
"c_private.«external:file:///completionPrv.lean».0.Foo.longAndHopefullyUniqueBooBoo"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 21, "character": 5}}
@ -34,21 +28,14 @@
[{"label": "getInc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 21, "character": 5}},
"id":
{"const":
{"declName": "_private.«external:file:///completionPrv.lean».0.S.getInc"}},
"cPos": 1}},
["«external:file:///completionPrv.lean»",
21,
5,
1,
"c_private.«external:file:///completionPrv.lean».0.S.getInc"]},
{"label": "field1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 21, "character": 5}},
"id": {"const": {"declName": "S.field1"}},
"cPos": 1}}],
"data": ["«external:file:///completionPrv.lean»", 21, 5, 1, "cS.field1"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 25, "character": 4}}
@ -56,19 +43,12 @@
[{"label": "getInc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 25, "character": 4}},
"id":
{"const":
{"declName": "_private.«external:file:///completionPrv.lean».0.S.getInc"}},
"cPos": 1}},
["«external:file:///completionPrv.lean»",
25,
4,
1,
"c_private.«external:file:///completionPrv.lean».0.S.getInc"]},
{"label": "field1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///completionPrv.lean"},
"position": {"line": 25, "character": 4}},
"id": {"const": {"declName": "S.field1"}},
"cPos": 1}}],
"data": ["«external:file:///completionPrv.lean»", 25, 4, 1, "cS.field1"]}],
"isIncomplete": false}

View file

@ -1,166 +1,94 @@
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 10, "character": 17}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 10, "character": 17}},
"cPos": 0}},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 10, "character": 17}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 10, 17, 0]},
{"label": "bar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 10, "character": 17}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 10, 17, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 10, "character": 17}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 10, 17, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data": ["«external:file:///completionStructureInstance.lean»", 10, 17, 0]}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 13, "character": 18}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 13, "character": 18}},
"cPos": 0}},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 13, "character": 18}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 13, 18, 0]},
{"label": "bar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 13, "character": 18}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 13, 18, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 13, "character": 18}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 13, 18, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data": ["«external:file:///completionStructureInstance.lean»", 13, 18, 0]}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 17, "character": 2}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 17, "character": 2}},
"cPos": 0}},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 17, "character": 2}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 17, 2, 0]},
{"label": "bar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 17, "character": 2}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 17, 2, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 17, "character": 2}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 17, 2, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data": ["«external:file:///completionStructureInstance.lean»", 17, 2, 0]}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 21, "character": 3}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 21, "character": 3}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 21, 3, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 21, "character": 3}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 21, 3, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 21, "character": 3}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 21, 3, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 25, "character": 5}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 25, "character": 5}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 25, 5, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 25, "character": 5}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 25, 5, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 25, "character": 5}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 25, 5, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 29, "character": 9}}
@ -171,202 +99,114 @@
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 39, "character": 2}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 39, "character": 2}},
"cPos": 0}},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 39, "character": 2}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 39, 2, 0]},
{"label": "bar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 39, "character": 2}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 39, 2, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 39, "character": 2}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 39, 2, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data": ["«external:file:///completionStructureInstance.lean»", 39, 2, 0]}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 43, "character": 12}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 43, "character": 12}},
"cPos": 0}},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 43, "character": 12}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 43, 12, 0]},
{"label": "bar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 43, "character": 12}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 43, 12, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 43, "character": 12}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 43, 12, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data": ["«external:file:///completionStructureInstance.lean»", 43, 12, 0]}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 46, "character": 17}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 46, "character": 17}},
"cPos": 0}},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 46, "character": 17}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 46, 17, 0]},
{"label": "bar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 46, "character": 17}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 46, 17, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 46, "character": 17}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 46, 17, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data": ["«external:file:///completionStructureInstance.lean»", 46, 17, 0]}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 50, "character": 2}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 50, "character": 2}},
"cPos": 0}},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 50, "character": 2}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 50, 2, 0]},
{"label": "bar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 50, "character": 2}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 50, 2, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 50, "character": 2}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 50, 2, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data": ["«external:file:///completionStructureInstance.lean»", 50, 2, 0]}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 55, "character": 3}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 55, "character": 3}},
"cPos": 1}},
"data": ["«external:file:///completionStructureInstance.lean»", 55, 3, 1]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 55, "character": 3}},
"cPos": 1}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 55, 3, 1]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 55, "character": 3}},
"cPos": 1}}],
"data": ["«external:file:///completionStructureInstance.lean»", 55, 3, 1]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 60, "character": 5}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 60, "character": 5}},
"cPos": 1}},
"data": ["«external:file:///completionStructureInstance.lean»", 60, 5, 1]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 60, "character": 5}},
"cPos": 1}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 60, 5, 1]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 60, "character": 5}},
"cPos": 1}}],
"data": ["«external:file:///completionStructureInstance.lean»", 60, 5, 1]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 66, "character": 4}}
@ -374,210 +214,118 @@
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 72, "character": 2}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 72, "character": 2}},
"cPos": 0}},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 72, "character": 2}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 72, 2, 0]},
{"label": "bar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 72, "character": 2}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 72, 2, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 72, "character": 2}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 72, 2, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data": ["«external:file:///completionStructureInstance.lean»", 72, 2, 0]}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 78, "character": 4}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 78, "character": 4}},
"cPos": 0}},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 78, "character": 4}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 78, 4, 0]},
{"label": "bar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 78, "character": 4}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 78, 4, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 78, "character": 4}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 78, 4, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data": ["«external:file:///completionStructureInstance.lean»", 78, 4, 0]}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 82, "character": 27}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 82, "character": 27}},
"cPos": 0}},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 82, "character": 27}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 82, 27, 0]},
{"label": "bar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 82, "character": 27}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 82, 27, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 82, "character": 27}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 82, 27, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data": ["«external:file:///completionStructureInstance.lean»", 82, 27, 0]}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 85, "character": 32}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 85, "character": 32}},
"cPos": 0}},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 85, "character": 32}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 85, 32, 0]},
{"label": "bar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 85, "character": 32}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 85, 32, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 85, "character": 32}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 85, 32, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data": ["«external:file:///completionStructureInstance.lean»", 85, 32, 0]}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 88, "character": 32}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 88, "character": 32}},
"cPos": 0}},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 88, "character": 32}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 88, 32, 0]},
{"label": "bar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 88, "character": 32}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 88, 32, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 88, "character": 32}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 88, 32, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data": ["«external:file:///completionStructureInstance.lean»", 88, 32, 0]}],
"isIncomplete": true}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 91, "character": 33}}
{"items":
[{"label": "barfoo",
[{"label": "foo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 91, "character": 33}},
"cPos": 0}},
"data": ["«external:file:///completionStructureInstance.lean»", 91, 33, 0]},
{"label": "foobar",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 91, "character": 33}},
"cPos": 0}},
{"label": "foo",
"data": ["«external:file:///completionStructureInstance.lean»", 91, 33, 0]},
{"label": "barfoo",
"kind": 5,
"detail": "field",
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 91, "character": 33}},
"cPos": 0}}],
"data": ["«external:file:///completionStructureInstance.lean»", 91, 33, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 96, "character": 52}}
@ -585,9 +333,9 @@
[{"label": "aLongUniqueIdentifier",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///completionStructureInstance.lean"},
"position": {"line": 96, "character": 52}},
"id": {"const": {"declName": "aLongUniqueIdentifier"}},
"cPos": 0}}],
["«external:file:///completionStructureInstance.lean»",
96,
52,
0,
"caLongUniqueIdentifier"]}],
"isIncomplete": false}

File diff suppressed because it is too large Load diff

View file

@ -1,20 +1,10 @@
{"textDocument": {"uri": "file:///dotIdCompletion.lean"},
"position": {"line": 4, "character": 5}}
{"items":
[{"label": "truth",
[{"label": "true",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///dotIdCompletion.lean"},
"position": {"line": 4, "character": 5}},
"id": {"const": {"declName": "Boo.truth"}},
"cPos": 0}},
{"label": "true",
"data": ["«external:file:///dotIdCompletion.lean»", 4, 5, 0, "cBoo.true"]},
{"label": "truth",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///dotIdCompletion.lean"},
"position": {"line": 4, "character": 5}},
"id": {"const": {"declName": "Boo.true"}},
"cPos": 0}}],
"data": ["«external:file:///dotIdCompletion.lean»", 4, 5, 0, "cBoo.truth"]}],
"isIncomplete": false}

View file

@ -4,11 +4,7 @@
[{"label": "zero",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///dottedIdentNotation.lean"},
"position": {"line": 11, "character": 22}},
"id": {"const": {"declName": "MyNat.zero"}},
"cPos": 0}}],
["«external:file:///dottedIdentNotation.lean»", 11, 22, 0, "cMyNat.zero"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///dottedIdentNotation.lean"},
"position": {"line": 14, "character": 30}}
@ -16,11 +12,7 @@
[{"label": "succ",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///dottedIdentNotation.lean"},
"position": {"line": 14, "character": 30}},
"id": {"const": {"declName": "MyNat.succ"}},
"cPos": 0}}],
["«external:file:///dottedIdentNotation.lean»", 14, 30, 0, "cMyNat.succ"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///dottedIdentNotation.lean"},
"position": {"line": 23, "character": 23}}
@ -28,11 +20,7 @@
[{"label": "zero",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///dottedIdentNotation.lean"},
"position": {"line": 23, "character": 23}},
"id": {"const": {"declName": "MyNat.zero"}},
"cPos": 0}}],
["«external:file:///dottedIdentNotation.lean»", 23, 23, 0, "cMyNat.zero"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///dottedIdentNotation.lean"},
"position": {"line": 26, "character": 32}}
@ -40,11 +28,7 @@
[{"label": "succ",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///dottedIdentNotation.lean"},
"position": {"line": 26, "character": 32}},
"id": {"const": {"declName": "MyNat.succ"}},
"cPos": 0}}],
["«external:file:///dottedIdentNotation.lean»", 26, 32, 0, "cMyNat.succ"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///dottedIdentNotation.lean"},
"position": {"line": 33, "character": 31}}
@ -52,11 +36,7 @@
[{"label": "zero",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///dottedIdentNotation.lean"},
"position": {"line": 33, "character": 31}},
"id": {"const": {"declName": "MyNat.zero"}},
"cPos": 0}}],
["«external:file:///dottedIdentNotation.lean»", 33, 31, 0, "cMyNat.zero"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///dottedIdentNotation.lean"},
"position": {"line": 38, "character": 31}}
@ -67,11 +47,7 @@
[{"label": "zero",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///dottedIdentNotation.lean"},
"position": {"line": 51, "character": 24}},
"id": {"const": {"declName": "MyNat.zero"}},
"cPos": 0}}],
["«external:file:///dottedIdentNotation.lean»", 51, 24, 0, "cMyNat.zero"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///dottedIdentNotation.lean"},
"position": {"line": 64, "character": 32}}
@ -79,9 +55,5 @@
[{"label": "succ",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///dottedIdentNotation.lean"},
"position": {"line": 64, "character": 32}},
"id": {"const": {"declName": "MyNat.succ"}},
"cPos": 0}}],
["«external:file:///dottedIdentNotation.lean»", 64, 32, 0, "cMyNat.succ"]}],
"isIncomplete": false}

View file

@ -3,10 +3,5 @@
{"items":
[{"label": "foo",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///editCompletion.lean"},
"position": {"line": 3, "character": 22}},
"id": {"const": {"declName": "Foo.foo"}},
"cPos": 1}}],
"data": ["«external:file:///editCompletion.lean»", 3, 22, 1, "cFoo.foo"]}],
"isIncomplete": false}

View file

@ -1,24 +1,9 @@
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 28, "character": 30}}
{"items":
[{"textEdit":
{"replace":
{"start": {"line": 28, "character": 23},
"end": {"line": 28, "character": 30}},
"newText": "testPkg.bar",
"insert":
{"start": {"line": 28, "character": 23},
"end": {"line": 28, "character": 30}}},
"label": "testPkg.bar",
[{"label": "testPkg.foo2",
"kind": 10,
"documentation": {"value": "(error) Error 0", "kind": "markdown"},
"detail": "error name",
"data":
{"params":
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 28, "character": 30}},
"cPos": 0}},
{"textEdit":
"edit":
{"replace":
{"start": {"line": 28, "character": 23},
"end": {"line": 28, "character": 30}},
@ -26,16 +11,25 @@
"insert":
{"start": {"line": 28, "character": 23},
"end": {"line": 28, "character": 30}}},
"label": "testPkg.foo2",
"kind": 10,
"documentation": {"value": "(error) Error 2", "kind": "markdown"},
"detail": "error name",
"data":
{"params":
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 28, "character": 30}},
"cPos": 0}},
{"textEdit":
"data": ["«external:file:///errorExplanationInteractive.lean»", 28, 30, 0]},
{"label": "testPkg.bar",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 28, "character": 23},
"end": {"line": 28, "character": 30}},
"newText": "testPkg.bar",
"insert":
{"start": {"line": 28, "character": 23},
"end": {"line": 28, "character": 30}}},
"documentation": {"value": "(error) Error 0", "kind": "markdown"},
"detail": "error name",
"data": ["«external:file:///errorExplanationInteractive.lean»", 28, 30, 0]},
{"label": "testPkg.foo1",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 28, "character": 23},
"end": {"line": 28, "character": 30}},
@ -43,20 +37,29 @@
"insert":
{"start": {"line": 28, "character": 23},
"end": {"line": 28, "character": 30}}},
"label": "testPkg.foo1",
"kind": 10,
"documentation": {"value": "(error) Error 1", "kind": "markdown"},
"detail": "error name",
"data":
{"params":
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 28, "character": 30}},
"cPos": 0}}],
"data": ["«external:file:///errorExplanationInteractive.lean»", 28, 30, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 30, "character": 31}}
{"items":
[{"textEdit":
[{"label": "testPkg.foo2",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 30, "character": 23},
"end": {"line": 30, "character": 31}},
"newText": "testPkg.foo2",
"insert":
{"start": {"line": 30, "character": 23},
"end": {"line": 30, "character": 31}}},
"documentation": {"value": "(error) Error 2", "kind": "markdown"},
"detail": "error name",
"data": ["«external:file:///errorExplanationInteractive.lean»", 30, 31, 0]},
{"label": "testPkg.bar",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 30, "character": 23},
"end": {"line": 30, "character": 31}},
@ -64,33 +67,12 @@
"insert":
{"start": {"line": 30, "character": 23},
"end": {"line": 30, "character": 31}}},
"label": "testPkg.bar",
"kind": 10,
"documentation": {"value": "(error) Error 0", "kind": "markdown"},
"detail": "error name",
"data":
{"params":
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 30, "character": 31}},
"cPos": 0}},
{"textEdit":
{"replace":
{"start": {"line": 30, "character": 23},
"end": {"line": 30, "character": 31}},
"newText": "testPkg.foo2",
"insert":
{"start": {"line": 30, "character": 23},
"end": {"line": 30, "character": 31}}},
"label": "testPkg.foo2",
"data": ["«external:file:///errorExplanationInteractive.lean»", 30, 31, 0]},
{"label": "testPkg.foo1",
"kind": 10,
"documentation": {"value": "(error) Error 2", "kind": "markdown"},
"detail": "error name",
"data":
{"params":
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 30, "character": 31}},
"cPos": 0}},
{"textEdit":
"edit":
{"replace":
{"start": {"line": 30, "character": 23},
"end": {"line": 30, "character": 31}},
@ -98,20 +80,16 @@
"insert":
{"start": {"line": 30, "character": 23},
"end": {"line": 30, "character": 31}}},
"label": "testPkg.foo1",
"kind": 10,
"documentation": {"value": "(error) Error 1", "kind": "markdown"},
"detail": "error name",
"data":
{"params":
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 30, "character": 31}},
"cPos": 0}}],
"data": ["«external:file:///errorExplanationInteractive.lean»", 30, 31, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 32, "character": 32}}
{"items":
[{"textEdit":
[{"label": "testPkg.foo2",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 32, "character": 23},
"end": {"line": 32, "character": 32}},
@ -119,16 +97,12 @@
"insert":
{"start": {"line": 32, "character": 23},
"end": {"line": 32, "character": 32}}},
"label": "testPkg.foo2",
"kind": 10,
"documentation": {"value": "(error) Error 2", "kind": "markdown"},
"detail": "error name",
"data":
{"params":
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 32, "character": 32}},
"cPos": 0}},
{"textEdit":
"data": ["«external:file:///errorExplanationInteractive.lean»", 32, 32, 0]},
{"label": "testPkg.foo1",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 32, "character": 23},
"end": {"line": 32, "character": 32}},
@ -136,37 +110,16 @@
"insert":
{"start": {"line": 32, "character": 23},
"end": {"line": 32, "character": 32}}},
"label": "testPkg.foo1",
"kind": 10,
"documentation": {"value": "(error) Error 1", "kind": "markdown"},
"detail": "error name",
"data":
{"params":
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 32, "character": 32}},
"cPos": 0}}],
"data": ["«external:file:///errorExplanationInteractive.lean»", 32, 32, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 34, "character": 32}}
{"items":
[{"textEdit":
{"replace":
{"start": {"line": 34, "character": 23},
"end": {"line": 34, "character": 32}},
"newText": "testPkg.foo1",
"insert":
{"start": {"line": 34, "character": 23},
"end": {"line": 34, "character": 32}}},
"label": "testPkg.foo1",
[{"label": "testPkg.foo2",
"kind": 10,
"documentation": {"value": "(error) Error 1", "kind": "markdown"},
"detail": "error name",
"data":
{"params":
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 34, "character": 32}},
"cPos": 0}},
{"textEdit":
"edit":
{"replace":
{"start": {"line": 34, "character": 23},
"end": {"line": 34, "character": 32}},
@ -174,15 +127,22 @@
"insert":
{"start": {"line": 34, "character": 23},
"end": {"line": 34, "character": 32}}},
"label": "testPkg.foo2",
"kind": 10,
"documentation": {"value": "(error) Error 2", "kind": "markdown"},
"detail": "error name",
"data":
{"params":
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 34, "character": 32}},
"cPos": 0}}],
"data": ["«external:file:///errorExplanationInteractive.lean»", 34, 32, 0]},
{"label": "testPkg.foo1",
"kind": 10,
"edit":
{"replace":
{"start": {"line": 34, "character": 23},
"end": {"line": 34, "character": 32}},
"newText": "testPkg.foo1",
"insert":
{"start": {"line": 34, "character": 23},
"end": {"line": 34, "character": 32}}},
"documentation": {"value": "(error) Error 1", "kind": "markdown"},
"detail": "error name",
"data": ["«external:file:///errorExplanationInteractive.lean»", 34, 32, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///errorExplanationInteractive.lean"},
"position": {"line": 37, "character": 31}}

View file

@ -1,56 +1,29 @@
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 6, "character": 11}}
{"items":
[{"label": "gfxacc",
[{"label": "gfxadc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 6, "character": 11}},
"id": {"const": {"declName": "gfxacc"}},
"cPos": 0}},
"data": ["«external:file:///inWordCompletion.lean»", 6, 11, 0, "cgfxadc"]},
{"label": "gfxacc",
"kind": 3,
"data": ["«external:file:///inWordCompletion.lean»", 6, 11, 0, "cgfxacc"]},
{"label": "gfxabc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 6, "character": 11}},
"id": {"const": {"declName": "gfxabc"}},
"cPos": 0}},
{"label": "gfxadc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 6, "character": 11}},
"id": {"const": {"declName": "gfxadc"}},
"cPos": 0}}],
"data": ["«external:file:///inWordCompletion.lean»", 6, 11, 0, "cgfxabc"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 14, "character": 15}}
{"items":
[{"label": "gfxacc",
[{"label": "gfxabc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 14, "character": 15}},
"id": {"const": {"declName": "Boo.gfxacc"}},
"cPos": 0}},
{"label": "gfxabc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 14, "character": 15}},
"id": {"const": {"declName": "Boo.gfxabc"}},
"cPos": 0}},
["«external:file:///inWordCompletion.lean»", 14, 15, 0, "cBoo.gfxabc"]},
{"label": "gfxadc",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///inWordCompletion.lean"},
"position": {"line": 14, "character": 15}},
"id": {"const": {"declName": "Boo.gfxadc"}},
"cPos": 0}}],
["«external:file:///inWordCompletion.lean»", 14, 15, 0, "cBoo.gfxadc"]},
{"label": "gfxacc",
"kind": 3,
"data":
["«external:file:///inWordCompletion.lean»", 14, 15, 0, "cBoo.gfxacc"]}],
"isIncomplete": false}

View file

@ -4,17 +4,9 @@
[{"label": "foo",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///internalNamesIssue.lean"},
"position": {"line": 9, "character": 11}},
"id": {"const": {"declName": "Foo.foo"}},
"cPos": 0}},
["«external:file:///internalNamesIssue.lean»", 9, 11, 0, "cFoo.foo"]},
{"label": "bla",
"kind": 3,
"data":
{"params":
{"textDocument": {"uri": "file:///internalNamesIssue.lean"},
"position": {"line": 9, "character": 11}},
"id": {"const": {"declName": "Foo.bla"}},
"cPos": 0}}],
["«external:file:///internalNamesIssue.lean»", 9, 11, 0, "cFoo.bla"]}],
"isIncomplete": false}

View file

@ -1,54 +1,29 @@
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}}
{"items":
[{"label": "binop_lazy%",
"kind": 14,
"detail": "keyword",
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}},
"cPos": 0}},
{"label": "bin",
[{"label": "bin",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}},
"id": {"const": {"declName": "bin"}},
"cPos": 0}},
{"label": "binrel_no_prop%",
"data": ["«external:file:///keywordCompletion.lean»", 4, 10, 0, "cbin"]},
{"label": "binop_lazy%",
"kind": 14,
"detail": "keyword",
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}},
"cPos": 0}},
{"label": "binrel%",
"kind": 14,
"detail": "keyword",
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}},
"cPos": 0}},
{"label": "binder_predicate",
"kind": 14,
"detail": "keyword",
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}},
"cPos": 0}},
"data": ["«external:file:///keywordCompletion.lean»", 4, 10, 0]},
{"label": "binop%",
"kind": 14,
"detail": "keyword",
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 10}},
"cPos": 0}}],
"data": ["«external:file:///keywordCompletion.lean»", 4, 10, 0]},
{"label": "binrel_no_prop%",
"kind": 14,
"detail": "keyword",
"data": ["«external:file:///keywordCompletion.lean»", 4, 10, 0]},
{"label": "binrel%",
"kind": 14,
"detail": "keyword",
"data": ["«external:file:///keywordCompletion.lean»", 4, 10, 0]},
{"label": "binder_predicate",
"kind": 14,
"detail": "keyword",
"data": ["«external:file:///keywordCompletion.lean»", 4, 10, 0]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 13}}
@ -56,9 +31,5 @@
[{"label": "binop_lazy%",
"kind": 14,
"detail": "keyword",
"data":
{"params":
{"textDocument": {"uri": "file:///keywordCompletion.lean"},
"position": {"line": 4, "character": 13}},
"cPos": 0}}],
"data": ["«external:file:///keywordCompletion.lean»", 4, 13, 0]}],
"isIncomplete": false}

View file

@ -3,56 +3,26 @@
{"items":
[{"label": "value",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 6, "character": 11}},
"id": {"const": {"declName": "S.value"}},
"cPos": 1}},
"data": ["«external:file:///match.lean»", 6, 11, 1, "cS.value"]},
{"label": "fn1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 6, "character": 11}},
"id": {"const": {"declName": "S.fn1"}},
"cPos": 1}},
"data": ["«external:file:///match.lean»", 6, 11, 1, "cS.fn1"]},
{"label": "name",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 6, "character": 11}},
"id": {"const": {"declName": "S.name"}},
"cPos": 1}}],
"data": ["«external:file:///match.lean»", 6, 11, 1, "cS.name"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 10, "character": 10}}
{"items":
[{"label": "value",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 10, "character": 10}},
"id": {"const": {"declName": "S.value"}},
"cPos": 1}},
"data": ["«external:file:///match.lean»", 10, 10, 1, "cS.value"]},
{"label": "fn1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 10, "character": 10}},
"id": {"const": {"declName": "S.fn1"}},
"cPos": 1}},
"data": ["«external:file:///match.lean»", 10, 10, 1, "cS.fn1"]},
{"label": "name",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 10, "character": 10}},
"id": {"const": {"declName": "S.name"}},
"cPos": 1}}],
"data": ["«external:file:///match.lean»", 10, 10, 1, "cS.name"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///match.lean"},
"position": {"line": 14, "character": 2}}

View file

@ -1,28 +1,13 @@
{"textDocument": {"uri": "file:///matchStxCompletion.lean"},
"position": {"line": 8, "character": 9}}
{"items":
[{"label": "f2",
[{"label": "f1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///matchStxCompletion.lean"},
"position": {"line": 8, "character": 9}},
"id": {"const": {"declName": "C.f2"}},
"cPos": 1}},
"data": ["«external:file:///matchStxCompletion.lean»", 8, 9, 1, "cC.f1"]},
{"label": "b1",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///matchStxCompletion.lean"},
"position": {"line": 8, "character": 9}},
"id": {"const": {"declName": "C.b1"}},
"cPos": 1}},
{"label": "f1",
"data": ["«external:file:///matchStxCompletion.lean»", 8, 9, 1, "cC.b1"]},
{"label": "f2",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///matchStxCompletion.lean"},
"position": {"line": 8, "character": 9}},
"id": {"const": {"declName": "C.f1"}},
"cPos": 1}}],
"data": ["«external:file:///matchStxCompletion.lean»", 8, 9, 1, "cC.f2"]}],
"isIncomplete": false}

View file

@ -4,11 +4,11 @@
[{"label": "aaaaaaaa",
"kind": 21,
"data":
{"params":
{"textDocument": {"uri": "file:///travellingCompletions.lean"},
"position": {"line": 7, "character": 37}},
"id": {"const": {"declName": "Foo.aaaaaaaa"}},
"cPos": 0}}],
["«external:file:///travellingCompletions.lean»",
7,
37,
0,
"cFoo.aaaaaaaa"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///travellingCompletions.lean"},
"position": {"line": 20, "character": 20}}
@ -16,11 +16,11 @@
[{"label": "foobar",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///travellingCompletions.lean"},
"position": {"line": 20, "character": 20}},
"id": {"const": {"declName": "Bar.foobar"}},
"cPos": 2}}],
["«external:file:///travellingCompletions.lean»",
20,
20,
2,
"cBar.foobar"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///travellingCompletions.lean"},
"position": {"line": 24, "character": 16}}
@ -28,11 +28,11 @@
[{"label": "foobar",
"kind": 5,
"data":
{"params":
{"textDocument": {"uri": "file:///travellingCompletions.lean"},
"position": {"line": 24, "character": 16}},
"id": {"const": {"declName": "Bar.foobar"}},
"cPos": 2}}],
["«external:file:///travellingCompletions.lean»",
24,
16,
2,
"cBar.foobar"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///travellingCompletions.lean"},
"position": {"line": 38, "character": 45}}
@ -40,19 +40,19 @@
[{"label": "continuousSMul",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///travellingCompletions.lean"},
"position": {"line": 38, "character": 45}},
"id": {"const": {"declName": "Prod.continuousSMul"}},
"cPos": 1}},
["«external:file:///travellingCompletions.lean»",
38,
45,
1,
"cProd.continuousSMul"]},
{"label": "continuousAdd",
"kind": 23,
"data":
{"params":
{"textDocument": {"uri": "file:///travellingCompletions.lean"},
"position": {"line": 38, "character": 45}},
"id": {"const": {"declName": "Prod.continuousAdd"}},
"cPos": 1}}],
["«external:file:///travellingCompletions.lean»",
38,
45,
1,
"cProd.continuousAdd"]}],
"isIncomplete": false}
{"textDocument": {"uri": "file:///travellingCompletions.lean"},
"position": {"line": 42, "character": 25}}
@ -60,9 +60,9 @@
[{"label": "intro",
"kind": 4,
"data":
{"params":
{"textDocument": {"uri": "file:///travellingCompletions.lean"},
"position": {"line": 42, "character": 25}},
"id": {"const": {"declName": "True.intro"}},
"cPos": 1}}],
["«external:file:///travellingCompletions.lean»",
42,
25,
1,
"cTrue.intro"]}],
"isIncomplete": false}