@jupyter-lsp/jupyterlab-lsp
Version:
Language Server Protocol integration for JupyterLab
72 lines • 2.38 kB
JavaScript
import { StateField, StateEffect } from '@codemirror/state';
import { EditorView, Decoration } from '@codemirror/view';
var Private;
(function (Private) {
Private.specCounter = 0;
})(Private || (Private = {}));
export function createMarkManager(specs) {
const specId = ++Private.specCounter;
const kindToMark = Object.fromEntries(Object.entries(specs).map(([k, spec]) => [
k,
Decoration.mark({
...spec,
_id: Private.specCounter
})
]));
const addMark = StateEffect.define({
map: ({ from, to, kind }, change) => ({
from: change.mapPos(from),
to: change.mapPos(to),
kind
})
});
const removeMark = StateEffect.define();
const markField = StateField.define({
create() {
return Decoration.none;
},
update(marks, tr) {
marks = marks.map(tr.changes);
for (let e of tr.effects) {
if (e.is(addMark)) {
marks = marks.update({
add: [
kindToMark[e.value.kind].range(Math.min(e.value.from, tr.newDoc.length), Math.min(e.value.to, tr.newDoc.length))
]
});
}
else if (e.is(removeMark)) {
marks = marks.update({
filter: (from, to, value) => {
return value.spec['_id'] !== specId;
}
});
}
}
return marks;
},
provide: f => EditorView.decorations.from(f)
});
const views = new Set();
return {
putMarks(view, positions) {
const effects = positions.map(position => addMark.of(position));
if (!view.state.field(markField, false)) {
effects.push(StateEffect.appendConfig.of([markField]));
}
view.dispatch({ effects });
views.add(view);
},
clearAllMarks() {
for (let view of views) {
this.clearEditorMarks(view);
}
views.clear();
},
clearEditorMarks(view) {
const effects = [removeMark.of(null)];
view.dispatch({ effects });
}
};
}
//# sourceMappingURL=marks.js.map