From e61af474c1e37952f2e59a2a0e5842185ae1adc5 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 24 Apr 2009 09:00:29 +0000 Subject: 26876 with updated documentation: add ZLE_{REMOVE,SPACE}_SUFFIX_CHARS --- ChangeLog | 10 +++++++- Doc/Zsh/compwid.yo | 5 ++++ Doc/Zsh/params.yo | 43 ++++++++++++++++++++++++++++++++++ NEWS | 4 ++++ Src/Zle/compresult.c | 8 +++---- Src/Zle/zle.h | 4 ++++ Src/Zle/zle_misc.c | 65 +++++++++++++++++++++++++++++++++++++++++----------- 7 files changed, 120 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index b2ca7ab76..39bbffbb1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-04-24 Peter Stephenson + + * 26876 (documentation slightly modified): NEWS, Doc/Zsh/compwid.yo, + Doc/Zsh/params.yo, Src/Zle/compresult.c, Src/Zle/zle.h, + Src/Zle/zle_misc.c: add ZLE_REMOVE_SUFFIX_CHARS and + ZLE_SPACE_SUFFIX_CHARS to make actions for suffix removals when + not controlled by completion system more configurable. + 2009-04-23 Clint Adams * 26877, 26879: Completion/Debian/Command/_apt: handle apt-get @@ -11608,5 +11616,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.4665 $ +* $Revision: 1.4666 $ ***************************************************** diff --git a/Doc/Zsh/compwid.yo b/Doc/Zsh/compwid.yo index 80427330d..b8786dd26 100644 --- a/Doc/Zsh/compwid.yo +++ b/Doc/Zsh/compwid.yo @@ -58,6 +58,11 @@ endmenu() texinode(Completion Special Parameters)(Completion Builtin Commands)()(Completion Widgets) sect(Completion Special Parameters) +The parameters tt(ZLE_REMOVE_SUFFIX_CHARS) and tt(ZLE_SPACE_SUFFIX_CHARS) +are used by the completion mechanism, but are not special. +ifzman(See em(Parameters Used By The Shell) in zmanref(zshparam))\ +ifnzman(noderef(Parameters Used By The Shell)). + Inside completion widgets, and any functions called from them, some parameters have special meaning; outside these functions they are not special to the shell in any way. These parameters are used to pass diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 7a8efdd94..e36becf53 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -1330,4 +1330,47 @@ item(tt(ZDOTDIR))( The directory to search for shell startup files (.zshrc, etc), if not tt($HOME). ) +vindex(ZLE_REMOVE_SUFFIX_CHARS) +vindex(ZLE_SPACE_SUFFIX_CHARS) +xitem(tt(ZLE_REMOVE_SUFFIX_CHARS)) +item(tt(ZLE_SPACE_SUFFIX_CHARS))( +These parameters are used by the line editor. In certain circumstances +suffixes (typically space or slash) added by the completion system +will be removed automatically, either because the next editing command +was not an insertable character, or because the character was marked +as requiring the suffix to be removed. + +These variables can contain the sets of characters that will cause the +suffix to be removed. If tt(ZLE_REMOVE_SUFFIX_CHARS) is set, those +characters will cause the suffix to be removed; if +tt(ZLE_SPACE_SUFFIX_CHARS) is set, those characters will cause the +suffix to be removed and replaced by a space. + +If tt(ZLE_REMOVE_SUFFIX_CHARS) is not set, the default behaviour is +equivalent to: + +example(ZLE_REMOVE_SUFFIX_CHARS=$' \t\n;&|') + +If tt(ZLE_REMOVE_SUFFIX_CHARS) is set but is empty, no characters have this +behaviour. tt(ZLE_SPACE_SUFFIX_CHARS) takes precedence, so that the +following: + +example(ZLE_SPACE_SUFFIX_CHARS=$'&|') + +causes the characters `tt(&)' and `tt(|)' to remove the suffix but to +replace it with a space. + +To illustrate the difference, suppose that the option tt(AUTO_REMOVE_SLASH) +is in effect and the directory tt(DIR) has just been completed, with an +appended tt(/), following which the user types `tt(&)'. The default result +is `tt(DIR&)'. With tt(ZLE_REMOVE_SUFFIX_CHARS) set but without including +`tt(&)' the result is `tt(DIR/&)'. With tt(ZLE_SPACE_SUFFIX_CHARS) set to +include `tt(&)' the result is `tt(DIR &)'. + +Note that certain completions may provide their own suffix removal +or replacement behaviour which overrides the values described here. +See the completion system documentation in +ifzman(zmanref(zshcompsys))\ +ifnzman(noderef(Completion System)). +) enditem() diff --git a/NEWS b/NEWS index e103840ee..b26617a60 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,10 @@ shells. The variable ZSH_PATCHLEVEL can be used to test for unreleased versions of the shell; it is present but less useful in released versions. +The variables ZLE_REMOVE_SUFFIX_CHARS and ZLE_SPACE_SUFFIX_CHARS allow more +control over the way automatically removed suffixes are treated in +completion. + Major changes between versions 4.3.6 and 4.3.9 ---------------------------------------------- diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c index e595802dd..43733b0c6 100644 --- a/Src/Zle/compresult.c +++ b/Src/Zle/compresult.c @@ -1011,7 +1011,7 @@ do_single(Cmatch m) stringaszleline(m->suf, 0, &len, NULL, NULL); makesuffixstr(m->remf, m->rems, len); if (len == 1) - addsuffix(SUFTYP_POSSTR, wsuf, 1, 1); + addsuffix(SUFTYP_POSSTR, 0, wsuf, 1, 1); free(wsuf); } } @@ -1104,7 +1104,7 @@ do_single(Cmatch m) makesuffixstr(m->remf, m->rems, 1); else if (isset(AUTOREMOVESLASH)) { makesuffix(1); - addsuffix(SUFTYP_POSSTR, ZWS("/"), 1, 1); + addsuffix(SUFTYP_POSSTR, 0, ZWS("/"), 1, 1); } } } @@ -1119,7 +1119,7 @@ do_single(Cmatch m) /* If a suffix was added, and is removable, let * * `,' and `}' remove it. */ if (isset(AUTOPARAMKEYS)) - addsuffix(SUFTYP_POSSTR, ZWS(",}"), 2, suffixnoinslen); + addsuffix(SUFTYP_POSSTR, 0, ZWS(",}"), 2, suffixnoinslen); } else if (!menucmp) { /*{{*/ /* Otherwise, add a `,' suffix, and let `}' remove it. */ @@ -1129,7 +1129,7 @@ do_single(Cmatch m) minfo.insc++; makesuffix(1); if ((!menucmp || minfo.we) && isset(AUTOPARAMKEYS)) - addsuffix(SUFTYP_POSSTR, ZWS(",}"), 2, 1); + addsuffix(SUFTYP_POSSTR, 0, ZWS(",}"), 2, 1); } } else if (!havesuff && (!(m->flags & CMF_FILE) || !sr)) { /* If we didn't add a suffix, add a space, unless we are * diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h index 1fd6d87a2..577a4442f 100644 --- a/Src/Zle/zle.h +++ b/Src/Zle/zle.h @@ -380,6 +380,10 @@ enum suffixtype { SUFTYP_NEGRNG /* Range of characters not to match */ }; +/* Additional flags to suffixes */ +enum suffixflags { + SUFFLAGS_SPACE = 0x0001 /* Add a space when removing suffix */ +}; #ifdef MULTIBYTE_SUPPORT /* diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index 961776f43..0beb43d6d 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -1232,6 +1232,7 @@ struct suffixset; struct suffixset { struct suffixset *next; /* Next in the list */ int tp; /* The SUFTYP_* from enum suffixtype */ + int flags; /* Some of SUFFLAGS_* */ ZLE_STRING_T chars; /* Set of characters to match (or not) */ int lenstr; /* Length of chars */ int lensuf; /* Length of suffix */ @@ -1255,13 +1256,14 @@ suffixnoinslen; /**/ mod_export void -addsuffix(int tp, ZLE_STRING_T chars, int lenstr, int lensuf) +addsuffix(int tp, int flags, ZLE_STRING_T chars, int lenstr, int lensuf) { struct suffixset *newsuf = zalloc(sizeof(struct suffixset)); newsuf->next = suffixlist; suffixlist = newsuf; newsuf->tp = tp; + newsuf->flags = flags; if (lenstr) { newsuf->chars = zalloc(lenstr*sizeof(ZLE_CHAR_T)); ZS_memcpy(newsuf->chars, chars, lenstr); @@ -1271,6 +1273,24 @@ addsuffix(int tp, ZLE_STRING_T chars, int lenstr, int lensuf) newsuf->lensuf = lensuf; } + +/* Same as addsuffix, but from metafied string */ + +/**/ +mod_export void +addsuffixstring(int tp, int flags, char *chars, int lensuf) +{ + int slen, alloclen; + ZLE_STRING_T suffixstr; + + /* string needs to be writable... I've been regretting this for years.. */ + chars = ztrdup(chars); + suffixstr = stringaszleline(chars, 0, &slen, &alloclen, NULL); + addsuffix(tp, flags, suffixstr, slen, lensuf); + zfree(suffixstr, alloclen); + zsfree(chars); +} + /* Set up suffix: the last n characters are a suffix that should be * * removed in the usual word end conditions. */ @@ -1278,7 +1298,17 @@ addsuffix(int tp, ZLE_STRING_T chars, int lenstr, int lensuf) mod_export void makesuffix(int n) { - addsuffix(SUFTYP_POSSTR, ZWS(" \t\n;&|"), 6, n); + char *suffixchars; + + if (!(suffixchars = getsparam("ZLE_REMOVE_SUFFIX_CHARS"))) + suffixchars = " \t\n;&|"; + + addsuffixstring(SUFTYP_POSSTR, 0, suffixchars, n); + + /* Do this second so it takes precedence */ + if ((suffixchars = getsparam("ZLE_SPACE_SUFFIX_CHARS")) && *suffixchars) + addsuffixstring(SUFTYP_POSSTR, SUFFLAGS_SPACE, suffixchars, n); + suffixnoinslen = n; } @@ -1301,7 +1331,7 @@ makeparamsuffix(int br, int n) lenstr += 6; } if (lenstr) - addsuffix(SUFTYP_POSSTR, charstr, lenstr, n); + addsuffix(SUFTYP_POSSTR, 0, charstr, lenstr, n); } /* Set up suffix given a string containing the characters on which to * @@ -1344,11 +1374,11 @@ makesuffixstr(char *f, char *s, int n) ZLE_CHAR_T str[2]; if (wptr > lasts) - addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, + addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, 0, lasts, wptr - lasts, n); str[0] = *wptr; str[1] = wptr[2]; - addsuffix(inv ? SUFTYP_NEGRNG : SUFTYP_POSRNG, + addsuffix(inv ? SUFTYP_NEGRNG : SUFTYP_POSRNG, 0, str, 2, n); wptr += 3; @@ -1360,7 +1390,7 @@ makesuffixstr(char *f, char *s, int n) } } if (wptr > lasts) - addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, + addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, 0, lasts, wptr - lasts, n); free(ws); } else @@ -1410,7 +1440,7 @@ iremovesuffix(ZLE_INT_T c, int keep) zsfree(suffixfunc); suffixfunc = NULL; } else { - int sl = 0; + int sl = 0, flags = 0; struct suffixset *ss; if (c == NO_INSERT_CHAR) { @@ -1463,8 +1493,10 @@ iremovesuffix(ZLE_INT_T c, int keep) } break; } - if (found) + if (found) { + flags = ss->flags; break; + } } if (!found) @@ -1472,12 +1504,17 @@ iremovesuffix(ZLE_INT_T c, int keep) } if (sl) { /* must be shifting wide character lengths */ - if (zlemetaline != NULL) { - unmetafy_line(); - backdel(sl, CUT_RAW); - metafy_line(); - } else - backdel(sl, CUT_RAW); + backdel(sl, CUT_RAW); + if (flags & SUFFLAGS_SPACE) + { + /* Add a space and advance over it */ + spaceinline(1); + if (zlemetaline) { + zlemetaline[zlemetacs++] = ' '; + } else { + zleline[zlecs++] = ZWC(' '); + } + } if (!keep) invalidatelist(); } -- cgit 1.4.1