From ba13b459409dd5aea708ae7bca9059d17cbedceb Mon Sep 17 00:00:00 2001 From: Ajeet D'Souza <98ajeet@gmail.com> Date: Wed, 10 Jun 2020 18:00:22 +0530 Subject: [PATCH] Add --score flag to show score with query result --- CHANGELOG.md | 1 + Cargo.lock | 89 ++++++++++++++-------------- README.md | 2 +- src/db.rs | 47 ++++++++++++++- src/fzf.rs | 50 +++------------- src/subcommand/query.rs | 124 +++++++++++++++++++++++++--------------- 6 files changed, 179 insertions(+), 134 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07851f5..0e5aadd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `$_ZO_FZF_OPTS` to specify custom options for `fzf` - `zoxide query --list` to list all matches +- `zoxide query --score` to show score along with result ### Changed diff --git a/Cargo.lock b/Cargo.lock index 3a1e45a..ac24085 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,7 +29,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hermit-abi 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -49,7 +49,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -112,23 +112,22 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs-sys 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "dirs-sys" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", "redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "dunce" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -142,7 +141,7 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -159,7 +158,7 @@ name = "hermit-abi" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -169,7 +168,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.70" +version = "0.2.71" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -183,9 +182,9 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-error-attr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -194,16 +193,16 @@ name = "proc-macro-error-attr" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", "syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "proc-macro2" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -211,10 +210,10 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -223,7 +222,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -282,20 +281,20 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.110" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.110" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -320,18 +319,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-error 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" -version = "1.0.23" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -340,9 +339,9 @@ name = "syn-mid" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -418,9 +417,9 @@ dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dunce 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dunce 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "float-ord 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -442,19 +441,19 @@ dependencies = [ "checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" "checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" "checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" -"checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" -"checksum dunce 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0ad6bf6a88548d1126045c413548df1453d9be094a8ab9fd59bf1fdd338da4f" +"checksum dirs-sys 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" +"checksum dunce 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b2641c4a7c0c4101df53ea572bffdc561c146f6c2eb09e4df02bc4811e3feeb4" "checksum float-ord 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7bad48618fdb549078c333a7a8528acb57af271d0433bdecd523eb620628364e" "checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hermit-abi 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f" +"checksum libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" "checksum ppv-lite86 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" "checksum proc-macro-error 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678" "checksum proc-macro-error-attr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53" -"checksum proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "1502d12e458c49a4c9cbff560d0fe0060c252bc29799ed94ca2ed4bb665a0101" -"checksum quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea" +"checksum proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" +"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" "checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" "checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" @@ -462,12 +461,12 @@ dependencies = [ "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" "checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" -"checksum serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)" = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c" -"checksum serde_derive 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)" = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984" +"checksum serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)" = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d" +"checksum serde_derive 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)" = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum structopt 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "863246aaf5ddd0d6928dfeb1a9ca65f505599e4e1b399935ef7e75107516b4ef" "checksum structopt-derive 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d239ca4b13aee7a2142e6795cbd69e457665ff8037aed33b3effdc430d2f927a" -"checksum syn 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "95b5f192649e48a5302a13f2feb224df883b98933222369e4b3b0fe2a5447269" +"checksum syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6" "checksum syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" diff --git a/README.md b/README.md index c637acd..ebe6b04 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,6 @@ eval "$(zoxide init zsh)" - `$_ZO_EXCLUDE_DIRS`: list of directories separated by platform-specific characters ("`:`" on Linux/macOS, "`;`" on Windows) to be excluded from the database - `$_ZO_FZF_OPTS`: custom flags to pass to `fzf` -- `$_ZO_MAXAGE`: sets the maximum total rank after which entries start getting deleted +- `$_ZO_MAXAGE`: sets the maximum total age after which entries start getting deleted [`dirs` documentation]: https://docs.rs/dirs/latest/dirs/fn.data_local_dir.html diff --git a/src/db.rs b/src/db.rs index b65f4f2..fd7ba35 100644 --- a/src/db.rs +++ b/src/db.rs @@ -3,6 +3,7 @@ use float_ord::FloatOrd; use serde::{Deserialize, Serialize}; use uuid::Uuid; +use std::fmt::{self, Display, Formatter}; use std::fs::{self, OpenOptions}; use std::io::{self, Write}; use std::path::{Path, PathBuf}; @@ -182,7 +183,7 @@ pub struct DbMatches<'a> { impl<'a> DbMatches<'a> { pub fn new(db: &'a mut Db, now: Epoch, keywords: &[String]) -> DbMatches<'a> { db.dirs - .sort_unstable_by_key(|dir| FloatOrd(dir.get_frecency(now))); + .sort_unstable_by_key(|dir| FloatOrd(dir.get_score(now))); let idxs = (0..db.dirs.len()).rev(); let keywords = keywords @@ -257,7 +258,7 @@ impl Dir { true } - pub fn get_frecency(&self, now: Epoch) -> Rank { + pub fn get_score(&self, now: Epoch) -> Rank { const HOUR: Epoch = 60 * 60; const DAY: Epoch = 24 * HOUR; const WEEK: Epoch = 7 * DAY; @@ -273,4 +274,46 @@ impl Dir { self.rank * 0.25 } } + + pub fn display(&self) -> DirDisplay { + DirDisplay { dir: self } + } + + pub fn display_score(&self, now: Epoch) -> DirScoreDisplay { + DirScoreDisplay { dir: self, now } + } +} + +pub struct DirDisplay<'a> { + dir: &'a Dir, +} + +impl Display for DirDisplay<'_> { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{}", self.dir.path) + } +} + +pub struct DirScoreDisplay<'a> { + dir: &'a Dir, + now: Epoch, +} + +impl Display for DirScoreDisplay<'_> { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + const SCORE_MIN: Rank = 0.0; + const SCORE_MAX: Rank = 9999.0; + + let score = self.dir.get_score(self.now); + + let score_clamped = if score > SCORE_MAX { + SCORE_MAX + } else if score > SCORE_MIN { + score + } else { + SCORE_MIN + }; + + write!(f, "{:>4.0} {}", score_clamped, self.dir.path) + } } diff --git a/src/fzf.rs b/src/fzf.rs index 2a74537..abc3e8e 100644 --- a/src/fzf.rs +++ b/src/fzf.rs @@ -1,23 +1,20 @@ use crate::config::zo_fzf_opts; -use crate::db::{Dir, Epoch}; use crate::error::SilentExit; use anyhow::{bail, Context, Result}; use std::io::Write; use std::process::{Child, Command, Stdio}; -use std::str; pub struct Fzf { child: Child, - lines: Vec, } impl Fzf { pub fn new() -> Result { let mut command = Command::new("fzf"); command - .args(&["-n2..", "--no-sort"]) + .arg("-n2..") .stdin(Stdio::piped()) .stdout(Stdio::piped()); @@ -27,37 +24,16 @@ impl Fzf { let child = command.spawn().context("could not launch fzf")?; - Ok(Fzf { - child, - lines: Vec::new(), - }) + Ok(Fzf { child }) } - pub fn write_dir(&mut self, dir: &Dir, now: Epoch) { - let frecency = dir.get_frecency(now); - - let frecency_scaled = if frecency > 9999.0 { - 9999 - } else if frecency > 0.0 { - frecency as u32 - } else { - 0 - }; - - self.lines - .push(format!("{:>4} {}", frecency_scaled, dir.path)); - } - - pub fn wait_selection(mut self) -> Result> { + pub fn write(&mut self, line: String) -> Result<()> { // unwrap() is safe here since we have captured `stdin` let stdin = self.child.stdin.as_mut().unwrap(); + writeln!(stdin, "{}", line).context("could not write into fzf stdin") + } - self.lines.sort_unstable(); - - for line in self.lines.iter() { - writeln!(stdin, "{}", line).context("could not write into fzf stdin")?; - } - + pub fn wait_select(self) -> Result> { let output = self .child .wait_with_output() @@ -65,17 +41,9 @@ impl Fzf { match output.status.code() { // normal exit - Some(0) => { - let path_bytes = output - .stdout - .get(12..output.stdout.len().saturating_sub(1)) - .context("fzf returned invalid output")?; - - let path_str = - str::from_utf8(path_bytes).context("invalid utf-8 sequence in fzf output")?; - - Ok(Some(path_str.to_string())) - } + Some(0) => String::from_utf8(output.stdout) + .context("invalid utf-8 sequence in fzf output") + .map(Some), // no match Some(1) => Ok(None), diff --git a/src/subcommand/query.rs b/src/subcommand/query.rs index da77f12..5fb7a79 100644 --- a/src/subcommand/query.rs +++ b/src/subcommand/query.rs @@ -1,7 +1,8 @@ +use crate::db::Dir; use crate::fzf::Fzf; use crate::util; -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use structopt::StructOpt; use std::io::{self, Write}; @@ -20,77 +21,110 @@ pub struct Query { /// List all matching directories #[structopt(short, long, conflicts_with = "interactive")] list: bool, + + /// Display score along with result + #[structopt(short, long)] + score: bool, } impl Query { pub fn run(&self) -> Result<()> { if self.list { - return query_list(&self.keywords); + return self.query_list(); } if self.interactive { - return query_interactive(&self.keywords); + return self.query_interactive(); } - // if the input is already a valid path, simply return it + // if the input is already a valid path, simply print it as-is if let [path] = self.keywords.as_slice() { if Path::new(path).is_dir() { - println!("{}", path); + let dir = Dir { + path: path.to_string(), + rank: 0.0, + last_accessed: 0, + }; + + if self.score { + println!("{}", dir.display_score(0)) + } else { + println!("{}", dir.display()); + } + return Ok(()); } } - query(&self.keywords) - } -} - -fn query(keywords: &[String]) -> Result<()> { - let mut db = util::get_db()?; - let now = util::get_current_time()?; - - let mut matches = db.matches(now, keywords); - - match matches.next() { - Some(dir) => println!("{}", dir.path), - None => bail!("no match found"), + self.query() } - Ok(()) -} + fn query(&self) -> Result<()> { + let mut db = util::get_db()?; + let now = util::get_current_time()?; -fn query_interactive(keywords: &[String]) -> Result<()> { - let mut db = util::get_db()?; - let now = util::get_current_time()?; + let mut matches = db.matches(now, &self.keywords); - let mut fzf = Fzf::new()?; + match matches.next() { + Some(dir) => { + if self.score { + println!("{}", dir.display_score(now)) + } else { + println!("{}", dir.display()); + } + } + None => bail!("no match found"), + } - let mut matches = db.matches(now, keywords); - - while let Some(dir) = matches.next() { - fzf.write_dir(dir, now); + Ok(()) } - match fzf.wait_selection()? { - Some(path) => println!("{}", path), - None => bail!("no match found"), - }; + fn query_interactive(&self) -> Result<()> { + let mut db = util::get_db()?; + let now = util::get_current_time()?; - Ok(()) -} + let mut fzf = Fzf::new()?; + let mut matches = db.matches(now, &self.keywords); -fn query_list(keywords: &[String]) -> Result<()> { - let mut db = util::get_db()?; - let now = util::get_current_time()?; + while let Some(dir) = matches.next() { + fzf.write(format!("{}", dir.display_score(now)))?; + } - let mut matches = db.matches(now, keywords); + match fzf.wait_select()? { + Some(selection) => { + if self.score { + print!("{}", selection) + } else { + let selection = selection + .get(5..) + .with_context(|| format!("fzf returned invalid output: {}", selection))?; + print!("{}", selection) + } + } + None => bail!("no match found"), + }; - let stdout = io::stdout(); - let mut handle = stdout.lock(); - - while let Some(dir) = matches.next() { - let path = &dir.path; - writeln!(handle, "{}", path).unwrap(); + Ok(()) } - Ok(()) + fn query_list(&self) -> Result<()> { + let mut db = util::get_db()?; + let now = util::get_current_time()?; + + let mut matches = db.matches(now, &self.keywords); + + let stdout = io::stdout(); + let mut handle = stdout.lock(); + + while let Some(dir) = matches.next() { + if self.score { + writeln!(handle, "{}", dir.display_score(now)) + } else { + writeln!(handle, "{}", dir.display()) + } + .unwrap(); + } + + Ok(()) + } }