metadata.ts 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. import { EditorView } from '@codemirror/view'
  2. import { Transaction, Text } from '@codemirror/state'
  3. const metadataChangeRe = /\\(documentclass|usepackage|RequirePackage|label)\b/
  4. export const metadata = () => [
  5. // trigger metadata reload if edited line contains metadata-related commands
  6. EditorView.updateListener.of(update => {
  7. if (update.docChanged) {
  8. let needsMetadataUpdate = false
  9. for (const transaction of update.transactions) {
  10. // ignore remote changes
  11. if (transaction.annotation(Transaction.remote)) {
  12. continue
  13. }
  14. transaction.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
  15. const docs: [Text, number, number][] = [
  16. [update.startState.doc, fromA, toA],
  17. [update.state.doc, fromB, toB],
  18. ]
  19. for (const [doc, from, to] of docs) {
  20. const fromLine = doc.lineAt(from).number
  21. const toLine = doc.lineAt(to).number
  22. for (const line of doc.iterLines(fromLine, toLine + 1)) {
  23. if (metadataChangeRe.test(line)) {
  24. needsMetadataUpdate = true
  25. return
  26. }
  27. }
  28. }
  29. })
  30. if (needsMetadataUpdate) {
  31. window.dispatchEvent(new CustomEvent('editor:metadata-outdated'))
  32. break
  33. }
  34. }
  35. }
  36. }),
  37. ]