term: Add new function .attr() to toggle terminal attributes
Also add .supports_attr() to test for attribute support without writing anything to output. Update .reset() to use sgr0 instead of op.
This commit is contained in:
parent
7d8a0fdb7d
commit
690495de03
@ -45,6 +45,54 @@ pub mod color {
|
||||
pub static BRIGHT_WHITE: Color = 15u16;
|
||||
}
|
||||
|
||||
pub mod attr {
|
||||
/// Terminal attributes for use with term.attr().
|
||||
/// Most attributes can only be turned on and must be turned off with term.reset().
|
||||
/// The ones that can be turned off explicitly take a boolean value.
|
||||
/// Color is also represented as an attribute for convenience.
|
||||
pub enum Attr {
|
||||
/// Bold (or possibly bright) mode
|
||||
Bold,
|
||||
/// Dim mode, also called faint or half-bright. Often not supported
|
||||
Dim,
|
||||
/// Italics mode. Often not supported
|
||||
Italic(bool),
|
||||
/// Underline mode
|
||||
Underline(bool),
|
||||
/// Blink mode
|
||||
Blink,
|
||||
/// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
|
||||
Standout(bool),
|
||||
/// Reverse mode, inverts the foreground and background colors
|
||||
Reverse,
|
||||
/// Secure mode, also called invis mode. Hides the printed text
|
||||
Secure,
|
||||
/// Convenience attribute to set the foreground color
|
||||
ForegroundColor(super::color::Color),
|
||||
/// Convenience attribute to set the background color
|
||||
BackgroundColor(super::color::Color)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "win32"))]
|
||||
priv 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::ForegroundColor(_) => "setaf",
|
||||
attr::BackgroundColor(_) => "setab"
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "win32"))]
|
||||
pub struct Terminal {
|
||||
num_colors: u16,
|
||||
@ -124,17 +172,64 @@ impl Terminal {
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Sets the given terminal attribute, if supported.
|
||||
/// Returns true if the attribute was supported, false otherwise.
|
||||
pub fn attr(&self, attr: attr::Attr) -> bool {
|
||||
match attr {
|
||||
attr::ForegroundColor(c) => self.fg(c),
|
||||
attr::BackgroundColor(c) => self.bg(c),
|
||||
_ => {
|
||||
let cap = cap_for_attr(attr);
|
||||
let parm = self.ti.strings.find_equiv(&cap);
|
||||
if parm.is_some() {
|
||||
let s = expand(*parm.unwrap(), [], &mut Variables::new());
|
||||
if s.is_ok() {
|
||||
self.out.write(s.unwrap());
|
||||
return true
|
||||
} else {
|
||||
warn!("%s", s.unwrap_err());
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether the given terminal attribute is supported.
|
||||
pub fn supports_attr(&self, attr: attr::Attr) -> bool {
|
||||
match attr {
|
||||
attr::ForegroundColor(_) | attr::BackgroundColor(_) => {
|
||||
self.num_colors > 0
|
||||
}
|
||||
_ => {
|
||||
let cap = cap_for_attr(attr);
|
||||
self.ti.strings.find_equiv(&cap).is_some()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Resets all terminal attributes and color to the default.
|
||||
pub fn reset(&self) {
|
||||
let mut vars = Variables::new();
|
||||
let s = do self.ti.strings.find_equiv(&("op"))
|
||||
.map_consume_default(Err(~"can't find terminfo capability `op`")) |op| {
|
||||
expand(copy *op, [], &mut vars)
|
||||
};
|
||||
let mut cap = self.ti.strings.find_equiv(&("sgr0"));
|
||||
if cap.is_none() {
|
||||
// are there any terminals that have color/attrs and not sgr0?
|
||||
// Try falling back to sgr, then op
|
||||
cap = self.ti.strings.find_equiv(&("sgr"));
|
||||
if cap.is_none() {
|
||||
cap = self.ti.strings.find_equiv(&("op"));
|
||||
}
|
||||
}
|
||||
let s = do cap.map_consume_default(Err(~"can't find terminfo capability `sgr0`")) |op| {
|
||||
expand(*op, [], &mut Variables::new())
|
||||
};
|
||||
if s.is_ok() {
|
||||
self.out.write(s.unwrap());
|
||||
} else if self.num_colors > 0 {
|
||||
warn!("%s", s.unwrap_err());
|
||||
} else {
|
||||
// if we support attributes but not color, it would be nice to still warn!()
|
||||
// but it's not worth testing all known attributes just for this.
|
||||
debug!("%s", s.unwrap_err());
|
||||
}
|
||||
}
|
||||
@ -160,6 +255,14 @@ impl Terminal {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn attr(&self, _attr: attr::Attr) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn supports_attr(&self, _attr: attr::Attr) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn reset(&self) {
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user