@kolisachint/hoocode-tui 0.5.66 → 0.5.67
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/components/editor.d.ts +4 -18
- package/dist/components/editor.d.ts.map +1 -1
- package/dist/components/editor.js +19 -54
- package/dist/components/editor.js.map +1 -1
- package/dist/components/frame.d.ts +117 -0
- package/dist/components/frame.d.ts.map +1 -0
- package/dist/components/frame.js +203 -0
- package/dist/components/frame.js.map +1 -0
- package/dist/components/select-list.d.ts.map +1 -1
- package/dist/components/select-list.js +8 -2
- package/dist/components/select-list.js.map +1 -1
- package/dist/components/settings-list.d.ts.map +1 -1
- package/dist/components/settings-list.js +7 -2
- package/dist/components/settings-list.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -3,7 +3,8 @@ import { decodePrintableKey, matchesKey } from "../keys.js";
|
|
|
3
3
|
import { KillRing } from "../kill-ring.js";
|
|
4
4
|
import { CURSOR_MARKER } from "../tui.js";
|
|
5
5
|
import { UndoStack } from "../undo-stack.js";
|
|
6
|
-
import { getSegmenter, isPunctuationChar, isWhitespaceChar,
|
|
6
|
+
import { getSegmenter, isPunctuationChar, isWhitespaceChar, visibleWidth } from "../utils.js";
|
|
7
|
+
import { DEFAULT_FRAME_BORDER_CHARS, renderFrameEdge, } from "./frame.js";
|
|
7
8
|
import { SelectList } from "./select-list.js";
|
|
8
9
|
const baseSegmenter = getSegmenter();
|
|
9
10
|
/** Regex matching paste markers like `[paste #1 +123 lines]` or `[paste #2 1234 chars]`. */
|
|
@@ -170,23 +171,7 @@ export function wordWrapLine(line, maxWidth, preSegmented) {
|
|
|
170
171
|
}
|
|
171
172
|
return chunks;
|
|
172
173
|
}
|
|
173
|
-
export const DEFAULT_EDITOR_BORDER_CHARS =
|
|
174
|
-
horizontal: "─",
|
|
175
|
-
vertical: "│",
|
|
176
|
-
topLeft: "┌",
|
|
177
|
-
topRight: "┐",
|
|
178
|
-
bottomLeft: "└",
|
|
179
|
-
bottomRight: "┘",
|
|
180
|
-
};
|
|
181
|
-
/** Border cells kept between the label and the top-right corner, so it reads as inset rather than jammed. */
|
|
182
|
-
const LABEL_RIGHT_INSET = 2;
|
|
183
|
-
/**
|
|
184
|
-
* Border cells required to the *left* of the label. Below this the label is
|
|
185
|
-
* dropped rather than drawn: a label butting straight up against the scroll
|
|
186
|
-
* indicator reads as one run-on string, and a border with no run of border in it
|
|
187
|
-
* has stopped looking like a border.
|
|
188
|
-
*/
|
|
189
|
-
const MIN_LABEL_LEAD_IN = 4;
|
|
174
|
+
export const DEFAULT_EDITOR_BORDER_CHARS = DEFAULT_FRAME_BORDER_CHARS;
|
|
190
175
|
const SLASH_COMMAND_SELECT_LIST_LAYOUT = {
|
|
191
176
|
minPrimaryColumnWidth: 12,
|
|
192
177
|
maxPrimaryColumnWidth: 32,
|
|
@@ -385,45 +370,23 @@ export class Editor {
|
|
|
385
370
|
* @param box - Whether to draw corners
|
|
386
371
|
*/
|
|
387
372
|
renderBorder(edge, hidden, barWidth, box) {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
// reader needs *now*, while the label says which session this is, which
|
|
398
|
-
// they can also read in the footer.
|
|
399
|
-
const label = edge === "top" ? this.topBorderLabel : undefined;
|
|
400
|
-
const leadIn = label ? barWidth - indicatorWidth - visibleWidth(label.plain) - LABEL_RIGHT_INSET : -1;
|
|
401
|
-
let bar;
|
|
402
|
-
if (label && leadIn >= MIN_LABEL_LEAD_IN) {
|
|
403
|
-
bar =
|
|
404
|
-
this.borderColor(indicator + chars.horizontal.repeat(leadIn)) +
|
|
405
|
-
label.styled +
|
|
406
|
-
this.borderColor(chars.horizontal.repeat(LABEL_RIGHT_INSET));
|
|
407
|
-
}
|
|
408
|
-
else if (indicatorWidth > 0) {
|
|
409
|
-
const remaining = barWidth - indicatorWidth;
|
|
410
|
-
bar = this.borderColor(remaining >= 0 ? indicator + chars.horizontal.repeat(remaining) : truncateToWidth(indicator, barWidth));
|
|
411
|
-
}
|
|
412
|
-
else {
|
|
413
|
-
bar = this.borderColor(chars.horizontal.repeat(barWidth));
|
|
414
|
-
}
|
|
415
|
-
if (!box)
|
|
416
|
-
return bar;
|
|
417
|
-
// Corners must stay aligned, so pad back any width lost to truncation.
|
|
418
|
-
bar += this.borderColor(chars.horizontal.repeat(Math.max(0, barWidth - visibleWidth(bar))));
|
|
419
|
-
const left = edge === "top" ? chars.topLeft : chars.bottomLeft;
|
|
420
|
-
const right = edge === "top" ? chars.topRight : chars.bottomRight;
|
|
421
|
-
return this.borderColor(left) + bar + this.borderColor(right);
|
|
373
|
+
return renderFrameEdge({
|
|
374
|
+
edge,
|
|
375
|
+
barWidth,
|
|
376
|
+
box,
|
|
377
|
+
chars: this.borderChars,
|
|
378
|
+
color: this.borderColor,
|
|
379
|
+
label: this.topBorderLabel,
|
|
380
|
+
hidden,
|
|
381
|
+
});
|
|
422
382
|
}
|
|
423
383
|
render(width) {
|
|
424
384
|
// Box mode needs 2 columns for the side borders plus at least 1 content
|
|
425
385
|
// column; below that it degrades to rule mode rather than overflowing.
|
|
426
386
|
const box = this.border === "box" && width >= 4;
|
|
387
|
+
// `none` is for an editor nested in a frame that already rules it: the
|
|
388
|
+
// rows are the same, the two horizontals are simply not drawn.
|
|
389
|
+
const bare = this.border === "none";
|
|
427
390
|
const borderWidth = box ? 1 : 0;
|
|
428
391
|
const innerWidth = Math.max(1, width - borderWidth * 2);
|
|
429
392
|
const maxPadding = Math.max(0, Math.floor((innerWidth - 1) / 2));
|
|
@@ -466,7 +429,8 @@ export class Editor {
|
|
|
466
429
|
const leftPadding = " ".repeat(paddingX);
|
|
467
430
|
const rightPadding = leftPadding;
|
|
468
431
|
// Render top border (with scroll indicator if scrolled down)
|
|
469
|
-
|
|
432
|
+
if (!bare)
|
|
433
|
+
result.push(this.renderBorder("top", this.scrollOffset, barWidth, box));
|
|
470
434
|
// Render each visible layout line
|
|
471
435
|
// Emit hardware cursor marker only when focused and not showing autocomplete
|
|
472
436
|
const emitCursorMarker = this.focused && !this.autocompleteState;
|
|
@@ -516,7 +480,8 @@ export class Editor {
|
|
|
516
480
|
}
|
|
517
481
|
// Render bottom border (with scroll indicator if more content below)
|
|
518
482
|
const linesBelow = layoutLines.length - (this.scrollOffset + visibleLines.length);
|
|
519
|
-
|
|
483
|
+
if (!bare)
|
|
484
|
+
result.push(this.renderBorder("bottom", linesBelow, barWidth, box));
|
|
520
485
|
// Add autocomplete list if active
|
|
521
486
|
if (this.autocompleteState && this.autocompleteList) {
|
|
522
487
|
const autocompleteResult = this.autocompleteList.render(contentWidth);
|