Merge pull request #1263 from rtfeldman/basile/multiline-prompt

Multiline prompt in REPL
This commit is contained in:
Richard Feldman 2021-05-03 21:17:17 -04:00 committed by GitHub
commit 83a4f259f5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 42 deletions

61
Cargo.lock generated
View file

@ -845,9 +845,9 @@ dependencies = [
[[package]]
name = "dirs-next"
version = "2.0.0"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
checksum = "cf36e65a80337bea855cd4ef9b8401ffce06a7baedf2e85ec467b1ac3f6e82b6"
dependencies = [
"cfg-if 1.0.0",
"dirs-sys-next",
@ -992,16 +992,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "fs2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
dependencies = [
"libc",
"winapi 0.3.9",
]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
@ -1949,6 +1939,19 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "nix"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
dependencies = [
"bitflags",
"cc",
"cfg-if 0.1.10",
"libc",
"void",
]
[[package]]
name = "nix"
version = "0.18.0"
@ -1961,18 +1964,6 @@ dependencies = [
"libc",
]
[[package]]
name = "nix"
version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2"
dependencies = [
"bitflags",
"cc",
"cfg-if 1.0.0",
"libc",
]
[[package]]
name = "nix"
version = "0.20.0"
@ -3392,18 +3383,15 @@ dependencies = [
[[package]]
name = "rustyline"
version = "7.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8227301bfc717136f0ecbd3d064ba8199e44497a0bdd46bb01ede4387cfd2cec"
version = "6.2.0"
source = "git+https://github.com/rtfeldman/rustyline?tag=prompt-fix#a6b8a20d2bf5c3793d7367848be2f4afec2f0d99"
dependencies = [
"bitflags",
"cfg-if 1.0.0",
"cfg-if 0.1.10",
"dirs-next",
"fs2",
"libc",
"log",
"memchr",
"nix 0.19.1",
"nix 0.17.0",
"scopeguard",
"unicode-segmentation",
"unicode-width",
@ -3413,9 +3401,8 @@ dependencies = [
[[package]]
name = "rustyline-derive"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db9dfbf470021de34cfaf6983067f460ea19164934a7c2d4b92eec0968eb95f1"
version = "0.3.1"
source = "git+https://github.com/rtfeldman/rustyline?tag=prompt-fix#a6b8a20d2bf5c3793d7367848be2f4afec2f0d99"
dependencies = [
"quote 1.0.9",
"syn 1.0.65",
@ -4060,6 +4047,12 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "vte"
version = "0.3.3"

View file

@ -53,8 +53,8 @@ roc_editor = { path = "../editor" }
# TODO switch to clap 3.0.0 once it's out. Tried adding clap = "~3.0.0-beta.1" and cargo wouldn't accept it
clap = { git = "https://github.com/rtfeldman/clap", branch = "master" }
const_format = "0.2.8"
rustyline = "7.0.0"
rustyline-derive = "0.4.0"
rustyline = { git = "https://github.com/rtfeldman/rustyline", tag = "prompt-fix" }
rustyline-derive = { git = "https://github.com/rtfeldman/rustyline", tag = "prompt-fix" }
im = "14" # im and im-rc should always have the same version!
im-rc = "14" # im and im-rc should always have the same version!
bumpalo = { version = "3.2", features = ["collections"] }

View file

@ -3,9 +3,11 @@ use gen::{gen_and_eval, ReplOutput};
use roc_gen::llvm::build::OptLevel;
use roc_parse::parser::{EExpr, SyntaxError};
use rustyline::error::ReadlineError;
use rustyline::highlight::{Highlighter, PromptInfo};
use rustyline::validate::{self, ValidationContext, ValidationResult, Validator};
use rustyline::Editor;
use rustyline_derive::{Completer, Helper, Highlighter, Hinter};
use rustyline_derive::{Completer, Helper, Hinter};
use std::borrow::Cow;
use std::io;
use target_lexicon::Triple;
@ -26,11 +28,12 @@ pub const WELCOME_MESSAGE: &str = concatcp!(
);
pub const INSTRUCTIONS: &str = "Enter an expression, or :help, or :exit/:q.\n";
pub const PROMPT: &str = concatcp!("\n", BLUE, "»", END_COL, " ");
pub const CONT_PROMPT: &str = concatcp!(BLUE, "", END_COL, " ");
mod eval;
mod gen;
#[derive(Completer, Helper, Hinter, Highlighter)]
#[derive(Completer, Helper, Hinter)]
struct ReplHelper {
validator: InputValidator,
pending_src: String,
@ -45,6 +48,24 @@ impl ReplHelper {
}
}
impl Highlighter for ReplHelper {
fn has_continuation_prompt(&self) -> bool {
true
}
fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
prompt: &'p str,
info: PromptInfo<'_>,
) -> Cow<'b, str> {
if info.line_no() > 0 {
CONT_PROMPT.into()
} else {
prompt.into()
}
}
}
impl Validator for ReplHelper {
fn validate(
&self,
@ -72,10 +93,12 @@ impl Validator for InputValidator {
Ok(ValidationResult::Incomplete)
} else {
let arena = bumpalo::Bump::new();
match roc_parse::test_helpers::parse_expr_with(&arena, ctx.input()) {
let state = roc_parse::parser::State::new(ctx.input().trim().as_bytes());
match roc_parse::expr::parse_loc_expr(0, &arena, state) {
// Special case some syntax errors to allow for multi-line inputs
Err(SyntaxError::Expr(EExpr::DefMissingFinalExpr(_, _)))
| Err(SyntaxError::Expr(EExpr::DefMissingFinalExpr2(_, _, _))) => {
Err((_, EExpr::DefMissingFinalExpr(_, _), _))
| Err((_, EExpr::DefMissingFinalExpr2(_, _, _), _)) => {
Ok(ValidationResult::Incomplete)
}
_ => Ok(ValidationResult::Valid(None)),

View file

@ -1360,7 +1360,7 @@ fn parse_expr_end<'a>(
}
}
fn parse_loc_expr<'a>(
pub fn parse_loc_expr<'a>(
min_indent: u16,
arena: &'a Bump,
state: State<'a>,