mirror of
https://github.com/Horizontal42/summarum.git
synced 2026-11-11 01:02:01 +03:00
Merge 7a5d767fbc into bede889ced
This commit is contained in:
commit
f6ae919a66
1 changed files with 26 additions and 13 deletions
|
|
@ -78,19 +78,21 @@ const highlightField = StateField.define<DecorationSet>({
|
||||||
const varHighlightReCache = new Map<string, { assignment: RegExp; highlight: RegExp }>();
|
const varHighlightReCache = new Map<string, { assignment: RegExp; highlight: RegExp }>();
|
||||||
|
|
||||||
/** Highlights every occurrence of the variable under the cursor. */
|
/** Highlights every occurrence of the variable under the cursor. */
|
||||||
function buildVarHighlight(state: EditorState): DecorationSet {
|
function buildVarHighlight(view: EditorView): DecorationSet {
|
||||||
const builder = new RangeSetBuilder<Decoration>();
|
const builder = new RangeSetBuilder<Decoration>();
|
||||||
const sel = state.selection.main;
|
const sel = view.state.selection.main;
|
||||||
if (!sel.empty) return builder.finish();
|
if (!sel.empty) return builder.finish();
|
||||||
const text = state.doc.toString();
|
const doc = view.state.doc;
|
||||||
// expand a word around the cursor
|
// expand a word around the cursor
|
||||||
const isWordCh = (ch: string) => /[\p{L}\d_]/u.test(ch);
|
const isWordCh = (ch: string) => /[\p{L}\d_]/u.test(ch);
|
||||||
let a = sel.head;
|
const line = doc.lineAt(sel.head);
|
||||||
let b = sel.head;
|
const lineText = line.text;
|
||||||
while (a > 0 && isWordCh(text[a - 1])) a--;
|
let localA = sel.head - line.from;
|
||||||
while (b < text.length && isWordCh(text[b])) b++;
|
let localB = sel.head - line.from;
|
||||||
if (a === b) return builder.finish();
|
while (localA > 0 && isWordCh(lineText[localA - 1])) localA--;
|
||||||
const word = text.slice(a, b);
|
while (localB < lineText.length && isWordCh(lineText[localB])) localB++;
|
||||||
|
if (localA === localB) return builder.finish();
|
||||||
|
const word = lineText.slice(localA, localB);
|
||||||
if (!/^[\p{L}_][\p{L}\d_]*$/u.test(word)) return builder.finish();
|
if (!/^[\p{L}_][\p{L}\d_]*$/u.test(word)) return builder.finish();
|
||||||
|
|
||||||
let cachedRe = varHighlightReCache.get(word);
|
let cachedRe = varHighlightReCache.get(word);
|
||||||
|
|
@ -105,9 +107,20 @@ function buildVarHighlight(state: EditorState): DecorationSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
// only highlight if the word is actually assigned somewhere in the document
|
// only highlight if the word is actually assigned somewhere in the document
|
||||||
if (!cachedRe.assignment.test(text)) return builder.finish();
|
let hasAssignment = false;
|
||||||
for (const m of text.matchAll(cachedRe.highlight)) {
|
for (const line of doc.iterLines()) {
|
||||||
builder.add(m.index, m.index + word.length, Decoration.mark({ class: "tok-var-active" }));
|
if (cachedRe.assignment.test(line)) {
|
||||||
|
hasAssignment = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasAssignment) return builder.finish();
|
||||||
|
|
||||||
|
for (const range of view.visibleRanges) {
|
||||||
|
const chunk = doc.sliceString(range.from, range.to);
|
||||||
|
for (const m of chunk.matchAll(cachedRe.highlight)) {
|
||||||
|
builder.add(range.from + m.index, range.from + m.index + word.length, Decoration.mark({ class: "tok-var-active" }));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return builder.finish();
|
return builder.finish();
|
||||||
}
|
}
|
||||||
|
|
@ -143,7 +156,7 @@ const varHighlightPlugin = ViewPlugin.fromClass(
|
||||||
schedule(view: EditorView) {
|
schedule(view: EditorView) {
|
||||||
if (this.timeout) clearTimeout(this.timeout);
|
if (this.timeout) clearTimeout(this.timeout);
|
||||||
this.timeout = setTimeout(() => {
|
this.timeout = setTimeout(() => {
|
||||||
const decos = buildVarHighlight(view.state);
|
const decos = buildVarHighlight(view);
|
||||||
view.dispatch({ effects: setVarHighlight.of(decos) });
|
view.dispatch({ effects: setVarHighlight.of(decos) });
|
||||||
}, 150);
|
}, 150);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue