Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Code Reviews

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Post History

60%
+1 −0
Code Reviews Feedback for a Nix-Darwin configuration

Hello, im looking for some feedback on my nix-dawrin setup. This is the setup im currently using, its works, but the structure is cobbled together from multiple sources, and im not experienced eno...

0 answers  ·  posted 2mo ago by hest‭

#2: Nominated for promotion by user avatar Alexei‭ · 2024-09-09T06:24:56Z (2 months ago)
#1: Initial revision by user avatar hest‭ · 2024-09-08T14:05:00Z (2 months ago)
Feedback for a Nix-Darwin configuration
Hello, im looking for some feedback on my nix-dawrin setup. 

This is the setup im currently using, its works, but the structure is cobbled together from multiple sources, and im not experienced enough with nix to have a good feeling about best practices or correct usage of features.

would love some feedback on how to improve and clean up / simplify the code; about language features im not using/missusing ; tips of where i could split up some code, or merge for a more concise code-structure. 

some point i know specifically already:

* settings a default shell: i have settings for a default / login shell, but it doesn't seems to stick correctly.
* split apps.nix, extract the config for yabai / skhd / homebrew to their own file, not sure if the preferred way is .nix files or external, 'native' config files that i import into nix
* would like to move more GUI apps to homemanger, but my understanding is that MacOS doesn't handle installing GUI apps through the nix store very well. So right now ive opted to do GUI apps via homebrew, but it feels cleaner if i could get rid of homebrew completely, but maybe that is not possible.
* any good good flake from other users that could benefit my setup would be great to hear about.

If anything is unclear just let me know, and hopefully i can clarify, or provide some sort of answer at least.

Link to github with current version: https://github.com/hesthub/nix-config/tree/337c091ba90af6d48b570b834e0c4552081806b1

flake.nix
```
{
  description = "Nix for macOS configuration";

  nixConfig = {
    experimental-features = ["nix-command" "flakes"];
  };

  inputs = {
    nixpkgs-darwin.url = "github:nixos/nixpkgs/nixpkgs-unstable";

    home-manager = {
      url = "github:nix-community/home-manager/master";
      inputs.nixpkgs.follows = "nixpkgs-darwin";
    };

    darwin = {
      url = "github:lnl7/nix-darwin";
      inputs.nixpkgs.follows = "nixpkgs-darwin";
    };
  };

  outputs = inputs @ {
    self,
    nixpkgs,
    darwin,
    home-manager,
    ...
  }: {
    darwinConfigurations.mbp = darwin.lib.darwinSystem {
      system = "x86_64-darwin";
      modules = [
        ./modules/nix-core.nix
        ./modules/system.nix
        ./modules/apps.nix

        ./modules/host-users.nix

        home-manager.darwinModules.home-manager
        {
          home-manager.useGlobalPkgs = true;
          home-manager.useUserPackages = true;

          home-manager.extraSpecialArgs = inputs;
          home-manager.users.hest = import ./home;
        }
      ];
    };
    # nix code formater
    formatter.x86_64-darwin = nixpkgs.legacyPackages.x86_64-darwin.alejandra;
  };
}
```

Makefile
```
include .env
export

darwin:
	nix build .#darwinConfigurations.mbp.system \
		--extra-experimental-features 'nix-command flakes'

	./result/sw/bin/darwin-rebuild switch --impure --flake .#mbp

bootstrap:
# 	install nix
	curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
# 	install homebrew
	/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

ssh_keys:
#	Generate ssh keys
	ssh-keygen -t ed25519 -C "$$M_MAIL" -f ~/.ssh/$$M_ID -N $$PASSWORD
	ssh-keygen -t rsa -C "$$G_MAIL" -f ~/.ssh/$$G_ID -N $$PASSWORD
	ssh-keygen -t ed25519 -C "$$C_MAIL" -f ~/.ssh/$$C_ID -N $$PASSWORD
# 	add keys to ssh-agent
	ssh-add --apple-use-keychain ~/.ssh/$$M_ID
	ssh-add --apple-use-keychain ~/.ssh/$$C_ID
	ssh-add --apple-use-keychain ~/.ssh/$$G_ID

post-fix:
#	 add fish to available shell if not already present
	if ! grep -qF "/etc/profiles/per-user/${M_USER}/bin/fish" /etc/shells; \
		then echo "/etc/profiles/per-user/${M_USER}/bin/fish" | sudo tee -a /etc/shells; fi

#	add nix user bin to path if not already present
	if ! grep -qF "/etc/profiles/per-user/${M_USER}/bin" /etc/paths; \
		then echo "/etc/profiles/per-user/${M_USER}/bin" | sudo tee -a /etc/paths; fi

#	copy iterm config to dynamic profiles if not already present
	if [[ ! -f /Users/${M_USER}/Library/Application\ Support/iTerm2/DynamicProfiles/iterm2.json ]];\
		then cp ./dotfiles/iterm2.json /Users/${M_USER}/Library/Application\ Support/iTerm2/DynamicProfiles/; fi

#   rtx add plugins and install them
	rtx plugin add dotnet
	rtx plugin add azure-cli
	rtx install

# 	enable shims support for IDEA IDEs ( they support asdf but not mise nativly)
	ln -s ~/.local/share/mise ~/.asdf
#	add complettion for mise in fish
	mise completion fish > ~/.config/fish/completions/mise.fish

update:
	nix flake update

history:
	nix profile history --profile /nix/var/nix/profiles/system

gc:
	sudo nix profile wipe-history --profile /nix/var/nix/profiles/system  --older-than 7d

	sudo nix store gc --debug

fmt:
	nix fmt

.PHONY: clean  
clean:  
	rm -rf result
```


## inside the dir /modules

nix-core.nix
```
{
  pkgs,
  lib,
  ...
}: {
  nix.settings.experimental-features = ["nix-command" "flakes"];

  nixpkgs.config.allowUnfree = true;

  services.nix-daemon.enable = true;
  nix.package = pkgs.nix;

  programs.nix-index.enable = true;

  nix.gc = {
    automatic = lib.mkDefault true;
    options = lib.mkDefault "--delete-older-than 1w";
  };

  nix.settings.auto-optimise-store = true;
}
```
host-users.nix
```
{...} @ args: let
  hostname = "mbp";
  username = "hest";
in {
  networking.hostName = hostname;
  networking.computerName = hostname;
  system.defaults.smb.NetBIOSName = hostname;

  users.users."${username}" = {
    home = "/Users/${username}";
    description = username;
    shell = "/run/current-system/sw/bin/fish";
  };

  nix.settings.trusted-users = [username];
}
```
apps.nix
```
{pkgs, ...}: {
  environment.systemPackages = with pkgs; [
    neovim
    git
    yabai
    skhd
  ];
  environment.variables.EDITOR = "nvim";
  environment.loginShell = "/etc/profiles/per-user/hest/bin/fish";

  services.skhd = {
    enable = true;
    skhdConfig = ''
      # toggle window split type
      alt - e : yabai -m window --toggle split

      # rotate tree
      alt - r : yabai -m space --rotate 90

      # mirror tree y-axis
      alt - y : yabai -m space --mirror y-axis

      # mirror tree x-axis
      alt - x : yabai -m space --mirror x-axis

      # balance size of windows
      shift + alt - 0 : yabai -m space --balance

      # get name of curretn window
      shift + alt - v : yabai -m query --windows --window | jq | pbcopy
      # toggle window native fullscreen
      shift + alt - f : yabai -m window --toggle native-fullscreen

      # toggle window float
      shift + alt - t : yabai -m window --toggle float && yabai -m window --grid 4:4:1:1:2:2

      # fast focus desktop
      alt+shift - 1 : yabai -m space --focus    i
      alt+shift - 2 : yabai -m space --focus   ii
      alt+shift - 3 : yabai -m space --focus  iii
      alt+shift - 4 : yabai -m space --focus   iv
      alt+shift - 5 : yabai -m space --focus    v

      ctrl + alt - 1 : yabai -m window --space    i; yabai -m space --focus    i
      ctrl + alt - 2 : yabai -m window --space   ii; yabai -m space --focus   ii
      ctrl + alt - 3 : yabai -m window --space  iii; yabai -m space --focus  iii
      ctrl + alt - 4 : yabai -m window --space   iv; yabai -m space --focus   iv
      ctrl + alt - 5 : yabai -m window --space    v; yabai -m space --focus    v

      # toggle stack icons
      shift + alt - b :  hs -c 'stackline.config:toggle("appearance.showIcons")'

      #reset layout ( undo stacking )
      ctrl + alt - b: yabai -m space --layout bsp

      #stack windows
      cmd + ctrl - left  : yabai -m window west --stack $(yabai -m query --windows --window | jq -r '.id')
      cmd + ctrl - down  : yabai -m window south --stack $(yabai -m query --windows --window | jq -r '.id')
      cmd + ctrl - up    : yabai -m window north --stack $(yabai -m query --windows --window | jq -r '.id')
      cmd + ctrl - right : yabai -m window east --stack $(yabai -m query --windows --window | jq -r '.id')

      # focus up/down stack
      ctrl - up : yabai -m window --focus stack.prev
      ctrl - down : yabai -m window --focus stack.next

      # shift windows and focus space
      ctrl + shift - left : yabai -m window --space prev; yabai -m space --focus prev
      ctrl + shift - right : yabai -m window --space next; yabai -m space --focus next

    '';
  };

  services.yabai = {
    enable = true;
    package = pkgs.yabai;
    enableScriptingAddition = true;
    config = {
      focus_follows_mouse = "autoraise";
      window_placement = "second_child";
      window_topmost = "off";
      window_shadow = "on";
      window_opacity = "off";
      active_window_opacity = "1.0";
      normal_window_opacity = "0.90";
      window_border = "off";
      window_border_width = "6";
      active_window_border_color = "0xff775759";
      normal_window_border_color = "0xff555555";
      insert_feedback_color = "0xffd75f5f";
      split_ratio = "0.50";
      auto_balance = "off";
      mouse_modifier = "fn";
      mouse_action1 = "move";
      mouse_action2 = "resize";
      mouse_drop_action = "swap";
      mouse_follows_focus = "on";
      layout = "bsp";
      top_padding = "10";
      bottom_padding = "10";
      left_padding = "10";
      right_padding = "10";
      window_gap = "06";
    };
    extraConfig = ''
      sudo yabai --load-sa
      yabai -m signal --add event=dock_did_restart action="sudo yabai --load-sa"

      # yabai -m space --create
      # yabai -m space --create
      # yabai -m space --create
      # yabai -m space --create

      yabai -m space 1 --label i
      yabai -m space 2 --label ii
      yabai -m space 3 --label iii
      yabai -m space 4 --label iv
      yabai -m space 5 --label v

      yabai -m rule --add app="^System Preferences$" manage=off
      yabai -m rule --add app="^Calculator$" manage=off
      yabai -m rule --add app="^JetBrains Toolbox$" manage=off
      yabai -m rule --add app="^Simulator$" manage=off
    '';
  };

  homebrew = {
    enable = true;

    onActivation = {
      autoUpdate = false;
      # 'zap': uninstalls all formulae(and related files) not listed here.
      # cleanup = "zap";
    };

    masApps = {
      Keynote = 409183694;
      # Xcode = 497799835;
      Amphetamine = 937984704;
    };

    taps = [
      #"homebrew/cask"
      "homebrew/cask-fonts"
      "homebrew/services"
      "homebrew/cask-versions"
    ];

    brews = [
      "mas"
      "tmux"
      "curl" # no not install curl via nixpkgs, it's not working well on macOS!
    ];

    casks = [
      "aldente"
      "bitwarden"
      "docker"
      "insomnia"
      "iterm2"
      "jetbrains-toolbox"
      "logitech-g-hub"
      "maccy"
      "microsoft-teams"
      "mqttx"
      "openlens"
      "postman"
      "raycast"
      "slack"
      "tailscale"
      "visual-studio-code"
      "warp"
      "zoom"
    ];
  };
}
```
system.nix
```
{pkgs, ...}:
###################################################################################
#
#  macOS's System configuration
#
#  All the configuration options are documented here:
#    https://daiderd.com/nix-darwin/manual/index.html#sec-options
#  and see the source code of this project to get more undocumented options:
#    https://github.com/rgcr/m-cli
#
###################################################################################
{
  system = {
    # activationScripts are executed every time you boot the system or run `nixos-rebuild` / `darwin-rebuild`.
    activationScripts.postUserActivation.text = ''
      # activateSettings -u will reload the settings from the database and apply them to the current session,
      # so we do not need to logout and login again to make the changes take effect.
      /System/Library/PrivateFrameworks/SystemAdministration.framework/Resources/activateSettings -u
    '';

    keyboard = {
      enableKeyMapping = true; # enable key mapping so that we can use `option` as `control`
      remapCapsLockToEscape = true; # remap caps lock to escape, useful for vim users
      swapLeftCommandAndLeftAlt = false;
    };

    defaults = {
      dock = {
        autohide = true;
        show-recents = false; # disable recent apps
        static-only = true;
      };

      finder = {
        _FXShowPosixPathInTitle = true; # show full path in finder title
        AppleShowAllExtensions = false; # show all file extensions
        FXEnableExtensionChangeWarning = false; # disable warning when changing file extension
        QuitMenuItem = true; # enable quit menu item
        ShowPathbar = true; # show path bar
        ShowStatusBar = true; # show status bar
      };

      trackpad = {
        Clicking = true; # enable tap to click()
        TrackpadRightClick = true; # enable two finger right click
        TrackpadThreeFingerDrag = false; # enable three finger drag
      };

      NSGlobalDomain = {
        "com.apple.swipescrolldirection" = false; # enable natural scrolling(default to true)
        "com.apple.sound.beep.feedback" = 0; # disable beep sound when pressing volume up/down key

        "com.apple.keyboard.fnState" = true; # enable function keys
        AppleInterfaceStyle = "Dark"; # dark mode
        AppleKeyboardUIMode = 3; # Mode 3 enables full keyboard control.
        ApplePressAndHoldEnabled = true; # enable press and hold

        InitialKeyRepeat = 15; # normal minimum is 15 (225 ms), maximum is 120 (1800 ms)
        # sets how fast it repeats once it starts.
        KeyRepeat = 3; # normal minimum is 2 (30 ms), maximum is 120 (1800 ms)

        NSAutomaticCapitalizationEnabled = false; # disable auto capitalization(自动大写)
        NSAutomaticDashSubstitutionEnabled = false; # disable auto dash substitution(智能破折号替换)
        NSAutomaticPeriodSubstitutionEnabled = false; # disable auto period substitution(智能句号替换)
        NSAutomaticQuoteSubstitutionEnabled = false; # disable auto quote substitution(智能引号替换)
        NSAutomaticSpellingCorrectionEnabled = false; # disable auto spelling correction(自动拼写检查)
        NSNavPanelExpandedStateForSaveMode = true; # expand save panel by default(保存文件时的路径选择/文件名输入页)
        NSNavPanelExpandedStateForSaveMode2 = true;
        _HIHideMenuBar = true; # hide menu bar
      };

      # Customize settings that not supported by nix-darwin directly
      # see the source code of this project to get more undocumented options:
      #    https://github.com/rgcr/m-cli
      #
      # All custom entries can be found by running `defaults read` command.
      # or `defaults read xxx` to read a specific domain.
      CustomUserPreferences = {
        ".GlobalPreferences" = {
          # automatically switch to a new space when switching to the application
          AppleSpacesSwitchOnActivate = true;
        };
        NSGlobalDomain = {
          # Add a context menu item for showing the Web Inspector in web views
          WebKitDeveloperExtras = true;
        };
        "com.apple.finder" = {
          ShowExternalHardDrivesOnDesktop = false;
          ShowHardDrivesOnDesktop = false;
          ShowMountedServersOnDesktop = true;
          ShowRemovableMediaOnDesktop = true;
          _FXSortFoldersFirst = true;
          # When performing a search, search the current folder by default
          FXDefaultSearchScope = "SCcf";
        };
        "com.apple.desktopservices" = {
          # Avoid creating .DS_Store files on network or USB volumes
          DSDontWriteNetworkStores = true;
          DSDontWriteUSBStores = true;
        };
        "com.apple.screensaver" = {
          # Require password immediately after sleep or screen saver begins
          askForPassword = 1;
          askForPasswordDelay = 0;
        };
        "com.apple.screencapture" = {
          location = "~/Desktop";
          type = "png";
        };
        "com.apple.AdLib" = {
          allowApplePersonalizedAdvertising = false;
        };
        "com.apple.ImageCapture".disableHotPlug = true;
      };

      loginwindow = {
        GuestEnabled = false; # disable guest user
        SHOWFULLNAME = true; # show full name in login window
      };
    };
  };

  # Add ability to used TouchID for sudo authentication
  security.pam.enableSudoTouchIdAuth = true;

  programs.fish.enable = true;
  environment.shells = [
    pkgs.fish
  ];
  fonts = {
    # use fonts specified by user rather than default ones
    fontDir.enable = true;

    fonts = with pkgs; [
      material-design-icons
      font-awesome

      (nerdfonts.override {
        fonts = [
          "FiraCode"
          "JetBrainsMono"
        ];
      })
    ];
  };
}
```

## Inside dir /home

core.nix
```
{pkgs, ...}: {
  home.packages = with pkgs; [
    jq
    diff-so-fancy
    bat
    btop
    #dust
    eza
    gotop
    wget
    lf
    tree
    tldr
    glow
    kubectl
    k9s
    jc
    dotnetPackages.Nuget
    unixtools.watch
  ];

  programs = {
    neovim = {
      enable = true;
      defaultEditor = true;
      vimAlias = true;
    };

    bat = {
      enable = true;
      config = {
        theme = "Nord";
        style = "numbers,changes,header";
      };
    };

    eza = {
      enable = true;
      git = true;
      icons = true;
    };

    ssh = {
      enable = true;
      addKeysToAgent = "yes";
    };

    navi.enable = true;
    nushell.enable = true;
    ripgrep.enable = true;
    awscli.enable = true;
  };
}
```
default.nix
```
{...}: let
  username = "hest";
in {
  imports = [
    ./core.nix
    ./mise.nix
    ./git.nix
    ./fish.nix
    ./k9s.nix
  ];
  home = {
    username = "${username}";
    homeDirectory = "/Users/${username}";

    stateVersion = "23.05";
  };
  # might be dangerous on macos ?
  xdg.enable = true;
  xdg.configHome = "/Users/${username}/.config";
  programs.home-manager.enable = true;
}
```
fish.nix
```
let
  insultfunction = builtins.readFile ./fish-functions/insulter.fish;
in
  {
    config,
    lib,
    pkgs,
    ...
  }: {
    home.packages = with pkgs; [
      fish
      fzf
      grc
      fishPlugins.autopair
      fishPlugins.colored-man-pages
      fishPlugins.done
      fishPlugins.fzf
      fishPlugins.grc
      fishPlugins.sponge
      fishPlugins.z
    ];

    programs.fish = {
      enable = true;

      shellInit = ''
        /Users/hest/.local/bin/mise activate fish --shims | source
      '';

      interactiveShellInit = ''
        insulter

        /Users/hest/.local/bin/mise activate fish | source

        set fish_greeting # Disable greeting
        abbr -a -- .. "cd .."
        abbr -a -- ... "cd ../.."
        abbr -a -- .... "cd ../../.."
        abbr -a -- ..... "cd ../../../.."
        abbr -a -- - "cd -"
      '';
      shellAbbrs = {
        k = "kubectl";
        g = "git";
        cat = "bat";
        vi = "nvim";
        vim = "nvim";
        ls = "eza -1 -F --group-directories-first";
        lsa = "eza -1 -F --group-directories-first -a";
        ll = "eza -1 -F --group-directories-first -l --git";
        lla = "eza -1 -F --group-directories-first -l -a --git";
        lt = "eza -1 -F -T";
        gitbt = "git log --graph --simplify-by-decoration --pretty=format:'%d' --all";
        azlistdev = "az containerapp list --subscription ${builtins.getEnv "AZ_SUB_DEV"} --resource-group ${builtins.getEnv "AZ_RG_DEV"} | jq '.[] | \"\\(.properties.runningStatus) \\(.name)\"'";
        azlistprod = "az containerapp list --subscription ${builtins.getEnv "AZ_SUB_PROD"} --resource-group ${builtins.getEnv "AZ_RG_PROD"} | jq '.[] | \"\\(.properties.runningStatus) \\(.name)\"'";
        azdev = "az containerapp logs show --subscription ${builtins.getEnv "AZ_SUB_DEV"} --resource-group ${builtins.getEnv "AZ_RG_DEV"} --follow --format text -n";
        azprod = "az containerapp logs show --subscription ${builtins.getEnv "AZ_SUB_PROD"} --resource-group ${builtins.getEnv "AZ_RG_PROD"} --follow --format text -n";
      };

      functions = {
        update_git = ''
          set back (pwd)
          for d in (find . -type d -name .git)
            cd "$d/.."
            pwd
            git pull
            cd $back
          end
        '';

        gcp = ''
          git add .
          git commit -m "$argv"
          git push origin HEAD
        '';

        insulter = insultfunction;

        gitignore = "curl -sL https://www.gitignore.io/api/$argv";
      };

      plugins = [
        {
          name = "autopair";
          src = pkgs.fishPlugins.autopair.src;
        }
        {
          name = "done";
          src = pkgs.fishPlugins.done.src;
        }
        {
          name = "fzf";
          src = pkgs.fishPlugins.fzf.src;
        }
        {
          name = "grc";
          src = pkgs.fishPlugins.grc.src;
        }
        {
          name = "sponge";
          src = pkgs.fishPlugins.sponge.src;
        }
        {
          name = "z";
          src = pkgs.fishPlugins.z.src;
        }
      ];
    };
  }
```
git.nix
```
{
  config,
  lib,
  pkgs,
  ...
}: {
  home.activation.removeExistingGitconfig = lib.hm.dag.entryBefore ["checkLinkTargets"] ''
    rm -f ~/.gitconfig
  '';

  programs.git = {
    enable = true;
    lfs.enable = true;
    diff-so-fancy.enable = true;

    includes = [
      {
        condition = "gitdir:${builtins.getEnv "M_DIR"}";
        contents = {
          core.sshCommand = "ssh -i ~/.ssh/${builtins.getEnv "M_ID"}";
          user = {
            name = "${builtins.getEnv "M_USER"}";
            email = "${builtins.getEnv "M_MAIL"}";
          };
        };
      }
      {
        condition = "gitdir:${builtins.getEnv "C_DIR"}";
        contents = {
          core.sshCommand = "ssh -i ~/.ssh/${builtins.getEnv "C_ID"}";
          user = {
            name = "${builtins.getEnv "C_USER"}";
            email = "${builtins.getEnv "C_MAIL"}";
          };
        };
      }
      {
        condition = "gitdir:${builtins.getEnv "G_DIR"}";
        contents = {
          core.sshCommand = "ssh -i ~/.ssh/${builtins.getEnv "G_ID"}";
          user = {
            name = "${builtins.getEnv "G_USER"}";
            email = "${builtins.getEnv "G_MAIL"}";
          };
        };
      }
    ];

    extraConfig = {
      init.defaultBranch = "main";
      push.autoSetupRemote = true;
      pull.rebase = true;
    };

    aliases = {
      br = "branch";
      co = "checkout";
      st = "status";
      ls = "log --pretty=format:\"%C(yellow)%h%Cred%d\\\\ %Creset%s%Cblue\\\\ [%cn]\" --decorate";
      ll = "log --pretty=format:\"%C(yellow)%h%Cred%d\\\\ %Creset%s%Cblue\\\\ [%cn]\" --decorate --numstat";
      lg = "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
      cm = "commit -m";
      ca = "commit -am";
      dc = "diff --cached";
      amend = "commit --amend -m";

      # aliases for submodule
      update = "submodule update --init --recursive";
      foreach = "submodule foreach";
    };
    ignores = [
      "!.vscode/extensions.json"
      "!.vscode/launch.json"
      "!.vscode/settings.json"
      "!.vscode/tasks.json"
      "!flake.lock"
      ".classpath"
      ".env"
      ".flattened-pom.xml"
      ".gradle/"
      ".idea/"
      ".mise.toml"
      ".project"
      ".rtx.toml"
      ".vscode/*"
      "*.code-workspace"
      "*.iml"
      "*.lock"
      "*.settings"
      "*.tgz"
      "bin/"
      "build/"
      "out/"
    ];
  };
}
```
k9s.nix
```
{
  config,
  lib,
  pkgs,
  ...
}: {
  programs.k9s = {
    enable = true;
    views = {};
    skins = {
      skin = {
        k9s = {
          body = {
            fgColor = "#DADEE8";
            bgColor = "default";
            logoColor = "#B48EAD";
          };
          prompt = {
            fgColor = "#DADEE8";
            bgColor = "#30343F";
            suggestColor = "#D08770";
          };
          info = {
            fgColor = "#81A1C1";
            sectionColor = "#DADEE8";
          };
          dialog = {
            fgColor = "#DADEE8";
            bgColor = "default";
            buttonFgColor = "#DADEE8";
            buttonBgColor = "#B48EAD";
            buttonFocusFgColor = "#EBCB8B";
            buttonFocusBgColor = "#81A1C1";
            labelFgColor = "#D08770";
            fieldFgColor = "#DADEE8";
          };
          frame = {
            border = {
              fgColor = "#D9DEE8";
              focusColor = "#383D4A";
            };
            menu = {
              fgColor = "#DADEE8";
              keyColor = "#81A1C1";
              numKeyColor = "#81A1C1";
            };
            crumbs = {
              fgColor = "#DADEE8";
              bgColor = "#383D4A";
              activeColor = "#383D4A";
            };
            status = {
              newColor = "#88C0D0";
              modifyColor = "#B48EAD";
              addColor = "#A3BE8C";
              errorColor = "#BF616A";
              highlightColor = "#D08770";
              killColor = "#8891A7";
              completedColor = "#8891A7";
            };
            title = {
              fgColor = "#DADEE8";
              bgColor = "#383D4A";
              highlightColor = "#D08770";
              counterColor = "#B48EAD";
              filterColor = "#81A1C1";
            };
          };
          views = {
            charts = {
              bgColor = "default";
              defaultDialColors = ["#B48EAD" "#BF616A"];
              defaultChartColors = ["#B48EAD" "#BF616A"];
            };
            table = {
              fgColor = "#DADEE8";
              bgColor = "default";
              header = {
                fgColor = "#DADEE8";
                bgColor = "default";
                sorterColor = "#88C0D0";
              };
            };
            xray = {
              fgColor = "#DADEE8";
              bgColor = "default";
              cursorColor = "#383D4A";
              graphicColor = "#B48EAD";
              showIcons = false;
            };
            yaml = {
              keyColor = "#81A1C1";
              colonColor = "#B48EAD";
              valueColor = "#DADEE8";
            };
            logs = {
              fgColor = "#DADEE8";
              bgColor = "default";
              indicator = {
                fgColor = "#DADEE8";
                bgColor = "#B48EAD";
                toggleOnColor = "#B48EAD";
                toggleOffColor = "#88C0D0";
              };
            };
            help = {
              fgColor = "#DADEE8";
              bgColor = "#30343F";
              indicator = {
                fgColor = "#BF616A";
              };
            };
          };
        };
      };
    };
  };
}
```
mise.nix
```
# wont install tools automaticly
# mise activate fish | source
# mise use --global go@1.21.4
{
  config,
  lib,
  pkgs,
  ...
}: {
  programs.mise = {
    enable = true;
    globalConfig = {
      tools = {
        go = "latest";
        java = ["openjdk-21"];
        nodejs = ["lts" "18"];
        dotnet = ["7" "8"];
      };

      settings = {
        verbose = false;
        experimental = false;
      };
    };
  };
}
```
...