mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
fix: tab name width calculating (#58)
This commit is contained in:
parent
35ca32e74b
commit
05433c38d0
2 changed files with 34 additions and 26 deletions
|
|
@ -2,7 +2,7 @@ use std::ops::ControlFlow;
|
||||||
|
|
||||||
use config::THEME;
|
use config::THEME;
|
||||||
use ratatui::{buffer::Buffer, layout::{Alignment, Rect}, text::{Line, Span}, widgets::{Paragraph, Widget}};
|
use ratatui::{buffer::Buffer, layout::{Alignment, Rect}, text::{Line, Span}, widgets::{Paragraph, Widget}};
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
|
||||||
|
|
||||||
use crate::Ctx;
|
use crate::Ctx;
|
||||||
|
|
||||||
|
|
@ -12,6 +12,25 @@ pub(super) struct Tabs<'a> {
|
||||||
|
|
||||||
impl<'a> Tabs<'a> {
|
impl<'a> Tabs<'a> {
|
||||||
pub(super) fn new(cx: &'a Ctx) -> Self { Self { cx } }
|
pub(super) fn new(cx: &'a Ctx) -> Self { Self { cx } }
|
||||||
|
|
||||||
|
fn truncate(&self, name: &str) -> String {
|
||||||
|
let mut width = 0;
|
||||||
|
let flow =
|
||||||
|
name.chars().try_fold(String::with_capacity(THEME.tab.max_width as usize), |mut s, c| {
|
||||||
|
width += c.width().unwrap_or(0);
|
||||||
|
if s.width() < THEME.tab.max_width as usize {
|
||||||
|
s.push(c);
|
||||||
|
ControlFlow::Continue(s)
|
||||||
|
} else {
|
||||||
|
ControlFlow::Break(s)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
match flow {
|
||||||
|
ControlFlow::Break(s) => s,
|
||||||
|
ControlFlow::Continue(s) => s,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Widget for Tabs<'a> {
|
impl<'a> Widget for Tabs<'a> {
|
||||||
|
|
@ -24,25 +43,12 @@ impl<'a> Widget for Tabs<'a> {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, tab)| {
|
.map(|(i, tab)| {
|
||||||
let mut text = format!("{}", i + 1);
|
let mut text = format!("{}", i + 1);
|
||||||
if let Some(dir_name) = tab.current_name() {
|
if THEME.tab.max_width >= 3 {
|
||||||
text.push(' ');
|
text.push(' ');
|
||||||
text.push_str(dir_name);
|
text.push_str(tab.name());
|
||||||
|
text = self.truncate(&text);
|
||||||
}
|
}
|
||||||
|
|
||||||
let threshold = THEME.tab.max_width.max(1);
|
|
||||||
let truncated = text.chars().try_fold(String::with_capacity(threshold), |mut text, c| {
|
|
||||||
if text.width() > threshold {
|
|
||||||
ControlFlow::Break(text)
|
|
||||||
} else {
|
|
||||||
text.push(c);
|
|
||||||
ControlFlow::Continue(text)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let text = match truncated {
|
|
||||||
ControlFlow::Break(text) => text,
|
|
||||||
ControlFlow::Continue(text) => text,
|
|
||||||
};
|
|
||||||
|
|
||||||
if i == tabs.idx() {
|
if i == tabs.idx() {
|
||||||
Span::styled(format!(" {text} "), THEME.tab.active.get())
|
Span::styled(format!(" {text} "), THEME.tab.active.get())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -264,21 +264,23 @@ impl Tab {
|
||||||
};
|
};
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_name(&self) -> Option<&str> {
|
|
||||||
self
|
|
||||||
.current
|
|
||||||
.cwd
|
|
||||||
.file_name()
|
|
||||||
.and_then(|name| name.to_str())
|
|
||||||
.or_else(|| self.current.cwd.to_str())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tab {
|
impl Tab {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mode(&self) -> &Mode { &self.mode }
|
pub fn mode(&self) -> &Mode { &self.mode }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
self
|
||||||
|
.current
|
||||||
|
.cwd
|
||||||
|
.file_name()
|
||||||
|
.and_then(|n| n.to_str())
|
||||||
|
.or_else(|| self.current.cwd.to_str())
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn history(&self, path: &Path) -> Option<&Folder> { self.history.get(path) }
|
pub fn history(&self, path: &Path) -> Option<&Folder> { self.history.get(path) }
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue