diff --git a/Cargo.lock b/Cargo.lock index fadb71dc14..2bfce3e185 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1686,6 +1686,16 @@ dependencies = [ "instant", ] +[[package]] +name = "fd-lock" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0010f02effd88c702318c5dde0463206be67495d0b4d906ba7c0a8f166cc7f06" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "filesize" version = "0.2.0" @@ -1766,16 +1776,6 @@ dependencies = [ "percent-encoding 2.1.0", ] -[[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 = "fs_extra" version = "1.2.0" @@ -5349,13 +5349,14 @@ checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd" [[package]] name = "rustyline" version = "8.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e1b597fcd1eeb1d6b25b493538e5aa19629eb08932184b85fef931ba87e893" +source = "git+https://github.com/kkawakam/rustyline.git#795867591dc72c2be172af45aabd1c6ecd579225" dependencies = [ "bitflags", "cfg-if 1.0.0", + "clipboard-win", "dirs-next", - "fs2", + "error-code", + "fd-lock", "libc", "log 0.4.14", "memchr", diff --git a/crates/nu-cli/Cargo.toml b/crates/nu-cli/Cargo.toml index 60be56763f..add2c671df 100644 --- a/crates/nu-cli/Cargo.toml +++ b/crates/nu-cli/Cargo.toml @@ -76,7 +76,7 @@ rayon = "1.5.0" regex = "1.4.3" roxmltree = "0.14.0" rust-embed = "5.9.0" -rustyline = { version = "8.0.0", optional = true } +rustyline = { git = "https://github.com/kkawakam/rustyline.git", optional = true } serde = { version = "1.0.123", features = ["derive"] } serde_bytes = "0.11.5" serde_ini = "0.2.0" diff --git a/crates/nu-cli/src/line_editor.rs b/crates/nu-cli/src/line_editor.rs index 06624df8ad..0f5baa69dd 100644 --- a/crates/nu-cli/src/line_editor.rs +++ b/crates/nu-cli/src/line_editor.rs @@ -19,7 +19,8 @@ use rustyline::{ config::Configurer, config::{ColorMode, CompletionType, Config}, error::ReadlineError, - At, Cmd, Editor, Movement, Word, + line_buffer::LineBuffer, + At, Cmd, ConditionalEventHandler, Editor, EventHandler, Movement, Word, }; #[cfg(feature = "rustyline-support")] @@ -36,6 +37,34 @@ pub fn convert_rustyline_result_to_string(input: Result) } } +#[derive(Clone)] +#[cfg(feature = "rustyline-support")] +struct PartialCompleteHintHandler; + +#[cfg(feature = "rustyline-support")] +impl ConditionalEventHandler for PartialCompleteHintHandler { + fn handle( + &self, + _evt: &rustyline::Event, + _n: rustyline::RepeatCount, + _positive: bool, + ctx: &rustyline::EventContext, + ) -> Option { + Some(match ctx.hint_text() { + Some(hint_text) if ctx.pos() == ctx.line().len() => { + let mut line_buffer = LineBuffer::with_capacity(hint_text.len()); + line_buffer.update(hint_text, 0); + line_buffer.move_to_next_word(At::AfterEnd, Word::Vi, 1); + + let text = hint_text[0..line_buffer.pos()].to_string(); + + Cmd::Insert(1, text) + } + _ => Cmd::Move(Movement::ForwardWord(1, At::AfterEnd, Word::Vi)), + }) + } +} + #[cfg(feature = "rustyline-support")] pub fn default_rustyline_editor_configuration() -> Editor { #[cfg(windows)] @@ -56,7 +85,7 @@ pub fn default_rustyline_editor_configuration() -> Editor { ); rl.bind_sequence( convert_keyevent(KeyEvent::ControlRight), - Cmd::Move(Movement::ForwardWord(1, At::AfterEnd, Word::Vi)), + EventHandler::Conditional(Box::new(PartialCompleteHintHandler)), ); // workaround for multiline-paste hang in rustyline (see https://github.com/kkawakam/rustyline/issues/202) diff --git a/crates/nu-command/Cargo.toml b/crates/nu-command/Cargo.toml index 721f13b568..1782e05468 100644 --- a/crates/nu-command/Cargo.toml +++ b/crates/nu-command/Cargo.toml @@ -74,7 +74,7 @@ rayon = "1.5.0" regex = "1.4.3" roxmltree = "0.14.0" rust-embed = "5.9.0" -rustyline = { version = "8.0.0", optional = true } +rustyline = { git = "https://github.com/kkawakam/rustyline.git", optional = true } serde = { version = "1.0.123", features = ["derive"] } serde_bytes = "0.11.5" serde_ini = "0.2.0"