|
@@ -2,130 +2,92 @@
|
|
|
* shell_help.c
|
|
|
*/
|
|
|
#include "private.h"
|
|
|
+#include "clish/private.h"
|
|
|
#include "lub/string.h"
|
|
|
|
|
|
#include <stdio.h>
|
|
|
#include <string.h>
|
|
|
+#include <ctype.h>
|
|
|
|
|
|
|
|
|
|
|
|
* Provide a detailed list of the possible command completions
|
|
|
*/
|
|
|
-static void
|
|
|
-available_commands(clish_shell_t * this, const char *line, bool_t full)
|
|
|
+static int available_commands(clish_shell_t * this,
|
|
|
+ help_argv_t *help, const char *line)
|
|
|
{
|
|
|
- char *buf = NULL;
|
|
|
size_t max_width = 0;
|
|
|
const clish_command_t *cmd;
|
|
|
- if (NULL == clish_shell_getfirst_command(this, line, CLISH_NSPACE_HELP)) {
|
|
|
-
|
|
|
- * A totally wrong command has been inputed
|
|
|
- * Indicate the point of error and display
|
|
|
- * a list of possible commands
|
|
|
- */
|
|
|
- char *prompt = clish_view__get_prompt(this->view,
|
|
|
- this->viewid);
|
|
|
- unsigned error_offset = strlen(prompt) + 1;
|
|
|
- lub_string_free(prompt);
|
|
|
+ clish_shell_iterator_t iter;
|
|
|
|
|
|
-
|
|
|
- cmd = clish_shell_resolve_prefix(this, line);
|
|
|
- if (cmd) {
|
|
|
- error_offset +=
|
|
|
- strlen(clish_command__get_name(cmd)) + 1;
|
|
|
-
|
|
|
- buf = lub_string_dup(clish_command__get_name(cmd));
|
|
|
- } else {
|
|
|
-
|
|
|
- buf = lub_string_dup("");
|
|
|
- }
|
|
|
-
|
|
|
- fprintf(stderr, "%*s\n", error_offset, "^");
|
|
|
- } else {
|
|
|
-
|
|
|
- buf = lub_string_dup(line);
|
|
|
- }
|
|
|
-
|
|
|
- for (cmd = clish_shell_getfirst_command(this, buf, CLISH_NSPACE_HELP);
|
|
|
- cmd; cmd = clish_shell_getnext_command(this, buf)) {
|
|
|
+
|
|
|
+ clish_shell_iterator_init(&iter, CLISH_NSPACE_HELP);
|
|
|
+ while ((cmd = clish_shell_find_next_completion(this, line, &iter))) {
|
|
|
size_t width;
|
|
|
- const char *name;
|
|
|
- if (full) {
|
|
|
- name = clish_command__get_name(cmd);
|
|
|
- } else {
|
|
|
- name = clish_command__get_suffix(cmd);
|
|
|
- }
|
|
|
+ const char *name = clish_command__get_suffix(cmd);
|
|
|
width = strlen(name);
|
|
|
- if (width > max_width) {
|
|
|
+ if (width > max_width)
|
|
|
max_width = width;
|
|
|
- }
|
|
|
+ lub_argv_add(help->matches, name);
|
|
|
+ lub_argv_add(help->help, clish_command__get_text(cmd));
|
|
|
+ lub_argv_add(help->detail, clish_command__get_detail(cmd));
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- for (cmd = clish_shell_getfirst_command(this, buf, CLISH_NSPACE_HELP);
|
|
|
- cmd; cmd = clish_shell_getnext_command(this, buf)) {
|
|
|
- const char *name;
|
|
|
- if (full) {
|
|
|
- name = clish_command__get_name(cmd);
|
|
|
- } else {
|
|
|
- name = clish_command__get_suffix(cmd);
|
|
|
- }
|
|
|
- fprintf(stderr, " %-*s %s\n",
|
|
|
- (int)max_width, name, clish_command__get_text(cmd));
|
|
|
- }
|
|
|
-
|
|
|
- lub_string_free(buf);
|
|
|
+ return max_width;
|
|
|
}
|
|
|
|
|
|
|
|
|
-void clish_shell_help(clish_shell_t * this, const char *line)
|
|
|
+void clish_shell_help(clish_shell_t *this, const char *line)
|
|
|
{
|
|
|
- const clish_command_t *cmd, *next_cmd, *first_cmd;
|
|
|
+ help_argv_t help;
|
|
|
+ size_t max_width = 0;
|
|
|
+ const clish_command_t *cmd;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ help.matches = lub_argv_new(NULL, 0);
|
|
|
+ help.help = lub_argv_new(NULL, 0);
|
|
|
+ help.detail = lub_argv_new(NULL, 0);
|
|
|
+
|
|
|
+
|
|
|
+ max_width = available_commands(this, &help, line);
|
|
|
|
|
|
-
|
|
|
- cmd = clish_shell_resolve_prefix(this, line);
|
|
|
+
|
|
|
+ cmd = clish_shell_resolve_command(this, line);
|
|
|
+
|
|
|
if (cmd) {
|
|
|
- clish_shell_iterator_t iter;
|
|
|
+ size_t width = 0;
|
|
|
+ width = clish_command_help(cmd, &help, this->viewid, line);
|
|
|
+ if (width > max_width)
|
|
|
+ max_width = width;
|
|
|
+ }
|
|
|
+ if (lub_argv__get_count(help.matches) == 0)
|
|
|
+ goto end;
|
|
|
|
|
|
-
|
|
|
- clish_shell_iterator_init(&iter, CLISH_NSPACE_HELP);
|
|
|
- first_cmd = clish_shell_find_next_completion(this, line, &iter);
|
|
|
- next_cmd = clish_shell_find_next_completion(this, line, &iter);
|
|
|
- } else {
|
|
|
- first_cmd = next_cmd = NULL;
|
|
|
+
|
|
|
+ for (i = 0; i < lub_argv__get_count(help.matches); i++) {
|
|
|
+ fprintf(stderr, " %-*s %s\n", (int)max_width,
|
|
|
+ lub_argv__get_arg(help.matches, i),
|
|
|
+ lub_argv__get_arg(help.help, i));
|
|
|
}
|
|
|
- if (cmd && !next_cmd && (!first_cmd || (first_cmd == cmd))) {
|
|
|
-
|
|
|
- switch (this->state) {
|
|
|
- case SHELL_STATE_HELPING:
|
|
|
- {
|
|
|
- const char *detail =
|
|
|
- clish_command__get_detail(cmd);
|
|
|
- if (NULL != detail)
|
|
|
- fprintf(stderr, "%s\n", detail);
|
|
|
- else
|
|
|
- clish_command_help(cmd, this->viewid, line);
|
|
|
- break;
|
|
|
- }
|
|
|
- case SHELL_STATE_OK:
|
|
|
- case SHELL_STATE_SCRIPT_ERROR:
|
|
|
- case SHELL_STATE_SYNTAX_ERROR:
|
|
|
-
|
|
|
- clish_command_help(cmd, this->viewid, line);
|
|
|
- break;
|
|
|
- default:
|
|
|
-
|
|
|
- break;
|
|
|
- }
|
|
|
- } else {
|
|
|
-
|
|
|
- available_commands(this, line, BOOL_FALSE);
|
|
|
+
|
|
|
+
|
|
|
+ if ((lub_argv__get_count(help.matches) == 1) &&
|
|
|
+ (SHELL_STATE_HELPING == this->state)) {
|
|
|
+ const char *detail = lub_argv__get_arg(help.detail, 0);
|
|
|
+ if (detail)
|
|
|
+ fprintf(stderr, "%s\n", detail);
|
|
|
}
|
|
|
+
|
|
|
|
|
|
if (this->state == SHELL_STATE_HELPING)
|
|
|
this->state = SHELL_STATE_OK;
|
|
|
else
|
|
|
this->state = SHELL_STATE_HELPING;
|
|
|
+
|
|
|
+end:
|
|
|
+ lub_argv_delete(help.matches);
|
|
|
+ lub_argv_delete(help.help);
|
|
|
+ lub_argv_delete(help.detail);
|
|
|
}
|
|
|
|
|
|
|