mirror of
https://github.com/Llewellynvdm/zoxide.git
synced 2025-01-24 15:48:24 +00:00
Fix formatting
This commit is contained in:
parent
02029aef98
commit
a60a305279
7
build.rs
7
build.rs
@ -1,6 +1,5 @@
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::process::Command;
|
||||
use std::{env, io};
|
||||
|
||||
fn main() {
|
||||
let pkg_version = env::var("CARGO_PKG_VERSION").unwrap();
|
||||
@ -10,8 +9,8 @@ fn main() {
|
||||
};
|
||||
println!("cargo:rustc-env=ZOXIDE_VERSION={}", version);
|
||||
|
||||
// Since we are generating completions in the package directory, we need to
|
||||
// set this so that Cargo doesn't rebuild every time.
|
||||
// Since we are generating completions in the package directory, we need to set this so that
|
||||
// Cargo doesn't rebuild every time.
|
||||
println!("cargo:rerun-if-changed=src");
|
||||
println!("cargo:rerun-if-changed=templates");
|
||||
println!("cargo:rerun-if-changed=tests");
|
||||
|
@ -1,3 +1,6 @@
|
||||
# comment_width = 100
|
||||
# error_on_line_overflow = true
|
||||
# error_on_unformatted = true
|
||||
# group_imports = "StdExternalCrate"
|
||||
# imports_granularity = "Module"
|
||||
max_width = 120
|
||||
@ -6,3 +9,4 @@ use_field_init_shorthand = true
|
||||
use_small_heuristics = "Max"
|
||||
use_try_shorthand = true
|
||||
# wrap_comments = true
|
||||
# version = "Two"
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clap::{AppSettings, ArgEnum, Clap, ValueHint};
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::{AppSettings, ArgEnum, Clap, ValueHint};
|
||||
|
||||
const ENV_HELP: &str = "ENVIRONMENT VARIABLES:
|
||||
_ZO_DATA_DIR Path for zoxide data files
|
||||
_ZO_ECHO Prints the matched directory before navigating to it when set to 1
|
||||
|
@ -1,16 +1,15 @@
|
||||
use crate::app::{Add, Run};
|
||||
use crate::config;
|
||||
use crate::db::DatabaseFile;
|
||||
use crate::util;
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
|
||||
use std::path::Path;
|
||||
use crate::app::{Add, Run};
|
||||
use crate::db::DatabaseFile;
|
||||
use crate::{config, util};
|
||||
|
||||
impl Run for Add {
|
||||
fn run(&self) -> Result<()> {
|
||||
// These characters can't be printed cleanly to a single line, so they
|
||||
// can cause confusion when writing to fzf / stdout.
|
||||
// These characters can't be printed cleanly to a single line, so they can cause confusion
|
||||
// when writing to fzf / stdout.
|
||||
const EXCLUDE_CHARS: &[char] = &['\n', '\r'];
|
||||
|
||||
let data_dir = config::data_dir()?;
|
||||
@ -22,11 +21,10 @@ impl Run for Add {
|
||||
let mut db = db.open()?;
|
||||
|
||||
for path in &self.paths {
|
||||
let path = if config::resolve_symlinks() { util::canonicalize(path) } 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)?;
|
||||
|
||||
// Ignore path if it contains unsupported characters, or if it's in
|
||||
// the exclude list.
|
||||
// Ignore path if it contains unsupported characters, or if it's in the exclude list.
|
||||
if path.contains(EXCLUDE_CHARS) || exclude_dirs.iter().any(|glob| glob.matches(path)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
use crate::app::{Import, ImportFrom, Run};
|
||||
use crate::config;
|
||||
use crate::db::{Database, DatabaseFile, Dir};
|
||||
use std::fs;
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
use std::fs;
|
||||
use crate::app::{Import, ImportFrom, Run};
|
||||
use crate::config;
|
||||
use crate::db::{Database, DatabaseFile, Dir};
|
||||
|
||||
impl Run for Import {
|
||||
fn run(&self) -> Result<()> {
|
||||
@ -37,9 +37,8 @@ fn from_autojump<'a>(db: &mut Database<'a>, buffer: &'a str) -> Result<()> {
|
||||
|
||||
let rank = split.next().with_context(|| format!("invalid entry: {}", line))?;
|
||||
let mut rank = rank.parse::<f64>().with_context(|| format!("invalid rank: {}", rank))?;
|
||||
// Normalize the rank using a sigmoid function. Don't import actual
|
||||
// ranks from autojump, since its scoring algorithm is very different,
|
||||
// and might take a while to get normalized.
|
||||
// Normalize the rank using a sigmoid function. Don't import actual ranks from autojump,
|
||||
// since its scoring algorithm is very different and might take a while to get normalized.
|
||||
rank = sigmoid(rank);
|
||||
|
||||
let path = split.next().with_context(|| format!("invalid entry: {}", line))?;
|
||||
|
@ -1,12 +1,12 @@
|
||||
use crate::app::{Init, InitShell, Run};
|
||||
use crate::config;
|
||||
use crate::error::BrokenPipeHandler;
|
||||
use crate::shell::{self, Opts};
|
||||
use std::io::{self, Write};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use askama::Template;
|
||||
|
||||
use std::io::{self, Write};
|
||||
use crate::app::{Init, InitShell, Run};
|
||||
use crate::config;
|
||||
use crate::error::BrokenPipeHandler;
|
||||
use crate::shell::{self, Opts};
|
||||
|
||||
impl Run for Init {
|
||||
fn run(&self) -> Result<()> {
|
||||
|
@ -5,10 +5,10 @@ mod init;
|
||||
mod query;
|
||||
mod remove;
|
||||
|
||||
pub use crate::app::_app::*;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
pub use crate::app::_app::*;
|
||||
|
||||
pub trait Run {
|
||||
fn run(&self) -> Result<()>;
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
use crate::app::{Query, Run};
|
||||
use crate::config;
|
||||
use crate::db::{Database, DatabaseFile};
|
||||
use crate::error::BrokenPipeHandler;
|
||||
use crate::fzf::Fzf;
|
||||
use crate::util;
|
||||
use std::io::{self, Write};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use std::io::{self, Write};
|
||||
use crate::app::{Query, Run};
|
||||
use crate::db::{Database, DatabaseFile};
|
||||
use crate::error::BrokenPipeHandler;
|
||||
use crate::fzf::Fzf;
|
||||
use crate::{config, util};
|
||||
|
||||
impl Run for Query {
|
||||
fn run(&self) -> Result<()> {
|
||||
|
@ -1,13 +1,12 @@
|
||||
use crate::app::{Remove, Run};
|
||||
use crate::config;
|
||||
use crate::db::DatabaseFile;
|
||||
use crate::error::BrokenPipeHandler;
|
||||
use crate::fzf::Fzf;
|
||||
use crate::util;
|
||||
use std::io::Write;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
|
||||
use std::io::Write;
|
||||
use crate::app::{Remove, Run};
|
||||
use crate::db::DatabaseFile;
|
||||
use crate::error::BrokenPipeHandler;
|
||||
use crate::fzf::Fzf;
|
||||
use crate::{config, util};
|
||||
|
||||
impl Run for Remove {
|
||||
fn run(&self) -> Result<()> {
|
||||
|
@ -1,12 +1,12 @@
|
||||
use crate::db::Rank;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use dirs_next as dirs;
|
||||
use glob::Pattern;
|
||||
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
use crate::db::Rank;
|
||||
|
||||
pub fn data_dir() -> Result<PathBuf> {
|
||||
let path = match env::var_os("_ZO_DATA_DIR") {
|
||||
|
@ -1,11 +1,11 @@
|
||||
use anyhow::{bail, Context, Result};
|
||||
use bincode::Options as _;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use bincode::Options as _;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct DirList<'a>(#[serde(borrow)] pub Vec<Dir<'a>>);
|
||||
|
||||
@ -17,8 +17,8 @@ impl DirList<'_> {
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<DirList> {
|
||||
// Assume a maximum size for the database. This prevents bincode from
|
||||
// throwing strange errors when it encounters invalid data.
|
||||
// Assume a maximum size for the database. This prevents bincode from throwing strange
|
||||
// errors when it encounters invalid data.
|
||||
const MAX_SIZE: u64 = 32 << 20; // 32 MiB
|
||||
let deserializer = &mut bincode::options().with_fixint_encoding().with_limit(MAX_SIZE);
|
||||
|
||||
@ -149,10 +149,10 @@ pub type Epoch = u64;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{Dir, DirList};
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use super::{Dir, DirList};
|
||||
|
||||
#[test]
|
||||
fn zero_copy() {
|
||||
let dirs = DirList(vec![Dir { path: "/".into(), rank: 0.0, last_accessed: 0 }]);
|
||||
|
@ -1,16 +1,15 @@
|
||||
mod dir;
|
||||
mod stream;
|
||||
|
||||
pub use dir::{Dir, DirList, Epoch, Rank};
|
||||
pub use stream::Stream;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use tempfile::{NamedTempFile, PersistError};
|
||||
|
||||
use std::fs;
|
||||
use std::io::{self, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
pub use dir::{Dir, DirList, Epoch, Rank};
|
||||
pub use stream::Stream;
|
||||
use tempfile::{NamedTempFile, PersistError};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Database<'file> {
|
||||
pub dirs: DirList<'file>,
|
||||
@ -28,9 +27,8 @@ impl<'file> Database<'file> {
|
||||
let mut file = NamedTempFile::new_in(self.data_dir)
|
||||
.with_context(|| format!("could not create temporary database in: {}", self.data_dir.display()))?;
|
||||
|
||||
// Preallocate enough space on the file, preventing copying later on.
|
||||
// This optimization may fail on some filesystems, but it is safe to
|
||||
// ignore it and proceed.
|
||||
// Preallocate enough space on the file, preventing copying later on. This optimization may
|
||||
// fail on some filesystems, but it is safe to ignore it and proceed.
|
||||
let _ = file.as_file().set_len(buffer.len() as _);
|
||||
file.write_all(&buffer)
|
||||
.with_context(|| format!("could not write to temporary database: {}", file.path().display()))?;
|
||||
@ -89,8 +87,8 @@ impl<'file> Database<'file> {
|
||||
Stream::new(self, now)
|
||||
}
|
||||
|
||||
/// Removes the directory with `path` from the store.
|
||||
/// This does not preserve ordering, but is O(1).
|
||||
/// Removes the directory with `path` from the store. This does not preserve ordering, but is
|
||||
/// O(1).
|
||||
pub fn remove<S: AsRef<str>>(&mut self, path: S) -> bool {
|
||||
let path = path.as_ref();
|
||||
|
||||
@ -124,15 +122,16 @@ impl<'file> Database<'file> {
|
||||
|
||||
#[cfg(windows)]
|
||||
fn persist<P: AsRef<Path>>(mut file: NamedTempFile, path: P) -> Result<(), PersistError> {
|
||||
use rand::distributions::{Distribution, Uniform};
|
||||
use rand::rngs::SmallRng;
|
||||
use rand::SeedableRng;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
// File renames on Windows are not atomic and sometimes fail with `PermissionDenied`.
|
||||
// This is extremely unlikely unless it's running in a loop on multiple threads.
|
||||
// Nevertheless, we guard against it by retrying the rename a fixed number of times.
|
||||
use rand::distributions::{Distribution, Uniform};
|
||||
use rand::rngs::SmallRng;
|
||||
use rand::SeedableRng;
|
||||
|
||||
// File renames on Windows are not atomic and sometimes fail with `PermissionDenied`. This is
|
||||
// extremely unlikely unless it's running in a loop on multiple threads. Nevertheless, we guard
|
||||
// against it by retrying the rename a fixed number of times.
|
||||
const MAX_TRIES: usize = 10;
|
||||
let mut rng = None;
|
||||
|
||||
@ -170,9 +169,8 @@ impl DatabaseFile {
|
||||
}
|
||||
|
||||
pub fn open(&mut self) -> Result<Database> {
|
||||
// Read the entire database to memory. For smaller files, this is
|
||||
// faster than mmap / streaming, and allows for zero-copy
|
||||
// deserialization.
|
||||
// Read the entire database to memory. For smaller files, this is faster than
|
||||
// mmap / streaming, and allows for zero-copy deserialization.
|
||||
let path = db_path(&self.data_dir);
|
||||
match fs::read(&path) {
|
||||
Ok(buffer) => {
|
||||
@ -182,9 +180,8 @@ impl DatabaseFile {
|
||||
Ok(Database { dirs, modified: false, data_dir: &self.data_dir })
|
||||
}
|
||||
Err(e) if e.kind() == io::ErrorKind::NotFound => {
|
||||
// Create data directory, but don't create any file yet.
|
||||
// The file will be created later by [`Database::save`]
|
||||
// if any data is modified.
|
||||
// Create data directory, but don't create any file yet. The file will be created
|
||||
// later by [`Database::save`] if any data is modified.
|
||||
fs::create_dir_all(&self.data_dir)
|
||||
.with_context(|| format!("unable to create data directory: {}", self.data_dir.display()))?;
|
||||
Ok(Database { dirs: DirList::new(), modified: false, data_dir: &self.data_dir })
|
||||
|
@ -1,12 +1,11 @@
|
||||
use super::{Database, Dir, Epoch};
|
||||
use crate::util;
|
||||
use std::iter::Rev;
|
||||
use std::ops::Range;
|
||||
use std::{fs, path};
|
||||
|
||||
use ordered_float::OrderedFloat;
|
||||
|
||||
use std::fs;
|
||||
use std::iter::Rev;
|
||||
use std::ops::Range;
|
||||
use std::path;
|
||||
use super::{Database, Dir, Epoch};
|
||||
use crate::util;
|
||||
|
||||
pub struct Stream<'db, 'file> {
|
||||
db: &'db mut Database<'file>,
|
||||
@ -27,8 +26,7 @@ impl<'db, 'file> Stream<'db, 'file> {
|
||||
db.dirs.sort_unstable_by_key(|dir| OrderedFloat(dir.score(now)));
|
||||
let idxs = (0..db.dirs.len()).rev();
|
||||
|
||||
// If a directory is deleted and hasn't been used for 90 days, delete
|
||||
// it from the database.
|
||||
// If a directory is deleted and hasn't been used for 90 days, delete it from the database.
|
||||
let expire_below = now.saturating_sub(90 * 24 * 60 * 60);
|
||||
|
||||
Stream {
|
||||
@ -124,11 +122,11 @@ impl<'db, 'file> Stream<'db, 'file> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Database;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use rstest::rstest;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use super::Database;
|
||||
|
||||
#[rstest]
|
||||
// Case normalization
|
||||
|
@ -1,9 +1,9 @@
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::io;
|
||||
|
||||
// Custom error type for early exit.
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
/// Custom error type for early exit.
|
||||
#[derive(Debug)]
|
||||
pub struct SilentExit {
|
||||
pub code: i32,
|
||||
|
10
src/fzf.rs
10
src/fzf.rs
@ -1,10 +1,10 @@
|
||||
use crate::config;
|
||||
use crate::error::SilentExit;
|
||||
use std::io;
|
||||
use std::process::{Child, ChildStdin, Command, Stdio};
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
use std::io;
|
||||
use std::process::{Child, ChildStdin, Command, Stdio};
|
||||
use crate::config;
|
||||
use crate::error::SilentExit;
|
||||
|
||||
pub struct Fzf {
|
||||
child: Child,
|
||||
@ -33,7 +33,7 @@ impl Fzf {
|
||||
}
|
||||
|
||||
pub fn stdin(&mut self) -> &mut ChildStdin {
|
||||
// unwrap is safe here because command.stdin() has been piped
|
||||
// unwrap is safe here because command.stdin() has been piped.
|
||||
self.child.stdin.as_mut().unwrap()
|
||||
}
|
||||
|
||||
|
@ -6,14 +6,13 @@ mod fzf;
|
||||
mod shell;
|
||||
mod util;
|
||||
|
||||
use crate::app::{App, Run};
|
||||
use crate::error::SilentExit;
|
||||
use std::io::{self, Write};
|
||||
use std::{env, process};
|
||||
|
||||
use clap::Clap;
|
||||
|
||||
use std::env;
|
||||
use std::io::{self, Write};
|
||||
use std::process;
|
||||
use crate::app::{App, Run};
|
||||
use crate::error::SilentExit;
|
||||
|
||||
pub fn main() {
|
||||
// Forcibly disable backtraces.
|
||||
|
11
src/shell.rs
11
src/shell.rs
@ -35,12 +35,12 @@ make_template!(Zsh, "zsh.txt");
|
||||
#[cfg(feature = "shell_tests")]
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use askama::Template;
|
||||
use assert_cmd::Command;
|
||||
use rstest::rstest;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[rstest]
|
||||
fn bash_bash(
|
||||
#[values(None, Some("z"))] cmd: Option<&str>,
|
||||
@ -102,8 +102,8 @@ mod tests {
|
||||
let opts = Opts { cmd, hook, echo, resolve_symlinks };
|
||||
let mut source = String::new();
|
||||
|
||||
// Filter out lines using edit:*, since those functions
|
||||
// are only available in the interactive editor.
|
||||
// Filter out lines using edit:*, since those functions are only available in the
|
||||
// interactive editor.
|
||||
for line in Elvish(&opts).render().unwrap().split('\n').filter(|line| !line.contains("edit:")) {
|
||||
source.push_str(line);
|
||||
source.push('\n');
|
||||
@ -356,8 +356,7 @@ mod tests {
|
||||
let opts = Opts { cmd, hook, echo, resolve_symlinks };
|
||||
let source = Zsh(&opts).render().unwrap();
|
||||
|
||||
// ShellCheck doesn't support zsh yet.
|
||||
// https://github.com/koalaman/shellcheck/issues/809
|
||||
// ShellCheck doesn't support zsh yet: https://github.com/koalaman/shellcheck/issues/809
|
||||
Command::new("shellcheck")
|
||||
.args(&["--enable", "all", "--shell", "bash", "-"])
|
||||
.write_stdin(source)
|
||||
|
17
src/util.rs
17
src/util.rs
@ -1,11 +1,11 @@
|
||||
use crate::db::Epoch;
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
use std::env;
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use std::time::SystemTime;
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
use crate::db::Epoch;
|
||||
|
||||
pub fn canonicalize<P: AsRef<Path>>(path: &P) -> Result<PathBuf> {
|
||||
dunce::canonicalize(path).with_context(|| format!("could not resolve path: {}", path.as_ref().display()))
|
||||
}
|
||||
@ -26,11 +26,8 @@ pub fn path_to_str<P: AsRef<Path>>(path: &P) -> Result<&str> {
|
||||
path.to_str().with_context(|| format!("invalid unicode in path: {}", path.display()))
|
||||
}
|
||||
|
||||
/// Resolves the absolute version of a path.
|
||||
///
|
||||
/// If path is already absolute, the path is still processed to be cleaned, as it can contained ".." or "." (or other)
|
||||
/// character.
|
||||
/// If path is relative, use the current directory to build the absolute path.
|
||||
/// Returns the absolute version of a path. Like [`std::path::Path::canonicalize`], but doesn't
|
||||
/// resolve symlinks.
|
||||
pub fn resolve_path<P: AsRef<Path>>(path: &P) -> Result<PathBuf> {
|
||||
let path = path.as_ref();
|
||||
let base_path;
|
||||
@ -135,7 +132,7 @@ pub fn resolve_path<P: AsRef<Path>>(path: &P) -> Result<PathBuf> {
|
||||
Ok(stack.iter().collect())
|
||||
}
|
||||
|
||||
// Convert a string to lowercase, with a fast path for ASCII strings.
|
||||
/// Convert a string to lowercase, with a fast path for ASCII strings.
|
||||
pub fn to_lowercase<S: AsRef<str>>(s: S) -> String {
|
||||
let s = s.as_ref();
|
||||
if s.is_ascii() {
|
||||
|
@ -9,10 +9,9 @@ fn completions_bash() {
|
||||
Command::new("bash").args(&["--noprofile", "--norc", "-c", source]).assert().success().stdout("").stderr("");
|
||||
}
|
||||
|
||||
// Elvish: the completions file uses editor commands to add completions to the
|
||||
// shell. However, Elvish does not support running editor commands from a
|
||||
// script, so we can't create a test for this.
|
||||
// <https://github.com/elves/elvish/issues/1299>
|
||||
// Elvish: the completions file uses editor commands to add completions to the shell. However,
|
||||
// Elvish does not support running editor commands from a script, so we can't create a test for
|
||||
// this. See: https://github.com/elves/elvish/issues/1299
|
||||
|
||||
#[test]
|
||||
fn completions_fish() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clap::{ArgEnum, Clap};
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
use clap::{ArgEnum, Clap};
|
||||
|
||||
#[derive(Clap, Debug)]
|
||||
struct App {
|
||||
#[clap(arg_enum)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user