# (C) 2010 magicant

# Completion script for the "ps" command.
# Supports POSIX 2008, procps 3.2.8, FreeBSD 8.1, OpenBSD 4.8, NetBSD 5.0,
# Mac OS X 10.6.4, SunOS 5.10, HP-UX 11i v3.

function completion/ps {

        typeset -x PS_PERSONALITY=posix
        case $("${WORDS[1]}" --version 2>/dev/null) in
                (*'procps'*) typeset type=procps ;;
                (*)          typeset type="$(uname 2>/dev/null)" ;;
        esac
        case $type in
                (procps) typeset long=true ;;
                (*)      typeset long= ;;
        esac

        typeset OPTIONS ARGOPT PREFIX
        OPTIONS=( #>#
        "A; print all processes"
        "a; print all processes with terminals"
        "G: ${long:+--Group:}; specify real group IDs of processes to print"
        "o: ${long:+--format:}; specify format items to print"
        "p: ${long:+--pid:}; specify process IDs of processes to print"
        "t: ${long:+--tty:}; specify terminals of processes to print"
        "U: ${long:+--User:}; specify real user IDs of processes to print"
        ) #<#

        case $type in (procps|*BSD|Darwin|SunOS|HP-UX)
                OPTIONS=("$OPTIONS" #>#
                "j; print job info"
                "l; print in the long format"
                ) #<#
                case $type in (procps|Darwin|SunOS|HP-UX)
                        OPTIONS=("$OPTIONS" #>#
                        "d; print all processes but session leaders"
                        "e; print all processes"
                        "f; print in the full format"
                        "u: ${long:+--user:}; specify effective user IDs of processes to print"
                        ) #<#
                        case $type in
                        (procps)
                                OPTIONS=("$OPTIONS" #>#
                                "g:; specify session IDs or effective group IDs of processes to print"
                                "--group:; specify effective group IDs of processes to print"
                                ) #<#
                                ;;
                        (*)
                                OPTIONS=("$OPTIONS" #>#
                                "g:; specify process group IDs of processes to print"
                                ) #<#
                                ;;
                        esac
                esac
        esac
        case $type in (procps)
                OPTIONS=("$OPTIONS" #>#
                "F; print in the extra full format"
                "m; print threads after each process"
                "N --deselect; print processes not selected by other options"
                "n:; specify the name list file"
                "T; print threads rather than processes"
                "Z M --context; print security contexts"
                "V --version; print version info"
                "--columns: --cols: --width:; specify the screen width"
                "--cumulative; include child processes' CPU time in their parent's"
                "--headers; print a header line for each screen page"
                "--info; print debugging info"
                "--lines: --rows:; specify the screen height"
                "--no-headers; don't print the header line"
                "--ppid:; specify parent process IDs of processes to print"
                "--sort:; specify sort keys"
                "--help"
                ) #<#
        esac
        case $type in (procps|*BSD|Darwin)
                OPTIONS=("$OPTIONS" #>#
                "O:; specify format items to print in addition to the default ones"
                "w; wide format"
                ) #<#
                case $type in (*BSD|Darwin)
                        OPTIONS=("$OPTIONS" #>#
                        "C; use the raw CPU percentage"
                        "c; print only the command name for the command column"
                        "L; print available format items"
                        "m; sort by memory usage"
                        "N:; specify the name list file"
                        "r; sort by current CPU usage"
                        "S; include child processes' CPU time in their parent's"
                        "T; print processes associated with the current terminal"
                        "v; print in the virtual memory format"
                        "x; print processes with terminals as well"
                        ) #<#
                        case $type in
                        (FreeBSD)
                                OPTIONS=("$OPTIONS" #>#
                                "d; print process family trees"
                                "f; print data even for swapped-out processes"
                                "H; print thread info"
                                "X; don't print processes with terminals"
                                "Z; print MAC labels as well"
                                ) #<#
                                ;;
                        (OpenBSD)
                                OPTIONS=("$OPTIONS" #>#
                                "k; print thread info"
                                "W:; specify a file to extract swap info from"
                                ) #<#
                                ;;
                        (NetBSD)
                                OPTIONS=("$OPTIONS" #>#
                                "k:; specify sort keys"
                                "s; print threads rather than processes"
                                "W:; specify a file to extract swap info from"
                                ) #<#
                                ;;
                        esac
                        case $type in
                        (Darwin)
                                OPTIONS=("$OPTIONS" #>#
                                "E; print environment variables as well"
                                "M; print thread info"
                                "X; don't print processes with terminals"
                                ) #<#
                                ;;
                        (*)
                                OPTIONS=("$OPTIONS" #>#
                                "e; print environment variables as well"
                                "M:; specify a core file to print"
                                "u; print in the user-oriented format"
                                ) #<#
                                ;;
                        esac
                esac
        esac
        case $type in (procps|SunOS|HP-UX)
                OPTIONS=("$OPTIONS" #>#
                "s: ${long:+--sid:}; specify session IDs of processes to print"
                ) #<#
                case $type in (procps|SunOS)
                        OPTIONS=("$OPTIONS" #>#
                        "L; print thread info"
                        "P; print running processor numbers (PSR) as well"
                        "y; print RSS instead of F and ADDR (with -l)"
                        ) #<#
                        case $type in (SunOS)
                                OPTIONS=("$OPTIONS" #>#
                                "Z; print zone info as well"
                                "z:; specify zones of processes to print"
                                ) #<#
                        esac
                esac
                case $type in (procps|HP-UX)
                        OPTIONS=("$OPTIONS" #>#
                        "C:; specify the name of process to print"
                        "H ${long:+--forest}; print process family trees"
                        "P; print process resource manager (PRM) info as well"
                        ) #<#
                        case $type in (HP-UX)
                                OPTIONS=("$OPTIONS" #>#
                                "R:; specify PRM process group IDs of processes to print"
                                "x; print in the extended format"
                                "Z:; specify processor set IDs of processes to print"
                                ) #<#
                        esac
                esac
        esac

        command -f completion//parseoptions -e
        case $ARGOPT in
        (-)
                command -f completion//completeoptions
                ;;
        (C)
                typeset word="${TARGETWORD#"$PREFIX"}"
                PREFIX=${TARGETWORD%"${word##*[ ,]}"}
                complete -P "$PREFIX" -- $(ps -A -o comm= 2>/dev/null)
                ;;
        (G|--[Gg]roup)
                complete -P "$PREFIX" -g
                ;;
        (g)
                typeset word="${TARGETWORD#"$PREFIX"}"
                PREFIX=${TARGETWORD%"${word##*[ ,]}"}
                case $type in
                (procps)
                        case $word in
                        (*[![:digit:]\ ,]*)
                                ;;
                        (*)
                                # complete a session ID
                                typeset sid tty
                                while read -r sid tty; do
                                        complete -P "$PREFIX" -R 0 -D "$tty" -- "$sid"
                                done 2>/dev/null <(ps -A -o sid= -o tty= | sort -u)
                                ;;
                        esac
                        complete -P "$PREFIX" -g
                        ;;
                (*)
                        ;;
                esac
                ;;
        ([MNnW])
                complete -P "$PREFIX" -f
                ;;
        ([kOo]|--format|--sort)
                # complete a format item
                typeset word="${TARGETWORD#"$PREFIX"}"
                PREFIX=${TARGETWORD%"${word##*[ ,+-]}"}
                case $type in
                (procps)
                        typeset key name
                        while read -r key name; do
                                complete -P "$PREFIX" -- "$key"
                        done <(ps L)
                        ;;
                (*BSD|Darwin)
                        complete -P "$PREFIX" -- $(ps -L 2>/dev/null)
                        ;;
                (*)
                        case $type in
                        (SunOS)
                                complete -P "$PREFIX" -- addr class ctid gid f \
                                        fname lwp nlwp osz pmem pri project \
                                        projid pset psr rgid rss ruid s sid \
                                        stime taskid uid wchan zone zoneid
                                ;;
                        (HP-UX)
                                complete -P "$PREFIX" -- addr cls cpu flags \
                                        gid pri prmgrp prmid pset rgid ruid \
                                        sid state stime sz uid wchan
                                ;;
                        esac
                        complete -P "$PREFIX" -- args comm etime group nice \
                                pcpu pgid pid ppid rgroup ruser time tty user vsz
                        ;;
                esac
                ;;
        (p|--pid|--ppid)
                # complete a process ID
                typeset pid args
                while read -r pid args; do
                        complete -P "$PREFIX" -D "$args" -- "$pid"
                done <(ps -A -o pid= -o args= 2>/dev/null)
                ;;
        (R)
                #TODO
                ;;
        (s|--sid)
                # complete a session ID
                typeset sid tty
                while read -r sid tty; do
                        complete -P "$PREFIX" -R 0 -D "$tty" -- "$sid"
                done 2>/dev/null <(ps -A -o sid= -o tty= | sort -u)
                ;;
        (t|--tty)
                typeset ttys
                ttys=($(ps -A -o tty=))
                complete -P "$PREFIX" -A '*[[:alnum:]]*' -- "$ttys" "${ttys#tty}"
                ;;
        ([Uu]|--[Uu]ser)
                complete -P "$PREFIX" -u
                ;;
        (Z)
                #TODO
                ;;
        (z)
                #TODO
                ;;
        (--columns|--cols|--width|--lines|--rows)
                ;;
        (*)
                command -f completion/ps::bsd
                ;;
        esac

}

# parse BSD style options
function completion/ps::bsd {
#TODO
}


# vim: set ft=sh ts=8 sts=8 sw=8 et:
