Skip to content

Commit

Permalink
Cache most used apps and use for ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
l4l committed Dec 6, 2020
1 parent 6790c4a commit d7d40d4
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 7 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ serde = { version = "1.0.117", features = ["derive"] }
toml = "0.5.7"
structopt = "0.3.21"
either = "1.6.1"
lazy_static = "1.4.0"

[profile.release]
lto = true
18 changes: 14 additions & 4 deletions src/desktop.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
use std::fs::{self, DirEntry};
use std::path::{Path, PathBuf};

use lazy_static::lazy_static;
use xdg::BaseDirectories;

lazy_static! {
pub static ref XDG_DIRS: BaseDirectories = BaseDirectories::new().unwrap();
}

pub struct Entry {
pub name: String,
pub desktop_fname: String,
pub exec: String,
pub is_terminal: bool,
}

pub fn find_entries() -> Vec<Entry> {
let xdg = BaseDirectories::new().unwrap();

let mut dirs = xdg.get_data_dirs();
dirs.push(xdg.get_data_home());
let mut dirs = XDG_DIRS.get_data_dirs();
dirs.push(XDG_DIRS.get_data_home());
let mut entries = vec![];
traverse_dirs(&mut entries, dirs);
entries.sort_unstable_by(|x, y| x.name.cmp(&y.name));
Expand Down Expand Up @@ -72,6 +76,12 @@ fn traverse_dir_entry(mut entries: &mut Vec<Entry>, dir_entry: DirEntry) {
(Some(n), Some(e)) => {
entries.push(Entry {
name: n.to_owned(),
desktop_fname: dir_entry_path
.file_name()
.unwrap()
.to_str()
.expect("desktop file name is not in utf-8")
.to_owned(),
exec: e.to_owned(),
is_terminal: main_section
.attr("Terminal")
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use sctk::{
};
use structopt::{clap::ArgGroup, StructOpt};

pub use desktop::Entry as DesktopEntry;
pub use desktop::{Entry as DesktopEntry, XDG_DIRS};

mod config;
mod desktop;
Expand Down
61 changes: 59 additions & 2 deletions src/mode/apps.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,51 @@
use std::cmp::Reverse;
use std::collections::HashMap;
use std::ffi::CString;
use std::fs::File;
use std::io::{BufRead, BufReader, Write};

use crate::draw::ListItem;
use crate::DesktopEntry;

pub struct AppsMode {
entries: Vec<DesktopEntry>,
term: Vec<CString>,
usage: HashMap<String, usize>,
}

impl AppsMode {
pub fn new(entries: Vec<DesktopEntry>, term: Vec<CString>) -> Self {
Self { entries, term }
pub fn new(mut entries: Vec<DesktopEntry>, term: Vec<CString>) -> Self {
let usage: HashMap<String, usize> = crate::XDG_DIRS
.place_cache_file(concat!(crate::prog_name!(), ".cache"))
.and_then(File::open)
.map_err(|e| log::error!("cannot open cache file: {}", e))
.map(BufReader::new)
.into_iter()
.flat_map(|rdr| {
rdr.lines()
.filter(|l| l.as_ref().map(|l| !l.is_empty()).unwrap_or(true))
.map(|l| {
let line = l.map_err(|e| log::error!("unable to read the line: {}", e))?;
let mut iter = line.split(' ');
let (count, progname) = (iter.next().ok_or(())?, iter.next().ok_or(())?);

let count = count.parse().map_err(|e| {
log::error!("unable to parse count (\"{}\"): {}", count, e)
})?;

Ok((progname.to_string(), count))
})
})
.collect::<Result<_, ()>>()
.unwrap_or_default();

entries.sort_by_key(|e| Reverse(usage.get(&e.desktop_fname).unwrap_or(&0)));

Self {
entries,
term,
usage,
}
}

pub fn eval(&mut self, idx: usize) -> std::convert::Infallible {
Expand All @@ -30,6 +65,28 @@ impl AppsMode {
} else {
(&args[0], &args[1..])
};

*self.usage.entry(entry.desktop_fname.clone()).or_default() += 1;

if let Err(e) = crate::XDG_DIRS
.place_cache_file(concat!(crate::prog_name!(), ".cache"))
.and_then(File::create)
.and_then(|mut f| {
let mut buf = vec![];

for (progname, count) in &self.usage {
let s = format!("{} ", count);
buf.extend(s.as_bytes());
buf.extend(progname.as_bytes());
buf.push(b'\n');
}

f.write_all(&buf)
})
{
log::error!("failed to update cache: {}", e);
}

log::debug!("executing command: {:?} {:?}", prog, args);
nix::unistd::execvp(prog, args).unwrap();

Expand Down

0 comments on commit d7d40d4

Please sign in to comment.