Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: trailing components
- X-seq: zsh-workers 44421
- From: Peter Stephenson <p.stephenson@xxxxxxxxxxx>
- To: Zsh Hackers' List <zsh-workers@xxxxxxx>
- Subject: PATCH: trailing components
- Date: Tue, 18 Jun 2019 14:00:06 +0100
- Cms-type: 201P
- Dkim-filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20190618130010euoutp02a693964e6f27369d84cb98a22df24feb~pTHS3jF0_0797607976euoutp02C
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1560862810; bh=dvWW9a8GVN4a2Hefqxgs2/7aucXwnDvblFSCGxrf6rc=; h=Subject:From:To:Date:References:From; b=ZSDmNN475lp/UE0+QqHPwVAFUs3Km3tEJF4KkleCpRd3n1iO3HPQ1qAltXYwceNqt ZvC8bClFMJWzfyEBf6w4lihIUao4AFVxRfXUu9th4NPccosiTxSO4/6+jU5+IigGb8 D+3JMwibvjuNN27U/kpPDqOE/pFPV4Aah54CL0iY=
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- List-unsubscribe: <mailto:zsh-workers-unsubscribe@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- References: <CGME20190618130008eucas1p176cc19c1c8b831fc30b4bf7b3294f3af@eucas1p1.samsung.com>
I needed to preserve a number of trailing components of a path (other
than one) and couldn't think of an easy way of doing it. Rather than
craft obscure pattern substitutions, or use an ad-hoc expression to
strip the prefix, I came up with a patch to add an optional number after
the "t" in history style modifiers to do this. I put it after rather
than before because history-style colon expressions are quite sensitive
to what the first character is after the colon.
Before I come up with tests and fix up the ensuing failures, you can let
me know if there's a better way of doing this to save me the trouble.
pws
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index a212d742d..d28a30767 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -316,9 +316,11 @@ immediately by a tt(g). In parameter expansion the tt(&) must appear
inside braces, and in filename generation it must be quoted with a
backslash.
)
-item(tt(t))(
+item(tt(t) [ var(digits) ])(
Remove all leading pathname components, leaving the tail. This works
-like `tt(basename)'.
+like `tt(basename)'. Any trailing slashes are first removed.
+If followed by any number of decimal digits, that number of trailing
+components is preserved.
)
item(tt(u))(
Convert the words to all uppercase.
diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c
index f963d5712..f242e1b28 100644
--- a/Src/Zle/compctl.c
+++ b/Src/Zle/compctl.c
@@ -2511,7 +2511,7 @@ makecomplistcmd(char *os, int incmd, int flags)
else if (!(cmdstr &&
(((ccp = (Compctlp) compctltab->getnode(compctltab, cmdstr)) &&
(cc = ccp->cc)) ||
- ((s = dupstring(cmdstr)) && remlpaths(&s) &&
+ ((s = dupstring(cmdstr)) && remlpaths(&s, 1) &&
(ccp = (Compctlp) compctltab->getnode(compctltab, s)) &&
(cc = ccp->cc))))) {
if (flags & CFN_DEFAULT)
diff --git a/Src/hist.c b/Src/hist.c
index 901cd3b1a..2117f2bd6 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -798,7 +798,7 @@ histsubchar(int c)
c = (cflag) ? ':' : ingetc();
cflag = 0;
if (c == ':') {
- int gbal = 0;
+ int gbal = 0, count;
if ((c = ingetc()) == 'g') {
gbal = 1;
@@ -856,7 +856,18 @@ histsubchar(int c)
}
break;
case 't':
- if (!remlpaths(&sline)) {
+ c = ingetc();
+ if (idigit(c)) {
+ count = 0;
+ do {
+ count = 10 * count + (c - '0');
+ c = ingetc();
+ } while (idigit(c));
+ }
+ else
+ count = 1;
+ inungetc(c);
+ if (!remlpaths(&sline, count)) {
herrflush();
zerr("modifier failed: t");
return -1;
@@ -2040,7 +2051,7 @@ rembutext(char **junkptr)
/**/
mod_export int
-remlpaths(char **junkptr)
+remlpaths(char **junkptr, int count)
{
char *str = strend(*junkptr);
@@ -2050,12 +2061,21 @@ remlpaths(char **junkptr)
--str;
str[1] = '\0';
}
- for (; str >= *junkptr; --str)
- if (IS_DIRSEP(*str)) {
- *str = '\0';
- *junkptr = dupstring(str + 1);
- return 1;
+ for (;;) {
+ for (; str >= *junkptr; --str) {
+ if (IS_DIRSEP(*str)) {
+ if (--count > 0 && str > *junkptr) {
+ --str;
+ break;
+ }
+ *str = '\0';
+ *junkptr = dupstring(str + 1);
+ return 1;
+ }
}
+ if (str <= *junkptr)
+ break;
+ }
return 0;
}
diff --git a/Src/subst.c b/Src/subst.c
index 60eb33390..d1fff2e67 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -4193,7 +4193,7 @@ modify(char **str, char **ptr)
{
char *ptr1, *ptr2, *ptr3, *lptr, c, *test, *sep, *t, *tt, tc, *e;
char *copy, *all, *tmp, sav, sav1, *ptr1end;
- int gbal, wall, rec, al, nl, charlen, dellen;
+ int gbal, wall, rec, al, nl, charlen, dellen, count = 1;
convchar_t del;
test = NULL;
@@ -4217,7 +4217,6 @@ modify(char **str, char **ptr)
case 'h':
case 'r':
case 'e':
- case 't':
case 'l':
case 'u':
case 'q':
@@ -4226,6 +4225,17 @@ modify(char **str, char **ptr)
c = **ptr;
break;
+ case 't':
+ c = **ptr;
+ if (idigit((*ptr)[1])) {
+ count = 0;
+ do {
+ count = 10 * count + ((*ptr)[1] - '0');
+ ++(*ptr);
+ } while (idigit((*ptr)[1]));
+ }
+ break;
+
case 's':
c = **ptr;
(*ptr)++;
@@ -4401,7 +4411,7 @@ modify(char **str, char **ptr)
rembutext(©);
break;
case 't':
- remlpaths(©);
+ remlpaths(©, count);
break;
case 'l':
copy = casemodify(tt, CASMOD_LOWER);
@@ -4487,7 +4497,7 @@ modify(char **str, char **ptr)
rembutext(str);
break;
case 't':
- remlpaths(str);
+ remlpaths(str, count);
break;
case 'l':
*str = casemodify(*str, CASMOD_LOWER);
Messages sorted by:
Reverse Date,
Date,
Thread,
Author