123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- /*
- * shell_help.c
- */
- #include "private.h"
- #include "lub/string.h"
- #include <stdio.h>
- #include <string.h>
- /*--------------------------------------------------------- */
- /*
- * Provide a detailed list of the possible command completions
- */
- static void
- available_commands(clish_shell_t * this, const char *line, bool_t full)
- {
- 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);
- /* find the best match... */
- cmd = clish_shell_resolve_prefix(this, line);
- if (cmd) {
- error_offset +=
- strlen(clish_command__get_name(cmd)) + 1;
- /* take a copy for help purposes */
- buf = lub_string_dup(clish_command__get_name(cmd));
- } else {
- /* show all possible commands */
- buf = lub_string_dup("");
- }
- /* indicate the point of error */
- fprintf(stderr, "%*s\n", error_offset, "^");
- } else {
- /* take a copy */
- buf = lub_string_dup(line);
- }
- /* iterate round to determine max_width */
- for (cmd = clish_shell_getfirst_command(this, buf, CLISH_NSPACE_HELP);
- cmd; cmd = clish_shell_getnext_command(this, buf)) {
- size_t width;
- const char *name;
- if (full) {
- name = clish_command__get_name(cmd);
- } else {
- name = clish_command__get_suffix(cmd);
- }
- width = strlen(name);
- if (width > max_width) {
- max_width = width;
- }
- }
- /* now iterate round to print the help */
- 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));
- }
- /* cleanup */
- lub_string_free(buf);
- }
- /*--------------------------------------------------------- */
- void clish_shell_help(clish_shell_t * this, const char *line)
- {
- const clish_command_t *cmd, *next_cmd, *first_cmd;
- /* if there are further commands then we need to show them too */
- cmd = clish_shell_resolve_prefix(this, line);
- if (cmd) {
- clish_shell_iterator_t iter;
- /* skip the command already known about */
- 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;
- }
- if (cmd && !next_cmd && (!first_cmd || (first_cmd == cmd))) {
- /* we've resolved a particular command */
- 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:
- /* get the command to provide help */
- clish_command_help(cmd, this->viewid, line);
- break;
- default:
- /* do nothing */
- break;
- }
- } else {
- /* dump the available commands */
- available_commands(this, line, BOOL_FALSE);
- }
- /* update the state */
- if (this->state == SHELL_STATE_HELPING)
- this->state = SHELL_STATE_OK;
- else
- this->state = SHELL_STATE_HELPING;
- }
- /*--------------------------------------------------------- */
|