Handle zero-width graphemes (usually ill-formed) more gracefully.
This commit is contained in:
parent
a28629d8b4
commit
d7d98946e5
|
@ -5,8 +5,7 @@ use std::io::{BufWriter, Write};
|
||||||
|
|
||||||
use crossterm::{self, execute, queue};
|
use crossterm::{self, execute, queue};
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
|
use unicode_width::UnicodeWidthStr;
|
||||||
use crate::utils::grapheme_width;
|
|
||||||
|
|
||||||
use super::smallstring::SmallString;
|
use super::smallstring::SmallString;
|
||||||
|
|
||||||
|
@ -93,9 +92,9 @@ impl Screen {
|
||||||
// Write everything to the buffered output.
|
// Write everything to the buffered output.
|
||||||
for y in 0..self.h {
|
for y in 0..self.h {
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
queue!(out, crossterm::cursor::MoveTo(0, y as u16)).unwrap();
|
|
||||||
while x < self.w {
|
while x < self.w {
|
||||||
if let Some((style, ref text)) = buf[y * self.w + x] {
|
if let Some((style, ref text)) = buf[y * self.w + x] {
|
||||||
|
queue!(out, crossterm::cursor::MoveTo(x as u16, y as u16)).unwrap();
|
||||||
if style != last_style {
|
if style != last_style {
|
||||||
queue!(
|
queue!(
|
||||||
out,
|
out,
|
||||||
|
@ -106,10 +105,8 @@ impl Screen {
|
||||||
last_style = style;
|
last_style = style;
|
||||||
}
|
}
|
||||||
write!(out, "{}", text).unwrap();
|
write!(out, "{}", text).unwrap();
|
||||||
x += 1;
|
|
||||||
} else {
|
|
||||||
x += 1;
|
|
||||||
}
|
}
|
||||||
|
x += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,16 +130,26 @@ impl Screen {
|
||||||
let mut buf = self.buf.borrow_mut();
|
let mut buf = self.buf.borrow_mut();
|
||||||
let mut x = x;
|
let mut x = x;
|
||||||
for g in UnicodeSegmentation::graphemes(text, true) {
|
for g in UnicodeSegmentation::graphemes(text, true) {
|
||||||
let width = grapheme_width(g);
|
if x < self.w {
|
||||||
if width > 0 {
|
let width = UnicodeWidthStr::width(g);
|
||||||
if x < self.w {
|
if width > 0 {
|
||||||
buf[y * self.w + x] = Some((style, g.into()));
|
buf[y * self.w + x] = Some((style, g.into()));
|
||||||
}
|
x += 1;
|
||||||
x += 1;
|
for _ in 1..width {
|
||||||
for _ in 0..(width - 1) {
|
if x < self.w {
|
||||||
if x < self.w {
|
buf[y * self.w + x] = None;
|
||||||
buf[y * self.w + x] = None;
|
}
|
||||||
|
x += 1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// If it's a zero-width character, prepend a space
|
||||||
|
// to give it width. While this isn't strictly
|
||||||
|
// unicode compliant, it serves the purpose of this
|
||||||
|
// type of editor well by making all graphemes visible,
|
||||||
|
// even if they're otherwise illformed.
|
||||||
|
let mut graph = SmallString::from_str(" ");
|
||||||
|
graph.push_str(g);
|
||||||
|
buf[y * self.w + x] = Some((style, graph));
|
||||||
x += 1;
|
x += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user