Escape ansi sequences

This commit is contained in:
Capucho 2020-07-27 22:09:33 +01:00 committed by Marcel Märtens
parent c399afa7c5
commit a2d70e6ff6
3 changed files with 60 additions and 35 deletions

10
Cargo.lock generated
View File

@ -69,6 +69,15 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8052e2d8aabbb8d556d6abbcce2a22b9590996c5f849b9c7ce4544a2e3b984e"
[[package]]
name = "ansi-parser"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "761ac675f1638a6a49e26f6ac3a4067ca3fefa8029816ae4ef8d3fa3d06a5194"
dependencies = [
"nom 4.2.3",
]
[[package]]
name = "ansi_term"
version = "0.11.0"
@ -4901,6 +4910,7 @@ dependencies = [
name = "veloren-server-cli"
version = "0.7.0"
dependencies = [
"ansi-parser",
"crossterm",
"lazy_static",
"tracing",

View File

@ -17,3 +17,4 @@ tracing-subscriber = { version = "0.2.3", default-features = false, features = [
crossterm = "0.17"
tui = { version = "0.10", default-features = false, features = ['crossterm'] }
lazy_static = "1"
ansi-parser = "0.6"

View File

@ -27,6 +27,54 @@ lazy_static! {
static ref LOG: TuiLog<'static> = TuiLog::default();
}
#[derive(Debug, Default, Clone)]
struct TuiLog<'a> {
inner: Arc<Mutex<Text<'a>>>,
}
impl<'a> TuiLog<'a> {
fn resize(&self, h: usize) {
let mut inner = self.inner.lock().unwrap();
if inner.height() > h {
let length = inner.height() - h;
inner.lines.drain(0..length);
}
}
}
impl<'a> Write for TuiLog<'a> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
use ansi_parser::{AnsiParser, AnsiSequence, Output};
use tui::text::{Span,Spans};
let line = String::from_utf8(buf.into())
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
let mut spans = Vec::new();
for out in line.ansi_parse() {
match out {
Output::TextBlock(text) => spans.push(text.to_string().into()),
Output::Escape(seq) => info!("{:?}",seq)
}
}
self.inner.lock().unwrap().lines.push(Spans(spans));
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
#[derive(Debug, Copy, Clone)]
enum Message {
Quit,
}
fn main() -> io::Result<()> {
// Init logging
let filter = match std::env::var_os(RUST_LOG_ENV).map(|s| s.into_string()) {
@ -99,7 +147,7 @@ fn main() -> io::Result<()> {
use crossterm::event::{KeyModifiers, *};
if poll(Duration::from_millis(50)).unwrap() {
if poll(Duration::from_millis(10)).unwrap() {
// It's guaranteed that the `read()` won't block when the `poll()`
// function returns `true`
match read().unwrap() {
@ -183,37 +231,3 @@ fn main() -> io::Result<()> {
Ok(())
}
#[derive(Debug, Default, Clone)]
struct TuiLog<'a> {
inner: Arc<Mutex<Text<'a>>>,
}
impl<'a> TuiLog<'a> {
fn resize(&self, h: usize) {
let mut inner = self.inner.lock().unwrap();
if inner.height() > h {
let length = inner.height() - h;
inner.lines.drain(0..length);
}
}
}
impl<'a> Write for TuiLog<'a> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let line = String::from_utf8(buf.into())
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
self.inner.lock().unwrap().lines.push(From::from(line));
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
#[derive(Debug, Copy, Clone)]
enum Message {
Quit,
}