Skip to content

Commit 79d266e

Browse files
committed
Add a baseToken method to string streams
That overlay modes can use to access the underlying token info.
1 parent deaa842 commit 79d266e

4 files changed

Lines changed: 40 additions & 1 deletion

File tree

doc/manual.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3261,6 +3261,12 @@ <h2>Writing CodeMirror Modes</h2>
32613261
one, in order to scan ahead across line boundaries. Note that
32623262
you want to do this carefully, since looking far ahead will make
32633263
mode state caching much less effective.</dd>
3264+
3265+
<dt><code><strong>baseToken</strong>() → ?{type: ?string, size: number}</code></dt>
3266+
<dd>Modes added
3267+
through <a href="#addOverlay"><code>addOverlay</code></a>
3268+
(and <em>only</em> such modes) can use this method to inspect
3269+
the current token produced by the underlying mode.</dd>
32643270
</dl>
32653271

32663272
<p id="blankLine">By default, blank lines are simply skipped when

src/line/highlight.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ class Context {
1818
this.doc = doc
1919
this.line = line
2020
this.maxLookAhead = lookAhead || 0
21+
this.baseTokens = null
22+
this.baseTokenPos = 1
2123
}
2224

2325
lookAhead(n) {
@@ -26,6 +28,15 @@ class Context {
2628
return line
2729
}
2830

31+
baseToken(n) {
32+
if (!this.baseTokens) return null
33+
while (this.baseTokens[this.baseTokenPos] >= n)
34+
this.baseTokenPos += 2
35+
let type = this.baseTokens[this.baseTokenPos + 1]
36+
return {type: type && type.replace(/( |^)overlay .*/, ""),
37+
size: this.baseTokens[this.baseTokenPos] - n}
38+
}
39+
2940
nextLine() {
3041
this.line++
3142
if (this.maxLookAhead > 0) this.maxLookAhead--
@@ -60,6 +71,7 @@ export function highlightLine(cm, line, context, forceToEnd) {
6071

6172
// Run overlays, adjust style array.
6273
for (let o = 0; o < cm.state.overlays.length; ++o) {
74+
context.baseTokens = st
6375
let overlay = cm.state.overlays[o], i = 1, at = 0
6476
context.state = true
6577
runMode(cm, line.text, overlay.mode, context, (end, style) => {
@@ -83,8 +95,10 @@ export function highlightLine(cm, line, context, forceToEnd) {
8395
}
8496
}
8597
}, lineClasses)
98+
context.state = state
99+
context.baseTokens = null
100+
context.baseTokenPos = 1
86101
}
87-
context.state = state
88102

89103
return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}
90104
}

src/util/StringStream.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ class StringStream {
8181
let oracle = this.lineOracle
8282
return oracle && oracle.lookAhead(n)
8383
}
84+
baseToken() {
85+
let oracle = this.lineOracle
86+
return oracle && oracle.baseToken(this.pos)
87+
}
8488
}
8589

8690
export default StringStream

test/test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2218,6 +2218,21 @@ testCM("getTokenTypeAt", function(cm) {
22182218
eq(cm.getTokenTypeAt(Pos(0, 6)), "string");
22192219
}, {value: "1 + 'foo'", mode: "javascript"});
22202220

2221+
testCM("addOverlay", function(cm) {
2222+
cm.addOverlay({
2223+
token: function(stream) {
2224+
var base = stream.baseToken()
2225+
if (!/comment/.test(base.type) && stream.match(/\d+/)) return "x"
2226+
stream.next()
2227+
}
2228+
})
2229+
var x = byClassName(cm.getWrapperElement(), "cm-x")
2230+
is(x.length, 1)
2231+
is(x[0].textContent, "233")
2232+
cm.replaceRange("", Pos(0, 4), Pos(0, 6))
2233+
is(byClassName(cm.getWrapperElement(), "cm-x").length, 2)
2234+
}, {value: "foo /* 100 */\nbar + 233;\nbaz", mode: "javascript"})
2235+
22212236
testCM("resizeLineWidget", function(cm) {
22222237
addDoc(cm, 200, 3);
22232238
var widget = document.createElement("pre");

0 commit comments

Comments
 (0)