4 [[ ${@[(r)--]} = '--' ]] && shift ${@[(i)--]}
5 local -a completions=() completions_display=()
6 local index=0 name id sel_type="$1"
9 (node) compset -P '*[#.:/@]' ;;
10 (desktop) compset -P '*[#.:]' ;;
11 (monitor) compset -P '*[#.]' ;;
14 case "$sel_type $IPREFIX" in
16 local ipfx=${${IPREFIX##*@}%:}
18 if completions=("${(@f)$(bspc query --names -D -m ${ipfx} 2> /dev/null)}") ;then
19 until ((++index > $#completions)) do
20 completions[index]="^${index}:${completions[index]}"
22 completions+='focused'
23 _describe "${sel_type} selector" completions $@ -S '' -J ${sel_type}
27 [ -n "$ipfx[(r)#]" ] &&
34 bspc query -N -n .window 2> /dev/null |
37 if which xdotool &> /dev/null ;then
38 name=$(xdotool getwindowname $id 2> /dev/null)
39 elif which xprop &> /dev/null ;then
40 name=$(xprop -id $id -notype WM_NAME 2> /dev/null) &&
41 [[ "$name" = 'WM_NAME ='* ]] &&
42 name="${${name#*\"}%\"*}" ||
45 name="install xdotool or xprop to see window titles here"
47 completions+="$id:$name"
50 ((desktop|monitor)*[^:.])
51 local max_name_len=0 max_index_len i
52 local -a snames names ids
53 bspc query -${(U)sel_type[1]} 2> /dev/null |
56 name=$(bspc query --names -${(U)sel_type[1]} -${sel_type[1]} $id 2> /dev/null)
57 [[ "$name" == *[:.!]* ]] &&
58 sel_name="%${name//:/\\:}" ||
60 ((max_name_len = $#sel_name > max_name_len ? $#sel_name : max_name_len))
65 max_index_len=$(($#index + 1))
66 ((max_name_len >= max_name_len)) && ((max_name_len=max_name_len + 1))
67 for ((i = 1 ; i <= $#ids ; i++)) ;do
68 (($#ids[i] <= max_name_len)) &&
69 completions_display+="${(r($max_name_len+1))ids[i]}:${names[i]}" ||
70 completions_display+="${ids[i]}:${names[i]}"
71 completions+="${ids[i]}:${names[i]}"
73 for ((i = 1 ; i <= $#ids ; i++)) ;do
74 completions+="${snames[i]}:${names[i]}"
75 completions_display+="${(r($max_name_len))snames[i]}:${names[i]}"
77 for ((i = 1 ; i <= $#ids ; i++)) ;do
78 completions+="^${i}:${names[i]}"
79 completions_display+="^${i}:${names[i]}"
82 (node*('@'(*':'|*'/'|)))
83 _describe 'node path' jump -S '/' -r "#. ${quote}" -J nodes
88 _bspc_prefix '!' "${sel_type} modifiers" ${sel_type}_mod $@ -J ${sel_type}_mod
93 if (( $#completions_display)) ;then
94 _describe "${sel_type} selector" ${sel_type}_desc $@ -S '.' -r ". \n:#${quote}\-" -J ${sel_type} \
95 -- completions_display completions $@ -S '.' -r ". \n:#${quote}\-" -J ${sel_type}
97 _describe "${sel_type} selector" ${sel_type}_desc $@ -S '.' -r ". \n:#${quote}\-" -J ${sel_type} \
98 -- completions $@ -S '.' -r ". \n:#${quote}\-" -J ${sel_type}
104 _bspc_selector desktop -S ':' -qr ".#\-\n ${quote}"
107 _bspc_selector monitor -S ':' -r ".#\-\n ${quote}"
113 [[ ${@[(r)--]} = '--' ]] && shift ${@[(i)--]}
114 [[ "$PREFIX[1]" == "$1" ]] &&
117 _describe $@[2,-1] $a -- $@[3,-1] $b -p "$1"
120 _bspc_query_names() {
121 [[ ${@[(r)--]} = '--' ]] && shift ${@[(i)--]}
122 local -a items=("${(@f)$(bspc query $2 --names 2> /dev/null)}") ||
125 for c in '\' ':' '[' '(' '*'
126 items=("${(@)items//$c/\\$c}")
127 _values -w "$1" "${items[@]}"
131 local -a commands=(node desktop monitor query rule wm subscribe config quit) \
132 resize_handle=(top bottom top_left top_right bottom_left bottom_right left right) \
133 node_state=(tiled pseudo_tiled floating fullscreen) \
134 flag=(hidden sticky private locked marked urgent) \
135 layer=(below normal above) \
136 dir=(north west south east) \
137 cycle_dir=(next prev)
138 local -a jump=($dir first second brother parent 1 2) \
139 node_desc=($dir $cycle_dir any last newest older newer focused pointed biggest smallest) \
140 node_mod=($node_state $flag $layer focused automatic local \
141 active leaf window same_class descendant_of ancestor_of) \
142 desktop_desc=($cycle_dir any last newest older newer focused) \
143 desktop_mod=(focused occupied local urgent) \
144 monitor_desc=($dir $cycle_dir any last newest older newer focused pointed primary) \
145 monitor_mod=(focused occupied) \
146 presel_dir=($dir cancel)
147 local quote="${compstate[quote]}" context state state_descr line
151 compset -S "${quote}"
153 if ((CURRENT==1)) ;then
154 _describe 'command or domain' commands
160 ((CURRENT==2)) && _bspc_selector node
161 ((CURRENT>2)) && [[ "$words[2]" != '-'* ]] && compset -n 2
162 ((CURRENT>2)) && [[ "$words[CURRENT-2]" =~ "^-(m|d|n|s|-to-(monitor|desktop|node)|-swap)$" ]] &&
163 _values 'option' '--follow[If passed, the focused node will stay focused]'
165 '*'{-a,--activate}'[Activate the selected or given node]::node selector:_bspc_selector -- node'\
166 '*'{-B,--balance}'[Adjust the split ratios of the tree rooted at the selected node so that all windows occupy the same area]'\
167 '*'{-C,--circulate}'[Circulate the windows of the tree rooted at the selected node]:direction:(forward backward)'\
168 '*'{-c,--close}'[Close the windows rooted at the selected node]'\
169 '*'{-d,--to-desktop}'[Send the selected node to the given desktop]:desktop selector:_bspc_selector -- desktop'\
170 '*'{-E,--equalize}'[Reset the split ratios of the tree rooted at the selected node to their default value]'\
171 '*'{-F,--flip}'[Flip the the tree rooted at selected node]: :(horizontal vertical)'\
172 '*'{-f,--focus}'[Focus the selected or given node]::node selector:_bspc_selector -- node'\
173 '*'{-g,--flag}'[Set or toggle the given flag for the selected node]: :-> flag'\
174 '*'{-i,--insert-receptacle}'[Insert a receptacle node at the selected node]'\
175 '*'{-k,--kill}'[Kill the windows rooted at the selected node]'\
176 '*'{-l,--layer}"[Set the stacking layer of the selected window]:stacking layer:($layer)"\
177 '*'{-m,--to-monitor}'[Send the selected node to the given monitor]:monitor selector:_bspc_selector -- monitor'\
178 '*'{-n,--to-node}'[Transplant the selected node to the given node]:node selector:_bspc_selector -- node'\
179 '*'{-o,--presel-ratio}'[Set the splitting ratio of the preselection area]:preselect ratio: ( )'\
180 '*'{-p,--presel-dir}'[Preselect the splitting area of the selected node or cancel the preselection]: :_bspc_prefix -- "~" preselect presel_dir'\
181 '*'{-r,--ratio}'[Set the splitting ratio of the selected node (0 < ratio < 1)]: :( )'\
182 '*'{-R,--rotate}'[Rotate the tree rooted at the selected node]:angle:(90 270 180)'\
183 '*'{-s,--swap}'[Swap the selected node with the given node]:node selector:_bspc_selector -- node'\
184 '*'{-t,--state}'[Set the state of the selected window]: :_bspc_prefix -- "~" "node state" node_state '\
185 '*'{-v,--move}'[Move the selected window by dx pixels horizontally and dy pixels vertically]:dx:( ):dy:( )'\
186 '*'{-z,--resize}"[Resize the selected window by moving the given handle by dx pixels horizontally and dy pixels vertically]:handle:($resize_handle):dx:( ):dy:( )"
187 [ "$state" = flag ] && _values 'flag' "${flag[@]:#urgent}::set flag:(on off)"
190 ((CURRENT==2)) && _bspc_selector desktop
191 ((CURRENT>2)) && [[ "$words[2]" != '-'* ]] && compset -n 2
192 ((CURRENT>2)) && [[ "$words[CURRENT-2]" =~ "^-m|-s|--monitor|--swap$" ]] &&
193 _values 'option' '--follow[If passed, the focused desktop will stay focused]'
195 '*'{-a,--activate}'[Activate the selected or given desktop]:: :_bspc_selector -- desktop'\
196 '*'{-b,--bubble}"[Bubble the selected desktop in the given direction]:direction:($cycle_dir)"\
197 '*'{-f,--focus}'[Focus the selected or given desktop]:: :_bspc_selector -- desktop'\
198 '*'{-l,--layout}"[Set or cycle the layout of the selected desktop]:desktop layout:($cycle_dir monocle tiled)"\
199 '*'{-m,--to-monitor}'[Send the selected desktop to the given monitor]: :_bspc_selector -- monitor'\
200 '*'{-n,--rename}'[Rename the selected desktop]:desktop name:( )'\
201 '*'{-r,--remove}'[Remove the selected desktop]'\
202 '*'{-s,--swap}'[Swap the selected desktop with the given desktop]: :_bspc_selector -- desktop'
205 ((CURRENT==2)) && _bspc_selector monitor
206 ((CURRENT>2)) && [[ "$words[2]" != '-'* ]] && compset -n 2
208 '*'{-a,--add-desktops}'[Create desktops with the given names in the selected monitor]:*:add desktops:( )'\
209 '*'{-d,--reset-desktops}'[Rename, add or remove desktops]:*: :->desktops'\
210 '*'{-f,--focus}'[Focus the selected or given monitor]:: :_bspc_selector -- monitor'\
211 '*'{-g,--rectangle}'[Set the rectangle of the selected monitor]:WxH+X+Y:( )'\
212 '*'{-n,--rename}'[Rename the selected monitor]: :( )'\
213 '*'{-o,--reorder-desktops}'[Reorder the desktops of the selected monitor]:*:reorder desktops:_bspc_query_names -- desktops -D'\
214 '*'{-r,--remove}'[Remove the selected monitor]'\
215 '*'{-s,--swap}'[Swap the selected monitor with the given monitor]: :_bspc_selector -- monitor'
218 local -a cmds_no_names=('-T' '--tree' '-N' '--nodes')
219 local -a cmds=($cmds_no_names '-D' '--desktops' '-M' '--monitors')
221 '*'{-d,--desktop}'[Constrain matches to the selected desktop]: :_bspc_selector -- desktop'\
222 '*'{-m,--monitor}'[Constrain matches to the selected monitor]: :_bspc_selector -- monitor'\
223 '*'{-n,--node}'[Constrain matches to the selected node]: :_bspc_selector -- node'\
224 "($cmds_no_names --names)--names[Print names instead of IDs. Can only be used with -M and -D]"\
225 "($cmds --names)"{-N,--nodes}'[List the IDs of the matching nodes]'\
226 "($cmds --names)"{-T,--tree}'[Print a JSON representation of the matching item]'\
227 "($cmds)"{-D,--desktops}'[List the IDs (or names) of the matching desktops]'\
228 "($cmds)"{-M,--monitors}'[List the IDs (or names) of the matching monitors]'
232 '*'{-d,--dump-state}'[Dump the current world state on standard output]'\
233 '*'{-l,--load-state}'[Load a world state from the given file]:load state from file:_files'\
234 '*'{-a,--add-monitor}'[Add a monitor for the given name and rectangle]:add monitor:( )'\
235 '*'{-O,--reorder-monitors}'[Reorder the list of monitors to match the given order]:*: :_bspc_query_names -- monitors -M'\
236 '*'{-o,--adopt-orphans}'[Manage all the unmanaged windows remaining from a previous session]'\
237 '*'{-h,--record-history}'[Enable or disable the recording of node focus history]:history:(on off)'\
238 '*'{-g,--get-status}'[Print the current status information]'
241 if [[ "$words[CURRENT-1]" != (-c|--count) ]] ;then
242 _values -w "options" \
243 '(-f --fifo)'{-f,--fifo}'[Print a path to a FIFO from which events can be read and return]'\
244 '(-c --count)'{-c,--count}'[Stop the corresponding bspc process after having received specified count of events]'
245 _values -w -S "_" events all report pointer_action \
246 "monitor:: :(add rename remove swap focus geometry)"\
247 "desktop:: :(add rename remove swap transfer focus activate layout)"\
248 "node:: :(add remove swap transfer focus activate presel stack geometry state flag layer)"
252 local -a completions by_index
253 local index=0 target settings class id instance json
255 {-a,--add}'[Create a new rule]:*: :->add'\
256 {-r,--remove}'[Remove the given rules]:*: :->remove'\
257 '(-l --list)'{-l,--list}'[List the rules]'
258 compset -N "-([ar]|-add|-remove)"
259 case $state$CURRENT in
262 bspc query -N -n '.window' 2> /dev/null |
264 json=$(bspc query -T -n $id 2>/dev/null) || continue
265 [[ "$json[1]" = '{' ]] || continue
266 class=${${json##*\"className\":\"}%%\",\"*}
267 instance=${${json##*\"instanceName\":\"}%%\",\"*}
268 [[ "$class[1]" != '{' && "$instance[1]" != '{' ]] || continue
269 if [ -n "$IPREFIX" ] ;then
270 [[ "$IPREFIX" == ("${class}:"|('\'|)'*:') ]] &&
271 completions[(r)$instance]=$instance
273 class=${class%%:/\\:}
274 completions[(r)$class]="$class"
279 _values -w 'add rule' {border,focus,follow,manage,center}': :(on off)'\
282 'monitor: :_bspc_selector -- monitor'\
283 'desktop: :_bspc_selector -- desktop'\
284 'node: :_bspc_selector -- node'\
286 'split_ratio:split ratio:( )'\
287 "split_dir:split direction:(${dir})"\
288 "state:state:(${node_state})"\
289 "${flag[@]:#urgent}:set flag:(on off)"\
290 "layer:layer:(${layer})"
295 bspc rule -l 2> /dev/null |
296 while IFS=" " read target settings ;do
297 by_index+="^$((index++)):${target} ${settings}"
298 if [ -n "$IPREFIX" ] ;then
299 completions+="${target#*:}"
301 completions+="${target%:*}"
304 [[ -z "$IPREFIX" ]] &&
305 _describe 'remove rule by position' '(head tail)' -J by_index -- by_index -J by_index
313 _describe 'match window instance' completions ||
314 _describe 'match window class' completions -q -S ':'
317 local -a {look,behaviour,input}{_bool,}
318 look_bool=(borderless_monocle gapless_monocle)
319 look=({normal,active,focused}_border_color {top,right,bottom,left}_padding {top,right,bottom,left}_monocle_padding presel_feedback_color border_width window_gap)
320 behaviour_bool=(single_monocle removal_adjustment ignore_ewmh_focus center_pseudo_tiled honor_size_hints remove_disabled_monitors remove_unplugged_monitors merge_overlapping_monitors)
321 behaviour=(mapping_events_count ignore_ewmh_fullscreen external_rules_command split_ratio automatic_scheme initial_polarity directional_focus_tightness status_prefix)
322 input_bool=(swallow_first_click focus_follows_pointer pointer_follows_{focus,monitor})
323 input=(click_to_focus pointer_motion_interval pointer_modifier pointer_action{1,2,3})
324 if [[ "$CURRENT" == (2|3) ]];then
326 '-d[Set settings for the selected desktop]: :_bspc_selector -- desktop'\
327 '-m[Set settings for the selected monitor]: :_bspc_selector -- monitor'\
328 '-n[Set settings for the selected node]: :_bspc_selector -- node'
330 if [[ "${words[2]}" == -* ]] ;then
331 (( CURRENT == 3 )) && return
332 if (( CURRENT > 3 )) ;then
336 if ((CURRENT==2)) ;then
337 _describe 'look' look -J look -- look_bool -J look
338 _describe 'input' input -J input -- input_bool -J input
339 _describe 'behaviour' behaviour -J behaviour -- behaviour_bool -J behaviour
340 elif ((CURRENT==3)) ;then
343 (ignore_ewmh_fullscreen)
344 _values -S "," "set $setting" all none "enter:: :(exit)" "exit:: :(enter)"
347 _values "set $setting" first_child second_child
349 (pointer_action(1|2|3))
350 _values "set $setting" move resize_side resize_corner focus none
353 _values "set $setting" shift control lock mod1 mod2 mod3 mod4 mod5
355 (directional_focus_tightness)
356 _values "set $setting" low high
359 _values "set $setting" any button1 button2 button3 none
362 [[ -n $look_bool[(r)$setting] ]] ||
363 [[ -n $behaviour_bool[(r)$setting] ]] ||
364 [[ -n $input_bool[(r)$setting] ]] &&
365 _values "set $setting" true false