Fix exit codes in z and fzf

This commit is contained in:
Ajeet D'Souza 2020-03-17 12:34:53 +05:30
parent 146e5709fb
commit 03e8cd47a2
5 changed files with 87 additions and 61 deletions

View File

@ -25,7 +25,7 @@ class z(ranger.api.commands.Command):
output = subprocess.check_output(["zoxide", "query"] + self.args[1:]) output = subprocess.check_output(["zoxide", "query"] + self.args[1:])
output = output.decode("utf-8") output = output.decode("utf-8")
query_prefix = "query:" query_prefix = "query: "
if output.startswith(query_prefix): if output.startswith(query_prefix):
directory = output[len(query_prefix) :].strip() directory = output[len(query_prefix) :].strip()

View File

@ -23,7 +23,7 @@ pub fn main() -> Result<()> {
let opt = Zoxide::from_args(); let opt = Zoxide::from_args();
let env = envy::prefixed("_ZO_") let env = envy::prefixed("_ZO_")
.from_env::<Env>() .from_env::<Env>()
.with_context(|| "Could not parse environment variables")?; .with_context(|| "could not parse environment variables")?;
match opt { match opt {
Zoxide::Add(add) => add.run(&env)?, Zoxide::Add(add) => add.run(&env)?,

View File

@ -108,55 +108,57 @@ struct HookConfig {
const BASH_Z: &str = r#" const BASH_Z: &str = r#"
_z_cd() { _z_cd() {
cd "${@}" > /dev/null cd "$@" || return "$?"
if [ "${?}" -eq 0 ]; then
if [ -n "$_ZO_ECHO" ]; then if [ -n "$_ZO_ECHO" ]; then
echo "${PWD}" echo "$PWD"
fi fi
fi
} }
z() { z() {
if [ "${#}" -eq 0 ]; then if [ "$#" -eq 0 ]; then
_z_cd "${HOME}" _z_cd ~ || return "$?"
elif [ "${#}" -eq 1 ] && [ "${1}" = '-' ]; then elif [ "$#" -eq 1 ] && [ "$1" = '-' ]; then
_z_cd '-' _z_cd ~- || return "$?"
else else
local result=$(zoxide query "${@}") result="$(zoxide query $@)" || return "$?"
case "${result}" in case "$result" in
"query: "*) "query: "*)
_z_cd "${result:7}" _z_cd "${result:7}" || return "$?"
;; ;;
*) *)
if [ -n "${result}" ]; then if [ -n "$result" ]; then
echo "${result}" echo "$result"
fi fi
;; ;;
esac esac
fi fi
} }
"#; "#;
const FISH_Z: &str = r#" const FISH_Z: &str = r#"
function _z_cd function _z_cd
cd "$argv" > /dev/null cd "$argv"
or return "$status"
if [ "$status" -eq 0 ] commandline -f repaint
commandline -f repaint
if [ -n "$_ZO_ECHO" ] if [ -n "$_ZO_ECHO" ]
echo "$PWD" echo "$PWD"
end
end end
end end
function z function z
set -l argc (count "$argv") set argc (count "$argv")
if [ "$argc" -eq 0 ] if [ "$argc" -eq 0 ]
_z_cd "$HOME" _z_cd "$HOME"
else if [ "$argc" -eq 1 ] or return "$status"
and [ "$argv[1]" = '-' ]
else if [ "$argc" -eq 1 ]; and [ "$argv[1]" = '-' ]
_z_cd '-' _z_cd '-'
or return "$status"
else else
# TODO: use string-collect from fish 3.1.0 once it has wider adoption # TODO: use string-collect from fish 3.1.0 once it has wider adoption
set -l IFS '' set -l IFS ''
@ -165,6 +167,7 @@ function z
switch "$result" switch "$result"
case 'query: *' case 'query: *'
_z_cd (string sub -s 8 "$result") _z_cd (string sub -s 8 "$result")
or return "$status"
case '*' case '*'
if [ -n "$result" ] if [ -n "$result" ]
echo "$result" echo "$result"
@ -194,12 +197,12 @@ const ZSH_ALIAS: &str = BASH_ALIAS;
const BASH_HOOK_PROMPT: &str = r#" const BASH_HOOK_PROMPT: &str = r#"
_zoxide_hook() { _zoxide_hook() {
zoxide add zoxide add
} }
case "$PROMPT_COMMAND" in case "$PROMPT_COMMAND" in
*_zoxide_hook*) ;; *_zoxide_hook*) ;;
*) PROMPT_COMMAND="_zoxide_hook${PROMPT_COMMAND:+;${PROMPT_COMMAND}}" ;; *) PROMPT_COMMAND="_zoxide_hook${PROMPT_COMMAND:+;${PROMPT_COMMAND}}" ;;
esac esac
"#; "#;
@ -211,27 +214,27 @@ end
const ZSH_HOOK_PROMPT: &str = r#" const ZSH_HOOK_PROMPT: &str = r#"
_zoxide_hook() { _zoxide_hook() {
zoxide add zoxide add
} }
[[ -n "${precmd_functions[(r)_zoxide_hook]}" ]] || { [[ -n "${precmd_functions[(r)_zoxide_hook]}" ]] || {
precmd_functions+=(_zoxide_hook) precmd_functions+=(_zoxide_hook)
} }
"#; "#;
const BASH_HOOK_PWD: &str = r#" const BASH_HOOK_PWD: &str = r#"
_zoxide_hook() { _zoxide_hook() {
if [ -z "${_ZO_PWD}" ]; then if [ -z "${_ZO_PWD}" ]; then
_ZO_PWD="${PWD}" _ZO_PWD="${PWD}"
elif [ "${_ZO_PWD}" != "${PWD}" ]; then elif [ "${_ZO_PWD}" != "${PWD}" ]; then
_ZO_PWD="${PWD}" _ZO_PWD="${PWD}"
zoxide add zoxide add
fi fi
} }
case "$PROMPT_COMMAND" in case "$PROMPT_COMMAND" in
*_zoxide_hook*) ;; *_zoxide_hook*) ;;
*) PROMPT_COMMAND="_zoxide_hook${PROMPT_COMMAND:+;${PROMPT_COMMAND}}" ;; *) PROMPT_COMMAND="_zoxide_hook${PROMPT_COMMAND:+;${PROMPT_COMMAND}}" ;;
esac esac
"#; "#;
@ -243,7 +246,7 @@ end
const ZSH_HOOK_PWD: &str = r#" const ZSH_HOOK_PWD: &str = r#"
_zoxide_hook() { _zoxide_hook() {
zoxide add zoxide add
} }
chpwd_functions=(${chpwd_functions[@]} "_zoxide_hook") chpwd_functions=(${chpwd_functions[@]} "_zoxide_hook")

View File

@ -1,6 +1,6 @@
use crate::env::Env; use crate::env::Env;
use crate::util; use crate::util;
use anyhow::Result; use anyhow::{bail, Result};
use std::path::Path; use std::path::Path;
use structopt::StructOpt; use structopt::StructOpt;
@ -15,14 +15,15 @@ pub struct Query {
impl Query { impl Query {
pub fn run(mut self, env: &Env) -> Result<()> { pub fn run(mut self, env: &Env) -> Result<()> {
let path_opt = if self.interactive { let path_opt = if self.interactive {
self.query_interactive(env) self.query_interactive(env)?
} else { } else {
self.query(env) self.query(env)?
}?; };
if let Some(path) = path_opt { match path_opt {
println!("query: {}", path.trim()); Some(path) => println!("query: {}", path.trim()),
} None => bail!("no match found"),
};
Ok(()) Ok(())
} }
@ -41,10 +42,10 @@ impl Query {
let now = util::get_current_time()?; let now = util::get_current_time()?;
if let Some(dir) = util::get_db(env)?.query(&self.keywords, now) { if let Some(dir) = util::get_db(env)?.query(&self.keywords, now) {
return Ok(Some(dir.path)); Ok(Some(dir.path))
} else {
Ok(None)
} }
Ok(None)
} }
fn query_interactive(&mut self, env: &Env) -> Result<Option<String>> { fn query_interactive(&mut self, env: &Env) -> Result<Option<String>> {

View File

@ -2,7 +2,7 @@ use crate::db::DB;
use crate::dir::Dir; use crate::dir::Dir;
use crate::env::Env; use crate::env::Env;
use crate::types::Epoch; use crate::types::Epoch;
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, bail, Context, Result};
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::process::{Command, Stdio}; use std::process::{Command, Stdio};
use std::time::SystemTime; use std::time::SystemTime;
@ -25,15 +25,16 @@ pub fn get_current_time() -> Result<Epoch> {
} }
pub fn fzf_helper(now: Epoch, mut dirs: Vec<Dir>) -> Result<Option<String>> { pub fn fzf_helper(now: Epoch, mut dirs: Vec<Dir>) -> Result<Option<String>> {
let fzf = Command::new("fzf") let mut fzf = Command::new("fzf")
.arg("-n2..") .arg("-n2..")
.stdin(Stdio::piped()) .stdin(Stdio::piped())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.spawn() .spawn()
.with_context(|| anyhow!("could not launch fzf"))?; .with_context(|| anyhow!("could not launch fzf"))?;
let mut fzf_stdin = fzf let fzf_stdin = fzf
.stdin .stdin
.as_mut()
.ok_or_else(|| anyhow!("could not connect to fzf stdin"))?; .ok_or_else(|| anyhow!("could not connect to fzf stdin"))?;
for dir in dirs.iter_mut() { for dir in dirs.iter_mut() {
@ -56,8 +57,9 @@ pub fn fzf_helper(now: Epoch, mut dirs: Vec<Dir>) -> Result<Option<String>> {
.with_context(|| anyhow!("could not write into fzf stdin"))?; .with_context(|| anyhow!("could not write into fzf stdin"))?;
} }
let mut fzf_stdout = fzf let fzf_stdout = fzf
.stdout .stdout
.as_mut()
.ok_or_else(|| anyhow!("could not connect to fzf stdout"))?; .ok_or_else(|| anyhow!("could not connect to fzf stdout"))?;
let mut output = String::new(); let mut output = String::new();
@ -65,5 +67,25 @@ pub fn fzf_helper(now: Epoch, mut dirs: Vec<Dir>) -> Result<Option<String>> {
.read_to_string(&mut output) .read_to_string(&mut output)
.with_context(|| anyhow!("could not read from fzf stdout"))?; .with_context(|| anyhow!("could not read from fzf stdout"))?;
Ok(output.get(12..).map(str::to_string)) let status = fzf.wait().with_context(|| "could not wait on fzf")?;
match status.code() {
// normal exit
Some(0) => match output.get(12..) {
Some(path) => Ok(Some(path.to_string())),
None => bail!("fzf returned invalid output"),
},
// no match
Some(1) => Ok(None),
// error
Some(2) => bail!("fzf returned an error"),
// terminated by a signal
Some(128..=254) | None => bail!("fzf was terminated"),
// unknown
_ => bail!("fzf returned an unknown error"),
}
} }