add fav + opti

This commit is contained in:
2026-05-21 10:26:49 +02:00
parent 4f18a72785
commit 72ad88e888
12 changed files with 788 additions and 362 deletions

View File

@ -43,7 +43,8 @@ fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>, app: &mut App)
if event::poll(Duration::from_millis(250))? {
if let Event::Key(key) = event::read()? {
if key.modifiers.contains(KeyModifiers::CONTROL) {
// Ctrl+j / Ctrl+k : scroll prévisualisation (tous modes sauf aide)
if key.modifiers.contains(KeyModifiers::CONTROL) && app.mode != Mode::Help {
match key.code {
KeyCode::Char('j') => {
app.scroll_preview_down();
@ -58,75 +59,18 @@ fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>, app: &mut App)
}
match app.mode {
Mode::Normal => match key.code {
KeyCode::Enter => app.paste_selected(),
KeyCode::Char('j') | KeyCode::Down => app.next(),
KeyCode::Char('k') | KeyCode::Up => app.previous(),
KeyCode::Char('G') => {
if !app.filtered_items.is_empty() {
let l = app.filtered_items.len() - 1;
app.list_state.select(Some(l));
app.update_preview();
}
last_d = false;
last_g = false;
}
KeyCode::Char('g') => {
last_d = false;
if last_g {
if !app.filtered_items.is_empty() {
app.list_state.select(Some(0));
app.update_preview();
}
last_g = false;
} else {
last_g = true;
}
}
KeyCode::Char('d') => {
last_g = false;
if last_d {
app.mode = Mode::ConfirmDelete;
last_d = false;
} else {
last_d = true;
}
}
KeyCode::Char('u') => {
app.undo_delete();
last_d = false;
last_g = false;
}
KeyCode::Char('e') => {
app.toggle_encrypt();
last_d = false;
last_g = false;
}
KeyCode::Char('t') => {
app.cycle_type_filter();
last_d = false;
last_g = false;
}
KeyCode::Char('/') => {
app.mode = Mode::Search;
app.input_buffer.clear();
app.update_search();
last_d = false;
last_g = false;
}
KeyCode::Char(':') => {
app.mode = Mode::Command;
app.input_buffer.clear();
last_d = false;
last_g = false;
}
KeyCode::Char('q') => app.should_quit = true,
_ => {
last_d = false;
last_g = false;
}
},
// ----------------------------------------------------------
Mode::Help => {
// N'importe quelle touche ferme l'aide
app.mode = Mode::Normal;
}
// ----------------------------------------------------------
Mode::Normal => {
last_d = handle_normal(app, key.code, last_d, &mut last_g);
}
// ----------------------------------------------------------
Mode::Search => match key.code {
KeyCode::Esc => {
app.mode = Mode::Normal;
@ -136,6 +80,10 @@ fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>, app: &mut App)
KeyCode::Enter => app.paste_selected(),
KeyCode::Down => app.next(),
KeyCode::Up => app.previous(),
KeyCode::Char('o') if app.input_buffer.is_empty() => {
// `o` sans texte saisi → ouvre URL
app.open_url_selected();
}
KeyCode::Char(c) => {
app.input_buffer.push(c);
app.update_search();
@ -147,11 +95,11 @@ fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>, app: &mut App)
_ => {}
},
// ----------------------------------------------------------
Mode::Command => match key.code {
KeyCode::Esc => {
app.mode = Mode::Normal;
app.input_buffer.clear();
app.update_search();
}
KeyCode::Char(c) => app.input_buffer.push(c),
KeyCode::Backspace => {
@ -168,12 +116,13 @@ fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>, app: &mut App)
app.pending_action = None;
app.mode = Mode::PasswordInput;
}
_ => {}
_ => app.set_error(format!("Commande inconnue : {cmd}")),
}
}
_ => {}
},
// ----------------------------------------------------------
Mode::ConfirmDelete => match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') | KeyCode::Enter => {
if let Some(item) = app.get_selected_item() {
@ -194,6 +143,7 @@ fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>, app: &mut App)
_ => {}
},
// ----------------------------------------------------------
Mode::PasswordInput => match key.code {
KeyCode::Esc => {
app.mode = Mode::Normal;
@ -223,3 +173,105 @@ fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>, app: &mut App)
}
}
}
/// Gère les touches en mode Normal. Retourne le nouvel état de `last_d`.
fn handle_normal(app: &mut App, code: KeyCode, last_d: bool, last_g: &mut bool) -> bool {
match code {
KeyCode::Char('?') => {
app.mode = Mode::Help;
*last_g = false;
false
}
KeyCode::Enter => {
app.paste_selected();
*last_g = false;
false
}
KeyCode::Char('j') | KeyCode::Down => {
app.next();
*last_g = false;
false
}
KeyCode::Char('k') | KeyCode::Up => {
app.previous();
*last_g = false;
false
}
KeyCode::Char('G') => {
if !app.filtered_items.is_empty() {
let l = app.filtered_items.len() - 1;
app.list_state.select(Some(l));
app.update_preview();
}
*last_g = false;
false
}
KeyCode::Char('g') => {
if *last_g {
if !app.filtered_items.is_empty() {
app.list_state.select(Some(0));
app.update_preview();
}
*last_g = false;
} else {
*last_g = true;
}
false
}
KeyCode::Char('d') => {
*last_g = false;
if last_d {
app.mode = Mode::ConfirmDelete;
false
} else {
true // dernier appui était 'd'
}
}
KeyCode::Char('u') => {
app.undo_delete();
*last_g = false;
false
}
KeyCode::Char('p') => {
app.toggle_pin();
*last_g = false;
false
}
KeyCode::Char('o') => {
app.open_url_selected();
*last_g = false;
false
}
KeyCode::Char('e') => {
app.toggle_encrypt();
*last_g = false;
false
}
KeyCode::Char('t') => {
app.cycle_type_filter();
*last_g = false;
false
}
KeyCode::Char('/') => {
app.mode = Mode::Search;
app.input_buffer.clear();
app.update_search();
*last_g = false;
false
}
KeyCode::Char(':') => {
app.mode = Mode::Command;
app.input_buffer.clear();
*last_g = false;
false
}
KeyCode::Char('q') => {
app.should_quit = true;
false
}
_ => {
*last_g = false;
false
}
}
}