Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: PATCH: add -t <fmt> option to history



On Thu, 26 Feb 2009 16:35:12 +0000
Stephane Chazelas <Stephane_Chazelas@xxxxxxxx> wrote:
> On Thu, Feb 26, 2009 at 03:52:46PM +0000, Peter Stephenson wrote:
> > I needed a new strftime extension for months without a leading blank or
> > zero; does anyone know if %N is used elsewhere as an extension (it's not
> > in POSIX)?
> [...]
> 
> GNU strftime has %-<x> to remove the 0 padding, as in %-m.
> See
> info libc --index-search=strftime
> for more.

We might as well support that extension, so we don't need a new character.
I haven't bothered with the other extensions---it's hardly worth the effort
to support them natively, and if we don't we get more system dependent
behaviour than is really good for us.

Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.120
diff -u -r1.120 builtins.yo
--- Doc/Zsh/builtins.yo	12 Feb 2009 09:56:26 -0000	1.120
+++ Doc/Zsh/builtins.yo	26 Feb 2009 17:13:20 -0000
@@ -484,7 +484,9 @@
 findex(fc)
 cindex(history, editing)
 cindex(editing history)
-xitem(tt(fc) [ tt(-e) var(ename) ] [ tt(-nlrdDfEim) ] [ var(old)tt(=)var(new) ... ] [ var(first) [ var(last) ] ])
+xitem(tt(fc) [ tt(-e) var(ename) ] [ tt(-m) var(match) ] [ var(old)tt(=)var(new) ... ] [ var(first) [ var(last) ] ])
+xitem(tt(fc) tt(-l) [ tt(-nrdfEiD) ] [ tt(-t) var(timefmt) ] [ tt(-m) var(match) ])
+xitem(      [ var(old)tt(=)var(new) ... ] [ var(first) [ var(last) ] ])
 xitem(tt(fc) tt(-p) [ tt(-a) ] [ var(filename) [ var(histsize) [ var(savehistsize) ] ] ])
 xitem(tt(fc) tt(-P))
 item(tt(fc) tt(-ARWI) [ var(filename) ])(
@@ -517,13 +519,26 @@
 
 The flag tt(-r) reverses the order of the commands and the
 flag tt(-n) suppresses command numbers when listing.
-Also when listing, tt(-d) prints timestamps for each command, and
-tt(-f) prints full time-date stamps.  Adding the tt(-E) flag
-causes the dates to be printed as `var(dd)tt(.)var(mm)tt(.)var(yyyy)',
-instead of the default `var(mm)tt(/)var(dd)tt(/)var(yyyy)'.
-Adding the tt(-i) flag causes the dates to be printed in ISO8601
-`var(yyyy)tt(-)var(mm)tt(-)var(dd)' format.
-With the tt(-D) flag, tt(fc) prints elapsed times.
+
+Also when listing,
+startsitem()
+sitem(tt(-d))(prints timestamps for each command)
+sitem(tt(-f))(prints full time-date stamps in the US
+`var(MM)tt(/)var(DD)tt(/)var(YY) var(hh):var(mm)' format)
+sitem(tt(-E))(prints full time-date stamps in the European
+`var(dd)tt(.)var(mm)tt(.)var(yyyy) var(hh):var(mm)' format)
+sitem(tt(-i))(prints full time-date stamps in ISO8601
+`var(yyyy)tt(-)var(mm)tt(-)var(dd) var(hh):var(mm)' format)
+sitem(tt(-t) var(fmt))(prints time and date stamps in the given format;
+var(fmt) is formatted with the strftime function with the zsh extensions
+described for the tt(%D{)var(string)tt(}) prompt format in
+ifzman(the section EXPANSION OF PROMPT SEQUENCES in zmanref(zshmisc))\
+ifnzman(noderef(Prompt Expansion)).  The resulting formatted string must be
+no more than 256 characters or will not be printed.
+)
+sitem(tt(-D))(prints elapsed times; may be combined with one of the
+options above.)
+endsitem()
 
 cindex(history, stack)
 cindex(stack, history)
Index: Doc/Zsh/calsys.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/calsys.yo,v
retrieving revision 1.15
diff -u -r1.15 calsys.yo
--- Doc/Zsh/calsys.yo	10 Dec 2008 13:30:27 -0000	1.15
+++ Doc/Zsh/calsys.yo	26 Feb 2009 17:13:20 -0000
@@ -613,9 +613,11 @@
 kindex(date-format)
 item(tt(date-format))(
 A tt(strftime) format string (see manref(strftime)(3)) with the zsh
-extensions tt(%f) for a day of the month with no leading zero or space
-for single digits, and tt(%k) or tt(%l) for the hour of the day on the 24-
-or 12-hour clock, again with no leading zero or space for single digits.
+extensions providing various numbers with no leading zero or space
+if the number is a single digit as described for the
+tt(%D{)var(string)tt(}) prompt format in
+ifzman(the section EXPANSION OF PROMPT SEQUENCES in zmanref(zshmisc))\
+ifnzman(noderef(Prompt Expansion)).
 
 This is used for outputting dates in tt(calendar), both to support
 the tt(-v) option and when adding recurring events back to the calendar
Index: Doc/Zsh/prompt.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/prompt.yo,v
retrieving revision 1.16
diff -u -r1.16 prompt.yo
--- Doc/Zsh/prompt.yo	16 Sep 2008 15:04:44 -0000	1.16
+++ Doc/Zsh/prompt.yo	26 Feb 2009 17:13:20 -0000
@@ -171,11 +171,23 @@
 )
 item(tt(%D{)var(string)tt(}))(
 var(string) is formatted using the tt(strftime) function.
-See manref(strftime)(3) for more details.  Three additional codes are
-available:  tt(%f) prints the day of the month, like tt(%e) but
-without any preceding space if the day is a single digit, and
-tt(%K)/tt(%L) correspond to tt(%k)/tt(%l) for the hour of the day
-(24/12 hour clock) in the same way.
+See manref(strftime)(3) for more details.  Various zsh
+extensions provide numbers with no leading zero or space
+if the number is a single digit:
+
+startsitem()
+sitem(tt(%f))(a day of the month)
+sitem(tt(%k))(the hour of the day on the 24-hour clock)
+sitem(tt(%l))(the hour of the day on the 12-hour clock)
+endsitem()
+
+The GNU extension that a `tt(-)' between the tt(%) and the
+format character causes a leading zero or space to be stripped
+is handled directly by the shell for the format characters tt(d), tt(f),
+tt(H), tt(K), tt(L), tt(m), tt(M), tt(S) and tt(y); any other format
+characters are provided to tt(strftime()) with any leading `tt(-)',
+present, so the handling is system dependent.  Further GNU
+extensions are not supported at present.
 )
 enditem()
 
Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.221
diff -u -r1.221 builtin.c
--- Src/builtin.c	25 Feb 2009 10:24:01 -0000	1.221
+++ Src/builtin.c	26 Feb 2009 17:13:20 -0000
@@ -69,7 +69,7 @@
      * But that's actually not useful, so it's more consistent to
      * cause an error.
      */
-    BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "nlre:IRWAdDfEimpPa", NULL),
+    BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "aAdDe:EfiIlmnpPrRt:W", NULL),
     BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
     BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "E:%F:%HL:%R:%Z:%ghlprtux", "E"),
     BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "kmMtuUz", NULL),
@@ -81,7 +81,7 @@
     BUILTIN("hashinfo", 0, bin_hashinfo, 0, 0, 0, NULL, NULL),
 #endif
 
-    BUILTIN("history", 0, bin_fc, 0, -1, BIN_FC, "nrdDfEimpPa", "l"),
+    BUILTIN("history", 0, bin_fc, 0, -1, BIN_FC, "adDEfimnpPrt:", "l"),
     BUILTIN("integer", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "HL:%R:%Z:%ghi:%lprtux", "i"),
     BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL),
     BUILTIN("kill", BINF_HANDLES_OPTS, bin_kill, 0, -1, 0, NULL, NULL),
@@ -1599,7 +1599,7 @@
 {
     int fclistdone = 0;
     zlong tmp;
-    char *s;
+    char *s, *tdfmt, *timebuf;
     Histent ent;
 
     /* reverse range if required */
@@ -1625,6 +1625,25 @@
 	return 1;
     }
 
+    if (OPT_ISSET(ops,'d') || OPT_ISSET(ops,'f') ||
+	OPT_ISSET(ops,'E') || OPT_ISSET(ops,'i') ||
+	OPT_ISSET(ops,'t')) {
+	if (OPT_ISSET(ops,'t')) {
+	    tdfmt = OPT_ARG(ops,'t');
+	} else if (OPT_ISSET(ops,'i')) {
+	    tdfmt = "%Y-%m-%d %H:%M";
+	} else if (OPT_ISSET(ops,'E')) {
+	    tdfmt = "%f.%-m.%Y %H:%M";
+	} else if (OPT_ISSET(ops,'f')) {
+	    tdfmt = "%-m/%f/%Y %H:%M";
+	} else {
+	    tdfmt = "%H:%M";
+	}
+	timebuf = zhalloc(256);
+    } else {
+	tdfmt = timebuf = NULL;
+    }
+
     for (;;) {
 	s = dupstring(ent->node.nam);
 	/* this if does the pattern matching, if required */
@@ -1641,24 +1660,11 @@
 	    }
 	    /* output actual time (and possibly date) of execution of the
 	       command, if required */
-	    if (OPT_ISSET(ops,'d') || OPT_ISSET(ops,'f') ||
-		OPT_ISSET(ops,'E') || OPT_ISSET(ops,'i')) {
+	    if (tdfmt != NULL) {
 		struct tm *ltm;
 		ltm = localtime(&ent->stim);
-		if (OPT_ISSET(ops,'i')) {
-		    fprintf(f, "%d-%02d-%02d ",
-			    ltm->tm_year + 1900,
-			    ltm->tm_mon + 1, ltm->tm_mday);
-		} else if (OPT_ISSET(ops,'E')) {
-		    fprintf(f, "%d.%d.%d ",
-			    ltm->tm_mday, ltm->tm_mon + 1,
-			    ltm->tm_year + 1900);
-		} else if (OPT_ISSET(ops,'f')) {
-		    fprintf(f, "%d/%d/%d ",
-			    ltm->tm_mon + 1, ltm->tm_mday,
-			    ltm->tm_year + 1900);
-		}
-		fprintf(f, "%02d:%02d  ", ltm->tm_hour, ltm->tm_min);
+		if (ztrftime(timebuf, 256, tdfmt, ltm))
+		    fprintf(f, "%s  ", timebuf);
 	    }
 	    /* display the time taken by the command, if required */
 	    if (OPT_ISSET(ops,'D')) {
Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.209
diff -u -r1.209 utils.c
--- Src/utils.c	19 Feb 2009 10:15:10 -0000	1.209
+++ Src/utils.c	26 Feb 2009 17:13:20 -0000
@@ -2436,14 +2436,19 @@
      "Aug", "Sep", "Oct", "Nov", "Dec"};
 #endif
     char *origbuf = buf;
-    char tmp[3];
+    char tmp[4];
 
 
-    tmp[0] = '%';
-    tmp[2] = '\0';
     while (*fmt)
 	if (*fmt == '%') {
+	    int strip;
+
 	    fmt++;
+	    if (*fmt == '-') {
+		strip = 1;
+		fmt++;
+	    } else
+		strip = 0;
 	    /*
 	     * Assume this format will take up at least two
 	     * characters.  Not always true, but if that matters
@@ -2454,51 +2459,67 @@
 		return -1;
 	    switch (*fmt++) {
 	    case 'd':
-		*buf++ = '0' + tm->tm_mday / 10;
+		if (strip || tm->tm_mday > 9)
+		    *buf++ = '0' + tm->tm_mday / 10;
 		*buf++ = '0' + tm->tm_mday % 10;
 		break;
 	    case 'e':
+		strip = 1;
+		/* FALLTHROUGH */
 	    case 'f':
 		if (tm->tm_mday > 9)
 		    *buf++ = '0' + tm->tm_mday / 10;
-		else if (fmt[-1] == 'e')
+		else if (!strip)
 		    *buf++ = ' ';
 		*buf++ = '0' + tm->tm_mday % 10;
 		break;
 	    case 'k':
+		strip = 1;
+		/* FALLTHROUGH */
+	    case 'H':
 	    case 'K':
 		if (tm->tm_hour > 9)
 		    *buf++ = '0' + tm->tm_hour / 10;
-		else if (fmt[-1] == 'k')
-		    *buf++ = ' ';
+		else if (!strip) {
+		    if (fmt[-1] == 'H')
+			*buf++ = '0';
+		    else
+			*buf++ = ' ';
+		}
 		*buf++ = '0' + tm->tm_hour % 10;
 		break;
 	    case 'l':
+		strip = 1;
+		/* FALLTHROUGH */
 	    case 'L':
 		hr12 = tm->tm_hour % 12;
 		if (hr12 == 0)
 		    hr12 = 12;
 	        if (hr12 > 9)
 		    *buf++ = '1';
-		else if (fmt[-1] == 'l')
+		else if (!strip)
 		    *buf++ = ' ';
 
 		*buf++ = '0' + (hr12 % 10);
 		break;
 	    case 'm':
-		*buf++ = '0' + (tm->tm_mon + 1) / 10;
+		if (tm->tm_mon > 8 || !strip)
+		    *buf++ = '0' + (tm->tm_mon + 1) / 10;
 		*buf++ = '0' + (tm->tm_mon + 1) % 10;
 		break;
 	    case 'M':
-		*buf++ = '0' + tm->tm_min / 10;
+		if (tm->tm_min > 9 || !strip)
+		    *buf++ = '0' + tm->tm_min / 10;
 		*buf++ = '0' + tm->tm_min % 10;
 		break;
 	    case 'S':
-		*buf++ = '0' + tm->tm_sec / 10;
+		if (tm->tm_sec > 9 || !strip)
+		    *buf++ = '0' + tm->tm_sec / 10;
 		*buf++ = '0' + tm->tm_sec % 10;
 		break;
 	    case 'y':
-		*buf++ = '0' + (tm->tm_year / 10) % 10;
+		if (tm->tm_year > 9 || !strip)
+		    *buf++ = '0' + (tm->tm_year / 10) % 10;
 		*buf++ = '0' + tm->tm_year % 10;
 		break;
 	    case '\0':
@@ -2507,6 +2528,26 @@
 		fmt--;
 		break;
 #ifndef HAVE_STRFTIME
+	    case 'Y':
+	    {
+		/*
+		 * Not worth handling this natively if
+		 * strftime has it.
+		 */
+		int year, digits, testyear;
+		year = tm->tm_year + 1900;
+		digits = 1;
+		testyear = year;
+		while (testyear > 9) {
+		    digits++;
+		    testyear /= 10;
+		}
+		if (ztrftimebuf(&bufsize, digits))
+		    return -1;
+		sprintf(buf, "%d", year);
+		buf += digits;
+		break;
+	    }
 	    case 'a':
 		if (ztrftimebuf(&bufsize, strlen(astr[tm->tm_wday]) - 2))
 		    return -1;
@@ -2532,7 +2573,7 @@
 		 * in the accounting in bufsize (but nowhere else).
 		 */
 		*buf = '\1';
-		tmp[1] = fmt[-1];
+		sprintf(tmp, strip ? "%%-%c" : "%%%c", fmt[-1]);
 		if (!strftime(buf, bufsize + 2, tmp, tm))
 		{
 		    if (*buf) {


-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070



Messages sorted by: Reverse Date, Date, Thread, Author