Since commit 70ee23399 (vi: code shrink) the ':set' command is unable to process multiple options on a line. Fix this by temporarily null-terminating each option.
Change the default setting for all options to off to match vim. Actually, 'flash' isn't an option in vim, only traditional vi, where it's on by default. In vim the corresponding option is 'visualbell' which defaults to off. POSIX doesn't have either of these. Allow the abbreviation 'ts' for the 'tabstop' option. function old new delta colon 3292 3297 +5 .rodata 105142 105145 +3 vi_main 305 301 -4 setops 85 - -85 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 2/1 up/down: 8/-89) Total: -81 bytes Signed-off-by: Ron Yorston <r...@pobox.com> --- editors/vi.c | 80 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/editors/vi.c b/editors/vi.c index e48ad68c7..33976e9ad 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -287,10 +287,12 @@ struct globals { // the rest smallint vi_setops; -#define VI_AUTOINDENT 1 -#define VI_SHOWMATCH 2 -#define VI_IGNORECASE 4 -#define VI_ERR_METHOD 8 +// the order of these values must match that in setops() +#define VI_AUTOINDENT (1 << 0) +#define VI_ERR_METHOD (1 << 1) +#define VI_IGNORECASE (1 << 2) +#define VI_SHOWMATCH (1 << 3) +#define VI_TABSTOP (1 << 4) #define autoindent (vi_setops & VI_AUTOINDENT) #define showmatch (vi_setops & VI_SHOWMATCH ) #define ignorecase (vi_setops & VI_IGNORECASE) @@ -2408,17 +2410,40 @@ static char *get_address(char *p, int *b, int *e) // get two colon addrs, if pre } # if ENABLE_FEATURE_VI_SET && ENABLE_FEATURE_VI_SETOPTS -static void setops(const char *args, const char *nm_longname, int flg_no, int opt) +// order must match option flags +#define OPTS \ + "ai\0""autoindent\0" \ + "fl\0""flash\0" \ + "ic\0""ignorecase\0" \ + "sm\0""showmatch\0" \ + "ts\0""tabstop\0" + +static void setops(const char *args, int flg_no) { - const char *a = args + flg_no; + char *eq; + int index, opt; + + // check for options with "=", they don't take "no" as a prefix + eq = strchr(args, '='); + if (eq) { + *eq = '\0'; + flg_no = 0; + } - if (strcmp(a, nm_longname) == 0 - || strcmp(a, nm_longname + 3) == 0 - ) { - if (flg_no) - vi_setops &= ~opt; - else - vi_setops |= opt; + index = index_in_strings(OPTS, args + flg_no); + if (index == -1) + return; + + opt = 1 << (index/2); + if (opt == VI_TABSTOP) { + int t = bb_strtou(eq + 1, NULL, 10); + if (t > 0 && t <= MAX_TABSTOP) + tabstop = t; + } + else if (flg_no) { + vi_setops &= ~opt; + } else { + vi_setops |= opt; } } # endif @@ -2778,10 +2803,10 @@ static void colon(char *buf) # if ENABLE_FEATURE_VI_SET } else if (strncmp(cmd, "set", i) == 0) { // set or clear features # if ENABLE_FEATURE_VI_SETOPTS - char *argp; + char *argp, *argn, oldch; # endif // only blank is regarded as args delimiter. What about tab '\t'? - if (!args[0] || strcasecmp(args, "all") == 0) { + if (!args[0] || strcmp(args, "all") == 0) { // print out values of all options # if ENABLE_FEATURE_VI_SETOPTS status_line_bold( @@ -2805,17 +2830,12 @@ static void colon(char *buf) i = 0; if (argp[0] == 'n' && argp[1] == 'o') // "noXXX" i = 2; - setops(argp, "ai""\0""autoindent", i, VI_AUTOINDENT); - setops(argp, "fl""\0""flash" , i, VI_ERR_METHOD); - setops(argp, "ic""\0""ignorecase", i, VI_IGNORECASE); - setops(argp, "sm""\0""showmatch" , i, VI_SHOWMATCH ); - if (strncmp(argp, "tabstop=", 8) == 0) { - int t = bb_strtou(argp + 8, NULL, 10); - if (t > 0 && t <= MAX_TABSTOP) - tabstop = t; - } - argp = skip_non_whitespace(argp); - argp = skip_whitespace(argp); + argn = skip_non_whitespace(argp); + oldch = *argn; + *argn = '\0'; + setops(argp, i); + *argn = oldch; + argp = skip_whitespace(argn); } # endif /* FEATURE_VI_SETOPTS */ # endif /* FEATURE_VI_SET */ @@ -4442,10 +4462,10 @@ int vi_main(int argc, char **argv) } #endif - // autoindent is not default in vim 7.3 - vi_setops = /*VI_AUTOINDENT |*/ VI_SHOWMATCH | VI_IGNORECASE; - // 1- process $HOME/.exrc file (not inplemented yet) - // 2- process EXINIT variable from environment + // all of our options are disabled by default in vim + //vi_setops = 0; + // 1- process EXINIT variable from environment + // 2- if EXINIT is unset process $HOME/.exrc file (not inplemented yet) // 3- process command line args #if ENABLE_FEATURE_VI_COLON { -- 2.30.2 _______________________________________________ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox