1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-27 02:25:28 +03:00

add window:set_left_status

refs: https://github.com/wez/wezterm/issues/1561
This commit is contained in:
Wez Furlong 2022-08-06 20:41:39 -07:00
parent 28d803e3f4
commit e4435938a8
7 changed files with 99 additions and 31 deletions

View File

@ -36,6 +36,7 @@ As features stabilize some brief notes about them will accumulate here.
* [mouse_bindings](config/mouse.md) can now handle scroll events. Thanks to [@Funami580](https://github.com/Funami580)! [#2173](https://github.com/wez/wezterm/issues/2173) [#2296](https://github.com/wez/wezterm/pull/2296)
* [mouse_bindings](config/mouse.md) may now also be defined based on whether the alt-screen is active and/or whether the application in the pane has enabled mouse reporting. [#581](https://github.com/wez/wezterm/issues/581)
* `wezterm.action.CopyMode('ClearSelectionMode')` allows clearing the selection mode without leaving [Copy Mode](copymode.md). Thanks to [@aznhe21](https://github.com/aznhe21)! [#2352](https://github.com/wez/wezterm/pull/2352)
* [window:set_left_status](config/lua/window/set_left_status.md) for setting status to the left of the tabs in the tab bar [#1561](https://github.com/wez/wezterm/issues/1561)
#### Changed
* If `timeout_milliseconds` is specified in

View File

@ -0,0 +1,17 @@
# `window:set_left_status(string)`
*Since: nightly builds only*
This method can be used to change the content that is displayed in the tab bar,
to the left of the tabs. The content is displayed
left-aligned and will take as much space as needed to display the content
that you set; it will not be implicitly clipped.
The parameter is a string that can contain escape sequences that change
presentation.
It is recommended that you use [wezterm.format](../wezterm/format.md) to
compose the string.
See [window:set_right_status](set_right_status.md) for examples.

View File

@ -89,6 +89,10 @@ impl UserData for GuiWin {
this.window.notify(TermWindowNotif::SetRightStatus(status));
Ok(())
});
methods.add_method("set_left_status", |_, this, status: String| {
this.window.notify(TermWindowNotif::SetLeftStatus(status));
Ok(())
});
methods.add_async_method("get_dimensions", |_, this, _: ()| async move {
let (tx, rx) = smol::channel::bounded(1);
this.window.notify(TermWindowNotif::GetDimensions(tx));

View File

@ -19,6 +19,8 @@ pub struct TabBarState {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TabBarItem {
None,
LeftStatus,
RightStatus,
Tab { tab_idx: usize, active: bool },
NewTabButton,
}
@ -187,6 +189,7 @@ impl TabBarState {
pane_info: &[PaneInformation],
colors: Option<&TabBarColors>,
config: &ConfigHandle,
left_status: &str,
right_status: &str,
) -> Self {
let colors = colors.cloned().unwrap_or_else(TabBarColors::default);
@ -257,6 +260,24 @@ impl TabBarState {
let mut x = 0;
let mut items = vec![];
let black_cell = Cell::blank_with_attrs(
CellAttributes::default()
.set_background(ColorSpec::TrueColor(*colors.background))
.clone(),
);
let left_status_line = parse_status_text(left_status, black_cell.attrs().clone());
if left_status_line.len() > 0 {
items.push(TabEntry {
item: TabBarItem::LeftStatus,
title: left_status_line.clone(),
x,
width: left_status_line.len(),
});
x += left_status_line.len();
line.append_line(left_status_line, SEQ_ZERO);
}
for (tab_idx, tab_title) in tab_titles.iter().enumerate() {
let tab_title_len = tab_title.len.min(tab_width_max);
let active = tab_idx == active_tab_no;
@ -332,26 +353,21 @@ impl TabBarState {
x += width;
}
let black_cell = Cell::blank_with_attrs(
CellAttributes::default()
.set_background(ColorSpec::TrueColor(*colors.background))
.clone(),
);
let status_space_available = title_width.saturating_sub(x);
let mut status_line = parse_status_text(right_status, black_cell.attrs().clone());
let mut right_status_line = parse_status_text(right_status, black_cell.attrs().clone());
items.push(TabEntry {
item: TabBarItem::None,
title: status_line.clone(),
item: TabBarItem::RightStatus,
title: right_status_line.clone(),
x,
width: status_space_available,
});
while status_line.len() > status_space_available {
status_line.remove_cell(0, SEQ_ZERO);
while right_status_line.len() > status_space_available {
right_status_line.remove_cell(0, SEQ_ZERO);
}
line.append_line(status_line, SEQ_ZERO);
line.append_line(right_status_line, SEQ_ZERO);
while line.len() < title_width {
line.insert_cell(x, black_cell.clone(), title_width, SEQ_ZERO);
}

View File

@ -110,6 +110,7 @@ pub enum TermWindowNotif {
pane_id: PaneId,
assignment: KeyAssignment,
},
SetLeftStatus(String),
SetRightStatus(String),
GetDimensions(Sender<(Dimensions, WindowState)>),
GetSelectionForPane {
@ -366,6 +367,7 @@ pub struct TermWindow {
tab_bar: TabBarState,
fancy_tab_bar: Option<box_model::ComputedElement>,
pub right_status: String,
pub left_status: String,
last_ui_item: Option<UIItem>,
/// Tracks whether the current mouse-down event is part of click-focus.
/// If so, we ignore mouse events until released
@ -658,6 +660,7 @@ impl TermWindow {
tab_bar: TabBarState::default(),
fancy_tab_bar: None,
right_status: String::new(),
left_status: String::new(),
last_mouse_coords: (0, -1),
window_drag_position: None,
current_mouse_event: None,
@ -931,6 +934,14 @@ impl TermWindow {
self.schedule_next_status_update();
}
}
TermWindowNotif::SetLeftStatus(status) => {
if status != self.left_status {
self.left_status = status;
self.update_title_post_status();
} else {
self.schedule_next_status_update();
}
}
TermWindowNotif::GetDimensions(tx) => {
tx.try_send((self.dimensions, self.window_state))
.map_err(chan_err)
@ -1629,6 +1640,7 @@ impl TermWindow {
&panes,
self.config.resolved_palette.tab_bar.as_ref(),
&self.config,
&self.left_status,
&self.right_status,
);
if new_tab_bar != self.tab_bar {

View File

@ -395,7 +395,7 @@ impl super::TermWindow {
TabBarItem::NewTabButton { .. } => {
self.spawn_tab(&SpawnTabDomain::CurrentPaneDomain);
}
TabBarItem::None => {
TabBarItem::None | TabBarItem::LeftStatus | TabBarItem::RightStatus => {
// Potentially starting a drag by the tab bar
if !self
.window_state
@ -410,7 +410,10 @@ impl super::TermWindow {
TabBarItem::Tab { tab_idx, .. } => {
self.close_tab_idx(tab_idx).ok();
}
TabBarItem::NewTabButton { .. } | TabBarItem::None => {}
TabBarItem::NewTabButton { .. }
| TabBarItem::None
| TabBarItem::LeftStatus
| TabBarItem::RightStatus => {}
},
WMEK::Press(MousePress::Right) => match item {
TabBarItem::Tab { .. } => {
@ -419,7 +422,7 @@ impl super::TermWindow {
TabBarItem::NewTabButton { .. } => {
self.show_launcher();
}
TabBarItem::None => {}
TabBarItem::None | TabBarItem::LeftStatus | TabBarItem::RightStatus => {}
},
WMEK::Move => match item {
TabBarItem::None => {

View File

@ -488,6 +488,7 @@ impl super::TermWindow {
.cloned()
.unwrap_or_else(TabBarColors::default);
let mut left_status = vec![];
let mut left_eles = vec![];
let mut right_eles = vec![];
let bar_colors = ElementColors {
@ -525,7 +526,7 @@ impl super::TermWindow {
});
match item.item {
TabBarItem::None => element
TabBarItem::RightStatus | TabBarItem::LeftStatus | TabBarItem::None => element
.item_type(UIItemType::TabBar(TabBarItem::None))
.line_height(Some(1.75))
.margin(BoxDimension {
@ -709,7 +710,8 @@ impl super::TermWindow {
for item in items {
match item.item {
TabBarItem::None => right_eles.push(item_to_elem(item)),
TabBarItem::LeftStatus => left_status.push(item_to_elem(item)),
TabBarItem::None | TabBarItem::RightStatus => right_eles.push(item_to_elem(item)),
TabBarItem::Tab { tab_idx, active } => {
let mut elem = item_to_elem(item);
elem.max_width = Some(Dimension::Pixels(max_tab_width));
@ -774,21 +776,34 @@ impl super::TermWindow {
}
}
let left_ele = Element::new(&font, ElementContent::Children(left_eles))
.vertical_align(VerticalAlign::Bottom)
.colors(bar_colors.clone())
.padding(BoxDimension {
left: Dimension::Cells(0.5),
right: Dimension::Cells(0.),
top: Dimension::Cells(0.),
bottom: Dimension::Cells(0.),
})
.zindex(1);
let right_ele = Element::new(&font, ElementContent::Children(right_eles))
.colors(bar_colors.clone())
.float(Float::Right);
let mut children = vec![];
let content = ElementContent::Children(vec![left_ele, right_ele]);
if !left_status.is_empty() {
children.push(
Element::new(&font, ElementContent::Children(left_status))
.colors(bar_colors.clone()),
);
}
children.push(
Element::new(&font, ElementContent::Children(left_eles))
.vertical_align(VerticalAlign::Bottom)
.colors(bar_colors.clone())
.padding(BoxDimension {
left: Dimension::Cells(0.5),
right: Dimension::Cells(0.),
top: Dimension::Cells(0.),
bottom: Dimension::Cells(0.),
})
.zindex(1),
);
children.push(
Element::new(&font, ElementContent::Children(right_eles))
.colors(bar_colors.clone())
.float(Float::Right),
);
let content = ElementContent::Children(children);
let tabs = Element::new(&font, content)
.display(DisplayType::Block)