diff --git a/README.md b/README.md index 05ceede..a57665d 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ A cd command that learns your habits - [zsh](#zsh) - [bash](#bash) - [fish](#fish) + - [POSIX](#posix) - [Configuration](#configuration) - [`init` flags](#init-flags) - [Environment variables](#environment-variables) @@ -89,6 +90,20 @@ Add the following line to your `~/.config/fish/config.fish`: zoxide init fish | source ``` +#### POSIX + +Add the following line to your shell's configuration file (or, run it manually): + +``` sh +eval "$(zoxide init posix)" +``` + +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 we store our hook in `PS1`, in order to be evaluated every time the prompt is +displayed. + +NOTE: There is no PWD hook provided for POSIX shells. + ## Configuration ### `init` flags diff --git a/src/main.rs b/src/main.rs index 2d22a54..8d64a43 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,7 @@ pub fn main() -> Result<()> { match opt { Zoxide::Add(add) => add.run(&env)?, - Zoxide::Init(init) => init.run(), + Zoxide::Init(init) => init.run()?, Zoxide::Migrate(migrate) => migrate.run(&env)?, Zoxide::Query(query) => query.run(&env)?, Zoxide::Remove(remove) => remove.run(&env)?, diff --git a/src/subcommand/init.rs b/src/subcommand/init.rs index ff237b2..49a6c0c 100644 --- a/src/subcommand/init.rs +++ b/src/subcommand/init.rs @@ -1,7 +1,9 @@ +use anyhow::{bail, Result}; use clap::arg_enum; -use std::io::{self, Write}; use structopt::StructOpt; +use std::io::{self, Write}; + #[derive(Debug, StructOpt)] #[structopt(about = "Generates shell configuration")] pub struct Init { @@ -25,16 +27,19 @@ pub struct Init { } impl Init { - pub fn run(&self) { + pub fn run(&self) -> Result<()> { let config = match self.shell { Shell::bash => BASH_CONFIG, Shell::fish => FISH_CONFIG, + Shell::posix => POSIX_CONFIG, Shell::zsh => ZSH_CONFIG, }; let stdout = io::stdout(); let mut handle = stdout.lock(); + // If any `writeln!` call fails to write to stdout, we assume the user's + // computer is on fire and panic. writeln!(handle, "{}", config.z).unwrap(); if !self.no_define_aliases { writeln!(handle, "{}", config.alias).unwrap(); @@ -43,8 +48,13 @@ impl Init { match self.hook { Hook::none => (), Hook::prompt => writeln!(handle, "{}", config.hook.prompt).unwrap(), - Hook::pwd => writeln!(handle, "{}", config.hook.pwd).unwrap(), - }; + Hook::pwd => match config.hook.pwd { + Some(pwd_hook) => writeln!(handle, "{}", pwd_hook).unwrap(), + None => bail!("PWD hooks are currently unsupported on this shell."), + }, + } + + Ok(()) } } @@ -54,6 +64,7 @@ arg_enum! { enum Shell { bash, fish, + posix, zsh, } } @@ -73,7 +84,7 @@ const BASH_CONFIG: ShellConfig = ShellConfig { alias: BASH_ALIAS, hook: HookConfig { prompt: BASH_HOOK_PROMPT, - pwd: BASH_HOOK_PWD, + pwd: Some(BASH_HOOK_PWD), }, }; @@ -82,7 +93,16 @@ const FISH_CONFIG: ShellConfig = ShellConfig { alias: FISH_ALIAS, hook: HookConfig { prompt: FISH_HOOK_PROMPT, - pwd: FISH_HOOK_PWD, + pwd: Some(FISH_HOOK_PWD), + }, +}; + +const POSIX_CONFIG: ShellConfig = ShellConfig { + z: POSIX_Z, + alias: POSIX_ALIAS, + hook: HookConfig { + prompt: POSIX_HOOK_PROMPT, + pwd: None, }, }; @@ -91,7 +111,7 @@ const ZSH_CONFIG: ShellConfig = ShellConfig { alias: ZSH_ALIAS, hook: HookConfig { prompt: ZSH_HOOK_PROMPT, - pwd: ZSH_HOOK_PWD, + pwd: Some(ZSH_HOOK_PWD), }, }; @@ -103,7 +123,7 @@ struct ShellConfig { struct HookConfig { prompt: &'static str, - pwd: &'static str, + pwd: Option<&'static str>, } const BASH_Z: &str = r#" @@ -119,12 +139,17 @@ z() { if [ "$#" -eq 0 ]; then _z_cd ~ || return "$?" elif [ "$#" -eq 1 ] && [ "$1" = '-' ]; then - _z_cd ~- || return "$?" + if [ -n "$OLDPWD" ]; then + _z_cd "$OLDPWD" || return "$?" + else + echo "zoxide: \$OLDPWD is not set" + return 1 + fi else - result="$(zoxide query $@)" || return "$?" + result="$(zoxide query "$@")" || return "$?" case "$result" in "query: "*) - _z_cd "${result:7}" || return "$?" + _z_cd "${result#query: }" || return "$?" ;; *) if [ -n "$result" ]; then @@ -177,6 +202,8 @@ function z end "#; +const POSIX_Z: &str = BASH_Z; + const ZSH_Z: &str = BASH_Z; const BASH_ALIAS: &str = r#" @@ -193,6 +220,8 @@ abbr -a zq 'zoxide query' abbr -a zr 'zoxide remove' "#; +const POSIX_ALIAS: &str = BASH_ALIAS; + const ZSH_ALIAS: &str = BASH_ALIAS; const BASH_HOOK_PROMPT: &str = r#" @@ -212,6 +241,17 @@ function _zoxide_hook --on-event fish_prompt end "#; +const POSIX_HOOK_PROMPT: &str = r#" +_zoxide_hook() { + zoxide add > /dev/null +} + +case "$PS1" in + *\$\(_zoxide_hook\)*) ;; + *) PS1="\$(_zoxide_hook)${PS1}" ;; +esac +"#; + const ZSH_HOOK_PROMPT: &str = r#" _zoxide_hook() { zoxide add