130 lines
3.0 KiB
Plaintext
130 lines
3.0 KiB
Plaintext
<div id="command-line" class="w-full flex flex-row bg-base">
|
|
<input
|
|
id="command-line-input"
|
|
type="text"
|
|
size="1"
|
|
class="bg-base focus:outline-none active:outline-none cursor-default caret-transparent m-0"
|
|
/>
|
|
<div id="caret" aria-hidden="true" class="bg-text inline-block"> </div>
|
|
<p id="status-text" class="absolute w-full h-full bg-base hidden italic"></p>
|
|
</div>
|
|
|
|
<script>
|
|
const cmds: Record<string, () => void> = {
|
|
q: () => {
|
|
const cmdEvent = new CustomEvent("closebuffer");
|
|
window.dispatchEvent(cmdEvent);
|
|
},
|
|
"help iccf": () => {
|
|
const cmdEvent = new CustomEvent("openiccf");
|
|
window.dispatchEvent(cmdEvent);
|
|
},
|
|
};
|
|
|
|
const container = document.getElementById("command-line") as HTMLDivElement;
|
|
const commandLineInput = document.getElementById(
|
|
"command-line-input",
|
|
) as HTMLInputElement;
|
|
const caret = document.getElementById("caret") as HTMLDivElement;
|
|
const statusText = document.getElementById(
|
|
"status-text",
|
|
) as HTMLParagraphElement;
|
|
const allowedCharRegex = /[\w\d\s!@#$%^&*()-_+=|\\~`{[}\]:;"'<,>.?/]/;
|
|
|
|
let isInCmdMode = false;
|
|
|
|
commandLineInput.value = "";
|
|
caret.style.display = "none";
|
|
|
|
function enableCmdMode() {
|
|
caret.style.display = "block";
|
|
statusText.classList.add("hidden");
|
|
commandLineInput.value = ":";
|
|
commandLineInput.style.width = "1ch";
|
|
isInCmdMode = true;
|
|
|
|
const event = new Event("cmdmodeenabled");
|
|
container.dispatchEvent(event);
|
|
}
|
|
|
|
function disableCmdMode({ clear } = { clear: true }) {
|
|
caret.style.display = "none";
|
|
isInCmdMode = false;
|
|
if (clear) {
|
|
commandLineInput.value = "";
|
|
commandLineInput.style.width = "0ch";
|
|
}
|
|
|
|
const event = new Event("cmdmodedisabled");
|
|
container.dispatchEvent(event);
|
|
}
|
|
|
|
function appendChar(event: KeyboardEvent) {
|
|
commandLineInput.value += event.key;
|
|
commandLineInput.style.width = `${commandLineInput.value.length}ch`;
|
|
}
|
|
|
|
function deleteChar() {
|
|
commandLineInput.value = commandLineInput.value.substring(
|
|
0,
|
|
commandLineInput.value.length - 1,
|
|
);
|
|
commandLineInput.style.width = `${commandLineInput.value.length}ch`;
|
|
}
|
|
|
|
function executeCommand() {
|
|
disableCmdMode({ clear: false });
|
|
const command = commandLineInput.value.substring(1);
|
|
const fn = cmds[command];
|
|
if (fn) {
|
|
fn();
|
|
} else {
|
|
statusText.innerHTML = `E492: Not an editor command: ${command}`;
|
|
statusText.classList.remove("hidden");
|
|
statusText.classList.add("text-red");
|
|
}
|
|
}
|
|
|
|
document.addEventListener("keydown", (event) => {
|
|
switch (event.key) {
|
|
case ":":
|
|
if (!isInCmdMode) {
|
|
enableCmdMode();
|
|
} else {
|
|
appendChar(event);
|
|
}
|
|
break;
|
|
|
|
case "Escape":
|
|
if (isInCmdMode) {
|
|
event.preventDefault();
|
|
disableCmdMode();
|
|
}
|
|
break;
|
|
|
|
case "Backspace":
|
|
if (!isInCmdMode) break;
|
|
if (commandLineInput.value === ":") {
|
|
disableCmdMode();
|
|
} else {
|
|
deleteChar();
|
|
}
|
|
break;
|
|
|
|
case "Enter":
|
|
executeCommand();
|
|
break;
|
|
|
|
default:
|
|
if (
|
|
event.key.length === 1 &&
|
|
allowedCharRegex.test(event.key) &&
|
|
isInCmdMode
|
|
) {
|
|
appendChar(event);
|
|
}
|
|
break;
|
|
}
|
|
});
|
|
</script>
|