setDataLine.ts 1.2 KB

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