ktx/packages/cli/src/prompt-navigation.ts
2026-05-10 23:12:26 +02:00

45 lines
1.5 KiB
TypeScript

const MULTISELECT_MENU_NAVIGATION_HINT =
'Use Up/Down to move, Space to select or unselect, Enter to confirm, Escape to go back, or Ctrl+C to exit.';
const TEXT_INPUT_NAVIGATION_HINT = 'Press Escape to go back.';
function removeTrailingBlankLines(message: string): string {
return message.replace(/\n+$/, '');
}
function withTextInputBodySpacing(message: string): string {
const normalized = removeTrailingBlankLines(message);
if (!normalized.includes('\n')) {
return normalized;
}
const [title, ...bodyLines] = normalized.split('\n');
if (bodyLines[0] === '') {
return normalized;
}
return `${title}\n\n${bodyLines.join('\n')}`;
}
export function withMenuOptionSpacing(message: string): string {
if (!message.includes('\n') || message.endsWith('\n')) {
return message;
}
return `${message}\n`;
}
export function withMenuOptionsSpacing<T extends { message: string }>(options: T): T {
return { ...options, message: withMenuOptionSpacing(options.message) };
}
export function withMultiselectNavigation(message: string): string {
if (message.includes(MULTISELECT_MENU_NAVIGATION_HINT)) {
return message;
}
return `${message}\n${MULTISELECT_MENU_NAVIGATION_HINT}`;
}
export function withTextInputNavigation(message: string): string {
const messageWithoutHint = removeTrailingBlankLines(message)
.split('\n')
.filter((line) => line !== TEXT_INPUT_NAVIGATION_HINT)
.join('\n');
return `${withTextInputBodySpacing(messageWithoutHint)}\n${TEXT_INPUT_NAVIGATION_HINT}\n`;
}