fix(borders): properly handle wide chars in pane titles (#698)
* work * fix(frame): properly handle widechars in frame titles * style(fmt): make rustfmt happy * fix(truncate): do not reverse second part of string (oops) * docs(changelog): document change
This commit is contained in:
parent
1c9dc35121
commit
86fdd2400e
3 changed files with 62 additions and 28 deletions
|
|
@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||||
* Fix bug when opening new tab the new pane's viewport would sometimes be calculated incorrectly (https://github.com/zellij-org/zellij/pull/683)
|
* Fix bug when opening new tab the new pane's viewport would sometimes be calculated incorrectly (https://github.com/zellij-org/zellij/pull/683)
|
||||||
* Fix bug when in some cases closing a tab would not clear the previous pane's contents (https://github.com/zellij-org/zellij/pull/684)
|
* Fix bug when in some cases closing a tab would not clear the previous pane's contents (https://github.com/zellij-org/zellij/pull/684)
|
||||||
* Fix bug where tabs would sometimes be created with the wrong index in their name (https://github.com/zellij-org/zellij/pull/686)
|
* Fix bug where tabs would sometimes be created with the wrong index in their name (https://github.com/zellij-org/zellij/pull/686)
|
||||||
|
* Fix bug where wide chars would mess up pane titles (https://github.com/zellij-org/zellij/pull/698)
|
||||||
|
|
||||||
## [0.16.0] - 2021-08-31
|
## [0.16.0] - 2021-08-31
|
||||||
* Plugins don't crash zellij anymore on receiving mouse events (https://github.com/zellij-org/zellij/pull/620)
|
* Plugins don't crash zellij anymore on receiving mouse events (https://github.com/zellij-org/zellij/pull/620)
|
||||||
|
|
|
||||||
20
test-template.yaml
Normal file
20
test-template.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
template:
|
||||||
|
direction: Horizontal
|
||||||
|
parts:
|
||||||
|
- direction: Vertical
|
||||||
|
borderless: true
|
||||||
|
split_size:
|
||||||
|
Fixed: 1
|
||||||
|
run:
|
||||||
|
plugin: tab-bar
|
||||||
|
- direction: Vertical
|
||||||
|
borderless: true
|
||||||
|
- direction: Vertical
|
||||||
|
borderless: true
|
||||||
|
- direction: Vertical
|
||||||
|
borderless: true
|
||||||
|
split_size:
|
||||||
|
Fixed: 2
|
||||||
|
run:
|
||||||
|
plugin: status-bar
|
||||||
|
|
@ -4,6 +4,8 @@ use ansi_term::Style;
|
||||||
use zellij_utils::pane_size::Viewport;
|
use zellij_utils::pane_size::Viewport;
|
||||||
use zellij_utils::zellij_tile::prelude::PaletteColor;
|
use zellij_utils::zellij_tile::prelude::PaletteColor;
|
||||||
|
|
||||||
|
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
|
||||||
|
|
||||||
fn color_string(character: &str, color: Option<PaletteColor>) -> String {
|
fn color_string(character: &str, color: Option<PaletteColor>) -> String {
|
||||||
match color {
|
match color {
|
||||||
Some(color) => match color {
|
Some(color) => match color {
|
||||||
|
|
@ -33,11 +35,11 @@ impl PaneFrame {
|
||||||
let full_indication =
|
let full_indication =
|
||||||
format!(" {}/{} ", self.scroll_position.0, self.scroll_position.1);
|
format!(" {}/{} ", self.scroll_position.0, self.scroll_position.1);
|
||||||
let short_indication = format!(" {} ", self.scroll_position.0);
|
let short_indication = format!(" {} ", self.scroll_position.0);
|
||||||
if prefix.chars().count() + full_indication.chars().count() <= max_length {
|
if prefix.width() + full_indication.width() <= max_length {
|
||||||
Some(format!("{}{}", prefix, full_indication))
|
Some(format!("{}{}", prefix, full_indication))
|
||||||
} else if full_indication.chars().count() <= max_length {
|
} else if full_indication.width() <= max_length {
|
||||||
Some(full_indication)
|
Some(full_indication)
|
||||||
} else if short_indication.chars().count() <= max_length {
|
} else if short_indication.width() <= max_length {
|
||||||
Some(short_indication)
|
Some(short_indication)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
@ -52,28 +54,41 @@ impl PaneFrame {
|
||||||
let full_text = format!(" {} ", &self.title);
|
let full_text = format!(" {} ", &self.title);
|
||||||
if max_length <= 6 {
|
if max_length <= 6 {
|
||||||
None
|
None
|
||||||
} else if full_text.chars().count() <= max_length {
|
} else if full_text.width() <= max_length {
|
||||||
Some(full_text)
|
Some(full_text)
|
||||||
} else {
|
} else {
|
||||||
let length_of_each_half = (max_length - middle_truncated_sign.chars().count()) / 2;
|
let length_of_each_half = (max_length - middle_truncated_sign.width()) / 2;
|
||||||
let first_part: String = full_text.chars().take(length_of_each_half).collect();
|
|
||||||
let second_part: String = full_text
|
let mut first_part: String = String::with_capacity(length_of_each_half);
|
||||||
.chars()
|
for char in full_text.chars() {
|
||||||
.skip(full_text.chars().count() - length_of_each_half)
|
if first_part.width() + char.width().unwrap_or(0) > length_of_each_half {
|
||||||
.collect();
|
break;
|
||||||
let title_left_side = if first_part.chars().count()
|
} else {
|
||||||
+ middle_truncated_sign.chars().count()
|
first_part.push(char);
|
||||||
+ second_part.chars().count()
|
}
|
||||||
< max_length
|
}
|
||||||
{
|
|
||||||
// this means we lost 1 character when dividing the total length into halves
|
let mut second_part: String = String::with_capacity(length_of_each_half);
|
||||||
format!(
|
for char in full_text.chars().rev() {
|
||||||
"{}{}{}",
|
if second_part.width() + char.width().unwrap_or(0) > length_of_each_half {
|
||||||
first_part, middle_truncated_sign_long, second_part
|
break;
|
||||||
)
|
} else {
|
||||||
} else {
|
second_part.insert(0, char);
|
||||||
format!("{}{}{}", first_part, middle_truncated_sign, second_part)
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
let title_left_side =
|
||||||
|
if first_part.width() + middle_truncated_sign.width() + second_part.width()
|
||||||
|
< max_length
|
||||||
|
{
|
||||||
|
// this means we lost 1 character when dividing the total length into halves
|
||||||
|
format!(
|
||||||
|
"{}{}{}",
|
||||||
|
first_part, middle_truncated_sign_long, second_part
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format!("{}{}{}", first_part, middle_truncated_sign, second_part)
|
||||||
|
};
|
||||||
Some(title_left_side)
|
Some(title_left_side)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -83,15 +98,13 @@ impl PaneFrame {
|
||||||
let right_boundary = boundary_type::TOP_RIGHT;
|
let right_boundary = boundary_type::TOP_RIGHT;
|
||||||
let left_side = self.render_title_left_side(total_title_length);
|
let left_side = self.render_title_left_side(total_title_length);
|
||||||
let right_side = left_side.as_ref().and_then(|left_side| {
|
let right_side = left_side.as_ref().and_then(|left_side| {
|
||||||
let space_left = total_title_length.saturating_sub(left_side.chars().count() + 1); // 1 for a middle separator
|
let space_left = total_title_length.saturating_sub(left_side.width() + 1); // 1 for a middle separator
|
||||||
self.render_title_right_side(space_left)
|
self.render_title_right_side(space_left)
|
||||||
});
|
});
|
||||||
let title_text = match (left_side, right_side) {
|
let title_text = match (left_side, right_side) {
|
||||||
(Some(left_side), Some(right_side)) => {
|
(Some(left_side), Some(right_side)) => {
|
||||||
let mut middle = String::new();
|
let mut middle = String::new();
|
||||||
for _ in
|
for _ in (left_side.width() + right_side.width())..total_title_length {
|
||||||
(left_side.chars().count() + right_side.chars().count())..total_title_length
|
|
||||||
{
|
|
||||||
middle.push_str(boundary_type::HORIZONTAL);
|
middle.push_str(boundary_type::HORIZONTAL);
|
||||||
}
|
}
|
||||||
format!(
|
format!(
|
||||||
|
|
@ -101,7 +114,7 @@ impl PaneFrame {
|
||||||
}
|
}
|
||||||
(Some(left_side), None) => {
|
(Some(left_side), None) => {
|
||||||
let mut middle_padding = String::new();
|
let mut middle_padding = String::new();
|
||||||
for _ in left_side.chars().count()..total_title_length {
|
for _ in left_side.width()..total_title_length {
|
||||||
middle_padding.push_str(boundary_type::HORIZONTAL);
|
middle_padding.push_str(boundary_type::HORIZONTAL);
|
||||||
}
|
}
|
||||||
format!(
|
format!(
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue