X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fmain-readline.c;h=b8c645955ac1de77f62e8019f8e01935911160e6;hb=782e132bccab8a1d3cb362dabad8c1171129ae3b;hp=0fe06729d0cce79de7c7ec3c5b1dfa94ae83fe2e;hpb=c1eb3099a1a7f4c9b9f8c6238336ee5b69147fd6;p=protos%2Flibecoli.git diff --git a/lib/main-readline.c b/lib/main-readline.c index 0fe0672..b8c6459 100644 --- a/lib/main-readline.c +++ b/lib/main-readline.c @@ -34,8 +34,9 @@ #include #include +#include +#include #include - #include #include #include @@ -44,6 +45,8 @@ #include #include #include +#include +#include static struct ec_node *commands; @@ -51,7 +54,7 @@ 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_elt *elt; + static const struct ec_completed_item *item; char *out_string; @@ -98,21 +101,28 @@ static char **my_attempted_completion(const char *text, int start, int end) } /* this function builds the help string */ -static char *get_tk_help(const struct ec_node *node) +static char *get_node_help(const struct ec_completed_elt *elt) { - const struct ec_node *node2; + const struct ec_node *node; char *help = NULL; - char *tk_help = NULL; - - for (node2 = node; - node2 != NULL && tk_help == NULL; - node2 = ec_node_parent(node2)) - tk_help = ec_keyval_get(ec_node_attrs(node2), "help"); + const char *node_help = NULL; + const char *node_desc = NULL; + size_t i; + + for (i = 0; i < elt->pathlen; i++) { + node = elt->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); + } - if (tk_help == NULL) - tk_help = ""; + if (node_help == NULL) + node_help = ""; + if (node_desc == NULL) + return NULL; - if (asprintf(&help, "%-20s %s", ec_node_desc(node), tk_help) < 0) + if (asprintf(&help, "%-20s %s", node_desc, node_help) < 0) return NULL; return help; @@ -120,12 +130,14 @@ static char *get_tk_help(const struct ec_node *node) static int show_help(int ignore, int invoking_key) { - const struct ec_completed_elt *elt; + const struct ec_completed_item *item; struct ec_completed_iter *iter; struct ec_completed *c; + struct ec_parsed *p; char *line; unsigned int count, i; char **helps = NULL; + int match = 0; (void)ignore; (void)invoking_key; @@ -133,33 +145,43 @@ static int show_help(int ignore, int invoking_key) line = strdup(rl_line_buffer); if (line == NULL) return 1; - line[rl_point] = '\0'; + /* check if the current line matches */ + p = ec_node_parse(commands, line); + if (ec_parsed_matches(p)) + match = 1; + ec_parsed_free(p); + + /* complete at current cursor position */ + line[rl_point] = '\0'; c = ec_node_complete(commands, line); + //ec_completed_dump(stdout, c); free(line); if (c == NULL) return 1; - //ec_completed_dump(stdout, c); count = ec_completed_count(c, EC_MATCH | EC_NO_MATCH); - helps = calloc(count + 1, sizeof(char *)); + helps = calloc(count + match + 1, sizeof(char *)); if (helps == NULL) return 1; + 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 = 1, elt = ec_completed_iter_next(iter); - i <= count && elt != NULL; - i++, elt = ec_completed_iter_next(iter)) { - helps[i] = get_tk_help(elt->node); + 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); } ec_completed_free(c); - rl_display_match_list(helps, count, 1000); + rl_display_match_list(helps, count + match, 1000); /* XXX 1000 */ rl_forced_update_display(); @@ -179,10 +201,11 @@ static int create_commands(void) if (cmdlist == NULL) goto fail; + cmd = EC_NODE_SEQ(NULL, ec_node_str(NULL, "hello"), EC_NODE_OR("name", - ec_node_str(NULL, "john"), + ec_node_str("john", "john"), ec_node_str(NULL, "johnny"), ec_node_str(NULL, "mike") ), @@ -192,6 +215,8 @@ static int create_commands(void) goto fail; ec_keyval_set(ec_node_attrs(cmd), "help", "say hello to someone several times", NULL); + ec_keyval_set(ec_node_attrs(ec_node_find(cmd, "john")), + "help", "specific help for john", NULL); 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")), @@ -199,24 +224,57 @@ static int create_commands(void) if (ec_node_or_add(cmdlist, cmd) < 0) goto fail; -#if 0 - cmd = EC_NODE_CMD(NULL, "good morning john|johnny|mike [count]", + + cmd = EC_NODE_CMD(NULL, "good morning name [count]", + EC_NODE_CMD("name", "bob|bobby|michael"), ec_node_int("count", 0, 10, 10)); if (cmd == NULL) goto fail; ec_keyval_set(ec_node_attrs(cmd), "help", "say good morning to someone several times", NULL); + 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); if (ec_node_or_add(cmdlist, cmd) < 0) goto fail; -#endif + + + cmd = EC_NODE_CMD(NULL, + "buy potatoes,carrots,pumpkins"); + if (cmd == NULL) + goto fail; + ec_keyval_set(ec_node_attrs(cmd), "help", + "buy some vegetables", NULL); + if (ec_node_or_add(cmdlist, cmd) < 0) + goto fail; + + + cmd = EC_NODE_CMD(NULL, "eat vegetables", + ec_node_many("vegetables", + EC_NODE_OR(NULL, + ec_node_str(NULL, "potatoes"), + ec_node_once(NULL, + ec_node_str(NULL, "carrots")), + ec_node_once(NULL, + ec_node_str(NULL, "pumpkins"))), + 1, 0)); + if (cmd == NULL) + goto fail; + ec_keyval_set(ec_node_attrs(cmd), "help", + "eat vegetables (take some more potatoes)", NULL); + if (ec_node_or_add(cmdlist, cmd) < 0) + goto fail; + cmd = EC_NODE_SEQ(NULL, ec_node_str(NULL, "bye") ); - ec_keyval_set(ec_node_attrs(cmd), "help", "say bye to someone", NULL); + ec_keyval_set(ec_node_attrs(cmd), "help", "say bye", NULL); if (ec_node_or_add(cmdlist, cmd) < 0) goto fail; + commands = ec_node_sh_lex(NULL, cmdlist); if (commands == NULL) goto fail;