Files
Netcatty/components/terminal/runtime/terminalCommandExecution.ts
T

71 lines
2.0 KiB
TypeScript

import type { RefObject } from "react";
import type { Terminal as XTerm } from "@xterm/xterm";
import type { Host } from "../../../types";
import {
markPromptLineBreakCommandPending,
type PromptLineBreakState,
} from "./promptLineBreak";
import {
getAlignedPrompt,
isNonPromptLine,
reconcilePromptWithExternalCommand,
} from "../autocomplete/promptDetector";
type TerminalCommandExecutionContext = {
host: Pick<Host, "id" | "label">;
sessionId: string;
onCommandExecuted?: (
command: string,
hostId: string,
hostLabel: string,
sessionId: string,
) => void;
onCommandSubmitted?: (
command: string,
hostId: string,
hostLabel: string,
sessionId: string,
) => void;
commandBufferRef: RefObject<string>;
promptLineBreakStateRef?: RefObject<PromptLineBreakState>;
};
export const shouldRecordShellHistory = (
command: string,
term?: XTerm | null,
): boolean => {
if (!term) return true;
const { prompt, alignedTyped } = getAlignedPrompt(term, command, true);
if (!prompt.isAtPrompt) return false;
if (alignedTyped?.trim() === command.trim()) return true;
if (reconcilePromptWithExternalCommand(prompt, command)) return true;
const liveCommand = prompt.userInput.trim();
if (liveCommand.length === 0) {
return !isNonPromptLine(`${prompt.promptText}${command.trim()}`);
}
return liveCommand === command.trim();
};
export const recordTerminalCommandExecution = (
command: string,
ctx: TerminalCommandExecutionContext,
term?: XTerm | null,
): string | null => {
const cmd = command.trim();
if (cmd) {
ctx.onCommandSubmitted?.(cmd, ctx.host.id, ctx.host.label, ctx.sessionId);
}
if (cmd && shouldRecordShellHistory(cmd, term)) {
ctx.onCommandExecuted?.(cmd, ctx.host.id, ctx.host.label, ctx.sessionId);
ctx.commandBufferRef.current = "";
markPromptLineBreakCommandPending(ctx.promptLineBreakStateRef, term, command);
return cmd;
}
ctx.commandBufferRef.current = "";
markPromptLineBreakCommandPending(ctx.promptLineBreakStateRef, term, command);
return null;
};