calc: Store history
This commit is contained in:
+64
-10
@@ -1,6 +1,9 @@
|
|||||||
use std::{
|
use std::{
|
||||||
cmp::{max, min, Ordering},
|
cmp::{max, min, Ordering},
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
env,
|
||||||
|
io::Write,
|
||||||
|
fs::{read_to_string, File},
|
||||||
default::Default,
|
default::Default,
|
||||||
process::{exit, Command},
|
process::{exit, Command},
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
@@ -419,18 +422,71 @@ impl InterfaceWidget for Shell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Calc {
|
struct Calc {
|
||||||
old: Vec<(String, String)>,
|
old: Arc<Mutex<Vec<(String, String)>>>,
|
||||||
result: Option<String>,
|
result: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Calc {
|
||||||
|
fn new() -> Calc {
|
||||||
|
let old: Arc<Mutex<Vec<(String, String)>>> = Arc::new(Mutex::new(Vec::new()));
|
||||||
|
let old_local = old.clone();
|
||||||
|
thread::Builder::new()
|
||||||
|
.name("calc".to_string())
|
||||||
|
.spawn(move || {
|
||||||
|
let home = env::var_os("HOME").unwrap().into_string().unwrap();
|
||||||
|
let s = match read_to_string(format!("{}/.cache/wldash/calc", home)) {
|
||||||
|
Ok(s) => s,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut old = old_local.lock().unwrap();
|
||||||
|
for line in s.lines() {
|
||||||
|
let pos = match line.find("=") {
|
||||||
|
Some(v) => v,
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
|
let (input, res) = line.split_at(pos);
|
||||||
|
let (input, res) = (input.trim(), res[1..].trim());
|
||||||
|
old.push((input.to_string(), res.to_string()));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Calc{
|
||||||
|
old,
|
||||||
|
result: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sync(&self) {
|
||||||
|
let home = env::var_os("HOME").unwrap().into_string().unwrap();
|
||||||
|
let mut f = match File::create(format!("{}/.cache/wldash/calc", home)) {
|
||||||
|
Ok(f) => f,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let old = self.old.lock().unwrap();
|
||||||
|
for (input, res) in old.iter() {
|
||||||
|
write!(f, "{}={}\n", input, res).unwrap();
|
||||||
|
}
|
||||||
|
f.sync_data().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl InterfaceWidget for Calc {
|
impl InterfaceWidget for Calc {
|
||||||
fn trigger(&mut self, intf: &mut InnerInterface) {
|
fn trigger(&mut self, intf: &mut InnerInterface) {
|
||||||
|
let mut old = self.old.lock().unwrap();
|
||||||
if intf.selection == 0 {
|
if intf.selection == 0 {
|
||||||
if let Some(res) = &self.result {
|
if let Some(res) = &self.result {
|
||||||
self.old.push((intf.prompt.input.to_string(), res.to_string()));
|
old.push((intf.prompt.input.to_string(), res.to_string()));
|
||||||
|
while old.len() > 32 {
|
||||||
|
old.remove(0);
|
||||||
|
}
|
||||||
|
drop(old);
|
||||||
|
self.sync();
|
||||||
}
|
}
|
||||||
} else if self.old.len() >= intf.selection {
|
} else if old.len() >= intf.selection {
|
||||||
let (input, res) = &self.old[self.old.len() - intf.selection];
|
let (input, res) = &old[old.len() - intf.selection];
|
||||||
self.result = Some(res.to_string());
|
self.result = Some(res.to_string());
|
||||||
intf.prompt.set(input);
|
intf.prompt.set(input);
|
||||||
intf.selection = 0;
|
intf.selection = 0;
|
||||||
@@ -454,6 +510,7 @@ impl InterfaceWidget for Calc {
|
|||||||
fonts: &mut FontMap,
|
fonts: &mut FontMap,
|
||||||
view: &mut BufferView,
|
view: &mut BufferView,
|
||||||
) -> Geometry {
|
) -> Geometry {
|
||||||
|
let old = self.old.lock().unwrap();
|
||||||
let fg = Color::WHITE;
|
let fg = Color::WHITE;
|
||||||
|
|
||||||
let line_height = intf.size.ceil() as u32;
|
let line_height = intf.size.ceil() as u32;
|
||||||
@@ -487,7 +544,7 @@ impl InterfaceWidget for Calc {
|
|||||||
font.auto_draw_text(&mut result_line, c, res).unwrap();
|
font.auto_draw_text(&mut result_line, c, res).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (idx, (input, res)) in self.old.iter().rev().enumerate() {
|
for (idx, (input, res)) in old.iter().rev().enumerate() {
|
||||||
if prompt_offset < line_height {
|
if prompt_offset < line_height {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -503,7 +560,7 @@ impl InterfaceWidget for Calc {
|
|||||||
|
|
||||||
let content_height = min(
|
let content_height = min(
|
||||||
intf.geometry.height,
|
intf.geometry.height,
|
||||||
(self.old.len() + 2) as u32 * line_height + 16,
|
(old.len() + 2) as u32 * line_height + 16,
|
||||||
);
|
);
|
||||||
Geometry {
|
Geometry {
|
||||||
x: intf.geometry.x,
|
x: intf.geometry.x,
|
||||||
@@ -540,10 +597,7 @@ impl Interface {
|
|||||||
Interface {
|
Interface {
|
||||||
launcher: Launcher::new(events),
|
launcher: Launcher::new(events),
|
||||||
shell: Shell {},
|
shell: Shell {},
|
||||||
calc: Calc {
|
calc: Calc::new(),
|
||||||
old: Vec::new(),
|
|
||||||
result: None,
|
|
||||||
},
|
|
||||||
inner: InnerInterface {
|
inner: InnerInterface {
|
||||||
font,
|
font,
|
||||||
size,
|
size,
|
||||||
|
|||||||
Reference in New Issue
Block a user