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