shell_command_generator.c 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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_find_next_completion(const clish_shell_t *
  18. this, const char *line, clish_shell_iterator_t * iter)
  19. {
  20. const clish_command_t *result, *cmd;
  21. /* ask the local view for next command */
  22. result = clish_view_find_next_completion(this->view,
  23. iter->last_cmd, line, iter->field, BOOL_TRUE);
  24. /* ask the global view for next command */
  25. cmd = clish_view_find_next_completion(this->global,
  26. iter->last_cmd, line, iter->field, BOOL_TRUE);
  27. if (clish_command_diff(result, cmd) > 0)
  28. result = cmd;
  29. if (!result)
  30. iter->last_cmd = NULL;
  31. else
  32. iter->last_cmd = clish_command__get_name(result);
  33. return result;
  34. }
  35. /*--------------------------------------------------------- */
  36. void clish_shell_param_generator(clish_shell_t *this, lub_argv_t *matches,
  37. const clish_command_t *cmd, const char *line, unsigned offset)
  38. {
  39. const char *name = clish_command__get_name(cmd);
  40. char *text = lub_string_dup(&line[offset]);
  41. clish_ptype_t *ptype;
  42. unsigned idx = lub_argv_wordcount(name);
  43. /* get the index of the current parameter */
  44. unsigned index = lub_argv_wordcount(line) - idx;
  45. if ((0 != index) || (line[offset - 1] == ' ')) {
  46. lub_argv_t *argv = lub_argv_new(line, 0);
  47. clish_pargv_t *pargv = clish_pargv_create();
  48. clish_pargv_t *completion_pargv = clish_pargv_create();
  49. unsigned completion_index = 0;
  50. const clish_param_t *param = NULL;
  51. /* if there is some text for the parameter then adjust the index */
  52. if ((0 != index) && (text[0] != '\0'))
  53. index--;
  54. /* Parse command line to get completion pargv's */
  55. clish_pargv_parse(pargv, cmd, this->viewid,
  56. clish_command__get_paramv(cmd),
  57. argv, &idx, completion_pargv, index + idx);
  58. clish_pargv_delete(pargv);
  59. lub_argv_delete(argv);
  60. while ((param = clish_pargv__get_param(completion_pargv,
  61. completion_index++))) {
  62. char *result;
  63. /* The param is args so it has no completion */
  64. if (param == clish_command__get_args(cmd))
  65. continue;
  66. /* The switch has no completion string */
  67. if (CLISH_PARAM_SWITCH == clish_param__get_mode(param))
  68. continue;
  69. /* The subcommand is identified by it's value */
  70. if (CLISH_PARAM_SUBCOMMAND ==
  71. clish_param__get_mode(param)) {
  72. result = clish_param__get_value(param);
  73. if (result)
  74. lub_argv_add(matches, result);
  75. }
  76. /* The common PARAM. Let ptype do the work */
  77. if ((ptype = clish_param__get_ptype(param)))
  78. clish_ptype_word_generator(ptype, matches, text);
  79. }
  80. clish_pargv_delete(completion_pargv);
  81. }
  82. lub_string_free(text);
  83. }
  84. /*--------------------------------------------------------- */