X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fmain-readline.c;h=5bbe18e7a08977816a4a49781c5bfd6e6c96eb9f;hb=ff1f48e335ca77cc97e49ea86b292233731ecb78;hp=b8c645955ac1de77f62e8019f8e01935911160e6;hpb=6c99f3bcdcb786bee560c1582f3ad3c306681d6e;p=protos%2Flibecoli.git diff --git a/lib/main-readline.c b/lib/main-readline.c index b8c6459..5bbe18e 100644 --- a/lib/main-readline.c +++ b/lib/main-readline.c @@ -28,11 +28,13 @@ #define _GNU_SOURCE /* for asprintf */ #include #include +#include #include #include #include +#include #include #include #include @@ -47,6 +49,7 @@ #include #include #include +#include static struct ec_node *commands; @@ -54,9 +57,15 @@ static char *my_completion_entry(const char *s, int state) { static struct ec_completed *c; static struct ec_completed_iter *iter; - static const struct ec_completed_item *item; - char *out_string; + const struct ec_completed_item *item; + enum ec_completed_type item_type; + const char *item_str, *item_display; + + (void)s; + /* don't append a quote */ + rl_completion_suppress_quote = 1; + rl_basic_quote_characters = ""; if (state == 0) { char *line; @@ -74,19 +83,35 @@ static char *my_completion_entry(const char *s, int state) return NULL; ec_completed_iter_free(iter); - iter = ec_completed_iter(c, EC_MATCH); + iter = ec_completed_iter(c, EC_MATCH | EC_PARTIAL_MATCH); if (iter == NULL) return NULL; } - elt = ec_completed_iter_next(iter); - if (elt == NULL) + item = ec_completed_iter_next(iter); + if (item == NULL) return NULL; - if (asprintf(&out_string, "%s%s", s, elt->add) < 0) - return NULL; + item_str = ec_completed_item_get_str(item); + if (c->count_match == 1) { + + /* don't add the trailing space for partial completions */ + if (state == 0) { + item_type = ec_completed_item_get_type(item); + if (item_type == EC_MATCH) + rl_completion_suppress_append = 0; + else + rl_completion_suppress_append = 1; + } + + return strdup(item_str); + } else if (rl_completion_type == '?') { + /* on second try only show the display part */ + item_display = ec_completed_item_get_display(item); + return strdup(item_display); + } - return out_string; + return strdup(item_str); } static char **my_attempted_completion(const char *text, int start, int end) @@ -101,21 +126,29 @@ static char **my_attempted_completion(const char *text, int start, int end) } /* this function builds the help string */ -static char *get_node_help(const struct ec_completed_elt *elt) +static char *get_node_help(const struct ec_completed_node *compnode) { - const struct ec_node *node; +// const struct ec_completed_item *item; +// const struct ec_node *node; char *help = NULL; const char *node_help = NULL; const char *node_desc = NULL; - size_t i; - - for (i = 0; i < elt->pathlen; i++) { - node = elt->path[i]; +// size_t i; + + (void)compnode; +#if 0 //XXX + /* Since we display only one help per node, only look at the first item + * to get the path. The objective is to retrieve the most precise + * help for this node. */ + item = TAILQ_FIRST(&compnode->items); + for (i = 0; i < item->pathlen; i++) { + node = item->path[i]; if (node_help == NULL) node_help = ec_keyval_get(ec_node_attrs(node), "help"); if (node_desc == NULL) node_desc = ec_node_desc(node); } +#endif if (node_help == NULL) node_help = ""; @@ -130,8 +163,7 @@ static char *get_node_help(const struct ec_completed_elt *elt) static int show_help(int ignore, int invoking_key) { - const struct ec_completed_item *item; - struct ec_completed_iter *iter; + const struct ec_completed_node *compnode; struct ec_completed *c; struct ec_parsed *p; char *line; @@ -160,7 +192,14 @@ static int show_help(int ignore, int invoking_key) if (c == NULL) return 1; - count = ec_completed_count(c, EC_MATCH | EC_NO_MATCH); + /* let's display one contextual help per node */ + count = 0; + TAILQ_FOREACH(compnode, &c->nodes, next) { + if (TAILQ_EMPTY(&compnode->items)) + continue; + count++; + } + helps = calloc(count + match + 1, sizeof(char *)); if (helps == NULL) return 1; @@ -168,15 +207,12 @@ static int show_help(int ignore, int invoking_key) if (match) helps[1] = ""; - iter = ec_completed_iter(c, EC_MATCH | EC_NO_MATCH); - if (iter == NULL) - goto fail; - /* strangely, rl_display_match_list() expects first index at 1 */ - for (i = match + 1, item = ec_completed_iter_next(iter); - i < count + match + 1 && item != NULL; - i++, item = ec_completed_iter_next(iter)) { - helps[i] = get_node_help(item); + i = match + 1; + TAILQ_FOREACH(compnode, &c->nodes, next) { + if (TAILQ_EMPTY(&compnode->items)) + continue; + helps[i++] = get_node_help(compnode); } ec_completed_free(c); @@ -187,10 +223,7 @@ static int show_help(int ignore, int invoking_key) return 0; -fail: - free(helps); - // free helps[n] XXX - return 1; + // free helps[n] XXX on error ? } static int create_commands(void) @@ -220,7 +253,7 @@ static int create_commands(void) ec_keyval_set(ec_node_attrs(ec_node_find(cmd, "name")), "help", "the name of the person", NULL); ec_keyval_set(ec_node_attrs(ec_node_find(cmd, "int")), - "help", "an integer", NULL); + "help", "an integer (0-10)", NULL); if (ec_node_or_add(cmdlist, cmd) < 0) goto fail; @@ -235,7 +268,7 @@ static int create_commands(void) ec_keyval_set(ec_node_attrs(ec_node_find(cmd, "name")), "help", "the person to greet", NULL); ec_keyval_set(ec_node_attrs(ec_node_find(cmd, "count")), "help", - "how many times to greet", NULL); + "how many times to greet (0-10)", NULL); if (ec_node_or_add(cmdlist, cmd) < 0) goto fail; @@ -275,6 +308,15 @@ static int create_commands(void) goto fail; + cmd = EC_NODE_SEQ(NULL, + ec_node_str(NULL, "load"), + ec_node("file", NULL) + ); + ec_keyval_set(ec_node_attrs(cmd), "help", "load a file", NULL); + if (ec_node_or_add(cmdlist, cmd) < 0) + goto fail; + + commands = ec_node_sh_lex(NULL, cmdlist); if (commands == NULL) goto fail; @@ -290,9 +332,12 @@ static int create_commands(void) int main(void) { struct ec_parsed *p; -// const char *name; char *line; + if (ec_init() < 0) { + fprintf(stderr, "cannot init ecoli: %s\n", strerror(errno)); + return 1; + } if (create_commands() < 0) return 1;