parent
781e8ba3a3
commit
af1dd02257
11 changed files with 480 additions and 3 deletions
40
.forgejo/workflows/webrepl.yaml
Normal file
40
.forgejo/workflows/webrepl.yaml
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
name: webrepl
|
||||||
|
on: [push]
|
||||||
|
#on:
|
||||||
|
# push:
|
||||||
|
# branches:
|
||||||
|
# - main
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: docker
|
||||||
|
|
||||||
|
container:
|
||||||
|
image: rust:1.83-alpine
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Install dependencies
|
||||||
|
run: apk add --no-cache git nodejs util-linux
|
||||||
|
|
||||||
|
- name: Install wasm-pack
|
||||||
|
run: cargo install wasm-pack
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Build talc-web
|
||||||
|
run: wasm-pack build --release --no-typescript --no-pack --target web
|
||||||
|
working-directory: talc-web
|
||||||
|
|
||||||
|
- name: Save artifacts
|
||||||
|
uses: forgejo/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: webrepl
|
||||||
|
path: |
|
||||||
|
*.html
|
||||||
|
*.js
|
||||||
|
*.css
|
||||||
|
pkg/
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
- name: Done
|
||||||
|
run: echo done!
|
92
Cargo.lock
generated
92
Cargo.lock
generated
|
@ -29,6 +29,12 @@ version = "2.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
@ -144,8 +150,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi",
|
||||||
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -163,6 +171,16 @@ dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.76"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
@ -288,6 +306,12 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.20.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.20"
|
version = "0.2.20"
|
||||||
|
@ -427,9 +451,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.94"
|
version = "2.0.95"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "987bc0be1cdea8b10216bd06e2ca407d40b9543468fafd3ddfb02f36e77f71f3"
|
checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -477,6 +501,16 @@ dependencies = [
|
||||||
"talc-macros",
|
"talc-macros",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "talc-web"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"talc-lang",
|
||||||
|
"talc-std",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
|
@ -507,6 +541,60 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.99"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.99"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.99"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.99"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.99"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["talc-lang", "talc-bin", "talc-std", "talc-macros"]
|
members = ["talc-lang", "talc-bin", "talc-std", "talc-macros", "talc-web"]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
- [Installation](./install/installation.md)
|
- [Installation](./install/installation.md)
|
||||||
- [Tour of the REPL](./install/repl.md)
|
- [Tour of the REPL](./install/repl.md)
|
||||||
|
- [The Web REPL](./install/webrepl.md)
|
||||||
|
|
||||||
# The language
|
# The language
|
||||||
|
|
||||||
|
|
18
docs/src/install/webrepl.md
Normal file
18
docs/src/install/webrepl.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# The Web REPL
|
||||||
|
|
||||||
|
As an alterative to the command-line REPL, you can try out Talc in the browser
|
||||||
|
at (https://talc.trimill.xyz/repl)[https://talc.trimill.xyz/repl]. Although
|
||||||
|
the full Talc language and standard library (aside from file I/O and process
|
||||||
|
control) are available, editing features are more limited than the command-line
|
||||||
|
interface - especially of note is the lack of syntax highlighting and tab
|
||||||
|
completion.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Just like the command-line REPL, enter an expression and press Enter to
|
||||||
|
evaluate it. Use the up and down arrows to access input history.
|
||||||
|
|
||||||
|
For multiline editing, use Shift+Enter to insert a newline. Hold the Control
|
||||||
|
key while pressing the up or down arrows to move the cursor between lines.
|
||||||
|
|
||||||
|
To clear the screen, press Ctrl+L.
|
16
talc-web/Cargo.toml
Normal file
16
talc-web/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "talc-web"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
talc-lang = { path = "../talc-lang" }
|
||||||
|
talc-std = { path = "../talc-std", default-features = false, features = ["rand", "regex"] }
|
||||||
|
getrandom = { version = "0.2", features = ["js"] }
|
||||||
|
wasm-bindgen = "0.2"
|
16
talc-web/README.md
Normal file
16
talc-web/README.md
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Talc Web
|
||||||
|
|
||||||
|
The `talc-web` crate provides a WASM interface to execute Talc expressions
|
||||||
|
in a REPL. Together with the associated HTML, CSS, and JavaScript files, this
|
||||||
|
creates an alternative to the command-line REPL.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
In the `talc-web` directory, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wasm-pack build --release --no-typescript --no-pack --target web
|
||||||
|
```
|
||||||
|
|
||||||
|
See (the main README.md)[../README.md] for more information about building
|
||||||
|
Talc.
|
29
talc-web/index.html
Normal file
29
talc-web/index.html
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<title>Talc Web REPL</title>
|
||||||
|
|
||||||
|
<script type="module" src="main.js"></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="terminal">
|
||||||
|
<div id="history">
|
||||||
|
<div>Talc Web REPL</div>
|
||||||
|
<div>For help, see
|
||||||
|
<a href="https://talc.trimill.xyz/" target="_blank">the docs</a>
|
||||||
|
or
|
||||||
|
<a href="https://g.trimill.xyz/trimill/talc" target="_blank">the repository</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input_line">
|
||||||
|
<div id="prompt" class="prompt">>> </div>
|
||||||
|
<div id="input" style="display: inline-block" contenteditable="true"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
161
talc-web/main.js
Normal file
161
talc-web/main.js
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
import init, * as talc from "./pkg/talc_web.js";
|
||||||
|
await init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DOM
|
||||||
|
*/
|
||||||
|
|
||||||
|
const $ = (q) => document.querySelector(q);
|
||||||
|
|
||||||
|
function newEl(tag, attrs, children) {
|
||||||
|
const el = document.createElement(tag);
|
||||||
|
for (const attr in attrs) {
|
||||||
|
el.setAttribute(attr, attrs[attr]);
|
||||||
|
}
|
||||||
|
for (const child of children) {
|
||||||
|
if (typeof(child) === "string") {
|
||||||
|
el.appendChild(document.createTextNode(child));
|
||||||
|
} else {
|
||||||
|
el.appendChild(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* History
|
||||||
|
*/
|
||||||
|
|
||||||
|
let historyEntries = [""];
|
||||||
|
let historyIndex = 0;
|
||||||
|
let currentLine = "";
|
||||||
|
|
||||||
|
function prevHistory() {
|
||||||
|
const inputEl = $("#input");
|
||||||
|
if (historyIndex === 0) {
|
||||||
|
currentLine = inputEl.innerText;
|
||||||
|
}
|
||||||
|
historyIndex = Math.min(historyIndex+1, historyEntries.length);
|
||||||
|
const text = historyEntries[historyEntries.length - historyIndex];
|
||||||
|
inputEl.innerText = text;
|
||||||
|
|
||||||
|
document.getSelection().setPosition(inputEl, inputEl.childNodes.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextHistory() {
|
||||||
|
const inputEl = $("#input");
|
||||||
|
historyIndex = Math.max(historyIndex-1, 0);
|
||||||
|
let text;
|
||||||
|
if (historyIndex === 0) {
|
||||||
|
text = currentLine;
|
||||||
|
} else {
|
||||||
|
text = historyEntries[historyEntries.length - historyIndex];
|
||||||
|
}
|
||||||
|
inputEl.innerText = text;
|
||||||
|
|
||||||
|
document.getSelection().setPosition(inputEl, inputEl.childNodes.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* REPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
function nextLine() {
|
||||||
|
const newPrompt = newEl("div", {"class": "prompt"}, []);
|
||||||
|
newPrompt.innerHTML = $("#prompt").innerHTML;
|
||||||
|
|
||||||
|
const newInput = newEl("div", {}, []);
|
||||||
|
newInput.innerHTML = $("#input").innerHTML;
|
||||||
|
|
||||||
|
$("#history").appendChild(newEl(
|
||||||
|
"div",
|
||||||
|
{"class": "input_line"},
|
||||||
|
[newPrompt, newInput]
|
||||||
|
));
|
||||||
|
|
||||||
|
$("#input").innerHTML = "";
|
||||||
|
|
||||||
|
currentLine = "";
|
||||||
|
historyIndex = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function execLine() {
|
||||||
|
const inputLine = $("#input").innerText;
|
||||||
|
nextLine();
|
||||||
|
historyEntries.push(inputLine);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const fixedInput = inputLine.replaceAll("\u00a0", " ");
|
||||||
|
const out = talc.eval_line(fixedInput);
|
||||||
|
if (out !== undefined) {
|
||||||
|
$("#history").appendChild(newEl("div", {}, [out]));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
$("#history").appendChild(newEl("div", {}, [
|
||||||
|
newEl("span", {"class": "error"}, ["Error: "]),
|
||||||
|
newEl("pre", {"class": "err_msg"}, [e.toString()])
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Input
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handleCtrlKey(event) {
|
||||||
|
switch (event.code) {
|
||||||
|
case "KeyL":
|
||||||
|
event.preventDefault();
|
||||||
|
$("#history").innerHTML = "";
|
||||||
|
break;
|
||||||
|
case "KeyC":
|
||||||
|
event.preventDefault();
|
||||||
|
nextLine();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyPressed(event) {
|
||||||
|
if (event.key === "Enter" && !event.shiftKey) {
|
||||||
|
event.preventDefault();
|
||||||
|
execLine()
|
||||||
|
} else if (event.ctrlKey) {
|
||||||
|
handleCtrlKey(event);
|
||||||
|
} else if (event.key === "ArrowUp") {
|
||||||
|
event.preventDefault();
|
||||||
|
prevHistory();
|
||||||
|
} else if (event.key === "ArrowDown") {
|
||||||
|
event.preventDefault();
|
||||||
|
nextHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.scrollTo(0, document.body.scrollHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Listeners
|
||||||
|
*/
|
||||||
|
|
||||||
|
$("#input").addEventListener("keydown", keyPressed);
|
||||||
|
$("#input").focus();
|
||||||
|
|
||||||
|
$("#terminal").addEventListener("click", (event) => {
|
||||||
|
if (event.target.id === "terminal" || event.target.id === "input") {
|
||||||
|
$("#input").focus();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Query parameter
|
||||||
|
*/
|
||||||
|
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const initialLine = urlParams.get("eval");
|
||||||
|
|
||||||
|
if (initialLine !== null) {
|
||||||
|
$("#input").innerText = initialLine;
|
||||||
|
execLine();
|
||||||
|
}
|
51
talc-web/src/lib.rs
Normal file
51
talc-web/src/lib.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
|
use talc_lang::{
|
||||||
|
compiler, parser,
|
||||||
|
symbol::{symbol, Symbol},
|
||||||
|
value::Value,
|
||||||
|
vm::Vm,
|
||||||
|
};
|
||||||
|
use wasm_bindgen::prelude::wasm_bindgen;
|
||||||
|
|
||||||
|
type BoxError = Box<dyn std::error::Error>;
|
||||||
|
|
||||||
|
struct Talc {
|
||||||
|
vm: Vm,
|
||||||
|
globals: Vec<Symbol>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Talc {
|
||||||
|
pub fn eval_line(&mut self, line: &str) -> Result<Option<String>, BoxError> {
|
||||||
|
let expr = parser::parse(line)?;
|
||||||
|
let func = compiler::compile_repl(&expr, &mut self.globals)?;
|
||||||
|
let func = Rc::new(func);
|
||||||
|
let res = self.vm.run_function(func.clone(), vec![func.into()])?;
|
||||||
|
let res_str = (res != Value::Nil).then(|| format!("{res:#}"));
|
||||||
|
self.vm.set_global(symbol!("_"), res);
|
||||||
|
Ok(res_str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_local! {
|
||||||
|
static TALC: RefCell<Talc> = {
|
||||||
|
let mut vm = Vm::new(128, Vec::new());
|
||||||
|
talc_std::load_all(&mut vm);
|
||||||
|
|
||||||
|
let globals = vec![symbol!("_")];
|
||||||
|
vm.set_global(symbol!("_"), Value::Nil);
|
||||||
|
|
||||||
|
RefCell::new(Talc { vm, globals })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(start)]
|
||||||
|
pub fn start() {
|
||||||
|
TALC.with(|_| ());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn eval_line(line: &str) -> Result<Option<String>, String> {
|
||||||
|
TALC.with_borrow_mut(|t| t.eval_line(line))
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
57
talc-web/style.css
Normal file
57
talc-web/style.css
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
body {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 14pt;
|
||||||
|
|
||||||
|
background-color: #14171d;
|
||||||
|
color: #c7c6c3;
|
||||||
|
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input_line {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#prompt {
|
||||||
|
margin-bottom: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#input:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div, pre {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#terminal {
|
||||||
|
min-height: calc(100vh - 60px - 8px);
|
||||||
|
padding: 10px;
|
||||||
|
border: 4px solid #4d4754;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #82bfb3;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited {
|
||||||
|
color: #82bfb3;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.err_msg {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: #cc5c5c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt {
|
||||||
|
color: #789ebf;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue