@pierre/diffs 1.3.0-beta.6 → 1.3.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/dist/components/CodeView.d.ts +4 -1
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +45 -6
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts.map +1 -1
  6. package/dist/components/File.js +5 -2
  7. package/dist/components/File.js.map +1 -1
  8. package/dist/components/FileDiff.d.ts +36 -23
  9. package/dist/components/FileDiff.d.ts.map +1 -1
  10. package/dist/components/FileDiff.js +126 -58
  11. package/dist/components/FileDiff.js.map +1 -1
  12. package/dist/components/UnresolvedFile.d.ts +3 -2
  13. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  14. package/dist/components/UnresolvedFile.js +4 -2
  15. package/dist/components/UnresolvedFile.js.map +1 -1
  16. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  17. package/dist/components/VirtualizedFile.js +3 -7
  18. package/dist/components/VirtualizedFile.js.map +1 -1
  19. package/dist/components/VirtualizedFileDiff.d.ts +10 -4
  20. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  21. package/dist/components/VirtualizedFileDiff.js +178 -49
  22. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  23. package/dist/editor/editor.d.ts +2 -2
  24. package/dist/editor/editor.d.ts.map +1 -1
  25. package/dist/editor/editor.js +163 -106
  26. package/dist/editor/editor.js.map +1 -1
  27. package/dist/editor/editor2.js +1 -1
  28. package/dist/editor/selection.d.ts +1 -1
  29. package/dist/editor/selection.d.ts.map +1 -1
  30. package/dist/editor/selection.js +87 -37
  31. package/dist/editor/selection.js.map +1 -1
  32. package/dist/editor/textMeasure.d.ts.map +1 -1
  33. package/dist/editor/textMeasure.js +25 -7
  34. package/dist/editor/textMeasure.js.map +1 -1
  35. package/dist/editor/tokenzier.d.ts +2 -0
  36. package/dist/editor/tokenzier.d.ts.map +1 -1
  37. package/dist/editor/tokenzier.js +11 -3
  38. package/dist/editor/tokenzier.js.map +1 -1
  39. package/dist/editor/utils.d.ts +3 -1
  40. package/dist/editor/utils.d.ts.map +1 -1
  41. package/dist/editor/utils.js +14 -1
  42. package/dist/editor/utils.js.map +1 -1
  43. package/dist/index.d.ts +5 -3
  44. package/dist/index.js +3 -1
  45. package/dist/managers/InteractionManager.d.ts.map +1 -1
  46. package/dist/managers/InteractionManager.js +0 -1
  47. package/dist/managers/InteractionManager.js.map +1 -1
  48. package/dist/react/EditorContext.js.map +1 -1
  49. package/dist/react/MultiFileDiff.d.ts +3 -4
  50. package/dist/react/MultiFileDiff.d.ts.map +1 -1
  51. package/dist/react/MultiFileDiff.js.map +1 -1
  52. package/dist/react/index.d.ts +2 -2
  53. package/dist/react/utils/useFileDiffInstance.js +14 -15
  54. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  55. package/dist/renderers/DiffHunksRenderer.d.ts +2 -2
  56. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  57. package/dist/renderers/DiffHunksRenderer.js +29 -16
  58. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  59. package/dist/renderers/FileRenderer.js.map +1 -1
  60. package/dist/ssr/index.d.ts +2 -2
  61. package/dist/ssr/preloadDiffs.d.ts +11 -10
  62. package/dist/ssr/preloadDiffs.d.ts.map +1 -1
  63. package/dist/ssr/preloadDiffs.js +14 -6
  64. package/dist/ssr/preloadDiffs.js.map +1 -1
  65. package/dist/types.d.ts +59 -5
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/utils/areHunkDataEqual.js +1 -1
  68. package/dist/utils/areHunkDataEqual.js.map +1 -1
  69. package/dist/utils/awaitWithTimeout.d.ts +5 -0
  70. package/dist/utils/awaitWithTimeout.d.ts.map +1 -0
  71. package/dist/utils/awaitWithTimeout.js +15 -0
  72. package/dist/utils/awaitWithTimeout.js.map +1 -0
  73. package/dist/utils/cloneFileDiffMetadata.d.ts +7 -0
  74. package/dist/utils/cloneFileDiffMetadata.d.ts.map +1 -0
  75. package/dist/utils/cloneFileDiffMetadata.js +16 -0
  76. package/dist/utils/cloneFileDiffMetadata.js.map +1 -0
  77. package/dist/utils/computeEstimatedDiffHeights.d.ts +3 -1
  78. package/dist/utils/computeEstimatedDiffHeights.d.ts.map +1 -1
  79. package/dist/utils/computeEstimatedDiffHeights.js +8 -1
  80. package/dist/utils/computeEstimatedDiffHeights.js.map +1 -1
  81. package/dist/utils/createPreElement.js +0 -1
  82. package/dist/utils/createPreElement.js.map +1 -1
  83. package/dist/utils/getDiffFileInput.d.ts +14 -0
  84. package/dist/utils/getDiffFileInput.d.ts.map +1 -0
  85. package/dist/utils/getDiffFileInput.js +24 -0
  86. package/dist/utils/getDiffFileInput.js.map +1 -0
  87. package/dist/utils/getDiffHunksRendererOptions.js +1 -0
  88. package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
  89. package/dist/utils/getFiletypeFromFileName.d.ts.map +1 -1
  90. package/dist/utils/getFiletypeFromFileName.js +2 -0
  91. package/dist/utils/getFiletypeFromFileName.js.map +1 -1
  92. package/dist/utils/hydratePartialDiff.d.ts +10 -0
  93. package/dist/utils/hydratePartialDiff.d.ts.map +1 -0
  94. package/dist/utils/hydratePartialDiff.js +140 -0
  95. package/dist/utils/hydratePartialDiff.js.map +1 -0
  96. package/dist/utils/iterateOverDiff.js +3 -3
  97. package/dist/utils/iterateOverDiff.js.map +1 -1
  98. package/dist/utils/parseDiffFromFile.d.ts +1 -1
  99. package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  100. package/dist/utils/parseDiffFromFile.js +26 -5
  101. package/dist/utils/parseDiffFromFile.js.map +1 -1
  102. package/dist/utils/setWrapperNodeProps.js +0 -1
  103. package/dist/utils/setWrapperNodeProps.js.map +1 -1
  104. package/dist/utils/updateDiffHunks.d.ts +5 -1
  105. package/dist/utils/updateDiffHunks.d.ts.map +1 -1
  106. package/dist/utils/updateDiffHunks.js +26 -4
  107. package/dist/utils/updateDiffHunks.js.map +1 -1
  108. package/dist/worker/WorkerPoolManager.d.ts +7 -2
  109. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  110. package/dist/worker/WorkerPoolManager.js +78 -15
  111. package/dist/worker/WorkerPoolManager.js.map +1 -1
  112. package/dist/worker/index.d.ts +2 -2
  113. package/dist/worker/types.d.ts +7 -1
  114. package/dist/worker/types.d.ts.map +1 -1
  115. package/dist/worker/worker-portable.js +5 -3
  116. package/dist/worker/worker-portable.js.map +1 -1
  117. package/dist/worker/worker.js +5 -3
  118. package/dist/worker/worker.js.map +1 -1
  119. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"getDiffHunksRendererOptions.js","names":[],"sources":["../../src/utils/getDiffHunksRendererOptions.ts"],"sourcesContent":["import type { FileDiffOptions } from '../components/FileDiff';\nimport type { DiffHunksRendererOptions } from '../renderers/DiffHunksRenderer';\n\n// Build the renderer option snapshot with direct property reads. CodeView item\n// options may inherit prototype getters, so object spread can miss values.\nexport function getDiffHunksRendererOptions<LAnnotation>(\n options: FileDiffOptions<LAnnotation> | undefined\n): DiffHunksRendererOptions {\n return {\n theme: options?.theme,\n disableLineNumbers: options?.disableLineNumbers,\n overflow: options?.overflow,\n collapsed: options?.collapsed,\n disableFileHeader: options?.disableFileHeader,\n disableVirtualizationBuffers: options?.disableVirtualizationBuffers,\n stickyHeader: options?.stickyHeader,\n preferredHighlighter: options?.preferredHighlighter,\n useCSSClasses: options?.useCSSClasses,\n useTokenTransformer: options?.useTokenTransformer,\n tokenizeMaxLineLength: options?.tokenizeMaxLineLength,\n tokenizeMaxLength: options?.tokenizeMaxLength,\n diffStyle: options?.diffStyle,\n diffIndicators: options?.diffIndicators,\n disableBackground: options?.disableBackground,\n hunkSeparators:\n typeof options?.hunkSeparators === 'function'\n ? 'custom'\n : options?.hunkSeparators,\n expandUnchanged: options?.expandUnchanged,\n collapsedContextThreshold: options?.collapsedContextThreshold,\n lineDiffType: options?.lineDiffType,\n maxLineDiffLength: options?.maxLineDiffLength,\n expansionLineCount: options?.expansionLineCount,\n headerRenderMode:\n options?.renderCustomHeader != null ? 'custom' : 'default',\n };\n}\n"],"mappings":";AAKA,SAAgB,4BACd,SAC0B;CAC1B,OAAO;EACL,OAAO,SAAS;EAChB,oBAAoB,SAAS;EAC7B,UAAU,SAAS;EACnB,WAAW,SAAS;EACpB,mBAAmB,SAAS;EAC5B,8BAA8B,SAAS;EACvC,cAAc,SAAS;EACvB,sBAAsB,SAAS;EAC/B,eAAe,SAAS;EACxB,qBAAqB,SAAS;EAC9B,uBAAuB,SAAS;EAChC,mBAAmB,SAAS;EAC5B,WAAW,SAAS;EACpB,gBAAgB,SAAS;EACzB,mBAAmB,SAAS;EAC5B,gBACE,OAAO,SAAS,mBAAmB,aAC/B,WACA,SAAS;EACf,iBAAiB,SAAS;EAC1B,2BAA2B,SAAS;EACpC,cAAc,SAAS;EACvB,mBAAmB,SAAS;EAC5B,oBAAoB,SAAS;EAC7B,kBACE,SAAS,sBAAsB,OAAO,WAAW;CACrD;AACF"}
1
+ {"version":3,"file":"getDiffHunksRendererOptions.js","names":[],"sources":["../../src/utils/getDiffHunksRendererOptions.ts"],"sourcesContent":["import type { FileDiffOptions } from '../components/FileDiff';\nimport type { DiffHunksRendererOptions } from '../renderers/DiffHunksRenderer';\n\n// Build the renderer option snapshot with direct property reads. CodeView item\n// options may inherit prototype getters, so object spread can miss values.\nexport function getDiffHunksRendererOptions<LAnnotation>(\n options: FileDiffOptions<LAnnotation> | undefined\n): DiffHunksRendererOptions {\n return {\n theme: options?.theme,\n disableLineNumbers: options?.disableLineNumbers,\n overflow: options?.overflow,\n collapsed: options?.collapsed,\n disableFileHeader: options?.disableFileHeader,\n disableVirtualizationBuffers: options?.disableVirtualizationBuffers,\n stickyHeader: options?.stickyHeader,\n preferredHighlighter: options?.preferredHighlighter,\n useCSSClasses: options?.useCSSClasses,\n useTokenTransformer: options?.useTokenTransformer,\n tokenizeMaxLineLength: options?.tokenizeMaxLineLength,\n tokenizeMaxLength: options?.tokenizeMaxLength,\n diffStyle: options?.diffStyle,\n diffIndicators: options?.diffIndicators,\n disableBackground: options?.disableBackground,\n hunkSeparators:\n typeof options?.hunkSeparators === 'function'\n ? 'custom'\n : options?.hunkSeparators,\n expandUnchanged: options?.expandUnchanged,\n loadDiffFiles: options?.loadDiffFiles,\n collapsedContextThreshold: options?.collapsedContextThreshold,\n lineDiffType: options?.lineDiffType,\n maxLineDiffLength: options?.maxLineDiffLength,\n expansionLineCount: options?.expansionLineCount,\n headerRenderMode:\n options?.renderCustomHeader != null ? 'custom' : 'default',\n };\n}\n"],"mappings":";AAKA,SAAgB,4BACd,SAC0B;CAC1B,OAAO;EACL,OAAO,SAAS;EAChB,oBAAoB,SAAS;EAC7B,UAAU,SAAS;EACnB,WAAW,SAAS;EACpB,mBAAmB,SAAS;EAC5B,8BAA8B,SAAS;EACvC,cAAc,SAAS;EACvB,sBAAsB,SAAS;EAC/B,eAAe,SAAS;EACxB,qBAAqB,SAAS;EAC9B,uBAAuB,SAAS;EAChC,mBAAmB,SAAS;EAC5B,WAAW,SAAS;EACpB,gBAAgB,SAAS;EACzB,mBAAmB,SAAS;EAC5B,gBACE,OAAO,SAAS,mBAAmB,aAC/B,WACA,SAAS;EACf,iBAAiB,SAAS;EAC1B,eAAe,SAAS;EACxB,2BAA2B,SAAS;EACpC,cAAc,SAAS;EACvB,mBAAmB,SAAS;EAC5B,oBAAoB,SAAS;EAC7B,kBACE,SAAS,sBAAsB,OAAO,WAAW;CACrD;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"getFiletypeFromFileName.d.ts","names":[],"sources":["../../src/utils/getFiletypeFromFileName.ts"],"mappings":";;;cAOa,wBAAA,EAA0B,kBAwVtC;AAAA,iBAEe,uBAAA,CAAwB,QAAA,WAAmB,kBAAkB;AAAA,iBA4B7D,uBAAA,CACd,OAAA,UACA,GAAA,EAAK,kBAAkB;AAAA,iBAgBT,0BAAA;AAAA,iBAIA,kBAAA,CACd,GAAA,UACA,IAAA,EAAM,kBAAkB;AAAA,iBAgBV,sBAAA,IAA0B,kBAAkB"}
1
+ {"version":3,"file":"getFiletypeFromFileName.d.ts","names":[],"sources":["../../src/utils/getFiletypeFromFileName.ts"],"mappings":";;;cAOa,wBAAA,EAA0B,kBA0VtC;AAAA,iBAEe,uBAAA,CAAwB,QAAA,WAAmB,kBAAkB;AAAA,iBA4B7D,uBAAA,CACd,OAAA,UACA,GAAA,EAAK,kBAAkB;AAAA,iBAgBT,0BAAA;AAAA,iBAIA,kBAAA,CACd,GAAA,UACA,IAAA,EAAM,kBAAkB;AAAA,iBAgBV,sBAAA,IAA0B,kBAAkB"}
@@ -310,6 +310,8 @@ const EXTENSION_TO_FILE_FORMAT = {
310
310
  tfvars: "tfvars",
311
311
  toml: "toml",
312
312
  ts: "typescript",
313
+ mts: "typescript",
314
+ cts: "typescript",
313
315
  tsp: "typespec",
314
316
  tsv: "tsv",
315
317
  tsx: "tsx",
@@ -1 +1 @@
1
- {"version":3,"file":"getFiletypeFromFileName.js","names":[],"sources":["../../src/utils/getFiletypeFromFileName.ts"],"sourcesContent":["import type { ExtensionFormatMap, SupportedLanguages } from '../types';\n\nconst CUSTOM_EXTENSION_TO_FILE_FORMAT: Map<string, SupportedLanguages> =\n new Map();\n\nlet customExtensionsVersion = 0;\n\nexport const EXTENSION_TO_FILE_FORMAT: ExtensionFormatMap = {\n '1c': '1c',\n abap: 'abap',\n as: 'actionscript-3',\n ada: 'ada',\n adb: 'ada',\n ads: 'ada',\n adoc: 'asciidoc',\n asciidoc: 'asciidoc',\n 'component.html': 'angular-html',\n 'component.ts': 'angular-ts',\n conf: 'nginx',\n htaccess: 'apache',\n cls: 'tex',\n trigger: 'apex',\n apl: 'apl',\n applescript: 'applescript',\n scpt: 'applescript',\n ara: 'ara',\n asm: 'asm',\n s: 'riscv',\n astro: 'astro',\n awk: 'awk',\n bal: 'ballerina',\n sh: 'zsh',\n bash: 'zsh',\n bat: 'cmd',\n cmd: 'cmd',\n be: 'berry',\n beancount: 'beancount',\n bib: 'bibtex',\n bicep: 'bicep',\n 'blade.php': 'blade',\n bsl: 'bsl',\n c: 'c',\n h: 'objective-cpp',\n cs: 'csharp',\n cpp: 'cpp',\n hpp: 'cpp',\n cc: 'cpp',\n cxx: 'cpp',\n hh: 'cpp',\n cdc: 'cdc',\n cairo: 'cairo',\n clar: 'clarity',\n clj: 'clojure',\n cljs: 'clojure',\n cljc: 'clojure',\n soy: 'soy',\n cmake: 'cmake',\n 'CMakeLists.txt': 'cmake',\n cob: 'cobol',\n cbl: 'cobol',\n cobol: 'cobol',\n CODEOWNERS: 'codeowners',\n ql: 'ql',\n coffee: 'coffeescript',\n lisp: 'lisp',\n cl: 'lisp',\n lsp: 'lisp',\n log: 'log',\n v: 'verilog',\n cql: 'cql',\n cr: 'crystal',\n css: 'css',\n csv: 'csv',\n cue: 'cue',\n cypher: 'cypher',\n cyp: 'cypher',\n d: 'd',\n dart: 'dart',\n dax: 'dax',\n desktop: 'desktop',\n diff: 'diff',\n patch: 'diff',\n Dockerfile: 'dockerfile',\n dockerfile: 'dockerfile',\n env: 'dotenv',\n dm: 'dream-maker',\n edge: 'edge',\n el: 'emacs-lisp',\n ex: 'elixir',\n exs: 'elixir',\n elm: 'elm',\n erb: 'erb',\n erl: 'erlang',\n hrl: 'erlang',\n f: 'fortran-fixed-form',\n for: 'fortran-fixed-form',\n fs: 'fsharp',\n fsi: 'fsharp',\n fsx: 'fsharp',\n f03: 'f03',\n f08: 'f08',\n f18: 'f18',\n f77: 'f77',\n f90: 'fortran-free-form',\n f95: 'fortran-free-form',\n fnl: 'fennel',\n fish: 'fish',\n ftl: 'ftl',\n tres: 'gdresource',\n res: 'gdresource',\n gd: 'gdscript',\n gdshader: 'gdshader',\n gs: 'genie',\n feature: 'gherkin',\n COMMIT_EDITMSG: 'git-commit',\n 'git-rebase-todo': 'git-rebase',\n gjs: 'glimmer-js',\n gleam: 'gleam',\n gts: 'glimmer-ts',\n glsl: 'glsl',\n vert: 'glsl',\n frag: 'glsl',\n shader: 'shaderlab',\n gp: 'gnuplot',\n plt: 'gnuplot',\n gnuplot: 'gnuplot',\n go: 'go',\n graphql: 'graphql',\n gql: 'graphql',\n groovy: 'groovy',\n gvy: 'groovy',\n hack: 'hack',\n haml: 'haml',\n hbs: 'handlebars',\n handlebars: 'handlebars',\n hs: 'haskell',\n lhs: 'haskell',\n hx: 'haxe',\n hcl: 'hcl',\n hjson: 'hjson',\n hlsl: 'hlsl',\n fx: 'hlsl',\n html: 'html',\n htm: 'html',\n http: 'http',\n rest: 'http',\n hxml: 'hxml',\n hy: 'hy',\n imba: 'imba',\n ini: 'ini',\n cfg: 'ini',\n jade: 'pug',\n pug: 'pug',\n java: 'java',\n js: 'javascript',\n mjs: 'javascript',\n cjs: 'javascript',\n jinja: 'jinja',\n jinja2: 'jinja',\n j2: 'jinja',\n jison: 'jison',\n jl: 'julia',\n json: 'json',\n json5: 'json5',\n jsonc: 'jsonc',\n jsonl: 'jsonl',\n jsonnet: 'jsonnet',\n libsonnet: 'jsonnet',\n jssm: 'jssm',\n jsx: 'jsx',\n kt: 'kotlin',\n kts: 'kts',\n kql: 'kusto',\n tex: 'tex',\n ltx: 'tex',\n lean: 'lean4',\n less: 'less',\n liquid: 'liquid',\n lit: 'lit',\n ll: 'llvm',\n logo: 'logo',\n lua: 'lua',\n luau: 'luau',\n Makefile: 'makefile',\n mk: 'makefile',\n makefile: 'makefile',\n md: 'markdown',\n markdown: 'markdown',\n marko: 'marko',\n m: 'wolfram',\n mat: 'matlab',\n mdc: 'mdc',\n mdx: 'mdx',\n wiki: 'wikitext',\n mediawiki: 'wikitext',\n mmd: 'mermaid',\n mermaid: 'mermaid',\n mips: 'mipsasm',\n mojo: 'mojo',\n '🔥': 'mojo',\n move: 'move',\n nar: 'narrat',\n nf: 'nextflow',\n nim: 'nim',\n nims: 'nim',\n nimble: 'nim',\n nix: 'nix',\n nu: 'nushell',\n mm: 'objective-cpp',\n ml: 'ocaml',\n mli: 'ocaml',\n mll: 'ocaml',\n mly: 'ocaml',\n pas: 'pascal',\n p: 'pascal',\n pl: 'prolog',\n pm: 'perl',\n t: 'perl',\n raku: 'raku',\n p6: 'raku',\n pl6: 'raku',\n php: 'php',\n phtml: 'php',\n pls: 'plsql',\n sql: 'sql',\n po: 'po',\n polar: 'polar',\n pcss: 'postcss',\n pot: 'pot',\n potx: 'potx',\n pq: 'powerquery',\n pqm: 'powerquery',\n ps1: 'powershell',\n psm1: 'powershell',\n psd1: 'powershell',\n prisma: 'prisma',\n pro: 'prolog',\n P: 'prolog',\n properties: 'properties',\n proto: 'protobuf',\n pp: 'puppet',\n purs: 'purescript',\n py: 'python',\n pyw: 'python',\n pyi: 'python',\n qml: 'qml',\n qmldir: 'qmldir',\n qss: 'qss',\n r: 'r',\n R: 'r',\n rkt: 'racket',\n rktl: 'racket',\n razor: 'razor',\n cshtml: 'razor',\n rb: 'ruby',\n rbw: 'ruby',\n reg: 'reg',\n regex: 'regexp',\n rel: 'rel',\n rs: 'rust',\n rst: 'rst',\n rake: 'ruby',\n gemspec: 'ruby',\n jbuilder: 'ruby',\n builder: 'ruby',\n rabl: 'ruby',\n arb: 'ruby',\n ru: 'ruby',\n podspec: 'ruby',\n Gemfile: 'ruby',\n Rakefile: 'ruby',\n Guardfile: 'ruby',\n Capfile: 'ruby',\n Berksfile: 'ruby',\n Brewfile: 'ruby',\n Vagrantfile: 'ruby',\n Thorfile: 'ruby',\n Appraisals: 'ruby',\n Dangerfile: 'ruby',\n sas: 'sas',\n sass: 'sass',\n scala: 'scala',\n sc: 'scala',\n scm: 'scheme',\n ss: 'scheme',\n sld: 'scheme',\n scss: 'scss',\n sdbl: 'sdbl',\n shadergraph: 'shader',\n st: 'smalltalk',\n sol: 'solidity',\n sparql: 'sparql',\n rq: 'sparql',\n spl: 'splunk',\n config: 'ssh-config',\n do: 'stata',\n ado: 'stata',\n dta: 'stata',\n styl: 'stylus',\n stylus: 'stylus',\n svelte: 'svelte',\n swift: 'swift',\n sv: 'system-verilog',\n svh: 'system-verilog',\n service: 'systemd',\n socket: 'systemd',\n device: 'systemd',\n timer: 'systemd',\n talon: 'talonscript',\n tasl: 'tasl',\n tcl: 'tcl',\n templ: 'templ',\n tf: 'tf',\n tfvars: 'tfvars',\n toml: 'toml',\n ts: 'typescript',\n tsp: 'typespec',\n tsv: 'tsv',\n tsx: 'tsx',\n ttl: 'turtle',\n twig: 'twig',\n typ: 'typst',\n vv: 'v',\n vala: 'vala',\n vapi: 'vala',\n vb: 'vb',\n vbs: 'vb',\n bas: 'vb',\n vh: 'verilog',\n vhd: 'vhdl',\n vhdl: 'vhdl',\n vim: 'vimscript',\n vue: 'vue',\n 'vine.ts': 'vue-vine',\n vy: 'vyper',\n wasm: 'wasm',\n wat: 'wasm',\n wy: '文言',\n wgsl: 'wgsl',\n wit: 'wit',\n wl: 'wolfram',\n nb: 'wolfram',\n xml: 'xml',\n xsl: 'xsl',\n xslt: 'xsl',\n yaml: 'yaml',\n yml: 'yml',\n zs: 'zenscript',\n zig: 'zig',\n zsh: 'zsh',\n sty: 'tex',\n};\n\nexport function getFiletypeFromFileName(fileName: string): SupportedLanguages {\n if (CUSTOM_EXTENSION_TO_FILE_FORMAT.has(fileName)) {\n return CUSTOM_EXTENSION_TO_FILE_FORMAT.get(fileName) ?? 'text';\n }\n // Handle special files without extensions first\n if (EXTENSION_TO_FILE_FORMAT[fileName] != null) {\n return EXTENSION_TO_FILE_FORMAT[fileName];\n }\n\n // Try compound extensions first (e.g., .blade.php, .component.ts)\n const compoundMatch = fileName.match(/\\.([^/\\\\]+\\.[^/\\\\]+)$/);\n if (compoundMatch != null) {\n if (CUSTOM_EXTENSION_TO_FILE_FORMAT.has(compoundMatch[1])) {\n return CUSTOM_EXTENSION_TO_FILE_FORMAT.get(compoundMatch[1]) ?? 'text';\n }\n if (EXTENSION_TO_FILE_FORMAT[compoundMatch[1]] != null) {\n return EXTENSION_TO_FILE_FORMAT[compoundMatch[1]] ?? 'text';\n }\n }\n\n // Fall back to simple extension\n const simpleMatch = fileName.match(/\\.([^.]+)$/)?.[1] ?? '';\n if (CUSTOM_EXTENSION_TO_FILE_FORMAT.has(simpleMatch)) {\n return CUSTOM_EXTENSION_TO_FILE_FORMAT.get(simpleMatch) ?? 'text';\n }\n return EXTENSION_TO_FILE_FORMAT[simpleMatch] ?? 'text';\n}\n\nexport function replaceCustomExtensions(\n version: number,\n map: ExtensionFormatMap\n): boolean {\n if (version <= customExtensionsVersion) {\n return false;\n }\n CUSTOM_EXTENSION_TO_FILE_FORMAT.clear();\n for (const key in map) {\n const lang = map[key];\n if (lang != null) {\n CUSTOM_EXTENSION_TO_FILE_FORMAT.set(key, lang);\n }\n }\n customExtensionsVersion = version;\n return true;\n}\n\nexport function getCustomExtensionsVersion(): number {\n return customExtensionsVersion;\n}\n\nexport function setCustomExtension(\n key: string,\n lang: SupportedLanguages\n): boolean {\n const existing = CUSTOM_EXTENSION_TO_FILE_FORMAT.get(key);\n if (existing === lang) {\n return false;\n }\n if (existing != null) {\n console.warn(\n `setCustomExtension: overriding custom mapping for \"${key}\" from \"${existing}\" to \"${lang}\"`\n );\n }\n CUSTOM_EXTENSION_TO_FILE_FORMAT.set(key, lang);\n customExtensionsVersion++;\n return true;\n}\n\nexport function getCustomExtensionsMap(): ExtensionFormatMap {\n return Object.fromEntries(\n CUSTOM_EXTENSION_TO_FILE_FORMAT\n ) as ExtensionFormatMap;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"getFiletypeFromFileName.js","names":[],"sources":["../../src/utils/getFiletypeFromFileName.ts"],"sourcesContent":["import type { ExtensionFormatMap, SupportedLanguages } from '../types';\n\nconst CUSTOM_EXTENSION_TO_FILE_FORMAT: Map<string, SupportedLanguages> =\n new Map();\n\nlet customExtensionsVersion = 0;\n\nexport const EXTENSION_TO_FILE_FORMAT: ExtensionFormatMap = {\n '1c': '1c',\n abap: 'abap',\n as: 'actionscript-3',\n ada: 'ada',\n adb: 'ada',\n ads: 'ada',\n adoc: 'asciidoc',\n asciidoc: 'asciidoc',\n 'component.html': 'angular-html',\n 'component.ts': 'angular-ts',\n conf: 'nginx',\n htaccess: 'apache',\n cls: 'tex',\n trigger: 'apex',\n apl: 'apl',\n applescript: 'applescript',\n scpt: 'applescript',\n ara: 'ara',\n asm: 'asm',\n s: 'riscv',\n astro: 'astro',\n awk: 'awk',\n bal: 'ballerina',\n sh: 'zsh',\n bash: 'zsh',\n bat: 'cmd',\n cmd: 'cmd',\n be: 'berry',\n beancount: 'beancount',\n bib: 'bibtex',\n bicep: 'bicep',\n 'blade.php': 'blade',\n bsl: 'bsl',\n c: 'c',\n h: 'objective-cpp',\n cs: 'csharp',\n cpp: 'cpp',\n hpp: 'cpp',\n cc: 'cpp',\n cxx: 'cpp',\n hh: 'cpp',\n cdc: 'cdc',\n cairo: 'cairo',\n clar: 'clarity',\n clj: 'clojure',\n cljs: 'clojure',\n cljc: 'clojure',\n soy: 'soy',\n cmake: 'cmake',\n 'CMakeLists.txt': 'cmake',\n cob: 'cobol',\n cbl: 'cobol',\n cobol: 'cobol',\n CODEOWNERS: 'codeowners',\n ql: 'ql',\n coffee: 'coffeescript',\n lisp: 'lisp',\n cl: 'lisp',\n lsp: 'lisp',\n log: 'log',\n v: 'verilog',\n cql: 'cql',\n cr: 'crystal',\n css: 'css',\n csv: 'csv',\n cue: 'cue',\n cypher: 'cypher',\n cyp: 'cypher',\n d: 'd',\n dart: 'dart',\n dax: 'dax',\n desktop: 'desktop',\n diff: 'diff',\n patch: 'diff',\n Dockerfile: 'dockerfile',\n dockerfile: 'dockerfile',\n env: 'dotenv',\n dm: 'dream-maker',\n edge: 'edge',\n el: 'emacs-lisp',\n ex: 'elixir',\n exs: 'elixir',\n elm: 'elm',\n erb: 'erb',\n erl: 'erlang',\n hrl: 'erlang',\n f: 'fortran-fixed-form',\n for: 'fortran-fixed-form',\n fs: 'fsharp',\n fsi: 'fsharp',\n fsx: 'fsharp',\n f03: 'f03',\n f08: 'f08',\n f18: 'f18',\n f77: 'f77',\n f90: 'fortran-free-form',\n f95: 'fortran-free-form',\n fnl: 'fennel',\n fish: 'fish',\n ftl: 'ftl',\n tres: 'gdresource',\n res: 'gdresource',\n gd: 'gdscript',\n gdshader: 'gdshader',\n gs: 'genie',\n feature: 'gherkin',\n COMMIT_EDITMSG: 'git-commit',\n 'git-rebase-todo': 'git-rebase',\n gjs: 'glimmer-js',\n gleam: 'gleam',\n gts: 'glimmer-ts',\n glsl: 'glsl',\n vert: 'glsl',\n frag: 'glsl',\n shader: 'shaderlab',\n gp: 'gnuplot',\n plt: 'gnuplot',\n gnuplot: 'gnuplot',\n go: 'go',\n graphql: 'graphql',\n gql: 'graphql',\n groovy: 'groovy',\n gvy: 'groovy',\n hack: 'hack',\n haml: 'haml',\n hbs: 'handlebars',\n handlebars: 'handlebars',\n hs: 'haskell',\n lhs: 'haskell',\n hx: 'haxe',\n hcl: 'hcl',\n hjson: 'hjson',\n hlsl: 'hlsl',\n fx: 'hlsl',\n html: 'html',\n htm: 'html',\n http: 'http',\n rest: 'http',\n hxml: 'hxml',\n hy: 'hy',\n imba: 'imba',\n ini: 'ini',\n cfg: 'ini',\n jade: 'pug',\n pug: 'pug',\n java: 'java',\n js: 'javascript',\n mjs: 'javascript',\n cjs: 'javascript',\n jinja: 'jinja',\n jinja2: 'jinja',\n j2: 'jinja',\n jison: 'jison',\n jl: 'julia',\n json: 'json',\n json5: 'json5',\n jsonc: 'jsonc',\n jsonl: 'jsonl',\n jsonnet: 'jsonnet',\n libsonnet: 'jsonnet',\n jssm: 'jssm',\n jsx: 'jsx',\n kt: 'kotlin',\n kts: 'kts',\n kql: 'kusto',\n tex: 'tex',\n ltx: 'tex',\n lean: 'lean4',\n less: 'less',\n liquid: 'liquid',\n lit: 'lit',\n ll: 'llvm',\n logo: 'logo',\n lua: 'lua',\n luau: 'luau',\n Makefile: 'makefile',\n mk: 'makefile',\n makefile: 'makefile',\n md: 'markdown',\n markdown: 'markdown',\n marko: 'marko',\n m: 'wolfram',\n mat: 'matlab',\n mdc: 'mdc',\n mdx: 'mdx',\n wiki: 'wikitext',\n mediawiki: 'wikitext',\n mmd: 'mermaid',\n mermaid: 'mermaid',\n mips: 'mipsasm',\n mojo: 'mojo',\n '🔥': 'mojo',\n move: 'move',\n nar: 'narrat',\n nf: 'nextflow',\n nim: 'nim',\n nims: 'nim',\n nimble: 'nim',\n nix: 'nix',\n nu: 'nushell',\n mm: 'objective-cpp',\n ml: 'ocaml',\n mli: 'ocaml',\n mll: 'ocaml',\n mly: 'ocaml',\n pas: 'pascal',\n p: 'pascal',\n pl: 'prolog',\n pm: 'perl',\n t: 'perl',\n raku: 'raku',\n p6: 'raku',\n pl6: 'raku',\n php: 'php',\n phtml: 'php',\n pls: 'plsql',\n sql: 'sql',\n po: 'po',\n polar: 'polar',\n pcss: 'postcss',\n pot: 'pot',\n potx: 'potx',\n pq: 'powerquery',\n pqm: 'powerquery',\n ps1: 'powershell',\n psm1: 'powershell',\n psd1: 'powershell',\n prisma: 'prisma',\n pro: 'prolog',\n P: 'prolog',\n properties: 'properties',\n proto: 'protobuf',\n pp: 'puppet',\n purs: 'purescript',\n py: 'python',\n pyw: 'python',\n pyi: 'python',\n qml: 'qml',\n qmldir: 'qmldir',\n qss: 'qss',\n r: 'r',\n R: 'r',\n rkt: 'racket',\n rktl: 'racket',\n razor: 'razor',\n cshtml: 'razor',\n rb: 'ruby',\n rbw: 'ruby',\n reg: 'reg',\n regex: 'regexp',\n rel: 'rel',\n rs: 'rust',\n rst: 'rst',\n rake: 'ruby',\n gemspec: 'ruby',\n jbuilder: 'ruby',\n builder: 'ruby',\n rabl: 'ruby',\n arb: 'ruby',\n ru: 'ruby',\n podspec: 'ruby',\n Gemfile: 'ruby',\n Rakefile: 'ruby',\n Guardfile: 'ruby',\n Capfile: 'ruby',\n Berksfile: 'ruby',\n Brewfile: 'ruby',\n Vagrantfile: 'ruby',\n Thorfile: 'ruby',\n Appraisals: 'ruby',\n Dangerfile: 'ruby',\n sas: 'sas',\n sass: 'sass',\n scala: 'scala',\n sc: 'scala',\n scm: 'scheme',\n ss: 'scheme',\n sld: 'scheme',\n scss: 'scss',\n sdbl: 'sdbl',\n shadergraph: 'shader',\n st: 'smalltalk',\n sol: 'solidity',\n sparql: 'sparql',\n rq: 'sparql',\n spl: 'splunk',\n config: 'ssh-config',\n do: 'stata',\n ado: 'stata',\n dta: 'stata',\n styl: 'stylus',\n stylus: 'stylus',\n svelte: 'svelte',\n swift: 'swift',\n sv: 'system-verilog',\n svh: 'system-verilog',\n service: 'systemd',\n socket: 'systemd',\n device: 'systemd',\n timer: 'systemd',\n talon: 'talonscript',\n tasl: 'tasl',\n tcl: 'tcl',\n templ: 'templ',\n tf: 'tf',\n tfvars: 'tfvars',\n toml: 'toml',\n ts: 'typescript',\n mts: 'typescript',\n cts: 'typescript',\n tsp: 'typespec',\n tsv: 'tsv',\n tsx: 'tsx',\n ttl: 'turtle',\n twig: 'twig',\n typ: 'typst',\n vv: 'v',\n vala: 'vala',\n vapi: 'vala',\n vb: 'vb',\n vbs: 'vb',\n bas: 'vb',\n vh: 'verilog',\n vhd: 'vhdl',\n vhdl: 'vhdl',\n vim: 'vimscript',\n vue: 'vue',\n 'vine.ts': 'vue-vine',\n vy: 'vyper',\n wasm: 'wasm',\n wat: 'wasm',\n wy: '文言',\n wgsl: 'wgsl',\n wit: 'wit',\n wl: 'wolfram',\n nb: 'wolfram',\n xml: 'xml',\n xsl: 'xsl',\n xslt: 'xsl',\n yaml: 'yaml',\n yml: 'yml',\n zs: 'zenscript',\n zig: 'zig',\n zsh: 'zsh',\n sty: 'tex',\n};\n\nexport function getFiletypeFromFileName(fileName: string): SupportedLanguages {\n if (CUSTOM_EXTENSION_TO_FILE_FORMAT.has(fileName)) {\n return CUSTOM_EXTENSION_TO_FILE_FORMAT.get(fileName) ?? 'text';\n }\n // Handle special files without extensions first\n if (EXTENSION_TO_FILE_FORMAT[fileName] != null) {\n return EXTENSION_TO_FILE_FORMAT[fileName];\n }\n\n // Try compound extensions first (e.g., .blade.php, .component.ts)\n const compoundMatch = fileName.match(/\\.([^/\\\\]+\\.[^/\\\\]+)$/);\n if (compoundMatch != null) {\n if (CUSTOM_EXTENSION_TO_FILE_FORMAT.has(compoundMatch[1])) {\n return CUSTOM_EXTENSION_TO_FILE_FORMAT.get(compoundMatch[1]) ?? 'text';\n }\n if (EXTENSION_TO_FILE_FORMAT[compoundMatch[1]] != null) {\n return EXTENSION_TO_FILE_FORMAT[compoundMatch[1]] ?? 'text';\n }\n }\n\n // Fall back to simple extension\n const simpleMatch = fileName.match(/\\.([^.]+)$/)?.[1] ?? '';\n if (CUSTOM_EXTENSION_TO_FILE_FORMAT.has(simpleMatch)) {\n return CUSTOM_EXTENSION_TO_FILE_FORMAT.get(simpleMatch) ?? 'text';\n }\n return EXTENSION_TO_FILE_FORMAT[simpleMatch] ?? 'text';\n}\n\nexport function replaceCustomExtensions(\n version: number,\n map: ExtensionFormatMap\n): boolean {\n if (version <= customExtensionsVersion) {\n return false;\n }\n CUSTOM_EXTENSION_TO_FILE_FORMAT.clear();\n for (const key in map) {\n const lang = map[key];\n if (lang != null) {\n CUSTOM_EXTENSION_TO_FILE_FORMAT.set(key, lang);\n }\n }\n customExtensionsVersion = version;\n return true;\n}\n\nexport function getCustomExtensionsVersion(): number {\n return customExtensionsVersion;\n}\n\nexport function setCustomExtension(\n key: string,\n lang: SupportedLanguages\n): boolean {\n const existing = CUSTOM_EXTENSION_TO_FILE_FORMAT.get(key);\n if (existing === lang) {\n return false;\n }\n if (existing != null) {\n console.warn(\n `setCustomExtension: overriding custom mapping for \"${key}\" from \"${existing}\" to \"${lang}\"`\n );\n }\n CUSTOM_EXTENSION_TO_FILE_FORMAT.set(key, lang);\n customExtensionsVersion++;\n return true;\n}\n\nexport function getCustomExtensionsMap(): ExtensionFormatMap {\n return Object.fromEntries(\n CUSTOM_EXTENSION_TO_FILE_FORMAT\n ) as ExtensionFormatMap;\n}\n"],"mappings":";AAEA,MAAM,kDACJ,IAAI,IAAI;AAEV,IAAI,0BAA0B;AAE9B,MAAa,2BAA+C;CAC1D,MAAM;CACN,MAAM;CACN,IAAI;CACJ,KAAK;CACL,KAAK;CACL,KAAK;CACL,MAAM;CACN,UAAU;CACV,kBAAkB;CAClB,gBAAgB;CAChB,MAAM;CACN,UAAU;CACV,KAAK;CACL,SAAS;CACT,KAAK;CACL,aAAa;CACb,MAAM;CACN,KAAK;CACL,KAAK;CACL,GAAG;CACH,OAAO;CACP,KAAK;CACL,KAAK;CACL,IAAI;CACJ,MAAM;CACN,KAAK;CACL,KAAK;CACL,IAAI;CACJ,WAAW;CACX,KAAK;CACL,OAAO;CACP,aAAa;CACb,KAAK;CACL,GAAG;CACH,GAAG;CACH,IAAI;CACJ,KAAK;CACL,KAAK;CACL,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,KAAK;CACL,OAAO;CACP,MAAM;CACN,KAAK;CACL,MAAM;CACN,MAAM;CACN,KAAK;CACL,OAAO;CACP,kBAAkB;CAClB,KAAK;CACL,KAAK;CACL,OAAO;CACP,YAAY;CACZ,IAAI;CACJ,QAAQ;CACR,MAAM;CACN,IAAI;CACJ,KAAK;CACL,KAAK;CACL,GAAG;CACH,KAAK;CACL,IAAI;CACJ,KAAK;CACL,KAAK;CACL,KAAK;CACL,QAAQ;CACR,KAAK;CACL,GAAG;CACH,MAAM;CACN,KAAK;CACL,SAAS;CACT,MAAM;CACN,OAAO;CACP,YAAY;CACZ,YAAY;CACZ,KAAK;CACL,IAAI;CACJ,MAAM;CACN,IAAI;CACJ,IAAI;CACJ,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,GAAG;CACH,KAAK;CACL,IAAI;CACJ,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,MAAM;CACN,KAAK;CACL,MAAM;CACN,KAAK;CACL,IAAI;CACJ,UAAU;CACV,IAAI;CACJ,SAAS;CACT,gBAAgB;CAChB,mBAAmB;CACnB,KAAK;CACL,OAAO;CACP,KAAK;CACL,MAAM;CACN,MAAM;CACN,MAAM;CACN,QAAQ;CACR,IAAI;CACJ,KAAK;CACL,SAAS;CACT,IAAI;CACJ,SAAS;CACT,KAAK;CACL,QAAQ;CACR,KAAK;CACL,MAAM;CACN,MAAM;CACN,KAAK;CACL,YAAY;CACZ,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,KAAK;CACL,OAAO;CACP,MAAM;CACN,IAAI;CACJ,MAAM;CACN,KAAK;CACL,MAAM;CACN,MAAM;CACN,MAAM;CACN,IAAI;CACJ,MAAM;CACN,KAAK;CACL,KAAK;CACL,MAAM;CACN,KAAK;CACL,MAAM;CACN,IAAI;CACJ,KAAK;CACL,KAAK;CACL,OAAO;CACP,QAAQ;CACR,IAAI;CACJ,OAAO;CACP,IAAI;CACJ,MAAM;CACN,OAAO;CACP,OAAO;CACP,OAAO;CACP,SAAS;CACT,WAAW;CACX,MAAM;CACN,KAAK;CACL,IAAI;CACJ,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,MAAM;CACN,MAAM;CACN,QAAQ;CACR,KAAK;CACL,IAAI;CACJ,MAAM;CACN,KAAK;CACL,MAAM;CACN,UAAU;CACV,IAAI;CACJ,UAAU;CACV,IAAI;CACJ,UAAU;CACV,OAAO;CACP,GAAG;CACH,KAAK;CACL,KAAK;CACL,KAAK;CACL,MAAM;CACN,WAAW;CACX,KAAK;CACL,SAAS;CACT,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,KAAK;CACL,IAAI;CACJ,KAAK;CACL,MAAM;CACN,QAAQ;CACR,KAAK;CACL,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,GAAG;CACH,IAAI;CACJ,IAAI;CACJ,GAAG;CACH,MAAM;CACN,IAAI;CACJ,KAAK;CACL,KAAK;CACL,OAAO;CACP,KAAK;CACL,KAAK;CACL,IAAI;CACJ,OAAO;CACP,MAAM;CACN,KAAK;CACL,MAAM;CACN,IAAI;CACJ,KAAK;CACL,KAAK;CACL,MAAM;CACN,MAAM;CACN,QAAQ;CACR,KAAK;CACL,GAAG;CACH,YAAY;CACZ,OAAO;CACP,IAAI;CACJ,MAAM;CACN,IAAI;CACJ,KAAK;CACL,KAAK;CACL,KAAK;CACL,QAAQ;CACR,KAAK;CACL,GAAG;CACH,GAAG;CACH,KAAK;CACL,MAAM;CACN,OAAO;CACP,QAAQ;CACR,IAAI;CACJ,KAAK;CACL,KAAK;CACL,OAAO;CACP,KAAK;CACL,IAAI;CACJ,KAAK;CACL,MAAM;CACN,SAAS;CACT,UAAU;CACV,SAAS;CACT,MAAM;CACN,KAAK;CACL,IAAI;CACJ,SAAS;CACT,SAAS;CACT,UAAU;CACV,WAAW;CACX,SAAS;CACT,WAAW;CACX,UAAU;CACV,aAAa;CACb,UAAU;CACV,YAAY;CACZ,YAAY;CACZ,KAAK;CACL,MAAM;CACN,OAAO;CACP,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,KAAK;CACL,MAAM;CACN,MAAM;CACN,aAAa;CACb,IAAI;CACJ,KAAK;CACL,QAAQ;CACR,IAAI;CACJ,KAAK;CACL,QAAQ;CACR,IAAI;CACJ,KAAK;CACL,KAAK;CACL,MAAM;CACN,QAAQ;CACR,QAAQ;CACR,OAAO;CACP,IAAI;CACJ,KAAK;CACL,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,OAAO;CACP,OAAO;CACP,MAAM;CACN,KAAK;CACL,OAAO;CACP,IAAI;CACJ,QAAQ;CACR,MAAM;CACN,IAAI;CACJ,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,MAAM;CACN,KAAK;CACL,IAAI;CACJ,MAAM;CACN,MAAM;CACN,IAAI;CACJ,KAAK;CACL,KAAK;CACL,IAAI;CACJ,KAAK;CACL,MAAM;CACN,KAAK;CACL,KAAK;CACL,WAAW;CACX,IAAI;CACJ,MAAM;CACN,KAAK;CACL,IAAI;CACJ,MAAM;CACN,KAAK;CACL,IAAI;CACJ,IAAI;CACJ,KAAK;CACL,KAAK;CACL,MAAM;CACN,MAAM;CACN,KAAK;CACL,IAAI;CACJ,KAAK;CACL,KAAK;CACL,KAAK;AACP;AAEA,SAAgB,wBAAwB,UAAsC;CAC5E,IAAI,gCAAgC,IAAI,QAAQ,GAC9C,OAAO,gCAAgC,IAAI,QAAQ,KAAK;CAG1D,IAAI,yBAAyB,aAAa,MACxC,OAAO,yBAAyB;CAIlC,MAAM,gBAAgB,SAAS,MAAM,uBAAuB;CAC5D,IAAI,iBAAiB,MAAM;EACzB,IAAI,gCAAgC,IAAI,cAAc,EAAE,GACtD,OAAO,gCAAgC,IAAI,cAAc,EAAE,KAAK;EAElE,IAAI,yBAAyB,cAAc,OAAO,MAChD,OAAO,yBAAyB,cAAc,OAAO;CAEzD;CAGA,MAAM,cAAc,SAAS,MAAM,YAAY,CAAC,GAAG,MAAM;CACzD,IAAI,gCAAgC,IAAI,WAAW,GACjD,OAAO,gCAAgC,IAAI,WAAW,KAAK;CAE7D,OAAO,yBAAyB,gBAAgB;AAClD;AAEA,SAAgB,wBACd,SACA,KACS;CACT,IAAI,WAAW,yBACb,OAAO;CAET,gCAAgC,MAAM;CACtC,KAAK,MAAM,OAAO,KAAK;EACrB,MAAM,OAAO,IAAI;EACjB,IAAI,QAAQ,MACV,gCAAgC,IAAI,KAAK,IAAI;CAEjD;CACA,0BAA0B;CAC1B,OAAO;AACT;AAEA,SAAgB,6BAAqC;CACnD,OAAO;AACT;AAEA,SAAgB,mBACd,KACA,MACS;CACT,MAAM,WAAW,gCAAgC,IAAI,GAAG;CACxD,IAAI,aAAa,MACf,OAAO;CAET,IAAI,YAAY,MACd,QAAQ,KACN,sDAAsD,IAAI,UAAU,SAAS,QAAQ,KAAK,EAC5F;CAEF,gCAAgC,IAAI,KAAK,IAAI;CAC7C;CACA,OAAO;AACT;AAEA,SAAgB,yBAA6C;CAC3D,OAAO,OAAO,YACZ,+BACF;AACF"}
@@ -0,0 +1,10 @@
1
+ import { FileDiffLoadedFiles, FileDiffMetadata } from "../types.js";
2
+
3
+ //#region src/utils/hydratePartialDiff.d.ts
4
+ /**
5
+ * Hydrates a partial diff in place with full file line arrays.
6
+ */
7
+ declare function hydratePartialDiff(type: 'clone' | 'merge', fileDiff: FileDiffMetadata, files: FileDiffLoadedFiles): FileDiffMetadata;
8
+ //#endregion
9
+ export { hydratePartialDiff };
10
+ //# sourceMappingURL=hydratePartialDiff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hydratePartialDiff.d.ts","names":[],"sources":["../../src/utils/hydratePartialDiff.ts"],"mappings":";;;;;AAkBA;iBAAgB,kBAAA,CACd,IAAA,qBACA,QAAA,EAAU,gBAAA,EACV,KAAA,EAAO,mBAAA,GACN,gBAAA"}
@@ -0,0 +1,140 @@
1
+ import { cloneFileDiffMetadata } from "./cloneFileDiffMetadata.js";
2
+ import { splitFileContents } from "./splitFileContents.js";
3
+ //#region src/utils/hydratePartialDiff.ts
4
+ /**
5
+ * Hydrates a partial diff in place with full file line arrays.
6
+ */
7
+ function hydratePartialDiff(type, fileDiff, files) {
8
+ const targetFileDiff = type === "clone" ? cloneFileDiffMetadata(fileDiff) : fileDiff;
9
+ if (!targetFileDiff.isPartial) throw new Error("hydratePartialDiff: fileDiff must be partial");
10
+ switch (targetFileDiff.type) {
11
+ case "change":
12
+ case "rename-changed": return hydrateTwoSidedFileDiff(targetFileDiff, requireOldFile(targetFileDiff, files), requireNewFile(targetFileDiff, files));
13
+ case "rename-pure": {
14
+ const newFile = requireNewFile(targetFileDiff, files);
15
+ requireMissingOldFile(targetFileDiff, files);
16
+ const lines = splitFileContents(newFile.contents);
17
+ targetFileDiff.isPartial = false;
18
+ targetFileDiff.deletionLines = lines;
19
+ targetFileDiff.additionLines = lines;
20
+ setHydratedCacheKey(targetFileDiff, null, newFile);
21
+ return targetFileDiff;
22
+ }
23
+ }
24
+ throw new Error(`hydratePartialDiff: ${targetFileDiff.type} diffs cannot be hydrated from loaded files`);
25
+ }
26
+ function hydrateTwoSidedFileDiff(fileDiff, oldFile, newFile) {
27
+ const deletionLines = splitFileContents(oldFile.contents);
28
+ const additionLines = splitFileContents(newFile.contents);
29
+ const { hunks, splitLineCount, unifiedLineCount } = hydrateHunks(fileDiff.hunks, additionLines.length);
30
+ fileDiff.hunks = hunks;
31
+ fileDiff.splitLineCount = splitLineCount;
32
+ fileDiff.unifiedLineCount = unifiedLineCount;
33
+ fileDiff.isPartial = false;
34
+ fileDiff.deletionLines = deletionLines;
35
+ fileDiff.additionLines = additionLines;
36
+ setHydratedCacheKey(fileDiff, oldFile, newFile);
37
+ return fileDiff;
38
+ }
39
+ function hydrateHunks(hunks, totalAdditionLines) {
40
+ let splitLineCount = 0;
41
+ let unifiedLineCount = 0;
42
+ let lastHunkAdditionEnd = 0;
43
+ const hydratedHunks = [];
44
+ for (const hunk of hunks) {
45
+ const additionLineIndex = Math.max(hunk.additionStart - 1, 0);
46
+ const deletionLineIndex = Math.max(hunk.deletionStart - 1, 0);
47
+ let contentAdditionLineIndex = additionLineIndex;
48
+ let contentDeletionLineIndex = deletionLineIndex;
49
+ let hunkAdditionLines = 0;
50
+ let hunkDeletionLines = 0;
51
+ let hunkSplitLineCount = 0;
52
+ let hunkUnifiedLineCount = 0;
53
+ const hunkContent = [];
54
+ for (const content of hunk.hunkContent) {
55
+ if (content.type === "context") {
56
+ hunkContent.push({
57
+ ...content,
58
+ additionLineIndex: contentAdditionLineIndex,
59
+ deletionLineIndex: contentDeletionLineIndex
60
+ });
61
+ contentAdditionLineIndex += content.lines;
62
+ contentDeletionLineIndex += content.lines;
63
+ hunkSplitLineCount += content.lines;
64
+ hunkUnifiedLineCount += content.lines;
65
+ continue;
66
+ }
67
+ hunkContent.push({
68
+ ...content,
69
+ additionLineIndex: contentAdditionLineIndex,
70
+ deletionLineIndex: contentDeletionLineIndex
71
+ });
72
+ contentAdditionLineIndex += content.additions;
73
+ contentDeletionLineIndex += content.deletions;
74
+ hunkAdditionLines += content.additions;
75
+ hunkDeletionLines += content.deletions;
76
+ hunkSplitLineCount += Math.max(content.additions, content.deletions);
77
+ hunkUnifiedLineCount += content.additions + content.deletions;
78
+ }
79
+ const collapsedBefore = Math.max(hunk.additionStart - 1 - lastHunkAdditionEnd, 0);
80
+ hydratedHunks.push({
81
+ ...hunk,
82
+ collapsedBefore,
83
+ additionLineIndex,
84
+ deletionLineIndex,
85
+ additionLines: hunkAdditionLines,
86
+ deletionLines: hunkDeletionLines,
87
+ hunkContent,
88
+ splitLineStart: splitLineCount + collapsedBefore,
89
+ unifiedLineStart: unifiedLineCount + collapsedBefore,
90
+ splitLineCount: hunkSplitLineCount,
91
+ unifiedLineCount: hunkUnifiedLineCount
92
+ });
93
+ splitLineCount += collapsedBefore + hunkSplitLineCount;
94
+ unifiedLineCount += collapsedBefore + hunkUnifiedLineCount;
95
+ lastHunkAdditionEnd = hunk.additionStart + hunk.additionCount - 1;
96
+ }
97
+ if (hydratedHunks.length > 0) {
98
+ const lastHunk = hydratedHunks[hydratedHunks.length - 1];
99
+ const lastHunkEnd = Math.max(lastHunk.additionStart + lastHunk.additionCount - 1, 0);
100
+ const collapsedAfter = Math.max(totalAdditionLines - lastHunkEnd, 0);
101
+ splitLineCount += collapsedAfter;
102
+ unifiedLineCount += collapsedAfter;
103
+ }
104
+ return {
105
+ hunks: hydratedHunks,
106
+ splitLineCount,
107
+ unifiedLineCount
108
+ };
109
+ }
110
+ function requireOldFile(fileDiff, files) {
111
+ if (files.oldFile == null) throw new Error(`hydratePartialDiff: ${fileDiff.type} diff for ${fileDiff.name} requires oldFile`);
112
+ return files.oldFile;
113
+ }
114
+ function requireNewFile(fileDiff, files) {
115
+ if (files.newFile == null) throw new Error(`hydratePartialDiff: ${fileDiff.type} diff for ${fileDiff.name} requires newFile`);
116
+ return files.newFile;
117
+ }
118
+ function requireMissingOldFile(fileDiff, files) {
119
+ if (files.oldFile !== null) throw new Error(`hydratePartialDiff: ${fileDiff.type} diff for ${fileDiff.name} requires oldFile to be null`);
120
+ }
121
+ function getHydratedCacheKey(fileDiff, oldFile, newFile) {
122
+ if (fileDiff.cacheKey != null) return `${fileDiff.cacheKey}:hydrated`;
123
+ return getLoadedFileCacheKey(oldFile, newFile);
124
+ }
125
+ function setHydratedCacheKey(fileDiff, oldFile, newFile) {
126
+ const cacheKey = getHydratedCacheKey(fileDiff, oldFile, newFile);
127
+ if (cacheKey == null) {
128
+ delete fileDiff.cacheKey;
129
+ return;
130
+ }
131
+ fileDiff.cacheKey = cacheKey;
132
+ }
133
+ function getLoadedFileCacheKey(oldFile, newFile) {
134
+ if (oldFile != null && newFile != null) return oldFile.cacheKey != null && newFile.cacheKey != null ? `${oldFile.cacheKey}:${newFile.cacheKey}` : void 0;
135
+ return oldFile?.cacheKey ?? newFile?.cacheKey;
136
+ }
137
+ //#endregion
138
+ export { hydratePartialDiff };
139
+
140
+ //# sourceMappingURL=hydratePartialDiff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hydratePartialDiff.js","names":[],"sources":["../../src/utils/hydratePartialDiff.ts"],"sourcesContent":["import type {\n FileContents,\n FileDiffLoadedFiles,\n FileDiffMetadata,\n Hunk,\n} from '../types';\nimport { cloneFileDiffMetadata } from './cloneFileDiffMetadata';\nimport { splitFileContents } from './splitFileContents';\n\ninterface HydratedHunksResult {\n hunks: Hunk[];\n splitLineCount: number;\n unifiedLineCount: number;\n}\n\n/**\n * Hydrates a partial diff in place with full file line arrays.\n */\nexport function hydratePartialDiff(\n type: 'clone' | 'merge',\n fileDiff: FileDiffMetadata,\n files: FileDiffLoadedFiles\n): FileDiffMetadata {\n const targetFileDiff =\n type === 'clone' ? cloneFileDiffMetadata(fileDiff) : fileDiff;\n\n if (!targetFileDiff.isPartial) {\n throw new Error('hydratePartialDiff: fileDiff must be partial');\n }\n\n switch (targetFileDiff.type) {\n case 'change':\n case 'rename-changed': {\n const oldFile = requireOldFile(targetFileDiff, files);\n const newFile = requireNewFile(targetFileDiff, files);\n return hydrateTwoSidedFileDiff(targetFileDiff, oldFile, newFile);\n }\n case 'rename-pure': {\n const newFile = requireNewFile(targetFileDiff, files);\n requireMissingOldFile(targetFileDiff, files);\n const lines = splitFileContents(newFile.contents);\n targetFileDiff.isPartial = false;\n targetFileDiff.deletionLines = lines;\n targetFileDiff.additionLines = lines;\n setHydratedCacheKey(targetFileDiff, null, newFile);\n return targetFileDiff;\n }\n }\n throw new Error(\n `hydratePartialDiff: ${targetFileDiff.type} diffs cannot be hydrated from loaded files`\n );\n}\n\nfunction hydrateTwoSidedFileDiff(\n fileDiff: FileDiffMetadata,\n oldFile: FileContents,\n newFile: FileContents\n): FileDiffMetadata {\n const deletionLines = splitFileContents(oldFile.contents);\n const additionLines = splitFileContents(newFile.contents);\n const { hunks, splitLineCount, unifiedLineCount } = hydrateHunks(\n fileDiff.hunks,\n additionLines.length\n );\n\n fileDiff.hunks = hunks;\n fileDiff.splitLineCount = splitLineCount;\n fileDiff.unifiedLineCount = unifiedLineCount;\n fileDiff.isPartial = false;\n fileDiff.deletionLines = deletionLines;\n fileDiff.additionLines = additionLines;\n setHydratedCacheKey(fileDiff, oldFile, newFile);\n return fileDiff;\n}\n\nfunction hydrateHunks(\n hunks: Hunk[],\n totalAdditionLines: number\n): HydratedHunksResult {\n let splitLineCount = 0;\n let unifiedLineCount = 0;\n let lastHunkAdditionEnd = 0;\n\n const hydratedHunks: Hunk[] = [];\n\n for (const hunk of hunks) {\n const additionLineIndex = Math.max(hunk.additionStart - 1, 0);\n const deletionLineIndex = Math.max(hunk.deletionStart - 1, 0);\n let contentAdditionLineIndex = additionLineIndex;\n let contentDeletionLineIndex = deletionLineIndex;\n let hunkAdditionLines = 0;\n let hunkDeletionLines = 0;\n let hunkSplitLineCount = 0;\n let hunkUnifiedLineCount = 0;\n const hunkContent: Hunk['hunkContent'] = [];\n\n for (const content of hunk.hunkContent) {\n if (content.type === 'context') {\n hunkContent.push({\n ...content,\n additionLineIndex: contentAdditionLineIndex,\n deletionLineIndex: contentDeletionLineIndex,\n });\n contentAdditionLineIndex += content.lines;\n contentDeletionLineIndex += content.lines;\n hunkSplitLineCount += content.lines;\n hunkUnifiedLineCount += content.lines;\n continue;\n }\n\n hunkContent.push({\n ...content,\n additionLineIndex: contentAdditionLineIndex,\n deletionLineIndex: contentDeletionLineIndex,\n });\n contentAdditionLineIndex += content.additions;\n contentDeletionLineIndex += content.deletions;\n hunkAdditionLines += content.additions;\n hunkDeletionLines += content.deletions;\n hunkSplitLineCount += Math.max(content.additions, content.deletions);\n hunkUnifiedLineCount += content.additions + content.deletions;\n }\n\n const collapsedBefore = Math.max(\n hunk.additionStart - 1 - lastHunkAdditionEnd,\n 0\n );\n hydratedHunks.push({\n ...hunk,\n collapsedBefore,\n additionLineIndex,\n deletionLineIndex,\n additionLines: hunkAdditionLines,\n deletionLines: hunkDeletionLines,\n hunkContent,\n splitLineStart: splitLineCount + collapsedBefore,\n unifiedLineStart: unifiedLineCount + collapsedBefore,\n splitLineCount: hunkSplitLineCount,\n unifiedLineCount: hunkUnifiedLineCount,\n });\n\n splitLineCount += collapsedBefore + hunkSplitLineCount;\n unifiedLineCount += collapsedBefore + hunkUnifiedLineCount;\n lastHunkAdditionEnd = hunk.additionStart + hunk.additionCount - 1;\n }\n\n if (hydratedHunks.length > 0) {\n const lastHunk = hydratedHunks[hydratedHunks.length - 1];\n const lastHunkEnd = Math.max(\n lastHunk.additionStart + lastHunk.additionCount - 1,\n 0\n );\n const collapsedAfter = Math.max(totalAdditionLines - lastHunkEnd, 0);\n splitLineCount += collapsedAfter;\n unifiedLineCount += collapsedAfter;\n }\n\n return { hunks: hydratedHunks, splitLineCount, unifiedLineCount };\n}\n\nfunction requireOldFile(\n fileDiff: FileDiffMetadata,\n files: FileDiffLoadedFiles\n): FileContents {\n if (files.oldFile == null) {\n throw new Error(\n `hydratePartialDiff: ${fileDiff.type} diff for ${fileDiff.name} requires oldFile`\n );\n }\n return files.oldFile;\n}\n\nfunction requireNewFile(\n fileDiff: FileDiffMetadata,\n files: FileDiffLoadedFiles\n): FileContents {\n if (files.newFile == null) {\n throw new Error(\n `hydratePartialDiff: ${fileDiff.type} diff for ${fileDiff.name} requires newFile`\n );\n }\n return files.newFile;\n}\n\nfunction requireMissingOldFile(\n fileDiff: FileDiffMetadata,\n files: FileDiffLoadedFiles\n): void {\n if (files.oldFile !== null) {\n throw new Error(\n `hydratePartialDiff: ${fileDiff.type} diff for ${fileDiff.name} requires oldFile to be null`\n );\n }\n}\n\nfunction getHydratedCacheKey(\n fileDiff: FileDiffMetadata,\n oldFile: FileContents | null,\n newFile: FileContents | null\n): string | undefined {\n if (fileDiff.cacheKey != null) {\n return `${fileDiff.cacheKey}:hydrated`;\n }\n return getLoadedFileCacheKey(oldFile, newFile);\n}\n\nfunction setHydratedCacheKey(\n fileDiff: FileDiffMetadata,\n oldFile: FileContents | null,\n newFile: FileContents | null\n): void {\n const cacheKey = getHydratedCacheKey(fileDiff, oldFile, newFile);\n if (cacheKey == null) {\n delete fileDiff.cacheKey;\n return;\n }\n fileDiff.cacheKey = cacheKey;\n}\n\nfunction getLoadedFileCacheKey(\n oldFile: FileContents | null,\n newFile: FileContents | null\n): string | undefined {\n if (oldFile != null && newFile != null) {\n return oldFile.cacheKey != null && newFile.cacheKey != null\n ? `${oldFile.cacheKey}:${newFile.cacheKey}`\n : undefined;\n }\n return oldFile?.cacheKey ?? newFile?.cacheKey;\n}\n"],"mappings":"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"}
@@ -24,10 +24,10 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
24
24
  else if (diffStyle === "split") return breakSplit;
25
25
  else return breakUnified && breakSplit;
26
26
  },
27
- shouldSkip(unifiedHeight, splitHeight) {
27
+ shouldSkip(unifiedCount, splitCount) {
28
28
  if (!state.isWindowedHighlight) return false;
29
- const skipUnified = state.unifiedCount + unifiedHeight < startingLine;
30
- const skipSplit = state.splitCount + splitHeight < startingLine;
29
+ const skipUnified = unifiedCount > 0 && state.unifiedCount + unifiedCount <= startingLine;
30
+ const skipSplit = splitCount > 0 && state.splitCount + splitCount <= startingLine;
31
31
  if (diffStyle === "unified") return skipUnified;
32
32
  else if (diffStyle === "split") return skipSplit;
33
33
  else return skipUnified && skipSplit;
@@ -1 +1 @@
1
- {"version":3,"file":"iterateOverDiff.js","names":[],"sources":["../../src/utils/iterateOverDiff.ts"],"sourcesContent":["import { DEFAULT_COLLAPSED_CONTEXT_THRESHOLD } from '../constants';\nimport type {\n ChangeContent,\n FileDiffMetadata,\n Hunk,\n HunkExpansionRegion,\n} from '../types';\nimport {\n getExpandedRegion,\n getTrailingExpandedRegion,\n} from './virtualDiffLayout';\n\nexport interface DiffLineMetadata {\n unifiedLineIndex: number;\n splitLineIndex: number;\n lineIndex: number;\n lineNumber: number;\n noEOFCR: boolean;\n}\n\nexport interface DiffLineCallbackBase {\n hunkIndex: number;\n hunk: Hunk | undefined; // undefined for trailing expansion region\n collapsedBefore: number; // > 0 means separator before this line, value = hidden lines\n collapsedAfter: number; // > 0 only on final line if trailing collapsed content\n}\n\ninterface DiffLineCallbackContextChange extends DiffLineCallbackBase {\n type: 'change' | 'context' | 'context-expanded';\n deletionLine: DiffLineMetadata;\n additionLine: DiffLineMetadata;\n}\n\ninterface DiffLineCallbackChangeDeletion extends DiffLineCallbackBase {\n type: 'change';\n deletionLine: DiffLineMetadata;\n additionLine?: undefined;\n}\n\ninterface DiffLineCallbackChangeAddition extends DiffLineCallbackBase {\n type: 'change';\n deletionLine?: undefined;\n additionLine: DiffLineMetadata;\n}\n\nexport type DiffLineCallbackProps =\n | DiffLineCallbackContextChange\n | DiffLineCallbackChangeDeletion\n | DiffLineCallbackChangeAddition;\n\ntype DiffStyle = 'unified' | 'split' | 'both';\n\ntype LineIterationBounds = [startIndex: number, endIndex: number];\n\ntype ChangeContentSide = 'deletions' | 'additions';\n\ntype ContextLineCallback = (index: number) => boolean | void;\n\ninterface IterationState {\n isWindowedHighlight: boolean;\n viewportStart: number;\n viewportEnd: number;\n splitCount: number;\n unifiedCount: number;\n finalHunkIndex: number;\n shouldBreak(): boolean;\n shouldSkip(unifiedHeight: number, splitHeight: number): boolean;\n incrementCounts(unifiedValue: number, splitValue: number): void;\n isInWindow(unifiedHeight: number, splitHeight: number): boolean;\n isInUnifiedWindow(height: number): boolean;\n isInSplitWindow(height: number): boolean;\n emit(props: DiffLineCallbackProps, silent?: boolean): boolean;\n}\n\ninterface IterationStartState {\n hunkIndex: number;\n splitCount: number;\n unifiedCount: number;\n}\n\ninterface HunkPrefixCounts {\n splitCount: number;\n unifiedCount: number;\n}\n\ninterface IterationStartStateProps extends Omit<\n IterateOverDiffProps,\n 'callback' | 'totalLines'\n> {\n startingLine: number;\n collapsedContextThreshold: number;\n}\n\ninterface HunkPrefixCountsProps extends Pick<\n IterationStartStateProps,\n 'diff' | 'expandedHunks' | 'collapsedContextThreshold'\n> {}\n\nexport type DiffLineCallback = (props: DiffLineCallbackProps) => boolean | void;\n\nexport interface IterateOverDiffProps {\n diff: FileDiffMetadata;\n diffStyle: DiffStyle;\n startingLine?: number;\n totalLines?: number;\n expandedHunks?: Map<number, HunkExpansionRegion> | true;\n collapsedContextThreshold?: number;\n callback: DiffLineCallback;\n}\n\nexport function iterateOverDiff({\n diff,\n diffStyle,\n startingLine = 0,\n totalLines = Infinity,\n expandedHunks,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n callback,\n}: IterateOverDiffProps): void {\n const iterationStart = getIterationStartState({\n diff,\n diffStyle,\n startingLine,\n expandedHunks,\n collapsedContextThreshold,\n });\n const state: IterationState = {\n viewportStart: startingLine,\n viewportEnd: startingLine + totalLines,\n isWindowedHighlight: startingLine > 0 || totalLines < Infinity,\n splitCount: iterationStart.splitCount,\n unifiedCount: iterationStart.unifiedCount,\n finalHunkIndex: diff.hunks.length - 1,\n shouldBreak() {\n if (!state.isWindowedHighlight) {\n return false;\n }\n\n const breakUnified = state.unifiedCount >= startingLine + totalLines;\n const breakSplit = state.splitCount >= startingLine + totalLines;\n\n if (diffStyle === 'unified') {\n return breakUnified;\n } else if (diffStyle === 'split') {\n return breakSplit;\n } else {\n return breakUnified && breakSplit;\n }\n },\n shouldSkip(unifiedHeight: number, splitHeight: number) {\n if (!state.isWindowedHighlight) {\n return false;\n }\n\n const skipUnified = state.unifiedCount + unifiedHeight < startingLine;\n const skipSplit = state.splitCount + splitHeight < startingLine;\n\n if (diffStyle === 'unified') {\n return skipUnified;\n } else if (diffStyle === 'split') {\n return skipSplit;\n } else {\n return skipUnified && skipSplit;\n }\n },\n incrementCounts(unifiedValue: number, splitValue: number) {\n if (diffStyle === 'unified' || diffStyle === 'both') {\n state.unifiedCount += unifiedValue;\n }\n if (diffStyle === 'split' || diffStyle === 'both') {\n state.splitCount += splitValue;\n }\n },\n isInWindow(unifiedHeight: number, splitHeight: number) {\n if (!state.isWindowedHighlight) {\n return true;\n }\n\n const unifiedInWindow = state.isInUnifiedWindow(unifiedHeight);\n const splitInWindow = state.isInSplitWindow(splitHeight);\n\n if (diffStyle === 'unified') {\n return unifiedInWindow;\n } else if (diffStyle === 'split') {\n return splitInWindow;\n } else {\n return unifiedInWindow || splitInWindow;\n }\n },\n isInUnifiedWindow(unifiedHeight: number) {\n return (\n !state.isWindowedHighlight ||\n (state.unifiedCount >= startingLine - unifiedHeight &&\n state.unifiedCount < startingLine + totalLines)\n );\n },\n isInSplitWindow(splitHeight: number) {\n return (\n !state.isWindowedHighlight ||\n (state.splitCount >= startingLine - splitHeight &&\n state.splitCount < startingLine + totalLines)\n );\n },\n emit(props: DiffLineCallbackProps, silent = false): boolean {\n if (!silent) {\n if (diffStyle === 'unified') {\n state.incrementCounts(1, 0);\n } else if (diffStyle === 'split') {\n state.incrementCounts(0, 1);\n } else {\n state.incrementCounts(1, 1);\n }\n }\n return callback(props) ?? false;\n },\n };\n\n hunkIterator: for (\n let hunkIndex = iterationStart.hunkIndex;\n hunkIndex < diff.hunks.length;\n hunkIndex++\n ) {\n const hunk = diff.hunks[hunkIndex];\n if (hunk == null) {\n throw new Error('iterateOverDiff: invalid hunk index');\n }\n if (state.shouldBreak()) {\n break;\n }\n\n const leadingRegion = getExpandedRegion({\n isPartial: diff.isPartial,\n rangeSize: hunk.collapsedBefore,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold,\n });\n const trailingRegion =\n hunkIndex === state.finalHunkIndex\n ? getTrailingExpandedRegion({\n fileDiff: diff,\n hunkIndex,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'iterateOverDiff',\n })\n : undefined;\n const expandedLineCount = leadingRegion.fromStart + leadingRegion.fromEnd;\n\n function getTrailingCollapsedAfter(\n unifiedLineIndex: number,\n splitLineIndex: number\n ) {\n if (\n trailingRegion == null ||\n trailingRegion.collapsedLines <= 0 ||\n trailingRegion.fromStart + trailingRegion.fromEnd > 0\n ) {\n return 0;\n }\n if (diffStyle === 'unified') {\n return unifiedLineIndex ===\n hunk.unifiedLineStart + hunk.unifiedLineCount - 1\n ? trailingRegion.collapsedLines\n : 0;\n }\n return splitLineIndex === hunk.splitLineStart + hunk.splitLineCount - 1\n ? trailingRegion.collapsedLines\n : 0;\n }\n\n let consumedCollapsed = leadingRegion.collapsedLines === 0;\n function consumePendingCollapsed() {\n if (consumedCollapsed) {\n return 0;\n }\n consumedCollapsed = true;\n return leadingRegion.collapsedLines;\n }\n\n // Emit for expanded lines\n if (!state.shouldSkip(expandedLineCount, expandedLineCount)) {\n let unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.rangeSize;\n let splitLineIndex = hunk.splitLineStart - leadingRegion.rangeSize;\n\n let deletionLineIndex = hunk.deletionLineIndex - leadingRegion.rangeSize;\n let additionLineIndex = hunk.additionLineIndex - leadingRegion.rangeSize;\n let deletionLineNumber = hunk.deletionStart - leadingRegion.rangeSize;\n let additionLineNumber = hunk.additionStart - leadingRegion.rangeSize;\n\n if (\n walkContextLines(state, leadingRegion.fromStart, diffStyle, (index) => {\n return state.emit({\n hunkIndex,\n hunk: hunk,\n collapsedBefore: 0,\n collapsedAfter: 0,\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n });\n })\n ) {\n break hunkIterator;\n }\n\n unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.fromEnd;\n splitLineIndex = hunk.splitLineStart - leadingRegion.fromEnd;\n\n deletionLineIndex = hunk.deletionLineIndex - leadingRegion.fromEnd;\n additionLineIndex = hunk.additionLineIndex - leadingRegion.fromEnd;\n deletionLineNumber = hunk.deletionStart - leadingRegion.fromEnd;\n additionLineNumber = hunk.additionStart - leadingRegion.fromEnd;\n if (\n walkContextLines(\n state,\n leadingRegion.fromEnd,\n diffStyle,\n (index) => {\n return state.emit({\n hunkIndex,\n hunk,\n collapsedBefore: consumePendingCollapsed(),\n collapsedAfter: 0,\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n });\n },\n () => {\n // The collapsed separator belongs before this fromEnd slice. If the\n // render window starts inside the slice, consume it with the skipped\n // rows so it is not attached to the first emitted row.\n consumePendingCollapsed();\n }\n )\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(expandedLineCount, expandedLineCount);\n consumePendingCollapsed();\n }\n\n let unifiedLineIndex = hunk.unifiedLineStart;\n let splitLineIndex = hunk.splitLineStart;\n\n let deletionLineIndex = hunk.deletionLineIndex;\n let additionLineIndex = hunk.additionLineIndex;\n let deletionLineNumber = hunk.deletionStart;\n let additionLineNumber = hunk.additionStart;\n const lastContent = hunk.hunkContent.at(-1);\n\n for (const content of hunk.hunkContent) {\n if (state.shouldBreak()) {\n break hunkIterator;\n }\n\n const isLastContent = content === lastContent;\n\n // Hunk Context Content\n if (content.type === 'context') {\n if (!state.shouldSkip(content.lines, content.lines)) {\n if (\n walkContextLines(\n state,\n content.lines,\n diffStyle,\n (index) => {\n const isLastLine = isLastContent && index === content.lines - 1;\n const unifiedRowIndex = unifiedLineIndex + index;\n const splitRowIndex = splitLineIndex + index;\n return state.emit({\n hunkIndex,\n hunk,\n collapsedBefore: consumePendingCollapsed(),\n collapsedAfter: getTrailingCollapsedAfter(\n unifiedRowIndex,\n splitRowIndex\n ),\n type: 'context',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: isLastLine && hunk.noEOFCRDeletions,\n unifiedLineIndex: unifiedRowIndex,\n splitLineIndex: splitRowIndex,\n },\n additionLine: {\n unifiedLineIndex: unifiedRowIndex,\n splitLineIndex: splitRowIndex,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: isLastLine && hunk.noEOFCRAdditions,\n },\n });\n },\n () => {\n // When windowing starts inside context content, the leading\n // separator was above the visible range and should not be\n // emitted on the first rendered context line.\n consumePendingCollapsed();\n }\n )\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(content.lines, content.lines);\n consumePendingCollapsed();\n }\n unifiedLineIndex += content.lines;\n splitLineIndex += content.lines;\n\n deletionLineIndex += content.lines;\n additionLineIndex += content.lines;\n deletionLineNumber += content.lines;\n additionLineNumber += content.lines;\n }\n // Hunk Change Content\n else {\n const splitCount = Math.max(content.deletions, content.additions);\n const unifiedCount = content.deletions + content.additions;\n const shouldSkipChange = state.shouldSkip(unifiedCount, splitCount);\n if (!shouldSkipChange) {\n const iterationRanges = getChangeIterationRanges(\n state,\n content,\n diffStyle\n );\n const firstRangeStart = iterationRanges[0]?.[0] ?? 0;\n if (firstRangeStart > 0) {\n // Change rows can be windowed from the middle of the block too. In\n // that case the leading separator belongs to skipped rows, not to\n // the first visible deletion/addition row.\n consumePendingCollapsed();\n }\n // Change ranges are already clipped to the active window. Counts move\n // once for the whole change block after the selected rows emit.\n for (const [rangeStart, rangeEnd] of iterationRanges) {\n for (let index = rangeStart; index < rangeEnd; index++) {\n const unifiedRowIndex = unifiedLineIndex + index;\n const splitRowIndex =\n diffStyle === 'unified'\n ? splitLineIndex +\n (index < content.deletions\n ? index\n : index - content.deletions)\n : splitLineIndex + index;\n const collapsedAfter = getTrailingCollapsedAfter(\n unifiedRowIndex,\n splitRowIndex\n );\n if (\n state.emit(\n getChangeLineData({\n hunkIndex,\n hunk,\n collapsedBefore: consumePendingCollapsed(),\n collapsedAfter,\n diffStyle,\n index,\n unifiedLineIndex,\n splitLineIndex,\n additionLineIndex,\n deletionLineIndex,\n additionLineNumber,\n deletionLineNumber,\n content,\n isLastContent,\n unifiedCount,\n splitCount,\n }),\n true\n )\n ) {\n break hunkIterator;\n }\n }\n }\n }\n\n consumePendingCollapsed();\n state.incrementCounts(unifiedCount, splitCount);\n unifiedLineIndex += unifiedCount;\n splitLineIndex += splitCount;\n deletionLineIndex += content.deletions;\n additionLineIndex += content.additions;\n deletionLineNumber += content.deletions;\n additionLineNumber += content.additions;\n }\n }\n\n if (trailingRegion != null) {\n const { collapsedLines, fromStart, fromEnd } = trailingRegion;\n const len = fromStart + fromEnd;\n if (\n walkContextLines(\n state,\n len,\n diffStyle,\n (index) => {\n const isLastLine = index === len - 1;\n return state.emit({\n hunkIndex: diff.hunks.length,\n hunk: undefined,\n collapsedBefore: 0,\n collapsedAfter: isLastLine ? collapsedLines : 0,\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n });\n },\n undefined,\n () => state.shouldBreak()\n )\n ) {\n break hunkIterator;\n }\n }\n }\n}\n\n// Seek the iterator to the hunk that contains `startingLine` without changing\n// the public meaning of `startingLine`: it is a dense rendered-row index, not\n// a raw split/unified line index. We first build prefix counts for each hunk\n// under the current expansion/collapse settings, binary-search those counts to\n// find the first hunk whose rendered rows cross `startingLine`, then seed the\n// running split/unified counters as if every prior hunk had already been\n// walked.\nfunction getIterationStartState({\n diff,\n diffStyle,\n startingLine,\n expandedHunks,\n collapsedContextThreshold,\n}: IterationStartStateProps): IterationStartState {\n if (startingLine <= 0 || diffStyle === 'both') {\n return { hunkIndex: 0, splitCount: 0, unifiedCount: 0 };\n }\n\n const prefixCounts = getHunkPrefixCounts({\n diff,\n expandedHunks,\n collapsedContextThreshold,\n });\n\n let low = 0;\n let high = diff.hunks.length - 1;\n let result = diff.hunks.length;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n const counts = prefixCounts[mid + 1];\n if (counts == null) {\n throw new Error('iterateOverDiff: invalid hunk prefix index');\n }\n const selectedCount =\n diffStyle === 'unified' ? counts.unifiedCount : counts.splitCount;\n\n if (selectedCount > startingLine) {\n result = mid;\n high = mid - 1;\n } else {\n low = mid + 1;\n }\n }\n\n if (result >= diff.hunks.length) {\n const counts = prefixCounts[diff.hunks.length];\n if (counts == null) {\n throw new Error('iterateOverDiff: invalid terminal hunk prefix index');\n }\n return {\n hunkIndex: diff.hunks.length,\n splitCount: counts.splitCount,\n unifiedCount: counts.unifiedCount,\n };\n }\n\n const counts = prefixCounts[result];\n if (counts == null) {\n throw new Error('iterateOverDiff: invalid selected hunk prefix index');\n }\n return {\n hunkIndex: result,\n splitCount: counts.splitCount,\n unifiedCount: counts.unifiedCount,\n };\n}\n\n// Build cumulative rendered-row counts at every hunk boundary for the current\n// expansion state. Entry 0 is always zero rows before the first hunk; entry N\n// is the split/unified row count after hunks [0, N). These counts let\n// getIterationStartState binary-search by dense rendered row without replaying\n// every prior hunk.\nfunction getHunkPrefixCounts({\n diff,\n expandedHunks,\n collapsedContextThreshold,\n}: HunkPrefixCountsProps): HunkPrefixCounts[] {\n let splitCount = 0;\n let unifiedCount = 0;\n const finalHunkIndex = diff.hunks.length - 1;\n const prefixCounts: HunkPrefixCounts[] = [\n {\n splitCount: 0,\n unifiedCount: 0,\n },\n ];\n\n for (let index = 0; index < diff.hunks.length; index++) {\n const hunk = diff.hunks[index];\n if (hunk == null) {\n throw new Error('iterateOverDiff: invalid hunk summary index');\n }\n\n const leadingRegion = getExpandedRegion({\n isPartial: diff.isPartial,\n rangeSize: hunk.collapsedBefore,\n expandedHunks,\n hunkIndex: index,\n collapsedContextThreshold,\n });\n const leadingCount = leadingRegion.fromStart + leadingRegion.fromEnd;\n splitCount += leadingCount + hunk.splitLineCount;\n unifiedCount += leadingCount + hunk.unifiedLineCount;\n\n const trailingRegion =\n index === finalHunkIndex\n ? getTrailingExpandedRegion({\n fileDiff: diff,\n hunkIndex: index,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'iterateOverDiff',\n })\n : undefined;\n if (trailingRegion != null) {\n const trailingCount = trailingRegion.fromStart + trailingRegion.fromEnd;\n splitCount += trailingCount;\n unifiedCount += trailingCount;\n }\n\n prefixCounts.push({ splitCount, unifiedCount });\n }\n\n return prefixCounts;\n}\n\n// Clip a run of context rows to a single bounded hull around the active rendered\n// window. `diffStyle: both` can make split and unified rows visible in disjoint\n// ranges, so these bounds may include interior gaps that still need per-row\n// filtering before emitting.\nfunction getContextLineIterationBounds(\n state: IterationState,\n count: number,\n diffStyle: DiffStyle\n): LineIterationBounds {\n if (!state.isWindowedHighlight || count <= 0) {\n return [0, count];\n }\n\n const ranges: LineIterationBounds[] = [];\n function pushRange(currentCount: number): void {\n const start = Math.max(0, state.viewportStart - currentCount);\n const end = Math.min(count, state.viewportEnd - currentCount);\n if (end > start) {\n ranges.push([start, end]);\n }\n }\n\n if (diffStyle !== 'split') {\n pushRange(state.unifiedCount);\n }\n if (diffStyle !== 'unified') {\n pushRange(state.splitCount);\n }\n\n if (ranges.length === 0) {\n return [0, 0];\n }\n\n let start = ranges[0][0];\n let end = ranges[0][1];\n for (let index = 1; index < ranges.length; index++) {\n const range = ranges[index];\n start = Math.min(start, range[0]);\n end = Math.max(end, range[1]);\n }\n return [start, end];\n}\n\n// Walk context rows through the active window while keeping split and\n// unified counters aligned. The callback only runs after the final per-row\n// window check, which keeps `diffStyle: both` gap rows from being emitted.\nfunction walkContextLines(\n state: IterationState,\n count: number,\n diffStyle: DiffStyle,\n callback: ContextLineCallback,\n onSkippedStart?: () => void,\n shouldBreak?: () => boolean\n): boolean {\n const [startIndex, endIndex] = getContextLineIterationBounds(\n state,\n count,\n diffStyle\n );\n if (startIndex > 0) {\n state.incrementCounts(startIndex, startIndex);\n onSkippedStart?.();\n }\n\n let index = startIndex;\n while (index < count) {\n if (shouldBreak?.() === true) {\n return true;\n }\n if (index >= endIndex) {\n state.incrementCounts(count - index, count - index);\n break;\n }\n if (state.isInWindow(0, 0)) {\n if (callback(index) === true) {\n return true;\n }\n } else {\n state.incrementCounts(1, 1);\n }\n index++;\n }\n\n return false;\n}\n\n// Clip a change block to the rows that can be visible in the active coordinate\n// space. `diffStyle: both` iterates in split row space, but includes the unified\n// ranges too so either view can render the visible change rows it needs.\nfunction getChangeIterationRanges(\n state: IterationState,\n content: ChangeContent,\n diffStyle: DiffStyle\n): LineIterationBounds[] {\n // If not a window highlight, then we should just render the entire range\n if (!state.isWindowedHighlight) {\n return [\n [\n 0,\n diffStyle === 'unified'\n ? content.deletions + content.additions\n : Math.max(content.deletions, content.additions),\n ],\n ];\n }\n const useUnified = diffStyle !== 'split';\n const useSplit = diffStyle !== 'unified';\n const iterationSpace = diffStyle === 'unified' ? 'unified' : 'split';\n const iterationRanges: LineIterationBounds[] = [];\n function getVisibleRange(\n start: number,\n count: number\n ): LineIterationBounds | undefined {\n const end = start + count;\n if (end <= state.viewportStart || start >= state.viewportEnd) {\n return undefined;\n }\n const visibleStart = Math.max(0, state.viewportStart - start);\n const visibleEnd = Math.min(count, state.viewportEnd - start);\n return visibleEnd > visibleStart ? [visibleStart, visibleEnd] : undefined;\n }\n function mapRangeToIteration(\n range: LineIterationBounds,\n kind: ChangeContentSide\n ): LineIterationBounds {\n if (iterationSpace === 'split') {\n // For split iteration, additions/deletions are already in split row space.\n return range;\n }\n return kind === 'additions'\n ? [range[0] + content.deletions, range[1] + content.deletions]\n : range;\n }\n function pushRange(\n range: LineIterationBounds | undefined,\n kind: ChangeContentSide\n ) {\n if (range == null) {\n return;\n }\n const [start, end] = mapRangeToIteration(range, kind);\n if (end > start) {\n iterationRanges.push([start, end]);\n }\n }\n\n if (useUnified) {\n pushRange(\n getVisibleRange(state.unifiedCount, content.deletions),\n 'deletions'\n );\n pushRange(\n getVisibleRange(\n state.unifiedCount + content.deletions,\n content.additions\n ),\n 'additions'\n );\n }\n\n if (useSplit) {\n pushRange(\n getVisibleRange(state.splitCount, content.deletions),\n 'deletions'\n );\n pushRange(\n getVisibleRange(state.splitCount, content.additions),\n 'additions'\n );\n }\n\n if (iterationRanges.length === 0) {\n return iterationRanges;\n }\n\n iterationRanges.sort((a, b) => a[0] - b[0]);\n const merged: LineIterationBounds[] = [iterationRanges[0]];\n for (const [start, end] of iterationRanges.slice(1)) {\n const last = merged[merged.length - 1];\n if (start <= last[1]) {\n last[1] = Math.max(last[1], end);\n } else {\n merged.push([start, end]);\n }\n }\n\n return merged;\n}\n\ninterface GetChangeLineDataProps {\n hunkIndex: number;\n hunk: Hunk;\n collapsedBefore: number;\n collapsedAfter: number;\n diffStyle: DiffStyle;\n index: number;\n unifiedLineIndex: number;\n splitLineIndex: number;\n additionLineIndex: number;\n additionLineNumber: number;\n deletionLineNumber: number;\n deletionLineIndex: number;\n content: ChangeContent;\n isLastContent: boolean;\n unifiedCount: number;\n splitCount: number;\n}\n\n// Build the callback payload for one change row, mapping the selected row index\n// into split/unified coordinates and addition/deletion line metadata.\nfunction getChangeLineData({\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n diffStyle,\n index,\n unifiedLineIndex,\n splitLineIndex,\n additionLineIndex,\n deletionLineIndex,\n additionLineNumber,\n deletionLineNumber,\n content,\n isLastContent,\n unifiedCount,\n splitCount,\n}: GetChangeLineDataProps): DiffLineCallbackProps {\n const unifiedDeletionLineIndex =\n index < content.deletions ? unifiedLineIndex + index : undefined;\n const unifiedAdditionLineIndex =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? unifiedLineIndex + index\n : undefined\n : index < content.additions\n ? unifiedLineIndex + content.deletions + index\n : undefined;\n\n const resolvedSplitLineIndex =\n diffStyle === 'unified'\n ? splitLineIndex +\n (index < content.deletions ? index : index - content.deletions)\n : splitLineIndex + index;\n\n const deletionLineIndexValue =\n index < content.deletions ? deletionLineIndex + index : undefined;\n const deletionLineNumberValue =\n index < content.deletions ? deletionLineNumber + index : undefined;\n const additionLineIndexValue =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? additionLineIndex + (index - content.deletions)\n : undefined\n : index < content.additions\n ? additionLineIndex + index\n : undefined;\n const additionLineNumberValue =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? additionLineNumber + (index - content.deletions)\n : undefined\n : index < content.additions\n ? additionLineNumber + index\n : undefined;\n\n const noEOFCRDeletion =\n diffStyle === 'unified'\n ? isLastContent &&\n index === content.deletions - 1 &&\n hunk.noEOFCRDeletions\n : isLastContent && index === splitCount - 1 && hunk.noEOFCRDeletions;\n const noEOFCRAddition =\n diffStyle === 'unified'\n ? isLastContent && index === unifiedCount - 1 && hunk.noEOFCRAdditions\n : isLastContent && index === splitCount - 1 && hunk.noEOFCRAdditions;\n\n const deletionLine: DiffLineMetadata | undefined =\n deletionLineIndexValue != null &&\n deletionLineNumberValue != null &&\n unifiedDeletionLineIndex != null\n ? {\n lineNumber: deletionLineNumberValue,\n lineIndex: deletionLineIndexValue,\n noEOFCR: noEOFCRDeletion,\n unifiedLineIndex: unifiedDeletionLineIndex,\n splitLineIndex: resolvedSplitLineIndex,\n }\n : undefined;\n const additionLine: DiffLineMetadata | undefined =\n additionLineIndexValue != null &&\n additionLineNumberValue != null &&\n unifiedAdditionLineIndex != null\n ? {\n unifiedLineIndex: unifiedAdditionLineIndex,\n splitLineIndex: resolvedSplitLineIndex,\n lineIndex: additionLineIndexValue,\n lineNumber: additionLineNumberValue,\n noEOFCR: noEOFCRAddition,\n }\n : undefined;\n\n if (deletionLine == null && additionLine != null) {\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine: undefined,\n additionLine,\n };\n } else if (deletionLine != null && additionLine == null) {\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine,\n additionLine: undefined,\n };\n }\n\n if (deletionLine == null || additionLine == null) {\n throw new Error('iterateOverDiff: missing change line data');\n }\n\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine,\n additionLine,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"iterateOverDiff.js","names":[],"sources":["../../src/utils/iterateOverDiff.ts"],"sourcesContent":["import { DEFAULT_COLLAPSED_CONTEXT_THRESHOLD } from '../constants';\nimport type {\n ChangeContent,\n FileDiffMetadata,\n Hunk,\n HunkExpansionRegion,\n} from '../types';\nimport {\n getExpandedRegion,\n getTrailingExpandedRegion,\n} from './virtualDiffLayout';\n\nexport interface DiffLineMetadata {\n unifiedLineIndex: number;\n splitLineIndex: number;\n lineIndex: number;\n lineNumber: number;\n noEOFCR: boolean;\n}\n\nexport interface DiffLineCallbackBase {\n hunkIndex: number;\n hunk: Hunk | undefined; // undefined for trailing expansion region\n collapsedBefore: number; // > 0 means separator before this line, value = hidden lines\n collapsedAfter: number; // > 0 only on final line if trailing collapsed content\n}\n\ninterface DiffLineCallbackContextChange extends DiffLineCallbackBase {\n type: 'change' | 'context' | 'context-expanded';\n deletionLine: DiffLineMetadata;\n additionLine: DiffLineMetadata;\n}\n\ninterface DiffLineCallbackChangeDeletion extends DiffLineCallbackBase {\n type: 'change';\n deletionLine: DiffLineMetadata;\n additionLine?: undefined;\n}\n\ninterface DiffLineCallbackChangeAddition extends DiffLineCallbackBase {\n type: 'change';\n deletionLine?: undefined;\n additionLine: DiffLineMetadata;\n}\n\nexport type DiffLineCallbackProps =\n | DiffLineCallbackContextChange\n | DiffLineCallbackChangeDeletion\n | DiffLineCallbackChangeAddition;\n\ntype DiffStyle = 'unified' | 'split' | 'both';\n\ntype LineIterationBounds = [startIndex: number, endIndex: number];\n\ntype ChangeContentSide = 'deletions' | 'additions';\n\ntype ContextLineCallback = (index: number) => boolean | void;\n\ninterface IterationState {\n isWindowedHighlight: boolean;\n viewportStart: number;\n viewportEnd: number;\n splitCount: number;\n unifiedCount: number;\n finalHunkIndex: number;\n shouldBreak(): boolean;\n shouldSkip(unifiedHeight: number, splitHeight: number): boolean;\n incrementCounts(unifiedValue: number, splitValue: number): void;\n isInWindow(unifiedHeight: number, splitHeight: number): boolean;\n isInUnifiedWindow(height: number): boolean;\n isInSplitWindow(height: number): boolean;\n emit(props: DiffLineCallbackProps, silent?: boolean): boolean;\n}\n\ninterface IterationStartState {\n hunkIndex: number;\n splitCount: number;\n unifiedCount: number;\n}\n\ninterface HunkPrefixCounts {\n splitCount: number;\n unifiedCount: number;\n}\n\ninterface IterationStartStateProps extends Omit<\n IterateOverDiffProps,\n 'callback' | 'totalLines'\n> {\n startingLine: number;\n collapsedContextThreshold: number;\n}\n\ninterface HunkPrefixCountsProps extends Pick<\n IterationStartStateProps,\n 'diff' | 'expandedHunks' | 'collapsedContextThreshold'\n> {}\n\nexport type DiffLineCallback = (props: DiffLineCallbackProps) => boolean | void;\n\nexport interface IterateOverDiffProps {\n diff: FileDiffMetadata;\n diffStyle: DiffStyle;\n startingLine?: number;\n totalLines?: number;\n expandedHunks?: Map<number, HunkExpansionRegion> | true;\n collapsedContextThreshold?: number;\n callback: DiffLineCallback;\n}\n\nexport function iterateOverDiff({\n diff,\n diffStyle,\n startingLine = 0,\n totalLines = Infinity,\n expandedHunks,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n callback,\n}: IterateOverDiffProps): void {\n const iterationStart = getIterationStartState({\n diff,\n diffStyle,\n startingLine,\n expandedHunks,\n collapsedContextThreshold,\n });\n const state: IterationState = {\n viewportStart: startingLine,\n viewportEnd: startingLine + totalLines,\n isWindowedHighlight: startingLine > 0 || totalLines < Infinity,\n splitCount: iterationStart.splitCount,\n unifiedCount: iterationStart.unifiedCount,\n finalHunkIndex: diff.hunks.length - 1,\n shouldBreak() {\n if (!state.isWindowedHighlight) {\n return false;\n }\n\n const breakUnified = state.unifiedCount >= startingLine + totalLines;\n const breakSplit = state.splitCount >= startingLine + totalLines;\n\n if (diffStyle === 'unified') {\n return breakUnified;\n } else if (diffStyle === 'split') {\n return breakSplit;\n } else {\n return breakUnified && breakSplit;\n }\n },\n shouldSkip(unifiedCount: number, splitCount: number) {\n if (!state.isWindowedHighlight) {\n return false;\n }\n\n const skipUnified =\n unifiedCount > 0 && state.unifiedCount + unifiedCount <= startingLine;\n const skipSplit =\n splitCount > 0 && state.splitCount + splitCount <= startingLine;\n\n if (diffStyle === 'unified') {\n return skipUnified;\n } else if (diffStyle === 'split') {\n return skipSplit;\n } else {\n return skipUnified && skipSplit;\n }\n },\n incrementCounts(unifiedValue: number, splitValue: number) {\n if (diffStyle === 'unified' || diffStyle === 'both') {\n state.unifiedCount += unifiedValue;\n }\n if (diffStyle === 'split' || diffStyle === 'both') {\n state.splitCount += splitValue;\n }\n },\n isInWindow(unifiedHeight: number, splitHeight: number) {\n if (!state.isWindowedHighlight) {\n return true;\n }\n\n const unifiedInWindow = state.isInUnifiedWindow(unifiedHeight);\n const splitInWindow = state.isInSplitWindow(splitHeight);\n\n if (diffStyle === 'unified') {\n return unifiedInWindow;\n } else if (diffStyle === 'split') {\n return splitInWindow;\n } else {\n return unifiedInWindow || splitInWindow;\n }\n },\n isInUnifiedWindow(unifiedHeight: number) {\n return (\n !state.isWindowedHighlight ||\n (state.unifiedCount >= startingLine - unifiedHeight &&\n state.unifiedCount < startingLine + totalLines)\n );\n },\n isInSplitWindow(splitHeight: number) {\n return (\n !state.isWindowedHighlight ||\n (state.splitCount >= startingLine - splitHeight &&\n state.splitCount < startingLine + totalLines)\n );\n },\n emit(props: DiffLineCallbackProps, silent = false): boolean {\n if (!silent) {\n if (diffStyle === 'unified') {\n state.incrementCounts(1, 0);\n } else if (diffStyle === 'split') {\n state.incrementCounts(0, 1);\n } else {\n state.incrementCounts(1, 1);\n }\n }\n return callback(props) ?? false;\n },\n };\n\n hunkIterator: for (\n let hunkIndex = iterationStart.hunkIndex;\n hunkIndex < diff.hunks.length;\n hunkIndex++\n ) {\n const hunk = diff.hunks[hunkIndex];\n if (hunk == null) {\n throw new Error('iterateOverDiff: invalid hunk index');\n }\n if (state.shouldBreak()) {\n break;\n }\n\n const leadingRegion = getExpandedRegion({\n isPartial: diff.isPartial,\n rangeSize: hunk.collapsedBefore,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold,\n });\n const trailingRegion =\n hunkIndex === state.finalHunkIndex\n ? getTrailingExpandedRegion({\n fileDiff: diff,\n hunkIndex,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'iterateOverDiff',\n })\n : undefined;\n const expandedLineCount = leadingRegion.fromStart + leadingRegion.fromEnd;\n\n function getTrailingCollapsedAfter(\n unifiedLineIndex: number,\n splitLineIndex: number\n ) {\n if (\n trailingRegion == null ||\n trailingRegion.collapsedLines <= 0 ||\n trailingRegion.fromStart + trailingRegion.fromEnd > 0\n ) {\n return 0;\n }\n if (diffStyle === 'unified') {\n return unifiedLineIndex ===\n hunk.unifiedLineStart + hunk.unifiedLineCount - 1\n ? trailingRegion.collapsedLines\n : 0;\n }\n return splitLineIndex === hunk.splitLineStart + hunk.splitLineCount - 1\n ? trailingRegion.collapsedLines\n : 0;\n }\n\n let consumedCollapsed = leadingRegion.collapsedLines === 0;\n function consumePendingCollapsed() {\n if (consumedCollapsed) {\n return 0;\n }\n consumedCollapsed = true;\n return leadingRegion.collapsedLines;\n }\n\n // Emit for expanded lines\n if (!state.shouldSkip(expandedLineCount, expandedLineCount)) {\n let unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.rangeSize;\n let splitLineIndex = hunk.splitLineStart - leadingRegion.rangeSize;\n\n let deletionLineIndex = hunk.deletionLineIndex - leadingRegion.rangeSize;\n let additionLineIndex = hunk.additionLineIndex - leadingRegion.rangeSize;\n let deletionLineNumber = hunk.deletionStart - leadingRegion.rangeSize;\n let additionLineNumber = hunk.additionStart - leadingRegion.rangeSize;\n\n if (\n walkContextLines(state, leadingRegion.fromStart, diffStyle, (index) => {\n return state.emit({\n hunkIndex,\n hunk: hunk,\n collapsedBefore: 0,\n collapsedAfter: 0,\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n });\n })\n ) {\n break hunkIterator;\n }\n\n unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.fromEnd;\n splitLineIndex = hunk.splitLineStart - leadingRegion.fromEnd;\n\n deletionLineIndex = hunk.deletionLineIndex - leadingRegion.fromEnd;\n additionLineIndex = hunk.additionLineIndex - leadingRegion.fromEnd;\n deletionLineNumber = hunk.deletionStart - leadingRegion.fromEnd;\n additionLineNumber = hunk.additionStart - leadingRegion.fromEnd;\n if (\n walkContextLines(\n state,\n leadingRegion.fromEnd,\n diffStyle,\n (index) => {\n return state.emit({\n hunkIndex,\n hunk,\n collapsedBefore: consumePendingCollapsed(),\n collapsedAfter: 0,\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n });\n },\n () => {\n // The collapsed separator belongs before this fromEnd slice. If the\n // render window starts inside the slice, consume it with the skipped\n // rows so it is not attached to the first emitted row.\n consumePendingCollapsed();\n }\n )\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(expandedLineCount, expandedLineCount);\n consumePendingCollapsed();\n }\n\n let unifiedLineIndex = hunk.unifiedLineStart;\n let splitLineIndex = hunk.splitLineStart;\n\n let deletionLineIndex = hunk.deletionLineIndex;\n let additionLineIndex = hunk.additionLineIndex;\n let deletionLineNumber = hunk.deletionStart;\n let additionLineNumber = hunk.additionStart;\n const lastContent = hunk.hunkContent.at(-1);\n\n for (const content of hunk.hunkContent) {\n if (state.shouldBreak()) {\n break hunkIterator;\n }\n\n const isLastContent = content === lastContent;\n\n // Hunk Context Content\n if (content.type === 'context') {\n if (!state.shouldSkip(content.lines, content.lines)) {\n if (\n walkContextLines(\n state,\n content.lines,\n diffStyle,\n (index) => {\n const isLastLine = isLastContent && index === content.lines - 1;\n const unifiedRowIndex = unifiedLineIndex + index;\n const splitRowIndex = splitLineIndex + index;\n return state.emit({\n hunkIndex,\n hunk,\n collapsedBefore: consumePendingCollapsed(),\n collapsedAfter: getTrailingCollapsedAfter(\n unifiedRowIndex,\n splitRowIndex\n ),\n type: 'context',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: isLastLine && hunk.noEOFCRDeletions,\n unifiedLineIndex: unifiedRowIndex,\n splitLineIndex: splitRowIndex,\n },\n additionLine: {\n unifiedLineIndex: unifiedRowIndex,\n splitLineIndex: splitRowIndex,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: isLastLine && hunk.noEOFCRAdditions,\n },\n });\n },\n () => {\n // When windowing starts inside context content, the leading\n // separator was above the visible range and should not be\n // emitted on the first rendered context line.\n consumePendingCollapsed();\n }\n )\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(content.lines, content.lines);\n consumePendingCollapsed();\n }\n unifiedLineIndex += content.lines;\n splitLineIndex += content.lines;\n\n deletionLineIndex += content.lines;\n additionLineIndex += content.lines;\n deletionLineNumber += content.lines;\n additionLineNumber += content.lines;\n }\n // Hunk Change Content\n else {\n const splitCount = Math.max(content.deletions, content.additions);\n const unifiedCount = content.deletions + content.additions;\n const shouldSkipChange = state.shouldSkip(unifiedCount, splitCount);\n if (!shouldSkipChange) {\n const iterationRanges = getChangeIterationRanges(\n state,\n content,\n diffStyle\n );\n const firstRangeStart = iterationRanges[0]?.[0] ?? 0;\n if (firstRangeStart > 0) {\n // Change rows can be windowed from the middle of the block too. In\n // that case the leading separator belongs to skipped rows, not to\n // the first visible deletion/addition row.\n consumePendingCollapsed();\n }\n // Change ranges are already clipped to the active window. Counts move\n // once for the whole change block after the selected rows emit.\n for (const [rangeStart, rangeEnd] of iterationRanges) {\n for (let index = rangeStart; index < rangeEnd; index++) {\n const unifiedRowIndex = unifiedLineIndex + index;\n const splitRowIndex =\n diffStyle === 'unified'\n ? splitLineIndex +\n (index < content.deletions\n ? index\n : index - content.deletions)\n : splitLineIndex + index;\n const collapsedAfter = getTrailingCollapsedAfter(\n unifiedRowIndex,\n splitRowIndex\n );\n if (\n state.emit(\n getChangeLineData({\n hunkIndex,\n hunk,\n collapsedBefore: consumePendingCollapsed(),\n collapsedAfter,\n diffStyle,\n index,\n unifiedLineIndex,\n splitLineIndex,\n additionLineIndex,\n deletionLineIndex,\n additionLineNumber,\n deletionLineNumber,\n content,\n isLastContent,\n unifiedCount,\n splitCount,\n }),\n true\n )\n ) {\n break hunkIterator;\n }\n }\n }\n }\n\n consumePendingCollapsed();\n state.incrementCounts(unifiedCount, splitCount);\n unifiedLineIndex += unifiedCount;\n splitLineIndex += splitCount;\n deletionLineIndex += content.deletions;\n additionLineIndex += content.additions;\n deletionLineNumber += content.deletions;\n additionLineNumber += content.additions;\n }\n }\n\n if (trailingRegion != null) {\n const { collapsedLines, fromStart, fromEnd } = trailingRegion;\n const len = fromStart + fromEnd;\n if (\n walkContextLines(\n state,\n len,\n diffStyle,\n (index) => {\n const isLastLine = index === len - 1;\n return state.emit({\n hunkIndex: diff.hunks.length,\n hunk: undefined,\n collapsedBefore: 0,\n collapsedAfter: isLastLine ? collapsedLines : 0,\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n });\n },\n undefined,\n () => state.shouldBreak()\n )\n ) {\n break hunkIterator;\n }\n }\n }\n}\n\n// Seek the iterator to the hunk that contains `startingLine` without changing\n// the public meaning of `startingLine`: it is a dense rendered-row index, not\n// a raw split/unified line index. We first build prefix counts for each hunk\n// under the current expansion/collapse settings, binary-search those counts to\n// find the first hunk whose rendered rows cross `startingLine`, then seed the\n// running split/unified counters as if every prior hunk had already been\n// walked.\nfunction getIterationStartState({\n diff,\n diffStyle,\n startingLine,\n expandedHunks,\n collapsedContextThreshold,\n}: IterationStartStateProps): IterationStartState {\n if (startingLine <= 0 || diffStyle === 'both') {\n return { hunkIndex: 0, splitCount: 0, unifiedCount: 0 };\n }\n\n const prefixCounts = getHunkPrefixCounts({\n diff,\n expandedHunks,\n collapsedContextThreshold,\n });\n\n let low = 0;\n let high = diff.hunks.length - 1;\n let result = diff.hunks.length;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n const counts = prefixCounts[mid + 1];\n if (counts == null) {\n throw new Error('iterateOverDiff: invalid hunk prefix index');\n }\n const selectedCount =\n diffStyle === 'unified' ? counts.unifiedCount : counts.splitCount;\n\n if (selectedCount > startingLine) {\n result = mid;\n high = mid - 1;\n } else {\n low = mid + 1;\n }\n }\n\n if (result >= diff.hunks.length) {\n const counts = prefixCounts[diff.hunks.length];\n if (counts == null) {\n throw new Error('iterateOverDiff: invalid terminal hunk prefix index');\n }\n return {\n hunkIndex: diff.hunks.length,\n splitCount: counts.splitCount,\n unifiedCount: counts.unifiedCount,\n };\n }\n\n const counts = prefixCounts[result];\n if (counts == null) {\n throw new Error('iterateOverDiff: invalid selected hunk prefix index');\n }\n return {\n hunkIndex: result,\n splitCount: counts.splitCount,\n unifiedCount: counts.unifiedCount,\n };\n}\n\n// Build cumulative rendered-row counts at every hunk boundary for the current\n// expansion state. Entry 0 is always zero rows before the first hunk; entry N\n// is the split/unified row count after hunks [0, N). These counts let\n// getIterationStartState binary-search by dense rendered row without replaying\n// every prior hunk.\nfunction getHunkPrefixCounts({\n diff,\n expandedHunks,\n collapsedContextThreshold,\n}: HunkPrefixCountsProps): HunkPrefixCounts[] {\n let splitCount = 0;\n let unifiedCount = 0;\n const finalHunkIndex = diff.hunks.length - 1;\n const prefixCounts: HunkPrefixCounts[] = [\n {\n splitCount: 0,\n unifiedCount: 0,\n },\n ];\n\n for (let index = 0; index < diff.hunks.length; index++) {\n const hunk = diff.hunks[index];\n if (hunk == null) {\n throw new Error('iterateOverDiff: invalid hunk summary index');\n }\n\n const leadingRegion = getExpandedRegion({\n isPartial: diff.isPartial,\n rangeSize: hunk.collapsedBefore,\n expandedHunks,\n hunkIndex: index,\n collapsedContextThreshold,\n });\n const leadingCount = leadingRegion.fromStart + leadingRegion.fromEnd;\n splitCount += leadingCount + hunk.splitLineCount;\n unifiedCount += leadingCount + hunk.unifiedLineCount;\n\n const trailingRegion =\n index === finalHunkIndex\n ? getTrailingExpandedRegion({\n fileDiff: diff,\n hunkIndex: index,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'iterateOverDiff',\n })\n : undefined;\n if (trailingRegion != null) {\n const trailingCount = trailingRegion.fromStart + trailingRegion.fromEnd;\n splitCount += trailingCount;\n unifiedCount += trailingCount;\n }\n\n prefixCounts.push({ splitCount, unifiedCount });\n }\n\n return prefixCounts;\n}\n\n// Clip a run of context rows to a single bounded hull around the active rendered\n// window. `diffStyle: both` can make split and unified rows visible in disjoint\n// ranges, so these bounds may include interior gaps that still need per-row\n// filtering before emitting.\nfunction getContextLineIterationBounds(\n state: IterationState,\n count: number,\n diffStyle: DiffStyle\n): LineIterationBounds {\n if (!state.isWindowedHighlight || count <= 0) {\n return [0, count];\n }\n\n const ranges: LineIterationBounds[] = [];\n function pushRange(currentCount: number): void {\n const start = Math.max(0, state.viewportStart - currentCount);\n const end = Math.min(count, state.viewportEnd - currentCount);\n if (end > start) {\n ranges.push([start, end]);\n }\n }\n\n if (diffStyle !== 'split') {\n pushRange(state.unifiedCount);\n }\n if (diffStyle !== 'unified') {\n pushRange(state.splitCount);\n }\n\n if (ranges.length === 0) {\n return [0, 0];\n }\n\n let start = ranges[0][0];\n let end = ranges[0][1];\n for (let index = 1; index < ranges.length; index++) {\n const range = ranges[index];\n start = Math.min(start, range[0]);\n end = Math.max(end, range[1]);\n }\n return [start, end];\n}\n\n// Walk context rows through the active window while keeping split and\n// unified counters aligned. The callback only runs after the final per-row\n// window check, which keeps `diffStyle: both` gap rows from being emitted.\nfunction walkContextLines(\n state: IterationState,\n count: number,\n diffStyle: DiffStyle,\n callback: ContextLineCallback,\n onSkippedStart?: () => void,\n shouldBreak?: () => boolean\n): boolean {\n const [startIndex, endIndex] = getContextLineIterationBounds(\n state,\n count,\n diffStyle\n );\n if (startIndex > 0) {\n state.incrementCounts(startIndex, startIndex);\n onSkippedStart?.();\n }\n\n let index = startIndex;\n while (index < count) {\n if (shouldBreak?.() === true) {\n return true;\n }\n if (index >= endIndex) {\n state.incrementCounts(count - index, count - index);\n break;\n }\n if (state.isInWindow(0, 0)) {\n if (callback(index) === true) {\n return true;\n }\n } else {\n state.incrementCounts(1, 1);\n }\n index++;\n }\n\n return false;\n}\n\n// Clip a change block to the rows that can be visible in the active coordinate\n// space. `diffStyle: both` iterates in split row space, but includes the unified\n// ranges too so either view can render the visible change rows it needs.\nfunction getChangeIterationRanges(\n state: IterationState,\n content: ChangeContent,\n diffStyle: DiffStyle\n): LineIterationBounds[] {\n // If not a window highlight, then we should just render the entire range\n if (!state.isWindowedHighlight) {\n return [\n [\n 0,\n diffStyle === 'unified'\n ? content.deletions + content.additions\n : Math.max(content.deletions, content.additions),\n ],\n ];\n }\n const useUnified = diffStyle !== 'split';\n const useSplit = diffStyle !== 'unified';\n const iterationSpace = diffStyle === 'unified' ? 'unified' : 'split';\n const iterationRanges: LineIterationBounds[] = [];\n function getVisibleRange(\n start: number,\n count: number\n ): LineIterationBounds | undefined {\n const end = start + count;\n if (end <= state.viewportStart || start >= state.viewportEnd) {\n return undefined;\n }\n const visibleStart = Math.max(0, state.viewportStart - start);\n const visibleEnd = Math.min(count, state.viewportEnd - start);\n return visibleEnd > visibleStart ? [visibleStart, visibleEnd] : undefined;\n }\n function mapRangeToIteration(\n range: LineIterationBounds,\n kind: ChangeContentSide\n ): LineIterationBounds {\n if (iterationSpace === 'split') {\n // For split iteration, additions/deletions are already in split row space.\n return range;\n }\n return kind === 'additions'\n ? [range[0] + content.deletions, range[1] + content.deletions]\n : range;\n }\n function pushRange(\n range: LineIterationBounds | undefined,\n kind: ChangeContentSide\n ) {\n if (range == null) {\n return;\n }\n const [start, end] = mapRangeToIteration(range, kind);\n if (end > start) {\n iterationRanges.push([start, end]);\n }\n }\n\n if (useUnified) {\n pushRange(\n getVisibleRange(state.unifiedCount, content.deletions),\n 'deletions'\n );\n pushRange(\n getVisibleRange(\n state.unifiedCount + content.deletions,\n content.additions\n ),\n 'additions'\n );\n }\n\n if (useSplit) {\n pushRange(\n getVisibleRange(state.splitCount, content.deletions),\n 'deletions'\n );\n pushRange(\n getVisibleRange(state.splitCount, content.additions),\n 'additions'\n );\n }\n\n if (iterationRanges.length === 0) {\n return iterationRanges;\n }\n\n iterationRanges.sort((a, b) => a[0] - b[0]);\n const merged: LineIterationBounds[] = [iterationRanges[0]];\n for (const [start, end] of iterationRanges.slice(1)) {\n const last = merged[merged.length - 1];\n if (start <= last[1]) {\n last[1] = Math.max(last[1], end);\n } else {\n merged.push([start, end]);\n }\n }\n\n return merged;\n}\n\ninterface GetChangeLineDataProps {\n hunkIndex: number;\n hunk: Hunk;\n collapsedBefore: number;\n collapsedAfter: number;\n diffStyle: DiffStyle;\n index: number;\n unifiedLineIndex: number;\n splitLineIndex: number;\n additionLineIndex: number;\n additionLineNumber: number;\n deletionLineNumber: number;\n deletionLineIndex: number;\n content: ChangeContent;\n isLastContent: boolean;\n unifiedCount: number;\n splitCount: number;\n}\n\n// Build the callback payload for one change row, mapping the selected row index\n// into split/unified coordinates and addition/deletion line metadata.\nfunction getChangeLineData({\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n diffStyle,\n index,\n unifiedLineIndex,\n splitLineIndex,\n additionLineIndex,\n deletionLineIndex,\n additionLineNumber,\n deletionLineNumber,\n content,\n isLastContent,\n unifiedCount,\n splitCount,\n}: GetChangeLineDataProps): DiffLineCallbackProps {\n const unifiedDeletionLineIndex =\n index < content.deletions ? unifiedLineIndex + index : undefined;\n const unifiedAdditionLineIndex =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? unifiedLineIndex + index\n : undefined\n : index < content.additions\n ? unifiedLineIndex + content.deletions + index\n : undefined;\n\n const resolvedSplitLineIndex =\n diffStyle === 'unified'\n ? splitLineIndex +\n (index < content.deletions ? index : index - content.deletions)\n : splitLineIndex + index;\n\n const deletionLineIndexValue =\n index < content.deletions ? deletionLineIndex + index : undefined;\n const deletionLineNumberValue =\n index < content.deletions ? deletionLineNumber + index : undefined;\n const additionLineIndexValue =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? additionLineIndex + (index - content.deletions)\n : undefined\n : index < content.additions\n ? additionLineIndex + index\n : undefined;\n const additionLineNumberValue =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? additionLineNumber + (index - content.deletions)\n : undefined\n : index < content.additions\n ? additionLineNumber + index\n : undefined;\n\n const noEOFCRDeletion =\n diffStyle === 'unified'\n ? isLastContent &&\n index === content.deletions - 1 &&\n hunk.noEOFCRDeletions\n : isLastContent && index === splitCount - 1 && hunk.noEOFCRDeletions;\n const noEOFCRAddition =\n diffStyle === 'unified'\n ? isLastContent && index === unifiedCount - 1 && hunk.noEOFCRAdditions\n : isLastContent && index === splitCount - 1 && hunk.noEOFCRAdditions;\n\n const deletionLine: DiffLineMetadata | undefined =\n deletionLineIndexValue != null &&\n deletionLineNumberValue != null &&\n unifiedDeletionLineIndex != null\n ? {\n lineNumber: deletionLineNumberValue,\n lineIndex: deletionLineIndexValue,\n noEOFCR: noEOFCRDeletion,\n unifiedLineIndex: unifiedDeletionLineIndex,\n splitLineIndex: resolvedSplitLineIndex,\n }\n : undefined;\n const additionLine: DiffLineMetadata | undefined =\n additionLineIndexValue != null &&\n additionLineNumberValue != null &&\n unifiedAdditionLineIndex != null\n ? {\n unifiedLineIndex: unifiedAdditionLineIndex,\n splitLineIndex: resolvedSplitLineIndex,\n lineIndex: additionLineIndexValue,\n lineNumber: additionLineNumberValue,\n noEOFCR: noEOFCRAddition,\n }\n : undefined;\n\n if (deletionLine == null && additionLine != null) {\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine: undefined,\n additionLine,\n };\n } else if (deletionLine != null && additionLine == null) {\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine,\n additionLine: undefined,\n };\n }\n\n if (deletionLine == null || additionLine == null) {\n throw new Error('iterateOverDiff: missing change line data');\n }\n\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine,\n additionLine,\n };\n}\n"],"mappings":"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"}
@@ -8,7 +8,7 @@ import { CreatePatchOptionsNonabortable } from "diff";
8
8
  * If both `oldFile` and `newFile` have a `cacheKey`, the resulting diff will
9
9
  * automatically get a combined cache key in the format `oldKey:newKey`.
10
10
  */
11
- declare function parseDiffFromFile(oldFile: FileContents, newFile: FileContents, options?: CreatePatchOptionsNonabortable, throwOnError?: boolean): FileDiffMetadata;
11
+ declare function parseDiffFromFile(oldFile: FileContents | null, newFile: FileContents | null, options?: CreatePatchOptionsNonabortable, throwOnError?: boolean): FileDiffMetadata;
12
12
  //#endregion
13
13
  export { parseDiffFromFile };
14
14
  //# sourceMappingURL=parseDiffFromFile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parseDiffFromFile.d.ts","names":[],"sources":["../../src/utils/parseDiffFromFile.ts"],"mappings":";;;;;;AAWA;;;;iBAAgB,iBAAA,CAGd,OAAA,EAAS,YAAA,EACT,OAAA,EAAS,YAAA,EACT,OAAA,GAAU,8BAAA,EACV,YAAA,aACC,gBAAA"}
1
+ {"version":3,"file":"parseDiffFromFile.d.ts","names":[],"sources":["../../src/utils/parseDiffFromFile.ts"],"mappings":";;;;;;AAaA;;;;iBAAgB,iBAAA,CACd,OAAA,EAAS,YAAA,SACT,OAAA,EAAS,YAAA,SACT,OAAA,GAAU,8BAAA,EACV,YAAA,aACC,gBAAA"}
@@ -1,6 +1,7 @@
1
1
  import { processFile } from "./parsePatchFiles.js";
2
2
  import { createTwoFilesPatch } from "diff";
3
3
  //#region src/utils/parseDiffFromFile.ts
4
+ const MISSING_FILE_NAME = "/dev/null";
4
5
  /**
5
6
  * Parses a diff from two file contents objects.
6
7
  *
@@ -8,18 +9,38 @@ import { createTwoFilesPatch } from "diff";
8
9
  * automatically get a combined cache key in the format `oldKey:newKey`.
9
10
  */
10
11
  function parseDiffFromFile(oldFile, newFile, options, throwOnError = false) {
11
- const fileData = processFile(createTwoFilesPatch(oldFile.name, newFile.name, oldFile.contents, newFile.contents, oldFile.header, newFile.header, options), {
12
+ if (oldFile === null && newFile === null) throw new Error("parseDiffFromFile: You must pass oldFile, newFile, or both");
13
+ const resolvedOldFile = oldFile ?? createMissingFile();
14
+ const resolvedNewFile = newFile ?? createMissingFile();
15
+ const fileData = processFile(createTwoFilesPatch(resolvedOldFile.name, resolvedNewFile.name, resolvedOldFile.contents, resolvedNewFile.contents, resolvedOldFile.header, resolvedNewFile.header, options), {
12
16
  cacheKey: (() => {
13
- if (oldFile.cacheKey != null && newFile.cacheKey != null) return `${oldFile.cacheKey}:${newFile.cacheKey}`;
17
+ const oldCacheKey = oldFile?.cacheKey ?? oldFile?.name;
18
+ const newCacheKey = newFile?.cacheKey ?? newFile?.name;
19
+ if (oldCacheKey != null && newCacheKey != null) return oldCacheKey + ":" + newCacheKey;
20
+ return oldCacheKey ?? newCacheKey;
14
21
  })(),
15
- oldFile,
16
- newFile,
22
+ oldFile: resolvedOldFile,
23
+ newFile: resolvedNewFile,
17
24
  throwOnError
18
25
  });
19
26
  if (fileData == null) throw new Error("parseDiffFrom: FileInvalid diff -- probably need to fix something -- if the files are the same maybe?");
20
- if (newFile.lang != null) fileData.lang = newFile.lang;
27
+ if (oldFile === null) {
28
+ fileData.type = "new";
29
+ fileData.prevName = void 0;
30
+ } else if (newFile === null) {
31
+ fileData.type = "deleted";
32
+ fileData.prevName = void 0;
33
+ }
34
+ const language = newFile?.lang ?? (newFile === null ? oldFile?.lang : void 0);
35
+ if (language != null) fileData.lang = language;
21
36
  return fileData;
22
37
  }
38
+ function createMissingFile() {
39
+ return {
40
+ name: MISSING_FILE_NAME,
41
+ contents: ""
42
+ };
43
+ }
23
44
  //#endregion
24
45
  export { parseDiffFromFile };
25
46
 
@@ -1 +1 @@
1
- {"version":3,"file":"parseDiffFromFile.js","names":[],"sources":["../../src/utils/parseDiffFromFile.ts"],"sourcesContent":["import { type CreatePatchOptionsNonabortable, createTwoFilesPatch } from 'diff';\n\nimport type { FileContents, FileDiffMetadata } from '../types';\nimport { processFile } from './parsePatchFiles';\n\n/**\n * Parses a diff from two file contents objects.\n *\n * If both `oldFile` and `newFile` have a `cacheKey`, the resulting diff will\n * automatically get a combined cache key in the format `oldKey:newKey`.\n */\nexport function parseDiffFromFile(\n // FIXME(amadeus): oldFile/newFile should be optional to simulate new/deleted\n // files\n oldFile: FileContents,\n newFile: FileContents,\n options?: CreatePatchOptionsNonabortable,\n throwOnError = false\n): FileDiffMetadata {\n const patch = createTwoFilesPatch(\n oldFile.name,\n newFile.name,\n oldFile.contents,\n newFile.contents,\n oldFile.header,\n newFile.header,\n options\n );\n\n const fileData = processFile(patch, {\n cacheKey: (() => {\n if (oldFile.cacheKey != null && newFile.cacheKey != null) {\n return `${oldFile.cacheKey}:${newFile.cacheKey}`;\n }\n return undefined;\n })(),\n oldFile,\n newFile,\n throwOnError,\n });\n if (fileData == null) {\n throw new Error(\n 'parseDiffFrom: FileInvalid diff -- probably need to fix something -- if the files are the same maybe?'\n );\n }\n // If we've been provided an override for language in the newFile, let’s pass\n // it through to FileDiffMetadata.\n if (newFile.lang != null) {\n fileData.lang = newFile.lang;\n }\n return fileData;\n}\n"],"mappings":";;;;;;;;;AAWA,SAAgB,kBAGd,SACA,SACA,SACA,eAAe,OACG;CAWlB,MAAM,WAAW,YAVH,oBACZ,QAAQ,MACR,QAAQ,MACR,QAAQ,UACR,QAAQ,UACR,QAAQ,QACR,QAAQ,QACR,OAG+B,GAAG;EAClC,iBAAiB;GACf,IAAI,QAAQ,YAAY,QAAQ,QAAQ,YAAY,MAClD,OAAO,GAAG,QAAQ,SAAS,GAAG,QAAQ;EAG1C,EAAA,CAAG;EACH;EACA;EACA;CACF,CAAC;CACD,IAAI,YAAY,MACd,MAAM,IAAI,MACR,uGACF;CAIF,IAAI,QAAQ,QAAQ,MAClB,SAAS,OAAO,QAAQ;CAE1B,OAAO;AACT"}
1
+ {"version":3,"file":"parseDiffFromFile.js","names":[],"sources":["../../src/utils/parseDiffFromFile.ts"],"sourcesContent":["import { type CreatePatchOptionsNonabortable, createTwoFilesPatch } from 'diff';\n\nimport type { FileContents, FileDiffMetadata } from '../types';\nimport { processFile } from './parsePatchFiles';\n\nconst MISSING_FILE_NAME = '/dev/null';\n\n/**\n * Parses a diff from two file contents objects.\n *\n * If both `oldFile` and `newFile` have a `cacheKey`, the resulting diff will\n * automatically get a combined cache key in the format `oldKey:newKey`.\n */\nexport function parseDiffFromFile(\n oldFile: FileContents | null,\n newFile: FileContents | null,\n options?: CreatePatchOptionsNonabortable,\n throwOnError = false\n): FileDiffMetadata {\n if (oldFile === null && newFile === null) {\n throw new Error(\n 'parseDiffFromFile: You must pass oldFile, newFile, or both'\n );\n }\n\n const resolvedOldFile = oldFile ?? createMissingFile();\n const resolvedNewFile = newFile ?? createMissingFile();\n const patch = createTwoFilesPatch(\n resolvedOldFile.name,\n resolvedNewFile.name,\n resolvedOldFile.contents,\n resolvedNewFile.contents,\n resolvedOldFile.header,\n resolvedNewFile.header,\n options\n );\n\n const fileData = processFile(patch, {\n cacheKey: (() => {\n const oldCacheKey = oldFile?.cacheKey ?? oldFile?.name;\n const newCacheKey = newFile?.cacheKey ?? newFile?.name;\n if (oldCacheKey != null && newCacheKey != null) {\n return oldCacheKey + ':' + newCacheKey;\n }\n return oldCacheKey ?? newCacheKey;\n })(),\n oldFile: resolvedOldFile,\n newFile: resolvedNewFile,\n throwOnError,\n });\n if (fileData == null) {\n throw new Error(\n 'parseDiffFrom: FileInvalid diff -- probably need to fix something -- if the files are the same maybe?'\n );\n }\n if (oldFile === null) {\n fileData.type = 'new';\n fileData.prevName = undefined;\n } else if (newFile === null) {\n fileData.type = 'deleted';\n fileData.prevName = undefined;\n }\n // If we've been provided an override for language in the newFile, let’s pass\n // it through to FileDiffMetadata.\n const language =\n newFile?.lang ?? (newFile === null ? oldFile?.lang : undefined);\n if (language != null) {\n fileData.lang = language;\n }\n return fileData;\n}\n\nfunction createMissingFile(): FileContents {\n return { name: MISSING_FILE_NAME, contents: '' };\n}\n"],"mappings":";;;AAKA,MAAM,oBAAoB;;;;;;;AAQ1B,SAAgB,kBACd,SACA,SACA,SACA,eAAe,OACG;CAClB,IAAI,YAAY,QAAQ,YAAY,MAClC,MAAM,IAAI,MACR,4DACF;CAGF,MAAM,kBAAkB,WAAW,kBAAkB;CACrD,MAAM,kBAAkB,WAAW,kBAAkB;CAWrD,MAAM,WAAW,YAVH,oBACZ,gBAAgB,MAChB,gBAAgB,MAChB,gBAAgB,UAChB,gBAAgB,UAChB,gBAAgB,QAChB,gBAAgB,QAChB,OAG+B,GAAG;EAClC,iBAAiB;GACf,MAAM,cAAc,SAAS,YAAY,SAAS;GAClD,MAAM,cAAc,SAAS,YAAY,SAAS;GAClD,IAAI,eAAe,QAAQ,eAAe,MACxC,OAAO,cAAc,MAAM;GAE7B,OAAO,eAAe;EACxB,EAAA,CAAG;EACH,SAAS;EACT,SAAS;EACT;CACF,CAAC;CACD,IAAI,YAAY,MACd,MAAM,IAAI,MACR,uGACF;CAEF,IAAI,YAAY,MAAM;EACpB,SAAS,OAAO;EAChB,SAAS,WAAW,KAAA;CACtB,OAAO,IAAI,YAAY,MAAM;EAC3B,SAAS,OAAO;EAChB,SAAS,WAAW,KAAA;CACtB;CAGA,MAAM,WACJ,SAAS,SAAS,YAAY,OAAO,SAAS,OAAO,KAAA;CACvD,IAAI,YAAY,MACd,SAAS,OAAO;CAElB,OAAO;AACT;AAEA,SAAS,oBAAkC;CACzC,OAAO;EAAE,MAAM;EAAmB,UAAU;CAAG;AACjD"}
@@ -27,7 +27,6 @@ function setPreNodeProperties(pre, { type, diffIndicators, disableBackground, di
27
27
  if (type === "diff") pre.setAttribute("data-diff-type", split ? "split" : "single");
28
28
  else pre.removeAttribute("data-diff-type");
29
29
  pre.setAttribute("data-overflow", overflow);
30
- pre.tabIndex = 0;
31
30
  pre.style.setProperty("--diffs-min-number-column-width-default", `${`${totalLines}`.length}ch`);
32
31
  return pre;
33
32
  }