Skip to content
59 changes: 24 additions & 35 deletions src/libterm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@
#![feature(vec_push_all)]
#![cfg_attr(windows, feature(libc))]

#[macro_use] extern crate log;
#[macro_use]
extern crate log;

pub use terminfo::TerminfoTerminal;
#[cfg(windows)]
Expand Down Expand Up @@ -100,25 +101,19 @@ impl Write for WriterWrapper {
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
/// opened.
pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
TerminfoTerminal::new(WriterWrapper {
wrapped: box std::io::stdout(),
})
TerminfoTerminal::new(WriterWrapper { wrapped: box std::io::stdout() })
}

#[cfg(windows)]
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
/// opened.
pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
let ti = TerminfoTerminal::new(WriterWrapper {
wrapped: box std::io::stdout(),
});
let ti = TerminfoTerminal::new(WriterWrapper { wrapped: box std::io::stdout() });

match ti {
Some(t) => Some(t),
None => {
WinConsole::new(WriterWrapper {
wrapped: box std::io::stdout(),
})
WinConsole::new(WriterWrapper { wrapped: box std::io::stdout() })
}
}
}
Expand All @@ -127,25 +122,19 @@ pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
/// opened.
pub fn stderr() -> Option<Box<Terminal<WriterWrapper> + Send>> {
TerminfoTerminal::new(WriterWrapper {
wrapped: box std::io::stderr(),
})
TerminfoTerminal::new(WriterWrapper { wrapped: box std::io::stderr() })
}

#[cfg(windows)]
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
/// opened.
pub fn stderr() -> Option<Box<Terminal<WriterWrapper> + Send>> {
let ti = TerminfoTerminal::new(WriterWrapper {
wrapped: box std::io::stderr(),
});
let ti = TerminfoTerminal::new(WriterWrapper { wrapped: box std::io::stderr() });

match ti {
Some(t) => Some(t),
None => {
WinConsole::new(WriterWrapper {
wrapped: box std::io::stderr(),
})
WinConsole::new(WriterWrapper { wrapped: box std::io::stderr() })
}
}
}
Expand All @@ -157,23 +146,23 @@ pub mod color {
/// Number for a terminal color
pub type Color = u16;

pub const BLACK: Color = 0;
pub const RED: Color = 1;
pub const GREEN: Color = 2;
pub const YELLOW: Color = 3;
pub const BLUE: Color = 4;
pub const BLACK: Color = 0;
pub const RED: Color = 1;
pub const GREEN: Color = 2;
pub const YELLOW: Color = 3;
pub const BLUE: Color = 4;
pub const MAGENTA: Color = 5;
pub const CYAN: Color = 6;
pub const WHITE: Color = 7;

pub const BRIGHT_BLACK: Color = 8;
pub const BRIGHT_RED: Color = 9;
pub const BRIGHT_GREEN: Color = 10;
pub const BRIGHT_YELLOW: Color = 11;
pub const BRIGHT_BLUE: Color = 12;
pub const CYAN: Color = 6;
pub const WHITE: Color = 7;

pub const BRIGHT_BLACK: Color = 8;
pub const BRIGHT_RED: Color = 9;
pub const BRIGHT_GREEN: Color = 10;
pub const BRIGHT_YELLOW: Color = 11;
pub const BRIGHT_BLUE: Color = 12;
pub const BRIGHT_MAGENTA: Color = 13;
pub const BRIGHT_CYAN: Color = 14;
pub const BRIGHT_WHITE: Color = 15;
pub const BRIGHT_CYAN: Color = 14;
pub const BRIGHT_WHITE: Color = 15;
}

/// Terminal attributes
Expand Down Expand Up @@ -206,7 +195,7 @@ pub mod attr {
/// Convenience attribute to set the foreground color
ForegroundColor(super::color::Color),
/// Convenience attribute to set the background color
BackgroundColor(super::color::Color)
BackgroundColor(super::color::Color),
}
}

Expand Down
100 changes: 54 additions & 46 deletions src/libterm/terminfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ use self::parm::{expand, Number, Variables};
#[derive(Debug)]
pub struct TermInfo {
/// Names for the terminal
pub names: Vec<String> ,
pub names: Vec<String>,
/// Map of capability name to boolean value
pub bools: HashMap<String, bool>,
/// Map of capability name to numeric value
pub numbers: HashMap<String, u16>,
/// Map of capability name to raw (unexpanded) string
pub strings: HashMap<String, Vec<u8> >
pub strings: HashMap<String, Vec<u8>>,
}

pub mod searcher;
Expand All @@ -49,19 +49,19 @@ pub mod parm;

fn cap_for_attr(attr: attr::Attr) -> &'static str {
match attr {
attr::Bold => "bold",
attr::Dim => "dim",
attr::Italic(true) => "sitm",
attr::Italic(false) => "ritm",
attr::Underline(true) => "smul",
attr::Underline(false) => "rmul",
attr::Blink => "blink",
attr::Standout(true) => "smso",
attr::Standout(false) => "rmso",
attr::Reverse => "rev",
attr::Secure => "invis",
attr::Bold => "bold",
attr::Dim => "dim",
attr::Italic(true) => "sitm",
attr::Italic(false) => "ritm",
attr::Underline(true) => "smul",
attr::Underline(false) => "rmul",
attr::Blink => "blink",
attr::Standout(true) => "smso",
attr::Standout(false) => "rmso",
attr::Reverse => "rev",
attr::Secure => "invis",
attr::ForegroundColor(_) => "setaf",
attr::BackgroundColor(_) => "setab"
attr::BackgroundColor(_) => "setab",
}
}

Expand All @@ -70,7 +70,7 @@ fn cap_for_attr(attr: attr::Attr) -> &'static str {
pub struct TerminfoTerminal<T> {
num_colors: u16,
out: T,
ti: Box<TermInfo>
ti: Box<TermInfo>,
}

impl<T: Write+Send+'static> Terminal<T> for TerminfoTerminal<T> {
Expand All @@ -80,12 +80,12 @@ impl<T: Write+Send+'static> Terminal<T> for TerminfoTerminal<T> {
let s = expand(self.ti
.strings
.get("setaf")
.unwrap()
,
&[Number(color as isize)], &mut Variables::new());
.unwrap(),
&[Number(color as isize)],
&mut Variables::new());
if s.is_ok() {
try!(self.out.write_all(&s.unwrap()));
return Ok(true)
return Ok(true);
}
}
Ok(false)
Expand All @@ -97,12 +97,12 @@ impl<T: Write+Send+'static> Terminal<T> for TerminfoTerminal<T> {
let s = expand(self.ti
.strings
.get("setab")
.unwrap()
,
&[Number(color as isize)], &mut Variables::new());
.unwrap(),
&[Number(color as isize)],
&mut Variables::new());
if s.is_ok() {
try!(self.out.write_all(&s.unwrap()));
return Ok(true)
return Ok(true);
}
}
Ok(false)
Expand All @@ -116,12 +116,10 @@ impl<T: Write+Send+'static> Terminal<T> for TerminfoTerminal<T> {
let cap = cap_for_attr(attr);
let parm = self.ti.strings.get(cap);
if parm.is_some() {
let s = expand(parm.unwrap(),
&[],
&mut Variables::new());
let s = expand(parm.unwrap(), &[], &mut Variables::new());
if s.is_ok() {
try!(self.out.write_all(&s.unwrap()));
return Ok(true)
return Ok(true);
}
}
Ok(false)
Expand Down Expand Up @@ -151,22 +149,27 @@ impl<T: Write+Send+'static> Terminal<T> for TerminfoTerminal<T> {
cap = self.ti.strings.get("op");
}
}
let s = cap.map_or(Err("can't find terminfo capability `sgr0`".to_owned()), |op| {
expand(op, &[], &mut Variables::new())
});
let s = cap.map_or(Err("can't find terminfo capability `sgr0`".to_owned()),
|op| expand(op, &[], &mut Variables::new()));
if s.is_ok() {
return self.out.write_all(&s.unwrap())
return self.out.write_all(&s.unwrap());
}
Ok(())
}

fn get_ref<'a>(&'a self) -> &'a T { &self.out }
fn get_ref<'a>(&'a self) -> &'a T {
&self.out
}

fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.out }
fn get_mut<'a>(&'a mut self) -> &'a mut T {
&mut self.out
}
}

impl<T: Write+Send+'static> UnwrappableTerminal<T> for TerminfoTerminal<T> {
fn unwrap(self) -> T { self.out }
fn unwrap(self) -> T {
self.out
}
}

impl<T: Write+Send+'static> TerminfoTerminal<T> {
Expand All @@ -186,16 +189,16 @@ impl<T: Write+Send+'static> TerminfoTerminal<T> {
Err(err) => return match env::var("MSYSCON") {
Ok(ref val) if &val[..] == "mintty.exe" => {
// msys terminal
Some(box TerminfoTerminal{
Some(box TerminfoTerminal {
out: out,
ti: msys_terminfo(),
num_colors: 8,
})
},
}
_ => {
debug!("error finding terminfo entry: {:?}", err);
None
},
}
},
};

Expand All @@ -206,20 +209,25 @@ impl<T: Write+Send+'static> TerminfoTerminal<T> {
}

let inf = ti.unwrap();
let nc = if inf.strings.get("setaf").is_some()
&& inf.strings.get("setab").is_some() {
inf.numbers.get("colors").map_or(0, |&n| n)
} else { 0 };

Some(box TerminfoTerminal {out: out,
ti: inf,
num_colors: nc})
let nc = if inf.strings.get("setaf").is_some() && inf.strings.get("setab").is_some() {
inf.numbers.get("colors").map_or(0, |&n| n)
} else {
0
};

Some(box TerminfoTerminal {
out: out,
ti: inf,
num_colors: nc,
})
}

fn dim_if_necessary(&self, color: color::Color) -> color::Color {
if color >= self.num_colors && color >= 8 && color < 16 {
color-8
} else { color }
} else {
color
}
}
}

Expand Down
Loading