Fix formatting

This commit is contained in:
Ajeet D'Souza 2023-01-09 11:07:26 +05:30
parent b61f98b269
commit df26bb039b
11 changed files with 109 additions and 43 deletions

View File

@ -1,6 +1,5 @@
group_imports = "StdExternalCrate" group_imports = "StdExternalCrate"
imports_granularity = "Module" imports_granularity = "Module"
max_width = 120
newline_style = "Native" newline_style = "Native"
use_field_init_shorthand = true use_field_init_shorthand = true
use_small_heuristics = "Max" use_small_heuristics = "Max"

View File

@ -19,7 +19,10 @@ impl Run for Add {
let mut db = Database::open()?; let mut db = Database::open()?;
for path in &self.paths { for path in &self.paths {
let path = if config::resolve_symlinks() { util::canonicalize } else { util::resolve_path }(path)?; let path =
if config::resolve_symlinks() { util::canonicalize } else { util::resolve_path }(
path,
)?;
let path = util::path_to_str(&path)?; let path = util::path_to_str(&path)?;
// Ignore path if it contains unsupported characters, or if it's in the exclude // Ignore path if it contains unsupported characters, or if it's in the exclude

View File

@ -26,7 +26,8 @@ impl Run for Edit {
let stdout = &mut io::stdout().lock(); let stdout = &mut io::stdout().lock();
for dir in db.dirs().iter().rev() { for dir in db.dirs().iter().rev() {
write!(stdout, "{}\0", dir.display().with_score(now).with_separator('\t')).pipe_exit("fzf")?; write!(stdout, "{}\0", dir.display().with_score(now).with_separator('\t'))
.pipe_exit("fzf")?;
} }
Ok(()) Ok(())
} }

View File

@ -7,8 +7,9 @@ use crate::db::Database;
impl Run for Import { impl Run for Import {
fn run(&self) -> Result<()> { fn run(&self) -> Result<()> {
let buffer = fs::read_to_string(&self.path) let buffer = fs::read_to_string(&self.path).with_context(|| {
.with_context(|| format!("could not open database for importing: {}", &self.path.display()))?; format!("could not open database for importing: {}", &self.path.display())
})?;
let mut db = Database::open()?; let mut db = Database::open()?;
if !self.merge && !db.dirs().is_empty() { if !self.merge && !db.dirs().is_empty() {
@ -58,7 +59,8 @@ fn import_z(db: &mut Database, buffer: &str) -> Result<()> {
let mut split = line.rsplitn(3, '|'); let mut split = line.rsplitn(3, '|');
let last_accessed = split.next().with_context(|| format!("invalid entry: {line}"))?; let last_accessed = split.next().with_context(|| format!("invalid entry: {line}"))?;
let last_accessed = last_accessed.parse().with_context(|| format!("invalid epoch: {last_accessed}"))?; let last_accessed =
last_accessed.parse().with_context(|| format!("invalid epoch: {last_accessed}"))?;
let rank = split.next().with_context(|| format!("invalid entry: {line}"))?; let rank = split.next().with_context(|| format!("invalid entry: {line}"))?;
let rank = rank.parse().with_context(|| format!("invalid rank: {rank}"))?; let rank = rank.parse().with_context(|| format!("invalid rank: {rank}"))?;

View File

@ -48,10 +48,11 @@ impl Query {
} else { } else {
let handle = &mut io::stdout(); let handle = &mut io::stdout();
let Some(dir) = stream.next() else { let Some(dir) = stream.next() else {
if stream.did_exclude() { bail!(if stream.did_exclude() {
bail!("you are already in the only match"); "you are already in the only match"
} } else {
bail!("no match found"); "no match found"
});
}; };
let dir = if self.score { dir.display().with_score(now) } else { dir.display() }; let dir = if self.score { dir.display().with_score(now) } else { dir.display() };
writeln!(handle, "{dir}").pipe_exit("stdout")?; writeln!(handle, "{dir}").pipe_exit("stdout")?;

View File

@ -26,7 +26,8 @@ pub fn exclude_dirs() -> Result<Vec<Pattern>> {
Some(paths) => env::split_paths(&paths) Some(paths) => env::split_paths(&paths)
.map(|path| { .map(|path| {
let pattern = path.to_str().context("invalid unicode in _ZO_EXCLUDE_DIRS")?; let pattern = path.to_str().context("invalid unicode in _ZO_EXCLUDE_DIRS")?;
Pattern::new(pattern).with_context(|| format!("invalid glob in _ZO_EXCLUDE_DIRS: {pattern}")) Pattern::new(pattern)
.with_context(|| format!("invalid glob in _ZO_EXCLUDE_DIRS: {pattern}"))
}) })
.collect(), .collect(),
None => { None => {
@ -47,8 +48,9 @@ pub fn fzf_opts() -> Option<OsString> {
pub fn maxage() -> Result<Rank> { pub fn maxage() -> Result<Rank> {
env::var_os("_ZO_MAXAGE").map_or(Ok(10_000.0), |maxage| { env::var_os("_ZO_MAXAGE").map_or(Ok(10_000.0), |maxage| {
let maxage = maxage.to_str().context("invalid unicode in _ZO_MAXAGE")?; let maxage = maxage.to_str().context("invalid unicode in _ZO_MAXAGE")?;
let maxage = let maxage = maxage
maxage.parse::<u32>().with_context(|| format!("unable to parse _ZO_MAXAGE as integer: {maxage}"))?; .parse::<u32>()
.with_context(|| format!("unable to parse _ZO_MAXAGE as integer: {maxage}"))?;
Ok(maxage as Rank) Ok(maxage as Rank)
}) })
} }

View File

@ -39,11 +39,14 @@ impl Database {
Err(e) if e.kind() == io::ErrorKind::NotFound => { Err(e) if e.kind() == io::ErrorKind::NotFound => {
// Create data directory, but don't create any file yet. The file will be // Create data directory, but don't create any file yet. The file will be
// created later by [`Database::save`] if any data is modified. // created later by [`Database::save`] if any data is modified.
fs::create_dir_all(data_dir) fs::create_dir_all(data_dir).with_context(|| {
.with_context(|| format!("unable to create data directory: {}", data_dir.display()))?; format!("unable to create data directory: {}", data_dir.display())
})?;
Ok(Self::new(path, Vec::new(), |_| Vec::new(), false)) Ok(Self::new(path, Vec::new(), |_| Vec::new(), false))
} }
Err(e) => Err(e).with_context(|| format!("could not read from database: {}", path.display())), Err(e) => {
Err(e).with_context(|| format!("could not read from database: {}", path.display()))
}
} }
} }
@ -64,7 +67,9 @@ impl Database {
pub fn add(&mut self, path: impl AsRef<str> + Into<String>, by: Rank, now: Epoch) { pub fn add(&mut self, path: impl AsRef<str> + Into<String>, by: Rank, now: Epoch) {
self.with_dirs_mut(|dirs| match dirs.iter_mut().find(|dir| dir.path == path.as_ref()) { self.with_dirs_mut(|dirs| match dirs.iter_mut().find(|dir| dir.path == path.as_ref()) {
Some(dir) => dir.rank = (dir.rank + by).max(0.0), Some(dir) => dir.rank = (dir.rank + by).max(0.0),
None => dirs.push(Dir { path: path.into().into(), rank: by.max(0.0), last_accessed: now }), None => {
dirs.push(Dir { path: path.into().into(), rank: by.max(0.0), last_accessed: now })
}
}); });
self.with_dirty_mut(|dirty| *dirty = true); self.with_dirty_mut(|dirty| *dirty = true);
} }
@ -73,7 +78,9 @@ impl Database {
/// directory is always in the database, it is expected that the user either /// directory is always in the database, it is expected that the user either
/// does a check before calling this, or calls `dedup()` afterward. /// does a check before calling this, or calls `dedup()` afterward.
pub fn add_unchecked(&mut self, path: impl AsRef<str> + Into<String>, rank: Rank, now: Epoch) { pub fn add_unchecked(&mut self, path: impl AsRef<str> + Into<String>, rank: Rank, now: Epoch) {
self.with_dirs_mut(|dirs| dirs.push(Dir { path: path.into().into(), rank, last_accessed: now })); self.with_dirs_mut(|dirs| {
dirs.push(Dir { path: path.into().into(), rank, last_accessed: now })
});
self.with_dirty_mut(|dirty| *dirty = true); self.with_dirty_mut(|dirty| *dirty = true);
} }
@ -85,7 +92,9 @@ impl Database {
dir.rank = (dir.rank + by).max(0.0); dir.rank = (dir.rank + by).max(0.0);
dir.last_accessed = now; dir.last_accessed = now;
} }
None => dirs.push(Dir { path: path.into().into(), rank: by.max(0.0), last_accessed: now }), None => {
dirs.push(Dir { path: path.into().into(), rank: by.max(0.0), last_accessed: now })
}
}); });
self.with_dirty_mut(|dirty| *dirty = true); self.with_dirty_mut(|dirty| *dirty = true);
} }
@ -166,7 +175,9 @@ impl Database {
pub fn sort_by_score(&mut self, now: Epoch) { pub fn sort_by_score(&mut self, now: Epoch) {
self.with_dirs_mut(|dirs| { self.with_dirs_mut(|dirs| {
dirs.sort_unstable_by(|dir1: &Dir, dir2: &Dir| dir1.score(now).total_cmp(&dir2.score(now))) dirs.sort_unstable_by(|dir1: &Dir, dir2: &Dir| {
dir1.score(now).total_cmp(&dir2.score(now))
})
}); });
self.with_dirty_mut(|dirty| *dirty = true); self.with_dirty_mut(|dirty| *dirty = true);
} }
@ -182,7 +193,8 @@ impl Database {
fn serialize(dirs: &[Dir<'_>]) -> Result<Vec<u8>> { fn serialize(dirs: &[Dir<'_>]) -> Result<Vec<u8>> {
(|| -> bincode::Result<_> { (|| -> bincode::Result<_> {
// Preallocate buffer with combined size of sections. // Preallocate buffer with combined size of sections.
let buffer_size = bincode::serialized_size(&Self::VERSION)? + bincode::serialized_size(&dirs)?; let buffer_size =
bincode::serialized_size(&Self::VERSION)? + bincode::serialized_size(&dirs)?;
let mut buffer = Vec::with_capacity(buffer_size as usize); let mut buffer = Vec::with_capacity(buffer_size as usize);
// Serialize sections into buffer. // Serialize sections into buffer.
@ -210,7 +222,9 @@ impl Database {
// Deserialize sections. // Deserialize sections.
let version = deserializer.deserialize(bytes_version)?; let version = deserializer.deserialize(bytes_version)?;
let dirs = match version { let dirs = match version {
Self::VERSION => deserializer.deserialize(bytes_dirs).context("could not deserialize database")?, Self::VERSION => {
deserializer.deserialize(bytes_dirs).context("could not deserialize database")?
}
version => { version => {
bail!("unsupported version (got {version}, supports {})", Self::VERSION) bail!("unsupported version (got {version}, supports {})", Self::VERSION)
} }

View File

@ -100,12 +100,19 @@ mod tests {
// Filter out lines using edit:*, since those functions are only available in // Filter out lines using edit:*, since those functions are only available in
// the interactive editor. // the interactive editor.
for line in Elvish(&opts).render().unwrap().split('\n').filter(|line| !line.contains("edit:")) { for line in
Elvish(&opts).render().unwrap().split('\n').filter(|line| !line.contains("edit:"))
{
source.push_str(line); source.push_str(line);
source.push('\n'); source.push('\n');
} }
Command::new("elvish").args(["-c", &source, "-norc"]).assert().success().stdout("").stderr(""); Command::new("elvish")
.args(["-c", &source, "-norc"])
.assert()
.success()
.stdout("")
.stderr("");
} }
#[apply(opts)] #[apply(opts)]
@ -151,8 +158,12 @@ mod tests {
let tempdir = tempfile::tempdir().unwrap(); let tempdir = tempfile::tempdir().unwrap();
let tempdir = tempdir.path(); let tempdir = tempdir.path();
let assert = let assert = Command::new("nu")
Command::new("nu").env("HOME", tempdir).args(["--commands", &source]).assert().success().stderr(""); .env("HOME", tempdir)
.args(["--commands", &source])
.assert()
.success()
.stderr("");
if opts.hook != InitHook::Pwd { if opts.hook != InitHook::Pwd {
assert.stdout(""); assert.stdout("");
@ -179,7 +190,8 @@ mod tests {
let opts = Opts { cmd, hook, echo, resolve_symlinks }; let opts = Opts { cmd, hook, echo, resolve_symlinks };
let source = Posix(&opts).render().unwrap(); let source = Posix(&opts).render().unwrap();
let assert = Command::new("dash").args(["-e", "-u", "-c", &source]).assert().success().stderr(""); let assert =
Command::new("dash").args(["-e", "-u", "-c", &source]).assert().success().stderr("");
if opts.hook != InitHook::Pwd { if opts.hook != InitHook::Pwd {
assert.stdout(""); assert.stdout("");
} }
@ -234,7 +246,12 @@ mod tests {
let mut source = Xonsh(&opts).render().unwrap(); let mut source = Xonsh(&opts).render().unwrap();
source.push('\n'); source.push('\n');
Command::new("black").args(["--check", "--diff", "-"]).write_stdin(source).assert().success().stdout(""); Command::new("black")
.args(["--check", "--diff", "-"])
.write_stdin(source)
.assert()
.success()
.stdout("");
} }
#[apply(opts)] #[apply(opts)]

View File

@ -159,7 +159,9 @@ pub fn write(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> Result<()> {
let result = (|| { let result = (|| {
// Write to the tmpfile. // Write to the tmpfile.
let _ = tmp_file.set_len(contents.len() as u64); let _ = tmp_file.set_len(contents.len() as u64);
tmp_file.write_all(contents).with_context(|| format!("could not write to file: {}", tmp_path.display()))?; tmp_file
.write_all(contents)
.with_context(|| format!("could not write to file: {}", tmp_path.display()))?;
// Set the owner of the tmpfile (UNIX only). // Set the owner of the tmpfile (UNIX only).
#[cfg(unix)] #[cfg(unix)]
@ -224,16 +226,21 @@ fn rename(from: impl AsRef<Path>, to: impl AsRef<Path>) -> Result<()> {
loop { loop {
match fs::rename(from, to) { match fs::rename(from, to) {
Err(e) if e.kind() == io::ErrorKind::PermissionDenied && attempts < MAX_ATTEMPTS => attempts += 1, Err(e) if e.kind() == io::ErrorKind::PermissionDenied && attempts < MAX_ATTEMPTS => {
attempts += 1
}
result => { result => {
break result.with_context(|| format!("could not rename file: {} -> {}", from.display(), to.display())); break result.with_context(|| {
format!("could not rename file: {} -> {}", from.display(), to.display())
});
} }
} }
} }
} }
pub fn canonicalize(path: impl AsRef<Path>) -> Result<PathBuf> { pub fn canonicalize(path: impl AsRef<Path>) -> Result<PathBuf> {
dunce::canonicalize(&path).with_context(|| format!("could not resolve path: {}", path.as_ref().display())) dunce::canonicalize(&path)
.with_context(|| format!("could not resolve path: {}", path.as_ref().display()))
} }
pub fn current_dir() -> Result<PathBuf> { pub fn current_dir() -> Result<PathBuf> {
@ -241,8 +248,10 @@ pub fn current_dir() -> Result<PathBuf> {
} }
pub fn current_time() -> Result<Epoch> { pub fn current_time() -> Result<Epoch> {
let current_time = let current_time = SystemTime::now()
SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).context("system clock set to invalid time")?.as_secs(); .duration_since(SystemTime::UNIX_EPOCH)
.context("system clock set to invalid time")?
.as_secs();
Ok(current_time) Ok(current_time)
} }
@ -271,7 +280,9 @@ pub fn resolve_path(path: impl AsRef<Path>) -> Result<PathBuf> {
match components.next() { match components.next() {
Some(Component::Prefix(prefix)) => match prefix.kind() { Some(Component::Prefix(prefix)) => match prefix.kind() {
Prefix::Disk(drive_letter) | Prefix::VerbatimDisk(drive_letter) => Some(drive_letter), Prefix::Disk(drive_letter) | Prefix::VerbatimDisk(drive_letter) => {
Some(drive_letter)
}
_ => None, _ => None,
}, },
_ => None, _ => None,
@ -324,8 +335,9 @@ pub fn resolve_path(path: impl AsRef<Path>) -> Result<PathBuf> {
components.next(); components.next();
let current_dir = env::current_dir()?; let current_dir = env::current_dir()?;
let drive_letter = get_drive_letter(&current_dir) let drive_letter = get_drive_letter(&current_dir).with_context(|| {
.with_context(|| format!("could not get drive letter: {}", current_dir.display()))?; format!("could not get drive letter: {}", current_dir.display())
})?;
base_path = get_drive_path(drive_letter); base_path = get_drive_path(drive_letter);
stack.extend(base_path.components()); stack.extend(base_path.components());
} }

View File

@ -6,7 +6,12 @@ use assert_cmd::Command;
#[test] #[test]
fn completions_bash() { fn completions_bash() {
let source = include_str!("../contrib/completions/zoxide.bash"); let source = include_str!("../contrib/completions/zoxide.bash");
Command::new("bash").args(["--noprofile", "--norc", "-c", source]).assert().success().stdout("").stderr(""); Command::new("bash")
.args(["--noprofile", "--norc", "-c", source])
.assert()
.success()
.stdout("")
.stderr("");
} }
// Elvish: the completions file uses editor commands to add completions to the // Elvish: the completions file uses editor commands to add completions to the

View File

@ -9,8 +9,11 @@ use ignore::Walk;
fn main() -> Result<()> { fn main() -> Result<()> {
let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let dir = dir.parent().with_context(|| format!("could not find workspace root: {}", dir.display()))?; let dir = dir
env::set_current_dir(dir).with_context(|| format!("could not set current directory: {}", dir.display()))?; .parent()
.with_context(|| format!("could not find workspace root: {}", dir.display()))?;
env::set_current_dir(dir)
.with_context(|| format!("could not set current directory: {}", dir.display()))?;
let nix_enabled = enable_nix(); let nix_enabled = enable_nix();
let app = App::parse(); let app = App::parse();
@ -55,7 +58,10 @@ impl CommandExt for &mut Command {
fn run_ci(nix_enabled: bool) -> Result<()> { fn run_ci(nix_enabled: bool) -> Result<()> {
// Run cargo-clippy. // Run cargo-clippy.
Command::new("cargo").args(["clippy", "--all-features", "--all-targets"]).args(["--", "-Dwarnings"]).run()?; Command::new("cargo")
.args(["clippy", "--all-features", "--all-targets"])
.args(["--", "-Dwarnings"])
.run()?;
run_fmt(nix_enabled, true)?; run_fmt(nix_enabled, true)?;
run_lint(nix_enabled)?; run_lint(nix_enabled)?;
run_tests(nix_enabled, "") run_tests(nix_enabled, "")
@ -120,7 +126,8 @@ fn enable_nix() -> bool {
if nix_enabled { if nix_enabled {
return true; return true;
} }
let nix_detected = Command::new("nix-shell").arg("--version").status().map(|s| s.success()).unwrap_or(false); let nix_detected =
Command::new("nix-shell").arg("--version").status().map(|s| s.success()).unwrap_or(false);
if !nix_detected { if !nix_detected {
return false; return false;
} }
@ -129,6 +136,9 @@ fn enable_nix() -> bool {
let args = env::args(); let args = env::args();
let cmd = shell_words::join(args); let cmd = shell_words::join(args);
let status = Command::new("nix-shell").args(["--pure", "--run", &cmd, "--", "shell.nix"]).status().unwrap(); let status = Command::new("nix-shell")
.args(["--pure", "--run", &cmd, "--", "shell.nix"])
.status()
.unwrap();
process::exit(status.code().unwrap_or(1)); process::exit(status.code().unwrap_or(1));
} }