From 7f1350edf71df44072b20fdcd059173c63260b89 Mon Sep 17 00:00:00 2001 From: wugeer <1284057728@qq.com> Date: Sat, 19 Oct 2024 15:27:55 +0800 Subject: [PATCH] feat: add keybinding to copy commit message --- CHANGELOG.md | 1 + src/components/commitlist.rs | 27 +++++++++++++++++++++++++++ src/keys/key_list.rs | 2 ++ src/strings.rs | 14 ++++++++++++++ src/tabs/revlog.rs | 20 ++++++++++++++++++++ 5 files changed, 64 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59b1710c60..7bfd5e80bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * use default shell instead of bash on Unix-like OS [[@yerke](https://github.com/yerke)] ([#2343](https://github.com/extrawurst/gitui/pull/2343)) ### Fixes +* add keybinding to copy commit message ([#2370](https://github.com/extrawurst/gitui/issues/2370)) * respect env vars like `GIT_CONFIG_GLOBAL` ([#2298](https://github.com/extrawurst/gitui/issues/2298)) * Set `CREATE_NO_WINDOW` flag when executing Git hooks on Windows ([#2371](https://github.com/extrawurst/gitui/pull/2371)) diff --git a/src/components/commitlist.rs b/src/components/commitlist.rs index 8249429542..adb9e505d4 100644 --- a/src/components/commitlist.rs +++ b/src/components/commitlist.rs @@ -170,6 +170,33 @@ impl CommitList { Ok(()) } + /// + pub fn selected_commit_message(&self) -> Option { + let commit = self.selected_entry().map(|e| e.id); + let data = commit.and_then(|id| { + sync::get_commit_details(&self.repo.borrow(), id).ok() + }); + data.as_ref().and_then(|data| data.message.as_ref()).map( + |message| { + message.body.as_ref().map_or_else( + || message.subject.clone(), + |body| format!("{}\n{}", message.subject, body), + ) + }, + ) + } + + /// + pub fn copy_commit_msg(&self) -> Result<()> { + if let Some(yank) = self.selected_commit_message() { + crate::clipboard::copy_string(&yank)?; + self.queue.push(InternalEvent::ShowInfoMsg( + strings::copy_success(&yank), + )); + }; + Ok(()) + } + /// pub fn checkout(&self) { if let Some(commit_hash) = diff --git a/src/keys/key_list.rs b/src/keys/key_list.rs index 2903499587..58284b7bf5 100644 --- a/src/keys/key_list.rs +++ b/src/keys/key_list.rs @@ -93,6 +93,7 @@ pub struct KeysList { pub toggle_signoff: GituiKeyEvent, pub toggle_verify: GituiKeyEvent, pub copy: GituiKeyEvent, + pub copy_commit_msg: GituiKeyEvent, pub create_branch: GituiKeyEvent, pub rename_branch: GituiKeyEvent, pub select_branch: GituiKeyEvent, @@ -190,6 +191,7 @@ impl Default for KeysList { toggle_signoff: GituiKeyEvent::new(KeyCode::Char('s'), KeyModifiers::CONTROL), toggle_verify: GituiKeyEvent::new(KeyCode::Char('f'), KeyModifiers::CONTROL), copy: GituiKeyEvent::new(KeyCode::Char('y'), KeyModifiers::empty()), + copy_commit_msg: GituiKeyEvent::new(KeyCode::Char('m'), KeyModifiers::empty()), create_branch: GituiKeyEvent::new(KeyCode::Char('c'), KeyModifiers::empty()), rename_branch: GituiKeyEvent::new(KeyCode::Char('r'), KeyModifiers::empty()), select_branch: GituiKeyEvent::new(KeyCode::Char('b'), KeyModifiers::empty()), diff --git a/src/strings.rs b/src/strings.rs index c4cff10f70..8771191da4 100644 --- a/src/strings.rs +++ b/src/strings.rs @@ -636,6 +636,20 @@ pub mod commands { CMD_GROUP_LOG, ) } + + pub fn copy_commit_msg( + key_config: &SharedKeyConfig, + ) -> CommandText { + CommandText::new( + format!( + "Copy Msg [{}]", + key_config.get_hint(key_config.keys.copy_commit_msg), + ), + "copy selected commit msg to clipboard", + CMD_GROUP_LOG, + ) + } + pub fn copy_path(key_config: &SharedKeyConfig) -> CommandText { CommandText::new( format!( diff --git a/src/tabs/revlog.rs b/src/tabs/revlog.rs index 11415a36ea..4b09266c56 100644 --- a/src/tabs/revlog.rs +++ b/src/tabs/revlog.rs @@ -478,6 +478,16 @@ impl Component for Revlog { self.list.copy_commit_hash() ); return Ok(EventState::Consumed); + } else if key_match( + k, + self.key_config.keys.copy_commit_msg, + ) { + try_or_popup!( + self, + strings::POPUP_FAIL_COPY, + self.list.copy_commit_msg() + ); + return Ok(EventState::Consumed); } else if key_match(k, self.key_config.keys.push) { self.queue.push(InternalEvent::PushTags); return Ok(EventState::Consumed); @@ -611,6 +621,8 @@ impl Component for Revlog { Ok(EventState::NotConsumed) } + // TODO: cleanup + #[allow(clippy::too_many_lines)] fn commands( &self, out: &mut Vec, @@ -677,6 +689,12 @@ impl Component for Revlog { self.visible || force_all, )); + out.push(CommandInfo::new( + strings::commands::copy_commit_msg(&self.key_config), + self.selected_commit().is_some(), + self.visible || force_all, + )); + out.push(CommandInfo::new( strings::commands::log_tag_commit(&self.key_config), self.selected_commit().is_some(), @@ -718,11 +736,13 @@ impl Component for Revlog { self.selected_commit().is_some(), (self.visible && !self.is_search_pending()) || force_all, )); + out.push(CommandInfo::new( strings::commands::log_reword_commit(&self.key_config), self.selected_commit().is_some(), (self.visible && !self.is_search_pending()) || force_all, )); + out.push(CommandInfo::new( strings::commands::log_find_commit(&self.key_config), self.can_start_search(),