diff options
-rw-r--r-- | src/main.rs | 95 |
1 files changed, 84 insertions, 11 deletions
diff --git a/src/main.rs b/src/main.rs index ffdb690..a8fbcf2 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | // std | 7 | // std |
8 | use std::f64; | 8 | use std::f64; |
9 | use std::borrow::Cow::{self, Borrowed, Owned}; | ||
9 | 10 | ||
10 | // modules | 11 | // modules |
11 | mod lex; | 12 | mod lex; |
@@ -19,14 +20,80 @@ use crate::format::*; | |||
19 | 20 | ||
20 | // extern crates | 21 | // extern crates |
21 | use rustyline::error::ReadlineError; | 22 | use rustyline::error::ReadlineError; |
22 | use rustyline::Editor; | 23 | use rustyline::{ Editor, Context, Helper }; |
23 | use rustyline::config::{ Builder, ColorMode, EditMode, CompletionType }; | 24 | use rustyline::config::{ Builder, ColorMode, EditMode, CompletionType }; |
25 | use rustyline::hint::Hinter; | ||
26 | use rustyline::completion::{ FilenameCompleter, Completer, Pair }; | ||
24 | use rustyline::highlight::{ Highlighter, MatchingBracketHighlighter }; | 27 | use rustyline::highlight::{ Highlighter, MatchingBracketHighlighter }; |
25 | use rustyline::hint::{ Hinter, HistoryHinter }; | 28 | |
26 | use clap::{Arg, App}; | 29 | use clap::{Arg, App}; |
27 | use lazy_static::lazy_static; | 30 | use lazy_static::lazy_static; |
28 | 31 | ||
29 | struct LineHelper (MatchingBracketHighlighter, HistoryHinter); | 32 | |
33 | struct RLHelper { | ||
34 | completer: FilenameCompleter, | ||
35 | highlighter: LineHighlighter, | ||
36 | hinter: AnswerHinter, | ||
37 | } | ||
38 | |||
39 | struct AnswerHinter { } | ||
40 | impl Hinter for AnswerHinter { | ||
41 | fn hint(&self, line: &str, _: usize, _: &Context) -> Option<String> { | ||
42 | let input = line.trim(); | ||
43 | let input = input.replace(" ", ""); | ||
44 | if input.len() == 0 { | ||
45 | return Some("".into()) | ||
46 | } | ||
47 | let dry_run = eval_math_expression(&input); | ||
48 | match dry_run { | ||
49 | Ok(ans) => return Some(format!(" = {}", ans)), | ||
50 | Err(_) => return Some(format!("")) | ||
51 | }; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | struct LineHighlighter { } | ||
56 | impl Highlighter for LineHighlighter { | ||
57 | fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> { | ||
58 | Owned(format!("\x1b[90m{}\x1b[0m", hint)) | ||
59 | } | ||
60 | fn highlight<'l>(&self, line: &'l str, _: usize) -> Cow<'l, str> { | ||
61 | let op = eval_math_expression(line); | ||
62 | match op { | ||
63 | Ok(_) => Owned(line.into()), | ||
64 | Err(_) => Owned(format!("\x1b[31m{}\x1b[0m", line)) | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
69 | impl Highlighter for RLHelper { | ||
70 | fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> { | ||
71 | self.highlighter.highlight_hint(hint) | ||
72 | } | ||
73 | fn highlight<'l>(&self, line: &'l str, pos: usize) -> Cow<'l, str> { | ||
74 | self.highlighter.highlight(line, pos) | ||
75 | } | ||
76 | } | ||
77 | |||
78 | impl Completer for RLHelper { | ||
79 | type Candidate = Pair; | ||
80 | fn complete( | ||
81 | &self, | ||
82 | line: &str, | ||
83 | pos: usize, | ||
84 | ctx: &Context<'_>, | ||
85 | ) -> Result<(usize, Vec<Pair>), ReadlineError> { | ||
86 | self.completer.complete(line, pos, ctx) | ||
87 | } | ||
88 | } | ||
89 | |||
90 | impl Hinter for RLHelper { | ||
91 | fn hint(&self, line: &str, a: usize, b: &Context) -> Option<String> { | ||
92 | self.hinter.hint(line, a, b) | ||
93 | } | ||
94 | } | ||
95 | |||
96 | impl Helper for RLHelper {} | ||
30 | 97 | ||
31 | struct Configuration { | 98 | struct Configuration { |
32 | radian_mode: bool, | 99 | radian_mode: bool, |
@@ -57,10 +124,16 @@ fn main() { | |||
57 | .completion_type(CompletionType::Circular) | 124 | .completion_type(CompletionType::Circular) |
58 | .max_history_size(1000) | 125 | .max_history_size(1000) |
59 | .build(); | 126 | .build(); |
60 | let mut rl = Editor::<()>::with_config(config); | 127 | let mut rl = Editor::with_config(config); |
128 | let h = RLHelper { | ||
129 | completer: FilenameCompleter::new(), | ||
130 | highlighter: LineHighlighter {}, | ||
131 | hinter: AnswerHinter {} | ||
132 | }; | ||
133 | rl.set_helper(Some(h)); | ||
61 | if rl.load_history("history.txt").is_err() { | 134 | if rl.load_history("history.txt").is_err() { |
62 | println!("No previous history."); | 135 | println!("No previous history.") |
63 | } | 136 | }; |
64 | 137 | ||
65 | loop { | 138 | loop { |
66 | let readline = rl.readline("> "); | 139 | let readline = rl.readline("> "); |
@@ -127,11 +200,11 @@ fn parse_arguments() -> Configuration { | |||
127 | .unwrap_or("10") | 200 | .unwrap_or("10") |
128 | .parse() | 201 | .parse() |
129 | .unwrap(), | 202 | .unwrap(), |
130 | base: config.value_of("base") | 203 | base: config.value_of("base") |
131 | .unwrap_or("10") | 204 | .unwrap_or("10") |
132 | .parse() | 205 | .parse() |
133 | .unwrap(), | 206 | .unwrap(), |
134 | input, | 207 | input, |
135 | } | 208 | } |
136 | } | 209 | } |
137 | 210 | ||