Skip to content

Commit c295db1

Browse files
committed
Add command completion and clear screen functionality to terminal
- Introduced Ctrl+L key binding to clear the terminal screen. - Added TAB key functionality for command completion, displaying possible completions based on user input. - Implemented a getCompletions function to suggest commands and arguments dynamically. - Enhanced user experience by allowing single and multiple command completions to be displayed in the terminal.
1 parent 04ecbd4 commit c295db1

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

static/terminal-window/terminal-window.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ const CONSTANTS = {
77
},
88
KEYS: {
99
CTRL_C: "\x03",
10+
CTRL_L: "\x0C",
1011
ENTER: "\r",
1112
BACKSPACE: "\u007F",
13+
TAB: "\t",
1214
ARROW: {
1315
LEFT: "\u001b[D",
1416
RIGHT: "\u001b[C",
@@ -192,6 +194,36 @@ document.addEventListener("DOMContentLoaded", () => {
192194
return;
193195
}
194196

197+
// Handle Ctrl+L (clear screen)
198+
if (data === CONSTANTS.KEYS.CTRL_L) {
199+
terminal.clear();
200+
terminal.prompt();
201+
state.term.write(state.commandBuffer);
202+
return;
203+
}
204+
205+
if (data === CONSTANTS.KEYS.TAB) {
206+
if (!state.awaitingPassword) {
207+
const completions = getCompletions(state.commandBuffer);
208+
if (completions.length === 1) {
209+
// Clear current line
210+
state.term.write(
211+
"\r$ " + " ".repeat(state.commandBuffer.length) + "\r$ "
212+
);
213+
state.commandBuffer = completions[0];
214+
state.cursorPosition = state.commandBuffer.length;
215+
state.term.write(state.commandBuffer);
216+
} else if (completions.length > 1) {
217+
// Show all possible completions
218+
terminal.print("");
219+
terminal.print(completions.join(" "));
220+
terminal.prompt();
221+
state.term.write(state.commandBuffer);
222+
}
223+
}
224+
return;
225+
}
226+
195227
if (state.awaitingPassword) {
196228
// Handle password input
197229
switch (data) {
@@ -372,6 +404,34 @@ document.addEventListener("DOMContentLoaded", () => {
372404
},
373405
};
374406

407+
const getCompletions = (input) => {
408+
// If no input, return all commands
409+
if (!input) return Object.keys(commands);
410+
411+
const [cmd, ...args] = input.split(" ");
412+
413+
// If we have a complete command and arguments
414+
if (input.endsWith(" ")) {
415+
// Handle command-specific argument completion
416+
switch (cmd.toLowerCase()) {
417+
case "su":
418+
// Example: could suggest usernames here
419+
return ["root", "admin"];
420+
default:
421+
return [];
422+
}
423+
}
424+
425+
// If we're still typing the command
426+
if (!args.length) {
427+
return Object.keys(commands).filter((command) =>
428+
command.toLowerCase().startsWith(cmd.toLowerCase())
429+
);
430+
}
431+
432+
return [];
433+
};
434+
375435
const processCommand = async (cmd) => {
376436
if (state.awaitingPassword) {
377437
terminal.print("Verifying access...");

0 commit comments

Comments
 (0)