setDataLine.ts 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. // Ref: https://github.com/uiwjs/react-codemirror/blob/bf3b862923d0cb04ccf4bb9da0791bdc7fd6d29b/extensions/classname/src/index.ts
  2. import { RangeSetBuilder } from '@codemirror/state';
  3. import {
  4. EditorView, Decoration, ViewPlugin, DecorationSet, ViewUpdate,
  5. } from '@codemirror/view';
  6. const stripeDeco = (view: EditorView) => {
  7. const builder = new RangeSetBuilder<Decoration>();
  8. for (const { from, to } of view.visibleRanges) {
  9. for (let pos = from; pos <= to;) {
  10. const line = view.state.doc.lineAt(pos);
  11. const cls = line.number.toString();
  12. builder.add(
  13. line.from,
  14. line.from,
  15. Decoration.line({
  16. attributes: { 'data-line': cls },
  17. }),
  18. );
  19. pos = line.to + 1;
  20. }
  21. }
  22. return builder.finish();
  23. };
  24. export const setDataLine = ViewPlugin.fromClass(
  25. class {
  26. decorations: DecorationSet;
  27. constructor(view: EditorView) {
  28. this.decorations = stripeDeco(view);
  29. }
  30. update(update: ViewUpdate) {
  31. if (update.docChanged || update.viewportChanged) {
  32. this.decorations = stripeDeco(update.view);
  33. }
  34. }
  35. },
  36. {
  37. decorations: v => v.decorations,
  38. },
  39. );