pi-ast-sgrep 2.0.0 → 2.0.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.
package/dist/present.d.ts CHANGED
@@ -45,6 +45,9 @@ export declare function formatSearchResult(response: EnvelopeLike, meta: {
45
45
  }, theme?: PresentTheme): string;
46
46
  export declare function formatStatusResult(response: EnvelopeLike, theme?: PresentTheme): string;
47
47
  export declare function formatIndexResult(command: string, response: EnvelopeLike, theme?: PresentTheme): string;
48
+ /** Local stand-in so we do not take a pi-tui dependency. Over-counts wide glyphs rather than under-count. */
49
+ export declare function visibleWidth(text: string): number;
50
+ export declare function truncateToWidth(text: string, maxWidth: number, ellipsis?: string): string;
48
51
  export declare function formatCodemodeResult(value: unknown, meta?: {
49
52
  stats?: {
50
53
  calls: number;
@@ -62,6 +65,6 @@ export declare class AsgrepText {
62
65
  constructor(text?: string);
63
66
  setText(text: string): void;
64
67
  invalidate(): void;
65
- render(_width: number): string[];
68
+ render(width: number): string[];
66
69
  }
67
70
  export declare function presentText(formatted: string, last: unknown): AsgrepText;
package/dist/present.js CHANGED
@@ -84,6 +84,97 @@ export function formatIndexResult(command, response, theme) {
84
84
  const tail = count === undefined ? "done" : `${count} file${count === 1 ? "" : "s"}`;
85
85
  return header(theme, command, [tail]);
86
86
  }
87
+ function ansiLengthAt(text, index) {
88
+ if (text.charCodeAt(index) !== 0x1b)
89
+ return 0;
90
+ const next = text[index + 1];
91
+ if (next === "[") {
92
+ let cursor = index + 2;
93
+ while (cursor < text.length) {
94
+ const code = text.charCodeAt(cursor);
95
+ if (code >= 0x40 && code <= 0x7e)
96
+ return cursor - index + 1;
97
+ cursor += 1;
98
+ }
99
+ return text.length - index;
100
+ }
101
+ if (next === "]") {
102
+ let cursor = index + 2;
103
+ while (cursor < text.length) {
104
+ if (text.charCodeAt(cursor) === 0x07)
105
+ return cursor - index + 1;
106
+ if (text.charCodeAt(cursor) === 0x1b && text[cursor + 1] === "\\")
107
+ return cursor - index + 2;
108
+ cursor += 1;
109
+ }
110
+ return text.length - index;
111
+ }
112
+ if (next === "P" || next === "X" || next === "^" || next === "_") {
113
+ let cursor = index + 2;
114
+ while (cursor < text.length) {
115
+ if (text.charCodeAt(cursor) === 0x1b && text[cursor + 1] === "\\")
116
+ return cursor - index + 2;
117
+ cursor += 1;
118
+ }
119
+ return text.length - index;
120
+ }
121
+ return Math.min(2, text.length - index);
122
+ }
123
+ function cellWidthAt(text, index) {
124
+ const code = text.charCodeAt(index);
125
+ if (code === 0x09)
126
+ return { width: 3, length: 1 };
127
+ if (code >= 0xd800 && code <= 0xdbff)
128
+ return { width: 2, length: 2 };
129
+ if (code <= 0x1f || (code >= 0x7f && code <= 0x9f))
130
+ return { width: 0, length: 1 };
131
+ if (code <= 0x7e)
132
+ return { width: 1, length: 1 };
133
+ return { width: 2, length: 1 };
134
+ }
135
+ /** Local stand-in so we do not take a pi-tui dependency. Over-counts wide glyphs rather than under-count. */
136
+ export function visibleWidth(text) {
137
+ let width = 0;
138
+ for (let index = 0; index < text.length;) {
139
+ const ansi = ansiLengthAt(text, index);
140
+ if (ansi > 0) {
141
+ index += ansi;
142
+ continue;
143
+ }
144
+ const cell = cellWidthAt(text, index);
145
+ width += cell.width;
146
+ index += cell.length;
147
+ }
148
+ return width;
149
+ }
150
+ export function truncateToWidth(text, maxWidth, ellipsis = "...") {
151
+ const limit = Math.max(0, maxWidth);
152
+ if (limit <= 0)
153
+ return "";
154
+ if (visibleWidth(text) <= limit)
155
+ return text;
156
+ const ellipsisWidth = visibleWidth(ellipsis);
157
+ if (ellipsisWidth >= limit)
158
+ return ellipsis.slice(0, limit);
159
+ const budget = limit - ellipsisWidth;
160
+ let kept = "";
161
+ let width = 0;
162
+ for (let index = 0; index < text.length;) {
163
+ const ansi = ansiLengthAt(text, index);
164
+ if (ansi > 0) {
165
+ kept += text.slice(index, index + ansi);
166
+ index += ansi;
167
+ continue;
168
+ }
169
+ const cell = cellWidthAt(text, index);
170
+ if (width + cell.width > budget)
171
+ break;
172
+ kept += text.slice(index, index + cell.length);
173
+ width += cell.width;
174
+ index += cell.length;
175
+ }
176
+ return `${kept}${ellipsis}`;
177
+ }
87
178
  function compactValue(value) {
88
179
  if (value === null || value === undefined)
89
180
  return String(value);
@@ -149,8 +240,11 @@ export class AsgrepText {
149
240
  this.#text = text;
150
241
  }
151
242
  invalidate() { }
152
- render(_width) {
153
- return this.#text.length === 0 ? [""] : this.#text.split("\n");
243
+ render(width) {
244
+ const maxWidth = Math.max(1, width);
245
+ if (this.#text.length === 0)
246
+ return [""];
247
+ return this.#text.split("\n").map((line) => truncateToWidth(line, maxWidth));
154
248
  }
155
249
  }
156
250
  export function presentText(formatted, last) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-ast-sgrep",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Native Code Mode, structural, graph, and semantic code search for Pi",
5
5
  "type": "module",
6
6
  "license": "MIT",