mirror of
https://github.com/nushell/reedline.git
synced 2024-09-11 15:55:50 +03:00
Update crossterm to version 0.26.1 (#560)
* update crossterm to 0.26.1 * add event_listener_kitty_proto example * add comment * remove trait
This commit is contained in:
parent
89cb811838
commit
27f4417191
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -187,9 +187,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.24.0"
|
||||
version = "0.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab9f7409c70a38a56216480fba371ee460207dd8926ccf5b4160591759559170"
|
||||
checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crossterm_winapi",
|
||||
|
@ -15,7 +15,7 @@ doctest = true
|
||||
[dependencies]
|
||||
chrono = "0.4.19"
|
||||
clipboard = { version = "0.5.0", optional = true }
|
||||
crossterm = { version = "0.24.0", features = ["serde"] }
|
||||
crossterm = { version = "0.26.1", features = ["serde"] }
|
||||
itertools = "0.10.3"
|
||||
nu-ansi-term = "0.47.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
@ -12,7 +12,7 @@ use {
|
||||
},
|
||||
};
|
||||
|
||||
use crossterm::cursor::CursorShape;
|
||||
use crossterm::cursor::SetCursorStyle;
|
||||
use reedline::CursorConfig;
|
||||
#[cfg(not(any(feature = "sqlite", feature = "sqlite-dynlib")))]
|
||||
use reedline::FileBackedHistory;
|
||||
@ -61,8 +61,8 @@ fn main() -> Result<()> {
|
||||
let completer = Box::new(DefaultCompleter::new_with_wordlen(commands.clone(), 2));
|
||||
|
||||
let cursor_config = CursorConfig {
|
||||
vi_insert: Some(CursorShape::Line),
|
||||
vi_normal: Some(CursorShape::Block),
|
||||
vi_insert: Some(SetCursorStyle::BlinkingBar),
|
||||
vi_normal: Some(SetCursorStyle::SteadyBlock),
|
||||
emacs: None,
|
||||
};
|
||||
|
||||
|
@ -38,11 +38,17 @@ fn print_events_helper() -> Result<()> {
|
||||
// It's guaranteed that read() wont block if `poll` returns `Ok(true)`
|
||||
let event = crossterm::event::read()?;
|
||||
|
||||
if let Event::Key(KeyEvent { code, modifiers }) = event {
|
||||
if let Event::Key(KeyEvent {
|
||||
code,
|
||||
modifiers,
|
||||
kind,
|
||||
state,
|
||||
}) = event
|
||||
{
|
||||
match code {
|
||||
KeyCode::Char(c) => {
|
||||
println!(
|
||||
"Char: {} code: {:#08x}; Modifier {:?}; Flags {:#08b}\r",
|
||||
"Char: {} code: {:#08x}; Modifier {:?}; Flags {:#08b}; Kind {kind:?}; state {state:?}\r",
|
||||
c,
|
||||
u32::from(c),
|
||||
modifiers,
|
||||
@ -51,7 +57,7 @@ fn print_events_helper() -> Result<()> {
|
||||
}
|
||||
_ => {
|
||||
println!(
|
||||
"Keycode: {code:?}; Modifier {modifiers:?}; Flags {modifiers:#08b}\r"
|
||||
"Keycode: {code:?}; Modifier {modifiers:?}; Flags {modifiers:#08b}; Kind {kind:?}; state {state:?}\r"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
104
examples/event_listener_kitty_proto.rs
Normal file
104
examples/event_listener_kitty_proto.rs
Normal file
@ -0,0 +1,104 @@
|
||||
use crossterm::event::{
|
||||
KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags,
|
||||
};
|
||||
use crossterm::execute;
|
||||
use {
|
||||
crossterm::{
|
||||
event::{poll, Event, KeyCode, KeyEvent},
|
||||
terminal, Result,
|
||||
},
|
||||
std::{
|
||||
io::{stdout, Write},
|
||||
time::Duration,
|
||||
},
|
||||
};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
println!("Ready to print events (Abort with ESC):");
|
||||
print_events()?;
|
||||
println!();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// **For debugging purposes only:** Track the terminal events observed by [`Reedline`] and print them.
|
||||
pub fn print_events() -> Result<()> {
|
||||
stdout().flush()?;
|
||||
terminal::enable_raw_mode()?;
|
||||
// enable kitty protocol
|
||||
//
|
||||
// Note that, currently, only the following support this protocol:
|
||||
// * [kitty terminal](https://sw.kovidgoyal.net/kitty/)
|
||||
// * [foot terminal](https://codeberg.org/dnkl/foot/issues/319)
|
||||
// * [WezTerm terminal](https://wezfurlong.org/wezterm/config/lua/config/enable_kitty_keyboard.html)
|
||||
// * [notcurses library](https://github.com/dankamongmen/notcurses/issues/2131)
|
||||
// * [neovim text editor](https://github.com/neovim/neovim/pull/18181)
|
||||
// * [kakoune text editor](https://github.com/mawww/kakoune/issues/4103)
|
||||
// * [dte text editor](https://gitlab.com/craigbarnes/dte/-/issues/138)
|
||||
//
|
||||
// Refer to https://sw.kovidgoyal.net/kitty/keyboard-protocol/ if you're curious.
|
||||
execute!(
|
||||
stdout(),
|
||||
PushKeyboardEnhancementFlags(
|
||||
KeyboardEnhancementFlags::REPORT_EVENT_TYPES
|
||||
| KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES
|
||||
)
|
||||
)
|
||||
.unwrap();
|
||||
let result = print_events_helper();
|
||||
execute!(stdout(), PopKeyboardEnhancementFlags).unwrap();
|
||||
terminal::disable_raw_mode()?;
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
// this fn is totally ripped off from crossterm's examples
|
||||
// it's really a diagnostic routine to see if crossterm is
|
||||
// even seeing the events. if you press a key and no events
|
||||
// are printed, it's a good chance your terminal is eating
|
||||
// those events.
|
||||
fn print_events_helper() -> Result<()> {
|
||||
loop {
|
||||
// Wait up to 5s for another event
|
||||
if poll(Duration::from_millis(5_000))? {
|
||||
// It's guaranteed that read() wont block if `poll` returns `Ok(true)`
|
||||
let event = crossterm::event::read()?;
|
||||
|
||||
if let Event::Key(KeyEvent {
|
||||
code,
|
||||
modifiers,
|
||||
kind,
|
||||
state,
|
||||
}) = event
|
||||
{
|
||||
match code {
|
||||
KeyCode::Char(c) => {
|
||||
println!(
|
||||
"Char: {} code: {:#08x}; Modifier {:?}; Flags {:#08b}; Kind {kind:?}; state {state:?}\r",
|
||||
c,
|
||||
u32::from(c),
|
||||
modifiers,
|
||||
modifiers
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
println!(
|
||||
"Keycode: {code:?}; Modifier {modifiers:?}; Flags {modifiers:#08b}; Kind {kind:?}; state {state:?}\r"
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("Event::{event:?}\r");
|
||||
}
|
||||
|
||||
// hit the esc key to git out
|
||||
if event == Event::Key(KeyCode::Esc.into()) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Timeout expired, no event for 5s
|
||||
println!("Waiting for you to type...\r");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
use crate::{enums::ReedlineEvent, PromptEditMode};
|
||||
pub use crossterm::event::Event;
|
||||
use crate::{
|
||||
enums::{ReedlineEvent, ReedlineRawEvent},
|
||||
PromptEditMode,
|
||||
};
|
||||
|
||||
/// Define the style of parsing for the edit events
|
||||
/// Available default options:
|
||||
@ -7,7 +9,7 @@ pub use crossterm::event::Event;
|
||||
/// - Vi
|
||||
pub trait EditMode: Send {
|
||||
/// Translate the given user input event into what the `LineEditor` understands
|
||||
fn parse_event(&mut self, event: Event) -> ReedlineEvent;
|
||||
fn parse_event(&mut self, event: ReedlineRawEvent) -> ReedlineEvent;
|
||||
|
||||
/// What to display in the prompt indicator
|
||||
fn edit_mode(&self) -> PromptEditMode;
|
||||
|
@ -1,13 +1,13 @@
|
||||
use crossterm::cursor::CursorShape;
|
||||
use crossterm::cursor::SetCursorStyle;
|
||||
|
||||
/// Maps cursor shapes to each edit mode (emacs, vi normal & vi insert).
|
||||
/// If any of the fields is `None`, the cursor won't get changed by Reedline for that mode.
|
||||
#[derive(Default)]
|
||||
pub struct CursorConfig {
|
||||
/// The cursor to be used when in vi insert mode
|
||||
pub vi_insert: Option<CursorShape>,
|
||||
pub vi_insert: Option<SetCursorStyle>,
|
||||
/// The cursor to be used when in vi normal mode
|
||||
pub vi_normal: Option<CursorShape>,
|
||||
pub vi_normal: Option<SetCursorStyle>,
|
||||
/// The cursor to be used when in emacs mode
|
||||
pub emacs: Option<CursorShape>,
|
||||
pub emacs: Option<SetCursorStyle>,
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
},
|
||||
EditMode,
|
||||
},
|
||||
enums::{EditCommand, ReedlineEvent},
|
||||
enums::{EditCommand, ReedlineEvent, ReedlineRawEvent},
|
||||
PromptEditMode,
|
||||
};
|
||||
use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
|
||||
@ -108,9 +108,11 @@ impl Default for Emacs {
|
||||
}
|
||||
|
||||
impl EditMode for Emacs {
|
||||
fn parse_event(&mut self, event: Event) -> ReedlineEvent {
|
||||
match event {
|
||||
Event::Key(KeyEvent { code, modifiers }) => match (modifiers, code) {
|
||||
fn parse_event(&mut self, event: ReedlineRawEvent) -> ReedlineEvent {
|
||||
match event.into() {
|
||||
Event::Key(KeyEvent {
|
||||
code, modifiers, ..
|
||||
}) => match (modifiers, code) {
|
||||
(modifier, KeyCode::Char(c)) => {
|
||||
// Note. The modifier can also be a combination of modifiers, for
|
||||
// example:
|
||||
@ -152,6 +154,9 @@ impl EditMode for Emacs {
|
||||
|
||||
Event::Mouse(_) => ReedlineEvent::Mouse,
|
||||
Event::Resize(width, height) => ReedlineEvent::Resize(width, height),
|
||||
Event::FocusGained => ReedlineEvent::None,
|
||||
Event::FocusLost => ReedlineEvent::None,
|
||||
Event::Paste(_) => ReedlineEvent::None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,10 +180,11 @@ mod test {
|
||||
#[test]
|
||||
fn ctrl_l_leads_to_clear_screen_event() {
|
||||
let mut emacs = Emacs::default();
|
||||
let ctrl_l = Event::Key(KeyEvent {
|
||||
modifiers: KeyModifiers::CONTROL,
|
||||
code: KeyCode::Char('l'),
|
||||
});
|
||||
let ctrl_l = ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
|
||||
KeyCode::Char('l'),
|
||||
KeyModifiers::CONTROL,
|
||||
)))
|
||||
.unwrap();
|
||||
let result = emacs.parse_event(ctrl_l);
|
||||
|
||||
assert_eq!(result, ReedlineEvent::ClearScreen);
|
||||
@ -194,10 +200,11 @@ mod test {
|
||||
);
|
||||
|
||||
let mut emacs = Emacs::new(keybindings);
|
||||
let ctrl_l = Event::Key(KeyEvent {
|
||||
modifiers: KeyModifiers::CONTROL,
|
||||
code: KeyCode::Char('l'),
|
||||
});
|
||||
let ctrl_l = ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
|
||||
KeyCode::Char('l'),
|
||||
KeyModifiers::CONTROL,
|
||||
)))
|
||||
.unwrap();
|
||||
let result = emacs.parse_event(ctrl_l);
|
||||
|
||||
assert_eq!(result, ReedlineEvent::HistoryHintComplete);
|
||||
@ -206,10 +213,11 @@ mod test {
|
||||
#[test]
|
||||
fn inserting_character_works() {
|
||||
let mut emacs = Emacs::default();
|
||||
let l = Event::Key(KeyEvent {
|
||||
modifiers: KeyModifiers::NONE,
|
||||
code: KeyCode::Char('l'),
|
||||
});
|
||||
let l = ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
|
||||
KeyCode::Char('l'),
|
||||
KeyModifiers::NONE,
|
||||
)))
|
||||
.unwrap();
|
||||
let result = emacs.parse_event(l);
|
||||
|
||||
assert_eq!(
|
||||
@ -222,10 +230,11 @@ mod test {
|
||||
fn inserting_capital_character_works() {
|
||||
let mut emacs = Emacs::default();
|
||||
|
||||
let uppercase_l = Event::Key(KeyEvent {
|
||||
modifiers: KeyModifiers::SHIFT,
|
||||
code: KeyCode::Char('l'),
|
||||
});
|
||||
let uppercase_l = ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
|
||||
KeyCode::Char('l'),
|
||||
KeyModifiers::SHIFT,
|
||||
)))
|
||||
.unwrap();
|
||||
let result = emacs.parse_event(uppercase_l);
|
||||
|
||||
assert_eq!(
|
||||
@ -239,10 +248,11 @@ mod test {
|
||||
let keybindings = Keybindings::default();
|
||||
|
||||
let mut emacs = Emacs::new(keybindings);
|
||||
let ctrl_l = Event::Key(KeyEvent {
|
||||
modifiers: KeyModifiers::CONTROL,
|
||||
code: KeyCode::Char('l'),
|
||||
});
|
||||
let ctrl_l = ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
|
||||
KeyCode::Char('l'),
|
||||
KeyModifiers::CONTROL,
|
||||
)))
|
||||
.unwrap();
|
||||
let result = emacs.parse_event(ctrl_l);
|
||||
|
||||
assert_eq!(result, ReedlineEvent::None);
|
||||
@ -252,10 +262,11 @@ mod test {
|
||||
fn inserting_capital_character_for_non_ascii_remains_as_is() {
|
||||
let mut emacs = Emacs::default();
|
||||
|
||||
let uppercase_l = Event::Key(KeyEvent {
|
||||
modifiers: KeyModifiers::SHIFT,
|
||||
code: KeyCode::Char('😀'),
|
||||
});
|
||||
let uppercase_l = ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
|
||||
KeyCode::Char('😀'),
|
||||
KeyModifiers::SHIFT,
|
||||
)))
|
||||
.unwrap();
|
||||
let result = emacs.parse_event(uppercase_l);
|
||||
|
||||
assert_eq!(
|
||||
|
@ -4,7 +4,7 @@ mod emacs;
|
||||
mod keybindings;
|
||||
mod vi;
|
||||
|
||||
pub use base::{EditMode, Event};
|
||||
pub use base::EditMode;
|
||||
pub use cursors::CursorConfig;
|
||||
pub use emacs::{default_emacs_keybindings, Emacs};
|
||||
pub use keybindings::Keybindings;
|
||||
|
@ -11,7 +11,7 @@ use self::motion::ViCharSearch;
|
||||
use super::EditMode;
|
||||
use crate::{
|
||||
edit_mode::{keybindings::Keybindings, vi::parser::parse},
|
||||
enums::{EditCommand, ReedlineEvent},
|
||||
enums::{EditCommand, ReedlineEvent, ReedlineRawEvent},
|
||||
PromptEditMode, PromptViMode,
|
||||
};
|
||||
|
||||
@ -57,9 +57,11 @@ impl Vi {
|
||||
}
|
||||
|
||||
impl EditMode for Vi {
|
||||
fn parse_event(&mut self, event: Event) -> ReedlineEvent {
|
||||
match event {
|
||||
Event::Key(KeyEvent { code, modifiers }) => match (self.mode, modifiers, code) {
|
||||
fn parse_event(&mut self, event: ReedlineRawEvent) -> ReedlineEvent {
|
||||
match event.into() {
|
||||
Event::Key(KeyEvent {
|
||||
code, modifiers, ..
|
||||
}) => match (self.mode, modifiers, code) {
|
||||
(ViMode::Normal, modifier, KeyCode::Char(c)) => {
|
||||
let c = c.to_ascii_lowercase();
|
||||
|
||||
@ -149,6 +151,9 @@ impl EditMode for Vi {
|
||||
|
||||
Event::Mouse(_) => ReedlineEvent::Mouse,
|
||||
Event::Resize(width, height) => ReedlineEvent::Resize(width, height),
|
||||
Event::FocusGained => ReedlineEvent::None,
|
||||
Event::FocusLost => ReedlineEvent::None,
|
||||
Event::Paste(_) => ReedlineEvent::None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,10 +173,11 @@ mod test {
|
||||
#[test]
|
||||
fn esc_leads_to_normal_mode_test() {
|
||||
let mut vi = Vi::default();
|
||||
let esc = Event::Key(KeyEvent {
|
||||
modifiers: KeyModifiers::NONE,
|
||||
code: KeyCode::Esc,
|
||||
});
|
||||
let esc = ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
|
||||
KeyCode::Esc,
|
||||
KeyModifiers::NONE,
|
||||
)))
|
||||
.unwrap();
|
||||
let result = vi.parse_event(esc);
|
||||
|
||||
assert_eq!(
|
||||
@ -197,10 +203,11 @@ mod test {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let esc = Event::Key(KeyEvent {
|
||||
modifiers: KeyModifiers::NONE,
|
||||
code: KeyCode::Char('e'),
|
||||
});
|
||||
let esc = ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
|
||||
KeyCode::Char('e'),
|
||||
KeyModifiers::NONE,
|
||||
)))
|
||||
.unwrap();
|
||||
let result = vi.parse_event(esc);
|
||||
|
||||
assert_eq!(result, ReedlineEvent::ClearScreen);
|
||||
@ -222,10 +229,11 @@ mod test {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let esc = Event::Key(KeyEvent {
|
||||
modifiers: KeyModifiers::SHIFT,
|
||||
code: KeyCode::Char('$'),
|
||||
});
|
||||
let esc = ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
|
||||
KeyCode::Char('$'),
|
||||
KeyModifiers::SHIFT,
|
||||
)))
|
||||
.unwrap();
|
||||
let result = vi.parse_event(esc);
|
||||
|
||||
assert_eq!(result, ReedlineEvent::CtrlD);
|
||||
@ -241,10 +249,11 @@ mod test {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let esc = Event::Key(KeyEvent {
|
||||
modifiers: KeyModifiers::NONE,
|
||||
code: KeyCode::Char('q'),
|
||||
});
|
||||
let esc = ReedlineRawEvent::convert_from(Event::Key(KeyEvent::new(
|
||||
KeyCode::Char('q'),
|
||||
KeyModifiers::NONE,
|
||||
)))
|
||||
.unwrap();
|
||||
let result = vi.parse_event(esc);
|
||||
|
||||
assert_eq!(result, ReedlineEvent::None);
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::CursorConfig;
|
||||
use crate::{enums::ReedlineRawEvent, CursorConfig};
|
||||
#[cfg(feature = "bashisms")]
|
||||
use crate::{
|
||||
history::SearchFilter,
|
||||
@ -493,7 +493,7 @@ impl Reedline {
|
||||
|
||||
self.repaint(prompt)?;
|
||||
|
||||
let mut crossterm_events: Vec<Event> = vec![];
|
||||
let mut crossterm_events: Vec<ReedlineRawEvent> = vec![];
|
||||
let mut reedline_events: Vec<ReedlineEvent> = vec![];
|
||||
|
||||
loop {
|
||||
@ -528,7 +528,11 @@ impl Reedline {
|
||||
enter @ Event::Key(KeyEvent {
|
||||
code: KeyCode::Enter,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
..
|
||||
}) => {
|
||||
let enter = ReedlineRawEvent::convert_from(enter);
|
||||
match enter {
|
||||
Some(enter) => {
|
||||
crossterm_events.push(enter);
|
||||
// Break early to check if the input is complete and
|
||||
// can be send to the hosting application. If
|
||||
@ -538,8 +542,15 @@ impl Reedline {
|
||||
paste_enter_state = crossterm_events.len() > EVENTS_THRESHOLD;
|
||||
break;
|
||||
}
|
||||
None => continue,
|
||||
}
|
||||
}
|
||||
x => {
|
||||
crossterm_events.push(x);
|
||||
let raw_event = ReedlineRawEvent::convert_from(x);
|
||||
match raw_event {
|
||||
Some(evt) => crossterm_events.push(evt),
|
||||
None => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
40
src/enums.rs
40
src/enums.rs
@ -1,3 +1,4 @@
|
||||
use crossterm::event::{Event, KeyEvent, KeyEventKind};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::{Display, Formatter};
|
||||
use strum_macros::EnumIter;
|
||||
@ -560,3 +561,42 @@ pub(crate) enum EventStatus {
|
||||
Inapplicable,
|
||||
Exits(Signal),
|
||||
}
|
||||
|
||||
/// A simple wrapper for [crossterm::event::Event]
|
||||
///
|
||||
/// Which will make sure that the given event doesn't contain [KeyEventKind::Release]
|
||||
/// and convert from [KeyEventKind::Repeat] to [KeyEventKind::Press]
|
||||
pub struct ReedlineRawEvent {
|
||||
inner: Event,
|
||||
}
|
||||
|
||||
impl ReedlineRawEvent {
|
||||
/// It will return None if `evt` is released Key.
|
||||
pub fn convert_from(evt: Event) -> Option<Self> {
|
||||
match evt {
|
||||
Event::Key(KeyEvent {
|
||||
kind: KeyEventKind::Release,
|
||||
..
|
||||
}) => None,
|
||||
Event::Key(KeyEvent {
|
||||
code,
|
||||
modifiers,
|
||||
kind: KeyEventKind::Repeat,
|
||||
state,
|
||||
}) => Some(Self {
|
||||
inner: Event::Key(KeyEvent {
|
||||
code,
|
||||
modifiers,
|
||||
kind: KeyEventKind::Press,
|
||||
state,
|
||||
}),
|
||||
}),
|
||||
other => Some(Self { inner: other }),
|
||||
}
|
||||
}
|
||||
|
||||
/// Consume and get crossterm event object.
|
||||
pub fn into(self) -> Event {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ pub use core_editor::Editor;
|
||||
pub use core_editor::LineBuffer;
|
||||
|
||||
mod enums;
|
||||
pub use enums::{EditCommand, ReedlineEvent, Signal, UndoBehavior};
|
||||
pub use enums::{EditCommand, ReedlineEvent, ReedlineRawEvent, Signal, UndoBehavior};
|
||||
|
||||
mod painting;
|
||||
pub use painting::{Painter, StyledText};
|
||||
@ -259,7 +259,7 @@ pub use prompt::{
|
||||
mod edit_mode;
|
||||
pub use edit_mode::{
|
||||
default_emacs_keybindings, default_vi_insert_keybindings, default_vi_normal_keybindings,
|
||||
CursorConfig, EditMode, Emacs, Event, Keybindings, Vi,
|
||||
CursorConfig, EditMode, Emacs, Keybindings, Vi,
|
||||
};
|
||||
|
||||
mod highlighter;
|
||||
|
@ -186,7 +186,7 @@ impl Painter {
|
||||
_ => None,
|
||||
};
|
||||
if let Some(shape) = shape {
|
||||
self.stdout.queue(cursor::SetCursorShape(shape))?;
|
||||
self.stdout.queue(shape)?;
|
||||
}
|
||||
}
|
||||
self.stdout.queue(cursor::Show)?;
|
||||
|
@ -57,6 +57,15 @@ impl Display for ReedLineCrossTermKeyCode {
|
||||
KeyCode::Char(_) => write!(f, "Char_<letter>"),
|
||||
KeyCode::Null => write!(f, "Null"),
|
||||
KeyCode::Esc => write!(f, "Esc"),
|
||||
KeyCode::CapsLock => write!(f, "CapsLock"),
|
||||
KeyCode::ScrollLock => write!(f, "ScrollLock"),
|
||||
KeyCode::NumLock => write!(f, "NumLock"),
|
||||
KeyCode::PrintScreen => write!(f, "PrintScreen"),
|
||||
KeyCode::Pause => write!(f, "Pause"),
|
||||
KeyCode::Menu => write!(f, "Menu"),
|
||||
KeyCode::KeypadBegin => write!(f, "KeypadBegin"),
|
||||
KeyCode::Media(_) => write!(f, "Media<media>"),
|
||||
KeyCode::Modifier(_) => write!(f, "Modifier<modifier>"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user