Skip to content

Commit ba8b8d1

Browse files
committed
feat: add keybinding to copy commit message
1 parent 2a590fd commit ba8b8d1

File tree

8 files changed

+68
-8
lines changed

8 files changed

+68
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212

1313
### Fixes
1414
* respect env vars like `GIT_CONFIG_GLOBAL` ([#2298](https://github.com/extrawurst/gitui/issues/2298))
15+
* keybinding to copy commit message ([#2370](https://github.com/extrawurst/gitui/issues/2370))
1516

1617
### Added
1718
* add popups for viewing, adding, updating and removing remotes [[@robin-thoene](https://github.com/robin-thoene)] ([#2172](https://github.com/extrawurst/gitui/issues/2172))

asyncgit/src/sync/commit_filter.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,7 @@ pub fn filter_commit_by_search(
214214

215215
Ok(msg_summary_match
216216
|| msg_body_match
217-
|| file_match
218-
|| authors_match)
217+
|| file_match || authors_match)
219218
},
220219
))
221220
}

src/components/commitlist.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,33 @@ impl CommitList {
170170
Ok(())
171171
}
172172

173+
///
174+
pub fn selected_commit_message(&self) -> Option<String> {
175+
let commit = self.selected_entry().map(|e| e.id);
176+
let data = commit.and_then(|id| {
177+
sync::get_commit_details(&self.repo.borrow(), id).ok()
178+
});
179+
data.as_ref().and_then(|data| data.message.as_ref()).map(
180+
|message| {
181+
message.body.as_ref().map_or_else(
182+
|| message.subject.clone(),
183+
|body| format!("{}\n{}", message.subject, body),
184+
)
185+
},
186+
)
187+
}
188+
189+
///
190+
pub fn copy_commit_msg(&self) -> Result<()> {
191+
if let Some(yank) = self.selected_commit_message() {
192+
crate::clipboard::copy_string(&yank)?;
193+
self.queue.push(InternalEvent::ShowInfoMsg(
194+
strings::copy_success(&yank),
195+
));
196+
};
197+
Ok(())
198+
}
199+
173200
///
174201
pub fn checkout(&self) {
175202
if let Some(commit_hash) =

src/keys/key_list.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ pub struct KeysList {
9393
pub toggle_signoff: GituiKeyEvent,
9494
pub toggle_verify: GituiKeyEvent,
9595
pub copy: GituiKeyEvent,
96+
pub copy_commit_msg: GituiKeyEvent,
9697
pub create_branch: GituiKeyEvent,
9798
pub rename_branch: GituiKeyEvent,
9899
pub select_branch: GituiKeyEvent,
@@ -190,6 +191,7 @@ impl Default for KeysList {
190191
toggle_signoff: GituiKeyEvent::new(KeyCode::Char('s'), KeyModifiers::CONTROL),
191192
toggle_verify: GituiKeyEvent::new(KeyCode::Char('f'), KeyModifiers::CONTROL),
192193
copy: GituiKeyEvent::new(KeyCode::Char('y'), KeyModifiers::empty()),
194+
copy_commit_msg: GituiKeyEvent::new(KeyCode::Char('m'), KeyModifiers::empty()),
193195
create_branch: GituiKeyEvent::new(KeyCode::Char('c'), KeyModifiers::empty()),
194196
rename_branch: GituiKeyEvent::new(KeyCode::Char('r'), KeyModifiers::empty()),
195197
select_branch: GituiKeyEvent::new(KeyCode::Char('b'), KeyModifiers::empty()),

src/popups/remotelist.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,7 @@ impl RemoteListPopup {
245245
.enumerate()
246246
.map(|(i, remote)| {
247247
let selected = (self.selection as usize
248-
- self.scroll.get_top())
249-
== i;
248+
- self.scroll.get_top()) == i;
250249
let mut remote_name = remote.clone();
251250
if remote_name.len()
252251
> name_length

src/strings.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,20 @@ pub mod commands {
636636
CMD_GROUP_LOG,
637637
)
638638
}
639+
640+
pub fn copy_commit_msg(
641+
key_config: &SharedKeyConfig,
642+
) -> CommandText {
643+
CommandText::new(
644+
format!(
645+
"Copy Msg [{}]",
646+
key_config.get_hint(key_config.keys.copy_commit_msg),
647+
),
648+
"copy selected commit msg to clipboard",
649+
CMD_GROUP_LOG,
650+
)
651+
}
652+
639653
pub fn copy_path(key_config: &SharedKeyConfig) -> CommandText {
640654
CommandText::new(
641655
format!(

src/tabs/revlog.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,16 @@ impl Component for Revlog {
478478
self.list.copy_commit_hash()
479479
);
480480
return Ok(EventState::Consumed);
481+
} else if key_match(
482+
k,
483+
self.key_config.keys.copy_commit_msg,
484+
) {
485+
try_or_popup!(
486+
self,
487+
strings::POPUP_FAIL_COPY,
488+
self.list.copy_commit_msg()
489+
);
490+
return Ok(EventState::Consumed);
481491
} else if key_match(k, self.key_config.keys.push) {
482492
self.queue.push(InternalEvent::PushTags);
483493
return Ok(EventState::Consumed);
@@ -611,6 +621,8 @@ impl Component for Revlog {
611621
Ok(EventState::NotConsumed)
612622
}
613623

624+
//TODO: cleanup
625+
#[allow(clippy::too_many_lines)]
614626
fn commands(
615627
&self,
616628
out: &mut Vec<CommandInfo>,
@@ -677,6 +689,12 @@ impl Component for Revlog {
677689
self.visible || force_all,
678690
));
679691

692+
out.push(CommandInfo::new(
693+
strings::commands::copy_commit_msg(&self.key_config),
694+
self.selected_commit().is_some(),
695+
self.visible || force_all,
696+
));
697+
680698
out.push(CommandInfo::new(
681699
strings::commands::log_tag_commit(&self.key_config),
682700
self.selected_commit().is_some(),
@@ -718,11 +736,13 @@ impl Component for Revlog {
718736
self.selected_commit().is_some(),
719737
(self.visible && !self.is_search_pending()) || force_all,
720738
));
739+
721740
out.push(CommandInfo::new(
722741
strings::commands::log_reword_commit(&self.key_config),
723742
self.selected_commit().is_some(),
724743
(self.visible && !self.is_search_pending()) || force_all,
725744
));
745+
726746
out.push(CommandInfo::new(
727747
strings::commands::log_find_commit(&self.key_config),
728748
self.can_start_search(),

src/tabs/status.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -686,8 +686,7 @@ impl Status {
686686
strings::commands::select_staging(&self.key_config),
687687
!focus_on_diff,
688688
(self.visible
689-
&& !focus_on_diff
690-
&& self.focus == Focus::WorkDir)
689+
&& !focus_on_diff && self.focus == Focus::WorkDir)
691690
|| force_all,
692691
)
693692
.order(strings::order::NAV),
@@ -697,8 +696,7 @@ impl Status {
697696
strings::commands::select_unstaged(&self.key_config),
698697
!focus_on_diff,
699698
(self.visible
700-
&& !focus_on_diff
701-
&& self.focus == Focus::Stage)
699+
&& !focus_on_diff && self.focus == Focus::Stage)
702700
|| force_all,
703701
)
704702
.order(strings::order::NAV),

0 commit comments

Comments
 (0)