Display current repository path in the top-right corner (#1387)

This commit is contained in:
Alexandru Macovei 2022-10-20 17:23:58 +03:00 committed by GitHub
parent c7e54fa17d
commit 9c2d8c0e0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 78 additions and 13 deletions

View File

@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* add `vendor-openssl` feature to allow building without vendored openssl [[@jirutka](https://github.com/jirutka)]
* allow copying marked commits [[@remique](https://github.com/remique)] ([#1288](https://github.com/extrawurst/gitui/issues/1288))
* display tags and branches in the log view [[@alexmaco]](https://github.com/alexmaco)([#1371](https://github.com/extrawurst/gitui/pull/1371))
* display current repository path in the top-right corner [[@alexmaco]](https://github.com/alexmaco)([#1387](https://github.com/extrawurst/gitui/pull/1387))
### Fixes
* remove insecure dependency `ansi_term` ([#1290](https://github.com/extrawurst/gitui/issues/1290))

View File

@ -22,7 +22,7 @@ use crate::{
Action, InternalEvent, NeedsUpdate, Queue, StackablePopupOpen,
},
setup_popups,
strings::{self, order},
strings::{self, ellipsis_trim_start, order},
tabs::{FilesTab, Revlog, StashList, Stashing, Status},
ui::style::{SharedTheme, Theme},
AsyncAppNotification, AsyncNotification,
@ -41,11 +41,14 @@ use std::{
};
use tui::{
backend::Backend,
layout::{Constraint, Direction, Layout, Margin, Rect},
layout::{
Alignment, Constraint, Direction, Layout, Margin, Rect,
},
text::{Span, Spans},
widgets::{Block, Borders, Tabs},
widgets::{Block, Borders, Paragraph, Tabs},
Frame,
};
use unicode_width::UnicodeWidthStr;
#[derive(Clone)]
pub enum QuitState {
@ -94,6 +97,7 @@ pub struct App {
input: Input,
popup_stack: PopupStack,
options: SharedOptions,
repo_path_text: String,
// "Flags"
requires_redraw: Cell<bool>,
@ -114,6 +118,9 @@ impl App {
) -> Result<Self> {
log::trace!("open repo at: {:?}", &repo);
let repo_path_text =
repo_work_dir(&repo.borrow()).unwrap_or_default();
let queue = Queue::new();
let theme = Rc::new(theme);
let key_config = Rc::new(key_config);
@ -311,6 +318,7 @@ impl App {
requires_redraw: Cell::new(false),
file_to_open: None,
repo,
repo_path_text,
popup_stack: PopupStack::default(),
};
@ -339,7 +347,7 @@ impl App {
self.cmdbar.borrow().draw(f, chunks_main[2]);
self.draw_tabs(f, chunks_main[0]);
self.draw_top_bar(f, chunks_main[0]);
//TODO: component property + a macro `fullscreen_popup_open!`
// to make this scale better?
@ -1104,23 +1112,47 @@ impl App {
}
//TODO: make this dynamic
fn draw_tabs<B: Backend>(&self, f: &mut Frame<B>, r: Rect) {
fn draw_top_bar<B: Backend>(&self, f: &mut Frame<B>, r: Rect) {
const DIVIDER_PAD_SPACES: usize = 2;
const SIDE_PADS: usize = 2;
const MARGIN_LEFT_AND_RIGHT: usize = 2;
let r = r.inner(&Margin {
vertical: 0,
horizontal: 1,
});
let tabs = [
let tab_labels = [
Span::raw(strings::tab_status(&self.key_config)),
Span::raw(strings::tab_log(&self.key_config)),
Span::raw(strings::tab_files(&self.key_config)),
Span::raw(strings::tab_stashing(&self.key_config)),
Span::raw(strings::tab_stashes(&self.key_config)),
]
.iter()
.cloned()
.map(Spans::from)
.collect();
];
let divider = strings::tab_divider(&self.key_config);
// heuristic, since tui doesn't provide a way to know
// how much space is needed to draw a `Tabs`
let tabs_len: usize =
tab_labels.iter().map(Span::width).sum::<usize>()
+ tab_labels.len().saturating_sub(1)
* (divider.width() + DIVIDER_PAD_SPACES)
+ SIDE_PADS + MARGIN_LEFT_AND_RIGHT;
let left_right = Layout::default()
.direction(Direction::Horizontal)
.constraints(vec![
Constraint::Length(
u16::try_from(tabs_len).unwrap_or(r.width),
),
Constraint::Min(0),
])
.split(r);
let table_area = r; // use entire area to allow drawing the horizontal separator line
let text_area = left_right[1];
let tabs = tab_labels.into_iter().map(Spans::from).collect();
f.render_widget(
Tabs::new(tabs)
@ -1131,9 +1163,21 @@ impl App {
)
.style(self.theme.tab(false))
.highlight_style(self.theme.tab(true))
.divider(strings::tab_divider(&self.key_config))
.divider(divider)
.select(self.tab),
r,
table_area,
);
f.render_widget(
Paragraph::new(Spans::from(vec![Span::styled(
ellipsis_trim_start(
&self.repo_path_text,
text_area.width as usize,
),
self.theme.title(true),
)]))
.alignment(Alignment::Right),
text_area,
);
}
}

View File

@ -1,4 +1,8 @@
use std::borrow::Cow;
use asyncgit::sync::CommitId;
use unicode_truncate::UnicodeTruncateStr;
use unicode_width::UnicodeWidthStr;
use crate::keys::SharedKeyConfig;
@ -34,6 +38,7 @@ pub mod symbol {
pub const FOLDER_ICON_COLLAPSED: &str = "\u{25b8}"; //▸
pub const FOLDER_ICON_EXPANDED: &str = "\u{25be}"; //▾
pub const EMPTY_STR: &str = "";
pub const ELLIPSIS: char = '\u{2026}'; // …
}
pub fn title_branches() -> String {
@ -348,6 +353,21 @@ pub fn rename_branch_popup_msg(
"new branch name".to_string()
}
pub fn ellipsis_trim_start(s: &str, width: usize) -> Cow<str> {
if s.width() <= width {
Cow::Borrowed(s)
} else {
Cow::Owned(format!(
"[{}]{}",
symbol::ELLIPSIS,
s.unicode_truncate_start(
width.saturating_sub(3 /* front indicator */)
)
.0
))
}
}
pub mod commit {
use crate::keys::SharedKeyConfig;