_rusted/
lib.rs

1#[macro_use] extern crate error_chain;
2#[macro_use] extern crate nom;
3#[macro_use] extern crate log;
4#[cfg(test)]
5#[macro_use] extern crate nom_test_helpers;
6
7use std::io::{self, Write};
8use std::default::Default;
9use std::collections::HashMap;
10use std::process;
11
12use errors::*;
13
14const DEFAULT_PROMPT: &'static str = "*";
15
16pub struct Config {
17    pub prompt: String,
18    pub dirty: bool,
19    pub show_prompt: bool,
20    pub current_index: Option<usize>,
21    pub default_filename: Option<String>,
22    pub cut_buffer: Vec<String>,
23    pub marks: HashMap<char, usize>,
24    pub last_error: Option<String>,
25    pub print_errors: bool,
26}
27
28impl Default for Config {
29    fn default() -> Config {
30        Config {
31            prompt: DEFAULT_PROMPT.into(),
32            dirty: false,
33            show_prompt: false,
34            current_index: None,
35            default_filename: None,
36            cut_buffer: vec![],
37            marks: HashMap::new(),
38            last_error: None,
39            print_errors: false,
40        }
41    }
42}
43
44impl Config {
45    pub fn update_curidx(&mut self, idx: usize) {
46        let loc = if let Some(v) = self.current_index.as_ref() {
47            *v + idx
48        } else {
49            idx
50        };
51        self.current_index = Some(loc);
52    }
53}
54
55pub type Buffer = Vec<String>;
56
57pub fn insert_all(buffer: &mut Buffer, index: usize, elements: &[String]) -> Result<()> {
58    for (idx, elem) in elements.into_iter().enumerate() {
59        buffer.insert(index + idx, elem.to_owned());
60    }
61    Ok(())
62}
63
64pub fn run(config: &mut Config) -> Result<()> {
65    let mut buffer = Buffer::new();
66    loop {
67        if config.show_prompt {
68            write!(&mut io::stdout(), "{}", config.prompt)
69                                .chain_err(|| "Couldn't write prompt")?;
70        }
71        io::stdout().flush().chain_err(|| "Couldn't flush stdout")?;
72        let mut inp = String::new();
73        io::stdin().read_line(&mut inp).chain_err(|| "Couldn't read input")?;
74        let inp = parse::parse_line(inp.trim());
75        let inp = match inp {
76            nom::IResult::Done(_, o) => o,
77            x => {
78                debug!("Not done, got {:?}", x);
79                continue;
80            },
81        };
82        debug!("Command: {:?}, current index: {:?}", &inp, config.current_index);
83        match inp.run(&mut buffer, config) {
84            Err(Error(ErrorKind::Unknown, _)) => {
85                println!("?");
86            },
87            Err(Error(ErrorKind::Msg(s), _)) => {
88                if config.print_errors {
89                    println!("{}", s);
90                } else {
91                    println!("?");
92                }
93                config.last_error = Some(s);
94            },
95            Err(_) => process::exit(1),
96            _ => (),
97        };
98    }
99}
100
101mod errors;
102mod parse;
103mod cli;
104mod commands;