80 lines
2.4 KiB
Rust
80 lines
2.4 KiB
Rust
use std::io::{self, Write};
|
|
|
|
use anyhow::{Context, Result};
|
|
|
|
use crate::cmd::{Query, Run};
|
|
use crate::config;
|
|
use crate::db::{Database, DatabaseFile};
|
|
use crate::error::BrokenPipeHandler;
|
|
use crate::util::{self, Fzf};
|
|
|
|
impl Run for Query {
|
|
fn run(&self) -> Result<()> {
|
|
let data_dir = config::data_dir()?;
|
|
let mut db = DatabaseFile::new(data_dir);
|
|
let mut db = db.open()?;
|
|
self.query(&mut db).and(db.save())
|
|
}
|
|
}
|
|
|
|
impl Query {
|
|
fn query(&self, db: &mut Database) -> Result<()> {
|
|
let now = util::current_time()?;
|
|
|
|
let mut stream = db.stream(now).with_keywords(&self.keywords);
|
|
if !self.all {
|
|
let resolve_symlinks = config::resolve_symlinks();
|
|
stream = stream.with_exists(resolve_symlinks);
|
|
}
|
|
if let Some(path) = &self.exclude {
|
|
stream = stream.with_exclude(path);
|
|
}
|
|
|
|
if self.interactive {
|
|
let mut fzf = Fzf::new(false)?;
|
|
let stdin = fzf.stdin();
|
|
|
|
let selection = loop {
|
|
let dir = match stream.next() {
|
|
Some(dir) => dir,
|
|
None => break fzf.select()?,
|
|
};
|
|
|
|
match writeln!(stdin, "{}", dir.display_score(now)) {
|
|
Err(e) if e.kind() == io::ErrorKind::BrokenPipe => break fzf.select()?,
|
|
result => result.context("could not write to fzf")?,
|
|
}
|
|
};
|
|
|
|
if self.score {
|
|
print!("{}", selection);
|
|
} else {
|
|
let path = selection.get(5..).context("could not read selection from fzf")?;
|
|
print!("{}", path);
|
|
}
|
|
} else if self.list {
|
|
let stdout = io::stdout();
|
|
let handle = &mut stdout.lock();
|
|
while let Some(dir) = stream.next() {
|
|
if self.score {
|
|
writeln!(handle, "{}", dir.display_score(now))
|
|
} else {
|
|
writeln!(handle, "{}", dir.display())
|
|
}
|
|
.pipe_exit("stdout")?;
|
|
}
|
|
handle.flush().pipe_exit("stdout")?;
|
|
} else {
|
|
let dir = stream.next().context("no match found")?;
|
|
if self.score {
|
|
writeln!(io::stdout(), "{}", dir.display_score(now))
|
|
} else {
|
|
writeln!(io::stdout(), "{}", dir.display())
|
|
}
|
|
.pipe_exit("stdout")?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|