WIP making the buffer faster.
This commit is contained in:
parent
66a80baeed
commit
945505c5ff
|
@ -17,7 +17,7 @@ use utils::digit_count;
|
|||
pub mod formatter;
|
||||
mod screen;
|
||||
|
||||
use self::screen::Screen;
|
||||
use self::screen::{Color, Screen, Style};
|
||||
|
||||
/// Generalized ui loop.
|
||||
macro_rules! ui_loop {
|
||||
|
@ -203,8 +203,7 @@ impl<'a> TermUI<'a> {
|
|||
}
|
||||
|
||||
fn go_to_line_ui_loop(&mut self) {
|
||||
let foreground = color::Black;
|
||||
let background = color::Cyan;
|
||||
let style = Style(Color::Black, Color::Cyan);
|
||||
|
||||
let mut cancel = false;
|
||||
let prefix = "Jump to line: ";
|
||||
|
@ -220,15 +219,14 @@ impl<'a> TermUI<'a> {
|
|||
self.screen.clear();
|
||||
self.draw_editor(&self.editor, (0, 0), (self.height - 1, self.width - 1));
|
||||
for i in 0..self.width {
|
||||
self.screen.draw(i, 0, " ", foreground, background);
|
||||
self.screen.draw(i, 0, " ", style);
|
||||
}
|
||||
self.screen.draw(1, 0, prefix, foreground, background);
|
||||
self.screen.draw(1, 0, prefix, style);
|
||||
self.screen.draw(
|
||||
prefix.len() + 1,
|
||||
0,
|
||||
&line[..],
|
||||
foreground,
|
||||
background,
|
||||
style,
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -281,19 +279,18 @@ impl<'a> TermUI<'a> {
|
|||
c1: (usize, usize),
|
||||
c2: (usize, usize),
|
||||
) {
|
||||
let fg = color::Black;
|
||||
let bg = color::Cyan;
|
||||
let style = Style(Color::Black, Color::Cyan);
|
||||
|
||||
// Fill in top row with info line color
|
||||
for i in c1.1..(c2.1 + 1) {
|
||||
self.screen.draw(i, c1.0, " ", fg, bg);
|
||||
self.screen.draw(i, c1.0, " ", style);
|
||||
}
|
||||
|
||||
// Filename and dirty marker
|
||||
let filename = editor.file_path.display();
|
||||
let dirty_char = if editor.dirty { "*" } else { "" };
|
||||
let name = format!("{}{}", filename, dirty_char);
|
||||
self.screen.draw(c1.1 + 1, c1.0, &name[..], fg, bg);
|
||||
self.screen.draw(c1.1 + 1, c1.0, &name[..], style);
|
||||
|
||||
// Percentage position in document
|
||||
// TODO: use view instead of cursor for calculation if there is more
|
||||
|
@ -306,7 +303,7 @@ impl<'a> TermUI<'a> {
|
|||
};
|
||||
let pstring = format!("{}%", percentage);
|
||||
self.screen
|
||||
.draw(c2.1 - pstring.len(), c1.0, &pstring[..], fg, bg);
|
||||
.draw(c2.1 - pstring.len(), c1.0, &pstring[..], style);
|
||||
|
||||
// Text encoding info and tab style
|
||||
let nl = match editor.line_ending_type {
|
||||
|
@ -325,7 +322,7 @@ impl<'a> TermUI<'a> {
|
|||
"UTF8:{} {}:{}",
|
||||
nl, soft_tabs_str, editor.soft_tab_width as usize
|
||||
);
|
||||
self.screen.draw(c2.1 - 30, c1.0, &info_line[..], fg, bg);
|
||||
self.screen.draw(c2.1 - 30, c1.0, &info_line[..], style);
|
||||
|
||||
// Draw main text editing area
|
||||
self.draw_editor_text(editor, (c1.0 + 1, c1.1), c2);
|
||||
|
@ -364,7 +361,8 @@ impl<'a> TermUI<'a> {
|
|||
// Fill in the gutter with the appropriate background
|
||||
for y in c1.0..(c2.0 + 1) {
|
||||
for x in c1.1..(c1.1 + gutter_width - 1) {
|
||||
self.screen.draw(x, y, " ", color::White, color::Blue);
|
||||
self.screen
|
||||
.draw(x, y, " ", Style(Color::White, Color::Blue));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,8 +377,7 @@ impl<'a> TermUI<'a> {
|
|||
lnx,
|
||||
lny,
|
||||
&format!("{}", line_num)[..],
|
||||
color::White,
|
||||
color::Blue,
|
||||
Style(Color::White, Color::Blue),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -430,8 +427,7 @@ impl<'a> TermUI<'a> {
|
|||
px as usize,
|
||||
py as usize,
|
||||
" ",
|
||||
color::Black,
|
||||
color::White,
|
||||
Style(Color::Black, Color::White),
|
||||
);
|
||||
}
|
||||
} else if g == "\t" {
|
||||
|
@ -442,8 +438,7 @@ impl<'a> TermUI<'a> {
|
|||
tpx as usize,
|
||||
py as usize,
|
||||
" ",
|
||||
color::White,
|
||||
color::Black,
|
||||
Style(Color::White, Color::Black),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -453,8 +448,7 @@ impl<'a> TermUI<'a> {
|
|||
px as usize,
|
||||
py as usize,
|
||||
" ",
|
||||
color::Black,
|
||||
color::White,
|
||||
Style(Color::Black, Color::White),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
@ -463,16 +457,14 @@ impl<'a> TermUI<'a> {
|
|||
px as usize,
|
||||
py as usize,
|
||||
g,
|
||||
color::Black,
|
||||
color::White,
|
||||
Style(Color::Black, Color::White),
|
||||
);
|
||||
} else {
|
||||
self.screen.draw(
|
||||
px as usize,
|
||||
py as usize,
|
||||
g,
|
||||
color::White,
|
||||
color::Black,
|
||||
Style(Color::White, Color::Black),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -524,8 +516,12 @@ impl<'a> TermUI<'a> {
|
|||
if (px >= c1.1 as isize) && (py >= c1.0 as isize) && (px <= c2.1 as isize)
|
||||
&& (py <= c2.0 as isize)
|
||||
{
|
||||
self.screen
|
||||
.draw(px as usize, py as usize, " ", color::Black, color::White);
|
||||
self.screen.draw(
|
||||
px as usize,
|
||||
py as usize,
|
||||
" ",
|
||||
Style(Color::Black, Color::White),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use termion::raw::{IntoRawMode, RawTerminal};
|
|||
|
||||
pub(crate) struct Screen {
|
||||
out: RefCell<AlternateScreen<RawTerminal<io::Stdout>>>,
|
||||
buf: RefCell<Vec<Option<String>>>,
|
||||
buf: RefCell<Vec<Option<(Style, String)>>>,
|
||||
w: usize,
|
||||
h: usize,
|
||||
}
|
||||
|
@ -20,11 +20,8 @@ pub(crate) struct Screen {
|
|||
impl Screen {
|
||||
pub(crate) fn new() -> Self {
|
||||
let (w, h) = termion::terminal_size().unwrap();
|
||||
let buf = std::iter::repeat(Some(format!(
|
||||
"{}{} ",
|
||||
color::Fg(color::Black),
|
||||
color::Bg(color::Black)
|
||||
))).take(w as usize * h as usize)
|
||||
let buf = std::iter::repeat(Some((Style(Color::Black, Color::Black), " ".to_string())))
|
||||
.take(w as usize * h as usize)
|
||||
.collect();
|
||||
Screen {
|
||||
out: RefCell::new(AlternateScreen::from(io::stdout().into_raw_mode().unwrap())),
|
||||
|
@ -37,20 +34,13 @@ impl Screen {
|
|||
pub(crate) fn clear(&self) {
|
||||
for cell in self.buf.borrow_mut().iter_mut() {
|
||||
match *cell {
|
||||
Some(ref mut text) => {
|
||||
Some((ref mut style, ref mut text)) => {
|
||||
*style = Style(Color::Black, Color::Black);
|
||||
text.clear();
|
||||
text.push_str(&format!(
|
||||
"{}{} ",
|
||||
color::Fg(color::Black),
|
||||
color::Bg(color::Black)
|
||||
));
|
||||
text.push_str(" ");
|
||||
}
|
||||
_ => {
|
||||
*cell = Some(format!(
|
||||
"{}{} ",
|
||||
color::Fg(color::Black),
|
||||
color::Bg(color::Black)
|
||||
));
|
||||
*cell = Some((Style(Color::Black, Color::Black), " ".to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,45 +51,40 @@ impl Screen {
|
|||
self.h = h;
|
||||
self.buf.borrow_mut().resize(
|
||||
w * h,
|
||||
Some(format!(
|
||||
"{}{} ",
|
||||
color::Fg(color::Black),
|
||||
color::Bg(color::Black)
|
||||
)),
|
||||
Some((Style(Color::Black, Color::Black), " ".to_string())),
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn present(&self) {
|
||||
let buf = self.buf.borrow();
|
||||
let mut tmp_string = String::new();
|
||||
for y in 0..self.h {
|
||||
for x in 0..self.w {
|
||||
if let Some(ref cell) = buf[y * self.w + x] {
|
||||
let mut x = 0;
|
||||
let mut last_style = Style(Color::Black, Color::Black);
|
||||
let mut left_x = 0;
|
||||
while x < self.w {
|
||||
if let Some((style, ref text)) = buf[y * self.w + x] {
|
||||
write!(
|
||||
self.out.borrow_mut(),
|
||||
"{}{}",
|
||||
"{}{}{}",
|
||||
termion::cursor::Goto((x + 1) as u16, (y + 1) as u16),
|
||||
cell
|
||||
style,
|
||||
text,
|
||||
).unwrap();
|
||||
}
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
self.out.borrow_mut().flush().unwrap();
|
||||
}
|
||||
|
||||
pub(crate) fn draw<C1: color::Color + Copy, C2: color::Color + Copy>(
|
||||
&self,
|
||||
x: usize,
|
||||
y: usize,
|
||||
text: &str,
|
||||
fg: C1,
|
||||
bg: C2,
|
||||
) {
|
||||
pub(crate) fn draw(&self, x: usize, y: usize, text: &str, style: Style) {
|
||||
let mut buf = self.buf.borrow_mut();
|
||||
let mut x = x;
|
||||
for g in UnicodeSegmentation::graphemes(text, true) {
|
||||
let width = UnicodeWidthStr::width(g);
|
||||
if width > 0 {
|
||||
buf[y * self.w + x] = Some(format!("{}{}{}", color::Fg(fg), color::Bg(bg), g));
|
||||
buf[y * self.w + x] = Some((style, g.to_string()));
|
||||
x += 1;
|
||||
for _ in 0..(width - 1) {
|
||||
buf[y * self.w + x] = None;
|
||||
|
@ -130,3 +115,71 @@ impl Drop for Screen {
|
|||
self.show_cursor();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub(crate) enum Color {
|
||||
Black,
|
||||
Blue,
|
||||
Cyan,
|
||||
Green,
|
||||
LightBlack,
|
||||
LightBlue,
|
||||
LightCyan,
|
||||
LightGreen,
|
||||
LightMagenta,
|
||||
LightRed,
|
||||
LightWhite,
|
||||
LightYellow,
|
||||
Magenta,
|
||||
Red,
|
||||
Rgb(u8, u8, u8),
|
||||
White,
|
||||
Yellow,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub(crate) struct Style(pub Color, pub Color); // Fg, Bg
|
||||
|
||||
impl std::fmt::Display for Style {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self.0 {
|
||||
Color::Black => write!(f, "{}", color::Fg(color::Black)),
|
||||
Color::Blue => write!(f, "{}", color::Fg(color::Blue)),
|
||||
Color::Cyan => write!(f, "{}", color::Fg(color::Cyan)),
|
||||
Color::Green => write!(f, "{}", color::Fg(color::Green)),
|
||||
Color::LightBlack => write!(f, "{}", color::Fg(color::LightBlack)),
|
||||
Color::LightBlue => write!(f, "{}", color::Fg(color::LightBlue)),
|
||||
Color::LightCyan => write!(f, "{}", color::Fg(color::LightCyan)),
|
||||
Color::LightGreen => write!(f, "{}", color::Fg(color::LightGreen)),
|
||||
Color::LightMagenta => write!(f, "{}", color::Fg(color::LightMagenta)),
|
||||
Color::LightRed => write!(f, "{}", color::Fg(color::LightRed)),
|
||||
Color::LightWhite => write!(f, "{}", color::Fg(color::LightWhite)),
|
||||
Color::LightYellow => write!(f, "{}", color::Fg(color::LightYellow)),
|
||||
Color::Magenta => write!(f, "{}", color::Fg(color::Magenta)),
|
||||
Color::Red => write!(f, "{}", color::Fg(color::Red)),
|
||||
Color::Rgb(r, g, b) => write!(f, "{}", color::Fg(color::Rgb(r, g, b))),
|
||||
Color::White => write!(f, "{}", color::Fg(color::White)),
|
||||
Color::Yellow => write!(f, "{}", color::Fg(color::Yellow)),
|
||||
}?;
|
||||
|
||||
match self.1 {
|
||||
Color::Black => write!(f, "{}", color::Bg(color::Black)),
|
||||
Color::Blue => write!(f, "{}", color::Bg(color::Blue)),
|
||||
Color::Cyan => write!(f, "{}", color::Bg(color::Cyan)),
|
||||
Color::Green => write!(f, "{}", color::Bg(color::Green)),
|
||||
Color::LightBlack => write!(f, "{}", color::Bg(color::LightBlack)),
|
||||
Color::LightBlue => write!(f, "{}", color::Bg(color::LightBlue)),
|
||||
Color::LightCyan => write!(f, "{}", color::Bg(color::LightCyan)),
|
||||
Color::LightGreen => write!(f, "{}", color::Bg(color::LightGreen)),
|
||||
Color::LightMagenta => write!(f, "{}", color::Bg(color::LightMagenta)),
|
||||
Color::LightRed => write!(f, "{}", color::Bg(color::LightRed)),
|
||||
Color::LightWhite => write!(f, "{}", color::Bg(color::LightWhite)),
|
||||
Color::LightYellow => write!(f, "{}", color::Bg(color::LightYellow)),
|
||||
Color::Magenta => write!(f, "{}", color::Bg(color::Magenta)),
|
||||
Color::Red => write!(f, "{}", color::Bg(color::Red)),
|
||||
Color::Rgb(r, g, b) => write!(f, "{}", color::Bg(color::Rgb(r, g, b))),
|
||||
Color::White => write!(f, "{}", color::Bg(color::White)),
|
||||
Color::Yellow => write!(f, "{}", color::Bg(color::Yellow)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user