0

I make following to this post : export-ls-colors-apply-the-rule-for-every-file-beginning-by-readme

I summarize the issue briefly:

eval `/opt/local/libexec/gnubin/dircolors ~/.dircolors`
export LS_COLORS="${LS_COLORS}*README=00;37;44"

Then, when creating a README file, then I will get :

README

But now, I would like to apply the rule and do the same for every filename beginning by README (like README_something, README_important).

for this, I tried to put:

 export LS_COLORS="${LS_COLORS}*README*=00;37;44"

but it is not displayed as above image (only white).

Potential solution

A potential solution would be to recompile ls command from coreutils sources package (I am on MacOS Big Sur 11.2.3).

The modification is located here :

https://github.com/wertarbyte/coreutils/blob/master/src/ls.c#L4206

I am looking into what modifications are required if I want the files README_string where string is any kind of string to be colorified by the command "l" with the following alias in ~/.zshrc :

alias l='grc -es --colour=auto ls --color -Gh -C -lrt'

How can I carry out this recompilation?

Edit

Below the part of the code that manages the colorifying of file (https://github.com/wertarbyte/coreutils/blob/master/src/ls.c#L4206 ):

/* Check the file's suffix only if still classified as C_FILE.  */
  ext = NULL;
  if (type == C_FILE)
    {
      /* Test if NAME has a recognized suffix.  */

      len = strlen (name);
      name += len;      /* Pointer to final \0.  */
      for (ext = color_ext_list; ext != NULL; ext = ext->next)
        {
          if (ext->ext.len <= len
              && strncmp (name - ext->ext.len, ext->ext.string,
                          ext->ext.len) == 0)
            break;
        }
    }

I would like the file without extension to be colorified. I have some notions of C language but not enough to understand what happens in this section of the code.

What modifications could I apply for getting colorifying without extension ?

halfer
  • 19,824
  • 17
  • 99
  • 186
  • Have you tried `exa`? ( https://the.exa.website/ ). It supports glob patterns in LS_COLORS, and by default has some highlighting of README files. – Gairfowl Apr 01 '21 at 06:29
  • @Gairfowl I tried it but an interesting functionality seems to not exist : the colorization as a function of size wen I do an `exa -l` . Moreover, I have to modified all my LS_COLOR since rendering colors are not the same with `exa` compared to `ls`. –  Apr 01 '21 at 06:36
  • @youpilat13 : Just being curious: You try to avoid the - admittedly tedious - task to rewrite your LS_COLOR settings for `exa`, but you want to go through all the hassels to recompile `ls` instead, which, including testing your changes and not getting updates for `ls` anymore, which in overall will likely cost you much more effort in the end? – user1934428 Apr 01 '21 at 06:47
  • @user1934428 . Don't worry, I have nothing against `exa` but this is a little bit tricky since I don't use only LS_CLORS : I am using another layer with `grc` command (`grc -es --colour=auto ls --color -Gh -C -lrt` and this is the combination of the two that makes the rendering, not just LS_COLORS. That's why I would like to modify slightly the behavior of `ls`for files begining by README* and without extension separated by a point. –  Apr 01 '21 at 07:20

1 Answers1

1

You can use grc to colorize the README files in addition to what it's doing now. Since you have already set up the alias, just add a regex/color pair to a copy of the grc config file for ls:

mkdir ~/.grc/
{
cat /usr/local/share/grc/conf.ls
cat << here
-
# README
regexp=(README[^.]*$)
colours=white on_blue blink
here
} > ~/.grc/conf.ls


If you still want to try changing the source for ls, you'll need several modifications. Based on the source in your link, it looks like you need to ...

Change line 551 to:

    C_CLR_TO_EOL, C_README

Add this after line 593:

    { LEN_STR_PAIR ("37;44") },

Change line 4231 (return false;) to this:

    {
      if (startsWith(name, "README"))
        {
          if (is_colored (C_NORM))
            restore_default_color ();
          put_indicator (&color_indicator[C_LEFT]);
          put_indicator (&color_indicator[C_README]);
          put_indicator (&color_indicator[C_RIGHT]);
          return true;
        }
      else
        return false;
    }

And add this function somewhere before the print_color_indicator function:

bool startsWith(const char *pre, const char *str)
  {
    size_t lenpre = strlen(pre), lenstr = strlen(str);
    return lenstr < lenpre ? false : memcmp(pre, str, lenpre) == 0;
  }

All of this C code is completely untested (and my C is very rusty). It's also not recommended - as noted in the comments, this will be difficult to implement and to support.

Gairfowl
  • 2,226
  • 6
  • 9
  • Thanks a lot ! `grc` was the solution : why doing complicated instead of simple ? Best regards –  Apr 01 '21 at 20:07