mirror of
https://github.com/nushell/reedline.git
synced 2024-09-19 03:57:45 +03:00
Merge pull request #285 from nushell/list_things
list things with `reedline --list`
This commit is contained in:
commit
8a22413d52
36
Cargo.lock
generated
36
Cargo.lock
generated
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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)]
|
||||
|
@ -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
7
src/internal/mod.rs
Normal 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
142
src/internal/query.rs
Normal 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
|
||||
}
|
@ -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,
|
||||
};
|
||||
|
49
src/main.rs
49
src/main.rs
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user