#!/bin/zsh # # Figure out where to get the best help, and get it. # # Install this function by placing it in your FPATH and then # adding to your .zshrc the lines: # unalias run-help # autoload -Uz run-help # .run-help.eval() { output="$( eval "COLUMNS=$COLUMNS $1" 2>&1 )" || return [[ -n $output ]] || return print "$output" | ${=PAGER:-more} } run-help() { emulate -RL zsh local HELPDIR="${HELPDIR:-@runhelpdir@}" [[ $1 == "." ]] && 1="dot" [[ $1 == ":" ]] && 1="colon" # Check whether Util/helpfiles has been used to generate zsh help if [[ $# == 0 || $1 == "-l" ]] then if [[ -d $HELPDIR ]] then echo "Here is a list of topics for which special help is available:" echo "" print -rc $HELPDIR/*(:t) else echo "There is no list of special help topics available at this time." fi return 0 elif [[ -n "${HELPDIR:-}" && -r $HELPDIR/$1 && $1 != compctl ]] then ${=PAGER:-more} $HELPDIR/$1 return $? fi # No zsh help; use "whence" to figure out where else we might look local what places noalias newline=' ' integer i=0 didman=0 places=( "${(@f)$(builtin whence -va $1)}" ) if [[ $places = *"not found"* && $1 != ${(Q)1} ]]; then # Different when unquoted, so try stripping quotes. places=( "${(@f)$(builtin whence -va ${(Q)1})}" ) if (( ${#places} )); then set -- "${(Q)@}" fi # Quotation is significant to aliases, so suppress lookup. noalias=1 fi { while ((i++ < $#places)) do what=$places[$i] [[ -n $noalias && $what = *" is an alias "* ]] && continue builtin print -r $what case $what in (*( is an alias for (noglob|nocorrect))*) [[ ${what[(w)7]:t} != ${what[(w)1]} ]] && run_help_orig_cmd=${what[(w)1]} run-help ${what[(w)7]:t} ;; (*( is an alias)*) [[ ${what[(w)6]:t} != ${what[(w)1]} ]] && run_help_orig_cmd=${what[(w)1]} run-help ${what[(w)6]:t} ;; (*( is a * builtin)) case ${what[(w)1]} in (compctl) man zshcompctl;; (comp*) man zshcompwid;; (bindkey|vared|zle) man zshzle;; (*setopt) man zshoptions;; (cap|getcap|setcap) ;& (clone) ;& (ln|mkdir|mv|rm|rmdir|sync) ;& (sched) ;& (echotc|echoti|sched|stat|zprof|zpty|zsocket|zstyle|ztcp) man zshmodules;; (zftp) man zshftpsys;; (*) man zshbuiltins;; esac ;; (*( is hashed to *)) man ${what[(w)-1]:t} ;; (*( is a reserved word)) man zshmisc ;; ( comp*( is a* function)* ) man zshcompsys ;; ( zf*( is a* function)* ) man zshzftpsys ;; ( ((run-help*|which-command) is a* function)* ) man zshcontrib ;; ( * ) if (( ! didman++ )); then local cmd_args help builtin read -zr cmd_args # Get the original command line. builtin print -z "$cmd_args" # Put it back on the buffer stack. # Retain only subcommands & options. cmd_args=( ${${(z)cmd_args}[(r)${run_help_orig_cmd:-$1},(r)(-|--)]} ) (( $#cmd_args )) && shift cmd_args whence "run-help-$1:t" >/dev/null && eval "run-help-$1:t ${(@q)cmd_args}" && return # For safety, skip all option flags & anything that looks like a file. while [[ $#cmd_args -gt 0 && ( -e $~cmd_args[1] || $cmd_args[1] == [-+]* ) ]]; do shift cmd_args done # Try if we're dealing with a subcommand and can get help on that. if [[ -n $cmd_args[1] ]]; then # The order in which we try these matters. for help in "$cmd_args[1] "{--help,-h} {-h,--help}" $cmd_args[1]"; do .run-help.eval "$1:t $help" && return done fi # Try the man page. POSIXLY_CORRECT=1 man $1:t 2>/dev/null && return # Try getting help on the main command. for help in -h --help; do .run-help.eval "$1:t $help" && return done if [[ $what = *( is a* function)* ]]; then local func=$what[(w)1] # Try to show function source from file, because parsed functions # don't contain comments. autoload +X -Uz $func [[ -n $functions_source[$func] ]] && ${=PAGER:-more} -- $functions_source[$func] && return builtin functions $func | ${=PAGER:-more} && return fi print -u2 "run-help: no help found for '$what[(w)1]'" return 1 fi ;; esac if ((i < $#places && ! didman)) then builtin print -nP "%SPress any key for more help or q to quit%s" builtin read -k what [[ $what != $newline ]] && echo [[ $what == [qQ] ]] && break fi done } always { unset run_help_orig_cmd } } run-help "$@"