summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--test-template.yaml20
-rw-r--r--zellij-server/src/ui/pane_boundaries_frame.rs69
3 files changed, 62 insertions, 28 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7908d67e8..8cf07418c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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 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 wide chars would mess up pane titles (https://github.com/zellij-org/zellij/pull/698)
## [0.16.0] - 2021-08-31
* Plugins don't crash zellij anymore on receiving mouse events (https://github.com/zellij-org/zellij/pull/620)
diff --git a/test-template.yaml b/test-template.yaml
new file mode 100644
index 000000000..b9c496d41
--- /dev/null
+++ b/test-template.yaml
@@ -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
diff --git a/zellij-server/src/ui/pane_boundaries_frame.rs b/zellij-server/src/ui/pane_boundaries_frame.rs
index d3cd6d5af..493441496 100644
--- a/zellij-server/src/ui/pane_boundaries_frame.rs
+++ b/zellij-server/src/ui/pane_boundaries_frame.rs
@@ -4,6 +4,8 @@ use ansi_term::Style;
use zellij_utils::pane_size::Viewport;
use zellij_utils::zellij_tile::prelude::PaletteColor;
+use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
+
fn color_string(character: &str, color: Option<PaletteColor>) -> String {
match color {
Some(color) => match color {
@@ -33,11 +35,11 @@ impl PaneFrame {
let full_indication =
format!(" {}/{} ", self.scroll_position.0, self.scroll_position.1);
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))
- } else if full_indication.chars().count() <= max_length {
+ } else if full_indication.width() <= max_length {
Some(full_indication)
- } else if short_indication.chars().count() <= max_length {
+ } else if short_indication.width() <= max_length {
Some(short_indication)
} else {
None
@@ -52,28 +54,41 @@ impl PaneFrame {
let full_text = format!(" {} ", &self.title);
if max_length <= 6 {
None
- } else if full_text.chars().count() <= max_length {
+ } else if full_text.width() <= max_length {
Some(full_text)
} else {
- let length_of_each_half = (max_length - middle_truncated_sign.chars().count()) / 2;
- let first_part: String = full_text.chars().take(length_of_each_half).collect();
- let second_part: String = full_text
- .chars()
- .skip(full_text.chars().count() - length_of_each_half)
- .collect();
- let title_left_side = if first_part.chars().count()
- + middle_truncated_sign.chars().count()
- + second_part.chars().count()
- < 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)
- };
+ let length_of_each_half = (max_length - middle_truncated_sign.width()) / 2;
+
+ let mut first_part: String = String::with_capacity(length_of_each_half);
+ for char in full_text.chars() {
+ if first_part.width() + char.width().unwrap_or(0) > length_of_each_half {
+ break;
+ } else {
+ first_part.push(char);
+ }
+ }
+
+ let mut second_part: String = String::with_capacity(length_of_each_half);
+ for char in full_text.chars().rev() {
+ if second_part.width() + char.width().unwrap_or(0) > length_of_each_half {
+ break;
+ } else {
+ second_part.insert(0, char);
+ }
+ }
+
+ 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)
}
}
@@ -83,15 +98,13 @@ impl PaneFrame {
let right_boundary = boundary_type::TOP_RIGHT;
let left_side = self.render_title_left_side(total_title_length);
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)
});
let title_text = match (left_side, right_side) {
(Some(left_side), Some(right_side)) => {
let mut middle = String::new();
- for _ in
- (left_side.chars().count() + right_side.chars().count())..total_title_length
- {
+ for _ in (left_side.width() + right_side.width())..total_title_length {
middle.push_str(boundary_type::HORIZONTAL);
}
format!(
@@ -101,7 +114,7 @@ impl PaneFrame {
}
(Some(left_side), None) => {
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);
}
format!(