From e73278990c66fdd49c263b5533773f2ef62d4f7e Mon Sep 17 00:00:00 2001 From: Chris Gillespie <6572184+gillespiecd@users.noreply.github.com> Date: Fri, 4 Dec 2020 09:29:40 -0800 Subject: [PATCH] Bump Rustyline to 7.0.0 (#2776) * Bump Rustyline to 7.0.0 * Append history instead of always save * Add associated type to Hinter * Convert to using Rustyline KeyEvent * Use AcceptOrInsertLine as struct * Cargo fmt * Make convert_keyevent pub * Better naming for RL conversion --- Cargo.lock | 43 +++++------ crates/nu-cli/Cargo.toml | 2 +- crates/nu-cli/src/cli.rs | 16 ++-- crates/nu-cli/src/keybinding.rs | 114 ++++++++++++++++++----------- crates/nu-cli/src/shell/helper.rs | 1 + docs/sample_config/keybindings.yml | 18 ++--- 6 files changed, 109 insertions(+), 85 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 70ac84f067..6ebfb2d5be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1251,16 +1251,6 @@ dependencies = [ "dirs-sys", ] -[[package]] -name = "dirs-next" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf36e65a80337bea855cd4ef9b8401ffce06a7baedf2e85ec467b1ac3f6e82b6" -dependencies = [ - "cfg-if 1.0.0", - "dirs-sys-next", -] - [[package]] name = "dirs-sys" version = "0.3.5" @@ -1272,17 +1262,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "dirs-sys-next" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99de365f605554ae33f115102a02057d4fc18b01f3284d6870be0938743cfe7d" -dependencies = [ - "libc", - "redox_users", - "winapi 0.3.9", -] - [[package]] name = "doc-comment" version = "0.3.3" @@ -1562,6 +1541,16 @@ 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" @@ -4826,16 +4815,18 @@ dependencies = [ [[package]] name = "rustyline" -version = "6.3.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0d5e7b0219a3eadd5439498525d4765c59b7c993ef0c12244865cd2d988413" +checksum = "1a5f54deba50e65ee4cf786dbc37e8b3c63bdccccbcf9d3a8a9fd0c1bb7e1984" dependencies = [ - "cfg-if 0.1.10", - "dirs-next", + "bitflags", + "cfg-if 1.0.0", + "dirs 3.0.1", + "fs2", "libc", "log 0.4.11", "memchr", - "nix 0.18.0", + "nix 0.19.0", "scopeguard", "unicode-segmentation", "unicode-width", diff --git a/crates/nu-cli/Cargo.toml b/crates/nu-cli/Cargo.toml index 8db023f25f..81b4b23714 100644 --- a/crates/nu-cli/Cargo.toml +++ b/crates/nu-cli/Cargo.toml @@ -75,7 +75,7 @@ rayon = "1.4.0" regex = "1.3.9" roxmltree = "0.13.0" rust-embed = "5.6.0" -rustyline = {version = "6.3.0", optional = true} +rustyline = {version = "7.0.0", optional = true} serde = {version = "1.0.115", features = ["derive"]} serde_bytes = "0.11.5" serde_ini = "0.2.0" diff --git a/crates/nu-cli/src/cli.rs b/crates/nu-cli/src/cli.rs index 704f520caf..43b1ad0763 100644 --- a/crates/nu-cli/src/cli.rs +++ b/crates/nu-cli/src/cli.rs @@ -1,24 +1,25 @@ use crate::commands::classified::block::run_block; use crate::commands::classified::maybe_text_codec::{MaybeTextCodec, StringOrBinary}; use crate::evaluation_context::EvaluationContext; +#[cfg(feature = "rustyline-support")] +use crate::keybinding::{convert_keyevent, KeyEvent}; use crate::path::canonicalize; use crate::prelude::*; #[cfg(feature = "rustyline-support")] use crate::shell::Helper; use crate::EnvironmentSyncer; use futures_codec::FramedRead; +use log::{debug, trace}; use nu_errors::ShellError; use nu_protocol::hir::{ClassifiedCommand, Expression, InternalCommand, Literal, NamedArguments}; use nu_protocol::{Primitive, ReturnSuccess, Scope, UntaggedValue, Value}; - -use log::{debug, trace}; #[cfg(feature = "rustyline-support")] use rustyline::{ self, config::Configurer, config::{ColorMode, CompletionType, Config}, error::ReadlineError, - At, Cmd, Editor, KeyPress, Movement, Word, + At, Cmd, Editor, Movement, Word, }; use std::error::Error; use std::iter::Iterator; @@ -678,16 +679,19 @@ fn default_rustyline_editor_configuration() -> Editor { // add key bindings to move over a whole word with Ctrl+ArrowLeft and Ctrl+ArrowRight rl.bind_sequence( - KeyPress::ControlLeft, + convert_keyevent(KeyEvent::ControlLeft), Cmd::Move(Movement::BackwardWord(1, Word::Vi)), ); rl.bind_sequence( - KeyPress::ControlRight, + convert_keyevent(KeyEvent::ControlRight), Cmd::Move(Movement::ForwardWord(1, At::AfterEnd, Word::Vi)), ); // workaround for multiline-paste hang in rustyline (see https://github.com/kkawakam/rustyline/issues/202) - rl.bind_sequence(KeyPress::BracketedPasteStart, rustyline::Cmd::Noop); + rl.bind_sequence( + convert_keyevent(KeyEvent::BracketedPasteStart), + rustyline::Cmd::Noop, + ); // Let's set the defaults up front and then override them later if the user indicates // defaults taken from here https://github.com/kkawakam/rustyline/blob/2fe886c9576c1ea13ca0e5808053ad491a6fe049/src/config.rs#L150-L167 diff --git a/crates/nu-cli/src/keybinding.rs b/crates/nu-cli/src/keybinding.rs index f6b9f3f6f9..ccfa7a5be5 100644 --- a/crates/nu-cli/src/keybinding.rs +++ b/crates/nu-cli/src/keybinding.rs @@ -1,38 +1,64 @@ +use rustyline::{KeyCode, Modifiers}; use serde::{Deserialize, Serialize}; -fn convert_keypress(keypress: KeyPress) -> rustyline::KeyPress { - match keypress { - KeyPress::UnknownEscSeq => rustyline::KeyPress::UnknownEscSeq, - KeyPress::Backspace => rustyline::KeyPress::Backspace, - KeyPress::BackTab => rustyline::KeyPress::BackTab, - KeyPress::BracketedPasteStart => rustyline::KeyPress::BracketedPasteStart, - KeyPress::BracketedPasteEnd => rustyline::KeyPress::BracketedPasteEnd, - KeyPress::Char(c) => rustyline::KeyPress::Char(c), - KeyPress::ControlDown => rustyline::KeyPress::ControlDown, - KeyPress::ControlLeft => rustyline::KeyPress::ControlLeft, - KeyPress::ControlRight => rustyline::KeyPress::ControlRight, - KeyPress::ControlUp => rustyline::KeyPress::ControlUp, - KeyPress::Ctrl(c) => rustyline::KeyPress::Ctrl(c), - KeyPress::Delete => rustyline::KeyPress::Delete, - KeyPress::Down => rustyline::KeyPress::Down, - KeyPress::End => rustyline::KeyPress::End, - KeyPress::Enter => rustyline::KeyPress::Enter, - KeyPress::Esc => rustyline::KeyPress::Esc, - KeyPress::F(u) => rustyline::KeyPress::F(u), - KeyPress::Home => rustyline::KeyPress::Home, - KeyPress::Insert => rustyline::KeyPress::Insert, - KeyPress::Left => rustyline::KeyPress::Left, - KeyPress::Meta(c) => rustyline::KeyPress::Meta(c), - KeyPress::Null => rustyline::KeyPress::Null, - KeyPress::PageDown => rustyline::KeyPress::PageDown, - KeyPress::PageUp => rustyline::KeyPress::PageUp, - KeyPress::Right => rustyline::KeyPress::Right, - KeyPress::ShiftDown => rustyline::KeyPress::ShiftDown, - KeyPress::ShiftLeft => rustyline::KeyPress::ShiftLeft, - KeyPress::ShiftRight => rustyline::KeyPress::ShiftRight, - KeyPress::ShiftUp => rustyline::KeyPress::ShiftUp, - KeyPress::Tab => rustyline::KeyPress::Tab, - KeyPress::Up => rustyline::KeyPress::Up, +pub fn convert_keyevent(key_event: KeyEvent) -> rustyline::KeyEvent { + match key_event { + KeyEvent::UnknownEscSeq => convert_to_rl_keyevent(rustyline::KeyCode::UnknownEscSeq, None), + KeyEvent::Backspace => convert_to_rl_keyevent(rustyline::KeyCode::Backspace, None), + KeyEvent::BackTab => convert_to_rl_keyevent(rustyline::KeyCode::BackTab, None), + KeyEvent::BracketedPasteStart => { + convert_to_rl_keyevent(rustyline::KeyCode::BracketedPasteStart, None) + } + KeyEvent::BracketedPasteEnd => { + convert_to_rl_keyevent(rustyline::KeyCode::BracketedPasteEnd, None) + } + KeyEvent::Char(c) => convert_to_rl_keyevent(rustyline::KeyCode::Char(c), None), + KeyEvent::ControlDown => { + convert_to_rl_keyevent(rustyline::KeyCode::Down, Some(Modifiers::CTRL)) + } + KeyEvent::ControlLeft => { + convert_to_rl_keyevent(rustyline::KeyCode::Left, Some(Modifiers::CTRL)) + } + KeyEvent::ControlRight => { + convert_to_rl_keyevent(rustyline::KeyCode::Right, Some(Modifiers::CTRL)) + } + KeyEvent::ControlUp => { + convert_to_rl_keyevent(rustyline::KeyCode::Up, Some(Modifiers::CTRL)) + } + KeyEvent::Ctrl(c) => rustyline::KeyEvent::ctrl(c), + KeyEvent::Delete => convert_to_rl_keyevent(rustyline::KeyCode::Delete, None), + KeyEvent::Down => convert_to_rl_keyevent(rustyline::KeyCode::Down, None), + KeyEvent::End => convert_to_rl_keyevent(rustyline::KeyCode::End, None), + KeyEvent::Enter => convert_to_rl_keyevent(rustyline::KeyCode::Enter, None), + KeyEvent::Esc => convert_to_rl_keyevent(rustyline::KeyCode::Esc, None), + KeyEvent::F(u) => convert_to_rl_keyevent(rustyline::KeyCode::F(u), None), + KeyEvent::Home => convert_to_rl_keyevent(rustyline::KeyCode::Home, None), + KeyEvent::Insert => convert_to_rl_keyevent(rustyline::KeyCode::Insert, None), + KeyEvent::Left => convert_to_rl_keyevent(rustyline::KeyCode::Left, None), + KeyEvent::Meta(c) => rustyline::KeyEvent::new(c, Modifiers::NONE), + KeyEvent::Null => convert_to_rl_keyevent(rustyline::KeyCode::Null, None), + KeyEvent::PageDown => convert_to_rl_keyevent(rustyline::KeyCode::PageDown, None), + KeyEvent::PageUp => convert_to_rl_keyevent(rustyline::KeyCode::PageUp, None), + KeyEvent::Right => convert_to_rl_keyevent(rustyline::KeyCode::Right, None), + KeyEvent::ShiftDown => { + convert_to_rl_keyevent(rustyline::KeyCode::Down, Some(Modifiers::SHIFT)) + } + KeyEvent::ShiftLeft => { + convert_to_rl_keyevent(rustyline::KeyCode::Left, Some(Modifiers::SHIFT)) + } + KeyEvent::ShiftRight => { + convert_to_rl_keyevent(rustyline::KeyCode::Right, Some(Modifiers::SHIFT)) + } + KeyEvent::ShiftUp => convert_to_rl_keyevent(rustyline::KeyCode::Up, Some(Modifiers::SHIFT)), + KeyEvent::Tab => convert_to_rl_keyevent(rustyline::KeyCode::Tab, None), + KeyEvent::Up => convert_to_rl_keyevent(rustyline::KeyCode::Up, None), + } +} + +fn convert_to_rl_keyevent(key_event: KeyCode, modifier: Option) -> rustyline::KeyEvent { + rustyline::KeyEvent { + 0: key_event, + 1: modifier.unwrap_or(Modifiers::NONE), } } @@ -97,7 +123,9 @@ fn convert_cmd(cmd: Cmd) -> rustyline::Cmd { match cmd { Cmd::Abort => rustyline::Cmd::Abort, Cmd::AcceptLine => rustyline::Cmd::AcceptLine, - Cmd::AcceptOrInsertLine => rustyline::Cmd::AcceptOrInsertLine, + Cmd::AcceptOrInsertLine => rustyline::Cmd::AcceptOrInsertLine { + accept_in_the_middle: false, + }, Cmd::BeginningOfHistory => rustyline::Cmd::BeginningOfHistory, Cmd::CapitalizeWord => rustyline::Cmd::CapitalizeWord, Cmd::ClearScreen => rustyline::Cmd::ClearScreen, @@ -140,18 +168,18 @@ fn convert_cmd(cmd: Cmd) -> rustyline::Cmd { } } -fn convert_keybinding(keybinding: Keybinding) -> (rustyline::KeyPress, rustyline::Cmd) { +fn convert_keybinding(keybinding: Keybinding) -> (rustyline::KeyEvent, rustyline::Cmd) { ( - convert_keypress(keybinding.key), + convert_keyevent(keybinding.key), convert_cmd(keybinding.binding), ) } #[derive(Serialize, Deserialize, Debug, Clone)] -pub enum KeyPress { +pub enum KeyEvent { /// Unsupported escape sequence (on unix platform) UnknownEscSeq, - /// ⌫ or `KeyPress::Ctrl('H')` + /// ⌫ or `KeyEvent::Ctrl('H')` Backspace, /// ⇤ (usually Shift-Tab) BackTab, @@ -177,9 +205,9 @@ pub enum KeyPress { Down, /// ⇲ End, - /// ↵ or `KeyPress::Ctrl('M')` + /// ↵ or `KeyEvent::Ctrl('M')` Enter, - /// Escape or `KeyPress::Ctrl('[')` + /// Escape or `KeyEvent::Ctrl('[')` Esc, /// Function key F(u8), @@ -191,7 +219,7 @@ pub enum KeyPress { Left, /// Escape-char or Alt-char Meta(char), - /// `KeyPress::Char('\0')` + /// `KeyEvent::Char('\0')` Null, /// ⇟ PageDown, @@ -207,7 +235,7 @@ pub enum KeyPress { ShiftRight, /// Shift-↑ ShiftUp, - /// ⇥ or `KeyPress::Ctrl('I')` + /// ⇥ or `KeyEvent::Ctrl('I')` Tab, /// ↑ arrow key Up, @@ -399,7 +427,7 @@ pub type RepeatCount = usize; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Keybinding { - key: KeyPress, + key: KeyEvent, binding: Cmd, } diff --git a/crates/nu-cli/src/shell/helper.rs b/crates/nu-cli/src/shell/helper.rs index 3e8995bc3d..de1bd9bc70 100644 --- a/crates/nu-cli/src/shell/helper.rs +++ b/crates/nu-cli/src/shell/helper.rs @@ -62,6 +62,7 @@ impl rustyline::completion::Completer for Helper { } impl rustyline::hint::Hinter for Helper { + type Hint = String; fn hint(&self, line: &str, pos: usize, ctx: &rustyline::Context<'_>) -> Option { self.hinter.as_ref().and_then(|h| h.hint(line, pos, &ctx)) } diff --git a/docs/sample_config/keybindings.yml b/docs/sample_config/keybindings.yml index 65178171c2..6856e8345b 100644 --- a/docs/sample_config/keybindings.yml +++ b/docs/sample_config/keybindings.yml @@ -74,7 +74,7 @@ Enter: binding: AcceptLine: - + # Next match from history - key: Down: #Down Arrow Key @@ -150,7 +150,7 @@ binding: Undo: 1 -# KeyPress::UnknownEscSeq => Cmd::Noop, +# KeyEvent::UnknownEscSeq => Cmd::Noop, - key: UnknownEscSeq: binding: @@ -161,7 +161,7 @@ ########################################################## # /// Unsupported escape sequence (on unix platform) # UnknownEscSeq, -# /// ⌫ or `KeyPress::Ctrl('H')` +# /// ⌫ or `KeyEvent::Ctrl('H')` # Backspace, # /// ⇤ (usually Shift-Tab) # BackTab, @@ -187,9 +187,9 @@ # Down, # /// ⇲ # End, -# /// ↵ or `KeyPress::Ctrl('M')` +# /// ↵ or `KeyEvent::Ctrl('M')` # Enter, -# /// Escape or `KeyPress::Ctrl('[')` +# /// Escape or `KeyEvent::Ctrl('[')` # Esc, # /// Function key # F(u8), @@ -201,7 +201,7 @@ # Left, # /// Escape-char or Alt-char # Meta(char), -# /// `KeyPress::Char('\0')` +# /// `KeyEvent::Char('\0')` # Null, # /// ⇟ # PageDown, @@ -217,7 +217,7 @@ # ShiftRight, # /// Shift-↑ # ShiftUp, -# /// ⇥ or `KeyPress::Ctrl('I')` +# /// ⇥ or `KeyEvent::Ctrl('I')` # Tab, # /// ↑ arrow key # Up, @@ -330,7 +330,7 @@ # BeforeEnd, # /// After end of word. # AfterEnd, - + ########################################################## # Possible options for Anchor ########################################################## @@ -381,4 +381,4 @@ # /// beginning-of-buffer # BeginningOfBuffer, # /// end-of-buffer -# EndOfBuffer, \ No newline at end of file +# EndOfBuffer,