gommand/static/keyboard-shortcuts.js

133 lines
4.1 KiB
JavaScript

document.addEventListener("DOMContentLoaded", function() {
const input = document.getElementById("command-input");
if (!input) return;
let commandHistory = JSON.parse(sessionStorage.getItem("commandHistory")) || [];
let historyIndex = commandHistory.length;
let tabIndex = -1;
let tabMatches = [];
document.querySelector("form").addEventListener("submit", function(event) {
const command = input.value.trim();
if (command) {
commandHistory.push(command);
sessionStorage.setItem("commandHistory", JSON.stringify(commandHistory));
historyIndex = commandHistory.length;
}
});
window.addEventListener("keydown", function(event) {
if (document.activeElement !== input) return;
const cursorPos = input.selectionStart;
const textLength = input.value.length;
// Prevent default behavior for specific Ctrl+Key shortcuts
if (event.ctrlKey && ["w", "n", "p", "h", "e", "a", "k", "u", "d", "r", "t"].includes(event.key.toLowerCase())) {
event.preventDefault();
event.stopPropagation();
}
// Ctrl+A: Move cursor to the beginning
if (event.ctrlKey && event.key === "a") {
input.setSelectionRange(0, 0);
}
// Ctrl+E: Move cursor to the end
else if (event.ctrlKey && event.key === "e") {
input.setSelectionRange(textLength, textLength);
}
// Ctrl+U: Clear the input field
else if (event.ctrlKey && event.key === "u") {
input.value = "";
}
// Ctrl+K: Delete everything after the cursor
else if (event.ctrlKey && event.key === "k") {
input.value = input.value.substring(0, cursorPos);
}
// Ctrl+W: Delete the previous word
else if (event.ctrlKey && event.key === "w") {
const beforeCursor = input.value.substring(0, cursorPos);
const afterCursor = input.value.substring(cursorPos);
const newBeforeCursor = beforeCursor.replace(/\S+\s*$/, ""); // Delete last word
input.value = newBeforeCursor + afterCursor;
input.setSelectionRange(newBeforeCursor.length, newBeforeCursor.length);
}
// Ctrl+H: Delete the previous character (Backspace)
else if (event.ctrlKey && event.key === "h") {
if (cursorPos > 0) {
input.value = input.value.substring(0, cursorPos - 1) + input.value.substring(cursorPos);
input.setSelectionRange(cursorPos - 1, cursorPos - 1);
}
}
// Ctrl+D: Delete character under cursor (or clear input if empty)
else if (event.ctrlKey && event.key === "d") {
if (textLength === 0) {
console.log("Ctrl+D: No input, simulating EOF");
} else if (cursorPos < textLength) {
input.value = input.value.substring(0, cursorPos) + input.value.substring(cursorPos + 1);
input.setSelectionRange(cursorPos, cursorPos);
}
}
// Ctrl+P: Previous command (up)
else if (event.ctrlKey && event.key === "p") {
if (historyIndex > 0) {
historyIndex--;
input.value = commandHistory[historyIndex];
} else if (historyIndex === 0) {
input.value = commandHistory[0];
}
}
// Ctrl+N: Next command (down)
else if (event.ctrlKey && event.key === "n") {
if (historyIndex < commandHistory.length - 1) {
historyIndex++;
input.value = commandHistory[historyIndex];
} else {
historyIndex = commandHistory.length;
input.value = "";
}
}
// Ctrl+R: Prevent page reload (for future reverse search)
else if (event.ctrlKey && event.key === "r") {
console.log("Reverse search triggered (not yet implemented)");
}
// Tab Completion
else if (event.key === "Tab") {
event.preventDefault();
const currentText = input.value.trim();
if (currentText === "") return;
// Find all matching commands from history
if (tabIndex === -1) {
tabMatches = commandHistory.filter(cmd => cmd.startsWith(currentText));
if (tabMatches.length === 0) return;
}
// Cycle through matches
if (event.shiftKey) {
tabIndex = tabIndex > 0 ? tabIndex - 1 : tabMatches.length - 1; // Shift+Tab goes backward
} else {
tabIndex = (tabIndex + 1) % tabMatches.length;
}
input.value = tabMatches[tabIndex];
}
// Allow Enter key to submit form
if (event.key === "Enter") {
tabIndex = -1; // Reset tab completion cycle
return;
}
}, true);
});