pass state to completed api
[protos/libecoli.git] / lib / main-readline.c
index 0fe0672..9d898ff 100644 (file)
@@ -34,8 +34,9 @@
 #include <readline/history.h>
 
 #include <ecoli_node.h>
+#include <ecoli_parsed.h>
+#include <ecoli_completed.h>
 #include <ecoli_keyval.h>
-
 #include <ecoli_node_str.h>
 #include <ecoli_node_seq.h>
 #include <ecoli_node_space.h>
@@ -44,6 +45,8 @@
 #include <ecoli_node_int.h>
 #include <ecoli_node_option.h>
 #include <ecoli_node_cmd.h>
+#include <ecoli_node_many.h>
+#include <ecoli_node_once.h>
 
 static struct ec_node *commands;
 
@@ -123,9 +126,11 @@ static int show_help(int ignore, int invoking_key)
        const struct ec_completed_elt *elt;
        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 +138,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] = "<return>";
+
        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;
+       for (i = match + 1, elt = ec_completed_iter_next(iter);
+            i < count + match + 1 && elt != NULL;
             i++, elt = ec_completed_iter_next(iter)) {
                helps[i] = get_tk_help(elt->node);
        }
 
        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,6 +194,7 @@ static int create_commands(void)
        if (cmdlist == NULL)
                goto fail;
 
+
        cmd = EC_NODE_SEQ(NULL,
                ec_node_str(NULL, "hello"),
                EC_NODE_OR("name",
@@ -199,8 +215,8 @@ 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 bob|bobby|michael [count]",
                        ec_node_int("count", 0, 10, 10));
        if (cmd == NULL)
                goto fail;
@@ -208,7 +224,35 @@ static int create_commands(void)
                "say good morning to someone several times", 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, "sell vegetable",
+                       ec_node_many("vegetable",
+                               EC_NODE_OR(NULL,
+                                       ec_node_once(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",
+               "sell vegetables", NULL);
+       if (ec_node_or_add(cmdlist, cmd) < 0)
+               goto fail;
+
 
        cmd = EC_NODE_SEQ(NULL,
                ec_node_str(NULL, "bye")
@@ -217,6 +261,7 @@ static int create_commands(void)
        if (ec_node_or_add(cmdlist, cmd) < 0)
                goto fail;
 
+
        commands = ec_node_sh_lex(NULL, cmdlist);
        if (commands == NULL)
                goto fail;