Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for LS_COLORS #560

Open
i-am-logger opened this issue Sep 19, 2024 · 7 comments
Open

add support for LS_COLORS #560

i-am-logger opened this issue Sep 19, 2024 · 7 comments
Labels
feature A new feature or a feature request

Comments

@i-am-logger
Copy link
Contributor

to generate something like this

  programs.bash.initExtra = ''
      export LS_COLORS="${generateLsColors config.lib.stylix.colors}"
    '';
  };
@trueNAHO trueNAHO added the feature A new feature or a feature request label Sep 19, 2024
@trueNAHO
Copy link
Collaborator

Is LS_COLORS not is specifically for ls? AFAIK, ls can take the terminal colors, which Stylix should already apply in (nearly?) all cases.

@i-am-logger
Copy link
Contributor Author

some utillities like lsd rely on LS_COLORS

I've implemented it this way which works

{ config, lib, pkgs, ... }:

with lib;

let
  cfg = config.stylix.ls-colors;

  # This function generates LS_COLORS based on Stylix colors
  generateLsColors = colors: ''
    di=${colors.base0D}  # directory
    fi=${colors.base05}  # file
    ln=${colors.base0C}  # symlink
    ex=${colors.base0A}  # executable
    bd=${colors.base0E}  # block device
    cd=${colors.base0E}  # character device
    so=${colors.base0E}  # socket
    pi=${colors.base0E}  # pipe
    or=${colors.base08}  # orphan symlink
    mi=${colors.base08}  # missing file
    su=${colors.base0B}  # setuid
    sg=${colors.base0B}  # setgid
    tw=${colors.base0A}  # sticky other writable
    ow=${colors.base0A}  # other writable
    st=${colors.base0E}  # sticky
    *.tar=${colors.base08}
    *.tgz=${colors.base08}
    *.zip=${colors.base08}
    *.gz=${colors.base08}
    *.bz2=${colors.base08}
    *.rpm=${colors.base08}
    *.deb=${colors.base08}
    *.jpg=${colors.base0D}
    *.jpeg=${colors.base0D}
    *.gif=${colors.base0D}
    *.png=${colors.base0D}
    *.svg=${colors.base0D}
    *.mp3=${colors.base0C}
    *.mp4=${colors.base0C}
    *.flac=${colors.base0C}
    *.wav=${colors.base0C}
    *.ogg=${colors.base0C}
    *.pdf=${colors.base08}
    *.doc=${colors.base08}
    *.docx=${colors.base08}
    *.odt=${colors.base08}
    *.txt=${colors.base05}
    *.md=${colors.base05}
    *.xml=${colors.base05}
    *.json=${colors.base05}
    *.yml=${colors.base05}
    *.yaml=${colors.base05}
    *.ini=${colors.base05}
    *.cfg=${colors.base05}
    *.conf=${colors.base05}
    *.py=${colors.base0E}
    *.rb=${colors.base0E}
    *.js=${colors.base0E}
    *.ts=${colors.base0E}
    *.sh=${colors.base0E}
    *.bash=${colors.base0E}
    *.zsh=${colors.base0E}
    *.nix=${colors.base0E}
    *.vim=${colors.base0E}
    *.lua=${colors.base0E}
    *.cpp=${colors.base0E}
    *.c=${colors.base0E}
    *.h=${colors.base0E}
    *.rs=${colors.base0E}
    *.go=${colors.base0E}
    *.java=${colors.base0E}
    *.class=${colors.base0E}
    *.cs=${colors.base0E}
    *.html=${colors.base09}
    *.css=${colors.base09}
    *.scss=${colors.base09}
    *.less=${colors.base09}
    *.sql=${colors.base09}
  '';

in
{
  options.stylix.ls-colors = {
    enable = mkEnableOption "Stylix-based LS_COLORS";
  };

  config = mkIf cfg.enable {
    environment.sessionVariables = {
      LS_COLORS = generateLsColors config.lib.stylix.colors;
    };

    environment.extraInit = ''
      export LS_COLORS="${generateLsColors config.lib.stylix.colors}"
    '';
    programs.bash.interactiveShellInit = ''
      export LS_COLORS="${generateLsColors config.lib.stylix.colors}"
    '';
    programs.zsh.interactiveShellInit = mkIf config.programs.zsh.enable ''
      export LS_COLORS="${generateLsColors config.lib.stylix.colors}"
    '';
    programs.fish.interactiveShellInit = mkIf config.programs.fish.enable ''
      set -gx LS_COLORS "${generateLsColors config.lib.stylix.colors}"
    '';
  };
}

@i-am-logger
Copy link
Contributor Author

sorry, that script was old version

... }:

with lib;

let
  cfg = config.stylix.ls-colors;

  hexDigitToInt = c:
    let
      hexChars = "0123456789abcdef";
    in
    stringLength (head (splitString c (toLower hexChars)));

  hexToRgb = hexColor:
    let
      r = substring 0 2 hexColor;
      g = substring 2 2 hexColor;
      b = substring 4 2 hexColor;
      toDecimal = hex: hexDigitToInt (substring 0 1 hex) * 16 + hexDigitToInt (substring 1 1 hex);
    in
    "${toString (toDecimal r)};${toString (toDecimal g)};${toString (toDecimal b)}";

  generateLsColors = colors:
    let
      mkColor = color: "38;2;${hexToRgb color}";
      colorMap = {
        # Special files and directories
        di = mkColor colors.base0D; # directory
        fi = mkColor colors.base05; # regular file
        ln = mkColor colors.base0C; # symbolic link
        ex = mkColor colors.base0A; # executable file
        bd = mkColor colors.base0E; # block device
        cd = mkColor colors.base0E; # character device
        so = mkColor colors.base0E; # socket
        pi = mkColor colors.base0E; # named pipe (FIFO)
        or = mkColor colors.base08; # orphaned symlink
        mi = mkColor colors.base08; # missing file
        su = mkColor colors.base0B; # file that is setuid (u+s)
        sg = mkColor colors.base0B; # file that is setgid (g+s)
        ca = mkColor colors.base0B; # file with capability
        tw = mkColor colors.base0A; # directory that is sticky and other-writable (+t,o+w)
        ow = mkColor colors.base0A; # directory that is other-writable (o+w) and not sticky
        st = mkColor colors.base0E; # directory with sticky bit set (+t) and not other-writable
        ee = mkColor colors.base05; # empty file (arrow for classifyAlt)
        no = mkColor colors.base05; # normal non-filename text
        rs = mkColor colors.base05; # reset to no color
        mh = mkColor colors.base05; # multi-hardlink
        lc = mkColor colors.base05; # left code (opening part of color sequence)
        rc = mkColor colors.base05; # right code (closing part of color sequence)
        ec = mkColor colors.base05; # end code (for non-filename text)
        # File extensions
        "*.bash" = mkColor colors.base0D;
        "*.bz2" = mkColor colors.base08;
        "*.c" = mkColor colors.base0D;
        "*.cfg" = mkColor colors.base05;
        "*.class" = mkColor colors.base0D;
        "*.conf" = mkColor colors.base05;
        "*.cpp" = mkColor colors.base0D;
        "*.cs" = mkColor colors.base0D;
        "*.css" = mkColor colors.base09;
        "*.deb" = mkColor colors.base08;
        "*.doc" = mkColor colors.base08;
        "*.docx" = mkColor colors.base08;
        "*.flac" = mkColor colors.base0C;
        "*.gif" = mkColor colors.base0D;
        "*.go" = mkColor colors.base0D;
        "*.gz" = mkColor colors.base08;
        "*.h" = mkColor colors.base0D;
        "*.html" = mkColor colors.base09;
        "*.ini" = mkColor colors.base05;
        "*.java" = mkColor colors.base0D;
        "*.jpeg" = mkColor colors.base0D;
        "*.jpg" = mkColor colors.base0D;
        "*.js" = mkColor colors.base0D;
        "*.json" = mkColor colors.base05;
        "*.less" = mkColor colors.base09;
        "*.lua" = mkColor colors.base0D;
        "*.md" = mkColor colors.base05;
        "*.mp3" = mkColor colors.base0C;
        "*.mp4" = mkColor colors.base0C;
        "*.nix" = mkColor colors.base0D;
        "*.odt" = mkColor colors.base08;
        "*.ogg" = mkColor colors.base0C;
        "*.pdf" = mkColor colors.base08;
        "*.png" = mkColor colors.base0D;
        "*.py" = mkColor colors.base0D;
        "*.rb" = mkColor colors.base0D;
        "*.rpm" = mkColor colors.base08;
        "*.rs" = mkColor colors.base0D;
        "*.scss" = mkColor colors.base09;
        "*.sh" = mkColor colors.base0D;
        "*.sql" = mkColor colors.base09;
        "*.svg" = mkColor colors.base0D;
        "*.tar" = mkColor colors.base08;
        "*.tgz" = mkColor colors.base08;
        "*.ts" = mkColor colors.base0D;
        "*.txt" = mkColor colors.base05;
        "*.vim" = mkColor colors.base0D;
        "*.wav" = mkColor colors.base0C;
        "*.xml" = mkColor colors.base05;
        "*.yaml" = mkColor colors.base05;
        "*.yml" = mkColor colors.base05;
        "*.zip" = mkColor colors.base08;
        "*.zsh" = mkColor colors.base0D;
      };
    in
    concatStringsSep ":" (mapAttrsToList (k: v: "${k}=${v}") colorMap);

in
{
  options.stylix.ls-colors = {
    enable = mkEnableOption "Stylix-based LS_COLORS";
  };

  config = mkIf cfg.enable {
    environment.sessionVariables = {
      LS_COLORS = generateLsColors config.lib.stylix.colors;
    };

    environment.extraInit = ''
      export LS_COLORS="${generateLsColors config.lib.stylix.colors}"
    '';

    programs.bash.interactiveShellInit = ''
      export LS_COLORS="${generateLsColors config.lib.stylix.colors}"
    '';

    programs.zsh.interactiveShellInit = mkIf config.programs.zsh.enable ''
      export LS_COLORS="${generateLsColors config.lib.stylix.colors}"
    '';

    programs.fish.interactiveShellInit = mkIf config.programs.fish.enable ''
      set -gx LS_COLORS "${generateLsColors config.lib.stylix.colors}"
    '';
  };
}

@danth
Copy link
Owner

danth commented Sep 20, 2024

Please could you submit this as a pull request so that we can more easily review the changes?

@jeanlucthumm
Copy link

jeanlucthumm commented Oct 1, 2024

For nushell add:

  programs.nushell.environmentVariables = {
    LS_COLORS = ''${generateLsColors config.lib.stylix.colors}'';
  };

@arunoruto
Copy link
Contributor

arunoruto commented Nov 5, 2024

One can also use vivid for this. I am currently always setting my LS_COLORS with $(vivid generate <theme>). The command will be evaluated on shell startup and the LS_COLORS is set. Stylix just needs to create the config for vivid and make sure it is installed in home-manager. I already created a base16 repo for vivid, so feel free to make changes and/or PRs :D

Maybe it wouldn't be a bad idea to have it home-manager as an option with appropriate options, so stylix doesn't have to do the heavy lifting here.
EDIT I created a PR for this: nix-community/home-manager#6045

@trueNAHO
Copy link
Collaborator

trueNAHO commented Nov 7, 2024

One can also use vivid for this. I am currently always setting my LS_COLORS with $(vivid generate <theme>).

Great suggestion! Using this tool would delegate some of Stylix's responsibilities.

The command will be evaluated on shell startup and the LS_COLORS is set. Stylix just needs to create the config for vivid and make sure it is installed in home-manager.

To improve runtime performance, the vivid generate <theme> output could be injected at Nix build time.

I already created a base16 repo for vivid, so feel free to make changes and/or PRs :D

Maybe it wouldn't be a bad idea to have it home-manager as an option with appropriate options, so stylix doesn't have to do the heavy lifting here. EDIT I created a PR for this: nix-community/home-manager#6045

Let's wait for this PR to get merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature A new feature or a feature request
Projects
None yet
Development

No branches or pull requests

5 participants