konradsz / igrep

Interactive Grep
MIT License
663 stars 17 forks source link

feature idea: add a keybinding to copy the filename and/or line number to the clipboard #64

Closed slashformotion closed 9 months ago

slashformotion commented 10 months ago

Alternatively the filename and/or line number could be printed to the stdout and then the user would pipe the output to is clipboard utility

konradsz commented 10 months ago

Hi there! Can you tell me what is your use case for this? That would be rather simple addition, but I am not sure what it brings to the table :)

slashformotion commented 9 months ago

I am using igrep to search xml tag definition through XSD files (XML schemas) and then I use the filename of the schema I found to validate an XML payload. Currently, I copy the name of the file manually and it would be more practical to just press a key to get the filename in my clipboard.

As I said, a good first step would be to print the name of the file to the screen and let the user handle the clipboard part through their platform utils.

konradsz commented 9 months ago

Hey, your use case seems to be quite unique and I wouldn't want to pollute igrep's keybindings with copying filename. I prepared a little diff for you that at the exit of application prints all the filenames you "yanked" using yy key bind. I encourage you to apply it on main and build your version of igrep with this little feature built-in :)

diff --git a/src/app.rs b/src/app.rs
index 372e7d1..937aef3 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -29,6 +29,7 @@ pub struct App {
     context_viewer: ContextViewer,
     search_popup: SearchPopup,
     keymap_popup: KeymapPopup,
+    filenames: Vec<String>,
 }

 impl App {
@@ -47,6 +48,7 @@ impl App {
             result_list: ResultList::default(),
             search_popup: SearchPopup::default(),
             keymap_popup: KeymapPopup::default(),
+            filenames: Vec::new(),
         }
     }

@@ -96,6 +98,10 @@ impl App {
             }
         }

+        for filename in &self.filenames {
+            println!("{}", filename);
+        }
+
         Ok(())
     }

@@ -234,6 +240,12 @@ impl Application for App {
     fn on_keymap_right(&mut self) {
         self.keymap_popup.go_right();
     }
+
+    fn on_print_filename(&mut self) {
+        if let Some((file_name, _)) = self.result_list.get_selected_entry() {
+            self.filenames.push(file_name.to_string());
+        }
+    }
 }

 #[cfg_attr(test, mockall::automock)]
@@ -262,4 +274,5 @@ pub trait Application {
     fn on_keymap_down(&mut self);
     fn on_keymap_left(&mut self);
     fn on_keymap_right(&mut self);
+    fn on_print_filename(&mut self);
 }
diff --git a/src/ui/input_handler.rs b/src/ui/input_handler.rs
index b806afd..92f17fb 100644
--- a/src/ui/input_handler.rs
+++ b/src/ui/input_handler.rs
@@ -177,6 +177,9 @@ impl InputHandler {
             "dw" => consume_buffer_and_execute(&mut self.input_buffer, &mut || {
                 app.on_remove_current_file()
             }),
+            "yy" => {
+                consume_buffer_and_execute(&mut self.input_buffer, &mut || app.on_print_filename())
+            }
             "v" => consume_buffer_and_execute(&mut self.input_buffer, &mut || {
                 app.on_toggle_context_viewer_vertical()
             }),
@@ -193,6 +196,7 @@ impl InputHandler {
             "?" => {
                 consume_buffer_and_execute(&mut self.input_buffer, &mut || app.on_toggle_keymap())
             }
+            "y" => self.input_state = InputState::Incomplete("y…".into()),
             "g" => self.input_state = InputState::Incomplete("g…".into()),
             "d" => self.input_state = InputState::Incomplete("d…".into()),
             buf => {
slashformotion commented 9 months ago

ok, thank you very much!