From a31a0a2c41424db01d268fb06eab4e6e6dc76feb Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Fri, 19 Dec 2014 22:43:31 -0800 Subject: [PATCH] Basic file loading/saving. --- src/files.rs | 34 ++++++++++++++ src/main.rs | 127 ++++++++++++++++++++++++++++++++++----------------- 2 files changed, 120 insertions(+), 41 deletions(-) create mode 100644 src/files.rs diff --git a/src/files.rs b/src/files.rs new file mode 100644 index 0000000..8889a33 --- /dev/null +++ b/src/files.rs @@ -0,0 +1,34 @@ +use std::io::{IoResult, BufferedReader, BufferedWriter}; +use std::io::fs::File; +use std::path::Path; + +use buffer::TextBuffer; + +pub fn load_file_to_buffer(path: &Path) -> IoResult { + let mut tb = TextBuffer::new(); + let mut f = BufferedReader::new(try!(File::open(path))); + + loop { + let line = f.read_line(); + if let Ok(ref s) = line { + let tbl = tb.len(); + tb.insert_text(s.as_slice(), tbl); + } + else { + break; + } + } + + return Ok(tb); +} + +pub fn save_buffer_to_file(tb: &TextBuffer, path: &Path) -> IoResult<()> { + let mut iter = tb.root_iter(); + let mut f = BufferedWriter::new(try!(File::create(path))); + + for c in iter { + f.write_char(c); + } + + return Ok(()); +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index f6ca8d1..f2c5e66 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,11 +4,14 @@ extern crate serialize; use std::char; +use std::path::Path; use docopt::Docopt; use buffer::TextBuffer; use rustbox::{Style,Color}; +use files::{load_file_to_buffer, save_buffer_to_file}; mod buffer; +mod files; // Usage documentation string @@ -29,6 +32,21 @@ Options: } +// Key codes +const K_ENTER: u16 = 13; +const K_TAB: u16 = 9; +const K_SPACE: u16 = 32; +const K_BACKSPACE: u16 = 127; +//const K_DOWN: u16 = 65516; +//const K_LEFT: u16 = 65515; +//const K_RIGHT: u16 = 65514; +//const K_UP: u16 = 65517; +const K_ESC: u16 = 27; +const K_CTRL_Q: u16 = 17; +const K_CTRL_S: u16 = 19; + + + fn main() { // Get command-line arguments let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit()); @@ -38,51 +56,18 @@ fn main() { let mut width = rustbox::width(); let mut height = rustbox::height(); - - let mut tb = TextBuffer::new(); + + // Load file, if specified + let mut tb = if let Option::Some(s) = args.arg_file { + load_file_to_buffer(&Path::new(s.as_slice())).unwrap() + } + else { + TextBuffer::new() + }; rustbox::init(); loop { - // Handle events. We block on the first event, so that the - // program doesn't loop like crazy, but then continue pulling - // events in a non-blocking way until we run out of events - // to handle. - let mut e = rustbox::poll_event(); // Block until we get an event - loop { - match e { - rustbox::Event::KeyEvent(modifier, key, character) => { - // Return - if key == 13 { - let p = tb.len(); - tb.insert_text("\n", p); - } - // Esc - else if key == 27 { - quit = true; - break; - } - // Some key - else if let Option::Some(c) = char::from_u32(character) { - let p = tb.len(); - tb.insert_text(c.to_string().as_slice(), p); - } - }, - - rustbox::Event::ResizeEvent(w, h) => { - width = w as uint; - height = h as uint; - } - - _ => { - break; - } - } - - e = rustbox::peek_event(0); // Get next event (if any) - } - - // Draw the text buffer to screen rustbox::clear(); { @@ -118,6 +103,66 @@ fn main() { rustbox::present(); + // Handle events. We block on the first event, so that the + // program doesn't loop like crazy, but then continue pulling + // events in a non-blocking way until we run out of events + // to handle. + let mut e = rustbox::poll_event(); // Block until we get an event + loop { + match e { + rustbox::Event::KeyEvent(modifier, key, character) => { + //println!(" {} {} {}", modifier, key, character); + match key { + K_CTRL_Q | K_ESC => { + quit = true; + break; + }, + + K_CTRL_S => { + save_buffer_to_file(&tb, &Path::new("untitled.txt")); + }, + + K_ENTER => { + let p = tb.len(); + tb.insert_text("\n", p); + }, + + K_SPACE => { + let p = tb.len(); + tb.insert_text(" ", p); + }, + + K_TAB => { + let p = tb.len(); + tb.insert_text("\t", p); + }, + + // Character + 0 => { + if let Option::Some(c) = char::from_u32(character) { + let p = tb.len(); + tb.insert_text(c.to_string().as_slice(), p); + } + }, + + _ => {} + } + }, + + rustbox::Event::ResizeEvent(w, h) => { + width = w as uint; + height = h as uint; + } + + _ => { + break; + } + } + + e = rustbox::peek_event(0); // Get next event (if any) + } + + // Quit if quit flag is set if quit { break;