shell_help.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * shell_help.c
  3. */
  4. #include "private.h"
  5. #include "clish/types.h"
  6. #include "lub/string.h"
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. /*--------------------------------------------------------- */
  11. /*
  12. * Provide a detailed list of the possible command completions
  13. */
  14. static void available_commands(clish_shell_t * this,
  15. clish_help_t *help, const char *line, size_t *max_width)
  16. {
  17. const clish_command_t *cmd;
  18. clish_shell_iterator_t iter;
  19. if (max_width)
  20. *max_width = 0;
  21. /* Search for COMMAND completions */
  22. clish_shell_iterator_init(&iter, CLISH_NSPACE_HELP);
  23. while ((cmd = clish_shell_find_next_completion(this, line, &iter))) {
  24. size_t width;
  25. const char *name = clish_command__get_suffix(cmd);
  26. if (max_width) {
  27. width = strlen(name);
  28. if (width > *max_width)
  29. *max_width = width;
  30. }
  31. lub_argv_add(help->name, name);
  32. lub_argv_add(help->help, clish_command__get_text(cmd));
  33. lub_argv_add(help->detail, clish_command__get_detail(cmd));
  34. }
  35. }
  36. /*--------------------------------------------------------- */
  37. void clish_shell_help(clish_shell_t *this, const char *line)
  38. {
  39. clish_help_t help;
  40. size_t max_width = 0;
  41. const clish_command_t *cmd;
  42. int i;
  43. help.name = lub_argv_new(NULL, 0);
  44. help.help = lub_argv_new(NULL, 0);
  45. help.detail = lub_argv_new(NULL, 0);
  46. /* Get COMMAND completions */
  47. available_commands(this, &help, line, &max_width);
  48. /* Resolve a command */
  49. cmd = clish_shell_resolve_command(this, line);
  50. /* Search for PARAM completion */
  51. if (cmd) {
  52. size_t width = 0;
  53. int status;
  54. status = clish_command_help(cmd, &help, this->viewid,
  55. line, &width);
  56. if (width > max_width)
  57. max_width = width;
  58. /* Add <cr> if command is completed */
  59. if (!status) {
  60. lub_argv_add(help.name, "<cr>");
  61. lub_argv_add(help.help, NULL);
  62. lub_argv_add(help.detail, NULL);
  63. }
  64. }
  65. if (lub_argv__get_count(help.name) == 0)
  66. goto end;
  67. /* Print help messages */
  68. for (i = 0; i < lub_argv__get_count(help.name); i++) {
  69. fprintf(stderr, " %-*s %s\n", (int)max_width,
  70. lub_argv__get_arg(help.name, i),
  71. lub_argv__get_arg(help.help, i) ?
  72. lub_argv__get_arg(help.help, i) : "");
  73. }
  74. /* Print details */
  75. if ((lub_argv__get_count(help.name) == 1) &&
  76. (SHELL_STATE_HELPING == this->state)) {
  77. const char *detail = lub_argv__get_arg(help.detail, 0);
  78. if (detail)
  79. fprintf(stderr, "%s\n", detail);
  80. }
  81. /* update the state */
  82. if (this->state == SHELL_STATE_HELPING)
  83. this->state = SHELL_STATE_OK;
  84. else
  85. this->state = SHELL_STATE_HELPING;
  86. end:
  87. lub_argv_delete(help.name);
  88. lub_argv_delete(help.help);
  89. lub_argv_delete(help.detail);
  90. }
  91. /*--------------------------------------------------------- */