Search code examples
colorslsgnu-coreutils

Recompiling ls command to get wanted colors of a file beginning by README_* , i.e extended with a string


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 ?


Solution

  • 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.