Skip to content

Instantly share code, notes, and snippets.

@tuliopc23
Created July 8, 2025 21:13
Show Gist options
  • Save tuliopc23/90931734a68ce5a05f32e538debb3fd3 to your computer and use it in GitHub Desktop.
Save tuliopc23/90931734a68ce5a05f32e538debb3fd3 to your computer and use it in GitHub Desktop.
My Terminal
<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:200' rel='stylesheet' type='text/css'>
<div class="container">
<div class="window">
<div class="handle">
<div class="buttons">
<button class="close">
</button>
<button class="minimize">
</button>
<button class="maximize">
</button>
</div>
<span class="title"></span>
</div>
<div class="terminal"></div>
</div>
</div>

My Terminal

This is basically just a mockup of iTerm on Mac OS X with some basic functionality. ###Commands:

  • help: displays a currently very unhelpful help message.
  • clear: clears the terminal display.
  • fortune: randomly selects a fortune from a database by bmc on GitHub and displays it.

A Pen by Marcus Bizal on CodePen.

License.

/*
// Made with <3 by Marcus Bizal
// github.com/marcbizal
// linkedin.com/in/marcbizal
*/
$(document).ready(function() {
"use strict";
// UTILITY
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
// END UTILITY
// COMMANDS
function clear() {
terminal.text("");
}
function help() {
terminal.append("There is no help... MUAHAHAHAHA. >:D\n");
}
function echo(args) {
var str = args.join(" ");
terminal.append(str + "\n");
}
function fortune() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://cdn.rawgit.com/bmc/fortunes/master/fortunes', false);
xhr.send(null);
if (xhr.status === 200) {
var fortunes = xhr.responseText.split("%");
var fortune = fortunes[getRandomInt(0, fortunes.length)].trim();
terminal.append(fortune + "\n");
}
}
// END COMMANDS
var title = $(".title");
var terminal = $(".terminal");
var prompt = "➜";
var path = "~";
var commandHistory = [];
var historyIndex = 0;
var command = "";
var commands = [{
"name": "clear",
"function": clear
}, {
"name": "help",
"function": help
}, {
"name": "fortune",
"function": fortune
}, {
"name": "echo",
"function": echo
}];
function processCommand() {
var isValid = false;
// Create args list by splitting the command
// by space characters and then shift off the
// actual command.
var args = command.split(" ");
var cmd = args[0];
args.shift();
// Iterate through the available commands to find a match.
// Then call that command and pass in any arguments.
for (var i = 0; i < commands.length; i++) {
if (cmd === commands[i].name) {
commands[i].function(args);
isValid = true;
break;
}
}
// No match was found...
if (!isValid) {
terminal.append("zsh: command not found: " + command + "\n");
}
// Add to command history and clean up.
commandHistory.push(command);
historyIndex = commandHistory.length;
command = "";
}
function displayPrompt() {
terminal.append("<span class=\"prompt\">" + prompt + "</span> ");
terminal.append("<span class=\"path\">" + path + "</span> ");
}
// Delete n number of characters from the end of our output
function erase(n) {
command = command.slice(0, -n);
terminal.html(terminal.html().slice(0, -n));
}
function clearCommand() {
if (command.length > 0) {
erase(command.length);
}
}
function appendCommand(str) {
terminal.append(str);
command += str;
}
/*
// Keypress doesn't catch special keys,
// so we catch the backspace here and
// prevent it from navigating to the previous
// page. We also handle arrow keys for command history.
*/
$(document).keydown(function(e) {
e = e || window.event;
var keyCode = typeof e.which === "number" ? e.which : e.keyCode;
// BACKSPACE
if (keyCode === 8 && e.target.tagName !== "INPUT" && e.target.tagName !== "TEXTAREA") {
e.preventDefault();
if (command !== "") {
erase(1);
}
}
// UP or DOWN
if (keyCode === 38 || keyCode === 40) {
// Move up or down the history
if (keyCode === 38) {
// UP
historyIndex--;
if (historyIndex < 0) {
historyIndex++;
}
} else if (keyCode === 40) {
// DOWN
historyIndex++;
if (historyIndex > commandHistory.length - 1) {
historyIndex--;
}
}
// Get command
var cmd = commandHistory[historyIndex];
if (cmd !== undefined) {
clearCommand();
appendCommand(cmd);
}
}
});
$(document).keypress(function(e) {
// Make sure we get the right event
e = e || window.event;
var keyCode = typeof e.which === "number" ? e.which : e.keyCode;
// Which key was pressed?
switch (keyCode) {
// ENTER
case 13:
{
terminal.append("\n");
processCommand();
displayPrompt();
break;
}
default:
{
appendCommand(String.fromCharCode(keyCode));
}
}
});
// Set the window title
title.text("1. marc@mbp: ~ (zsh)");
// Get the date for our fake last-login
var date = new Date().toString(); date = date.substr(0, date.indexOf("GMT") - 1);
// Display last-login and promt
terminal.append("Last login: " + date + " on ttys000\n"); displayPrompt();
});
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
$button-diameter: 12px;
$button-not-focused: rgb(220, 220, 220);
$button-close: rgb(255, 97, 89);
$button-minimize: rgb(255, 191, 47);
$button-maximize: rgb(37, 204, 62);
$button-spacing: 4px;
$window-not-focused: rgb(246, 246, 246);
$window-focused: linear-gradient(0deg, rgb(216, 216, 216), rgb(236, 236, 236));
$window-border: rgb(179, 179, 179);
$handle-height: 22px;
$window-width: 640px;
$window-height: 480px;
html, body {
height: 100%;
overflow: hidden;
}
body {
background: #3a7bd5;
background-image: -webkit-radial-gradient(top, circle cover, #00d2ff 0%, #3a7bd5 80%);
display: flex;
justify-content: center;
align-items: center;
}
* {
box-sizing: border-box;
}
textarea, input, button {
outline: none;
}
.window-button {
padding: 0;
margin: 0;
margin-right: $button-spacing;
width: $button-diameter;
height: $button-diameter;
background-color: $button-not-focused;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: $button-diameter / 2;
color: rgba(0, 0, 0, 0.5);
}
.window {
animation: bounceIn 1s ease-in-out;
width: $window-width;
.handle {
height: $handle-height;
background: $window-focused;
border-top: 1px solid white;
border-bottom: 1px solid $window-border;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
color: rgba(0, 0, 0, 0.7);
font-family: Helvetica, sans-serif;
font-size: 13px;
line-height: $handle-height;
text-align: center;
}
.buttons {
position: absolute;
float: left;
margin: 0 $button-spacing * 2;
.close {
@extend .window-button;
background-color: $button-close;
}
.minimize {
@extend .window-button;
background-color: $button-minimize;
}
.maximize {
@extend .window-button;
background-color: $button-maximize;
}
}
.terminal {
padding: $button-spacing;
background-color: black;
opacity: 0.7;
height: $window-height / 2 - $handle-height;
color: white;
font-family: 'Source Code Pro', monospace;
font-weight: 200;
font-size: 14px;
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
word-wrap: break-word;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
overflow-y: auto;
&::after {
content: "|";
animation: blink 2s steps(1) infinite;
}
}
}
.prompt {
color: rgb(189, 227, 113);
}
.path {
color: rgb(94, 215, 255);
}
@keyframes blink { 50% { color: transparent; } }
@keyframes bounceIn {
0% {
transform: translateY(-1000px);
}
60% {
transform: translateY(200px);
}
100% {
transform: translateY(0px);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment