pi-ask-tool-extension 0.2.5 → 0.2.6
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/package.json +1 -1
- package/src/ask-inline-note.ts +14 -4
- package/src/ask-inline-ui.ts +2 -0
- package/src/ask-tabs-ui.ts +36 -3
package/package.json
CHANGED
package/src/ask-inline-note.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { wrapTextWithAnsi } from "@mariozechner/pi-tui";
|
|
1
|
+
import { CURSOR_MARKER, wrapTextWithAnsi } from "@mariozechner/pi-tui";
|
|
2
2
|
|
|
3
3
|
const INLINE_NOTE_SEPARATOR = " — note: ";
|
|
4
4
|
const INLINE_EDIT_CURSOR_INVERT_ON = "\u001b[7m";
|
|
@@ -17,14 +17,19 @@ function clampCursorIndex(index: number, rawTextLength: number): number {
|
|
|
17
17
|
return Math.floor(index);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
function buildEditingInlineNote(
|
|
20
|
+
function buildEditingInlineNote(
|
|
21
|
+
rawNote: string,
|
|
22
|
+
editingCursorIndex?: number,
|
|
23
|
+
includeHardwareCursorMarker = false,
|
|
24
|
+
): string {
|
|
21
25
|
const cursorIndex = clampCursorIndex(editingCursorIndex ?? rawNote.length, rawNote.length);
|
|
22
26
|
const beforeCursor = sanitizeNoteForInlineDisplay(rawNote.slice(0, cursorIndex));
|
|
23
27
|
const rawCharAtCursor = rawNote.slice(cursorIndex, cursorIndex + 1);
|
|
24
28
|
const charAtCursor = sanitizeNoteForInlineDisplay(rawCharAtCursor) || " ";
|
|
25
29
|
const afterCursorStartIndex = rawCharAtCursor.length > 0 ? cursorIndex + 1 : cursorIndex;
|
|
26
30
|
const afterCursor = sanitizeNoteForInlineDisplay(rawNote.slice(afterCursorStartIndex));
|
|
27
|
-
const
|
|
31
|
+
const cursorMarker = includeHardwareCursorMarker ? CURSOR_MARKER : "";
|
|
32
|
+
const cursorCell = `${cursorMarker}${INLINE_EDIT_CURSOR_INVERT_ON}${charAtCursor}${INLINE_EDIT_CURSOR_INVERT_OFF}`;
|
|
28
33
|
return `${beforeCursor}${cursorCell}${afterCursor}`;
|
|
29
34
|
}
|
|
30
35
|
|
|
@@ -48,6 +53,7 @@ export function buildOptionLabelWithInlineNote(
|
|
|
48
53
|
isEditingNote: boolean,
|
|
49
54
|
maxInlineLabelLength?: number,
|
|
50
55
|
editingCursorIndex?: number,
|
|
56
|
+
includeHardwareCursorMarker = false,
|
|
51
57
|
): string {
|
|
52
58
|
const sanitizedNote = sanitizeNoteForInlineDisplay(rawNote);
|
|
53
59
|
if (!isEditingNote && sanitizedNote.trim().length === 0) {
|
|
@@ -55,7 +61,9 @@ export function buildOptionLabelWithInlineNote(
|
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
const labelPrefix = `${baseOptionLabel}${INLINE_NOTE_SEPARATOR}`;
|
|
58
|
-
const inlineNote = isEditingNote
|
|
64
|
+
const inlineNote = isEditingNote
|
|
65
|
+
? buildEditingInlineNote(rawNote, editingCursorIndex, includeHardwareCursorMarker)
|
|
66
|
+
: sanitizedNote.trim();
|
|
59
67
|
const inlineLabel = `${labelPrefix}${inlineNote}`;
|
|
60
68
|
|
|
61
69
|
if (maxInlineLabelLength == null) {
|
|
@@ -74,6 +82,7 @@ export function buildWrappedOptionLabelWithInlineNote(
|
|
|
74
82
|
maxInlineLabelLength: number,
|
|
75
83
|
wrapPadding = INLINE_NOTE_WRAP_PADDING,
|
|
76
84
|
editingCursorIndex?: number,
|
|
85
|
+
includeHardwareCursorMarker = false,
|
|
77
86
|
): string[] {
|
|
78
87
|
const inlineLabel = buildOptionLabelWithInlineNote(
|
|
79
88
|
baseOptionLabel,
|
|
@@ -81,6 +90,7 @@ export function buildWrappedOptionLabelWithInlineNote(
|
|
|
81
90
|
isEditingNote,
|
|
82
91
|
undefined,
|
|
83
92
|
editingCursorIndex,
|
|
93
|
+
includeHardwareCursorMarker,
|
|
84
94
|
);
|
|
85
95
|
const sanitizedWrapPadding = Number.isFinite(wrapPadding) ? Math.max(0, Math.floor(wrapPadding)) : 0;
|
|
86
96
|
const sanitizedMaxInlineLabelLength = Number.isFinite(maxInlineLabelLength)
|
package/src/ask-inline-ui.ts
CHANGED
|
@@ -187,6 +187,7 @@ export async function askSingleQuestionWithInlineNote(
|
|
|
187
187
|
Math.max(1, width - prefixWidth),
|
|
188
188
|
INLINE_NOTE_WRAP_PADDING,
|
|
189
189
|
isEditingThisOption ? activeEditingCursorIndex : undefined,
|
|
190
|
+
isEditingThisOption,
|
|
190
191
|
);
|
|
191
192
|
const continuationPrefix = " ".repeat(prefixWidth);
|
|
192
193
|
addLine(`${cursorPrefix}${theme.fg(optionColor, `${markerText}${wrappedInlineLabelLines[0] ?? ""}`)}`);
|
|
@@ -288,6 +289,7 @@ export async function askSingleQuestionWithInlineNote(
|
|
|
288
289
|
};
|
|
289
290
|
|
|
290
291
|
return {
|
|
292
|
+
focused: true,
|
|
291
293
|
render,
|
|
292
294
|
invalidate: () => {
|
|
293
295
|
cachedRenderedLines = undefined;
|
package/src/ask-tabs-ui.ts
CHANGED
|
@@ -388,6 +388,7 @@ export async function askQuestionsWithTabs(
|
|
|
388
388
|
Math.max(1, width - prefixWidth),
|
|
389
389
|
INLINE_NOTE_WRAP_PADDING,
|
|
390
390
|
isEditingThisOption ? activeEditingCursorIndex : undefined,
|
|
391
|
+
isEditingThisOption,
|
|
391
392
|
);
|
|
392
393
|
const continuationPrefix = " ".repeat(prefixWidth);
|
|
393
394
|
addLine(`${cursorPrefix}${theme.fg(optionColor, `${markerText}${wrappedInlineLabelLines[0] ?? ""}`)}`);
|
|
@@ -404,12 +405,12 @@ export async function askQuestionsWithTabs(
|
|
|
404
405
|
addLine(
|
|
405
406
|
theme.fg(
|
|
406
407
|
"dim",
|
|
407
|
-
" ↑↓ move •
|
|
408
|
+
" ↑↓ move • Space toggle/select • Enter next • Tab add note • ←/→ switch tabs • Esc cancel",
|
|
408
409
|
),
|
|
409
410
|
);
|
|
410
411
|
} else {
|
|
411
412
|
addLine(
|
|
412
|
-
theme.fg("dim", " ↑↓ move • Enter select • Tab add note • ←/→ switch tabs • Esc cancel"),
|
|
413
|
+
theme.fg("dim", " ↑↓ move • Space/Enter select • Tab add note • ←/→ switch tabs • Esc cancel"),
|
|
413
414
|
);
|
|
414
415
|
}
|
|
415
416
|
}
|
|
@@ -533,7 +534,7 @@ export async function askQuestionsWithTabs(
|
|
|
533
534
|
return;
|
|
534
535
|
}
|
|
535
536
|
|
|
536
|
-
if (matchesKey(data, Key.
|
|
537
|
+
if (matchesKey(data, Key.space)) {
|
|
537
538
|
const cursorOptionIndex = cursorOptionIndexByQuestion[questionIndex];
|
|
538
539
|
|
|
539
540
|
if (preparedQuestion.multi) {
|
|
@@ -566,6 +567,37 @@ export async function askQuestionsWithTabs(
|
|
|
566
567
|
return;
|
|
567
568
|
}
|
|
568
569
|
|
|
570
|
+
requestUiRerender();
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
if (matchesKey(data, Key.enter)) {
|
|
575
|
+
const cursorOptionIndex = cursorOptionIndexByQuestion[questionIndex];
|
|
576
|
+
|
|
577
|
+
if (preparedQuestion.multi) {
|
|
578
|
+
if (
|
|
579
|
+
cursorOptionIndex === preparedQuestion.otherOptionIndex &&
|
|
580
|
+
selectedOptionIndexesByQuestion[questionIndex].includes(cursorOptionIndex) &&
|
|
581
|
+
getTrimmedQuestionNote(questionIndex, cursorOptionIndex).length === 0
|
|
582
|
+
) {
|
|
583
|
+
openNoteEditorForActiveOption();
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
advanceToNextTabOrSubmit();
|
|
588
|
+
requestUiRerender();
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
selectedOptionIndexesByQuestion[questionIndex] = [cursorOptionIndex];
|
|
593
|
+
if (
|
|
594
|
+
cursorOptionIndex === preparedQuestion.otherOptionIndex &&
|
|
595
|
+
getTrimmedQuestionNote(questionIndex, cursorOptionIndex).length === 0
|
|
596
|
+
) {
|
|
597
|
+
openNoteEditorForActiveOption();
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
|
|
569
601
|
advanceToNextTabOrSubmit();
|
|
570
602
|
requestUiRerender();
|
|
571
603
|
return;
|
|
@@ -585,6 +617,7 @@ export async function askQuestionsWithTabs(
|
|
|
585
617
|
};
|
|
586
618
|
|
|
587
619
|
return {
|
|
620
|
+
focused: true,
|
|
588
621
|
render,
|
|
589
622
|
invalidate: () => {
|
|
590
623
|
cachedRenderedLines = undefined;
|