Repository: cantino/mcfly (language: rust)

Issue:
Issue : Deleting an entry makes the cursor go back to the top
When cleaning-up history, it's frequent that we need to delete multiple contiguous lines/entries.

This could be super quick with repeated strokes on F2 (if `delete_without_confirm` is enabled).
Unfortunately, it's not convenient, because, after deletion, the cursor goes back to the top item.

Suggestion: after deletion of entry on line N, line N (and the corresponding entry) should stay selected (unless N was the last item, in which case line N-1 should be selected).
This is basically the standard behavior of all UX where user can select and delete items in a list using up/down arrows and Del.

By the way, is there a way to always enable  `delete_without_confirm` on Ctrl-R ?


Discussion / hints:
to always enable delete_without_confirm, set MCFLY_DELETE_WITHOUT_CONFIRM=true in your shell config

- bash / zsh

```sh
export MCFLY_DELETE_WITHOUT_CONFIRM=true
```

- fish

```sh
set -gx MCFLY_DELETE_WITHOUT_CONFIRM true

```

@cantino The quick fix to allowing this functionality is to remove self.selection = 0; from below.

```rust
    fn refresh_matches(&mut self) {
        self.selection = 0;
        self.matches = self.history.find_matches(
            &self.input.command,
            self.settings.results as i16,
            self.settings.fuzzy,
            &self.result_sort,
        );
    }
```

However, this would make any functionality that also call refresh_matches to not reset the selection to the top, i.e., changing result sort. What are your thoughts on this?
@navazjm Would be great to change the code a bit so that the selection tweak only applies when the delete hotkey is pressed.
Yes, I think it needs to be an option to `refresh_matches` and only set for deletion, not universally. I'm open to a PR for that change!

Fix patch:
diff --git a/src/interface.rs b/src/interface.rs
index b93a7daf..e4daa7e5 100644
--- a/src/interface.rs
+++ b/src/interface.rs
@@ -386,12 +386,14 @@ impl<'a> Interface<'a> {
                 self.delete_requests.push(command.cmd.clone());
             }
             self.build_cache_table();
-            self.refresh_matches();
+            self.refresh_matches(false);
         }
     }
 
-    fn refresh_matches(&mut self) {
-        self.selection = 0;
+    fn refresh_matches(&mut self, reset_selection: bool) {
+        if reset_selection {
+            self.selection = 0;
+        }
         self.matches = self.history.find_matches(
             &self.input.command,
             self.settings.results as i16,
@@ -413,7 +415,7 @@ impl<'a> Interface<'a> {
         //        let mut screen = stdout().into_raw_mode().unwrap();
         write!(screen, "{}", clear::All).unwrap();
 
-        self.refresh_matches();
+        self.refresh_matches(true);
         self.results(&mut screen);
         self.menubar(&mut screen);
         self.prompt(&mut screen);
@@ -482,11 +484,11 @@ impl<'a> Interface<'a> {
             Key::Ctrl('e') => self.input.move_cursor(Move::EOL),
             Key::Ctrl('w') | Key::Alt('\x08') | Key::Alt('\x7f') => {
                 self.input.delete(Move::BackwardWord);
-                self.refresh_matches();
+                self.refresh_matches(true);
             }
             Key::Alt('d') => {
                 self.input.delete(Move::ForwardWord);
-                self.refresh_matches();
+                self.refresh_matches(true);
             }
             Key::Ctrl('v') => {
                 self.debug = !self.debug;
@@ -499,29 +501,30 @@ impl<'a> Interface<'a> {
             Key::Down | Key::PageDown | Key::Ctrl('n') => self.move_selection(MoveSelection::Down),
             Key::Ctrl('k') => {
                 self.input.delete(Move::EOL);
-                self.refresh_matches();
+                self.refresh_matches(true);
             }
             Key::Ctrl('u') => {
                 self.input.delete(Move::BOL);
-                self.refresh_matches();
+                self.refresh_matches(true);
+                self.selection = 0;
             }
             Key::Backspace | Key::Ctrl('h') => {
                 self.input.delete(Move::Backward);
-                self.refresh_matches();
+                self.refresh_matches(true);
             }
             Key::Delete | Key::Ctrl('d') => {
                 self.input.delete(Move::Forward);
-                self.refresh_matches();
+                self.refresh_matches(true);
             }
             Key::Home => self.input.move_cursor(Move::BOL),
             Key::End => self.input.move_cursor(Move::EOL),
             Key::Char(c) => {
                 self.input.insert(c);
-                self.refresh_matches();
+                self.refresh_matches(true);
             }
             Key::F(1) => {
                 self.switch_result_sort();
-                self.refresh_matches();
+                self.refresh_matches(true);
             }
             Key::F(2) => {
                 if !self.matches.is_empty() {
@@ -567,21 +570,21 @@ impl<'a> Interface<'a> {
                 Key::Esc => self.in_vim_insert_mode = false,
                 Key::Backspace => {
                     self.input.delete(Move::Backward);
-                    self.refresh_matches();
+                    self.refresh_matches(true);
                 }
                 Key::Delete => {
                     self.input.delete(Move::Forward);
-                    self.refresh_matches();
+                    self.refresh_matches(true);
                 }
                 Key::Home => self.input.move_cursor(Move::BOL),
                 Key::End => self.input.move_cursor(Move::EOL),
                 Key::Char(c) => {
                     self.input.insert(c);
-                    self.refresh_matches();
+                    self.refresh_matches(true);
                 }
                 Key::F(1) => {
                     self.switch_result_sort();
-                    self.refresh_matches();
+                    self.refresh_matches(true);
                 }
                 Key::F(2) => {
                     if !self.matches.is_empty() {
@@ -640,11 +643,11 @@ impl<'a> Interface<'a> {
                 }
                 Key::Backspace => {
                     self.input.delete(Move::Backward);
-                    self.refresh_matches();
+                    self.refresh_matches(true);
                 }
                 Key::Delete | Key::Char('x') => {
                     self.input.delete(Move::Forward);
-                    self.refresh_matches();
+                    self.refresh_matches(true);
                 }
                 Key::Home => self.input.move_cursor(Move::BOL),
                 Key::End => self.input.move_cursor(Move::EOL),
@@ -653,7 +656,7 @@ impl<'a> Interface<'a> {
                 }
                 Key::F(1) => {
                     self.switch_result_sort();
-                    self.refresh_matches();
+                    self.refresh_matches(true);
                 },
                 Key::F(2) => {
                     if !self.matches.is_empty() {


Test patch: