shell_command.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * shell_word_generator.c
  3. */
  4. #include <string.h>
  5. #include "private.h"
  6. #include "lub/string.h"
  7. #include "lub/argv.h"
  8. /*-------------------------------------------------------- */
  9. void
  10. clish_shell_iterator_init(clish_shell_iterator_t * iter,
  11. clish_nspace_visibility_t field)
  12. {
  13. iter->last_cmd = NULL;
  14. iter->field = field;
  15. }
  16. /*--------------------------------------------------------- */
  17. const clish_command_t *clish_shell_resolve_command(const clish_shell_t * this,
  18. const char *line)
  19. {
  20. clish_command_t *cmd, *result;
  21. /* Search the current view */
  22. result = clish_view_resolve_command(this->view, line, BOOL_TRUE);
  23. /* Search the global view */
  24. cmd = clish_view_resolve_command(this->global, line, BOOL_TRUE);
  25. result = clish_command_choose_longest(result, cmd);
  26. return result;
  27. }
  28. /*--------------------------------------------------------- */
  29. const clish_command_t *clish_shell_resolve_prefix(const clish_shell_t * this,
  30. const char *line)
  31. {
  32. clish_command_t *cmd, *result;
  33. /* Search the current view */
  34. result = clish_view_resolve_prefix(this->view, line, BOOL_TRUE);
  35. /* Search the global view */
  36. cmd = clish_view_resolve_prefix(this->global, line, BOOL_TRUE);
  37. result = clish_command_choose_longest(result, cmd);
  38. return result;
  39. }
  40. /*-------------------------------------------------------- */
  41. const clish_command_t *clish_shell_find_next_completion(const clish_shell_t *
  42. this, const char *line, clish_shell_iterator_t * iter)
  43. {
  44. const clish_command_t *result, *cmd;
  45. /* ask the local view for next command */
  46. result = clish_view_find_next_completion(this->view,
  47. iter->last_cmd, line, iter->field, BOOL_TRUE);
  48. /* ask the global view for next command */
  49. cmd = clish_view_find_next_completion(this->global,
  50. iter->last_cmd, line, iter->field, BOOL_TRUE);
  51. if (clish_command_diff(result, cmd) > 0)
  52. result = cmd;
  53. if (!result)
  54. iter->last_cmd = NULL;
  55. else
  56. iter->last_cmd = clish_command__get_name(result);
  57. return result;
  58. }
  59. /*--------------------------------------------------------- */
  60. void clish_shell_param_generator(clish_shell_t *this, lub_argv_t *matches,
  61. const clish_command_t *cmd, const char *line, unsigned offset)
  62. {
  63. const char *name = clish_command__get_name(cmd);
  64. char *text = lub_string_dup(&line[offset]);
  65. clish_ptype_t *ptype;
  66. unsigned idx = lub_argv_wordcount(name);
  67. /* get the index of the current parameter */
  68. unsigned index = lub_argv_wordcount(line) - idx;
  69. if ((0 != index) || (offset && line[offset - 1] == ' ')) {
  70. lub_argv_t *argv = lub_argv_new(line, 0);
  71. clish_pargv_t *pargv = clish_pargv_create();
  72. clish_pargv_t *completion_pargv = clish_pargv_create();
  73. unsigned completion_index = 0;
  74. const clish_param_t *param = NULL;
  75. /* if there is some text for the parameter then adjust the index */
  76. if ((0 != index) && (text[0] != '\0'))
  77. index--;
  78. /* Parse command line to get completion pargv's */
  79. clish_pargv_parse(pargv, cmd, this->viewid,
  80. clish_command__get_paramv(cmd),
  81. argv, &idx, completion_pargv, index + idx);
  82. clish_pargv_delete(pargv);
  83. lub_argv_delete(argv);
  84. while ((param = clish_pargv__get_param(completion_pargv,
  85. completion_index++))) {
  86. char *result;
  87. /* The param is args so it has no completion */
  88. if (param == clish_command__get_args(cmd))
  89. continue;
  90. /* The switch has no completion string */
  91. if (CLISH_PARAM_SWITCH == clish_param__get_mode(param))
  92. continue;
  93. /* The subcommand is identified by it's value */
  94. if (CLISH_PARAM_SUBCOMMAND ==
  95. clish_param__get_mode(param)) {
  96. result = clish_param__get_value(param);
  97. if (result)
  98. lub_argv_add(matches, result);
  99. }
  100. /* The common PARAM. Let ptype do the work */
  101. if ((ptype = clish_param__get_ptype(param)))
  102. clish_ptype_word_generator(ptype, matches, text);
  103. }
  104. clish_pargv_delete(completion_pargv);
  105. }
  106. lub_string_free(text);
  107. }
  108. /*--------------------------------------------------------- */