improved textarea normal editor mode, not just vim
This commit is contained in:
@@ -91,10 +91,10 @@ required-features = ["gui", "computed"]
|
|||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "textarea_vim"
|
name = "textarea_vim"
|
||||||
required-features = ["gui", "cursor-style", "textarea"]
|
required-features = ["gui", "cursor-style", "textarea", "textmode-vim"]
|
||||||
path = "examples/textarea_vim.rs"
|
path = "examples/textarea_vim.rs"
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "textarea_normal"
|
name = "textarea_normal"
|
||||||
required-features = ["gui", "cursor-style", "textarea"]
|
required-features = ["gui", "cursor-style", "textarea", "textmode-normal"]
|
||||||
path = "examples/textarea_normal.rs"
|
path = "examples/textarea_normal.rs"
|
||||||
|
|||||||
@@ -200,9 +200,16 @@ Press ? for help, Ctrl+Q to quit.";
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle key press in NORMALMODE (always editing)
|
/// Handle key press in NORMALMODE (always editing, casual editor style)
|
||||||
fn handle_key_press(key_event: KeyEvent, editor: &mut AutoCursorTextArea) -> anyhow::Result<bool> {
|
fn handle_key_press(
|
||||||
let KeyEvent { code: key, modifiers, .. } = key_event;
|
key_event: KeyEvent,
|
||||||
|
editor: &mut AutoCursorTextArea,
|
||||||
|
) -> anyhow::Result<bool> {
|
||||||
|
let KeyEvent {
|
||||||
|
code: key,
|
||||||
|
modifiers,
|
||||||
|
..
|
||||||
|
} = key_event;
|
||||||
|
|
||||||
// Quit
|
// Quit
|
||||||
if (key == KeyCode::Char('q') && modifiers.contains(KeyModifiers::CONTROL))
|
if (key == KeyCode::Char('q') && modifiers.contains(KeyModifiers::CONTROL))
|
||||||
@@ -214,52 +221,32 @@ fn handle_key_press(key_event: KeyEvent, editor: &mut AutoCursorTextArea) -> any
|
|||||||
|
|
||||||
match (key, modifiers) {
|
match (key, modifiers) {
|
||||||
// Movement
|
// Movement
|
||||||
(KeyCode::Char('h'), _) | (KeyCode::Left, _) => editor.move_left(),
|
(KeyCode::Left, _) => editor.move_left(),
|
||||||
(KeyCode::Char('l'), _) | (KeyCode::Right, _) => editor.move_right(),
|
(KeyCode::Right, _) => editor.move_right(),
|
||||||
(KeyCode::Char('j'), _) | (KeyCode::Down, _) => editor.move_down(),
|
(KeyCode::Up, _) => editor.move_up(),
|
||||||
(KeyCode::Char('k'), _) | (KeyCode::Up, _) => editor.move_up(),
|
(KeyCode::Down, _) => editor.move_down(),
|
||||||
|
|
||||||
// Word movement
|
// Word movement (Ctrl+Arrows)
|
||||||
(KeyCode::Char('w'), _) => editor.move_word_next(),
|
(KeyCode::Left, m) if m.contains(KeyModifiers::CONTROL) => editor.move_word_prev(),
|
||||||
(KeyCode::Char('b'), _) => editor.move_word_prev(),
|
(KeyCode::Right, m) if m.contains(KeyModifiers::CONTROL) => editor.move_word_next(),
|
||||||
(KeyCode::Char('e'), _) => {
|
(KeyCode::Right, m) if m.contains(KeyModifiers::CONTROL | KeyModifiers::SHIFT) => {
|
||||||
if editor.get_command_buffer() == "g" {
|
editor.move_word_end()
|
||||||
editor.move_word_end_prev();
|
|
||||||
editor.clear_command_buffer();
|
|
||||||
} else {
|
|
||||||
editor.move_word_end();
|
|
||||||
editor.clear_command_buffer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Big word movement
|
|
||||||
(KeyCode::Char('W'), _) => editor.move_big_word_next(),
|
|
||||||
(KeyCode::Char('B'), _) => editor.move_big_word_prev(),
|
|
||||||
(KeyCode::Char('E'), _) => editor.move_big_word_end(),
|
|
||||||
|
|
||||||
// Line/document movement
|
// Line/document movement
|
||||||
(KeyCode::Char('0'), _) | (KeyCode::Home, _) => editor.move_line_start(),
|
(KeyCode::Home, _) => editor.move_line_start(),
|
||||||
(KeyCode::Char('$'), _) | (KeyCode::End, _) => editor.move_line_end(),
|
(KeyCode::End, _) => editor.move_line_end(),
|
||||||
(KeyCode::Char('g'), _) => {
|
(KeyCode::Home, m) if m.contains(KeyModifiers::CONTROL) => editor.move_first_line(),
|
||||||
if editor.get_command_buffer() == "g" {
|
(KeyCode::End, m) if m.contains(KeyModifiers::CONTROL) => editor.move_last_line(),
|
||||||
editor.move_first_line();
|
|
||||||
editor.clear_command_buffer();
|
|
||||||
} else {
|
|
||||||
editor.clear_command_buffer();
|
|
||||||
editor.add_to_command_buffer('g');
|
|
||||||
editor.set_debug_message("g".to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(KeyCode::Char('G'), _) => editor.move_last_line(),
|
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
(KeyCode::Char('x'), _) => editor.delete_char_forward(),
|
(KeyCode::Delete, _) => editor.delete_char_forward(),
|
||||||
(KeyCode::Char('X'), _) => editor.delete_char_backward(),
|
(KeyCode::Backspace, _) => editor.delete_char_backward(),
|
||||||
|
|
||||||
// Debug/info
|
// Debug/info
|
||||||
(KeyCode::Char('?'), _) => {
|
(KeyCode::Char('?'), _) => {
|
||||||
editor.set_debug_message(format!(
|
editor.set_debug_message(format!(
|
||||||
"{}, Mode: NORMALMODE (always editing, underscore cursor)",
|
"{}, Mode: NORMALMODE (casual editor, underscore cursor)",
|
||||||
editor.get_cursor_info()
|
editor.get_cursor_info()
|
||||||
));
|
));
|
||||||
editor.clear_command_buffer();
|
editor.clear_command_buffer();
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ impl CursorManager {
|
|||||||
// NORMALMODE: force underscore for every mode
|
// NORMALMODE: force underscore for every mode
|
||||||
#[cfg(feature = "textmode-normal")]
|
#[cfg(feature = "textmode-normal")]
|
||||||
{
|
{
|
||||||
let style = SetCursorStyle::SteadyUnderScore;
|
let style = SetCursorStyle::SteadyBar;
|
||||||
return execute!(io::stdout(), style);
|
return execute!(io::stdout(), style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,13 +36,22 @@ impl ModeManager {
|
|||||||
|
|
||||||
/// Transition to new mode with automatic cursor update (when cursor-style feature enabled)
|
/// Transition to new mode with automatic cursor update (when cursor-style feature enabled)
|
||||||
pub fn transition_to_mode(current_mode: AppMode, new_mode: AppMode) -> std::io::Result<AppMode> {
|
pub fn transition_to_mode(current_mode: AppMode, new_mode: AppMode) -> std::io::Result<AppMode> {
|
||||||
if current_mode != new_mode {
|
#[cfg(feature = "textmode-normal")]
|
||||||
#[cfg(feature = "cursor-style")]
|
{
|
||||||
{
|
// Always force Edit in normalmode
|
||||||
let _ = CursorManager::update_for_mode(new_mode);
|
return Ok(AppMode::Edit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "textmode-normal"))]
|
||||||
|
{
|
||||||
|
if current_mode != new_mode {
|
||||||
|
#[cfg(feature = "cursor-style")]
|
||||||
|
{
|
||||||
|
let _ = CursorManager::update_for_mode(new_mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(new_mode)
|
||||||
}
|
}
|
||||||
Ok(new_mode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enter highlight mode with cursor styling
|
/// Enter highlight mode with cursor styling
|
||||||
|
|||||||
@@ -54,7 +54,13 @@ impl EditorState {
|
|||||||
current_field: 0,
|
current_field: 0,
|
||||||
cursor_pos: 0,
|
cursor_pos: 0,
|
||||||
ideal_cursor_column: 0,
|
ideal_cursor_column: 0,
|
||||||
|
// NORMALMODE: always start in Edit
|
||||||
|
#[cfg(feature = "textmode-normal")]
|
||||||
current_mode: AppMode::Edit,
|
current_mode: AppMode::Edit,
|
||||||
|
// Default (vim): start in ReadOnly
|
||||||
|
#[cfg(not(feature = "textmode-normal"))]
|
||||||
|
current_mode: AppMode::ReadOnly,
|
||||||
|
|
||||||
#[cfg(feature = "suggestions")]
|
#[cfg(feature = "suggestions")]
|
||||||
suggestions: SuggestionsUIState {
|
suggestions: SuggestionsUIState {
|
||||||
is_active: false,
|
is_active: false,
|
||||||
|
|||||||
@@ -53,10 +53,19 @@ impl<D: DataProvider> FormEditor<D> {
|
|||||||
{
|
{
|
||||||
let mut editor = editor;
|
let mut editor = editor;
|
||||||
editor.initialize_validation();
|
editor.initialize_validation();
|
||||||
|
|
||||||
|
#[cfg(feature = "cursor-style")]
|
||||||
|
{
|
||||||
|
let _ = CursorManager::update_for_mode(editor.ui_state.current_mode);
|
||||||
|
}
|
||||||
editor
|
editor
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "validation"))]
|
#[cfg(not(feature = "validation"))]
|
||||||
{
|
{
|
||||||
|
#[cfg(feature = "cursor-style")]
|
||||||
|
{
|
||||||
|
let _ = CursorManager::update_for_mode(editor.ui_state.current_mode);
|
||||||
|
}
|
||||||
editor
|
editor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,6 @@ pub mod validation;
|
|||||||
#[cfg(feature = "computed")]
|
#[cfg(feature = "computed")]
|
||||||
pub mod computed;
|
pub mod computed;
|
||||||
|
|
||||||
#[path = "textmode/check.rs"]
|
|
||||||
mod textmode_check;
|
|
||||||
|
|
||||||
#[cfg(feature = "cursor-style")]
|
#[cfg(feature = "cursor-style")]
|
||||||
pub use canvas::CursorManager;
|
pub use canvas::CursorManager;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
// src/textmode/check.rs
|
|
||||||
|
|
||||||
#[cfg(all(feature = "textmode-vim", feature = "textmode-normal"))]
|
|
||||||
compile_error!("Enable exactly one of: textmode-vim or textmode-normal.");
|
|
||||||
|
|
||||||
#[cfg(not(any(feature = "textmode-vim", feature = "textmode-normal")))]
|
|
||||||
compile_error!("No textmode selected. Enable one of: textmode-vim or textmode-normal.");
|
|
||||||
Reference in New Issue
Block a user