@@ -407,6 +407,10 @@ const showCommandSuggestion = ref(false);
407407const selectedCommandIndex = ref (0 );
408408const commandSuggestionLoading = ref (false );
409409
410+ function normalizeCommandSearchText(value : string ) {
411+ return value .trim ().replace (/ ^ \/ + / , " " ).toLowerCase ();
412+ }
413+
410414/** 从所有指令中展平获取启用的普通指令和子指令 */
411415const enabledCommands = computed (() => {
412416 const result: SuggestionCommand [] = [];
@@ -431,6 +435,7 @@ const enabledCommands = computed(() => {
431435 description: cmd .description ,
432436 plugin_display_name: cmd .plugin_display_name ,
433437 enabled: cmd .enabled ,
438+ reserved: cmd .reserved ,
434439 });
435440 }
436441 // 同时加入别名(别名也需要加上 / 前缀)
@@ -449,6 +454,7 @@ const enabledCommands = computed(() => {
449454 description: cmd .description ,
450455 plugin_display_name: cmd .plugin_display_name ,
451456 enabled: cmd .enabled ,
457+ reserved: cmd .reserved ,
452458 });
453459 }
454460 });
@@ -458,15 +464,40 @@ const enabledCommands = computed(() => {
458464 return result ;
459465});
460466
467+ function sortSystemPluginCommandsFirst(commands : SuggestionCommand []) {
468+ return [... commands ].sort ((a , b ) => Number (b .reserved ) - Number (a .reserved ));
469+ }
470+
461471/** 根据当前输入过滤候选指令 */
462472const filteredCommands = computed (() => {
463473 const text = props .prompt ;
464474 if (! text || ! text .startsWith (" /" )) return [];
465475
466- const prefix = text .toLowerCase ();
467- return enabledCommands .value
468- .filter ((cmd ) => cmd .effective_command .toLowerCase ().startsWith (prefix ))
469- .slice (0 , 8 ); // 最多显示8条
476+ const query = normalizeCommandSearchText (text );
477+ if (! query ) return sortSystemPluginCommandsFirst (enabledCommands .value );
478+
479+ const startsWithMatches: SuggestionCommand [] = [];
480+ const containsMatches: SuggestionCommand [] = [];
481+
482+ for (const cmd of enabledCommands .value ) {
483+ const commandText = normalizeCommandSearchText (cmd .effective_command );
484+ const pluginText = normalizeCommandSearchText (cmd .plugin_display_name || " " );
485+ const descriptionText = normalizeCommandSearchText (cmd .description || " " );
486+ const matchesCommand = commandText .includes (query );
487+ const matchesMetadata =
488+ pluginText .includes (query ) || descriptionText .includes (query );
489+
490+ if (commandText .startsWith (query )) {
491+ startsWithMatches .push (cmd );
492+ } else if (matchesCommand || matchesMetadata ) {
493+ containsMatches .push (cmd );
494+ }
495+ }
496+
497+ return [
498+ ... sortSystemPluginCommandsFirst (startsWithMatches ),
499+ ... sortSystemPluginCommandsFirst (containsMatches ),
500+ ];
470501});
471502
472503const localPrompt = computed ({
@@ -659,11 +690,7 @@ function handleKeyDown(e: KeyboardEvent) {
659690function handleInput() {
660691 const text = props .prompt ;
661692 if (text && text .startsWith (" /" ) && ! isComposing .value ) {
662- const prefix = text .toLowerCase ();
663- const hasMatch = enabledCommands .value .some ((cmd ) =>
664- cmd .effective_command .toLowerCase ().startsWith (prefix ),
665- );
666- showCommandSuggestion .value = hasMatch ;
693+ showCommandSuggestion .value = filteredCommands .value .length > 0 ;
667694 selectedCommandIndex .value = 0 ;
668695 } else {
669696 showCommandSuggestion .value = false ;
0 commit comments