mirror of
https://github.com/lune-org/lune.git
synced 2025-05-04 10:43:57 +01:00
feat(repl): initial implementation
This commit is contained in:
parent
2867ccb9b8
commit
bd594e6f07
3 changed files with 209 additions and 4 deletions
115
Cargo.lock
generated
115
Cargo.lock
generated
|
@ -367,6 +367,17 @@ version = "0.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
|
||||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
version = "4.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362"
|
||||
dependencies = [
|
||||
"error-code",
|
||||
"str-buf",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.0"
|
||||
|
@ -545,6 +556,12 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "endian-type"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.9.3"
|
||||
|
@ -607,12 +624,33 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "error-code"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"str-buf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
|
||||
|
||||
[[package]]
|
||||
name = "fd-lock"
|
||||
version = "3.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef033ed5e9bad94e55838ca0ca906db0e043f517adda0c8b79c7a8c66c93c1b5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"rustix",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.26"
|
||||
|
@ -793,6 +831,15 @@ version = "0.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
|
||||
dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.9"
|
||||
|
@ -1042,6 +1089,7 @@ dependencies = [
|
|||
"env_logger 0.10.0",
|
||||
"futures-util",
|
||||
"glam",
|
||||
"home",
|
||||
"hyper",
|
||||
"hyper-tungstenite",
|
||||
"include_dir",
|
||||
|
@ -1060,6 +1108,7 @@ dependencies = [
|
|||
"rbx_xml",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"rustyline",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
|
@ -1159,6 +1208,27 @@ dependencies = [
|
|||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nibble_vec"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.16"
|
||||
|
@ -1362,6 +1432,16 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "radix_trie"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd"
|
||||
dependencies = [
|
||||
"endian-type",
|
||||
"nibble_vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
|
@ -1718,6 +1798,29 @@ dependencies = [
|
|||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustyline"
|
||||
version = "12.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "994eca4bca05c87e86e15d90fc7a91d1be64b4482b38cb2d27474568fe7c9db9"
|
||||
dependencies = [
|
||||
"bitflags 2.3.3",
|
||||
"cfg-if",
|
||||
"clipboard-win",
|
||||
"fd-lock",
|
||||
"home",
|
||||
"libc",
|
||||
"log",
|
||||
"memchr",
|
||||
"nix",
|
||||
"radix_trie",
|
||||
"scopeguard",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
"utf8parse",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.15"
|
||||
|
@ -1973,6 +2076,12 @@ version = "0.1.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
|
||||
|
||||
[[package]]
|
||||
name = "str-buf"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
|
@ -2338,6 +2447,12 @@ dependencies = [
|
|||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
|
|
|
@ -74,6 +74,7 @@ lz4_flex = "0.11"
|
|||
pin-project = "1.0"
|
||||
os_str_bytes = "6.4"
|
||||
urlencoding = "2.1"
|
||||
home = "0.5.5"
|
||||
|
||||
### RUNTIME
|
||||
|
||||
|
@ -119,6 +120,7 @@ regex = { optional = true, version = "1.7", default-features = false, features =
|
|||
"std",
|
||||
"unicode-perl",
|
||||
] }
|
||||
rustyline = "12.0.0"
|
||||
|
||||
### ROBLOX
|
||||
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
use std::{fmt::Write as _, process::ExitCode};
|
||||
use std::{
|
||||
fmt::Write as _,
|
||||
io::ErrorKind,
|
||||
path::PathBuf,
|
||||
process::{exit, ExitCode},
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use clap::{CommandFactory, Parser};
|
||||
use rustyline::{error::ReadlineError, DefaultEditor};
|
||||
|
||||
use lune::Lune;
|
||||
use tokio::{
|
||||
|
@ -148,10 +154,92 @@ impl Cli {
|
|||
}
|
||||
// HACK: We know that we didn't get any arguments here but since
|
||||
// script_path is optional clap will not error on its own, to fix
|
||||
// we will duplicate the cli command and make arguments required,
|
||||
// which will then fail and print out the normal help message
|
||||
// we will duplicate the CLI command and fetch the version of
|
||||
// lune to display
|
||||
let cmd = Cli::command();
|
||||
cmd.arg_required_else_help(true).get_matches();
|
||||
let lune_version = cmd.get_version();
|
||||
|
||||
// The version is mandatory and will always exist
|
||||
println!("Lune v{}", lune_version.unwrap());
|
||||
|
||||
let lune_instance = Lune::new();
|
||||
|
||||
let mut repl = DefaultEditor::new()?;
|
||||
|
||||
match repl.load_history(&(|| -> PathBuf {
|
||||
let dir_opt = home::home_dir();
|
||||
|
||||
if let Some(dir) = dir_opt {
|
||||
dir.join(".lune_history")
|
||||
} else {
|
||||
eprintln!("Failed to find user home directory, abort!");
|
||||
// Doesn't feel right to exit directly with a exit code of 1
|
||||
// Lmk if there is a better way of doing this
|
||||
exit(1);
|
||||
}
|
||||
})()) {
|
||||
Ok(_) => (),
|
||||
Err(err) => {
|
||||
match err {
|
||||
err => {
|
||||
if let ReadlineError::Io(io_err) = err {
|
||||
if io_err.kind() == ErrorKind::NotFound {
|
||||
std::fs::write(
|
||||
// We know for sure that the home dir already exists
|
||||
home::home_dir().unwrap().join(".lune_history"),
|
||||
String::new(),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eprintln!("WARN: Failed to load REPL history")
|
||||
}
|
||||
};
|
||||
|
||||
let mut interrupt_counter = 0u32;
|
||||
|
||||
loop {
|
||||
let mut source_code = String::new();
|
||||
|
||||
match repl.readline("> ") {
|
||||
Ok(code) => {
|
||||
source_code = code;
|
||||
|
||||
// If source code eval was requested, we reset the counter
|
||||
interrupt_counter = 0;
|
||||
}
|
||||
|
||||
Err(ReadlineError::Interrupted) => {
|
||||
// HACK: We actually want the user to do ^C twice to exit,
|
||||
// but the user would need to ^C one more time even after
|
||||
// the check passes, so we check for 1 instead of 2
|
||||
if interrupt_counter != 1 {
|
||||
println!("Interrupt: ^C again to exit");
|
||||
|
||||
// Increment the counter
|
||||
interrupt_counter += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(ReadlineError::Eof) => break,
|
||||
Err(err) => {
|
||||
eprintln!("REPL ERROR: {}", err.to_string());
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
let eval_result = lune_instance.run("REPL", source_code).await;
|
||||
|
||||
match eval_result {
|
||||
Ok(_) => (),
|
||||
Err(err) => eprintln!("{}", err),
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(ExitCode::SUCCESS);
|
||||
}
|
||||
// Figure out if we should read from stdin or from a file,
|
||||
// reading from stdin is marked by passing a single "-"
|
||||
|
|
Loading…
Add table
Reference in a new issue