mirror of
https://github.com/nushell/reedline.git
synced 2024-10-27 01:45:51 +03:00
Make reedline handling cursor shapes more configurable (#515)
Adds a struct to configure the cursor shape Co-authored-by: sholderbach <sholderbach@users.noreply.github.com> resolve https://github.com/nushell/reedline/issues/514
This commit is contained in:
parent
de8fc988df
commit
475495d785
@ -12,6 +12,8 @@ use {
|
||||
},
|
||||
};
|
||||
|
||||
use crossterm::cursor::CursorShape;
|
||||
use reedline::CursorConfig;
|
||||
#[cfg(not(any(feature = "sqlite", feature = "sqlite-dynlib")))]
|
||||
use reedline::FileBackedHistory;
|
||||
|
||||
@ -58,11 +60,18 @@ 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),
|
||||
emacs: None,
|
||||
};
|
||||
|
||||
let mut line_editor = Reedline::create()
|
||||
.with_history(history)
|
||||
.with_completer(completer)
|
||||
.with_quick_completions(true)
|
||||
.with_partial_completions(true)
|
||||
.with_cursor_config(cursor_config)
|
||||
.with_highlighter(Box::new(ExampleHighlighter::new(commands)))
|
||||
.with_hinter(Box::new(
|
||||
DefaultHinter::default().with_style(Style::new().fg(Color::DarkGray)),
|
||||
|
13
src/edit_mode/cursors.rs
Normal file
13
src/edit_mode/cursors.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crossterm::cursor::CursorShape;
|
||||
|
||||
/// 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>,
|
||||
/// The cursor to be used when in vi normal mode
|
||||
pub vi_normal: Option<CursorShape>,
|
||||
/// The cursor to be used when in emacs mode
|
||||
pub emacs: Option<CursorShape>,
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
mod base;
|
||||
mod cursors;
|
||||
mod emacs;
|
||||
mod keybindings;
|
||||
mod vi;
|
||||
|
||||
pub use base::EditMode;
|
||||
pub use cursors::CursorConfig;
|
||||
pub use emacs::{default_emacs_keybindings, Emacs};
|
||||
pub use keybindings::Keybindings;
|
||||
pub use vi::{default_vi_insert_keybindings, default_vi_normal_keybindings, Vi};
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::CursorConfig;
|
||||
#[cfg(feature = "bashisms")]
|
||||
use crate::{
|
||||
history::SearchFilter,
|
||||
@ -128,6 +129,9 @@ pub struct Reedline {
|
||||
// Text editor used to open the line buffer for editing
|
||||
buffer_editor: Option<BufferEditor>,
|
||||
|
||||
// Use different cursors depending on the current edit mode
|
||||
cursor_shapes: Option<CursorConfig>,
|
||||
|
||||
#[cfg(feature = "external_printer")]
|
||||
external_printer: Option<ExternalPrinter<String>>,
|
||||
}
|
||||
@ -179,6 +183,7 @@ impl Reedline {
|
||||
use_ansi_coloring: true,
|
||||
menus: Vec::new(),
|
||||
buffer_editor: None,
|
||||
cursor_shapes: None,
|
||||
#[cfg(feature = "external_printer")]
|
||||
external_printer: None,
|
||||
}
|
||||
@ -377,6 +382,14 @@ impl Reedline {
|
||||
self
|
||||
}
|
||||
|
||||
/// A builder that enables reedline changing the cursor shape based on the current edit mode.
|
||||
/// The current implementation sets the cursor shape when drawing the prompt.
|
||||
/// Do not use this if the cursor shape is set elsewhere, e.g. in the terminal settings or by ansi escape sequences.
|
||||
pub fn with_cursor_config(mut self, cursor_shapes: CursorConfig) -> Self {
|
||||
self.cursor_shapes = Some(cursor_shapes);
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns the corresponding expected prompt style for the given edit mode
|
||||
pub fn prompt_edit_mode(&self) -> PromptEditMode {
|
||||
self.edit_mode.edit_mode()
|
||||
@ -1393,6 +1406,7 @@ impl Reedline {
|
||||
self.prompt_edit_mode(),
|
||||
None,
|
||||
self.use_ansi_coloring,
|
||||
&self.cursor_shapes,
|
||||
)?;
|
||||
}
|
||||
|
||||
@ -1460,6 +1474,7 @@ impl Reedline {
|
||||
self.prompt_edit_mode(),
|
||||
menu,
|
||||
self.use_ansi_coloring,
|
||||
&self.cursor_shapes,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -260,7 +260,7 @@ pub use prompt::{
|
||||
mod edit_mode;
|
||||
pub use edit_mode::{
|
||||
default_emacs_keybindings, default_vi_insert_keybindings, default_vi_normal_keybindings,
|
||||
EditMode, Emacs, Keybindings, Vi,
|
||||
CursorConfig, EditMode, Emacs, Keybindings, Vi,
|
||||
};
|
||||
|
||||
mod highlighter;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::PromptEditMode;
|
||||
use crate::{CursorConfig, PromptEditMode, PromptViMode};
|
||||
|
||||
use {
|
||||
super::utils::{coerce_crlf, line_width},
|
||||
@ -137,6 +137,7 @@ impl Painter {
|
||||
prompt_mode: PromptEditMode,
|
||||
menu: Option<&ReedlineMenu>,
|
||||
use_ansi_coloring: bool,
|
||||
cursor_config: &Option<CursorConfig>,
|
||||
) -> Result<()> {
|
||||
self.stdout.queue(cursor::Hide)?;
|
||||
|
||||
@ -175,13 +176,20 @@ impl Painter {
|
||||
// can print without overwriting the things written during the painting
|
||||
self.last_required_lines = required_lines;
|
||||
|
||||
self.stdout
|
||||
.queue(RestorePosition)?
|
||||
.queue(cursor::SetCursorShape(match prompt_mode {
|
||||
PromptEditMode::Vi(crate::PromptViMode::Insert) => cursor::CursorShape::Line,
|
||||
_ => cursor::CursorShape::Block,
|
||||
}))?
|
||||
.queue(cursor::Show)?;
|
||||
self.stdout.queue(RestorePosition)?;
|
||||
|
||||
if let Some(shapes) = cursor_config {
|
||||
let shape = match &prompt_mode {
|
||||
PromptEditMode::Emacs => shapes.emacs,
|
||||
PromptEditMode::Vi(PromptViMode::Insert) => shapes.vi_insert,
|
||||
PromptEditMode::Vi(PromptViMode::Normal) => shapes.vi_normal,
|
||||
_ => None,
|
||||
};
|
||||
if let Some(shape) = shape {
|
||||
self.stdout.queue(cursor::SetCursorShape(shape))?;
|
||||
}
|
||||
}
|
||||
self.stdout.queue(cursor::Show)?;
|
||||
|
||||
self.stdout.flush()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user