ansi parser: PtyView to display cursor & scrolling
This commit is contained in:
parent
4ab20be1c5
commit
ef1a477d4a
1 changed files with 380 additions and 129 deletions
|
@ -8,30 +8,45 @@ use {
|
|||
std::io::Read,
|
||||
//async_std::{io::{Read, ReadExt}},
|
||||
crate::{
|
||||
core::{InnerViewPort, OuterViewPort},
|
||||
core::{View, InnerViewPort, OuterViewPort, ViewPort, Observer, ObserverBroadcast},
|
||||
projection::ProjectionHelper,
|
||||
terminal::{
|
||||
TerminalAtom,
|
||||
TerminalStyle,
|
||||
TerminalView
|
||||
},
|
||||
index::buffer::IndexBuffer
|
||||
singleton::{
|
||||
SingletonBuffer,
|
||||
SingletonView
|
||||
},
|
||||
index::{
|
||||
buffer::IndexBuffer,
|
||||
IndexView,
|
||||
IndexArea
|
||||
}
|
||||
},
|
||||
cgmath::Point2,
|
||||
cgmath::{Vector2, Point2},
|
||||
vte::{Params, Parser, Perform}
|
||||
};
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
pub fn read_ansi_from<R: Read + Unpin>(ansi_reader: &mut R, port: InnerViewPort<dyn TerminalView>) {
|
||||
let mut statemachine = Parser::new();
|
||||
|
||||
let buf_port = ViewPort::new();
|
||||
let size_port = ViewPort::<dyn SingletonView<Item = Vector2<i16>>>::new();
|
||||
let cursor_port = ViewPort::<dyn SingletonView<Item = Point2<i16>>>::new();
|
||||
let offset_port = ViewPort::<dyn SingletonView<Item = Vector2<i16>>>::new();
|
||||
|
||||
let mut performer = PerfAtom {
|
||||
cursor: Point2::new(0, 0),
|
||||
style: TerminalStyle::default(),
|
||||
invert: false,
|
||||
term_width: 120,
|
||||
|
||||
cursor_save: Point2::new(0, 0),
|
||||
|
||||
buf: IndexBuffer::new(port),
|
||||
buf: IndexBuffer::new(buf_port.inner()),
|
||||
size: SingletonBuffer::new(Vector2::new(120, 40), size_port.inner()),
|
||||
offset: SingletonBuffer::new(Vector2::new(0, 0), offset_port.inner()),
|
||||
cursor: SingletonBuffer::new(Point2::new(0, 0), cursor_port.inner()),
|
||||
cursty: TerminalStyle::default(),
|
||||
curinv: false,
|
||||
cursav: Point2::new(0, 0),
|
||||
|
||||
colors: ColorPalett {
|
||||
black: (1, 1, 1),
|
||||
|
@ -42,7 +57,16 @@ pub fn read_ansi_from<R: Read + Unpin>(ansi_reader: &mut R, port: InnerViewPort<
|
|||
magenta: (118, 38, 113),
|
||||
cyan: (44, 181, 233),
|
||||
white: (204, 204, 204)
|
||||
}
|
||||
},
|
||||
|
||||
pty_proj: PtyView::new(
|
||||
buf_port.outer(),
|
||||
cursor_port.outer().map(|x| Some(x)),
|
||||
offset_port.outer().map(|x| Some(x)),
|
||||
size_port.outer().map(|x| Some(x)),
|
||||
|
||||
port
|
||||
)
|
||||
};
|
||||
|
||||
let mut buf = [0; 2048];
|
||||
|
@ -63,6 +87,22 @@ pub fn read_ansi_from<R: Read + Unpin>(ansi_reader: &mut R, port: InnerViewPort<
|
|||
}
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
enum TTYColor {
|
||||
Rgb(u8, u8, u8),
|
||||
|
||||
// 3-Bit/4-Bit colors
|
||||
Black, LightBlack,
|
||||
Red, LightRed,
|
||||
Green, LightGreen,
|
||||
Yellow, LightYellow,
|
||||
Blue, LightBlue,
|
||||
Magenta,LightMagenta,
|
||||
Cyan, LightCyan,
|
||||
White, LightWhite,
|
||||
}
|
||||
|
||||
struct ColorPalett {
|
||||
black: (u8, u8, u8),
|
||||
red: (u8, u8, u8),
|
||||
|
@ -71,84 +111,279 @@ struct ColorPalett {
|
|||
blue: (u8, u8, u8),
|
||||
magenta: (u8, u8, u8),
|
||||
cyan: (u8, u8, u8),
|
||||
white: (u8, u8, u8)
|
||||
white: (u8, u8, u8),
|
||||
}
|
||||
|
||||
impl ColorPalett {
|
||||
fn get_rgb(&self, col: &TTYColor) -> (u8, u8, u8) {
|
||||
match col {
|
||||
TTYColor::Rgb(r,g,b) => (*r,*g,*b),
|
||||
TTYColor::Black | TTYColor::LightBlack => self.black,
|
||||
TTYColor::Red | TTYColor::LightRed => self.red,
|
||||
TTYColor::Green | TTYColor::LightGreen => self.green,
|
||||
TTYColor::Yellow | TTYColor::LightYellow => self.yellow,
|
||||
TTYColor::Blue | TTYColor::LightBlue => self.blue,
|
||||
TTYColor::Magenta | TTYColor::LightMagenta => self.magenta,
|
||||
TTYColor::Cyan | TTYColor::LightCyan => self.cyan,
|
||||
TTYColor::White | TTYColor::LightWhite => self.white,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
/// Display Cursor & scrolling
|
||||
struct PtyView {
|
||||
buf: Arc<dyn IndexView<Point2<i16>, Item = TerminalAtom>>,
|
||||
curpos: Arc<dyn SingletonView<Item = Option<Point2<i16>>>>,
|
||||
offset: Arc<dyn SingletonView<Item = Option<Vector2<i16>>>>,
|
||||
size: Arc<dyn SingletonView<Item = Option<Vector2<i16>>>>,
|
||||
|
||||
old_offset: Vector2<i16>,
|
||||
old_curpos: Point2<i16>,
|
||||
old_size: Vector2<i16>,
|
||||
|
||||
max_pt: Point2<i16>,
|
||||
|
||||
cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>,
|
||||
proj_helper: ProjectionHelper<usize, Self>
|
||||
}
|
||||
|
||||
impl View for PtyView {
|
||||
type Msg = IndexArea<Point2<i16>>;
|
||||
}
|
||||
|
||||
impl IndexView<Point2<i16>> for PtyView {
|
||||
type Item = TerminalAtom;
|
||||
|
||||
fn get(&self, pt: &Point2<i16>) -> Option<TerminalAtom> {
|
||||
let atom = self.buf.get(&(pt + self.old_offset));
|
||||
if self.old_curpos == *pt {
|
||||
if let Some(mut a) = atom {
|
||||
let bg_col = a.style.fg_color.unwrap_or((255,255,255));
|
||||
let fg_col = a.style.bg_color.unwrap_or((0,0,0));
|
||||
a.style.fg_color = Some(fg_col);
|
||||
a.style.bg_color = Some(bg_col);
|
||||
Some(a)
|
||||
} else {
|
||||
Some(TerminalAtom::new(' ', TerminalStyle::bg_color((255, 255, 255))))
|
||||
}
|
||||
} else {
|
||||
atom
|
||||
}
|
||||
}
|
||||
|
||||
fn area(&self) -> IndexArea<Point2<i16>> {
|
||||
IndexArea::Range(Point2::new(0, 0) ..= Point2::new(
|
||||
std::cmp::max(self.old_curpos.x, self.max_pt.x),
|
||||
std::cmp::max(self.old_curpos.y, self.max_pt.y)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl PtyView {
|
||||
fn new(
|
||||
buf_port: OuterViewPort<dyn IndexView<Point2<i16>, Item = TerminalAtom>>,
|
||||
curpos_port: OuterViewPort<dyn SingletonView<Item = Option<Point2<i16>>>>,
|
||||
offset_port: OuterViewPort<dyn SingletonView<Item = Option<Vector2<i16>>>>,
|
||||
size_port: OuterViewPort<dyn SingletonView<Item = Option<Vector2<i16>>>>,
|
||||
|
||||
out_port: InnerViewPort<dyn TerminalView>
|
||||
) -> Arc<RwLock<Self>> {
|
||||
let mut proj_helper = ProjectionHelper::new(out_port.0.update_hooks.clone());
|
||||
let proj = Arc::new(RwLock::new(
|
||||
PtyView {
|
||||
old_curpos: Point2::new(0, 0),
|
||||
old_size: Vector2::new(0, 0),
|
||||
old_offset: Vector2::new(0, 0),
|
||||
max_pt: Point2::new(0, 0),
|
||||
|
||||
curpos: proj_helper.new_singleton_arg(
|
||||
0,
|
||||
curpos_port,
|
||||
|s: &mut Self, _msg| {
|
||||
s.cast.notify(&IndexArea::Set(vec![ s.old_curpos ]));
|
||||
s.old_curpos = s.curpos.get().unwrap_or(Point2::new(0,0));
|
||||
s.cast.notify(&IndexArea::Set(vec![ s.old_curpos ]));
|
||||
}),
|
||||
|
||||
offset: proj_helper.new_singleton_arg(
|
||||
1,
|
||||
offset_port,
|
||||
|s: &mut Self, _msg| {
|
||||
// todo
|
||||
let new_offset = s.offset.get().unwrap_or(Vector2::new(0, 0));
|
||||
if s.old_offset != new_offset {
|
||||
s.old_offset = new_offset;
|
||||
s.cast.notify(&s.area());
|
||||
}
|
||||
}),
|
||||
|
||||
size: proj_helper.new_singleton_arg(
|
||||
2,
|
||||
size_port,
|
||||
|s: &mut Self, _msg| {
|
||||
let new_size = s.size.get().unwrap_or(Vector2::new(0, 0));
|
||||
if s.old_size != new_size {
|
||||
s.old_size = new_size;
|
||||
s.cast.notify(&s.area());
|
||||
}
|
||||
}),
|
||||
|
||||
buf: proj_helper.new_index_arg(
|
||||
3,
|
||||
buf_port,
|
||||
|s: &mut Self, area| {
|
||||
let size = s.old_size;
|
||||
let area = area.map(
|
||||
|pt| {
|
||||
*pt - s.old_offset
|
||||
}
|
||||
);
|
||||
|
||||
if s.max_pt.x < size.x || s.max_pt.y < size.y {
|
||||
match &area {
|
||||
IndexArea::Empty => {}
|
||||
IndexArea::Full => {}
|
||||
IndexArea::Range(_) => {}
|
||||
IndexArea::Set(v) => {
|
||||
let mx = v.iter().map(|pt| pt.x).max().unwrap_or(0);
|
||||
if mx > s.max_pt.x && mx < size.x {
|
||||
s.max_pt.x = mx;
|
||||
}
|
||||
|
||||
let my = v.iter().map(|pt| pt.y).max().unwrap_or(0);
|
||||
if my > s.max_pt.y && my < size.y {
|
||||
s.max_pt.y = my;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s.cast.notify(&area);
|
||||
}),
|
||||
|
||||
cast: out_port.get_broadcast(),
|
||||
proj_helper
|
||||
}
|
||||
));
|
||||
|
||||
proj.write().unwrap().proj_helper.set_proj(&proj);
|
||||
out_port.set_view(Some(proj.clone()));
|
||||
|
||||
proj
|
||||
}
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
struct PerfAtom {
|
||||
colors: ColorPalett,
|
||||
term_width: i16,
|
||||
|
||||
cursor: Point2<i16>,
|
||||
style: TerminalStyle,
|
||||
invert: bool,
|
||||
cursor_save: Point2<i16>,
|
||||
|
||||
buf: IndexBuffer<Point2<i16>, TerminalAtom>,
|
||||
size: SingletonBuffer<Vector2<i16>>,
|
||||
offset: SingletonBuffer<Vector2<i16>>,
|
||||
cursor: SingletonBuffer<Point2<i16>>,
|
||||
cursty: TerminalStyle,
|
||||
curinv: bool,
|
||||
cursav: Point2<i16>,
|
||||
|
||||
colors: ColorPalett,
|
||||
|
||||
pty_proj: Arc<RwLock<PtyView>>
|
||||
}
|
||||
|
||||
impl PerfAtom {
|
||||
fn write_atom(&mut self, pos: Point2<i16>, atom: Option<TerminalAtom>) {
|
||||
if let Some(mut a) = atom {
|
||||
self.buf.insert(pos, a);
|
||||
self.buf.insert(pos + self.offset.get(), a);
|
||||
} else {
|
||||
self.buf.remove(pos);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_style(&self) -> TerminalStyle {
|
||||
let mut style = self.style;
|
||||
if self.invert {
|
||||
style.fg_color = Some(self.style.bg_color.unwrap_or(self.colors.black));
|
||||
style.bg_color = Some(self.style.fg_color.unwrap_or(self.colors.white));
|
||||
let mut style = self.cursty;
|
||||
if self.curinv {
|
||||
style.fg_color = Some(self.cursty.bg_color.unwrap_or(self.colors.black));
|
||||
style.bg_color = Some(self.cursty.fg_color.unwrap_or(self.colors.white));
|
||||
}
|
||||
style
|
||||
}
|
||||
|
||||
fn set_fg_color(&mut self, col: &TTYColor) {
|
||||
self.cursty = self.cursty.add(TerminalStyle::fg_color(self.colors.get_rgb(col)));
|
||||
}
|
||||
|
||||
fn set_bg_color(&mut self, col: &TTYColor) {
|
||||
self.cursty = self.cursty.add(TerminalStyle::bg_color(self.colors.get_rgb(col)));
|
||||
}
|
||||
|
||||
fn linefeed(&mut self) {
|
||||
self.cursor.x = 0;
|
||||
self.cursor.y += 1;
|
||||
let size = self.size.get();
|
||||
let mut c = self.cursor.get_mut();
|
||||
c.x = 0;
|
||||
|
||||
if c.y+1 >= size.y {
|
||||
self.scroll_up(1);
|
||||
} else {
|
||||
c.y += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn carriage_return(&mut self) {
|
||||
self.cursor.x = 0;
|
||||
let mut c = self.cursor.get_mut();
|
||||
c.x = 0;
|
||||
}
|
||||
|
||||
fn horizontal_tab(&mut self) {
|
||||
self.cursor.x += 8 - (self.cursor.x % 8);
|
||||
let mut c = self.cursor.get_mut();
|
||||
c.x += 8 - (c.x % 8);
|
||||
}
|
||||
|
||||
fn backspace(&mut self) {
|
||||
self.write_atom(self.cursor, None);
|
||||
self.cursor.x -= 1;
|
||||
if self.cursor.x < 0 {
|
||||
self.cursor.y -= 0;
|
||||
self.cursor.x = self.term_width - 1;
|
||||
//self.write_atom(self.cursor.get(), None);
|
||||
let mut c = self.cursor.get_mut();
|
||||
c.x -= 1;
|
||||
if c.x < 0 {
|
||||
c.y -= 0;
|
||||
c.x = self.size.get().x - 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn cursor_up(&mut self, n: usize) {
|
||||
self.cursor.get_mut().y -= n as i16;
|
||||
}
|
||||
|
||||
fn cursor_down(&mut self, n: usize) {
|
||||
fn cursor_dn(&mut self, n: usize) {
|
||||
self.cursor.get_mut().y += n as i16;
|
||||
|
||||
// todo: scroll ?
|
||||
}
|
||||
|
||||
fn scroll_up(&mut self, n: usize) {
|
||||
self.offset.get_mut().y += n as i16;
|
||||
}
|
||||
|
||||
fn scroll_dn(&mut self, n: usize) {
|
||||
self.offset.get_mut().y -= n as i16;
|
||||
}
|
||||
|
||||
fn save_cursor_position(&mut self) {
|
||||
self.cursor_save = self.cursor;
|
||||
self.cursav = self.cursor.get();
|
||||
}
|
||||
|
||||
fn restore_cursor_position(&mut self) {
|
||||
self.cursor = self.cursor_save;
|
||||
self.cursor.set(self.cursav);
|
||||
}
|
||||
}
|
||||
|
||||
impl Perform for PerfAtom {
|
||||
fn print(&mut self, c: char) {
|
||||
self.write_atom(self.cursor, Some(TerminalAtom::new(c, self.get_style())));
|
||||
fn print(&mut self, ch: char) {
|
||||
let mut c = self.cursor.get_mut();
|
||||
self.write_atom(*c, Some(TerminalAtom::new(ch, self.get_style())));
|
||||
|
||||
self.cursor.x += 1;
|
||||
if self.cursor.x >= self.term_width {
|
||||
self.cursor.x = 0;
|
||||
self.cursor.y += 1;
|
||||
c.x += 1;
|
||||
if c.x >= self.size.get().x {
|
||||
self.linefeed();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,44 +427,61 @@ impl Perform for PerfAtom {
|
|||
'm' => while let Some(n) = piter.next() {
|
||||
match n[0] {
|
||||
0 => {
|
||||
self.style = TerminalStyle::default();
|
||||
self.invert = false;
|
||||
self.cursty = TerminalStyle::default();
|
||||
self.curinv = false;
|
||||
}
|
||||
1 => self.style = self.style.add(TerminalStyle::bold(true)),
|
||||
3 => self.style = self.style.add(TerminalStyle::italic(true)),
|
||||
4 => self.style = self.style.add(TerminalStyle::underline(true)),
|
||||
7 => self.invert = true,
|
||||
27 => self.invert = false,
|
||||
1 => self.cursty = self.cursty.add(TerminalStyle::bold(true)),
|
||||
3 => self.cursty = self.cursty.add(TerminalStyle::italic(true)),
|
||||
4 => self.cursty = self.cursty.add(TerminalStyle::underline(true)),
|
||||
7 => self.curinv = true,
|
||||
27 => self.curinv = false,
|
||||
|
||||
30 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.black)),
|
||||
40 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.black)),
|
||||
31 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.red)),
|
||||
41 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.red)),
|
||||
32 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.green)),
|
||||
42 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.green)),
|
||||
33 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.yellow)),
|
||||
43 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.yellow)),
|
||||
34 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.blue)),
|
||||
44 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.blue)),
|
||||
35 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.magenta)),
|
||||
45 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.magenta)),
|
||||
36 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.cyan)),
|
||||
46 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.cyan)),
|
||||
37 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.white)),
|
||||
47 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.white)),
|
||||
30 => self.set_fg_color(&TTYColor::Black),
|
||||
40 => self.set_bg_color(&TTYColor::Black),
|
||||
90 => self.set_fg_color(&TTYColor::LightBlack),
|
||||
100 => self.set_bg_color(&TTYColor::LightBlack),
|
||||
31 => self.set_fg_color(&TTYColor::Red),
|
||||
41 => self.set_bg_color(&TTYColor::Red),
|
||||
91 => self.set_fg_color(&TTYColor::LightRed),
|
||||
101 => self.set_bg_color(&TTYColor::LightRed),
|
||||
32 => self.set_fg_color(&TTYColor::Green),
|
||||
42 => self.set_bg_color(&TTYColor::Green),
|
||||
92 => self.set_fg_color(&TTYColor::LightGreen),
|
||||
102 => self.set_bg_color(&TTYColor::LightGreen),
|
||||
33 => self.set_fg_color(&TTYColor::Yellow),
|
||||
43 => self.set_bg_color(&TTYColor::Yellow),
|
||||
93 => self.set_fg_color(&TTYColor::LightYellow),
|
||||
103 => self.set_bg_color(&TTYColor::LightYellow),
|
||||
34 => self.set_fg_color(&TTYColor::Blue),
|
||||
44 => self.set_bg_color(&TTYColor::Blue),
|
||||
94 => self.set_fg_color(&TTYColor::LightBlue),
|
||||
104 => self.set_bg_color(&TTYColor::LightBlue),
|
||||
35 => self.set_fg_color(&TTYColor::Magenta),
|
||||
45 => self.set_bg_color(&TTYColor::Magenta),
|
||||
95 => self.set_fg_color(&TTYColor::LightMagenta),
|
||||
105 => self.set_bg_color(&TTYColor::LightMagenta),
|
||||
36 => self.set_fg_color(&TTYColor::Cyan),
|
||||
46 => self.set_bg_color(&TTYColor::Cyan),
|
||||
96 => self.set_fg_color(&TTYColor::LightCyan),
|
||||
106 => self.set_bg_color(&TTYColor::LightCyan),
|
||||
37 => self.set_fg_color(&TTYColor::White),
|
||||
47 => self.set_bg_color(&TTYColor::White),
|
||||
97 => self.set_fg_color(&TTYColor::LightWhite),
|
||||
107 => self.set_bg_color(&TTYColor::LightWhite),
|
||||
|
||||
38 => {
|
||||
let x = piter.next().unwrap();
|
||||
match x[0] {
|
||||
2 => {
|
||||
let r = piter.next().unwrap();
|
||||
let g = piter.next().unwrap();
|
||||
let b = piter.next().unwrap();
|
||||
self.style = self.style.add(TerminalStyle::fg_color((r[0] as u8, g[0] as u8, b[0] as u8)))
|
||||
let r = piter.next().unwrap()[0] as u8;
|
||||
let g = piter.next().unwrap()[0] as u8;
|
||||
let b = piter.next().unwrap()[0] as u8;
|
||||
self.set_fg_color(&TTYColor::Rgb(r,g,b));
|
||||
},
|
||||
5 => {
|
||||
let v = piter.next().unwrap();
|
||||
self.style = self.style.add(TerminalStyle::fg_color(ansi_colours::rgb_from_ansi256(v[0] as u8)))
|
||||
let rgb = ansi_colours::rgb_from_ansi256(v[0] as u8);
|
||||
self.set_fg_color(&TTYColor::Rgb(rgb.0, rgb.1, rgb.2));
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
@ -238,14 +490,15 @@ impl Perform for PerfAtom {
|
|||
let x = piter.next().unwrap();
|
||||
match x[0] {
|
||||
2 => {
|
||||
let r = piter.next().unwrap();
|
||||
let g = piter.next().unwrap();
|
||||
let b = piter.next().unwrap();
|
||||
self.style = self.style.add(TerminalStyle::bg_color((r[0] as u8, g[0] as u8, b[0] as u8)))
|
||||
let r = piter.next().unwrap()[0] as u8;
|
||||
let g = piter.next().unwrap()[0] as u8;
|
||||
let b = piter.next().unwrap()[0] as u8;
|
||||
self.set_bg_color(&TTYColor::Rgb(r,g,b));
|
||||
},
|
||||
5 => {
|
||||
let v = piter.next().unwrap();
|
||||
self.style = self.style.add(TerminalStyle::bg_color(ansi_colours::rgb_from_ansi256(v[0] as u8)))
|
||||
let rgb = ansi_colours::rgb_from_ansi256(v[0] as u8);
|
||||
self.set_bg_color(&TTYColor::Rgb(rgb.0, rgb.1, rgb.2));
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
@ -255,53 +508,52 @@ impl Perform for PerfAtom {
|
|||
}
|
||||
}
|
||||
'@' => {
|
||||
for x in self.cursor.x .. self.term_width {
|
||||
self.write_atom(Point2::new(x, self.cursor.y), Some(TerminalAtom::new(' ', self.style)));
|
||||
}
|
||||
}
|
||||
'A' => {
|
||||
self.cursor.y -= piter.next().unwrap_or(&[1])[0] as i16;
|
||||
}
|
||||
'B' => {
|
||||
self.cursor.y += piter.next().unwrap_or(&[1])[0] as i16;
|
||||
if self.cursor.x >= self.term_width {
|
||||
self.cursor.x = 0;
|
||||
let c = self.cursor.get();
|
||||
for x in c.x .. self.size.get().x {
|
||||
self.write_atom(Point2::new(x, c.y), Some(TerminalAtom::new(' ', self.cursty)));
|
||||
}
|
||||
}
|
||||
'A' => { self.cursor_up(piter.next().unwrap_or(&[1])[0] as usize); }
|
||||
'B' => { self.cursor_dn(piter.next().unwrap_or(&[1])[0] as usize); }
|
||||
'C' | 'a' => {
|
||||
self.cursor.x += piter.next().unwrap_or(&[1])[0] as i16;
|
||||
if self.cursor.x >= self.term_width {
|
||||
self.cursor.y += self.cursor.x / self.term_width;
|
||||
self.cursor.x %= self.term_width;
|
||||
let mut c = self.cursor.get_mut();
|
||||
c.x += piter.next().unwrap_or(&[1])[0] as i16;
|
||||
if c.x >= self.size.get().x {
|
||||
c.y += c.x / self.size.get().x;
|
||||
c.x %= self.size.get().x;
|
||||
}
|
||||
}
|
||||
'D' => {
|
||||
self.cursor.x -= piter.next().unwrap_or(&[1])[0] as i16;
|
||||
if self.cursor.x < 0 {
|
||||
self.cursor.x = self.term_width - 1;
|
||||
self.cursor.y -= 1;
|
||||
let mut c = self.cursor.get_mut();
|
||||
c.x -= piter.next().unwrap_or(&[1])[0] as i16;
|
||||
if c.x < 0 {
|
||||
c.x = self.size.get().x - 1;
|
||||
c.y -= 1;
|
||||
}
|
||||
}
|
||||
'd' => {
|
||||
self.cursor.y = piter.next().unwrap_or(&[1])[0] as i16 - 1;
|
||||
self.cursor.get_mut().y = piter.next().unwrap_or(&[1])[0] as i16 - 1;
|
||||
}
|
||||
'E' => {
|
||||
if self.cursor.x >= self.term_width {
|
||||
self.cursor.y += 1;
|
||||
let mut c = self.cursor.get_mut();
|
||||
if c.x >= self.size.get().x {
|
||||
c.y += 1;
|
||||
}
|
||||
self.cursor.x = 0;
|
||||
self.cursor.y += piter.next().unwrap_or(&[1])[0] as i16;
|
||||
c.x = 0;
|
||||
c.y += piter.next().unwrap_or(&[1])[0] as i16;
|
||||
}
|
||||
'F' => {
|
||||
self.cursor.x = 0;
|
||||
self.cursor.y -= piter.next().unwrap_or(&[1])[0] as i16;
|
||||
let mut c = self.cursor.get_mut();
|
||||
c.x = 0;
|
||||
c.y -= piter.next().unwrap_or(&[1])[0] as i16;
|
||||
}
|
||||
'G' | '`' => {
|
||||
self.cursor.x = piter.next().unwrap_or(&[1])[0] as i16 - 1;
|
||||
self.cursor.get_mut().x = piter.next().unwrap_or(&[1])[0] as i16 - 1;
|
||||
}
|
||||
'H' | 'f' => {
|
||||
self.cursor.y = piter.next().unwrap_or(&[1])[0] as i16 - 1;
|
||||
self.cursor.x = piter.next().unwrap_or(&[1])[0] as i16 - 1;
|
||||
let mut c = self.cursor.get_mut();
|
||||
c.y = piter.next().unwrap_or(&[1])[0] as i16 - 1;
|
||||
c.x = piter.next().unwrap_or(&[1])[0] as i16 - 1;
|
||||
}
|
||||
'J' => {
|
||||
let x = piter.next().unwrap_or(&[0 as u16; 1]);
|
||||
|
@ -309,13 +561,13 @@ impl Perform for PerfAtom {
|
|||
|
||||
// clear from cursor until end of screen
|
||||
0 => {
|
||||
let mut pos = self.cursor;
|
||||
let mut pos = self.cursor.get();
|
||||
|
||||
while pos.y < 100 {
|
||||
self.write_atom(pos, None);
|
||||
pos.x += 1;
|
||||
|
||||
if pos.x >= self.term_width {
|
||||
if pos.x >= self.size.get().x {
|
||||
pos.x = 0;
|
||||
pos.y += 1;
|
||||
}
|
||||
|
@ -324,13 +576,13 @@ impl Perform for PerfAtom {
|
|||
|
||||
// clear from cursor to begin
|
||||
1 => {
|
||||
let mut pos = self.cursor;
|
||||
let mut pos = self.cursor.get();
|
||||
while pos.y >= 0 || pos.x >= 0 {
|
||||
self.write_atom(pos, None);
|
||||
|
||||
pos.x -= 1;
|
||||
if pos.x < 0 {
|
||||
pos.x = self.term_width;
|
||||
pos.x = self.size.get().x;
|
||||
pos.y -= 1;
|
||||
}
|
||||
}
|
||||
|
@ -341,12 +593,12 @@ impl Perform for PerfAtom {
|
|||
// erase entire screen
|
||||
2 => {
|
||||
for y in 0 .. 100 {
|
||||
for x in 0 .. self.term_width {
|
||||
for x in 0 .. self.size.get().x {
|
||||
self.write_atom(Point2::new(x, y), None);
|
||||
}
|
||||
}
|
||||
|
||||
self.cursor = Point2::new(0, 0);
|
||||
self.cursor.set(Point2::new(0, 0));
|
||||
}
|
||||
|
||||
// invalid
|
||||
|
@ -359,22 +611,25 @@ impl Perform for PerfAtom {
|
|||
|
||||
// clear from cursor until end of line
|
||||
0 => {
|
||||
for x in self.cursor.x .. self.term_width {
|
||||
self.write_atom(Point2::new(x, self.cursor.y), Some(TerminalAtom::new(' ', self.get_style())));
|
||||
let c = self.cursor.get();
|
||||
for x in c.x .. self.size.get().x {
|
||||
self.write_atom(Point2::new(x, c.y), Some(TerminalAtom::new(' ', self.get_style())));
|
||||
}
|
||||
},
|
||||
|
||||
// clear from start of line until cursor
|
||||
1 => {
|
||||
for x in 0 .. self.cursor.x {
|
||||
self.write_atom(Point2::new(x, self.cursor.y), Some(TerminalAtom::new(' ', self.get_style())));
|
||||
let c = self.cursor.get();
|
||||
for x in 0 .. c.x {
|
||||
self.write_atom(Point2::new(x, c.y), Some(TerminalAtom::new(' ', self.get_style())));
|
||||
}
|
||||
},
|
||||
|
||||
// clear entire line
|
||||
2 => {
|
||||
for x in 0 .. self.term_width {
|
||||
self.write_atom(Point2::new(x, self.cursor.y), Some(TerminalAtom::new(' ', self.get_style())));
|
||||
let c = self.cursor.get();
|
||||
for x in 0 .. self.size.get().x {
|
||||
self.write_atom(Point2::new(x, c.y), Some(TerminalAtom::new(' ', self.get_style())));
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -386,7 +641,7 @@ impl Perform for PerfAtom {
|
|||
'M' => {
|
||||
let n = piter.next().unwrap_or(&[1])[0] as i16;
|
||||
for y in 0 .. n {
|
||||
for x in 0 .. self.term_width {
|
||||
for x in 0 .. self.size.get().x {
|
||||
self.write_atom(Point2::new(x, self.cursor.y+y), None);
|
||||
}
|
||||
}
|
||||
|
@ -401,14 +656,11 @@ impl Perform for PerfAtom {
|
|||
self.write_atom(Point2::new(self.cursor.x + x as i16, self.cursor.y), None);
|
||||
}
|
||||
}
|
||||
*/
|
||||
's' => {
|
||||
self.save_cursor_position();
|
||||
}
|
||||
'u' => {
|
||||
self.restore_cursor_position();
|
||||
}
|
||||
|
||||
*/
|
||||
'S' => { self.scroll_up(piter.next().unwrap_or(&[1])[0] as usize); }
|
||||
'T' => { self.scroll_dn(piter.next().unwrap_or(&[1])[0] as usize); }
|
||||
's' => { self.save_cursor_position(); }
|
||||
'u' => { self.restore_cursor_position(); }
|
||||
_ => {
|
||||
/*
|
||||
eprintln!(
|
||||
|
@ -421,7 +673,6 @@ impl Perform for PerfAtom {
|
|||
}
|
||||
|
||||
fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) {
|
||||
|
||||
match (byte, intermediates) {
|
||||
//(b'B', intermediates) => configure_charset!(StandardCharset::Ascii, intermediates),
|
||||
(b'D', []) => self.linefeed(),
|
||||
|
|
Loading…
Reference in a new issue