Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add completion for bluetoothctl #742

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions completions/bluetoothctl
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# bluetoothctl(1) completion -*- shell-script -*-

_bluetoothctl()
{
local cur=${COMP_WORDS[COMP_CWORD]}
local prev=${COMP_WORDS[COMP_CWORD-1]}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you intend to use the auto-loading mechanism of bash-completion (i.e., putting the file in the completions directory and letting bash-completion load it automatically on demand), I suggest using _init_completion for the initialization (as done in other completions). It doesn't only provide a better extraction of the words but also the contextual completions for the variable names and redirections. It might also be used by bash-completion for hooks in the future.

if [[ "$COMP_CWORD" == "1" ]]; then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if [[ "$COMP_CWORD" == "1" ]]; then
if ((COMP_CWORD == 1)); then
  • You can use the arithmetic command.

The same applies to the later lines testing COMP_CWORD.

# Parse help for list of commands and remove ansi colors
COMPREPLY=( $( compgen -W "$(bluetoothctl help | sed -n '/ /{s/\x1B\[[0-9;]*[a-zA-Z]//g;s/\x01//g;s/\x02//g;s/ .*//p}')" -- $cur))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
COMPREPLY=( $( compgen -W "$(bluetoothctl help | sed -n '/ /{s/\x1B\[[0-9;]*[a-zA-Z]//g;s/\x01//g;s/\x02//g;s/ .*//p}')" -- $cur))
COMPREPLY=( $( compgen -W "$(bluetoothctl help | sed -n '/ /{s/\x1B\[[0-9;]*[a-zA-Z]//g;s/\x01//g;s/\x02//g;s/ .*//p}')" -- "$cur"))
  • quoting
Suggested change
COMPREPLY=( $( compgen -W "$(bluetoothctl help | sed -n '/ /{s/\x1B\[[0-9;]*[a-zA-Z]//g;s/\x01//g;s/\x02//g;s/ .*//p}')" -- $cur))
COMPREPLY=( $( compgen -W "$(bluetoothctl help | sed -n '/ /{s/\x1B\[[0-9;]*[a-zA-Z]//g;s/\x01//g;s/\x02//g;s/ .*//p;}')" -- $cur))
  • POSIX sed requires a semicolon or newline before <right-brace>.
Suggested change
COMPREPLY=( $( compgen -W "$(bluetoothctl help | sed -n '/ /{s/\x1B\[[0-9;]*[a-zA-Z]//g;s/\x01//g;s/\x02//g;s/ .*//p}')" -- $cur))
COMPREPLY=( $( compgen -W "$(bluetoothctl help | sed -n '/ /{s/'$'\e''\[[0-9;]*[a-zA-Z]//g;s/['$'\x01\x02'']//g;s/ .*//p}')" -- $cur))
  • AFAIK, POSIX sed doesn't necessarily support the escape sequences like \x1B. Here, I'd suggest expanding the sequences using Bash's $'...' before passing it to sed.

These comments also apply to the later lines that contain the same structure.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, it might just be better to not use sed at all. I think this should be doable in bash only.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think either works, so you can use what you like.

return
fi
if [[ "$COMP_CWORD" == "2" ]]; then
case "$prev" in
info|pair|trust|untrust|block|unblock|remove|connect|disconnect)
# Return a device to complete
COMPREPLY=( $( compgen -W "$(bluetoothctl devices|awk '{print $2}')" -- $cur))
;;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
;;
;;
  • The indentation seems to be inconsistent with the other similar lines?

show|select)
# Return a controller address
COMPREPLY=( $( compgen -W "$(bluetoothctl list|awk '{print $2}')" -- $cur))
;;
power|pairable|discoverable|scan)
COMPREPLY=( $( compgen -W "on off" -- $cur))
;;
agent)
COMPREPLY=( $( compgen -W "on off capability" -- $cur))
;;
advertise)
COMPREPLY=( $( compgen -W "on off type" -- $cur))
;;
esac
fi
if [[ ${COMP_WORDS[1]} == "menu" ]]; then
if [[ "$COMP_CWORD" == "2" ]]; then
# List out submenues
COMPREPLY=( $(compgen -W "$(bluetoothctl help | sed -n '/Submenu/{s/\x1B\[[0-9;]*[a-zA-Z]//g;s/\x02//g;s/\x01//;s/ .*//p}')" -- $cur))
return
fi
if [[ "$COMP_CWORD" == "3" ]]; then
Comment on lines +38 to +39
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fi
if [[ "$COMP_CWORD" == "3" ]]; then
elif ((COMP_CWORD" == 3)); then

# Parse submenu and return commands.
COMPREPLY=( $( compgen -W "$(bluetoothctl menu $prev | sed -n '/ /{s/\x1B\[[0-9;]*[a-zA-Z]//g;s/\x01//g;s/\x02//g;s/ .*//p}' )" -- $cur))
fi
fi
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think complete -F _bluetoothctl bluetoothctl is missing.

# ex: filetype=sh