diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Doc/Zsh/expn.yo | 12 | ||||
-rw-r--r-- | Doc/Zsh/options.yo | 15 | ||||
-rw-r--r-- | Src/glob.c | 43 | ||||
-rw-r--r-- | Src/options.c | 1 | ||||
-rw-r--r-- | Src/zsh.h | 1 |
6 files changed, 60 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog index ba9113487..0ef6fe6ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2015-10-30 Peter Stephenson <p.stephenson@samsung.com> + + * 37022: Doc/Zsh/expn.yo, Doc/Zsh/options.yo, Src/glob.c, + Src/options.c, Src/zsh.h: add GLOB_STAR_SHORT option to + allow shorthand ** for **/* and *** for ***/*. + 2015-10-29 Peter Stephenson <p.stephenson@samsung.com> * 37018: Src/math.c, Src/params.c, Test/E01options.ztst: make diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index 5ea8610f2..20e0c8d35 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -2381,6 +2381,18 @@ follow symbolic links; the alternative form `tt(***/)' does, but is otherwise identical. Neither of these can be combined with other forms of globbing within the same path segment; in that case, the `tt(*)' operators revert to their usual effect. + +Even shorter forms are available when the option tt(GLOB_STAR_SHORT) is +set. In that case if no tt(/) immediately follows a tt(**) or tt(***) +they are treated as if both a tt(/) plus a further tt(*) are present. +Hence: + +example(setopt GLOBSTARSHORT +ls **.c) + +is equivalent to + +example(ls **/*.c) subsect(Glob Qualifiers) cindex(globbing, qualifiers) cindex(qualifiers, globbing) diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index fbf65abbc..60379cabc 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -534,6 +534,21 @@ cindex(globbing, of . files) item(tt(GLOB_DOTS) (tt(-4)))( Do not require a leading `tt(.)' in a filename to be matched explicitly. ) +pindex(GLOB_STAR_SHORT) +pindex(NO_GLOB_STAR_SHORT) +pindex(GLOBSTARSHORT) +pindex(NOGLOBSTARSHORT) +cindex(globbing, short forms) +cindex(globbing, ** special) +item(tt(GLOB_STAR_SHORT))( +When this option is set and the default zsh-style globbing is in +effect, the pattern `tt(**/*)' can be abbreviated to `tt(**)' and the +pattern `tt(***/*)' can be abbreviated to tt(***). Hence `tt(**.c)' +finds a file ending in tt(.c) in any subdirectory, and `tt(***.c)' does +the same while also following symbolic links. A tt(/) immediately +after the `tt(**)' or `tt(***)' forces the pattern to be treated as the +unabbreviated form. +) pindex(GLOB_SUBST) pindex(NO_GLOB_SUBST) pindex(GLOBSUBST) diff --git a/Src/glob.c b/Src/glob.c index 24e60d0c5..51ffeb5d5 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -682,25 +682,32 @@ parsecomplist(char *instr) char *str; int compflags = gf_noglobdots ? (PAT_FILE|PAT_NOGLD) : PAT_FILE; - if (instr[0] == Star && instr[1] == Star && - (instr[2] == '/' || (instr[2] == Star && instr[3] == '/'))) { - /* Match any number of directories. */ - int follow; - - /* with three stars, follow symbolic links */ - follow = (instr[2] == Star); - instr += (3 + follow); - - /* Now get the next path component if there is one. */ - l1 = (Complist) zhalloc(sizeof *l1); - if ((l1->next = parsecomplist(instr)) == NULL) { - errflag |= ERRFLAG_ERROR; - return NULL; + if (instr[0] == Star && instr[1] == Star) { + int shortglob = 0; + if (instr[2] == '/' || (instr[2] == Star && instr[3] == '/') + || (shortglob = isset(GLOBSTARSHORT))) { + /* Match any number of directories. */ + int follow; + + /* with three stars, follow symbolic links */ + follow = (instr[2] == Star); + /* + * With GLOBSTARSHORT, leave a star in place for the + * pattern inside the directory. + */ + instr += ((shortglob ? 1 : 3) + follow); + + /* Now get the next path component if there is one. */ + l1 = (Complist) zhalloc(sizeof *l1); + if ((l1->next = parsecomplist(instr)) == NULL) { + errflag |= ERRFLAG_ERROR; + return NULL; + } + l1->pat = patcompile(NULL, compflags | PAT_ANY, NULL); + l1->closure = 1; /* ...zero or more times. */ + l1->follow = follow; + return l1; } - l1->pat = patcompile(NULL, compflags | PAT_ANY, NULL); - l1->closure = 1; /* ...zero or more times. */ - l1->follow = follow; - return l1; } /* Parse repeated directories such as (dir/)# and (dir/)## */ diff --git a/Src/options.c b/Src/options.c index 1fb102f1d..3bf9f39a4 100644 --- a/Src/options.c +++ b/Src/options.c @@ -140,6 +140,7 @@ static struct optname optns[] = { {{NULL, "globassign", OPT_EMULATE|OPT_CSH}, GLOBASSIGN}, {{NULL, "globcomplete", 0}, GLOBCOMPLETE}, {{NULL, "globdots", OPT_EMULATE}, GLOBDOTS}, +{{NULL, "globstarshort", OPT_EMULATE}, GLOBSTARSHORT}, {{NULL, "globsubst", OPT_EMULATE|OPT_NONZSH}, GLOBSUBST}, {{NULL, "hashcmds", OPT_ALL}, HASHCMDS}, {{NULL, "hashdirs", OPT_ALL}, HASHDIRS}, diff --git a/Src/zsh.h b/Src/zsh.h index d03d171e4..a6f039741 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2215,6 +2215,7 @@ enum { GLOBASSIGN, GLOBCOMPLETE, GLOBDOTS, + GLOBSTARSHORT, GLOBSUBST, HASHCMDS, HASHDIRS, |