ash,hush: allow builtins to be tab-completed, closes 7532

function                                             old     new   delta
complete_cmd_dir_file                                678     830    +152
get_builtin_name                                       -      35     +35
optschanged                                          125     132      +7
hush_main                                           1069    1076      +7
save_command_ps_at_cur_history                        76      78      +2
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 4/0 up/down: 203/0)             Total: 203 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Ron Yorston 2020-01-21 16:01:58 +00:00 committed by Denys Vlasenko
parent 1ff7002b1d
commit 9e2a5668fd
4 changed files with 62 additions and 4 deletions

View File

@ -1818,10 +1818,19 @@ unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC;
# else
# define MAX_HISTORY 0
# endif
typedef const char *get_exe_name_t(int i) FAST_FUNC;
typedef struct line_input_t {
int flags;
int timeout;
const char *path_lookup;
# if ENABLE_FEATURE_TAB_COMPLETION \
&& (ENABLE_ASH || ENABLE_SH_IS_ASH || ENABLE_BASH_IS_ASH \
|| ENABLE_HUSH || ENABLE_SH_IS_HUSH || ENABLE_BASH_IS_HUSH \
)
/* function to fetch additional application-specific names to match */
get_exe_name_t *get_exe_name;
# define EDITING_HAS_get_exe_name 1
# endif
# if MAX_HISTORY
int cnt_history;
int cur_history;
@ -1868,6 +1877,10 @@ int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;
read_line_input(prompt, command, maxsize)
#endif
#ifndef EDITING_HAS_get_exe_name
# define EDITING_HAS_get_exe_name 0
#endif
#ifndef COMM_LEN
# ifdef TASK_COMM_LEN

View File

@ -813,18 +813,29 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
}
pf_len = strlen(pfind);
# if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1
if (type == FIND_EXE_ONLY && !dirbuf) {
# if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1
const char *p = applet_names;
while (*p) {
if (strncmp(pfind, p, pf_len) == 0)
add_match(xstrdup(p));
while (*p++ != '\0')
continue;
}
}
# endif
# if EDITING_HAS_get_exe_name
if (state->get_exe_name) {
i = 0;
for (;;) {
const char *b = state->get_exe_name(i++);
if (!b)
break;
if (strncmp(pfind, b, pf_len) == 0)
add_match(xstrdup(b));
}
}
# endif
}
for (i = 0; i < npaths; i++) {
DIR *dir;

View File

@ -9523,6 +9523,11 @@ evalpipe(union node *n, int flags)
return status;
}
/* setinteractive needs this forward reference */
#if EDITING_HAS_get_exe_name
static const char *get_builtin_name(int i) FAST_FUNC;
#endif
/*
* Controls whether the shell is interactive or not.
*/
@ -9554,8 +9559,12 @@ setinteractive(int on)
}
#endif
#if ENABLE_FEATURE_EDITING
if (!line_input_state)
if (!line_input_state) {
line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
# if EDITING_HAS_get_exe_name
line_input_state->get_exe_name = get_builtin_name;
# endif
}
#endif
}
}
@ -10023,6 +10032,14 @@ find_builtin(const char *name)
return bp;
}
#if EDITING_HAS_get_exe_name
static const char * FAST_FUNC
get_builtin_name(int i)
{
return /*i >= 0 &&*/ i < ARRAY_SIZE(builtintab) ? builtintab[i].name + 1 : NULL;
}
#endif
/*
* Execute a simple command.
*/

View File

@ -7889,6 +7889,20 @@ static const struct built_in_command *find_builtin(const char *name)
return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]);
}
#if EDITING_HAS_get_exe_name
static const char * FAST_FUNC get_builtin_name(int i)
{
if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) {
return bltins1[i].b_cmd;
}
i -= ARRAY_SIZE(bltins1);
if (i < ARRAY_SIZE(bltins2)) {
return bltins2[i].b_cmd;
}
return NULL;
}
#endif
static void remove_nested_vars(void)
{
struct variable *cur;
@ -10268,6 +10282,9 @@ int hush_main(int argc, char **argv)
# if ENABLE_FEATURE_EDITING
G.line_input_state = new_line_input_t(FOR_SHELL);
# if EDITING_HAS_get_exe_name
G.line_input_state->get_exe_name = get_builtin_name;
# endif
# endif
# if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0
{