UNPKG

@alisowski/codemirror-extensions-zebra-stripes

Version:

Styles alternating lines for CodeMirror6.

102 lines 2.88 kB
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; }