From 2783dd4b09077392ab69857b9248e1c68bae7fe8 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Fri, 23 Sep 2011 17:21:58 +0200 Subject: [PATCH] gsu: Initial completion support. This adds the framework for command completion of scripts which make use of the gsu subcommand library. The idea is to implement as much as possible as generic helpers within gsu in order to minimize code duplication in the scripts which source the gsu library. The new "complete" subcommand is automatically included in each application, just like the help, man and prefs commands we already have. This subommand is meant to be used as the completer which calls the custom subcommand completers included in the application. Two new public helper functions, gsu_complete_options() and gsu_cword_is_option_parameter() are introduced in this commit. The former function takes a usual getopt string and completes according to all options in this string. The latter is useful for completers which need to determine whether the current word is the parameter to some option in order to find out how to complete the current word. For example, the -s option of cmt's vmem command takes a mandatory parameter which is a number. So the completer for this command must complete differently depending on whether the previous word is "-s". --- misc/gsu/subcommand | 111 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 2 deletions(-) diff --git a/misc/gsu/subcommand b/misc/gsu/subcommand index f09c66d..f5f4745 100644 --- a/misc/gsu/subcommand +++ b/misc/gsu/subcommand @@ -18,7 +18,7 @@ export gsu_command_regex='^com_\([-a-zA-Z_0-9]\+\)()' _gsu_available_commands() { result="$({ - printf "help\nman\nprefs\n" + printf "help\nman\nprefs\ncomplete\n" sed -ne "s/$gsu_command_regex/\1/g;T;p" $0 } | sort | tr '\n' ' ')" } @@ -43,6 +43,26 @@ _gsu_print_available_commands() ) 2>&1 } +gsu_complete_options() +{ + local opts="$1" cword="$2" cur + local -a words + + shift 2 + words=("$@") + cur="${words[$cword]}" + ret=0 + [[ ! "$cur" == -* ]] && return + + ret=0 + for ((i=0; i < ${#opts}; i++)); do + opt="${opts:$i:1}" + [[ "$opt" == ":" ]] && continue + printf "%s" "-$opt " + let ret++ + done +} + export gsu_prefs_txt=" Print the current preferences. @@ -93,6 +113,11 @@ _com_prefs() done } +complete_prefs() +{ + gsu_complete_options "e" "$@" +} + export gsu_man_txt=" Print the manual. @@ -155,6 +180,18 @@ Usage: help [command] Without arguments, print the list of available commands. Otherwise, print the help text for the given command." +export gsu_complete_txt=" +Command line completion. + +Usage: complete [ ...] + +In the first form, the command prints all possible completions to stdout. +This can be used from the completion function of the shell. + +Completion code suitable to be evaled is written to stdout if no argument +was given. +" + _com_help() { local a b @@ -165,6 +202,7 @@ _com_help() printf "com_help()\n$gsu_help_txt" | head -n 4; echo "--" printf "com_man()\n$gsu_man_txt" | head -n 4; echo "--" printf "com_prefs()\n$gsu_prefs_txt" | head -n 4; echo "--" + printf "com_complete()\n$gsu_complete_txt" | head -n 4; echo "--" grep -A 2 "$gsu_command_regex" $0 } | grep -v -- '--' \ | sed -e "/$gsu_command_regex/bs" \ @@ -200,6 +238,11 @@ _com_help() ret=$GSU_SUCCESS return fi + if test "$1" = "complete"; then + echo "$gsu_complete_txt" + ret=$GSU_SUCCESS + return + fi ret=$GSU_SUCCESS if grep -q "^com_$1()" $0; then sed -e "1,/^com_$1()$/d" -e '/^{/,$d' -e 's/^## *//' $0 @@ -210,6 +253,12 @@ _com_help() ret=-$E_GSU_BAD_COMMAND } +complete_help() +{ + _gsu_available_commands + echo "$result" +} + # Wrapper for bash's getopts. # # Aborts on programming errors such as missing or invalid option string. On @@ -296,6 +345,64 @@ gsu_getopts() ret=$GSU_SUCCESS } +_com_complete() +{ + local cmd n cword="$1" + local -a words + + if (($# == 0)); then + cat <