Basic file loading/saving.

This commit is contained in:
Nathan Vegdahl 2014-12-19 22:43:31 -08:00
parent fec361ad29
commit a31a0a2c41
2 changed files with 120 additions and 41 deletions

34
src/files.rs Normal file
View File

@ -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<TextBuffer> {
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(());
}

View File

@ -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;