fix: ignore syntax nodes with nullKind at hoverableInfoAt?

It fixes one of the problems reported at #1403
This commit is contained in:
Leonardo de Moura 2022-08-01 12:18:36 -07:00
parent 2af7bf1b54
commit c95acef20e
3 changed files with 23 additions and 7 deletions

View file

@ -150,19 +150,23 @@ def InfoTree.smallestInfo? (p : Info → Bool) (t : InfoTree) : Option (ContextI
/-- Find an info node, if any, which should be shown on hover/cursor at position `hoverPos`. -/
partial def InfoTree.hoverableInfoAt? (t : InfoTree) (hoverPos : String.Pos) (includeStop := false) (omitAppFns := false) : Option (ContextInfo × Info) := Id.run do
let results := t.visitM (m := Id) (postNode := fun ctx i _ results => do
let results := t.visitM (m := Id) (postNode := fun ctx info _ results => do
let mut results := results.bind (·.getD [])
if omitAppFns && i.stx.isOfKind ``Parser.Term.app && i.stx[0].isIdent then
results := results.filter (·.2.2.stx != i.stx[0])
if results.isEmpty && (i matches Info.ofFieldInfo _ || i.toElabInfo?.isSome) && i.contains hoverPos includeStop then
let r := i.range?.get!
if omitAppFns && info.stx.isOfKind ``Parser.Term.app && info.stx[0].isIdent then
results := results.filter (·.2.2.stx != info.stx[0])
/-
Remark: we skip `info` nodes associated with the `nullKind` because some tactics (e.g., `rewrite`) attach auxiliary null nodes to control
which goal is displayed in the info views. See issue #1403
-/
if results.isEmpty && info.stx.getKind != nullKind && (info matches Info.ofFieldInfo _ || info.toElabInfo?.isSome) && info.contains hoverPos includeStop then
let r := info.range?.get!
let priority :=
if r.stop == hoverPos then
0 -- prefer results directly *after* the hover position (only matters for `includeStop = true`; see #767)
else if i matches .ofTermInfo { expr := .fvar .., .. } then
else if info matches .ofTermInfo { expr := .fvar .., .. } then
0 -- prefer results for constants over variables (which overlap at declaration names)
else 1
[(priority, ctx, i)]
[(priority, ctx, info)]
else
results) |>.getD []
let maxPrio? := results.map (·.1) |>.maximum?

View file

@ -0,0 +1,4 @@
example : True := by
rewrite []
--^ textDocument/hover
trivial

View file

@ -0,0 +1,8 @@
{"textDocument": {"uri": "file://1403.lean"},
"position": {"line": 1, "character": 2}}
{"range":
{"start": {"line": 1, "character": 2}, "end": {"line": 1, "character": 12}},
"contents":
{"value":
"`rewrite [e]` applies identity `e` as a rewrite rule to the target of the main goal.\nIf `e` is preceded by left arrow (`←` or `<-`), the rewrite is applied in the reverse direction.\nIf `e` is a defined constant, then the equational theorems associated with `e` are used. This provides a convenient way to unfold `e`.\n- `rewrite [e₁, ..., eₙ]` applies the given rules sequentially.\n- `rewrite [e] at l` rewrites `e` at location(s) `l`, where `l` is either `*` or a list of hypotheses in the local context. In the latter case, a turnstile `⊢` or `|-` can also be used, to signify the target of the goal.\n",
"kind": "markdown"}}