euank / pazi

An autojump "zap to directory" helper

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

z -h tries to cd into the help output

sdemos opened this issue · comments

I ran z -h to see what I could do and hit some confusing output -

$ z -h
pazi_cd:cd:7: file name too long: pazi 0.0.2\nEuan Kemp <euank@euank.com>\nA fast autojump tool\n\nUSAGE:\n    pazi [FLAGS] [OPTIONS] [dir_target] [SUBCOMMAND]\n\nFLAGS:\n    -d, --dir            print a directory matching a pattern; should be used via the 'z' function 'init' creates\n    -h, --help           Prints help information\n    -i, --interactive    interactively search directory matches\n    -V, --version        Prints version information\n\nOPTIONS:\n        --add-dir <directory>    add a directory to the frecency index\n        --debug <debug>          print debug information to stderr [env: PAZI_DEBUG=]\n\nARGS:\n    <dir_target>    \n\nSUBCOMMANDS:\n    help      Prints this message or the help of the given subcommand(s)\n    import    Import from another autojump program\n    init      Prints intialization logic for the given shell to eval

I noticed that z --help does the thing I expect. I dug into it a little bit and it looks like the zsh function pazi_cd only checks for the --help explicitly. That also means that z --version has a similar issue

$ z --version
pazi_cd:cd:7: no such file or directory: pazi 0.0.2

I don't know if the best solution is to just add checks for all possible help and version flags, or if there is some more general solution I didn't think of immediately.

After thinking about this a little, I think there may be a somewhat elegant solution possible.

The real problem here is that pazi needs to be run and then the output acted upon from shell based on the flags given.
Right now, I'm using shell to try and guess what the output will be by duplicating a tiny subset of flag parsing.

An alternate solution would be to duplicate no flag parsing, but to pass more information back up to the caller, that is for pazi_cd to call pazi --dir and get back enough information to know whether it can safely cd or not. On pazi's side, we can easily include type information (e.g. enum Result { CdResult(Dir), OutputResult((Output, ExitCode)) }).

This seems like a much better approach on the shell end of things. One way to accomplish this could be to have a first line of output with a well known set of possible values (e.g. it could be cd | print | error each of which would then do a well-defined thing with the remainder). This is still better than the eval that fasd does here.

However, since we have so few possible modes of operation, I think we can just overload exit-codes. Since pazi --dir may be called directly, it might make sense to have an opt in flag for this so the alias can have the extra information and other callers don't necessarily get it, but it might make sense to just always leave it on.

Concretely, what I'm suggesting is that pazi_cd turns into something like the following:

pazi_cd() {
    output="$(pazi --meta-exit-codes --dir -- "$@")"
    case $? in
      0) cd "${output}";; # success
      1) exit 1;; # error no output
      2) echo "${output}";; # success, print output (e.g. 'pazi')
      3) echo "${output}" && exit 1;; # error, output
    esac
}

Pazi would then be modified to interpret --meta-exit-codes as "re-parse the trailing args as the real args, and wrap output with more exit-code stuff".

Apologies for being so verbose in describing this; I know you probably have long-since got the point and it's really not all that complicated. I think it even could work to fix this problem :)

@LinuxMercedes what do you think?

Also, since it might give you a laugh @sdemos, the idea I thought about before the one in the above comment was to write a library that converts a clap-rs App into a posix-sh getopt parsing structure, use that to generate even more pazi init code, and go from there... I hope I'm not missing something obvious in the above because I really don't want to have to implement this backup idea.

It seems like either of the solutions you mentioned in the first comment would fix the issue.

The second comment seems like it would...work?

commented

@euank I particularly like the exit-code-parsing option, although I think you could collapse your error handling into

  1) [ "$output" != "" ] && echo "${output}"; exit 1;;

I can't see anything that would stop this from working with either bash or zsh.

Also, if we wanted to eventually be able to return multiple error codes, it might make sense for us to make 0 correspond to a path being output, 1 correspond to non-path OK output, and everything greater correspond to error codes. Basically, something like this:

pazi_cd() {
    output="$(pazi --meta-exit-codes --dir -- "$@")"
    ret=$?
    case $ret in
      0) cd "${output}";; # success, cd somewhere
      1) echo "${output}";; # success, print output (e.g. 'pazi')
      *) [ "$output" != "" ] && echo "${output}"; exit $ret;; # error
    esac
}

Or, if you really care about returning 1 in the case of an error, we could map "print output" to 127 or something.

I implemented my idea from above, which I believe resolves this issue; I'll ping this issue again once a pazi release includes that change as well.

awesome! thanks.