Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
70 changes: 57 additions & 13 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 {
Expand Down Expand Up @@ -94,6 +97,7 @@ pub struct App {
input: Input,
popup_stack: PopupStack,
options: SharedOptions,
repo_path_text: String,

// "Flags"
requires_redraw: Cell<bool>,
Expand All @@ -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);
Expand Down Expand Up @@ -311,6 +318,7 @@ impl App {
requires_redraw: Cell::new(false),
file_to_open: None,
repo,
repo_path_text,
popup_stack: PopupStack::default(),
};

Expand Down Expand Up @@ -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?
Expand Down Expand Up @@ -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)
Expand All @@ -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,
);
}
}
20 changes: 20 additions & 0 deletions src/strings.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use std::borrow::Cow;

use asyncgit::sync::CommitId;
use unicode_truncate::UnicodeTruncateStr;
use unicode_width::UnicodeWidthStr;

use crate::keys::SharedKeyConfig;

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;

Expand Down