added vim motions
This commit is contained in:
79
src/app.rs
79
src/app.rs
@@ -297,6 +297,11 @@ impl App {
|
||||
Some(executor::StructuredCommand::Confirm { .. })
|
||||
);
|
||||
let has_command = current_command.is_some();
|
||||
// Vim motions are disabled only when free text input is active.
|
||||
let is_text_input = matches!(
|
||||
current_command,
|
||||
Some(executor::StructuredCommand::Input { .. })
|
||||
);
|
||||
|
||||
match key.code {
|
||||
// ── Log scrolling (PageUp / PageDown always work) ─
|
||||
@@ -394,7 +399,66 @@ impl App {
|
||||
let _ = current_command.take();
|
||||
let _ = reply_tx.send("n".to_string());
|
||||
} else {
|
||||
// Kill the script if still running.
|
||||
if let Some(kx) = kill_tx.take() {
|
||||
let _ = kx.send(());
|
||||
}
|
||||
self.popup = None;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Vim motions (off during text input) ───────────
|
||||
KeyCode::Char('k') if !is_text_input => {
|
||||
if is_menu {
|
||||
if *menu_selected_index > 0 {
|
||||
*menu_selected_index -= 1;
|
||||
}
|
||||
} else if !has_command {
|
||||
*log_scroll_pos = log_scroll_pos.saturating_sub(1);
|
||||
*log_follow_bottom = false;
|
||||
}
|
||||
}
|
||||
KeyCode::Char('j') if !is_text_input => {
|
||||
if is_menu {
|
||||
if let Some(executor::StructuredCommand::Menu {
|
||||
options, ..
|
||||
}) = current_command
|
||||
{
|
||||
if *menu_selected_index + 1 < options.len() {
|
||||
*menu_selected_index += 1;
|
||||
}
|
||||
}
|
||||
} else if !has_command {
|
||||
*log_scroll_pos = log_scroll_pos.saturating_add(1);
|
||||
*log_follow_bottom =
|
||||
*log_scroll_pos + 1 >= log_buffer.len();
|
||||
}
|
||||
}
|
||||
KeyCode::Char('l') if !is_text_input => {
|
||||
// Forward / confirm — same logic as Enter.
|
||||
if let Some(cmd) = current_command.take() {
|
||||
let response = match &cmd {
|
||||
executor::StructuredCommand::Confirm { .. } => {
|
||||
"y".to_string()
|
||||
}
|
||||
executor::StructuredCommand::Menu {
|
||||
options, ..
|
||||
} => options
|
||||
.get(*menu_selected_index)
|
||||
.map(|o| o.id.clone())
|
||||
.unwrap_or_default(),
|
||||
_ => String::new(),
|
||||
};
|
||||
let _ = reply_tx.send(response);
|
||||
input_buffer.clear();
|
||||
*menu_selected_index = 0;
|
||||
}
|
||||
}
|
||||
KeyCode::Char('h') if !is_text_input => {
|
||||
// Back / cancel — same logic as Esc.
|
||||
if is_confirm {
|
||||
let _ = current_command.take();
|
||||
let _ = reply_tx.send("n".to_string());
|
||||
} else {
|
||||
if let Some(kx) = kill_tx.take() {
|
||||
let _ = kx.send(());
|
||||
}
|
||||
@@ -414,7 +478,7 @@ impl App {
|
||||
|
||||
Popup::UpdateConfirm { info } => {
|
||||
match key.code {
|
||||
KeyCode::Char('y') | KeyCode::Char('Y') => {
|
||||
KeyCode::Char('y') | KeyCode::Char('Y') | KeyCode::Char('l') => {
|
||||
let info = info.clone();
|
||||
self.popup = Some(Popup::Updating {
|
||||
info: info.clone(),
|
||||
@@ -453,7 +517,8 @@ impl App {
|
||||
}
|
||||
});
|
||||
}
|
||||
KeyCode::Char('n') | KeyCode::Char('N') | KeyCode::Esc => {
|
||||
KeyCode::Char('n') | KeyCode::Char('N')
|
||||
| KeyCode::Esc | KeyCode::Char('h') => {
|
||||
self.popup = None;
|
||||
}
|
||||
_ => {}
|
||||
@@ -478,24 +543,24 @@ impl App {
|
||||
// ── Main menu navigation ─────────────────────────────────────────
|
||||
match key.code {
|
||||
KeyCode::Char('q') => return Ok(true),
|
||||
KeyCode::Up => {
|
||||
KeyCode::Up | KeyCode::Char('k') => {
|
||||
let len = self.current_items().len();
|
||||
if len > 0 {
|
||||
self.selected_index = (self.selected_index + len - 1) % len;
|
||||
}
|
||||
}
|
||||
KeyCode::Down => {
|
||||
KeyCode::Down | KeyCode::Char('j') => {
|
||||
let len = self.current_items().len();
|
||||
if len > 0 {
|
||||
self.selected_index = (self.selected_index + 1) % len;
|
||||
}
|
||||
}
|
||||
KeyCode::Enter => {
|
||||
KeyCode::Enter | KeyCode::Char('l') => {
|
||||
if let Some(item) = self.selected_item().cloned() {
|
||||
self.activate_item(item).await?;
|
||||
}
|
||||
}
|
||||
KeyCode::Esc => {
|
||||
KeyCode::Esc | KeyCode::Char('h') => {
|
||||
if !self.breadcrumbs.is_empty() {
|
||||
self.breadcrumbs.pop();
|
||||
self.selected_index = 0;
|
||||
|
||||
Reference in New Issue
Block a user