mirror of
https://github.com/gitui-org/gitui
synced 2026-05-23 08:58:21 +00:00
allow inspecting tag annotation
This commit is contained in:
parent
a1f3931b59
commit
166826f5ea
6 changed files with 93 additions and 7 deletions
|
|
@ -4,7 +4,10 @@ use crate::{
|
|||
sync::{repository::repo, utils::bytes2string},
|
||||
};
|
||||
use scopetime::scope_time;
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap, HashSet},
|
||||
ops::Not,
|
||||
};
|
||||
|
||||
///
|
||||
#[derive(Clone, Hash, PartialEq, Debug)]
|
||||
|
|
@ -42,6 +45,8 @@ pub struct TagWithMetadata {
|
|||
pub message: String,
|
||||
///
|
||||
pub commit_id: CommitId,
|
||||
///
|
||||
pub annotation: Option<String>,
|
||||
}
|
||||
|
||||
static MAX_MESSAGE_WIDTH: usize = 100;
|
||||
|
|
@ -87,7 +92,12 @@ pub fn get_tags(repo_path: &RepoPath) -> Result<Tags> {
|
|||
.ok()
|
||||
.as_ref()
|
||||
.and_then(git2::Tag::message_bytes)
|
||||
.and_then(|msg| bytes2string(msg).ok());
|
||||
.and_then(|msg| {
|
||||
msg.is_empty()
|
||||
.not()
|
||||
.then(|| bytes2string(msg).ok())
|
||||
.flatten()
|
||||
});
|
||||
|
||||
if let Some(commit) = commit {
|
||||
adder(commit, Tag { name, annotation });
|
||||
|
|
@ -109,20 +119,26 @@ pub fn get_tags_with_metadata(
|
|||
|
||||
let tags_grouped_by_commit_id = get_tags(repo_path)?;
|
||||
|
||||
let tags_with_commit_id: Vec<(&str, &CommitId)> =
|
||||
let tags_with_commit_id: Vec<(&str, Option<&str>, &CommitId)> =
|
||||
tags_grouped_by_commit_id
|
||||
.iter()
|
||||
.flat_map(|(commit_id, tags)| {
|
||||
tags.iter()
|
||||
.map(|tag| (tag.name.as_ref(), commit_id))
|
||||
.collect::<Vec<(&str, &CommitId)>>()
|
||||
.map(|tag| {
|
||||
(
|
||||
tag.name.as_ref(),
|
||||
tag.annotation.as_deref(),
|
||||
commit_id,
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect();
|
||||
|
||||
let unique_commit_ids: HashSet<_> = tags_with_commit_id
|
||||
.iter()
|
||||
.copied()
|
||||
.map(|(_, &commit_id)| commit_id)
|
||||
.map(|(_, _, &commit_id)| commit_id)
|
||||
.collect();
|
||||
let mut commit_ids = Vec::with_capacity(unique_commit_ids.len());
|
||||
commit_ids.extend(unique_commit_ids);
|
||||
|
|
@ -136,7 +152,7 @@ pub fn get_tags_with_metadata(
|
|||
|
||||
let mut tags: Vec<TagWithMetadata> = tags_with_commit_id
|
||||
.into_iter()
|
||||
.filter_map(|(tag, commit_id)| {
|
||||
.filter_map(|(tag, annotation, commit_id)| {
|
||||
unique_commit_infos.get(commit_id).map(|commit_info| {
|
||||
TagWithMetadata {
|
||||
name: String::from(tag),
|
||||
|
|
@ -144,6 +160,7 @@ pub fn get_tags_with_metadata(
|
|||
time: commit_info.time,
|
||||
message: commit_info.message.clone(),
|
||||
commit_id: *commit_id,
|
||||
annotation: annotation.map(String::from),
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -674,6 +674,11 @@ impl App {
|
|||
flags
|
||||
.insert(NeedsUpdate::ALL | NeedsUpdate::COMMANDS);
|
||||
}
|
||||
InternalEvent::ShowInfoMsg(msg) => {
|
||||
self.msg.show_info(msg.as_str())?;
|
||||
flags
|
||||
.insert(NeedsUpdate::ALL | NeedsUpdate::COMMANDS);
|
||||
}
|
||||
InternalEvent::Update(u) => flags.insert(u),
|
||||
InternalEvent::OpenCommit => self.commit.show()?,
|
||||
InternalEvent::PopupStashing(opts) => {
|
||||
|
|
|
|||
|
|
@ -139,4 +139,13 @@ impl MsgComponent {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
///
|
||||
pub fn show_info(&mut self, msg: &str) -> Result<()> {
|
||||
self.title = strings::msg_title_info(&self.key_config);
|
||||
self.msg = msg.to_string();
|
||||
self.show()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ impl DrawableComponent for TagListComponent {
|
|||
Constraint::Length(10),
|
||||
// author width
|
||||
Constraint::Length(19),
|
||||
// attachement
|
||||
Constraint::Length(1),
|
||||
// commit id
|
||||
Constraint::Percentage(100),
|
||||
];
|
||||
|
|
@ -171,6 +173,13 @@ impl Component for TagListComponent {
|
|||
true,
|
||||
true,
|
||||
));
|
||||
out.push(CommandInfo::new(
|
||||
strings::commands::show_tag_annotation(
|
||||
&self.key_config,
|
||||
),
|
||||
self.can_show_annotation(),
|
||||
true,
|
||||
));
|
||||
}
|
||||
visibility_blocking(self)
|
||||
}
|
||||
|
|
@ -196,6 +205,10 @@ impl Component for TagListComponent {
|
|||
self.move_selection(ScrollType::PageDown);
|
||||
} else if key == self.key_config.keys.page_up {
|
||||
self.move_selection(ScrollType::PageUp);
|
||||
} else if key == self.key_config.keys.move_right
|
||||
&& self.can_show_annotation()
|
||||
{
|
||||
self.show_annotation();
|
||||
} else if key == self.key_config.keys.delete_tag {
|
||||
return self.selected_tag().map_or(
|
||||
Ok(EventState::NotConsumed),
|
||||
|
|
@ -372,6 +385,22 @@ impl TagListComponent {
|
|||
needs_update
|
||||
}
|
||||
|
||||
fn show_annotation(&self) {
|
||||
if let Some(tag) = self.selected_tag() {
|
||||
if let Some(annotation) = &tag.annotation {
|
||||
self.queue.push(InternalEvent::ShowInfoMsg(
|
||||
annotation.clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn can_show_annotation(&self) -> bool {
|
||||
self.selected_tag()
|
||||
.and_then(|t| t.annotation.as_ref())
|
||||
.is_some()
|
||||
}
|
||||
|
||||
///
|
||||
fn get_rows(&self) -> Vec<Row> {
|
||||
self.tags.as_ref().map_or_else(Vec::new, |tags| {
|
||||
|
|
@ -382,6 +411,7 @@ impl TagListComponent {
|
|||
///
|
||||
fn get_row(&self, tag: &TagWithMetadata) -> Row {
|
||||
const UPSTREAM_SYMBOL: &str = "\u{2191}";
|
||||
const ATTACHEMENT_SYMBOL: &str = "!";
|
||||
const EMPTY_SYMBOL: &str = " ";
|
||||
|
||||
let is_tag_missing_on_remote = self
|
||||
|
|
@ -399,6 +429,12 @@ impl TagListComponent {
|
|||
EMPTY_SYMBOL
|
||||
};
|
||||
|
||||
let has_attachement_str = if tag.annotation.is_some() {
|
||||
ATTACHEMENT_SYMBOL
|
||||
} else {
|
||||
EMPTY_SYMBOL
|
||||
};
|
||||
|
||||
let cells: Vec<Cell> = vec![
|
||||
Cell::from(has_remote_str)
|
||||
.style(self.theme.commit_author(false)),
|
||||
|
|
@ -408,6 +444,8 @@ impl TagListComponent {
|
|||
.style(self.theme.commit_time(false)),
|
||||
Cell::from(tag.author.clone())
|
||||
.style(self.theme.commit_author(false)),
|
||||
Cell::from(has_attachement_str)
|
||||
.style(self.theme.commit_time(false)),
|
||||
Cell::from(tag.message.clone())
|
||||
.style(self.theme.text(true, false)),
|
||||
];
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ pub enum InternalEvent {
|
|||
///
|
||||
ShowErrorMsg(String),
|
||||
///
|
||||
ShowInfoMsg(String),
|
||||
///
|
||||
Update(NeedsUpdate),
|
||||
///
|
||||
StatusLastFileMoved,
|
||||
|
|
|
|||
|
|
@ -87,6 +87,9 @@ pub fn msg_opening_editor(_key_config: &SharedKeyConfig) -> String {
|
|||
pub fn msg_title_error(_key_config: &SharedKeyConfig) -> String {
|
||||
"Error".to_string()
|
||||
}
|
||||
pub fn msg_title_info(_key_config: &SharedKeyConfig) -> String {
|
||||
"Info".to_string()
|
||||
}
|
||||
pub fn commit_title() -> String {
|
||||
"Commit".to_string()
|
||||
}
|
||||
|
|
@ -530,6 +533,18 @@ pub mod commands {
|
|||
CMD_GROUP_LOG,
|
||||
)
|
||||
}
|
||||
pub fn show_tag_annotation(
|
||||
key_config: &SharedKeyConfig,
|
||||
) -> CommandText {
|
||||
CommandText::new(
|
||||
format!(
|
||||
"Annotation [{}]",
|
||||
key_config.get_hint(key_config.keys.move_right),
|
||||
),
|
||||
"show tag annotation",
|
||||
CMD_GROUP_LOG,
|
||||
)
|
||||
}
|
||||
pub fn diff_home_end(
|
||||
key_config: &SharedKeyConfig,
|
||||
) -> CommandText {
|
||||
|
|
|
|||
Loading…
Reference in a new issue