aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-04-10 10:20:15 +0100
committerRon Yorston <rmy@pobox.com>2023-04-10 11:45:46 +0100
commit66c9b8f39acbba587eda0cababa3de37e89b8dff (patch)
tree732e6265edfd8e3a627c29f2b10410c9fa789ca6
parent3165054d234e0f37f1a230312f1fd2ab3677bbc0 (diff)
downloadbusybox-w32-66c9b8f39acbba587eda0cababa3de37e89b8dff.tar.gz
busybox-w32-66c9b8f39acbba587eda0cababa3de37e89b8dff.tar.bz2
busybox-w32-66c9b8f39acbba587eda0cababa3de37e89b8dff.zip
ash,hush: tab completion of functions and aliases
Rework the 'get_exe_name' functions in ash and hush so functions and aliases are considered when tab-completing a command. function old new delta ash_command_name - 188 +188 hush_command_name - 118 +118 complete_cmd_dir_file 876 880 +4 ash_builtin_name 17 - -17 hush_builtin_name 38 - -38 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 1/0 up/down: 310/-55) Total: 255 bytes (GitHub issue #301) Signed-off-by: Ron Yorston <rmy@pobox.com>
-rw-r--r--include/libbb.h9
-rw-r--r--libbb/lineedit.c8
-rw-r--r--shell/ash.c48
-rw-r--r--shell/hush.c34
4 files changed, 84 insertions, 15 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 6191debb1..66781da4f 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1924,7 +1924,14 @@ unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC;
1924# else 1924# else
1925# define MAX_HISTORY 0 1925# define MAX_HISTORY 0
1926# endif 1926# endif
1927typedef const char *get_exe_name_t(int i) FAST_FUNC; 1927typedef struct exe_state {
1928 int e_type; /* type of tab completion: builtin, alias, function */
1929 int e_index; /* index of current table entry or hash bucket */
1930# if ENABLE_SHELL_ASH || (ENABLE_SHELL_HUSH && ENABLE_HUSH_FUNCTIONS)
1931 void *e_ptr; /* current position in linked list */
1932# endif
1933} exe_state;
1934typedef const char *get_exe_name_t(exe_state *e) FAST_FUNC;
1928typedef const char *sh_get_var_t(const char *name) FAST_FUNC; 1935typedef const char *sh_get_var_t(const char *name) FAST_FUNC;
1929typedef struct line_input_t { 1936typedef struct line_input_t {
1930 int flags; 1937 int flags;
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 625884adf..5daceff16 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -875,9 +875,13 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
875# endif 875# endif
876# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH 876# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH
877 if (state->get_exe_name) { 877 if (state->get_exe_name) {
878 i = 0; 878# if ENABLE_SHELL_ASH || (ENABLE_SHELL_HUSH && ENABLE_HUSH_FUNCTIONS)
879 exe_state e = { 0, 0, NULL };
880# else
881 exe_state e = { 0, 0 };
882# endif
879 for (;;) { 883 for (;;) {
880 const char *b = state->get_exe_name(i++); 884 const char *b = state->get_exe_name(&e);
881 if (!b) 885 if (!b)
882 break; 886 break;
883 if (strncmp(basecmd, b, baselen) == 0) 887 if (strncmp(basecmd, b, baselen) == 0)
diff --git a/shell/ash.c b/shell/ash.c
index 26239ff09..c77ee8620 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -9732,7 +9732,7 @@ evalpipe(union node *n, int flags)
9732 9732
9733/* setinteractive needs this forward reference */ 9733/* setinteractive needs this forward reference */
9734#if ENABLE_FEATURE_TAB_COMPLETION 9734#if ENABLE_FEATURE_TAB_COMPLETION
9735static const char *ash_builtin_name(int i) FAST_FUNC; 9735static const char *ash_command_name(exe_state *e) FAST_FUNC;
9736#endif 9736#endif
9737 9737
9738/* 9738/*
@@ -9769,7 +9769,7 @@ setinteractive(int on)
9769 if (!line_input_state) { 9769 if (!line_input_state) {
9770 line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); 9770 line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
9771# if ENABLE_FEATURE_TAB_COMPLETION 9771# if ENABLE_FEATURE_TAB_COMPLETION
9772 line_input_state->get_exe_name = ash_builtin_name; 9772 line_input_state->get_exe_name = ash_command_name;
9773# endif 9773# endif
9774# if EDITING_HAS_sh_get_var 9774# if EDITING_HAS_sh_get_var
9775 line_input_state->sh_get_var = lookupvar; 9775 line_input_state->sh_get_var = lookupvar;
@@ -10284,9 +10284,47 @@ find_builtin(const char *name)
10284 10284
10285#if ENABLE_FEATURE_TAB_COMPLETION 10285#if ENABLE_FEATURE_TAB_COMPLETION
10286static const char * FAST_FUNC 10286static const char * FAST_FUNC
10287ash_builtin_name(int i) 10287ash_command_name(struct exe_state *e)
10288{ 10288{
10289 return /*i >= 0 &&*/ i < ARRAY_SIZE(builtintab) ? builtintab[i].name + 1 : NULL; 10289 if (e->e_type == 0) {
10290 if (/*e->e_index >= 0 &&*/ e->e_index < ARRAY_SIZE(builtintab)) {
10291 return builtintab[e->e_index++].name + 1;
10292 }
10293 e->e_type++;
10294 e->e_index = 0;
10295 e->e_ptr = cmdtable[0];
10296 }
10297 if (e->e_type == 1) {
10298 struct tblentry *cmdp = (struct tblentry *)e->e_ptr;
10299 while (e->e_index < CMDTABLESIZE) {
10300 while (cmdp) {
10301 if (cmdp->cmdtype == CMDFUNCTION) {
10302 e->e_ptr = cmdp->next;
10303 return cmdp->cmdname;
10304 }
10305 cmdp = cmdp->next;
10306 }
10307 cmdp = cmdtable[++e->e_index];
10308 }
10309# if ENABLE_ASH_ALIAS
10310 e->e_type++;
10311 e->e_index = 0;
10312 e->e_ptr = atab[0];
10313# endif
10314 }
10315# if ENABLE_ASH_ALIAS
10316 if (e->e_type == 2) {
10317 struct alias *ap = (struct alias *)e->e_ptr;
10318 while (e->e_index < ATABSIZE) {
10319 while (ap) {
10320 e->e_ptr = ap->next;
10321 return ap->name;
10322 }
10323 ap = atab[++e->e_index];
10324 }
10325 }
10326# endif
10327 return NULL;
10290} 10328}
10291#endif 10329#endif
10292 10330
diff --git a/shell/hush.c b/shell/hush.c
index 330a0aa79..443bdeccf 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -8220,15 +8220,35 @@ static const struct built_in_command *find_builtin(const char *name)
8220} 8220}
8221 8221
8222#if ENABLE_HUSH_JOB && ENABLE_FEATURE_TAB_COMPLETION 8222#if ENABLE_HUSH_JOB && ENABLE_FEATURE_TAB_COMPLETION
8223static const char * FAST_FUNC hush_builtin_name(int i) 8223static const char * FAST_FUNC hush_command_name(exe_state *e)
8224{ 8224{
8225 if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) { 8225 if (e->e_type == 0) {
8226 return bltins1[i].b_cmd; 8226 if (/*e->e_index >= 0 && */ e->e_index < ARRAY_SIZE(bltins1)) {
8227 return bltins1[e->e_index++].b_cmd;
8228 }
8229 e->e_type++;
8230 e->e_index = 0;
8231 /* e->e_ptr = NULL; */
8232 }
8233 if (e->e_type == 1) {
8234 if (e->e_index < ARRAY_SIZE(bltins2)) {
8235 return bltins2[e->e_index++].b_cmd;
8236 }
8237# if ENABLE_HUSH_FUNCTIONS
8238 e->e_type++;
8239 /* e->e_index = 0; */
8240 e->e_ptr = G.top_func;
8241# endif
8227 } 8242 }
8228 i -= ARRAY_SIZE(bltins1); 8243# if ENABLE_HUSH_FUNCTIONS
8229 if (i < ARRAY_SIZE(bltins2)) { 8244 if (e->e_type == 2) {
8230 return bltins2[i].b_cmd; 8245 struct function *funcp = (struct function *)e->e_ptr;
8246 while (funcp) {
8247 e->e_ptr = funcp->next;
8248 return funcp->name;
8249 }
8231 } 8250 }
8251# endif
8232 return NULL; 8252 return NULL;
8233} 8253}
8234#endif 8254#endif
@@ -10716,7 +10736,7 @@ int hush_main(int argc, char **argv)
10716# if ENABLE_FEATURE_EDITING 10736# if ENABLE_FEATURE_EDITING
10717 G.line_input_state = new_line_input_t(FOR_SHELL); 10737 G.line_input_state = new_line_input_t(FOR_SHELL);
10718# if ENABLE_FEATURE_TAB_COMPLETION 10738# if ENABLE_FEATURE_TAB_COMPLETION
10719 G.line_input_state->get_exe_name = hush_builtin_name; 10739 G.line_input_state->get_exe_name = hush_command_name;
10720# endif 10740# endif
10721# if EDITING_HAS_sh_get_var 10741# if EDITING_HAS_sh_get_var
10722 G.line_input_state->sh_get_var = get_local_var_value; 10742 G.line_input_state->sh_get_var = get_local_var_value;