|
|
@@ -2,6 +2,7 @@ import { FitAddon } from "@xterm/addon-fit";
|
|
|
import { Terminal } from "@xterm/xterm";
|
|
|
import React from "react";
|
|
|
import { Command } from "#/state/commandSlice";
|
|
|
+import { sendTerminalCommand } from "#/services/terminalService";
|
|
|
|
|
|
/*
|
|
|
NOTE: Tests for this hook are indirectly covered by the tests for the XTermTerminal component.
|
|
|
@@ -26,6 +27,7 @@ export const useTerminal = (commands: Command[] = []) => {
|
|
|
fitAddon.current = new FitAddon();
|
|
|
|
|
|
let resizeObserver: ResizeObserver;
|
|
|
+ let commandBuffer = "";
|
|
|
|
|
|
if (ref.current) {
|
|
|
/* Initialize the terminal in the DOM */
|
|
|
@@ -33,6 +35,44 @@ export const useTerminal = (commands: Command[] = []) => {
|
|
|
terminal.current.open(ref.current);
|
|
|
|
|
|
terminal.current.write("$ ");
|
|
|
+ terminal.current.onKey(({ key, domEvent }) => {
|
|
|
+ if (domEvent.key === "Enter") {
|
|
|
+ terminal.current?.write("\r\n");
|
|
|
+ sendTerminalCommand(commandBuffer);
|
|
|
+ commandBuffer = "";
|
|
|
+ } else if (domEvent.key === "Backspace") {
|
|
|
+ if (commandBuffer.length > 0) {
|
|
|
+ commandBuffer = commandBuffer.slice(0, -1);
|
|
|
+ terminal.current?.write("\b \b");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // Ignore paste event
|
|
|
+ if (key.charCodeAt(0) === 22) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ commandBuffer += key;
|
|
|
+ terminal.current?.write(key);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ terminal.current.attachCustomKeyEventHandler((arg) => {
|
|
|
+ if (arg.ctrlKey && arg.code === "KeyV" && arg.type === "keydown") {
|
|
|
+ navigator.clipboard.readText().then((text) => {
|
|
|
+ terminal.current?.write(text);
|
|
|
+ commandBuffer += text;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (arg.ctrlKey && arg.code === "KeyC" && arg.type === "keydown") {
|
|
|
+ const selection = terminal.current?.getSelection();
|
|
|
+ if (selection) {
|
|
|
+ const clipboardItem = new ClipboardItem({
|
|
|
+ "text/plain": new Blob([selection], { type: "text/plain" }),
|
|
|
+ });
|
|
|
+
|
|
|
+ navigator.clipboard.write([clipboardItem]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ });
|
|
|
|
|
|
/* Listen for resize events */
|
|
|
resizeObserver = new ResizeObserver(() => {
|