aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2013-04-05 00:51:54 -0500
committerJesse Luehrs <doy@tozt.net>2013-04-05 00:51:54 -0500
commit33d773ff5a8154bb18c93c48b5a4607f2882bcdf (patch)
tree149f0774ba7aab6c9c2e4199bd4cb509cbba3bc1
parentfe705e95db0fda3dc5b753cac8bda94b21f2a5e0 (diff)
downloadrust-term-33d773ff5a8154bb18c93c48b5a4607f2882bcdf.tar.gz
rust-term-33d773ff5a8154bb18c93c48b5a4607f2882bcdf.zip
handle optional terminal capabilities slightly better
-rw-r--r--src/hexes.rs25
-rw-r--r--src/info.rs65
-rw-r--r--test/tput.rs6
3 files changed, 73 insertions, 23 deletions
diff --git a/src/hexes.rs b/src/hexes.rs
index b1fed14..4de2f12 100644
--- a/src/hexes.rs
+++ b/src/hexes.rs
@@ -39,10 +39,15 @@ pub fn Term () -> Term {
cbreak();
echo(false);
- print(info::keypad_xmit());
- print(info::enter_ca_mode());
- print(info::exit_attribute_mode());
- print(info::cursor_normal());
+ // XXX need to come up with a better way to handle optional caps
+ // should be able to use something like has_keypad_xmit or something
+ for ["smkx", "smcup", "sgr0", "cnorm"].each() |&cap| {
+ match info::escape(cap) {
+ Some(e) => print(e),
+ None => (), // not a big deal if these don't exist
+ }
+ }
+
print(info::clear_screen());
Term { r: Reader(), w: Writer() }
@@ -162,10 +167,14 @@ impl Term {
impl Drop for Term {
fn finalize (&self) {
- print(info::keypad_local());
- print(info::exit_ca_mode());
- print(info::exit_attribute_mode());
- print(info::cursor_normal());
+ // XXX need to come up with a better way to handle optional caps
+ // should be able to use something like has_keypad_xmit or something
+ for ["rmkx", "rmcup", "sgr0", "cnorm"].each() |&cap| {
+ match info::escape(cap) {
+ Some(e) => print(e),
+ None => (), // not a big deal if these don't exist
+ }
+ }
// XXX should really restore the previous termios mode...
cooked();
diff --git a/src/info.rs b/src/info.rs
index 5504de1..e4aa546 100644
--- a/src/info.rs
+++ b/src/info.rs
@@ -26,14 +26,33 @@ pub fn init () {
macro_rules! def_escape(
($name:ident -> $escape:expr) => (
- pub fn $name () -> ~str { escape($escape) }
+ pub fn $name () -> ~str {
+ let attr = $escape;
+ match escape(attr) {
+ Some(e) => e,
+ None => fail!(fmt!("%s is not supported on this terminal",
+ attr)),
+ }
+ }
);
($name:ident -> $escape:expr, $ty1:ident) => (
- pub fn $name (p1: $ty1) -> ~str { escape1($escape, p1 as int) }
+ pub fn $name (p1: $ty1) -> ~str {
+ let attr = $escape;
+ match escape1(attr, p1 as int) {
+ Some(e) => e,
+ None => fail!(fmt!("%s is not supported on this terminal",
+ attr)),
+ }
+ }
);
($name:ident -> $escape:expr, $ty1:ident, $ty2:ident) => (
pub fn $name (p1: $ty1, p2: $ty2) -> ~str {
- escape2($escape, p1 as int, p2 as int)
+ let attr = $escape;
+ match escape2(attr, p1 as int, p2 as int) {
+ Some(e) => e,
+ None => fail!(fmt!("%s is not supported on this terminal",
+ attr)),
+ }
}
);
)
@@ -131,14 +150,24 @@ def_escape!(key_f12 -> "kf12")
/// The terminal escape generated by the F<`n`> key.
pub fn key_f (n: uint) -> ~str {
- escape(fmt!("kf%?", n))
+ let attr = fmt!("kf%?", n);
+ match escape(attr) {
+ Some(e) => e,
+ None => fail!(fmt!("%s is not supported on this terminal", attr)),
+ }
}
/// The terminal escape corresponding to the `name` terminfo capability.
-pub fn escape (name: &str) -> ~str {
+pub fn escape (name: &str) -> Option<~str> {
do str::as_c_str(name) |c_name| {
unsafe {
- str::raw::from_c_str(tigetstr(c_name))
+ let e = tigetstr(c_name);
+ if e == ptr::null() {
+ None
+ }
+ else {
+ Some(str::raw::from_c_str(e))
+ }
}
}
}
@@ -148,10 +177,16 @@ pub fn escape (name: &str) -> ~str {
*
* This capability must take one parameter, which should be passed as `p1`.
*/
-pub fn escape1 (name: &str, p1: int) -> ~str {
+pub fn escape1 (name: &str, p1: int) -> Option<~str> {
do str::as_c_str(name) |c_name| {
unsafe {
- str::raw::from_c_str(tiparm1(tigetstr(c_name), p1))
+ let e = tigetstr(c_name);
+ if e == ptr::null() {
+ None
+ }
+ else {
+ Some(str::raw::from_c_str(tiparm1(e, p1)))
+ }
}
}
}
@@ -162,10 +197,16 @@ pub fn escape1 (name: &str, p1: int) -> ~str {
* This capability must take two parameters, which should be passed as `p1`
* and `p2`.
*/
-pub fn escape2 (name: &str, p1: int, p2: int) -> ~str {
+pub fn escape2 (name: &str, p1: int, p2: int) -> Option<~str> {
do str::as_c_str(name) |c_name| {
unsafe {
- str::raw::from_c_str(tiparm2(tigetstr(c_name), p1, p2))
+ let e = tigetstr(c_name);
+ if e == ptr::null() {
+ None
+ }
+ else {
+ Some(str::raw::from_c_str(tiparm2(e, p1, p2)))
+ }
}
}
}
@@ -176,10 +217,6 @@ unsafe fn tigetstr (name: *c_char) -> *c_char {
fail!(fmt!("%s is not a terminal capability",
unsafe { str::raw::from_c_str(name) }));
}
- else if c_out == ptr::null() {
- fail!(fmt!("The current terminal doesn't support %s",
- unsafe { str::raw::from_c_str(name) }));
- }
c_out
}
diff --git a/test/tput.rs b/test/tput.rs
index b2cfc59..3fe9ea1 100644
--- a/test/tput.rs
+++ b/test/tput.rs
@@ -6,5 +6,9 @@ fn main () {
}
term::info::init();
- print(term::info::escape(os::args()[1]));
+ let attr: &str = os::args()[1];
+ let escape = term::info::escape(attr).expect(
+ fmt!("%s is not supported on this terminal", attr)
+ );
+ print(escape);
}