123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- /*
- * shell_word_generator.c
- */
- #include <string.h>
- #include "private.h"
- #include "lub/string.h"
- #include "lub/argv.h"
- /*-------------------------------------------------------- */
- void
- clish_shell_iterator_init(clish_shell_iterator_t * iter,
- clish_nspace_visibility_t field)
- {
- iter->last_cmd = NULL;
- iter->field = field;
- }
- /*--------------------------------------------------------- */
- const clish_command_t *clish_shell_resolve_command(const clish_shell_t * this,
- const char *line)
- {
- clish_command_t *cmd, *result;
- /* Search the current view */
- result = clish_view_resolve_command(clish_shell__get_view(this), line, BOOL_TRUE);
- /* Search the global view */
- cmd = clish_view_resolve_command(this->global, line, BOOL_TRUE);
- result = clish_command_choose_longest(result, cmd);
- return result;
- }
- /*--------------------------------------------------------- */
- const clish_command_t *clish_shell_resolve_prefix(const clish_shell_t * this,
- const char *line)
- {
- clish_command_t *cmd, *result;
- /* Search the current view */
- result = clish_view_resolve_prefix(clish_shell__get_view(this), line, BOOL_TRUE);
- /* Search the global view */
- cmd = clish_view_resolve_prefix(this->global, line, BOOL_TRUE);
- result = clish_command_choose_longest(result, cmd);
- return result;
- }
- /*-------------------------------------------------------- */
- const clish_command_t *clish_shell_find_next_completion(const clish_shell_t *
- this, const char *line, clish_shell_iterator_t * iter)
- {
- const clish_command_t *result, *cmd;
- /* ask the local view for next command */
- result = clish_view_find_next_completion(clish_shell__get_view(this),
- iter->last_cmd, line, iter->field, BOOL_TRUE);
- /* ask the global view for next command */
- cmd = clish_view_find_next_completion(this->global,
- iter->last_cmd, line, iter->field, BOOL_TRUE);
- if (clish_command_diff(result, cmd) > 0)
- result = cmd;
- if (!result)
- iter->last_cmd = NULL;
- else
- iter->last_cmd = clish_command__get_name(result);
- return result;
- }
- /*--------------------------------------------------------- */
- void clish_shell_param_generator(clish_shell_t *this, lub_argv_t *matches,
- const clish_command_t *cmd, const char *line, unsigned offset)
- {
- const char *name = clish_command__get_name(cmd);
- char *text = lub_string_dup(&line[offset]);
- clish_ptype_t *ptype;
- unsigned idx = lub_argv_wordcount(name);
- /* get the index of the current parameter */
- unsigned index = lub_argv_wordcount(line) - idx;
- clish_context_t context;
- if ((0 != index) || (offset && line[offset - 1] == ' ')) {
- lub_argv_t *argv = lub_argv_new(line, 0);
- clish_pargv_t *pargv = clish_pargv_new();
- clish_pargv_t *completion = clish_pargv_new();
- unsigned completion_index = 0;
- const clish_param_t *param = NULL;
- /* if there is some text for the parameter then adjust the index */
- if ((0 != index) && (text[0] != '\0'))
- index--;
- /* Parse command line to get completion pargv's */
- /* Prepare context */
- context.shell = this;
- context.cmd = cmd;
- context.action = NULL;
- context.pargv = pargv;
- clish_shell_parse_pargv(pargv, cmd, &context,
- clish_command__get_paramv(cmd),
- argv, &idx, completion, index + idx);
- lub_argv_delete(argv);
- while ((param = clish_pargv__get_param(completion,
- completion_index++))) {
- char *result;
- /* The param is args so it has no completion */
- if (param == clish_command__get_args(cmd))
- continue;
- /* The switch has no completion string */
- if (CLISH_PARAM_SWITCH == clish_param__get_mode(param))
- continue;
- /* The subcommand is identified by it's value */
- if (CLISH_PARAM_SUBCOMMAND ==
- clish_param__get_mode(param)) {
- result = clish_param__get_value(param);
- if (result)
- lub_argv_add(matches, result);
- }
- /* The 'completion' field of PARAM */
- if (clish_param__get_completion(param)) {
- char *str, *q;
- char *saveptr;
- str = clish_shell_expand(
- clish_param__get_completion(param), SHELL_VAR_ACTION, &context);
- if (str) {
- for (q = strtok_r(str, " \n", &saveptr);
- q; q = strtok_r(NULL, " \n", &saveptr)) {
- if (q == strstr(q, text))
- lub_argv_add(matches, q);
- }
- lub_string_free(str);
- }
- }
- /* The common PARAM. Let ptype do the work */
- if ((ptype = clish_param__get_ptype(param)))
- clish_ptype_word_generator(ptype, matches, text);
- }
- clish_pargv_delete(completion);
- clish_pargv_delete(pargv);
- }
- lub_string_free(text);
- }
- /*--------------------------------------------------------- */
|