bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[grep-2.5.1-29] [PATCH] --initial-tab and 3 newly colorized items


From: Charles Levert
Subject: [grep-2.5.1-29] [PATCH] --initial-tab and 3 newly colorized items
Date: Fri, 14 Jan 2005 04:06:49 -0500
User-agent: Mutt/1.4.1i

Hi.

For reference, the version of grep I used for this is 2.5.1-29 from Fedora.
Please try applying the patch I have right now before requesting me to
update to some other version, it may just apply as is.


I have added the following two features:

        * A "-T" / "--initial-tab" option (both invocations are consistent
          with GNU diff).  This will make sure that the first character
          of a content line is on a tab stop.  The last separator (":")
          is positioned immediately before that so it remains possible
          to tell whitespace at the beginning of the content line from
          whitespace used for padding.  I believe it would be pointless
          overkill to try to follow the current column of output after
          printing a filename in Unicode; my implementation does something
          really simple that works.

        * Three other colors when "--color" is in effect.  They are
          for the filename, the numbers (line number and octet offset),
          and the separator (":").  These cannot be customized by the
          user yet, but each is put in its own variable so everything is
          in place for them to be.  (I didn't want to add a bunch of new
          environment variables for that, and I didn't want to venture
          a new mechanism for specifying colors, possibly by extending
          the current environment variable in a backward compatible way.
          This can be done later if the patch is accepted and popular,
          and if users actually request it.)

Please consider merging this patch with the official release.

(If you like the patch but think it is too big to be accepted without
paperwork, please contact me before doing anything else like rewriting
the whole thing differently just for the sake of doing it.)



========================================================================
[ Generated with ude,
    the unified-format diff-output ("unidiff") editor,
    version 0.1 of 2004-11-03.  ]
--- src/grep.c.orig-2.5.1-29    2004-09-29 14:01:58 -0400
+++ src/grep.c  2005-01-14 03:18:44 -0500
@@ -78,15 +78,23 @@
 /* If nonzero, show only the part of a line matching the expression. */
 static int only_matching;
 
+/* If nonzero, make sure first content char in a line is on a tab stop. */
+static int align_tabs;
+
 /* The color string used.  The user can overwrite it using the environment
-   variable GREP_COLOR.  The default is to print red.  */
+   variable GREP_COLOR.  The default is to print bold red.  */
 static const char *grep_color = "01;31";
 
+/* Other colors.  Looks damn good.  Not customizable yet.  */
+static const char *filename_color = "35";      /* magenta */
+static const char *num_color = "32";           /* green */
+static const char *sep_color = "36";           /* cyan */
+
 static struct exclude *excluded_patterns;
 static struct exclude *included_patterns;
 /* Short options.  */
 static char const short_options[] =
-"0123456789A:B:C:D:EFGHIPUVX:abcd:e:f:hiKLlm:noqRrsuvwxyZz";
+"0123456789A:B:C:D:EFGHIPTUVX:abcd:e:f:hiKLlm:noqRrsuvwxyZz";
 
 /* Non-boolean long options that have no corresponding short equivalents.  */
 enum
@@ -125,6 +133,7 @@ static struct option const long_options[
   {"help", no_argument, &show_help, 1},
   {"include", required_argument, NULL, INCLUDE_OPTION},
   {"ignore-case", no_argument, NULL, 'i'},
+  {"initial-tab", no_argument, NULL, 'T'},
   {"label", required_argument, NULL, LABEL_OPTION},
   {"line-buffered", no_argument, NULL, LINE_BUFFERED_OPTION},
   {"line-number", no_argument, NULL, 'n'},
@@ -498,43 +507,94 @@ nlscan (char const *lim)
   lastnl = lim;
 }
 
+/* Print a character separator.  */
+static void
+print_sep (char sep)
+{
+  if (color_option)
+    printf("\33[%sm", sep_color);
+  fputc(sep, stdout);
+  if (color_option)
+    fputs("\33[m", stdout);
+}
+
-/* Print a byte offset, followed by a character separator.  */
+/* Print a byte offset.  */
 static void
-print_offset_sep (uintmax_t pos, char sep)
+print_offset (uintmax_t pos, int min_width)
 {
   /* Do not rely on printf to print pos, since uintmax_t may be longer
      than long, and long long is not portable.  */
 
   char buf[sizeof pos * CHAR_BIT];
-  char *p = buf + sizeof buf - 1;
+  char *p = buf + sizeof buf;
-  *p = sep;
 
   do
-    *--p = '0' + pos % 10;
+    {
+      *--p = '0' + pos % 10;
+      --min_width;
+    }
   while ((pos /= 10) != 0);
 
+  /* Do this to maximize the probability of alignment across lines.  */
+  if (align_tabs)
+    while (--min_width >= 0)
+      *--p = ' ';
+
+  if (color_option)
+    printf("\33[%sm", num_color);
   fwrite (p, 1, buf + sizeof buf - p, stdout);
+  if (color_option)
+    fputs("\33[m", stdout);
 }
 
 static void
 prline (char const *beg, char const *lim, int sep, struct mb_cache *mb_cache)
 {
+  int pending_sep = 0;
+
   if (out_file)
-    printf ("%s%c", filename, sep & filename_mask);
+    {
+      if (color_option)
+       printf("\33[%sm", filename_color);
+      fputs(filename, stdout);
+      if (color_option)
+       fputs("\33[m", stdout);
+      if (filename_mask)
+       pending_sep = 1;
+      else
+       fputc(0, stdout);
+    }
   if (out_line)
     {
       nlscan (beg);
       totalnl = add_count (totalnl, 1);
+      if (pending_sep)
+       print_sep(sep);
-      print_offset_sep (totalnl, sep);
+      print_offset (totalnl, 4);
+      pending_sep = 1;
       lastnl = lim;
     }
   if (out_byte)
     {
       uintmax_t pos = add_count (totalcc, beg - bufbeg);
 #if defined(HAVE_DOS_FILE_CONTENTS)
       pos = dossified_pos (pos);
 #endif
+      if (pending_sep)
+       print_sep(sep);
-      print_offset_sep (pos, sep);
+      print_offset (pos, 6);
+      pending_sep = 1;
+    }
+  if (pending_sep)
+    {
+      /* This assumes sep is one column wide.
+       * Try doing this any other way with Unicode
+       * (and its combining and wide characters)
+       * filenames and you're wasting your efforts.  */
+      if (align_tabs)
+       printf("\t\b");
+
+      print_sep(sep);
     }
   if (only_matching)
     {
@@ -1130,6 +1190,7 @@ usage (int status)
   -L, --files-without-match only print FILE names containing no match\n\
   -l, --files-with-matches  only print FILE names containing matches\n\
   -c, --count               only print a count of matching lines per FILE\n\
+  -T, --initial-tab         make tabs line up (if needed)\n\
   -Z, --null                print 0 byte after FILE name\n"));
       printf (_("\
 \n\
@@ -1427,6 +1488,10 @@ main (int argc, char **argv)
        binary_files = WITHOUT_MATCH_BINARY_FILES;
        break;
 
+      case 'T':
+       align_tabs = 1;
+       break;
+
       case 'U':
 #if defined(HAVE_DOS_FILE_CONTENTS)
        dos_use_file_type = DOS_BINARY;
========================================================================




reply via email to

[Prev in Thread] Current Thread [Next in Thread]