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;
|
pub mod formatter;
|
||||||
mod screen;
|
mod screen;
|
||||||
|
|
||||||
use self::screen::Screen;
|
use self::screen::{Color, Screen, Style};
|
||||||
|
|
||||||
/// Generalized ui loop.
|
/// Generalized ui loop.
|
||||||
macro_rules! ui_loop {
|
macro_rules! ui_loop {
|
||||||
|
@ -203,8 +203,7 @@ impl<'a> TermUI<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn go_to_line_ui_loop(&mut self) {
|
fn go_to_line_ui_loop(&mut self) {
|
||||||
let foreground = color::Black;
|
let style = Style(Color::Black, Color::Cyan);
|
||||||
let background = color::Cyan;
|
|
||||||
|
|
||||||
let mut cancel = false;
|
let mut cancel = false;
|
||||||
let prefix = "Jump to line: ";
|
let prefix = "Jump to line: ";
|
||||||
|
@ -220,15 +219,14 @@ impl<'a> TermUI<'a> {
|
||||||
self.screen.clear();
|
self.screen.clear();
|
||||||
self.draw_editor(&self.editor, (0, 0), (self.height - 1, self.width - 1));
|
self.draw_editor(&self.editor, (0, 0), (self.height - 1, self.width - 1));
|
||||||
for i in 0..self.width {
|
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(
|
self.screen.draw(
|
||||||
prefix.len() + 1,
|
prefix.len() + 1,
|
||||||
0,
|
0,
|
||||||
&line[..],
|
&line[..],
|
||||||
foreground,
|
style,
|
||||||
background,
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -281,19 +279,18 @@ impl<'a> TermUI<'a> {
|
||||||
c1: (usize, usize),
|
c1: (usize, usize),
|
||||||
c2: (usize, usize),
|
c2: (usize, usize),
|
||||||
) {
|
) {
|
||||||
let fg = color::Black;
|
let style = Style(Color::Black, Color::Cyan);
|
||||||
let bg = color::Cyan;
|
|
||||||
|
|
||||||
// Fill in top row with info line color
|
// Fill in top row with info line color
|
||||||
for i in c1.1..(c2.1 + 1) {
|
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
|
// Filename and dirty marker
|
||||||
let filename = editor.file_path.display();
|
let filename = editor.file_path.display();
|
||||||
let dirty_char = if editor.dirty { "*" } else { "" };
|
let dirty_char = if editor.dirty { "*" } else { "" };
|
||||||
let name = format!("{}{}", filename, dirty_char);
|
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
|
// Percentage position in document
|
||||||
// TODO: use view instead of cursor for calculation if there is more
|
// TODO: use view instead of cursor for calculation if there is more
|
||||||
|
@ -306,7 +303,7 @@ impl<'a> TermUI<'a> {
|
||||||
};
|
};
|
||||||
let pstring = format!("{}%", percentage);
|
let pstring = format!("{}%", percentage);
|
||||||
self.screen
|
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
|
// Text encoding info and tab style
|
||||||
let nl = match editor.line_ending_type {
|
let nl = match editor.line_ending_type {
|
||||||
|
@ -325,7 +322,7 @@ impl<'a> TermUI<'a> {
|
||||||
"UTF8:{} {}:{}",
|
"UTF8:{} {}:{}",
|
||||||
nl, soft_tabs_str, editor.soft_tab_width as usize
|
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
|
// Draw main text editing area
|
||||||
self.draw_editor_text(editor, (c1.0 + 1, c1.1), c2);
|
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
|
// Fill in the gutter with the appropriate background
|
||||||
for y in c1.0..(c2.0 + 1) {
|
for y in c1.0..(c2.0 + 1) {
|
||||||
for x in c1.1..(c1.1 + gutter_width - 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,
|
lnx,
|
||||||
lny,
|
lny,
|
||||||
&format!("{}", line_num)[..],
|
&format!("{}", line_num)[..],
|
||||||
color::White,
|
Style(Color::White, Color::Blue),
|
||||||
color::Blue,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -430,8 +427,7 @@ impl<'a> TermUI<'a> {
|
||||||
px as usize,
|
px as usize,
|
||||||
py as usize,
|
py as usize,
|
||||||
" ",
|
" ",
|
||||||
color::Black,
|
Style(Color::Black, Color::White),
|
||||||
color::White,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if g == "\t" {
|
} else if g == "\t" {
|
||||||
|
@ -442,8 +438,7 @@ impl<'a> TermUI<'a> {
|
||||||
tpx as usize,
|
tpx as usize,
|
||||||
py as usize,
|
py as usize,
|
||||||
" ",
|
" ",
|
||||||
color::White,
|
Style(Color::White, Color::Black),
|
||||||
color::Black,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,8 +448,7 @@ impl<'a> TermUI<'a> {
|
||||||
px as usize,
|
px as usize,
|
||||||
py as usize,
|
py as usize,
|
||||||
" ",
|
" ",
|
||||||
color::Black,
|
Style(Color::Black, Color::White),
|
||||||
color::White,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -463,16 +457,14 @@ impl<'a> TermUI<'a> {
|
||||||
px as usize,
|
px as usize,
|
||||||
py as usize,
|
py as usize,
|
||||||
g,
|
g,
|
||||||
color::Black,
|
Style(Color::Black, Color::White),
|
||||||
color::White,
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
self.screen.draw(
|
self.screen.draw(
|
||||||
px as usize,
|
px as usize,
|
||||||
py as usize,
|
py as usize,
|
||||||
g,
|
g,
|
||||||
color::White,
|
Style(Color::White, Color::Black),
|
||||||
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)
|
if (px >= c1.1 as isize) && (py >= c1.0 as isize) && (px <= c2.1 as isize)
|
||||||
&& (py <= c2.0 as isize)
|
&& (py <= c2.0 as isize)
|
||||||
{
|
{
|
||||||
self.screen
|
self.screen.draw(
|
||||||
.draw(px as usize, py as usize, " ", color::Black, color::White);
|
px as usize,
|
||||||
|
py as usize,
|
||||||
|
" ",
|
||||||
|
Style(Color::Black, Color::White),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ use termion::raw::{IntoRawMode, RawTerminal};
|
||||||
|
|
||||||
pub(crate) struct Screen {
|
pub(crate) struct Screen {
|
||||||
out: RefCell<AlternateScreen<RawTerminal<io::Stdout>>>,
|
out: RefCell<AlternateScreen<RawTerminal<io::Stdout>>>,
|
||||||
buf: RefCell<Vec<Option<String>>>,
|
buf: RefCell<Vec<Option<(Style, String)>>>,
|
||||||
w: usize,
|
w: usize,
|
||||||
h: usize,
|
h: usize,
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,8 @@ pub(crate) struct Screen {
|
||||||
impl Screen {
|
impl Screen {
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
let (w, h) = termion::terminal_size().unwrap();
|
let (w, h) = termion::terminal_size().unwrap();
|
||||||
let buf = std::iter::repeat(Some(format!(
|
let buf = std::iter::repeat(Some((Style(Color::Black, Color::Black), " ".to_string())))
|
||||||
"{}{} ",
|
.take(w as usize * h as usize)
|
||||||
color::Fg(color::Black),
|
|
||||||
color::Bg(color::Black)
|
|
||||||
))).take(w as usize * h as usize)
|
|
||||||
.collect();
|
.collect();
|
||||||
Screen {
|
Screen {
|
||||||
out: RefCell::new(AlternateScreen::from(io::stdout().into_raw_mode().unwrap())),
|
out: RefCell::new(AlternateScreen::from(io::stdout().into_raw_mode().unwrap())),
|
||||||
|
@ -37,20 +34,13 @@ impl Screen {
|
||||||
pub(crate) fn clear(&self) {
|
pub(crate) fn clear(&self) {
|
||||||
for cell in self.buf.borrow_mut().iter_mut() {
|
for cell in self.buf.borrow_mut().iter_mut() {
|
||||||
match *cell {
|
match *cell {
|
||||||
Some(ref mut text) => {
|
Some((ref mut style, ref mut text)) => {
|
||||||
|
*style = Style(Color::Black, Color::Black);
|
||||||
text.clear();
|
text.clear();
|
||||||
text.push_str(&format!(
|
text.push_str(" ");
|
||||||
"{}{} ",
|
|
||||||
color::Fg(color::Black),
|
|
||||||
color::Bg(color::Black)
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*cell = Some(format!(
|
*cell = Some((Style(Color::Black, Color::Black), " ".to_string()));
|
||||||
"{}{} ",
|
|
||||||
color::Fg(color::Black),
|
|
||||||
color::Bg(color::Black)
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,45 +51,40 @@ impl Screen {
|
||||||
self.h = h;
|
self.h = h;
|
||||||
self.buf.borrow_mut().resize(
|
self.buf.borrow_mut().resize(
|
||||||
w * h,
|
w * h,
|
||||||
Some(format!(
|
Some((Style(Color::Black, Color::Black), " ".to_string())),
|
||||||
"{}{} ",
|
|
||||||
color::Fg(color::Black),
|
|
||||||
color::Bg(color::Black)
|
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn present(&self) {
|
pub(crate) fn present(&self) {
|
||||||
let buf = self.buf.borrow();
|
let buf = self.buf.borrow();
|
||||||
|
let mut tmp_string = String::new();
|
||||||
for y in 0..self.h {
|
for y in 0..self.h {
|
||||||
for x in 0..self.w {
|
let mut x = 0;
|
||||||
if let Some(ref cell) = buf[y * self.w + x] {
|
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!(
|
write!(
|
||||||
self.out.borrow_mut(),
|
self.out.borrow_mut(),
|
||||||
"{}{}",
|
"{}{}{}",
|
||||||
termion::cursor::Goto((x + 1) as u16, (y + 1) as u16),
|
termion::cursor::Goto((x + 1) as u16, (y + 1) as u16),
|
||||||
cell
|
style,
|
||||||
|
text,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
}
|
}
|
||||||
|
x += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.out.borrow_mut().flush().unwrap();
|
self.out.borrow_mut().flush().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn draw<C1: color::Color + Copy, C2: color::Color + Copy>(
|
pub(crate) fn draw(&self, x: usize, y: usize, text: &str, style: Style) {
|
||||||
&self,
|
|
||||||
x: usize,
|
|
||||||
y: usize,
|
|
||||||
text: &str,
|
|
||||||
fg: C1,
|
|
||||||
bg: C2,
|
|
||||||
) {
|
|
||||||
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 = UnicodeWidthStr::width(g);
|
let width = UnicodeWidthStr::width(g);
|
||||||
if width > 0 {
|
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;
|
x += 1;
|
||||||
for _ in 0..(width - 1) {
|
for _ in 0..(width - 1) {
|
||||||
buf[y * self.w + x] = None;
|
buf[y * self.w + x] = None;
|
||||||
|
@ -130,3 +115,71 @@ impl Drop for Screen {
|
||||||
self.show_cursor();
|
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