@alisowski/codemirror-extensions-zebra-stripes
Version:
Styles alternating lines for CodeMirror6.
102 lines • 2.88 kB
JavaScript
import { Facet, RangeSetBuilder } from '@codemirror/state';
import { EditorView, Decoration, ViewPlugin } from '@codemirror/view';
var lineNumber = Facet.define({
combine: values => {
return values.length && Array.isArray(values) ? values.flat() : [];
}
});
var stepSize = Facet.define({
combine: values => {
return values.length && Array.isArray(values) ? Math.min(...values) : 2;
}
});
var stripe = Decoration.line({
attributes: {
class: 'cm-zebra-stripe'
}
});
function stripeDeco(view) {
var step = view.state.facet(stepSize);
var num = view.state.facet(lineNumber);
var builder = new RangeSetBuilder();
for (var {
from,
to
} of view.visibleRanges) {
for (var pos = from; pos <= to;) {
var line = view.state.doc.lineAt(pos);
if (line.number % step === 0 && num.length === 0) {
builder.add(line.from, line.from, stripe);
}
if (num.length > 0 && num.flat().includes(line.number)) {
builder.add(line.from, line.from, stripe);
}
pos = line.to + 1;
}
}
return builder.finish();
}
var showStripes = ViewPlugin.fromClass(class {
constructor(view) {
this.decorations = void 0;
this.decorations = stripeDeco(view);
}
update(update) {
this.decorations = stripeDeco(update.view);
// if (update.docChanged || update.viewportChanged) {
// this.decorations = stripeDeco(update.view);
// }
}
}, {
decorations: v => v.decorations
});
var baseTheme = function baseTheme(opt) {
if (opt === void 0) {
opt = {};
}
return EditorView.baseTheme({
["&light ." + opt.className]: {
backgroundColor: opt.lightColor || '#eef6ff'
},
["&dark ." + opt.className]: {
backgroundColor: opt.darkColor || '#3a404d'
}
});
};
var range = (start, stop, step) => Array.from({
length: (stop - start) / step + 1
}, (_, i) => start + i * step);
export function zebraStripes(options) {
if (options === void 0) {
options = {};
}
var {
className = 'cm-zebra-stripe'
} = options;
stripe = Decoration.line({
attributes: {
class: className
}
});
if (options.lineNumber && Array.isArray(options.lineNumber)) {
options.step = null;
options.lineNumber = options.lineNumber.map(item => {
if (Array.isArray(item) && typeof item[0] === 'number' && typeof item[1] === 'number') {
return range(item[0], item[1], 1);
}
return item;
});
} else {
options.lineNumber = null;
}
var extensions = [options.lineNumber === null ? [] : lineNumber.of(options.lineNumber || []), options.step === null ? [] : stepSize.of(options.step || 2), showStripes];
if (className) {
var zebraStripeTheme = baseTheme({
lightColor: options.lightColor,
darkColor: options.darkColor,
className
});
extensions.push(zebraStripeTheme);
}
return extensions;
}