updated insert modes + fixed status bar help
All checks were successful
Version Check / check-version (pull_request) Successful in 3s
All checks were successful
Version Check / check-version (pull_request) Successful in 3s
This commit is contained in:
50
src/app.rs
50
src/app.rs
@@ -11,6 +11,12 @@ pub enum Mode {
|
||||
Search,
|
||||
}
|
||||
|
||||
pub enum InsertVariant {
|
||||
Start,
|
||||
End,
|
||||
Substitute,
|
||||
}
|
||||
|
||||
/// The core application state, holding all configuration variables and UI status.
|
||||
pub struct App {
|
||||
/// The list of configuration variables being edited.
|
||||
@@ -149,12 +155,25 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
/// Transitions the application into Insert Mode.
|
||||
pub fn enter_insert(&mut self) {
|
||||
/// Transitions the application into Insert Mode with a specific variant.
|
||||
pub fn enter_insert(&mut self, variant: InsertVariant) {
|
||||
if let Some(var) = self.vars.get(self.selected) {
|
||||
if !var.is_group {
|
||||
self.mode = Mode::Insert;
|
||||
self.status_message = None;
|
||||
match variant {
|
||||
InsertVariant::Start => {
|
||||
use tui_input::InputRequest;
|
||||
self.input.handle(InputRequest::GoToStart);
|
||||
}
|
||||
InsertVariant::End => {
|
||||
use tui_input::InputRequest;
|
||||
self.input.handle(InputRequest::GoToEnd);
|
||||
}
|
||||
InsertVariant::Substitute => {
|
||||
self.input = Input::new(String::new());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,9 +201,13 @@ impl App {
|
||||
to_remove.push(self.selected);
|
||||
|
||||
if is_group {
|
||||
let prefix = format!("{}.", selected_path);
|
||||
let prefix_dot = format!("{}.", selected_path);
|
||||
let prefix_bracket = format!("{}[", selected_path);
|
||||
for (i, var) in self.vars.iter().enumerate() {
|
||||
if var.path.starts_with(&prefix) {
|
||||
if i == self.selected {
|
||||
continue;
|
||||
}
|
||||
if var.path.starts_with(&prefix_dot) || var.path.starts_with(&prefix_bracket) {
|
||||
to_remove.push(i);
|
||||
}
|
||||
}
|
||||
@@ -279,9 +302,26 @@ impl App {
|
||||
self.vars.insert(insert_pos, new_item);
|
||||
self.selected = insert_pos;
|
||||
self.sync_input_with_selected();
|
||||
self.mode = Mode::Insert;
|
||||
self.enter_insert(InsertVariant::Start);
|
||||
self.status_message = None;
|
||||
}
|
||||
|
||||
/// Status bar helpers
|
||||
pub fn selected_is_group(&self) -> bool {
|
||||
self.vars.get(self.selected).map(|v| v.is_group).unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn selected_is_array(&self) -> bool {
|
||||
self.vars.get(self.selected)
|
||||
.map(|v| !v.is_group && v.path.contains('['))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn selected_is_missing(&self) -> bool {
|
||||
self.vars.get(self.selected)
|
||||
.map(|v| v.status == crate::format::ItemStatus::MissingFromActive)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_index(path: &str) -> Option<(&str, usize)> {
|
||||
|
||||
@@ -106,6 +106,8 @@ pub struct KeybindsConfig {
|
||||
pub down: String,
|
||||
pub up: String,
|
||||
pub edit: String,
|
||||
pub edit_append: String,
|
||||
pub edit_substitute: String,
|
||||
pub save: String,
|
||||
pub quit: String,
|
||||
pub normal_mode: String,
|
||||
@@ -125,6 +127,8 @@ impl Default for KeybindsConfig {
|
||||
down: "j".to_string(),
|
||||
up: "k".to_string(),
|
||||
edit: "i".to_string(),
|
||||
edit_append: "A".to_string(),
|
||||
edit_substitute: "S".to_string(),
|
||||
save: ":w".to_string(),
|
||||
quit: ":q".to_string(),
|
||||
normal_mode: "Esc".to_string(),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::app::{App, Mode};
|
||||
use crate::app::{App, InsertVariant, Mode};
|
||||
use crate::config::Config;
|
||||
use crate::format::FormatHandler;
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEvent};
|
||||
@@ -117,6 +117,8 @@ where
|
||||
(&self.config.keybinds.down, "down"),
|
||||
(&self.config.keybinds.up, "up"),
|
||||
(&self.config.keybinds.edit, "edit"),
|
||||
(&self.config.keybinds.edit_append, "edit_append"),
|
||||
(&self.config.keybinds.edit_substitute, "edit_substitute"),
|
||||
(&self.config.keybinds.search, "search"),
|
||||
(&self.config.keybinds.next_match, "next_match"),
|
||||
(&self.config.keybinds.previous_match, "previous_match"),
|
||||
@@ -147,7 +149,9 @@ where
|
||||
match action {
|
||||
"down" => self.app.next(),
|
||||
"up" => self.app.previous(),
|
||||
"edit" => self.app.enter_insert(),
|
||||
"edit" => self.app.enter_insert(InsertVariant::Start),
|
||||
"edit_append" => self.app.enter_insert(InsertVariant::End),
|
||||
"edit_substitute" => self.app.enter_insert(InsertVariant::Substitute),
|
||||
"search" => {
|
||||
self.app.mode = Mode::Search;
|
||||
self.app.search_query.clear();
|
||||
|
||||
32
src/ui.rs
32
src/ui.rs
@@ -269,14 +269,30 @@ pub fn draw(f: &mut Frame, app: &mut App, config: &Config) {
|
||||
),
|
||||
};
|
||||
|
||||
let status_msg = app
|
||||
.status_message
|
||||
.as_deref()
|
||||
.unwrap_or_else(|| match app.mode {
|
||||
Mode::Normal => " navigation | i: edit | /: search | :w: save | :q: quit ",
|
||||
Mode::Insert => " Esc: back to normal | Enter: commit ",
|
||||
Mode::Search => " Esc: back to normal | type to filter ",
|
||||
});
|
||||
let status_msg = if let Some(msg) = &app.status_message {
|
||||
msg.clone()
|
||||
} else {
|
||||
match app.mode {
|
||||
Mode::Normal => {
|
||||
let mut parts = vec!["j/k move", "gg/G jump", "/ search"];
|
||||
if !app.selected_is_group() {
|
||||
parts.push("i/A/S edit");
|
||||
}
|
||||
if app.selected_is_missing() {
|
||||
parts.push("a add");
|
||||
}
|
||||
if app.selected_is_array() {
|
||||
parts.push("o/O array");
|
||||
}
|
||||
parts.push("dd del");
|
||||
parts.push(":w save");
|
||||
parts.push(":q quit");
|
||||
parts.join(" · ")
|
||||
}
|
||||
Mode::Insert => "Esc normal · Enter commit".to_string(),
|
||||
Mode::Search => "Esc normal · type to filter".to_string(),
|
||||
}
|
||||
};
|
||||
|
||||
let status_line = Line::from(vec![
|
||||
Span::styled(mode_str, mode_style),
|
||||
|
||||
Reference in New Issue
Block a user