2016-03-07 15:01:20 +00:00
|
|
|
use std::io::{Write, Result as IoResult};
|
2016-03-07 16:57:17 +00:00
|
|
|
use {Color, Mode};
|
2016-03-07 15:01:20 +00:00
|
|
|
|
|
|
|
/// Controlling terminals.
|
|
|
|
pub trait TermControl {
|
|
|
|
/// Print the CSI (control sequence introducer) followed by a byte string.
|
|
|
|
fn csi(&mut self, b: &[u8]) -> IoResult<usize>;
|
|
|
|
/// Print OSC (operating system command) followed by a byte string.
|
|
|
|
fn osc(&mut self, b: &[u8]) -> IoResult<usize>;
|
|
|
|
/// Print OSC (device control string) followed by a byte string.
|
|
|
|
fn dsc(&mut self, b: &[u8]) -> IoResult<usize>;
|
|
|
|
/// Clear the terminal.
|
|
|
|
fn clear(&mut self) -> IoResult<usize> {
|
|
|
|
self.csi(b"2J")
|
|
|
|
}
|
|
|
|
/// Show the cursor.
|
|
|
|
fn show(&mut self) -> IoResult<usize> {
|
|
|
|
self.csi(b"?25h")
|
|
|
|
}
|
|
|
|
/// Hide the cursor.
|
|
|
|
fn hide(&mut self) -> IoResult<usize> {
|
|
|
|
self.csi(b"?25l")
|
|
|
|
}
|
2016-03-07 16:57:17 +00:00
|
|
|
/// Reset the rendition mode.
|
|
|
|
fn reset(&mut self) -> IoResult<usize> {
|
2016-03-07 15:01:20 +00:00
|
|
|
self.csi(b"m")
|
|
|
|
}
|
|
|
|
/// Go to a given position.
|
|
|
|
fn goto(&mut self, x: u16, y: u16) -> IoResult<usize> {
|
|
|
|
self.csi(&[
|
2016-03-07 16:39:25 +00:00
|
|
|
(x / 10000) as u8 + b'0', (x / 1000) as u8 % 10 + b'0', (x / 100) as u8 % 10 + b'0', (x / 10) as u8 % 10 + b'0', x as u8 % 10 + b'0',
|
2016-03-07 15:01:20 +00:00
|
|
|
b';',
|
2016-03-07 16:39:25 +00:00
|
|
|
(y / 10000) as u8 + b'0', (y / 1000) as u8 % 10 + b'0', (y / 100) as u8 % 10 + b'0', (y / 10) as u8 % 10 + b'0', y as u8 % 10 + b'0',
|
2016-03-07 15:01:20 +00:00
|
|
|
b'H',
|
|
|
|
])
|
|
|
|
}
|
2016-03-07 15:23:05 +00:00
|
|
|
/// Set graphic rendition.
|
|
|
|
fn rendition(&mut self, r: u8) -> IoResult<usize> {
|
|
|
|
self.csi(&[
|
|
|
|
r / 100 + b'0', r / 10 % 10 + b'0', r % 10 + b'0',
|
|
|
|
b'm',
|
|
|
|
])
|
|
|
|
}
|
2016-03-07 16:39:25 +00:00
|
|
|
/// Set foreground color
|
|
|
|
fn color(&mut self, color: Color) -> IoResult<usize> {
|
|
|
|
let ansi = color.to_ansi_val();
|
|
|
|
self.csi(&[
|
|
|
|
b'3',
|
|
|
|
b'8',
|
|
|
|
b';',
|
|
|
|
b'5',
|
|
|
|
b';',
|
|
|
|
b'0' + ansi / 100,
|
|
|
|
b'0' + ansi / 10 % 10,
|
|
|
|
b'0' + ansi % 10,
|
|
|
|
b'm',
|
|
|
|
])
|
|
|
|
}
|
|
|
|
/// Set background color
|
|
|
|
fn bg_color(&mut self, color: Color) -> IoResult<usize> {
|
|
|
|
let ansi = color.to_ansi_val();
|
|
|
|
self.csi(&[
|
|
|
|
b'4',
|
|
|
|
b'8',
|
|
|
|
b';',
|
|
|
|
b'5',
|
|
|
|
b';',
|
|
|
|
b'0' + ansi / 100,
|
|
|
|
b'0' + ansi / 10 % 10,
|
|
|
|
b'0' + ansi % 10,
|
|
|
|
b'm',
|
|
|
|
])
|
|
|
|
}
|
2016-03-07 16:57:17 +00:00
|
|
|
/// Set rendition mode (SGR).
|
|
|
|
fn mode(&mut self, mode: Mode) -> IoResult<usize> {
|
|
|
|
self.rendition(mode as u8)
|
|
|
|
}
|
2016-03-07 15:01:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<W: Write> TermControl for W {
|
|
|
|
fn csi(&mut self, b: &[u8]) -> IoResult<usize> {
|
|
|
|
self.write(b"\x1b[").and_then(|x| {
|
|
|
|
self.write(b).map(|y| x + y)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
fn osc(&mut self, b: &[u8]) -> IoResult<usize> {
|
|
|
|
self.write(b"\x1b]").and_then(|x| {
|
|
|
|
self.write(b).map(|y| x + y)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
fn dsc(&mut self, b: &[u8]) -> IoResult<usize> {
|
|
|
|
self.write(b"\x1bP").and_then(|x| {
|
|
|
|
self.write(b).map(|y| x + y)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|