Skip to content

Commit 155879a

Browse files
feat: redo keyword highlighting
Now keywords don't show their parser names, and they participate in occurrence highlighting Fixes #14
1 parent d214aaf commit 155879a

File tree

4 files changed

+33
-13
lines changed

4 files changed

+33
-13
lines changed

examples/website/DemoSite/Blog/Conditionals.lean

+13
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,19 @@ def squish'' (n : Option Nat) : Nat :=
9090

9191
```
9292

93+
Here is a mutual block:
94+
```lean demo
95+
mutual
96+
def f : Nat → Nat
97+
| 0 => 1
98+
| n + 1 => g n
99+
100+
def g : Nat → Nat
101+
| 0 => 0
102+
| n + 1 => f n
103+
end
104+
```
105+
93106
Here is a proof with some lambdas and big terms in it, to check highlighting:
94107
```lean demo
95108
def grow : Nat → α → α

src/verso-blog/Verso/Genre/Blog/HighlightCode.lean

+12-9
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ partial defmethod Highlighted.Token.Kind.priority : Highlighted.Token.Kind → N
1717
| .const .. => 5
1818
| .option .. => 4
1919
| .sort => 4
20-
| .keyword _ _ => 3
20+
| .keyword _ _ _ => 3
2121
| .docComment => 1
2222
| .unknown => 0
2323

@@ -417,12 +417,12 @@ partial def renderTagged [Monad m] [MonadLiftT IO m] [MonadMCtx m] [MonadEnv m]
417417
let mut toks : Array Highlighted := #[]
418418
let mut current := ""
419419
while !todo.isEmpty do
420-
for kw in ["let", "fun", ":=", "=>", "do", "match", "with", "if", "then", "else", "break", "continue", "for", "in", "mut"] do
420+
for kw in ["let", "fun", "do", "match", "with", "if", "then", "else", "break", "continue", "for", "in", "mut"] do
421421
if kw.isPrefixOf todo && tokenEnder (todo.drop kw.length) then
422422
if !current.isEmpty then
423423
toks := toks.push <| .text current
424424
current := ""
425-
toks := toks.push <| .token ⟨.keyword none none, kw⟩
425+
toks := toks.push <| .token ⟨.keyword none none none, kw⟩
426426
todo := todo.drop kw.length
427427
break
428428
let c := todo.get 0
@@ -521,7 +521,7 @@ def findTactics (ids : HashMap Lsp.RefIdent Lsp.RefIdent) (stx : Syntax) : Highl
521521
}
522522
return
523523

524-
partial def highlight' (ids : HashMap Lsp.RefIdent Lsp.RefIdent) (stx : Syntax) (lookingAt : Option Name := none) : HighlightM Unit := do
524+
partial def highlight' (ids : HashMap Lsp.RefIdent Lsp.RefIdent) (stx : Syntax) (lookingAt : Option (Name × String.Pos) := none) : HighlightM Unit := do
525525
findTactics ids stx
526526
match stx with
527527
| `($e.%$tk$field:ident) =>
@@ -550,7 +550,9 @@ partial def highlight' (ids : HashMap Lsp.RefIdent Lsp.RefIdent) (stx : Syntax)
550550
| stx@(.atom i x) =>
551551
let docs ← match lookingAt with
552552
| none => pure none
553-
| some n => findDocString? (← getEnv) n
553+
| some (n, _) => findDocString? (← getEnv) n
554+
let name := lookingAt.map (·.1)
555+
let occ := lookingAt.map fun (n, pos) => s!"{n}-{pos}"
554556
if let .sort ← identKind ids ⟨stx⟩ then
555557
emitToken i ⟨.sort, x⟩
556558
return
@@ -560,11 +562,11 @@ partial def highlight' (ids : HashMap Lsp.RefIdent Lsp.RefIdent) (stx : Syntax)
560562
| some '#' =>
561563
match x.get? ((0 : String.Pos) + '#') with
562564
| some c =>
563-
if c.isAlpha then .keyword lookingAt docs
565+
if c.isAlpha then .keyword name occ docs
564566
else .unknown
565567
| _ => .unknown
566568
| some c =>
567-
if c.isAlpha then .keyword lookingAt docs
569+
if c.isAlpha then .keyword name occ docs
568570
else .unknown
569571
| _ => .unknown
570572
| .node _ `str #[.atom i string] =>
@@ -586,9 +588,10 @@ partial def highlight' (ids : HashMap Lsp.RefIdent Lsp.RefIdent) (stx : Syntax)
586588
| _, _ =>
587589
highlight' ids dot
588590
highlight' ids name
589-
| .node _ k children =>
591+
| stx@(.node _ k children) =>
592+
let pos := stx.getPos?
590593
for child in children do
591-
highlight' ids child (lookingAt := some k)
594+
highlight' ids child (lookingAt := pos.map (k, ·))
592595

593596
def highlight (stx : Syntax) (messages : Array Message) : TermElabM Highlighted := do
594597
let modrefs := Lean.Server.findModuleRefs (← getFileMap) (← getInfoTrees).toArray

src/verso-blog/Verso/Genre/Blog/Highlighted.lean

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ deriving instance Repr for Std.Format.FlattenBehavior
88
deriving instance Repr for Std.Format
99

1010
inductive Highlighted.Token.Kind where
11-
| keyword (name : Option Name) (docs : Option String)
11+
| /-- `occurrence` is a unique identifier that unites the various keyword tokens from a given production -/
12+
keyword (name : Option Name) (occurrence : Option String) (docs : Option String)
1213
| const (name : Name) (signature : String) (docs : Option String)
1314
| var (name : FVarId) (type : String)
1415
| str (string : String)
@@ -22,7 +23,7 @@ open Highlighted.Token.Kind in
2223
open Syntax (mkCApp) in
2324
instance : Quote Highlighted.Token.Kind where
2425
quote
25-
| .keyword n docs => mkCApp ``keyword #[quote n, quote docs]
26+
| .keyword n occ docs => mkCApp ``keyword #[quote n, quote occ, quote docs]
2627
| .const n sig docs => mkCApp ``const #[quote n, quote sig, quote docs]
2728
| .option n docs => mkCApp ``option #[quote n, quote docs]
2829
| .var (.mk n) type => mkCApp ``var #[mkCApp ``FVarId.mk #[quote n], quote type]

src/verso-blog/Verso/Genre/Blog/Template.lean

+5-2
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,14 @@ defmethod Highlighted.Token.Kind.«class» : Highlighted.Token.Kind → String
4646
| .const _ _ _ => "const"
4747
| .option _ _ => "option"
4848
| .docComment => "doc-comment"
49-
| .keyword _ _ => "keyword"
49+
| .keyword _ _ _ => "keyword"
5050
| .unknown => "unknown"
5151

5252
defmethod Highlighted.Token.Kind.data : Highlighted.Token.Kind → String
5353
| .const n _ _ => "const-" ++ toString n
5454
| .var ⟨v⟩ _ => "var-" ++ toString v
5555
| .option n _ => "option-" ++ toString n
56+
| .keyword _ (some occ) _ => "kw-occ-" ++ toString occ
5657
| _ => ""
5758

5859

@@ -66,11 +67,13 @@ defmethod Highlighted.Token.Kind.hover? : (tok : Highlighted.Token.Kind) → Opt
6667
| none => .empty
6768
| some txt => {{<hr/><pre class="docstring">{{txt}}</pre>}}
6869
some <| hover {{ <code>{{sig}}</code> {{docs}} }}
69-
| .option n doc | .keyword (some n) doc =>
70+
| .option n doc =>
7071
let docs := match doc with
7172
| none => .empty
7273
| some txt => {{<hr/><pre class="docstring">{{txt}}</pre>}}
7374
some <| hover {{ <code>{{toString n}}</code> {{docs}} }}
75+
| .keyword _ _ none => none
76+
| .keyword _ _ (some doc) => some <| hover {{<pre class="docstring">{{doc}}</pre>}}
7477
| .var _ type =>
7578
some <| hover {{ <code>{{type}}</code> }}
7679
| .str s =>

0 commit comments

Comments
 (0)