Merge pull request #285 from nushell/list_things

list things with `reedline --list`
This commit is contained in:
Darren Schroeder 2022-02-02 08:35:41 -06:00 committed by GitHub
commit 8a22413d52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 286 additions and 31 deletions

36
Cargo.lock generated
View File

@ -129,6 +129,15 @@ dependencies = [
"wasi",
]
[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "instant"
version = "0.1.12"
@ -397,6 +406,8 @@ dependencies = [
"rstest",
"serde",
"strip-ansi-escapes",
"strum",
"strum_macros",
"tempfile",
"unicode-segmentation",
"unicode-width",
@ -433,6 +444,12 @@ dependencies = [
"semver",
]
[[package]]
name = "rustversion"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
[[package]]
name = "scopeguard"
version = "1.1.0"
@ -510,6 +527,25 @@ dependencies = [
"vte",
]
[[package]]
name = "strum"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb"
[[package]]
name = "strum_macros"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn",
]
[[package]]
name = "syn"
version = "1.0.84"

View File

@ -24,6 +24,8 @@ serde = { version = "1.0", features = ["derive"] }
unicode-segmentation = "1.8.0"
unicode-width = "0.1.9"
strip-ansi-escapes = "0.1.1"
strum = "0.23"
strum_macros = "0.23"
[dev-dependencies]
tempfile = "3.2.0"

View File

@ -1,11 +1,10 @@
use crate::{Completer, Span};
use std::{
collections::{BTreeMap, BTreeSet},
str::Chars,
sync::Arc,
};
use crate::{Completer, Span};
/// A default completer that can detect keywords
///
/// # Example

View File

@ -1,6 +1,5 @@
use crate::{core_editor::get_default_clipboard, EditCommand, UndoBehavior};
use super::{Clipboard, ClipboardMode, LineBuffer};
use crate::{core_editor::get_default_clipboard, EditCommand, UndoBehavior};
pub struct Editor {
line_buffer: LineBuffer,

View File

@ -1,6 +1,5 @@
use crossterm::event::Event;
use crate::{enums::ReedlineEvent, PromptEditMode};
use crossterm::event::Event;
/// Define the style of parsing for the edit events
/// Available default options:

View File

@ -1,12 +1,10 @@
use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
use super::{keybindings::Keybindings, EditMode};
use crate::{
default_emacs_keybindings,
enums::{EditCommand, ReedlineEvent},
PromptEditMode,
};
use super::{keybindings::Keybindings, EditMode};
use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
/// This parses the incoming Events like a emacs style-editor
pub struct Emacs {

View File

@ -1,17 +1,14 @@
use std::collections::HashMap;
use crate::enums::ReedlineEvent;
use {
crate::EditCommand,
crate::{enums::ReedlineEvent, EditCommand},
crossterm::event::{KeyCode, KeyModifiers},
serde::{Deserialize, Serialize},
std::collections::HashMap,
};
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Hash, Debug)]
pub struct KeyCombination {
modifier: KeyModifiers,
key_code: KeyCode,
pub modifier: KeyModifiers,
pub key_code: KeyCode,
}
/// Main definition of editor keybindings
@ -63,6 +60,11 @@ impl Keybindings {
let key_combo = KeyCombination { modifier, key_code };
self.bindings.get(&key_combo).cloned()
}
/// Get assigned keybindings
pub fn get_keybindings(&self) -> &HashMap<KeyCombination, ReedlineEvent> {
&self.bindings
}
}
pub fn edit_bind(command: EditCommand) -> ReedlineEvent {

View File

@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize};
use strum_macros::EnumIter;
/// Valid ways how `Reedline::read_line()` can return
#[derive(Debug)]
@ -16,7 +17,7 @@ pub enum Signal {
/// Editing actions which can be mapped to key bindings.
///
/// Executed by `Reedline::run_edit_commands()`
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, EnumIter)]
pub enum EditCommand {
/// Move to the start of the buffer
MoveToStart,
@ -208,7 +209,7 @@ pub enum UndoBehavior {
}
/// Reedline supported actions.
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, EnumIter)]
pub enum ReedlineEvent {
/// No op event
None,

View File

@ -1,6 +1,5 @@
use std::collections::vec_deque::Iter;
use crate::core_editor::LineBuffer;
use std::collections::vec_deque::Iter;
/// Browsing modes for a [`History`]
#[derive(Debug, Clone, PartialEq, Eq)]

View File

@ -1,3 +1,5 @@
use super::{base::HistoryNavigationQuery, History};
use crate::core_editor::LineBuffer;
use std::{
collections::{vec_deque::Iter, VecDeque},
fs::{File, OpenOptions},
@ -5,10 +7,6 @@ use std::{
path::PathBuf,
};
use crate::core_editor::LineBuffer;
use super::{base::HistoryNavigationQuery, History};
/// Default size of the [`FileBackedHistory`] used when calling [`FileBackedHistory::default()`]
pub const HISTORY_SIZE: usize = 1000;
pub const NEWLINE_ESCAPE: &str = "<\\n>";

7
src/internal/mod.rs Normal file
View File

@ -0,0 +1,7 @@
mod query;
pub use query::{
get_reedline_default_keybindings, get_reedline_edit_commands,
get_reedline_keybinding_modifiers, get_reedline_keycodes, get_reedline_prompt_edit_modes,
get_reedline_reedline_events,
};

142
src/internal/query.rs Normal file
View File

@ -0,0 +1,142 @@
use crate::default_emacs_keybindings;
use crate::default_vi_insert_keybindings;
use crate::EditCommand;
use crate::PromptEditMode;
use crate::ReedlineEvent;
use crossterm::event::KeyCode;
use strum::IntoEnumIterator;
#[derive(Debug)]
struct KeyCodes;
impl KeyCodes {
pub fn iterator() -> std::slice::Iter<'static, KeyCode> {
static KEYCODE: [KeyCode; 29] = [
crossterm::event::KeyCode::Backspace,
crossterm::event::KeyCode::Enter,
crossterm::event::KeyCode::Left,
crossterm::event::KeyCode::Right,
crossterm::event::KeyCode::Up,
crossterm::event::KeyCode::Down,
crossterm::event::KeyCode::Home,
crossterm::event::KeyCode::End,
crossterm::event::KeyCode::PageUp,
crossterm::event::KeyCode::PageDown,
crossterm::event::KeyCode::Tab,
crossterm::event::KeyCode::BackTab,
crossterm::event::KeyCode::Delete,
crossterm::event::KeyCode::Insert,
crossterm::event::KeyCode::F(1),
crossterm::event::KeyCode::F(2),
crossterm::event::KeyCode::F(3),
crossterm::event::KeyCode::F(4),
crossterm::event::KeyCode::F(5),
crossterm::event::KeyCode::F(6),
crossterm::event::KeyCode::F(7),
crossterm::event::KeyCode::F(8),
crossterm::event::KeyCode::F(9),
crossterm::event::KeyCode::F(10),
crossterm::event::KeyCode::F(11),
crossterm::event::KeyCode::F(12),
crossterm::event::KeyCode::Char('a'),
crossterm::event::KeyCode::Null,
crossterm::event::KeyCode::Esc,
];
KEYCODE.iter()
}
}
/// Return a Vec of the Reedline Keybinding Modifiers
pub fn get_reedline_keybinding_modifiers() -> Vec<String> {
vec![
"Alt".to_string(),
"Control".to_string(),
"Shift".to_string(),
"None".to_string(),
]
}
/// Return a Vec<String> of the Reedline PromptEditModes
pub fn get_reedline_prompt_edit_modes() -> Vec<String> {
let mut modes = vec![];
for em in PromptEditMode::iter() {
modes.push(em.to_string());
}
modes
}
/// Return a Vec<String> of the Reedline KeyCodes
pub fn get_reedline_keycodes() -> Vec<String> {
let mut keycodes = vec![];
for kc in KeyCodes::iterator() {
// TODO: Perhaps this should be impl Display so we can control the output
keycodes.push(format!("{:?}", kc));
}
keycodes
}
/// Return a Vec<String> of the Reedline ReedlineEvents
pub fn get_reedline_reedline_events() -> Vec<String> {
let mut rles = vec![];
for rle in ReedlineEvent::iter() {
// TODO: Perhaps this should be impl Display so we can control the output
rles.push(format!("{:?}", rle));
}
rles
}
/// Return a Vec<String> of the Reedline EditCommands
pub fn get_reedline_edit_commands() -> Vec<String> {
let mut ecs = vec![];
for edit in EditCommand::iter() {
// TODO: Perhaps this should be impl Display so we can control the output
ecs.push(format!("{:?}", edit));
}
ecs
}
/// Get the default keybindings and return a Veec<(String, String, String, String)>
/// where String 1 is mode, String 2 is key_modifiers, String 3 is key_code, and
/// Sting 4 is event
pub fn get_reedline_default_keybindings() -> Vec<(String, String, String, String)> {
let mut keybindings = vec![];
let emacs = default_emacs_keybindings();
let vi_normal = default_vi_insert_keybindings();
let vi_insert = default_vi_insert_keybindings();
for emacs_kb in emacs.get_keybindings() {
let mode = "emacs";
let key_modifiers = emacs_kb.0.modifier;
let key_code = emacs_kb.0.key_code;
let event = emacs_kb.1;
keybindings.push((
mode.to_string(),
format!("{:?}", key_modifiers),
format!("{:?}", key_code),
format!("{:?}", event),
))
}
for vi_n_kb in vi_normal.get_keybindings() {
let mode = "vi_normal";
let key_modifiers = vi_n_kb.0.modifier;
let key_code = vi_n_kb.0.key_code;
let event = vi_n_kb.1;
keybindings.push((
mode.to_string(),
format!("{:?}", key_modifiers),
format!("{:?}", key_code),
format!("{:?}", event),
))
}
for vi_i_kb in vi_insert.get_keybindings() {
let mode = "vi_insert";
let key_modifiers = vi_i_kb.0.modifier;
let key_code = vi_i_kb.0.key_code;
let event = vi_i_kb.1;
keybindings.push((
mode.to_string(),
format!("{:?}", key_modifiers),
format!("{:?}", key_code),
format!("{:?}", event),
));
}
keybindings
}

View File

@ -220,3 +220,10 @@ pub use validator::{DefaultValidator, ValidationResult, Validator};
mod menu;
pub use menu::{CompletionMenu, HistoryMenu, Menu};
mod internal;
pub use internal::{
get_reedline_default_keybindings, get_reedline_edit_commands,
get_reedline_keybinding_modifiers, get_reedline_keycodes, get_reedline_prompt_edit_modes,
get_reedline_reedline_events,
};

View File

@ -6,9 +6,11 @@ use {
nu_ansi_term::{Color, Style},
reedline::{
default_emacs_keybindings, default_vi_insert_keybindings, default_vi_normal_keybindings,
CompletionMenu, DefaultCompleter, DefaultHinter, DefaultPrompt, EditMode, Emacs,
ExampleHighlighter, FileBackedHistory, HistoryMenu, Keybindings, Reedline, ReedlineEvent,
Signal, Vi,
get_reedline_default_keybindings, get_reedline_edit_commands,
get_reedline_keybinding_modifiers, get_reedline_keycodes, get_reedline_prompt_edit_modes,
get_reedline_reedline_events, CompletionMenu, DefaultCompleter, DefaultHinter,
DefaultPrompt, EditMode, Emacs, ExampleHighlighter, FileBackedHistory, HistoryMenu,
Keybindings, Reedline, ReedlineEvent, Signal, Vi,
},
std::{
io::{stdout, Write},
@ -28,6 +30,11 @@ fn main() -> Result<()> {
println!();
return Ok(());
};
if args.len() > 1 && args[1] == "--list" {
get_all_keybinding_info();
println!();
return Ok(());
}
let history = Box::new(FileBackedHistory::with_file(50, "history.txt".into())?);
let commands = vec![
@ -218,3 +225,39 @@ fn add_menu_keybindings(keybindings: &mut Keybindings) {
ReedlineEvent::MenuPrevious,
);
}
/// List all keybinding information
fn get_all_keybinding_info() {
println!("--Key Modifiers--");
for mods in get_reedline_keybinding_modifiers().iter() {
println!("{}", mods);
}
println!("\n--Modes--");
for modes in get_reedline_prompt_edit_modes().iter() {
println!("{}", modes);
}
println!("\n--Key Codes--");
for kcs in get_reedline_keycodes().iter() {
println!("{}", kcs);
}
println!("\n--Reedline Events--");
for rle in get_reedline_reedline_events().iter() {
println!("{}", rle);
}
println!("\n--Edit Commands--");
for edit in get_reedline_edit_commands().iter() {
println!("{}", edit);
}
println!("\n--Default Keybindings--");
for (mode, modifier, code, event) in get_reedline_default_keybindings() {
println!(
"mode: {}, keymodifiers: {}, keycode: {}, event: {}",
mode, modifier, code, event
)
}
}

View File

@ -1,7 +1,6 @@
use nu_ansi_term::{ansi::RESET, Style};
use super::{Menu, MenuTextStyle};
use crate::{painter::Painter, Completer, History, LineBuffer, Span};
use nu_ansi_term::{ansi::RESET, Style};
/// Default values used as reference for the menu. These values are set during
/// the initial declaration of the menu and are always kept as reference for the

View File

@ -1,7 +1,13 @@
use {
chrono::Local,
crossterm::style::Color,
std::{borrow::Cow, env},
serde::{Deserialize, Serialize},
std::{
borrow::Cow,
env,
fmt::{Display, Formatter},
},
strum_macros::EnumIter,
};
/// The default color for the prompt
@ -42,6 +48,7 @@ impl PromptHistorySearch {
}
/// Modes that the prompt can be in
#[derive(Serialize, Deserialize, Clone, Debug, EnumIter)]
pub enum PromptEditMode {
/// The default mode
Default,
@ -57,6 +64,7 @@ pub enum PromptEditMode {
}
/// The vi-specific modes that the prompt can be in
#[derive(Serialize, Deserialize, Clone, Debug, EnumIter)]
pub enum PromptViMode {
/// The default mode
Normal,
@ -65,6 +73,22 @@ pub enum PromptViMode {
Insert,
}
impl Default for PromptViMode {
fn default() -> Self {
PromptViMode::Normal
}
}
impl Display for PromptEditMode {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
match self {
PromptEditMode::Default => write!(f, "Default"),
PromptEditMode::Emacs => write!(f, "Emacs"),
PromptEditMode::Vi(_) => write!(f, "Vi_Normal\nVi_Insert"),
PromptEditMode::Custom(s) => write!(f, "Custom_{}", s),
}
}
}
/// API to provide a custom prompt.
///
/// Implementors have to provide [`str`]-based content which will be