diff options
author | Jesse Luehrs <doy@tozt.net> | 2013-03-21 01:14:23 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2013-03-21 01:14:23 -0500 |
commit | 50db2cec5f96d2f26ab5363a1beb870ed6482abc (patch) | |
tree | 3e3668fcdf96ead4e06dbf176b6b2a17bd5175de | |
parent | 0896e60afd21c9c6724fb06c6328bb890c4f911d (diff) | |
download | rust-term-50db2cec5f96d2f26ab5363a1beb870ed6482abc.tar.gz rust-term-50db2cec5f96d2f26ab5363a1beb870ed6482abc.zip |
turn this into an object
-rw-r--r-- | src/info.rs | 44 | ||||
-rw-r--r-- | src/term.rs | 58 | ||||
-rw-r--r-- | test/rl.rs | 41 |
3 files changed, 84 insertions, 59 deletions
diff --git a/src/info.rs b/src/info.rs index d785d1c..b4a5d60 100644 --- a/src/info.rs +++ b/src/info.rs @@ -1,55 +1,23 @@ use core::libc::{c_char,c_int}; -use util::guard; pub fn init () { unsafe { c::setupterm(ptr::null(), 1, ptr::null()) }; } -pub fn clear () { - write_escape("clear"); -} - -pub fn move (col: uint, row: uint) { - if col == 0u && row == 0u { - write_escape("home"); - } - else { - write_escape2("cup", row as int, col as int); - } -} - -pub fn cursor (enabled: bool) { - if enabled { - write_escape("civis"); - } - else { - write_escape("cnorm"); - } -} - -pub fn with_alternate_screen<T> (body: &fn () -> T) -> T { - do guard(|| { write_escape("rmcup") }) { - write_escape("smcup"); - body() - } -} - -fn write_escape (name: &str) { - let output = do str::as_c_str(name) |c_name| { +pub fn escape (name: &str) -> ~str { + do str::as_c_str(name) |c_name| { unsafe { str::raw::from_c_str(tigetstr(c_name)) } - }; - io::print(output); + } } -fn write_escape2 (name: &str, p1: int, p2: int) { - let output = do str::as_c_str(name) |c_name| { +pub fn escape2 (name: &str, p1: int, p2: int) -> ~str { + do str::as_c_str(name) |c_name| { unsafe { str::raw::from_c_str(tiparm2(tigetstr(c_name), p1, p2)) } - }; - io::print(output); + } } unsafe fn tigetstr (name: *c_char) -> *c_char { diff --git a/src/term.rs b/src/term.rs index a2cd24f..faceb12 100644 --- a/src/term.rs +++ b/src/term.rs @@ -3,6 +3,64 @@ #[crate_type = "lib"]; pub use ios::{cooked,cbreak,raw,echo,size,isatty}; +use info::{init,escape,escape2}; + +struct Writer { + priv cleanup: bool, + priv alternate: bool, +} + +pub fn Writer (cleanup: bool) -> Writer { + init(); + Writer { cleanup: cleanup, alternate: false } +} + +impl Writer { + pub fn clear (&self) { + io::print(escape("clear")); + } + + pub fn move (&self, col: uint, row: uint) { + if col == 0u && row == 0u { + io::print(escape("home")); + } + else { + io::print(escape2("cup", row as int, col as int)); + } + } + + pub fn cursor (&self, enabled: bool) { + if enabled { + io::print(escape("civis")); + } + else { + io::print(escape("cnorm")); + } + } + + pub fn alternate_screen (&mut self, enable: bool) { + if enable { + io::print(escape("smcup")); + self.alternate = true; + } + else { + io::print(escape("rmcup")); + self.alternate = false; + } + } +} + +impl Drop for Writer { + fn finalize (&self) { + if self.cleanup { + if self.alternate { + io::print(escape("rmcup")); + } + io::print(escape("sgr0")); + io::print(escape("cnorm")); + } + } +} pub mod ios; pub mod info; @@ -1,54 +1,53 @@ extern mod term; use core::io::ReaderUtil; -fn term_app (body: &fn ()) { - term::info::init(); +fn term_app (body: &fn (w: &mut term::Writer)) { + let mut writer = term::Writer(true); do term::ios::preserve { - do term::info::with_alternate_screen { - body() - } + writer.alternate_screen(true); + body(&mut writer); } } -fn draw_map (rows: uint, cols: uint) { +fn draw_map (w: &term::Writer, rows: uint, cols: uint) { for uint::range(0, rows) |i| { - term::info::move(0, i); + w.move(0, i); io::print(str::repeat(".", cols)); } } -fn draw_character (x: uint, y: uint) { - term::info::move(x, y); +fn draw_character (w: &term::Writer, x: uint, y: uint) { + w.move(x, y); io::print("@"); - term::info::move(x, y); + w.move(x, y); } -fn draw_ground (x: uint, y: uint) { - term::info::move(x, y); +fn draw_ground (w: &term::Writer, x: uint, y: uint) { + w.move(x, y); io::print("."); } fn main () { let (cols, rows) = term::size(); - do term_app { + do term_app |w| { term::cbreak(); term::echo(false); - term::info::clear(); + w.clear(); - draw_map(rows, cols); + draw_map(w, rows, cols); let mut (x, y) = (0u, 0u); let mut cursor = true; loop { - draw_character(x, y); + draw_character(w, x, y); match io::stdin().read_char() { 'q' => { break } - 'h' if x > 0 => { draw_ground(x, y); x -= 1 } - 'j' if y < rows - 1 => { draw_ground(x, y); y += 1 } - 'k' if y > 0 => { draw_ground(x, y); y -= 1 } - 'l' if x < cols - 1 => { draw_ground(x, y); x += 1 } - ' ' => { term::info::cursor(cursor); cursor = !cursor } + 'h' if x > 0 => { draw_ground(w, x, y); x -= 1 } + 'j' if y < rows - 1 => { draw_ground(w, x, y); y += 1 } + 'k' if y > 0 => { draw_ground(w, x, y); y -= 1 } + 'l' if x < cols - 1 => { draw_ground(w, x, y); x += 1 } + ' ' => { w.cursor(cursor); cursor = !cursor } _ => { } } } |