57 lines
1.8 KiB
Rust
57 lines
1.8 KiB
Rust
use std::io::{self, Write};
|
|
|
|
use anyhow::{bail, Context, Result};
|
|
|
|
use crate::cmd::{Remove, Run};
|
|
use crate::config;
|
|
use crate::db::DatabaseFile;
|
|
use crate::util::{self, Fzf};
|
|
|
|
impl Run for Remove {
|
|
fn run(&self) -> Result<()> {
|
|
let data_dir = config::data_dir()?;
|
|
let mut db = DatabaseFile::new(data_dir);
|
|
let mut db = db.open()?;
|
|
|
|
if self.interactive {
|
|
let keywords = &self.paths;
|
|
let now = util::current_time()?;
|
|
let mut stream = db.stream(now).with_keywords(keywords);
|
|
|
|
let mut fzf = Fzf::new(true)?;
|
|
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")?,
|
|
}
|
|
};
|
|
|
|
let paths = selection.lines().filter_map(|line| line.get(5..));
|
|
for path in paths {
|
|
if !db.remove(path) {
|
|
bail!("path not found in database: {}", path);
|
|
}
|
|
}
|
|
} else {
|
|
for path in &self.paths {
|
|
if !db.remove(path) {
|
|
let path_abs = util::resolve_path(path)?;
|
|
let path_abs = util::path_to_str(&path_abs)?;
|
|
if path_abs != path && !db.remove(path_abs) {
|
|
bail!("path not found in database: {} ({})", path, path_abs)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
db.save()
|
|
}
|
|
}
|