Files

87 lines
2.0 KiB
TypeScript
Raw Permalink Normal View History

type StringRef = {
current: string;
};
type SerialLineModeInputOptions = {
bufferRef: StringRef;
localEcho?: boolean;
writeToSession: (data: string) => void;
writeToTerminal: (data: string) => void;
};
const submitLine = ({
bufferRef,
localEcho,
writeToSession,
writeToTerminal,
}: SerialLineModeInputOptions) => {
const line = `${bufferRef.current}\r`;
writeToSession(line);
bufferRef.current = "";
if (localEcho) writeToTerminal("\r\n");
};
const appendText = (
text: string,
{ bufferRef, localEcho, writeToTerminal }: SerialLineModeInputOptions,
) => {
if (!text) return;
bufferRef.current += text;
if (localEcho) writeToTerminal(text);
};
const clearLine = ({
bufferRef,
localEcho,
writeToTerminal,
}: SerialLineModeInputOptions) => {
if (localEcho && bufferRef.current.length > 0) {
writeToTerminal("\b \b".repeat(bufferRef.current.length));
}
bufferRef.current = "";
};
export function handleSerialLineModeInput(
data: string,
options: SerialLineModeInputOptions,
): void {
if (data === "\r" || data === "\n") {
submitLine(options);
return;
}
if (data === "\x7f" || data === "\b") {
if (options.bufferRef.current.length > 0) {
options.bufferRef.current = options.bufferRef.current.slice(0, -1);
if (options.localEcho) options.writeToTerminal("\b \b");
}
return;
}
if (data === "\x03") {
options.bufferRef.current = "";
options.writeToSession(data);
if (options.localEcho) options.writeToTerminal("^C\r\n");
return;
}
if (data === "\x15") {
clearLine(options);
return;
}
const normalizedData = data.replace(/\r\n/g, "\r").replace(/\n/g, "\r");
if (normalizedData.includes("\r")) {
const parts = normalizedData.split("\r");
parts.forEach((part, index) => {
appendText(part, options);
if (index < parts.length - 1) submitLine(options);
});
return;
}
if (data.charCodeAt(0) >= 32 || data.length > 1) {
appendText(data, options);
}
}