blob: fc18bb35d6839f60b0ea4feca3b4f18fa2d2f18c [file]
/-
Copyright (c) 2021 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Wojciech Nawrocki
-/
prelude
import Lean.Widget.Basic
import Lean.Widget.InteractiveCode
import Lean.Widget.InteractiveGoal
import Lean.Widget.InteractiveDiagnostic
import Lean.Server.Rpc.RequestHandling
import Lean.Server.FileWorker.RequestHandling
/-! Registers all widget-related RPC procedures. -/
namespace Lean.Widget
open Server Lean.Elab
structure MsgToInteractive where
msg : WithRpcRef MessageData
indent : Nat
deriving Inhabited, RpcEncodable
builtin_initialize
registerBuiltinRpcProcedure
`Lean.Widget.InteractiveDiagnostics.msgToInteractive
MsgToInteractive
(TaggedText MsgEmbed)
fun ⟨⟨m⟩, i⟩ => RequestM.asTask do msgToInteractive m i (hasWidgets := true)
/-- The information that the infoview uses to render a popup
for when the user hovers over an expression.
-/
structure InfoPopup where
type : Option CodeWithInfos
/-- Show the term with the implicit arguments. -/
exprExplicit : Option CodeWithInfos
/-- Docstring. In markdown. -/
doc : Option String
deriving Inhabited, RpcEncodable
/-- Given elaborator info for a particular subexpression. Produce the `InfoPopup`.
The intended usage of this is for the infoview to pass the `InfoWithCtx` which
was stored for a particular `SubexprInfo` tag in a `TaggedText` generated with `ppExprTagged`.
-/
def makePopup : WithRpcRef InfoWithCtx → RequestM (RequestTask InfoPopup)
| ⟨i⟩ => RequestM.asTask do
i.ctx.runMetaM i.info.lctx do
let type? ← match (← i.info.type?) with
| some type => some <$> ppExprTagged type
| none => pure none
let exprExplicit? ← match i.info with
| Elab.Info.ofTermInfo ti =>
pure <| some <| ← ppExprTaggedWithoutTopLevelHighlight ti.expr (explicit := true)
| Elab.Info.ofOmissionInfo { toTermInfo := ti, .. } =>
-- Omitted terms are simply to be expanded, not printed explicitly.
-- Keep the top-level tag so that users can also see the explicit version
-- of the omitted term.
pure <| some <| ← ppExprTagged ti.expr (explicit := false)
| Elab.Info.ofFieldInfo fi => pure <| some <| TaggedText.text fi.fieldName.toString
| _ => pure none
return {
type := type?
exprExplicit := exprExplicit?
doc := ← i.info.docString? : InfoPopup
}
where
ppExprTaggedWithoutTopLevelHighlight (e : Expr) (explicit : Bool) : MetaM CodeWithInfos := do
let pp ← ppExprTagged e (explicit := explicit)
return match pp with
| .tag _ tt => tt
| tt => tt
builtin_initialize
registerBuiltinRpcProcedure
`Lean.Widget.InteractiveDiagnostics.infoToInteractive
(WithRpcRef InfoWithCtx)
InfoPopup
makePopup
builtin_initialize
registerBuiltinRpcProcedure
`Lean.Widget.getInteractiveGoals
Lsp.PlainGoalParams
(Option InteractiveGoals)
FileWorker.getInteractiveGoals
builtin_initialize
registerBuiltinRpcProcedure
`Lean.Widget.getInteractiveTermGoal
Lsp.PlainTermGoalParams
(Option InteractiveTermGoal)
FileWorker.getInteractiveTermGoal
structure GetInteractiveDiagnosticsParams where
/-- Return diagnostics for these lines only if present,
otherwise return all diagnostics. -/
lineRange? : Option Lsp.LineRange
deriving Inhabited, FromJson, ToJson
structure GetGoToLocationParams where
kind : GoToKind
info : WithRpcRef InfoWithCtx
deriving RpcEncodable
builtin_initialize
registerBuiltinRpcProcedure
`Lean.Widget.getGoToLocation
GetGoToLocationParams
(Array Lsp.LocationLink)
fun ⟨kind, ⟨i⟩⟩ => RequestM.asTask do
let rc ← read
let ls ← FileWorker.locationLinksOfInfo kind i
if !ls.isEmpty then return ls
-- TODO(WN): unify handling of delab'd (infoview) and elab'd (editor) applications
let .ofTermInfo ti := i.info | return #[]
let .app _ _ := ti.expr | return #[]
let some nm := ti.expr.getAppFn.constName? | return #[]
i.ctx.runMetaM ti.lctx <|
locationLinksFromDecl rc.srcSearchPath rc.doc.meta.uri nm none
def lazyTraceChildrenToInteractive (children : WithRpcRef LazyTraceChildren) :
RequestM (RequestTask (Array (TaggedText MsgEmbed))) :=
RequestM.asTask do
let ⟨indent, children⟩ := children
children.mapM fun ⟨child⟩ =>
msgToInteractive child (hasWidgets := true) (indent := indent)
builtin_initialize registerBuiltinRpcProcedure ``lazyTraceChildrenToInteractive _ _ lazyTraceChildrenToInteractive
end Lean.Widget