Skip to content

Commit

Permalink
Add autocomplete for commands
Browse files Browse the repository at this point in the history
  • Loading branch information
pindab0ter committed Apr 9, 2024
1 parent 21fadc2 commit 57dad78
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 2 deletions.
16 changes: 16 additions & 0 deletions assets/js/shell/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,19 @@ export function getPagesInPath(path: string): HugoPage[] {
return pages.filter((page: HugoPage) => page.Path.startsWith(path));
}
}

export function longestCommonPrefix(strings: string[]): string {
if (strings.length === 0) return "";
if (strings.length === 1) return strings[0];

const sortedStrings = strings.slice().sort();
const firstString = sortedStrings[0];
const lastString = sortedStrings[sortedStrings.length - 1];

let i = 0;
while (i < firstString.length && firstString.charAt(i) === lastString.charAt(i)) {
i++;
}

return firstString.substring(0, i);
}
33 changes: 31 additions & 2 deletions assets/js/shell/prompt.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { commands } from "./commands";
import { Command } from "./Command";
import { longestCommonPrefix } from "./helpers";

export default function initialisePrompt(): void {
document.addEventListener("DOMContentLoaded", () => {
Expand Down Expand Up @@ -50,6 +51,8 @@ function listenForKeyboardInput(promptInput: HTMLSpanElement, promptBlur: HTMLSp
* Handle enter key press to clear the prompt input.
*/
document.addEventListener("keydown", (event: KeyboardEvent) => {
const input = promptInput.textContent.replace(/\xA0/g, " ").trim();

switch (event.key) {
case "ArrowLeft":
case "ArrowRight":
Expand All @@ -62,14 +65,40 @@ function listenForKeyboardInput(promptInput: HTMLSpanElement, promptBlur: HTMLSp
case "Enter":
event.preventDefault();

const input = promptInput.textContent.replace(/\xA0/g, " ").trim();

promptInput.textContent = "";
promptBlur.textContent = "";

parseCommand(input);
break;

case "Tab":
event.preventDefault();

if (input.length === 0) {
return;
}

const matchingCommands = commands.filter((command: Command) =>
command.name.startsWith(input),
);
switch (matchingCommands.length) {
case 0:
return;
case 1:
promptInput.textContent = matchingCommands[0].name;
promptBlur.textContent = matchingCommands[0].name;
moveCaretToEnd(promptInput);
return;
default:
const matchingPrefix = longestCommonPrefix(
matchingCommands.map((command: Command) => command.name),
);
promptInput.textContent = matchingPrefix;
promptBlur.textContent = matchingPrefix;
moveCaretToEnd(promptInput);
}
break;

// Remove focus from prompt input
case "Escape":
promptInput.blur();
Expand Down

0 comments on commit 57dad78

Please sign in to comment.