Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
# HomeTerm
# (Reiden's) HomeTerm

> Welcome to reiden's fork of the original HomeTerm!
>
> This repo is a fork of Jared's HomeTerm project, but with certain changes deemed necessary for regular usage.
>
> Key changes:
> - Added tab autocomplete, **super** necessary for any terminal user.
> - Replaced `open <path>` with `./<path>` to be more aligned with conventional terminal usage. After all, each link behaves a binary that opens a new page.
>
> Enjoy!


A homepage disguised as a toy terminal!

Expand All @@ -19,7 +30,7 @@ Here are the currently available commands that can be run on the terminal.
| `ls` | `ls [<path to dir>]` | List children of current working directory or given directory. |
| `tree` | `tree [<path to dir>]` | Lists all children of current working directory or given directory in tree format |
| `cd` | `cd [<path>]` | Move into given directory. If no path given move to root. |
| `open` | `open <path to link>` | Open a link in a new tab. |
| `open` | `./<path to link>` | Open a link in a new tab. |
| `touch` | `touch <path to link> <url>` | Create a new link |
| `mkdir` | `mkdir <path to dir>` | Create a new directory |
| `rm` | `rm <path to link>` | Delete link |
Expand Down
8 changes: 7 additions & 1 deletion src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
const COMMANDS = {
ls: { func: joinWriter(list, treeWriter), help: "usage: ls [<path to dir>]" },
cd: { func: joinWriter(cd, textWriter), help: "usage: cd [<path>]" },
open: { func: joinWriter(openLink, textWriter), help: "usage: open <path>" },
'./': { func: joinWriter(openLink, textWriter), help: "usage: ./<path>" },
open: { func: joinWriter(openRedirect, textWriter), help: "usage: ./<path>" },
touch: {
func: joinWriter(touch, textWriter),
help: "usage: touch <path to link> <url>",
Expand Down Expand Up @@ -104,6 +105,11 @@ function handleKeyPresses(e) {
return pushCommand(commandHistory[commandHistoryCursor]);
}
break;
case "Tab":
e.preventDefault();
const curr_input = document.getElementById("prompt-input");
if (curr_input.value == '') break;
return completeToken(curr_input.value);
default:
break;
}
Expand Down
4 changes: 4 additions & 0 deletions src/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ function cd(input) {
position = [];
}

function openRedirect(input) {
return COMMANDS.open.help;
}

function openLink(input) {
if (input.length) {
try {
Expand Down
86 changes: 85 additions & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,82 @@ function pushCommand(cmd) {
focusPrompt();
}

function completeToken(pref) {
const prompt = document.getElementById("prompt-input");

// Autocomplete for commands
const cmdParts = pref.split(' ');
if (!pref.startsWith('./') && cmdParts.length === 1) {
const prefix = cmdParts[0];
const matches = Object.keys(COMMANDS).filter(cmd => cmd.startsWith(prefix));

if (matches.length === 1) {
prompt.value = matches[0] + ' ';
}

focusPrompt();
return;
}

// Extract out correct pathPrefix and incomplete pathSuffix
var pathPrefix;
if (pref.startsWith('./')) {
pathPrefix = (pref.slice(2) + '_').split('/');
} else {
pathPrefix = (pref.split(' ')[1] + '_').split('/');
}

let pathSuffix = pathPrefix.pop().slice(0, -1); // Remove the last character
pathPrefix = pathPrefix.join('/');

// Find possible autocomplete targets
let targets = list([pathPrefix]);
if (!Array.isArray(targets)) {
focusPrompt();
return;
}

// Initialize possible match variable
let possible = '';

// Iterate over targets to find matching keys
for (let i = 0; i < targets.length; i++) {
let { key, _ } = targets[i];

// Have found unique (so far) match
if (key.includes(pathSuffix) && !possible) {
possible = key;
}
// Multiple options, pass
else if (key.startsWith(pathSuffix)) {
focusPrompt();
return;
}
}

if (possible == '') {
focusPrompt();
return;
}

// Construct final prompt value
var result;
if (pref.startsWith('./')) {
result = "./";
} else {
result = pref.split(' ')[0] + ' ';
}
result += pathPrefix;
if (pathPrefix) {
result += '/'
}
result += possible;

prompt.value = result;
focusPrompt();
}


// Returns link url if link or cursor if directory
// Throw error if bad path
function locatePath(path) {
Expand Down Expand Up @@ -105,13 +181,21 @@ function replacePrompt() {

// Parse command input by keeping strings in "" together as an single item
function parseCommand(input) {
const re = /"([^"]+)"|([^\s]+)/g;

// New open syntax.
const parsedCmd = [];
if (input.startsWith("./")) {
parsedCmd.push("./");
input = input.slice(2);
}

const re = /"([^"]+)"|([^\s]+)/g;
let temp;
while ((temp = re.exec(input)) !== null) {
const val = temp[1] || temp[2]; // Get the correct capture group
parsedCmd.push(val);
}
console.log(parsedCmd);
return parsedCmd;
}

Expand Down