@ashx-j/lunr-tui 0.1.7 → 0.2.1

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.
@@ -5,10 +5,14 @@ import type { Component } from "../tui.ts";
5
5
  export declare class Box implements Component {
6
6
  children: Component[];
7
7
  private paddingX;
8
- private paddingY;
8
+ private paddingTop;
9
+ private paddingBottom;
9
10
  private bgFn?;
10
11
  private cache?;
11
12
  constructor(paddingX?: number, paddingY?: number, bgFn?: (text: string) => string);
13
+ setPadding(paddingX: number, paddingY: number): void;
14
+ setPaddingTop(paddingTop: number): void;
15
+ setPaddingBottom(paddingBottom: number): void;
12
16
  addChild(component: Component): void;
13
17
  removeChild(component: Component): void;
14
18
  clear(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../src/components/box.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAU3C;;GAEG;AACH,qBAAa,GAAI,YAAW,SAAS;IACpC,QAAQ,EAAE,SAAS,EAAE,CAAM;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,IAAI,CAAC,CAA2B;IAGxC,OAAO,CAAC,KAAK,CAAC,CAAc;IAE5B,YAAY,QAAQ,SAAI,EAAE,QAAQ,SAAI,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAItE;IAED,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAGnC;IAED,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAMtC;IAED,KAAK,IAAI,IAAI,CAGZ;IAED,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAG7C;IAED,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,UAAU;IAWlB,UAAU,IAAI,IAAI,CAKjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAmD9B;IAED,OAAO,CAAC,OAAO;CAUf","sourcesContent":["import type { Component } from \"../tui.ts\";\nimport { applyBackgroundToLine, visibleWidth } from \"../utils.ts\";\n\ntype RenderCache = {\n\tchildLines: string[];\n\twidth: number;\n\tbgSample: string | undefined;\n\tlines: string[];\n};\n\n/**\n * Box component - a container that applies padding and background to all children\n */\nexport class Box implements Component {\n\tchildren: Component[] = [];\n\tprivate paddingX: number;\n\tprivate paddingY: number;\n\tprivate bgFn?: (text: string) => string;\n\n\t// Cache for rendered output\n\tprivate cache?: RenderCache;\n\n\tconstructor(paddingX = 1, paddingY = 1, bgFn?: (text: string) => string) {\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t\tthis.bgFn = bgFn;\n\t}\n\n\taddChild(component: Component): void {\n\t\tthis.children.push(component);\n\t\tthis.invalidateCache();\n\t}\n\n\tremoveChild(component: Component): void {\n\t\tconst index = this.children.indexOf(component);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t\tthis.invalidateCache();\n\t\t}\n\t}\n\n\tclear(): void {\n\t\tthis.children = [];\n\t\tthis.invalidateCache();\n\t}\n\n\tsetBgFn(bgFn?: (text: string) => string): void {\n\t\tthis.bgFn = bgFn;\n\t\t// Don't invalidate here - we'll detect bgFn changes by sampling output\n\t}\n\n\tprivate invalidateCache(): void {\n\t\tthis.cache = undefined;\n\t}\n\n\tprivate matchCache(width: number, childLines: string[], bgSample: string | undefined): boolean {\n\t\tconst cache = this.cache;\n\t\treturn (\n\t\t\t!!cache &&\n\t\t\tcache.width === width &&\n\t\t\tcache.bgSample === bgSample &&\n\t\t\tcache.childLines.length === childLines.length &&\n\t\t\tcache.childLines.every((line, i) => line === childLines[i])\n\t\t);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.invalidateCache();\n\t\tfor (const child of this.children) {\n\t\t\tchild.invalidate?.();\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.children.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\t\tconst leftPad = \" \".repeat(this.paddingX);\n\n\t\t// Render all children\n\t\tconst childLines: string[] = [];\n\t\tfor (const child of this.children) {\n\t\t\tconst lines = child.render(contentWidth);\n\t\t\tfor (const line of lines) {\n\t\t\t\tchildLines.push(leftPad + line);\n\t\t\t}\n\t\t}\n\n\t\tif (childLines.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Check if bgFn output changed by sampling\n\t\tconst bgSample = this.bgFn ? this.bgFn(\"test\") : undefined;\n\n\t\t// Check cache validity\n\t\tif (this.matchCache(width, childLines, bgSample)) {\n\t\t\treturn this.cache!.lines;\n\t\t}\n\n\t\t// Apply background and padding\n\t\tconst result: string[] = [];\n\n\t\t// Top padding\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Content\n\t\tfor (const line of childLines) {\n\t\t\tresult.push(this.applyBg(line, width));\n\t\t}\n\n\t\t// Bottom padding\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Update cache\n\t\tthis.cache = { childLines, width, bgSample, lines: result };\n\n\t\treturn result;\n\t}\n\n\tprivate applyBg(line: string, width: number): string {\n\t\tconst visLen = visibleWidth(line);\n\t\tconst padNeeded = Math.max(0, width - visLen);\n\t\tconst padded = line + \" \".repeat(padNeeded);\n\n\t\tif (this.bgFn) {\n\t\t\treturn applyBackgroundToLine(padded, width, this.bgFn);\n\t\t}\n\t\treturn padded;\n\t}\n}\n"]}
1
+ {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../src/components/box.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAU3C;;GAEG;AACH,qBAAa,GAAI,YAAW,SAAS;IACpC,QAAQ,EAAE,SAAS,EAAE,CAAM;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,IAAI,CAAC,CAA2B;IAGxC,OAAO,CAAC,KAAK,CAAC,CAAc;IAE5B,YAAY,QAAQ,SAAI,EAAE,QAAQ,SAAI,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAKtE;IAED,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAKnD;IAED,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAGtC;IAED,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAG5C;IAED,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAGnC;IAED,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAMtC;IAED,KAAK,IAAI,IAAI,CAGZ;IAED,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAG7C;IAED,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,UAAU;IAWlB,UAAU,IAAI,IAAI,CAKjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAmD9B;IAED,OAAO,CAAC,OAAO;CAUf","sourcesContent":["import type { Component } from \"../tui.ts\";\nimport { applyBackgroundToLine, visibleWidth } from \"../utils.ts\";\n\ntype RenderCache = {\n\tchildLines: string[];\n\twidth: number;\n\tbgSample: string | undefined;\n\tlines: string[];\n};\n\n/**\n * Box component - a container that applies padding and background to all children\n */\nexport class Box implements Component {\n\tchildren: Component[] = [];\n\tprivate paddingX: number;\n\tprivate paddingTop: number;\n\tprivate paddingBottom: number;\n\tprivate bgFn?: (text: string) => string;\n\n\t// Cache for rendered output\n\tprivate cache?: RenderCache;\n\n\tconstructor(paddingX = 1, paddingY = 1, bgFn?: (text: string) => string) {\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingTop = paddingY;\n\t\tthis.paddingBottom = paddingY;\n\t\tthis.bgFn = bgFn;\n\t}\n\n\tsetPadding(paddingX: number, paddingY: number): void {\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingTop = paddingY;\n\t\tthis.paddingBottom = paddingY;\n\t\tthis.invalidateCache();\n\t}\n\n\tsetPaddingTop(paddingTop: number): void {\n\t\tthis.paddingTop = paddingTop;\n\t\tthis.invalidateCache();\n\t}\n\n\tsetPaddingBottom(paddingBottom: number): void {\n\t\tthis.paddingBottom = paddingBottom;\n\t\tthis.invalidateCache();\n\t}\n\n\taddChild(component: Component): void {\n\t\tthis.children.push(component);\n\t\tthis.invalidateCache();\n\t}\n\n\tremoveChild(component: Component): void {\n\t\tconst index = this.children.indexOf(component);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t\tthis.invalidateCache();\n\t\t}\n\t}\n\n\tclear(): void {\n\t\tthis.children = [];\n\t\tthis.invalidateCache();\n\t}\n\n\tsetBgFn(bgFn?: (text: string) => string): void {\n\t\tthis.bgFn = bgFn;\n\t\t// Don't invalidate here - we'll detect bgFn changes by sampling output\n\t}\n\n\tprivate invalidateCache(): void {\n\t\tthis.cache = undefined;\n\t}\n\n\tprivate matchCache(width: number, childLines: string[], bgSample: string | undefined): boolean {\n\t\tconst cache = this.cache;\n\t\treturn (\n\t\t\t!!cache &&\n\t\t\tcache.width === width &&\n\t\t\tcache.bgSample === bgSample &&\n\t\t\tcache.childLines.length === childLines.length &&\n\t\t\tcache.childLines.every((line, i) => line === childLines[i])\n\t\t);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.invalidateCache();\n\t\tfor (const child of this.children) {\n\t\t\tchild.invalidate?.();\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.children.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\t\tconst leftPad = \" \".repeat(this.paddingX);\n\n\t\t// Render all children\n\t\tconst childLines: string[] = [];\n\t\tfor (const child of this.children) {\n\t\t\tconst lines = child.render(contentWidth);\n\t\t\tfor (const line of lines) {\n\t\t\t\tchildLines.push(leftPad + line);\n\t\t\t}\n\t\t}\n\n\t\tif (childLines.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Check if bgFn output changed by sampling\n\t\tconst bgSample = this.bgFn ? this.bgFn(\"test\") : undefined;\n\n\t\t// Check cache validity\n\t\tif (this.matchCache(width, childLines, bgSample)) {\n\t\t\treturn this.cache!.lines;\n\t\t}\n\n\t\t// Apply background and padding\n\t\tconst result: string[] = [];\n\n\t\t// Top padding\n\t\tfor (let i = 0; i < this.paddingTop; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Content\n\t\tfor (const line of childLines) {\n\t\t\tresult.push(this.applyBg(line, width));\n\t\t}\n\n\t\t// Bottom padding\n\t\tfor (let i = 0; i < this.paddingBottom; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Update cache\n\t\tthis.cache = { childLines, width, bgSample, lines: result };\n\n\t\treturn result;\n\t}\n\n\tprivate applyBg(line: string, width: number): string {\n\t\tconst visLen = visibleWidth(line);\n\t\tconst padNeeded = Math.max(0, width - visLen);\n\t\tconst padded = line + \" \".repeat(padNeeded);\n\n\t\tif (this.bgFn) {\n\t\t\treturn applyBackgroundToLine(padded, width, this.bgFn);\n\t\t}\n\t\treturn padded;\n\t}\n}\n"]}
@@ -5,15 +5,31 @@ import { applyBackgroundToLine, visibleWidth } from "../utils.js";
5
5
  export class Box {
6
6
  children = [];
7
7
  paddingX;
8
- paddingY;
8
+ paddingTop;
9
+ paddingBottom;
9
10
  bgFn;
10
11
  // Cache for rendered output
11
12
  cache;
12
13
  constructor(paddingX = 1, paddingY = 1, bgFn) {
13
14
  this.paddingX = paddingX;
14
- this.paddingY = paddingY;
15
+ this.paddingTop = paddingY;
16
+ this.paddingBottom = paddingY;
15
17
  this.bgFn = bgFn;
16
18
  }
19
+ setPadding(paddingX, paddingY) {
20
+ this.paddingX = paddingX;
21
+ this.paddingTop = paddingY;
22
+ this.paddingBottom = paddingY;
23
+ this.invalidateCache();
24
+ }
25
+ setPaddingTop(paddingTop) {
26
+ this.paddingTop = paddingTop;
27
+ this.invalidateCache();
28
+ }
29
+ setPaddingBottom(paddingBottom) {
30
+ this.paddingBottom = paddingBottom;
31
+ this.invalidateCache();
32
+ }
17
33
  addChild(component) {
18
34
  this.children.push(component);
19
35
  this.invalidateCache();
@@ -76,7 +92,7 @@ export class Box {
76
92
  // Apply background and padding
77
93
  const result = [];
78
94
  // Top padding
79
- for (let i = 0; i < this.paddingY; i++) {
95
+ for (let i = 0; i < this.paddingTop; i++) {
80
96
  result.push(this.applyBg("", width));
81
97
  }
82
98
  // Content
@@ -84,7 +100,7 @@ export class Box {
84
100
  result.push(this.applyBg(line, width));
85
101
  }
86
102
  // Bottom padding
87
- for (let i = 0; i < this.paddingY; i++) {
103
+ for (let i = 0; i < this.paddingBottom; i++) {
88
104
  result.push(this.applyBg("", width));
89
105
  }
90
106
  // Update cache
@@ -1 +1 @@
1
- {"version":3,"file":"box.js","sourceRoot":"","sources":["../../src/components/box.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component } from \"../tui.ts\";\nimport { applyBackgroundToLine, visibleWidth } from \"../utils.ts\";\n\ntype RenderCache = {\n\tchildLines: string[];\n\twidth: number;\n\tbgSample: string | undefined;\n\tlines: string[];\n};\n\n/**\n * Box component - a container that applies padding and background to all children\n */\nexport class Box implements Component {\n\tchildren: Component[] = [];\n\tprivate paddingX: number;\n\tprivate paddingY: number;\n\tprivate bgFn?: (text: string) => string;\n\n\t// Cache for rendered output\n\tprivate cache?: RenderCache;\n\n\tconstructor(paddingX = 1, paddingY = 1, bgFn?: (text: string) => string) {\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t\tthis.bgFn = bgFn;\n\t}\n\n\taddChild(component: Component): void {\n\t\tthis.children.push(component);\n\t\tthis.invalidateCache();\n\t}\n\n\tremoveChild(component: Component): void {\n\t\tconst index = this.children.indexOf(component);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t\tthis.invalidateCache();\n\t\t}\n\t}\n\n\tclear(): void {\n\t\tthis.children = [];\n\t\tthis.invalidateCache();\n\t}\n\n\tsetBgFn(bgFn?: (text: string) => string): void {\n\t\tthis.bgFn = bgFn;\n\t\t// Don't invalidate here - we'll detect bgFn changes by sampling output\n\t}\n\n\tprivate invalidateCache(): void {\n\t\tthis.cache = undefined;\n\t}\n\n\tprivate matchCache(width: number, childLines: string[], bgSample: string | undefined): boolean {\n\t\tconst cache = this.cache;\n\t\treturn (\n\t\t\t!!cache &&\n\t\t\tcache.width === width &&\n\t\t\tcache.bgSample === bgSample &&\n\t\t\tcache.childLines.length === childLines.length &&\n\t\t\tcache.childLines.every((line, i) => line === childLines[i])\n\t\t);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.invalidateCache();\n\t\tfor (const child of this.children) {\n\t\t\tchild.invalidate?.();\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.children.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\t\tconst leftPad = \" \".repeat(this.paddingX);\n\n\t\t// Render all children\n\t\tconst childLines: string[] = [];\n\t\tfor (const child of this.children) {\n\t\t\tconst lines = child.render(contentWidth);\n\t\t\tfor (const line of lines) {\n\t\t\t\tchildLines.push(leftPad + line);\n\t\t\t}\n\t\t}\n\n\t\tif (childLines.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Check if bgFn output changed by sampling\n\t\tconst bgSample = this.bgFn ? this.bgFn(\"test\") : undefined;\n\n\t\t// Check cache validity\n\t\tif (this.matchCache(width, childLines, bgSample)) {\n\t\t\treturn this.cache!.lines;\n\t\t}\n\n\t\t// Apply background and padding\n\t\tconst result: string[] = [];\n\n\t\t// Top padding\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Content\n\t\tfor (const line of childLines) {\n\t\t\tresult.push(this.applyBg(line, width));\n\t\t}\n\n\t\t// Bottom padding\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Update cache\n\t\tthis.cache = { childLines, width, bgSample, lines: result };\n\n\t\treturn result;\n\t}\n\n\tprivate applyBg(line: string, width: number): string {\n\t\tconst visLen = visibleWidth(line);\n\t\tconst padNeeded = Math.max(0, width - visLen);\n\t\tconst padded = line + \" \".repeat(padNeeded);\n\n\t\tif (this.bgFn) {\n\t\t\treturn applyBackgroundToLine(padded, width, this.bgFn);\n\t\t}\n\t\treturn padded;\n\t}\n}\n"]}
1
+ {"version":3,"file":"box.js","sourceRoot":"","sources":["../../src/components/box.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component } from \"../tui.ts\";\nimport { applyBackgroundToLine, visibleWidth } from \"../utils.ts\";\n\ntype RenderCache = {\n\tchildLines: string[];\n\twidth: number;\n\tbgSample: string | undefined;\n\tlines: string[];\n};\n\n/**\n * Box component - a container that applies padding and background to all children\n */\nexport class Box implements Component {\n\tchildren: Component[] = [];\n\tprivate paddingX: number;\n\tprivate paddingTop: number;\n\tprivate paddingBottom: number;\n\tprivate bgFn?: (text: string) => string;\n\n\t// Cache for rendered output\n\tprivate cache?: RenderCache;\n\n\tconstructor(paddingX = 1, paddingY = 1, bgFn?: (text: string) => string) {\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingTop = paddingY;\n\t\tthis.paddingBottom = paddingY;\n\t\tthis.bgFn = bgFn;\n\t}\n\n\tsetPadding(paddingX: number, paddingY: number): void {\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingTop = paddingY;\n\t\tthis.paddingBottom = paddingY;\n\t\tthis.invalidateCache();\n\t}\n\n\tsetPaddingTop(paddingTop: number): void {\n\t\tthis.paddingTop = paddingTop;\n\t\tthis.invalidateCache();\n\t}\n\n\tsetPaddingBottom(paddingBottom: number): void {\n\t\tthis.paddingBottom = paddingBottom;\n\t\tthis.invalidateCache();\n\t}\n\n\taddChild(component: Component): void {\n\t\tthis.children.push(component);\n\t\tthis.invalidateCache();\n\t}\n\n\tremoveChild(component: Component): void {\n\t\tconst index = this.children.indexOf(component);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t\tthis.invalidateCache();\n\t\t}\n\t}\n\n\tclear(): void {\n\t\tthis.children = [];\n\t\tthis.invalidateCache();\n\t}\n\n\tsetBgFn(bgFn?: (text: string) => string): void {\n\t\tthis.bgFn = bgFn;\n\t\t// Don't invalidate here - we'll detect bgFn changes by sampling output\n\t}\n\n\tprivate invalidateCache(): void {\n\t\tthis.cache = undefined;\n\t}\n\n\tprivate matchCache(width: number, childLines: string[], bgSample: string | undefined): boolean {\n\t\tconst cache = this.cache;\n\t\treturn (\n\t\t\t!!cache &&\n\t\t\tcache.width === width &&\n\t\t\tcache.bgSample === bgSample &&\n\t\t\tcache.childLines.length === childLines.length &&\n\t\t\tcache.childLines.every((line, i) => line === childLines[i])\n\t\t);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.invalidateCache();\n\t\tfor (const child of this.children) {\n\t\t\tchild.invalidate?.();\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tif (this.children.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\t\tconst leftPad = \" \".repeat(this.paddingX);\n\n\t\t// Render all children\n\t\tconst childLines: string[] = [];\n\t\tfor (const child of this.children) {\n\t\t\tconst lines = child.render(contentWidth);\n\t\t\tfor (const line of lines) {\n\t\t\t\tchildLines.push(leftPad + line);\n\t\t\t}\n\t\t}\n\n\t\tif (childLines.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Check if bgFn output changed by sampling\n\t\tconst bgSample = this.bgFn ? this.bgFn(\"test\") : undefined;\n\n\t\t// Check cache validity\n\t\tif (this.matchCache(width, childLines, bgSample)) {\n\t\t\treturn this.cache!.lines;\n\t\t}\n\n\t\t// Apply background and padding\n\t\tconst result: string[] = [];\n\n\t\t// Top padding\n\t\tfor (let i = 0; i < this.paddingTop; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Content\n\t\tfor (const line of childLines) {\n\t\t\tresult.push(this.applyBg(line, width));\n\t\t}\n\n\t\t// Bottom padding\n\t\tfor (let i = 0; i < this.paddingBottom; i++) {\n\t\t\tresult.push(this.applyBg(\"\", width));\n\t\t}\n\n\t\t// Update cache\n\t\tthis.cache = { childLines, width, bgSample, lines: result };\n\n\t\treturn result;\n\t}\n\n\tprivate applyBg(line: string, width: number): string {\n\t\tconst visLen = visibleWidth(line);\n\t\tconst padNeeded = Math.max(0, width - visLen);\n\t\tconst padded = line + \" \".repeat(padNeeded);\n\n\t\tif (this.bgFn) {\n\t\t\treturn applyBackgroundToLine(padded, width, this.bgFn);\n\t\t}\n\t\treturn padded;\n\t}\n}\n"]}
package/dist/mouse.d.ts CHANGED
@@ -6,8 +6,8 @@
6
6
  *
7
7
  * Wheel: bit 6 set. low bits 0=up, 1=down, 2=left, 3=right.
8
8
  */
9
- export declare const MOUSE_TRACKING_ENABLE = "\u001B[?1000h\u001B[?1006h";
10
- export declare const MOUSE_TRACKING_DISABLE = "\u001B[?1006l\u001B[?1000l";
9
+ export declare const MOUSE_TRACKING_ENABLE = "\u001B[?1000h\u001B[?1002h\u001B[?1006h";
10
+ export declare const MOUSE_TRACKING_DISABLE = "\u001B[?1006l\u001B[?1002l\u001B[?1000l";
11
11
  export type MouseKind = "wheel" | "button" | "move";
12
12
  export interface ParsedMouseEvent {
13
13
  kind: MouseKind;
@@ -1 +1 @@
1
- {"version":3,"file":"mouse.d.ts","sourceRoot":"","sources":["../src/mouse.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,qBAAqB,+BAA2B,CAAC;AAC9D,eAAO,MAAM,sBAAsB,+BAA2B,CAAC;AAE/D,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,SAAS,CAAC;IAChB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CACjB;AAWD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAqB1E","sourcesContent":["/**\n * Terminal mouse event parsing (SGR + X10).\n *\n * SGR: ESC[<button;x;yM (press) / m (release)\n * X10: ESC[M + 3 bytes (button+32, x+32, y+32)\n *\n * Wheel: bit 6 set. low bits 0=up, 1=down, 2=left, 3=right.\n */\n\nexport const MOUSE_TRACKING_ENABLE = \"\\x1b[?1000h\\x1b[?1006h\";\nexport const MOUSE_TRACKING_DISABLE = \"\\x1b[?1006l\\x1b[?1000l\";\n\nexport type MouseKind = \"wheel\" | \"button\" | \"move\";\n\nexport interface ParsedMouseEvent {\n\tkind: MouseKind;\n\t/** Raw low button id, or 64+low for wheel. */\n\tbutton: number;\n\t/** +1 wheel up (older chat), -1 wheel down (newer). 0 if not vertical wheel. */\n\tdelta: number;\n\tx: number;\n\ty: number;\n\tshift: boolean;\n\talt: boolean;\n\tctrl: boolean;\n\trelease: boolean;\n}\n\nconst BUTTON_SHIFT = 4;\nconst BUTTON_ALT = 8;\nconst BUTTON_CTRL = 16;\nconst BUTTON_MOTION = 32;\nconst BUTTON_WHEEL = 64;\nconst BUTTON_EXTRA = 128;\n\nconst SGR_MOUSE = /^\\x1b\\[<(\\d+);(\\d+);(\\d+)([Mm])$/;\n\nexport function parseMouseEvent(data: string): ParsedMouseEvent | undefined {\n\tif (!data.startsWith(\"\\x1b[\")) return undefined;\n\n\tconst sgr = data.match(SGR_MOUSE);\n\tif (sgr) {\n\t\tconst cb = Number.parseInt(sgr[1]!, 10);\n\t\tconst x = Number.parseInt(sgr[2]!, 10);\n\t\tconst y = Number.parseInt(sgr[3]!, 10);\n\t\tif (!Number.isFinite(cb) || !Number.isFinite(x) || !Number.isFinite(y)) return undefined;\n\t\treturn decodeMouse(cb, x, y, sgr[4] === \"m\");\n\t}\n\n\tif (data.startsWith(\"\\x1b[M\") && data.length >= 6) {\n\t\tconst cb = data.charCodeAt(3) - 32;\n\t\tconst x = data.charCodeAt(4) - 32;\n\t\tconst y = data.charCodeAt(5) - 32;\n\t\tif (cb < 0 || x < 1 || y < 1) return undefined;\n\t\treturn decodeMouse(cb, x, y, (cb & 3) === 3);\n\t}\n\n\treturn undefined;\n}\n\nfunction decodeMouse(cb: number, x: number, y: number, release: boolean): ParsedMouseEvent {\n\tconst shift = (cb & BUTTON_SHIFT) !== 0;\n\tconst alt = (cb & BUTTON_ALT) !== 0;\n\tconst ctrl = (cb & BUTTON_CTRL) !== 0;\n\tconst motion = (cb & BUTTON_MOTION) !== 0;\n\tconst wheel = (cb & BUTTON_WHEEL) !== 0;\n\tconst extra = (cb & BUTTON_EXTRA) !== 0;\n\tconst low = cb & 3;\n\n\tif (wheel) {\n\t\tlet delta = 0;\n\t\tif (low === 0) delta = 1;\n\t\telse if (low === 1) delta = -1;\n\t\treturn {\n\t\t\tkind: \"wheel\",\n\t\t\tbutton: BUTTON_WHEEL + low,\n\t\t\tdelta,\n\t\t\tx,\n\t\t\ty,\n\t\t\tshift,\n\t\t\talt,\n\t\t\tctrl,\n\t\t\trelease: false,\n\t\t};\n\t}\n\n\tif (motion) {\n\t\treturn {\n\t\t\tkind: \"move\",\n\t\t\tbutton: extra ? 8 + low : low,\n\t\t\tdelta: 0,\n\t\t\tx,\n\t\t\ty,\n\t\t\tshift,\n\t\t\talt,\n\t\t\tctrl,\n\t\t\trelease: false,\n\t\t};\n\t}\n\n\treturn {\n\t\tkind: \"button\",\n\t\tbutton: extra ? 8 + low : low,\n\t\tdelta: 0,\n\t\tx,\n\t\ty,\n\t\tshift,\n\t\talt,\n\t\tctrl,\n\t\trelease,\n\t};\n}\n"]}
1
+ {"version":3,"file":"mouse.d.ts","sourceRoot":"","sources":["../src/mouse.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,qBAAqB,4CAAsC,CAAC;AACzE,eAAO,MAAM,sBAAsB,4CAAsC,CAAC;AAE1E,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,SAAS,CAAC;IAChB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CACjB;AAWD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAqB1E","sourcesContent":["/**\n * Terminal mouse event parsing (SGR + X10).\n *\n * SGR: ESC[<button;x;yM (press) / m (release)\n * X10: ESC[M + 3 bytes (button+32, x+32, y+32)\n *\n * Wheel: bit 6 set. low bits 0=up, 1=down, 2=left, 3=right.\n */\n\nexport const MOUSE_TRACKING_ENABLE = \"\\x1b[?1000h\\x1b[?1002h\\x1b[?1006h\";\nexport const MOUSE_TRACKING_DISABLE = \"\\x1b[?1006l\\x1b[?1002l\\x1b[?1000l\";\n\nexport type MouseKind = \"wheel\" | \"button\" | \"move\";\n\nexport interface ParsedMouseEvent {\n\tkind: MouseKind;\n\t/** Raw low button id, or 64+low for wheel. */\n\tbutton: number;\n\t/** +1 wheel up (older chat), -1 wheel down (newer). 0 if not vertical wheel. */\n\tdelta: number;\n\tx: number;\n\ty: number;\n\tshift: boolean;\n\talt: boolean;\n\tctrl: boolean;\n\trelease: boolean;\n}\n\nconst BUTTON_SHIFT = 4;\nconst BUTTON_ALT = 8;\nconst BUTTON_CTRL = 16;\nconst BUTTON_MOTION = 32;\nconst BUTTON_WHEEL = 64;\nconst BUTTON_EXTRA = 128;\n\nconst SGR_MOUSE = /^\\x1b\\[<(\\d+);(\\d+);(\\d+)([Mm])$/;\n\nexport function parseMouseEvent(data: string): ParsedMouseEvent | undefined {\n\tif (!data.startsWith(\"\\x1b[\")) return undefined;\n\n\tconst sgr = data.match(SGR_MOUSE);\n\tif (sgr) {\n\t\tconst cb = Number.parseInt(sgr[1]!, 10);\n\t\tconst x = Number.parseInt(sgr[2]!, 10);\n\t\tconst y = Number.parseInt(sgr[3]!, 10);\n\t\tif (!Number.isFinite(cb) || !Number.isFinite(x) || !Number.isFinite(y)) return undefined;\n\t\treturn decodeMouse(cb, x, y, sgr[4] === \"m\");\n\t}\n\n\tif (data.startsWith(\"\\x1b[M\") && data.length >= 6) {\n\t\tconst cb = data.charCodeAt(3) - 32;\n\t\tconst x = data.charCodeAt(4) - 32;\n\t\tconst y = data.charCodeAt(5) - 32;\n\t\tif (cb < 0 || x < 1 || y < 1) return undefined;\n\t\treturn decodeMouse(cb, x, y, (cb & 3) === 3);\n\t}\n\n\treturn undefined;\n}\n\nfunction decodeMouse(cb: number, x: number, y: number, release: boolean): ParsedMouseEvent {\n\tconst shift = (cb & BUTTON_SHIFT) !== 0;\n\tconst alt = (cb & BUTTON_ALT) !== 0;\n\tconst ctrl = (cb & BUTTON_CTRL) !== 0;\n\tconst motion = (cb & BUTTON_MOTION) !== 0;\n\tconst wheel = (cb & BUTTON_WHEEL) !== 0;\n\tconst extra = (cb & BUTTON_EXTRA) !== 0;\n\tconst low = cb & 3;\n\n\tif (wheel) {\n\t\tlet delta = 0;\n\t\tif (low === 0) delta = 1;\n\t\telse if (low === 1) delta = -1;\n\t\treturn {\n\t\t\tkind: \"wheel\",\n\t\t\tbutton: BUTTON_WHEEL + low,\n\t\t\tdelta,\n\t\t\tx,\n\t\t\ty,\n\t\t\tshift,\n\t\t\talt,\n\t\t\tctrl,\n\t\t\trelease: false,\n\t\t};\n\t}\n\n\tif (motion) {\n\t\treturn {\n\t\t\tkind: \"move\",\n\t\t\tbutton: extra ? 8 + low : low,\n\t\t\tdelta: 0,\n\t\t\tx,\n\t\t\ty,\n\t\t\tshift,\n\t\t\talt,\n\t\t\tctrl,\n\t\t\trelease: false,\n\t\t};\n\t}\n\n\treturn {\n\t\tkind: \"button\",\n\t\tbutton: extra ? 8 + low : low,\n\t\tdelta: 0,\n\t\tx,\n\t\ty,\n\t\tshift,\n\t\talt,\n\t\tctrl,\n\t\trelease,\n\t};\n}\n"]}
package/dist/mouse.js CHANGED
@@ -6,8 +6,8 @@
6
6
  *
7
7
  * Wheel: bit 6 set. low bits 0=up, 1=down, 2=left, 3=right.
8
8
  */
9
- export const MOUSE_TRACKING_ENABLE = "\x1b[?1000h\x1b[?1006h";
10
- export const MOUSE_TRACKING_DISABLE = "\x1b[?1006l\x1b[?1000l";
9
+ export const MOUSE_TRACKING_ENABLE = "\x1b[?1000h\x1b[?1002h\x1b[?1006h";
10
+ export const MOUSE_TRACKING_DISABLE = "\x1b[?1006l\x1b[?1002l\x1b[?1000l";
11
11
  const BUTTON_SHIFT = 4;
12
12
  const BUTTON_ALT = 8;
13
13
  const BUTTON_CTRL = 16;
package/dist/mouse.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mouse.js","sourceRoot":"","sources":["../src/mouse.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Terminal mouse event parsing (SGR + X10).\n *\n * SGR: ESC[<button;x;yM (press) / m (release)\n * X10: ESC[M + 3 bytes (button+32, x+32, y+32)\n *\n * Wheel: bit 6 set. low bits 0=up, 1=down, 2=left, 3=right.\n */\n\nexport const MOUSE_TRACKING_ENABLE = \"\\x1b[?1000h\\x1b[?1006h\";\nexport const MOUSE_TRACKING_DISABLE = \"\\x1b[?1006l\\x1b[?1000l\";\n\nexport type MouseKind = \"wheel\" | \"button\" | \"move\";\n\nexport interface ParsedMouseEvent {\n\tkind: MouseKind;\n\t/** Raw low button id, or 64+low for wheel. */\n\tbutton: number;\n\t/** +1 wheel up (older chat), -1 wheel down (newer). 0 if not vertical wheel. */\n\tdelta: number;\n\tx: number;\n\ty: number;\n\tshift: boolean;\n\talt: boolean;\n\tctrl: boolean;\n\trelease: boolean;\n}\n\nconst BUTTON_SHIFT = 4;\nconst BUTTON_ALT = 8;\nconst BUTTON_CTRL = 16;\nconst BUTTON_MOTION = 32;\nconst BUTTON_WHEEL = 64;\nconst BUTTON_EXTRA = 128;\n\nconst SGR_MOUSE = /^\\x1b\\[<(\\d+);(\\d+);(\\d+)([Mm])$/;\n\nexport function parseMouseEvent(data: string): ParsedMouseEvent | undefined {\n\tif (!data.startsWith(\"\\x1b[\")) return undefined;\n\n\tconst sgr = data.match(SGR_MOUSE);\n\tif (sgr) {\n\t\tconst cb = Number.parseInt(sgr[1]!, 10);\n\t\tconst x = Number.parseInt(sgr[2]!, 10);\n\t\tconst y = Number.parseInt(sgr[3]!, 10);\n\t\tif (!Number.isFinite(cb) || !Number.isFinite(x) || !Number.isFinite(y)) return undefined;\n\t\treturn decodeMouse(cb, x, y, sgr[4] === \"m\");\n\t}\n\n\tif (data.startsWith(\"\\x1b[M\") && data.length >= 6) {\n\t\tconst cb = data.charCodeAt(3) - 32;\n\t\tconst x = data.charCodeAt(4) - 32;\n\t\tconst y = data.charCodeAt(5) - 32;\n\t\tif (cb < 0 || x < 1 || y < 1) return undefined;\n\t\treturn decodeMouse(cb, x, y, (cb & 3) === 3);\n\t}\n\n\treturn undefined;\n}\n\nfunction decodeMouse(cb: number, x: number, y: number, release: boolean): ParsedMouseEvent {\n\tconst shift = (cb & BUTTON_SHIFT) !== 0;\n\tconst alt = (cb & BUTTON_ALT) !== 0;\n\tconst ctrl = (cb & BUTTON_CTRL) !== 0;\n\tconst motion = (cb & BUTTON_MOTION) !== 0;\n\tconst wheel = (cb & BUTTON_WHEEL) !== 0;\n\tconst extra = (cb & BUTTON_EXTRA) !== 0;\n\tconst low = cb & 3;\n\n\tif (wheel) {\n\t\tlet delta = 0;\n\t\tif (low === 0) delta = 1;\n\t\telse if (low === 1) delta = -1;\n\t\treturn {\n\t\t\tkind: \"wheel\",\n\t\t\tbutton: BUTTON_WHEEL + low,\n\t\t\tdelta,\n\t\t\tx,\n\t\t\ty,\n\t\t\tshift,\n\t\t\talt,\n\t\t\tctrl,\n\t\t\trelease: false,\n\t\t};\n\t}\n\n\tif (motion) {\n\t\treturn {\n\t\t\tkind: \"move\",\n\t\t\tbutton: extra ? 8 + low : low,\n\t\t\tdelta: 0,\n\t\t\tx,\n\t\t\ty,\n\t\t\tshift,\n\t\t\talt,\n\t\t\tctrl,\n\t\t\trelease: false,\n\t\t};\n\t}\n\n\treturn {\n\t\tkind: \"button\",\n\t\tbutton: extra ? 8 + low : low,\n\t\tdelta: 0,\n\t\tx,\n\t\ty,\n\t\tshift,\n\t\talt,\n\t\tctrl,\n\t\trelease,\n\t};\n}\n"]}
1
+ {"version":3,"file":"mouse.js","sourceRoot":"","sources":["../src/mouse.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,mCAAmC,CAAC;AACzE,MAAM,CAAC,MAAM,sBAAsB,GAAG,mCAAmC,CAAC;AAkB1E,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,UAAU,GAAG,CAAC,CAAC;AACrB,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,aAAa,GAAG,EAAE,CAAC;AACzB,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,MAAM,YAAY,GAAG,GAAG,CAAC;AAEzB,MAAM,SAAS,GAAG,kCAAkC,CAAC;AAErD,MAAM,UAAU,eAAe,CAAC,IAAY,EAAgC;IAC3E,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IAEhD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAClC,IAAI,GAAG,EAAE,CAAC;QACT,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC;QACvC,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,SAAS,CAAC;QACzF,OAAO,WAAW,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACnD,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QAClC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAC/C,OAAO,WAAW,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,SAAS,WAAW,CAAC,EAAU,EAAE,CAAS,EAAE,CAAS,EAAE,OAAgB,EAAoB;IAC1F,MAAM,KAAK,GAAG,CAAC,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,CAAC,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,CAAC,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,CAAC,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,CAAC,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,CAAC,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC;IAEnB,IAAI,KAAK,EAAE,CAAC;QACX,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,GAAG,KAAK,CAAC;YAAE,KAAK,GAAG,CAAC,CAAC;aACpB,IAAI,GAAG,KAAK,CAAC;YAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QAC/B,OAAO;YACN,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,YAAY,GAAG,GAAG;YAC1B,KAAK;YACL,CAAC;YACD,CAAC;YACD,KAAK;YACL,GAAG;YACH,IAAI;YACJ,OAAO,EAAE,KAAK;SACd,CAAC;IACH,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACZ,OAAO;YACN,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG;YAC7B,KAAK,EAAE,CAAC;YACR,CAAC;YACD,CAAC;YACD,KAAK;YACL,GAAG;YACH,IAAI;YACJ,OAAO,EAAE,KAAK;SACd,CAAC;IACH,CAAC;IAED,OAAO;QACN,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG;QAC7B,KAAK,EAAE,CAAC;QACR,CAAC;QACD,CAAC;QACD,KAAK;QACL,GAAG;QACH,IAAI;QACJ,OAAO;KACP,CAAC;AAAA,CACF","sourcesContent":["/**\n * Terminal mouse event parsing (SGR + X10).\n *\n * SGR: ESC[<button;x;yM (press) / m (release)\n * X10: ESC[M + 3 bytes (button+32, x+32, y+32)\n *\n * Wheel: bit 6 set. low bits 0=up, 1=down, 2=left, 3=right.\n */\n\nexport const MOUSE_TRACKING_ENABLE = \"\\x1b[?1000h\\x1b[?1002h\\x1b[?1006h\";\nexport const MOUSE_TRACKING_DISABLE = \"\\x1b[?1006l\\x1b[?1002l\\x1b[?1000l\";\n\nexport type MouseKind = \"wheel\" | \"button\" | \"move\";\n\nexport interface ParsedMouseEvent {\n\tkind: MouseKind;\n\t/** Raw low button id, or 64+low for wheel. */\n\tbutton: number;\n\t/** +1 wheel up (older chat), -1 wheel down (newer). 0 if not vertical wheel. */\n\tdelta: number;\n\tx: number;\n\ty: number;\n\tshift: boolean;\n\talt: boolean;\n\tctrl: boolean;\n\trelease: boolean;\n}\n\nconst BUTTON_SHIFT = 4;\nconst BUTTON_ALT = 8;\nconst BUTTON_CTRL = 16;\nconst BUTTON_MOTION = 32;\nconst BUTTON_WHEEL = 64;\nconst BUTTON_EXTRA = 128;\n\nconst SGR_MOUSE = /^\\x1b\\[<(\\d+);(\\d+);(\\d+)([Mm])$/;\n\nexport function parseMouseEvent(data: string): ParsedMouseEvent | undefined {\n\tif (!data.startsWith(\"\\x1b[\")) return undefined;\n\n\tconst sgr = data.match(SGR_MOUSE);\n\tif (sgr) {\n\t\tconst cb = Number.parseInt(sgr[1]!, 10);\n\t\tconst x = Number.parseInt(sgr[2]!, 10);\n\t\tconst y = Number.parseInt(sgr[3]!, 10);\n\t\tif (!Number.isFinite(cb) || !Number.isFinite(x) || !Number.isFinite(y)) return undefined;\n\t\treturn decodeMouse(cb, x, y, sgr[4] === \"m\");\n\t}\n\n\tif (data.startsWith(\"\\x1b[M\") && data.length >= 6) {\n\t\tconst cb = data.charCodeAt(3) - 32;\n\t\tconst x = data.charCodeAt(4) - 32;\n\t\tconst y = data.charCodeAt(5) - 32;\n\t\tif (cb < 0 || x < 1 || y < 1) return undefined;\n\t\treturn decodeMouse(cb, x, y, (cb & 3) === 3);\n\t}\n\n\treturn undefined;\n}\n\nfunction decodeMouse(cb: number, x: number, y: number, release: boolean): ParsedMouseEvent {\n\tconst shift = (cb & BUTTON_SHIFT) !== 0;\n\tconst alt = (cb & BUTTON_ALT) !== 0;\n\tconst ctrl = (cb & BUTTON_CTRL) !== 0;\n\tconst motion = (cb & BUTTON_MOTION) !== 0;\n\tconst wheel = (cb & BUTTON_WHEEL) !== 0;\n\tconst extra = (cb & BUTTON_EXTRA) !== 0;\n\tconst low = cb & 3;\n\n\tif (wheel) {\n\t\tlet delta = 0;\n\t\tif (low === 0) delta = 1;\n\t\telse if (low === 1) delta = -1;\n\t\treturn {\n\t\t\tkind: \"wheel\",\n\t\t\tbutton: BUTTON_WHEEL + low,\n\t\t\tdelta,\n\t\t\tx,\n\t\t\ty,\n\t\t\tshift,\n\t\t\talt,\n\t\t\tctrl,\n\t\t\trelease: false,\n\t\t};\n\t}\n\n\tif (motion) {\n\t\treturn {\n\t\t\tkind: \"move\",\n\t\t\tbutton: extra ? 8 + low : low,\n\t\t\tdelta: 0,\n\t\t\tx,\n\t\t\ty,\n\t\t\tshift,\n\t\t\talt,\n\t\t\tctrl,\n\t\t\trelease: false,\n\t\t};\n\t}\n\n\treturn {\n\t\tkind: \"button\",\n\t\tbutton: extra ? 8 + low : low,\n\t\tdelta: 0,\n\t\tx,\n\t\ty,\n\t\tshift,\n\t\talt,\n\t\tctrl,\n\t\trelease,\n\t};\n}\n"]}
package/dist/tui.d.ts CHANGED
@@ -23,6 +23,11 @@ export interface Component {
23
23
  * Default is false - release events are filtered out.
24
24
  */
25
25
  wantsKeyRelease?: boolean;
26
+ /**
27
+ * When true, pinned chat can start an in-app text selection on this
28
+ * component without holding Shift. Default false.
29
+ */
30
+ selectable?: boolean;
26
31
  /**
27
32
  * Invalidate any cached rendering state.
28
33
  * Called when theme changes or when component needs to re-render from scratch.
@@ -147,6 +152,8 @@ export declare class TUI extends Container {
147
152
  private inputListeners;
148
153
  /** Global callback for debug key (Shift+Ctrl+D). Called before input is forwarded to focused component. */
149
154
  onDebug?: () => void;
155
+ /** Called with selected user/assistant text after an in-app drag-release. */
156
+ onTextSelected?: (text: string) => void;
150
157
  private renderRequested;
151
158
  private renderTimer;
152
159
  private lastRenderAt;
@@ -171,10 +178,18 @@ export declare class TUI extends Container {
171
178
  private chatScrollOffset;
172
179
  private lastChatViewportHeight;
173
180
  private lastChatScrollMax;
181
+ private chatLaidOut;
182
+ private chatUsesGutter;
183
+ /** Bumped on non-scroll `requestRender` so offset-only paints can reuse chat layout. */
184
+ private contentEpoch;
185
+ private chatLayoutCache;
174
186
  private alternateScreen;
175
187
  private alternateScreenActive;
176
188
  private mouseTrackingActive;
177
189
  private static readonly WHEEL_LINES;
190
+ private chatHitRegions;
191
+ private chatScrollbar;
192
+ private selection;
178
193
  constructor(terminal: Terminal, showHardwareCursor?: boolean);
179
194
  get fullRedraws(): number;
180
195
  getShowHardwareCursor(): boolean;
@@ -217,8 +232,11 @@ export declare class TUI extends Container {
217
232
  private containsComponent;
218
233
  private getPinIndex;
219
234
  private collectChildLines;
235
+ private appendRenderedChild;
220
236
  private snapStartToKittyImageHeader;
221
237
  render(width: number): string[];
238
+ private copyHitRegions;
239
+ private shiftHitRegions;
222
240
  /**
223
241
  * Show an overlay component with configurable positioning and sizing.
224
242
  * Returns a handle to control the overlay's visibility.
@@ -241,11 +259,15 @@ export declare class TUI extends Container {
241
259
  private queryCellSize;
242
260
  stop(): void;
243
261
  requestRender(force?: boolean): void;
262
+ private requestRenderFromScroll;
263
+ private queueRender;
244
264
  private scheduleRender;
245
265
  private syncMouseTracking;
246
266
  private enableMouseTracking;
247
267
  private disableMouseTracking;
248
268
  private handleMouseEvent;
269
+ private hitSelectable;
270
+ private selectedText;
249
271
  private handleInput;
250
272
  private consumeOsc11BackgroundResponse;
251
273
  private consumeTerminalColorSchemeReport;