lean4-htt/src/Lean/Server/FileWorker/WidgetRequests.lean
2021-08-24 08:57:41 -07:00

126 lines
4.5 KiB
Text

/-
Copyright (c) 2021 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Wojciech Nawrocki
-/
import Lean.Widget.InteractiveCode
import Lean.Widget.InteractiveGoal
import Lean.Widget.InteractiveDiagnostic
import Lean.Server.Rpc.RequestHandling
/-! Registers all widget-related RPC procedures. -/
namespace Lean.Widget
open Server
builtin_initialize
registerRpcCallHandler
`Lean.Widget.ExprWithCtx.tagged
(WithRpcRef ExprWithCtx)
CodeWithInfos
fun ⟨e⟩ => RequestM.asTask do e.ctx.runMetaM e.lctx (exprToInteractive e.expr)
registerRpcCallHandler
`Lean.Widget.ExprWithCtx.taggedExplicit
(WithRpcRef ExprWithCtx)
CodeWithInfos
fun ⟨e⟩ => RequestM.asTask do e.ctx.runMetaM e.lctx (exprToInteractiveExplicit e.expr)
registerRpcCallHandler
`Lean.Widget.ExprWithCtx.inferType
(WithRpcRef ExprWithCtx)
(WithRpcRef ExprWithCtx)
fun ⟨e⟩ => RequestM.asTask do WithRpcRef.mk <$> e.ctx.runMetaM e.lctx (inferType e.expr)
structure MsgToInteractive where
msg : WithRpcRef MessageData
indent : Nat
deriving Inhabited, RpcEncoding
builtin_initialize
registerRpcCallHandler
`Lean.Widget.InteractiveDiagnostics.msgToInteractive
MsgToInteractive
(TaggedText MsgEmbed)
fun ⟨⟨m⟩, i⟩ => RequestM.asTask do msgToInteractive m i
structure InfoPopup where
type : Option CodeWithInfos
exprExplicit : Option CodeWithInfos
doc : Option String
deriving Inhabited, RpcEncoding
builtin_initialize
registerRpcCallHandler
`Lean.Widget.InteractiveDiagnostics.infoToInteractive
(WithRpcRef InfoWithCtx)
InfoPopup
fun ⟨i⟩ => RequestM.asTask do
i.ctx.runMetaM i.lctx do
let type? ← match (← i.info.type?) with
| some type => some <$> exprToInteractive type
| none => none
let exprExplicit? ← match i.info with
| Elab.Info.ofTermInfo ti => some <$> exprToInteractiveExplicit ti.expr
| Elab.Info.ofFieldInfo fi => some (TaggedText.text fi.fieldName.toString)
| _ => none
return {
type := type?
exprExplicit := exprExplicit?
doc := ← i.info.docString? : InfoPopup
}
open RequestM in
def getInteractiveGoals (p : Lsp.PlainGoalParams) : RequestM (RequestTask InteractiveGoals) := do
let doc ← readDoc
let text := doc.meta.text
let hoverPos := text.lspPosToUtf8Pos p.position
-- NOTE: use `>=` since the cursor can be *after* the input
withWaitFindSnap doc (fun s => s.endPos >= hoverPos)
(notFoundX := return { goals := #[] }) fun snap => do
for t in snap.cmdState.infoState.trees do
if let rs@(_ :: _) := t.goalsAt? doc.meta.text hoverPos then
let goals ← List.join <$> rs.mapM fun { ctxInfo := ci, tacticInfo := ti, useAfter := useAfter } =>
let ci := if useAfter then { ci with mctx := ti.mctxAfter } else { ci with mctx := ti.mctxBefore }
let goals := if useAfter then ti.goalsAfter else ti.goalsBefore
ci.runMetaM {} <| goals.mapM (fun g => Meta.withPPInaccessibleNames (goalToInteractive g))
return { goals := goals.toArray }
return { goals := #[] }
open RequestM in
partial def getInteractiveTermGoal (p : Lsp.PlainTermGoalParams)
: RequestM (RequestTask (Option InteractiveGoal)) := do
let doc ← readDoc
let text := doc.meta.text
let hoverPos := text.lspPosToUtf8Pos p.position
withWaitFindSnap doc (fun s => s.endPos > hoverPos)
(notFoundX := pure none) fun snap => do
for t in snap.cmdState.infoState.trees do
if let some (ci, i@(Elab.Info.ofTermInfo ti)) := t.termGoalAt? hoverPos then
let ty ← ci.runMetaM i.lctx do
Meta.instantiateMVars <| ti.expectedType?.getD (← Meta.inferType ti.expr)
-- for binders, hide the last hypothesis (the binder itself)
let lctx' := if ti.isBinder then i.lctx.pop else i.lctx
let goal ← ci.runMetaM lctx' do
Meta.withPPInaccessibleNames <| goalToInteractive (← Meta.mkFreshExprMVar ty).mvarId!
--let range := if let some r := i.range? then r.toLspRange text else ⟨p.position, p.position⟩
return some goal
return none
builtin_initialize
registerRpcCallHandler
`Lean.Widget.getInteractiveGoals
Lsp.PlainGoalParams
InteractiveGoals
getInteractiveGoals
registerRpcCallHandler
`Lean.Widget.getInteractiveTermGoal
Lsp.PlainTermGoalParams
(Option InteractiveGoal)
getInteractiveTermGoal
end Lean.Widget