133 lines
4.1 KiB
JavaScript
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);
|
|
});
|