84 lines
2.7 KiB
JavaScript
84 lines
2.7 KiB
JavaScript
'use strict';
|
|
|
|
const readline = require('readline');
|
|
|
|
const COMMAND_CHOICES = [
|
|
{ value: '/new', desc: '创建新对话' },
|
|
{ value: '/resume', desc: '加载旧对话' },
|
|
{ value: '/allow', desc: '切换运行模式(只读/无限制)' },
|
|
{ value: '/model', desc: '切换模型和思考模式' },
|
|
{ value: '/status', desc: '查看当前对话状态' },
|
|
{ value: '/compact', desc: '压缩当前对话' },
|
|
{ value: '/config', desc: '查看当前配置' },
|
|
{ value: '/help', desc: '显示指令列表' },
|
|
{ value: '/exit', desc: '退出程序' },
|
|
];
|
|
|
|
async function openCommandMenu(options) {
|
|
const { rl, prompt, pageSize, colorEnabled, resetAnsi, onInput } = options;
|
|
let latestInput = '';
|
|
|
|
rl.pause();
|
|
rl.line = '';
|
|
rl.cursor = 0;
|
|
readline.clearLine(process.stdout, 0);
|
|
readline.cursorTo(process.stdout, 0);
|
|
|
|
try {
|
|
const { default: search } = await import('@inquirer/search');
|
|
const chosen = await search({
|
|
message: prompt.trimEnd(),
|
|
pageSize,
|
|
theme: {
|
|
helpMode: 'never',
|
|
prefix: '',
|
|
icon: { cursor: '>' },
|
|
style: {
|
|
message: (text) => text,
|
|
searchTerm: (text) => `/${(text || '').replace(/^\/+/, '')}`,
|
|
highlight: (text) => (colorEnabled ? `\x1b[94m${text}${resetAnsi}` : text),
|
|
keysHelpTip: () => '',
|
|
description: (text) => text,
|
|
answer: () => '',
|
|
},
|
|
},
|
|
source: async (input) => {
|
|
latestInput = input || '';
|
|
if (typeof onInput === 'function') onInput(latestInput);
|
|
const term = latestInput.replace(/^\/+/, '').toLowerCase();
|
|
const maxCmdLen = Math.max(...COMMAND_CHOICES.map((c) => c.value.length));
|
|
const indentLen = Math.max(0, prompt.length - 2);
|
|
const indent = ' '.repeat(indentLen);
|
|
const format = (c) => {
|
|
const pad = ' '.repeat(Math.max(1, maxCmdLen - c.value.length + 2));
|
|
return `${indent}${c.value}${pad}${c.desc}`;
|
|
};
|
|
const filtered = term
|
|
? COMMAND_CHOICES.filter((c) => {
|
|
return (
|
|
c.value.toLowerCase().includes(term) ||
|
|
c.desc.toLowerCase().includes(term)
|
|
);
|
|
})
|
|
: COMMAND_CHOICES;
|
|
return filtered.map((c) => ({
|
|
name: format(c),
|
|
value: c.value,
|
|
}));
|
|
},
|
|
});
|
|
return { chosen, term: latestInput };
|
|
} catch (err) {
|
|
console.log('指令菜单不可用,请先安装依赖: npm i @inquirer/search');
|
|
return { chosen: null, term: '' };
|
|
} finally {
|
|
if (process.stdin.isTTY) process.stdin.setRawMode(true);
|
|
process.stdin.resume();
|
|
try {
|
|
rl.resume();
|
|
} catch (_) {}
|
|
}
|
|
}
|
|
|
|
module.exports = { openCommandMenu };
|