diff --git a/Cargo.lock b/Cargo.lock index cb26eb698..6ae0dc0db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1164,7 +1164,7 @@ version = "3.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c15b8ec3b5755a188c141c1f6a98e76de31b936209bf066b647979e2a84764a9" dependencies = [ - "nix 0.20.0", + "nix", "winapi 0.3.9", ] @@ -1326,16 +1326,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-next" version = "2.0.0" @@ -1514,6 +1504,12 @@ dependencies = [ "cfg-if 1.0.0", ] +[[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.7.1" @@ -2995,6 +2991,15 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec 1.6.1", +] + [[package]] name = "nipper" version = "0.1.8" @@ -3008,30 +3013,6 @@ dependencies = [ "tendril", ] -[[package]] -name = "nix" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055" -dependencies = [ - "bitflags", - "cc", - "cfg-if 0.1.10", - "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" @@ -3151,7 +3132,7 @@ dependencies = [ "ctrlc", "derive-new", "directories-next", - "dirs-next 2.0.0", + "dirs-next", "dtparse", "dunce", "eml-parser", @@ -3202,7 +3183,7 @@ dependencies = [ "roxmltree", "rusqlite", "rust-embed", - "rustyline 6.3.0", + "rustyline", "serde 1.0.124", "serde_bytes", "serde_ini", @@ -3253,7 +3234,7 @@ dependencies = [ "ctrlc", "derive-new", "directories-next", - "dirs-next 2.0.0", + "dirs-next", "dtparse", "dunce", "eml-parser", @@ -3304,7 +3285,7 @@ dependencies = [ "roxmltree", "rusqlite", "rust-embed", - "rustyline 7.1.0", + "rustyline", "serde 1.0.124", "serde_bytes", "serde_ini", @@ -3342,7 +3323,7 @@ dependencies = [ "chrono", "derive-new", "directories-next", - "dirs-next 2.0.0", + "dirs-next", "getset", "indexmap", "log 0.4.14", @@ -3371,7 +3352,7 @@ dependencies = [ "bytes 0.5.6", "codespan-reporting", "derive-new", - "dirs-next 2.0.0", + "dirs-next", "dunce", "encoding_rs", "filesize", @@ -4533,6 +4514,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.3.23" @@ -4987,38 +4978,21 @@ checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd" [[package]] name = "rustyline" -version = "6.3.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0d5e7b0219a3eadd5439498525d4765c59b7c993ef0c12244865cd2d988413" -dependencies = [ - "cfg-if 0.1.10", - "dirs-next 1.0.2", - "libc", - "log 0.4.14", - "memchr", - "nix 0.18.0", - "scopeguard", - "unicode-segmentation", - "unicode-width", - "utf8parse 0.2.0", - "winapi 0.3.9", -] - -[[package]] -name = "rustyline" -version = "7.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8227301bfc717136f0ecbd3d064ba8199e44497a0bdd46bb01ede4387cfd2cec" +checksum = "b9e1b597fcd1eeb1d6b25b493538e5aa19629eb08932184b85fef931ba87e893" dependencies = [ "bitflags", "cfg-if 1.0.0", - "dirs-next 2.0.0", + "dirs-next", "fs2", "libc", "log 0.4.14", "memchr", - "nix 0.19.1", + "nix", + "radix_trie", "scopeguard", + "smallvec 1.6.1", "unicode-segmentation", "unicode-width", "utf8parse 0.2.0", @@ -5424,7 +5398,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83bdb7831b2d85ddf4a7b148aa19d0587eddbe8671a436b7bd1182eaad0f2829" dependencies = [ - "dirs-next 2.0.0", + "dirs-next", ] [[package]] @@ -5851,7 +5825,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" dependencies = [ - "dirs-next 2.0.0", + "dirs-next", "rustversion", "winapi 0.3.9", ] diff --git a/crates/nu-cli/Cargo.toml b/crates/nu-cli/Cargo.toml index 2e5b7d651..503b1c9d9 100644 --- a/crates/nu-cli/Cargo.toml +++ b/crates/nu-cli/Cargo.toml @@ -77,7 +77,7 @@ rayon = "1.5.0" regex = "1.4.3" roxmltree = "0.14.0" rust-embed = "5.9.0" -rustyline = { version = "6.3.0", optional = true } +rustyline = { version = "8.0.0", 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/keybinding.rs b/crates/nu-cli/src/keybinding.rs index 201fcd802..4b7defa40 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/line_editor.rs b/crates/nu-cli/src/line_editor.rs index d78a823bd..4875b0534 100644 --- a/crates/nu-cli/src/line_editor.rs +++ b/crates/nu-cli/src/line_editor.rs @@ -7,6 +7,9 @@ use crate::prelude::*; #[allow(unused_imports)] use nu_engine::script::LineResult; +#[cfg(feature = "rustyline-support")] +use crate::keybinding::{convert_keyevent, KeyEvent}; + #[cfg(feature = "rustyline-support")] use crate::shell::Helper; @@ -16,7 +19,7 @@ use rustyline::{ config::Configurer, config::{ColorMode, CompletionType, Config}, error::ReadlineError, - At, Cmd, Editor, KeyPress, Movement, Word, + At, Cmd, Editor, Movement, Word, }; #[cfg(feature = "rustyline-support")] @@ -40,22 +43,27 @@ pub fn default_rustyline_editor_configuration() -> Editor { #[cfg(not(windows))] const DEFAULT_COMPLETION_MODE: CompletionType = CompletionType::List; - let config = Config::builder().color_mode(ColorMode::Forced).build(); + let config = Config::builder() + .check_cursor_position(true) + .color_mode(ColorMode::Forced) + .build(); let mut rl: Editor<_> = Editor::with_config(config); // 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 rl.set_max_history_size(100); diff --git a/crates/nu-cli/src/shell/helper.rs b/crates/nu-cli/src/shell/helper.rs index e9908f98b..2c5691553 100644 --- a/crates/nu-cli/src/shell/helper.rs +++ b/crates/nu-cli/src/shell/helper.rs @@ -57,6 +57,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/crates/nu-command/Cargo.toml b/crates/nu-command/Cargo.toml index 55762dabe..218b445a5 100644 --- a/crates/nu-command/Cargo.toml +++ b/crates/nu-command/Cargo.toml @@ -78,7 +78,7 @@ rayon = "1.5.0" regex = "1.4.3" roxmltree = "0.14.0" rust-embed = "5.9.0" -rustyline = { version = "7.1.0", optional = true } +rustyline = { version = "8.0.0", optional = true } serde = { version = "1.0.123", features = ["derive"] } serde_bytes = "0.11.5" serde_ini = "0.2.0" diff --git a/crates/nu-command/tests/commands/open.rs b/crates/nu-command/tests/commands/open.rs index 7c95a8005..994d2699d 100644 --- a/crates/nu-command/tests/commands/open.rs +++ b/crates/nu-command/tests/commands/open.rs @@ -245,7 +245,7 @@ fn open_dir_is_ls() { cwd: dirs.test(), pipeline( r#" open . - | count + | length "# )); diff --git a/docs/sample_config/keybindings.yml b/docs/sample_config/keybindings.yml index 65178171c..6856e8345 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,