From 9d9260615369a488b21b12514e7cade5e90fd3a6 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 2 Jan 2020 14:56:21 +0100 Subject: add completion source files --- complete.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ complete.h | 1 + 2 files changed, 70 insertions(+) create mode 100644 complete.c create mode 100644 complete.h diff --git a/complete.c b/complete.c new file mode 100644 index 0000000..a9e64f3 --- /dev/null +++ b/complete.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include + +#include "complete.h" + +/* + * generate simple bash completion for getopt long, + * using "complete -W". + */ +#define CASE_IMAGE \ + " --image)\n" \ + " COMPREPLY=( $(compgen -f -- \"$cur\") )\n" \ + " ;;\n" + +void complete_bash(const char *command, struct option *opts) +{ + bool have_image = false; + char opt_all[1024]; + char opt_arg[1024]; + int pos_all = 0; + int pos_arg = 0; + int i; + + for (i = 0; opts[i].name != NULL; i++) { + /* options with argument completion */ + if (strcmp(opts[i].name, "image") == 0) { + have_image = true; + + } else if (opts[i].has_arg) { + /* options without argument completion */ + pos_arg += snprintf(opt_arg+pos_arg, sizeof(opt_arg)-pos_arg, + "%s--%s", + pos_arg ? " | " : "", + opts[i].name); + } + + /* (long) option completion */ + pos_all += snprintf(opt_all+pos_all, sizeof(opt_all)-pos_all, + "%s--%s", + pos_all ? " " : "", + opts[i].name); + } + if (!pos_arg) + snprintf(opt_arg+pos_arg, sizeof(opt_arg)-pos_arg, "--dummy"); + + printf("_%s_complete()\n" + "{\n" + " local cur prev\n" + " cur=\"${COMP_WORDS[COMP_CWORD]}\"\n" + " prev=\"${COMP_WORDS[COMP_CWORD-1]}\"\n" + " case \"$prev\" in\n" + "%s" + " %s)\n" + " COMPREPLY=()\n" + " ;;\n" + " *)\n" + " COMPREPLY=( $(compgen -W \"%s\" -- \"$cur\") )\n" + " ;;\n" + " esac\n" + " return 0\n" + "}\n" + "complete -F _%s_complete %s\n" + "\n", + command, + have_image ? CASE_IMAGE : "", + opt_arg, opt_all, command, command); +} diff --git a/complete.h b/complete.h new file mode 100644 index 0000000..a1fd02b --- /dev/null +++ b/complete.h @@ -0,0 +1 @@ +void complete_bash(const char *command, struct option *opts); -- cgit