diff options
author | Ron Yorston <rmy@pobox.com> | 2020-01-21 16:01:58 +0000 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-01-29 15:23:17 +0100 |
commit | 9e2a5668fd38db169d9d91b13089a99df4c9bd37 (patch) | |
tree | 3d823cd22bf7627fbb5ef90fdcfae794c1f94ab2 | |
parent | 1ff7002b1d229c678fdffebec602fb4c54439a31 (diff) | |
download | busybox-w32-9e2a5668fd38db169d9d91b13089a99df4c9bd37.tar.gz busybox-w32-9e2a5668fd38db169d9d91b13089a99df4c9bd37.tar.bz2 busybox-w32-9e2a5668fd38db169d9d91b13089a99df4c9bd37.zip |
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>
-rw-r--r-- | include/libbb.h | 13 | ||||
-rw-r--r-- | libbb/lineedit.c | 17 | ||||
-rw-r--r-- | shell/ash.c | 19 | ||||
-rw-r--r-- | shell/hush.c | 17 |
4 files changed, 62 insertions, 4 deletions
diff --git a/include/libbb.h b/include/libbb.h index 05a560977..392c0443d 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1818,10 +1818,19 @@ unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC; | |||
1818 | # else | 1818 | # else |
1819 | # define MAX_HISTORY 0 | 1819 | # define MAX_HISTORY 0 |
1820 | # endif | 1820 | # endif |
1821 | typedef const char *get_exe_name_t(int i) FAST_FUNC; | ||
1821 | typedef struct line_input_t { | 1822 | typedef struct line_input_t { |
1822 | int flags; | 1823 | int flags; |
1823 | int timeout; | 1824 | int timeout; |
1824 | const char *path_lookup; | 1825 | const char *path_lookup; |
1826 | # if ENABLE_FEATURE_TAB_COMPLETION \ | ||
1827 | && (ENABLE_ASH || ENABLE_SH_IS_ASH || ENABLE_BASH_IS_ASH \ | ||
1828 | || ENABLE_HUSH || ENABLE_SH_IS_HUSH || ENABLE_BASH_IS_HUSH \ | ||
1829 | ) | ||
1830 | /* function to fetch additional application-specific names to match */ | ||
1831 | get_exe_name_t *get_exe_name; | ||
1832 | # define EDITING_HAS_get_exe_name 1 | ||
1833 | # endif | ||
1825 | # if MAX_HISTORY | 1834 | # if MAX_HISTORY |
1826 | int cnt_history; | 1835 | int cnt_history; |
1827 | int cur_history; | 1836 | int cur_history; |
@@ -1868,6 +1877,10 @@ int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC; | |||
1868 | read_line_input(prompt, command, maxsize) | 1877 | read_line_input(prompt, command, maxsize) |
1869 | #endif | 1878 | #endif |
1870 | 1879 | ||
1880 | #ifndef EDITING_HAS_get_exe_name | ||
1881 | # define EDITING_HAS_get_exe_name 0 | ||
1882 | #endif | ||
1883 | |||
1871 | 1884 | ||
1872 | #ifndef COMM_LEN | 1885 | #ifndef COMM_LEN |
1873 | # ifdef TASK_COMM_LEN | 1886 | # ifdef TASK_COMM_LEN |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index b1ec52b88..de236dea0 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -813,18 +813,29 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
813 | } | 813 | } |
814 | pf_len = strlen(pfind); | 814 | pf_len = strlen(pfind); |
815 | 815 | ||
816 | # if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1 | ||
817 | if (type == FIND_EXE_ONLY && !dirbuf) { | 816 | if (type == FIND_EXE_ONLY && !dirbuf) { |
817 | # if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1 | ||
818 | const char *p = applet_names; | 818 | const char *p = applet_names; |
819 | |||
820 | while (*p) { | 819 | while (*p) { |
821 | if (strncmp(pfind, p, pf_len) == 0) | 820 | if (strncmp(pfind, p, pf_len) == 0) |
822 | add_match(xstrdup(p)); | 821 | add_match(xstrdup(p)); |
823 | while (*p++ != '\0') | 822 | while (*p++ != '\0') |
824 | continue; | 823 | continue; |
825 | } | 824 | } |
826 | } | ||
827 | # endif | 825 | # endif |
826 | # if EDITING_HAS_get_exe_name | ||
827 | if (state->get_exe_name) { | ||
828 | i = 0; | ||
829 | for (;;) { | ||
830 | const char *b = state->get_exe_name(i++); | ||
831 | if (!b) | ||
832 | break; | ||
833 | if (strncmp(pfind, b, pf_len) == 0) | ||
834 | add_match(xstrdup(b)); | ||
835 | } | ||
836 | } | ||
837 | # endif | ||
838 | } | ||
828 | 839 | ||
829 | for (i = 0; i < npaths; i++) { | 840 | for (i = 0; i < npaths; i++) { |
830 | DIR *dir; | 841 | DIR *dir; |
diff --git a/shell/ash.c b/shell/ash.c index d6040f47e..fb4028219 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -9523,6 +9523,11 @@ evalpipe(union node *n, int flags) | |||
9523 | return status; | 9523 | return status; |
9524 | } | 9524 | } |
9525 | 9525 | ||
9526 | /* setinteractive needs this forward reference */ | ||
9527 | #if EDITING_HAS_get_exe_name | ||
9528 | static const char *get_builtin_name(int i) FAST_FUNC; | ||
9529 | #endif | ||
9530 | |||
9526 | /* | 9531 | /* |
9527 | * Controls whether the shell is interactive or not. | 9532 | * Controls whether the shell is interactive or not. |
9528 | */ | 9533 | */ |
@@ -9554,8 +9559,12 @@ setinteractive(int on) | |||
9554 | } | 9559 | } |
9555 | #endif | 9560 | #endif |
9556 | #if ENABLE_FEATURE_EDITING | 9561 | #if ENABLE_FEATURE_EDITING |
9557 | if (!line_input_state) | 9562 | if (!line_input_state) { |
9558 | line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); | 9563 | line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); |
9564 | # if EDITING_HAS_get_exe_name | ||
9565 | line_input_state->get_exe_name = get_builtin_name; | ||
9566 | # endif | ||
9567 | } | ||
9559 | #endif | 9568 | #endif |
9560 | } | 9569 | } |
9561 | } | 9570 | } |
@@ -10023,6 +10032,14 @@ find_builtin(const char *name) | |||
10023 | return bp; | 10032 | return bp; |
10024 | } | 10033 | } |
10025 | 10034 | ||
10035 | #if EDITING_HAS_get_exe_name | ||
10036 | static const char * FAST_FUNC | ||
10037 | get_builtin_name(int i) | ||
10038 | { | ||
10039 | return /*i >= 0 &&*/ i < ARRAY_SIZE(builtintab) ? builtintab[i].name + 1 : NULL; | ||
10040 | } | ||
10041 | #endif | ||
10042 | |||
10026 | /* | 10043 | /* |
10027 | * Execute a simple command. | 10044 | * Execute a simple command. |
10028 | */ | 10045 | */ |
diff --git a/shell/hush.c b/shell/hush.c index 97202b953..6e44d4e11 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -7889,6 +7889,20 @@ static const struct built_in_command *find_builtin(const char *name) | |||
7889 | return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]); | 7889 | return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]); |
7890 | } | 7890 | } |
7891 | 7891 | ||
7892 | #if EDITING_HAS_get_exe_name | ||
7893 | static const char * FAST_FUNC get_builtin_name(int i) | ||
7894 | { | ||
7895 | if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) { | ||
7896 | return bltins1[i].b_cmd; | ||
7897 | } | ||
7898 | i -= ARRAY_SIZE(bltins1); | ||
7899 | if (i < ARRAY_SIZE(bltins2)) { | ||
7900 | return bltins2[i].b_cmd; | ||
7901 | } | ||
7902 | return NULL; | ||
7903 | } | ||
7904 | #endif | ||
7905 | |||
7892 | static void remove_nested_vars(void) | 7906 | static void remove_nested_vars(void) |
7893 | { | 7907 | { |
7894 | struct variable *cur; | 7908 | struct variable *cur; |
@@ -10268,6 +10282,9 @@ int hush_main(int argc, char **argv) | |||
10268 | 10282 | ||
10269 | # if ENABLE_FEATURE_EDITING | 10283 | # if ENABLE_FEATURE_EDITING |
10270 | G.line_input_state = new_line_input_t(FOR_SHELL); | 10284 | G.line_input_state = new_line_input_t(FOR_SHELL); |
10285 | # if EDITING_HAS_get_exe_name | ||
10286 | G.line_input_state->get_exe_name = get_builtin_name; | ||
10287 | # endif | ||
10271 | # endif | 10288 | # endif |
10272 | # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 | 10289 | # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 |
10273 | { | 10290 | { |