diff --git a/src/Lean/Data/JsonRpc.lean b/src/Lean/Data/JsonRpc.lean index f654a0b22f..9680076be9 100644 --- a/src/Lean/Data/JsonRpc.lean +++ b/src/Lean/Data/JsonRpc.lean @@ -149,6 +149,8 @@ message ← err.getObjValAs? String "message"; let data? := err.getObjVal? "data"; pure (Message.responseError id code message data?) +-- HACK: The implementation must be made up of several `auxN`s instead +-- of one large block because of a bug in the compiler. instance messageFromJson : HasFromJson Message := ⟨fun j => do "2.0" ← j.getObjVal? "jsonrpc" | none; diff --git a/src/Lean/Data/Lsp.lean b/src/Lean/Data/Lsp.lean index b6bcf7484c..92d4e7f0b4 100644 --- a/src/Lean/Data/Lsp.lean +++ b/src/Lean/Data/Lsp.lean @@ -5,9 +5,10 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Gabriel Ebner, Marc Huisinga -/ import Lean.Data.Lsp.GeneralMessage -import Lean.Data.Lsp.Structure -import Lean.Data.Lsp.TextSync +import Lean.Data.Lsp.Structure +import Lean.Data.Lsp.TextSync import Lean.Data.Lsp.Communication import Lean.Data.Lsp.Capabilities import Lean.Data.Lsp.Diagnostics +import Lean.Data.Lsp.Hover import Lean.Data.Lsp.Utf16 diff --git a/src/Lean/Data/Lsp/Capabilities.lean b/src/Lean/Data/Lsp/Capabilities.lean index 79a4ea6e52..31697ed679 100644 --- a/src/Lean/Data/Lsp/Capabilities.lean +++ b/src/Lean/Data/Lsp/Capabilities.lean @@ -16,14 +16,17 @@ instance clientCapabilitiesHasFromJson : HasFromJson ClientCapabilities := -- TODO largely unimplemented structure ServerCapabilities := (textDocumentSync? : Option TextDocumentSyncOptions := none) +(hoverProvider : Bool := false) instance serverCapabilitiesHasToJson : HasToJson ServerCapabilities := ⟨fun o => mkObj $ - opt "textDocumentSync" o.textDocumentSync? ++ []⟩ + opt "textDocumentSync" o.textDocumentSync? ++ + [⟨"hoverProvider", o.hoverProvider⟩]⟩ def mkLeanServerCapabilities : ServerCapabilities := { textDocumentSync? := some { openClose := true - , change? := TextDocumentSyncKind.incremental }} + , change? := TextDocumentSyncKind.incremental } +, hoverProvider := true } end Lean.Lsp diff --git a/src/Lean/Data/Lsp/Hover.lean b/src/Lean/Data/Lsp/Hover.lean new file mode 100644 index 0000000000..364c61dbe0 --- /dev/null +++ b/src/Lean/Data/Lsp/Hover.lean @@ -0,0 +1,25 @@ +import Lean.Data.Json +import Lean.Data.Lsp.Structure + +namespace Lean.Lsp + +open Lean +open Lean.Json + +/- The result of a hover request. -/ +structure Hover := +/- The hover's content -/ +--(contents: MarkedString | MarkedString[] | MarkupContent) +/- An optional range is a range inside a text document +that is used to visualize a hover, e.g. by changing the background color. -/ +(range? : Range) + +structure HoverParams extends TextDocumentPositionParams + +instance hoverParamsHasFromJson : HasFromJson HoverParams := +⟨fun j => do + tdpp : TextDocumentPositionParams ← fromJson? j; + pure ⟨tdpp⟩⟩ + +end Lean.Lsp + diff --git a/src/Lean/Data/Lsp/Structure.lean b/src/Lean/Data/Lsp/Structure.lean index b921e1ad59..0c51482eb7 100644 --- a/src/Lean/Data/Lsp/Structure.lean +++ b/src/Lean/Data/Lsp/Structure.lean @@ -13,6 +13,12 @@ abbrev DocumentUri := String -- character is accepted liberally: actual character := min(line length, character) structure Position := (line : Nat) (character : Nat) +instance positionHasFromJson : HasFromJson Position := +⟨fun j => do + line ← j.getObjValAs? Nat "line"; + character ← j.getObjValAs? Nat "character"; + pure ⟨line, character⟩⟩ + -- [start, end) structure Range := (start : Position) («end» : Position) @@ -117,6 +123,11 @@ def TextEditBatch := Array TextEdit structure TextDocumentIdentifier := (uri : DocumentUri) +instance textDocumentIdentifierHasFromJson : HasFromJson TextDocumentIdentifier := +⟨fun j => do + uri ← j.getObjValAs? DocumentUri "uri"; + pure ⟨uri⟩⟩ + structure VersionedTextDocumentIdentifier := (uri : DocumentUri) -- increases after each change, undo and redo @@ -147,6 +158,12 @@ structure TextDocumentPositionParams := (textDocument : TextDocumentIdentifier) (position : Position) +instance textDocumentPositionParamsHasFromJson : HasFromJson TextDocumentPositionParams := +⟨fun j => do + textDocument ← j.getObjValAs? TextDocumentIdentifier "textDocument"; + position ← j.getObjValAs? Position "position"; + pure ⟨textDocument, position⟩⟩ + structure DocumentFilter := (language? : Option String := none) -- language id -- uri scheme like 'file' or 'untitled' @@ -176,12 +193,6 @@ structure TextDocumentRegistrationOptions := (documentSelector? : Option Documen instance documentUriHasFromJson : HasFromJson DocumentUri := ⟨fun j => j.getStr?⟩ -instance positionHasFromJson : HasFromJson Position := -⟨fun j => do - line ← j.getObjValAs? Nat "line"; - character ← j.getObjValAs? Nat "character"; - pure ⟨line, character⟩⟩ - instance rangeHasFromJson : HasFromJson Range := ⟨fun j => do start ← j.getObjValAs? Position "start"; @@ -223,11 +234,6 @@ instance diagnosticHasFromJson : HasFromJson Diagnostic := let relatedInformation? := j.getObjValAs? (Array DiagnosticRelatedInformation) "relatedInformation"; pure ⟨range, severity?, code?, source?, message, tags?, relatedInformation?⟩⟩ -instance textDocumentIdentifierHasFromJson : HasFromJson TextDocumentIdentifier := -⟨fun j => do - uri ← j.getObjValAs? DocumentUri "uri"; - pure ⟨uri⟩⟩ - instance versionedTextDocumentIdentifierHasFromJson : HasFromJson VersionedTextDocumentIdentifier := ⟨fun j => do uri ← j.getObjValAs? DocumentUri "uri"; diff --git a/src/Lean/Server/Server.lean b/src/Lean/Server/Server.lean index b0b6767ffd..8bbc3c987c 100644 --- a/src/Lean/Server/Server.lean +++ b/src/Lean/Server/Server.lean @@ -1,5 +1,6 @@ import Init.System.IO import Std.Data.RBMap + import Lean.Environment import Lean.Elab.Frontend import Lean.Data.Lsp @@ -147,6 +148,10 @@ match method with def handleRequest (s : ServerState) (id : RequestID) (method : String) (params : Json) : IO Unit := do match method with + | "textDocument/hover" => do + p ← parseParams HoverParams params; + writeLspResponse s.o id Json.null; + pure () | _ => throw (userError "Not supporting requests for now!") partial def mainLoop : ServerState → IO Unit @@ -184,5 +189,6 @@ def main (n : List String) : IO UInt32 := do i ← IO.stdin; o ← IO.stdout; Lean.initSearchPath; +env ← Lean.mkEmptyEnvironment; catch (Lean.Server.initialize i o) (fun err => o.putStrLn (toString err)); pure 0