bug fix:: Never reach readline_prompt() in nsh_initialize, moved it up to the top. Works now.
enhancement: TAB completion now works like Unix, it will autocomplete as much as possible for multiple matches.
This commit is contained in:
parent
09add96e22
commit
211f8bf76d
@ -101,6 +101,18 @@ static const struct extmatch_vtable_s g_nsh_extmatch =
|
|||||||
|
|
||||||
void nsh_initialize(void)
|
void nsh_initialize(void)
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_NSH_READLINE) && defined(CONFIG_READLINE_TABCOMPLETION)
|
||||||
|
/* Configure the NSH prompt */
|
||||||
|
|
||||||
|
(void)readline_prompt(g_nshprompt);
|
||||||
|
|
||||||
|
#ifdef CONFIG_READLINE_HAVE_EXTMATCH
|
||||||
|
/* Set up for tab completion on NSH commands */
|
||||||
|
|
||||||
|
(void)readline_extmatch(&g_nsh_extmatch);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Mount the /etc filesystem */
|
/* Mount the /etc filesystem */
|
||||||
|
|
||||||
(void)nsh_romfsetc();
|
(void)nsh_romfsetc();
|
||||||
@ -114,16 +126,4 @@ void nsh_initialize(void)
|
|||||||
/* Bring up the network */
|
/* Bring up the network */
|
||||||
|
|
||||||
(void)nsh_netinit();
|
(void)nsh_netinit();
|
||||||
|
|
||||||
#if defined(CONFIG_NSH_READLINE) && defined(CONFIG_READLINE_TABCOMPLETION)
|
|
||||||
/* Configure the NSH prompt */
|
|
||||||
|
|
||||||
(void)readline_prompt(g_nshprompt);
|
|
||||||
|
|
||||||
#ifdef CONFIG_READLINE_HAVE_EXTMATCH
|
|
||||||
/* Set up for tab completion on NSH commands */
|
|
||||||
|
|
||||||
(void)readline_extmatch(&g_nsh_extmatch);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,8 @@ static void tab_completion(FAR struct rl_common_s *vtbl, char *buf,
|
|||||||
int len = *nch;
|
int len = *nch;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
int name_len;
|
||||||
|
char tmp_name[CONFIG_TASK_NAME_SIZE+1];
|
||||||
|
|
||||||
if (len >= 1)
|
if (len >= 1)
|
||||||
{
|
{
|
||||||
@ -177,8 +179,6 @@ static void tab_completion(FAR struct rl_common_s *vtbl, char *buf,
|
|||||||
|
|
||||||
if (nr_matches == 1)
|
if (nr_matches == 1)
|
||||||
{
|
{
|
||||||
int name_len;
|
|
||||||
|
|
||||||
/* Yes... that that is the one we want. Was it a match with a
|
/* Yes... that that is the one we want. Was it a match with a
|
||||||
* builtin command? Or with an external command.
|
* builtin command? Or with an external command.
|
||||||
*/
|
*/
|
||||||
@ -229,18 +229,40 @@ static void tab_completion(FAR struct rl_common_s *vtbl, char *buf,
|
|||||||
{
|
{
|
||||||
RL_PUTC(vtbl, '\n');
|
RL_PUTC(vtbl, '\n');
|
||||||
|
|
||||||
|
/* See how many characters we can auto complete for the user
|
||||||
|
* For example, if we have the following commands:
|
||||||
|
* - prog1
|
||||||
|
* - prog2
|
||||||
|
* - prog3
|
||||||
|
* then it should automatically complete up to prog.
|
||||||
|
* We do this in one pass using a temp */
|
||||||
|
|
||||||
|
memset(tmp_name, 0, sizeof(tmp_name));
|
||||||
#ifdef CONFIG_READLINE_HAVE_EXTMATCH
|
#ifdef CONFIG_READLINE_HAVE_EXTMATCH
|
||||||
/* Show the possible external completions */
|
/* Show the possible external completions */
|
||||||
|
|
||||||
for (i = 0; i < nr_ext_matches; i++)
|
for (i = 0; i < nr_ext_matches; i++)
|
||||||
{
|
{
|
||||||
name = g_extmatch_vtbl->getname(ext_matches[i]);
|
name = g_extmatch_vtbl->getname(ext_matches[i]);
|
||||||
|
/* initialize temp */
|
||||||
|
|
||||||
|
if (tmp_name[0] == '\0')
|
||||||
|
{
|
||||||
|
strcpy(tmp_name, name);
|
||||||
|
}
|
||||||
|
|
||||||
RL_PUTC(vtbl, ' ');
|
RL_PUTC(vtbl, ' ');
|
||||||
RL_PUTC(vtbl, ' ');
|
RL_PUTC(vtbl, ' ');
|
||||||
|
|
||||||
for (j = 0; j < strlen(name); j++)
|
for (j = 0; j < strlen(name); j++)
|
||||||
{
|
{
|
||||||
|
/* removing characters that aren't common to all the
|
||||||
|
* matches */
|
||||||
|
|
||||||
|
if (name[j] != tmp_name[j])
|
||||||
|
{
|
||||||
|
tmp_name[j] = '\0';
|
||||||
|
}
|
||||||
RL_PUTC(vtbl, name[j]);
|
RL_PUTC(vtbl, name[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,18 +276,34 @@ static void tab_completion(FAR struct rl_common_s *vtbl, char *buf,
|
|||||||
for (i = 0; i < nr_builtin_matches; i++)
|
for (i = 0; i < nr_builtin_matches; i++)
|
||||||
{
|
{
|
||||||
name = builtin_getname(builtin_matches[i]);
|
name = builtin_getname(builtin_matches[i]);
|
||||||
|
/* initialize temp */
|
||||||
|
|
||||||
|
if (tmp_name[0] == '\0')
|
||||||
|
{
|
||||||
|
strcpy(tmp_name, name);
|
||||||
|
}
|
||||||
|
|
||||||
RL_PUTC(vtbl, ' ');
|
RL_PUTC(vtbl, ' ');
|
||||||
RL_PUTC(vtbl, ' ');
|
RL_PUTC(vtbl, ' ');
|
||||||
|
|
||||||
for (j = 0; j < strlen(name); j++)
|
for (j = 0; j < strlen(name); j++)
|
||||||
{
|
{
|
||||||
|
/* removing characters that aren't common to all the
|
||||||
|
* matches */
|
||||||
|
|
||||||
|
if (name[j] != tmp_name[j])
|
||||||
|
{
|
||||||
|
tmp_name[j] = '\0';
|
||||||
|
}
|
||||||
RL_PUTC(vtbl, name[j]);
|
RL_PUTC(vtbl, name[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
RL_PUTC(vtbl, '\n');
|
RL_PUTC(vtbl, '\n');
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
strcpy(buf, tmp_name);
|
||||||
|
|
||||||
|
name_len = strlen(tmp_name);
|
||||||
|
|
||||||
/* Output the original prompt */
|
/* Output the original prompt */
|
||||||
|
|
||||||
@ -277,10 +315,17 @@ static void tab_completion(FAR struct rl_common_s *vtbl, char *buf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < name_len; i++)
|
||||||
{
|
{
|
||||||
RL_PUTC(vtbl, buf[i]);
|
RL_PUTC(vtbl, buf[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Don't remove extra characters after the completed word, if any. */
|
||||||
|
|
||||||
|
if (len < name_len)
|
||||||
|
{
|
||||||
|
*nch = name_len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -341,7 +386,7 @@ FAR const char *readline_prompt(FAR const char *prompt)
|
|||||||
* Assumptions:
|
* Assumptions:
|
||||||
* The vtbl string is statically allocated a global. readline() will
|
* The vtbl string is statically allocated a global. readline() will
|
||||||
* simply remember the pointer to the structure. The structure must stay
|
* simply remember the pointer to the structure. The structure must stay
|
||||||
* allocated and available. Only one instance of such a structure is
|
* allocated and available. Only one instance of such a structure is
|
||||||
* supported. If there are multiple clients of readline(), they must all
|
* supported. If there are multiple clients of readline(), they must all
|
||||||
* share the same tab-completion logic (with exceptions in the case of
|
* share the same tab-completion logic (with exceptions in the case of
|
||||||
* the kernel build).
|
* the kernel build).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user