@code-yeongyu/senpi-tui 2026.7.26 → 2026.7.28

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 (46) hide show
  1. package/dist/components/editor.d.ts +16 -6
  2. package/dist/components/editor.d.ts.map +1 -1
  3. package/dist/components/editor.js +56 -120
  4. package/dist/components/editor.js.map +1 -1
  5. package/dist/components/image.d.ts.map +1 -1
  6. package/dist/components/image.js +7 -1
  7. package/dist/components/image.js.map +1 -1
  8. package/dist/editor-component.d.ts +18 -0
  9. package/dist/editor-component.d.ts.map +1 -1
  10. package/dist/editor-component.js.map +1 -1
  11. package/dist/index.d.ts +3 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +3 -2
  14. package/dist/index.js.map +1 -1
  15. package/dist/paste-markers.d.ts +29 -0
  16. package/dist/paste-markers.d.ts.map +1 -0
  17. package/dist/paste-markers.js +185 -0
  18. package/dist/paste-markers.js.map +1 -0
  19. package/dist/terminal-capabilities.d.ts +18 -0
  20. package/dist/terminal-capabilities.d.ts.map +1 -0
  21. package/dist/terminal-capabilities.js +62 -0
  22. package/dist/terminal-capabilities.js.map +1 -0
  23. package/dist/terminal-image.d.ts +31 -6
  24. package/dist/terminal-image.d.ts.map +1 -1
  25. package/dist/terminal-image.js +137 -92
  26. package/dist/terminal-image.js.map +1 -1
  27. package/dist/tmux-focus.d.ts +8 -0
  28. package/dist/tmux-focus.d.ts.map +1 -0
  29. package/dist/tmux-focus.js +14 -0
  30. package/dist/tmux-focus.js.map +1 -0
  31. package/dist/tmux-image-capability.d.ts +17 -0
  32. package/dist/tmux-image-capability.d.ts.map +1 -0
  33. package/dist/tmux-image-capability.js +61 -0
  34. package/dist/tmux-image-capability.js.map +1 -0
  35. package/dist/tmux-image-probe.d.ts +39 -0
  36. package/dist/tmux-image-probe.d.ts.map +1 -0
  37. package/dist/tmux-image-probe.js +121 -0
  38. package/dist/tmux-image-probe.js.map +1 -0
  39. package/dist/tui.d.ts +3 -0
  40. package/dist/tui.d.ts.map +1 -1
  41. package/dist/tui.js +63 -33
  42. package/dist/tui.js.map +1 -1
  43. package/dist/utils.d.ts.map +1 -1
  44. package/dist/utils.js +19 -0
  45. package/dist/utils.js.map +1 -1
  46. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/components/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAKN,KAAK,eAAe,EAEpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,MAAM,WAAW,UAAU;IAC1B,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,KAAM,YAAW,SAAS;IACtC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,OAAO,CAAC,CAAS;IAEzB,OAAO,CAAC,WAAW,CAAC,CAAW;IAC/B,OAAO,CAAC,WAAW,CAAC,CAAS;IAE7B,YACC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,YAAiB,EAC1B,UAAU,CAAC,EAAE,eAAe,EAQ5B;IAED,0DAA0D;IAC1D,UAAU,IAAI,MAAM,GAAG,SAAS,CAE/B;IAED,UAAU,IAAI,IAAI,CAGjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAiE9B;CACD"}
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/components/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAKN,KAAK,eAAe,EAEpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,MAAM,WAAW,UAAU;IAC1B,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,KAAM,YAAW,SAAS;IACtC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,OAAO,CAAC,CAAS;IAEzB,OAAO,CAAC,WAAW,CAAC,CAAW;IAC/B,OAAO,CAAC,WAAW,CAAC,CAAS;IAE7B,YACC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,YAAiB,EAC1B,UAAU,CAAC,EAAE,eAAe,EAQ5B;IAED,0DAA0D;IAC1D,UAAU,IAAI,MAAM,GAAG,SAAS,CAE/B;IAED,UAAU,IAAI,IAAI,CAGjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAsE9B;CACD"}
@@ -42,7 +42,13 @@ export class Image {
42
42
  if (result.imageId) {
43
43
  this.imageId = result.imageId;
44
44
  }
45
- if (caps.images === "kitty") {
45
+ if (caps.images === "kitty" && result.lines) {
46
+ // Unicode placeholder placement (tmux passthrough): each row is a
47
+ // real text line of placeholder cells; the first row also carries
48
+ // the virtual-placement transmission.
49
+ lines = result.lines;
50
+ }
51
+ else if (caps.images === "kitty") {
46
52
  // For Kitty: C=1 prevents cursor movement.
47
53
  // Don't need the cursor movement.
48
54
  lines = [result.sequence];
@@ -1 +1 @@
1
- {"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/components/image.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tallocateImageId,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetImageDimensions,\n\ttype ImageDimensions,\n\trenderImage,\n} from \"../terminal-image.ts\";\nimport { imageFallback } from \"../terminal-text.ts\";\nimport type { Component } from \"../tui.ts\";\n\nexport interface ImageTheme {\n\tfallbackColor: (str: string) => string;\n}\n\nexport interface ImageOptions {\n\tmaxWidthCells?: number;\n\tmaxHeightCells?: number;\n\tfilename?: string;\n\t/** Kitty image ID. If provided, reuses this ID (for animations/updates). */\n\timageId?: number;\n}\n\nexport class Image implements Component {\n\tprivate base64Data: string;\n\tprivate mimeType: string;\n\tprivate dimensions: ImageDimensions;\n\tprivate theme: ImageTheme;\n\tprivate options: ImageOptions;\n\tprivate imageId?: number;\n\n\tprivate cachedLines?: string[];\n\tprivate cachedWidth?: number;\n\n\tconstructor(\n\t\tbase64Data: string,\n\t\tmimeType: string,\n\t\ttheme: ImageTheme,\n\t\toptions: ImageOptions = {},\n\t\tdimensions?: ImageDimensions,\n\t) {\n\t\tthis.base64Data = base64Data;\n\t\tthis.mimeType = mimeType;\n\t\tthis.theme = theme;\n\t\tthis.options = options;\n\t\tthis.dimensions = dimensions || getImageDimensions(base64Data, mimeType) || { widthPx: 800, heightPx: 600 };\n\t\tthis.imageId = options.imageId;\n\t}\n\n\t/** Get the Kitty image ID used by this image (if any). */\n\tgetImageId(): number | undefined {\n\t\treturn this.imageId;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.cachedLines = undefined;\n\t\tthis.cachedWidth = undefined;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.cachedLines && this.cachedWidth === width) {\n\t\t\treturn this.cachedLines;\n\t\t}\n\n\t\tconst maxWidth = Math.max(1, Math.min(width - 2, this.options.maxWidthCells ?? 60));\n\t\tconst cellDimensions = getCellDimensions();\n\t\tconst defaultMaxHeight = Math.max(1, Math.ceil((maxWidth * cellDimensions.widthPx) / cellDimensions.heightPx));\n\t\tconst maxHeight = this.options.maxHeightCells ?? defaultMaxHeight;\n\n\t\tconst caps = getCapabilities();\n\t\tlet lines: string[];\n\n\t\tif (caps.images) {\n\t\t\tif (caps.images === \"kitty\" && this.imageId === undefined) {\n\t\t\t\tthis.imageId = allocateImageId();\n\t\t\t}\n\t\t\tconst result = renderImage(this.base64Data, this.dimensions, {\n\t\t\t\tmaxWidthCells: maxWidth,\n\t\t\t\tmaxHeightCells: maxHeight,\n\t\t\t\timageId: this.imageId,\n\t\t\t\tmoveCursor: false,\n\t\t\t});\n\n\t\t\tif (result) {\n\t\t\t\t// Store the image ID for later cleanup\n\t\t\t\tif (result.imageId) {\n\t\t\t\t\tthis.imageId = result.imageId;\n\t\t\t\t}\n\n\t\t\t\tif (caps.images === \"kitty\") {\n\t\t\t\t\t// For Kitty: C=1 prevents cursor movement.\n\t\t\t\t\t// Don't need the cursor movement.\n\t\t\t\t\tlines = [result.sequence];\n\n\t\t\t\t\t// Return `rows` lines so TUI accounts for image height.\n\t\t\t\t\tfor (let i = 0; i < result.rows - 1; i++) {\n\t\t\t\t\t\tlines.push(\"\");\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Return `rows` lines so TUI accounts for image height.\n\t\t\t\t\t// First (rows-1) lines are empty and cleared before the image is drawn.\n\t\t\t\t\t// Last line: move cursor back up, draw the image, then move back down\n\t\t\t\t\t// so TUI cursor accounting stays inside the scroll area.\n\t\t\t\t\tlines = [];\n\t\t\t\t\tfor (let i = 0; i < result.rows - 1; i++) {\n\t\t\t\t\t\tlines.push(\"\");\n\t\t\t\t\t}\n\t\t\t\t\tconst rowOffset = result.rows - 1;\n\t\t\t\t\tconst moveUp = rowOffset > 0 ? `\\x1b[${rowOffset}A` : \"\";\n\t\t\t\t\tlines.push(moveUp + result.sequence);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst fallback = imageFallback(this.mimeType, this.dimensions, this.options.filename);\n\t\t\t\tlines = [this.theme.fallbackColor(fallback)];\n\t\t\t}\n\t\t} else {\n\t\t\tconst fallback = imageFallback(this.mimeType, this.dimensions, this.options.filename);\n\t\t\tlines = [this.theme.fallbackColor(fallback)];\n\t\t}\n\n\t\tthis.cachedLines = lines;\n\t\tthis.cachedWidth = width;\n\n\t\treturn lines;\n\t}\n}\n"]}
1
+ {"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/components/image.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tallocateImageId,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetImageDimensions,\n\ttype ImageDimensions,\n\trenderImage,\n} from \"../terminal-image.ts\";\nimport { imageFallback } from \"../terminal-text.ts\";\nimport type { Component } from \"../tui.ts\";\n\nexport interface ImageTheme {\n\tfallbackColor: (str: string) => string;\n}\n\nexport interface ImageOptions {\n\tmaxWidthCells?: number;\n\tmaxHeightCells?: number;\n\tfilename?: string;\n\t/** Kitty image ID. If provided, reuses this ID (for animations/updates). */\n\timageId?: number;\n}\n\nexport class Image implements Component {\n\tprivate base64Data: string;\n\tprivate mimeType: string;\n\tprivate dimensions: ImageDimensions;\n\tprivate theme: ImageTheme;\n\tprivate options: ImageOptions;\n\tprivate imageId?: number;\n\n\tprivate cachedLines?: string[];\n\tprivate cachedWidth?: number;\n\n\tconstructor(\n\t\tbase64Data: string,\n\t\tmimeType: string,\n\t\ttheme: ImageTheme,\n\t\toptions: ImageOptions = {},\n\t\tdimensions?: ImageDimensions,\n\t) {\n\t\tthis.base64Data = base64Data;\n\t\tthis.mimeType = mimeType;\n\t\tthis.theme = theme;\n\t\tthis.options = options;\n\t\tthis.dimensions = dimensions || getImageDimensions(base64Data, mimeType) || { widthPx: 800, heightPx: 600 };\n\t\tthis.imageId = options.imageId;\n\t}\n\n\t/** Get the Kitty image ID used by this image (if any). */\n\tgetImageId(): number | undefined {\n\t\treturn this.imageId;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.cachedLines = undefined;\n\t\tthis.cachedWidth = undefined;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.cachedLines && this.cachedWidth === width) {\n\t\t\treturn this.cachedLines;\n\t\t}\n\n\t\tconst maxWidth = Math.max(1, Math.min(width - 2, this.options.maxWidthCells ?? 60));\n\t\tconst cellDimensions = getCellDimensions();\n\t\tconst defaultMaxHeight = Math.max(1, Math.ceil((maxWidth * cellDimensions.widthPx) / cellDimensions.heightPx));\n\t\tconst maxHeight = this.options.maxHeightCells ?? defaultMaxHeight;\n\n\t\tconst caps = getCapabilities();\n\t\tlet lines: string[];\n\n\t\tif (caps.images) {\n\t\t\tif (caps.images === \"kitty\" && this.imageId === undefined) {\n\t\t\t\tthis.imageId = allocateImageId();\n\t\t\t}\n\t\t\tconst result = renderImage(this.base64Data, this.dimensions, {\n\t\t\t\tmaxWidthCells: maxWidth,\n\t\t\t\tmaxHeightCells: maxHeight,\n\t\t\t\timageId: this.imageId,\n\t\t\t\tmoveCursor: false,\n\t\t\t});\n\n\t\t\tif (result) {\n\t\t\t\t// Store the image ID for later cleanup\n\t\t\t\tif (result.imageId) {\n\t\t\t\t\tthis.imageId = result.imageId;\n\t\t\t\t}\n\n\t\t\t\tif (caps.images === \"kitty\" && result.lines) {\n\t\t\t\t\t// Unicode placeholder placement (tmux passthrough): each row is a\n\t\t\t\t\t// real text line of placeholder cells; the first row also carries\n\t\t\t\t\t// the virtual-placement transmission.\n\t\t\t\t\tlines = result.lines;\n\t\t\t\t} else if (caps.images === \"kitty\") {\n\t\t\t\t\t// For Kitty: C=1 prevents cursor movement.\n\t\t\t\t\t// Don't need the cursor movement.\n\t\t\t\t\tlines = [result.sequence];\n\n\t\t\t\t\t// Return `rows` lines so TUI accounts for image height.\n\t\t\t\t\tfor (let i = 0; i < result.rows - 1; i++) {\n\t\t\t\t\t\tlines.push(\"\");\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Return `rows` lines so TUI accounts for image height.\n\t\t\t\t\t// First (rows-1) lines are empty and cleared before the image is drawn.\n\t\t\t\t\t// Last line: move cursor back up, draw the image, then move back down\n\t\t\t\t\t// so TUI cursor accounting stays inside the scroll area.\n\t\t\t\t\tlines = [];\n\t\t\t\t\tfor (let i = 0; i < result.rows - 1; i++) {\n\t\t\t\t\t\tlines.push(\"\");\n\t\t\t\t\t}\n\t\t\t\t\tconst rowOffset = result.rows - 1;\n\t\t\t\t\tconst moveUp = rowOffset > 0 ? `\\x1b[${rowOffset}A` : \"\";\n\t\t\t\t\tlines.push(moveUp + result.sequence);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst fallback = imageFallback(this.mimeType, this.dimensions, this.options.filename);\n\t\t\t\tlines = [this.theme.fallbackColor(fallback)];\n\t\t\t}\n\t\t} else {\n\t\t\tconst fallback = imageFallback(this.mimeType, this.dimensions, this.options.filename);\n\t\t\tlines = [this.theme.fallbackColor(fallback)];\n\t\t}\n\n\t\tthis.cachedLines = lines;\n\t\tthis.cachedWidth = width;\n\n\t\treturn lines;\n\t}\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import type { AutocompleteProvider } from "./autocomplete.ts";
2
+ import type { EditorPasteState } from "./paste-markers.ts";
2
3
  import type { Component } from "./tui.ts";
3
4
  /**
4
5
  * Interface for custom editor components.
@@ -27,6 +28,23 @@ export interface EditorComponent extends Component {
27
28
  * Falls back to getText() if not implemented.
28
29
  */
29
30
  getExpandedText?(): string;
31
+ /**
32
+ * Snapshot the paste-marker registry so collapsed markers can be
33
+ * transferred to another editor instance alongside getText().
34
+ *
35
+ * Paired contract: implement getPasteState and setPasteState together.
36
+ * Callers only hand collapsed markers to an editor that can export them
37
+ * again; an editor implementing setPasteState without getPasteState is
38
+ * treated as paste-unaware and receives expanded text instead.
39
+ */
40
+ getPasteState?(): EditorPasteState;
41
+ /**
42
+ * Install a paste-marker registry snapshot taken from another editor
43
+ * instance. Called after setText() with that editor's raw (marker) text.
44
+ * Paired contract: implement together with getPasteState (see above).
45
+ * When not implemented, callers must transfer the expanded text instead.
46
+ */
47
+ setPasteState?(state: EditorPasteState): void;
30
48
  /** Set the autocomplete provider */
31
49
  setAutocompleteProvider?(provider: AutocompleteProvider): void;
32
50
  /** Border color function */
@@ -1 +1 @@
1
- {"version":3,"file":"editor-component.d.ts","sourceRoot":"","sources":["../src/editor-component.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAKjD,mCAAmC;IACnC,OAAO,IAAI,MAAM,CAAC;IAElB,2BAA2B;IAC3B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,qEAAqE;IACrE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAMhC,iDAAiD;IACjD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAMlC,iDAAiD;IACjD,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAMlC,6CAA6C;IAC7C,kBAAkB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAExC;;;OAGG;IACH,eAAe,CAAC,IAAI,MAAM,CAAC;IAM3B,oCAAoC;IACpC,uBAAuB,CAAC,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAM/D,4BAA4B;IAC5B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAEtC,6BAA6B;IAC7B,WAAW,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpC,qDAAqD;IACrD,yBAAyB,CAAC,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACrD"}
1
+ {"version":3,"file":"editor-component.d.ts","sourceRoot":"","sources":["../src/editor-component.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAKjD,mCAAmC;IACnC,OAAO,IAAI,MAAM,CAAC;IAElB,2BAA2B;IAC3B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,qEAAqE;IACrE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAMhC,iDAAiD;IACjD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAMlC,iDAAiD;IACjD,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAMlC,6CAA6C;IAC7C,kBAAkB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAExC;;;OAGG;IACH,eAAe,CAAC,IAAI,MAAM,CAAC;IAE3B;;;;;;;;OAQG;IACH,aAAa,CAAC,IAAI,gBAAgB,CAAC;IAEnC;;;;;OAKG;IACH,aAAa,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAM9C,oCAAoC;IACpC,uBAAuB,CAAC,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAM/D,4BAA4B;IAC5B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAEtC,6BAA6B;IAC7B,WAAW,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpC,qDAAqD;IACrD,yBAAyB,CAAC,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACrD"}
@@ -1 +1 @@
1
- {"version":3,"file":"editor-component.js","sourceRoot":"","sources":["../src/editor-component.ts"],"names":[],"mappings":"","sourcesContent":["import type { AutocompleteProvider } from \"./autocomplete.ts\";\nimport type { Component } from \"./tui.ts\";\n\n/**\n * Interface for custom editor components.\n *\n * This allows extensions to provide their own editor implementation\n * (e.g., vim mode, emacs mode, custom keybindings) while maintaining\n * compatibility with the core application.\n */\nexport interface EditorComponent extends Component {\n\t// =========================================================================\n\t// Core text access (required)\n\t// =========================================================================\n\n\t/** Get the current text content */\n\tgetText(): string;\n\n\t/** Set the text content */\n\tsetText(text: string): void;\n\n\t/** Handle raw terminal input (key presses, paste sequences, etc.) */\n\thandleInput(data: string): void;\n\n\t// =========================================================================\n\t// Callbacks (required)\n\t// =========================================================================\n\n\t/** Called when user submits (e.g., Enter key) */\n\tonSubmit?: (text: string) => void;\n\n\t/** Called when text changes */\n\tonChange?: (text: string) => void;\n\n\t// =========================================================================\n\t// History support (optional)\n\t// =========================================================================\n\n\t/** Add text to history for up/down navigation */\n\taddToHistory?(text: string): void;\n\n\t// =========================================================================\n\t// Advanced text manipulation (optional)\n\t// =========================================================================\n\n\t/** Insert text at current cursor position */\n\tinsertTextAtCursor?(text: string): void;\n\n\t/**\n\t * Get text with any markers expanded (e.g., paste markers).\n\t * Falls back to getText() if not implemented.\n\t */\n\tgetExpandedText?(): string;\n\n\t// =========================================================================\n\t// Autocomplete support (optional)\n\t// =========================================================================\n\n\t/** Set the autocomplete provider */\n\tsetAutocompleteProvider?(provider: AutocompleteProvider): void;\n\n\t// =========================================================================\n\t// Appearance (optional)\n\t// =========================================================================\n\n\t/** Border color function */\n\tborderColor?: (str: string) => string;\n\n\t/** Set horizontal padding */\n\tsetPaddingX?(padding: number): void;\n\n\t/** Set max visible items in autocomplete dropdown */\n\tsetAutocompleteMaxVisible?(maxVisible: number): void;\n}\n"]}
1
+ {"version":3,"file":"editor-component.js","sourceRoot":"","sources":["../src/editor-component.ts"],"names":[],"mappings":"","sourcesContent":["import type { AutocompleteProvider } from \"./autocomplete.ts\";\nimport type { EditorPasteState } from \"./paste-markers.ts\";\nimport type { Component } from \"./tui.ts\";\n\n/**\n * Interface for custom editor components.\n *\n * This allows extensions to provide their own editor implementation\n * (e.g., vim mode, emacs mode, custom keybindings) while maintaining\n * compatibility with the core application.\n */\nexport interface EditorComponent extends Component {\n\t// =========================================================================\n\t// Core text access (required)\n\t// =========================================================================\n\n\t/** Get the current text content */\n\tgetText(): string;\n\n\t/** Set the text content */\n\tsetText(text: string): void;\n\n\t/** Handle raw terminal input (key presses, paste sequences, etc.) */\n\thandleInput(data: string): void;\n\n\t// =========================================================================\n\t// Callbacks (required)\n\t// =========================================================================\n\n\t/** Called when user submits (e.g., Enter key) */\n\tonSubmit?: (text: string) => void;\n\n\t/** Called when text changes */\n\tonChange?: (text: string) => void;\n\n\t// =========================================================================\n\t// History support (optional)\n\t// =========================================================================\n\n\t/** Add text to history for up/down navigation */\n\taddToHistory?(text: string): void;\n\n\t// =========================================================================\n\t// Advanced text manipulation (optional)\n\t// =========================================================================\n\n\t/** Insert text at current cursor position */\n\tinsertTextAtCursor?(text: string): void;\n\n\t/**\n\t * Get text with any markers expanded (e.g., paste markers).\n\t * Falls back to getText() if not implemented.\n\t */\n\tgetExpandedText?(): string;\n\n\t/**\n\t * Snapshot the paste-marker registry so collapsed markers can be\n\t * transferred to another editor instance alongside getText().\n\t *\n\t * Paired contract: implement getPasteState and setPasteState together.\n\t * Callers only hand collapsed markers to an editor that can export them\n\t * again; an editor implementing setPasteState without getPasteState is\n\t * treated as paste-unaware and receives expanded text instead.\n\t */\n\tgetPasteState?(): EditorPasteState;\n\n\t/**\n\t * Install a paste-marker registry snapshot taken from another editor\n\t * instance. Called after setText() with that editor's raw (marker) text.\n\t * Paired contract: implement together with getPasteState (see above).\n\t * When not implemented, callers must transfer the expanded text instead.\n\t */\n\tsetPasteState?(state: EditorPasteState): void;\n\n\t// =========================================================================\n\t// Autocomplete support (optional)\n\t// =========================================================================\n\n\t/** Set the autocomplete provider */\n\tsetAutocompleteProvider?(provider: AutocompleteProvider): void;\n\n\t// =========================================================================\n\t// Appearance (optional)\n\t// =========================================================================\n\n\t/** Border color function */\n\tborderColor?: (str: string) => string;\n\n\t/** Set horizontal padding */\n\tsetPaddingX?(padding: number): void;\n\n\t/** Set max visible items in autocomplete dropdown */\n\tsetAutocompleteMaxVisible?(maxVisible: number): void;\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { type AutocompleteItem, type AutocompleteProvider, type AutocompleteSuggestions, CombinedAutocompleteProvider, type SlashCommand, } from "./autocomplete.ts";
2
2
  export { Box } from "./components/box.ts";
3
3
  export { CancellableLoader } from "./components/cancellable-loader.ts";
4
- export { Editor, type EditorOptions, type EditorTheme } from "./components/editor.ts";
4
+ export { Editor, type EditorOptions, type EditorTheme, } from "./components/editor.ts";
5
5
  export { Image, type ImageOptions, type ImageTheme } from "./components/image.ts";
6
6
  export { Input } from "./components/input.ts";
7
7
  export { Loader, type LoaderIndicatorOptions } from "./components/loader.ts";
@@ -15,10 +15,11 @@ export type { EditorComponent } from "./editor-component.ts";
15
15
  export { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from "./fuzzy.ts";
16
16
  export { getKeybindings, type Keybinding, type KeybindingConflict, type KeybindingDefinition, type KeybindingDefinitions, type Keybindings, type KeybindingsConfig, KeybindingsManager, setKeybindings, TUI_KEYBINDINGS, } from "./keybindings.ts";
17
17
  export { decodeKittyPrintable, isKeyRelease, isKeyRepeat, isKittyProtocolActive, Key, type KeyEventType, type KeyId, matchesKey, parseKey, setKittyProtocolActive, } from "./keys.ts";
18
+ export { type EditorPasteState, expandPasteMarkers } from "./paste-markers.ts";
18
19
  export { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from "./stdin-buffer.ts";
19
20
  export { ProcessTerminal, type ProcessTerminalOptions, type Terminal } from "./terminal.ts";
20
21
  export { parseOsc11BackgroundColor, parseTerminalColorSchemeReport, type RgbColor, type TerminalColorScheme, } from "./terminal-colors.ts";
21
- export { allocateImageId, type CellDimensions, deleteAllKittyImages, deleteKittyImage, detectCapabilities, encodeITerm2, encodeKitty, getCapabilities, getCellDimensions, getGifDimensions, getImageDimensions, getJpegDimensions, getPngDimensions, getWebpDimensions, hyperlink, type ImageDimensions, type ImageProtocol, type ImageRenderOptions, renderImage, resetCapabilitiesCache, setCapabilities, setCellDimensions, type TerminalCapabilities, } from "./terminal-image.ts";
22
+ export { allocateImageId, buildKittyPlaceholderRow, type CellDimensions, deleteAllKittyImages, deleteKittyImage, detectCapabilities, encodeITerm2, encodeKitty, getCapabilities, getCellDimensions, getGifDimensions, getImageDimensions, getJpegDimensions, getPngDimensions, getWebpDimensions, hyperlink, type ImageDimensions, type ImageProtocol, type ImageRenderOptions, KITTY_PLACEHOLDER_MAX, outerKittyGraphicsMode, renderImage, resetCapabilitiesCache, setCapabilities, setCellDimensions, type TerminalCapabilities, type TmuxPassthroughState, wrapTmuxPassthrough, } from "./terminal-image.ts";
22
23
  export { imageFallback, sanitizeTerminalLabel } from "./terminal-text.ts";
23
24
  export { type Component, Container, CURSOR_MARKER, type Focusable, isFocusable, type OverlayAnchor, type OverlayHandle, type OverlayMargin, type OverlayOptions, type OverlayUnfocusOptions, type SizeValue, TUI, } from "./tui.ts";
24
25
  export { getGraphemeSegmenter, getWordSegmenter, sliceByColumn, truncateToWidth, visibleWidth, wrapTextWithAnsi, } from "./utils.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ export { CombinedAutocompleteProvider, } from "./autocomplete.js";
4
4
  // Components
5
5
  export { Box } from "./components/box.js";
6
6
  export { CancellableLoader } from "./components/cancellable-loader.js";
7
- export { Editor } from "./components/editor.js";
7
+ export { Editor, } from "./components/editor.js";
8
8
  export { Image } from "./components/image.js";
9
9
  export { Input } from "./components/input.js";
10
10
  export { Loader } from "./components/loader.js";
@@ -20,6 +20,7 @@ export { fuzzyFilter, fuzzyMatch } from "./fuzzy.js";
20
20
  export { getKeybindings, KeybindingsManager, setKeybindings, TUI_KEYBINDINGS, } from "./keybindings.js";
21
21
  // Keyboard input handling
22
22
  export { decodeKittyPrintable, isKeyRelease, isKeyRepeat, isKittyProtocolActive, Key, matchesKey, parseKey, setKittyProtocolActive, } from "./keys.js";
23
+ export { expandPasteMarkers } from "./paste-markers.js";
23
24
  // Input buffering for batch splitting
24
25
  export { StdinBuffer } from "./stdin-buffer.js";
25
26
  // Terminal interface and implementations
@@ -27,7 +28,7 @@ export { ProcessTerminal } from "./terminal.js";
27
28
  // Terminal colors
28
29
  export { parseOsc11BackgroundColor, parseTerminalColorSchemeReport, } from "./terminal-colors.js";
29
30
  // Terminal image support
30
- export { allocateImageId, deleteAllKittyImages, deleteKittyImage, detectCapabilities, encodeITerm2, encodeKitty, getCapabilities, getCellDimensions, getGifDimensions, getImageDimensions, getJpegDimensions, getPngDimensions, getWebpDimensions, hyperlink, renderImage, resetCapabilitiesCache, setCapabilities, setCellDimensions, } from "./terminal-image.js";
31
+ export { allocateImageId, buildKittyPlaceholderRow, deleteAllKittyImages, deleteKittyImage, detectCapabilities, encodeITerm2, encodeKitty, getCapabilities, getCellDimensions, getGifDimensions, getImageDimensions, getJpegDimensions, getPngDimensions, getWebpDimensions, hyperlink, KITTY_PLACEHOLDER_MAX, outerKittyGraphicsMode, renderImage, resetCapabilitiesCache, setCapabilities, setCellDimensions, wrapTmuxPassthrough, } from "./terminal-image.js";
31
32
  export { imageFallback, sanitizeTerminalLabel } from "./terminal-text.js";
32
33
  export { Container, CURSOR_MARKER, isFocusable, TUI, } from "./tui.js";
33
34
  // Utilities
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,uBAAuB;AACvB,OAAO,EAIN,4BAA4B,GAE5B,MAAM,mBAAmB,CAAC;AAC3B,aAAa;AACb,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,MAAM,EAAwC,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,KAAK,EAAsC,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAA+B,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EACN,gBAAgB,EAEhB,6BAA6B,EAC7B,QAAQ,EAGR,+BAA+B,GAC/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEN,UAAU,GAMV,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAoB,YAAY,EAA0B,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAG/D,iBAAiB;AACjB,OAAO,EAAmB,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,cAAc;AACd,OAAO,EACN,cAAc,EAOd,kBAAkB,EAClB,cAAc,EACd,eAAe,GACf,MAAM,kBAAkB,CAAC;AAC1B,0BAA0B;AAC1B,OAAO,EACN,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,GAAG,EAGH,UAAU,EACV,QAAQ,EACR,sBAAsB,GACtB,MAAM,WAAW,CAAC;AACnB,sCAAsC;AACtC,OAAO,EAAE,WAAW,EAAqD,MAAM,mBAAmB,CAAC;AACnG,yCAAyC;AACzC,OAAO,EAAE,eAAe,EAA8C,MAAM,eAAe,CAAC;AAC5F,kBAAkB;AAClB,OAAO,EACN,yBAAyB,EACzB,8BAA8B,GAG9B,MAAM,sBAAsB,CAAC;AAC9B,yBAAyB;AACzB,OAAO,EACN,eAAe,EAEf,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EAIT,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,iBAAiB,GAEjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAEN,SAAS,EACT,aAAa,EAEb,WAAW,EAOX,GAAG,GACH,MAAM,UAAU,CAAC;AAClB,YAAY;AACZ,OAAO,EACN,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,gBAAgB,GAChB,MAAM,YAAY,CAAC","sourcesContent":["// Core TUI interfaces and classes\n\n// Autocomplete support\nexport {\n\ttype AutocompleteItem,\n\ttype AutocompleteProvider,\n\ttype AutocompleteSuggestions,\n\tCombinedAutocompleteProvider,\n\ttype SlashCommand,\n} from \"./autocomplete.ts\";\n// Components\nexport { Box } from \"./components/box.ts\";\nexport { CancellableLoader } from \"./components/cancellable-loader.ts\";\nexport { Editor, type EditorOptions, type EditorTheme } from \"./components/editor.ts\";\nexport { Image, type ImageOptions, type ImageTheme } from \"./components/image.ts\";\nexport { Input } from \"./components/input.ts\";\nexport { Loader, type LoaderIndicatorOptions } from \"./components/loader.ts\";\nexport {\n\tclearRenderCache,\n\ttype DefaultTextStyle,\n\tgetMarkdownHighlightCallCount,\n\tMarkdown,\n\ttype MarkdownOptions,\n\ttype MarkdownTheme,\n\tresetMarkdownHighlightCallCount,\n} from \"./components/markdown.ts\";\nexport {\n\ttype SelectItem,\n\tSelectList,\n\ttype SelectListLayoutOptions,\n\ttype SelectListRenderRow,\n\ttype SelectListRowParts,\n\ttype SelectListTheme,\n\ttype SelectListTruncatePrimaryContext,\n} from \"./components/select-list.ts\";\nexport { type SettingItem, SettingsList, type SettingsListTheme } from \"./components/settings-list.ts\";\nexport { Spacer } from \"./components/spacer.ts\";\nexport { Text } from \"./components/text.ts\";\nexport { TruncatedText } from \"./components/truncated-text.ts\";\n// Editor component interface (for custom editors)\nexport type { EditorComponent } from \"./editor-component.ts\";\n// Fuzzy matching\nexport { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from \"./fuzzy.ts\";\n// Keybindings\nexport {\n\tgetKeybindings,\n\ttype Keybinding,\n\ttype KeybindingConflict,\n\ttype KeybindingDefinition,\n\ttype KeybindingDefinitions,\n\ttype Keybindings,\n\ttype KeybindingsConfig,\n\tKeybindingsManager,\n\tsetKeybindings,\n\tTUI_KEYBINDINGS,\n} from \"./keybindings.ts\";\n// Keyboard input handling\nexport {\n\tdecodeKittyPrintable,\n\tisKeyRelease,\n\tisKeyRepeat,\n\tisKittyProtocolActive,\n\tKey,\n\ttype KeyEventType,\n\ttype KeyId,\n\tmatchesKey,\n\tparseKey,\n\tsetKittyProtocolActive,\n} from \"./keys.ts\";\n// Input buffering for batch splitting\nexport { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from \"./stdin-buffer.ts\";\n// Terminal interface and implementations\nexport { ProcessTerminal, type ProcessTerminalOptions, type Terminal } from \"./terminal.ts\";\n// Terminal colors\nexport {\n\tparseOsc11BackgroundColor,\n\tparseTerminalColorSchemeReport,\n\ttype RgbColor,\n\ttype TerminalColorScheme,\n} from \"./terminal-colors.ts\";\n// Terminal image support\nexport {\n\tallocateImageId,\n\ttype CellDimensions,\n\tdeleteAllKittyImages,\n\tdeleteKittyImage,\n\tdetectCapabilities,\n\tencodeITerm2,\n\tencodeKitty,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetGifDimensions,\n\tgetImageDimensions,\n\tgetJpegDimensions,\n\tgetPngDimensions,\n\tgetWebpDimensions,\n\thyperlink,\n\ttype ImageDimensions,\n\ttype ImageProtocol,\n\ttype ImageRenderOptions,\n\trenderImage,\n\tresetCapabilitiesCache,\n\tsetCapabilities,\n\tsetCellDimensions,\n\ttype TerminalCapabilities,\n} from \"./terminal-image.ts\";\nexport { imageFallback, sanitizeTerminalLabel } from \"./terminal-text.ts\";\nexport {\n\ttype Component,\n\tContainer,\n\tCURSOR_MARKER,\n\ttype Focusable,\n\tisFocusable,\n\ttype OverlayAnchor,\n\ttype OverlayHandle,\n\ttype OverlayMargin,\n\ttype OverlayOptions,\n\ttype OverlayUnfocusOptions,\n\ttype SizeValue,\n\tTUI,\n} from \"./tui.ts\";\n// Utilities\nexport {\n\tgetGraphemeSegmenter,\n\tgetWordSegmenter,\n\tsliceByColumn,\n\ttruncateToWidth,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"./utils.ts\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,uBAAuB;AACvB,OAAO,EAIN,4BAA4B,GAE5B,MAAM,mBAAmB,CAAC;AAC3B,aAAa;AACb,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EACN,MAAM,GAGN,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,KAAK,EAAsC,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAA+B,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EACN,gBAAgB,EAEhB,6BAA6B,EAC7B,QAAQ,EAGR,+BAA+B,GAC/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEN,UAAU,GAMV,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAoB,YAAY,EAA0B,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAG/D,iBAAiB;AACjB,OAAO,EAAmB,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,cAAc;AACd,OAAO,EACN,cAAc,EAOd,kBAAkB,EAClB,cAAc,EACd,eAAe,GACf,MAAM,kBAAkB,CAAC;AAC1B,0BAA0B;AAC1B,OAAO,EACN,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,GAAG,EAGH,UAAU,EACV,QAAQ,EACR,sBAAsB,GACtB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAyB,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,sCAAsC;AACtC,OAAO,EAAE,WAAW,EAAqD,MAAM,mBAAmB,CAAC;AACnG,yCAAyC;AACzC,OAAO,EAAE,eAAe,EAA8C,MAAM,eAAe,CAAC;AAC5F,kBAAkB;AAClB,OAAO,EACN,yBAAyB,EACzB,8BAA8B,GAG9B,MAAM,sBAAsB,CAAC;AAC9B,yBAAyB;AACzB,OAAO,EACN,eAAe,EACf,wBAAwB,EAExB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EAIT,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EAGjB,mBAAmB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAEN,SAAS,EACT,aAAa,EAEb,WAAW,EAOX,GAAG,GACH,MAAM,UAAU,CAAC;AAClB,YAAY;AACZ,OAAO,EACN,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,gBAAgB,GAChB,MAAM,YAAY,CAAC","sourcesContent":["// Core TUI interfaces and classes\n\n// Autocomplete support\nexport {\n\ttype AutocompleteItem,\n\ttype AutocompleteProvider,\n\ttype AutocompleteSuggestions,\n\tCombinedAutocompleteProvider,\n\ttype SlashCommand,\n} from \"./autocomplete.ts\";\n// Components\nexport { Box } from \"./components/box.ts\";\nexport { CancellableLoader } from \"./components/cancellable-loader.ts\";\nexport {\n\tEditor,\n\ttype EditorOptions,\n\ttype EditorTheme,\n} from \"./components/editor.ts\";\nexport { Image, type ImageOptions, type ImageTheme } from \"./components/image.ts\";\nexport { Input } from \"./components/input.ts\";\nexport { Loader, type LoaderIndicatorOptions } from \"./components/loader.ts\";\nexport {\n\tclearRenderCache,\n\ttype DefaultTextStyle,\n\tgetMarkdownHighlightCallCount,\n\tMarkdown,\n\ttype MarkdownOptions,\n\ttype MarkdownTheme,\n\tresetMarkdownHighlightCallCount,\n} from \"./components/markdown.ts\";\nexport {\n\ttype SelectItem,\n\tSelectList,\n\ttype SelectListLayoutOptions,\n\ttype SelectListRenderRow,\n\ttype SelectListRowParts,\n\ttype SelectListTheme,\n\ttype SelectListTruncatePrimaryContext,\n} from \"./components/select-list.ts\";\nexport { type SettingItem, SettingsList, type SettingsListTheme } from \"./components/settings-list.ts\";\nexport { Spacer } from \"./components/spacer.ts\";\nexport { Text } from \"./components/text.ts\";\nexport { TruncatedText } from \"./components/truncated-text.ts\";\n// Editor component interface (for custom editors)\nexport type { EditorComponent } from \"./editor-component.ts\";\n// Fuzzy matching\nexport { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from \"./fuzzy.ts\";\n// Keybindings\nexport {\n\tgetKeybindings,\n\ttype Keybinding,\n\ttype KeybindingConflict,\n\ttype KeybindingDefinition,\n\ttype KeybindingDefinitions,\n\ttype Keybindings,\n\ttype KeybindingsConfig,\n\tKeybindingsManager,\n\tsetKeybindings,\n\tTUI_KEYBINDINGS,\n} from \"./keybindings.ts\";\n// Keyboard input handling\nexport {\n\tdecodeKittyPrintable,\n\tisKeyRelease,\n\tisKeyRepeat,\n\tisKittyProtocolActive,\n\tKey,\n\ttype KeyEventType,\n\ttype KeyId,\n\tmatchesKey,\n\tparseKey,\n\tsetKittyProtocolActive,\n} from \"./keys.ts\";\nexport { type EditorPasteState, expandPasteMarkers } from \"./paste-markers.ts\";\n// Input buffering for batch splitting\nexport { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from \"./stdin-buffer.ts\";\n// Terminal interface and implementations\nexport { ProcessTerminal, type ProcessTerminalOptions, type Terminal } from \"./terminal.ts\";\n// Terminal colors\nexport {\n\tparseOsc11BackgroundColor,\n\tparseTerminalColorSchemeReport,\n\ttype RgbColor,\n\ttype TerminalColorScheme,\n} from \"./terminal-colors.ts\";\n// Terminal image support\nexport {\n\tallocateImageId,\n\tbuildKittyPlaceholderRow,\n\ttype CellDimensions,\n\tdeleteAllKittyImages,\n\tdeleteKittyImage,\n\tdetectCapabilities,\n\tencodeITerm2,\n\tencodeKitty,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetGifDimensions,\n\tgetImageDimensions,\n\tgetJpegDimensions,\n\tgetPngDimensions,\n\tgetWebpDimensions,\n\thyperlink,\n\ttype ImageDimensions,\n\ttype ImageProtocol,\n\ttype ImageRenderOptions,\n\tKITTY_PLACEHOLDER_MAX,\n\touterKittyGraphicsMode,\n\trenderImage,\n\tresetCapabilitiesCache,\n\tsetCapabilities,\n\tsetCellDimensions,\n\ttype TerminalCapabilities,\n\ttype TmuxPassthroughState,\n\twrapTmuxPassthrough,\n} from \"./terminal-image.ts\";\nexport { imageFallback, sanitizeTerminalLabel } from \"./terminal-text.ts\";\nexport {\n\ttype Component,\n\tContainer,\n\tCURSOR_MARKER,\n\ttype Focusable,\n\tisFocusable,\n\ttype OverlayAnchor,\n\ttype OverlayHandle,\n\ttype OverlayMargin,\n\ttype OverlayOptions,\n\ttype OverlayUnfocusOptions,\n\ttype SizeValue,\n\tTUI,\n} from \"./tui.ts\";\n// Utilities\nexport {\n\tgetGraphemeSegmenter,\n\tgetWordSegmenter,\n\tsliceByColumn,\n\ttruncateToWidth,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"./utils.ts\";\n"]}
@@ -0,0 +1,29 @@
1
+ export interface EditorPasteState {
2
+ pastes: ReadonlyMap<number, string>;
3
+ markers?: ReadonlyMap<number, string>;
4
+ pasteCounter: number;
5
+ }
6
+ export interface PasteMarkerRemoval {
7
+ text: string;
8
+ removed: boolean;
9
+ }
10
+ export declare function expandPasteMarkers(text: string, state: EditorPasteState): string;
11
+ export declare function isPasteMarker(segment: string): boolean;
12
+ export declare function pasteMarkerId(segment: string): number | undefined;
13
+ export declare function segmentWithPasteMarkers(text: string, baseSegmenter: Intl.Segmenter, validMarkers: ReadonlySet<string>): Iterable<Intl.SegmentData>;
14
+ export declare class PasteMarkerRegistry {
15
+ private entries;
16
+ private pasteCounter;
17
+ private metadataBuilds;
18
+ add(content: string, lineCount: number, charCount: number): string;
19
+ authorizedMarkers(text: string): ReadonlySet<string>;
20
+ clear(): void;
21
+ expand(text: string): string;
22
+ get metadataBuildCount(): number;
23
+ install(state: EditorPasteState, text: string): void;
24
+ prune(text: string, previousText?: string): void;
25
+ remove(id: number, text: string): PasteMarkerRemoval;
26
+ snapshot(): EditorPasteState;
27
+ restore(state: EditorPasteState): void;
28
+ }
29
+ //# sourceMappingURL=paste-markers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paste-markers.d.ts","sourceRoot":"","sources":["../src/paste-markers.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CACjB;AAiDD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAyBhF;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGjE;AAED,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,IAAI,CAAC,SAAS,EAC7B,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAqB5B;AAED,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,cAAc,CAAK;IAE3B,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAMjE;IAED,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAMnD;IAED,KAAK,IAAI,IAAI,CAGZ;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3B;IAED,IAAI,kBAAkB,IAAI,MAAM,CAE/B;IAED,OAAO,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAKnD;IAED,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAM/C;IAED,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAiBnD;IAED,QAAQ,IAAI,gBAAgB,CAQ3B;IAED,OAAO,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAIrC;CACD"}
@@ -0,0 +1,185 @@
1
+ const PASTE_MARKER_REGEX = /\[paste #(\d+)( (\+\d+ lines|\d+ chars))?\]/g;
2
+ const PASTE_MARKER_SINGLE = /^\[paste #(\d+)( (\+\d+ lines|\d+ chars))?\]$/;
3
+ function formatPasteMarker(id, lineCount, charCount) {
4
+ return lineCount > 10 ? `[paste #${id} +${lineCount} lines]` : `[paste #${id} ${charCount} chars]`;
5
+ }
6
+ function countLines(content) {
7
+ let lineCount = 1;
8
+ for (let index = 0; index < content.length; index++) {
9
+ if (content.charCodeAt(index) === 10)
10
+ lineCount++;
11
+ }
12
+ return lineCount;
13
+ }
14
+ function createEntry(id, content, marker) {
15
+ const charCount = content.length;
16
+ const parsed = marker?.match(PASTE_MARKER_SINGLE);
17
+ const lineMatch = parsed?.[3]?.match(/^\+(\d+) lines$/);
18
+ const lineCount = lineMatch ? Number.parseInt(lineMatch[1], 10) : countLines(content);
19
+ const canonical = formatPasteMarker(id, lineCount, charCount);
20
+ return { content, marker: marker === canonical ? marker : canonical, lineCount, charCount };
21
+ }
22
+ function countOccurrences(text, marker) {
23
+ let count = 0;
24
+ let offset = 0;
25
+ while (offset <= text.length - marker.length) {
26
+ const index = text.indexOf(marker, offset);
27
+ if (index === -1)
28
+ break;
29
+ count++;
30
+ offset = index + marker.length;
31
+ }
32
+ return count;
33
+ }
34
+ function replaceSingleOccurrence(text, marker, replacement) {
35
+ const index = text.indexOf(marker);
36
+ if (index === -1 || text.indexOf(marker, index + marker.length) !== -1)
37
+ return text;
38
+ return text.slice(0, index) + replacement + text.slice(index + marker.length);
39
+ }
40
+ function entriesFromState(state) {
41
+ const entries = new Map();
42
+ for (const [id, content] of state.pastes) {
43
+ entries.set(id, createEntry(id, content, state.markers?.get(id)));
44
+ }
45
+ return entries;
46
+ }
47
+ export function expandPasteMarkers(text, state) {
48
+ const entries = entriesFromState(state);
49
+ const byMarker = new Map();
50
+ for (const entry of entries.values())
51
+ byMarker.set(entry.marker, entry);
52
+ const matches = [];
53
+ const counts = new Map();
54
+ for (const match of text.matchAll(PASTE_MARKER_REGEX)) {
55
+ const marker = match[0];
56
+ if (!byMarker.has(marker))
57
+ continue;
58
+ matches.push({ start: match.index, end: match.index + marker.length, marker });
59
+ counts.set(marker, (counts.get(marker) ?? 0) + 1);
60
+ }
61
+ if (matches.length === 0)
62
+ return text;
63
+ const chunks = [];
64
+ let offset = 0;
65
+ for (const match of matches) {
66
+ chunks.push(text.slice(offset, match.start));
67
+ const entry = byMarker.get(match.marker);
68
+ chunks.push(counts.get(match.marker) === 1 ? entry.content : match.marker);
69
+ offset = match.end;
70
+ }
71
+ chunks.push(text.slice(offset));
72
+ return chunks.join("");
73
+ }
74
+ export function isPasteMarker(segment) {
75
+ return segment.length >= 10 && PASTE_MARKER_SINGLE.test(segment);
76
+ }
77
+ export function pasteMarkerId(segment) {
78
+ const match = segment.length >= 10 ? PASTE_MARKER_SINGLE.exec(segment) : null;
79
+ return match ? Number.parseInt(match[1], 10) : undefined;
80
+ }
81
+ export function segmentWithPasteMarkers(text, baseSegmenter, validMarkers) {
82
+ if (validMarkers.size === 0 || !text.includes("[paste #"))
83
+ return baseSegmenter.segment(text);
84
+ const markers = [];
85
+ for (const match of text.matchAll(PASTE_MARKER_REGEX)) {
86
+ if (validMarkers.has(match[0]))
87
+ markers.push({ start: match.index, end: match.index + match[0].length });
88
+ }
89
+ if (markers.length === 0)
90
+ return baseSegmenter.segment(text);
91
+ const result = [];
92
+ let markerIndex = 0;
93
+ let marker = markers[0];
94
+ for (const segment of baseSegmenter.segment(text)) {
95
+ while (marker && segment.index >= marker.end)
96
+ marker = markers[++markerIndex];
97
+ if (!marker || segment.index < marker.start) {
98
+ result.push(segment);
99
+ }
100
+ else if (segment.index === marker.start) {
101
+ result.push({ segment: text.slice(marker.start, marker.end), index: marker.start, input: text });
102
+ }
103
+ }
104
+ return result;
105
+ }
106
+ export class PasteMarkerRegistry {
107
+ constructor() {
108
+ this.entries = new Map();
109
+ this.pasteCounter = 0;
110
+ this.metadataBuilds = 0;
111
+ }
112
+ add(content, lineCount, charCount) {
113
+ const id = ++this.pasteCounter;
114
+ const marker = formatPasteMarker(id, lineCount, charCount);
115
+ this.entries.set(id, { content, marker, lineCount, charCount });
116
+ this.metadataBuilds++;
117
+ return marker;
118
+ }
119
+ authorizedMarkers(text) {
120
+ const markers = new Set();
121
+ for (const entry of this.entries.values()) {
122
+ if (countOccurrences(text, entry.marker) === 1)
123
+ markers.add(entry.marker);
124
+ }
125
+ return markers;
126
+ }
127
+ clear() {
128
+ this.entries.clear();
129
+ this.pasteCounter = 0;
130
+ }
131
+ expand(text) {
132
+ return expandPasteMarkers(text, this.snapshot());
133
+ }
134
+ get metadataBuildCount() {
135
+ return this.metadataBuilds;
136
+ }
137
+ install(state, text) {
138
+ this.entries = entriesFromState(state);
139
+ this.metadataBuilds += this.entries.size;
140
+ this.pasteCounter = Math.max(state.pasteCounter, ...this.entries.keys(), 0);
141
+ this.prune(text);
142
+ }
143
+ prune(text, previousText) {
144
+ for (const [id, entry] of this.entries) {
145
+ const wasAuthorized = previousText === undefined || countOccurrences(previousText, entry.marker) === 1;
146
+ if (!wasAuthorized || countOccurrences(text, entry.marker) !== 1)
147
+ this.entries.delete(id);
148
+ }
149
+ this.pasteCounter = Math.max(...this.entries.keys(), 0);
150
+ }
151
+ remove(id, text) {
152
+ const removedEntry = this.entries.get(id);
153
+ if (!removedEntry || !this.entries.delete(id))
154
+ return { text, removed: false };
155
+ let updatedText = replaceSingleOccurrence(text, removedEntry.marker, "");
156
+ const higherIds = [...this.entries.keys()].filter((entryId) => entryId > id).sort((a, b) => a - b);
157
+ for (const oldId of higherIds) {
158
+ const entry = this.entries.get(oldId);
159
+ this.entries.delete(oldId);
160
+ if (countOccurrences(updatedText, entry.marker) !== 1)
161
+ continue;
162
+ const newId = oldId - 1;
163
+ const renamed = formatPasteMarker(newId, entry.lineCount, entry.charCount);
164
+ updatedText = replaceSingleOccurrence(updatedText, entry.marker, renamed);
165
+ this.entries.set(newId, { ...entry, marker: renamed });
166
+ }
167
+ this.pasteCounter = Math.max(...this.entries.keys(), 0);
168
+ return { text: updatedText, removed: true };
169
+ }
170
+ snapshot() {
171
+ const pastes = new Map();
172
+ const markers = new Map();
173
+ for (const [id, entry] of this.entries) {
174
+ pastes.set(id, entry.content);
175
+ markers.set(id, entry.marker);
176
+ }
177
+ return { pastes, markers, pasteCounter: this.pasteCounter };
178
+ }
179
+ restore(state) {
180
+ this.entries = entriesFromState(state);
181
+ this.metadataBuilds += this.entries.size;
182
+ this.pasteCounter = Math.max(state.pasteCounter, ...this.entries.keys(), 0);
183
+ }
184
+ }
185
+ //# sourceMappingURL=paste-markers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paste-markers.js","sourceRoot":"","sources":["../src/paste-markers.ts"],"names":[],"mappings":"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","sourcesContent":["const PASTE_MARKER_REGEX = /\\[paste #(\\d+)( (\\+\\d+ lines|\\d+ chars))?\\]/g;\nconst PASTE_MARKER_SINGLE = /^\\[paste #(\\d+)( (\\+\\d+ lines|\\d+ chars))?\\]$/;\n\ninterface PasteMarkerEntry {\n\tcontent: string;\n\tmarker: string;\n\tlineCount: number;\n\tcharCount: number;\n}\n\nexport interface EditorPasteState {\n\tpastes: ReadonlyMap<number, string>;\n\tmarkers?: ReadonlyMap<number, string>;\n\tpasteCounter: number;\n}\n\nexport interface PasteMarkerRemoval {\n\ttext: string;\n\tremoved: boolean;\n}\n\nfunction formatPasteMarker(id: number, lineCount: number, charCount: number): string {\n\treturn lineCount > 10 ? `[paste #${id} +${lineCount} lines]` : `[paste #${id} ${charCount} chars]`;\n}\n\nfunction countLines(content: string): number {\n\tlet lineCount = 1;\n\tfor (let index = 0; index < content.length; index++) {\n\t\tif (content.charCodeAt(index) === 10) lineCount++;\n\t}\n\treturn lineCount;\n}\n\nfunction createEntry(id: number, content: string, marker?: string): PasteMarkerEntry {\n\tconst charCount = content.length;\n\tconst parsed = marker?.match(PASTE_MARKER_SINGLE);\n\tconst lineMatch = parsed?.[3]?.match(/^\\+(\\d+) lines$/);\n\tconst lineCount = lineMatch ? Number.parseInt(lineMatch[1]!, 10) : countLines(content);\n\tconst canonical = formatPasteMarker(id, lineCount, charCount);\n\treturn { content, marker: marker === canonical ? marker : canonical, lineCount, charCount };\n}\n\nfunction countOccurrences(text: string, marker: string): number {\n\tlet count = 0;\n\tlet offset = 0;\n\twhile (offset <= text.length - marker.length) {\n\t\tconst index = text.indexOf(marker, offset);\n\t\tif (index === -1) break;\n\t\tcount++;\n\t\toffset = index + marker.length;\n\t}\n\treturn count;\n}\n\nfunction replaceSingleOccurrence(text: string, marker: string, replacement: string): string {\n\tconst index = text.indexOf(marker);\n\tif (index === -1 || text.indexOf(marker, index + marker.length) !== -1) return text;\n\treturn text.slice(0, index) + replacement + text.slice(index + marker.length);\n}\n\nfunction entriesFromState(state: EditorPasteState): Map<number, PasteMarkerEntry> {\n\tconst entries = new Map<number, PasteMarkerEntry>();\n\tfor (const [id, content] of state.pastes) {\n\t\tentries.set(id, createEntry(id, content, state.markers?.get(id)));\n\t}\n\treturn entries;\n}\n\nexport function expandPasteMarkers(text: string, state: EditorPasteState): string {\n\tconst entries = entriesFromState(state);\n\tconst byMarker = new Map<string, PasteMarkerEntry>();\n\tfor (const entry of entries.values()) byMarker.set(entry.marker, entry);\n\n\tconst matches: Array<{ end: number; marker: string; start: number }> = [];\n\tconst counts = new Map<string, number>();\n\tfor (const match of text.matchAll(PASTE_MARKER_REGEX)) {\n\t\tconst marker = match[0];\n\t\tif (!byMarker.has(marker)) continue;\n\t\tmatches.push({ start: match.index, end: match.index + marker.length, marker });\n\t\tcounts.set(marker, (counts.get(marker) ?? 0) + 1);\n\t}\n\tif (matches.length === 0) return text;\n\n\tconst chunks: string[] = [];\n\tlet offset = 0;\n\tfor (const match of matches) {\n\t\tchunks.push(text.slice(offset, match.start));\n\t\tconst entry = byMarker.get(match.marker)!;\n\t\tchunks.push(counts.get(match.marker) === 1 ? entry.content : match.marker);\n\t\toffset = match.end;\n\t}\n\tchunks.push(text.slice(offset));\n\treturn chunks.join(\"\");\n}\n\nexport function isPasteMarker(segment: string): boolean {\n\treturn segment.length >= 10 && PASTE_MARKER_SINGLE.test(segment);\n}\n\nexport function pasteMarkerId(segment: string): number | undefined {\n\tconst match = segment.length >= 10 ? PASTE_MARKER_SINGLE.exec(segment) : null;\n\treturn match ? Number.parseInt(match[1]!, 10) : undefined;\n}\n\nexport function segmentWithPasteMarkers(\n\ttext: string,\n\tbaseSegmenter: Intl.Segmenter,\n\tvalidMarkers: ReadonlySet<string>,\n): Iterable<Intl.SegmentData> {\n\tif (validMarkers.size === 0 || !text.includes(\"[paste #\")) return baseSegmenter.segment(text);\n\n\tconst markers: Array<{ start: number; end: number }> = [];\n\tfor (const match of text.matchAll(PASTE_MARKER_REGEX)) {\n\t\tif (validMarkers.has(match[0])) markers.push({ start: match.index, end: match.index + match[0].length });\n\t}\n\tif (markers.length === 0) return baseSegmenter.segment(text);\n\n\tconst result: Intl.SegmentData[] = [];\n\tlet markerIndex = 0;\n\tlet marker = markers[0];\n\tfor (const segment of baseSegmenter.segment(text)) {\n\t\twhile (marker && segment.index >= marker.end) marker = markers[++markerIndex];\n\t\tif (!marker || segment.index < marker.start) {\n\t\t\tresult.push(segment);\n\t\t} else if (segment.index === marker.start) {\n\t\t\tresult.push({ segment: text.slice(marker.start, marker.end), index: marker.start, input: text });\n\t\t}\n\t}\n\treturn result;\n}\n\nexport class PasteMarkerRegistry {\n\tprivate entries = new Map<number, PasteMarkerEntry>();\n\tprivate pasteCounter = 0;\n\tprivate metadataBuilds = 0;\n\n\tadd(content: string, lineCount: number, charCount: number): string {\n\t\tconst id = ++this.pasteCounter;\n\t\tconst marker = formatPasteMarker(id, lineCount, charCount);\n\t\tthis.entries.set(id, { content, marker, lineCount, charCount });\n\t\tthis.metadataBuilds++;\n\t\treturn marker;\n\t}\n\n\tauthorizedMarkers(text: string): ReadonlySet<string> {\n\t\tconst markers = new Set<string>();\n\t\tfor (const entry of this.entries.values()) {\n\t\t\tif (countOccurrences(text, entry.marker) === 1) markers.add(entry.marker);\n\t\t}\n\t\treturn markers;\n\t}\n\n\tclear(): void {\n\t\tthis.entries.clear();\n\t\tthis.pasteCounter = 0;\n\t}\n\n\texpand(text: string): string {\n\t\treturn expandPasteMarkers(text, this.snapshot());\n\t}\n\n\tget metadataBuildCount(): number {\n\t\treturn this.metadataBuilds;\n\t}\n\n\tinstall(state: EditorPasteState, text: string): void {\n\t\tthis.entries = entriesFromState(state);\n\t\tthis.metadataBuilds += this.entries.size;\n\t\tthis.pasteCounter = Math.max(state.pasteCounter, ...this.entries.keys(), 0);\n\t\tthis.prune(text);\n\t}\n\n\tprune(text: string, previousText?: string): void {\n\t\tfor (const [id, entry] of this.entries) {\n\t\t\tconst wasAuthorized = previousText === undefined || countOccurrences(previousText, entry.marker) === 1;\n\t\t\tif (!wasAuthorized || countOccurrences(text, entry.marker) !== 1) this.entries.delete(id);\n\t\t}\n\t\tthis.pasteCounter = Math.max(...this.entries.keys(), 0);\n\t}\n\n\tremove(id: number, text: string): PasteMarkerRemoval {\n\t\tconst removedEntry = this.entries.get(id);\n\t\tif (!removedEntry || !this.entries.delete(id)) return { text, removed: false };\n\n\t\tlet updatedText = replaceSingleOccurrence(text, removedEntry.marker, \"\");\n\t\tconst higherIds = [...this.entries.keys()].filter((entryId) => entryId > id).sort((a, b) => a - b);\n\t\tfor (const oldId of higherIds) {\n\t\t\tconst entry = this.entries.get(oldId)!;\n\t\t\tthis.entries.delete(oldId);\n\t\t\tif (countOccurrences(updatedText, entry.marker) !== 1) continue;\n\t\t\tconst newId = oldId - 1;\n\t\t\tconst renamed = formatPasteMarker(newId, entry.lineCount, entry.charCount);\n\t\t\tupdatedText = replaceSingleOccurrence(updatedText, entry.marker, renamed);\n\t\t\tthis.entries.set(newId, { ...entry, marker: renamed });\n\t\t}\n\t\tthis.pasteCounter = Math.max(...this.entries.keys(), 0);\n\t\treturn { text: updatedText, removed: true };\n\t}\n\n\tsnapshot(): EditorPasteState {\n\t\tconst pastes = new Map<number, string>();\n\t\tconst markers = new Map<number, string>();\n\t\tfor (const [id, entry] of this.entries) {\n\t\t\tpastes.set(id, entry.content);\n\t\t\tmarkers.set(id, entry.marker);\n\t\t}\n\t\treturn { pastes, markers, pasteCounter: this.pasteCounter };\n\t}\n\n\trestore(state: EditorPasteState): void {\n\t\tthis.entries = entriesFromState(state);\n\t\tthis.metadataBuilds += this.entries.size;\n\t\tthis.pasteCounter = Math.max(state.pasteCounter, ...this.entries.keys(), 0);\n\t}\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import { type TmuxExecFile } from "./tmux-image-probe.ts";
2
+ export type ImageProtocol = "kitty" | "iterm2" | null;
3
+ export interface TerminalCapabilities {
4
+ images: ImageProtocol;
5
+ trueColor: boolean;
6
+ hyperlinks: boolean;
7
+ tmuxPassthrough?: boolean;
8
+ kittyUnicodePlaceholders?: boolean;
9
+ }
10
+ export interface DetectedTerminalCapabilities extends TerminalCapabilities {
11
+ cellDimensions?: {
12
+ widthPx: number;
13
+ heightPx: number;
14
+ };
15
+ }
16
+ export declare function outerKittyGraphicsMode(clientTermname: string): "placeholder" | null;
17
+ export declare function detectTerminalCapabilities(env?: NodeJS.ProcessEnv, _platform?: NodeJS.Platform, execTmux?: TmuxExecFile): DetectedTerminalCapabilities;
18
+ //# sourceMappingURL=terminal-capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-capabilities.d.ts","sourceRoot":"","sources":["../src/terminal-capabilities.ts"],"names":[],"mappings":"AAKA,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE/E,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;AAEtD,MAAM,WAAW,oBAAoB;IACpC,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,4BAA6B,SAAQ,oBAAoB;IACzE,cAAc,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CACvD;AAED,wBAAgB,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAGnF;AAED,wBAAgB,0BAA0B,CACzC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,SAAS,GAAE,MAAM,CAAC,QAA2B,EAC7C,QAAQ,CAAC,EAAE,YAAY,GACrB,4BAA4B,CAwD9B"}
@@ -0,0 +1,62 @@
1
+ import { decideTmuxImageCapability, parseTmuxKittyTerminalOverride, } from "./tmux-image-capability.js";
2
+ import { probeTmuxImageState } from "./tmux-image-probe.js";
3
+ export function outerKittyGraphicsMode(clientTermname) {
4
+ const term = clientTermname.trim().toLowerCase();
5
+ return term.includes("kitty") || term.includes("ghostty") || term.includes("warp") ? "placeholder" : null;
6
+ }
7
+ export function detectTerminalCapabilities(env = process.env, _platform = process.platform, execTmux) {
8
+ const term = env.TERM ?? "";
9
+ const termProgram = (env.TERM_PROGRAM ?? "").toLowerCase();
10
+ const terminalEmulator = env.TERMINAL_EMULATOR ?? "";
11
+ const colorTerm = env.COLORTERM ?? "";
12
+ const trueColor = colorTerm === "truecolor" || colorTerm === "24bit";
13
+ if (env.TMUX || term.startsWith("tmux")) {
14
+ const state = probeTmuxImageState(env, execTmux);
15
+ const override = parseTmuxKittyTerminalOverride(env.PI_TUI_TMUX_KITTY_TERMINAL);
16
+ const decision = decideTmuxImageCapability(state, override);
17
+ return {
18
+ images: decision.enabled ? "kitty" : null,
19
+ trueColor,
20
+ hyperlinks: state.hyperlinks,
21
+ ...(decision.enabled ? { tmuxPassthrough: true } : {}),
22
+ ...(decision.enabled && decision.placement === "placeholder" ? { kittyUnicodePlaceholders: true } : {}),
23
+ ...(state.cellDimensions ? { cellDimensions: state.cellDimensions } : {}),
24
+ };
25
+ }
26
+ if (env.KITTY_WINDOW_ID) {
27
+ return { images: "kitty", trueColor: true, hyperlinks: true };
28
+ }
29
+ if (termProgram === "ghostty") {
30
+ return { images: "kitty", trueColor: true, hyperlinks: true, kittyUnicodePlaceholders: true };
31
+ }
32
+ if (env.WARP_SESSION_ID || env.WARP_TERMINAL_SESSION_UUID || termProgram === "warpterminal") {
33
+ return { images: "kitty", trueColor: true, hyperlinks: true };
34
+ }
35
+ if (env.WEZTERM_PANE || termProgram === "wezterm") {
36
+ return { images: "kitty", trueColor: true, hyperlinks: true };
37
+ }
38
+ if (termProgram === "iterm.app" || env.ITERM_SESSION_ID) {
39
+ return { images: "iterm2", trueColor: true, hyperlinks: true };
40
+ }
41
+ if (termProgram === "apple_terminal") {
42
+ return { images: null, trueColor: false, hyperlinks: true };
43
+ }
44
+ if (env.WT_SESSION) {
45
+ return { images: null, trueColor: true, hyperlinks: true };
46
+ }
47
+ if (termProgram === "vscode") {
48
+ return { images: null, trueColor: true, hyperlinks: true };
49
+ }
50
+ if (env.CMUX_WORKSPACE_ID || terminalEmulator.includes("JetBrains")) {
51
+ return { images: null, trueColor: true, hyperlinks: false };
52
+ }
53
+ if (term.startsWith("screen")) {
54
+ return { images: null, trueColor, hyperlinks: false };
55
+ }
56
+ return {
57
+ images: term === "xterm-kitty" ? "kitty" : null,
58
+ trueColor,
59
+ hyperlinks: false,
60
+ };
61
+ }
62
+ //# sourceMappingURL=terminal-capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-capabilities.js","sourceRoot":"","sources":["../src/terminal-capabilities.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tdecideTmuxImageCapability,\n\tparseTmuxKittyTerminalOverride,\n\ttype TmuxKittyTerminalOverride,\n} from \"./tmux-image-capability.ts\";\nimport { probeTmuxImageState, type TmuxExecFile } from \"./tmux-image-probe.ts\";\n\nexport type ImageProtocol = \"kitty\" | \"iterm2\" | null;\n\nexport interface TerminalCapabilities {\n\timages: ImageProtocol;\n\ttrueColor: boolean;\n\thyperlinks: boolean;\n\ttmuxPassthrough?: boolean;\n\tkittyUnicodePlaceholders?: boolean;\n}\n\nexport interface DetectedTerminalCapabilities extends TerminalCapabilities {\n\tcellDimensions?: { widthPx: number; heightPx: number };\n}\n\nexport function outerKittyGraphicsMode(clientTermname: string): \"placeholder\" | null {\n\tconst term = clientTermname.trim().toLowerCase();\n\treturn term.includes(\"kitty\") || term.includes(\"ghostty\") || term.includes(\"warp\") ? \"placeholder\" : null;\n}\n\nexport function detectTerminalCapabilities(\n\tenv: NodeJS.ProcessEnv = process.env,\n\t_platform: NodeJS.Platform = process.platform,\n\texecTmux?: TmuxExecFile,\n): DetectedTerminalCapabilities {\n\tconst term = env.TERM ?? \"\";\n\tconst termProgram = (env.TERM_PROGRAM ?? \"\").toLowerCase();\n\tconst terminalEmulator = env.TERMINAL_EMULATOR ?? \"\";\n\tconst colorTerm = env.COLORTERM ?? \"\";\n\tconst trueColor = colorTerm === \"truecolor\" || colorTerm === \"24bit\";\n\n\tif (env.TMUX || term.startsWith(\"tmux\")) {\n\t\tconst state = probeTmuxImageState(env, execTmux);\n\t\tconst override: TmuxKittyTerminalOverride = parseTmuxKittyTerminalOverride(env.PI_TUI_TMUX_KITTY_TERMINAL);\n\t\tconst decision = decideTmuxImageCapability(state, override);\n\t\treturn {\n\t\t\timages: decision.enabled ? \"kitty\" : null,\n\t\t\ttrueColor,\n\t\t\thyperlinks: state.hyperlinks,\n\t\t\t...(decision.enabled ? { tmuxPassthrough: true } : {}),\n\t\t\t...(decision.enabled && decision.placement === \"placeholder\" ? { kittyUnicodePlaceholders: true } : {}),\n\t\t\t...(state.cellDimensions ? { cellDimensions: state.cellDimensions } : {}),\n\t\t};\n\t}\n\n\tif (env.KITTY_WINDOW_ID) {\n\t\treturn { images: \"kitty\", trueColor: true, hyperlinks: true };\n\t}\n\tif (termProgram === \"ghostty\") {\n\t\treturn { images: \"kitty\", trueColor: true, hyperlinks: true, kittyUnicodePlaceholders: true };\n\t}\n\tif (env.WARP_SESSION_ID || env.WARP_TERMINAL_SESSION_UUID || termProgram === \"warpterminal\") {\n\t\treturn { images: \"kitty\", trueColor: true, hyperlinks: true };\n\t}\n\tif (env.WEZTERM_PANE || termProgram === \"wezterm\") {\n\t\treturn { images: \"kitty\", trueColor: true, hyperlinks: true };\n\t}\n\tif (termProgram === \"iterm.app\" || env.ITERM_SESSION_ID) {\n\t\treturn { images: \"iterm2\", trueColor: true, hyperlinks: true };\n\t}\n\tif (termProgram === \"apple_terminal\") {\n\t\treturn { images: null, trueColor: false, hyperlinks: true };\n\t}\n\tif (env.WT_SESSION) {\n\t\treturn { images: null, trueColor: true, hyperlinks: true };\n\t}\n\tif (termProgram === \"vscode\") {\n\t\treturn { images: null, trueColor: true, hyperlinks: true };\n\t}\n\tif (env.CMUX_WORKSPACE_ID || terminalEmulator.includes(\"JetBrains\")) {\n\t\treturn { images: null, trueColor: true, hyperlinks: false };\n\t}\n\tif (term.startsWith(\"screen\")) {\n\t\treturn { images: null, trueColor, hyperlinks: false };\n\t}\n\treturn {\n\t\timages: term === \"xterm-kitty\" ? \"kitty\" : null,\n\t\ttrueColor,\n\t\thyperlinks: false,\n\t};\n}\n"]}