mirror of
https://github.com/asciinema/avt.git
synced 2025-04-19 05:22:19 +03:00
Make parser return operation instead of calling executor
This commit is contained in:
parent
cea7113d95
commit
91580aa1bf
@ -1,5 +1,4 @@
|
||||
use avt::ops::Operation;
|
||||
use avt::parser::{Executor, Parser};
|
||||
use avt::parser::Parser;
|
||||
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
|
||||
use std::fs;
|
||||
|
||||
@ -21,28 +20,23 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
||||
});
|
||||
}
|
||||
|
||||
struct NoopExecutor;
|
||||
|
||||
impl Executor for NoopExecutor {
|
||||
fn execute(&mut self, _op: Operation) {}
|
||||
}
|
||||
|
||||
fn setup(filename: &str) -> impl Fn() -> (Parser, String, NoopExecutor) {
|
||||
fn setup(filename: &str) -> impl Fn() -> (Parser, String) {
|
||||
let filename = filename.to_owned();
|
||||
|
||||
move || {
|
||||
let parser = Parser::default();
|
||||
let text = sample_text(&filename);
|
||||
let executor = NoopExecutor {};
|
||||
|
||||
(parser, text, executor)
|
||||
(parser, text)
|
||||
}
|
||||
}
|
||||
|
||||
fn run<E: Executor>((mut parser, text, mut executor): (Parser, String, E)) -> (Parser, String, E) {
|
||||
parser.feed_str(&text, &mut executor);
|
||||
fn run((mut parser, text): (Parser, String)) -> (Parser, String) {
|
||||
text.chars().for_each(|ch| {
|
||||
parser.feed(ch);
|
||||
});
|
||||
|
||||
(parser, text, executor)
|
||||
(parser, text)
|
||||
}
|
||||
|
||||
fn sample_text(filename: &str) -> String {
|
||||
|
312
src/parser.rs
312
src/parser.rs
@ -38,33 +38,17 @@ struct Params(Vec<Param>);
|
||||
#[derive(Debug, Default, PartialEq)]
|
||||
struct Intermediates(Vec<char>);
|
||||
|
||||
pub trait Executor {
|
||||
fn execute(&mut self, op: Operation);
|
||||
}
|
||||
|
||||
impl Executor for Vec<Operation> {
|
||||
fn execute(&mut self, op: Operation) {
|
||||
self.push(op);
|
||||
}
|
||||
}
|
||||
|
||||
impl Parser {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub fn feed_str<S: AsRef<str>, E: Executor>(&mut self, input: S, executor: &mut E) {
|
||||
for ch in input.as_ref().chars() {
|
||||
self.feed(ch, executor);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn feed<E: Executor>(&mut self, input: char, executor: &mut E) {
|
||||
pub fn feed(&mut self, input: char) -> Option<Operation> {
|
||||
let input2 = if input >= '\u{a0}' { '\u{41}' } else { input };
|
||||
|
||||
match (&self.state, input2) {
|
||||
(State::Ground, '\u{20}'..='\u{7f}') => {
|
||||
executor.execute(Operation::Print(input));
|
||||
return Some(Operation::Print(input));
|
||||
}
|
||||
|
||||
(State::CsiParam, '\u{30}'..='\u{3b}') => {
|
||||
@ -83,7 +67,7 @@ impl Parser {
|
||||
|
||||
(State::CsiParam, '\u{40}'..='\u{7e}') => {
|
||||
self.state = State::Ground;
|
||||
self.csi_dispatch(input, executor);
|
||||
return self.csi_dispatch(input);
|
||||
}
|
||||
|
||||
(State::CsiEntry, '\u{30}'..='\u{39}') | (State::CsiEntry, '\u{3b}') => {
|
||||
@ -94,12 +78,12 @@ impl Parser {
|
||||
(State::Ground, '\u{00}'..='\u{17}')
|
||||
| (State::Ground, '\u{19}')
|
||||
| (State::Ground, '\u{1c}'..='\u{1f}') => {
|
||||
self.execute(input, executor);
|
||||
return self.execute(input);
|
||||
}
|
||||
|
||||
(State::CsiEntry, '\u{40}'..='\u{7e}') => {
|
||||
self.state = State::Ground;
|
||||
self.csi_dispatch(input, executor);
|
||||
return self.csi_dispatch(input);
|
||||
}
|
||||
|
||||
(State::OscString, '\u{20}'..='\u{7f}') => {
|
||||
@ -113,7 +97,7 @@ impl Parser {
|
||||
|
||||
(State::EscapeIntermediate, '\u{30}'..='\u{7e}') => {
|
||||
self.state = State::Ground;
|
||||
self.esc_dispatch(input, executor);
|
||||
return self.esc_dispatch(input);
|
||||
}
|
||||
|
||||
(State::CsiEntry, '\u{3c}'..='\u{3f}') => {
|
||||
@ -140,7 +124,7 @@ impl Parser {
|
||||
| (State::Escape, '\u{5c}')
|
||||
| (State::Escape, '\u{60}'..='\u{7e}') => {
|
||||
self.state = State::Ground;
|
||||
self.esc_dispatch(input, executor);
|
||||
return self.esc_dispatch(input);
|
||||
}
|
||||
|
||||
(State::Escape, '\u{5d}') => {
|
||||
@ -159,7 +143,7 @@ impl Parser {
|
||||
| (_, '\u{99}')
|
||||
| (_, '\u{9a}') => {
|
||||
self.state = State::Ground;
|
||||
self.execute(input, executor);
|
||||
return self.execute(input);
|
||||
}
|
||||
|
||||
(State::Escape, '\u{50}') => {
|
||||
@ -174,7 +158,7 @@ impl Parser {
|
||||
|
||||
(State::CsiIntermediate, '\u{40}'..='\u{7e}') => {
|
||||
self.state = State::Ground;
|
||||
self.csi_dispatch(input, executor);
|
||||
return self.csi_dispatch(input);
|
||||
}
|
||||
|
||||
(State::DcsParam, '\u{30}'..='\u{39}') | (State::DcsParam, '\u{3b}') => {
|
||||
@ -193,13 +177,13 @@ impl Parser {
|
||||
(State::CsiParam, '\u{00}'..='\u{17}')
|
||||
| (State::CsiParam, '\u{19}')
|
||||
| (State::CsiParam, '\u{1c}'..='\u{1f}') => {
|
||||
self.execute(input, executor);
|
||||
return self.execute(input);
|
||||
}
|
||||
|
||||
(State::Escape, '\u{00}'..='\u{17}')
|
||||
| (State::Escape, '\u{19}')
|
||||
| (State::Escape, '\u{1c}'..='\u{1f}') => {
|
||||
self.execute(input, executor);
|
||||
return self.execute(input);
|
||||
}
|
||||
|
||||
(State::DcsEntry, '\u{20}'..='\u{2f}') => {
|
||||
@ -220,7 +204,7 @@ impl Parser {
|
||||
(State::CsiEntry, '\u{00}'..='\u{17}')
|
||||
| (State::CsiEntry, '\u{19}')
|
||||
| (State::CsiEntry, '\u{1c}'..='\u{1f}') => {
|
||||
self.execute(input, executor);
|
||||
return self.execute(input);
|
||||
}
|
||||
|
||||
(State::DcsEntry, '\u{40}'..='\u{7e}') => {
|
||||
@ -247,7 +231,7 @@ impl Parser {
|
||||
(State::EscapeIntermediate, '\u{00}'..='\u{17}')
|
||||
| (State::EscapeIntermediate, '\u{19}')
|
||||
| (State::EscapeIntermediate, '\u{1c}'..='\u{1f}') => {
|
||||
self.execute(input, executor);
|
||||
return self.execute(input);
|
||||
}
|
||||
|
||||
(State::Escape, '\u{58}') | (State::Escape, '\u{5e}') | (State::Escape, '\u{5f}') => {
|
||||
@ -288,7 +272,7 @@ impl Parser {
|
||||
(State::CsiIntermediate, '\u{00}'..='\u{17}')
|
||||
| (State::CsiIntermediate, '\u{19}')
|
||||
| (State::CsiIntermediate, '\u{1c}'..='\u{1f}') => {
|
||||
self.execute(input, executor);
|
||||
return self.execute(input);
|
||||
}
|
||||
|
||||
(State::DcsEntry, '\u{3a}') => {
|
||||
@ -302,7 +286,7 @@ impl Parser {
|
||||
(State::CsiIgnore, '\u{00}'..='\u{17}')
|
||||
| (State::CsiIgnore, '\u{19}')
|
||||
| (State::CsiIgnore, '\u{1c}'..='\u{1f}') => {
|
||||
self.execute(input, executor);
|
||||
return self.execute(input);
|
||||
}
|
||||
|
||||
(State::DcsParam, '\u{20}'..='\u{2f}') => {
|
||||
@ -320,61 +304,27 @@ impl Parser {
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn execute<E: Executor>(&mut self, input: char, executor: &mut E) {
|
||||
fn execute(&mut self, input: char) -> Option<Operation> {
|
||||
use Operation::*;
|
||||
|
||||
match input {
|
||||
'\u{08}' => {
|
||||
executor.execute(Bs);
|
||||
}
|
||||
|
||||
'\u{09}' => {
|
||||
executor.execute(Ht);
|
||||
}
|
||||
|
||||
'\u{0a}' => {
|
||||
executor.execute(Lf);
|
||||
}
|
||||
|
||||
'\u{0b}' => {
|
||||
executor.execute(Lf);
|
||||
}
|
||||
|
||||
'\u{0c}' => {
|
||||
executor.execute(Lf);
|
||||
}
|
||||
|
||||
'\u{0d}' => {
|
||||
executor.execute(Cr);
|
||||
}
|
||||
|
||||
'\u{0e}' => {
|
||||
executor.execute(So);
|
||||
}
|
||||
|
||||
'\u{0f}' => {
|
||||
executor.execute(Si);
|
||||
}
|
||||
|
||||
'\u{84}' => {
|
||||
executor.execute(Lf);
|
||||
}
|
||||
|
||||
'\u{85}' => {
|
||||
executor.execute(Nel);
|
||||
}
|
||||
|
||||
'\u{88}' => {
|
||||
executor.execute(Hts);
|
||||
}
|
||||
|
||||
'\u{8d}' => {
|
||||
executor.execute(Ri);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
'\u{08}' => Some(Bs),
|
||||
'\u{09}' => Some(Ht),
|
||||
'\u{0a}' => Some(Lf),
|
||||
'\u{0b}' => Some(Lf),
|
||||
'\u{0c}' => Some(Lf),
|
||||
'\u{0d}' => Some(Cr),
|
||||
'\u{0e}' => Some(So),
|
||||
'\u{0f}' => Some(Si),
|
||||
'\u{84}' => Some(Lf),
|
||||
'\u{85}' => Some(Nel),
|
||||
'\u{88}' => Some(Hts),
|
||||
'\u{8d}' => Some(Ri),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -391,210 +341,128 @@ impl Parser {
|
||||
self.params.push(input);
|
||||
}
|
||||
|
||||
fn esc_dispatch<E: Executor>(&mut self, input: char, executor: &mut E) {
|
||||
fn esc_dispatch(&mut self, input: char) -> Option<Operation> {
|
||||
use Operation::*;
|
||||
|
||||
match (self.intermediates.0.first(), input) {
|
||||
(None, c) if ('@'..='_').contains(&c) => {
|
||||
self.execute(((input as u8) + 0x40) as char, executor)
|
||||
}
|
||||
(None, c) if ('@'..='_').contains(&c) => self.execute(((input as u8) + 0x40) as char),
|
||||
|
||||
(None, '7') => {
|
||||
executor.execute(Sc);
|
||||
}
|
||||
(None, '7') => Some(Sc),
|
||||
|
||||
(None, '8') => {
|
||||
executor.execute(Rc);
|
||||
}
|
||||
(None, '8') => Some(Rc),
|
||||
|
||||
(None, 'c') => {
|
||||
self.state = State::Ground;
|
||||
executor.execute(Ris);
|
||||
Some(Ris)
|
||||
}
|
||||
|
||||
(Some('#'), '8') => {
|
||||
executor.execute(Decaln);
|
||||
}
|
||||
(Some('#'), '8') => Some(Decaln),
|
||||
|
||||
(Some('('), '0') => {
|
||||
executor.execute(Gzd4(Charset::Drawing));
|
||||
}
|
||||
(Some('('), '0') => Some(Gzd4(Charset::Drawing)),
|
||||
|
||||
(Some('('), _) => {
|
||||
executor.execute(Gzd4(Charset::Ascii));
|
||||
}
|
||||
(Some('('), _) => Some(Gzd4(Charset::Ascii)),
|
||||
|
||||
(Some(')'), '0') => {
|
||||
executor.execute(G1d4(Charset::Drawing));
|
||||
}
|
||||
(Some(')'), '0') => Some(G1d4(Charset::Drawing)),
|
||||
|
||||
(Some(')'), _) => {
|
||||
executor.execute(G1d4(Charset::Ascii));
|
||||
}
|
||||
(Some(')'), _) => Some(G1d4(Charset::Ascii)),
|
||||
|
||||
_ => {}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn csi_dispatch<E: Executor>(&mut self, input: char, executor: &mut E) {
|
||||
fn csi_dispatch(&mut self, input: char) -> Option<Operation> {
|
||||
use Operation::*;
|
||||
|
||||
let ps = &mut self.params;
|
||||
|
||||
match (self.intermediates.0.first(), input) {
|
||||
(None, '@') => {
|
||||
executor.execute(Ich(ps.drain().next()));
|
||||
}
|
||||
(None, '@') => Some(Ich(ps.drain().next())),
|
||||
|
||||
(None, 'A') => {
|
||||
executor.execute(Cuu(ps.drain().next()));
|
||||
}
|
||||
(None, 'A') => Some(Cuu(ps.drain().next())),
|
||||
|
||||
(None, 'B') => {
|
||||
executor.execute(Cud(ps.drain().next()));
|
||||
}
|
||||
(None, 'B') => Some(Cud(ps.drain().next())),
|
||||
|
||||
(None, 'C') => {
|
||||
executor.execute(Cuf(ps.drain().next()));
|
||||
}
|
||||
(None, 'C') => Some(Cuf(ps.drain().next())),
|
||||
|
||||
(None, 'D') => {
|
||||
executor.execute(Cub(ps.drain().next()));
|
||||
}
|
||||
(None, 'D') => Some(Cub(ps.drain().next())),
|
||||
|
||||
(None, 'E') => {
|
||||
executor.execute(Cnl(ps.drain().next()));
|
||||
}
|
||||
(None, 'E') => Some(Cnl(ps.drain().next())),
|
||||
|
||||
(None, 'F') => {
|
||||
executor.execute(Cpl(ps.drain().next()));
|
||||
}
|
||||
(None, 'F') => Some(Cpl(ps.drain().next())),
|
||||
|
||||
(None, 'G') => {
|
||||
executor.execute(Cha(ps.drain().next()));
|
||||
}
|
||||
(None, 'G') => Some(Cha(ps.drain().next())),
|
||||
|
||||
(None, 'H') => {
|
||||
let mut ps = ps.drain();
|
||||
executor.execute(Cup(ps.next(), ps.next()));
|
||||
Some(Cup(ps.next(), ps.next()))
|
||||
}
|
||||
|
||||
(None, 'I') => {
|
||||
executor.execute(Cht(ps.drain().next()));
|
||||
}
|
||||
(None, 'I') => Some(Cht(ps.drain().next())),
|
||||
|
||||
(None, 'J') => {
|
||||
executor.execute(Ed(ps.drain().next()));
|
||||
}
|
||||
(None, 'J') => Some(Ed(ps.drain().next())),
|
||||
|
||||
(None, 'K') => {
|
||||
executor.execute(El(ps.drain().next()));
|
||||
}
|
||||
(None, 'K') => Some(El(ps.drain().next())),
|
||||
|
||||
(None, 'L') => {
|
||||
executor.execute(Il(ps.drain().next()));
|
||||
}
|
||||
(None, 'L') => Some(Il(ps.drain().next())),
|
||||
|
||||
(None, 'M') => {
|
||||
executor.execute(Dl(ps.drain().next()));
|
||||
}
|
||||
(None, 'M') => Some(Dl(ps.drain().next())),
|
||||
|
||||
(None, 'P') => {
|
||||
executor.execute(Dch(ps.drain().next()));
|
||||
}
|
||||
(None, 'P') => Some(Dch(ps.drain().next())),
|
||||
|
||||
(None, 'S') => {
|
||||
executor.execute(Su(ps.drain().next()));
|
||||
}
|
||||
(None, 'S') => Some(Su(ps.drain().next())),
|
||||
|
||||
(None, 'T') => {
|
||||
executor.execute(Sd(ps.drain().next()));
|
||||
}
|
||||
(None, 'T') => Some(Sd(ps.drain().next())),
|
||||
|
||||
(None, 'W') => {
|
||||
executor.execute(Ctc(ps.drain().next()));
|
||||
}
|
||||
(None, 'W') => Some(Ctc(ps.drain().next())),
|
||||
|
||||
(None, 'X') => {
|
||||
executor.execute(Ech(ps.drain().next()));
|
||||
}
|
||||
(None, 'X') => Some(Ech(ps.drain().next())),
|
||||
|
||||
(None, 'Z') => {
|
||||
executor.execute(Cbt(ps.drain().next()));
|
||||
}
|
||||
(None, 'Z') => Some(Cbt(ps.drain().next())),
|
||||
|
||||
(None, '`') => {
|
||||
executor.execute(Cha(ps.drain().next()));
|
||||
}
|
||||
(None, '`') => Some(Cha(ps.drain().next())),
|
||||
|
||||
(None, 'a') => {
|
||||
executor.execute(Cuf(ps.drain().next()));
|
||||
}
|
||||
(None, 'a') => Some(Cuf(ps.drain().next())),
|
||||
|
||||
(None, 'b') => {
|
||||
executor.execute(Rep(ps.drain().next()));
|
||||
}
|
||||
(None, 'b') => Some(Rep(ps.drain().next())),
|
||||
|
||||
(None, 'd') => {
|
||||
executor.execute(Vpa(ps.drain().next()));
|
||||
}
|
||||
(None, 'd') => Some(Vpa(ps.drain().next())),
|
||||
|
||||
(None, 'e') => {
|
||||
executor.execute(Vpr(ps.drain().next()));
|
||||
}
|
||||
(None, 'e') => Some(Vpr(ps.drain().next())),
|
||||
|
||||
(None, 'f') => {
|
||||
let mut ps = ps.drain();
|
||||
executor.execute(Cup(ps.next(), ps.next()));
|
||||
Some(Cup(ps.next(), ps.next()))
|
||||
}
|
||||
|
||||
(None, 'g') => {
|
||||
executor.execute(Tbc(ps.drain().next()));
|
||||
}
|
||||
(None, 'g') => Some(Tbc(ps.drain().next())),
|
||||
|
||||
(None, 'h') => {
|
||||
executor.execute(Sm(ps.take()));
|
||||
}
|
||||
(None, 'h') => Some(Sm(ps.take())),
|
||||
|
||||
(None, 'l') => {
|
||||
executor.execute(Rm(ps.take()));
|
||||
}
|
||||
(None, 'l') => Some(Rm(ps.take())),
|
||||
|
||||
(None, 'm') => {
|
||||
executor.execute(Sgr(ps.take()));
|
||||
}
|
||||
(None, 'm') => Some(Sgr(ps.take())),
|
||||
|
||||
(None, 'r') => {
|
||||
let mut ps = ps.drain();
|
||||
executor.execute(Decstbm(ps.next(), ps.next()));
|
||||
Some(Decstbm(ps.next(), ps.next()))
|
||||
}
|
||||
|
||||
(None, 's') => {
|
||||
executor.execute(Sc);
|
||||
}
|
||||
(None, 's') => Some(Sc),
|
||||
|
||||
(None, 't') => {
|
||||
let mut ps = ps.drain();
|
||||
executor.execute(Xtwinops(ps.next(), ps.next(), ps.next()));
|
||||
Some(Xtwinops(ps.next(), ps.next(), ps.next()))
|
||||
}
|
||||
|
||||
(None, 'u') => {
|
||||
executor.execute(Rc);
|
||||
}
|
||||
(None, 'u') => Some(Rc),
|
||||
|
||||
(Some('!'), 'p') => {
|
||||
executor.execute(Decstr);
|
||||
}
|
||||
(Some('!'), 'p') => Some(Decstr),
|
||||
|
||||
(Some('?'), 'h') => {
|
||||
executor.execute(PrvSm(ps.take()));
|
||||
}
|
||||
(Some('?'), 'h') => Some(PrvSm(ps.take())),
|
||||
|
||||
(Some('?'), 'l') => {
|
||||
executor.execute(PrvRm(ps.take()));
|
||||
}
|
||||
(Some('?'), 'l') => Some(PrvRm(ps.take())),
|
||||
|
||||
_ => {}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -762,15 +630,18 @@ mod tests {
|
||||
#[test]
|
||||
fn sgr() {
|
||||
let mut parser = Parser::new();
|
||||
let mut ops = Vec::new();
|
||||
|
||||
parser.feed_str("\x1b[;1;;23;456;m", &mut ops);
|
||||
let ops = "\x1b[;1;;23;456;m"
|
||||
.chars()
|
||||
.filter_map(|ch| parser.feed(ch))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(ops, vec![Sgr(ps(&[0, 1, 0, 23, 456, 0]))]);
|
||||
|
||||
ops.clear();
|
||||
|
||||
parser.feed_str("\x1b[;1;;38:2:1:2:3;m", &mut ops);
|
||||
let ops = "\x1b[;1;;38:2:1:2:3;m"
|
||||
.chars()
|
||||
.filter_map(|ch| parser.feed(ch))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(
|
||||
ops,
|
||||
@ -781,9 +652,10 @@ mod tests {
|
||||
#[test]
|
||||
fn dump() {
|
||||
let mut parser = Parser::new();
|
||||
let mut ops = Vec::new();
|
||||
|
||||
parser.feed_str("\x1b[;1;;38:2:1:2:3;", &mut ops);
|
||||
for ch in "\x1b[;1;;38:2:1:2:3;".chars() {
|
||||
parser.feed(ch);
|
||||
}
|
||||
|
||||
assert_eq!(parser.dump(), "\u{9b}0;1;0;38:2:1:2:3;0");
|
||||
}
|
||||
|
400
src/terminal.rs
400
src/terminal.rs
@ -9,7 +9,6 @@ use crate::color::Color;
|
||||
use crate::dump::Dump;
|
||||
use crate::line::Line;
|
||||
use crate::ops::{Operation, Param};
|
||||
use crate::parser::Executor;
|
||||
use crate::pen::{Intensity, Pen};
|
||||
use crate::tabs::Tabs;
|
||||
use rgb::RGB8;
|
||||
@ -121,6 +120,204 @@ impl Terminal {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute(&mut self, op: Operation) {
|
||||
use Operation::*;
|
||||
|
||||
match op {
|
||||
Bs => {
|
||||
self.bs();
|
||||
}
|
||||
|
||||
Cbt(param) => {
|
||||
self.cbt(param);
|
||||
}
|
||||
|
||||
Cha(param) => {
|
||||
self.cha(param);
|
||||
}
|
||||
|
||||
Cht(param) => {
|
||||
self.cht(param);
|
||||
}
|
||||
|
||||
Cnl(param) => {
|
||||
self.cnl(param);
|
||||
}
|
||||
|
||||
Cpl(param) => {
|
||||
self.cpl(param);
|
||||
}
|
||||
|
||||
Cr => {
|
||||
self.cr();
|
||||
}
|
||||
|
||||
Ctc(param) => {
|
||||
self.ctc(param);
|
||||
}
|
||||
|
||||
Cub(param) => {
|
||||
self.cub(param);
|
||||
}
|
||||
|
||||
Cud(param) => {
|
||||
self.cud(param);
|
||||
}
|
||||
|
||||
Cuf(param) => {
|
||||
self.cuf(param);
|
||||
}
|
||||
|
||||
Cup(param1, param2) => {
|
||||
self.cup(param1, param2);
|
||||
}
|
||||
|
||||
Cuu(param) => {
|
||||
self.cuu(param);
|
||||
}
|
||||
|
||||
Dch(param) => {
|
||||
self.dch(param);
|
||||
}
|
||||
|
||||
Decaln => {
|
||||
self.decaln();
|
||||
}
|
||||
|
||||
Decstbm(param1, param2) => {
|
||||
self.decstbm(param1, param2);
|
||||
}
|
||||
|
||||
Decstr => {
|
||||
self.decstr();
|
||||
}
|
||||
|
||||
Dl(param) => {
|
||||
self.dl(param);
|
||||
}
|
||||
|
||||
Ech(param) => {
|
||||
self.ech(param);
|
||||
}
|
||||
|
||||
Ed(param) => {
|
||||
self.ed(param);
|
||||
}
|
||||
|
||||
El(param) => {
|
||||
self.el(param);
|
||||
}
|
||||
|
||||
G1d4(charset) => {
|
||||
self.g1d4(charset);
|
||||
}
|
||||
|
||||
Gzd4(charset) => {
|
||||
self.gzd4(charset);
|
||||
}
|
||||
|
||||
Ht => {
|
||||
self.ht();
|
||||
}
|
||||
|
||||
Hts => {
|
||||
self.hts();
|
||||
}
|
||||
|
||||
Ich(param) => {
|
||||
self.ich(param);
|
||||
}
|
||||
|
||||
Il(param) => {
|
||||
self.il(param);
|
||||
}
|
||||
|
||||
Lf => {
|
||||
self.lf();
|
||||
}
|
||||
|
||||
Nel => {
|
||||
self.nel();
|
||||
}
|
||||
|
||||
Print(ch) => {
|
||||
self.print(ch);
|
||||
}
|
||||
|
||||
PrvRm(params) => {
|
||||
self.prv_rm(params);
|
||||
}
|
||||
|
||||
PrvSm(params) => {
|
||||
self.prv_sm(params);
|
||||
}
|
||||
|
||||
Rc => {
|
||||
self.rc();
|
||||
}
|
||||
|
||||
Rep(param) => {
|
||||
self.rep(param);
|
||||
}
|
||||
|
||||
Ri => {
|
||||
self.ri();
|
||||
}
|
||||
|
||||
Ris => {
|
||||
self.ris();
|
||||
}
|
||||
|
||||
Rm(params) => {
|
||||
self.rm(params);
|
||||
}
|
||||
|
||||
Sc => {
|
||||
self.sc();
|
||||
}
|
||||
|
||||
Sd(param) => {
|
||||
self.sd(param);
|
||||
}
|
||||
|
||||
Sgr(params) => {
|
||||
self.sgr(params);
|
||||
}
|
||||
|
||||
Si => {
|
||||
self.si();
|
||||
}
|
||||
|
||||
Sm(params) => {
|
||||
self.sm(params);
|
||||
}
|
||||
|
||||
So => {
|
||||
self.so();
|
||||
}
|
||||
|
||||
Su(param) => {
|
||||
self.su(param);
|
||||
}
|
||||
|
||||
Tbc(param) => {
|
||||
self.tbc(param);
|
||||
}
|
||||
|
||||
Vpa(param) => {
|
||||
self.vpa(param);
|
||||
}
|
||||
|
||||
Vpr(param) => {
|
||||
self.vpr(param);
|
||||
}
|
||||
|
||||
Xtwinops(param1, param2, param3) => {
|
||||
self.xtwinops(param1, param2, param3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cursor(&self) -> Cursor {
|
||||
self.cursor
|
||||
}
|
||||
@ -1203,206 +1400,6 @@ impl Default for Terminal {
|
||||
}
|
||||
}
|
||||
|
||||
impl Executor for Terminal {
|
||||
fn execute(&mut self, op: Operation) {
|
||||
use Operation::*;
|
||||
|
||||
match op {
|
||||
Bs => {
|
||||
self.bs();
|
||||
}
|
||||
|
||||
Cbt(param) => {
|
||||
self.cbt(param);
|
||||
}
|
||||
|
||||
Cha(param) => {
|
||||
self.cha(param);
|
||||
}
|
||||
|
||||
Cht(param) => {
|
||||
self.cht(param);
|
||||
}
|
||||
|
||||
Cnl(param) => {
|
||||
self.cnl(param);
|
||||
}
|
||||
|
||||
Cpl(param) => {
|
||||
self.cpl(param);
|
||||
}
|
||||
|
||||
Cr => {
|
||||
self.cr();
|
||||
}
|
||||
|
||||
Ctc(param) => {
|
||||
self.ctc(param);
|
||||
}
|
||||
|
||||
Cub(param) => {
|
||||
self.cub(param);
|
||||
}
|
||||
|
||||
Cud(param) => {
|
||||
self.cud(param);
|
||||
}
|
||||
|
||||
Cuf(param) => {
|
||||
self.cuf(param);
|
||||
}
|
||||
|
||||
Cup(param1, param2) => {
|
||||
self.cup(param1, param2);
|
||||
}
|
||||
|
||||
Cuu(param) => {
|
||||
self.cuu(param);
|
||||
}
|
||||
|
||||
Dch(param) => {
|
||||
self.dch(param);
|
||||
}
|
||||
|
||||
Decaln => {
|
||||
self.decaln();
|
||||
}
|
||||
|
||||
Decstbm(param1, param2) => {
|
||||
self.decstbm(param1, param2);
|
||||
}
|
||||
|
||||
Decstr => {
|
||||
self.decstr();
|
||||
}
|
||||
|
||||
Dl(param) => {
|
||||
self.dl(param);
|
||||
}
|
||||
|
||||
Ech(param) => {
|
||||
self.ech(param);
|
||||
}
|
||||
|
||||
Ed(param) => {
|
||||
self.ed(param);
|
||||
}
|
||||
|
||||
El(param) => {
|
||||
self.el(param);
|
||||
}
|
||||
|
||||
G1d4(charset) => {
|
||||
self.g1d4(charset);
|
||||
}
|
||||
|
||||
Gzd4(charset) => {
|
||||
self.gzd4(charset);
|
||||
}
|
||||
|
||||
Ht => {
|
||||
self.ht();
|
||||
}
|
||||
|
||||
Hts => {
|
||||
self.hts();
|
||||
}
|
||||
|
||||
Ich(param) => {
|
||||
self.ich(param);
|
||||
}
|
||||
|
||||
Il(param) => {
|
||||
self.il(param);
|
||||
}
|
||||
|
||||
Lf => {
|
||||
self.lf();
|
||||
}
|
||||
|
||||
Nel => {
|
||||
self.nel();
|
||||
}
|
||||
|
||||
Print(ch) => {
|
||||
self.print(ch);
|
||||
}
|
||||
|
||||
PrvRm(params) => {
|
||||
self.prv_rm(params);
|
||||
}
|
||||
|
||||
PrvSm(params) => {
|
||||
self.prv_sm(params);
|
||||
}
|
||||
|
||||
Rc => {
|
||||
self.rc();
|
||||
}
|
||||
|
||||
Rep(param) => {
|
||||
self.rep(param);
|
||||
}
|
||||
|
||||
Ri => {
|
||||
self.ri();
|
||||
}
|
||||
|
||||
Ris => {
|
||||
self.ris();
|
||||
}
|
||||
|
||||
Rm(params) => {
|
||||
self.rm(params);
|
||||
}
|
||||
|
||||
Sc => {
|
||||
self.sc();
|
||||
}
|
||||
|
||||
Sd(param) => {
|
||||
self.sd(param);
|
||||
}
|
||||
|
||||
Sgr(params) => {
|
||||
self.sgr(params);
|
||||
}
|
||||
|
||||
Si => {
|
||||
self.si();
|
||||
}
|
||||
|
||||
Sm(params) => {
|
||||
self.sm(params);
|
||||
}
|
||||
|
||||
So => {
|
||||
self.so();
|
||||
}
|
||||
|
||||
Su(param) => {
|
||||
self.su(param);
|
||||
}
|
||||
|
||||
Tbc(param) => {
|
||||
self.tbc(param);
|
||||
}
|
||||
|
||||
Vpa(param) => {
|
||||
self.vpa(param);
|
||||
}
|
||||
|
||||
Vpr(param) => {
|
||||
self.vpr(param);
|
||||
}
|
||||
|
||||
Xtwinops(param1, param2, param3) => {
|
||||
self.xtwinops(param1, param2, param3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Dump for Terminal {
|
||||
fn dump(&self) -> String {
|
||||
let (primary_ctx, alternate_ctx): (&SavedCtx, &SavedCtx) = match self.active_buffer_type {
|
||||
@ -1651,7 +1648,6 @@ mod tests {
|
||||
use super::Terminal;
|
||||
use crate::color::Color;
|
||||
use crate::ops::{Operation, Param};
|
||||
use crate::parser::Executor;
|
||||
use crate::pen::Intensity;
|
||||
use rgb::RGB8;
|
||||
use Operation::*;
|
||||
|
@ -19,7 +19,10 @@ impl Vt {
|
||||
}
|
||||
|
||||
pub fn feed_str(&mut self, s: &str) -> Changes {
|
||||
self.parser.feed_str(s, &mut self.terminal);
|
||||
s.chars()
|
||||
.filter_map(|ch| self.parser.feed(ch))
|
||||
.for_each(|op| self.terminal.execute(op));
|
||||
|
||||
let (lines, resized) = self.terminal.changes();
|
||||
let scrollback = self.terminal.gc();
|
||||
|
||||
@ -31,7 +34,9 @@ impl Vt {
|
||||
}
|
||||
|
||||
pub fn feed(&mut self, input: char) {
|
||||
self.parser.feed(input, &mut self.terminal);
|
||||
if let Some(op) = self.parser.feed(input) {
|
||||
self.terminal.execute(op);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size(&self) -> (usize, usize) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user