mirror of
https://github.com/leanprover/lean4.git
synced 2026-03-17 18:34:06 +00:00
feat: flag on TermInfo to force rendering of term in hover (#10805)
This PR adds a field `isDisplayableTerm` to `TermInfo` and all utility functions which create `TermInfo` that can be set to force the language server to render the term in hover popups.
This commit is contained in:
@@ -1590,14 +1590,15 @@ where
|
||||
|
||||
/-- Adds the `TermInfo` for the field of a projection. See `Lean.Parser.Term.identProjKind`. -/
|
||||
private def addProjTermInfo
|
||||
(stx : Syntax)
|
||||
(e : Expr)
|
||||
(expectedType? : Option Expr := none)
|
||||
(lctx? : Option LocalContext := none)
|
||||
(elaborator : Name := Name.anonymous)
|
||||
(isBinder force : Bool := false)
|
||||
(stx : Syntax)
|
||||
(e : Expr)
|
||||
(expectedType? : Option Expr := none)
|
||||
(lctx? : Option LocalContext := none)
|
||||
(elaborator : Name := Name.anonymous)
|
||||
(isBinder force : Bool := false)
|
||||
(isDisplayableTerm : Bool := false)
|
||||
: TermElabM Expr :=
|
||||
addTermInfo (Syntax.node .none Parser.Term.identProjKind #[stx]) e expectedType? lctx? elaborator isBinder force
|
||||
addTermInfo (Syntax.node .none Parser.Term.identProjKind #[stx]) e expectedType? lctx? elaborator isBinder force isDisplayableTerm
|
||||
|
||||
private def elabAppLValsAux (namedArgs : Array NamedArg) (args : Array Arg) (expectedType? : Option Expr) (explicit ellipsis : Bool)
|
||||
(f : Expr) (lvals : List LVal) : TermElabM Expr :=
|
||||
|
||||
@@ -72,6 +72,8 @@ structure TermInfo extends ElabInfo where
|
||||
expectedType? : Option Expr
|
||||
expr : Expr
|
||||
isBinder : Bool := false
|
||||
/-- Whether `expr` should always be displayed in the language server, e.g. in hovers. -/
|
||||
isDisplayableTerm : Bool := false
|
||||
deriving Inhabited
|
||||
|
||||
/--
|
||||
|
||||
@@ -1315,13 +1315,13 @@ def isTacticOrPostponedHole? (e : Expr) : TermElabM (Option MVarId) := do
|
||||
| _ => pure none
|
||||
|
||||
def mkTermInfo (elaborator : Name) (stx : Syntax) (e : Expr) (expectedType? : Option Expr := none)
|
||||
(lctx? : Option LocalContext := none) (isBinder := false) :
|
||||
(lctx? : Option LocalContext := none) (isBinder := false) (isDisplayableTerm := false) :
|
||||
TermElabM (Sum Info MVarId) := do
|
||||
match (← isTacticOrPostponedHole? e) with
|
||||
| some mvarId => return Sum.inr mvarId
|
||||
| none =>
|
||||
let e := removeSaveInfoAnnotation e
|
||||
return Sum.inl <| Info.ofTermInfo { elaborator, lctx := lctx?.getD (← getLCtx), expr := e, stx, expectedType?, isBinder }
|
||||
return Sum.inl <| Info.ofTermInfo { elaborator, lctx := lctx?.getD (← getLCtx), expr := e, stx, expectedType?, isBinder, isDisplayableTerm }
|
||||
|
||||
def mkPartialTermInfo (elaborator : Name) (stx : Syntax) (expectedType? : Option Expr := none)
|
||||
(lctx? : Option LocalContext := none) :
|
||||
@@ -1345,18 +1345,21 @@ is a constant they will see the constant's doc string.
|
||||
-/
|
||||
def addTermInfo (stx : Syntax) (e : Expr) (expectedType? : Option Expr := none)
|
||||
(lctx? : Option LocalContext := none) (elaborator := Name.anonymous)
|
||||
(isBinder := false) (force := false) : TermElabM Expr := do
|
||||
(isBinder := false) (force := false) (isDisplayableTerm := false): TermElabM Expr := do
|
||||
if (← read).inPattern && !force then
|
||||
return mkPatternWithRef e stx
|
||||
else
|
||||
discard <| withInfoContext'
|
||||
(pure ())
|
||||
(fun _ => mkTermInfo elaborator stx e expectedType? lctx? isBinder)
|
||||
(fun _ => mkTermInfo elaborator stx e expectedType? lctx? isBinder isDisplayableTerm)
|
||||
(mkPartialTermInfo elaborator stx expectedType? lctx?)
|
||||
return e
|
||||
|
||||
def addTermInfo' (stx : Syntax) (e : Expr) (expectedType? : Option Expr := none) (lctx? : Option LocalContext := none) (elaborator := Name.anonymous) (isBinder := false) : TermElabM Unit :=
|
||||
def addTermInfo' (stx : Syntax) (e : Expr) (expectedType? : Option Expr := none)
|
||||
(lctx? : Option LocalContext := none) (elaborator := Name.anonymous) (isBinder := false)
|
||||
(isDisplayableTerm := false) : TermElabM Unit :=
|
||||
discard <| addTermInfo stx e expectedType? lctx? elaborator isBinder
|
||||
(isDisplayableTerm := isDisplayableTerm)
|
||||
|
||||
def withInfoContext' (stx : Syntax) (x : TermElabM Expr)
|
||||
(mkInfo : Expr → TermElabM (Sum Info MVarId)) (mkInfoOnError : TermElabM Info) :
|
||||
@@ -1384,10 +1387,11 @@ def getBodyInfo? : Info → Option BodyInfo
|
||||
|
||||
def withTermInfoContext' (elaborator : Name) (stx : Syntax) (x : TermElabM Expr)
|
||||
(expectedType? : Option Expr := none) (lctx? : Option LocalContext := none)
|
||||
(isBinder : Bool := false) :
|
||||
(isBinder : Bool := false) (isDisplayableTerm : Bool := false):
|
||||
TermElabM Expr :=
|
||||
withInfoContext' stx x
|
||||
(mkTermInfo elaborator stx (expectedType? := expectedType?) (lctx? := lctx?) (isBinder := isBinder))
|
||||
(mkTermInfo elaborator stx (expectedType? := expectedType?) (lctx? := lctx?)
|
||||
(isBinder := isBinder) (isDisplayableTerm := isDisplayableTerm))
|
||||
(mkPartialTermInfo elaborator stx (expectedType? := expectedType?) (lctx? := lctx?))
|
||||
|
||||
/--
|
||||
|
||||
@@ -392,15 +392,19 @@ where
|
||||
let eFmt ← PrettyPrinter.ppSignature c
|
||||
return (some { eFmt with fmt := f!"```lean\n{eFmt.fmt}\n```" }, ← fmtModule? c)
|
||||
let eFmt ← Meta.ppExpr e
|
||||
let lctx ← getLCtx
|
||||
-- Try not to show too scary internals
|
||||
let showTerm :=
|
||||
if let .fvar _ := e then
|
||||
if let some ldecl := (← getLCtx).findFVar? e then
|
||||
!ldecl.userName.hasMacroScopes
|
||||
else
|
||||
false
|
||||
if ti.isDisplayableTerm then
|
||||
true
|
||||
else
|
||||
isAtomicFormat eFmt
|
||||
if let .fvar _ := e then
|
||||
if let some ldecl := lctx.findFVar? e then
|
||||
!ldecl.userName.hasMacroScopes
|
||||
else
|
||||
false
|
||||
else
|
||||
isAtomicFormat eFmt
|
||||
let fmt := if showTerm then f!"{eFmt} : {tpFmt}" else tpFmt
|
||||
return (some f!"```lean\n{fmt}\n```", none)
|
||||
| Info.ofFieldInfo fi =>
|
||||
|
||||
Reference in New Issue
Block a user