Hey, I’m totally new to Codemirror so I’m sure I’m doing something very wrong here
I’m trying to create a plugin that will automatically/always replace lines that begin with a certain signifier prefix
with a tag/badge containing the text replacement
. Here’s the attempt:
function hideLines(view, prefix, replacement) {
let decs = [];
let startLine = view.state.doc.lineAt(0);
let endLine = view.state.doc.lineAt(view.state.doc.length);
for (let i = startLine.number; i <= endLine.number; i++) {
let line = view.state.doc.line(i);
if (line.text.startsWith(prefix)) {
let d = Decoration.replace({ widget: new BadgeWidget(replacement) });
decs.push(d.range(line.from, line.to));
}
}
return Decoration.set(decs);
}
const hideLinesPlugin = (prefix, replacement) => ViewPlugin.fromClass(class {
constructor(view) {
this.decorations = hideLines(view, prefix, replacement);
}
update(update) {
if (update.docChanged) {
this.decorations = hideLines(update.view, prefix, replacement);
}
}
}, {
decorations: v => v.decorations,
});
which is mostly cobbled together from the examples in the docs (BadgeWidget
works correctly and is irrelevant to this problem). After passing a created plugin to extensions
, everything seems to work properly, but when I change the whole document (after, say, loading a file over the network) with
view.dispatch({
changes: { from: 0, to: view.state.doc.length, insert: newDocument },
});
I get some weird behavior of the document being partially displayed (not all text is there), along with a warning Measure loop restarted more than 5 times
in the console.
Note that these are long lines I’m replacing, and lineWrapping
is on, so replacing one of these lines does dramatically alter the viewport size; as such, I expect the way I’m doing this is causing some kind of thrashing when calculating the layout.
Any help is greatly appreciated!