From aefc18d819cb19da3d4baef29fe474937fabe99a Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Sun, 12 Feb 2023 18:06:56 +0800 Subject: [PATCH] Copy file path (#1516) * copy file path to click board * update change log * Add copy path info to command bar --- CHANGELOG.md | 1 + flake.lock | 0 src/components/revision_files.rs | 18 ++++++++++++++++++ src/components/status_tree.rs | 27 +++++++++++++++++++++++++++ src/strings.rs | 10 ++++++++++ 5 files changed, 56 insertions(+) create mode 100644 flake.lock diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c1d014a..d180b503 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * add no-verify option on commits to not run hooks [[@dam5h]](https://github.com/dam5h) ([#1374](https://github.com/extrawurst/gitui/issues/1374)) * allow `fetch` on status tab [[@alensiljak]](https://github.com/alensiljak) ([#1471](https://github.com/extrawurst/gitui/issues/1471)) * allow reset (soft,mixed,hard) from commit log ([#1500](https://github.com/extrawurst/gitui/issues/1500)) +* allow `copy` file path on revision files and status tree [[@yanganto]](https://github.com/yanganto) ([#1516](https://github.com/extrawurst/gitui/pull/1516)) ### Fixes * commit msg history ordered the wrong way ([#1445](https://github.com/extrawurst/gitui/issues/1445)) diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..e69de29b diff --git a/src/components/revision_files.rs b/src/components/revision_files.rs index 33b0fb3d..01dd750a 100644 --- a/src/components/revision_files.rs +++ b/src/components/revision_files.rs @@ -7,6 +7,7 @@ use crate::{ keys::{key_match, SharedKeyConfig}, queue::{InternalEvent, Queue, StackablePopupOpen}, strings::{self, order, symbol}, + try_or_popup, ui::{self, common_nav, style::SharedTheme}, AsyncAppNotification, AsyncNotification, }; @@ -447,6 +448,14 @@ impl Component for RevisionFilesComponent { ) .order(order::RARE_ACTION), ); + out.push( + CommandInfo::new( + strings::commands::copy_path(&self.key_config), + self.tree.selected_file().is_some(), + true, + ) + .order(order::RARE_ACTION), + ); tree_nav_cmds(&self.tree, &self.key_config, out); } else { self.current_file.commands(out, force_all); @@ -515,6 +524,15 @@ impl Component for RevisionFilesComponent { ); return Ok(EventState::Consumed); } + } else if key_match(key, self.key_config.keys.copy) { + if let Some(file) = self.selected_file_path() { + try_or_popup!( + self, + strings::POPUP_FAIL_COPY, + crate::clipboard::copy_string(&file) + ); + } + return Ok(EventState::Consumed); } else if !is_tree_focused { return self.current_file.event(event); } diff --git a/src/components/status_tree.rs b/src/components/status_tree.rs index f4c2f837..0302350d 100644 --- a/src/components/status_tree.rs +++ b/src/components/status_tree.rs @@ -302,6 +302,21 @@ impl StatusTreeComponent { selection_offset_visible, ) } + + // Copy the real path of selected file to clickboard + fn copy_file_path(&self) { + if let Some(item) = self.selection() { + if crate::clipboard::copy_string(&item.info.full_path) + .is_err() + { + if let Some(queue) = &self.queue { + queue.push(InternalEvent::ShowErrorMsg( + strings::POPUP_FAIL_COPY.to_string(), + )); + } + } + } + } } /// Used for drawing the `FileTreeComponent` @@ -430,6 +445,15 @@ impl Component for StatusTreeComponent { .order(order::RARE_ACTION), ); + out.push( + CommandInfo::new( + strings::commands::copy_path(&self.key_config), + self.selection_file().is_some(), + self.focused || force_all, + ) + .order(order::RARE_ACTION), + ); + CommandBlocking::PassingOn } @@ -481,6 +505,9 @@ impl Component for StatusTreeComponent { } } Ok(EventState::Consumed) + } else if key_match(e, self.key_config.keys.copy) { + self.copy_file_path(); + Ok(EventState::Consumed) } else if key_match(e, self.key_config.keys.move_down) { Ok(self diff --git a/src/strings.rs b/src/strings.rs index 6af5464c..f02cc883 100644 --- a/src/strings.rs +++ b/src/strings.rs @@ -558,6 +558,16 @@ pub mod commands { CMD_GROUP_LOG, ) } + pub fn copy_path(key_config: &SharedKeyConfig) -> CommandText { + CommandText::new( + format!( + "Copy Path [{}]", + key_config.get_hint(key_config.keys.copy), + ), + "copy selected file path to clipboard", + CMD_GROUP_LOG, + ) + } pub fn push_tags(key_config: &SharedKeyConfig) -> CommandText { CommandText::new( format!(