[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    Re: [PATCH] ash: perform autocompletion on builtin commands
From:       Denys Vlasenko <vda.linux () googlemail ! com>
Date:       2014-11-28 20:54:18
Message-ID: CAK1hOcM=i0KLnydep3MC_hfGYSVnGAWUxxZjVO2xfNdadnRGcA () mail ! gmail ! com
[Download RAW message or body]

I would propose a different implementation, something like
attached patch.

However, the problem is:

complete_cmd_dir_file                                773     895    +122
preadbuffer                                          516     562     +46
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 168/0)             Total: 168 bytes


This looks largish, considering that shell builtins are not
exactly such a long commands so that you'd often want
to use tab completion:

    . : [ [[ alias bg break cd chdir command continue echo eval exec
    exit export false fg getopts hash help history jobs kill let
    local printf pwd read readonly return set shift source test times
    trap true type ulimit umask unalias unset wait

They seem to mostly fall into two categories: (1) short coammnds
like "cd", "fg" or "kill", and (2) rarely interactively used commands
(do you ever use "continue" on command line? "getopts"?).

Who feels this addition is useful?

["1.patch" (text/x-patch)]

diff -d -urpN busybox.0/include/libbb.h busybox.1/include/libbb.h
--- busybox.0/include/libbb.h	2014-11-27 23:31:08.000000000 +0100
+++ busybox.1/include/libbb.h	2014-11-28 20:24:27.157817664 +0100
@@ -1475,6 +1475,10 @@ unsigned size_from_HISTFILESIZE(const ch
 typedef struct line_input_t {
 	int flags;
 	const char *path_lookup;
+# if ENABLE_FEATURE_TAB_COMPLETION
+	const char **compl_exe;
+	int compl_exe_cnt;
+# endif
 # if MAX_HISTORY
 	int cnt_history;
 	int cur_history;
diff -d -urpN busybox.0/libbb/lineedit.c busybox.1/libbb/lineedit.c
--- busybox.0/libbb/lineedit.c	2014-11-27 23:31:08.000000000 +0100
+++ busybox.1/libbb/lineedit.c	2014-11-28 20:29:07.651500676 +0100
@@ -828,6 +828,14 @@ static NOINLINE unsigned complete_cmd_di
 		closedir(dir);
 	} /* for every path */
 
+	if (state->compl_exe && type == FIND_EXE_ONLY) {
+		const char **completions = state->compl_exe;
+		int len = strlen(command);
+		for (i = 0; i < state->compl_exe_cnt && completions[i]; i++)
+			if (strncmp(command, completions[i], len) == 0)
+				add_match(xstrdup(completions[i]));
+	}
+
 	if (paths != path1) {
 		free(paths[0]); /* allocated memory is only in first member */
 		free(paths);
diff -d -urpN busybox.0/shell/ash.c busybox.1/shell/ash.c
--- busybox.0/shell/ash.c	2014-11-27 23:31:08.000000000 +0100
+++ busybox.1/shell/ash.c	2014-11-28 20:45:42.317234012 +0100
@@ -9683,6 +9683,16 @@ preadfd(void)
 		nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1, /*loop_on_EINTR:*/ 1);
 	else {
 		int timeout = -1;
+# if ENABLE_FEATURE_TAB_COMPLETION
+		int i;
+		const char *builtins[ARRAY_SIZE(builtintab)];
+
+		for (i = 0; i < ARRAY_SIZE(builtintab); i++)
+			builtins[i] = builtintab[i].name + 1;
+		line_input_state->compl_exe = builtins;
+		line_input_state->compl_exe_cnt = ARRAY_SIZE(builtintab);
+		line_input_state->path_lookup = pathval();
+# endif
 # if ENABLE_ASH_IDLE_TIMEOUT
 		if (iflag) {
 			const char *tmout_var = lookupvar("TMOUT");
@@ -9693,11 +9703,9 @@ preadfd(void)
 			}
 		}
 # endif
-# if ENABLE_FEATURE_TAB_COMPLETION
-		line_input_state->path_lookup = pathval();
-# endif
 		reinit_unicode_for_ash();
 		nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout);
+
 		if (nr == 0) {
 			/* Ctrl+C pressed */
 			if (trap[SIGINT]) {


_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic