Build a Browser‑Based Simulated Terminal with Command Autocomplete and History

This tutorial walks through creating a web‑based simulated Linux terminal, covering styled input handling, rendering logic, command parsing for ls, cd, cat, autocomplete, and command history, with both front‑end JavaScript and back‑end Node.js implementations and full code examples.

QQ Music Frontend Team
QQ Music Frontend Team
QQ Music Frontend Team
Build a Browser‑Based Simulated Terminal with Command Autocomplete and History

Simulated Terminal Overview

This article demonstrates how to build a browser‑based simulated terminal that mimics a Linux command line, supporting commands such as ls, cd, cat, a help command, autocomplete with the Tab key, and command history navigation using the arrow keys.

Styling the Input

The terminal UI is created by copying the appearance of the macOS Terminal into an input element and applying custom CSS. The core input element is: <input type="text" class="input-text"> Additional CSS removes borders, background, outlines, and sets the font size and color.

Rendering Logic

Each time the user presses Enter, the keydown event triggers the mainFunc function, which appends a new line to the terminal output and scrolls the view:

e_main.html($('#main').html() + '[<span id="usr">' + usrName + '</span>@<span class="host">ursb.me</span> ' + position + ']% ' + input + '<br/>');
e_html.animate({scrollTop: $(document).height()}, 0);

Help Command

A minimal help command prints a static help message:

switch (command) {
  case 'help':
    e_main.html($('#main').html() + '[<span id="usr">' + usrName + '</span>@<span class="host">ursb.me</span> ' + position + ']% ' + input + '<br/>Help text...');
    e_html.animate({scrollTop: $(document).height()}, 0);
    break;
}

List Files (ls)

The back‑end provides a /ls endpoint that returns the list of files and directories for the current path. The front‑end formats directories with a special CSS class:

router.get('/ls', (req, res) => {
  const { dir } = req.query;
  // Use glob to read files, filter directories, and return JSONP
});

Change Directory (cd)

The /cd endpoint validates the target directory and updates the current position. Errors return a 404 code with a message:

router.get('/cd', (req, res) => {
  const { pos, dir } = req.query;
  // Resolve path, check existence, and respond
});

Read File (cat)

The /cat endpoint reads a markdown file from the resolved path and returns its contents. If the file does not exist, a 404 error is returned:

router.get('/cat', (req, res) => {
  const { filename, dir } = req.query;
  // Resolve file path, read with fs.readFile, and respond
});

Autocomplete

When the user presses the Tab key, the pressTab function suggests completions for commands, file names, and directory names based on the global directory and files arrays fetched from the server:

if (command === 'l') e_input.val('ls');
if (command === 'c') e_input.val('cat');
// File and directory matching logic using startsWith and prefix handling

Command History

The terminal stores entered commands in an array hisCommand. Arrow‑up and arrow‑down keys navigate this history, restoring previous inputs without losing the current line:

let hisCommand = [];
let cour = 0; // pointer
let isInHis = 0;
function historyCmd(k) {
  if (k === 'up' && cour >= 1) {
    cour--;
    e_input.val(hisCommand[cour]);
  }
  if (k === 'down' && cour < hisCommand.length - 1) {
    cour++;
    e_input.val(hisCommand[cour]);
  }
}

Visual Demonstrations

The complete source code is available at airingursb/terminal , and readers are encouraged to submit pull requests to improve the project.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Command-lineautocompleteterminal
QQ Music Frontend Team
Written by

QQ Music Frontend Team

QQ Music Web Frontend Team

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.