重新编译 ls 命令以获取以 README_* 开头的文件的所需颜色,即用字符串扩展

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

我对此 post 进行了以下说明:

我简单总结一下问题:

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

然后,当创建一个README文件时,我会得到:

但是现在,我想应用该规则并对以 README 开头的每个文件名执行相同的操作(例如 README_somethingREADME_important)。

为此,我尝试输入:

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

但是没有像上图那样显示(只有白色)

可能的解决方案

一个潜在的解决方案是从 coreutils 源包中重新编译 ls 命令(我在 MacOS Big Sur 11.2.3 上)。

修改位置在这里:

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

我正在研究如果我想要文件 README_string 需要进行哪些修改,其中 string 是要通过命令“l”使用以下内容着色的任何类型的字符串~/.zshrc 中的别名:

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

如何进行重新编译?

编辑

下面管理文件着色的代码部分(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 [=13=].  */
      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;
        }
    }

我想把没有扩展名的文件着色。我对C语言有一些概念,但还不足以理解这部分代码中发生的事情。

我可以申请哪些修改来获得不扩展的着色?

您可以使用 grc 为 README 文件着色 现在。由于您已经设置了别名,只需将 regex/color 对添加到 grc 配置文件副本 ls:

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


如果您仍想尝试更改 ls 的源代码,您需要几个 修改。根据您 link 中的来源,您似乎需要 ...

将第 551 行更改为:

    C_CLR_TO_EOL, C_README

在第 593 行之后添加:

    { LEN_STR_PAIR ("37;44") },

将第 4231 行 (return false;) 更改为:

    {
      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;
    }

并在 print_color_indicator 函数之前的某处添加此函数:

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;
  }

所有这些 C 代码都完全未经测试(我的 C 非常生锈)。这也是 不推荐——如评论中所述,这将难以实施 并支持。