completions/busctl: Port to argparse

This is much faster!
This commit is contained in:
Fabian Homborg 2018-11-12 18:53:30 +01:00
parent 2d2f7c8fb1
commit 7a20e8d64d

View file

@ -18,34 +18,74 @@ function __fish_busctl
command busctl $mode $argv --no-legend --no-pager 2>/dev/null command busctl $mode $argv --no-legend --no-pager 2>/dev/null
end end
# Only get the arguments to the actual command, skipping all options and arguments to options function _fish_busctl
function __fish_busctl_get_command_args set -l args a-address= s-show-machine u-unique A-acquired ä-activatable \
set -l skip m-match= S-size= l-list q-quiet v-verbose e-expect-reply= Ä-auto-start= \
set -l skip_next 0 1-allow-interactive-authorization= t-timeout= 2-augment-creds= U-user 3-system \
set -l cmd (commandline -opc) H/host= M/machine= n-no-pager N-no-legend h/help V-version
for token in $cmd set -l cmdline (commandline -opc) (commandline -ct)
switch $token set -e cmdline[1]
# Options that take arguments - when given without "=", the next token is the arg - skip it argparse $args -- $cmdline 2>/dev/null
case '--address' '--match' '--expect-reply' '--auto-start' '--allow-interactive-authorization' \ or return
'--timeout' '--augment-creds' '-H' '--host' '-M' '--machine' set -l cmd $argv[1]
set skip_next 1 set -e argv[1]
continue switch "$cmd"
# Skip all options themselves case list help
case '-*' # Accepts nothing
continue return
# Command args only start after a command case status
case 'status' 'monitor' 'capture' 'tree' 'introspect' 'call' 'get-property' 'set-property' # A service
set -e skip if not set -q argv[2]
continue __fish_busctl_busnames
# These take no arguments, so abort completion
case 'list' 'help'
break
case '*'
if test "$skip_next" -eq 1; or set -q skip
set skip_next 0
continue
end end
echo $token case monitor capture tree
# Services
__fish_busctl_busnames
case introspect
# Service Object Interface
if not set -q argv[2]
__fish_busctl_busnames
else if not set -q argv[3]
__fish_busctl_objects $argv[1]
else if not set -q argv[4]
__fish_busctl_interfaces $argv[1..2]
end
case call
# SERVICE OBJECT INTERFACE METHOD [SIGNATURE [ARGUMENT...]]
if not set -q argv[2]
__fish_busctl_busnames
else if not set -q argv[3]
__fish_busctl_objects $argv[1]
else if not set -q argv[4]
__fish_busctl_interfaces $argv[1..2]
else if not set -q argv[5]
__fish_busctl_members method $argv[1..3]
else if not set -q argv[6]
__fish_busctl_signature $argv[1..4]
end
case get-property
# SERVICE OBJECT INTERFACE PROPERTY...
if not set -q argv[2]
__fish_busctl_busnames
else if not set -q argv[3]
__fish_busctl_objects $argv[1]
else if not set -q argv[4]
__fish_busctl_interfaces $argv[1..2]
else
__fish_busctl_members property $argv[1..3]
end
case set-property
# SERVICE OBJECT INTERFACE PROPERTY SIGNATURE ARGUMENT...
if not set -q argv[2]
__fish_busctl_busnames
else if not set -q argv[3]
__fish_busctl_objects $argv[1]
else if not set -q argv[4]
__fish_busctl_interfaces $argv[1..2]
else if not set -q argv[5]
__fish_busctl_members property $argv[1..3]
else if not set -q argv[6]
__fish_busctl_members signature $argv[1..4]
end end
end end
end end
@ -74,36 +114,6 @@ function __fish_busctl_signature -a busname -a object -a interface -a member
| string match ".$member *" | while read a b c d; echo $c; end | string match ".$member *" | while read a b c d; echo $c; end
end end
# This function completes service/busname, object, interface and then whatever the arguments are
# i.e. if argv[1] is "method", complete methods in the fourth place
function __fish_busctl_soi
set -l args (__fish_busctl_get_command_args)
set -l num (count $args)
switch $num
case 0 # We have nothing, need busname
__fish_busctl_busnames
case 1 # We have busname, need object
__fish_busctl_objects $args
case 2 # We have busname and object, need interface
__fish_busctl_interfaces $args
case '*' # We have busname and object and interface, what we need now depends on the command, so we get it as argument
if test $num -ge 4; and set -q argv[2] # Check >= 4 to repeat the last type for get-property
# Signatures have to be handled specially, because they're dependent on the member (method/property)
# that's at the beginning of the line and prefixed with a "."
# I.e. `busctl introspect` will print ".Capacity", but the argument to give to `get-property` is "Capacity"
if test "$argv[2]" = "signature"
__fish_busctl_signature $args
else
__fish_busctl_members $argv[2] $args
end
else if test $num -ge 3; and set -q argv[1]
__fish_busctl_members $argv[1] $args
else
return 1
end
end
end
### Commands ### Commands
set -l commands list status monitor capture tree introspect call get-property set-property help set -l commands list status monitor capture tree introspect call get-property set-property help
@ -111,19 +121,7 @@ complete -f -e -c busctl
complete -f -c busctl -n "not __fish_seen_subcommand_from $commands" -a "$commands" complete -f -c busctl -n "not __fish_seen_subcommand_from $commands" -a "$commands"
### Arguments to commands ### Arguments to commands
# "status" only takes a single service as argument complete -f -c busctl -a '(_fish_busctl)'
complete -f -c busctl -n "__fish_seen_subcommand_from status; and not count (__fish_busctl_get_command_args)" -a "(__fish_busctl_busnames)"
# These take multiple services
complete -x -c busctl -n "__fish_seen_subcommand_from monitor capture tree" -a "(__fish_busctl_busnames)"
# Read the busctl_soi calls as "Complete service, then object, then interface and then the arguments
# e.g. `call` takes service object interface method signature arguments
# We can't complete the arguments (without parsing the signature, which can look like "a{sv}" for an array of string-to-variant dictionaries)
complete -x -c busctl -n "__fish_seen_subcommand_from call" -a "(__fish_busctl_soi method signature)"
complete -x -c busctl -n "__fish_seen_subcommand_from get-property" -a "(__fish_busctl_soi property)"
complete -x -c busctl -n "__fish_seen_subcommand_from set-property" -a "(__fish_busctl_soi property signature)"
complete -x -c busctl -n "__fish_seen_subcommand_from introspect" -a "(__fish_busctl_soi)"
# Flags # Flags
# These are incomplete as I have no idea how to complete --address= or --match= # These are incomplete as I have no idea how to complete --address= or --match=