aboutsummaryrefslogtreecommitdiffhomepage
path: root/share/completions/busctl.fish
blob: 695c30355d0b9cbe732218d73679571bcb14ec6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# Fish completions for systemd's "busctl" dbus tool
# TODO:
# One issue is that sometimes these will come to a dead-end e.g. when a particular interface has no properties
# Another is that some busnames aren't accesible by the current user
# but this can't be predicted via the user that owns that name, e.g. `org.freedesktop.login1`
# is usually owned by a root-owned process, yet accessible (at least in part) by normal users

# A simple wrapper to call busctl with the correct mode and output
function __fish_busctl
	# TODO: If there's a "--address" argument we need to pass that
	# We also need to pass the _last_ of these (`busctl --user --system` operates on the system bus)
	set -l mode
    if __fish_contains_opt user
		set mode "--user"
	else
		set mode "--system"
	end
    command busctl $mode $argv --no-legend --no-pager ^/dev/null
end
	
# Only get the arguments to the actual command, skipping all options and arguments to options
function __fish_busctl_get_command_args
	set -l skip
	set -l skip_next 0
	set -l cmd (commandline -opc)
	for token in $cmd
		switch $token
			# Options that take arguments - when given without "=", the next token is the arg - skip it
			case '--address' '--match' '--expect-reply' '--auto-start' '--allow-interactive-authorization' \
				'--timeout' '--augment-creds' '-H' '--host' '-M' '--machine'
				set skip_next 1
				continue
			# Skip all options themselves
			case '-*'
				continue
			# Command args only start after a command
			case 'status' 'monitor' 'capture' 'tree' 'introspect' 'call' 'get-property' 'set-property'
				set -e skip
				continue
			# 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
				echo $token
		end
	end
end
				
function __fish_busctl_busnames
	__fish_busctl list --acquired | string replace -r '\s+.*$' ''
	# Describe unique names (":1.32") with their process (e.g. `:1.32\tsteam`)
	__fish_busctl list --unique | string replace -r '\s+\S+\s+(\S+)\s+.*$' '\t$1'
end

function __fish_busctl_objects -a busname
	__fish_busctl tree --list $busname | string replace -r '\s+.*$' ''
end

function __fish_busctl_interfaces -a busname -a object
	__fish_busctl introspect --list $busname $object | string replace -r '\s+.*$' ''
end
	
function __fish_busctl_members -a type -a busname -a object -a interface
	__fish_busctl introspect --list $busname $object $interface \
	| string match -- "* $type *" | string replace -r '.(\S+) .*' '$1'
end

function __fish_busctl_signature -a busname -a object -a interface -a member
	__fish_busctl introspect --list $busname $object $interface \
	| string match ".$member *" | while read a b c d; echo $c; 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
set -l commands list status monitor capture tree introspect call get-property set-property help

complete -f -e -c busctl
complete -A -f -c busctl -n "not __fish_seen_subcommand_from $commands" -a "$commands"

### Arguments to commands
# "status" only takes a single service as argument
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
# These are incomplete as I have no idea how to complete --address= or --match=
complete -f -c busctl -n "__fish_seen_subcommand_from call" -l quiet -d 'Suppress message payload display'
complete -f -c busctl -n "__fish_seen_subcommand_from call get-property" -l verbose
complete -f -c busctl -n "__fish_seen_subcommand_from tree" -l list -d 'Show a flat list instead of a tree'
complete -x -c busctl -n "__fish_seen_subcommand_from call" -l expect-reply -a "yes no"
complete -x -c busctl -n "__fish_seen_subcommand_from call" -l auto-start -a "yes no" -d 'Activate the peer if necessary'
complete -x -c busctl -n "__fish_seen_subcommand_from call" -l allow-interactive-authorization -a "yes no"
complete -x -c busctl -n "__fish_seen_subcommand_from call" -l timeout -a "(seq 0 100)"
complete -f -c busctl -n "__fish_seen_subcommand_from list" -l unique -d 'Only show unique (:X.Y) names'
complete -f -c busctl -n "__fish_seen_subcommand_from list" -l acquired -d 'Only show well-known names'
complete -f -c busctl -n "__fish_seen_subcommand_from list" -l activatable -d 'Only show peers that have not been activated yet but can be'
complete -f -c busctl -n "__fish_seen_subcommand_from list" -l show-machine -d 'Show the machine the peers belong to'
complete -x -c busctl -n "__fish_seen_subcommand_from list status" -l augment-creds -a "yes no"
complete -f -c busctl -l user
complete -f -c busctl -l system
complete -f -c busctl -s H -l host -a "(__fish_print_hostnames)"
complete -f -c busctl -s M -l machine -a "(__fish_systemd_machines)"
complete -f -c busctl -l no-pager
complete -f -c busctl -l no-legend
complete -f -c busctl -s h -l help
complete -f -c busctl -l version