mirror of
https://github.com/Llewellynvdm/zoxide.git
synced 2024-11-25 22:17:33 +00:00
Release v0.5.0
This commit is contained in:
parent
9dd1679e5a
commit
c82ef66fac
@ -5,13 +5,15 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## Unreleased
|
||||
## [0.5.0] - 2020-10-30
|
||||
|
||||
### Added
|
||||
|
||||
- Inaccessible directories are no longer removed; zoxide can now remember paths on removable devices.
|
||||
- `$_ZO_EXCLUDE_DIRS` now supports globs.
|
||||
- `zoxide init` now defines `__zoxide_z*` functions that can be aliased as needed.
|
||||
- Support for the [xonsh](https://xon.sh/) shell.
|
||||
- `zoxide import` can now import from Autojump.
|
||||
|
||||
### Changed
|
||||
|
||||
@ -19,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Fixed
|
||||
|
||||
- Clobber conflicting alias definitions in Bash/POSIX/Zsh shells.
|
||||
- Clobber conflicting alias definitions in bash/fish/zsh/POSIX shells.
|
||||
|
||||
### Removed
|
||||
|
||||
@ -176,6 +178,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- GitHub Actions pipeline to build and upload releases.
|
||||
- Support for the `zsh` shell.
|
||||
|
||||
[0.5.0]: https://github.com/ajeetdsouza/zoxide/compare/v0.4.3...v0.5.0
|
||||
[0.4.3]: https://github.com/ajeetdsouza/zoxide/compare/v0.4.2...v0.4.3
|
||||
[0.4.2]: https://github.com/ajeetdsouza/zoxide/compare/v0.4.1...v0.4.2
|
||||
[0.4.1]: https://github.com/ajeetdsouza/zoxide/compare/v0.4.0...v0.4.1
|
||||
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -585,7 +585,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "zoxide"
|
||||
version = "0.4.3"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"askama",
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "zoxide"
|
||||
version = "0.4.3"
|
||||
version = "0.5.0"
|
||||
authors = ["Ajeet D'Souza <98ajeet@gmail.com>"]
|
||||
description = "A faster way to navigate your filesystem"
|
||||
repository = "https://github.com/ajeetdsouza/zoxide/"
|
||||
|
24
README.md
24
README.md
@ -17,6 +17,7 @@ A faster way to navigate your filesystem
|
||||
- [fish](#fish)
|
||||
- [POSIX](#posix-shells)
|
||||
- [PowerShell](#powershell)
|
||||
- [xonsh](#xonsh)
|
||||
- [zsh](#zsh)
|
||||
- [Configuration](#configuration)
|
||||
- [`init` flags](#init-flags)
|
||||
@ -168,21 +169,6 @@ Add the following line to your shell's configuration file:
|
||||
eval "$(zoxide init posix --hook prompt)"
|
||||
```
|
||||
|
||||
The `prompt` hook is recommended for POSIX shells because the default `pwd`
|
||||
hook creates a temporary file for every session, which are only deleted upon
|
||||
reboot. If you do want to use `pwd` hooks instead, you may want to set up traps
|
||||
to perform a cleanup once the shell exits:
|
||||
|
||||
```sh
|
||||
trap '_zoxide_cleanup' EXIT HUP KILL TERM
|
||||
trap '_zoxide_cleanup; trap - INT; kill -s INT "$$"' INT
|
||||
trap '_zoxide_cleanup; trap - QUIT; kill -s QUIT "$$"' QUIT
|
||||
```
|
||||
|
||||
NOTE: If you modify your `PS1` at any point, you may need to re-run the above
|
||||
command. This is due to the fact that the hook is stored in `PS1`, in order to
|
||||
be evaluated every time the prompt is displayed.
|
||||
|
||||
#### PowerShell
|
||||
|
||||
Add the following line to your profile:
|
||||
@ -194,6 +180,14 @@ Invoke-Expression (& {
|
||||
})
|
||||
```
|
||||
|
||||
#### xonsh
|
||||
|
||||
Add the following line to your profile (usually `~/.xonshrc`):
|
||||
|
||||
```xonsh
|
||||
execx($(zoxide init xonsh), 'exec', __xonsh__.ctx, filename='zoxide')
|
||||
```
|
||||
|
||||
#### zsh
|
||||
|
||||
Add the following line to your `~/.zshrc`:
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::cmd::Cmd;
|
||||
use super::Cmd;
|
||||
use crate::config;
|
||||
use crate::util;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::cmd::Cmd;
|
||||
use super::Cmd;
|
||||
use crate::config;
|
||||
use crate::import::{Autojump, Import as _, Z};
|
||||
use crate::util;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::cmd::Cmd;
|
||||
use super::Cmd;
|
||||
use crate::config;
|
||||
use crate::shell::{self, Hook, Opts};
|
||||
|
||||
|
@ -5,6 +5,7 @@ mod query;
|
||||
mod remove;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::{AppSettings, Clap};
|
||||
|
||||
pub use add::Add;
|
||||
pub use import::Import;
|
||||
@ -15,3 +16,25 @@ pub use remove::Remove;
|
||||
pub trait Cmd {
|
||||
fn run(&self) -> Result<()>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clap)]
|
||||
#[clap(about, author, global_setting(AppSettings::GlobalVersion), global_setting(AppSettings::VersionlessSubcommands), version = env!("ZOXIDE_VERSION"))]
|
||||
pub enum App {
|
||||
Add(Add),
|
||||
Import(Import),
|
||||
Init(Init),
|
||||
Query(Query),
|
||||
Remove(Remove),
|
||||
}
|
||||
|
||||
impl Cmd for App {
|
||||
fn run(&self) -> Result<()> {
|
||||
match self {
|
||||
App::Add(cmd) => cmd.run(),
|
||||
App::Import(cmd) => cmd.run(),
|
||||
App::Init(cmd) => cmd.run(),
|
||||
App::Query(cmd) => cmd.run(),
|
||||
App::Remove(cmd) => cmd.run(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::cmd::Cmd;
|
||||
use super::Cmd;
|
||||
use crate::config;
|
||||
use crate::fzf::Fzf;
|
||||
use crate::util;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::cmd::Cmd;
|
||||
use super::Cmd;
|
||||
use crate::config;
|
||||
use crate::fzf::Fzf;
|
||||
use crate::store::Query;
|
||||
@ -49,7 +49,11 @@ impl Cmd for Remove {
|
||||
};
|
||||
|
||||
if !store.remove(path) {
|
||||
bail!("path not found in store: {}", &path)
|
||||
let path = util::resolve_path(&path)?;
|
||||
let path = util::path_to_str(&path)?;
|
||||
if !store.remove(path) {
|
||||
bail!("path not found in store: {}", &path)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -1,11 +1,9 @@
|
||||
use super::Import;
|
||||
use crate::util;
|
||||
|
||||
use crate::store::{Dir, Epoch, Store};
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
pub struct Autojump {
|
||||
@ -15,44 +13,50 @@ pub struct Autojump {
|
||||
|
||||
impl Import for Autojump {
|
||||
fn import<P: AsRef<Path>>(&self, store: &mut Store, path: P) -> Result<()> {
|
||||
let file = File::open(path).context("could not open autojump database")?;
|
||||
let reader = BufReader::new(file);
|
||||
let path = path.as_ref();
|
||||
let buffer = fs::read_to_string(path)
|
||||
.with_context(|| format!("could not open autojump database: {}", path.display()))?;
|
||||
|
||||
for (idx, line) in reader.lines().enumerate() {
|
||||
let mut entries = Vec::new();
|
||||
for (idx, line) in buffer.lines().enumerate() {
|
||||
(|| -> Result<()> {
|
||||
let line = line?;
|
||||
if line.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let split_idx = line
|
||||
.find('\t')
|
||||
.with_context(|| format!("invalid entry: {}", line))?;
|
||||
let (rank, path) = line.split_at(split_idx);
|
||||
let (rank, path) = (|| {
|
||||
let mut split = line.splitn(2, '\t');
|
||||
let rank = split.next()?;
|
||||
let path = split.next()?;
|
||||
Some((rank, path))
|
||||
})()
|
||||
.with_context(|| format!("invalid entry: {}", line))?;
|
||||
|
||||
let rank = rank
|
||||
.parse()
|
||||
.parse::<f64>()
|
||||
.with_context(|| format!("invalid rank: {}", rank))?;
|
||||
|
||||
let path = if self.resolve_symlinks {
|
||||
util::canonicalize
|
||||
} else {
|
||||
util::resolve_path
|
||||
}(&path)?;
|
||||
let path = util::path_to_str(&path)?;
|
||||
|
||||
if store.dirs.iter_mut().find(|dir| dir.path == path).is_none() {
|
||||
store.dirs.push(Dir {
|
||||
path: path.into(),
|
||||
rank,
|
||||
last_accessed: self.now,
|
||||
});
|
||||
store.modified = true;
|
||||
}
|
||||
|
||||
entries.push((path, rank));
|
||||
Ok(())
|
||||
})()
|
||||
.with_context(|| format!("line {}: error reading from z database", idx + 1))?;
|
||||
.with_context(|| format!("line {}: error reading from autojump database", idx + 1))?;
|
||||
}
|
||||
|
||||
let rank_sum = entries.iter().map(|(_, rank)| rank).sum::<f64>();
|
||||
for (path, rank) in entries.iter() {
|
||||
if store
|
||||
.dirs
|
||||
.iter_mut()
|
||||
.find(|dir| &dir.path == path)
|
||||
.is_none()
|
||||
{
|
||||
store.dirs.push(Dir {
|
||||
path: path.to_string(),
|
||||
rank: rank / rank_sum,
|
||||
last_accessed: self.now,
|
||||
});
|
||||
store.modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -1,5 +1,4 @@
|
||||
use super::Import;
|
||||
use crate::util;
|
||||
|
||||
use crate::store::{Dir, Store};
|
||||
use anyhow::{Context, Result};
|
||||
@ -33,13 +32,6 @@ impl Import for Z {
|
||||
})()
|
||||
.with_context(|| format!("invalid entry: {}", line))?;
|
||||
|
||||
let path = if self.resolve_symlinks {
|
||||
util::canonicalize
|
||||
} else {
|
||||
util::resolve_path
|
||||
}(&path)?;
|
||||
let path = util::path_to_str(&path)?;
|
||||
|
||||
let rank = rank
|
||||
.parse()
|
||||
.with_context(|| format!("invalid rank: {}", rank))?;
|
||||
@ -54,7 +46,7 @@ impl Import for Z {
|
||||
dir.last_accessed = dir.last_accessed.max(last_accessed);
|
||||
}
|
||||
None => store.dirs.push(Dir {
|
||||
path: path.into(),
|
||||
path: path.to_string(),
|
||||
rank,
|
||||
last_accessed,
|
||||
}),
|
||||
|
41
src/main.rs
41
src/main.rs
@ -7,43 +7,20 @@ mod shell;
|
||||
mod store;
|
||||
mod util;
|
||||
|
||||
use crate::cmd::{Add, Cmd, Import, Init, Query, Remove};
|
||||
use crate::cmd::{App, Cmd};
|
||||
use crate::error::SilentExit;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::{AppSettings, Clap};
|
||||
use clap::Clap;
|
||||
|
||||
use std::process;
|
||||
|
||||
#[derive(Debug, Clap)]
|
||||
#[clap(
|
||||
about,
|
||||
author,
|
||||
global_setting(AppSettings::GlobalVersion),
|
||||
global_setting(AppSettings::VersionlessSubcommands),
|
||||
version = env!("ZOXIDE_VERSION"))]
|
||||
enum Opts {
|
||||
Add(Add),
|
||||
Import(Import),
|
||||
Init(Init),
|
||||
Query(Query),
|
||||
Remove(Remove),
|
||||
}
|
||||
|
||||
pub fn main() -> Result<()> {
|
||||
let opts = Opts::parse();
|
||||
|
||||
let result: Result<()> = match opts {
|
||||
Opts::Add(cmd) => cmd.run(),
|
||||
Opts::Import(cmd) => cmd.run(),
|
||||
Opts::Init(cmd) => cmd.run(),
|
||||
Opts::Query(cmd) => cmd.run(),
|
||||
Opts::Remove(cmd) => cmd.run(),
|
||||
};
|
||||
|
||||
result.map_err(|e| match e.downcast::<SilentExit>() {
|
||||
Ok(SilentExit { code }) => process::exit(code),
|
||||
// TODO: change the error prefix to `zoxide:`
|
||||
Err(e) => e,
|
||||
})
|
||||
App::parse()
|
||||
.run()
|
||||
.map_err(|e| match e.downcast::<SilentExit>() {
|
||||
Ok(SilentExit { code }) => process::exit(code),
|
||||
// TODO: change the error prefix to `zoxide:`
|
||||
Err(e) => e,
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user