Full Code of budimanjojo/dotfiles for AI

main 994d428683ed cached
266 files
478.4 KB
166.2k tokens
1 requests
Download .txt
Showing preview only (550K chars total). Download the full file or copy to clipboard to get everything.
Repository: budimanjojo/dotfiles
Branch: main
Commit: 994d428683ed
Files: 266
Total size: 478.4 KB

Directory structure:
gitextract_4wydarc6/

├── .chezmoiroot
├── .editorconfig
├── .github/
│   ├── FUNDING.yml
│   ├── renovate.json
│   └── workflows/
│       ├── broken-link-check.yaml
│       ├── build-push-cache.yaml
│       ├── check-flakes.yaml
│       ├── renovate.yaml
│       ├── update-nvfetcher.yaml
│       └── update-sops-keys.yaml
├── .gitignore
├── .justfile
├── .sops.yaml
├── LICENSE
├── README.md
├── chezmoi/
│   ├── .chezmoi.yaml.tmpl
│   ├── .chezmoiignore
│   ├── .chezmoiscripts/
│   │   ├── run_once_after_90-cleanup.sh.tmpl
│   │   ├── run_once_before_10-setup-fish.sh.tmpl
│   │   ├── run_once_before_20-install-packages-archlinux.sh.tmpl
│   │   ├── run_once_before_20-install-packages-ubuntu.sh.tmpl
│   │   └── run_onchange_after_80-setup-terminal.sh.tmpl
│   └── dot_config/
│       ├── fontconfig/
│       │   └── fonts.conf.tmpl
│       └── termite/
│           └── config
├── flake.nix
├── flakeLib.nix
├── home/
│   ├── _modules/
│   │   ├── _default/
│   │   │   ├── default.nix
│   │   │   ├── nix.nix
│   │   │   └── sops.nix
│   │   ├── browser/
│   │   │   └── firefox/
│   │   │       └── default.nix
│   │   ├── default.nix
│   │   ├── editor/
│   │   │   └── neovim/
│   │   │       └── default.nix
│   │   ├── homelab/
│   │   │   └── kubernetes/
│   │   │       ├── default.nix
│   │   │       └── secret.sops.yaml
│   │   ├── multiplexer/
│   │   │   ├── tmux/
│   │   │   │   ├── config/
│   │   │   │   │   └── tmux.conf
│   │   │   │   └── default.nix
│   │   │   └── zellij/
│   │   │       ├── config/
│   │   │       │   ├── config.kdl
│   │   │       │   └── layouts/
│   │   │       │       └── default.kdl
│   │   │       └── default.nix
│   │   ├── programs/
│   │   │   ├── beeaccounting/
│   │   │   │   └── default.nix
│   │   │   ├── chezmoi/
│   │   │   │   └── default.nix
│   │   │   ├── fontconfig/
│   │   │   │   └── default.nix
│   │   │   ├── go/
│   │   │   │   └── default.nix
│   │   │   ├── obs-studio/
│   │   │   │   └── default.nix
│   │   │   ├── qmk/
│   │   │   │   ├── default.nix
│   │   │   │   └── qmk.ini
│   │   │   └── yamllint/
│   │   │       ├── config.yaml
│   │   │       └── default.nix
│   │   ├── services/
│   │   │   └── opencloud-client/
│   │   │       └── default.nix
│   │   ├── shell/
│   │   │   ├── dircolors/
│   │   │   │   └── default.nix
│   │   │   ├── fish/
│   │   │   │   └── default.nix
│   │   │   ├── git/
│   │   │   │   └── default.nix
│   │   │   ├── lf/
│   │   │   │   ├── configs/
│   │   │   │   │   ├── colors
│   │   │   │   │   └── icons
│   │   │   │   └── default.nix
│   │   │   ├── nix-direnv/
│   │   │   │   └── default.nix
│   │   │   └── starship/
│   │   │       └── default.nix
│   │   ├── terminal-emulator/
│   │   │   ├── alacritty/
│   │   │   │   └── default.nix
│   │   │   ├── contour/
│   │   │   │   ├── config/
│   │   │   │   │   └── contour.yml
│   │   │   │   └── default.nix
│   │   │   ├── kitty/
│   │   │   │   └── default.nix
│   │   │   └── wezterm/
│   │   │       ├── config/
│   │   │       │   └── wezterm.lua
│   │   │       └── default.nix
│   │   └── windowmanager/
│   │       ├── add-on/
│   │       │   ├── blueman-applet/
│   │       │   │   └── default.nix
│   │       │   ├── dunst/
│   │       │   │   └── default.nix
│   │       │   ├── gtk-theme/
│   │       │   │   └── default.nix
│   │       │   ├── nm-applet/
│   │       │   │   └── default.nix
│   │       │   ├── nwg-bar/
│   │       │   │   └── default.nix
│   │       │   ├── pasystray/
│   │       │   │   └── default.nix
│   │       │   ├── picom/
│   │       │   │   └── default.nix
│   │       │   ├── py3status/
│   │       │   │   ├── config
│   │       │   │   └── default.nix
│   │       │   ├── rofi/
│   │       │   │   ├── default.nix
│   │       │   │   └── style.rasi
│   │       │   ├── screenshotter/
│   │       │   │   ├── camera-shutter.oga
│   │       │   │   └── default.nix
│   │       │   ├── swayidle/
│   │       │   │   └── default.nix
│   │       │   ├── swaylock/
│   │       │   │   └── default.nix
│   │       │   ├── terminal-emulator/
│   │       │   │   └── default.nix
│   │       │   ├── theme/
│   │       │   │   └── tokyonight/
│   │       │   │       └── default.nix
│   │       │   ├── waybar/
│   │       │   │   └── default.nix
│   │       │   └── xdg/
│   │       │       └── default.nix
│   │       ├── hyprland/
│   │       │   ├── config/
│   │       │   │   ├── appearances.nix
│   │       │   │   ├── default.nix
│   │       │   │   ├── keybindings.nix
│   │       │   │   ├── window-rules.nix
│   │       │   │   └── ws-outputs.nix
│   │       │   └── default.nix
│   │       ├── i3/
│   │       │   ├── config/
│   │       │   │   ├── commands.nix
│   │       │   │   ├── default.nix
│   │       │   │   ├── keybindings.nix
│   │       │   │   ├── modes.nix
│   │       │   │   └── startups.nix
│   │       │   └── default.nix
│   │       └── sway/
│   │           ├── config/
│   │           │   ├── commands.nix
│   │           │   ├── default.nix
│   │           │   ├── keybindings.nix
│   │           │   ├── modes.nix
│   │           │   └── startups.nix
│   │           └── default.nix
│   └── budiman/
│       ├── config/
│       │   ├── gitcommit-message
│       │   └── neovim/
│       │       ├── appearance.nix
│       │       ├── autocmds.nix
│       │       ├── default.nix
│       │       ├── diagnostic.nix
│       │       ├── general.nix
│       │       ├── keymaps.nix
│       │       ├── lsp.nix
│       │       ├── lua/
│       │       │   └── utils.lua
│       │       └── plugins/
│       │           ├── blink-cmp/
│       │           │   └── default.nix
│       │           ├── chezmoi-vim/
│       │           │   └── default.nix
│       │           ├── cord/
│       │           │   └── default.nix
│       │           ├── default.nix
│       │           ├── endec/
│       │           │   └── default.nix
│       │           ├── gitsigns/
│       │           │   └── default.nix
│       │           ├── grug-far/
│       │           │   └── default.nix
│       │           ├── lualine/
│       │           │   └── default.nix
│       │           ├── luasnip/
│       │           │   ├── default.nix
│       │           │   └── lua-snippets/
│       │           │       └── gitcommit.lua
│       │           ├── mini/
│       │           │   ├── comment.nix
│       │           │   ├── default.nix
│       │           │   ├── icons.nix
│       │           │   ├── indentscope.nix
│       │           │   ├── surround.nix
│       │           │   └── trailspace.nix
│       │           ├── noice/
│       │           │   └── default.nix
│       │           ├── none-ls/
│       │           │   └── default.nix
│       │           ├── nvim-autopairs/
│       │           │   ├── _rules.lua
│       │           │   └── default.nix
│       │           ├── oil/
│       │           │   └── default.nix
│       │           ├── snacks/
│       │           │   ├── default.nix
│       │           │   ├── input.nix
│       │           │   └── picker.nix
│       │           ├── toggleterm/
│       │           │   └── default.nix
│       │           └── treesitter/
│       │               └── default.nix
│       ├── default.nix
│       ├── hosts/
│       │   ├── budimanjojo-firewall.nix
│       │   ├── budimanjojo-main.nix
│       │   ├── budimanjojo-nas.nix
│       │   ├── budimanjojo-oracle.nix
│       │   └── budimanjojo-ubuntu.nix
│       └── profiles/
│           ├── extra-gaming.nix
│           ├── extra-graphics.nix
│           ├── extra-utilities.nix
│           ├── server.nix
│           ├── workstation-common.nix
│           ├── workstation-hyprland.nix
│           ├── workstation-i3.nix
│           └── workstation-sway.nix
├── lib/
│   └── default.nix
├── overlays/
│   └── default.nix
├── packages/
│   ├── _sources/
│   │   ├── generated.json
│   │   └── generated.nix
│   ├── configure-gtk/
│   │   └── default.nix
│   ├── default.nix
│   ├── fish-plugins/
│   │   └── default.nix
│   ├── krr/
│   │   ├── about-time.nix
│   │   ├── alive-progress.nix
│   │   ├── default.nix
│   │   └── prometheus-api-client.nix
│   ├── kubectl-rook-ceph/
│   │   └── default.nix
│   ├── nvfetcher.toml
│   ├── nvim-plugins/
│   │   └── default.nix
│   ├── tokyonight-gtk-theme/
│   │   └── default.nix
│   └── tokyonight-icon-theme/
│       └── default.nix
├── shell.nix
└── system/
    ├── _modules/
    │   ├── _default/
    │   │   ├── default.nix
    │   │   ├── nix.nix
    │   │   ├── secret.sops.yaml
    │   │   ├── sops.nix
    │   │   └── users.nix
    │   ├── containers/
    │   │   └── beeaccounting/
    │   │       ├── default.nix
    │   │       └── secret.sops.yaml
    │   ├── default.nix
    │   ├── displaymanager/
    │   │   └── sddm/
    │   │       └── default.nix
    │   ├── monitoring/
    │   │   ├── node-exporter/
    │   │   │   └── default.nix
    │   │   └── smartctl-exporter/
    │   │       └── default.nix
    │   ├── myHardware.nix
    │   ├── programs/
    │   │   ├── adb/
    │   │   │   └── default.nix
    │   │   ├── hugo/
    │   │   │   └── default.nix
    │   │   ├── msmtp/
    │   │   │   ├── default.nix
    │   │   │   └── secret.sops.yaml
    │   │   ├── nh/
    │   │   │   └── default.nix
    │   │   └── qmk/
    │   │       └── default.nix
    │   ├── services/
    │   │   ├── btrfs-autoscrub/
    │   │   │   └── default.nix
    │   │   ├── grafana/
    │   │   │   ├── default.nix
    │   │   │   └── secret.sops.yaml
    │   │   ├── openssh/
    │   │   │   └── default.nix
    │   │   ├── prometheus/
    │   │   │   ├── default.nix
    │   │   │   └── rules/
    │   │   │       ├── embedded-exporter.yaml
    │   │   │       └── node-exporter.yaml
    │   │   └── restic-backup/
    │   │       ├── default.nix
    │   │       └── secret.sops.yaml
    │   ├── system/
    │   │   ├── autoupgrade/
    │   │   │   └── default.nix
    │   │   ├── bootloader/
    │   │   │   └── default.nix
    │   │   ├── cpu/
    │   │   │   └── default.nix
    │   │   ├── font/
    │   │   │   └── default.nix
    │   │   ├── sound/
    │   │   │   └── default.nix
    │   │   └── video/
    │   │       └── default.nix
    │   └── windowmanager/
    │       ├── add-on/
    │       │   ├── blueman/
    │       │   │   └── default.nix
    │       │   ├── gnome-keyring/
    │       │   │   └── default.nix
    │       │   ├── networkmanager/
    │       │   │   └── default.nix
    │       │   ├── polkit-gnome/
    │       │   │   └── default.nix
    │       │   └── thunar/
    │       │       └── default.nix
    │       ├── hyprland/
    │       │   └── default.nix
    │       ├── i3/
    │       │   └── default.nix
    │       └── sway/
    │           └── default.nix
    ├── hosts/
    │   ├── budimanjojo-firewall/
    │   │   ├── _modules/
    │   │   │   ├── default.nix
    │   │   │   ├── firewall/
    │   │   │   │   ├── config/
    │   │   │   │   │   ├── sets.nft
    │   │   │   │   │   ├── zone-directions.nft
    │   │   │   │   │   └── zone-rules.nft
    │   │   │   │   └── default.nix
    │   │   │   ├── network.nix
    │   │   │   ├── podman.nix
    │   │   │   ├── secret.sops.yaml
    │   │   │   ├── services/
    │   │   │   │   ├── adguardhome/
    │   │   │   │   │   ├── default.nix
    │   │   │   │   │   └── secret.sops.yaml
    │   │   │   │   ├── chrony/
    │   │   │   │   │   └── default.nix
    │   │   │   │   ├── fireqos/
    │   │   │   │   │   └── default.nix
    │   │   │   │   ├── frr/
    │   │   │   │   │   └── default.nix
    │   │   │   │   ├── kea/
    │   │   │   │   │   ├── ddns.nix
    │   │   │   │   │   ├── default.nix
    │   │   │   │   │   ├── dhcp.nix
    │   │   │   │   │   └── secret.sops.yaml
    │   │   │   │   ├── omada-controller/
    │   │   │   │   │   ├── default.nix
    │   │   │   │   │   ├── secret.sops.yaml
    │   │   │   │   │   └── ssl.crt
    │   │   │   │   ├── powerdns/
    │   │   │   │   │   ├── default.nix
    │   │   │   │   │   └── secret.sops.yaml
    │   │   │   │   ├── rsyslogd/
    │   │   │   │   │   └── default.nix
    │   │   │   │   └── tdarr/
    │   │   │   │       └── default.nix
    │   │   │   └── wireguard.nix
    │   │   ├── default.nix
    │   │   ├── disk-config.nix
    │   │   └── hardware-configuration.nix
    │   ├── budimanjojo-main/
    │   │   ├── default.nix
    │   │   └── hardware-configuration.nix
    │   ├── budimanjojo-nas/
    │   │   ├── _modules/
    │   │   │   ├── default.nix
    │   │   │   ├── incus.nix
    │   │   │   ├── network.nix
    │   │   │   ├── nfs.nix
    │   │   │   └── secret.sops.yaml
    │   │   ├── default.nix
    │   │   ├── disk-config.nix
    │   │   └── hardware-configuration.nix
    │   ├── budimanjojo-oracle/
    │   │   ├── _modules/
    │   │   │   ├── default.nix
    │   │   │   ├── firewall.nix
    │   │   │   ├── network.nix
    │   │   │   ├── secret.sops.yaml
    │   │   │   ├── services/
    │   │   │   │   ├── blocky/
    │   │   │   │   │   ├── config.yaml
    │   │   │   │   │   ├── default.nix
    │   │   │   │   │   └── secret.sops.yaml
    │   │   │   │   └── qbittorrent/
    │   │   │   │       └── default.nix
    │   │   │   └── wireguard.nix
    │   │   ├── default.nix
    │   │   └── hardware-configuration.nix
    │   ├── default.nix
    │   └── nixos-livecd/
    │       └── default.nix
    ├── profiles/
    │   ├── gaming.nix
    │   ├── server.nix
    │   ├── work.nix
    │   ├── workstation-common.nix
    │   ├── workstation-hyprland.nix
    │   ├── workstation-i3.nix
    │   └── workstation-sway.nix
    └── pubkeys/
        └── default.nix

================================================
FILE CONTENTS
================================================

================================================
FILE: .chezmoiroot
================================================
chezmoi


================================================
FILE: .editorconfig
================================================
; https://editorconfig.org/

; top-most EditorConfig file
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
; my custom property that trim trailing empty last lines
trim_trailing_lastline = true

[{*.just,*.justfile}]
indent_size = 4


================================================
FILE: .github/FUNDING.yml
================================================
github: budimanjojo


================================================
FILE: .github/renovate.json
================================================
{
  "extends": [
    "github>budimanjojo/renovate-config:default.json5"
  ],
  "username": "budimanjojo-bot[bot]",
  "gitAuthor": "budimanjojo-bot <111944664+budimanjojo-bot[bot]@users.noreply.github.com>",
  "repositories": ["budimanjojo/nix-config"],
  "automerge": true,
  "ignoreTests": true,
  "lockFileMaintenance": {
    "enabled": true,
    "schedule": [
      "after 1am and before 3am"
    ]
  },
  "nix": {
    "enabled": true
  },
  "customManagers": [
    {
      "customType": "regex",
      "fileMatch": ["chezmoi\\/\\.chezmoiscripts\\/.+\\.sh\\.tmpl$"],
      "matchStrings": [
        "# renovate: depName=(?<depName>.*) datasource=(?<datasource>.*)\\n\\s*current_\\w+_version=(?<currentValue>.+)\\b"
      ]
    },
    {
      "customType": "regex",
      "fileMatch": [
        "^system/.*\\.nix$"
      ],
      "matchStrings": [
        "image *= *\"(?<depName>.*?):(?<currentValue>.*?)(@(?<currentDigest>sha256:[a-f0-9]+))?\""
      ],
      "datasourceTemplate": "docker"
    }
  ],
  "packageRules": [
    {
      "matchDepNames": "wez/wezterm",
      "versioning": "regex:^(?<major>\\d{4})(?<minor>\\d{2})(?<patch>\\d{2})-(?<build>\\d+)-(?<revision>.+)$"
    }
  ]
}


================================================
FILE: .github/workflows/broken-link-check.yaml
================================================
---
name: Broken link check

on:
  workflow_dispatch:
  schedule:
    - cron: "0 0 * * 0"

jobs:
  check:
    name: Check
    runs-on: ubuntu-latest
    steps:
      - name: Generate token
        uses: tibdex/github-app-token@v2
        id: generate-token
        with:
          app_id: "${{ secrets.BOT_APP_ID }}"
          private_key: "${{ secrets.BOT_APP_PRIVATE_KEY }}"

      - name: Checkout
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          token: "${{ steps.generate-token.outputs.token }}"

      - name: Scan for broken links
        uses: lycheeverse/lychee-action@v2
        id: lychee
        env:
          GITHUB_TOKEN: "${{ steps.generate-token.outputs.token }}"
        with:
          args: --verbose --no-progress --exclude-mail './**/*.md'

      - name: Find link checker issue
        id: broken-link-check-issue
        uses: micalevisk/last-issue-action@v2
        with:
          state: open
          labels: |
            broken-links

      - name: Update issue
        uses: peter-evans/create-issue-from-file@v6
        with:
          title: Broken links detected 🔗
          issue-number: "${{ steps.broken-link-check-issue.outputs.issue-number }}"
          content-filepath: ./lychee/out.md
          token: "${{ steps.generate-token.outputs.token }}"
          labels: |
            broken-links


================================================
FILE: .github/workflows/build-push-cache.yaml
================================================
---
name: Build Push Cache

on:
  workflow_dispatch: {}
  push:
    paths:
      - "system/**"
      - "home/**"
      - "packages/**"
      - "overlays/**"
      - "flake.lock"
      - "*nix"

jobs:
  define-matrix:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
        id: cache
        with:
          path: /tmp/nix-cache
          key: nix-flake-inputs-${{ hashFiles('**/flake.lock') }}
          restore-keys: |
            nix-flake-inputs-

      - uses: cachix/install-nix-action@ab739621df7a23f52766f9ccc97f38da6b7af14f # v31.10.5

      - name: Import Nix store cache
        if: steps.cache.outputs.cache-hit == 'true'
        run: nix copy --all --no-check-sigs --from /tmp/nix-cache

      - name: Build and Export .#gc-keep to Nix store cache
        run: |
          # remove everything before copying so the cache doesn't grow over time
          sudo rm -rf /tmp/nix-cache
          nix copy --no-check-sigs --to /tmp/nix-cache .#gc-keep

      - id: set-matrix
        run: |
          set -Eeu
          matrix="$(nix eval --json '.#ghActions.matrix')"
          echo "matrix=$matrix" >> "$GITHUB_OUTPUT"

  build-push:
    name: ${{ matrix.attrset }}
    needs: define-matrix
    runs-on: ${{ matrix.runner }}
    strategy:
      fail-fast: false
      matrix: ${{ fromJSON(needs.define-matrix.outputs.matrix) }}
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
        id: cache
        with:
          path: /tmp/nix-cache
          key: nix-flake-inputs-${{ hashFiles('**/flake.lock') }}

      - name: Brutally add more storage to our runner
        uses: wimpysworld/nothing-but-nix@687c797a730352432950c707ab493fcc951818d7 # main
        with:
          hatchet-protocol: carve

      - uses: cachix/install-nix-action@ab739621df7a23f52766f9ccc97f38da6b7af14f # v31.10.5

      - name: Import Nix store cache
        if: steps.cache.outputs.cache-hit == 'true'
        run: nix copy --no-check-sigs --all --from /tmp/nix-cache

      - name: Login to Cachix
        uses: cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c # v17
        with:
          name: budimanjojo
          authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
          skipPush: true

      - name: Build
        id: build
        run: |
          result=$(nix build .#${{ matrix.attrset }} --print-out-paths)
          echo "result=$result" >> $GITHUB_OUTPUT

      - name: Push
        run: cachix push budimanjojo ${{ steps.build.outputs.result }}


================================================
FILE: .github/workflows/check-flakes.yaml
================================================
---
name: Check Flakes

on:
  pull_request_target:
    types:
      - opened
      - auto_merge_enabled
  push:
    paths:
      - '**.nix'
      - flake.lock

jobs:
  check_flakes:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - uses: cachix/install-nix-action@ab739621df7a23f52766f9ccc97f38da6b7af14f # v31
        with:
          nix_path: nixpkgs=channel:nixos-unstable
          extra_nix_config: |
            access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
      - run: nix flake check


================================================
FILE: .github/workflows/renovate.yaml
================================================
---
name: Renovate

on:
  workflow_dispatch:
    inputs:
      dryRun:
        description: Dry-Run
        default: "false"
        required: false
      logLevel:
        description: Log-level
        default: debug
        required: false
  schedule:
    - cron: 0 * * * *
  push:
    paths:
      - .github/renovate.json

env:
  LOG_LEVEL: debug
  RENOVATE_DRY_RUN: false
  RENOVATE_CONFIG_FILE: .github/renovate.json

jobs:
  renovate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - name: Generate Token
        uses: tibdex/github-app-token@v2
        id: generate-token
        with:
          app_id: ${{ secrets.BOT_APP_ID }}
          private_key: ${{ secrets.BOT_APP_PRIVATE_KEY }}
      - name: Override default config from dispatch variables
        run: |
          echo "RENOVATE_DRY_RUN=${{ github.event.inputs.dryRun || env.RENOVATE_DRY_RUN }}" >> "${GITHUB_ENV}"
          echo "LOG_LEVEL=${{ github.event.inputs.logLevel || env.LOG_LEVEL }}" >> "${GITHUB_ENV}"
      - name: Renovate
        uses: renovatebot/github-action@v46.1.12
        with:
          configurationFile: "${{ env.RENOVATE_CONFIG_FILE }}"
          token: "${{ steps.generate-token.outputs.token }}"


================================================
FILE: .github/workflows/update-nvfetcher.yaml
================================================
---
name: Update nvfetcher

on:
  workflow_dispatch: {}
  schedule:
    - cron: 0 * * * *
  push:
    paths:
      - packages/nvfetcher.toml

jobs:
  update-nvfetcher:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        # TODO: https://github.com/peter-evans/create-pull-request/issues/4228
        with:
          persist-credentials: false
      - uses: nixbuild/nix-quick-install-action@2c9db80fb984ceb1bcaa77cdda3fdf8cfba92035 # v34
        with:
          nix_conf: |
            keep-env-derivations = true
            keep-outputs = true
      - uses: nix-community/cache-nix-action@7df957e333c1e5da7721f60227dbba6d06080569 # v7.0.2
        with:
          primary-key: nvfetcher-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
          restore-prefixes-first-match: nvfetcher-${{ runner.os }}-
          gc-max-store-size-linux: 1G
          purge: true
          purge-prefixes: nvfetcher-${{ runner.os }}-
          purge-created: 0
          purge-last-accessed: 0
          purge-primary-key: never
      - run: nix profile install github:berberman/nvfetcher
      - id: update_nvfetcher
        run: |
          cd packages
          echo "OUTPUT<<EOF" >> $GITHUB_OUTPUT
          nvfetcher | sed -n '/Changes/,/$!d/p' >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT
      - name: Generate token
        uses: tibdex/github-app-token@v2
        id: generate-token
        with:
          app_id: ${{ secrets.BOT_APP_ID }}
          private_key: ${{ secrets.BOT_APP_PRIVATE_KEY }}
      - name: Create Pull Request
        id: cpr
        uses: peter-evans/create-pull-request@v8
        with:
          token: ${{ steps.generate-token.outputs.token }}
          title: "chore(deps): update packages managed by nvfetcher"
          commit-message: "chore(deps): update packages managed by nvfetcher"
          delete-branch: true
          labels: nvfetcher
          committer: budimanjojo-bot <111944664+budimanjojo-bot[bot]@users.noreply.github.com>
          author: budimanjojo-bot <111944664+budimanjojo-bot[bot]@users.noreply.github.com>
          body: |
            ${{ steps.update_nvfetcher.outputs.OUTPUT }}
      - name: Automerge
        if: steps.cpr.outputs.pull-request-operation == 'created'
        uses: peter-evans/enable-pull-request-automerge@v3
        with:
          token: ${{ steps.generate-token.outputs.token }}
          pull-request-number: ${{ steps.cpr.outputs.pull-request-number }}
          merge-method: squash


================================================
FILE: .github/workflows/update-sops-keys.yaml
================================================
---
name: Update SOPS keys

on:
  workflow_dispatch: {}
  schedule:
    - cron: 0 * * * *
  push:
    paths:
      - .sops.yaml

jobs:
  update-sops-keys:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        # TODO: https://github.com/peter-evans/create-pull-request/issues/4228
        with:
          persist-credentials: false
      - uses: cachix/install-nix-action@ab739621df7a23f52766f9ccc97f38da6b7af14f # v31
        with:
          nix_path: nixpkgs=channel:nixos-unstable
          extra_nix_config: |
            access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
      - uses: workflow/nix-shell-action@v4.0.0
        with:
          packages: sops,findutils
          script: |
            export SOPS_AGE_KEY=${{ secrets.SOPS_AGE_KEY }}
            find . -type f -name \*.sops.yaml ! -name .sops.yaml -exec sops updatekeys --yes {} \;
      - name: Generate token
        uses: tibdex/github-app-token@v2
        id: generate-token
        with:
          app_id: ${{ secrets.BOT_APP_ID }}
          private_key: ${{ secrets.BOT_APP_PRIVATE_KEY }}
      - name: Create Pull Request
        id: cpr
        uses: peter-evans/create-pull-request@v8
        with:
          token: ${{ steps.generate-token.outputs.token }}
          title: "chore(sops): update sops secrets with new public keys"
          commit-message: "chore(deps): update sops secrets with new public keys"
          delete-branch: true
          committer: budimanjojo-bot <111944664+budimanjojo-bot[bot]@users.noreply.github.com>
          author: budimanjojo-bot <111944664+budimanjojo-bot[bot]@users.noreply.github.com>
      - name: Automerge
        if: steps.cpr.outputs.pull-request-operation == 'created'
        uses: peter-evans/enable-pull-request-automerge@v3
        with:
          token: ${{ steps.generate-token.outputs.token }}
          pull-request-number: ${{ steps.cpr.outputs.pull-request-number }}
          merge-method: squash


================================================
FILE: .gitignore
================================================
.luarc.json
result


================================================
FILE: .justfile
================================================
set unstable := true
set shell := ['bash', '-euo', 'pipefail', '-c']

# `nix` is required
requireNixToRun := require('nix')

# the user running this needs to be a nix trusted-user for the extra-substituters to work
export NIX_CONFIG := '''
    extra-experimental-features = nix-command flakes
    extra-substituters = https://viperml.cachix.org https://budimanjojo.cachix.org
    extra-trusted-public-keys = viperml.cachix.org-1:qZhKBMTfmcLL+OG6fj/hzsMEedgKvZVFRRAhq7j8Vh8= budimanjojo.cachix.org-1:S0gy6IKTFXis9fFqEbVAS2zsvnZw/30NV2bWvGiN1YQ=
'''

# we use nix shebang to get into a nix shell with packages that's needed for each recipe
nixShebang := '/usr/bin/env -S nix shell --inputs-from ' + justfile_directory()
realShebang := '/usr/bin/env bash -euo pipefail'

[private]
default:
    @just -l

# update packages managed by `nvfetcher`
[group('repository')]
update-packages:
    #! {{ nixShebang }} nixpkgs#nvfetcher -c {{ realShebang }}
    cd ./packages
    nvfetcher

# update SOPS keys
[group('repository')]
update-sops-keys:
    #! {{ nixShebang }} nixpkgs#sops nixpkgs#findutils -c {{ realShebang }}
    find . -type f -name \*.sops.yaml ! -name .sops.yaml -exec sops updatekeys --yes {} \;

# do `nixos-rebuild switch` for current system
[group('nix')]
nixos-switch:
    sudo nixos-rebuild switch --flake .#{{ shell('hostname') }}

# do `home-manager switch` for current system
[group('nix')]
home-switch:
    home-manager switch --flake .#{{ shell('whoami') }}@{{ shell('hostname') }}

# create NixOS ISO
[group('nix')]
make-iso:
    nix build .#nixosConfigurations.nixos-livecd.config.system.build.isoImage

# garbage collect all unused store entries
[group('nix')]
gc day='7':
    # garbage collect all unused nix store entries (system-wide)
    sudo nix-collect-garbage --delete-older-than {{ day }}d
    # garbage collect all unused nix store entries (user-wide)
    # ref: https://github.com/NixOS/nix/issues/8508
    nix-collect-garbage --delete-older-than {{ day }}d

# verify all the store entries
# nix store can contains corrupted entries if the nix store object has been modified unexpectedly
# we need to fix the corrupted entries manually via `sudo nix store delete <path-1> <path-2> ...`
[group('nix')]
verify-store:
    nix store verify --all

# repair nix store objects
[group('nix')]
repair-store *paths:
    nix store repair {{ paths }}

# show all the auto gc root in the nix store
[group('nix')]
gcroot:
    #! {{ nixShebang }} nixpkgs#eza -c {{ realShebang }}
    eza -lag /nix/var/nix/gcroots/auto/


================================================
FILE: .sops.yaml
================================================
---
creation_rules:
  - path_regex: .*secret\.sops\.ya?ml$
    key_groups:
      - age:
          - age1zeqkpfz7e3s207ynea0z0auc0mrct0pc7w4sh6j3d0c4qac3dahqj9ufdg
          - age1tdwlq9y4jgejkhasqwynw5uaen9xwatcvr52l70trsdxkeyvlesqjnh7l8
          - age16p3zls5n0jks6amszwcuaqgl5dyuyf8k8wgeyrw562s5s88xtq3qq046fh
          - age1v52mx8gs4ephprep0wcc4j3fvvprppvs9vktf2p24yv52sqsf33sd5crk9
          - age1k8ufac2s0gs6nh0xsfavafz062vd36petmyv6nwmg00z4a7s4gnsjtd837
          - age1dcsm5awz8ekzchk7gsvndkc4kq65n2wzgavxtqe53vxdsfk9k9pqh3whru


================================================
FILE: LICENSE
================================================
This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <https://unlicense.org>


================================================
FILE: README.md
================================================
<div align="center">

<img src="https://raw.githubusercontent.com/NixOS/nixos-artwork/376ed4ba8dc2e611b7e8a62fdc680967ead5bd87/logo/nix-snowflake.svg" align="center" width="100px" height="100px"/>

### My Infrastructure IaC

...Managed with NixOS :snowflake:&nbsp; and chezmoi :robot:&nbsp;

</div>

## :book:&nbsp; Overview

This repository contains my machine configurations in Infrastructure as Code style.
This is possible thanks to combination of [NixOS modules](https://nixos.wiki/NixOS_modules), [home-manager](https://github.com/nix-community/home-manager/), and [chezmoi](https://www.chezmoi.io/).

This repo is a [Nix Flake](https://nixos.wiki/wiki/Flakes) that you can import and use yourself but I don't recommend doing that.
You should take it as an inspiration for your infrastructure instead.

Please note that this is a Work In Progress, so stuffs may change without further notice and this README can get outdated.
My goal is to have everything as reproducible as possible.

For NixOS machines, everything is managed by NixOS modules and `home-manager`.
As for non NixOS machines, I use combination of `home-manager` and `chezmoi`.
I use `chezmoi` mainly to configure the system using [chezmoi scripts](https://www.chezmoi.io/user-guide/use-scripts-to-perform-actions/) while `home-manager` to configure applications in the userspace.

## :camera:&nbsp; Screenshots

**Sway**
![sway](https://user-images.githubusercontent.com/13085918/155890643-aa0adb3c-695f-497d-9d5d-d4bb61907cd0.png)

**Tmux**
![tmux](https://user-images.githubusercontent.com/13085918/155890745-5fc83821-8008-4f91-8ebc-5852badeca22.png)

**Fish prompt**
![fish](https://user-images.githubusercontent.com/13085918/155890660-57039ad8-d769-4044-ad38-a4b821c634e9.png)

**Neovim**
![nvim1](https://user-images.githubusercontent.com/13085918/155890675-a3b8b3f8-479c-4fd0-9ed6-c74e0fc4de0a.png)
![nvim2](https://user-images.githubusercontent.com/13085918/155890676-38b95046-c35d-4db5-aa01-b9d8ee44f9d0.png)

## :package:&nbsp; Modules

- [Flake Parts](https://github.com/hercules-ci/flake-parts) to manage `flakes` outputs.
- [home-manager](https://github.com/nix-community/home-manager) to manage my home directory.
- [sops-nix](https://github.com/Mic92/sops-nix) is used to encrypt/decrypt my secrets safely.
- [Disko](https://github.com/nix-community/disko) to declaratively manage disks.
- [NUR](https://github.com/nix-community/NUR) for packages not available in the official NixOS repository.
- [nixvim](https://github.com/nix-community/nixvim) to create reproducible Neovim package.

## :open_file_folder:&nbsp; Directory structure

The structure of this repository is highly opinionated.
I shamelessly took the pieces I believe is the best from people and modified it.

- [./flake.nix](./flake.nix) is the entrypoint for `nixos-rebuild` and `home-manager` commands.
- [./flake.lock](./flake.lock) is the lock file for this flake, updated daily by [budimanjojo-bot](https://github.com/apps/budimanjojo-bot) powered by [Renovate](https://github.com/renovatebot/renovate).
- [./flakeLib.nix](./flakeLib.nix) is where I put helper functions used in `flake.nix` file, this is where the magic happens.
- [./lib](./lib) is where I put helper functions used in NixOS and `home-manager` modules.
- [./packages](./packages) is where I put my own packages, updated daily by [budimanjojo-bot](https://github.com/apps/budimanjojo-bot) powered by [nvfetcher](https://github.com/berberman/nvfetcher).
- [./overlays](./overlays) contains overlays for packages used in NixOS and `home-manager` modules.
- [./shell.nix](./shell.nix) accessible via `nix develop` to have tools needed available in current shell.
- [./system](./system) contains my own NixOS modules and per machine system configurations.
- [./home](./home) contains my own `home-manager` modules and per user configurations.
- [./chezmoi](./chezmoi) contains files used by `chezmoi`.

## :inbox_tray:&nbsp; How do I bootstrap a new machine

### NixOS

- Clone this repository in a directory inside the machine.
- Edit `./flake.nix` file and add the new machine specs inside `outputs.flake.nixosConfigurations` schema.
- Create `./system/hosts/<hostname>/default.nix` for the new machine and configure it.
- Create `./home/budiman/hosts/<hostname>.nix` for the new machine and configure it.
- Run `git add .` then `sudo nixos-rebuild switch --flake .#<hostname>` and I'm done.

### Non NixOS

- Install Nix and enable Flake.
- Edit `./flake.nix` file and add the new machine specs inside `outputs.flake.homeConfigurations` schema.
- Create `./home/budiman/hosts/<hostname>.nix` for the new machine and configure it.
- Run `git add .` then `nix run nixpkgs.home-manager -c home-manager switch --flake .#budiman@<hostname>` and I'm done.

## :pencil:&nbsp; Neovim

My `neovim` setup is packaged with [nixvim](https://github.com/nix-community/nixvim) and exposed at `legacyPackages.neovim` from this flake.
You can run it directly if you have `nix` installed and `flakes` enabled with: `nix run github:budimanjojo/nix-config#neovim`.

## :fish:&nbsp; Fish

Fish is enabled using the `home-manager` module.

On my non NixOS machines, `fish` is patched to work without system intervention and I have a `chezmoi` script that will switch the default shell for the user to `~/.nix-profile/bin/fish`.

These are the plugins I'm using:

- [Starship](https://starship.rs/)
- [FZF Fish](https://github.com/patrickF1/fzf.fish)
- [Puffer Fish](https://github.com/nickeb96/puffer-fish)
- [autopair.fish](https://github.com/jorgebucaran/autopair.fish)
- [fish-abbreviation-tips](https://github.com/gazorby/fish-abbreviation-tips)

## :abcd:&nbsp; Fonts

Starship requires powerline fonts to work.
I suggest [Nerd-fonts](https://github.com/ryanoasis/nerd-fonts).
The font in the screenshot above is using UbuntuMono Nerd Font Regular.
Unifont is also for some glyphs to work.
On non NixOS machines, `home-manager` will install these fonts automatically.

## :scroll:&nbsp; Cheatsheet

### Sway/i3/Hyprland keybindings

I use `Super` key for Sway/i3.
`hjkl` keys are mapped to `left`, `down`, `up`, `right` arrow keys.
`S` means Super key, [0-9] means number key 0 to 9.

|    Keypress     | Description                                |
| :-------------: | :----------------------------------------- |
|      `S+t`      | Open terminal app                          |
|      `S+w`      | Open browser                               |
|      `S+f`      | Open file manager                          |
|    `S+grave`    | Open rofi apps menu                        |
|     `S+Esc`     | Open rofi apps menu                        |
|     `S+F4`      | Close window                               |
|      `S+k`      | Change focus to window above               |
|      `S+j`      | Change focus to window below               |
|      `S+h`      | Change focus to left side window           |
|      `S+l`      | Change focus to right side window          |
|   `S+Shift+k`   | Move focused window up                     |
|   `S+Shift+j`   | Move focused window down                   |
|   `S+Shift+h`   | Move focused window left                   |
|   `S+Shift+l`   | Move focused window right                  |
|   `S+Ctrl+h`    | Split opened windows horizontally          |
|   `S+Ctrl+v`    | Split opened windows vertically            |
|   `S+Ctrl+q`    | Toggle opened windows split                |
|     `S+Tab`     | Go to next workspace                       |
|  `S+Shift+Tab`  | Go to previous workspace                   |
|   `S+Ctrl+t`    | Toggle window border on/off                |
|   `S+Ctrl+g`    | Toggle gaps on/off                         |
|   `S+Ctrl+f`    | Toggle fullscreen mode on/off              |
|   `S+Ctrl+s`    | Change container layout to stacking        |
|   `S+Ctrl+w`    | Change container layout to tabbed          |
|   `S+Ctrl+e`    | Toggle split layout to horizontal/vertical |
| `S+Shift+Space` | Toggle window floating on/off              |
|    `S+Space`    | Swap focus between tiling/floating window  |
|   `S+Shift+p`   | Move current focused window to scratchpad  |
|      `S+p`      | Show/hide scratchpad window                |
|    `S+[0-9]`    | Go to workspace #[0-9]                     |
| `S+Shift+[0-9]` | Move focused window to workspace #[0-9]    |
|   `S+Shift+r`   | Go to resize container mode                |
|   `S+Shift+g`   | Go to resize gaps mode                     |
|  `S+Ctrl+Del`   | Go to logout mode                          |
|  `Printscreen`  | Go to screenshot mode                      |
|   `S+Shift+c`   | Reload configuration                       |
|   `S+Shift+e`   | Exit                                       |

### Neovim keybindings

The prefix key is `Space`.
You can override this using your custom `.vimrc.local` file.
`<Leader>` means you need to press prefix key first.
If they are not in the table, that means it's using the default Vim keybindings.

|      Mode       |   Keypress   | Description                             |
| :-------------: | :----------: | :-------------------------------------- |
|    `Normal`     | `<Leader>w`  | Save file                               |
|    `Normal`     | `<Leader>x`  | Save file and quit                      |
|    `Normal`     | `<Leader>qq` | Quit                                    |
|    `Normal`     | `<Leader>qa` | Force quit without saving               |
|    `Normal`     | `<Leader>wq` | Save file and quit                      |
|    `Normal`     |     `Y`      | Yank from cursor to end of file         |
|    `Normal`     | `Control+k`  | Move to the split window above          |
|    `Normal`     | `Control+j`  | Move to the split window below          |
|    `Normal`     | `Control+h`  | Move to the left split window           |
|    `Normal`     | `Control+l`  | Move to the right split window          |
|    `Normal`     | `<Leader>s`  | Open new horizontal split window        |
|    `Normal`     | `<Leader>v`  | Open new vertical split window          |
|    `Insert`     | `Control+k`  | Move cursor Up                          |
|    `Insert`     | `Control+j`  | Move cursor Down                        |
|    `Insert`     | `Control+h`  | Move cursor Left                        |
|    `Insert`     | `Control+l`  | Move cursor Right                       |
|    `Normal`     | `<Leader>tn` | Open new tab                            |
|    `Normal`     | `<Leader>td` | Close tab                               |
|    `Normal`     | `<Leader>th` | Go to previous tab                      |
|    `Normal`     | `<Leader>tl` | Go to next tab                          |
|    `Normal`     | `<Leader>te` | Open new tab with current buffer's path |
|    `Normal`     | `<Leader>hh` | Jump back to older cursor position      |
|    `Normal`     | `<Leader>ll` | Jump forward to newer cursor position   |
| `Normal/Visual` |    `Tab`     | Indent current line or selection        |
| `Normal/Visual` | `Shift+Tab`  | De-indent current line or selection     |
|    `Normal`     | `<Leader>lr` | Restart LSP client                      |
|    `Normal`     | `<Leader>fz` | Open Picker                             |
|    `Normal`     | `<Leader>ff` | Open Picker to find files               |
|    `Normal`     | `<Leader>fg` | Open Picker to live grep                |
|    `Normal`     | `<Leader>fc` | Open Picker to see git log              |
|    `Normal`     | `<Leader>fb` | Open Picker to see opened buffers       |
|    `Normal`     | `<Leader>fh` | Open Picker to find help                |
|    `Normal`     | `<Leader>fk` | Open Picker to see keymappings          |
|    `Normal`     | `<Leader>fe` | Open Picker to find lsp diagnostics     |
|    `Normal`     | `<Leader>xx` | Toggle Trouble                          |
|    `Normal`     | `<Leader>xr` | Toggle Trouble to find lsp references   |
|    `Normal`     | `Control+f`  | Toggle oil.nvim file manager            |
|  `Normal/Term`  | `Control+t`  | Toggle floating terminal                |
|    `Normal`     | `<Leader>pp` | Format buffer with null-ls              |
|    `Visual`     | `<Leader>pp` | Range format buffer with null-ls        |
|    `Normal`     |     `rn`     | Do LSP buffer rename                    |
|    `Normal`     |     `gd`     | Do LSP buffer get definition            |
|    `Normal`     |     `gD`     | Do LSP buffer get declaration           |
|    `Normal`     |     `gh`     | Do LSP buffer get hover                 |
|    `Normal`     |     `gr`     | Do LSP buffer get references            |
|    `Normal`     |     `gi`     | Do LSP buffer get implementation        |

### Tmux keybindings

I override the default keybindings for Tmux to be more reasonable.
Prefix key is `Alt+a` for local session and `Alt+z` for nested session.
`<prefix>` means you need to press prefix key first, `<repeat>` means you don't need to press prefix key again after triggering it (I use unconventional way instead of `-r` flag so it will stay forever unless I press `Esc` key), `<copy-mode>` means you must be in copy-mode first.
The table below lists all the keybindings set.

| Keypress              | Description                                                     |
| :-------------------: | :-------------------------------------------------------------- |
|`<prefix><repeat>h`    | Move selection to left pane                                     |
|`<prefix><repeat>j`    | Move selection to pane below                                    |
|`<prefix><repeat>k`    | Move selection to pane above                                    |
|`<prefix><repeat>l`    | Move selection to right pane                                    |
|`<prefix><repeat>H`    | Resize current pane to the left by 2 columns                    |
|`<prefix><repeat>J`    | Resize current pane downwards by 2 lines                        |
|`<prefix><repeat>K`    | Resize current pane upwards by 2 lines                          |
|`<prefix><repeat>L`    | Resize current pane to the right by 2 columns                   |
|`<prefix><repeat>Alt+n`| Move selection to next window                                   |
|`<prefix><repeat>Alt+p`| Move selection to previous window                               |
|`<prefix><repeat>>`    | Swap to next pane                                               |
|`<prefix><repeat><`    | Swap to previous pane                                           |
|`<prefix>Alt+s`        | Split window horizontally with current pane path                |
|`<prefix>Alt+v`        | Split window vertically with current pane path                  |
|`<prefix>c`            | Open a new window with current pane path                        |
|`<prefix>Esc`          | Exit prefix key table                                           |
|`<prefix>Space`        | Exit prefix key table                                           |
|`<prefix>a`            | Enter copy mode                                                 |
|`<prefix>:`            | Enter tmux command prompt                                       |
|`<prefix>x`            | Close current pane                                              |
|`<prefix>X`            | Close current window                                            |
|`<copy-mode>b`         | Move cursor to word beginning                                   |
|`<copy-mode>e`         | Move cursor to word ending                                      |
|`<copy-mode>Home`      | Move cursor to start of line                                    |
|`<copy-mode>0`         | Move cursor to start of line                                    |
|`<copy-mode>End`       | Move cursor to end of line                                      |
|`<copy-mode>$`         | Move cursor to end of line                                      |
|`<copy-mode>PageUp`    | Move cursor one page up                                         |
|`<copy-mode>PageDn`    | Move cursor one page down                                       |
|`<copy-mode>v`         | Begin selection                                                 |
|`<copy-mode>Space`     | Begin selection                                                 |
|`<copy-mode>V`         | Select a line                                                   |
|`<copy-mode>Alt+v`     | Toggle box selection                                            |
|`<copy-mode>y`         | Copy selection to clipboard                                     |
|`<copy-mode>Y`         | Copy from cursor to end of line to clipboard                    |
|`<copy-mode>Esc`       | Exit copy mode                                                  |
|`<copy-mode>q`         | Exit copy mode                                                  |

### Zellij keybindings

I'm migrating my tmux to [Zellij](https://zellij.dev/).
I mimicked my tmux configuration to work in zellij but not everything works the same.
Prefix key is `Alt+a`, I use the "switch to normal mode" in zellij to achieve this.
`<normal>` means you need to be in normal mode, `<pane>` means pane mode, and so on.
The table below lists all the keybindings set.

|        Keypress        | Description                                                |
| :--------------------: | :--------------------------------------------------------- |
|    `<locked>Alt+a`     | Swith to normal mode (act like prefix key in tmux)         |
|    `<normal>Alt+s`     | Create new horizontal split window and back to locked mode |
|    `<normal>Alt+v`     | Create new vertical split window and back to locked mode   |
|      `<normal>r`       | Switch to renametab mode                                   |
|      `<normal>h`       | Move selection to left pane                                |
|      `<normal>j`       | Move selection to pane below                               |
|      `<normal>k`       | Move selection to pane above                               |
|      `<normal>l`       | Move selection to right pane                               |
|      `<normal>>`       | Move pane around                                           |
|      `<normal>H`       | Resize current pane upwards                                |
|      `<normal>J`       | Resize current pane downwards                              |
|      `<normal>H`       | Resize current pane to the left                            |
|      `<normal>L`       | Resize current pane to the right                           |
|    `<normal>Alt+n`     | Go to next window                                          |
|    `<normal>Alt+p`     | Go to previous window                                      |
|      `<normal>c`       | Open new tab and back to locked mode                       |
|      `<normal>x`       | Close current pane and back to locked mode                 |
|      `<normal>a`       | Open pane with $EDITOR and back to locked mode             |
| `<normal>Esc/' '/"\n"` | Switch back to locked mode                                 |
|   `<renametab>Alt+a`   | Switch to normal mode                                      |
|   `<renametab>"\n"`    | Switch to locked mode                                      |
|    `<renametab>Esc`    | Confirm tab name and back to locked mode                   |

## :coffee:&nbsp; Acknowledgements

I wrote most of the codes by myself, but there are a lot of stuffs inspired by these repositories.

- [MatthiasBenaets/nixos-config](https://github.com/MatthiasBenaets/nixos-config) for the awesome YouTube video introducing NixOS to me.
- [viperML/dotfiles](https://github.com/viperML/dotfiles) for answering stupid questions on Discord.
- [bjw-s/nix-config](https://github.com/bjw-s/nix-config) for being inspiration for my repo structure.
- [truxnell/nix-config](https://github.com/truxnell/nix-config) for being inspiration for my flakeLib functions.


================================================
FILE: chezmoi/.chezmoi.yaml.tmpl
================================================
{{- /* Checks if running interactively */ -}}
{{- $interactive := stdinIsATTY -}}

{{- /* Template file for chezmoi config file */ -}}
{{- $headless := false -}}{{/* true if this machine does not have a screen and keyboard */}}
{{- $agekey := false -}}{{/* true if this machine has agekey to decrypt secret */}}

{{- $hostname := .chezmoi.hostname -}}
{{- if eq $hostname "budimanjojo-main" -}}
{{-   $headless = false -}}
{{-   $agekey = true -}}
{{- end -}}
{{- if eq $hostname "budimanjojo-ubuntu" -}}
{{-   $headless = false -}}
{{-   $agekey = true -}}
{{- end -}}
{{- if hasKey . "headless" -}}
{{-   $headless = .headless -}}
{{- else if $interactive -}}
{{-   $headless = promptBool "headless" -}}
{{- end -}}
{{- if hasKey . "agekey" -}}
{{-   $agekey = .agekey -}}
{{- else if $interactive -}}
{{-   $agekey = promptBool "agekey" -}}
{{- end -}}

{{- if $interactive -}}
{{-   writeToStdout "💡 Tip: you can re-enter your data with `chezmoi init --data=false`.\n" -}}
{{- end -}}

data:
  headless: {{ $headless }}
  agekey: {{ $agekey }}
format: yaml
encryption: age
{{- if $agekey }}
age:
  identity: /home/budiman/.config/sops/age/keys.txt
  recipient: age1zeqkpfz7e3s207ynea0z0auc0mrct0pc7w4sh6j3d0c4qac3dahqj9ufdg
{{- end }}
merge:
  command: nvim
  args:
    - -d
    - "{{ "{{ .Destination }}" }}"
    - "{{ "{{ .Source }}" }}"
    - "{{ "{{ .Target }}" }}"
git:
  autoAdd: true


================================================
FILE: chezmoi/.chezmoiignore
================================================
{{- if .headless }}
.config/alacritty/
.config/kitty/
.config/termite/
.config/wezterm/
{{- end }}


================================================
FILE: chezmoi/.chezmoiscripts/run_once_after_90-cleanup.sh.tmpl
================================================
#!/bin/bash

echo -e "\033[0;32m>>>>> Begin Executing Cleanup Job <<<<<\033[0m"

# This script will ensure that I fixes changes I have made in the past
# For example, I used to install stuffs in /usr/local/bin but now I'm not anymore
# So this script will make sure I cleaned up my old unused stuffs

set -eufo pipefail

function not_needed_executable () {
  local dir=$2
  local path=$dir/$1
  local current_path
  current_path=$(command -v "$1" || echo "notfound")

  if [ "$current_path" == "notfound" ]; then
    echo "\"$1\" not found, skip deleting"
    return
  fi

  if [ "$current_path" != "$path" ] && [ -f "$path" ]; then
    if [ "$EUID" -ne 0 ]; then
      sudo rm "$path"
      echo "deleted $path, not needed anymore"
    else
      rm "$path"
      echo "deleted $path, not needed anymore"
    fi
  fi
}

function not_needed_directory () {
  local dir=$1
  if [ -d "$dir" ]; then
    if [ "$EUID" -ne 0 ]; then
      sudo rm -rf "$dir"
      echo "deleted $dir directory, not needed anymore"
    else
      rm -rf "$dir"
      echo "deleted $dir directory, not needed anymore"
    fi
  fi
}

function not_needed_file() {
  local file=$1
  if [ -f "$file" ]; then
    if [ "$EUID" -ne 0 ]; then
      sudo rm "$file"
      echo "deleted $file, not needed anymore"
    else
      rm "$file"
      echo "deleted $file, not needed anymore"
    fi
  fi
}

not_needed_executable "kubectl" "{{ .chezmoi.homeDir }}/.local/bin"
not_needed_executable "flux" "{{ .chezmoi.homeDir }}/.local/bin"
not_needed_executable "kustomize" "/usr/local/bin"
not_needed_executable "sops" "/usr/local/bin"
not_needed_executable "fzf" "/usr/local/bin"
not_needed_executable "starship" "/usr/local/bin"
not_needed_executable "zoxide" "/usr/local/bin"
not_needed_executable "rg" "/usr/local/bin"
not_needed_executable "fd" "/usr/local/bin"
not_needed_executable "bat" "/usr/local/bin"
not_needed_executable "age" "/usr/local/bin"
not_needed_executable "age-keygen" "/usr/local/bin"
not_needed_executable "chezmoi" "{{ .chezmoi.homeDir }}/.local/bin"
not_needed_executable "node" "/usr/local/bin"

not_needed_directory "{{ .chezmoi.homeDir }}/.local/share/nvim/lsp_servers"
not_needed_directory "{{ .chezmoi.homeDir }}/.local/share/aquaproj-aqua"
not_needed_directory "{{ .chezmoi.homeDir }}/.local/share/fonts/UbuntuMono"
not_needed_directory "{{ .chezmoi.homeDir }}/.local/share/fonts/Hack"
not_needed_directory "{{ .chezmoi.homeDir }}/.local/share/fonts/unifont"
not_needed_directory "{{ .chezmoi.homeDir }}/.local/share/fonts/unifont_upper"

not_needed_file "{{ .chezmoi.homeDir }}/.config/fish/conf.d/nix.fish"

if [ "$(command -v brew)" ]; then
  echo "uninstalling brew"
  /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)"
fi

echo -e "\033[0;32m>>>>> Finish Executing Cleanup Job<<<<<\033[0m"


================================================
FILE: chezmoi/.chezmoiscripts/run_once_before_10-setup-fish.sh.tmpl
================================================
{{ if (eq .chezmoi.os "linux") -}}
#!/bin/bash
set -eufo pipefail

echo -e "\0033[0;32m>>>>> Begin Setting Up Fish Shell <<<<<\033[0m"

set_default_shell() {
  local expected_default="{{ .chezmoi.homeDir }}/.nix-profile/bin/fish"
  local current_default

  current_default=$(grep "^{{ .chezmoi.username }}:" /etc/passwd | cut -d: -f7)

  if [ ! -x "$expected_default" ]; then
    echo "No fish binary found in $expected_default, skip changing default shell"
    return
  fi

  if [ "$current_default" != "$expected_default" ]; then
    echo "Changing default shell to fish"
    if ! grep -wq "$expected_default" /etc/shells; then
      echo "Adding $expected_default to /etc/shells"
      echo "$expected_default" | sudo tee -a /etc/shells >/dev/null
    fi
    chsh -s "$expected_default"
  fi
}

# Set fish as default shell
set_default_shell

echo -e "\0033[0;32m>>>>> Finish Setting Up Fish Shell <<<<<\033[0m"
{{ end -}}


================================================
FILE: chezmoi/.chezmoiscripts/run_once_before_20-install-packages-archlinux.sh.tmpl
================================================
{{ if (eq .chezmoi.osRelease.id "arch") -}}
#!/bin/bash

set -eufo pipefail

echo -e "\033[0;32m>>>>> Begin Setting Up Arch Linux Packages <<<<<\033[0m"

packages=(
  curl
  luajit
  npm
  unzip
)

aur_packages=(
)

{{   if (not .headless) -}}
packages+=(
  wezterm
)
{{   end -}}

echo "updating packages"
{{   if ne .chezmoi.username "root" -}}
sudo pacman -Syu --noconfirm
{{   else -}}
pacman -Syu --noconfirm
{{   end -}}

for package in ${packages[@]}; do
  if [ "$(pacman -Qq $package 2> /dev/null)" != $package ]; then
    echo "installing $package"
{{-   if ne .chezmoi.username "root" }}
    sudo pacman -S --noconfirm $package
{{-   else }}
    pacman -S --noconfirm $package
{{-   end }}
  fi
done

## Install yay
if [ ! $(command -v yay) ]; then
  echo "installing yay"
{{-   if ne .chezmoi.username "root" }}
  sudo pacman -S --needed --noconfirm git base-devel
{{-   else}}
  pacman -S --needed --noconfirm git base-devel
{{-   end }}
  git clone https://aur.archlinux.org/yay.git /tmp/yay
  cd /tmp/yay
  makepkg -si --noconfirm
  rm -rf /tmp/yay
fi

for aur_package in ${aur_packages[@]}; do
  if [ $(pacman -Qq $aur_package 2> /dev/null) != $aur_package ]; then
    echo "installing $aur_package from AUR"
    yay -S --noconfirm $aur_package
  fi
done

echo -e "\033[0;32m>>>>> Finish Setting Up Arch Linux Packages <<<<<\033[0m"
{{ end -}}


================================================
FILE: chezmoi/.chezmoiscripts/run_once_before_20-install-packages-ubuntu.sh.tmpl
================================================
{{ if (and (eq .chezmoi.os "linux") (eq .chezmoi.osRelease.id "debian" "ubuntu")) -}}
#!/bin/bash

set -eufo pipefail

echo -e "\033[0;32m>>>>> Begin Setting Up Ubuntu Packages <<<<<\033[0m"

# List of ppa repositories to add
repositories=(
)

# List of packages to install
packages=(
  curl
  unzip
)

# List of snap packages to install
snaps=()

for repository in ${repositories[@]}; do
  ppa_repo_source=${repository#ppa:}
  if ! $(apt-cache policy | grep http | awk '{print $2}' | sort -u | grep $ppa_repo_source &> /dev/null); then
    echo "adding $repository repository to apt"
{{ if ne .chezmoi.username "root" -}}
    sudo add-apt-repository -y $repository
{{ else -}}
    add-apt-repository -y $repository
{{ end -}}
    echo "false"
  fi
done

for package in ${packages[@]}; do
  if ! $(dpkg-query -W -f='installed' $package &> /dev/null); then
    echo "installing $package"
{{ if ne .chezmoi.username "root" -}}
    sudo apt install -y $package
{{ else -}}
    apt install -y ${packages[@]}
{{ end -}}
  fi
done

# renovate: depName=wez/wezterm datasource=github-releases
current_wezterm_version=20240203-110809-5046fc22

if [ ! $(command -v wezterm) ] || [ $(wezterm -V | head -n1 | cut -d" " -f2) != "$current_wezterm_version" ]; then
  echo "installing / upgrading wezterm"
  curl -Lo /tmp/wezterm https://github.com/wez/wezterm/releases/download/"$current_wezterm_version"/WezTerm-"$current_wezterm_version"-Ubuntu20.04.AppImage
  chmod +x /tmp/wezterm
  mv /tmp/wezterm {{ .chezmoi.homeDir }}/.local/bin/wezterm
fi

{{ if (eq .chezmoi.osRelease.id "ubuntu") -}}
for snap in ${snaps[@]}; do
  echo "installing $snap using snap"
{{   if ne .chezmoi.username "root" -}}
  sudo snap install $snap
{{   else -}}
  snap install $snap
{{   end -}}
done
{{ end -}}

echo -e "\033[0;32m>>>>> Finish Setting Up Ubuntu Packages <<<<<\033[0m"
{{ end -}}


================================================
FILE: chezmoi/.chezmoiscripts/run_onchange_after_80-setup-terminal.sh.tmpl
================================================
{{ if (and (eq .chezmoi.os "linux") (eq .chezmoi.osRelease.id "debian" "ubuntu")) -}}
#!/bin/bash

echo -e "\033[0;32m>>>>> Begin Setting Up Nix Applications <<<<<\033[0m"

set -eufo pipefail

# This script will ensure the applications installed by Nix is known by the OS
# So `update-alternatives` program used by Debian based OS to open program can work properly

# Run this script whenever the content of the host configuration for this machine changes
# {{ include (print "../" "/home/" .chezmoi.username "/hosts/" .chezmoi.hostname ".nix") | sha256sum }}

function add_nix_app_to_update_alternative() {
  local program="{{ .chezmoi.homeDir }}/.nix-profile/bin/$1"
  local priority=$2
  local to_link="${3:-x-terminal-emulator}"

  local found
  found=$(update-alternatives --quiet --list "$to_link" | grep -x "$program" || true)

  # if program is not installed, proceed to remove it from the list
  # this is not really an efficient approach but there's no way to get `update-alternatives` to show binary that doesn't exist
  if [[ ! -x "$program" ]]; then
    sudo update-alternatives --quiet --remove "$to_link" "$program"
    return
  fi

  if [[ -n "$found" ]]; then
    local cur_priority
    cur_priority="$(update-alternatives --quiet --display "$to_link" | sed -n "s|^$program - priority \([0-9]\+\)$|\1|p")"
    if [ "$cur_priority" != "$priority" ]; then
      echo "updating $program priority as $to_link from $cur_priority to $priority"
      sudo update-alternatives --install "$(which "$to_link")" "$to_link" "$program" "$priority"
      return
    fi
  else
    echo "installing $program as $to_link with priority of $priority"
    sudo update-alternatives --install "$(which "$to_link")" "$to_link" "$program" "$priority"
    return
  fi
}

add_nix_app_to_update_alternative "contour" "9999"
add_nix_app_to_update_alternative "alacritty" "9998"
add_nix_app_to_update_alternative "kitty" "9997"
add_nix_app_to_update_alternative "wezterm" "9996"

echo -e "\033[0;32m>>>>> Finish Setting Up Nix Applications <<<<<\033[0m"
{{ end -}}


================================================
FILE: chezmoi/dot_config/fontconfig/fonts.conf.tmpl
================================================
{{ if eq .chezmoi.hostname "budimanjojo-main" -}}
<fontconfig>
<alias>
    <family>serif</family>
    <prefer>
        <family>Hack Nerd Font Mono</family>
        <family>Ubuntu Nerd Font</family>
    </prefer>
</alias>
<alias>
    <family>sans-serif</family>
    <prefer>
        <family>Hack Nerd Font Mono</family>
        <family>Ubuntu Nerd Font</family>
    </prefer>
</alias>
<alias>
    <family>sans</family>
    <prefer>
        <family>Hack Nerd Font Mono</family>
        <family>Ubuntu Nerd Font</family>
    </prefer>
</alias>
<alias>
    <family>monospace</family>
    <prefer>
        <family>Hack Nerd Font Mono</family>
        <family>Ubuntu Nerd Font</family>
    </prefer>
</alias>
<match target="font">
    <edit name="hinting" mode="assign">
        <bool>true</bool>
    </edit>
    <edit name="hintstyle" mode="assign">
        <const>hintslight</const>
    </edit>
    <edit name="antialias" mode="assign">
        <bool>true</bool>
    </edit>
    <edit name="autohint" mode="assign">
        <bool>true</bool>
    </edit>
    <edit name="embeddedbitmap" mode="assign">
        <bool>false</bool>
    </edit>
</match>
</fontconfig>
{{ end -}}


================================================
FILE: chezmoi/dot_config/termite/config
================================================
[options]
#allow_bold = true
#audible_bell = false
#bold_is_bright = true
#cell_height_scale = 1.0
#cell_width_scale = 1.0
#clickable_url = true
#dynamic_title = true
font = UbuntuMono Nerd Font 12
# font = Hack Nerd Font Mono 12
#fullscreen = true
#icon_name = terminal
#mouse_autohide = false
#scroll_on_output = false
#scroll_on_keystroke = true
# Length of the scrollback buffer, 0 disabled the scrollback buffer
# and setting it to a negative value means "infinite scrollback"
scrollback_lines = 10000
#search_wrap = true
#urgent_on_bell = true
#hyperlinks = false

# $BROWSER is used by default if set, with xdg-open as a fallback
#browser = xdg-open

# "system", "on" or "off"
#cursor_blink = system

# "block", "underline" or "ibeam"
#cursor_shape = block

# Hide links that are no longer valid in url select overlay mode
#filter_unmatched_urls = true

# Emit escape sequences for extra modified keys
#modify_other_keys = false

# set size hints for the window
#size_hints = false

# "off", "left" or "right"
#scrollbar = off

[colors]
# If both of these are unset, cursor falls back to the foreground color,
# and cursor_foreground falls back to the background color.
#cursor = #dcdccc
#cursor_foreground = #dcdccc

foreground = #C0CAF5
#foreground_bold = #ffffff
background = #1A1B26

# 20% background transparency (requires a compositor)
background = rgba(29, 31, 33, 0.9)

# If unset, will reverse foreground and background
# highlight = #2f2f2f

# Colors from color0 to color254 can be set
color0 = #15161E
color1 = #F7768E
color2 = #9ECE6A
color3 = #E0AF68
color4 = #7AA2F7
color5 = #BB9AF7
color6 = #7DCFFF
color7 = #A9B1D6
color8 = #414868
color9 = #F7768E
color10 = #9ECE6A
color11 = #E0AF68
color12 = #7AA2F7
color13 = #BB9AF7
color14 = #7DCFFF
color15 = #C0CAF5

[hints]
#font = Monospace 12
#foreground = #dcdccc
#background = #3f3f3f
#active_foreground = #e68080
#active_background = #3f3f3f
#padding = 2
#border = #3f3f3f
#border_width = 0.5
#roundness = 2.0

# vim: ft=dosini cms=#%


================================================
FILE: flake.nix
================================================
{
  description = "My NixOS configurations IaC";

  inputs = {
    # nixpkgs and unstable
    nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
    nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";

    # flake-parts - very lightweight flake framework
    # https://flake.parts
    flake-parts.url = "github:hercules-ci/flake-parts";

    # home-manager - home user modules
    # https://github.com/nix-community/home-manager
    home-manager = {
      url = "github:nix-community/home-manager/release-25.11";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    # sops-nix - secrets with `sops`
    # https://github.com/Mic92/sops-nix
    sops-nix = {
      url = "github:Mic92/sops-nix";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    # Disko - declarative disk partitioning and formatting
    # https://github.com/nix-community/disko
    disko = {
      url = "github:nix-community/disko";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    # NUR - Nix User Repository
    # https://github.com/nix-community/NUR
    nur.url = "github:nix-community/NUR";

    # nvfetcher - tool to automate nix packages updates
    # https://github.com/berberman/nvfetcher
    nvfetcher = {
      url = "github:berberman/nvfetcher";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    # nixvim - Neovim distribution built around Nix modules
    # https://github.com/nix-community/nixvim
    nixvim = {
      url = "github:nix-community/nixvim/nixos-25.11";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    # Talhelper - A tool to help creating Talos Kubernetes cluster
    # https://github.com/budimanjojo/talhelper
    talhelper = {
      url = "github:budimanjojo/talhelper";
    };

    # Catppuccin for Nix - Soothing pastel theme for Nix
    # https://github.com/catppuccin/nix
    catppuccin.url = "github:catppuccin/nix/release-25.11";

    # nixGL - A wrapper tool for nix OpenGL application
    # https://github.com/nix-community/nixGL
    nixgl = {
      url = "github:nix-community/nixGL";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    # tdarr-plugins - My Tdarr plugins repo fork
    # https://github.com/budimanjojo/tdarr-plugins
    tdarr-plugins = {
      url = "github:budimanjojo/tdarr-plugins";
      flake = false;
    };

    # cache-nix-action - Cache Nix Store in GitHub Actions
    # https://github.com/nix-community/cache-nix-action
    cache-nix-action = {
      url = "github:nix-community/cache-nix-action";
      flake = false;
    };
  };

  outputs =
    { flake-parts, ... }@inputs:
    let
      # function to make `pkgs` for defined system with my overlays
      mkPkgsWithSystem =
        system:
        let
          localSystem = system;
          config = {
            allowUnfree = true;
            allowUnfreePredicate = _: true;
          };
        in
        import inputs.nixpkgs {
          inherit localSystem config;
          overlays = builtins.attrValues (import ./overlays { inherit inputs config; });
        };

      flakeLib = import ./flakeLib.nix { inherit inputs mkPkgsWithSystem; };
    in
    inputs.flake-parts.lib.mkFlake { inherit inputs; } {
      # systems for which you want to build the `perSystem` attributes
      systems = [
        "x86_64-linux"
        "aarch64-linux"
      ];

      # everything below `perSystem` will be enumerated and have `${system}`
      # added in the middle by `flake-parts`
      perSystem =
        {
          system,
          inputs',
          self',
          pkgs,
          ...
        }:
        {
          # override pkgs used by everything in `perSystem` to have my overlays
          _module.args.pkgs = mkPkgsWithSystem system;
          # accessible via `nix fmt` to format code
          formatter = pkgs.nixfmt-rfc-style;
          # accessible via `nix build .#<name>`
          legacyPackages = import ./packages { inherit inputs' self' pkgs; };
          packages = {
            # this is for cache-nix-action so stuffs don't get garbage collected
            # before I cache the nix store, mostly to not redownload inputs a lot
            gc-keep =
              (import "${inputs.cache-nix-action}/saveFromGC.nix" {
                inherit pkgs inputs;
                inputsInclude = [
                  "nixpkgs"
                  "nixpkgs-unstable"
                  "flake-parts"
                  "home-manager"
                  "sops-nix"
                  "disko"
                  "nur"
                  "nvfetcher"
                  "nixvim"
                  "talhelper"
                  "catppuccin"
                  "nixgl"
                ];
              }).package;
          };
          # accessible via `nix develop`
          devShells.default = import ./shell.nix { inherit inputs' pkgs; };
        };

      # all the other flake outputs those don't require `${system}`
      # string will be here and handled by `flake-parts`
      flake = rec {
        ghActions.matrix = flakeLib.mkGithubMatrix {
          inherit nixosConfigurations homeConfigurations;
        };

        nixosConfigurations = {
          # this is a NixOS live CD that has SSH enabled and some of my stuffs baked in
          # build with `nix build .#nixosConfigurations.nixos-livecd.config.system.build.isoImage`
          nixos-livecd = flakeLib.mkSystem {
            hostname = "nixos-livecd";
            homeUsers = [ ];
            baseModules = [ ./system/hosts ];
            extraModules = [
              { config.ghMatrix.enable = false; }
            ];
          };
          budimanjojo-main = flakeLib.mkSystem {
            hostname = "budimanjojo-main";
          };
          budimanjojo-nas = flakeLib.mkSystem {
            hostname = "budimanjojo-nas";
            extraModules = [ inputs.disko.nixosModules.disko ];
          };
          budimanjojo-firewall = flakeLib.mkSystem {
            hostname = "budimanjojo-firewall";
            extraModules = [ inputs.disko.nixosModules.disko ];
          };
          # this is my Oracle always free instance that I use as my WireGuard relay server
          # so my firewall can live behind a NAT and be fine in case I switch to a different
          # ISP that doesn't give me public routeable IP
          budimanjojo-oracle = flakeLib.mkSystem {
            hostname = "budimanjojo-oracle";
            system = "aarch64-linux";
          };
        };

        homeConfigurations = {
          "budiman@budimanjojo-ubuntu" = flakeLib.mkHome {
            hostname = "budimanjojo-ubuntu";
            system = "x86_64-linux";
          };
        };

      };
    };
}


================================================
FILE: flakeLib.nix
================================================
{ inputs, mkPkgsWithSystem }:
let
  # my own custom lib will be accessible with `lib.myLib.<name>`
  lib = inputs.nixpkgs.lib.extend (final: prev: { myLib = import ./lib { lib = final; }; });

  # This module is passed to all `nixosConfigurations` and `homeConfigurations` so I can
  # specify whether a machine should be built and pushed on CI or not
  ghMatrixModules =
    {
      config,
      lib,
      pkgs,
      ...
    }:
    let
      cfg = config.ghMatrix;
      inherit (lib) mkOption types;

      defaultRunners = {
        x86_64-linux = "ubuntu-24.04";
        aarch64-linux = "ubuntu-24.04-arm";
        x86_64-darwin = "macos-13";
        aarch64-darwin = "macos-14";
      };
    in
    {
      options.ghMatrix = {
        enable = mkOption {
          type = types.bool;
          default = true;
        };
        system = mkOption {
          type = types.str;
          default = pkgs.stdenv.hostPlatform.system;
          readOnly = true;
        };
        runner = mkOption {
          type = types.oneOf [
            types.str
            (types.listOf types.str)
          ];
          default = defaultRunners.${cfg.system};
        };
      };
    };
in
{
  mkGithubMatrix =
    {
      nixosConfigurations ? { },
      homeConfigurations ? { },
    }:
    let
      matrixSet = name: cfg: {
        system = cfg.config.ghMatrix.system;
        runner = cfg.config.ghMatrix.runner;
        attrset =
          if cfg.config ? system && cfg.config.system ? build then
            "nixosConfigurations.${name}.config.system.build.toplevel"
          else if cfg ? activationPackage then
            "homeConfigurations.${name}.activationPackage"
          else
            throw "${name} is neither `nixosConfigurations` or `homeConfigurations`";
      };

      filterAttr = attr: lib.filterAttrs (n: v: v.config.ghMatrix.enable) attr;
      mkList = attr: cfgs: builtins.attrValues (builtins.mapAttrs attr cfgs);
      result.include = mkList matrixSet (filterAttr (nixosConfigurations // homeConfigurations));
    in
    result;

  mkSystem =
    {
      hostname,
      adminUser ? "budiman", # default user to login with `sudo` access
      system ? "x86_64-linux",
      nixpkgs ? inputs.nixpkgs,
      # myPkgs defaulted to the `legacyPackages` from this flake
      myPkgs ? inputs.self.legacyPackages.${system},
      # homeUsers is list of home-manager users for the host
      # each user needs a `./home-manager/<name>/default.nix` file present
      # set it to empty list to disable home-manager altogether for the host
      homeUsers ? [ adminUser ],
      # baseModules is the base of the entire machine building
      baseModules ? [
        inputs.sops-nix.nixosModules.sops
        inputs.home-manager.nixosModules.home-manager
        inputs.catppuccin.nixosModules.catppuccin
        ./system/_modules # all machines get my own NixOS modules
        ./system/hosts # entrypoint to all machines
        {
          config = {
            mySystem = {
              adminUser = adminUser;
            };
          };
        }
      ],
      # extraModules is additional modules you want to add for the host
      extraModules ? [ ],
    }:
    let
      mkHomeUsers = lib.optionals (homeUsers != [ ]) [
        {
          config.home-manager = {
            users = builtins.listToAttrs (
              builtins.map (name: {
                name = name;
                value = {
                  imports = [ ./home/${name} ];
                  config.myHome = {
                    username = name;
                  };
                };
              }) homeUsers
            );
            useGlobalPkgs = true;
            useUserPackages = true;
            extraSpecialArgs = {
              inherit inputs myPkgs hostname;
            };
            sharedModules = [
              inputs.sops-nix.homeManagerModules.sops
              inputs.catppuccin.homeModules.catppuccin
              ./home/_modules # all users get my own home-manager modules
            ];
          };
        }
      ];
    in
    nixpkgs.lib.nixosSystem {
      inherit system lib;
      pkgs = mkPkgsWithSystem system;
      specialArgs = {
        inherit
          inputs
          myPkgs
          hostname
          ;
      };
      modules = baseModules ++ extraModules ++ mkHomeUsers ++ [ ghMatrixModules ];
    };

  mkHome =
    {
      hostname,
      username ? "budiman",
      system ? "x86_64-linux",
      nixpkgs ? inputs.nixpkgs,
      # myPkgs defaulted to the `legacyPackages` from this flake
      myPkgs ? inputs.self.legacyPackages.${system},
    }:
    inputs.home-manager.lib.homeManagerConfiguration {
      inherit lib;
      pkgs = mkPkgsWithSystem system;
      extraSpecialArgs = {
        inherit
          inputs
          myPkgs
          hostname
          ;
        # need to have this because a lot of my modules depends on `osConfig` argument
        osConfig = { };
      };
      modules = [
        inputs.sops-nix.homeManagerModules.sops
        inputs.catppuccin.homeModules.catppuccin
        ./home/_modules # all users get my own home-manager modules
        {
          imports = [ ./home/${username} ];
          config.myHome.username = username;
        }
        ghMatrixModules
      ];
    };
}


================================================
FILE: home/_modules/_default/default.nix
================================================
{ config, ... }:
let
  myHome = config.myHome;
in
{
  imports = [
    ./nix.nix
    ./sops.nix
  ];

  config = {
    home = {
      username = myHome.username;
      homeDirectory = "/home/" + myHome.username;
      stateVersion = "23.11";
    };

    programs.home-manager.enable = true;

    catppuccin = {
      flavor = "mocha";
      accent = "mauve";
    };
  };
}


================================================
FILE: home/_modules/_default/nix.nix
================================================
{
  lib,
  osConfig,
  pkgs,
  inputs,
  ...
}:
let
  isNixos = lib.myLib.isNixos osConfig;
in
{
  # only enable when we are not on NixOS
  nix = lib.mkIf (!isNixos) {
    package = pkgs.nix;
    registry = {
      stable.flake = inputs.nixpkgs;
      unstable.flake = inputs.nixpkgs-unstable;
    };

    gc.automatic = true;

    settings = {
      nix-path = "nixpkgs=${inputs.nixpkgs.outPath}";
      extra-substituters = [ "https://budimanjojo.cachix.org" ];
      trusted-substituters = [ "https://budimanjojo.cachix.org" ];
      extra-trusted-public-keys = [
        "budimanjojo.cachix.org-1:S0gy6IKTFXis9fFqEbVAS2zsvnZw/30NV2bWvGiN1YQ="
      ];
      experimental-features = [
        "nix-command"
        "flakes"
      ];
      auto-optimise-store = true;
      keep-outputs = true;
      keep-derivations = false;
      cores = 0;
      max-jobs = "auto";
    };
  };
}


================================================
FILE: home/_modules/_default/sops.nix
================================================
{
  lib,
  osConfig,
  pkgs,
  config,
  ...
}:
let
  isNixos = lib.myLib.isNixos osConfig;
in
{
  config = {
    home.packages = lib.mkIf (!isNixos) [
      pkgs.sops
      pkgs.age
    ];
    sops.age = {
      keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
      generateKey = true; # generate the key if it doesn't exist
    };
  };
}


================================================
FILE: home/_modules/browser/firefox/default.nix
================================================
{
  config,
  lib,
  pkgs,
  options,
  ...
}:
let
  inherit (lib)
    getExe
    mkOption
    types
    mkPackageOption
    mkIf
    ;

  cfg = config.myHome.browser.firefox;
  rofiExe = getExe config.programs.rofi.package;
  firefoxExe = getExe config.programs.firefox.package;

  # need a wrapper to replace Firefox profile manager
  # https://github.com/nix-community/home-manager/issues/3117
  rofiWrapper = pkgs.writeShellScriptBin "rofi-firefox-wrapper" ''
    cfgFile=$HOME/.mozilla/firefox/profiles.ini

    if test -f "$cfgFile"; then
      i=0
      profiles=$(grep 'Name' "$cfgFile" | sed 's/Name=//g')

      while read -r; do
        i=$((i+1))
      done < <(echo "$profiles")

      if [ $i -gt 1 ]; then
        options=$(echo "$profiles" | sed ':a; N; $!ba; s/\n/\\n/g')
        chosen=$(echo -e "$options" | ${rofiExe} -dmenu -P "Select Firefox Profile")
        if [ "$chosen" != "" ]; then
          ${firefoxExe} -P "$chosen"
        fi
      else
        ${firefoxExe}
      fi
    else
      ${firefoxExe}
    fi
  '';
in
{
  options.myHome.browser.firefox = {
    enable = mkOption {
      type = types.bool;
      default = false;
      description = ''
        Enable Firefox Web Browser.
        This module include a wrapper that will open up `rofi` profile selector when you have more than one profile or open Firefox normally otherwise.

        The wrapper can be accessed by pressing `Super+W` on the keyboard in i3, Hyprland, and Sway window manager.
      '';
    };
    package = mkPackageOption pkgs "firefox" { };
    profiles = mkOption {
      type = options.programs.firefox.profiles.type;
      default = {
        "" = {
          id = 0;
          name = "${config.myHome.username}";
          isDefault = true;
        };
      };
    };
  };

  config = mkIf (cfg.enable) {
    programs.firefox = {
      enable = true;
      package = cfg.package;
      profiles = cfg.profiles;
    };

    wayland.windowManager = {
      hyprland.settings.bind = [ "SUPER, w, exec, ${getExe rofiWrapper}" ];
      sway.config.keybindings."Mod4+w" = "exec --no-startup-id ${getExe rofiWrapper}";
    };

    xsession.windowManager.i3.config.keybindings."Mod4+w" = "exec --no-startup-id ${getExe rofiWrapper}";
  };
}


================================================
FILE: home/_modules/default.nix
================================================
{ lib, osConfig, ... }:
let
  inherit (lib)
    mkOption
    types
    myLib
    mkDefault
    ;
in
{
  imports = [
    ../../system/_modules/myHardware.nix
    # base module enabled for all users
    ./_default

    ./browser/firefox

    ./editor/neovim

    ./homelab/kubernetes

    ./multiplexer/tmux
    ./multiplexer/zellij

    ./programs/beeaccounting
    ./programs/chezmoi
    ./programs/fontconfig
    ./programs/obs-studio
    ./programs/go
    ./programs/qmk
    ./programs/yamllint

    ./services/opencloud-client

    ./shell/dircolors
    ./shell/fish
    ./shell/git
    ./shell/lf
    ./shell/nix-direnv
    ./shell/starship

    ./terminal-emulator/alacritty
    ./terminal-emulator/contour
    ./terminal-emulator/kitty
    ./terminal-emulator/wezterm

    ./windowmanager/add-on/blueman-applet
    ./windowmanager/add-on/dunst
    ./windowmanager/add-on/gtk-theme
    ./windowmanager/add-on/nm-applet
    ./windowmanager/add-on/nwg-bar
    ./windowmanager/add-on/pasystray
    ./windowmanager/add-on/picom
    ./windowmanager/add-on/py3status
    ./windowmanager/add-on/rofi
    ./windowmanager/add-on/screenshotter
    ./windowmanager/add-on/swayidle
    ./windowmanager/add-on/swaylock
    ./windowmanager/add-on/terminal-emulator
    ./windowmanager/add-on/theme/tokyonight
    ./windowmanager/add-on/waybar
    ./windowmanager/add-on/xdg

    ./windowmanager/hyprland
    ./windowmanager/i3
    ./windowmanager/sway
  ];

  options.myHome = {
    username = mkOption {
      type = types.str;
      default = "";
    };
    isWayland = mkOption {
      type = types.bool;
      default = false;
    };
  };

  # defaulting to use the system config on NixOS machine
  config.myHardware = mkDefault (myLib.copyFromSystem "myHardware" osConfig);
}


================================================
FILE: home/_modules/editor/neovim/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.editor.neovim;
in
{
  options.myHome.editor.neovim = {
    enable = lib.mkEnableOption "Neovim";
    package = lib.mkPackageOption pkgs "neovim" { };
  };

  config = lib.mkIf (cfg.enable) {
    home.packages = [ cfg.package ];

    programs.fish = {
      shellAliases = {
        vimdiff = "nvim -d";
      };
      shellAbbrs = {
        vi = "nvim";
        vim = "nvim";
      };
    };

    home.sessionVariables = {
      EDITOR = "nvim";
      VISUAL = "nvim";
      MANPAGER = "nvim +Man!";
    };
  };
}


================================================
FILE: home/_modules/homelab/kubernetes/default.nix
================================================
{
  config,
  lib,
  pkgs,
  myPkgs,
  ...
}:
let
  cfg = config.myHome.homelab.kubernetes;
in
{
  options.myHome.homelab.kubernetes = {
    enable = lib.mkEnableOption "Kubernetes tools for homelab";
  };

  config = lib.mkIf (cfg.enable) {
    myHome = {
      programs.yamllint.enable = true;
      shell = {
        git.enable = true;
        nix-direnv.enable = true;
      };
    };

    sops.secrets = {
      kubeconfig = {
        sopsFile = ./secret.sops.yaml;
        path = "${config.home.homeDirectory}/.kube/config";
      };
      talosconfig = {
        sopsFile = ./secret.sops.yaml;
        path = "${config.home.homeDirectory}/.talos/config";
      };
    };

    home.packages = with pkgs; [
      age
      envsubst
      fluxcd
      go-task
      jq
      just
      kubectl
      kubernetes-helm
      kustomize
      nodePackages.zx
      talosctl
      myPkgs.kubectl-rook-ceph
      myPkgs.talhelper
    ];

    programs.fish.shellAbbrs = {
      # kubectl
      k = {
        position = "anywhere";
        expansion = "kubectl";
      };
      kgp = {
        position = "anywhere";
        expansion = "kubectl get pod";
      };
      kgn = {
        position = "anywhere";
        expansion = "kubectl get nodes";
      };
      kl = "kubectl logs";
      kdp = "kubectl describe pod";

      # flux
      f = {
        position = "anywhere";
        expansion = "flux";
      };
      fgk = {
        position = "anywhere";
        expansion = "flux get ks";
      };
      fsa = "flux suspend kustomizatin --all";
      fra = "flux resume kustomization --all";

      # talosctl
      t = "talosctl";

      # talhelper
      th = "talhelper";
    };
  };
}


================================================
FILE: home/_modules/homelab/kubernetes/secret.sops.yaml
================================================
kubeconfig: ENC[AES256_GCM,data:pfVS55vfo3YNYpYLfQSot40QWl2VEJaVsO6SfbI2284uO/OLsK6VD/6XQBT9UhzPU8dbJolYePEfeaRIcU5v1qqX6ZsZRx4SSMuGw7yEjjSzVY3OdRIWeochIa5pUD8ke/l9g+3HfJxoD+cOOyobGw22okKqQ+VmHizl/45EoKp2pJa7qB9TtW/HD7HhNxmVKtGGfxuI5uvz46kFGkDviaRPKcrO4etwDSwLPuQ8OZWAAUilwZKgA9jCo6lRWtPdpQv9TDb4SGjWKeGiKo2Ojl2zUcxmKIBjbRtL29AwkYDcLWmzg+pTgHDNp9V8NLv/bIB6zRzdJQx4Ay/JAwskxy+7Zy1f+H3yj0c+Eh45JAVFuPdIqQoPBSjZBt3Rc0SOJXXg1yjT3OAk0EDkeepNBwNHdUSzYNvWDc+PXJDwbpDm+ivG3nYIGgUJ0vcWWZ9PpRDQ+GZ64wYOH7fCPR9JlesusdaCPqj0roSqXTBmsE42MlHFKYWTtOeNbWdpMr4EVmHhLxyPc/6pC3pBdxy430Ql0zfJrillLp55Qra+VDRg/ojXS307nT/eD/ItVatS+fopvh19Pw6pfXir2ouRsDfUr/hZ2inA9kYGmWHD5R1pzCazxywQ0lcIz0Rfvw1R07mF0bAVkUU+NSlALiCbfvWp4bhnS1SOBzZlW4Xdy1BWYnc8NfJIaDocNi8jISPRV0EjDrAj6SsjZ5VUdvD972XlTXM6/jfPtNr0sWwCMnquT+yvjLFKneqntgBk+zIdjj8d3w3l/Om2n2MOH3mxmweo1h9Oa8X/YYv43lZ0YxSdROWvVZY6SgYTTVj+/rCIm1yiGmwK0jGLEvHsWnnn1ROPZeDDFJ9+nB2pp79yn+c+WyoqOQLnfLSMVMrWnEBBaWIGVc7/mHhD/beUAl/ScLXkeyG3B1QOIiShjWtRsRpXZRz8wpl1JXNNnt6ybKpQIyBo4TPiRRzfdaoFbpk0OP2qIAnV3MQ7VcUNBNd5PbIK+/+jesvSQrEZAy2sCU9LBIOBEwd3tvfQOzPoY0V4y0rTHgIY8AWMBHA84JurzlbmHZ12OSVudn0LEca7xApUffyxe2TmesA2xdbTXAPTIAxS1CEc8UJeAjvDovZNZ+an8KAO8DLSHk0n7mYIDtCMtGNogZ2YYoDAhYppS65fUEkT8KRq1XCNTo6ZHGVfej3J6JCIoO5vtU/Yjq6O0TbEtYZyN5rlMGJJxK7zsjaBqlZFI/hYNehOwRb11kBjIC73grPGKMsgMhSlBT0nNT4YRfaUOr98sVheaYDpNVdqRhIDyLSD3QPTpky3VSdD4KiQheuyYUgFW7JvcF8GBknSQYR8PVWP3S3eAqj2YS2BxR0K7CeWK9PJYxVqAnkdjhhqk7CglFlS2UK76ER0gXIeRkpEWt4PaWDyMGJ10awOtYg6H0YUhTpKFs+r20XpC4bkoAfJajo3wnw30IwlqxIlL6M19wF87sc6lxzzifdJWTw78y1dKPorSGMBVAbbvaIF4gEEPd6W3dCyumMOaENayb3BEouABANGvhoQN4UWPI7tsYRnrx+s2yZBU1/tVtVQhGAobQcyeubbiERHRLbN+2q/kRleGKLQi2dG46pqNjYgYBG7QDIR7tg8c7FpNVx54SLhyFjvTnunGsSg5aRQKPE+NctreDhve4ILSog3cyrB6MBhhumIXg6KGhta9Sd/y78errveNp9FRQaKvvwgB1EShP2Qmj4epCZJCukiY8pPZA5dNQ0n+BC2E2A/MNaYv+OtQYzWGUs4+XGcvuJcQTH/M9MrLqNZSP9romUdhImFGE7vHpERDGueLkanDBX3cXU+d93FZ64YyPhkrv8VWY5EneCWKePiEkSuKiJp3W39qxNn4dzFFMcJHh51DA1dOEwevWrHfzPsr2QQjJ89Za7K4UzoU+Z4Ek0zm/LBG46rQ1opr2LVd17/km/yPNRivscIyDN1o+RH0cQtPPUhou6UpnA5gmMVXAtmHfXSjibE/ttdZ1dkzwnVDJAd55vmKEvQulE5e5g9WoaXo0Ysy58Kehp1g2tEjpA1uqrCbjqHfj9GvifDciAJa822a7NUwKu8ktW9vBpx/CPamnXkij+GFLm0uYWZdKrvcF47WqUXQ8Q4h7Y4ze5NheTJQenRMpjo65TyQmRqJlsZDc/Ie+Q9+9oarCS4o0aLvSedfDrd6tvKEExQ5ih6dtYazeYcZdT2ordG8G3Neww1EvKR6M+/+EMlwFTE/FyrX8Uk4kSFz25u7C+dp92O9B9WlvINHjBCkmJEOSXBzcr9sTxJLifAIIAfx8KCVZygGaEMV6JT1luXch7eme9CbV/nauQwhp1paqjFafMUG8B2SW17Ho9dkEW25HI+uDmQ1IvAUCRVhY3ngRZGpUKoaYVR3ZgEPsIF1F0dN9edQbjhog9rG0liD5Y0ZVGb9BKrSqUwHWp4zkAPW5NAIvxO9sq9/OfF/Jo3Qq45klbd/4n/w0M//R425HGwAs4JiPfBZctDcmZncqJdqULvUPRg9mjUWF8PagsJaVHW1Ukp8b+R7D5xLa+brc0+4QMs9VxgOah+BBJOAAq20IPjkeIwwc+EQI3/tyqiO3iCoNFE4hJssM5je3yAikimKYF1Do7JA9K/PrRoVtbkTlq6HrQBG9UM/CIeIsU1szkv55anWDhC/RcFB9J6WnVN6LLY/ZXkGM26D9hJui7oTsbyEVZUNwSB2CboNXB+EXpi79O+4RFJAnCh1OHYzbNEOOj6Zkju2E/Dk+8OttpOCrfRgk1n5xNsveP6fC8gj0vSrVimrWhnG2GCATL/0muwOW6nYnw1sLtCwiMKzemF3DpLYcFBWwQhwzyDk0z6raOgSErcH+j9UJsZEJNUfwt1mXS7yqWADLGvsnBMkKdbyGMUNr0w0BKwnK5ENS9gL6z5BSD32Zk5T7DB+JLgrn47Ry987tKUQQRqCrME2UUUnuk5UeUVWMdCzXME0lVsRqkInI2MTegoCkbT/HBK101+PjdLoNYPm9sHT6omfGdxlzNC9rnah15gXB2lCm4bliQ8+flq,iv:Dikm/1W8siNC4rK9elXCAWJvGNaGJtPRF+fL9kOBYLU=,tag:swr75OwWPjUwr8eMgBooEw==,type:str]
talosconfig: ENC[AES256_GCM,data:zukEgmExjlNc1gvDQXedX0uCQgmsaLuIpaVJQLlLNBLGA4Jr9JZ86oKlVR9dDqhnZ22Y08KvNNZs0fG//nttr8GBU94a9N0mbRU+DhVCho3PfAc4Iza0ztZZSEjofIFmR8q1LTKQhbqmnGGF2JB45kos6+do46MpfxMIJndpwJqRY/IAAeeB5pCs0aF8HxPF2ehmzcKXEZMBb5g2RJtP9G/z8xlzqgrHDnvbichR13LCpBcoV6X23FYs93dQxrVwskW+39STa5R/570deUHwQLUzC1kmjqh5ktMvpzSJtzAzpeyM6gJMzMsdpqFb5pzX9myuulWF/boU6qa1qH6/XBOtoT005Dayi1L7sMUgRcuXCGOxCJUCt/KORHFqXL2kNjkwXjIBUT4YkAjsq3110pEXRhLUPr3dKMTxdrrWcpeCk13DqroSyYJKo/DYoMuw5YJDDQ7Nbc3rFL9aaOMwoCaT7r0lZgKThwR9pOPerMxODhxHj0FzQclvZzxITZ25SKnsJnRIbVfm7pIWIRnBaf3ZhuLgZMCzeTiCz4iBwakoUmHmw3acW+C7RP4KVZXN/Qz8HQHxGsKD3ITnextTDIxkFSeoC8JJHLkRy8aCROv82xwR2YrfXxGRnxlyHfY+CaVRl0Ff5Q7nhOk1EJMbiLtP39S7e6HEKpk8z9eP99QLatIhNMfP1uVhdEbaJxyNnrVAokaG4RrxXf3zJdrd9vqpCYVmRScVht3kjmh7L5OXUd8JZ9t9gpFtlf7AfkmFQv2J9IFZDHGB9PmXf4iW+NX3+b+2BkW6F57z6cYddHvIlTcgJGWYLGSd6EHiPbM4Y9V9yWbwGlBQIJCN/Vm3/M3z1EKZCREMUouUbKDnLr4/sowYkb4m9OcBsnMcCuzVe374HmoRCKb3WiWzT7+JabkK0kRcp/PcS69mg8F5B+UyHUwH2tx2WeS2OBR7pc5MeEL142PW8iIalSI3dFfZUw4xMTvePiQ0vku7hxcg0cSysQXtgamXHVhzxLW8utbiWJINvt4etRBhUVeFHWW1kaPFSdQNbDyDH3EJyy6gKEL5KYNQqHLBo0kybJVEOti6dwC9xf1hdH0VS53Ssh2RPE9bKPBIRy7aag+DpZLHgiZijVcnWqdyd5rBRU3dA+j9qzu4jdHqm64puKUG57g/1yN+8hfoaYiOV1XdwZ5s8YcWtPOX4ufRoJAKMIGDG2EVALYurasdv/r+2r1zuoWI/yDM3i85WefpHz47Wr0A4WagzxlMA9pGBZui5UxoLfaFdL5WcPkh7RRkF6bjlnERQKEKanf7W/1Vb6szHChXZYf1XBb4qjAhmwhqXjmG8NvdY8kLte6RjZfU2GQuWe1nyGbIOGeqEy22XO571crOuusZnnIHVGmrymj9WJKPN8VSsoiMpTN7ZukNKrfZ9fpImwy3dqrMZhUuU9PxNaaJxKy8UGNxRDXG3KzWCqm9DakBJYtwgaotSjrQAzYj0f0DvjTACvJRyUUSGo9kdFyRYr836qVP1C2/bF1FYqwFh7a0m/WUZV+GUG2aUTlV6lF55+pgmSFSv3VjxSVvoEzQdqXSN40AaVoEf3CBHAjtMUqt00JQWZGAFQ78qpQdr5Xo8RPUXsmmGAnVY/bmnvtlM7Vs0dbEt7RPrgvMbIxdJvDZXXv0z01pFueY8g/fibc/TIDQ2k/if5xWbSAYaWG8K8KnTIK91hHr8GYhkYkYP5nWfzr9txEAvy71asngO6aVR/ZMQcot0GYkW1eiipjuAuxR6o6wqn5fDRO1ZsE4RFa67D7Mu7eZHNAm75iRd2ECp2EWqm6wvoKjnXSratlPH3s58cTwzuMJYxa4EmM0t9ZdePfQPQ00xqshakBczvu+D1Wz6tOq5V+kRWncjko49uPMfmbyYBuBOF7AhFK+MpFFuc7JWUYW6YW0K4FgZkt0pE6hwFWyneIoDFSwcMVKs0X6JAu3TX7xL8ssT0StDvRWIVR0MQkmnGEho5Im9w8W8UXnzopl/91prX5ACPfsvgsxYOEIaCkyH5EkEsaMAUBWHhRadkXZBWaHYqChruc23y78sO3xfRY6YnFOrnf2kFURF6pFE7XYNBOE0fb+P+QnvdxFCsQlC9xcBYuC0MAJoKyYbdnwyb52a/GDPpvzKmC7BHjgh3FW9riHY4O4CgXLcYO0DX9J92KE67fjArXQufjU2xiUKYS6zHb0w5jf4lorgeVU/r3RcEp3jKdGmp2/mMXJtqM823zdy9RKgmGlgg==,iv:u+cocP8bYeHCUtjuQrjfrQsoUMV4c3p3mDVYS6Hd07o=,tag:TsTIFGKw0t/0YB6Efl42Mw==,type:str]
sops:
    age:
        - recipient: age1zeqkpfz7e3s207ynea0z0auc0mrct0pc7w4sh6j3d0c4qac3dahqj9ufdg
          enc: |
            -----BEGIN AGE ENCRYPTED FILE-----
            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3UGVVYkw4ellQNU53OXRQ
            YmM3NjhNcFFmMThKMVBuNHZ2eElVYTlSWlZvCmZ0bSsvSjN5N1Vpd21BVmlrOWRm
            aXJzS0ZlQjduWlNiQjJabXA4UG9HQlEKLS0tIFQ5bUFtWCtJcCtSUGNCODk5OVJB
            azQ2bjFCd2V1VThBNERVb2V4VVkvMXcKqMOvVXQeb2RLQ+ce2s/YJ+gUoCbksFys
            WXLUNGwYF1rKOGdtWp3UBajpKIE2w4Gr6LAPm2Fn0raiVIWw4ucxVA==
            -----END AGE ENCRYPTED FILE-----
        - recipient: age1tdwlq9y4jgejkhasqwynw5uaen9xwatcvr52l70trsdxkeyvlesqjnh7l8
          enc: |
            -----BEGIN AGE ENCRYPTED FILE-----
            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwQUg4YlMwYzUyc0ZUYStj
            dFJpeUJtbjZwdjI1SjMrMlVYT1I5TGdNWW5rCm1CaVpPME0vOEpSckc4azlTSlJj
            VlVReCtObXNLQWtVem9BMHF0Z0NlWjQKLS0tIGtiMjhpM0s1TnVWTEZudmM0aWo4
            b2c1UUIvZHhndGF3NFF1V2dZYUxwRHMKlAvYwXo53J93mEbTShaYEHYgAfLmYz9R
            rZNxgFI7at1ayTpFQabtJDWmmKMbZK7hOZWrWnYGJ5FEAI144x8aFA==
            -----END AGE ENCRYPTED FILE-----
        - recipient: age16p3zls5n0jks6amszwcuaqgl5dyuyf8k8wgeyrw562s5s88xtq3qq046fh
          enc: |
            -----BEGIN AGE ENCRYPTED FILE-----
            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4WEZTYTcwajd1SEhYTUJZ
            L2xvZHdoaG5DTTB0UndyRS8xZnRlclB2KzFRCjlIQXdQTjA5eEE2ZmpVTWhzZk5W
            c0xQOCtFRURGMGxVa1d2VWUyaGlnU2sKLS0tIHUzVmJRcVVyQ1pqV3ZRSUZydDJw
            aGliY0ZIVlJPOHlzRTQzQWpzYTc1a1EKgmvkBFxGdcQbrRvARsq90WIUbqyx7lbt
            ZNkd2FHqFuGECe2L31AaW3pYj1x33EbI8+Dh6jU6OjZ7cuD1bwjcjA==
            -----END AGE ENCRYPTED FILE-----
        - recipient: age1v52mx8gs4ephprep0wcc4j3fvvprppvs9vktf2p24yv52sqsf33sd5crk9
          enc: |
            -----BEGIN AGE ENCRYPTED FILE-----
            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkUkd5VjNES1UxMlhqeEda
            T3ozZ1BBdk84M2pCOVhYWTBlZHFSTzViTVVVCmorNkZ3ZTRmcWpSaWZJMWFFb2Nu
            OUpVQ3d0bFhPREdzSTVXQmFzQ2gyMkEKLS0tIFZuRWQ4U0dBbnZYTy82WVhsckhT
            WFRqcXV3ZkR4c1dtd3I0QTM5WC9HQ0EKECenrjPSPpZW/0kPZj31pA2P4rJ5Tvxx
            Fim4Ob8aUqAGjpI+0so+6imQfQ9a6b1jCOZMuwrbqbR93wfd7sYL1w==
            -----END AGE ENCRYPTED FILE-----
        - recipient: age1k8ufac2s0gs6nh0xsfavafz062vd36petmyv6nwmg00z4a7s4gnsjtd837
          enc: |
            -----BEGIN AGE ENCRYPTED FILE-----
            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKd1ExR0c5SUpidUl6N2JD
            WE5JSzJaUkE1RE1rWlZ2V052Rld6SVdwZldJCk5LUTByMnhhV1lzcjVkYW1CclFp
            SDNrK1RZVzhjNStoRXUyOGt2WVNkRFUKLS0tIC9kVm01M3JTTlRRak9nblZRTDIw
            TzJPY2NQYkk4RVVWR1dlamVadGJNU2cKkEN8xZ2Oz/f3oA24WBzpVCMLyz4HsZMh
            KVnwkjo746csT+vM9Z7qzJw0Xo/dG7d/pv67AcFRZFp4HB4B5qvyEg==
            -----END AGE ENCRYPTED FILE-----
        - recipient: age1dcsm5awz8ekzchk7gsvndkc4kq65n2wzgavxtqe53vxdsfk9k9pqh3whru
          enc: |
            -----BEGIN AGE ENCRYPTED FILE-----
            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiMnR1TDNKV3pGeEg1ek1R
            M1NGZ2ZoeWw3aGZzeHkzV0J6RHpWd1V3Y1VJClVhQnNSSnpTQ3NRY2RCNXZPMGR3
            bUtpNzVjc2szcEg4dXlJR21UZkVkRm8KLS0tIEdzbHVaK0MrRmk1QTV2ejhtYTky
            ZDVSUEtLdFVqQ0xUZnRlVW5rOURoMWcKfAQ4D2gvDwQE1ZxIz4DfnVfv2OekuqlX
            0XuGxTpE/XP1yXqc7WgBr4DjV9L5ooYU5RiZD6hOaTlhPChE0VGVpg==
            -----END AGE ENCRYPTED FILE-----
    lastmodified: "2025-07-22T13:29:06Z"
    mac: ENC[AES256_GCM,data:krY/qF48bsUnCyeQ1gL8eA14QDpZHZk8zsjUhaJ3UFbaIvVkVZpdbhsgNjcNd8OSU7i36kSz8PvSobMKddBsNTW7J4+oAFuouBAteF/TUCAuMiUU7dz5WhCZ5O3gcY+eDdeErXmiYNtzZJz6WGq3k9mMoN2zjLQCs0dMZG3iXVg=,iv:fhGIMHp2/q8FBh9LeZUlJREfaS279RkhpQDw9OqfksY=,tag:BBE3OeojIWz8SdjPPI4rTA==,type:str]
    unencrypted_suffix: _unencrypted
    version: 3.10.2


================================================
FILE: home/_modules/multiplexer/tmux/config/tmux.conf
================================================
# SERVER OPTIONS
set -g buffer-limit 20 # number of buffers, older than limit buffer will be removed
set -g default-terminal "tmux-256color" # 256 color
set -g escape-time 0 # time for tmux to wait for key sequence
set -ga terminal-features ",*256col*:RGB" # true color support
set -ga terminal-overrides ',*:Smulx=\E[4::%p1%dm' # undercurl support
set -ga terminal-overrides ',*:Setulc=\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m' # undercurl colors

# SESSION OPTIONS
set -g base-index 1 # starting index for new window
set -g display-time 0 # time for which status line messages and indicators are displayed in miliseconds, 0 means diplay until a key is pressed
set -g history-limit 10000 # maximum number of lines held in window history
set -g mouse on # enable mouse support
set -g prefix M-a # prefix key is Alt+a
set -g prefix-timeout 0 # disable timeout after prefix key is pressed
set -g renumber-windows on # automatically renumber window when a window is closed
# set -g repeat-time 32767 # typing command without pressing prefix key again in the specified time in miliseconds (can be 200000 after 354926a956ba07ef38d2ddd91a7820e3c9634ab0)
set -g status-keys vi # use vi style keybindings in command prompt

# WINDOW OPTIONS
set -g aggressive-resize on # tmux will resize the window to the size of the smallest or largest session rather than the session it is attached
set -g automatic-rename on # automatic window renaming
set -g automatic-rename-format '#{pane_current_command}' # format of automatic window renaming
set -g mode-keys vi # use vi style keybindings in copy mode
set -g pane-base-index 1 # starting index for new pane

# PANE OPTIONS
set -g allow-rename off # allow programs to change the window name
set -g remain-on-exit off # destroy window when program exits

# KEYBINDING SETTINGS
# Some keybindings below have `switch-client -T prefix` appended to the command. I use it to mimic the behavior of `bind -r`
# so I can repeat commands without typing prefix key again. The problem with using `bind -r` is it doesn't work for bindings that
# doesn't have `-r` flag.
# For example, if I have a key to move to a pane with `-r` flag and a key to kill pane without `-r` flag
# in `prefix` keytable, to move to a pane and kill it I have to:
# Press prefix key, move to a pane, wait for `repeat-time`, press prefix key, kill the pane.
# Now, I can do:
# Press prefix key, move to a pane, kill the pane

# The downside of this approach is I can be stucked in prefix mode forever, what I do is have a key to exit prefix mode which
# I bound to `Esc` and `Space` key

# unbind all the default key bindings
unbind -T root -a
unbind -T prefix -a
unbind -T copy-mode -a
unbind -T copy-mode-vi -a

# root key-table
bind -T root -N "Alt+z to send prefix key to client" M-z send-prefix
bind -T root -N "select pane on mouse click on pane" MouseDown1Pane select-pane -t = \; send-keys -M
bind -T root -N "select window on mouse click on status" MouseDown1Status select-window -t =
bind -T root -N "resize pane on mouse drag on border" MouseDrag1Border resize-pane -M
bind -T root -N "select previous window on mouse wheel up on status" WheelUpStatus previous-window
bind -T root -N "select next window on mouse wheel down on status" WheelDownStatus next-window
bind -T root -N "go into copy mode to scroll history on mouse wheel up on pane" WheelUpPane \
  if-shell -F "#{||:#{pane_in_mode},#{mouse_any_flag}}" { send-keys -M } { copy-mode -e }

# prefix key-table
bind -T prefix -N "h to move to left pane" h select-pane -L \; switch-client -T prefix
bind -T prefix -N "j to move to bottom pane" j select-pane -D \; switch-client -T prefix
bind -T prefix -N "k to move to top pane" k select-pane -U \; switch-client -T prefix
bind -T prefix -N "l to move to right pane" l select-pane -R \; switch-client -T prefix

bind -T prefix -N "H to resize pane to the left by 2 columns" H resize-pane -L 2 \; switch-client -T prefix
bind -T prefix -N "J to resize pane downwards by 2 lines" J resize-pane -D 2 \; switch-client -T prefix
bind -T prefix -N "K to resize pane upwards by 2 lines" K resize-pane -U 2 \; switch-client -T prefix
bind -T prefix -N "L to resize pane to the right by 2 columns" L resize-pane -R 2 \; switch-client -T prefix

bind -T prefix -N "Alt+n to move to next window" M-n next-window \; switch-client -T prefix
bind -T prefix -N "Alt+p to move to previous window" M-p previous-window \; switch-client -T prefix

bind -T prefix -N "> to swap pane with the next pane" > swap-pane -D \; switch-client -T prefix
bind -T prefix -N "< to swap pane with the previous pane" < swap-pane -U \; switch-client -T prefix

bind -T prefix -N "Alt+s to split window horizontally with current pane path" M-s split-window -hc "#{pane_current_path}"
bind -T prefix -N "Alt+v to split window vertically with current pane path" M-v split-window -vc "#{pane_current_path}"
bind -T prefix -N "c to open a new window with current pane path" c new-window -c "#{pane_current_path}"

bind -T prefix -N "Esc to switch to root key table" -r Escape switch-client -T root
bind -T prefix -N "Space to switch to root key table" -r Space switch-client -T root
bind -T prefix -N "a to enter copy mode" a copy-mode
bind -T prefix -N ": to enter tmux command prompt" : command-prompt

bind -T prefix -N "x to close current pane" x kill-pane
bind -T prefix -N "X to close current window" X kill-window

# copy-mode-vi key-table
bind -T copy-mode-vi -N "h to move cursor left" h send-keys -X cursor-left
bind -T copy-mode-vi -N "j to move cursor down" j send-keys -X cursor-down
bind -T copy-mode-vi -N "k to move cursor down" k send-keys -X cursor-up
bind -T copy-mode-vi -N "l to move cursor down" l send-keys -X cursor-right
bind -T copy-mode-vi -N "b to move cursor to word beginning" b send-keys -X previous-word
bind -T copy-mode-vi -N "e to move cursor to word ending" e send-keys -X next-word-end
bind -T copy-mode-vi -N "Home to move cursor to start of line" Home send-keys -X start-of-line
bind -T copy-mode-vi -N "0 to move cursor to start of line" 0 send-keys -X start-of-line
bind -T copy-mode-vi -N "End to move cursor to end of line" End send-keys -X end-of-line
bind -T copy-mode-vi -N "$ to move cursor to end of line" \$ send-keys -X end-of-line
bind -T copy-mode-vi -N "PageUp to move cursor one page up" Npage send-keys -X page-up
bind -T copy-mode-vi -N "PageDn to move cursor one page down" Ppage send-keys -X page-down
bind -T copy-mode-vi -N "g to move cursor to top of history" g send-keys -X history-top
bind -T copy-mode-vi -N "G to move cursor to bottom of history" G send-keys -X history-bottom

bind -T copy-mode-vi -N "Scroll up 5 line on mouse wheel up on pane" WheelUpPane select-pane \; send-keys -X -N 5 scroll-up
bind -T copy-mode-vi -N "Scroll down 5 line on mouse wheel down on pane" WheelDownPane select-pane \; send-keys -X -N 5 scroll-down
bind -T copy-mode-vi -N "Select a line and copy it to clipboard on double click on pane" DoubleClick1Pane \
  select-pane \; send-keys -X select-line \; run-shell -d 0.3 \; send-keys -X copy-pipe-and-cancel
bind -T copy-mode-vi -N "Begin selection on mouse drag on pane" MouseDrag1Pane \
  select-pane \; send-keys -X begin-selection
bind -T copy-mode-vi -N "Copy selection to clipboard on releasing mouse drag on pane" MouseDragEnd1Pane \
  send-key -X copy-pipe-and-cancel

bind -T copy-mode-vi -N "v to begin selection" v send-keys -X begin-selection
bind -T copy-mode-vi -N "Space to begin selection" Space send-keys -X begin-selection
bind -T copy-mode-vi -N "V to select a line" V send-keys -X select-line
bind -T copy-mode-vi -N "Alt+v to toggle box selection" M-v send-keys -X rectangle-toggle
bind -T copy-mode-vi -N "y to copy selection to clipboard" y send-keys -X copy-pipe-and-cancel
bind -T copy-mode-vi -N "Y to copy from cursor to end of line to clipboard" Y send-keys -X copy-pipe-end-of-line-and-cancel

bind -T copy-mode-vi -N "Esc to exit copy mode" Escape send-keys -X cancel
bind -T copy-mode-vi -N "q to exit copy mode" q send-keys -X cancel


================================================
FILE: home/_modules/multiplexer/tmux/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.multiplexer.tmux;
  inherit (lib) mkEnableOption mkIf;
in
{
  options.myHome.multiplexer.tmux = {
    enable = mkEnableOption "tmux";
  };

  config = mkIf (cfg.enable) {
    catppuccin.tmux = {
      enable = true;
      extraConfig = ''
        set -g @catppuccin_window_number_position "right"
        set -g @catppuccin_window_current_number_color "#{@thm_green}"
        set -g @catppuccin_window_text ""
        set -g @catppuccin_window_number "#[bold]Tab ###I "
        set -g @catppuccin_window_current_text ""
        set -g @catppuccin_window_current_number "#[bold]Tab ###I "
        set -g @catppuccin_window_status_style "custom"
        set -g @catppuccin_window_right_separator "#[fg=#{@_ctp_status_bg},reverse]#[none]"

        set -g @catppuccin_window_left_separator "#[fg=#{@_ctp_status_bg}]#[none]"
        set -g @catppuccin_window_middle_separator "#[bg=#{@catppuccin_window_number_color},fg=#{@catppuccin_window_text_color}]"
        set -g @catppuccin_window_current_middle_separator "#[bg=#{@catppuccin_window_current_number_color},fg=#{@catppuccin_window_current_text_color}]"

        set -g window-status-separator ""
        set -g status-left-length 0
        set -g status-left "#[fg=#{@thm_fg} bold]TMUX (#S) "
        set -ga status-left "#{?client_prefix,#[fg=#{@thm_red} bold]PREFIX ,#{?#{==:#{pane_mode},copy-mode},#[fg=#{@thm_yellow} bold]COPY ,#[fg=#{@thm_green} bold]NORMAL }}"
        set -g status-right ""
      '';
    };

    programs.tmux = {
      enable = true;
      package = pkgs.tmux;
      extraConfig = ''
        ${
          if config.myHome.isWayland then
            "set -g copy-command '${pkgs.wl-clipboard}/bin/wl-copy'"
          else
            "set -g copy-command '${pkgs.xsel}/bin/xsel -i -b'"
        }

        ${builtins.readFile ./config/tmux.conf}
      '';
    };
  };
}


================================================
FILE: home/_modules/multiplexer/zellij/config/config.kdl
================================================
default_mode "normal"
theme "catppuccin-mocha"
keybinds clear-defaults=true {
  normal {
    bind "Alt a" { SwitchToMode "tmux"; }
    bind "Alt z" { SwitchToMode "locked"; }
  }

  locked {
    bind "Alt z" { SwitchToMode "tmux"; }
  }

  tmux {
    bind "Alt s" { NewPane "Right"; SwitchToMode "normal"; }
    bind "Alt v" { NewPane "Down"; SwitchToMode "normal"; }
    bind "r" { SwitchToMode "RenameTab"; }
    bind "h" { MoveFocus "Left"; }
    bind "j" { MoveFocus "Down"; }
    bind "k" { MoveFocus "Up"; }
    bind "l" { MoveFocus "Right"; }
    bind ">" { MovePane; }
    bind "H" { Resize "Left"; }
    bind "J" { Resize "Down"; }
    bind "K" { Resize "Up"; }
    bind "L" { Resize "Right"; }
    bind "Alt n" { GoToNextTab; }
    bind "Alt p" { GoToPreviousTab; }
    bind "c" { NewTab; SwitchToMode "normal"; }
    bind "x" { CloseFocus; SwitchToMode "normal"; }
    bind "a" { EditScrollback; SwitchToMode "normal"; }
    bind "Esc" "Space" "Enter" { SwitchToMode "normal"; }
  }

  RenameTab {
    bind "Alt a" { SwitchToMode "tmux"; }
    bind "Enter" { SwitchToMode "normal"; }
    bind "Esc" { UndoRenameTab; SwitchToMode "normal"; }
  }
}

plugins {
  tab-bar { path "tab-bar"; }
  status-bar { path "status-bar"; }
  strider { path "strider"; }
  compact-bar { path "compact-bar"; }
}

ui {
  pane_frames {
    rounded_corners true
  }
}


================================================
FILE: home/_modules/multiplexer/zellij/config/layouts/default.kdl
================================================
layout {
  pane
  pane size=1 borderless=true {
    plugin location="zellij:compact-bar"
  }
}


================================================
FILE: home/_modules/multiplexer/zellij/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.multiplexer.zellij;
  cmd = lib.getExe config.programs.zellij.package;
  inherit (lib) mkEnableOption mkPackageOption mkIf;
in
{
  options.myHome.multiplexer.zellij = {
    enable = mkEnableOption "Zellij";
    package = mkPackageOption pkgs "zellij" { };
  };

  config = mkIf (cfg.enable) {
    programs = {
      zellij = {
        enable = true;
        package = cfg.package;
      };

      fish.interactiveShellInit = ''
        set -gx ZELLIJ_AUTO_ATTACH true
        set -gx ZELLIJ_AUTO_EXIT true
        eval (${cmd} setup --generate-auto-start fish | string collect)
      '';
    };

    xdg.configFile."zellij".source = ./config;
  };
}


================================================
FILE: home/_modules/programs/beeaccounting/default.nix
================================================
{
  lib,
  osConfig,
  config,
  pkgs,
  ...
}:
with lib;
let
  systemEnabled = myLib.systemEnabled "mySystem.containers.beeaccounting.enable" osConfig;
  isAdminUser = myLib.isAdminUser config.myHome.username osConfig;
  adminUser = osConfig.users.users.${osConfig.mySystem.adminUser};
in
{
  config = mkIf (systemEnabled && isAdminUser) {
    xdg.desktopEntries = {
      bee-app = {
        name = "Bee2.9";
        genericName = "Accounting Software";
        icon = ./bee-app.ico;
        exec =
          let
            script = pkgs.writeShellScriptBin "bee-app" ''
              ${pkgs.xorg.xhost}/bin/xhost +local:${toString adminUser.uid} > /dev/null 2>&1 && \
              ${pkgs.docker}/bin/docker exec --user ${toString adminUser.uid} beeaccounting-app java -Xmx1g -jar /app/BeeUI-2.9.jar
            '';
          in
          "${script}/bin/bee-app";
        categories = [
          "Office"
          "Finance"
          "Java"
        ];
        comment = "Bee Accounting 2.9 Application";
        type = "Application";
        terminal = false;
        settings = {
          StartupWMClass = "AppLauncher";
        };
      };

      bee-updater = {
        name = "Bee2.9-Updater";
        genericName = "Software Updater";
        icon = ./bee-updater.ico;
        exec =
          let
            script = pkgs.writeShellScriptBin "bee-updater" ''
              ${pkgs.xorg.xhost}/bin/xhost +local:${toString adminUser.uid} > /dev/null 2>&1 && \
              ${pkgs.docker}/bin/docker exec --user ${toString adminUser.uid} beeaccounting-app java -Xmx1g -jar /app/BeeUpdater-2.9.jar
            '';
          in
          "${script}/bin/bee-updater";
        categories = [
          "Office"
          "Finance"
          "Java"
        ];
        comment = "Bee Accounting 2.9 Updater";
        type = "Application";
        terminal = false;
      };
    };

    wayland.windowManager.hyprland.settings.windowrulev2 = [
      "workspace 2, class:^(AppLauncher)$"
      "nodim, class:^(AppLauncher)$"
      "nofocus, class:^(AppLauncher)$, title:^(win)(.*)$"
      "noborder, class:^(AppLauncher)$, title:^(win)(.*)$"
      "noanim, class:^(AppLauncher)$, title:^(win)(.*)$"
      "nofocus, class:^(AppLauncher)$, title:^(JidePopup)$"
      "noborder, class:^(AppLauncher)$, title:^(JidePopup)$"
      "noanim, class:^(AppLauncher)$, title:^(JidePopup)$"
      "maxsize 400 180, class:^(AppLauncher)$, title:^(JidePopup)$"
    ];
  };
}


================================================
FILE: home/_modules/programs/chezmoi/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.programs.chezmoi;
  inherit (lib) mkEnableOption mkIf;
in
{
  options.myHome.programs.chezmoi = {
    enable = mkEnableOption "chezmoi";
  };

  config = mkIf (cfg.enable) {
    # we want to do stuffs after HM has finished linking stuffs in `$NIX_PROFILES/bin`
    home.activation.chezmoi = lib.hm.dag.entryAfter [ "installPackages" ] ''
      # I want chezmoi to have access to the userspace $PATH
      _saved_path=$PATH
      PATH="${config.home.path}/bin:$PATH"
      # a lot of my chezmoi scripts needs system programs to work, might be a bad idea idk
      PATH=$PATH:/usr/local/bin:/usr/bin:/bin

      run ${pkgs.chezmoi}/bin/chezmoi apply -S ${../../../..} $VERBOSE_ARG

      # return it back
      PATH=$_saved_path
    '';
  };
}


================================================
FILE: home/_modules/programs/fontconfig/default.nix
================================================
{
  lib,
  osConfig,
  pkgs,
  ...
}:
{
  config = lib.mkIf (!lib.myLib.isNixos osConfig) {
    fonts.fontconfig.enable = true;
    home.packages = with pkgs; [
      nerd-fonts.ubuntu-mono
      unifont
    ];
  };
}


================================================
FILE: home/_modules/programs/go/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.programs.go;
in
{
  options.myHome.programs.go.enable = lib.mkEnableOption "Go";

  config = lib.mkIf (cfg.enable) {
    programs.go = {
      enable = true;
      package = pkgs.unstable.go;
    };
  };
}


================================================
FILE: home/_modules/programs/obs-studio/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.programs.obs-studio;
in
{
  options.myHome.programs.obs-studio = {
    enable = lib.mkEnableOption "OBS Studio";
  };

  config = lib.mkIf (cfg.enable) {
    programs.obs-studio = {
      enable = true;
      plugins = lib.mkIf config.myHome.isWayland [ pkgs.obs-studio-plugins.wlrobs ];
    };
  };
}


================================================
FILE: home/_modules/programs/qmk/default.nix
================================================
{
  lib,
  config,
  osConfig,
  pkgs,
  ...
}:
let
  inherit (lib) myLib mkEnableOption mkIf;
  cfg = config.myHome.programs.qmk;
  systemEnabled = myLib.systemEnabled "mySystem.programs.qmk.enable" osConfig;
  isNixos = myLib.isNixos osConfig;
in
{
  options.myHome.programs.qmk = {
    enable = mkEnableOption "QMK";
  };

  config = mkIf (cfg.enable) {
    warnings = mkIf (!systemEnabled && isNixos) [
      ''
        You have enabled QMK home-manager module but not the NixOS system module and you are using NixOS.
        Some things might not work properly.
      ''
    ];
    myHome.shell.git.enable = true;

    xdg.configFile."qmk/qmk.ini".source = ./qmk.ini;

    home.packages = with pkgs; [ qmk ];
  };
}


================================================
FILE: home/_modules/programs/qmk/qmk.ini
================================================
[user]
qmk_home = /home/budiman/Github/qmk_firmware
keyboard = crkbd/rev1
keymap = budimanjojo

[mass_compile]
keymap = default

[config]

[console]

[compile]

[docs]

[flash]

[format_c]

[format_python]

[format_text]

[generate_autocorrect_data]

[generate_compilation_database]

[generate_develop_pr_list]

[generate_dfu_header]

[generate_info_json]

[hello]

[info]

[lint]

[kle2json]

[list_keymaps]

[list_layouts]

[new_keyboard]

[new_keymap]

[painter_convert_graphics]

[painter_make_font_image]

[painter_convert_font_image]

[general]


================================================
FILE: home/_modules/programs/yamllint/config.yaml
================================================
---
extends: relaxed

yaml-files:
  - '*.yaml'
  - '*.yml'
  - '.yamllint'

rules:
  empty-lines:
    max: 1
  empty-values: enable
  indentation:
    indent-sequences: consistent
  new-line-at-end-of-file: disable
  truthy:
    allowed-values:
      - 'true'
      - 'false'
      - 'yes'
      - 'no'
      - 'on'
      - 'off'


================================================
FILE: home/_modules/programs/yamllint/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.programs.yamllint;
in
{
  options.myHome.programs.yamllint = {
    enable = lib.mkEnableOption "YAMLlint";
  };

  config = lib.mkIf (cfg.enable) {
    home.packages = [ pkgs.yamllint ];
    xdg.configFile."yamllint/config".source = ./config.yaml;
  };
}


================================================
FILE: home/_modules/services/opencloud-client/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.services.opencloud-client;
in
{
  options.myHome.services.opencloud-client = {
    enable = lib.mkEnableOption "OpenCloud client";
  };

  config = lib.mkIf cfg.enable {
    systemd.user.services.opencloud-client = {
      Unit = {
        Description = "OpenCloud client";
        After = [ "graphical-session.target" ];
        PartOf = [ "graphical-session.target" ];
      };

      Service = {
        Environment = [ "PATH=${config.home.profileDirectory}/bin" ];
        ExecStart = "${pkgs.unstable.opencloud-desktop}/bin/opencloud";
      };

      Install = {
        WantedBy = [ "graphical-session.target" ];
      };
    };
  };
}


================================================
FILE: home/_modules/shell/dircolors/default.nix
================================================
{ config, lib, ... }:
let
  cfg = config.myHome.shell.dircolors;
in
{
  options.myHome.shell.dircolors = {
    enable = lib.mkEnableOption "dircolors";
  };

  config = lib.mkIf cfg.enable {
    programs.dircolors = {
      enable = true;
      settings = {
        DIR = "01;34";
        LINK = "01;36";
        FIFO = "40;33";
        SOCK = "01;35";
        BLK = "01;33";
        CHR = "33";
        ORPHAN = "31";
        EXEC = "01;32";
        "*.7z" = "01;31";
        "*.bz2" = "01;31";
        "*.gz" = "01;31";
        "*.lz" = "01;31";
        "*.lzma" = "01;31";
        "*.lzo" = "01;31";
        "*.rar" = "01;31";
        "*.tar" = "01;31";
        "*.tbz" = "01;31";
        "*.tgz" = "01;31";
        "*.xz" = "01;31";
        "*.zip" = "01;31";
        "*.zst" = "01;31";
        "*.zstd" = "01;31";
        "*.bmp" = "01;35";
        "*.tiff" = "01;35";
        "*.tif" = "01;35";
        "*.TIFF" = "01;35";
        "*.gif" = "01;35";
        "*.jpeg" = "01;35";
        "*.jpg" = "01;35";
        "*.png" = "01;35";
        "*.webp" = "01;35";
        "*.pot" = "01;35";
        "*.pcb" = "01;35";
        "*.gbr" = "01;35";
        "*.scm" = "01;35";
        "*.xcf" = "01;35";
        "*.spl" = "01;35";
        "*.stl" = "01;35";
        "*.dwg" = "01;35";
        "*.ply" = "01;35";
        "*.apk" = "01;31";
        "*.deb" = "01;31";
        "*.rpm" = "01;31";
        "*.jad" = "01;31";
        "*.jar" = "01;31";
        "*.crx" = "01;31";
        "*.xpi" = "01;31";
        "*.avi" = "01;35";
        "*.divx" = "01;35";
        "*.m2v" = "01;35";
        "*.m4v" = "01;35";
        "*.mkv" = "01;35";
        "*.MOV" = "01;35";
        "*.mov" = "01;35";
        "*.mp4" = "01;35";
        "*.mpeg" = "01;35";
        "*.mpg" = "01;35";
        "*.sample" = "01;35";
        "*.wmv" = "01;35";
        "*.3g2" = "01;35";
        "*.3gp" = "01;35";
        "*.gp3" = "01;35";
        "*.webm" = "01;35";
        "*.flv" = "01;35";
        "*.ogv" = "01;35";
        "*.f4v" = "01;35";
        "*.3ga" = "01;35";
        "*.aac" = "01;35";
        "*.m4a" = "01;35";
        "*.mp3" = "01;35";
        "*.mp4a" = "01;35";
        "*.oga" = "01;35";
        "*.ogg" = "01;35";
        "*.wma" = "01;35";
        "*.flac" = "01;35";
        "*.alac" = "01;35";
        "*.mid" = "01;35";
        "*.midi" = "01;35";
        "*.pcm" = "01;35";
        "*.wav" = "01;35";
        "*.ass" = "01;33";
        "*.srt" = "01;33";
        "*.ssa" = "01;33";
        "*.sub" = "01;33";
        "*.git" = "01;33";
        "*README" = "33";
        "*README.rst" = "33";
        "*README.md" = "33";
        "*LICENSE" = "33";
        "*COPYING" = "33";
        "*INSTALL" = "33";
        "*COPYRIGHT" = "33";
        "*AUTHORS" = "33";
        "*HISTORY" = "33";
        "*CONTRIBUTOS" = "33";
        "*PATENTS" = "33";
        "*VERSION" = "33";
        "*NOTICE" = "33";
        "*CHANGES" = "33";
        "*CHANGELOG" = "33";
        "*log" = "33";
        "*.txt" = "33";
        "*.md" = "33";
        "*.markdown" = "33";
        "*.nfo" = "33";
        "*.org" = "33";
        "*.pod" = "33";
        "*.rst" = "33";
        "*.tex" = "33";
        "*.texttile" = "33";
        "*.bib" = "35";
        "*.json" = "35";
        "*.jsonl" = "35";
        "*.jsonnet" = "35";
        "*.libsonnet" = "35";
        "*.rss" = "35";
        "*.xml" = "35";
        "*.fxml" = "35";
        "*.toml" = "35";
        "*.yaml" = "35";
        "*.yml" = "35";
        "*.dtd" = "35";
        "*.cbr" = "35";
        "*.cbz" = "35";
        "*.chm" = "35";
        "*.pdf" = "35";
        "*.PDF" = "35";
        "*.epub" = "35";
        "*.awk" = "35";
        "*.bash" = "35";
        "*.bat" = "35";
        "*.BAT" = "35";
        "*.sed" = "35";
        "*.sh" = "35";
        "*.zsh" = "35";
        "*.vim" = "35";
        "*.py" = "35";
        "*.ipynb" = "35";
        "*.rb" = "35";
        "*.gemspec" = "35";
        "*.pl" = "35";
        "*.PL" = "35";
        "*.t" = "35";
        "*.msql" = "35";
        "*.mysql" = "35";
        "*.pgsql" = "35";
        "*.sql" = "35";
        "*.r" = "35";
        "*.R" = "35";
        "*.cljw" = "35";
        "*.scala" = "35";
        "*.sc" = "35";
        "*.dart" = "35";
        "*.asm" = "35";
        "*.cl" = "35";
        "*.lisp" = "35";
        "*.rkt" = "35";
        "*.el" = "35";
        "*.elc" = "35";
        "*.eln" = "35";
        "*.lua" = "35";
        "*.c" = "35";
        "*.C" = "35";
        "*.h" = "35";
        "*.H" = "35";
        "*.tcc" = "35";
        "*.c++" = "35";
        "*.h++" = "35";
        "*.hpp" = "35";
        "*.hxx" = "35";
        "*ii." = "35";
        "*.m" = "35";
        "*.M" = "35";
        "*.cc" = "35";
        "*.cs" = "35";
        "*.cp" = "35";
        "*.cpp" = "35";
        "*.cxx" = "35";
        "*.go" = "35";
        "*.f" = "35";
        "*.F" = "35";
        "*.nim" = "35";
        "*.nimble" = "35";
        "*.s" = "35";
        "*.S" = "35";
        "*.rs" = "35";
        "*.scpt" = "35";
        "*.swift" = "35";
        "*.vala" = "35";
        "*.vapi" = "35";
        "*.hs" = "35";
        "*.lhs" = "35";
        "*.zig" = "35";
        "*.v" = "35";
        "*.pyc" = "35";
        "*.tf" = "35";
        "*.tfstate" = "35";
        "*.tfvars" = "35";
        "*.css" = "35";
        "*.less" = "35";
        "*.sass" = "35";
        "*.scss" = "35";
        "*.htm" = "35";
        "*.html" = "35";
        "*.jhtm" = "35";
        "*.mht" = "35";
        "*.eml" = "35";
        "*.coffee" = "35";
        "*.java" = "35";
        "*.js" = "35";
        "*.mjs" = "35";
        "*.jsm" = "35";
        "*.jsp" = "35";
        "*.rasi" = "35";
        "*.php" = "35";
        "*.twig" = "35";
        "*.vb" = "35";
        "*.vba" = "35";
        "*.vbs" = "35";
        "*.Dockerfile" = "35";
        "*.dockerignore" = "35";
        "*.Makefile" = "35";
        "*.MANIFEST" = "35";
        "*.am" = "35";
        "*.in" = "35";
        "*.hin" = "35";
        "*.scan" = "35";
        "*.m4" = "35";
        "*.old" = "35";
        "*.out" = "35";
        "*.SKIP" = "35";
        "*.diff" = "35";
        "*.patch" = "35";
        "*.tmpl" = "35";
        "*.j2" = "35";
        "*PKGBUILD" = "35";
        "*config" = "35";
        "*.conf" = "35";
        "*.service" = "31";
        "*.@.service" = "31";
        "*.socket" = "31";
        "*.swap" = "31";
        "*.device" = "31";
        "*.mount" = "31";
        "*.automount" = "31";
        "*.target" = "31";
        "*.path" = "31";
        "*.timer" = "31";
        "*.snapshot" = "31";
        "*.allow" = "31";
        "*.swp" = "31";
        "*.swo" = "31";
        "*.tmp" = "31";
        "*.pid" = "31";
        "*.state" = "31";
        "*.lock" = "31";
        "*.lockfile" = "31";
        "*.pacnew" = "31";
        "*.un" = "31";
        "*.orig" = "31";
      };
    };
  };
}


================================================
FILE: home/_modules/shell/fish/default.nix
================================================
{
  lib,
  config,
  osConfig,
  pkgs,
  myPkgs,
  ...
}:
let
  inherit (lib) myLib mkEnableOption mkIf;

  cfg = config.myHome.shell.fish;
  isNixos = myLib.isNixos osConfig;
in
{
  options.myHome.shell.fish = {
    enable = mkEnableOption "fish shell";
  };

  config = mkIf (cfg.enable) {
    myHome.shell = {
      dircolors.enable = true;
      starship.enable = true;
    };

    catppuccin = {
      fish.enable = true;
      # TODO: wait for the IFD issue is fixed
      # ref: https://github.com/catppuccin/nix/issues/392
      fzf.enable = mkIf (pkgs.stdenv.hostPlatform.system == "x86_64-linux") true;
      bat.enable = true;
    };

    programs = {
      fish = {
        enable = true;
        package = mkIf (!isNixos) (
          pkgs.fish.override {
            fishEnvPreInit = ''
              # This will ensure that $NIX_PROFILE variable is set as fast as possible
              # so Nix managed programs can work properly without needing to tweak the OS.
              # Usually this is done by Nix installer by putting these lines inside fish system config dir
              # but it's a hit or miss especially when fish is not installed in the system beforehand.
              # And I also found problem that vendor completion of Nix installed programs are not working
              # without calling fish twice, I assume it's because $NIX_PROFILE is not set fast enough
              if test -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.fish'
                . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.fish'
              end
            '';
          }
        );
        plugins =
          with pkgs.fishPlugins;
          [
            {
              name = "autopair";
              src = autopair.src;
            }
            {
              # TODO: might be better off use native fzf support
              name = "fzf-fish";
              src = fzf-fish.src;
            }
            {
              name = "puffer";
              src = puffer.src;
            }
            {
              name = "abbreviation-tips";
              src = myPkgs.fish-plugins.abbreviation-tips.src;
            }
            {
              name = "fish-completion-sync";
              src = myPkgs.fish-plugins.fish-completion-sync.src;
            }
          ]
          ++ [
            (mkIf (config.programs.tmux.enable && !config.programs.zellij.enable) {
              name = "tmux-fish";
              src = myPkgs.fish-plugins.tmux-fish.src;
            })
          ];

        functions = {
          mkcd = {
            body = "mkdir -p $argv; cd $argv";
            description = "mkdir and cd into in";
          };
        };

        shellInit = ''
          # disable fish greeting
          set -g fish_greeting

          # Termite and Alacritty tmux ssh error workaround
          if test $TERM = xterm-termite; or test $TERM = alacritty
            set -gx TERM xterm-256color
          end
        '';

        interactiveShellInit = ''
          # use vi keybindings
          fish_vi_key_bindings

          # fzf-fish
          set fzf_preview_dir_cmd eza --all --color=always
          set fzf_fd_opts --hidden --exclude=.git --exclude=.github --exclude=.cache
          fzf_configure_bindings --git_log=\cg --git_status=\cs --variables=\cv --directory=\cf --history=\cr

          ${lib.optionalString config.programs.tmux.enable "set fish_tmux_autostart true"}
        '';

        shellAbbrs = {
          cpr = "cp -rf";
          rmr = "rm -rf";
          md = "mdir -p";
          rd = "rmdir";

          # eza
          lsa = "eza -lag --git --icons --sort=type";
          ll = "eza -l --git --icons --sort = type";
        };
      };

      zoxide.enable = true;
      bat.enable = true;

      fzf = {
        enable = true;
        defaultCommand = "${pkgs.fd}/bin/fd --type f";
        defaultOptions = [
          "--cycle"
          "--layout reverse"
          "--border"
          "--height 40%"
          "--preview-window wrap"
          "--marker *"
        ];
        changeDirWidgetCommand = "${pkgs.fd}/bin/fd --type d";
        changeDirWidgetOptions = [ "--preview 'tree -C {} | head -200'" ];
      };
    };
    home.packages = with pkgs; [
      eza
      fd
    ];
  };
}


================================================
FILE: home/_modules/shell/git/default.nix
================================================
{
  config,
  lib,
  options,
  ...
}:
let
  cfg = config.myHome.shell.git;
  inherit (lib)
    mkEnableOption
    mkOption
    mkIf
    ;
in
{
  options.myHome.shell.git = {
    enable = mkEnableOption "git";
    config = mkOption {
      type = options.programs.git.extraConfig.type;
      default = options.programs.git.extraConfig.default;
    };
  };

  config = mkIf (cfg.enable) {
    programs.git = {
      enable = true;
      settings = cfg.config;
    };

    programs.gh = {
      enable = true;
      settings = {
        # https://github.com/nix-community/home-manager/issues/4744
        version = 1;
      };
    };

    programs.fish.shellAbbrs = {
      g = "git";
      ga = "git add .";
      gaa = "git add --all";
      gc = "git commit";
      gcm = "git commit -m";
      gs = "git status";
      gp = "git push";
      gpl = "git pull";
      gl = "git log";
      gd = "git diff";
      gds = "git diff --staged";
      gr = "git restore .";
      grs = "git restore --staged .";
    };
  };
}


================================================
FILE: home/_modules/shell/lf/configs/colors
================================================
# vim:ft=dircolors
# (This is not a dircolors file but it helps to highlight colors and comments)

# default values from dircolors
# (entries with a leading # are not implemented in lf)
# #no     00              # NORMAL
# fi      00              # FILE
# #rs     0               # RESET
# di      01;34           # DIR
# ln      01;36           # LINK
# #mh     00              # MULTIHARDLINK
# pi      40;33           # FIFO
# so      01;35           # SOCK
# #do     01;35           # DOOR
# bd      40;33;01        # BLK
# cd      40;33;01        # CHR
# or      40;31;01        # ORPHAN
# #mi     00              # MISSING
# su      37;41           # SETUID
# sg      30;43           # SETGID
# #ca     30;41           # CAPABILITY
# tw      30;42           # STICKY_OTHER_WRITABLE
# ow      34;42           # OTHER_WRITABLE
# st      37;44           # STICKY
# ex      01;32           # EXEC

# default values from lf (with matching order)
# ln      01;36   # LINK
# or      31;01   # ORPHAN
# tw      01;34   # STICKY_OTHER_WRITABLE
# ow      01;34   # OTHER_WRITABLE
# st      01;34   # STICKY
# di      01;34   # DIR
# pi      33      # FIFO
# so      01;35   # SOCK
# bd      33;01   # BLK
# cd      33;01   # CHR
# su      01;32   # SETUID
# sg      01;32   # SETGID
# ex      01;32   # EXEC
# fi      00      # FILE

# file types (with matching order)
ln      01;36   # LINK
or      31;01   # ORPHAN
tw      34      # STICKY_OTHER_WRITABLE
ow      34      # OTHER_WRITABLE
st      01;34   # STICKY
di      01;34   # DIR
pi      33      # FIFO
so      01;35   # SOCK
bd      33;01   # BLK
cd      33;01   # CHR
su      01;32   # SETUID
sg      01;32   # SETGID
ex      01;32   # EXEC
fi      00      # FILE

# archives or compressed (dircolors defaults)
*.tar   01;31
*.tgz   01;31
*.arc   01;31
*.arj   01;31
*.taz   01;31
*.lha   01;31
*.lz4   01;31
*.lzh   01;31
*.lzma  01;31
*.tlz   01;31
*.txz   01;31
*.tzo   01;31
*.t7z   01;31
*.zip   01;31
*.z     01;31
*.dz    01;31
*.gz    01;31
*.lrz   01;31
*.lz    01;31
*.lzo   01;31
*.xz    01;31
*.zst   01;31
*.tzst  01;31
*.bz2   01;31
*.bz    01;31
*.tbz   01;31
*.tbz2  01;31
*.tz    01;31
*.deb   01;31
*.rpm   01;31
*.jar   01;31
*.war   01;31
*.ear   01;31
*.sar   01;31
*.rar   01;31
*.alz   01;31
*.ace   01;31
*.zoo   01;31
*.cpio  01;31
*.7z    01;31
*.rz    01;31
*.cab   01;31
*.wim   01;31
*.swm   01;31
*.dwm   01;31
*.esd   01;31

# image formats (dircolors defaults)
*.jpg   01;35
*.jpeg  01;35
*.mjpg  01;35
*.mjpeg 01;35
*.gif   01;35
*.bmp   01;35
*.pbm   01;35
*.pgm   01;35
*.ppm   01;35
*.tga   01;35
*.xbm   01;35
*.xpm   01;35
*.tif   01;35
*.tiff  01;35
*.png   01;35
*.svg   01;35
*.svgz  01;35
*.mng   01;35
*.pcx   01;35
*.mov   01;35
*.mpg   01;35
*.mpeg  01;35
*.m2v   01;35
*.mkv   01;35
*.webm  01;35
*.ogm   01;35
*.mp4   01;35
*.m4v   01;35
*.mp4v  01;35
*.vob   01;35
*.qt    01;35
*.nuv   01;35
*.wmv   01;35
*.asf   01;35
*.rm    01;35
*.rmvb  01;35
*.flc   01;35
*.avi   01;35
*.fli   01;35
*.flv   01;35
*.gl    01;35
*.dl    01;35
*.xcf   01;35
*.xwd   01;35
*.yuv   01;35
*.cgm   01;35
*.emf   01;35
*.ogv   01;35
*.ogx   01;35

# audio formats (dircolors defaults)
*.aac   00;36
*.au    00;36
*.flac  00;36
*.m4a   00;36
*.mid   00;36
*.midi  00;36
*.mka   00;36
*.mp3   00;36
*.mpc   00;36
*.ogg   00;36
*.ra    00;36
*.wav   00;36
*.oga   00;36
*.opus  00;36
*.spx   00;36
*.xspf  00;36


================================================
FILE: home/_modules/shell/lf/configs/icons
================================================
# vim:ft=conf

# These examples require Nerd Fonts or a compatible font to be used.
# See https://www.nerdfonts.com for more information.

# default values from lf (with matching order)
# ln      l       # LINK
# or      l       # ORPHAN
# tw      t       # STICKY_OTHER_WRITABLE
# ow      d       # OTHER_WRITABLE
# st      t       # STICKY
# di      d       # DIR
# pi      p       # FIFO
# so      s       # SOCK
# bd      b       # BLK
# cd      c       # CHR
# su      u       # SETUID
# sg      g       # SETGID
# ex      x       # EXEC
# fi      -       # FILE

# file types (with matching order)
ln             # LINK
or             # ORPHAN
tw      t       # STICKY_OTHER_WRITABLE
ow             # OTHER_WRITABLE
st      t       # STICKY
di             # DIR
pi      p       # FIFO
so      s       # SOCK
bd      b       # BLK
cd      c       # CHR
su      u       # SETUID
sg      g       # SETGID
ex             # EXEC
fi             # FILE

# file extensions (vim-devicons)
*.styl          
*.sass          
*.scss          
*.htm           
*.html          
*.slim          
*.haml          
*.ejs           
*.css           
*.less          
*.md            
*.mdx           
*.markdown      
*.rmd           
*.json          
*.webmanifest   
*.js            
*.mjs           
*.jsx           
*.rb            
*.gemspec       
*.rake          
*.php           
*.py            
*.pyc           
*.pyo           
*.pyd           
*.coffee        
*.mustache      
*.hbs           
*.conf          
*.ini           
*.yml           
*.yaml          
*.toml          
*.bat           
*.mk            
*.jpg           
*.jpeg          
*.bmp           
*.png           
*.webp          
*.gif           
*.ico           
*.twig          
*.cpp           
*.c++           
*.cxx           
*.cc            
*.cp            
*.c             
*.cs            
*.h             
*.hh            
*.hpp           
*.hxx           
*.hs            
*.lhs           
*.nix           
*.lua           
*.java          
*.sh            
*.fish          
*.bash          
*.zsh           
*.ksh           
*.csh           
*.awk           
*.ps1           
*.ml            λ
*.mli           λ
*.diff          
*.db            
*.sql           
*.dump          
*.clj           
*.cljc          
*.cljs          
*.edn           
*.scala         
*.go            
*.dart          
*.xul           
*.sln           
*.suo           
*.pl            
*.pm            
*.t             
*.rss           
'*.f#'          
*.fsscript      
*.fsx           
*.fs            
*.fsi           
*.rs            
*.rlib          
*.d             
*.erl           
*.hrl           
*.ex            
*.exs           
*.eex           
*.leex          
*.heex          
*.vim           
*.ai            
*.psd           
*.psb           
*.ts            
*.tsx           
*.jl            
*.pp            
*.vue           
*.elm           
*.swift         
*.xcplayground  
*.tex           ﭨ
*.r             ﳒ
*.rproj         鉶
*.sol           ﲹ
*.pem           

# file names (vim-devicons) (case-insensitive not supported in lf)
*gruntfile.coffee       
*gruntfile.js           
*gruntfile.ls           
*gulpfile.coffee        
*gulpfile.js            
*gulpfile.ls            
*mix.lock               
*dropbox                
*.ds_store              
*.gitconfig             
*.gitignore             
*.gitattributes         
*.gitlab-ci.yml         
*.bashrc                
*.zshrc                 
*.zshenv                
*.zprofile              
*.vimrc                 
*.gvimrc                
*_vimrc                 
*_gvimrc                
*.bashprofile           
*favicon.ico            
*license                
*node_modules           
*react.jsx              
*procfile               
*dockerfile             
*docker-compose.yml     
*rakefile               
*config.ru              
*gemfile                
*makefile               
*cmakelists.txt         
*robots.txt             ﮧ

# file names (case-sensitive adaptations)
*Gruntfile.coffee       
*Gruntfile.js           
*Gruntfile.ls           
*Gulpfile.coffee        
*Gulpfile.js            
*Gulpfile.ls            
*Dropbox                
*.DS_Store              
*LICENSE                
*React.jsx              
*Procfile               
*Dockerfile             
*Docker-compose.yml     
*Rakefile               
*Gemfile                
*Makefile               
*CMakeLists.txt         

# file patterns (vim-devicons) (patterns not supported in lf)
# .*jquery.*\.js$         
# .*angular.*\.js$        
# .*backbone.*\.js$       
# .*require.*\.js$        
# .*materialize.*\.js$    
# .*materialize.*\.css$   
# .*mootools.*\.js$       
# .*vimrc.*               
# Vagrantfile$            

# file patterns (file name adaptations)
*jquery.min.js          
*angular.min.js         
*backbone.min.js        
*require.min.js         
*materialize.min.js     
*materialize.min.css    
*mootools.min.js        
*vimrc                  
Vagrantfile             

# archives or compressed (extensions from dircolors defaults)
*.tar   
*.tgz   
*.arc   
*.arj   
*.taz   
*.lha   
*.lz4   
*.lzh   
*.lzma  
*.tlz   
*.txz   
*.tzo   
*.t7z   
*.zip   
*.z     
*.dz    
*.gz    
*.lrz   
*.lz    
*.lzo   
*.xz    
*.zst   
*.tzst  
*.bz2   
*.bz    
*.tbz   
*.tbz2  
*.tz    
*.deb   
*.rpm   
*.jar   
*.war   
*.ear   
*.sar   
*.rar   
*.alz   
*.ace   
*.zoo   
*.cpio  
*.7z    
*.rz    
*.cab   
*.wim   
*.swm   
*.dwm   
*.esd   

# image formats (extensions from dircolors defaults)
*.jpg   
*.jpeg  
*.mjpg  
*.mjpeg 
*.gif   
*.bmp   
*.pbm   
*.pgm   
*.ppm   
*.tga   
*.xbm   
*.xpm   
*.tif   
*.tiff  
*.png   
*.svg   
*.svgz  
*.mng   
*.pcx   
*.mov   
*.mpg   
*.mpeg  
*.m2v   
*.mkv   
*.webm  
*.ogm   
*.mp4   
*.m4v   
*.mp4v  
*.vob   
*.qt    
*.nuv   
*.wmv   
*.asf   
*.rm    
*.rmvb  
*.flc   
*.avi   
*.fli   
*.flv   
*.gl    
*.dl    
*.xcf   
*.xwd   
*.yuv   
*.cgm   
*.emf   
*.ogv   
*.ogx   

# audio formats (extensions from dircolors defaults)
*.aac   
*.au    
*.flac  
*.m4a   
*.mid   
*.midi  
*.mka   
*.mp3   
*.mpc   
*.ogg   
*.ra    
*.wav   
*.oga   
*.opus  
*.spx   
*.xspf  

# other formats
*.pdf   


================================================
FILE: home/_modules/shell/lf/default.nix
================================================
{
  pkgs,
  lib,
  config,
  ...
}:
let
  myHome = config.myHome;
  cfg = myHome.shell.lf;
in
{
  options.myHome.shell.lf = {
    enable = lib.mkEnableOption "lf";
  };

  config = lib.mkIf (cfg.enable) {
    myHome.shell.dircolors.enable = true;

    xdg.configFile."lf/colors".source = ./configs/colors;
    xdg.configFile."lf/icons".source = ./configs/icons;
    programs.lf = {
      enable = true;
      keybindings = {
        "D" = "delete";
        "n" = "";
        "nd" = "push :newdir<space>";
        "nf" = "push :newfile<space>";
        "gf" = ":fzf_search";
        "gz" = "push :z<space>";
      };
      extraConfig = ''
        # previews
        set previewer ${pkgs.ctpv}/bin/ctpv
        set cleaner ${pkgs.ctpv}/bin/ctpvclear
        &${pkgs.ctpv}/bin/ctpv -s $id
        &${pkgs.ctpv}/bin/ctpvquit $id

        cmd newdir %{{
          ${pkgs.coreutils}/bin/mkdir "$@"
          lf -remote "send $id select \"$@\""
        }}

        cmd newfile %{{
          ${pkgs.coreutils}/bin/touch "$@"
          lf -remote "send $id select \"$@\""
        }}

        # zoxide
        cmd z %{{
          result="$(${pkgs.zoxide}/bin/zoxide query --exclude $PWD $@)"
          lf -remote "send $id cd \"$result\""
        }}

        # fzf with ripgrep
        cmd fzf_search ''${{
          res="$( \
            RG_PREFIX="${pkgs.ripgrep}/bin/rg --column --line-number --no-heading --color=always \
              --smart-case "
            FZF_DEFAULT_COMMAND="$RG_PREFIX '''" \
              ${pkgs.fzf}/bin/fzf --bind "change:reload:$RG_PREFIX {q} || true" \
              --ansi --layout=reverse --header 'Search in files' \
              | cut -d':' -f1
          )"
          [ ! -z "$res" ] && lf -remote "send $id select \"$res\""
        }}

        # opening files
        cmd open ''${{
          case $(${pkgs.file}/bin/file --mime-type -Lb "$f") in
            # text files
            text/*|application/json)
              $EDITOR "$fx";;

            # archive files
            application/x-bzip*|application/*zip|application/x-xz|application/x-rar|application/x-*-image)
              mntdir="$f-archivemount"
              [ ! -d "$mntdir" ] && {
                mkdir "$mntdir"
                ${pkgs.archivemount}/bin/archivemount "$f" "$mntdir"
                echo "$mntdir" >> "/tmp/__lf_archivemount_$id"
              }
              lf -remote "send $id cd \"$mntdir\""
              lf -remote "send $id reload"
              ;;
          esac
        }}

        # umount archives on quit
        cmd on-quit ''${{
          archivemount_dir="/tmp/__lf_archivemount_$id"
          if [ -f "$archivemount_dir" ]; then
            cat "$archivemount_dir" | \
              while read -r line; do
                /run/wrappers/bin/sudo ${pkgs.umount}/bin/umount "$line"
                ${pkgs.coreutils}/bin/rmdir "$line"
              done
            rm -f "$archivemount_dir"
          fi
        }}

        # dynamically set number of columns
        ''${{
          w=$(${pkgs.ncurses}/bin/tput cols)
          if [ "$w" -le 80 ]; then
            lf -remote "send $id set ratios 1:2"
          elif [ "$w" -le 160 ]; then
            lf -remote "send $id set ratios 1:2:3"
          else
            lf -remote "send $id set ratios 1:2:3:5"
          fi
        }}
      '';
      settings = {
        icons = true;
        drawbox = true;
      };
    };

    home.packages = with pkgs; [
      chafa
      poppler-utils
      ffmpegthumbnailer
    ];
  };
}


================================================
FILE: home/_modules/shell/nix-direnv/default.nix
================================================
{ config, lib, ... }:
let
  cfg = config.myHome.shell.nix-direnv;
in
{
  options.myHome.shell.nix-direnv = {
    enable = lib.mkEnableOption "nix-direnv";
  };

  config = lib.mkIf (cfg.enable) {
    programs.direnv = {
      enable = true;
      nix-direnv.enable = true;
    };
    home.sessionVariables.DIRENV_LOG_FORMAT = "";
  };
}


================================================
FILE: home/_modules/shell/starship/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.shell.starship;
in
{
  options.myHome.shell.starship = {
    enable = lib.mkEnableOption "Starship cross-shell prompt";
  };

  config = lib.mkIf (cfg.enable) {
    # TODO: wait for the IFD issue is fixed
    # ref: https://github.com/catppuccin/nix/issues/392
    catppuccin.starship.enable = lib.mkIf (pkgs.stdenv.hostPlatform.system == "x86_64-linux") true;

    programs.starship = {
      enable = true;
      settings = {
        add_newline = false;
        command_timeout = 1000;
        format = lib.concatStrings [
          "$os"
          "$username"
          "$hostname"
          "$directory"
          "$git_branch"
          "$git_status"
          "$fill"
          "$direnv"
          "$nix_shell"
          "$python"
          "$cmd_duration"
          "$status"
          "$line_break"
          "$character"
        ];

        os = {
          disabled = false;
          format = "[](fg:blue)[ $symbol ](fg:mantle bg:blue)[](fg:blue bg:surface0)";
          symbols = {
            Arch = "󰣇 ";
            NixOS = "󱄅 ";
            Ubuntu = " ";
          };
        };

        username = {
          style_user = "fg:peach bg:surface0";
          style_root = "fg:red bg:surface0";
          format = "[ $user]($style)";
          show_always = false;
        };

        hostname = {
          ssh_only = true;
          format = "[@$hostname](fg:green bg:surface0)";
        };

        directory = {
          truncation_length = 3;
          format = "[ in](fg:text bg:surface0)[ $path ](fg:blue bg:surface0)([$read_only ](fg:red bg:surface0))[](fg:surface0)";
          read_only = "";
          truncation_symbol = "../";
          truncate_to_repo = true;
          fish_style_pwd_dir_length = 1;
        };

        git_branch = {
          format = "[ $symbol$branch ](fg:mauve)";
          symbol = " ";
        };

        git_status = {
          format = "[$all_status$ahead_behind](fg:mauve)";
          conflicted = " ";
          ahead = " ";
          behind = " ";
          diverged = "󰆗 ";
          up_to_date = " ";
          untracked = " ";
          stashed = " ";
          modified = " ";
          staged = " ";
          renamed = " ";
          deleted = " ";
        };

        fill = {
          symbol = " ";
        };

        direnv = {
          disabled = false;
          format = "[$symbol\\($loaded/$allowed\\) ](fg:blue)";
          symbol = "  ";
        };

        nix_shell = {
          format = "[$symbol(\\($name\\)) ](fg:blue)";
          heuristic = true; # needed to detect `nix shell`
          symbol = "󱄅 "; # the default unicode is causing issue https://github.com/starship/starship/issues/5924
        };

        python = {
          format = "[\${symbol}\${pyenv_prefix}(\${version} )(\($virtualenv\) )]($style)";
          symbol = "🐍 ";
        };

        cmd_duration = {
          min_time = 0;
          format = "[](fg:surface0)[ took](fg:text bg:surface0)[ $duration ](fg:yellow bg:surface0)";
        };

        status = {
          disabled = false;
          format = "[](fg:blue bg:surface0)[ $symbol](fg:mantle bg:blue)[](fg:blue)";
          symbol = " ";
          success_symbol = " ";
        };

        character = {
          success_symbol = "[](green)";
          error_symbol = "[](green)";
          vicmd_symbol = "[](mauve)";
        };
      };
    };
  };
}


================================================
FILE: home/_modules/terminal-emulator/alacritty/default.nix
================================================
{
  lib,
  config,
  pkgs,
  ...
}:
with lib;
let
  cfg = config.myHome.terminal-emulator.alacritty;
in
{
  options.myHome.terminal-emulator.alacritty = {
    enable = mkEnableOption "alacritty";
  };

  config = mkIf (cfg.enable) {
    catppuccin.alacritty.enable = true;

    programs.alacritty = {
      enable = true;
      package = (config.lib.nixGL.wrap pkgs.alacritty);
      settings = {
        general.live_config_reload = true;
        env.TERM = "xterm-256color";
        window = {
          padding = {
            x = 10;
            y = 10;
          };
          dynamic_padding = true;
          decorations = "none";
          startup_mode = "Maximized";
        };
        scrolling.history = 10000;
        font = {
          size = 12.0;
          normal = {
            family = "UbuntuMono Nerd Font";
            style = "Regular";
          };
        };
        colors = {
          draw_bold_text_with_bright_colors = false;
        };
        bell.duration = 0;
      };
    };
  };
}


================================================
FILE: home/_modules/terminal-emulator/contour/config/contour.yml
================================================
---
on_mouse_select: CopyToSelectionClipboard
profiles:
  main:
    show_title_bar: false
    maximized: true
    environment:
      TERM: xterm-256color
      COLORTERM: truecolor
    margins:
      horizontal: 10
      vertical: 10
    history:
      limit: 10000
      auto_scroll_on_update: true
      scroll_multiplier: 3
    scrollbar:
      position: Hidden
    mouse:
      hide_while_typing: true
    font:
      # using 12 causes the underscore and long characters to cut off
      # https://github.com/contour-terminal/contour/issues/1603
      size: 12.1
      regular:
        family: UbuntuMono Nerd Font
        weight: normal
        slant: normal
      emoji: emoji
    draw_bold_text_with_bright_colors: false
    cursor:
      shape: rectangle
      blinking: false
    vi_mode_highlight_timeout: 300
    vi_mode_scrolloff: 8
    status_line:
      display: none
    colors: catppuccin_mocha
    hyperlink_decoration:
      normal: dotted
      hover: underline
color_schemes:
  catppuccin_mocha:
    default:
      background: "#1E1E2E" # base
      foreground: "#CDD6F4" # text
    cursor:
      default: "#F5E0DC" # rosewater
      text: "#1E1E2E" # base
    normal:
      black: "#45475A" # surface1
      red: "#F38BA8" # red
      green: "#A6E3A1" # green
      yellow: "#F9E2AF" # yellow
      blue: "#89B4FA" # blue
      magenta: "#F5C2E7" # pink
      cyan: "#94E2D5" # teal
      white: "#BAC2DE" # subtext1
    bright:
      black: "#585B70" # surface2
      red: "#F38BA8" # red
      green: "#A6E3A1" # green
      yellow: "#F9E2AF" # yellow
      blue: "#89B4FA" # blue
      magenta: "#F5C2E7" # pink
      cyan: "#94E2D5" # teal
      white: "#A6ADC8" # subtext0
    vi_mode_highlight:
      foreground: CellForeground
      background: "#1E1E2E" # base
    vi_mode_cursorline:
      foreground: CellForeground
      background: "#585B70" # surface2
      background_alpha: 0.1
    selection:
      foreground: CellForeground
      background: "#585B70" # surface2
    indicator_statusline:
      foreground: CellForeground
      background: "#89B4FA" # blue

input_mapping:
  - { mods: [Control, Shift], key: Plus, action: IncreaseFontSize }
  - { mods: [Control, Shift], key: Minus, action: DecreaseFontSize }
  - { mods: [Control], key: Backspace, action: ResetFontSize }
  - { mods: [Control, Shift], key: V, action: PasteClipboard, strip: false }
  - { mods: [Control, Shift], key: C, action: ViNormalMode, mode: "Insert" }


================================================
FILE: home/_modules/terminal-emulator/contour/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.terminal-emulator.contour;
in
{
  options.myHome.terminal-emulator.contour = {
    enable = lib.mkEnableOption "Contour Terminal Emulator";
  };

  config = lib.mkIf (cfg.enable) {
    home.packages = [ (config.lib.nixGL.wrap pkgs.contour) ];
    xdg.configFile."contour".source = ./config;
  };
}


================================================
FILE: home/_modules/terminal-emulator/kitty/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.terminal-emulator.kitty;
in
{
  options.myHome.terminal-emulator.kitty = {
    enable = lib.mkEnableOption "kitty";
  };

  config = lib.mkIf (cfg.enable) {
    programs.kitty = {
      enable = true;
      package = (config.lib.nixGL.wrap pkgs.kitty);
      catppuccin.enable = true;
      font = {
        name = "UbuntuMono Nerd Font";
        size = 12;
      };
      settings = {
        # Cursor
        cursor = "#C0CAF5";
        cursor_text_color = "#202124";
        cursor_shape = "underline";
        cursor_blink_interval = "-1";

        # Scrollback
        scrollback_lines = 10000;

        # Mouse
        mouse_hide_wait = "-1";
        url_color = "#73DACA";
        url_style = "curly";

        #Terminal bell
        enable_audio_bell = "no";
        visual_bell_duration = 0;

        # Window layout
        window_padding_width = 4;
        confirm_os_window_close = 0;

        # Advanced
        allow_remote_control = "no";
        shell_integration = "disabled";
        term = "xterm-256color";
      };
    };
  };
}


================================================
FILE: home/_modules/terminal-emulator/wezterm/config/wezterm.lua
================================================
local wezterm = require 'wezterm'
local act = wezterm.action

-- Start window maximized
wezterm.on("gui-startup", function(cmd)
  local _, _, window = wezterm.mux.spawn_window(cmd or {})
  window:gui_window():maximize()
end)

return {
  -- Fonts
  font = wezterm.font("UbuntuMono Nerd Font"),
  font_size = 12.0,

  -- Appearance
  color_scheme = "Catppuccin Mocha",
  window_decorations = "RESIZE",
  enable_tab_bar = false,
  enable_scroll_bar = false,
  warn_about_missing_glyphs = false,
  window_close_confirmation = "NeverPrompt",
  enable_wayland = false, -- this fixes weird issues that I don't understand why it's happening

  -- Window layout
  window_padding = {
    left = "1cell",
    right = "1cell",
    top = "0.5cell",
    bottom = "0.5cell",
  },

  -- Keyboard shortcuts
  disable_default_key_bindings = true,
  keys = {
    { key = "C",         mods = "CTRL|SHIFT", action = act.ActivateCopyMode },
    { key = "V",         mods = "CTRL|SHIFT", action = act.PasteFrom("Clipboard") },
    { key = "+",         mods = "CTRL|SHIFT", action = act.IncreaseFontSize },
    { key = "_",         mods = "CTRL|SHIFT", action = act.DecreaseFontSize },
    { key = "Backspace", mods = "CTRL|SHIFT", action = act.ResetFontSize },
  },
}


================================================
FILE: home/_modules/terminal-emulator/wezterm/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.terminal-emulator.wezterm;
in
{
  options.myHome.terminal-emulator.wezterm = {
    enable = lib.mkEnableOption "WezTerm";
  };

  config = lib.mkIf (cfg.enable) {
    programs.wezterm = {
      enable = true;
      package = (config.lib.nixGL.wrap pkgs.wezterm);
      extraConfig = builtins.readFile ./config/wezterm.lua;
    };
    home.packages = [ (config.lib.nixGL.wrap pkgs.contour) ];
  };
}


================================================
FILE: home/_modules/windowmanager/add-on/blueman-applet/default.nix
================================================
{ config, lib, ... }:
let
  myHome = config.myHome;
  cfg = myHome.windowmanager.add-on.blueman-applet;
in
{
  options.myHome.windowmanager.add-on.blueman-applet = {
    enable = lib.mkEnableOption "blueman-applet";
  };

  config = lib.mkIf (cfg.enable) { services.blueman-applet.enable = true; };
}


================================================
FILE: home/_modules/windowmanager/add-on/dunst/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.windowmanager.add-on.dunst;
in
{
  options.myHome.windowmanager.add-on.dunst = {
    enable = lib.mkEnableOption "dunst";
  };

  config = lib.mkIf (cfg.enable) {
    home.packages = [ pkgs.libnotify ];
    services.dunst = {
      enable = true;
      settings = {
        global = {
          follow = "mouse";
          width = 300;
          height = 300;
          origin = "top-right";
          offset = "10x10";
          scale = 0;
          notification_limit = 10;
          progress_bar = true;
          progress_bar_height = 10;
          progress_bar_frame_width = 1;
          progress_bar_min_width = 150;
          progress_bar_max_width = 300;
          indicate_hidden = "yes";
          transparency = 0;
          separator_height = 2;
          padding = 8;
          horizontal_padding = 8;
          text_icon_padding = 0;
          frame_width = 1;
          frame_color = "#C0CAF5";
          separator_color = "frame";
          sort = "yes";
          idle_threshold = 120;
          font = "UbuntuMono Nerd Font 12";
          line_height = 0;
          markup = "full";
          format = "<b>%s</b>\\n%b";
          alignment = "left";
          vertical_alignment = "center";
          show_age_threshold = 60;
          ellipsize = "middle";
          ignore_newline = "no";
          stack_duplicates = false;
          hide_duplicate_count = false;
          show_indicators = "yes";
          icon_position = "left";
          min_icon_size = 16;
          max_icon_size = 16;
          icon_path = "/usr/share/icons/Vimix-Doder-dark/16/actions/:/usr/share/icons/Vimix-Doder-dark/16/devices:/usr/share/icons/Vimix-Doder-dark/places/:/usr/share/icons/Vimix-Doder-dark/16/mimetypes/:/usr/share/icons/Vimix-Doder-dark/16/panel/:/usr/share/icons/Vimix-Doder-dark/16/status/";
          sticky_history = "yes";
          history_length = 20;
          dmenu = "/usr/bin/dmenu -p dunst:";
          browser = "$BROWSER";
          always_run_script = true;
          title = "Dunst";
          class = "Dunst";
          corner_radius = 5;
          ignore_dbusclose = false;
          layer = "top";
          force_xwayland = false;
          force_xinerama = false;
          mouse_left_click = "do_action";
          mouse_middle_click = "close_current";
          mouse_right_click = "close_current";
        };
        experimental = {
          per_monitor_dpi = false;
        };
        urgency_low = {
          background = "#1A1B26";
          foreground = "#7AA2F7";
          timeout = 10;
        };
        urgency_normal = {
          background = "#1A1B26";
          foreground = "#9ECE6A";
          timeout = 10;
        };
        urgency_critical = {
          background = "#1A1B26";
          foreground = "#F7768E";
          timeout = 0;
        };
      };
    };
  };
}


================================================
FILE: home/_modules/windowmanager/add-on/gtk-theme/default.nix
================================================
{
  config,
  lib,
  pkgs,
  myPkgs,
  ...
}:
let
  cfg = config.myHome.windowmanager.add-on.gtk-theme;
in
{
  options.myHome.windowmanager.add-on.gtk-theme = {
    enable = lib.mkEnableOption "gtk-theme";
  };

  config = lib.mkIf (cfg.enable) {
    home.pointerCursor = {
      package = pkgs.catppuccin-cursors.mochaMauve;
      name = "catppuccin-mocha-mauve-cursors";
      size = 24;
      gtk.enable = true;
      x11.enable = true;
    };
    gtk = {
      enable = true;
      font = {
        name = "UbuntuMono Nerd Font";
        package = pkgs.nerd-fonts.ubuntu-mono;
        size = 12;
      };
      theme = {
        name = "Tokyonight-Dark";
        package = myPkgs.tokyonight-gtk-theme;
      };
      iconTheme = {
        name = "Tokyonight-Dark";
        package = myPkgs.tokyonight-icon-theme;
      };
    };
  };
}


================================================
FILE: home/_modules/windowmanager/add-on/nm-applet/default.nix
================================================
{ config, lib, ... }:
let
  cfg = config.myHome.windowmanager.add-on.nm-applet;
in
{
  options.myHome.windowmanager.add-on.nm-applet = {
    enable = lib.mkEnableOption "nm-applet";
  };

  config = lib.mkIf (cfg.enable) {
    services.network-manager-applet.enable = true;
    xsession.preferStatusNotifierItems = true;
  };
}


================================================
FILE: home/_modules/windowmanager/add-on/nwg-bar/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.windowmanager.add-on.nwg-bar;
in
{
  options.myHome.windowmanager.add-on.nwg-bar = {
    enable = lib.mkEnableOption "nwg-bar";
  };

  config = lib.mkIf (cfg.enable) {
    myHome.windowmanager.add-on.swaylock.enable = true;

    home.packages = [ pkgs.nwg-bar ];
    xdg.configFile = {
      "nwg-bar/bar.json".text = ''
        [
          {
            "label": "_Lock",
            "exec": "${config.programs.swaylock.package}/bin/swaylock",
            "icon": "${pkgs.nwg-bar}/share/nwg-bar/images/system-lock-screen.svg"
          },
          {
            "label": "_Exit",
            "exec": "${
              if config.wayland.windowManager.sway.enable then
                "swaymsg exit"
              else if config.wayland.windowManager.hyprland.enable then
                "hyprctl dispatch exit"
              else
                ""
            }",
            "icon": "${pkgs.nwg-bar}/share/nwg-bar/images/system-log-out.svg"
          },
          {
            "label": "_Reboot",
            "exec": "systemctl reboot",
            "icon": "${pkgs.nwg-bar}/share/nwg-bar/images/system-reboot.svg"
          },
          {
            "label": "_Shutdown",
            "exec": "systemctl -i poweroff",
            "icon": "${pkgs.nwg-bar}/share/nwg-bar/images/system-shutdown.svg"
          },
          {
            "label": "UE_FI",
            "exec": "systemctl reboot --firmware-setup",
            "icon": "${pkgs.nwg-bar}/share/nwg-bar/images/system-reboot.svg"
          }
        ]
      '';

      "nwg-bar/style.css".text = ''
        window {
          border: 1px solid #C0CAF5;
          border-radius: 10px;
          background-color: #1A1B26;
        }
        button, image {
          color: #C0CAF5;
          background: none;
          border: none;
          box-shadow: none;
        }
        button {
          padding-left: 10px;
          padding-right: 10px;
          margin: 5px;
        }
        button:hover {
          background-color: #16161E
        }
      '';
    };
  };
}


================================================
FILE: home/_modules/windowmanager/add-on/pasystray/default.nix
================================================
{ config, lib, ... }:
let
  cfg = config.myHome.windowmanager.add-on.pasystray;
in
{
  options.myHome.windowmanager.add-on.pasystray = {
    enable = lib.mkEnableOption "pasystray";
  };

  config = lib.mkIf (cfg.enable) { services.pasystray.enable = true; };
}


================================================
FILE: home/_modules/windowmanager/add-on/picom/default.nix
================================================
{ config, lib, ... }:
let
  cfg = config.myHome.windowmanager.add-on.picom;
in
{
  options.myHome.windowmanager.add-on.picom = {
    enable = lib.mkEnableOption "picom";
  };

  config = lib.mkIf (cfg.enable) {
    services.picom = {
      enable = true;
      settings = {
        # Shadows
        shadow = true;
        shadow-radius = 7;
        shadow-opacity = 0.7;
        shadow-offset-x = -7;
        shadow-offset-y = -7;
        shadow-red = 0.8;
        shadow-green = 0;
        shadow-blue = 0;
        shadow-exclude = [
          "name = 'Notification'"
          "class_g = 'Conky'"
          "_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'"
          "_GTK_FRAME_EXTENTS@:c"
          #"_NET_WM_STATE@:32a *= '_NET_WM_STATE_STICKY'",
          "class_g ?= 'i3-frame'"
          "class_g ?= 'Dunst'"
        ];
        # shadow-exclude-reg = ""
        # xinerama-shadow-crop = false
        # xinerama-shadow-crop = true;

        # Fading
        fading = true;
        fade-in-step = 3.0e-2;
        fade-out-step = 3.0e-2;
        # fade-delta = 10
        fade-exclude = [ "_NET_WM_STATE@:32a *= '_NET_WM_STATE_FULLSCREEN'" ];
        # no-fading-openclose = false
        # no-fading-destroyed-argb = false

        # Transparency / Opacity
        inactive-opacity = 0.98;
        frame-opacity = 1.0;
        inactive-opacity-override = false;
        active-opacity = 1.0;
        inactive-dim = 0.3;
        focus-exclude = [
          "class_g = 'Cairo-clock'"
          "_NET_WM_STATE@:32a *= '_NET_WM_STATE_FULLSCREEN'"
        ];
        inactive-dim-fixed = 1.0;
        opacity-rule = [
          "50:class_g = 'Dmenu'"
          "93:class_g = 'URxvt' && !_NET_WM_STATE@:32a"
          "0:_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'"
          "93:class_g = 'Gnome-terminal'"
          "93:class_g = 'Thunar'"
        ];

        # Corners
        corner-radius = 0;
        rounded-corners-exclude = [
          "window_type = 'dock'"
          "window_type = 'desktop'"
        ];

        # Background-Blurring
        # blur-method =
        # blur-size = 12
        # blur-deviation = false
        # blur-strength = 5
        # blur-background = false
        # blur-background-frame = false
        # blur-background-fixed = false
        blur-kern = "3x3box";
        blur-background-exclude = [
          "window_type = 'dock'"
          "window_type = 'desktop'"
          "_GTK_FRAME_EXTENTS@:c"
        ];

        # General Settings
        # daemon = false
        backend = "xrender";
        # vsync = true;
        # dbus = false
        mark-wmwin-focused = true;
        mark-ovredir-focused = true;
        detect-rounded-corners = true;
        detect-client-opacity = true;
        use-ewmh-active-win = true;
        unredir-if-possible = false;
        unredir-if-possible-delay = 5000; # miliseconds
        unredir-if-possible-exclude = [ ];
        detect-transient = true;
        detect-client-leader = true;
        # resize-damage = 1
        invert-color-include = [ ];
        glx-no-stencil = true;
        glx-no-rebind-pixmap = true;
        use-damage = true;
        # xrender-sync-fence = false
        # glx-fshader-win = ""
        # force-win-blend = false
        # no-ewmh-fullscreen = false
        # max-brightness = 1.0
        # transparent-clipping = false
        log-level = "info";
        # log-file = "/path/to/your/log/file"
        # show-all-xerrors = false
        # write-pid-path = "/path/to/your/log/file"
        wintypes = {
          tooltip = {
            fade = true;
            shadow = false;
            opacity = 0.85;
            focus = true;
          };
          dock = {
            shadow = false;
          };
          dnd = {
            shadow = false;
          };
          popup_menu = {
            opacity = 0.8;
          };
          dropdown_menu = {
            opacity = 0.9;
            shadow = false;
          };
        };
      };
    };
  };
}


================================================
FILE: home/_modules/windowmanager/add-on/py3status/config
================================================
order += "frame net"
order += "net_rate"
order += "frame disks"
order += "uname"
order += "frame timedate"
order += "whoami"

general {
    separator_block_width = 15
}

net_rate {
    format = "[\?color=down  {down}] [\?color=up  {up}]"
    format_value = "{value:.0f}{unit}"
    thresholds = {
        'down': [
            (0, "#7AA2F7"),
            (1024, "#7AA2F7"),
            (1048576, "#7AA2F7"),
        ],
        'up': [
            (0, "#F7768E"),
            (1024, "#F7768E"),
            (1048576, "#F7768E"),
        ],
    }
}

frame disks {
    static_string {
        separator = false
        separator_block_width = 5
        format = shell(printf " " && df -h ~ | tail -n 1 | awk '{$1="";$6="";print $0}' | awk -F ' ' '{print $3}', str)
        color = "#9ECE6A"
    }
    static_string {
        format = shell(printf " " && df -h / | tail -n 1 | awk '{$1="";$6="";print $0}' | awk -F ' ' '{print $3}', str)
        color = "#F7768E"
    }
}

uname {
    format = " {release}"
    color = "#E0AF68"
}

frame timedate {
    clock {
        format = " {Asia/Jakarta}"
        format_time = "%a, %d %b %y"
        color = "#BB9AF7"
    }
    clock {
        format = " {Asia/Jakarta}"
        format_time = "%I:%M:%S %p"
        color = "#9ECE6A"
    }
}

whoami {
    format = " {username}"
    color = "#7AA2F7"
}


================================================
FILE: home/_modules/windowmanager/add-on/py3status/default.nix
================================================
{ config, lib, ... }:
let
  cfg = config.myHome.windowmanager.add-on.py3status;
in
{
  options.myHome.windowmanager.add-on.py3status = {
    enable = lib.mkEnableOption "py3status";
  };

  config = lib.mkIf (cfg.enable) { xdg.configFile."py3status/config".source = ./config; };
}


================================================
FILE: home/_modules/windowmanager/add-on/rofi/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  myHome = config.myHome;
  cfg = myHome.windowmanager.add-on.rofi;
in
{
  options.myHome.windowmanager.add-on.rofi = {
    enable = lib.mkEnableOption "rofi";
  };

  config = lib.mkIf (cfg.enable) {
    programs.rofi = {
      enable = true;
      extraConfig = {
        font = "UbuntuMono Nerd Font 12";
        display-drun = " ";
        show-icons = true;
        drun-display-format = "{name}";
        disable-history = false;
        sidebar-mode = false;
      };
      theme = ./style.rasi;
    };
  };
}


================================================
FILE: home/_modules/windowmanager/add-on/rofi/style.rasi
================================================
* {
  selected-normal-foreground:  #1A1B26;
  foreground:                  #C0CAF5;
  normal-foreground:           @foreground;
  alternate-normal-background: @background;
  selected-urgent-foreground:  @selected-normal-foreground;
  urgent-foreground:           @selected-normal-foreground;
  alternate-urgent-background: @selected-normal-background;
  active-foreground:           #C0CAF5;
  selected-active-foreground:  @active-foreground;
  alternate-active-background: #1A1B26;
  background:                  #1A1B26;
  alternate-normal-foreground: @foreground;
  normal-background:           @background;
  selected-normal-background:  #7AA2F7;
  spacing:                     2px;
  separatorcolor:              #C0CAF5;
  urgent-background:           #F7768E;
  selected-urgent-background:  @selected-normal-background;
  alternate-urgent-foreground: @urgent-foreground;
  background-color:            @background;
  alternate-active-foreground: @active-foreground;
  active-background:           @background;
  selected-active-background:  @selected-normal-background;
  prompt-foreground:           #F7768E;
}

#window {
  background-color: @background;
  border-color: @separatorcolor;
  border: 1px;
  border-radius: 5px;
  padding: 5px;
  width: 25%;
}

#mainbox {
  border: 0;
  padding: 2px;
}

#message {
  border: 2px 0px 0px;
  border-color: @separatorcolor;
  padding: 1px;
}

#textbox {
  text-color: @foreground;
}

#listview {
  fixed-height: 0;
  border: 1px 0px 0px ;
  border-color: @separatorcolor;
  spacing: 5px;
  scrollbar: false;
  padding: 10px 0px 0px ;
  lines: 10;
}

#element {
  border: 0;
  padding: 3px;
  cursor: pointer;
  spacing: 5px;
}

#element.normal.normal {
  background-color: @normal-background;
  text-color: @normal-foreground;
}
#element.normal.urgent {
  background-color: @urgent-background;
  text-color: @urgent-foreground;
}
#element.normal.active {
  background-color: @active-background;
  text-color: @active-foreground;
}
#element.selected.normal {
  background-color: @selected-normal-background;
  text-color: @selected-normal-foreground;
}
#element.selected.urgent {
  background-color: @selected-urgent-background;
  text-color: @selected-urgent-foreground;
}
#element.selected.active {
  background-color: @selected-active-background;
  text-color: @selected-active-foreground;
}
#element.alternate.normal {
  background-color: @alternate-normal-background;
  text-color: @alternate-normal-foreground;
}
#element.alternate.urgent {
  background-color: @alternate-urgent-background;
  text-color: @alternate-urgent-foreground;
}
#element.alternate.active {
  background-color: @alternate-active-background;
  text-color: @alternate-active-foreground;
}

#element-text {
  background-color: transparent;
  cursor: inherit;
  highlight: inherit;
  text-color: inherit;
}

#element-icon {
  background-color: transparent;
  size: 1em;
  cursor: inherit;
  text-color: inherit;
}

#scrollbar {
  width: 4px ;
  border: 0;
  handle-width: 8px ;
  padding: 0;
  handle-color: var(normal-foreground);
}

#sidebar {
  border-color: @separatorcolor;
  border: 2px dash 0 0;
}

#mode-switcher {
  border: 2px 0px 0px ;
  border-color: @separatorcolor;
}

#button {
  cursor: pointer;
  spacing: 0;
  text-color: @normal-foreground;
}

#button.selected {
  background-color: @selected-normal-background;
  text-color: @selected-normal-foreground;
}

#inputbar {
  spacing: 5px;
  text-color: @normal-foreground;
  padding: 3px ;
}

#case-indicator {
  spacing: 0;
  text-color: @normal-foreground;
}

#entry {
  spacing: 0;
  text-color: @normal-foreground;
}

#prompt {
  spacing: 0;
  text-color: @prompt-foreground;
}

#textbox-prompt-colon {
  expand: false;
  str: ":";
  text-color: @prompt-foreground;
}

#inputbar {
  children: [prompt,entry,case-indicator];
}


================================================
FILE: home/_modules/windowmanager/add-on/screenshotter/default.nix
================================================
{
  config,
  pkgs,
  lib,
  ...
}:
let
  cfg = config.myHome.windowmanager.add-on.screenshotter;
  wl-full-screenshot = pkgs.writeShellScriptBin "wl-full-screenshot" ''
    IMG=~/Desktop/$(date +%Y%m%d_%Hh%mm%Ss).png
    ${pkgs.grim}/bin/grim $IMG \
      && ${pkgs.wl-clipboard}/bin/wl-copy < "$IMG" \
      && ${pkgs.pipewire}/bin/pw-cat -p ${./camera-shutter.oga} \
      && ${pkgs.libnotify}/bin/notify-send "Screenshot copied to clipboard and saved in your Desktop folder"
  '';

  wl-region-screenshot = pkgs.writeShellScriptBin "wl-region-screenshot" ''
    IMG=~/Desktop/$(date +%Y%m%d_%Hh%mm%Ss).png
    ${pkgs.grim}/bin/grim -g "$(${pkgs.slurp}/bin/slurp)" "$IMG" \
      && ${pkgs.wl-clipboard}/bin/wl-copy < "$IMG" \
      && ${pkgs.pipewire}/bin/pw-cat -p ${./camera-shutter.oga} \
      && ${pkgs.libnotify}/bin/notify-send "Screenshot copied to clipboard and saved in your Desktop folder"
  '';

  x-full-screenshot = pkgs.writeShellScriptBin "x-full-screenshot" ''
    IMG=~/Desktop/$(date +%Y%m%d_%Hh%mm%Ss).png
    ${pkgs.scrot}/bin/scrot -e '${pkgs.xclip}/bin/xclip -sel clipboard -t image/png -i $f' -F "$IMG" \
      && ${pkgs.pipewire}/bin/pw-cat -p ${./camera-shutter.oga} \
      && ${pkgs.libnotify}/bin/notify-send "Screenshot copied to clipboard and saved in your Desktop folder"
  '';

  x-region-screenshot = pkgs.writeShellScriptBin "x-region-screenshot" ''
    IMG=~/Desktop/$(date +%Y%m%d_%Hh%mm%Ss).png
    ${pkgs.scrot}/bin/scrot -s -e '${pkgs.xclip}/bin/xclip -sel clipboard -t image/png -i $f' -F "$IMG" \
      && ${pkgs.pipewire}/bin/pw-cat -p ${./camera-shutter.oga} \
      && ${pkgs.libnotify}/bin/notify-send "Screenshot copied to clipboard and saved in your Desktop folder"
  '';

  modeName = "Screenshot: (Enter) Full screenshot, (s) Select region";
in
{
  options.myHome.windowmanager.add-on.screenshotter = {
    enable = lib.mkOption {
      type = lib.types.bool;
      default = false;
      description = ''
        Enable screenshotter.
        This module will let you go to `screenshot mode` on `Printscreen` keypress in.
        Once in the mode, you can press `Enter` to take full screenshot or `r` to take region screenshot with mouse selection.
        The screenshot will be saved in `~/Desktop` directory and in your clipboard so you can paste the picture in applications.

        Only works in i3, Hyprland, and Sway window manager.
      '';
    };
  };

  config = lib.mkIf (cfg.enable) {
    wayland.windowManager = {
      hyprland = {
        extraConfig = ''
          submap = ${modeName}
          bind = , return, execr, ${lib.getExe wl-full-screenshot}
          bind = , return, submap, reset
          bind = , s, exec, ${lib.getExe wl-region-screenshot}
          bind = , s, submap, reset
          # return to normal mode
          bind = , escape, submap, reset
          submap = reset
        '';
        settings.bind = [ ", print, submap, ${modeName}" ];
      };
      sway.config = {
        modes.${modeName} = {
          Return = "exec ${lib.getExe wl-full-screenshot}, mode default";
          "--release s" = "exec ${lib.getExe wl-region-screenshot}, mode default";
          Escape = "mode default";
        };
        keybindings = {
          Print = "mode \"${modeName}\"";
        };
      };
    };

    xsession.windowManager.i3.config = {
      modes.${modeName} = {
        Return = "exec ${lib.getExe x-full-screenshot}, mode default";
        "--release s" = "exec ${lib.getExe x-region-screenshot}, mode default";
        Escape = "mode default";
      };
      keybindings = {
        Print = "mode \"${modeName}\"";
      };
    };
  };
}


================================================
FILE: home/_modules/windowmanager/add-on/swayidle/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.windowmanager.add-on.swayidle;
  wmCfg = config.wayland.windowManager;
in
with lib;
{
  options.myHome.windowmanager.add-on.swayidle = {
    enable = mkEnableOption "Swayidle";
  };

  config = mkIf (cfg.enable) {
    services.swayidle = {
      enable = true;
      timeouts = [
        {
          timeout = 1800;
          command = (
            mkMerge [
              (mkIf wmCfg.sway.enable "${pkgs.sway}/bin/swaymsg \"output * dpms off\"")
              (mkIf wmCfg.hyprland.enable "${wmCfg.hyprland.finalPackage}/bin/hyprctl dispatch dpms off")
            ]
          );
          resumeCommand = (
            mkMerge [
              (mkIf wmCfg.sway.enable "${pkgs.sway}/bin/swaymsg \"output * dpms on\"")
              (mkIf wmCfg.hyprland.enable "${wmCfg.hyprland.finalPackage}/bin/hyprctl dispatch dpms on")
            ]
          );
        }
      ];
      systemdTarget = mkIf wmCfg.hyprland.enable "hyprland-session.target";
    };
  };
}


================================================
FILE: home/_modules/windowmanager/add-on/swaylock/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.myHome.windowmanager.add-on.swaylock;
in
{
  options.myHome.windowmanager.add-on.swaylock = {
    enable = lib.mkEnableOption "Swaylock";
  };

  config = lib.mkIf (cfg.enable) {
    programs.swaylock = {
      enable = true;
      package = pkgs.swaylock-effects;
      settings = {
        screenshots = true;
        show-failed-attempts = true;
        line-uses-inside = true;
        clock = true;
        timestr = "%I:%M%p";
        datestr = "%a, %d %b";
        indicator = true;
        effect-blur = "7x5";
        effect-compose = "50%,35%;center;${./text.png}";
        # Inside colors
        inside-color = "1A1B26";
        inside-wrong-color = "1A1B26";
        inside-ver-color = "1A1B26";
        inside-clear-color = "1A1B26";
        # Text colors
        text-color = "C0CAF5";
        text-wrong-color = "C0CAF5";
        text-ver-color = "C0CAF5";
        text-clear-color = "C0CAF5";
        text-caps-lock-color = "E0AF68";
        # Ring colors
        ring-color = "9ECE6A";
        ring-wrong-color = "F7768E";
        ring-ver-color = "7AA2F7";
        ring-clear-color = "E0AF68";
        # Highlight colors
        key-hl-color = "BB9AF7";
        bs-hl-color = "BB9AF7";
      };
    };
  };
}


================================================
FILE: home/_modules/windowmanager/add-on/terminal-emulator/default.nix
================================================
{ config, lib, ... }:
let
  cfg = config.myHome.windowmanager.add-on.terminal-emulator;
  super = "Mod4";
  inherit (lib)
    mkOption
    types
    mkIf
    mkMerge
    ;
  mkDefaultTerminal = term: {
    myHome.terminal-emulator.${term}.enable = true;
    wayland.windowManager = {
      hyprland.settings.bind = [ "SUPER, t, exec, ${term}" ];
      sway.config.keybindings."${super}+t" = "exec --no-startup-id ${term}";
    };
    xsession.windowManager.i3.config.keybindings."${super}+t" = "exec --no-startup-id ${term}";
  };
in
{
  options.myHome.windowmanager.add-on.terminal-emulator = {
    default = mkOption {
      type = types.nullOr (
        types.enum [
          "alacritty"
          "contour"
          "kitty"
          "wezterm"
        ]
      );
      default = null;
    };
  };

  config = mkIf (cfg.default != null) (mkMerge [
    (mkIf (cfg.default == "alacritty") (mkDefaultTerminal "alacritty"))
    (mkIf (cfg.default == "contour") (mkDefaultTerminal "contour"))
    (mkIf (cfg.default == "kitty") (mkDefaultTerminal "kitty"))
    (mkIf (cfg.default == "wezterm") (mkDefaultTerminal "wezterm"))
  ]);
}


================================================
FILE: home/_modules/windowmanager/add-on/theme/tokyonight/default.nix
================================================
{ config, lib, ... }:
let
  cfg = config.myHome.windowmanager.add-on.theme.tokyonight;
  # Tokyonight Night color scheme
  color = {
    bg = "#1a1b26";
    bg_dark = "#16161e";
    bg_highlight = "#292e42";
    blue = "#7aa2f7";
    blue0 = "#3d59a1";
    blue1 = "#2ac3de";
    blue2 = "#0db9d7";
    blue5 = "#89ddff";
    blue6 = "#b4f9f8";
    blue7 = "#394b70";
    comment = "#565f89";
    cyan = "#7dcfff";
    dark3 = "#545c7e";
    dark5 = "#737aa2";
    fg = "#c0caf5";
    fg_dark = "#a9b1d6";
    fg_gutter = "#3b4261";
    green = "#9ece6a";
    green1 = "#73daca";
    green2 = "#41a6b5";
    magenta = "#bb9af7";
    magenta2 = "#ff007c";
    orange = "#ff9e64";
    purple = "#9d7cd8";
    red = "#f7768e";
    red1 = "#db4b4b";
    teal = "#1abc9c";
    terminal_black = "#414868";
    yellow = "#e0af68";
  };
in
{
  options.myHome.windowmanager.add-on.theme.tokyonight = {
    enable = lib.mkOption {
      type = lib.types.bool;
      default = false;
      description = ''
        Enable Tokyonight Night theme for window manager.

        Only works in i3 and Sway window manager.
      '';
    };
  };

  config = lib.mkIf (cfg.enable) {
    wayland.windowManager.sway.config.colors = {
      focused = {
        border = color.bg;
        background = color.bg;
        text = color.red;
        indicator = color.blue;
        childBorder = color.fg_dark;
      };
      unfocused = {
        border = color.bg;
        background = color.bg;
        text = color.fg_dark;
        indicator = color.blue;
        childBorder = color.fg_dark;
      };
      focusedInactive = {
        border = color.bg;
        background = color.bg;
        text = color.fg_dark;
        indicator = color.blue;
        childBorder = color.fg_dark;
      };
      urgent = {
        border = color.red;
        background = color.red;
        text = color.fg_dark;
        indicator = color.blue;
        childBorder = color.fg_dark;
      };
    };
    xsession.windowManager.i3.config = {
      colors = {
        focused = {
          border = color.bg;
          background = color.bg;
          text = color.red;
          indicator = color.fg_dark;
          childBorder = color.bg;
        };
        unfocused = {
          border = color.bg;
          background = color.bg;
          text = color.fg_dark;
          indicator = color.fg_dark;
          childBorder = color.bg;
        };
        focusedInactive = {
          border = color.bg;
          background = color.bg;
          text = color.fg_dark;
          indicator = color.fg_dark;
          childBorder = color.bg;
        };
        urgent = {
          border = color.red;
          background = color.red;
          text = color.fg;
          indicator = color.fg_dark;
          childBorder = color.bg;
        };
      };
      # TODO: use polibar instead
      bars = [
        {
          trayOutput = (builtins.head (builtins.filter (m: m.primary) config.myHardware.monitors)).name;
          statusCommand = "py3status";
          fonts = {
            names = [ "UbuntuMono Nerd Font" ];
            size = 12.0;
          };
          position = "top";
          colors = {
            background = color.bg;
            separator = color.fg;
            activeWorkspace = {
              border = color.bg;
              background = color.bg;
              text = color.red;
            };
            focusedWorkspace = {
              border = color.bg;
              background = color.bg;
              text = color.red;
            };
            inactiveWorkspace = {
              border = color.bg;
              background = color.bg;
              text = color.fg;
            };
            urgentWorkspace = {
              border = color.red;
              background = color.red;
              text = color.fg;
            };
          };
        }
      ];
    };
  };
}


================================================
FILE: home/_modules/windowmanager/add-on/waybar/default.nix
================================================
{
  config,
  lib,
  pkgs,
  ...
}:
let
  myHome = config.myHome;
  myHardware = config.myHardware;
  cfg = myHome.windowmanager.add-on.waybar;

  leftModules = (
    if myHome.windowmanager.sway.enable then
      [
        "sway/workspaces"
        "sway/mode"
      ]
    else if myHome.windowmanager.hyprland.enable then
      [
        "hyprland/workspaces"
        "hyprland/submap"
      ]
    else
      [ ]
  );
  centerModules = [ "clock" ];
  rightModules = [
    "network#down"
    "network#up"
  ];

  modulesCfg = {
    "network#down" = {
      format = "󰁅 {bandwidthDownBits}";
      tooltip-format = "{ifname} {ipaddr}";
      interval = 1;
    };
    "network#up" = {
      format = "󰁝 {bandwidthUpBits}";
      tooltip-format = "{ifname} {ipaddr}";
      interval = 1;
    };

    clock = {
      format = "{:%A, %d %b %I:%M%p}";
      interval = 1;
      timezone = "Asia/Jakarta";
      tooltip = false;
    };
    "custom/power" = {
      format = "󰤆 ";
      tooltip = true;
      on-click = "${pkgs.nwg-bar}/bin/nwg-bar";
    };
    "sway/workspaces" = {
      format = "{value}";
    };
    "sway/mode" = {
      format = "󰔡 {}";
      max-length = 100;
    };
    "hyprland/workspaces" = {
      format = "{name}";
      on-click = "activate";
      on-scroll-up = "${config.wayland.windowManager.hyprland.finalPackage}/bin/hyprctl dispatch workspace e+1";
      on-scroll-down = "${config.wayland.windowManager.hyprland.finalPackage}/bin/hyprctl dispatch workspace e-1";
    };
    "hyprland/submap" = {
      format = "󰔡 {}";
      max-length = 100;
    };
  };
in
{
  options.myHome.windowmanager.add-on.waybar = {
    enable = lib.mkEnableOption "waybar";
  };

  config = lib.mkIf (cfg.enable) {
    programs.waybar = {
      enable = true;
      systemd.enable = true;
      settings = builtins.map (
        monitor:
        {
          output = monitor.name;
          layer = "top";
          position = "top";
          margin = "10 20 -5 20";

          modules-left = leftModules;
          modules-center = centerModules;
          modules-right =
            rightModules
            ++ (
              if monitor.primary then
                [
                  "tray"
                  "custom/power"
                ]
              else
                [ ]
            );
        }
        // modulesCfg
      ) myHardware.monitors;

      style = ''
        * {
            border: none;
            border-radius: 0;
            font-family: "UbuntuMono Nerd Font";
            font-size: 16px;
            font-weight: normal;
            padding: 1px;
        }

        button {
          min-height: 24px;
          min-width: 16px;
        }

        window#waybar {
            background-color: transparent;
            color: #C0CAF5;
            transition-property: background-color;
            transition-duration: .5s;
            border: 1px solid #C0CAF5;
            border-radius: 10px;
        }

        window#waybar.hidden {
            opacity: 0.2;
        }

        #workspaces button {
            color: #C0CAF5;
            padding: 0 3px;
            border-radius: 5px;
        }

        #workspaces button.focused {
            color: #7AA2F7;
        }

        #workspaces button.active {
            color: #7AA2F7;
        }

        #workspaces button.urgent {
            color: #F7768E;
        }

        #mode {
            color: #F7768E;
            padding-left: 2px;
        }

        #submap {
            color: #F7768E;
            padding-left: 2px;
        }

        #clock {
            color: #BB9AF7;
        }

        #network.down {
            color: #9ECE6A;
            padding-right: 8px;
        }

        #network.up {
            color: #7AA2F7;
            padding-right: 8px;
        }

        #tray {
            color: #C0CAF5;
            padding-right: 8px;
        }

        #custom-power {
            color: #F7768E;
            padding-right: 8px;
        }
      '';
    };
  };
}


================================================
FILE: home/_modules/windowmanager/add-on/xdg/default.nix
================================================
{ config, lib, ... }:
let
  cfg = config.myHome.windowmanager.add-on.xdg;
in
{
  options.myHome.windowmanager.add-on.xdg = {
    enable = lib.mkEnableOption "xdg";
  };

  config = lib.mkIf (cfg.enable) {
    xdg.userDirs = {
      enable = true;
      createDirectories = true;
    };
  };
}


================================================
FILE: home/_modules/windowmanager/hyprland/config/appearances.nix
================================================
{
  general = {
    gaps_in = 5;
    gaps_out = 20;
    "col.inactive_border" = "rgb(A9B1D6)";
    "col.active_border" = "rgb(A9B1D6)";
    layout = "master";
  };
  decoration = {
    rounding = 10;
    inactive_opacity = 0.7;
    dim_inactive = true;
    dim_strength = 0.3;
  };
  master = {
    new_on_top = true;
  };
}


================================================
FILE: home/_modules/windowmanager/hyprland/config/default.nix
================================================
{
  config,
  pkgs,
  lib,
  ...
}:
let
  myHardware = config.myHardware;
  resizeMode = "Resize: (h/Left) width- (j/Down) height-, (k/Up) height+, (l/Right) width+";
in
{
  # Submaps are impossible to be defined in settings
  extraConfig = ''
    # Resize window
    submap = ${resizeMode}
    binde = , h, resizeactive, -10 0
    binde = , j, resizeactive, 0 10
    binde = , k, resizeactive, 0 -10
    binde = , l, resizeactive, 10 0
    # Or use arrow keys
    binde = , left, resizeactive, -10 0
    binde = , down, resizeactive, 0 10
    binde = , up, resizeactive, 0 -10
    binde = , right, resizeactive, 10 0
    # Return to normal mode
    bind = , escape, submap, reset
    submap = reset
  '';

  settings =
    {
      # Monitor placement
      # [ "<name>,<width>x<height>,<x>x<y>,1" ... ]
      monitor = builtins.map (
        m: "${m.name},${toString m.width}x${toString m.height},${toString m.x}x${toString m.y},1"
      ) myHardware.monitors;

      # Wallpaper
      # [ "swaybg -o <name> -i <path>" ... ]
      exec-once = builtins.map (m: "${pkgs.swaybg}/bin/swaybg -o ${m.name} -i ${m.wallpaper}") (
        builtins.filter (m: m.wallpaper != null) myHardware.monitors
      );

      # General settings
      general = {
        resize_on_border = true;
      };
      input = {
        numlock_by_default = true;
        follow_mouse = 1;
      };
      misc = {
        mouse_move_enables_dpms = true;
        key_press_enables_dpms = true;
      };
      env = lib.mkIf (myHardware.gpuDriver == "nvidia") [
        "LIBVA_DRIVER_NAME,nvidia"
        "XDG_SESSION_TYPE,wayland"
        "GBM_BACKEND,nvidia-drm"
        "__GLX_VENDOR_LIBRARY_NAME,nvidia"
        "WLR_NO_HARDWARE_CURSORS,1"
      ];
    }
    // (import ./keybindings.nix { inherit config resizeMode pkgs; })
    // (import ./ws-outputs.nix { inherit config; })
    // (import ./window-rules.nix)
    // (import ./appearances.nix);
}


================================================
FILE: home/_modules/windowmanager/hyprland/config/keybindings.nix
================================================
{
  config,
  resizeMode,
  pkgs,
}:
{
  bindm = [
    # Super+mouse to drag/resize floating windows
    "SUPER, mouse:272, movewindow"
    "SUPER, mouse:273, resizewindow"
  ];
  bind = [
    # Kill focused window
    "SUPER, F4, killactive,"

    # Change focus around
    "SUPER, h, movefocus, l"
    "SUPER, j, movefocus, d"
    "SUPER, k, movefocus, u"
    "SUPER, l, movefocus, r"
    # Or use arrow keys
    "SUPER, left, movefocus, l"
    "SUPER, down, movefocus, d"
    "SUPER, up, movefocus, u"
    "SUPER, right, movefocus, r"

    # Move the focused window with the same, but add Shift
    "SUPER SHIFT, h, movewindow, l"
    "SUPER SHIFT, j, movewindow, d"
    "SUPER SHIFT, k, movewindow, u"
    "SUPER SHIFT, l, movewindow, r"
    # Or use arrow keys
    "SUPER SHIFT, left, movewindow, l"
    "SUPER SHIFT, down, movewindow, d"
    "SUPER SHIFT, up, movewindow, u"
    "SUPER SHIFT, right, movewindow, r"

    # Next/previous workspace
    "SUPER, tab, workspace, e+1"
    "SUPER SHIFT, tab, workspace, e-1"

    # Toggle fullscreen mode
    "SUPER SHIFT, f, fullscreen, 1"

    # Toggle floating mode
    "SUPER SHIFT, space, togglefloating,"

    # Move the currently focused window to the scratchpad
    "SUPER SHIFT, p, movetoworkspacesilent, special"

    # Show the next scratchpad window or hide the focused scratchpad window
    "SUPER, p, togglespecialworkspace,"

    # Switch to workspace
    "SUPER, 1, workspace, 1"
    "SUPER, 2, workspace, 2"
    "SUPER, 3, workspace, 3"
    "SUPER, 4, workspace, 4"
    "SUPER, 5, workspace, 5"
    "SUPER, 6, workspace, 6"
    "SUPER, 7, workspace, 7"
    "SUPER, 8, workspace, 8"
    "SUPER, 9, workspace, 9"
    "SUPER, 0, workspace, 10"

    # Move focused container to workspace
    "SUPER SHIFT, 1, movetoworkspace, 1"
    "SUPER SHIFT, 2, movetoworkspace, 2"
    "SUPER SHIFT, 3, movetoworkspace, 3"
    "SUPER SHIFT, 4, movetoworkspace, 4"
    "SUPER SHIFT, 5, movetoworkspace, 5"
    "SUPER SHIFT, 6, movetoworkspace, 6"
    "SUPER SHIFT, 7, movetoworkspace, 7"
    "SUPER SHIFT, 8, movetoworkspace, 8"
    "SUPER SHIFT, 9, movetoworkspace, 9"
    "SUPER SHIFT, 0, movetoworkspace, 10"

    # Reload the configuration file
    "SUPER SHIFT, c, execr, hyprctl reload"

    # Most used applications
    "SUPER, f, exec, thunar" # use system provided thunar package
    "SUPER, c, exec, ${pkgs.gnome-calculator}/bin/gnome-calculator"

    # Rofi as dmenu replacement
    "SUPER, grave, exec, ${config.programs.rofi.package}/bin/rofi -show drun"
    "SUPER, Escape, exec, ${config.programs.rofi.package}/bin/rofi -show drun"

    # Modes
    "SUPER SHIFT, r, submap, ${resizeMode}"

    # Logout menu
    "CTRL SUPER, delete, exec, ${pkgs.nwg-bar}/bin/nwg-bar"
  ];
}


================================================
FILE: home/_modules/windowmanager/hyprland/config/window-rules.nix
================================================
{
  windowrulev2 = [
    # Window floating and layout
    "float, class:^(pavucontrol)$"
    "float, class:^(thunar)$"
    "float, class:^(obs)$"
    "float, class:^(gnome-calculator|org\.gnome\.Calculator)$"
    "float, class:^(pamac-manager)$"
    "float, class:^(eog)$"
    "float, class:^(blueman-manager)$"
    "float, class:^(nm-connection-editor)$"
    "float, class:^(rhythmbox)$"
    "size 1000 640, class:^(rhythmbox)$"
    "float, title:^(File Transfer*)$"
    "float, title:^(Lxappearance)$"
    "pin, title:^(Lxappearance)$"
    "float, title:^(VirtualBox)$"
    "float, title:^(VirtualBox)$"
    "idleinhibit focus, fullscreen:1"
    "idleinhibit focus, class:^(org.libretro.RetroArch)$"
    "idleinhibit focus, class:^(com.github.iwalton3.jellyfin-media-player)$"

    # Window placement
    "workspace silent special, title:^(updater)$, class:^(kitty)$"
    "workspace 5, class:^(smplayer)$"
    "workspace 5, class:^(totem)$"
    "workspace 5, class:^(rhythmbox)$"
    "workspace 6, class:^(org.libretro.RetroArch)$"
    "workspace 7, class:^(Gimp)$"
    "workspace 9, class:^(obs)$"
    "workspace 10, class:^(VirtualBox)$"
    "noborder, title:^(Syncthing Tray( \(.*\))?)$"
    "size 550 400, title:^(Syncthing Tray( \(.*\))?)$"
    "move 1365 30, title:^(Syncthing Tray( \(.*\))?)$"
    "move 1465 30, title:^(Nextcloud)$, class:^(Nextcloud)$"
  ];
}


================================================
FILE: home/_modules/windowmanager/hyprland/config/ws-outputs.nix
================================================
{ config }:
let
  strBool = b: if b then "true" else "false";
  mkWorkspaces =
    monitors:
    builtins.concatMap (
      mon:
      builtins.map (
        ws: "${toString ws}, monitor:${mon.name}, default:${strBool (ws == builtins.head mon.workspaces)}"
      ) mon.workspaces
    ) monitors;
in
{
  # [ "<ws>, monitor:<name>, default:<bool>" "..." ]
  workspace = mkWorkspaces config.myHardware.monitors;
}


================================================
FILE: home/_modules/windowmanager/hyprland/default.nix
================================================
{
  config,
  osConfig,
  lib,
  pkgs,
  ...
}:
let
  myHardware = config.myHardware;
  cfg = config.myHome.windowmanager.hyprland;
  systemEnabled = lib.myLib.systemEnabled "mySystem.windowmanager.hyprland.enable" osConfig;
in
{
  options.myHome.windowmanager.hyprland = {
    enable = lib.mkEnableOption "Hyprland window manager";
  };

  config = lib.mkIf (cfg.enable) {
    myHome = {
      isWayland = true;

      windowmanager.add-on = {
        blueman-applet.enable = true;
        dunst.enable = true;
        gtk-theme.enable = true;
        nm-applet.enable = true;
        nwg-bar.enable = true;
        pasystray.enable = true;
        rofi.enable = true;
        swayidle.enable = true;
        waybar.enable = true;
        screenshotter.enable = true;
        terminal-emulator.default = "alacritty";
        xdg.enable = true;
      };
    };

    warnings = lib.mkIf (!systemEnabled) [
      ''
        You have enabled Hyprland home-manager module but not the NixOS system module.
        Some things might not work properly.
      ''
    ];

    assertions = [
      {
        assertion = builtins.length myHardware.monitors > 0;
        message = ''
          At least one monitor in the `config.myHardware.monitors` is
          needed to use Hyprland home-manager module.
        '';
      }
    ];

    wayland.windowManager.hyprland = {
      enable = true;
    } // (import ./config { inherit config lib pkgs; });

    systemd.user.startServices = "sd-switch";
  };
}


================================================
FILE: home/_modules/windowmanager/i3/config/commands.nix
================================================
[
  {
    criteria = {
      window_role = "pop-up";
    };
    command = "floating enable";
  }
  {
    criteria = {
      window_role = "prefwindow";
    };
    command = "floating enable";
  }
  {
    criteria = {
      class = "notify";
    };
    command = "floating enable border pixel 1";
  }
  {
    criteria = {
      title = "File Transfer*";
    };
    command = "floating enable";
  }
  {
    criteria = {
      class = "Galculator";
    };
    command = "floating enable";
  }
  {
    criteria = {
      class = "Lxappearance";
    };
    command = "floating enable sticky enable border normal";
  }
  {
    criteria = {
      class = "Oblogout";
    };
    command = "fullscreen enable";
  }
  {
    criteria = {
      class = "Pavucontrol";
    };
    command = "floating enable";
  }
  {
    criteria = {
      class = "VirtualBox";
    };
    command = "floating enable";
  }
  {
    criteria = {
      class = "Skype";
    };
    command = "floating enable";
  }
  {
    criteria = {
      class = "(?i)nvidia-settings";
    };
    command = "floating enable";
  }
  {
    criteria = {
      class = "smplayer";
    };
    command = "floating enable";
  }
  {
    criteria = {
      class = "Eog";
    };
    command = "floating enable";
  }
  {
    criteria = {
      class = "Rhythmbox";
    };
    command = "floating enable resize set 1000 640";
  }
  {
    criteria = {
      class = "obs";
    };
    command = "floating enable";
  }
]


================================================
FILE: home/_modules/windowmanager/i3/config/default.nix
================================================
{
  config,
  pkgs,
  lib,
}:
let
  myHardware = config.myHardware;
  modes = {
    resize = "Resize: (h/Left) width-, (j/Down) height-, (k/Up) height+, (l/Right) width+";
    gaps = "Gaps (o) outer, (i) inner";
    gapsOuter = "Outer Gaps (k/Up) grow locally, (K/Shift+Up) grow globally";
    gapsInner = "Inner Gaps (k/Up) grow locally, (K/Shift+Up) grow globally";
    system = "System (l) lock, (e) logout, (r) reboot, (s) shutdown, (f) UEFI";
  };
in
{
  floating.modifier = "Mod4";
  focus = {
    wrapping = "yes";
    followMouse = true;
    newWindow = "urgent";
  };
  gaps = {
    inner = 10;
    outer = 5;
    smartGaps = true;
  };

  # [ { output = "<xname>"; workspace = "<ws>"; } {...} ]
  workspaceOutputAssign = builtins.concatMap (
    mon:
    builtins.map (ws: {
      workspace = (toString ws);
      output = mon.xname;
    }) mon.workspaces
  ) myHardware.monitors;

  keybindings = import ./keybindings.nix { inherit config pkgs modes; };
  modes = import ./modes.nix { inherit modes pkgs; };
  window.commands = import ./commands.nix;
  startup = import ./startups.nix { inherit config pkgs lib; };
}


================================================
FILE: home/_modules/windowmanager/i3/config/keybindings.nix
================================================
{
  config,
  pkgs,
  modes,
}:
let
  super = "Mod4";
in
{
  # kill focused window
  "${super}+F4" = "kill";
  # change focus
  "${super}+h" = "focus left";
  "${super}+j" = "focus down";
  "${super}+k" = "focus up";
  "${super}+l" = "focus right";
  # alternatively, you can use the cursor keys
  "${super}+Left" = "focus left";
  "${super}+Down" = "focus down";
  "${super}+Up" = "focus up";
  "${super}+Right" = "focus right";
  # move focused window
  "${super}+Shift+h" = "move left";
  "${super}+Shift+j" = "move down";
  "${super}+Shift+k" = "move up";
  "${super}+Shift+l" = "move right";
  # alternatively, you can use the cursor keys
  "${super}+Shift+Left" = "move left";
  "${super}+Shift+Down" = "move down";
  "${super}+Shift+Up" = "move up";
  "${super}+Shift+Right" = "move right";
  # split in orientation
  "${super}+Control+h" = "split h; exec notify-send 'tile horizontally'";
  "${super}+Control+v" = "split v; exec notify-send 'tile vertically'";
  "${super}+Control+q" = "split toggle";
  # next/previous workspace
  "${super}+Tab" = "workspace next";
  "${super}+Shift+Tab" = "workspace prev";
  # toggle window border
  "${super}+Control+t" = "border toggle";
  # enter fullscreen mode for the focused container
  "${super}+Control+f" = "fullscreen toggle";
  # toggle gaps on and off, please uncomment if you don't have i3-gaps installed
  "${super}+Control+g" = ''
    exec --no-startup-id "if [ `i3-msg -t get_tree | grep -Po \
      '.*\\"gaps\\":{\\"inner\\":\K(-|)[0-9]+(?=.*\\"focused\\":true)'` -eq 0 ]; then \
              i3-msg gaps inner current set 0; i3-msg gaps outer current set 0; \
      else \
              i3-msg gaps inner current set 10; i3-msg gaps outer current set 5; \
      fi
  '';
  # change container layout (stacked, tabbed, toggle split)
  "${super}+Control+s" = "layout stacking";
  "${super}+Control+w" = "layout tabbed";
  "${super}+Control+e" = "layout toggle split";
  # toggle floating mode
  "${super}+Shift+space" = "floating toggle";
  # change focus between tiling / floating windows
  "${super}+space" = "focus mode_toggle";
  # switch to workspace
  "${super}+1" = "workspace 1";
  "${super}+2" = "workspace 2";
  "${super}+3" = "workspace 3";
  "${super}+4" = "workspace 4";
  "${super}+5" = "workspace 5";
  "${super}+6" = "workspace 6";
  "${super}+7" = "workspace 7";
  "${super}+8" = "workspace 8";
  "${super}+9" = "workspace 9";
  "${super}+0" = "workspace 10";
  # move focused container to workspace
  "${super}+Shift+1" = "move container to workspace 1";
  "${super}+Shift+2" = "move container to workspace 2";
  "${super}+Shift+3" = "move container to workspace 3";
  "${super}+Shift+4" = "move container to workspace 4";
  "${super}+Shift+5" = "move container to workspace 5";
  "${super}+Shift+6" = "move container to workspace 6";
  "${super}+Shift+7" = "move container to workspace 7";
  "${super}+Shift+8" = "move container to workspace 8";
  "${super}+Shift+9" = "move container to workspace 9";
  "${super}+Shift+0" = "move container to workspace 10";
  # reload the configuration file
  "${super}+Shift+c" = "reload";
  # exit i3 (logs you out of your X session)
  "${super}+Shift+e" = "exec \"i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'\"";
  # most used application shortcuts
  "${super}+f" = "exec --no-startup-id thunar"; # use system provided thunar package
  "${super}+c" = "exec ${pkgs.gnome-calculator}/bin/gnome-calculator";
  # rofi as dmenu replacement
  "${super}+grave" = "exec ${config.programs.rofi.package}/bin/rofi -show drun";
  "${super}+Escape" = "exec ${config.programs.rofi.package}/bin/rofi -show drun";
  # modes
  "${super}+Shift+r" = "mode \"${modes.resize}\"";
  "${super}+Shift+g" = "mode \"${modes.gaps}\"";
  "${super}+Control+Delete" = "mode \"${modes.system}\"";
}


================================================
FILE: home/_modules/windowmanager/i3/config/modes.nix
================================================
{ modes, pkgs }:
{
  # resize window (you can also use the mouse for that)
  ${modes.resize} = {
    h = "resize shrink width 10 px or 10 ppt";
    j = "resize shrink height 10 px or 10 ppt";
    k = "resize grow height 10 px or 10 ppt";
    l = "resize grow width 10 px or 10 ppt";
    # same bindings, but for the arrow keys
    Left = "resize shrink width 10 px or 10 ppt";
    Down = "resize shrink height 10 px or 10 ppt";
    Up = "resize grow height 10 px or 10 ppt";
    Right = "resize grow width 10 px or 10 ppt";
    # back to normal: Enter or Escape
    Return = "mode default";
    Escape = "mode default";
  };
  # resize gaps
  ${modes.gaps} = {
    o = "mode \"$mode_gaps_outer\"";
    i = "mode \"$mode_gaps_inner\"";
    Return = "mode \"${modes.gaps}\"";
    Escape = "mode default";
  };
  ${modes.gapsOuter} = {
    k = "gaps outer current plus 5";
    j = "gaps outer current minus 5";
    # same bindings, but for the arrow keys
    Up = "gaps outer current plus 5";
    Down = "gaps outer current minus 5";
    "Shift+k" = "gaps outer all plus 5";
    "Shift+j" = "gaps outer all minus 5";
    # same keybindings, but for the arrow keys
    "Shift+Up" = "gaps outer all plus 5";
    "Shift+Down" = "gaps outer all minus 5";
    Return = "mode \"${modes.gaps}\"";
    Escape = "mode default";
  };
  ${modes.gapsInner} = {
    k = "gaps inner current plus 5";
    j = "gaps inner current minus 5";
    # same bindings, but for the arrow keys
    Up = "gaps inner current plus 5";
    Down = "gaps inner current minus 5";
    "Shift+k" = "gaps inner all plus 5";
    "Shift+j" = "gaps inner all minus 5";
    # same keybindings, but for the arrow keys
    "Shift+Up" = "gaps inner all plus 5";
    "Shift+Down" = "gaps inner all minus 5";
    Return = "mode \"${modes.gaps}\"";
    Escape = "mode default";
  };
  # Press Ctrl+Alt+Delete will show log out menu
  ${modes.system} = {
    l = "exec --no-startup-id ${pkgs.i3lock}/bin/i3lock && sleep 1, mode default";
    e = "exec --no-startup-id i3-msg exit, mode default";
    r = "exec --no-startup-id systemctl reboot, mode default";
    s = "exec --no-startup-id systemctl poweroff -i, mode default";
    f = "exec --no-startup-id systemctl reboot --firmware-setup, mode default";
    # back to normal: Enter or Escape
    Return = "mode default";
    Escape = "mode default";
  };
}


================================================
FILE: home/_modules/windowmanager/i3/config/startups.nix
================================================
{
  config,
  pkgs,
  lib,
}:
let
  wallpapers = builtins.map (m: m.wallpaper) (
    builtins.filter (m: m.wallpaper != null) config.myHardware.monitors
  );
in
[
  {
    # "xrandr --pos <x>x<y> --mode <width>x<height> ..."
    command =
      "${pkgs.xorg.xrandr}/bin/xrandr"
      + (lib.concatMapStrings (
        mon:
        " --output ${mon.xname} --pos ${toString mon.x}x${toString mon.y} --mode ${toString mon.width}x${toString mon.height}"
        + (lib.optionalString (mon.primary) " --primary")
      ) config.myHardware.monitors);
    notification = false;
    always = true;
  }
  {
    # "feh --bg-fill <path> ..."
    command = "${pkgs.feh}/bin/feh" + (lib.concatMapStrings (wp: " --bg-fill ${wp}")) wallpapers;
    notification = false;
    always = true;
  }
  {
    command = "${pkgs.xfce.xfce4-power-manager}/bin/xfce4-power-manager";
    notification = false;
  }
  {
    command = "${pkgs.numlockx}/bin/numlockx";
    notification = false;
  }
]


================================================
FILE: home/_modules/windowmanager/i3/default.nix
================================================
{
  config,
  lib,
  osConfig,
  pkgs,
  ...
}:
let
  myHardware = config.myHardware;
  cfg = config.myHome.windowmanager.i3;
  systemEnabled = lib.myLib.systemEnabled "mySystem.windowmanager.i3.enable" osConfig;
in
{
  options.myHome.windowmanager.i3 = {
    enable = lib.mkEnableOption "i3";
  };

  config = lib.mkIf (cfg.enable) {
    myHome = {
      isWayland = false;

      windowmanager.add-on = {
        blueman-applet.enable = true;
        dunst.enable = true;
        gtk-theme.enable = true;
        nm-applet.enable = true;
        rofi.enable = true;
        theme.tokyonight.enable = true;
        screenshotter.enable = true;
        pasystray.enable = true;
        picom.enable = true;
        py3status.enable = true;
        terminal-emulator.default = "wezterm";
        xdg.enable = true;
      };
    };

    warnings = lib.mkIf (!systemEnabled) [
      ''
        You have enabled i3 home-manager module but not the NixOS system module.
        Some things might not work properly.
      ''
    ];

    assertions = [
      {
        assertion = builtins.length myHardware.monitors > 0;
        message = ''
          At least one monitor in the `config.myHardware.monitors` is
          needed to use i3 home-manager module.
        '';
      }
    ];

    xsession.windowManager.i3 = {
      enable = true;
      package = pkgs.i3-gaps;
      config = import ./config { inherit config pkgs lib; };
    };
  };
}


================================================
FILE: home/_modules/windowmanager/sway/config/commands.nix
================================================
[
  # Window title formatting
  {
    criteria = {
      class = ".*";
    };
    command = "title_format \"<b> %title</b>\"";
  }
  # window floating and layout
  {
    criteria = {
      window_role = "pop-up";
    };
    com
Download .txt
gitextract_4wydarc6/

├── .chezmoiroot
├── .editorconfig
├── .github/
│   ├── FUNDING.yml
│   ├── renovate.json
│   └── workflows/
│       ├── broken-link-check.yaml
│       ├── build-push-cache.yaml
│       ├── check-flakes.yaml
│       ├── renovate.yaml
│       ├── update-nvfetcher.yaml
│       └── update-sops-keys.yaml
├── .gitignore
├── .justfile
├── .sops.yaml
├── LICENSE
├── README.md
├── chezmoi/
│   ├── .chezmoi.yaml.tmpl
│   ├── .chezmoiignore
│   ├── .chezmoiscripts/
│   │   ├── run_once_after_90-cleanup.sh.tmpl
│   │   ├── run_once_before_10-setup-fish.sh.tmpl
│   │   ├── run_once_before_20-install-packages-archlinux.sh.tmpl
│   │   ├── run_once_before_20-install-packages-ubuntu.sh.tmpl
│   │   └── run_onchange_after_80-setup-terminal.sh.tmpl
│   └── dot_config/
│       ├── fontconfig/
│       │   └── fonts.conf.tmpl
│       └── termite/
│           └── config
├── flake.nix
├── flakeLib.nix
├── home/
│   ├── _modules/
│   │   ├── _default/
│   │   │   ├── default.nix
│   │   │   ├── nix.nix
│   │   │   └── sops.nix
│   │   ├── browser/
│   │   │   └── firefox/
│   │   │       └── default.nix
│   │   ├── default.nix
│   │   ├── editor/
│   │   │   └── neovim/
│   │   │       └── default.nix
│   │   ├── homelab/
│   │   │   └── kubernetes/
│   │   │       ├── default.nix
│   │   │       └── secret.sops.yaml
│   │   ├── multiplexer/
│   │   │   ├── tmux/
│   │   │   │   ├── config/
│   │   │   │   │   └── tmux.conf
│   │   │   │   └── default.nix
│   │   │   └── zellij/
│   │   │       ├── config/
│   │   │       │   ├── config.kdl
│   │   │       │   └── layouts/
│   │   │       │       └── default.kdl
│   │   │       └── default.nix
│   │   ├── programs/
│   │   │   ├── beeaccounting/
│   │   │   │   └── default.nix
│   │   │   ├── chezmoi/
│   │   │   │   └── default.nix
│   │   │   ├── fontconfig/
│   │   │   │   └── default.nix
│   │   │   ├── go/
│   │   │   │   └── default.nix
│   │   │   ├── obs-studio/
│   │   │   │   └── default.nix
│   │   │   ├── qmk/
│   │   │   │   ├── default.nix
│   │   │   │   └── qmk.ini
│   │   │   └── yamllint/
│   │   │       ├── config.yaml
│   │   │       └── default.nix
│   │   ├── services/
│   │   │   └── opencloud-client/
│   │   │       └── default.nix
│   │   ├── shell/
│   │   │   ├── dircolors/
│   │   │   │   └── default.nix
│   │   │   ├── fish/
│   │   │   │   └── default.nix
│   │   │   ├── git/
│   │   │   │   └── default.nix
│   │   │   ├── lf/
│   │   │   │   ├── configs/
│   │   │   │   │   ├── colors
│   │   │   │   │   └── icons
│   │   │   │   └── default.nix
│   │   │   ├── nix-direnv/
│   │   │   │   └── default.nix
│   │   │   └── starship/
│   │   │       └── default.nix
│   │   ├── terminal-emulator/
│   │   │   ├── alacritty/
│   │   │   │   └── default.nix
│   │   │   ├── contour/
│   │   │   │   ├── config/
│   │   │   │   │   └── contour.yml
│   │   │   │   └── default.nix
│   │   │   ├── kitty/
│   │   │   │   └── default.nix
│   │   │   └── wezterm/
│   │   │       ├── config/
│   │   │       │   └── wezterm.lua
│   │   │       └── default.nix
│   │   └── windowmanager/
│   │       ├── add-on/
│   │       │   ├── blueman-applet/
│   │       │   │   └── default.nix
│   │       │   ├── dunst/
│   │       │   │   └── default.nix
│   │       │   ├── gtk-theme/
│   │       │   │   └── default.nix
│   │       │   ├── nm-applet/
│   │       │   │   └── default.nix
│   │       │   ├── nwg-bar/
│   │       │   │   └── default.nix
│   │       │   ├── pasystray/
│   │       │   │   └── default.nix
│   │       │   ├── picom/
│   │       │   │   └── default.nix
│   │       │   ├── py3status/
│   │       │   │   ├── config
│   │       │   │   └── default.nix
│   │       │   ├── rofi/
│   │       │   │   ├── default.nix
│   │       │   │   └── style.rasi
│   │       │   ├── screenshotter/
│   │       │   │   ├── camera-shutter.oga
│   │       │   │   └── default.nix
│   │       │   ├── swayidle/
│   │       │   │   └── default.nix
│   │       │   ├── swaylock/
│   │       │   │   └── default.nix
│   │       │   ├── terminal-emulator/
│   │       │   │   └── default.nix
│   │       │   ├── theme/
│   │       │   │   └── tokyonight/
│   │       │   │       └── default.nix
│   │       │   ├── waybar/
│   │       │   │   └── default.nix
│   │       │   └── xdg/
│   │       │       └── default.nix
│   │       ├── hyprland/
│   │       │   ├── config/
│   │       │   │   ├── appearances.nix
│   │       │   │   ├── default.nix
│   │       │   │   ├── keybindings.nix
│   │       │   │   ├── window-rules.nix
│   │       │   │   └── ws-outputs.nix
│   │       │   └── default.nix
│   │       ├── i3/
│   │       │   ├── config/
│   │       │   │   ├── commands.nix
│   │       │   │   ├── default.nix
│   │       │   │   ├── keybindings.nix
│   │       │   │   ├── modes.nix
│   │       │   │   └── startups.nix
│   │       │   └── default.nix
│   │       └── sway/
│   │           ├── config/
│   │           │   ├── commands.nix
│   │           │   ├── default.nix
│   │           │   ├── keybindings.nix
│   │           │   ├── modes.nix
│   │           │   └── startups.nix
│   │           └── default.nix
│   └── budiman/
│       ├── config/
│       │   ├── gitcommit-message
│       │   └── neovim/
│       │       ├── appearance.nix
│       │       ├── autocmds.nix
│       │       ├── default.nix
│       │       ├── diagnostic.nix
│       │       ├── general.nix
│       │       ├── keymaps.nix
│       │       ├── lsp.nix
│       │       ├── lua/
│       │       │   └── utils.lua
│       │       └── plugins/
│       │           ├── blink-cmp/
│       │           │   └── default.nix
│       │           ├── chezmoi-vim/
│       │           │   └── default.nix
│       │           ├── cord/
│       │           │   └── default.nix
│       │           ├── default.nix
│       │           ├── endec/
│       │           │   └── default.nix
│       │           ├── gitsigns/
│       │           │   └── default.nix
│       │           ├── grug-far/
│       │           │   └── default.nix
│       │           ├── lualine/
│       │           │   └── default.nix
│       │           ├── luasnip/
│       │           │   ├── default.nix
│       │           │   └── lua-snippets/
│       │           │       └── gitcommit.lua
│       │           ├── mini/
│       │           │   ├── comment.nix
│       │           │   ├── default.nix
│       │           │   ├── icons.nix
│       │           │   ├── indentscope.nix
│       │           │   ├── surround.nix
│       │           │   └── trailspace.nix
│       │           ├── noice/
│       │           │   └── default.nix
│       │           ├── none-ls/
│       │           │   └── default.nix
│       │           ├── nvim-autopairs/
│       │           │   ├── _rules.lua
│       │           │   └── default.nix
│       │           ├── oil/
│       │           │   └── default.nix
│       │           ├── snacks/
│       │           │   ├── default.nix
│       │           │   ├── input.nix
│       │           │   └── picker.nix
│       │           ├── toggleterm/
│       │           │   └── default.nix
│       │           └── treesitter/
│       │               └── default.nix
│       ├── default.nix
│       ├── hosts/
│       │   ├── budimanjojo-firewall.nix
│       │   ├── budimanjojo-main.nix
│       │   ├── budimanjojo-nas.nix
│       │   ├── budimanjojo-oracle.nix
│       │   └── budimanjojo-ubuntu.nix
│       └── profiles/
│           ├── extra-gaming.nix
│           ├── extra-graphics.nix
│           ├── extra-utilities.nix
│           ├── server.nix
│           ├── workstation-common.nix
│           ├── workstation-hyprland.nix
│           ├── workstation-i3.nix
│           └── workstation-sway.nix
├── lib/
│   └── default.nix
├── overlays/
│   └── default.nix
├── packages/
│   ├── _sources/
│   │   ├── generated.json
│   │   └── generated.nix
│   ├── configure-gtk/
│   │   └── default.nix
│   ├── default.nix
│   ├── fish-plugins/
│   │   └── default.nix
│   ├── krr/
│   │   ├── about-time.nix
│   │   ├── alive-progress.nix
│   │   ├── default.nix
│   │   └── prometheus-api-client.nix
│   ├── kubectl-rook-ceph/
│   │   └── default.nix
│   ├── nvfetcher.toml
│   ├── nvim-plugins/
│   │   └── default.nix
│   ├── tokyonight-gtk-theme/
│   │   └── default.nix
│   └── tokyonight-icon-theme/
│       └── default.nix
├── shell.nix
└── system/
    ├── _modules/
    │   ├── _default/
    │   │   ├── default.nix
    │   │   ├── nix.nix
    │   │   ├── secret.sops.yaml
    │   │   ├── sops.nix
    │   │   └── users.nix
    │   ├── containers/
    │   │   └── beeaccounting/
    │   │       ├── default.nix
    │   │       └── secret.sops.yaml
    │   ├── default.nix
    │   ├── displaymanager/
    │   │   └── sddm/
    │   │       └── default.nix
    │   ├── monitoring/
    │   │   ├── node-exporter/
    │   │   │   └── default.nix
    │   │   └── smartctl-exporter/
    │   │       └── default.nix
    │   ├── myHardware.nix
    │   ├── programs/
    │   │   ├── adb/
    │   │   │   └── default.nix
    │   │   ├── hugo/
    │   │   │   └── default.nix
    │   │   ├── msmtp/
    │   │   │   ├── default.nix
    │   │   │   └── secret.sops.yaml
    │   │   ├── nh/
    │   │   │   └── default.nix
    │   │   └── qmk/
    │   │       └── default.nix
    │   ├── services/
    │   │   ├── btrfs-autoscrub/
    │   │   │   └── default.nix
    │   │   ├── grafana/
    │   │   │   ├── default.nix
    │   │   │   └── secret.sops.yaml
    │   │   ├── openssh/
    │   │   │   └── default.nix
    │   │   ├── prometheus/
    │   │   │   ├── default.nix
    │   │   │   └── rules/
    │   │   │       ├── embedded-exporter.yaml
    │   │   │       └── node-exporter.yaml
    │   │   └── restic-backup/
    │   │       ├── default.nix
    │   │       └── secret.sops.yaml
    │   ├── system/
    │   │   ├── autoupgrade/
    │   │   │   └── default.nix
    │   │   ├── bootloader/
    │   │   │   └── default.nix
    │   │   ├── cpu/
    │   │   │   └── default.nix
    │   │   ├── font/
    │   │   │   └── default.nix
    │   │   ├── sound/
    │   │   │   └── default.nix
    │   │   └── video/
    │   │       └── default.nix
    │   └── windowmanager/
    │       ├── add-on/
    │       │   ├── blueman/
    │       │   │   └── default.nix
    │       │   ├── gnome-keyring/
    │       │   │   └── default.nix
    │       │   ├── networkmanager/
    │       │   │   └── default.nix
    │       │   ├── polkit-gnome/
    │       │   │   └── default.nix
    │       │   └── thunar/
    │       │       └── default.nix
    │       ├── hyprland/
    │       │   └── default.nix
    │       ├── i3/
    │       │   └── default.nix
    │       └── sway/
    │           └── default.nix
    ├── hosts/
    │   ├── budimanjojo-firewall/
    │   │   ├── _modules/
    │   │   │   ├── default.nix
    │   │   │   ├── firewall/
    │   │   │   │   ├── config/
    │   │   │   │   │   ├── sets.nft
    │   │   │   │   │   ├── zone-directions.nft
    │   │   │   │   │   └── zone-rules.nft
    │   │   │   │   └── default.nix
    │   │   │   ├── network.nix
    │   │   │   ├── podman.nix
    │   │   │   ├── secret.sops.yaml
    │   │   │   ├── services/
    │   │   │   │   ├── adguardhome/
    │   │   │   │   │   ├── default.nix
    │   │   │   │   │   └── secret.sops.yaml
    │   │   │   │   ├── chrony/
    │   │   │   │   │   └── default.nix
    │   │   │   │   ├── fireqos/
    │   │   │   │   │   └── default.nix
    │   │   │   │   ├── frr/
    │   │   │   │   │   └── default.nix
    │   │   │   │   ├── kea/
    │   │   │   │   │   ├── ddns.nix
    │   │   │   │   │   ├── default.nix
    │   │   │   │   │   ├── dhcp.nix
    │   │   │   │   │   └── secret.sops.yaml
    │   │   │   │   ├── omada-controller/
    │   │   │   │   │   ├── default.nix
    │   │   │   │   │   ├── secret.sops.yaml
    │   │   │   │   │   └── ssl.crt
    │   │   │   │   ├── powerdns/
    │   │   │   │   │   ├── default.nix
    │   │   │   │   │   └── secret.sops.yaml
    │   │   │   │   ├── rsyslogd/
    │   │   │   │   │   └── default.nix
    │   │   │   │   └── tdarr/
    │   │   │   │       └── default.nix
    │   │   │   └── wireguard.nix
    │   │   ├── default.nix
    │   │   ├── disk-config.nix
    │   │   └── hardware-configuration.nix
    │   ├── budimanjojo-main/
    │   │   ├── default.nix
    │   │   └── hardware-configuration.nix
    │   ├── budimanjojo-nas/
    │   │   ├── _modules/
    │   │   │   ├── default.nix
    │   │   │   ├── incus.nix
    │   │   │   ├── network.nix
    │   │   │   ├── nfs.nix
    │   │   │   └── secret.sops.yaml
    │   │   ├── default.nix
    │   │   ├── disk-config.nix
    │   │   └── hardware-configuration.nix
    │   ├── budimanjojo-oracle/
    │   │   ├── _modules/
    │   │   │   ├── default.nix
    │   │   │   ├── firewall.nix
    │   │   │   ├── network.nix
    │   │   │   ├── secret.sops.yaml
    │   │   │   ├── services/
    │   │   │   │   ├── blocky/
    │   │   │   │   │   ├── config.yaml
    │   │   │   │   │   ├── default.nix
    │   │   │   │   │   └── secret.sops.yaml
    │   │   │   │   └── qbittorrent/
    │   │   │   │       └── default.nix
    │   │   │   └── wireguard.nix
    │   │   ├── default.nix
    │   │   └── hardware-configuration.nix
    │   ├── default.nix
    │   └── nixos-livecd/
    │       └── default.nix
    ├── profiles/
    │   ├── gaming.nix
    │   ├── server.nix
    │   ├── work.nix
    │   ├── workstation-common.nix
    │   ├── workstation-hyprland.nix
    │   ├── workstation-i3.nix
    │   └── workstation-sway.nix
    └── pubkeys/
        └── default.nix
Condensed preview — 266 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (536K chars).
[
  {
    "path": ".chezmoiroot",
    "chars": 8,
    "preview": "chezmoi\n"
  },
  {
    "path": ".editorconfig",
    "chars": 331,
    "preview": "; https://editorconfig.org/\n\n; top-most EditorConfig file\nroot = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_l"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 20,
    "preview": "github: budimanjojo\n"
  },
  {
    "path": ".github/renovate.json",
    "chars": 1192,
    "preview": "{\n  \"extends\": [\n    \"github>budimanjojo/renovate-config:default.json5\"\n  ],\n  \"username\": \"budimanjojo-bot[bot]\",\n  \"gi"
  },
  {
    "path": ".github/workflows/broken-link-check.yaml",
    "chars": 1385,
    "preview": "---\nname: Broken link check\n\non:\n  workflow_dispatch:\n  schedule:\n    - cron: \"0 0 * * 0\"\n\njobs:\n  check:\n    name: Chec"
  },
  {
    "path": ".github/workflows/build-push-cache.yaml",
    "chars": 2796,
    "preview": "---\nname: Build Push Cache\n\non:\n  workflow_dispatch: {}\n  push:\n    paths:\n      - \"system/**\"\n      - \"home/**\"\n      -"
  },
  {
    "path": ".github/workflows/check-flakes.yaml",
    "chars": 575,
    "preview": "---\nname: Check Flakes\n\non:\n  pull_request_target:\n    types:\n      - opened\n      - auto_merge_enabled\n  push:\n    path"
  },
  {
    "path": ".github/workflows/renovate.yaml",
    "chars": 1267,
    "preview": "---\nname: Renovate\n\non:\n  workflow_dispatch:\n    inputs:\n      dryRun:\n        description: Dry-Run\n        default: \"fa"
  },
  {
    "path": ".github/workflows/update-nvfetcher.yaml",
    "chars": 2557,
    "preview": "---\nname: Update nvfetcher\n\non:\n  workflow_dispatch: {}\n  schedule:\n    - cron: 0 * * * *\n  push:\n    paths:\n      - pac"
  },
  {
    "path": ".github/workflows/update-sops-keys.yaml",
    "chars": 2010,
    "preview": "---\nname: Update SOPS keys\n\non:\n  workflow_dispatch: {}\n  schedule:\n    - cron: 0 * * * *\n  push:\n    paths:\n      - .so"
  },
  {
    "path": ".gitignore",
    "chars": 19,
    "preview": ".luarc.json\nresult\n"
  },
  {
    "path": ".justfile",
    "chars": 2535,
    "preview": "set unstable := true\nset shell := ['bash', '-euo', 'pipefail', '-c']\n\n# `nix` is required\nrequireNixToRun := require('ni"
  },
  {
    "path": ".sops.yaml",
    "chars": 538,
    "preview": "---\ncreation_rules:\n  - path_regex: .*secret\\.sops\\.ya?ml$\n    key_groups:\n      - age:\n          - age1zeqkpfz7e3s207yn"
  },
  {
    "path": "LICENSE",
    "chars": 1211,
    "preview": "This is free and unencumbered software released into the public domain.\n\nAnyone is free to copy, modify, publish, use, c"
  },
  {
    "path": "README.md",
    "chars": 19835,
    "preview": "<div align=\"center\">\n\n<img src=\"https://raw.githubusercontent.com/NixOS/nixos-artwork/376ed4ba8dc2e611b7e8a62fdc680967ea"
  },
  {
    "path": "chezmoi/.chezmoi.yaml.tmpl",
    "chars": 1395,
    "preview": "{{- /* Checks if running interactively */ -}}\n{{- $interactive := stdinIsATTY -}}\n\n{{- /* Template file for chezmoi conf"
  },
  {
    "path": "chezmoi/.chezmoiignore",
    "chars": 99,
    "preview": "{{- if .headless }}\n.config/alacritty/\n.config/kitty/\n.config/termite/\n.config/wezterm/\n{{- end }}\n"
  },
  {
    "path": "chezmoi/.chezmoiscripts/run_once_after_90-cleanup.sh.tmpl",
    "chars": 2836,
    "preview": "#!/bin/bash\n\necho -e \"\\033[0;32m>>>>> Begin Executing Cleanup Job <<<<<\\033[0m\"\n\n# This script will ensure that I fixes "
  },
  {
    "path": "chezmoi/.chezmoiscripts/run_once_before_10-setup-fish.sh.tmpl",
    "chars": 925,
    "preview": "{{ if (eq .chezmoi.os \"linux\") -}}\n#!/bin/bash\nset -eufo pipefail\n\necho -e \"\\0033[0;32m>>>>> Begin Setting Up Fish Shell"
  },
  {
    "path": "chezmoi/.chezmoiscripts/run_once_before_20-install-packages-archlinux.sh.tmpl",
    "chars": 1359,
    "preview": "{{ if (eq .chezmoi.osRelease.id \"arch\") -}}\n#!/bin/bash\n\nset -eufo pipefail\n\necho -e \"\\033[0;32m>>>>> Begin Setting Up A"
  },
  {
    "path": "chezmoi/.chezmoiscripts/run_once_before_20-install-packages-ubuntu.sh.tmpl",
    "chars": 1860,
    "preview": "{{ if (and (eq .chezmoi.os \"linux\") (eq .chezmoi.osRelease.id \"debian\" \"ubuntu\")) -}}\n#!/bin/bash\n\nset -eufo pipefail\n\ne"
  },
  {
    "path": "chezmoi/.chezmoiscripts/run_onchange_after_80-setup-terminal.sh.tmpl",
    "chars": 2053,
    "preview": "{{ if (and (eq .chezmoi.os \"linux\") (eq .chezmoi.osRelease.id \"debian\" \"ubuntu\")) -}}\n#!/bin/bash\n\necho -e \"\\033[0;32m>>"
  },
  {
    "path": "chezmoi/dot_config/fontconfig/fonts.conf.tmpl",
    "chars": 1170,
    "preview": "{{ if eq .chezmoi.hostname \"budimanjojo-main\" -}}\n<fontconfig>\n<alias>\n    <family>serif</family>\n    <prefer>\n        <"
  },
  {
    "path": "chezmoi/dot_config/termite/config",
    "chars": 2006,
    "preview": "[options]\n#allow_bold = true\n#audible_bell = false\n#bold_is_bright = true\n#cell_height_scale = 1.0\n#cell_width_scale = 1"
  },
  {
    "path": "flake.nix",
    "chars": 6597,
    "preview": "{\n  description = \"My NixOS configurations IaC\";\n\n  inputs = {\n    # nixpkgs and unstable\n    nixpkgs.url = \"github:nixo"
  },
  {
    "path": "flakeLib.nix",
    "chars": 5288,
    "preview": "{ inputs, mkPkgsWithSystem }:\nlet\n  # my own custom lib will be accessible with `lib.myLib.<name>`\n  lib = inputs.nixpkg"
  },
  {
    "path": "home/_modules/_default/default.nix",
    "chars": 372,
    "preview": "{ config, ... }:\nlet\n  myHome = config.myHome;\nin\n{\n  imports = [\n    ./nix.nix\n    ./sops.nix\n  ];\n\n  config = {\n    ho"
  },
  {
    "path": "home/_modules/_default/nix.nix",
    "chars": 885,
    "preview": "{\n  lib,\n  osConfig,\n  pkgs,\n  inputs,\n  ...\n}:\nlet\n  isNixos = lib.myLib.isNixos osConfig;\nin\n{\n  # only enable when we"
  },
  {
    "path": "home/_modules/_default/sops.nix",
    "chars": 360,
    "preview": "{\n  lib,\n  osConfig,\n  pkgs,\n  config,\n  ...\n}:\nlet\n  isNixos = lib.myLib.isNixos osConfig;\nin\n{\n  config = {\n    home.p"
  },
  {
    "path": "home/_modules/browser/firefox/default.nix",
    "chars": 2248,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  options,\n  ...\n}:\nlet\n  inherit (lib)\n    getExe\n    mkOption\n    types\n    mkPackageOption"
  },
  {
    "path": "home/_modules/default.nix",
    "chars": 1772,
    "preview": "{ lib, osConfig, ... }:\nlet\n  inherit (lib)\n    mkOption\n    types\n    myLib\n    mkDefault\n    ;\nin\n{\n  imports = [\n    "
  },
  {
    "path": "home/_modules/editor/neovim/default.nix",
    "chars": 576,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.editor.neovim;\nin\n{\n  options.myHome.editor.neovim = {\n   "
  },
  {
    "path": "home/_modules/homelab/kubernetes/default.nix",
    "chars": 1692,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  myPkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.homelab.kubernetes;\nin\n{\n  options.myHome.homela"
  },
  {
    "path": "home/_modules/homelab/kubernetes/secret.sops.yaml",
    "chars": 9391,
    "preview": "kubeconfig: ENC[AES256_GCM,data:pfVS55vfo3YNYpYLfQSot40QWl2VEJaVsO6SfbI2284uO/OLsK6VD/6XQBT9UhzPU8dbJolYePEfeaRIcU5v1qqX"
  },
  {
    "path": "home/_modules/multiplexer/tmux/config/tmux.conf",
    "chars": 8063,
    "preview": "# SERVER OPTIONS\nset -g buffer-limit 20 # number of buffers, older than limit buffer will be removed\nset -g default-term"
  },
  {
    "path": "home/_modules/multiplexer/tmux/default.nix",
    "chars": 1910,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.multiplexer.tmux;\n  inherit (lib) mkEnableOption mkIf;\nin\n"
  },
  {
    "path": "home/_modules/multiplexer/zellij/config/config.kdl",
    "chars": 1358,
    "preview": "default_mode \"normal\"\ntheme \"catppuccin-mocha\"\nkeybinds clear-defaults=true {\n  normal {\n    bind \"Alt a\" { SwitchToMode"
  },
  {
    "path": "home/_modules/multiplexer/zellij/config/layouts/default.kdl",
    "chars": 95,
    "preview": "layout {\n  pane\n  pane size=1 borderless=true {\n    plugin location=\"zellij:compact-bar\"\n  }\n}\n"
  },
  {
    "path": "home/_modules/multiplexer/zellij/default.nix",
    "chars": 712,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.multiplexer.zellij;\n  cmd = lib.getExe config.programs.zel"
  },
  {
    "path": "home/_modules/programs/beeaccounting/default.nix",
    "chars": 2464,
    "preview": "{\n  lib,\n  osConfig,\n  config,\n  pkgs,\n  ...\n}:\nwith lib;\nlet\n  systemEnabled = myLib.systemEnabled \"mySystem.containers"
  },
  {
    "path": "home/_modules/programs/chezmoi/default.nix",
    "chars": 804,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.programs.chezmoi;\n  inherit (lib) mkEnableOption mkIf;\nin\n"
  },
  {
    "path": "home/_modules/programs/fontconfig/default.nix",
    "chars": 218,
    "preview": "{\n  lib,\n  osConfig,\n  pkgs,\n  ...\n}:\n{\n  config = lib.mkIf (!lib.myLib.isNixos osConfig) {\n    fonts.fontconfig.enable "
  },
  {
    "path": "home/_modules/programs/go/default.nix",
    "chars": 268,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.programs.go;\nin\n{\n  options.myHome.programs.go.enable = li"
  },
  {
    "path": "home/_modules/programs/obs-studio/default.nix",
    "chars": 364,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.programs.obs-studio;\nin\n{\n  options.myHome.programs.obs-st"
  },
  {
    "path": "home/_modules/programs/qmk/default.nix",
    "chars": 721,
    "preview": "{\n  lib,\n  config,\n  osConfig,\n  pkgs,\n  ...\n}:\nlet\n  inherit (lib) myLib mkEnableOption mkIf;\n  cfg = config.myHome.pro"
  },
  {
    "path": "home/_modules/programs/qmk/qmk.ini",
    "chars": 551,
    "preview": "[user]\nqmk_home = /home/budiman/Github/qmk_firmware\nkeyboard = crkbd/rev1\nkeymap = budimanjojo\n\n[mass_compile]\nkeymap = "
  },
  {
    "path": "home/_modules/programs/yamllint/config.yaml",
    "chars": 330,
    "preview": "---\nextends: relaxed\n\nyaml-files:\n  - '*.yaml'\n  - '*.yml'\n  - '.yamllint'\n\nrules:\n  empty-lines:\n    max: 1\n  empty-val"
  },
  {
    "path": "home/_modules/programs/yamllint/default.nix",
    "chars": 317,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.programs.yamllint;\nin\n{\n  options.myHome.programs.yamllint"
  },
  {
    "path": "home/_modules/services/opencloud-client/default.nix",
    "chars": 705,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.services.opencloud-client;\nin\n{\n  options.myHome.services."
  },
  {
    "path": "home/_modules/shell/dircolors/default.nix",
    "chars": 6919,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.myHome.shell.dircolors;\nin\n{\n  options.myHome.shell.dircolors = {\n    enable = "
  },
  {
    "path": "home/_modules/shell/fish/default.nix",
    "chars": 4279,
    "preview": "{\n  lib,\n  config,\n  osConfig,\n  pkgs,\n  myPkgs,\n  ...\n}:\nlet\n  inherit (lib) myLib mkEnableOption mkIf;\n\n  cfg = config"
  },
  {
    "path": "home/_modules/shell/git/default.nix",
    "chars": 1020,
    "preview": "{\n  config,\n  lib,\n  options,\n  ...\n}:\nlet\n  cfg = config.myHome.shell.git;\n  inherit (lib)\n    mkEnableOption\n    mkOpt"
  },
  {
    "path": "home/_modules/shell/lf/configs/colors",
    "chars": 3396,
    "preview": "# vim:ft=dircolors\n# (This is not a dircolors file but it helps to highlight colors and comments)\n\n# default values from"
  },
  {
    "path": "home/_modules/shell/lf/configs/icons",
    "chars": 6531,
    "preview": "# vim:ft=conf\n\n# These examples require Nerd Fonts or a compatible font to be used.\n# See https://www.nerdfonts.com for "
  },
  {
    "path": "home/_modules/shell/lf/default.nix",
    "chars": 3511,
    "preview": "{\n  pkgs,\n  lib,\n  config,\n  ...\n}:\nlet\n  myHome = config.myHome;\n  cfg = myHome.shell.lf;\nin\n{\n  options.myHome.shell.l"
  },
  {
    "path": "home/_modules/shell/nix-direnv/default.nix",
    "chars": 337,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.myHome.shell.nix-direnv;\nin\n{\n  options.myHome.shell.nix-direnv = {\n    enable "
  },
  {
    "path": "home/_modules/shell/starship/default.nix",
    "chars": 3462,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.shell.starship;\nin\n{\n  options.myHome.shell.starship = {\n "
  },
  {
    "path": "home/_modules/terminal-emulator/alacritty/default.nix",
    "chars": 1015,
    "preview": "{\n  lib,\n  config,\n  pkgs,\n  ...\n}:\nwith lib;\nlet\n  cfg = config.myHome.terminal-emulator.alacritty;\nin\n{\n  options.myHo"
  },
  {
    "path": "home/_modules/terminal-emulator/contour/config/contour.yml",
    "chars": 2465,
    "preview": "---\non_mouse_select: CopyToSelectionClipboard\nprofiles:\n  main:\n    show_title_bar: false\n    maximized: true\n    enviro"
  },
  {
    "path": "home/_modules/terminal-emulator/contour/default.nix",
    "chars": 360,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.terminal-emulator.contour;\nin\n{\n  options.myHome.terminal-"
  },
  {
    "path": "home/_modules/terminal-emulator/kitty/default.nix",
    "chars": 1112,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.terminal-emulator.kitty;\nin\n{\n  options.myHome.terminal-em"
  },
  {
    "path": "home/_modules/terminal-emulator/wezterm/config/wezterm.lua",
    "chars": 1245,
    "preview": "local wezterm = require 'wezterm'\nlocal act = wezterm.action\n\n-- Start window maximized\nwezterm.on(\"gui-startup\", functi"
  },
  {
    "path": "home/_modules/terminal-emulator/wezterm/default.nix",
    "chars": 461,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.terminal-emulator.wezterm;\nin\n{\n  options.myHome.terminal-"
  },
  {
    "path": "home/_modules/windowmanager/add-on/blueman-applet/default.nix",
    "chars": 301,
    "preview": "{ config, lib, ... }:\nlet\n  myHome = config.myHome;\n  cfg = myHome.windowmanager.add-on.blueman-applet;\nin\n{\n  options.m"
  },
  {
    "path": "home/_modules/windowmanager/add-on/dunst/default.nix",
    "chars": 2892,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.windowmanager.add-on.dunst;\nin\n{\n  options.myHome.windowma"
  },
  {
    "path": "home/_modules/windowmanager/add-on/gtk-theme/default.nix",
    "chars": 840,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  myPkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.windowmanager.add-on.gtk-theme;\nin\n{\n  options.m"
  },
  {
    "path": "home/_modules/windowmanager/add-on/nm-applet/default.nix",
    "chars": 328,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.myHome.windowmanager.add-on.nm-applet;\nin\n{\n  options.myHome.windowmanager.add-"
  },
  {
    "path": "home/_modules/windowmanager/add-on/nwg-bar/default.nix",
    "chars": 2098,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.windowmanager.add-on.nwg-bar;\nin\n{\n  options.myHome.window"
  },
  {
    "path": "home/_modules/windowmanager/add-on/pasystray/default.nix",
    "chars": 262,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.myHome.windowmanager.add-on.pasystray;\nin\n{\n  options.myHome.windowmanager.add-"
  },
  {
    "path": "home/_modules/windowmanager/add-on/picom/default.nix",
    "chars": 3976,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.myHome.windowmanager.add-on.picom;\nin\n{\n  options.myHome.windowmanager.add-on.p"
  },
  {
    "path": "home/_modules/windowmanager/add-on/py3status/config",
    "chars": 1346,
    "preview": "order += \"frame net\"\norder += \"net_rate\"\norder += \"frame disks\"\norder += \"uname\"\norder += \"frame timedate\"\norder += \"who"
  },
  {
    "path": "home/_modules/windowmanager/add-on/py3status/default.nix",
    "chars": 281,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.myHome.windowmanager.add-on.py3status;\nin\n{\n  options.myHome.windowmanager.add-"
  },
  {
    "path": "home/_modules/windowmanager/add-on/rofi/default.nix",
    "chars": 558,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  myHome = config.myHome;\n  cfg = myHome.windowmanager.add-on.rofi;\nin\n{\n  optio"
  },
  {
    "path": "home/_modules/windowmanager/add-on/rofi/style.rasi",
    "chars": 3823,
    "preview": "* {\n  selected-normal-foreground:  #1A1B26;\n  foreground:                  #C0CAF5;\n  normal-foreground:           @fore"
  },
  {
    "path": "home/_modules/windowmanager/add-on/screenshotter/default.nix",
    "chars": 3643,
    "preview": "{\n  config,\n  pkgs,\n  lib,\n  ...\n}:\nlet\n  cfg = config.myHome.windowmanager.add-on.screenshotter;\n  wl-full-screenshot ="
  },
  {
    "path": "home/_modules/windowmanager/add-on/swayidle/default.nix",
    "chars": 1021,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.windowmanager.add-on.swayidle;\n  wmCfg = config.wayland.wi"
  },
  {
    "path": "home/_modules/windowmanager/add-on/swaylock/default.nix",
    "chars": 1283,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.myHome.windowmanager.add-on.swaylock;\nin\n{\n  options.myHome.windo"
  },
  {
    "path": "home/_modules/windowmanager/add-on/terminal-emulator/default.nix",
    "chars": 1133,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.myHome.windowmanager.add-on.terminal-emulator;\n  super = \"Mod4\";\n  inherit (lib"
  },
  {
    "path": "home/_modules/windowmanager/add-on/theme/tokyonight/default.nix",
    "chars": 3887,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.myHome.windowmanager.add-on.theme.tokyonight;\n  # Tokyonight Night color scheme"
  },
  {
    "path": "home/_modules/windowmanager/add-on/waybar/default.nix",
    "chars": 4003,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  myHome = config.myHome;\n  myHardware = config.myHardware;\n  cfg = myHome.windo"
  },
  {
    "path": "home/_modules/windowmanager/add-on/xdg/default.nix",
    "chars": 293,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.myHome.windowmanager.add-on.xdg;\nin\n{\n  options.myHome.windowmanager.add-on.xdg"
  },
  {
    "path": "home/_modules/windowmanager/hyprland/config/appearances.nix",
    "chars": 325,
    "preview": "{\n  general = {\n    gaps_in = 5;\n    gaps_out = 20;\n    \"col.inactive_border\" = \"rgb(A9B1D6)\";\n    \"col.active_border\" ="
  },
  {
    "path": "home/_modules/windowmanager/hyprland/config/default.nix",
    "chars": 1926,
    "preview": "{\n  config,\n  pkgs,\n  lib,\n  ...\n}:\nlet\n  myHardware = config.myHardware;\n  resizeMode = \"Resize: (h/Left) width- (j/Dow"
  },
  {
    "path": "home/_modules/windowmanager/hyprland/config/keybindings.nix",
    "chars": 2739,
    "preview": "{\n  config,\n  resizeMode,\n  pkgs,\n}:\n{\n  bindm = [\n    # Super+mouse to drag/resize floating windows\n    \"SUPER, mouse:2"
  },
  {
    "path": "home/_modules/windowmanager/hyprland/config/window-rules.nix",
    "chars": 1371,
    "preview": "{\n  windowrulev2 = [\n    # Window floating and layout\n    \"float, class:^(pavucontrol)$\"\n    \"float, class:^(thunar)$\"\n "
  },
  {
    "path": "home/_modules/windowmanager/hyprland/config/ws-outputs.nix",
    "chars": 411,
    "preview": "{ config }:\nlet\n  strBool = b: if b then \"true\" else \"false\";\n  mkWorkspaces =\n    monitors:\n    builtins.concatMap (\n  "
  },
  {
    "path": "home/_modules/windowmanager/hyprland/default.nix",
    "chars": 1495,
    "preview": "{\n  config,\n  osConfig,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  myHardware = config.myHardware;\n  cfg = config.myHome.windowmanage"
  },
  {
    "path": "home/_modules/windowmanager/i3/config/commands.nix",
    "chars": 1460,
    "preview": "[\n  {\n    criteria = {\n      window_role = \"pop-up\";\n    };\n    command = \"floating enable\";\n  }\n  {\n    criteria = {\n  "
  },
  {
    "path": "home/_modules/windowmanager/i3/config/default.nix",
    "chars": 1128,
    "preview": "{\n  config,\n  pkgs,\n  lib,\n}:\nlet\n  myHardware = config.myHardware;\n  modes = {\n    resize = \"Resize: (h/Left) width-, ("
  },
  {
    "path": "home/_modules/windowmanager/i3/config/keybindings.nix",
    "chars": 3893,
    "preview": "{\n  config,\n  pkgs,\n  modes,\n}:\nlet\n  super = \"Mod4\";\nin\n{\n  # kill focused window\n  \"${super}+F4\" = \"kill\";\n  # change "
  },
  {
    "path": "home/_modules/windowmanager/i3/config/modes.nix",
    "chars": 2360,
    "preview": "{ modes, pkgs }:\n{\n  # resize window (you can also use the mouse for that)\n  ${modes.resize} = {\n    h = \"resize shrink "
  },
  {
    "path": "home/_modules/windowmanager/i3/config/startups.nix",
    "chars": 968,
    "preview": "{\n  config,\n  pkgs,\n  lib,\n}:\nlet\n  wallpapers = builtins.map (m: m.wallpaper) (\n    builtins.filter (m: m.wallpaper != "
  },
  {
    "path": "home/_modules/windowmanager/i3/default.nix",
    "chars": 1441,
    "preview": "{\n  config,\n  lib,\n  osConfig,\n  pkgs,\n  ...\n}:\nlet\n  myHardware = config.myHardware;\n  cfg = config.myHome.windowmanage"
  },
  {
    "path": "home/_modules/windowmanager/sway/config/commands.nix",
    "chars": 2092,
    "preview": "[\n  # Window title formatting\n  {\n    criteria = {\n      class = \".*\";\n    };\n    command = \"title_format \\\"<b> %title</"
  },
  {
    "path": "home/_modules/windowmanager/sway/config/default.nix",
    "chars": 1487,
    "preview": "{\n  config,\n  pkgs,\n  lib,\n}:\nlet\n  myHardware = config.myHardware;\n  modes = {\n    resize = \"Resize: (h/Left) width-, ("
  },
  {
    "path": "home/_modules/windowmanager/sway/config/keybindings.nix",
    "chars": 4107,
    "preview": "{\n  config,\n  modes,\n  pkgs,\n}:\nlet\n  super = \"Mod4\";\nin\n{\n  # Kill focused window\n  \"${super}+F4\" = \"kill\";\n  # Change "
  },
  {
    "path": "home/_modules/windowmanager/sway/config/modes.nix",
    "chars": 1581,
    "preview": "{ modes, pkgs }:\n{\n  # Resize  window\n  ${modes.resize} = {\n    h = \"resize shrink width\";\n    j = \"resize grow height\";"
  },
  {
    "path": "home/_modules/windowmanager/sway/config/startups.nix",
    "chars": 153,
    "preview": "{ pkgs }:\n[\n  {\n    command = \"${pkgs.sway-contrib.inactive-windows-transparency}/bin/inactive-windows-transparency.py -"
  },
  {
    "path": "home/_modules/windowmanager/sway/default.nix",
    "chars": 1614,
    "preview": "{\n  config,\n  osConfig,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  myHardware = config.myHardware;\n  cfg = config.myHome.windowmanage"
  },
  {
    "path": "home/budiman/config/gitcommit-message",
    "chars": 772,
    "preview": "\n\nSigned-off-by: budimanjojo <budimanjojo@gmail.com>\n# <type>[optional scope]: <description>                            "
  },
  {
    "path": "home/budiman/config/neovim/appearance.nix",
    "chars": 682,
    "preview": "{ pkgs, ... }:\n{\n  config = {\n    ## Highlght on yank\n    autoGroups.yankhighlight.clear = true;\n    autoCmd = [\n      {"
  },
  {
    "path": "home/budiman/config/neovim/autocmds.nix",
    "chars": 4468,
    "preview": "{\n  config = {\n    autoGroups.disabledeindenthastag.clear = true;\n    autoGroups.disableautocomment.clear = true;\n    au"
  },
  {
    "path": "home/budiman/config/neovim/default.nix",
    "chars": 240,
    "preview": "{\n  imports = [\n    ./lsp.nix\n    ./plugins\n    ./general.nix\n    ./appearance.nix\n    ./autocmds.nix\n    ./diagnostic.n"
  },
  {
    "path": "home/budiman/config/neovim/diagnostic.nix",
    "chars": 1337,
    "preview": "{ lib, ... }:\n{\n  config = {\n    diagnostic.settings = {\n      virtual_text = false;\n      update_in_insert = true;\n    "
  },
  {
    "path": "home/budiman/config/neovim/general.nix",
    "chars": 2570,
    "preview": "{\n  config = {\n    extraConfigLua = ''\n      -- General options\n      vim.cmd(\"filetype plugin indent on\")\n      vim.cmd"
  },
  {
    "path": "home/budiman/config/neovim/keymaps.nix",
    "chars": 5642,
    "preview": "{\n  config = {\n    extraConfigLuaPre = ''\n      -- Space is <Leader>\n      vim.keymap.set(\"\", \"<Space>\", \"<Nop>\", { sile"
  },
  {
    "path": "home/budiman/config/neovim/lsp.nix",
    "chars": 5471,
    "preview": "{ pkgs, config, ... }:\nlet\n  snacksPickerEnabled =\n    let\n      snacks = config.plugins.snacks;\n    in\n    snacks.setti"
  },
  {
    "path": "home/budiman/config/neovim/lua/utils.lua",
    "chars": 4085,
    "preview": "local M = {}\n\n-- Returns `cwd` or path of current buffer depending on whether the current window is terminal or nothing\n"
  },
  {
    "path": "home/budiman/config/neovim/plugins/blink-cmp/default.nix",
    "chars": 2977,
    "preview": "{\n  pkgs,\n  lib,\n  config,\n  ...\n}:\n{\n  config.plugins = {\n    blink-cmp = {\n      enable = true;\n      package = pkgs.u"
  },
  {
    "path": "home/budiman/config/neovim/plugins/chezmoi-vim/default.nix",
    "chars": 151,
    "preview": "{ myPkgs, ... }:\n{\n  config = {\n    extraPlugins = [\n      myPkgs.nvim-plugins.chezmoi-vim\n    ];\n\n    globals.\"chezmoi#"
  },
  {
    "path": "home/budiman/config/neovim/plugins/cord/default.nix",
    "chars": 97,
    "preview": "{\n  config.plugins.cord = {\n    enable = true;\n    settings.display.theme = \"catppuccin\";\n  };\n}\n"
  },
  {
    "path": "home/budiman/config/neovim/plugins/default.nix",
    "chars": 371,
    "preview": "{\n  imports = [\n    ./blink-cmp\n    ./chezmoi-vim\n    ./cord\n    ./endec\n    ./gitsigns\n    ./lualine\n    ./grug-far\n   "
  },
  {
    "path": "home/budiman/config/neovim/plugins/endec/default.nix",
    "chars": 418,
    "preview": "{ pkgs, ... }:\n{\n  config = {\n    extraPlugins = [ pkgs.unstable.vimPlugins.endec-nvim ];\n\n    extraConfigLua = ''\n     "
  },
  {
    "path": "home/budiman/config/neovim/plugins/gitsigns/default.nix",
    "chars": 1929,
    "preview": "{\n  config.plugins.gitsigns = {\n    enable = true;\n    settings = {\n      linehl = true;\n      current_line_blame = true"
  },
  {
    "path": "home/budiman/config/neovim/plugins/grug-far/default.nix",
    "chars": 1379,
    "preview": "{\n  config = {\n    plugins.grug-far = {\n      enable = true;\n      settings.keymaps = {\n        replace.n = \"<localleade"
  },
  {
    "path": "home/budiman/config/neovim/plugins/lualine/default.nix",
    "chars": 2389,
    "preview": "{\n  config.plugins.lualine = {\n    enable = true;\n    settings = {\n      options = {\n        theme = \"catppuccin-nvim\";\n"
  },
  {
    "path": "home/budiman/config/neovim/plugins/luasnip/default.nix",
    "chars": 3445,
    "preview": "{\n  pkgs,\n  myPkgs,\n  lib,\n  ...\n}:\nlet\n  vimPlugins = pkgs.vimPlugins // myPkgs.nvim-plugins;\nin\n{\n  config = {\n    ext"
  },
  {
    "path": "home/budiman/config/neovim/plugins/luasnip/lua-snippets/gitcommit.lua",
    "chars": 2634,
    "preview": "local ls = require('luasnip')\nlocal s = ls.snippet\nlocal text = ls.text_node\nlocal insert = ls.insert_node\nlocal choice "
  },
  {
    "path": "home/budiman/config/neovim/plugins/mini/comment.nix",
    "chars": 40,
    "preview": "{ plugins.mini.modules.comment = { }; }\n"
  },
  {
    "path": "home/budiman/config/neovim/plugins/mini/default.nix",
    "chars": 157,
    "preview": "{\n  imports = [\n    ./comment.nix\n    ./icons.nix\n    ./indentscope.nix\n    ./surround.nix\n    ./trailspace.nix\n  ];\n\n  "
  },
  {
    "path": "home/budiman/config/neovim/plugins/mini/icons.nix",
    "chars": 78,
    "preview": "{\n  plugins.mini = {\n    mockDevIcons = true;\n    modules.icons = { };\n  };\n}\n"
  },
  {
    "path": "home/budiman/config/neovim/plugins/mini/indentscope.nix",
    "chars": 120,
    "preview": "{\n  plugins.mini.modules.indentscope = {\n    draw.delay = 0;\n    symbol = \"▎\";\n    options.try_as_border = true;\n  };\n}\n"
  },
  {
    "path": "home/budiman/config/neovim/plugins/mini/surround.nix",
    "chars": 41,
    "preview": "{ plugins.mini.modules.surround = { }; }\n"
  },
  {
    "path": "home/budiman/config/neovim/plugins/mini/trailspace.nix",
    "chars": 900,
    "preview": "{\n  plugins.mini.modules.trailspace = { };\n\n  # custom `trim_trailing_lastline` editorconfig property\n  # that will remo"
  },
  {
    "path": "home/budiman/config/neovim/plugins/noice/default.nix",
    "chars": 1669,
    "preview": "{\n  config = {\n    colorschemes.catppuccin.settings.integrations = {\n      noice = true;\n      notify = true;\n    };\n\n  "
  },
  {
    "path": "home/budiman/config/neovim/plugins/none-ls/default.nix",
    "chars": 1059,
    "preview": "{ pkgs, ... }:\n{\n  config.plugins.none-ls = {\n    enable = true;\n    settings.diagnostics_format = \"[#{c}] #{m} (#{s})\";"
  },
  {
    "path": "home/budiman/config/neovim/plugins/nvim-autopairs/_rules.lua",
    "chars": 2458,
    "preview": "local rule = require('nvim-autopairs.rule')\nlocal cond = require('nvim-autopairs.conds')\nlocal ts_conds = require('nvim-"
  },
  {
    "path": "home/budiman/config/neovim/plugins/nvim-autopairs/default.nix",
    "chars": 231,
    "preview": "{\n  config = {\n    extraFiles.\"lua/nvim-autopairs/_rules.lua\".source = ./_rules.lua;\n    plugins.nvim-autopairs = {\n    "
  },
  {
    "path": "home/budiman/config/neovim/plugins/oil/default.nix",
    "chars": 1005,
    "preview": "{\n  config = {\n    plugins.oil = {\n      enable = true;\n      settings = {\n        columns = [\n          \"icon\"\n        "
  },
  {
    "path": "home/budiman/config/neovim/plugins/snacks/default.nix",
    "chars": 332,
    "preview": "{ pkgs, ... }:\n{\n  imports = [\n    ./picker.nix\n    ./input.nix\n  ];\n\n  config = {\n    plugins.snacks = {\n      enable ="
  },
  {
    "path": "home/budiman/config/neovim/plugins/snacks/input.nix",
    "chars": 258,
    "preview": "{ lib, config, ... }:\n{\n  plugins.snacks.settings = {\n    styles.input = {\n      relative = \"cursor\";\n      row = -3;\n  "
  },
  {
    "path": "home/budiman/config/neovim/plugins/snacks/picker.nix",
    "chars": 2077,
    "preview": "{ pkgs, ... }:\n{\n  plugins.snacks.settings.picker = {\n    layout = \"telescope\";\n\n    layouts.telescope = {\n      reverse"
  },
  {
    "path": "home/budiman/config/neovim/plugins/toggleterm/default.nix",
    "chars": 690,
    "preview": "{\n  config = {\n    plugins.toggleterm = {\n      enable = true;\n      settings = {\n        open_mapping = \"[[<C-t>]]\";\n  "
  },
  {
    "path": "home/budiman/config/neovim/plugins/treesitter/default.nix",
    "chars": 416,
    "preview": "{\n  config.plugins.treesitter = {\n    enable = true;\n    nixvimInjections = true;\n    settings = {\n      highlight = {\n "
  },
  {
    "path": "home/budiman/default.nix",
    "chars": 726,
    "preview": "{\n  hostname,\n  myPkgs,\n  config,\n  ...\n}:\n{\n  # host specific config\n  imports = [ ./hosts/${hostname}.nix ];\n\n  # glob"
  },
  {
    "path": "home/budiman/hosts/budimanjojo-firewall.nix",
    "chars": 53,
    "preview": "{ ... }:\n{\n  imports = [ ../profiles/server.nix ];\n}\n"
  },
  {
    "path": "home/budiman/hosts/budimanjojo-main.nix",
    "chars": 823,
    "preview": "{ pkgs, ... }:\n{\n  imports = [\n    ../profiles/workstation-hyprland.nix\n    ../profiles/extra-gaming.nix\n    ../profiles"
  },
  {
    "path": "home/budiman/hosts/budimanjojo-nas.nix",
    "chars": 53,
    "preview": "{ ... }:\n{\n  imports = [ ../profiles/server.nix ];\n}\n"
  },
  {
    "path": "home/budiman/hosts/budimanjojo-oracle.nix",
    "chars": 53,
    "preview": "{ ... }:\n{\n  imports = [ ../profiles/server.nix ];\n}\n"
  },
  {
    "path": "home/budiman/hosts/budimanjojo-ubuntu.nix",
    "chars": 632,
    "preview": "{ pkgs, inputs, ... }:\n{\n  config = {\n    myHome = {\n      programs = {\n        chezmoi.enable = true;\n        go.enable"
  },
  {
    "path": "home/budiman/profiles/extra-gaming.nix",
    "chars": 187,
    "preview": "{ pkgs, ... }:\n{\n  config = {\n    home.packages = with pkgs; [\n      (retroarch.withCores (\n        cores: with cores; ["
  },
  {
    "path": "home/budiman/profiles/extra-graphics.nix",
    "chars": 84,
    "preview": "{ pkgs, ... }:\n{\n  config.home.packages = with pkgs; [\n    gimp\n    inkscape\n  ];\n}\n"
  },
  {
    "path": "home/budiman/profiles/extra-utilities.nix",
    "chars": 132,
    "preview": "{ pkgs, ... }:\n{\n  config.home.packages = with pkgs; [\n    gparted\n    eog\n    totem\n    rhythmbox\n    jellyfin-media-pl"
  },
  {
    "path": "home/budiman/profiles/server.nix",
    "chars": 144,
    "preview": "{ ... }:\n{\n  config = {\n    myHome = {\n      shell = {\n        fish.enable = true;\n      };\n      multiplexer.tmux.enabl"
  },
  {
    "path": "home/budiman/profiles/workstation-common.nix",
    "chars": 424,
    "preview": "{ pkgs, ... }:\n{\n  config = {\n    myHome = {\n      shell = {\n        fish.enable = true;\n        lf.enable = true;\n     "
  },
  {
    "path": "home/budiman/profiles/workstation-hyprland.nix",
    "chars": 110,
    "preview": "{ ... }:\n{\n  imports = [ ./workstation-common.nix ];\n\n  config.myHome.windowmanager.hyprland.enable = true;\n}\n"
  },
  {
    "path": "home/budiman/profiles/workstation-i3.nix",
    "chars": 104,
    "preview": "{ ... }:\n{\n  imports = [ ./workstation-common.nix ];\n\n  config.myHome.windowmanager.i3.enable = true;\n}\n"
  },
  {
    "path": "home/budiman/profiles/workstation-sway.nix",
    "chars": 106,
    "preview": "{ ... }:\n{\n  imports = [ ./workstation-common.nix ];\n\n  config.myHome.windowmanager.sway.enable = true;\n}\n"
  },
  {
    "path": "lib/default.nix",
    "chars": 1469,
    "preview": "{ lib, ... }:\nrec {\n  # systemEnabled returns the value of `osConfig.module`\n  # returns false if `module` doesn't exist"
  },
  {
    "path": "overlays/default.nix",
    "chars": 2663,
    "preview": "{ inputs, config, ... }:\n{\n  # NUR pkgs set (declared in the flake inputs) will be accessible\n  # through `pkgs.nur`\n  n"
  },
  {
    "path": "packages/_sources/generated.json",
    "chars": 8221,
    "preview": "{\n    \"abbreviation-tips\": {\n        \"cargoLock\": null,\n        \"date\": null,\n        \"extract\": null,\n        \"name\": \""
  },
  {
    "path": "packages/_sources/generated.nix",
    "chars": 4678,
    "preview": "# This file was generated by nvfetcher, please do not modify it manually.\n{\n  fetchgit,\n  fetchurl,\n  fetchFromGitHub,\n "
  },
  {
    "path": "packages/configure-gtk/default.nix",
    "chars": 703,
    "preview": "{ pkgs }:\npkgs.writeTextFile {\n  name = \"configure-gtk\";\n  destination = \"/bin/configure-gtk\";\n  executable = true;\n  te"
  },
  {
    "path": "packages/default.nix",
    "chars": 868,
    "preview": "{\n  pkgs,\n  inputs',\n  self',\n  ...\n}:\n{\n  talhelper = inputs'.talhelper.packages.default;\n  configure-gtk = pkgs.callPa"
  },
  {
    "path": "packages/fish-plugins/default.nix",
    "chars": 441,
    "preview": "{ callPackage, buildFishPlugin }:\nlet\n  sourceData = callPackage ../_sources/generated.nix { };\nin\n{\n  abbreviation-tips"
  },
  {
    "path": "packages/krr/about-time.nix",
    "chars": 451,
    "preview": "{\n  lib,\n  python3,\n  callPackage,\n  ...\n}:\n\nlet\n  sourceData = callPackage ../_sources/generated.nix { };\nin\n\npython3.p"
  },
  {
    "path": "packages/krr/alive-progress.nix",
    "chars": 592,
    "preview": "{\n  lib,\n  python3,\n  pkgs,\n  callPackage,\n  ...\n}:\n\nlet\n  sourceData = callPackage ../_sources/generated.nix { };\n  abo"
  },
  {
    "path": "packages/krr/default.nix",
    "chars": 1513,
    "preview": "{\n  lib,\n  python3,\n  callPackage,\n  pkgs,\n}:\nlet\n  sourceData = callPackage ../_sources/generated.nix { };\n  prometheus"
  },
  {
    "path": "packages/krr/prometheus-api-client.nix",
    "chars": 569,
    "preview": "{\n  lib,\n  python3,\n  pkgs,\n  callPackage,\n  ...\n}:\n\nlet\n  sourceData = callPackage ../_sources/generated.nix { };\nin\n\np"
  },
  {
    "path": "packages/kubectl-rook-ceph/default.nix",
    "chars": 1274,
    "preview": "{\n  buildGoModule,\n  fetchFromGitHub,\n  installShellFiles,\n  lib,\n}:\n\nbuildGoModule rec {\n  pname = \"kubectl-rook-ceph\";"
  },
  {
    "path": "packages/nvfetcher.toml",
    "chars": 1426,
    "preview": "[tokyonight-gtk-theme]\nsrc.git = \"https://github.com/Fausto-Korpsvart/Tokyo-Night-GTK-Theme\"\nfetch.github = \"Fausto-Korp"
  },
  {
    "path": "packages/nvim-plugins/default.nix",
    "chars": 1292,
    "preview": "{\n  fetchFromGitHub,\n  pkgs,\n  callPackage,\n}:\n\nlet\n  sourceData = callPackage ../_sources/generated.nix { };\nin\n\n{\n  ch"
  },
  {
    "path": "packages/tokyonight-gtk-theme/default.nix",
    "chars": 1191,
    "preview": "{\n  stdenvNoCC,\n  lib,\n  callPackage,\n  pkgs,\n}:\n\nlet\n  sourceData = callPackage ../_sources/generated.nix { };\nin\nstden"
  },
  {
    "path": "packages/tokyonight-icon-theme/default.nix",
    "chars": 1776,
    "preview": "{\n  stdenvNoCC,\n  hicolor-icon-theme,\n  gtk3,\n  lib,\n  callPackage,\n}:\n\nlet\n  sourceData = callPackage ../_sources/gener"
  },
  {
    "path": "shell.nix",
    "chars": 75,
    "preview": "{ pkgs, ... }:\nwith pkgs;\nmkShell {\n  buildInputs = [\n    pkgs.just\n  ];\n}\n"
  },
  {
    "path": "system/_modules/_default/default.nix",
    "chars": 609,
    "preview": "{\n  config,\n  hostname,\n  pkgs,\n  lib,\n  ...\n}:\nlet\n  mySystem = config.mySystem;\nin\n{\n  imports = [\n    ./nix.nix\n    ."
  },
  {
    "path": "system/_modules/_default/nix.nix",
    "chars": 1337,
    "preview": "{ inputs, hostname, ... }:\n{\n  nix = {\n    # make `nix run` and `nix shell` use the same nixpkgs as the one used by this"
  },
  {
    "path": "system/_modules/_default/secret.sops.yaml",
    "chars": 4118,
    "preview": "adminPassword: ENC[AES256_GCM,data:sjzzXiIU7VbV9kc+f4npI90SFIfY0jAww4j414ZtfAUzwURgr3x0nA3+mou7MGeLKW3ZEl0qs3bEVUxU9mYm1"
  },
  {
    "path": "system/_modules/_default/sops.nix",
    "chars": 338,
    "preview": "{ config, pkgs, ... }:\nlet\n  mySystem = config.mySystem;\nin\n{\n  config = {\n    environment.systemPackages = [\n      pkgs"
  },
  {
    "path": "system/_modules/_default/users.nix",
    "chars": 442,
    "preview": "{ config, pkgs, ... }:\n{\n  sops.secrets = {\n    adminPassword = {\n      sopsFile = ./secret.sops.yaml;\n      neededForUs"
  },
  {
    "path": "system/_modules/containers/beeaccounting/default.nix",
    "chars": 2199,
    "preview": "{ lib, config, ... }:\nwith lib;\nlet\n  mySystem = config.mySystem;\n  cfg = mySystem.containers.beeaccounting;\n  ghcr-logi"
  },
  {
    "path": "system/_modules/containers/beeaccounting/secret.sops.yaml",
    "chars": 4088,
    "preview": "budimanjojo-ghcr-pull-token: ENC[AES256_GCM,data:skSIMsRrCX2qS+ATi6Aip3H8l2ySlipp+JArEmeOWuVbarGVKo/7dQ==,iv:GS7XIYLzttf"
  },
  {
    "path": "system/_modules/default.nix",
    "chars": 1177,
    "preview": "{ lib, ... }:\n{\n  imports = [\n    # contains config.myHardware options\n    # in a separate file because this module is s"
  },
  {
    "path": "system/_modules/displaymanager/sddm/default.nix",
    "chars": 1570,
    "preview": "{\n  config,\n  pkgs,\n  lib,\n  options,\n  ...\n}:\nlet\n  mySystem = config.mySystem;\n  myHardware = config.myHardware;\n  cfg"
  },
  {
    "path": "system/_modules/monitoring/node-exporter/default.nix",
    "chars": 430,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.mySystem.monitoring.node-exporter;\n  inherit (lib) mkEnableOption mkIf;\nin\n{\n  "
  },
  {
    "path": "system/_modules/monitoring/smartctl-exporter/default.nix",
    "chars": 738,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.mySystem.monitoring.smartctl-exporter;\n  inherit (lib) mkEnableOption mkIf;\nin\n"
  },
  {
    "path": "system/_modules/myHardware.nix",
    "chars": 2437,
    "preview": "{ lib, config, ... }:\nlet\n  inherit (lib) mkOption types;\nin\n{\n  options.myHardware = {\n    cpu = mkOption {\n      type "
  },
  {
    "path": "system/_modules/programs/adb/default.nix",
    "chars": 322,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.mySystem.programs.adb;\n  mySystem = config.mySystem;\nin\n{\n  options.mySystem.pr"
  },
  {
    "path": "system/_modules/programs/hugo/default.nix",
    "chars": 239,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.mySystem.programs.hugo;\nin\n{\n  options.mySystem.programs.hugo = {\n    enable = "
  },
  {
    "path": "system/_modules/programs/msmtp/default.nix",
    "chars": 898,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  mySystem = config.mySystem;\n  cfg = mySystem.programs.msmtp;\nin\n{\n  options.my"
  },
  {
    "path": "system/_modules/programs/msmtp/secret.sops.yaml",
    "chars": 4043,
    "preview": "gmail-password: ENC[AES256_GCM,data:CUz7IBEHhXfOanT9aSO5Gw==,iv:/r2hzqsEaqGBtnlzIXUk+ghNEm+0Hx1dRa5RFWqJbNQ=,tag:DcTF0Cl"
  },
  {
    "path": "system/_modules/programs/nh/default.nix",
    "chars": 804,
    "preview": "{\n  config,\n  lib,\n  options,\n  ...\n}:\nlet\n  cfg = config.mySystem.programs.nh;\n  inherit (lib)\n    mkEnableOption\n    m"
  },
  {
    "path": "system/_modules/programs/qmk/default.nix",
    "chars": 399,
    "preview": "{ config, lib, ... }:\nlet\n  mySystem = config.mySystem;\n  cfg = mySystem.programs.qmk;\nin\n{\n  options.mySystem.programs."
  },
  {
    "path": "system/_modules/services/btrfs-autoscrub/default.nix",
    "chars": 1837,
    "preview": "{\n  config,\n  options,\n  pkgs,\n  lib,\n  utils,\n  ...\n}:\nlet\n  cfg = config.mySystem.services.btrfs-autoscrub;\n  parentOp"
  },
  {
    "path": "system/_modules/services/grafana/default.nix",
    "chars": 1147,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.mySystem.services.grafana;\n  prometheusCfg = config.mySystem.services.prometheu"
  },
  {
    "path": "system/_modules/services/grafana/secret.sops.yaml",
    "chars": 4037,
    "preview": "grafana-password: ENC[AES256_GCM,data:T+AgSaSWbLc+KB8=,iv:UBnSF5xWdSPR/zTCYA2CArvJnQexE7uIKBIFUNTPNY4=,tag:9fUrNlgotTaJT"
  },
  {
    "path": "system/_modules/services/openssh/default.nix",
    "chars": 641,
    "preview": "{ config, lib, ... }:\nlet\n  mySystem = config.mySystem;\n  cfg = mySystem.services.openssh;\n  inherit (lib)\n    mkEnableO"
  },
  {
    "path": "system/_modules/services/prometheus/default.nix",
    "chars": 3425,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.mySystem.services.prometheus;\n  inherit (lib)\n    mkEnableOption\n    mkOption\n "
  },
  {
    "path": "system/_modules/services/prometheus/rules/embedded-exporter.yaml",
    "chars": 11564,
    "preview": "groups:\n  - name: EmbeddedExporter\n    rules:\n      - alert: PrometheusJobMissing\n        expr: 'absent(up{job=\"promethe"
  },
  {
    "path": "system/_modules/services/prometheus/rules/node-exporter.yaml",
    "chars": 16978,
    "preview": "groups:\n  - name: NodeExporter\n    rules:\n      - alert: HostOutOfMemory\n        expr: 'node_memory_MemAvailable_bytes /"
  },
  {
    "path": "system/_modules/services/restic-backup/default.nix",
    "chars": 1621,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.mySystem.services.restic-backup;\n  inherit (lib)\n    mkEnableOpti"
  },
  {
    "path": "system/_modules/services/restic-backup/secret.sops.yaml",
    "chars": 4302,
    "preview": "restic:\n    password: ENC[AES256_GCM,data:vcAJ+V2A2FHalb38LAFj3A==,iv:kvWV7+dOD9q0LpxuaYSePRH1HUiBwMvSVvhtUUguUkw=,tag:F"
  },
  {
    "path": "system/_modules/system/autoupgrade/default.nix",
    "chars": 524,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.mySystem.system.autoupgrade;\n  inherit (lib)\n    mkEnableOption\n    mkOption\n  "
  },
  {
    "path": "system/_modules/system/bootloader/default.nix",
    "chars": 886,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  myHardware = config.myHardware;\nin\n{\n  config = lib.mkMerge [\n    {\n      boot"
  },
  {
    "path": "system/_modules/system/cpu/default.nix",
    "chars": 379,
    "preview": "{ config, lib, ... }:\nlet\n  myHardware = config.myHardware;\nin\n{\n  config = lib.mkMerge [\n    (lib.mkIf (myHardware.cpu "
  },
  {
    "path": "system/_modules/system/font/default.nix",
    "chars": 289,
    "preview": "{\n  config,\n  lib,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.mySystem.system.font;\nin\n{\n  options.mySystem.system.font = {\n   "
  },
  {
    "path": "system/_modules/system/sound/default.nix",
    "chars": 787,
    "preview": "{\n  lib,\n  config,\n  pkgs,\n  ...\n}:\nlet\n  cfg = config.mySystem.system.sound;\nin\n{\n  options.mySystem.system.sound = {\n "
  },
  {
    "path": "system/_modules/system/video/default.nix",
    "chars": 2593,
    "preview": "{\n  pkgs,\n  lib,\n  config,\n  ...\n}:\nlet\n  cfg = config.mySystem.system.video;\n  myHardware = config.myHardware;\n  mySyst"
  },
  {
    "path": "system/_modules/windowmanager/add-on/blueman/default.nix",
    "chars": 281,
    "preview": "{ lib, config, ... }:\nlet\n  mySystem = config.mySystem;\n  cfg = mySystem.windowmanager.add-on.blueman;\nin\n{\n  options.my"
  },
  {
    "path": "system/_modules/windowmanager/add-on/gnome-keyring/default.nix",
    "chars": 288,
    "preview": "{ config, lib, ... }:\nlet\n  cfg = config.mySystem.windowmanager.add-on.gnome-keyring;\nin\n{\n  options.mySystem.windowmana"
  }
]

// ... and 66 more files (download for full content)

About this extraction

This page contains the full source code of the budimanjojo/dotfiles GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 266 files (478.4 KB), approximately 166.2k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!