diff --git a/Cargo.lock b/Cargo.lock index 60c479f..8fdb320 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -119,6 +119,11 @@ dependencies = [ "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "libivy" +version = "0.1.0" +source = "git+https://github.com/kennylevinsen/libivy.git#f0c58a9ee57fa42a79b05e73021ccc91311aa690" + [[package]] name = "libloading" version = "0.5.2" @@ -414,6 +419,7 @@ dependencies = [ "dbus 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "fuzzy-matcher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libivy 0.1.0 (git+https://github.com/kennylevinsen/libivy.git)", "libpulse-binding 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -452,6 +458,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb" "checksum libdbus-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "69382cb3be797cfe62ba89ac5e594a0e3022914ff44867ffbcfc03daa24eebd7" +"checksum libivy 0.1.0 (git+https://github.com/kennylevinsen/libivy.git)" = "" "checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" "checksum libpulse-binding 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7378bffd76492e876a0afb9a016359379a6b5a859fecd039248f76ce719fb" "checksum libpulse-sys 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dcac117c7e9fb50fe162d5fbc6b3818819bd173922f648fae017f913de68520" diff --git a/Cargo.toml b/Cargo.toml index 8c616b7..bafdf95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,10 @@ version = "0.1.0" authors = ["Kenny Levinsen "] edition = "2018" +[features] +ivy = [ "libivy" ] +default = [] + [dependencies] smithay-client-toolkit = "0.6.3" byteorder = "1.0" @@ -18,4 +22,5 @@ libpulse-binding = { version = "2.6.0"} dbus = "0.6" atty = "0.2" fuzzy-matcher = "0.2" -lazy_static = "1.3.0" \ No newline at end of file +lazy_static = "1.3.0" +libivy = { git = "https://github.com/kennylevinsen/libivy.git", optional = true } \ No newline at end of file diff --git a/src/launcher.rs b/src/launcher.rs index f8ec81b..4f2a110 100644 --- a/src/launcher.rs +++ b/src/launcher.rs @@ -6,8 +6,6 @@ use crate::module::{Input, ModuleImpl}; use std::cell::RefCell; use std::cmp::Ordering; use std::io::Read; -use std::process::Command; -use std::str; use atty::Stream; use chrono::{DateTime, Local}; @@ -17,7 +15,8 @@ use smithay_client_toolkit::keyboard::keysyms; pub struct Launcher { options: Vec, matches: Vec, - cur: String, + input: String, + result: Option, offset: usize, font: RefCell, dirty: bool, @@ -27,7 +26,7 @@ impl Launcher { pub fn new() -> Result { if !atty::is(Stream::Stdin) { let mut inbuf = String::new(); - std::io::stdin().read_to_string(&mut inbuf).unwrap(); + std::io::stdin().read_to_string(&mut inbuf)?; let options = inbuf .split("\n") .into_iter() @@ -38,7 +37,8 @@ impl Launcher { Ok(Launcher { options: options, matches: vec![], - cur: "".to_string(), + input: "".to_string(), + result: None, offset: 0, font: RefCell::new(Font::new(&ROBOTO_REGULAR, 32.0)), dirty: true, @@ -47,7 +47,8 @@ impl Launcher { Ok(Launcher { options: vec![], matches: vec![], - cur: "".to_string(), + input: "".to_string(), + result: None, offset: 0, font: RefCell::new(Font::new(&ROBOTO_REGULAR, 32.0)), dirty: true, @@ -62,13 +63,13 @@ impl Launcher { ) -> Result, ::std::io::Error> { buf.memset(bg); - let mut x_off = if self.cur.len() > 0 { + let mut x_off = if self.input.len() > 0 { let c = if self.matches.len() == 0 { Color::new(1.0, 0.5, 0.5, 1.0) } else { Color::new(1.0, 1.0, 1.0, 1.0) }; let dim = self.font.borrow_mut().auto_draw_text( &mut buf.subdimensions((0, 0, 1232, 32))?, bg, &c, - &self.cur, + &self.input, )?; dim.0 + 8 @@ -84,9 +85,9 @@ impl Launcher { Ok(b) => b, Err(_) => break, }; - let size = if idx == self.offset && self.cur.len() > 0 { + let size = if idx == self.offset && self.input.len() > 0 { let (_, indices) = - fuzzy_indices(&m.to_lowercase(), &self.cur.to_lowercase()).unwrap(); + fuzzy_indices(&m.to_lowercase(), &self.input.to_lowercase()).unwrap(); let mut colors = Vec::with_capacity(m.len()); for pos in 0..m.len() { if indices.contains(&pos) { @@ -125,12 +126,12 @@ impl Launcher { ) -> Result, ::std::io::Error> { buf.memset(bg); - let x_off = if self.cur.len() > 0 { + let x_off = if self.input.len() > 0 { let dim = self.font.borrow_mut().auto_draw_text( &mut buf.subdimensions((0, 0, 1232, 32))?, bg, &Color::new(1.0, 1.0, 1.0, 1.0), - &self.cur, + &self.input, )?; dim.0 + 16 @@ -138,21 +139,13 @@ impl Launcher { 0 }; - if let Ok(output) = Command::new("ivy") - .arg("-e") - .arg(&self.cur.chars().skip(1).collect::()) - .output() { - if let Ok(stdout) = str::from_utf8(&output.stdout) { - let stdout = stdout.trim(); - if stdout.len() > 0 { - self.font.borrow_mut().auto_draw_text( - &mut buf.subdimensions((x_off, 0, 1232-x_off, 32))?, - bg, - &Color::new(0.75, 0.75, 0.75, 1.0), - &format!(" = {:}", stdout), - )?; - } - } + if let Some(result) = &self.result { + self.font.borrow_mut().auto_draw_text( + &mut buf.subdimensions((x_off, 0, 1232-x_off, 32))?, + bg, + &Color::new(0.75, 0.75, 0.75, 1.0), + &format!(" = {:}", result), + )?; } Ok(vec![buf.get_signed_bounds()]) @@ -169,13 +162,23 @@ impl Launcher { &mut buf.subdimensions((0, 0, 1232, 32))?, bg, &Color::new(1.0, 1.0, 1.0, 1.0), - &self.cur, + &self.input, )?; Ok(vec![buf.get_signed_bounds()]) } } +#[cfg(feature = "ivy")] +fn calc(s: &str) -> Result { + libivy::eval(s) +} + +#[cfg(not(feature = "ivy"))] +fn calc(_s: &str) -> Result { + Err("ivy not enabled".to_string()) +} + impl ModuleImpl for Launcher { fn draw( &self, @@ -185,7 +188,7 @@ impl ModuleImpl for Launcher { ) -> Result, ::std::io::Error> { buf.memset(bg); - match self.cur.chars().next() { + match self.input.chars().next() { Some('=') => self.draw_calc(buf, bg), Some('!') => self.draw_shell(buf, bg), _ => self.draw_launcher(buf, bg), @@ -196,14 +199,21 @@ impl ModuleImpl for Launcher { fn update(&mut self, _time: &DateTime, force: bool) -> Result { if self.dirty || force { - match self.cur.chars().next() { - Some('=') => (), + match self.input.chars().next() { + Some('=') => { + if self.input.len() > 1 { + match calc(&self.input.chars().skip(1).collect::()) { + Ok(v) => self.result = Some(v), + Err(_) => self.result = None, + } + } + }, Some('!') => (), _ => { let mut m = self .options .iter() - .map(|x| (fuzzy_match(&x.to_lowercase(), &self.cur.to_lowercase()), x)) + .map(|x| (fuzzy_match(&x.to_lowercase(), &self.input.to_lowercase()), x)) .filter(|(x, _)| x.is_some()) .map(|(x, y)| (x.unwrap(), y.to_string())) .collect::>(); @@ -237,17 +247,18 @@ impl ModuleImpl for Launcher { match input { Input::Keypress { key, interpreted } => match key { keysyms::XKB_KEY_BackSpace => { - if self.cur.len() > 0 { - self.cur = self.cur[..self.cur.len() - 1].to_string(); + if self.input.len() > 0 { + self.input = self.input[..self.input.len() - 1].to_string(); self.offset = 0; + self.result = None; self.dirty = true } } keysyms::XKB_KEY_Return => { - match self.cur.chars().next() { + match self.input.chars().next() { Some('=') => (), Some('!') => { - println!("{}", self.cur.chars().skip(1).collect::()); + println!("{}", self.input.chars().skip(1).collect::()); std::process::exit(0); } _ => if self.matches.len() > self.offset { @@ -270,9 +281,10 @@ impl ModuleImpl for Launcher { } _ => match interpreted { Some(v) => { - self.cur += &v; + self.input += &v; self.offset = 0; - self.dirty = true + self.result = None; + self.dirty = true; } None => {} },