From 65445eba5e897b55b73848b7a797cc1a58ba725b Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Fri, 21 May 2021 17:42:27 +0200 Subject: [PATCH] support tree-view blaming (see #714) --- filetree/src/filetree.rs | 14 ++++++++++++- src/components/revision_files.rs | 36 ++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/filetree/src/filetree.rs b/filetree/src/filetree.rs index 5a92a67f..e373c642 100644 --- a/filetree/src/filetree.rs +++ b/filetree/src/filetree.rs @@ -1,6 +1,6 @@ use crate::{ error::Result, filetreeitems::FileTreeItems, - tree_iter::TreeIterator, + tree_iter::TreeIterator, TreeItemInfo, }; use std::{collections::BTreeSet, usize}; @@ -77,6 +77,18 @@ impl FileTree { self.visual_selection.as_ref() } + /// + pub fn selected_file(&self) -> Option<&TreeItemInfo> { + self.selection.and_then(|index| { + let item = &self.items.tree_items[index]; + if item.kind().is_path() { + None + } else { + Some(item.info()) + } + }) + } + /// pub fn collapse_recursive(&mut self) { if let Some(selection) = self.selection { diff --git a/src/components/revision_files.rs b/src/components/revision_files.rs index 32608d50..7a850dff 100644 --- a/src/components/revision_files.rs +++ b/src/components/revision_files.rs @@ -6,7 +6,7 @@ use super::{ }; use crate::{ keys::SharedKeyConfig, - queue::Queue, + queue::{InternalEvent, Queue}, strings::{self, order}, ui::{self, style::SharedTheme}, }; @@ -27,6 +27,7 @@ const FOLDER_ICON_EXPANDED: &str = "\u{25be}"; //▾ const EMPTY_STR: &str = ""; pub struct RevisionFilesComponent { + queue: Queue, title: String, theme: SharedTheme, files: Vec, @@ -41,12 +42,13 @@ pub struct RevisionFilesComponent { impl RevisionFilesComponent { /// pub fn new( - _queue: &Queue, + queue: &Queue, _sender: &Sender, theme: SharedTheme, key_config: SharedKeyConfig, ) -> Self { Self { + queue: queue.clone(), title: String::new(), tree: FileTree::default(), theme, @@ -109,6 +111,20 @@ impl RevisionFilesComponent { let path = format!("{}{}{}", indent_str, path_arrow, path); Span::styled(path, theme.file_tree_item(is_path, selected)) } + + fn blame(&self) -> bool { + self.tree.selected_file().map_or(false, |file| { + self.queue.borrow_mut().push_back( + InternalEvent::BlameFile( + file.full_path() + .strip_prefix("./") + .unwrap_or_default() + .to_string(), + ), + ); + true + }) + } } impl DrawableComponent for RevisionFilesComponent { @@ -178,6 +194,15 @@ impl Component for RevisionFilesComponent { .order(1), ); + out.push( + CommandInfo::new( + strings::commands::blame_file(&self.key_config), + self.tree.selected_file().is_some(), + true, + ) + .order(order::NAV), + ); + tree_nav_cmds(&self.tree, &self.key_config, out); } @@ -193,6 +218,13 @@ impl Component for RevisionFilesComponent { let consumed = if key == self.key_config.exit_popup { self.hide(); true + } else if key == self.key_config.blame { + if self.blame() { + self.hide(); + true + } else { + false + } } else { tree_nav(&mut self.tree, &self.key_config, key) };