116038816SMartin Matuska# Copyright (c) 2010-2016, Aneurin Price <aneurin.price@gmail.com>
216038816SMartin Matuska
316038816SMartin Matuska# Permission is hereby granted, free of charge, to any person
416038816SMartin Matuska# obtaining a copy of this software and associated documentation
516038816SMartin Matuska# files (the "Software"), to deal in the Software without
616038816SMartin Matuska# restriction, including without limitation the rights to use,
716038816SMartin Matuska# copy, modify, merge, publish, distribute, sublicense, and/or sell
816038816SMartin Matuska# copies of the Software, and to permit persons to whom the
916038816SMartin Matuska# Software is furnished to do so, subject to the following
1016038816SMartin Matuska# conditions:
1116038816SMartin Matuska
1216038816SMartin Matuska# The above copyright notice and this permission notice shall be
1316038816SMartin Matuska# included in all copies or substantial portions of the Software.
1416038816SMartin Matuska
1516038816SMartin Matuska# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1616038816SMartin Matuska# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1716038816SMartin Matuska# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1816038816SMartin Matuska# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1916038816SMartin Matuska# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
2016038816SMartin Matuska# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2116038816SMartin Matuska# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2216038816SMartin Matuska# OTHER DEALINGS IN THE SOFTWARE.
2316038816SMartin Matuska
2416038816SMartin Matuska__ZFS_CMD="@sbindir@/zfs"
2516038816SMartin Matuska__ZPOOL_CMD="@sbindir@/zpool"
2616038816SMartin Matuska
2716038816SMartin Matuska# Disable bash's built-in hostname completion, as this makes it impossible to
2816038816SMartin Matuska# provide completions containing an @-sign, which is necessary for completing
2916038816SMartin Matuska# snapshot names. If bash_completion is in use, this will already be disabled
3016038816SMartin Matuska# and replaced with better completions anyway.
3116038816SMartin Matuskashopt -u hostcomplete
3216038816SMartin Matuska
3316038816SMartin Matuska__zfs_get_commands()
3416038816SMartin Matuska{
3516038816SMartin Matuska    $__ZFS_CMD 2>&1 | awk '/^\t[a-z]/ {print $1}' | cut -f1 -d '|' | uniq
3616038816SMartin Matuska}
3716038816SMartin Matuska
3816038816SMartin Matuska__zfs_get_properties()
3916038816SMartin Matuska{
4016038816SMartin Matuska    $__ZFS_CMD get 2>&1 | awk '$2 == "YES" || $2 == "NO" {print $1}'; echo all name space
4116038816SMartin Matuska}
4216038816SMartin Matuska
4316038816SMartin Matuska__zfs_get_editable_properties()
4416038816SMartin Matuska{
4516038816SMartin Matuska    $__ZFS_CMD get 2>&1 | awk '$2 == "YES" {print $1"="}'
4616038816SMartin Matuska}
4716038816SMartin Matuska
4816038816SMartin Matuska__zfs_get_inheritable_properties()
4916038816SMartin Matuska{
5016038816SMartin Matuska    $__ZFS_CMD get 2>&1 | awk '$3 == "YES" {print $1}'
5116038816SMartin Matuska}
5216038816SMartin Matuska
5316038816SMartin Matuska__zfs_list_datasets()
5416038816SMartin Matuska{
5516038816SMartin Matuska    $__ZFS_CMD list -H -o name -s name -t filesystem,volume "$@"
5616038816SMartin Matuska}
5716038816SMartin Matuska
5816038816SMartin Matuska__zfs_list_filesystems()
5916038816SMartin Matuska{
6016038816SMartin Matuska    $__ZFS_CMD list -H -o name -s name -t filesystem
6116038816SMartin Matuska}
6216038816SMartin Matuska
6316038816SMartin Matuska__zfs_match_snapshot()
6416038816SMartin Matuska{
6516038816SMartin Matuska    local base_dataset="${cur%@*}"
66*bb2d13b6SMartin Matuska    if [[ "$base_dataset" != "$cur" ]]
6716038816SMartin Matuska    then
6816038816SMartin Matuska        $__ZFS_CMD list -H -o name -s name -t snapshot -d 1 "$base_dataset"
6916038816SMartin Matuska    else
70*bb2d13b6SMartin Matuska        if [[ "$cur" != "" ]] && __zfs_list_datasets "$cur" &> /dev/null
7116038816SMartin Matuska        then
72681ce946SMartin Matuska            $__ZFS_CMD list -H -o name -s name -t filesystem,volume -r "$cur" | tail -n +2
7316038816SMartin Matuska            # We output the base dataset name even though we might be
7416038816SMartin Matuska            # completing a command that can only take a snapshot, because it
7516038816SMartin Matuska            # prevents bash from considering the completion finished when it
7616038816SMartin Matuska            # ends in the bare @.
7716038816SMartin Matuska            echo "$cur"
7816038816SMartin Matuska            echo "$cur@"
7916038816SMartin Matuska        else
8016038816SMartin Matuska            local datasets
8116038816SMartin Matuska            datasets="$(__zfs_list_datasets)"
8216038816SMartin Matuska            # As above
8316038816SMartin Matuska            echo "$datasets"
8416038816SMartin Matuska            if [[ "$cur" == */ ]]
8516038816SMartin Matuska            then
8616038816SMartin Matuska                # If the current command ends with a slash, then the only way
8716038816SMartin Matuska                # it can be completed with a single tab press (ie. in this pass)
8816038816SMartin Matuska                # is if it has exactly one child, so that's the only time we
8916038816SMartin Matuska                # need to offer a suggestion with an @ appended.
9016038816SMartin Matuska                local num_children
9116038816SMartin Matuska                # This is actually off by one as zfs list includes the named
9216038816SMartin Matuska                # dataset in addition to its children
9316038816SMartin Matuska                num_children=$(__zfs_list_datasets -d 1 "${cur%/}" 2> /dev/null | wc -l)
9416038816SMartin Matuska                if [[ $num_children != 2 ]]
9516038816SMartin Matuska                then
9616038816SMartin Matuska                    return 0
9716038816SMartin Matuska                fi
9816038816SMartin Matuska            fi
9916038816SMartin Matuska            echo "$datasets" | awk '{print $1 "@"}'
10016038816SMartin Matuska        fi
10116038816SMartin Matuska    fi
10216038816SMartin Matuska}
10316038816SMartin Matuska
10416038816SMartin Matuska__zfs_match_snapshot_or_bookmark()
10516038816SMartin Matuska{
10616038816SMartin Matuska    local base_dataset="${cur%[#@]*}"
107*bb2d13b6SMartin Matuska    if [[ "$base_dataset" != "$cur" ]]
10816038816SMartin Matuska    then
10916038816SMartin Matuska        if [[ $cur == *@* ]]
11016038816SMartin Matuska        then
11116038816SMartin Matuska            $__ZFS_CMD list -H -o name -s name -t snapshot -d 1 "$base_dataset"
11216038816SMartin Matuska        else
11316038816SMartin Matuska            $__ZFS_CMD list -H -o name -s name -t bookmark -d 1 "$base_dataset"
11416038816SMartin Matuska        fi
11516038816SMartin Matuska    else
11616038816SMartin Matuska        $__ZFS_CMD list -H -o name -s name -t filesystem,volume
117*bb2d13b6SMartin Matuska        if [[ -e "$cur" ]] && $__ZFS_CMD list -H -o name -s name -t filesystem,volume "$cur" &> /dev/null
11816038816SMartin Matuska        then
11916038816SMartin Matuska            echo "$cur@"
12016038816SMartin Matuska            echo "$cur#"
12116038816SMartin Matuska        fi
12216038816SMartin Matuska    fi
12316038816SMartin Matuska}
12416038816SMartin Matuska
12516038816SMartin Matuska__zfs_match_multiple_snapshots()
12616038816SMartin Matuska{
12716038816SMartin Matuska    local existing_opts
12816038816SMartin Matuska    existing_opts="$(expr "$cur" : '\(.*\)[%,]')"
129*bb2d13b6SMartin Matuska    if [[ -e "$existing_opts" ]]
13016038816SMartin Matuska    then
13116038816SMartin Matuska        local base_dataset="${cur%@*}"
132*bb2d13b6SMartin Matuska        if [[ "$base_dataset" != "$cur" ]]
13316038816SMartin Matuska        then
13416038816SMartin Matuska            local cur="${cur##*,}"
13516038816SMartin Matuska            if [[ $cur =~ ^%|%.*% ]]
13616038816SMartin Matuska            then
13716038816SMartin Matuska                # correct range syntax is start%end
13816038816SMartin Matuska                return 1
13916038816SMartin Matuska            fi
14016038816SMartin Matuska            local range_start
14116038816SMartin Matuska            range_start="$(expr "$cur" : '\(.*%\)')"
14216038816SMartin Matuska            # shellcheck disable=SC2016
14316038816SMartin Matuska            $__ZFS_CMD list -H -o name -s name -t snapshot -d 1 "$base_dataset" | sed 's$.*@$'"$range_start"'$g'
14416038816SMartin Matuska        fi
14516038816SMartin Matuska    else
14616038816SMartin Matuska        __zfs_match_snapshot_or_bookmark
14716038816SMartin Matuska    fi
14816038816SMartin Matuska}
14916038816SMartin Matuska
15016038816SMartin Matuska__zfs_list_volumes()
15116038816SMartin Matuska{
15216038816SMartin Matuska    $__ZFS_CMD list -H -o name -s name -t volume
15316038816SMartin Matuska}
15416038816SMartin Matuska
15516038816SMartin Matuska__zfs_argument_chosen()
15616038816SMartin Matuska{
15716038816SMartin Matuska    local word property
15816038816SMartin Matuska    for word in $(seq $((COMP_CWORD-1)) -1 2)
15916038816SMartin Matuska    do
16016038816SMartin Matuska        local prev="${COMP_WORDS[$word]}"
16116038816SMartin Matuska        if [[ ${COMP_WORDS[$word-1]} != -[tos] ]]
16216038816SMartin Matuska        then
16316038816SMartin Matuska            if [[ "$prev" == [^,]*,* ]] || [[ "$prev" == *[@:\#]* ]]
16416038816SMartin Matuska            then
16516038816SMartin Matuska                return 0
16616038816SMartin Matuska            fi
16716038816SMartin Matuska            for property in "$@"
16816038816SMartin Matuska            do
16916038816SMartin Matuska                if [[ $prev == "$property"* ]]
17016038816SMartin Matuska                then
17116038816SMartin Matuska                    return 0
17216038816SMartin Matuska                fi
17316038816SMartin Matuska            done
17416038816SMartin Matuska        fi
17516038816SMartin Matuska    done
17616038816SMartin Matuska    return 1
17716038816SMartin Matuska}
17816038816SMartin Matuska
17916038816SMartin Matuska__zfs_complete_ordered_arguments()
18016038816SMartin Matuska{
18116038816SMartin Matuska    local list1=$1
18216038816SMartin Matuska    local list2=$2
18316038816SMartin Matuska    local cur=$3
18416038816SMartin Matuska    local extra=$4
18516038816SMartin Matuska    # shellcheck disable=SC2086
18616038816SMartin Matuska    if __zfs_argument_chosen $list1
18716038816SMartin Matuska    then
188681ce946SMartin Matuska        mapfile -t COMPREPLY < <(compgen -W "$list2 $extra" -- "$cur")
18916038816SMartin Matuska    else
190681ce946SMartin Matuska        mapfile -t COMPREPLY < <(compgen -W "$list1 $extra" -- "$cur")
19116038816SMartin Matuska    fi
19216038816SMartin Matuska}
19316038816SMartin Matuska
19416038816SMartin Matuska__zfs_complete_multiple_options()
19516038816SMartin Matuska{
19616038816SMartin Matuska    local options=$1
19716038816SMartin Matuska    local cur=$2
19816038816SMartin Matuska    local existing_opts
19916038816SMartin Matuska
200681ce946SMartin Matuska    mapfile -t COMPREPLY < <(compgen -W "$options" -- "${cur##*,}")
20116038816SMartin Matuska    existing_opts=$(expr "$cur" : '\(.*,\)')
202*bb2d13b6SMartin Matuska    if [[ -n "$existing_opts" ]]
20316038816SMartin Matuska    then
20416038816SMartin Matuska        COMPREPLY=( "${COMPREPLY[@]/#/${existing_opts}}" )
20516038816SMartin Matuska    fi
20616038816SMartin Matuska}
20716038816SMartin Matuska
20816038816SMartin Matuska__zfs_complete_switch()
20916038816SMartin Matuska{
21016038816SMartin Matuska    local options=$1
21116038816SMartin Matuska    if [[ ${cur:0:1} == - ]]
21216038816SMartin Matuska    then
213681ce946SMartin Matuska        mapfile -t COMPREPLY < <(compgen -W "-{$options}" -- "$cur")
21416038816SMartin Matuska        return 0
21516038816SMartin Matuska    else
21616038816SMartin Matuska        return 1
21716038816SMartin Matuska    fi
21816038816SMartin Matuska}
21916038816SMartin Matuska
22016038816SMartin Matuska__zfs_complete_nospace()
22116038816SMartin Matuska{
22216038816SMartin Matuska    # Google indicates that there may still be bash versions out there that
22316038816SMartin Matuska    # don't have compopt.
22416038816SMartin Matuska    if type compopt &> /dev/null
22516038816SMartin Matuska    then
22616038816SMartin Matuska        compopt -o nospace
22716038816SMartin Matuska    fi
22816038816SMartin Matuska}
22916038816SMartin Matuska
23016038816SMartin Matuska__zfs_complete()
23116038816SMartin Matuska{
23216038816SMartin Matuska    local cur prev cmd cmds
23316038816SMartin Matuska    COMPREPLY=()
23416038816SMartin Matuska    if type _get_comp_words_by_ref &> /dev/null
23516038816SMartin Matuska    then
23616038816SMartin Matuska        # Don't split on colon
23716038816SMartin Matuska        _get_comp_words_by_ref -n : -c cur -p prev -w COMP_WORDS -i COMP_CWORD
23816038816SMartin Matuska    else
23916038816SMartin Matuska        cur="${COMP_WORDS[COMP_CWORD]}"
24016038816SMartin Matuska        prev="${COMP_WORDS[COMP_CWORD-1]}"
24116038816SMartin Matuska    fi
24216038816SMartin Matuska    cmd="${COMP_WORDS[1]}"
24316038816SMartin Matuska
24416038816SMartin Matuska    if [[ ${prev##*/} == zfs ]]
24516038816SMartin Matuska    then
24616038816SMartin Matuska        cmds=$(__zfs_get_commands)
247681ce946SMartin Matuska        mapfile -t COMPREPLY < <(compgen -W "$cmds -?" -- "$cur")
24816038816SMartin Matuska        return 0
24916038816SMartin Matuska    fi
25016038816SMartin Matuska
25116038816SMartin Matuska    case "${cmd}" in
25216038816SMartin Matuska        bookmark)
25316038816SMartin Matuska            if __zfs_argument_chosen
25416038816SMartin Matuska            then
255681ce946SMartin Matuska                mapfile -t COMPREPLY < <(compgen -W "${prev%@*}# ${prev/@/#}" -- "$cur")
25616038816SMartin Matuska            else
257681ce946SMartin Matuska                mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur")
25816038816SMartin Matuska            fi
25916038816SMartin Matuska            ;;
26016038816SMartin Matuska        clone)
26116038816SMartin Matuska            case "${prev}" in
26216038816SMartin Matuska                -o)
263681ce946SMartin Matuska                    mapfile -t COMPREPLY < <(compgen -W "$(__zfs_get_editable_properties)" -- "$cur")
26416038816SMartin Matuska                    __zfs_complete_nospace
26516038816SMartin Matuska                    ;;
26616038816SMartin Matuska                *)
26716038816SMartin Matuska                    if ! __zfs_complete_switch "o,p"
26816038816SMartin Matuska                    then
26916038816SMartin Matuska                        if __zfs_argument_chosen
27016038816SMartin Matuska                        then
271681ce946SMartin Matuska                            mapfile -t COMPREPLY < <(compgen -W "$(__zfs_list_datasets)" -- "$cur")
27216038816SMartin Matuska                        else
273681ce946SMartin Matuska                            mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur")
27416038816SMartin Matuska                        fi
27516038816SMartin Matuska                    fi
27616038816SMartin Matuska                    ;;
27716038816SMartin Matuska            esac
27816038816SMartin Matuska            ;;
27916038816SMartin Matuska        get)
28016038816SMartin Matuska            case "${prev}" in
28116038816SMartin Matuska                -d)
282681ce946SMartin Matuska                    mapfile -t COMPREPLY < <(compgen -W "" -- "$cur")
28316038816SMartin Matuska                    ;;
28416038816SMartin Matuska                -t)
28516038816SMartin Matuska                    __zfs_complete_multiple_options "filesystem volume snapshot bookmark all" "$cur"
28616038816SMartin Matuska                    ;;
28716038816SMartin Matuska                -s)
28816038816SMartin Matuska                    __zfs_complete_multiple_options "local default inherited temporary received none" "$cur"
28916038816SMartin Matuska                    ;;
29016038816SMartin Matuska                -o)
29116038816SMartin Matuska                    __zfs_complete_multiple_options "name property value source received all" "$cur"
29216038816SMartin Matuska                    ;;
29316038816SMartin Matuska                *)
29416038816SMartin Matuska                    if ! __zfs_complete_switch "H,r,p,d,o,t,s"
29516038816SMartin Matuska                    then
29616038816SMartin Matuska                        # shellcheck disable=SC2046
29716038816SMartin Matuska                        if __zfs_argument_chosen $(__zfs_get_properties)
29816038816SMartin Matuska                        then
299681ce946SMartin Matuska                            mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur")
30016038816SMartin Matuska                        else
30116038816SMartin Matuska                            __zfs_complete_multiple_options "$(__zfs_get_properties)" "$cur"
30216038816SMartin Matuska                        fi
30316038816SMartin Matuska                    fi
30416038816SMartin Matuska                    ;;
30516038816SMartin Matuska            esac
30616038816SMartin Matuska            ;;
30716038816SMartin Matuska        inherit)
30816038816SMartin Matuska            if ! __zfs_complete_switch "r"
30916038816SMartin Matuska            then
31016038816SMartin Matuska                __zfs_complete_ordered_arguments "$(__zfs_get_inheritable_properties)" "$(__zfs_match_snapshot)" "$cur"
31116038816SMartin Matuska            fi
31216038816SMartin Matuska            ;;
31316038816SMartin Matuska        list)
31416038816SMartin Matuska            case "${prev}" in
31516038816SMartin Matuska                -d)
316681ce946SMartin Matuska                    mapfile -t COMPREPLY < <(compgen -W "" -- "$cur")
31716038816SMartin Matuska                    ;;
31816038816SMartin Matuska                -t)
31916038816SMartin Matuska                    __zfs_complete_multiple_options "filesystem volume snapshot bookmark all" "$cur"
32016038816SMartin Matuska                    ;;
32116038816SMartin Matuska                -o)
32216038816SMartin Matuska                    __zfs_complete_multiple_options "$(__zfs_get_properties)" "$cur"
32316038816SMartin Matuska                    ;;
32416038816SMartin Matuska                -s|-S)
325681ce946SMartin Matuska                    mapfile -t COMPREPLY < <(compgen -W "$(__zfs_get_properties)" -- "$cur")
32616038816SMartin Matuska                    ;;
32716038816SMartin Matuska                *)
32816038816SMartin Matuska                    if ! __zfs_complete_switch "H,r,d,o,t,s,S"
32916038816SMartin Matuska                    then
330681ce946SMartin Matuska                        mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur")
33116038816SMartin Matuska                    fi
33216038816SMartin Matuska                    ;;
33316038816SMartin Matuska            esac
33416038816SMartin Matuska            ;;
33516038816SMartin Matuska        promote)
336681ce946SMartin Matuska            mapfile -t COMPREPLY < <(compgen -W "$(__zfs_list_filesystems)" -- "$cur")
33716038816SMartin Matuska            ;;
33816038816SMartin Matuska        rollback)
33916038816SMartin Matuska            if ! __zfs_complete_switch "r,R,f"
34016038816SMartin Matuska            then
341681ce946SMartin Matuska                mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur")
34216038816SMartin Matuska            fi
34316038816SMartin Matuska            ;;
34416038816SMartin Matuska        send)
34516038816SMartin Matuska            if ! __zfs_complete_switch "D,n,P,p,R,v,e,L,i,I"
34616038816SMartin Matuska            then
34716038816SMartin Matuska                if __zfs_argument_chosen
34816038816SMartin Matuska                then
349681ce946SMartin Matuska                    mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur")
35016038816SMartin Matuska                else
35116038816SMartin Matuska                    if [[ $prev == -*i* ]]
35216038816SMartin Matuska                    then
353681ce946SMartin Matuska                        mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot_or_bookmark)" -- "$cur")
35416038816SMartin Matuska                    else
355681ce946SMartin Matuska                        mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur")
35616038816SMartin Matuska                    fi
35716038816SMartin Matuska                fi
35816038816SMartin Matuska            fi
35916038816SMartin Matuska            ;;
36016038816SMartin Matuska        snapshot)
36116038816SMartin Matuska            case "${prev}" in
36216038816SMartin Matuska                -o)
363681ce946SMartin Matuska                    mapfile -t COMPREPLY < <(compgen -W "$(__zfs_get_editable_properties)" -- "$cur")
36416038816SMartin Matuska                    __zfs_complete_nospace
36516038816SMartin Matuska                    ;;
36616038816SMartin Matuska                *)
36716038816SMartin Matuska                    if ! __zfs_complete_switch "o,r"
36816038816SMartin Matuska                    then
369681ce946SMartin Matuska                        mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur")
37016038816SMartin Matuska                        __zfs_complete_nospace
37116038816SMartin Matuska                    fi
37216038816SMartin Matuska                    ;;
37316038816SMartin Matuska            esac
37416038816SMartin Matuska            ;;
37516038816SMartin Matuska        set)
37616038816SMartin Matuska            __zfs_complete_ordered_arguments "$(__zfs_get_editable_properties)" "$(__zfs_match_snapshot)" "$cur"
37716038816SMartin Matuska            __zfs_complete_nospace
37816038816SMartin Matuska            ;;
37916038816SMartin Matuska        upgrade)
38016038816SMartin Matuska            case "${prev}" in
38116038816SMartin Matuska                -a|-V|-v)
382681ce946SMartin Matuska                    mapfile -t COMPREPLY < <(compgen -W "" -- "$cur")
38316038816SMartin Matuska                    ;;
38416038816SMartin Matuska                *)
38516038816SMartin Matuska                    if ! __zfs_complete_switch "a,V,v,r"
38616038816SMartin Matuska                    then
387681ce946SMartin Matuska                        mapfile -t COMPREPLY < <(compgen -W "$(__zfs_list_filesystems)" -- "$cur")
38816038816SMartin Matuska                    fi
38916038816SMartin Matuska                    ;;
39016038816SMartin Matuska            esac
39116038816SMartin Matuska            ;;
39216038816SMartin Matuska        destroy)
39316038816SMartin Matuska            if ! __zfs_complete_switch "d,f,n,p,R,r,v"
39416038816SMartin Matuska            then
39516038816SMartin Matuska                __zfs_complete_multiple_options "$(__zfs_match_multiple_snapshots)" "$cur"
39616038816SMartin Matuska                __zfs_complete_nospace
39716038816SMartin Matuska            fi
39816038816SMartin Matuska            ;;
39916038816SMartin Matuska        *)
400681ce946SMartin Matuska            mapfile -t COMPREPLY < <(compgen -W "$(__zfs_match_snapshot)" -- "$cur")
40116038816SMartin Matuska            ;;
40216038816SMartin Matuska    esac
40316038816SMartin Matuska    if type __ltrim_colon_completions &> /dev/null
40416038816SMartin Matuska    then
40516038816SMartin Matuska        __ltrim_colon_completions "$cur"
40616038816SMartin Matuska    fi
40716038816SMartin Matuska    return 0
40816038816SMartin Matuska}
40916038816SMartin Matuska
41016038816SMartin Matuska__zpool_get_commands()
41116038816SMartin Matuska{
41216038816SMartin Matuska    $__ZPOOL_CMD 2>&1 | awk '/^\t[a-z]/ {print $1}' | uniq
41316038816SMartin Matuska}
41416038816SMartin Matuska
41516038816SMartin Matuska__zpool_get_properties()
41616038816SMartin Matuska{
41716038816SMartin Matuska    $__ZPOOL_CMD get 2>&1 | awk '$2 == "YES" || $2 == "NO" {print $1}'; echo all
41816038816SMartin Matuska}
41916038816SMartin Matuska
42016038816SMartin Matuska__zpool_get_editable_properties()
42116038816SMartin Matuska{
42216038816SMartin Matuska    $__ZPOOL_CMD get 2>&1 | awk '$2 == "YES" {print $1"="}'
42316038816SMartin Matuska}
42416038816SMartin Matuska
42516038816SMartin Matuska__zpool_list_pools()
42616038816SMartin Matuska{
42716038816SMartin Matuska    $__ZPOOL_CMD list -H -o name
42816038816SMartin Matuska}
42916038816SMartin Matuska
43016038816SMartin Matuska__zpool_complete()
43116038816SMartin Matuska{
43216038816SMartin Matuska    local cur prev cmd cmds pools
43316038816SMartin Matuska    COMPREPLY=()
43416038816SMartin Matuska    cur="${COMP_WORDS[COMP_CWORD]}"
43516038816SMartin Matuska    prev="${COMP_WORDS[COMP_CWORD-1]}"
43616038816SMartin Matuska    cmd="${COMP_WORDS[1]}"
43716038816SMartin Matuska
43816038816SMartin Matuska    if [[ ${prev##*/} == zpool ]]
43916038816SMartin Matuska    then
44016038816SMartin Matuska        cmds=$(__zpool_get_commands)
441681ce946SMartin Matuska        mapfile -t COMPREPLY < <(compgen -W "$cmds" -- "$cur")
44216038816SMartin Matuska        return 0
44316038816SMartin Matuska    fi
44416038816SMartin Matuska
44516038816SMartin Matuska    case "${cmd}" in
44616038816SMartin Matuska        get)
44716038816SMartin Matuska            __zfs_complete_ordered_arguments "$(__zpool_get_properties)" "$(__zpool_list_pools)" "$cur"
44816038816SMartin Matuska            return 0
44916038816SMartin Matuska            ;;
45016038816SMartin Matuska        import)
45116038816SMartin Matuska            if [[ $prev == -d ]]
45216038816SMartin Matuska            then
45316038816SMartin Matuska                _filedir -d
45416038816SMartin Matuska            else
455681ce946SMartin Matuska                mapfile -t COMPREPLY < <(compgen -W "$(__zpool_list_pools) -d" -- "$cur")
45616038816SMartin Matuska            fi
45716038816SMartin Matuska            return 0
45816038816SMartin Matuska            ;;
45916038816SMartin Matuska        set)
46016038816SMartin Matuska            __zfs_complete_ordered_arguments "$(__zpool_get_editable_properties)" "$(__zpool_list_pools)" "$cur"
46116038816SMartin Matuska            __zfs_complete_nospace
46216038816SMartin Matuska            return 0
46316038816SMartin Matuska            ;;
46416038816SMartin Matuska        add|attach|clear|create|detach|offline|online|remove|replace)
46516038816SMartin Matuska            pools="$(__zpool_list_pools)"
46616038816SMartin Matuska            # shellcheck disable=SC2086
46716038816SMartin Matuska            if __zfs_argument_chosen $pools
46816038816SMartin Matuska            then
46916038816SMartin Matuska                _filedir
47016038816SMartin Matuska            else
471681ce946SMartin Matuska                mapfile -t COMPREPLY < <(compgen -W "$pools" -- "$cur")
47216038816SMartin Matuska            fi
47316038816SMartin Matuska            return 0
47416038816SMartin Matuska            ;;
47516038816SMartin Matuska        *)
476681ce946SMartin Matuska            mapfile -t COMPREPLY < <(compgen -W "$(__zpool_list_pools)" -- "$cur")
47716038816SMartin Matuska            return 0
47816038816SMartin Matuska            ;;
47916038816SMartin Matuska    esac
48016038816SMartin Matuska
48116038816SMartin Matuska}
48216038816SMartin Matuska
48316038816SMartin Matuskacomplete -F __zfs_complete zfs
48416038816SMartin Matuskacomplete -F __zpool_complete zpool
485