From 645314b21583c8e1b582887dec5342dc942f1927 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Sat, 29 Feb 2020 09:19:43 -0600 Subject: [PATCH] Move readline.rs into the vm crate --- Cargo.lock | 2 + Cargo.toml | 1 + src/shell.rs | 9 ++-- src/shell/{rustyline_helper.rs => helper.rs} | 48 +++++++++--------- vm/Cargo.toml | 1 + vm/src/lib.rs | 1 + {src/shell => vm/src}/readline.rs | 51 +++++++++++--------- 7 files changed, 62 insertions(+), 51 deletions(-) rename src/shell/{rustyline_helper.rs => helper.rs} (82%) rename {src/shell => vm/src}/readline.rs (79%) diff --git a/Cargo.lock b/Cargo.lock index cc9f4166f9..50b3be9a17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1420,6 +1420,7 @@ dependencies = [ name = "rustpython" version = "0.1.1" dependencies = [ + "cfg-if", "clap", "cpython", "dirs 2.0.2", @@ -1539,6 +1540,7 @@ dependencies = [ "rustpython-compiler", "rustpython-derive", "rustpython-parser", + "rustyline", "serde", "serde_json", "sha-1", diff --git a/Cargo.toml b/Cargo.toml index d26f57e996..ee3ec28149 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ rustpython-parser = {path = "parser", version = "0.1.1"} rustpython-vm = {path = "vm", version = "0.1.1"} dirs = "2.0" num-traits = "0.2.8" +cfg-if = "0.1" flame = { version = "0.2", optional = true } flamescope = { version = "0.1", optional = true } diff --git a/src/shell.rs b/src/shell.rs index aa31b3949e..7371c34efa 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -1,9 +1,8 @@ -mod readline; -#[cfg(not(target_os = "wasi"))] -mod rustyline_helper; +mod helper; use rustpython_compiler::{compile, error::CompileError, error::CompileErrorType}; use rustpython_parser::error::ParseErrorType; +use rustpython_vm::readline::{Readline, ReadlineResult}; use rustpython_vm::{ exceptions::{print_exception, PyBaseExceptionRef}, obj::objtype, @@ -12,8 +11,6 @@ use rustpython_vm::{ VirtualMachine, }; -use readline::{Readline, ReadlineResult}; - enum ShellExecResult { Ok, PyErr(PyBaseExceptionRef), @@ -49,7 +46,7 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> { crate_version!() ); - let mut repl = Readline::new(vm, scope.clone()); + let mut repl = Readline::new(helper::ShellHelper::new(vm, scope.clone())); let mut full_input = String::new(); // Retrieve a `history_path_str` dependent on the OS diff --git a/src/shell/rustyline_helper.rs b/src/shell/helper.rs similarity index 82% rename from src/shell/rustyline_helper.rs rename to src/shell/helper.rs index 45b3ca3246..30900d1da8 100644 --- a/src/shell/rustyline_helper.rs +++ b/src/shell/helper.rs @@ -2,10 +2,6 @@ use rustpython_vm::obj::objstr::PyStringRef; use rustpython_vm::pyobject::{PyIterable, PyResult, TryFromObject}; use rustpython_vm::scope::{NameProtocol, Scope}; use rustpython_vm::VirtualMachine; -use rustyline::{ - completion::Completer, highlight::Highlighter, hint::Hinter, validate::Validator, Context, - Helper, -}; pub struct ShellHelper<'vm> { vm: &'vm VirtualMachine, @@ -146,24 +142,32 @@ impl<'vm> ShellHelper<'vm> { } } -impl Completer for ShellHelper<'_> { - type Candidate = String; +cfg_if::cfg_if! { + if #[cfg(not(target_os = "wasi"))] { + use rustyline::{ + completion::Completer, highlight::Highlighter, hint::Hinter, validate::Validator, Context, + Helper, + }; + impl Completer for ShellHelper<'_> { + type Candidate = String; - fn complete( - &self, - line: &str, - pos: usize, - _ctx: &Context, - ) -> rustyline::Result<(usize, Vec)> { - Ok(self - .complete_opt(&line[0..pos]) - // as far as I can tell, there's no better way to do both completion - // and indentation (or even just indentation) - .unwrap_or_else(|| (line.len(), vec!["\t".to_owned()]))) + fn complete( + &self, + line: &str, + pos: usize, + _ctx: &Context, + ) -> rustyline::Result<(usize, Vec)> { + Ok(self + .complete_opt(&line[0..pos]) + // as far as I can tell, there's no better way to do both completion + // and indentation (or even just indentation) + .unwrap_or_else(|| (line.len(), vec!["\t".to_owned()]))) + } + } + + impl Hinter for ShellHelper<'_> {} + impl Highlighter for ShellHelper<'_> {} + impl Validator for ShellHelper<'_> {} + impl Helper for ShellHelper<'_> {} } } - -impl Hinter for ShellHelper<'_> {} -impl Highlighter for ShellHelper<'_> {} -impl Validator for ShellHelper<'_> {} -impl Helper for ShellHelper<'_> {} diff --git a/vm/Cargo.toml b/vm/Cargo.toml index a026f9d4ab..f0e9a89e59 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -89,6 +89,7 @@ gethostname = "0.2.0" subprocess = "0.2.2" num_cpus = "1" socket2 = { version = "0.3", features = ["unix"] } +rustyline = "6.0" [target.'cfg(not(any(target_arch = "wasm32", target_os = "redox")))'.dependencies] dns-lookup = "1.0" diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 68d7403e29..6e791e264f 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -70,6 +70,7 @@ pub mod obj; pub mod py_serde; mod pyhash; pub mod pyobject; +pub mod readline; pub mod scope; mod sequence; pub mod slots; diff --git a/src/shell/readline.rs b/vm/src/readline.rs similarity index 79% rename from src/shell/readline.rs rename to vm/src/readline.rs index 3eb9d6e2c3..35ce10db77 100644 --- a/src/shell/readline.rs +++ b/vm/src/readline.rs @@ -1,8 +1,6 @@ use std::io; use std::path::Path; -use rustpython_vm::{scope::Scope, VirtualMachine}; - type OtherError = Box; type OtherResult = Result; @@ -19,13 +17,16 @@ pub enum ReadlineResult { mod basic_readline { use super::*; - pub struct BasicReadline<'vm> { - vm: &'vm VirtualMachine, + pub trait Helper {} + impl Helper for T {} + + pub struct Readline { + helper: H, } - impl<'vm> BasicReadline<'vm> { - pub fn new(vm: &'vm VirtualMachine, _scope: Scope) -> Self { - BasicReadline { vm } + impl Readline { + pub fn new(helper: H) -> Self { + Readline { helper } } pub fn load_history(&mut self, _path: &Path) -> OtherResult<()> { @@ -60,16 +61,19 @@ mod basic_readline { } } -#[cfg(not(target_os = "wasi"))] +#[cfg(not(target_arch = "wasm32"))] mod rustyline_readline { - use super::{super::rustyline_helper::ShellHelper, *}; + use super::*; - pub struct RustylineReadline<'vm> { - repl: rustyline::Editor>, + pub trait Helper: rustyline::Helper {} + impl Helper for T {} + + pub struct Readline { + repl: rustyline::Editor, } - impl<'vm> RustylineReadline<'vm> { - pub fn new(vm: &'vm VirtualMachine, scope: Scope) -> Self { + impl Readline { + pub fn new(helper: H) -> Self { use rustyline::{At, Cmd, CompletionType, Config, Editor, KeyPress, Movement, Word}; let mut repl = Editor::with_config( Config::builder() @@ -85,8 +89,8 @@ mod rustyline_readline { KeyPress::ControlRight, Cmd::Move(Movement::ForwardWord(1, At::AfterEnd, Word::Vi)), ); - repl.set_helper(Some(ShellHelper::new(vm, scope))); - RustylineReadline { repl } + repl.set_helper(Some(helper)); + Readline { repl } } pub fn load_history(&mut self, path: &Path) -> OtherResult<()> { @@ -126,17 +130,18 @@ mod rustyline_readline { } } -#[cfg(target_os = "wasi")] -type ReadlineInner<'vm> = basic_readline::BasicReadline<'vm>; +#[cfg(target_arch = "wasm32")] +use basic_readline as readline_inner; +#[cfg(not(target_arch = "wasm32"))] +use rustyline_readline as readline_inner; -#[cfg(not(target_os = "wasi"))] -type ReadlineInner<'vm> = rustyline_readline::RustylineReadline<'vm>; +pub use readline_inner::Helper; -pub struct Readline<'vm>(ReadlineInner<'vm>); +pub struct Readline(readline_inner::Readline); -impl<'vm> Readline<'vm> { - pub fn new(vm: &'vm VirtualMachine, scope: Scope) -> Self { - Readline(ReadlineInner::new(vm, scope)) +impl Readline { + pub fn new(helper: H) -> Self { + Readline(readline_inner::Readline::new(helper)) } pub fn load_history(&mut self, path: &Path) -> OtherResult<()> { self.0.load_history(path)