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,
|
std::io::Read,
|
||||||
//async_std::{io::{Read, ReadExt}},
|
//async_std::{io::{Read, ReadExt}},
|
||||||
crate::{
|
crate::{
|
||||||
core::{InnerViewPort, OuterViewPort},
|
core::{View, InnerViewPort, OuterViewPort, ViewPort, Observer, ObserverBroadcast},
|
||||||
|
projection::ProjectionHelper,
|
||||||
terminal::{
|
terminal::{
|
||||||
TerminalAtom,
|
TerminalAtom,
|
||||||
TerminalStyle,
|
TerminalStyle,
|
||||||
TerminalView
|
TerminalView
|
||||||
},
|
},
|
||||||
index::buffer::IndexBuffer
|
singleton::{
|
||||||
|
SingletonBuffer,
|
||||||
|
SingletonView
|
||||||
},
|
},
|
||||||
cgmath::Point2,
|
index::{
|
||||||
|
buffer::IndexBuffer,
|
||||||
|
IndexView,
|
||||||
|
IndexArea
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cgmath::{Vector2, Point2},
|
||||||
vte::{Params, Parser, Perform}
|
vte::{Params, Parser, Perform}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
||||||
pub fn read_ansi_from<R: Read + Unpin>(ansi_reader: &mut R, port: InnerViewPort<dyn TerminalView>) {
|
pub fn read_ansi_from<R: Read + Unpin>(ansi_reader: &mut R, port: InnerViewPort<dyn TerminalView>) {
|
||||||
let mut statemachine = Parser::new();
|
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 {
|
let mut performer = PerfAtom {
|
||||||
cursor: Point2::new(0, 0),
|
buf: IndexBuffer::new(buf_port.inner()),
|
||||||
style: TerminalStyle::default(),
|
size: SingletonBuffer::new(Vector2::new(120, 40), size_port.inner()),
|
||||||
invert: false,
|
offset: SingletonBuffer::new(Vector2::new(0, 0), offset_port.inner()),
|
||||||
term_width: 120,
|
cursor: SingletonBuffer::new(Point2::new(0, 0), cursor_port.inner()),
|
||||||
|
cursty: TerminalStyle::default(),
|
||||||
cursor_save: Point2::new(0, 0),
|
curinv: false,
|
||||||
|
cursav: Point2::new(0, 0),
|
||||||
buf: IndexBuffer::new(port),
|
|
||||||
|
|
||||||
colors: ColorPalett {
|
colors: ColorPalett {
|
||||||
black: (1, 1, 1),
|
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),
|
magenta: (118, 38, 113),
|
||||||
cyan: (44, 181, 233),
|
cyan: (44, 181, 233),
|
||||||
white: (204, 204, 204)
|
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];
|
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 {
|
struct ColorPalett {
|
||||||
black: (u8, u8, u8),
|
black: (u8, u8, u8),
|
||||||
red: (u8, u8, u8),
|
red: (u8, u8, u8),
|
||||||
|
@ -71,84 +111,279 @@ struct ColorPalett {
|
||||||
blue: (u8, u8, u8),
|
blue: (u8, u8, u8),
|
||||||
magenta: (u8, u8, u8),
|
magenta: (u8, u8, u8),
|
||||||
cyan: (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 {
|
struct PerfAtom {
|
||||||
colors: ColorPalett,
|
|
||||||
term_width: i16,
|
|
||||||
|
|
||||||
cursor: Point2<i16>,
|
|
||||||
style: TerminalStyle,
|
|
||||||
invert: bool,
|
|
||||||
cursor_save: Point2<i16>,
|
|
||||||
|
|
||||||
buf: IndexBuffer<Point2<i16>, TerminalAtom>,
|
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 {
|
impl PerfAtom {
|
||||||
fn write_atom(&mut self, pos: Point2<i16>, atom: Option<TerminalAtom>) {
|
fn write_atom(&mut self, pos: Point2<i16>, atom: Option<TerminalAtom>) {
|
||||||
if let Some(mut a) = atom {
|
if let Some(mut a) = atom {
|
||||||
self.buf.insert(pos, a);
|
self.buf.insert(pos + self.offset.get(), a);
|
||||||
} else {
|
} else {
|
||||||
self.buf.remove(pos);
|
self.buf.remove(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_style(&self) -> TerminalStyle {
|
fn get_style(&self) -> TerminalStyle {
|
||||||
let mut style = self.style;
|
let mut style = self.cursty;
|
||||||
if self.invert {
|
if self.curinv {
|
||||||
style.fg_color = Some(self.style.bg_color.unwrap_or(self.colors.black));
|
style.fg_color = Some(self.cursty.bg_color.unwrap_or(self.colors.black));
|
||||||
style.bg_color = Some(self.style.fg_color.unwrap_or(self.colors.white));
|
style.bg_color = Some(self.cursty.fg_color.unwrap_or(self.colors.white));
|
||||||
}
|
}
|
||||||
style
|
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) {
|
fn linefeed(&mut self) {
|
||||||
self.cursor.x = 0;
|
let size = self.size.get();
|
||||||
self.cursor.y += 1;
|
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) {
|
fn carriage_return(&mut self) {
|
||||||
self.cursor.x = 0;
|
let mut c = self.cursor.get_mut();
|
||||||
|
c.x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn horizontal_tab(&mut self) {
|
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) {
|
fn backspace(&mut self) {
|
||||||
self.write_atom(self.cursor, None);
|
//self.write_atom(self.cursor.get(), None);
|
||||||
self.cursor.x -= 1;
|
let mut c = self.cursor.get_mut();
|
||||||
if self.cursor.x < 0 {
|
c.x -= 1;
|
||||||
self.cursor.y -= 0;
|
if c.x < 0 {
|
||||||
self.cursor.x = self.term_width - 1;
|
c.y -= 0;
|
||||||
|
c.x = self.size.get().x - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cursor_up(&mut self, n: usize) {
|
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) {
|
fn save_cursor_position(&mut self) {
|
||||||
self.cursor_save = self.cursor;
|
self.cursav = self.cursor.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restore_cursor_position(&mut self) {
|
fn restore_cursor_position(&mut self) {
|
||||||
self.cursor = self.cursor_save;
|
self.cursor.set(self.cursav);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Perform for PerfAtom {
|
impl Perform for PerfAtom {
|
||||||
fn print(&mut self, c: char) {
|
fn print(&mut self, ch: char) {
|
||||||
self.write_atom(self.cursor, Some(TerminalAtom::new(c, self.get_style())));
|
let mut c = self.cursor.get_mut();
|
||||||
|
self.write_atom(*c, Some(TerminalAtom::new(ch, self.get_style())));
|
||||||
|
|
||||||
self.cursor.x += 1;
|
c.x += 1;
|
||||||
if self.cursor.x >= self.term_width {
|
if c.x >= self.size.get().x {
|
||||||
self.cursor.x = 0;
|
self.linefeed();
|
||||||
self.cursor.y += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,44 +427,61 @@ impl Perform for PerfAtom {
|
||||||
'm' => while let Some(n) = piter.next() {
|
'm' => while let Some(n) = piter.next() {
|
||||||
match n[0] {
|
match n[0] {
|
||||||
0 => {
|
0 => {
|
||||||
self.style = TerminalStyle::default();
|
self.cursty = TerminalStyle::default();
|
||||||
self.invert = false;
|
self.curinv = false;
|
||||||
}
|
}
|
||||||
1 => self.style = self.style.add(TerminalStyle::bold(true)),
|
1 => self.cursty = self.cursty.add(TerminalStyle::bold(true)),
|
||||||
3 => self.style = self.style.add(TerminalStyle::italic(true)),
|
3 => self.cursty = self.cursty.add(TerminalStyle::italic(true)),
|
||||||
4 => self.style = self.style.add(TerminalStyle::underline(true)),
|
4 => self.cursty = self.cursty.add(TerminalStyle::underline(true)),
|
||||||
7 => self.invert = true,
|
7 => self.curinv = true,
|
||||||
27 => self.invert = false,
|
27 => self.curinv = false,
|
||||||
|
|
||||||
30 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.black)),
|
30 => self.set_fg_color(&TTYColor::Black),
|
||||||
40 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.black)),
|
40 => self.set_bg_color(&TTYColor::Black),
|
||||||
31 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.red)),
|
90 => self.set_fg_color(&TTYColor::LightBlack),
|
||||||
41 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.red)),
|
100 => self.set_bg_color(&TTYColor::LightBlack),
|
||||||
32 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.green)),
|
31 => self.set_fg_color(&TTYColor::Red),
|
||||||
42 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.green)),
|
41 => self.set_bg_color(&TTYColor::Red),
|
||||||
33 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.yellow)),
|
91 => self.set_fg_color(&TTYColor::LightRed),
|
||||||
43 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.yellow)),
|
101 => self.set_bg_color(&TTYColor::LightRed),
|
||||||
34 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.blue)),
|
32 => self.set_fg_color(&TTYColor::Green),
|
||||||
44 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.blue)),
|
42 => self.set_bg_color(&TTYColor::Green),
|
||||||
35 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.magenta)),
|
92 => self.set_fg_color(&TTYColor::LightGreen),
|
||||||
45 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.magenta)),
|
102 => self.set_bg_color(&TTYColor::LightGreen),
|
||||||
36 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.cyan)),
|
33 => self.set_fg_color(&TTYColor::Yellow),
|
||||||
46 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.cyan)),
|
43 => self.set_bg_color(&TTYColor::Yellow),
|
||||||
37 => self.style = self.style.add(TerminalStyle::fg_color(self.colors.white)),
|
93 => self.set_fg_color(&TTYColor::LightYellow),
|
||||||
47 => self.style = self.style.add(TerminalStyle::bg_color(self.colors.white)),
|
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 => {
|
38 => {
|
||||||
let x = piter.next().unwrap();
|
let x = piter.next().unwrap();
|
||||||
match x[0] {
|
match x[0] {
|
||||||
2 => {
|
2 => {
|
||||||
let r = piter.next().unwrap();
|
let r = piter.next().unwrap()[0] as u8;
|
||||||
let g = piter.next().unwrap();
|
let g = piter.next().unwrap()[0] as u8;
|
||||||
let b = piter.next().unwrap();
|
let b = piter.next().unwrap()[0] as u8;
|
||||||
self.style = self.style.add(TerminalStyle::fg_color((r[0] as u8, g[0] as u8, b[0] as u8)))
|
self.set_fg_color(&TTYColor::Rgb(r,g,b));
|
||||||
},
|
},
|
||||||
5 => {
|
5 => {
|
||||||
let v = piter.next().unwrap();
|
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();
|
let x = piter.next().unwrap();
|
||||||
match x[0] {
|
match x[0] {
|
||||||
2 => {
|
2 => {
|
||||||
let r = piter.next().unwrap();
|
let r = piter.next().unwrap()[0] as u8;
|
||||||
let g = piter.next().unwrap();
|
let g = piter.next().unwrap()[0] as u8;
|
||||||
let b = piter.next().unwrap();
|
let b = piter.next().unwrap()[0] as u8;
|
||||||
self.style = self.style.add(TerminalStyle::bg_color((r[0] as u8, g[0] as u8, b[0] as u8)))
|
self.set_bg_color(&TTYColor::Rgb(r,g,b));
|
||||||
},
|
},
|
||||||
5 => {
|
5 => {
|
||||||
let v = piter.next().unwrap();
|
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 {
|
let c = self.cursor.get();
|
||||||
self.write_atom(Point2::new(x, self.cursor.y), Some(TerminalAtom::new(' ', self.style)));
|
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.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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
'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' => {
|
'C' | 'a' => {
|
||||||
self.cursor.x += piter.next().unwrap_or(&[1])[0] as i16;
|
let mut c = self.cursor.get_mut();
|
||||||
if self.cursor.x >= self.term_width {
|
c.x += piter.next().unwrap_or(&[1])[0] as i16;
|
||||||
self.cursor.y += self.cursor.x / self.term_width;
|
if c.x >= self.size.get().x {
|
||||||
self.cursor.x %= self.term_width;
|
c.y += c.x / self.size.get().x;
|
||||||
|
c.x %= self.size.get().x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'D' => {
|
'D' => {
|
||||||
self.cursor.x -= piter.next().unwrap_or(&[1])[0] as i16;
|
let mut c = self.cursor.get_mut();
|
||||||
if self.cursor.x < 0 {
|
c.x -= piter.next().unwrap_or(&[1])[0] as i16;
|
||||||
self.cursor.x = self.term_width - 1;
|
if c.x < 0 {
|
||||||
self.cursor.y -= 1;
|
c.x = self.size.get().x - 1;
|
||||||
|
c.y -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'd' => {
|
'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' => {
|
'E' => {
|
||||||
if self.cursor.x >= self.term_width {
|
let mut c = self.cursor.get_mut();
|
||||||
self.cursor.y += 1;
|
if c.x >= self.size.get().x {
|
||||||
|
c.y += 1;
|
||||||
}
|
}
|
||||||
self.cursor.x = 0;
|
c.x = 0;
|
||||||
self.cursor.y += piter.next().unwrap_or(&[1])[0] as i16;
|
c.y += piter.next().unwrap_or(&[1])[0] as i16;
|
||||||
}
|
}
|
||||||
'F' => {
|
'F' => {
|
||||||
self.cursor.x = 0;
|
let mut c = self.cursor.get_mut();
|
||||||
self.cursor.y -= piter.next().unwrap_or(&[1])[0] as i16;
|
c.x = 0;
|
||||||
|
c.y -= piter.next().unwrap_or(&[1])[0] as i16;
|
||||||
}
|
}
|
||||||
'G' | '`' => {
|
'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' => {
|
'H' | 'f' => {
|
||||||
self.cursor.y = piter.next().unwrap_or(&[1])[0] as i16 - 1;
|
let mut c = self.cursor.get_mut();
|
||||||
self.cursor.x = piter.next().unwrap_or(&[1])[0] as i16 - 1;
|
c.y = piter.next().unwrap_or(&[1])[0] as i16 - 1;
|
||||||
|
c.x = piter.next().unwrap_or(&[1])[0] as i16 - 1;
|
||||||
}
|
}
|
||||||
'J' => {
|
'J' => {
|
||||||
let x = piter.next().unwrap_or(&[0 as u16; 1]);
|
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
|
// clear from cursor until end of screen
|
||||||
0 => {
|
0 => {
|
||||||
let mut pos = self.cursor;
|
let mut pos = self.cursor.get();
|
||||||
|
|
||||||
while pos.y < 100 {
|
while pos.y < 100 {
|
||||||
self.write_atom(pos, None);
|
self.write_atom(pos, None);
|
||||||
pos.x += 1;
|
pos.x += 1;
|
||||||
|
|
||||||
if pos.x >= self.term_width {
|
if pos.x >= self.size.get().x {
|
||||||
pos.x = 0;
|
pos.x = 0;
|
||||||
pos.y += 1;
|
pos.y += 1;
|
||||||
}
|
}
|
||||||
|
@ -324,13 +576,13 @@ impl Perform for PerfAtom {
|
||||||
|
|
||||||
// clear from cursor to begin
|
// clear from cursor to begin
|
||||||
1 => {
|
1 => {
|
||||||
let mut pos = self.cursor;
|
let mut pos = self.cursor.get();
|
||||||
while pos.y >= 0 || pos.x >= 0 {
|
while pos.y >= 0 || pos.x >= 0 {
|
||||||
self.write_atom(pos, None);
|
self.write_atom(pos, None);
|
||||||
|
|
||||||
pos.x -= 1;
|
pos.x -= 1;
|
||||||
if pos.x < 0 {
|
if pos.x < 0 {
|
||||||
pos.x = self.term_width;
|
pos.x = self.size.get().x;
|
||||||
pos.y -= 1;
|
pos.y -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -341,12 +593,12 @@ impl Perform for PerfAtom {
|
||||||
// erase entire screen
|
// erase entire screen
|
||||||
2 => {
|
2 => {
|
||||||
for y in 0 .. 100 {
|
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.write_atom(Point2::new(x, y), None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.cursor = Point2::new(0, 0);
|
self.cursor.set(Point2::new(0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// invalid
|
// invalid
|
||||||
|
@ -359,22 +611,25 @@ impl Perform for PerfAtom {
|
||||||
|
|
||||||
// clear from cursor until end of line
|
// clear from cursor until end of line
|
||||||
0 => {
|
0 => {
|
||||||
for x in self.cursor.x .. self.term_width {
|
let c = self.cursor.get();
|
||||||
self.write_atom(Point2::new(x, self.cursor.y), Some(TerminalAtom::new(' ', self.get_style())));
|
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
|
// clear from start of line until cursor
|
||||||
1 => {
|
1 => {
|
||||||
for x in 0 .. self.cursor.x {
|
let c = self.cursor.get();
|
||||||
self.write_atom(Point2::new(x, self.cursor.y), Some(TerminalAtom::new(' ', self.get_style())));
|
for x in 0 .. c.x {
|
||||||
|
self.write_atom(Point2::new(x, c.y), Some(TerminalAtom::new(' ', self.get_style())));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// clear entire line
|
// clear entire line
|
||||||
2 => {
|
2 => {
|
||||||
for x in 0 .. self.term_width {
|
let c = self.cursor.get();
|
||||||
self.write_atom(Point2::new(x, self.cursor.y), Some(TerminalAtom::new(' ', self.get_style())));
|
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' => {
|
'M' => {
|
||||||
let n = piter.next().unwrap_or(&[1])[0] as i16;
|
let n = piter.next().unwrap_or(&[1])[0] as i16;
|
||||||
for y in 0 .. n {
|
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);
|
self.write_atom(Point2::new(x, self.cursor.y+y), None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,13 +657,10 @@ impl Perform for PerfAtom {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
's' => {
|
'S' => { self.scroll_up(piter.next().unwrap_or(&[1])[0] as usize); }
|
||||||
self.save_cursor_position();
|
'T' => { self.scroll_dn(piter.next().unwrap_or(&[1])[0] as usize); }
|
||||||
}
|
's' => { self.save_cursor_position(); }
|
||||||
'u' => {
|
'u' => { self.restore_cursor_position(); }
|
||||||
self.restore_cursor_position();
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
/*
|
/*
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
@ -421,7 +673,6 @@ impl Perform for PerfAtom {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) {
|
fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) {
|
||||||
|
|
||||||
match (byte, intermediates) {
|
match (byte, intermediates) {
|
||||||
//(b'B', intermediates) => configure_charset!(StandardCharset::Ascii, intermediates),
|
//(b'B', intermediates) => configure_charset!(StandardCharset::Ascii, intermediates),
|
||||||
(b'D', []) => self.linefeed(),
|
(b'D', []) => self.linefeed(),
|
||||||
|
|
Loading…
Reference in a new issue