Jim Meyering <[EMAIL PROTECTED]> wrote: >>I think it would be better for plain files to not have any ANSI >>escape sequences around them, and for colouring to apply only to >>directories, *.gz and so on.
>>Shall I send a patch for this? > >Please do. diff -ru coreutils-5.0.91/src/ls.c coreutils-5.0.91.new/src/ls.c --- coreutils-5.0.91/src/ls.c 2003-07-27 07:33:36.000000000 +0100 +++ coreutils-5.0.91.new/src/ls.c 2004-01-24 18:13:49.334955240 +0000 @@ -253,7 +253,7 @@ static int file_interesting (const struct dirent *next); static uintmax_t gobble_file (const char *name, enum filetype type, int explicit_arg, const char *dirname); -static void print_color_indicator (const char *name, mode_t mode, int linkok); +static bool print_color_indicator (const char *name, mode_t mode, int linkok); static void put_indicator (const struct bin_str *ind); static int put_indicator_direct (const struct bin_str *ind); static int length_of_file_name_and_frills (const struct fileinfo *f); @@ -499,6 +499,13 @@ static int print_with_color; +/* Whether we used any colors in the output so far. If so, we will + need to restore the default color later. If not, we will need to + print some stuff (prep_non_filename_text ()) before using color for + the first time. */ + +static bool used_color = false; + enum color_type { color_never, /* 0: default or --color=never */ @@ -517,13 +524,13 @@ enum indicator_no { - C_LEFT, C_RIGHT, C_END, C_NORM, C_FILE, C_DIR, C_LINK, C_FIFO, C_SOCK, + C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK, C_FIFO, C_SOCK, C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR }; static const char *const indicator_name[]= { - "lc", "rc", "ec", "no", "fi", "di", "ln", "pi", "so", + "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so", "bd", "cd", "mi", "or", "ex", "do", NULL }; @@ -539,8 +546,9 @@ { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */ { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */ { 0, NULL }, /* ec: End color (replaces lc+no+rc) */ - { LEN_STR_PAIR ("0") }, /* no: Normal */ - { LEN_STR_PAIR ("0") }, /* fi: File: default */ + { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */ + { 0, NULL }, /* no: Normal */ + { 0, NULL }, /* fi: File: default */ { LEN_STR_PAIR ("01;34") }, /* di: Directory: bright blue */ { LEN_STR_PAIR ("01;36") }, /* ln: Symlink: bright cyan */ { LEN_STR_PAIR ("33") }, /* pi: Pipe: yellow/brown */ @@ -993,7 +1001,8 @@ signal (sig, SIG_IGN); #endif - restore_default_color (); + if (used_color) + restore_default_color (); /* SIGTSTP is special, since the application can receive that signal more than once. In this case, don't set the signal handler to the default. @@ -1051,7 +1060,6 @@ may have just reset it -- e.g., if LS_COLORS is invalid. */ if (print_with_color) { - prep_non_filename_text (); /* Avoid following symbolic links when possible. */ if (color_indicator[C_ORPHAN].string != NULL || (color_indicator[C_MISSING].string != NULL @@ -1208,7 +1216,7 @@ } /* Restore default color before exiting */ - if (print_with_color) + if (used_color) { put_indicator (&color_indicator[C_LEFT]); put_indicator (&color_indicator[C_RIGHT]); @@ -3271,8 +3279,8 @@ print_name_with_quoting (const char *p, mode_t mode, int linkok, struct obstack *stack) { - if (print_with_color) - print_color_indicator (p, mode, linkok); + const bool used_color_this_time + = print_with_color && print_color_indicator (p, mode, linkok); if (stack) PUSH_CURRENT_DIRED_POS (stack); @@ -3282,7 +3290,7 @@ if (stack) PUSH_CURRENT_DIRED_POS (stack); - if (print_with_color) + if (used_color_this_time) prep_non_filename_text (); } @@ -3294,7 +3302,7 @@ else { put_indicator (&color_indicator[C_LEFT]); - put_indicator (&color_indicator[C_NORM]); + put_indicator (&color_indicator[C_RESET]); put_indicator (&color_indicator[C_RIGHT]); } } @@ -3354,7 +3362,8 @@ DIRED_PUTCHAR (c); } -static void +/* Returns whether any color sequence was printed. */ +static bool print_color_indicator (const char *name, mode_t mode, int linkok) { int type = C_FILE; @@ -3406,16 +3415,32 @@ } } } - - put_indicator (&color_indicator[C_LEFT]); - put_indicator (ext ? &(ext->seq) : &color_indicator[type]); - put_indicator (&color_indicator[C_RIGHT]); + + { + const struct bin_str *const s + = ext ? &(ext->seq) : &color_indicator[type]; + if (s->string != NULL) + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (s); + put_indicator (&color_indicator[C_RIGHT]); + return true; + } + else + return false; + } } /* Output a color indicator (which may contain nulls). */ static void put_indicator (const struct bin_str *ind) { + if (! used_color) + { + used_color = true; + prep_non_filename_text (); + } + register int i; register const char *p; @@ -3431,6 +3456,12 @@ static int put_indicator_direct (const struct bin_str *ind) { + if (! used_color) + { + used_color = true; + prep_non_filename_text (); + } + size_t len; if (ind->len <= 0) return 0; diff -ru coreutils-5.0.91/tests/ls-2/tests coreutils-5.0.91.new/tests/ls-2/tests --- coreutils-5.0.91/tests/ls-2/tests 2003-04-08 11:36:44.000000000 +0100 +++ coreutils-5.0.91.new/tests/ls-2/tests 2004-01-24 17:58:31.098548392 +0000 @@ -32,6 +32,7 @@ $ENV{LS_COLORS}='ln=01;36:di=01;34:or=40;31;01' }}; my $unlink_d = {POST => sub {unlink 'd' or die "d: $!\n"}}; +my $creat_d = {PRE => sub {local *FH; open(FH, '>d') or die "d: $!\n"}}; sub make_j_d () { @@ -85,6 +86,9 @@ {OUT => "\e[0m\e[01;[EMAIL PROTECTED]"}, $slink_d, $unlink_d], + # A listing with only plain files should have no color sequences at all. + ['no-color', '--color=always d', {OUT => "d\n"}, $creat_d, $unlink_d], + # Test for a bug that was introduced in coreutils-4.5.4; fixed in 4.5.5. # To demonstrate it, the file in question (with executable bit set) # must not be a command line argument. -- Ed Avis <[EMAIL PROTECTED]> _______________________________________________ Bug-coreutils mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-coreutils