refactor: impl

This commit is contained in:
2026-03-01 12:41:03 +08:00
parent c2c3956a82
commit 5d026dfd80
7 changed files with 202 additions and 149 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
export { useCommander, initializeCommands, defaultCommands } from "./useCommander";
export { useCommander } from "./useCommander";
export type { UseCommanderReturn } from "./useCommander";
export { rollSimple, rollFormula } from "./useDiceRoller";
export type { DiceRollerResult } from "./useDiceRoller";
@@ -1,45 +1,14 @@
import { createSignal } from "solid-js";
import type {
MdCommanderCommand,
MdCommanderCommandMap,
CommanderEntry,
CompletionItem,
TrackerItem,
TrackerAttribute,
TrackerCommand,
TrackerViewMode,
MdCommanderCommandMap,
} from "../types";
import { parseInput, getCompletions } from "./completions";
import { setupHelpCommand, clearCommand, rollCommand, trackCommand, untrackCommand, listTrackCommand } from "../commands";
import {
addTrackerItem as addTracker,
removeTrackerItem as removeTracker,
updateTrackerAttribute as updateTrackerAttr,
updateTrackerClasses as updateTrackerClassesStore,
moveTrackerItem as moveTracker,
removeTrackerClass as removeClassFromTracker,
getTrackerItems,
getTrackerHistory,
findTrackerIndex,
} from "../stores";
// ==================== 默认命令 ====================
export const defaultCommands: MdCommanderCommandMap = {
help: { command: "help" }, // 占位,稍后初始化
clear: clearCommand,
roll: rollCommand,
track: trackCommand,
untrack: untrackCommand,
list: listTrackCommand,
};
// 初始化默认命令(包括 help)
export function initializeCommands(customCommands?: MdCommanderCommandMap): MdCommanderCommandMap {
const commands = { ...defaultCommands, ...customCommands };
commands.help = setupHelpCommand(commands);
return commands;
}
// ==================== Commander Hook ====================
@@ -58,30 +27,31 @@ export interface UseCommanderReturn {
handleCommand: () => void;
updateCompletions: () => void;
acceptCompletion: () => void;
commands: MdCommanderCommandMap;
commands: () => MdCommanderCommandMap;
setCommands: (cmds: MdCommanderCommandMap) => void;
historyIndex: () => number;
setHistoryIndex: (v: number) => void;
commandHistory: () => string[];
navigateHistory: (direction: 'up' | 'down') => void;
navigateHistory: (direction: "up" | "down") => void;
// Tracker 相关 - 直接暴露 store API
// Tracker 相关
viewMode: () => TrackerViewMode;
setViewMode: (mode: TrackerViewMode) => void;
trackerItems: () => TrackerItem[];
trackerHistory: () => TrackerCommand[];
addTrackerItem: typeof addTracker;
removeTrackerItem: typeof removeTracker;
addTrackerItem: (item: Omit<TrackerItem, "id">) => TrackerItem;
removeTrackerItem: (emmet: string) => boolean;
removeTrackerItemByIndex: (index: number) => void;
updateTrackerAttribute: typeof updateTrackerAttr;
updateTrackerAttribute: (emmet: string, attrName: string, attr: TrackerAttribute) => boolean;
updateTrackerAttributeByIndex: (index: number, attrName: string, attr: TrackerAttribute) => void;
updateTrackerClassesByIndex: (index: number, classes: string[]) => void;
moveTrackerItem: typeof moveTracker;
moveTrackerItemByIndex: (index: number, direction: 'up' | 'down') => void;
removeTrackerItemClass: typeof removeClassFromTracker;
moveTrackerItem: (emmet: string, direction: "up" | "down") => boolean;
moveTrackerItemByIndex: (index: number, direction: "up" | "down") => void;
removeTrackerItemClass: (emmet: string, className: string) => boolean;
removeTrackerItemClassByIndex: (index: number, className: string) => void;
}
export function useCommander(customCommands?: MdCommanderCommandMap): UseCommanderReturn {
export function useCommander(initialCommands?: MdCommanderCommandMap): UseCommanderReturn {
const [inputValue, setInputValue] = createSignal("");
const [entries, setEntries] = createSignal<CommanderEntry[]>([]);
const [showCompletions, setShowCompletions] = createSignal(false);
@@ -91,8 +61,7 @@ export function useCommander(customCommands?: MdCommanderCommandMap): UseCommand
const [commandHistory, setCommandHistory] = createSignal<string[]>([]);
const [historyIndex, setHistoryIndex] = createSignal(-1);
const [viewMode, setViewMode] = createSignal<TrackerViewMode>("history");
const commands = initializeCommands(customCommands);
const [commands, setCommands] = createSignal<MdCommanderCommandMap>(initialCommands || {});
// ==================== 命令执行 ====================
@@ -100,9 +69,10 @@ export function useCommander(customCommands?: MdCommanderCommandMap): UseCommand
const input = inputValue().trim();
if (!input) return;
const parsed = parseInput(input, commands);
const cmds = commands();
const parsed = parseInput(input, cmds);
const commandName = parsed.command;
const cmd = commands[commandName!];
const cmd = cmds[commandName!];
let result: { message: string; type?: "success" | "error" | "warning" | "info"; isHtml?: boolean };
@@ -110,7 +80,7 @@ export function useCommander(customCommands?: MdCommanderCommandMap): UseCommand
result = { message: `未知命令:${commandName}`, type: "error" };
} else if (cmd.handler) {
try {
result = cmd.handler({ params: parsed.params, options: parsed.options }, commands);
result = cmd.handler({ params: parsed.params, options: parsed.options }, cmds);
} catch (e) {
result = {
message: `执行错误:${e instanceof Error ? e.message : String(e)}`,
@@ -143,7 +113,7 @@ export function useCommander(customCommands?: MdCommanderCommandMap): UseCommand
// ==================== 自动补全 ====================
const updateCompletions = () => {
const comps = getCompletions(inputValue(), commands);
const comps = getCompletions(inputValue(), commands());
setCompletions(comps);
setShowCompletions(comps.length > 0 && isFocused());
setSelectedCompletionState(0);
@@ -151,8 +121,8 @@ export function useCommander(customCommands?: MdCommanderCommandMap): UseCommand
const setSelectedCompletion = (v: number | ((prev: number) => number)) => {
const maxIdx = completions().length - 1;
if (typeof v === 'function') {
setSelectedCompletionState(prev => {
if (typeof v === "function") {
setSelectedCompletionState((prev) => {
const next = v(prev);
return Math.max(0, Math.min(next, maxIdx));
});
@@ -168,7 +138,7 @@ export function useCommander(customCommands?: MdCommanderCommandMap): UseCommand
if (!comp) return;
const input = inputValue();
const parsed = parseInput(input, commands);
const parsed = parseInput(input, commands());
let newValue: string;
if (comp.type === "command") {
@@ -179,7 +149,7 @@ export function useCommander(customCommands?: MdCommanderCommandMap): UseCommand
.join(" ");
newValue = `${parsed.command || ""} ${existingOptions}${existingOptions ? " " : ""}${comp.insertText}`;
} else if (comp.type === "value") {
const cmd = parsed.command ? commands[parsed.command] : null;
const cmd = parsed.command ? commands()[parsed.command] : null;
const paramDefs = cmd?.parameters || [];
const usedParams = Object.keys(parsed.params);
const isTypingLastParam = paramDefs.length === usedParams.length && !input.endsWith(" ");
@@ -204,12 +174,12 @@ export function useCommander(customCommands?: MdCommanderCommandMap): UseCommand
// ==================== 命令历史 ====================
const navigateHistory = (direction: 'up' | 'down') => {
const navigateHistory = (direction: "up" | "down") => {
const history = commandHistory();
if (history.length === 0) return;
let newIndex = historyIndex();
if (direction === 'up') {
if (direction === "up") {
if (newIndex < history.length - 1) newIndex++;
} else {
if (newIndex > 0) {
@@ -226,37 +196,47 @@ export function useCommander(customCommands?: MdCommanderCommandMap): UseCommand
};
// ==================== Tracker 操作 ====================
const {
getTrackerItems,
getTrackerHistory,
addTrackerItem,
removeTrackerItem,
updateTrackerAttribute,
updateTrackerClasses,
moveTrackerItem,
removeTrackerClass,
} = require("../stores") as typeof import("../stores");
const getEmmetFromIndex = (index: number): string | null => {
const items = getTrackerItems();
if (index < 0 || index >= items.length) return null;
const item = items[index];
return `${item.tag}${item.id ? '#' + item.id : ''}${item.classes.length > 0 ? '.' + item.classes.join('.') : ''}`;
return `${item.tag}${item.id ? "#" + item.id : ""}${item.classes.length > 0 ? "." + item.classes.join(".") : ""}`;
};
const removeTrackerItemByIndex = (index: number) => {
const emmet = getEmmetFromIndex(index);
if (emmet) removeTracker(emmet);
if (emmet) removeTrackerItem(emmet);
};
const updateTrackerAttributeByIndex = (index: number, attrName: string, attr: TrackerAttribute) => {
const emmet = getEmmetFromIndex(index);
if (emmet) updateTrackerAttr(emmet, attrName, attr);
if (emmet) updateTrackerAttribute(emmet, attrName, attr);
};
const updateTrackerClassesByIndex = (index: number, classes: string[]) => {
const emmet = getEmmetFromIndex(index);
if (emmet) updateTrackerClassesStore(emmet, classes);
if (emmet) updateTrackerClasses(emmet, classes);
};
const moveTrackerItemByIndex = (index: number, direction: 'up' | 'down') => {
const moveTrackerItemByIndex = (index: number, direction: "up" | "down") => {
const emmet = getEmmetFromIndex(index);
if (emmet) moveTracker(emmet, direction);
if (emmet) moveTrackerItem(emmet, direction);
};
const removeTrackerItemClassByIndex = (index: number, className: string) => {
const emmet = getEmmetFromIndex(index);
if (emmet) removeClassFromTracker(emmet, className);
if (emmet) removeTrackerClass(emmet, className);
};
return {
@@ -275,6 +255,7 @@ export function useCommander(customCommands?: MdCommanderCommandMap): UseCommand
updateCompletions,
acceptCompletion,
commands,
setCommands,
historyIndex,
setHistoryIndex,
commandHistory,
@@ -283,15 +264,15 @@ export function useCommander(customCommands?: MdCommanderCommandMap): UseCommand
setViewMode,
trackerItems: getTrackerItems,
trackerHistory: getTrackerHistory,
addTrackerItem: addTracker,
removeTrackerItem: removeTracker,
addTrackerItem,
removeTrackerItem,
removeTrackerItemByIndex,
updateTrackerAttribute: updateTrackerAttr,
updateTrackerAttribute,
updateTrackerAttributeByIndex,
updateTrackerClassesByIndex,
moveTrackerItem: moveTracker,
moveTrackerItem,
moveTrackerItemByIndex,
removeTrackerItemClass: removeClassFromTracker,
removeTrackerItemClass,
removeTrackerItemClassByIndex,
};
}