├── .gitignore ├── bin ├── cputil.nix ├── default.nix ├── kcfg.nix ├── kctx.nix ├── nvidia-offload.nix ├── pw.nix ├── up.nix └── xurls.nix ├── darwin ├── com.googlecode.iterm2.plist └── home.nix ├── flake.lock ├── flake.nix ├── home.nix ├── hosts ├── denna │ ├── configuration.nix │ └── hardware-configuration.nix ├── iso │ ├── configuration.nix │ └── hardware-configuration.nix ├── kvothe │ └── configuration.nix ├── sini │ ├── configuration.nix │ └── hardware-configuration.nix ├── ssh.nix └── wyndle │ ├── ca.crt │ ├── configuration.nix │ └── hardware-configuration.nix ├── nvim ├── _init.lua ├── colors │ └── plain.lua ├── ftplugin │ ├── c.vim │ ├── css.vim │ ├── go.vim │ ├── html.vim │ ├── javascript.vim │ ├── json.vim │ ├── lua.vim │ ├── markdown.vim │ ├── nix.vim │ ├── python.vim │ ├── sh.vim │ ├── text.vim │ ├── typescript.vim │ └── yaml.vim └── lua │ ├── completion.lua │ ├── dapx.lua │ ├── fuzzy │ ├── buffers.lua │ ├── edit.lua │ ├── fuzzy.lua │ └── jump.lua │ ├── fzy │ ├── buffers.lua │ ├── edit.lua │ ├── fzy.lua │ └── jump.lua │ ├── lsp │ ├── c.lua │ ├── config.lua │ ├── copilot.lua │ ├── go.lua │ ├── js.lua │ ├── json.lua │ ├── lua.lua │ ├── python.lua │ ├── rust.lua │ └── yaml.lua │ ├── maps.lua │ ├── settings.lua │ ├── statusline │ ├── git.lua │ └── line.lua │ ├── tree.lua │ ├── treesitter.lua │ └── utils.lua ├── programs ├── alacritty.nix ├── bash.nix ├── chromium.nix ├── common.nix ├── default.nix ├── firefox.nix ├── fish.nix ├── ghostty.nix ├── git.nix ├── jujutsu.nix ├── neovim.nix ├── readline.nix ├── ssh.nix ├── tmux.nix └── zed │ ├── default.nix │ ├── keymap.nix │ ├── settings.nix │ └── themes │ ├── icy-dusk.json │ └── icy.json ├── prompt ├── git.go ├── go.mod ├── go.sum └── prompt.go ├── readme └── services └── default.nix /.gitignore: -------------------------------------------------------------------------------- 1 | prompt/prompt 2 | result 3 | config/nvim/init.vim 4 | .luarc.json 5 | .direnv 6 | -------------------------------------------------------------------------------- /bin/cputil.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | let 4 | name = "cputil"; 5 | cpufreqctl = "${pkgs.auto-cpufreq}/bin/cpufreqctl.auto-cpufreq"; 6 | asusctl = "${pkgs.asusctl}/bin/asusctl"; 7 | in 8 | pkgs.writeShellScriptBin name 9 | '' 10 | mode="$1" 11 | case "$mode" in 12 | "perf") 13 | doas ${cpufreqctl} --governor --set=performance 14 | ${asusctl} profile -P performance 15 | ;; 16 | "save") 17 | doas ${cpufreqctl} --governor --set=powersave 18 | ${asusctl} profile -P quiet 19 | printf "\n" 20 | esac 21 | '' 22 | 23 | -------------------------------------------------------------------------------- /bin/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs, host, ... }: 2 | 3 | let 4 | 5 | # open a window with live video feed from the camera 6 | webcam = pkgs.writeScriptBin "webcam" '' 7 | ${pkgs.mpv}/bin/mpv av://v4l2:/dev/video0 --profile=low-latency --untimed 8 | ''; 9 | 10 | # create new repo on git.icyphox.sh 11 | git-new-repo = pkgs.writeScriptBin "git-new-repo" '' 12 | repo="$1" 13 | [[ "$1" == "" ]] && repo="$(basename "$PWD")" 14 | ssh git@denna git init --bare "$repo" 15 | read -p "descripton: " desc 16 | printf '%s' "$desc" > .git/description 17 | rsync .git/description git@denna:"$repo" 18 | ''; 19 | 20 | # adds a new push-only remote 21 | git-new-push-remote = pkgs.writeScriptBin "git-new-push-remote" '' 22 | [[ "$@" == "" ]] && { 23 | printf '%s\n' "usage: git new-push-remote " 24 | exit 25 | } 26 | 27 | old_push_remote="$(git remote -v | grep '(push)' | awk '{print $2}')" 28 | git remote set-url "$(git remote show)" --add --push "$1" 29 | git remote set-url "$(git remote show)" --add --push "$old_push_remote" 30 | ''; 31 | 32 | # json pretty 33 | jp = pkgs.writeScriptBin "jp" '' 34 | ${pkgs.coreutils}/bin/cat | ${pkgs.jq}/bin/jq "$@" 35 | ''; 36 | 37 | # screen record with ffmpeg and slop 38 | record = import ./record.nix pkgs; 39 | 40 | # xurls 41 | xurls = import ./xurls.nix pkgs; 42 | 43 | # file uploader 44 | # uploader = import ./up.nix pkgs; 45 | 46 | # nvidia offload 47 | nvidia-offload = import ./nvidia-offload.nix pkgs; 48 | 49 | # power profiles script 50 | cputil = import ./cputil.nix pkgs; 51 | 52 | # password manager 53 | pw = import ./pw.nix pkgs; 54 | 55 | # kubectx wrapper 56 | kctx = import ./kctx.nix pkgs; 57 | 58 | # kubeconfig manager 59 | kcfg = import ./kcfg.nix pkgs; 60 | 61 | in 62 | [ 63 | git-new-push-remote 64 | git-new-repo 65 | jp 66 | kctx 67 | kcfg 68 | ] 69 | -------------------------------------------------------------------------------- /bin/kcfg.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | let 4 | name = "kcfg"; 5 | fzy = "${pkgs.fzy}/bin/fzy"; 6 | fd = "${pkgs.fd}/bin/fd"; 7 | in 8 | pkgs.writeShellScriptBin name 9 | '' 10 | cfg="$(${fd} . ~/code/upcloud/.kube | ${fzy})" 11 | export KUBECONFIG="$cfg" 12 | echo "KUBECONFIG set to $cfg" 13 | '' 14 | -------------------------------------------------------------------------------- /bin/kctx.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | let 4 | name = "kctx"; 5 | kubectx = "${pkgs.kubectx}/bin/kubectx"; 6 | fzy = "${pkgs.fzy}/bin/fzy"; 7 | in 8 | pkgs.writeShellScriptBin name 9 | '' 10 | ctx="$(${kubectx} | ${fzy})" 11 | ${kubectx} "$ctx" 12 | '' 13 | -------------------------------------------------------------------------------- /bin/nvidia-offload.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | pkgs.writeShellScriptBin "nvidia-offload" 4 | '' 5 | export __NV_PRIME_RENDER_OFFLOAD=1 6 | export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0 7 | export __GLX_VENDOR_LIBRARY_NAME=nvidia 8 | export __VK_LAYER_NV_optimus=NVIDIA_only 9 | exec -a "$0" "$@" 10 | '' 11 | -------------------------------------------------------------------------------- /bin/pw.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | let 4 | name = "pw"; 5 | gpg = "${pkgs.gnupg}/bin/gpg"; 6 | pwgen = "${pkgs.pwgen}/bin/pwgen"; 7 | git = "${pkgs.git}/bin/git"; 8 | copy = "${pkgs.wl-clipboard}/bin/wl-copy"; 9 | in 10 | pkgs.writeShellScriptBin name 11 | '' 12 | # pw - a mnml password manager 13 | [[ -z "$PW_DIR" ]] && PW_DIR="$HOME/.pw" 14 | init() { 15 | if [[ ! -e "$PW_DIR" ]]; then 16 | mkdir -p "$PW_DIR" 17 | printf "pw: password directory initialized at %s\n" "$PW_DIR" 18 | else 19 | printf "PW_DIR is %s\n" "$PW_DIR" 20 | die "$PW_DIR exists" 21 | fi 22 | } 23 | add() { 24 | # $1: path to file 25 | # $2 [optional]: password text 26 | [[ -z "$PW_KEY" ]] && die "\$PW_KEY not set" 27 | if [[ "$#" -eq 2 ]]; then 28 | pass="$2" 29 | else 30 | # uses default length of 25 chars, unless PW_LEN is set 31 | pass="$(${pwgen} "''${PW_LEN:-25}" 1 -s)" 32 | printf "pw: generated password for %s\n" "$1" 33 | fi 34 | if [[ ! -f "$PW_DIR/$1.gpg" ]]; then 35 | printf "%s" "$pass" | ${gpg} -aer "$PW_KEY" -o "$PW_DIR/$1.gpg" 36 | printf "pw: %s/%s.gpg created\n" "$PW_DIR" "$1" 37 | else 38 | die "the file $PW_DIR/$1.gpg exists" 39 | fi 40 | ( 41 | cd $PW_DIR 42 | ${git} add . 43 | ${git} commit -m "$(date)" 44 | remote="$(${git} remote show)" 45 | branch="$(${git} branch --show-current)" 46 | ${git} pull -r "$remote" "$branch" 47 | ${git} push "$remote" "$branch" 48 | ) 49 | } 50 | list() { 51 | (cd "$PW_DIR"; find *.gpg | awk -F '.gpg' '{ print $1 }' ) 52 | } 53 | del() { 54 | checkf "$PW_DIR/$1.gpg" 55 | read -rn 1 -p "pw: are you sure you want to delete $1? [y/n]: " 56 | printf "\n" 57 | [[ "$REPLY" == [yY] ]] && { 58 | rm -f "$PW_DIR/$1.gpg" 59 | printf "pw: deleted %s" "$1" 60 | } 61 | } 62 | show() { 63 | checkf "$PW_DIR/$1.gpg" 64 | ${gpg} --decrypt --quiet --use-agent "$PW_DIR/$1.gpg" 65 | } 66 | # TODO: rework having to checkf twice 67 | copy() { 68 | checkf "$PW_DIR/$1.gpg" 69 | if [[ "$OSTYPE" =~ darwin* ]]; then 70 | show "$1" | head -1 | pbcopy | tr -d '\n' 71 | else 72 | show "$1" | head -1 | ${copy} -n 73 | fi 74 | printf "pw: copied %s to clipboard\n" "$1" 75 | } 76 | usage() { 77 | usage=" 78 | pw - mnml password manager 79 | usage: pw [options] [NAME] 80 | All options except -i and -h require a NAME argument. 81 | options: 82 | -i Initializes password directory at \$HOME/.pw or at \$PW_DIR, if it exists. 83 | -a Add a password. 84 | -g Generate a password. 85 | -s Print password to STDOUT. 86 | -l List out all passwords. 87 | -c Copy existing password to clipboard. 88 | -d Delete password. 89 | -h Display this help message and exit. 90 | Requires PW_KEY to be set. Optionally, set PW_DIR for custom directory location. 91 | Set PW_LEN to an integer of your choice, to override the default password length of 25. 92 | " 93 | printf "%s" "$usage" 94 | exit 1 95 | } 96 | checkf() { 97 | [[ ! -f "$1" ]] && 98 | die "$1 does not exist" 99 | } 100 | die() { 101 | printf "error: %s\n" "$1" >&2 102 | exit 1 103 | } 104 | main() { 105 | [[ -z "$1" ]] && { 106 | usage 107 | } 108 | while getopts "ila:g:s:c:d:h" options 109 | do 110 | # shellcheck disable=SC2221,SC2222 111 | case "$options" in 112 | i) init ;; 113 | l) list ;; 114 | g) add "$OPTARG" ;; 115 | a) 116 | read -rsp "enter password: " pass 117 | printf "\n" 118 | add "$OPTARG" "$pass" 119 | ;; 120 | s) show "$OPTARG" ;; 121 | c) copy "$OPTARG" ;; 122 | d) del "$OPTARG" ;; 123 | *|h) usage ;; 124 | esac 125 | done 126 | shift $(( OPTIND -1 )) 127 | } 128 | main "$@" 129 | '' 130 | -------------------------------------------------------------------------------- /bin/up.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | let 3 | name = "up"; 4 | xclip = "${pkgs.xclip}/bin/xclip"; 5 | in 6 | pkgs.writeScriptBin name 7 | '' 8 | id=$( cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 3 | head -n 1 ) 9 | 10 | if [ $# != 1 ]; then 11 | echo "needs an arg" 12 | else 13 | if [ -f "$1" ]; then 14 | ext="''${1##*.}" 15 | id="$id.$ext" 16 | scp "$1" ferrn:~/www/nerd/uploads/"$id" 17 | echo "https://u.peppe.rs/$id" 18 | echo "https://u.peppe.rs/$id" | ${xclip} -selection clipboard 19 | echo "https://u.peppe.rs/$id" | ${xclip} -i 20 | else 21 | echo "file does not exist" 22 | fi 23 | fi 24 | '' 25 | -------------------------------------------------------------------------------- /bin/xurls.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | let 4 | name = "xurls"; 5 | fzy = "${pkgs.fzy}/bin/fzy"; 6 | copy = "${pkgs.wl-clipboard}/bin/wl-copy"; 7 | in 8 | pkgs.writeShellScriptBin name 9 | '' 10 | content="$(tmux capture-pane -J -p)" 11 | 12 | mapfile -t urls < <(echo "$content" | grep -oE '(https?|ftp|file):/?//[-A-Za-z0-9+&@#/%?=~_|!:,.;]*[-A-Za-z0-9+&@#/%=~_|]') 13 | mapfile -t wwws < <(echo "$content" | grep -oE '(http?s://)?www\.[a-zA-Z](-?[a-zA-Z0-9])+\.[a-zA-Z]{2,}(/\S+)*' | grep -vE '^https?://' |sed 's/^\(.*\)$/http:\/\/\1/') 14 | mapfile -t ips < <(echo "$content" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(:[0-9]{1,5})?(/\S+)*' |sed 's/^\(.*\)$/http:\/\/\1/') 15 | mapfile -t gits < <(echo "$content" | grep -oE '(ssh://)?git@\S*' | sed 's/:/\//g' | sed 's/^\(ssh\/\/\/\)\{0,1\}git@\(.*\)$/https:\/\/\2/') 16 | 17 | items="$(printf '%s\n' "''${urls[@]}" "''${wwws[@]}" "''${ips[@]}" "''${gits[@]}" | 18 | grep -v '^$' | 19 | sort -u | 20 | nl -w3 -s ' ' 21 | )" 22 | 23 | [ -z "$items" ] && exit 24 | 25 | u="$(${fzy} <<< "$items" | awk '{ print $2 }')" 26 | ${copy} "$u" 27 | '' 28 | 29 | -------------------------------------------------------------------------------- /darwin/home.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , lib 4 | , self 5 | , host 6 | , ... 7 | }: 8 | 9 | { 10 | home.stateVersion = "24.05"; 11 | home.username = "icy"; 12 | manual.manpages.enable = true; 13 | 14 | 15 | imports = [ 16 | ../programs/common.nix 17 | ]; 18 | 19 | programs.bash = { 20 | shellAliases = { 21 | ls = "ls --color=auto"; 22 | }; 23 | }; 24 | 25 | home.packages = with pkgs; [ 26 | # prompt 27 | tmux 28 | git 29 | fzy 30 | ripgrep 31 | pass 32 | fd 33 | gnupg 34 | colima 35 | docker 36 | docker-buildx 37 | pinentry_mac 38 | kubectl 39 | 40 | ice-bar 41 | 42 | go 43 | gopls 44 | gotools 45 | nix-your-shell 46 | ] ++ (import ../bin { inherit pkgs host; }); 47 | } 48 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "advisory-db": { 4 | "flake": false, 5 | "locked": { 6 | "lastModified": 1710515894, 7 | "narHash": "sha256-tmQ9TMCb2jZY3jYdf53qIberkYV3dnUzdAYYK/NB+No=", 8 | "owner": "rustsec", 9 | "repo": "advisory-db", 10 | "rev": "369d98c1b95b7b56d0859605916d7b81a7d1f1c4", 11 | "type": "github" 12 | }, 13 | "original": { 14 | "owner": "rustsec", 15 | "repo": "advisory-db", 16 | "type": "github" 17 | } 18 | }, 19 | "crane": { 20 | "inputs": { 21 | "nixpkgs": [ 22 | "nix-your-shell", 23 | "nixpkgs" 24 | ] 25 | }, 26 | "locked": { 27 | "lastModified": 1710886643, 28 | "narHash": "sha256-saTZuv9YeZ9COHPuj8oedGdUwJZcbQ3vyRqe7NVJMsQ=", 29 | "owner": "ipetkov", 30 | "repo": "crane", 31 | "rev": "5bace74e9a65165c918205cf67ad3977fe79c584", 32 | "type": "github" 33 | }, 34 | "original": { 35 | "owner": "ipetkov", 36 | "repo": "crane", 37 | "type": "github" 38 | } 39 | }, 40 | "crane_2": { 41 | "locked": { 42 | "lastModified": 1742394900, 43 | "narHash": "sha256-vVOAp9ahvnU+fQoKd4SEXB2JG2wbENkpqcwlkIXgUC0=", 44 | "owner": "ipetkov", 45 | "repo": "crane", 46 | "rev": "70947c1908108c0c551ddfd73d4f750ff2ea67cd", 47 | "type": "github" 48 | }, 49 | "original": { 50 | "owner": "ipetkov", 51 | "repo": "crane", 52 | "type": "github" 53 | } 54 | }, 55 | "darwin": { 56 | "inputs": { 57 | "nixpkgs": [ 58 | "nixpkgs" 59 | ] 60 | }, 61 | "locked": { 62 | "lastModified": 1747494142, 63 | "narHash": "sha256-7TAUwDVZWq82t/x3+zZ5y+Tjl2hLL2c8+8pv9zCUbTo=", 64 | "owner": "lnl7", 65 | "repo": "nix-darwin", 66 | "rev": "8e251e45346e9d58e0eece2512e40c183f967e8f", 67 | "type": "github" 68 | }, 69 | "original": { 70 | "owner": "lnl7", 71 | "ref": "master", 72 | "repo": "nix-darwin", 73 | "type": "github" 74 | } 75 | }, 76 | "flake-compat": { 77 | "locked": { 78 | "lastModified": 1733328505, 79 | "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", 80 | "owner": "edolstra", 81 | "repo": "flake-compat", 82 | "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", 83 | "type": "github" 84 | }, 85 | "original": { 86 | "owner": "edolstra", 87 | "repo": "flake-compat", 88 | "type": "github" 89 | } 90 | }, 91 | "home-manager": { 92 | "inputs": { 93 | "nixpkgs": [ 94 | "nixpkgs" 95 | ] 96 | }, 97 | "locked": { 98 | "lastModified": 1747439237, 99 | "narHash": "sha256-5rCGrnkglKKj4cav1U3HC+SIUNJh08pqOK4spQv9RjA=", 100 | "owner": "nix-community", 101 | "repo": "home-manager", 102 | "rev": "ae755329092c87369b9e9a1510a8cf1ce2b1c708", 103 | "type": "github" 104 | }, 105 | "original": { 106 | "owner": "nix-community", 107 | "repo": "home-manager", 108 | "type": "github" 109 | } 110 | }, 111 | "nix-your-shell": { 112 | "inputs": { 113 | "advisory-db": "advisory-db", 114 | "crane": "crane", 115 | "nixpkgs": [ 116 | "nixpkgs" 117 | ], 118 | "systems": "systems" 119 | }, 120 | "locked": { 121 | "lastModified": 1744134530, 122 | "narHash": "sha256-NWgdXO6sQMQVnbvwSB+gBmMnU9s8ghx1ltGvOPec+qo=", 123 | "owner": "MercuryTechnologies", 124 | "repo": "nix-your-shell", 125 | "rev": "e66f4ece4687d4c0890ab5994bfef2826f68180c", 126 | "type": "github" 127 | }, 128 | "original": { 129 | "owner": "MercuryTechnologies", 130 | "repo": "nix-your-shell", 131 | "type": "github" 132 | } 133 | }, 134 | "nixos-hardware": { 135 | "locked": { 136 | "lastModified": 1747129300, 137 | "narHash": "sha256-L3clA5YGeYCF47ghsI7Tcex+DnaaN/BbQ4dR2wzoiKg=", 138 | "owner": "nixos", 139 | "repo": "nixos-hardware", 140 | "rev": "e81fd167b33121269149c57806599045fd33eeed", 141 | "type": "github" 142 | }, 143 | "original": { 144 | "owner": "nixos", 145 | "repo": "nixos-hardware", 146 | "type": "github" 147 | } 148 | }, 149 | "nixpkgs": { 150 | "locked": { 151 | "lastModified": 1747327360, 152 | "narHash": "sha256-LSmTbiq/nqZR9B2t4MRnWG7cb0KVNU70dB7RT4+wYK4=", 153 | "owner": "NixOS", 154 | "repo": "nixpkgs", 155 | "rev": "e06158e58f3adee28b139e9c2bcfcc41f8625b46", 156 | "type": "github" 157 | }, 158 | "original": { 159 | "owner": "NixOS", 160 | "ref": "nixos-unstable", 161 | "repo": "nixpkgs", 162 | "type": "github" 163 | } 164 | }, 165 | "nixpkgs-master": { 166 | "locked": { 167 | "lastModified": 1747517186, 168 | "narHash": "sha256-ESuD8SaqgysQQ5wW3H49egueDyT4h2jhCM84WcPOCMQ=", 169 | "owner": "NixOS", 170 | "repo": "nixpkgs", 171 | "rev": "9f65f287d309c02a57c7a2b0ce26c6cf46dc3149", 172 | "type": "github" 173 | }, 174 | "original": { 175 | "owner": "NixOS", 176 | "ref": "master", 177 | "repo": "nixpkgs", 178 | "type": "github" 179 | } 180 | }, 181 | "nixpkgs-stable": { 182 | "locked": { 183 | "lastModified": 1747335874, 184 | "narHash": "sha256-IKKIXTSYJMmUtE+Kav5Rob8SgLPnfnq4Qu8LyT4gdqQ=", 185 | "owner": "NixOS", 186 | "repo": "nixpkgs", 187 | "rev": "ba8b70ee098bc5654c459d6a95dfc498b91ff858", 188 | "type": "github" 189 | }, 190 | "original": { 191 | "owner": "NixOS", 192 | "ref": "nixos-24.11", 193 | "repo": "nixpkgs", 194 | "type": "github" 195 | } 196 | }, 197 | "prompt": { 198 | "inputs": { 199 | "nixpkgs": [ 200 | "nixpkgs" 201 | ] 202 | }, 203 | "locked": { 204 | "lastModified": 1701510523, 205 | "narHash": "sha256-uf0JCa+PP/aM77icihT79hew1/TTcMJV6AoIfmuLABM=", 206 | "ref": "master", 207 | "rev": "9450828084f42d3f1eb261c00820cfd2bf8b819b", 208 | "revCount": 7, 209 | "type": "git", 210 | "url": "https://git.peppe.rs/cli/prompt" 211 | }, 212 | "original": { 213 | "ref": "master", 214 | "type": "git", 215 | "url": "https://git.peppe.rs/cli/prompt" 216 | } 217 | }, 218 | "root": { 219 | "inputs": { 220 | "darwin": "darwin", 221 | "home-manager": "home-manager", 222 | "nix-your-shell": "nix-your-shell", 223 | "nixos-hardware": "nixos-hardware", 224 | "nixpkgs": "nixpkgs", 225 | "nixpkgs-master": "nixpkgs-master", 226 | "nixpkgs-stable": "nixpkgs-stable", 227 | "prompt": "prompt", 228 | "zed": "zed" 229 | } 230 | }, 231 | "rust-overlay": { 232 | "inputs": { 233 | "nixpkgs": [ 234 | "zed", 235 | "nixpkgs" 236 | ] 237 | }, 238 | "locked": { 239 | "lastModified": 1747363019, 240 | "narHash": "sha256-N4dwkRBmpOosa4gfFkFf/LTD8oOcNkAyvZ07JvRDEf0=", 241 | "owner": "oxalica", 242 | "repo": "rust-overlay", 243 | "rev": "0e624f2b1972a34be1a9b35290ed18ea4b419b6f", 244 | "type": "github" 245 | }, 246 | "original": { 247 | "owner": "oxalica", 248 | "repo": "rust-overlay", 249 | "type": "github" 250 | } 251 | }, 252 | "systems": { 253 | "locked": { 254 | "lastModified": 1681028828, 255 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 256 | "owner": "nix-systems", 257 | "repo": "default", 258 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 259 | "type": "github" 260 | }, 261 | "original": { 262 | "owner": "nix-systems", 263 | "repo": "default", 264 | "type": "github" 265 | } 266 | }, 267 | "zed": { 268 | "inputs": { 269 | "crane": "crane_2", 270 | "flake-compat": "flake-compat", 271 | "nixpkgs": [ 272 | "nixpkgs" 273 | ], 274 | "rust-overlay": "rust-overlay" 275 | }, 276 | "locked": { 277 | "lastModified": 1747508752, 278 | "narHash": "sha256-RlZKLttv4fTa4AcwYbcrJjeVUHVV9Up8ek7PL/FGtnI=", 279 | "owner": "zed-industries", 280 | "repo": "zed", 281 | "rev": "230eb12f7220aea21733a259b670201bc79c7020", 282 | "type": "github" 283 | }, 284 | "original": { 285 | "owner": "zed-industries", 286 | "repo": "zed", 287 | "type": "github" 288 | } 289 | } 290 | }, 291 | "root": "root", 292 | "version": 7 293 | } 294 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "icy's nixos config"; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 | nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-24.11"; 7 | nixpkgs-master.url = "github:NixOS/nixpkgs/master"; 8 | 9 | 10 | nixos-hardware.url = "github:nixos/nixos-hardware"; 11 | 12 | home-manager = { 13 | url = "github:nix-community/home-manager"; 14 | inputs.nixpkgs.follows = "nixpkgs"; 15 | }; 16 | 17 | darwin = { 18 | url = "github:lnl7/nix-darwin/master"; 19 | inputs.nixpkgs.follows = "nixpkgs"; 20 | }; 21 | 22 | prompt = { 23 | url = "git+https://git.peppe.rs/cli/prompt?ref=master"; 24 | inputs.nixpkgs.follows = "nixpkgs"; 25 | }; 26 | 27 | 28 | nix-your-shell = { 29 | url = "github:MercuryTechnologies/nix-your-shell"; 30 | inputs.nixpkgs.follows = "nixpkgs"; 31 | }; 32 | 33 | zed = { 34 | url = "github:zed-industries/zed"; 35 | inputs.nixpkgs.follows = "nixpkgs"; 36 | }; 37 | }; 38 | 39 | outputs = 40 | { self 41 | , nixpkgs 42 | , nixpkgs-master 43 | , nixos-hardware 44 | , nix-your-shell 45 | , home-manager 46 | , prompt 47 | , # zed, 48 | darwin 49 | , ... 50 | }@inputs: 51 | 52 | let 53 | supportedSystems = [ 54 | "x86_64-linux" 55 | "x86_64-darwin" 56 | "aarch64-linux" 57 | "aarch64-darwin" 58 | ]; 59 | forAllSystems = nixpkgs.lib.genAttrs supportedSystems; 60 | in 61 | { 62 | 63 | darwinConfigurations = { 64 | kvothe = darwin.lib.darwinSystem { 65 | system = "aarch64-darwin"; 66 | modules = [ 67 | { 68 | imports = [ ./hosts/kvothe/configuration.nix ]; 69 | _module.args.self = self; 70 | nixpkgs.overlays = [ 71 | nix-your-shell.overlays.default 72 | # prompt.overlay 73 | ]; 74 | } 75 | home-manager.darwinModules.home-manager 76 | { 77 | home-manager.useGlobalPkgs = true; 78 | home-manager.useUserPackages = true; 79 | home-manager.users.icy = { 80 | imports = [ ./darwin/home.nix ]; 81 | _module.args.self = self; 82 | _module.args.host = "kvothe"; 83 | _module.args.inputs = inputs; 84 | }; 85 | } 86 | ]; 87 | }; 88 | }; 89 | 90 | nixosConfigurations = { 91 | wyndle = nixpkgs.lib.nixosSystem { 92 | system = "x86_64-linux"; 93 | modules = [ 94 | { 95 | imports = [ ./hosts/wyndle/configuration.nix ]; 96 | _module.args.self = self; 97 | nixpkgs.overlays = [ 98 | nix-your-shell.overlays.default 99 | prompt.overlay 100 | ]; 101 | } 102 | home-manager.nixosModules.home-manager 103 | { 104 | home-manager.useGlobalPkgs = true; 105 | home-manager.useUserPackages = true; 106 | home-manager.users.icy = { 107 | imports = [ ./home.nix ]; 108 | _module.args.self = self; 109 | _module.args.host = "wyndle"; 110 | _module.args.inputs = inputs; 111 | }; 112 | } 113 | ]; 114 | }; 115 | }; 116 | 117 | nixosConfigurations = { 118 | sini = nixpkgs.lib.nixosSystem { 119 | system = "x86_64-linux"; 120 | modules = [ 121 | ({ 122 | config = { 123 | nix.registry.nixpkgs.flake = nixpkgs; 124 | }; 125 | }) 126 | ( 127 | { config, pkgs, ... }: 128 | { 129 | services.pixelfed.package = nixpkgs-master.legacyPackages."x86_64-linux".pixelfed; 130 | services.pixelfed.phpPackage = nixpkgs-master.legacyPackages."x86_64-linux".php82; 131 | } 132 | ) 133 | # ({ pkgs, ... }: { 134 | # imports = [ nix-snapshotter.nixosModules.default ]; 135 | # nixpkgs.overlays = [ nix-snapshotter.overlays.default ]; 136 | # }) 137 | { 138 | imports = [ ./hosts/sini/configuration.nix ]; 139 | _module.args.self = self; 140 | } 141 | ]; 142 | }; 143 | }; 144 | 145 | nixosConfigurations = { 146 | denna = nixpkgs.lib.nixosSystem { 147 | system = "x86_64-linux"; 148 | modules = [ 149 | ({ 150 | config = { 151 | nix.registry.nixpkgs.flake = nixpkgs; 152 | }; 153 | }) 154 | { 155 | imports = [ ./hosts/denna/configuration.nix ]; 156 | _module.args.self = self; 157 | } 158 | ]; 159 | }; 160 | }; 161 | 162 | nixosConfigurations = { 163 | iso = nixpkgs.lib.nixosSystem { 164 | system = "x86_64-linux"; 165 | modules = [ 166 | ({ 167 | config = { 168 | nix.registry.nixpkgs.flake = nixpkgs; 169 | }; 170 | }) 171 | { 172 | imports = [ ./hosts/iso/configuration.nix ]; 173 | _module.args.self = self; 174 | } 175 | ]; 176 | }; 177 | }; 178 | 179 | devShells = forAllSystems ( 180 | system: 181 | let 182 | nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; }); 183 | pkgs = nixpkgsFor.${system}; 184 | in 185 | { 186 | default = pkgs.mkShell { 187 | nativeBuildInputs = with pkgs; [ 188 | nixd 189 | nixfmt-rfc-style 190 | ]; 191 | }; 192 | } 193 | ); 194 | }; 195 | } 196 | -------------------------------------------------------------------------------- /home.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , self 4 | , host 5 | , lib 6 | , inputs 7 | , ... 8 | }: 9 | 10 | let 11 | mkTuple = lib.hm.gvariant.mkTuple; 12 | in 13 | { 14 | 15 | imports = [ 16 | ./programs 17 | ./services 18 | ]; 19 | 20 | fonts.fontconfig.enable = true; 21 | manual.manpages.enable = true; 22 | 23 | home.stateVersion = "24.11"; 24 | home.username = "icy"; 25 | home.homeDirectory = "/home/icy"; 26 | home.extraOutputsToInstall = [ "man" ]; 27 | 28 | home.packages = [ 29 | pkgs.git 30 | pkgs.unzip 31 | pkgs.curl 32 | pkgs.tmux 33 | pkgs.ripgrep 34 | pkgs.fd 35 | pkgs.imagemagick 36 | pkgs.ffmpeg 37 | pkgs.wget 38 | pkgs.tree 39 | pkgs.mpv 40 | pkgs.noto-fonts-cjk-sans 41 | pkgs.noto-fonts-emoji 42 | pkgs.jq 43 | pkgs.yq-go 44 | pkgs.fzy 45 | pkgs.nixpkgs-fmt 46 | pkgs.libnotify 47 | pkgs.signal-desktop 48 | pkgs.calibre 49 | pkgs.pinentry 50 | pkgs.libreoffice 51 | pkgs.go 52 | pkgs.dconf 53 | pkgs.chromium 54 | pkgs.nix-your-shell 55 | pkgs.geary 56 | pkgs.pass 57 | pkgs.newsflash 58 | pkgs.errands 59 | pkgs.wl-clipboard 60 | pkgs.nvtop 61 | pkgs.vesktop 62 | pkgs.smile 63 | pkgs.apostrophe 64 | 65 | pkgs.gnome-pomodoro 66 | pkgs.gnome-tweaks 67 | pkgs.gnome-shell-extensions 68 | pkgs.gnomeExtensions.appindicator 69 | pkgs.gnomeExtensions.dash-to-dock 70 | pkgs.gnomeExtensions.search-light 71 | pkgs.gnomeExtensions.hide-top-bar 72 | 73 | pkgs.prompt 74 | pkgs.zed-editor 75 | # inputs.zed.packages.${pkgs.system}.zed-editor 76 | 77 | ] ++ (import ./bin { inherit pkgs host; }); 78 | 79 | dconf.settings = { 80 | "org/gnome/mutter" = { 81 | experimental-features = [ "scale-monitor-framebuffer" ]; 82 | }; 83 | "org/gnome/desktop/input-sources" = { 84 | show-all-sources = true; 85 | sources = [ 86 | (mkTuple [ 87 | "xkb" 88 | "us+workman" 89 | ]) 90 | (mkTuple [ 91 | "xkb" 92 | "us" 93 | ]) 94 | ]; 95 | xkb-options = [ 96 | "terminate:ctrl_alt_bksp" 97 | "compose:ralt" 98 | ]; 99 | }; 100 | "org/gnome/mutter" = { 101 | overlay-key = [ "" ]; 102 | }; 103 | "org/gnome/shell/extensions/search-light" = { 104 | shortcut-search = [ "space" ]; 105 | }; 106 | "org/gnome/settings-daemon/plugins/media-keys" = { 107 | screensaver = [ "q" ]; 108 | }; 109 | 110 | "org/gnome/shell/keybindings" = { 111 | show-screenshot-ui = [ "4" ]; 112 | }; 113 | 114 | "org/gnome/shell/keybindings/screenshot-window" = { 115 | screenshot-window = [ "space" ]; 116 | }; 117 | 118 | "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = { 119 | binding = [ ";" ]; 120 | command = "smile"; 121 | name = "emoji"; 122 | }; 123 | }; 124 | 125 | xdg = { 126 | userDirs = { 127 | enable = true; 128 | desktop = "\$HOME/desktop"; 129 | documents = "\$HOME/docs"; 130 | download = "\$HOME/downloads"; 131 | pictures = "\$HOME/pics"; 132 | videos = "\$HOME/vids"; 133 | }; 134 | }; 135 | 136 | } 137 | -------------------------------------------------------------------------------- /hosts/denna/configuration.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, lib, ... }: 2 | 3 | { 4 | imports = 5 | [ 6 | ./hardware-configuration.nix 7 | ../ssh.nix 8 | ]; 9 | 10 | boot.loader.systemd-boot.enable = true; 11 | boot.loader.efi.canTouchEfiVariables = true; 12 | systemd.network.wait-online.enable = false; 13 | 14 | networking.hostName = "denna"; 15 | networking.networkmanager.enable = true; 16 | 17 | time.timeZone = "Europe/Helsinki"; 18 | 19 | i18n.defaultLocale = "en_US.UTF-8"; 20 | 21 | i18n.extraLocaleSettings = { 22 | LC_ADDRESS = "en_US.UTF-8"; 23 | LC_IDENTIFICATION = "en_US.UTF-8"; 24 | LC_MEASUREMENT = "en_US.UTF-8"; 25 | LC_MONETARY = "en_US.UTF-8"; 26 | LC_NAME = "en_US.UTF-8"; 27 | LC_NUMERIC = "en_US.UTF-8"; 28 | LC_PAPER = "en_US.UTF-8"; 29 | LC_TELEPHONE = "en_US.UTF-8"; 30 | LC_TIME = "en_US.UTF-8"; 31 | }; 32 | 33 | hardware.pulseaudio.enable = true; 34 | hardware.opengl = { 35 | enable = true; 36 | extraPackages = with pkgs; [ 37 | intel-media-driver 38 | vaapiIntel 39 | vaapiVdpau 40 | libvdpau-va-gl 41 | intel-compute-runtime 42 | ]; 43 | }; 44 | 45 | security = { 46 | doas.enable = true; 47 | sudo.enable = true; 48 | doas.extraConfig = '' 49 | permit nopass :wheel 50 | ''; 51 | doas.extraRules = [{ 52 | users = [ "icy" ]; 53 | }]; 54 | }; 55 | 56 | users.users.icy = { 57 | isNormalUser = true; 58 | description = "icy"; 59 | extraGroups = [ "networkmanager" "wheel" "docker" ]; 60 | packages = with pkgs; [ ]; 61 | }; 62 | 63 | users.users.git = { 64 | isNormalUser = true; 65 | description = "git"; 66 | extraGroups = [ "networkmanager" "wheel" ]; 67 | homeMode = "755"; 68 | packages = with pkgs; [ ]; 69 | }; 70 | 71 | 72 | nixpkgs.config.allowUnfree = true; 73 | environment.systemPackages = with pkgs; [ 74 | vim 75 | wget 76 | git 77 | nfs-utils 78 | soju 79 | ]; 80 | 81 | services = { 82 | openssh.enable = true; 83 | tailscale.enable = true; 84 | # nix-snapshotter.enable = true; 85 | }; 86 | 87 | services.soju = { 88 | enable = true; 89 | hostName = "denna"; 90 | listen = [ "irc+insecure://0.0.0.0" ]; 91 | }; 92 | 93 | services.k3s = let address = "100.77.4.74"; in { 94 | enable = true; 95 | role = "agent"; 96 | extraFlags = "--node-ip=${address} --node-external-ip=${address} --flannel-iface=tailscale0"; 97 | serverAddr = "https://sini:6443"; 98 | tokenFile = "/var/lib/rancher/k3s/token"; 99 | }; 100 | 101 | services.openiscsi = { 102 | enable = true; 103 | name = config.networking.hostName; 104 | }; 105 | 106 | environment.etc = { 107 | "rancher/k3s/registries.yaml" = { 108 | text = '' 109 | mirrors: 110 | sini:5000: 111 | endpoint: 112 | - "http://sini:5000" 113 | ''; 114 | }; 115 | }; 116 | 117 | systemd.tmpfiles.rules = [ 118 | "L+ /usr/local/bin - - - - /run/current-system/sw/bin/" 119 | ]; 120 | 121 | nix.settings.experimental-features = [ "nix-command" "flakes" ]; 122 | system.stateVersion = "24.05"; 123 | } 124 | 125 | -------------------------------------------------------------------------------- /hosts/denna/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { config, lib, pkgs, modulesPath, ... }: 5 | 6 | { 7 | imports = 8 | [ 9 | (modulesPath + "/installer/scan/not-detected.nix") 10 | ]; 11 | 12 | boot.initrd.availableKernelModules = [ "xhci_pci" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" ]; 13 | boot.initrd.kernelModules = [ ]; 14 | boot.kernelModules = [ "kvm-intel" ]; 15 | boot.extraModulePackages = [ ]; 16 | 17 | fileSystems."/" = 18 | { 19 | device = "/dev/disk/by-uuid/92a27eb2-9814-48fd-8f76-cc152d5a8700"; 20 | fsType = "ext4"; 21 | }; 22 | 23 | fileSystems."/boot" = 24 | { 25 | device = "/dev/disk/by-uuid/219A-16D2"; 26 | fsType = "vfat"; 27 | options = [ "fmask=0022" "dmask=0022" ]; 28 | }; 29 | 30 | swapDevices = [ ]; 31 | 32 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 33 | # (the default) this is the recommended approach. When using systemd-networkd it's 34 | # still possible to use this option, but it's recommended to use it in conjunction 35 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 36 | networking.useDHCP = lib.mkDefault true; 37 | # networking.interfaces.enp0s20f0u3u1u2.useDHCP = lib.mkDefault true; 38 | # networking.interfaces.enp1s0.useDHCP = lib.mkDefault true; 39 | # networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true; 40 | 41 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 42 | hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /hosts/iso/configuration.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, lib, ... }: 2 | 3 | { 4 | imports = 5 | [ 6 | ./hardware-configuration.nix 7 | ../ssh.nix 8 | ]; 9 | 10 | boot.loader.systemd-boot.enable = true; 11 | boot.loader.efi.canTouchEfiVariables = true; 12 | systemd.network.wait-online.enable = false; 13 | 14 | networking.hostName = "iso"; 15 | networking.networkmanager.enable = true; 16 | 17 | time.timeZone = "Europe/Helsinki"; 18 | 19 | i18n.defaultLocale = "en_US.UTF-8"; 20 | 21 | i18n.extraLocaleSettings = { 22 | LC_ADDRESS = "en_US.UTF-8"; 23 | LC_IDENTIFICATION = "en_US.UTF-8"; 24 | LC_MEASUREMENT = "en_US.UTF-8"; 25 | LC_MONETARY = "en_US.UTF-8"; 26 | LC_NAME = "en_US.UTF-8"; 27 | LC_NUMERIC = "en_US.UTF-8"; 28 | LC_PAPER = "en_US.UTF-8"; 29 | LC_TELEPHONE = "en_US.UTF-8"; 30 | LC_TIME = "en_US.UTF-8"; 31 | }; 32 | 33 | sound.enable = true; 34 | hardware.pulseaudio.enable = true; 35 | hardware.opengl = { 36 | enable = true; 37 | extraPackages = with pkgs; [ 38 | intel-media-driver 39 | vaapiIntel 40 | vaapiVdpau 41 | libvdpau-va-gl 42 | intel-compute-runtime 43 | ]; 44 | }; 45 | 46 | security = { 47 | doas.enable = true; 48 | sudo.enable = true; 49 | doas.extraConfig = '' 50 | permit nopass :wheel 51 | ''; 52 | doas.extraRules = [{ 53 | users = [ "icy" ]; 54 | }]; 55 | }; 56 | 57 | users.users.icy = { 58 | isNormalUser = true; 59 | description = "icy"; 60 | extraGroups = [ "networkmanager" "wheel" "docker" ]; 61 | packages = with pkgs; [ ]; 62 | }; 63 | 64 | users.users.git = { 65 | isNormalUser = true; 66 | description = "git"; 67 | extraGroups = [ "networkmanager" "wheel" ]; 68 | homeMode = "755"; 69 | packages = with pkgs; [ ]; 70 | }; 71 | 72 | 73 | nixpkgs.config.allowUnfree = true; 74 | environment.systemPackages = with pkgs; [ 75 | vim 76 | wget 77 | git 78 | nfs-utils 79 | ]; 80 | 81 | services = { 82 | openssh.enable = true; 83 | tailscale.enable = true; 84 | # nix-snapshotter.enable = true; 85 | }; 86 | 87 | services.k3s = let address = "100.109.134.88"; in { 88 | enable = true; 89 | role = "agent"; 90 | extraFlags = "--node-ip=${address} --node-external-ip=${address} --flannel-iface=tailscale0"; 91 | serverAddr = "https://sini:6443"; 92 | tokenFile = "/var/lib/rancher/k3s/token"; 93 | }; 94 | 95 | services.openiscsi = { 96 | enable = true; 97 | name = config.networking.hostName; 98 | }; 99 | 100 | environment.etc = { 101 | "rancher/k3s/registries.yaml" = { 102 | text = '' 103 | mirrors: 104 | sini:5000: 105 | endpoint: 106 | - "http://sini:5000" 107 | ''; 108 | }; 109 | }; 110 | 111 | systemd.tmpfiles.rules = [ 112 | "L+ /usr/local/bin - - - - /run/current-system/sw/bin/" 113 | ]; 114 | 115 | nix.settings.experimental-features = [ "nix-command" "flakes" ]; 116 | system.stateVersion = "24.05"; 117 | } 118 | 119 | -------------------------------------------------------------------------------- /hosts/iso/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { config, lib, pkgs, modulesPath, ... }: 5 | 6 | { 7 | imports = 8 | [ 9 | (modulesPath + "/installer/scan/not-detected.nix") 10 | ]; 11 | 12 | boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "sd_mod" ]; 13 | boot.initrd.kernelModules = [ ]; 14 | boot.kernelModules = [ ]; 15 | boot.extraModulePackages = [ ]; 16 | 17 | fileSystems."/" = 18 | { 19 | device = "/dev/disk/by-uuid/355bf4cf-648a-4c43-8741-ac1804e2d31a"; 20 | fsType = "ext4"; 21 | }; 22 | 23 | fileSystems."/boot" = 24 | { 25 | device = "/dev/disk/by-uuid/4E8B-13EC"; 26 | fsType = "vfat"; 27 | options = [ "fmask=0077" "dmask=0077" ]; 28 | }; 29 | 30 | swapDevices = 31 | [{ device = "/dev/disk/by-uuid/c056b71a-e6eb-49ca-a137-3a24d9e299d9"; }]; 32 | 33 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 34 | # (the default) this is the recommended approach. When using systemd-networkd it's 35 | # still possible to use this option, but it's recommended to use it in conjunction 36 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 37 | networking.useDHCP = lib.mkDefault true; 38 | # networking.interfaces.eno1.useDHCP = lib.mkDefault true; 39 | 40 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 41 | hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /hosts/kvothe/configuration.nix: -------------------------------------------------------------------------------- 1 | { self, config, pkgs, lib, ... }: 2 | 3 | { 4 | 5 | nixpkgs.config.allowUnfree = true; 6 | 7 | programs = { 8 | bash.enable = true; 9 | fish.enable = true; 10 | }; 11 | 12 | services = { 13 | tailscale = { 14 | enable = true; 15 | }; 16 | }; 17 | 18 | environment = { 19 | variables = { 20 | EDITOR = "nvim"; 21 | }; 22 | shells = [ pkgs.bash ]; 23 | }; 24 | 25 | users.knownUsers = [ "icy" ]; 26 | users.users.icy = { 27 | name = "icy"; 28 | home = "/Users/icy"; 29 | uid = 501; 30 | shell = pkgs.fish; 31 | }; 32 | 33 | networking = { 34 | hostName = "kvothe"; 35 | localHostName = "kvothe"; 36 | dns = [ 37 | "100.100.100.100" 38 | ]; 39 | knownNetworkServices = [ 40 | "Thunderbolt Bridge" 41 | "Wi-Fi" 42 | ]; 43 | }; 44 | 45 | security.pam.services.sudo_local.touchIdAuth = true; 46 | # security.pam.enableSudoTouchIdAuth = true; 47 | 48 | 49 | system = { 50 | primaryUser = "icy"; 51 | activationScripts.applications.text = pkgs.lib.mkForce ( 52 | '' 53 | echo "setting up /Applications..." >&2 54 | rm -rf /Applications/Nix\ Apps 55 | mkdir -p /Applications/Nix\ Apps 56 | find ${ 57 | pkgs.buildEnv { 58 | name = "system-applications"; 59 | paths = config.environment.systemPackages; 60 | pathsToLink = "/Applications"; 61 | } 62 | }/Applications -maxdepth 1 -type l -exec readlink '{}' + | 63 | while read -r src; do 64 | app_name=$(basename "$src") 65 | echo "copying $src" >&2 66 | ${pkgs.mkalias}/bin/mkalias "$src" "/Applications/Nix Apps/$app_name" 67 | done 68 | '' 69 | ); 70 | 71 | defaults = { 72 | screencapture.location = "/Users/icy/Pictures/Screenshots"; 73 | }; 74 | 75 | stateVersion = 5; 76 | }; 77 | 78 | homebrew = { 79 | enable = true; 80 | onActivation = { 81 | autoUpdate = true; 82 | cleanup = "uninstall"; 83 | upgrade = true; 84 | }; 85 | casks = [ 86 | "orion" 87 | "karabiner-elements" 88 | "halloy" 89 | "zed" 90 | "raycast" 91 | "signal@beta" 92 | "zen" 93 | ]; 94 | }; 95 | } 96 | -------------------------------------------------------------------------------- /hosts/sini/configuration.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, lib, ... }: 2 | 3 | { 4 | imports = 5 | [ 6 | ./hardware-configuration.nix 7 | ../ssh.nix 8 | ]; 9 | 10 | boot.loader.systemd-boot.enable = true; 11 | boot.loader.efi.canTouchEfiVariables = true; 12 | systemd.network.wait-online.enable = false; 13 | 14 | networking.hostName = "sini"; # Define your hostname. 15 | 16 | networking.networkmanager.enable = true; 17 | 18 | time.timeZone = "Europe/Helsinki"; 19 | 20 | i18n.defaultLocale = "en_US.UTF-8"; 21 | 22 | i18n.extraLocaleSettings = { 23 | LC_ADDRESS = "en_US.UTF-8"; 24 | LC_IDENTIFICATION = "en_US.UTF-8"; 25 | LC_MEASUREMENT = "en_US.UTF-8"; 26 | LC_MONETARY = "en_US.UTF-8"; 27 | LC_NAME = "en_US.UTF-8"; 28 | LC_NUMERIC = "en_US.UTF-8"; 29 | LC_PAPER = "en_US.UTF-8"; 30 | LC_TELEPHONE = "en_US.UTF-8"; 31 | LC_TIME = "en_US.UTF-8"; 32 | }; 33 | 34 | sound.enable = true; 35 | hardware.pulseaudio.enable = true; 36 | hardware.opengl = { 37 | enable = true; 38 | extraPackages = with pkgs; [ 39 | intel-media-driver 40 | vaapiIntel 41 | vaapiVdpau 42 | libvdpau-va-gl 43 | intel-compute-runtime 44 | ]; 45 | }; 46 | 47 | security = { 48 | doas.enable = true; 49 | sudo.enable = true; 50 | doas.extraConfig = '' 51 | permit nopass :wheel 52 | ''; 53 | doas.extraRules = [{ 54 | users = [ "icy" ]; 55 | }]; 56 | }; 57 | 58 | users.users.icy = { 59 | isNormalUser = true; 60 | description = "icy"; 61 | extraGroups = [ "networkmanager" "wheel" "docker" ]; 62 | packages = with pkgs; [ ]; 63 | }; 64 | 65 | users.users.git = { 66 | isNormalUser = true; 67 | description = "git"; 68 | extraGroups = [ "networkmanager" "wheel" ]; 69 | homeMode = "755"; 70 | packages = with pkgs; [ ]; 71 | }; 72 | 73 | 74 | nixpkgs.config.allowUnfree = true; 75 | environment.systemPackages = with pkgs; [ 76 | vim 77 | wget 78 | git 79 | nfs-utils 80 | ]; 81 | 82 | services = { 83 | openssh.enable = true; 84 | tailscale.enable = true; 85 | # nix-snapshotter.enable = true; 86 | }; 87 | 88 | services.pixelfed = { 89 | enable = true; 90 | domain = "ani.place"; 91 | secretFile = "/home/icy/svc/pixelfed/.env"; 92 | nginx.listen = [ 93 | { 94 | addr = "0.0.0.0"; 95 | port = 3535; 96 | } 97 | ]; 98 | }; 99 | 100 | # building only 101 | virtualisation.docker.enable = true; 102 | 103 | services.k3s = let address = "100.122.122.12"; in { 104 | enable = true; 105 | extraFlags = "--disable=traefik --disable=servicelb --disable=metrics-server --bind-address=${address} --node-ip=${address} --node-external-ip=${address} --flannel-external-ip=true --flannel-iface=tailscale0"; 106 | }; 107 | 108 | environment.etc = { 109 | "rancher/k3s/registries.yaml" = { 110 | text = '' 111 | mirrors: 112 | sini:5000: 113 | endpoint: 114 | - "http://sini:5000" 115 | ''; 116 | }; 117 | }; 118 | 119 | services.openiscsi = { 120 | enable = true; 121 | name = config.networking.hostName; 122 | }; 123 | 124 | systemd.tmpfiles.rules = [ 125 | "L+ /usr/local/bin - - - - /run/current-system/sw/bin/" 126 | ]; 127 | 128 | services.dockerRegistry = { 129 | enable = true; 130 | listenAddress = "0.0.0.0"; 131 | port = 5000; 132 | enableGarbageCollect = true; 133 | }; 134 | 135 | nix.settings.experimental-features = [ "nix-command" "flakes" ]; 136 | system.stateVersion = "24.05"; 137 | } 138 | 139 | -------------------------------------------------------------------------------- /hosts/sini/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { config, lib, pkgs, modulesPath, ... }: 5 | 6 | { 7 | imports = 8 | [ 9 | (modulesPath + "/installer/scan/not-detected.nix") 10 | ]; 11 | 12 | boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ]; 13 | boot.initrd.kernelModules = [ ]; 14 | boot.kernelModules = [ "kvm-intel" ]; 15 | boot.extraModulePackages = [ ]; 16 | 17 | fileSystems."/" = 18 | { 19 | device = "/dev/disk/by-uuid/16a54d44-96ca-4b94-b4b5-66c5964fdbf5"; 20 | fsType = "ext4"; 21 | }; 22 | 23 | boot.initrd.luks.devices."luks-bbed123c-7bda-4d76-9d39-a47b3452ab55".device = "/dev/disk/by-uuid/bbed123c-7bda-4d76-9d39-a47b3452ab55"; 24 | 25 | fileSystems."/boot" = 26 | { 27 | device = "/dev/disk/by-uuid/4246-3555"; 28 | fsType = "vfat"; 29 | options = [ "fmask=0022" "dmask=0022" ]; 30 | }; 31 | 32 | swapDevices = 33 | [{ device = "/dev/disk/by-uuid/f812a558-7d9a-4dbd-a343-2f556156832f"; }]; 34 | 35 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 36 | # (the default) this is the recommended approach. When using systemd-networkd it's 37 | # still possible to use this option, but it's recommended to use it in conjunction 38 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 39 | networking.useDHCP = lib.mkDefault true; 40 | # networking.interfaces.enp2s0.useDHCP = lib.mkDefault true; 41 | # networking.interfaces.wlp3s0.useDHCP = lib.mkDefault true; 42 | 43 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 44 | hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /hosts/ssh.nix: -------------------------------------------------------------------------------- 1 | { config, lib, pkgs, modulesPath, ... }: 2 | 3 | let 4 | keys = [ 5 | "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICJPYX06+qKr9IHWfkgCtHbExoBOOwS/+iAWbog9bAdk icy@wyndle" 6 | "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIlcByNC93n6dH41uxdLvbtf8XfKF0hoN35548PRga3M icy@kvothe" 7 | ]; 8 | 9 | in 10 | 11 | { 12 | users.users.git.openssh.authorizedKeys.keys = keys; 13 | users.users.icy.openssh.authorizedKeys.keys = keys; 14 | } 15 | -------------------------------------------------------------------------------- /hosts/wyndle/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBZTCCAQugAwIBAgIRAKCb3JL6WUD6sXF9s+8YmrwwCgYIKoZIzj0EAwIwEjEQ 3 | MA4GA1UEAxMHa290aS1jYTAeFw0yNDEwMDcxNjMxNDJaFw0zNDEwMDUxNjMxNDJa 4 | MBIxEDAOBgNVBAMTB2tvdGktY2EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATh 5 | vfUO+tRvEao00PWrCmxBeFFzadlhgmaSPU/RH5NB3Ot76itrtjLo/z0TkuwCsqjP 6 | Yai6CLbgOiTZfQJdcTFao0IwQDAOBgNVHQ8BAf8EBAMCAqQwDwYDVR0TAQH/BAUw 7 | AwEB/zAdBgNVHQ4EFgQUaoWbyrmIMYCUHEc8zyrnWO+WLrMwCgYIKoZIzj0EAwID 8 | SAAwRQIhAI/c4bICkQal1LPKq9qvhFIzSpxra/ezkFDXai2EAKW6AiAeHvBi8IHa 9 | IOQMD8+m4Ee5dR8PdIpaJ2f+jWXdtjBOng== 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /hosts/wyndle/configuration.nix: -------------------------------------------------------------------------------- 1 | { self, config, pkgs, lib, ... }: 2 | 3 | { 4 | imports = 5 | [ 6 | ./hardware-configuration.nix 7 | ]; 8 | 9 | boot = { 10 | loader.systemd-boot.enable = true; 11 | loader.systemd-boot.consoleMode = "max"; 12 | loader.efi.canTouchEfiVariables = true; 13 | kernel.sysctl."net.ipv4.ip_forward" = 1; 14 | resumeDevice = "/dev/nvme0n1p2"; 15 | kernelPackages = pkgs.linuxPackages_latest; 16 | kernelModules = [ "i2c-dev" "v4l2loopback" ]; 17 | }; 18 | 19 | boot.blacklistedKernelModules = [ "nouveau" "nvidia" "nvidia_drm" "nvidia_modeset" ]; 20 | boot.extraModprobeConfig = '' 21 | blacklist nouveau 22 | options nouveau modeset=0 23 | options v4l2loopback video_nr=2,3 width=640,1920 max_width=1920 height=480,1080 max_height=1080 format=YU12,YU12 exclusive_caps=1,1 card_label=Phone,Laptop debug=1 24 | ''; 25 | 26 | boot.extraModulePackages = with config.boot.kernelPackages; [ 27 | v4l2loopback 28 | ]; 29 | 30 | networking = { 31 | nameservers = [ "8.8.8.8" "8.8.4.4" ]; 32 | networkmanager.enable = true; 33 | hostName = "wyndle"; 34 | useDHCP = false; 35 | interfaces.wlp6s0.useDHCP = true; 36 | firewall.checkReversePath = "loose"; 37 | }; 38 | 39 | i18n.defaultLocale = "en_US.UTF-8"; 40 | i18n.inputMethod = { 41 | enabled = "ibus"; 42 | }; 43 | time.timeZone = "Europe/Helsinki"; 44 | 45 | nixpkgs.config = { 46 | allowUnfree = true; 47 | allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ 48 | "steam" 49 | "steam-original" 50 | "steam-runtime" 51 | ]; 52 | chromium = { 53 | commandLineArgs = "--ozone-platform=wayland --enable-features=TouchpadOverscrollHistoryNavigation"; 54 | }; 55 | firefox.enablePlasmaBrowserIntegration = true; 56 | }; 57 | 58 | 59 | environment = { 60 | sessionVariables = rec { 61 | NIXOS_OZONE_WL = "1"; 62 | }; 63 | variables = { 64 | MOZ_USE_XINPUT2 = "1"; 65 | GDK_SCALE = "2"; 66 | GDK_DPI_SCALE = "1"; 67 | }; 68 | systemPackages = with pkgs; [ 69 | man-pages 70 | git 71 | man-pages-posix 72 | (lib.hiPrio pkgs.bashInteractive) 73 | ]; 74 | gnome.excludePackages = (with pkgs; [ 75 | gnome-photos 76 | gnome-tour 77 | ]) ++ (with pkgs; [ 78 | cheese 79 | epiphany 80 | geary 81 | totem 82 | ]); 83 | }; 84 | 85 | documentation = { 86 | dev.enable = true; 87 | man.generateCaches = true; 88 | }; 89 | 90 | users.motd = with config; '' 91 | Host ${networking.hostName} 92 | OS NixOS ${system.nixos.release} (${system.nixos.codeName}) 93 | Version ${system.nixos.version} 94 | Kernel ${boot.kernelPackages.kernel.version} 95 | ''; 96 | 97 | console = { 98 | font = "${pkgs.terminus_font}/share/consolefonts/ter-u28n.psf.gz"; 99 | keyMap = "us"; 100 | }; 101 | 102 | hardware = { 103 | bluetooth = { 104 | enable = true; 105 | powerOnBoot = true; 106 | disabledPlugins = [ "sap" ]; 107 | }; 108 | nvidia.prime = { 109 | offload.enable = false; 110 | amdgpuBusId = "PCI:8:0:0"; 111 | nvidiaBusId = "PCI:1:0:0"; 112 | }; 113 | logitech.wireless = { 114 | enable = true; 115 | enableGraphical = true; 116 | }; 117 | graphics.extraPackages = [ pkgs.amdvlk ]; 118 | }; 119 | 120 | services = { 121 | asusd = { 122 | enable = true; 123 | enableUserService = true; 124 | }; 125 | supergfxd = { 126 | enable = true; 127 | settings = { 128 | mode = "integrated"; 129 | vfio_enable = false; 130 | vfio_save = false; 131 | always_reboot = true; 132 | no_logind = false; 133 | logout_timeout_s = 180; 134 | }; 135 | 136 | }; 137 | pipewire = { 138 | enable = true; 139 | wireplumber.enable = true; 140 | alsa.enable = true; 141 | alsa.support32Bit = true; 142 | pulse.enable = true; 143 | }; 144 | xserver = { 145 | enable = true; 146 | xkb.layout = "us"; 147 | desktopManager.gnome.enable = true; 148 | displayManager.gdm.enable = true; 149 | dpi = 192; 150 | videoDrivers = [ "amdgpu" ]; 151 | screenSection = '' 152 | Option "metamodes" "nvidia-auto-select +0+0 {ForceFullCompositionPipeline=On}" 153 | Option "AllowIndirectGLXProtocol" "off" 154 | Option "TripleBuffer" "on" 155 | ''; 156 | }; 157 | 158 | libinput = { 159 | enable = true; 160 | mouse = { 161 | scrollButton = 8; 162 | scrollMethod = "button"; 163 | }; 164 | }; 165 | 166 | ddccontrol.enable = true; 167 | tailscale.enable = true; 168 | # 1. chmod for rootless backligh1t 169 | # 2. lotus58 bootloader mode for rootless qmk flashing 170 | udev = { 171 | extraRules = '' 172 | ACTION=="add", SUBSYSTEM=="backlight", KERNEL=="amdgpu_bl1", MODE="0666", RUN+="${pkgs.coreutils}/bin/chmod a+w /sys/class/backlight/%k/brightness" 173 | ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0036", TAG+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1" 174 | KERNEL=="i2c-[0-9]*", GROUP="i2c", MODE="0660" 175 | 176 | # Remove NVIDIA USB xHCI Host Controller devices, if present 177 | ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c0330", ATTR{power/control}="auto", ATTR{remove}="1" 178 | # Remove NVIDIA USB Type-C UCSI devices, if present 179 | ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c8000", ATTR{power/control}="auto", ATTR{remove}="1" 180 | # Remove NVIDIA Audio devices, if present 181 | ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x040300", ATTR{power/control}="auto", ATTR{remove}="1" 182 | # Remove NVIDIA VGA/3D controller devices 183 | ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x03[0-9]*", ATTR{power/control}="auto", ATTR{remove}="1" 184 | ''; 185 | extraHwdb = '' 186 | evdev:input:b0003v0B05p19B6* 187 | KEYBOARD_KEY_ff31007c=f20 # x11 mic-mute 188 | ''; 189 | path = [ 190 | pkgs.coreutils 191 | ]; 192 | }; 193 | logind.extraConfig = '' 194 | HandlePowerKey=hibernate 195 | ''; 196 | 197 | keyd = { 198 | enable = true; 199 | keyboards.default = { 200 | ids = [ "*" ]; 201 | extraConfig = '' 202 | [main] 203 | capslock = overload(capslock, rightalt) 204 | leftmeta = layer(meta_mac) 205 | rightmeta = layer(meta_mac) 206 | leftalt = layer(option_mac) 207 | rightalt = layer(option_mac) 208 | 209 | [capslock] 210 | h = left 211 | j = down 212 | k = up 213 | l = right 214 | 215 | # Activates when both capslock and shift is pressed 216 | [capslock+shift] 217 | h = C-left 218 | j = C-down 219 | k = C-up 220 | l = C-right 221 | 222 | # macOS style bindings 223 | [meta_mac:M] 224 | l = C-l 225 | a = C-a 226 | t = C-t 227 | w = C-w 228 | f = C-f 229 | c = C-c 230 | v = C-v 231 | backspace = C-backspace 232 | leftshift = compose 233 | 234 | [option_mac:A] 235 | backspace = C-backspace 236 | ''; 237 | }; 238 | }; 239 | pcscd.enable = true; 240 | }; 241 | 242 | virtualisation.docker = { 243 | enable = true; 244 | logDriver = "json-file"; 245 | extraOptions = '' 246 | --insecure-registry "http://sini:5000" 247 | ''; 248 | }; 249 | 250 | security = { 251 | doas.enable = true; 252 | sudo.enable = true; 253 | doas.extraConfig = '' 254 | permit nopass :wheel 255 | ''; 256 | doas.extraRules = [{ 257 | users = [ "icy" ]; 258 | }]; 259 | pki.certificateFiles = [ ./ca.crt ]; 260 | }; 261 | 262 | powerManagement = { 263 | enable = true; 264 | powertop.enable = true; 265 | }; 266 | 267 | users.users.icy = { 268 | isNormalUser = true; 269 | extraGroups = [ "wheel" "docker" "audio" "video" "dialout" "i2c" ]; 270 | }; 271 | 272 | programs = { 273 | steam.enable = true; 274 | gamemode.enable = true; 275 | }; 276 | 277 | nix = { 278 | package = pkgs.nixVersions.stable; 279 | extraOptions = '' 280 | experimental-features = nix-command flakes ca-derivations 281 | warn-dirty = false 282 | keep-outputs = false 283 | ''; 284 | settings = { 285 | trusted-users = [ 286 | "root" 287 | "icy" 288 | ]; 289 | }; 290 | }; 291 | 292 | # https://github.com/NixOS/nixpkgs/issues/180175 293 | systemd.services.systemd-udevd.restartIfChanged = false; 294 | systemd.services.NetworkManager-wait-online.enable = lib.mkForce 295 | false; 296 | 297 | 298 | # This value determines the NixOS release from which the default 299 | # settings for stateful data, like file locations and database versions 300 | # on your system were taken. It‘s perfectly fine and recommended to leave 301 | # this value at the release version of the first install of this system. 302 | # Before changing this value read the documentation for this option 303 | # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). 304 | system.stateVersion = "21.11"; # Did you read the comment? 305 | 306 | } 307 | 308 | -------------------------------------------------------------------------------- /hosts/wyndle/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { config, lib, pkgs, modulesPath, ... }: 5 | 6 | { 7 | imports = 8 | [ 9 | (modulesPath + "/installer/scan/not-detected.nix") 10 | ]; 11 | 12 | boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ]; 13 | boot.initrd.kernelModules = [ ]; 14 | boot.kernelModules = [ "kvm-amd" ]; 15 | boot.extraModulePackages = [ ]; 16 | 17 | fileSystems."/" = 18 | { 19 | device = "/dev/disk/by-uuid/f66408c3-50c9-421a-80c1-8163761f3817"; 20 | fsType = "ext4"; 21 | }; 22 | 23 | fileSystems."/boot" = 24 | { 25 | device = "/dev/disk/by-uuid/E85D-EAD8"; 26 | fsType = "vfat"; 27 | }; 28 | 29 | swapDevices = [ ]; 30 | 31 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 32 | hardware.opengl.enable = true; 33 | hardware.nvidia.modesetting.enable = false; 34 | hardware.pulseaudio.enable = false; 35 | } 36 | -------------------------------------------------------------------------------- /nvim/_init.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | -- TODO: ref: https://github.com/neovim/neovim/pull/15436 4 | -- require 'impatient' 5 | 6 | require 'settings' 7 | require 'completion' 8 | require 'maps' 9 | require 'statusline.line' 10 | require 'treesitter' 11 | require 'tree' 12 | require 'fzy/fzy' 13 | 14 | -- lsp setup 15 | require 'lsp.config' 16 | require 'lsp.python' 17 | require 'lsp.go' 18 | require 'lsp.lua' 19 | require 'lsp.json' 20 | require 'lsp.js' 21 | require 'lsp.rust' 22 | 23 | -- plugins not in nixpkgs 24 | require 'packer'.startup(function(use) 25 | use 'preservim/vim-textobj-quote' 26 | end) 27 | 28 | require 'dapx' 29 | -------------------------------------------------------------------------------- /nvim/colors/plain.lua: -------------------------------------------------------------------------------- 1 | local o = vim.o 2 | local g = vim.g 3 | local api = vim.api 4 | 5 | vim.cmd('hi clear') 6 | 7 | if g.syntax_on == 1 then 8 | vim.cmd('syntax reset') 9 | end 10 | 11 | g.colors_name = 'plain' 12 | 13 | local background = '#f4f4f4' 14 | local grey_bg_light = '#E5E5E5' 15 | local black = '#676767' 16 | local blue = '#6587bf' 17 | local green = '#7c9f4b' 18 | local light_green = '#6d8b42' 19 | local light_red = '#c66666' 20 | local red = '#db7070' 21 | local grey = '#767676' 22 | local light_grey = '#dfdfdf' 23 | local border = '#999999' 24 | local highlight = '#424242' 25 | local dark_yellow = '#d69822' 26 | local yellow = '#f3e430' 27 | local light_yellow = '#fadaa0' 28 | local orange = '#D75F5F' 29 | local purple = '#8e69d5' 30 | local white = '#FFFFFF' 31 | local cyan = '#509c93' 32 | 33 | g.terminal_color_0 = black 34 | g.terminal_color_1 = red 35 | g.terminal_color_2 = green 36 | g.terminal_color_3 = dark_yellow 37 | g.terminal_color_4 = blue 38 | g.terminal_color_5 = purple 39 | g.terminal_color_6 = cyan 40 | g.terminal_color_7 = grey 41 | 42 | g.terminal_color_8 = black 43 | g.terminal_color_9 = red 44 | g.terminal_color_10 = green 45 | g.terminal_color_11 = dark_yellow 46 | g.terminal_color_12 = blue 47 | g.terminal_color_13 = purple 48 | g.terminal_color_14 = cyan 49 | g.terminal_color_15 = grey 50 | 51 | local highlights = { 52 | -- This highlight group can be used when one wants to disable a highlight 53 | -- group using `winhl` 54 | Disabled = {}, 55 | -- These highlight groups can be used for statuslines, for example when 56 | -- displaying ALE warnings and errors. 57 | BlackOnLightYellow = { fg = black, bg = light_yellow }, 58 | LightRedBackground = { bg = light_red }, 59 | WhiteOnBlue = { fg = white, bg = blue }, 60 | WhiteOnOrange = { fg = white, bg = orange }, 61 | WhiteOnRed = { fg = white, bg = red }, 62 | WhiteOnYellow = { fg = white, bg = dark_yellow }, 63 | Yellow = { fg = dark_yellow, bold = true }, 64 | Bold = { fg = black, bold = true }, 65 | Boolean = { link = 'Keyword' }, 66 | Character = { link = 'String' }, 67 | ColorColumn = { bg = highlight }, 68 | Comment = { fg = grey, italic = true }, 69 | Conceal = {}, 70 | Constant = { fg = black }, 71 | Cursor = { bg = black }, 72 | -- This is to work around https://github.com/neovim/neovim/issues/9800. 73 | CursorLine = { ctermfg = 'black' }, 74 | CursorLineNr = { fg = black, bold = true }, 75 | Directory = { fg = purple }, 76 | EndOfBuffer = { fg = background, bg = background }, 77 | Error = { link = 'ErrorMsg' }, 78 | ErrorMsg = { fg = red, bold = true }, 79 | FoldColumn = { fg = light_grey, bg = background }, 80 | Folded = { link = 'Comment' }, 81 | Identifier = { fg = black }, 82 | Function = { fg = black }, 83 | IncSearch = { link = 'Search' }, 84 | CurSearch = { link = 'Search' }, 85 | Include = { fg = black, bold = true }, 86 | InstanceVariable = { fg = purple }, 87 | Keyword = { fg = black, bold = true }, 88 | Label = { link = 'Keyword' }, 89 | LineNr = { fg = grey }, 90 | Macro = { fg = orange }, 91 | MatchParen = { bold = true }, 92 | MoreMsg = { fg = black }, 93 | ModeMsg = { fg = black, bold = true }, 94 | MsgSeparator = { fg = border }, 95 | NonText = { fg = light_grey }, 96 | Normal = { fg = black , bg = background }, 97 | NormalFloat = { fg = black }, 98 | FloatTitle = { fg = black, bold = true }, 99 | FloatBorder = { fg = border }, 100 | Number = { fg = blue }, 101 | Operator = { fg = black }, 102 | Pmenu = { fg = black, bg = grey_bg_light }, 103 | PmenuSbar = { bg = grey_bg_light }, 104 | PmenuSel = { bg = light_grey, bold = true }, 105 | PmenuThumb = { bg = light_grey }, 106 | PreCondit = { link = 'Macro' }, 107 | PreProc = { fg = black }, 108 | Question = { fg = black }, 109 | QuickFixLine = { bg = highlight, bold = true }, 110 | Regexp = { fg = orange }, 111 | Search = { bg = light_yellow }, 112 | SignColumn = { link = 'FoldColumn' }, 113 | Special = { fg = black }, 114 | SpecialKey = { link = 'Number' }, 115 | SpellBad = { sp = red, underline = true }, 116 | SpellCap = { sp = dark_yellow, underline = true }, 117 | SpellLocal = { sp = blue, underline = true }, 118 | SpellRare = { sp = purple, underline = true }, 119 | Statement = { link = 'Keyword' }, 120 | StatusLine = { fg = black, bg = background }, 121 | StatusLineNC = { fg = black, bg = grey_bg_light }, 122 | StatusLineTab = { fg = black, bg = background, bold = true }, 123 | WinBar = { fg = black, bold = true }, 124 | WinBarNc = { fg = black, bold = true }, 125 | WinBarFill = { fg = border }, 126 | StorageClass = { link = 'Keyword' }, 127 | String = { fg = cyan }, 128 | SnippetTabstop = {}, 129 | Symbol = { fg = orange }, 130 | TabLine = { fg = black, bg = light_grey }, 131 | TabLineFill = { fg = black, bg = light_grey }, 132 | TabLineSel = { fg = black, bg = background, bold = true }, 133 | Title = { fg = black, bold = true }, 134 | Todo = { fg = grey, bold = true }, 135 | Type = { link = 'Constant' }, 136 | Underlined = { underline = true }, 137 | VertSplit = { fg = border }, 138 | WinSeparator = { fg = border }, 139 | Visual = { bg = light_grey }, 140 | WarningMsg = { fg = dark_yellow, bold = true }, 141 | Whitespace = { fg = light_grey }, 142 | WildMenu = { link = 'PmenuSel' }, 143 | -- ALE 144 | ALEError = { fg = red, bold = true }, 145 | ALEErrorSign = { fg = red, bold = true }, 146 | ALEWarning = { fg = dark_yellow, bold = true }, 147 | ALEWarningSign = { fg = dark_yellow, bold = true }, 148 | -- ccc.nvim 149 | CccFloatNormal = { link = 'NormalFloat' }, 150 | CccFloatBorder = { link = 'FloatBorder' }, 151 | -- CSS 152 | cssClassName = { link = 'Keyword' }, 153 | cssColor = { link = 'Number' }, 154 | cssIdentifier = { link = 'Keyword' }, 155 | cssImportant = { link = 'Keyword' }, 156 | cssProp = { link = 'Identifier' }, 157 | cssTagName = { link = 'Keyword' }, 158 | -- Diffs 159 | DiffAdd = { fg = green, bg = background }, 160 | DiffChange = { bg = highlight }, 161 | DiffDelete = { fg = red }, 162 | DiffText = { bg = light_yellow }, 163 | diffAdded = { link = 'DiffAdd' }, 164 | diffChanged = { link = 'DiffChange' }, 165 | diffFile = { fg = black, bold = true }, 166 | diffLine = { fg = blue }, 167 | diffRemoved = { link = 'DiffDelete' }, 168 | -- Dot/Graphviz 169 | dotKeyChar = { link = 'Operator' }, 170 | -- diffview.nvim 171 | DiffviewCursorLine = { bg = highlight }, 172 | DiffviewDiffAddAsDelete = { bg = light_red }, 173 | DiffviewDiffDelete = { fg = light_grey }, 174 | DiffviewDiffDeleteDim = { fg = light_grey }, 175 | DiffviewFilePanelFileName = { fg = black }, 176 | DiffviewFilePanelPath = { fg = purple }, 177 | DiffviewFilePanelRootPath = { fg = purple }, 178 | DiffviewFilePanelTitle = { fg = black, bold = true }, 179 | DiffviewFilePanelInsertions = { fg = green }, 180 | DiffviewFilePanelDeletions = { fg = red }, 181 | DiffviewStatusModified = { fg = dark_yellow, bold = true }, 182 | DiffviewStatusAdded = { fg = green, bold = true }, 183 | DiffviewStatusCopied = { fg = green, bold = true }, 184 | DiffviewStatusDeleted = { fg = red, bold = true }, 185 | -- Flash 186 | FlashBackdrop = { link = 'None' }, 187 | FlashLabel = { fg = red, bold = true }, 188 | -- Fugitive 189 | FugitiveblameHash = { fg = purple }, 190 | FugitiveblameTime = { fg = blue }, 191 | gitCommitOverflow = { link = 'ErrorMsg' }, 192 | gitCommitSummary = { link = 'String' }, 193 | -- gitcommit 194 | ['@string.special.url.gitcommit'] = { fg = black }, 195 | ['@markup.link.gitcommit'] = { fg = green, bold = true }, 196 | ['@comment.warning.gitcommit'] = { fg = red, bold = true }, 197 | -- Gitsigns 198 | GitSignsAdd = { fg = green }, 199 | GitSignsDelete = { fg = red }, 200 | GitSignsChange = { fg = grey }, 201 | -- HAML 202 | hamlClass = { fg = black }, 203 | hamlDocType = { link = 'Comment' }, 204 | hamlId = { fg = black }, 205 | hamlTag = { fg = black, bold = true }, 206 | -- hop.nvim 207 | HopNextKey = { fg = red, bold = true }, 208 | HopNextKey1 = { fg = dark_yellow }, 209 | HopNextKey2 = { fg = dark_yellow }, 210 | HopUnmatched = {}, 211 | -- HTML 212 | htmlArg = { link = 'Identifier' }, 213 | htmlLink = { link = 'Directory' }, 214 | htmlScriptTag = { link = 'htmlTag' }, 215 | htmlSpecialTagName = { link = 'htmlTag' }, 216 | htmlTag = { fg = black, bold = true }, 217 | htmlTagName = { link = 'htmlTag' }, 218 | htmlItalic = { italic = true }, 219 | htmlBold = { bold = true }, 220 | -- Inko 221 | inkoCommentBold = { fg = grey, bold = true }, 222 | inkoCommentInlineUrl = { link = 'Number' }, 223 | inkoCommentItalic = { fg = grey, italic = true }, 224 | inkoCommentTitle = { fg = grey, bold = true }, 225 | inkoInstanceVariable = { link = 'InstanceVariable' }, 226 | inkoKeywordArgument = { link = 'Regexp' }, 227 | ['@variable.member.inko'] = { link = 'InstanceVariable' }, 228 | ['@constant.builtin.inko'] = { link = 'Keyword' }, 229 | -- Java 230 | javaAnnotation = { link = 'Directory' }, 231 | javaCommentTitle = { link = 'javaComment' }, 232 | javaDocParam = { link = 'Todo' }, 233 | javaDocTags = { link = 'Todo' }, 234 | javaExternal = { link = 'Keyword' }, 235 | javaStorageClass = { link = 'Keyword' }, 236 | -- Javascript 237 | JavaScriptNumber = { link = 'Number' }, 238 | javaScriptBraces = { link = 'Operator' }, 239 | javaScriptFunction = { link = 'Keyword' }, 240 | javaScriptIdentifier = { link = 'Keyword' }, 241 | javaScriptMember = { link = 'Identifier' }, 242 | -- JSON 243 | jsonKeyword = { link = 'String' }, 244 | -- Lua 245 | luaFunction = { link = 'Keyword' }, 246 | -- LSP 247 | DiagnosticUnderlineError = { underline = true, sp = red }, 248 | DiagnosticUnderlineWarn = { underline = true, sp = dark_yellow }, 249 | LspDiagnosticsUnderlineError = { link = 'DiagnosticUnderlineError' }, 250 | LspDiagnosticsUnderlineWarning = { link = 'DiagnosticUnderlineWarn' }, 251 | DiagnosticFloatingError = { fg = red, bold = true }, 252 | DiagnosticFloatingHint = { fg = black, bold = true }, 253 | DiagnosticFloatingInfo = { fg = blue, bold = true }, 254 | DiagnosticFloatingWarn = { fg = dark_yellow, bold = true }, 255 | DiagnosticError = { fg = red }, 256 | DiagnosticHint = { fg = grey }, 257 | DiagnosticInfo = { fg = blue }, 258 | DiagnosticWarn = { fg = dark_yellow }, 259 | -- Make 260 | makeTarget = { link = 'Function' }, 261 | -- Markdown 262 | markdownCode = { link = 'markdownCodeBlock' }, 263 | markdownCodeBlock = { link = 'Comment' }, 264 | markdownListMarker = { link = 'Keyword' }, 265 | markdownOrderedListMarker = { link = 'Keyword' }, 266 | markdownUrl = { fg = blue }, 267 | -- mini.pick 268 | MiniPickBorder = { fg = border }, 269 | MiniPickBorderBusy = { link = 'MiniPickBorder' }, 270 | MiniPickBorderText = { fg = black }, 271 | MiniPickHeader = { fg = black, bold = true }, 272 | MiniPickMatchCurrent = { bg = light_grey, bold = true }, 273 | MiniPickMatchRanges = { fg = dark_yellow, bold = true }, 274 | MiniPickNormal = { fg = black }, 275 | MiniPickPrompt = { fg = black, bold = true }, 276 | -- netrw 277 | netrwClassify = { link = 'Identifier' }, 278 | -- Neogit 279 | NeogitBranch = { fg = green, bold = true }, 280 | NeogitBranchHead = { link = 'NeogitBranch' }, 281 | NeogitCommitViewHeader = { fg = dark_yellow, bold = true }, 282 | NeogitCursorLine = { bg = highlight }, 283 | NeogitDiffAdd = { link = 'DiffAdd' }, 284 | NeogitDiffAddHighlight = { link = 'NeogitDiffAdd' }, 285 | NeogitDiffContext = { link = 'Normal' }, 286 | NeogitDiffContextHighlight = { link = 'Normal' }, 287 | NeogitDiffDelete = { link = 'DiffDelete' }, 288 | NeogitDiffDeleteHighlight = { link = 'NeogitDiffDelete' }, 289 | NeogitDiffHeader = { fg = black, bold = true }, 290 | NeogitDiffHeaderHighlight = { link = 'NeogitDiffHeader' }, 291 | NeogitFilePath = { fg = purple }, 292 | NeogitGraphBlue = { fg = blue }, 293 | NeogitGraphBoldBlue = { fg = blue, bold = true }, 294 | NeogitGraphBoldCyan = { fg = cyan, bold = true }, 295 | NeogitGraphBoldGray = { fg = grey, bold = true }, 296 | NeogitGraphBoldGreen = { fg = green, bold = true }, 297 | NeogitGraphBoldOrange = { fg = orange, bold = true }, 298 | NeogitGraphBoldPurple = { fg = purple, bold = true }, 299 | NeogitGraphBoldRed = { fg = red, bold = true }, 300 | NeogitGraphBoldWhite = { fg = black, bold = true }, 301 | NeogitGraphBoldYellow = { fg = dark_yellow, bold = true }, 302 | NeogitGraphCyan = { fg = cyan }, 303 | NeogitGraphGray = { fg = grey }, 304 | NeogitGraphGreen = { fg = green }, 305 | NeogitGraphOrange = { fg = orange }, 306 | NeogitGraphPurple = { fg = purple }, 307 | NeogitGraphRed = { fg = red }, 308 | NeogitGraphWhite = { fg = black }, 309 | NeogitGraphYellow = { fg = dark_yellow }, 310 | NeogitHunkHeader = { fg = blue }, 311 | NeogitHunkHeaderHighlight = { link = 'NeogitHunkHeader' }, 312 | NeogitPopupActionKey = { link = 'NeogitPopupOptionKey' }, 313 | NeogitPopupBranchName = { link = 'NeogitBranch' }, 314 | NeogitPopupConfigEnabled = { link = 'NeogitPopupOptionEnabled' }, 315 | NeogitPopupConfigKey = { link = 'NeogitPopupOptionKey' }, 316 | NeogitPopupOptionEnabled = { bg = light_green, bold = true }, 317 | NeogitPopupOptionKey = { bold = true }, 318 | NeogitPopupSectionTitle = { link = 'Title' }, 319 | NeogitPopupSwitchEnabled = { link = 'NeogitPopupOptionEnabled' }, 320 | NeogitPopupSwitchKey = { link = 'NeogitPopupOptionKey' }, 321 | NeogitRemote = { link = 'NeogitBranch' }, 322 | -- Perl 323 | perlPackageDecl = { link = 'Identifier' }, 324 | perlStatementInclude = { link = 'Statement' }, 325 | perlStatementPackage = { link = 'Statement' }, 326 | podCmdText = { link = 'Todo' }, 327 | podCommand = { link = 'Comment' }, 328 | podVerbatimLine = { link = 'Todo' }, 329 | -- Ruby 330 | rubyAttribute = { link = 'Identifier' }, 331 | rubyClass = { link = 'Keyword' }, 332 | rubyClassVariable = { link = 'rubyInstancevariable' }, 333 | rubyConstant = { link = 'Constant' }, 334 | rubyDefine = { link = 'Keyword' }, 335 | rubyFunction = { link = 'Function' }, 336 | rubyInstanceVariable = { link = 'InstanceVariable' }, 337 | rubyMacro = { link = 'Identifier' }, 338 | rubyModule = { link = 'rubyClass' }, 339 | rubyRegexp = { link = 'Regexp' }, 340 | rubyRegexpCharClass = { link = 'Regexp' }, 341 | rubyRegexpDelimiter = { link = 'Regexp' }, 342 | rubyRegexpQuantifier = { link = 'Regexp' }, 343 | rubyRegexpSpecial = { link = 'Regexp' }, 344 | rubyStringDelimiter = { link = 'String' }, 345 | rubySymbol = { link = 'Symbol' }, 346 | -- Rust 347 | rustCommentBlockDoc = { link = 'Comment' }, 348 | rustCommentLineDoc = { link = 'Comment' }, 349 | rustFuncCall = { link = 'Identifier' }, 350 | rustModPath = { link = 'Identifier' }, 351 | ['@function.macro.rust'] = { link = 'Macro' }, 352 | ['@attribute.rust'] = { link = 'Identifier' }, 353 | -- pounce.nvim 354 | PounceAccept = { fg = black, bg = yellow, bold = true }, 355 | PounceAcceptBest = { link = 'PounceAccept' }, 356 | PounceMatch = { bg = light_yellow }, 357 | PounceUnmatched = {}, 358 | PounceGap = { link = 'None' }, 359 | -- Python 360 | pythonOperator = { link = 'Keyword' }, 361 | -- SASS 362 | sassClass = { link = 'cssClassName' }, 363 | sassId = { link = 'cssIdentifier' }, 364 | -- Shell 365 | shFunctionKey = { link = 'Keyword' }, 366 | -- Snippy 367 | SnippyPlaceholder = { link = 'SnippetTabstop' }, 368 | -- SQL 369 | sqlKeyword = { link = 'Keyword' }, 370 | -- Typescript 371 | typescriptBraces = { link = 'Operator' }, 372 | typescriptEndColons = { link = 'Operator' }, 373 | typescriptExceptions = { link = 'Keyword' }, 374 | typescriptFuncKeyword = { link = 'Keyword' }, 375 | typescriptFunction = { link = 'Function' }, 376 | typescriptIdentifier = { link = 'Identifier' }, 377 | typescriptLogicSymbols = { link = 'Operator' }, 378 | -- Telescope 379 | TelescopeBorder = { fg = border }, 380 | TelescopeMatching = { fg = dark_yellow, bold = true }, 381 | TelescopePromptNormal = { fg = black }, 382 | TelescopePromptBorder = { fg = border }, 383 | TelescopePromptPrefix = { fg = black, bold = true }, 384 | TelescopeSelection = { bg = light_grey, bold = true }, 385 | TelescopeTitle = { fg = black, bold = true }, 386 | TelescopeNormal = { fg = black }, 387 | -- Treesitter 388 | TSEmphasis = { italic = true }, 389 | TSField = {}, 390 | TSStringEscape = { fg = green, bold = true }, 391 | TSStrong = { bold = true }, 392 | TSURI = { fg = blue, underline = true }, 393 | TSUnderline = { underline = true }, 394 | TSConstMacro = { link = 'Macro' }, 395 | TSDanger = { link = 'Todo' }, 396 | TSKeywordOperator = { link = 'Keyword' }, 397 | TSNamespace = { link = 'Constant' }, 398 | TSNote = { link = 'Todo' }, 399 | TSProperty = { link = 'TSField' }, 400 | TSStringRegex = { link = 'Regexp' }, 401 | TSSymbol = { link = 'Symbol' }, 402 | TSTypeBuiltin = { link = 'Keyword' }, 403 | TSWarning = { link = 'Todo' }, 404 | ['@markup.link'] = { fg = blue }, 405 | ['@property.json'] = { bold = true }, 406 | ['@text.emphasis'] = { italic = true }, 407 | ['@text.reference'] = { fg = purple }, 408 | ['@text.strong'] = { bold = true }, 409 | ['@text.uri'] = { fg = blue }, 410 | ['@variable.builtin'] = { bold = true }, 411 | 412 | -- Custom Tree-sitter captures added by this theme. 413 | ['@variable.parameter.reference'] = { fg = orange }, 414 | 415 | -- Ruby uses "TSLabel" for instance variables, for some reason. See 416 | -- https://github.com/tree-sitter/tree-sitter-ruby/issues/184 for more 417 | -- details. 418 | rubyTSLabel = { link = 'InstanceVariable' }, 419 | -- TOML 420 | -- 421 | -- tomlTSTypeBuiltin is used for section titles (e.g. `[dependencies]`), while 422 | -- tomlTSProperty is used for key-value pairs. These rules ensure the syntax 423 | -- is consistent with https://github.com/cespare/vim-toml. 424 | tomlTSProperty = { fg = black }, 425 | tomlTSTypeBuiltin = { fg = black, bold = true }, 426 | -- Vimscript 427 | VimCommentTitle = { link = 'Todo' }, 428 | VimIsCommand = { link = 'Constant' }, 429 | vimGroup = { link = 'Constant' }, 430 | vimHiGroup = { link = 'Constant' }, 431 | -- XML 432 | xmlAttrib = { link = 'Identifier' }, 433 | xmlTag = { link = 'Identifier' }, 434 | xmlTagName = { link = 'Identifier' }, 435 | -- YAML 436 | yamlPlainScalar = { link = 'String' }, 437 | -- YARD 438 | yardComment = { link = 'Comment' }, 439 | yardType = { link = 'Todo' }, 440 | yardTypeList = { link = 'Todo' }, 441 | 442 | -- custom highlight groups 443 | ['@variable'] = { fg = black }, 444 | 445 | -- statusline 446 | LinePrimaryBlock = { fg = black, bg = background }, 447 | LineSecondaryBlock = { fg = blue, bg = background }, 448 | LineError = { link = 'DiagnosticError' }, 449 | LineHint = { link = 'DiagnosticHint' }, 450 | LineInfo = { link = 'DiagnosticInfo' }, 451 | LineWarning = { link = 'DiagnosticWarn' }, 452 | } 453 | 454 | for group, opts in pairs(highlights) do 455 | api.nvim_set_hl(0, group, opts) 456 | end 457 | -------------------------------------------------------------------------------- /nvim/ftplugin/c.vim: -------------------------------------------------------------------------------- 1 | setlocal tabstop=2 2 | setlocal shiftwidth=2 3 | setlocal autoindent 4 | setlocal smarttab 5 | setlocal noexpandtab 6 | setlocal textwidth=80 7 | setlocal formatoptions=croql 8 | -------------------------------------------------------------------------------- /nvim/ftplugin/css.vim: -------------------------------------------------------------------------------- 1 | setlocal ts=2 sts=2 sw=2 expandtab 2 | -------------------------------------------------------------------------------- /nvim/ftplugin/go.vim: -------------------------------------------------------------------------------- 1 | setlocal noexpandtab 2 | setlocal autoindent 3 | setlocal shiftwidth=4 4 | setlocal smarttab 5 | setlocal formatoptions=croql 6 | setlocal tabstop=4 7 | 8 | 9 | lua <'] = cmp.mapping.scroll_docs(-4), 21 | [''] = cmp.mapping.scroll_docs(4), 22 | [''] = cmp.mapping.complete(), 23 | [''] = cmp.mapping.abort(), 24 | [''] = cmp.mapping.confirm({ select = true }), 25 | [""] = cmp.mapping(function(fallback) 26 | if cmp.visible() then 27 | cmp.select_next_item() 28 | elseif luasnip.expand_or_jumpable() then 29 | luasnip.expand_or_jump() 30 | elseif has_words_before() then 31 | cmp.complete() 32 | else 33 | fallback() 34 | end 35 | end, { "i", "s" }), 36 | 37 | [""] = cmp.mapping(function(fallback) 38 | if cmp.visible() then 39 | cmp.select_prev_item() 40 | elseif luasnip.jumpable(-1) then 41 | luasnip.jump(-1) 42 | else 43 | fallback() 44 | end 45 | end, { "i", "s" }), 46 | 47 | }), 48 | sources = cmp.config.sources({ 49 | { name = 'nvim_lsp' }, 50 | { name = 'luasnip' }, 51 | { name = 'path' }, 52 | { name = 'buffer' }, 53 | }) 54 | }) 55 | 56 | cmp.setup.cmdline('/', { 57 | mapping = cmp.mapping.preset.cmdline(), 58 | sources = { 59 | { name = 'buffer' }, 60 | { name = 'luasnip' } 61 | } 62 | }) 63 | 64 | -- cmp.setup.cmdline(':', { 65 | -- mapping = cmp.mapping.preset.cmdline(), 66 | -- sources = cmp.config.sources({ 67 | -- { name = 'path' } 68 | -- }, { 69 | -- { name = 'cmdline' } 70 | -- }) 71 | -- }) 72 | 73 | local capabilities = require('cmp_nvim_lsp').default_capabilities() 74 | require('lspconfig')['gopls'].setup { 75 | capabilities = capabilities 76 | } 77 | 78 | -------------------------------------------------------------------------------- /nvim/lua/dapx.lua: -------------------------------------------------------------------------------- 1 | local dap = require 'dap' 2 | local dapui = require 'dapui' 3 | 4 | dap.set_log_level('INFO') 5 | 6 | dap.configurations.go = { 7 | { 8 | type = "go", 9 | name = "Debug", 10 | request = "launch", 11 | program = "${file}", 12 | }, 13 | } 14 | 15 | dap.adapters.go = { 16 | type = "server", 17 | port = "${port}", 18 | executable = { 19 | command = 'dlv', 20 | args = { "dap", "-l", "127.0.0.1:${port}" }, 21 | }, 22 | } 23 | 24 | require 'dap-go'.setup { 25 | dap_configurations = { 26 | { 27 | type = "go", 28 | name = "Debug (main.go)", 29 | request = "launch", 30 | program = "${workspaceFolderBasename}/cmd/main.go", 31 | }, 32 | { 33 | type = "go", 34 | name = "Debug (Build Flags & Arguments)", 35 | request = "launch", 36 | program = "${file}", 37 | args = require("dap-go").get_arguments, 38 | buildFlags = require("dap-go").get_build_flags, 39 | }, 40 | }, 41 | } 42 | 43 | dapui.setup { 44 | controls = { 45 | element = "repl", 46 | enabled = true, 47 | icons = { 48 | disconnect = "■", 49 | pause = "", 50 | play = "▶", 51 | run_last = "≪", 52 | step_back = "←", 53 | step_into = "↓", 54 | step_out = "↑", 55 | step_over = "→", 56 | terminate = "✗" 57 | } 58 | }, 59 | expand_lines = false, 60 | icons = { expanded = "▾", collapsed = "▸" }, 61 | mappings = { 62 | open = "o", 63 | remove = "d", 64 | edit = "e", 65 | repl = "r", 66 | toggle = "t", 67 | }, 68 | layouts = { 69 | { 70 | elements = { 71 | "scopes", 72 | "repl", 73 | }, 74 | size = 0.3, 75 | position = "bottom" 76 | }, 77 | { 78 | elements = { 79 | "breakpoints" 80 | }, 81 | size = 0.1, 82 | position = "left", 83 | }, 84 | }, 85 | floating = { 86 | max_height = nil, 87 | max_width = nil, 88 | border = "single", 89 | mappings = { 90 | close = { "q", "" }, 91 | }, 92 | }, 93 | windows = { indent = 1 }, 94 | render = { 95 | max_type_length = nil, 96 | }, 97 | } 98 | 99 | dap.listeners.before.attach.dapui_config = function() 100 | dapui.open() 101 | end 102 | dap.listeners.before.launch.dapui_config = function() 103 | dapui.open() 104 | end 105 | --dap.listeners.before.event_terminated.dapui_config = function() 106 | -- dapui.close() 107 | --end 108 | dap.listeners.before.event_exited.dapui_config = function() 109 | dapui.close() 110 | end 111 | 112 | vim.fn.sign_define('DapBreakpoint', {text = '•'}) 113 | 114 | require 'dapui.config.highlights'.setup() 115 | -------------------------------------------------------------------------------- /nvim/lua/fuzzy/buffers.lua: -------------------------------------------------------------------------------- 1 | local fn = vim.fn 2 | local cmd = vim.cmd 3 | local M = {} 4 | 5 | function M.fzy_buffers() 6 | local buffers = {} 7 | 8 | -- list of buffers 9 | local nbuf = fn.range(1, fn.bufnr('$')) 10 | 11 | -- filter out buffers that don't have 'buflisted' set 12 | for _, n in ipairs(nbuf) do 13 | if fn.buflisted(n) then 14 | buffers[fn.bufname(n)] = n 15 | end 16 | end 17 | 18 | -- write buffer names to file to feed to fzy 19 | local buffile = fn.tempname() 20 | local f = io.open(buffile, "a") 21 | for b, _ in pairs(buffers) do 22 | f:write(b, '\n') 23 | end 24 | f:close() 25 | 26 | local fzy_cmd = { 27 | 'fzy -p "buf > " ', 28 | '< ' .. buffile, 29 | } 30 | 31 | require('fzy/fzy').fzy_search(table.concat(fzy_cmd), function(stdout) 32 | -- strip '\n' 33 | local selected, _ = stdout:gsub('\n', '') 34 | cmd('bd!') 35 | 36 | cmd('buffer ' .. buffers[ selected ]) 37 | -- housekeeping 38 | os.remove(buffile) 39 | end 40 | ) 41 | 42 | end 43 | 44 | return M 45 | -------------------------------------------------------------------------------- /nvim/lua/fuzzy/edit.lua: -------------------------------------------------------------------------------- 1 | local fn = vim.fn 2 | local cmd = vim.cmd 3 | local M = {} 4 | 5 | function M.fuzzy_edit(fuzzy_cmd) 6 | fuzzy_cmd = { 7 | ls_cmd, 8 | '| zf', 9 | } 10 | 11 | require('fuzzy/fuzzy').fuzzy_search(table.concat(fuzzy_cmd), function(stdout) 12 | -- strip '\n' 13 | local selected, _ = stdout:gsub('\n', '') 14 | cmd('bd!') 15 | cmd('e ' .. selected) 16 | end 17 | ) 18 | end 19 | 20 | return M 21 | -------------------------------------------------------------------------------- /nvim/lua/fuzzy/fuzzy.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local api = vim.api 3 | local o = vim.o 4 | local fn = vim.fn 5 | 6 | function M.fuzzy_search(cmd, exit_fn) 7 | local width = o.columns - 4 8 | local height = 11 9 | if (o.columns >= 85) then 10 | width = 80 11 | end 12 | 13 | local buf = api.nvim_create_buf(false, true) 14 | api.nvim_buf_set_option(buf, 'bufhidden', 'wipe') 15 | api.nvim_buf_set_option(buf, 'modifiable', true) 16 | 17 | api.nvim_open_win( 18 | buf, 19 | true, 20 | { 21 | relative = 'editor', 22 | style = 'minimal', 23 | noautocmd = true, 24 | border = 'rounded', 25 | width = width, 26 | height = height, 27 | col = math.min((o.columns - width) / 2), 28 | row = math.min((o.lines - height) / 2 - 1), 29 | } 30 | ) 31 | local file = vim.fn.tempname() 32 | api.nvim_command('startinsert!') 33 | 34 | vim.fn.termopen(cmd .. ' > ' .. file, {on_exit = function() 35 | local f = io.open(file, 'r') 36 | local stdout = f:read('*all') 37 | exit_fn(stdout) 38 | f:close() 39 | os.remove(file) 40 | end}) 41 | end 42 | return M 43 | -------------------------------------------------------------------------------- /nvim/lua/fuzzy/jump.lua: -------------------------------------------------------------------------------- 1 | local fn = vim.fn 2 | local cmd = vim.cmd 3 | local M = {} 4 | 5 | local function get_line_nr(s) 6 | for c in s:gmatch('%d+%s') do 7 | c = string.gsub(c, '%s', '') 8 | return tonumber(c) 9 | end 10 | end 11 | 12 | local function annotated_input() 13 | local lines = {} 14 | 15 | -- index each line in the current buffer 16 | -- for jumping to 17 | -- 18 | for nr = 1, fn.line('$') do 19 | table.insert(lines, fn.getline(nr)) 20 | end 21 | 22 | local outfile = fn.tempname() 23 | local f = io.open(outfile, 'a') 24 | for n, l in pairs(lines) do 25 | f:write(n .. '\t' .. l, '\n') 26 | end 27 | f:close() 28 | 29 | return outfile, lines 30 | end 31 | 32 | function M.fzy_jmp() 33 | local idxfile, lines = annotated_input() 34 | 35 | fzy_cmd = { 36 | 'fzy -p "jmp > " ', 37 | '< ' .. idxfile, 38 | } 39 | 40 | require('fzy/fzy').fzy_search(table.concat(fzy_cmd), function(stdout) 41 | -- strip '\n' 42 | local selected, _ = stdout:gsub('\n', '') 43 | cmd('bd!') 44 | 45 | -- jump to line 46 | cmd(':' .. get_line_nr(selected)) 47 | -- housekeeping 48 | os.remove(idxfile) 49 | end 50 | ) 51 | 52 | end 53 | return M 54 | -------------------------------------------------------------------------------- /nvim/lua/fzy/buffers.lua: -------------------------------------------------------------------------------- 1 | local fn = vim.fn 2 | local cmd = vim.cmd 3 | local M = {} 4 | 5 | local function normalize_path(path) 6 | return vim.fn.fnamemodify(vim.fn.expand(path), ':p:~:.') 7 | end 8 | 9 | function M.fzy_buffers(exclude) 10 | local buffers = {} 11 | 12 | -- list of buffers 13 | local nbuf = fn.range(1, fn.bufnr('$')) 14 | 15 | -- filter out buffers that don't have 'buflisted' set 16 | for _, n in ipairs(nbuf) do 17 | if fn.buflisted(n) then 18 | buffers[fn.bufname(n)] = n 19 | end 20 | end 21 | 22 | -- write buffer names to file to feed to fzy 23 | local buffile = fn.tempname() 24 | local f = io.open(buffile, "a") 25 | for b, _ in pairs(buffers) do 26 | local path = normalize_path(b) 27 | if not string.match(path, exclude) then 28 | f:write(path, '\n') 29 | end 30 | end 31 | f:close() 32 | 33 | local fzy_cmd = { 34 | 'fzy -p "buf > " ', 35 | '< ' .. buffile, 36 | } 37 | 38 | require('fzy/fzy').fzy_search(table.concat(fzy_cmd), function(stdout) 39 | -- strip '\n' 40 | local selected, _ = stdout:gsub('\n', '') 41 | cmd('bd!') 42 | 43 | cmd('buffer ' .. buffers[ selected ]) 44 | -- housekeeping 45 | os.remove(buffile) 46 | end 47 | ) 48 | 49 | end 50 | 51 | return M 52 | -------------------------------------------------------------------------------- /nvim/lua/fzy/edit.lua: -------------------------------------------------------------------------------- 1 | local fn = vim.fn 2 | local cmd = vim.cmd 3 | local M = {} 4 | 5 | function M.fzy_edit(ls_cmd) 6 | fzy_cmd = { 7 | ls_cmd, 8 | '| zf', 9 | } 10 | 11 | require('fzy/fzy').fzy_search(table.concat(fzy_cmd), function(stdout) 12 | -- strip '\n' 13 | local selected, _ = stdout:gsub('\n', '') 14 | cmd('bd!') 15 | cmd('e ' .. selected) 16 | end 17 | ) 18 | end 19 | 20 | return M 21 | -------------------------------------------------------------------------------- /nvim/lua/fzy/fzy.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local api = vim.api 3 | local o = vim.o 4 | local fn = vim.fn 5 | 6 | function M.fzy_search(cmd, exit_fn) 7 | local width = o.columns - 4 8 | local height = 11 9 | if (o.columns >= 85) then 10 | width = 80 11 | end 12 | 13 | buf = api.nvim_create_buf(false, true) 14 | api.nvim_buf_set_option(buf, 'bufhidden', 'wipe') 15 | api.nvim_buf_set_option(buf, 'modifiable', true) 16 | 17 | api.nvim_open_win( 18 | buf, 19 | true, 20 | { 21 | relative = 'editor', 22 | style = 'minimal', 23 | noautocmd = true, 24 | border = 'rounded', 25 | width = width, 26 | height = height, 27 | col = math.min((o.columns - width) / 2), 28 | row = math.min((o.lines - height) / 2 - 1), 29 | } 30 | ) 31 | local file = vim.fn.tempname() 32 | api.nvim_command('startinsert!') 33 | 34 | vim.fn.termopen(cmd .. ' > ' .. file, {on_exit = function() 35 | local f = io.open(file, 'r') 36 | stdout = f:read('*all') 37 | exit_fn(stdout) 38 | f:close() 39 | os.remove(file) 40 | end}) 41 | end 42 | return M 43 | -------------------------------------------------------------------------------- /nvim/lua/fzy/jump.lua: -------------------------------------------------------------------------------- 1 | local fn = vim.fn 2 | local cmd = vim.cmd 3 | local M = {} 4 | 5 | local function get_line_nr(s) 6 | for c in s:gmatch('%d+%s') do 7 | c = string.gsub(c, '%s', '') 8 | return tonumber(c) 9 | end 10 | end 11 | 12 | local function annotated_input() 13 | local lines = {} 14 | 15 | -- index each line in the current buffer 16 | -- for jumping to 17 | -- 18 | for nr = 1, fn.line('$') do 19 | table.insert(lines, fn.getline(nr)) 20 | end 21 | 22 | local outfile = fn.tempname() 23 | local f = io.open(outfile, 'a') 24 | for n, l in pairs(lines) do 25 | f:write(n .. '\t' .. l, '\n') 26 | end 27 | f:close() 28 | 29 | return outfile, lines 30 | end 31 | 32 | function M.fzy_jmp() 33 | local idxfile, lines = annotated_input() 34 | 35 | fzy_cmd = { 36 | 'fzy -p "jmp > " ', 37 | '< ' .. idxfile, 38 | } 39 | 40 | require('fzy/fzy').fzy_search(table.concat(fzy_cmd), function(stdout) 41 | -- strip '\n' 42 | local selected, _ = stdout:gsub('\n', '') 43 | cmd('bd!') 44 | 45 | -- jump to line 46 | cmd(':' .. get_line_nr(selected)) 47 | -- housekeeping 48 | os.remove(idxfile) 49 | end 50 | ) 51 | 52 | end 53 | return M 54 | -------------------------------------------------------------------------------- /nvim/lua/lsp/c.lua: -------------------------------------------------------------------------------- 1 | require('lspconfig').ccls.setup { 2 | init_options = { 3 | cache = { 4 | directory = ".ccls-cache"; 5 | }; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /nvim/lua/lsp/config.lua: -------------------------------------------------------------------------------- 1 | vim.diagnostic.config({ 2 | virtual_text = false, 3 | signs = true, 4 | underline = true, 5 | update_in_insert = true, 6 | severity_sort = false, 7 | }) 8 | 9 | -- hover for diagnostic 10 | vim.opt.updatetime = 250 11 | vim.cmd [[autocmd! CursorHold,CursorHoldI * lua vim.diagnostic.open_float(bor, {focus=false, border='rounded'})]] 12 | 13 | vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { 14 | border = "rounded", 15 | }) 16 | -------------------------------------------------------------------------------- /nvim/lua/lsp/copilot.lua: -------------------------------------------------------------------------------- 1 | require 'copilot'.setup{ 2 | suggestion = { 3 | enabled = true, 4 | auto_trigger = true, 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /nvim/lua/lsp/go.lua: -------------------------------------------------------------------------------- 1 | require('lspconfig').gopls.setup { 2 | filetypes = { 'go', 'gomod' }, 3 | gopls = { 4 | experimentalPostfixCompletions = true, 5 | analyses = { 6 | unusedparams = true, 7 | shadow = true, 8 | }, 9 | staticcheck = true, 10 | buildFlags = {"-tags=cgo"}, 11 | }, 12 | on_attach = require('maps').on_attach, 13 | } 14 | -------------------------------------------------------------------------------- /nvim/lua/lsp/js.lua: -------------------------------------------------------------------------------- 1 | require 'lspconfig'.eslint.setup{} 2 | -- require 'lspconfig'.tsserver.setup{} 3 | -------------------------------------------------------------------------------- /nvim/lua/lsp/json.lua: -------------------------------------------------------------------------------- 1 | require'lspconfig'.jsonls.setup{} 2 | -------------------------------------------------------------------------------- /nvim/lua/lsp/lua.lua: -------------------------------------------------------------------------------- 1 | local runtime_path = vim.split(package.path, ';') 2 | table.insert(runtime_path, "lua/?.lua") 3 | table.insert(runtime_path, "lua/?/init.lua") 4 | 5 | require'lspconfig'.lua_ls.setup { 6 | settings = { 7 | Lua = { 8 | runtime = { 9 | version = 'LuaJIT', 10 | path = runtime_path, 11 | }, 12 | diagnostics = { 13 | globals = {'vim'}, 14 | }, 15 | workspace = { 16 | library = vim.api.nvim_get_runtime_file("", true), 17 | }, 18 | telemetry = { 19 | enable = false, 20 | }, 21 | }, 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /nvim/lua/lsp/python.lua: -------------------------------------------------------------------------------- 1 | require('lspconfig').pyright.setup{ on_attach = require('maps').on_attach } 2 | -------------------------------------------------------------------------------- /nvim/lua/lsp/rust.lua: -------------------------------------------------------------------------------- 1 | require'lspconfig'.rust_analyzer.setup{} 2 | -------------------------------------------------------------------------------- /nvim/lua/lsp/yaml.lua: -------------------------------------------------------------------------------- 1 | require('lspconfig').yamlls.setup{ on_attach = require('maps').on_attach } 2 | -------------------------------------------------------------------------------- /nvim/lua/maps.lua: -------------------------------------------------------------------------------- 1 | local cmd = vim.cmd 2 | local map = vim.keymap.set 3 | local dap = require 'dap' 4 | local treeapi = require 'nvim-tree.api' 5 | local u = require 'utils' 6 | local M = {} 7 | 8 | -- map the leader key 9 | map('n', '', '', {}) 10 | vim.g.mapleader = ' ' 11 | 12 | 13 | local options = { silent = true } 14 | map('n', '', ':nohlsearch', options) 15 | map('n', 'n', ':bnext', options) 16 | map('n', 'p', ':bprev', options) 17 | 18 | -- search matches in the middle of the window 19 | map('n', 'n', 'nzzzv', options) 20 | map('n', 'N', 'Nzzzv', options) 21 | 22 | -- remain in visual after indenting 23 | map('v', '<', '', '>gv', options) 25 | 26 | -- Not an editor command: Wqa 27 | cmd(':command! WQ wq') 28 | cmd(':command! WQ wq') 29 | cmd(':command! Wq wq') 30 | cmd(':command! Wqa wqa') 31 | cmd(':command! W w') 32 | cmd(':command! Q q') 33 | 34 | local function fzy_ignore(patterns) 35 | local pattern_cmd = {} 36 | for _, p in ipairs(patterns) do 37 | table.insert(pattern_cmd, string.format("-E '%s'", p)) 38 | end 39 | 40 | return table.concat(pattern_cmd, ' ') 41 | end 42 | 43 | -- fzy mappings 44 | if vim.fn.executable('fzy') then 45 | _G.fzy_edit = require('fzy.edit').fzy_edit 46 | map( 47 | '', 48 | 'e', 49 | string.format( 50 | ':call v:lua.fzy_edit("fd -t f -t l")', 51 | fzy_ignore{ 52 | '*.git/*', 53 | '*node_modules*', 54 | '*.pyc', 55 | '*migrations*', 56 | '*result*', 57 | '*.direnv/*', 58 | } 59 | ), 60 | { noremap=true, silent=true } 61 | ) 62 | 63 | _G.fzy_buffers = require('fzy.buffers').fzy_buffers 64 | map('', 65 | 'b', 66 | ':call v:lua.fzy_buffers("NvimTree_1")', 67 | { noremap=true, silent=true } 68 | ) 69 | 70 | _G.fzy_jmp = require('fzy.jump').fzy_jmp 71 | map('', 72 | 'f', 73 | ':call v:lua.fzy_jmp()', 74 | { noremap=true, silent=true} 75 | ) 76 | else 77 | print('fzy not in PATH!') 78 | end 79 | 80 | -- lspconfig 81 | function M.on_attach(client, bufnr) 82 | local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end 83 | buf_set_keymap('n', 'gD', 'lua vim.lsp.buf.declaration()', options) 84 | buf_set_keymap('n', 'gd', 'lua vim.lsp.buf.definition()', options) 85 | buf_set_keymap('n', 'ga', 'lua vim.lsp.buf.code_action()', options) 86 | buf_set_keymap('n', 'K', 'lua vim.lsp.buf.hover()', options) 87 | buf_set_keymap('n', 'L', 'lua vim.lsp.buf.signature_help()', options) 88 | buf_set_keymap('n', 'gi', 'lua vim.lsp.buf.implementation()', options) 89 | buf_set_keymap('n', '[d', 'lua vim.diagnostic.goto_prev()', options) 90 | buf_set_keymap('n', ']d', 'lua vim.diagnostic.goto_next()', options) 91 | buf_set_keymap('n', 'rn', 'lua vim.lsp.buf.rename()', options) 92 | map('n', 'ff', function() 93 | vim.lsp.buf.format { async = true } 94 | end) 95 | end 96 | 97 | -- vim.api.nvim_exec([[ 98 | -- " Use and to navigate through popup menu 99 | -- inoremap pumvisible() ? "\" : "\" 100 | -- inoremap pumvisible() ? "\" : "\" 101 | -- 102 | -- ]], false) 103 | 104 | -- abbreviations 105 | local star = '★' 106 | local stars = {} 107 | for n = 1, 5 108 | do 109 | table.insert(stars, star) 110 | u.iabbrev(n .. '*', table.concat(stars)) 111 | end 112 | 113 | 114 | -- dap 115 | -- Start debugging session 116 | map("n", "ds", function() 117 | dap.continue() 118 | require 'dapui'.open() 119 | vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("=", false, true, true), "n", false) -- Spaces buffers evenly 120 | end) 121 | 122 | -- Set breakpoints, get variable values, step into/out of functions, etc. 123 | map("n", "dl", require("dap.ui.widgets").hover) 124 | map("n", "dc", dap.continue) 125 | map("n", "db", dap.toggle_breakpoint) 126 | map("n", "dn", dap.step_over) 127 | map("n", "di", dap.step_into) 128 | map("n", "do", dap.step_out) 129 | map("n", "dC", dap.clear_breakpoints) 130 | 131 | -- Close debugger and clear breakpoints 132 | map("n", "de", function() 133 | dap.clear_breakpoints() 134 | require 'dapui'.close() 135 | dap.terminate() 136 | vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("=", false, true, true), "n", false) 137 | end) 138 | 139 | 140 | local function toggle_tree() 141 | treeapi.tree.toggle({ find_file = true }) 142 | end 143 | 144 | -- nvim-tree 145 | map('n', 'tt', toggle_tree) 146 | map('n', 'tf', treeapi.tree.focus) 147 | 148 | return M 149 | -------------------------------------------------------------------------------- /nvim/lua/settings.lua: -------------------------------------------------------------------------------- 1 | local o = vim.opt 2 | local autocmd = vim.api.nvim_create_autocmd 3 | local g = vim.g 4 | local cmd = vim.cmd 5 | 6 | -- global options 7 | o.swapfile = true 8 | o.dir = '/tmp' 9 | o.smartcase = true 10 | o.laststatus = 2 11 | o.hlsearch = true 12 | o.incsearch = true 13 | o.ignorecase = true 14 | o.scrolloff = 12 15 | o.timeoutlen = 3000 16 | o.ttimeoutlen = 100 17 | o.undodir = '~/.cache/nvim/undodir' 18 | o.foldenable = false 19 | o.conceallevel = 2 20 | o.mouse = 'a' 21 | o.wildmenu = true 22 | o.tabstop = 4 23 | o.shiftwidth = 4 24 | o.softtabstop = 4 25 | o.showmode = true 26 | o.cursorline = false 27 | o.listchars='tab:│ ,nbsp:␣,trail:·,extends:>,precedes:<' 28 | o.hidden = true 29 | o.completeopt = { 'menuone', 'noselect', 'noinsert' } 30 | o.formatoptions:append('c') 31 | o.signcolumn = 'yes:2' 32 | o.wildignore = [[ 33 | .git,.hg,.svn 34 | *.aux,*.out,*.toc 35 | *.o,*.obj,*.exe,*.dll,*.manifest,*.rbc,*.class 36 | *.ai,*.bmp,*.gif,*.ico,*.jpg,*.jpeg,*.png,*.psd,*.webp 37 | *.avi,*.divx,*.mp4,*.webm,*.mov,*.m2ts,*.mkv,*.vob,*.mpg,*.mpeg 38 | *.mp3,*.oga,*.ogg,*.wav,*.flac 39 | *.eot,*.otf,*.ttf,*.woff 40 | *.doc,*.pdf,*.cbr,*.cbz 41 | *.zip,*.tar.gz,*.tar.bz2,*.rar,*.tar.xz,*.kgb 42 | *.swp,.lock,.DS_Store,._* 43 | ]] 44 | 45 | cmd('syntax on') 46 | cmd('colorscheme plain') 47 | autocmd('TextYankPost', { 48 | pattern = '*', 49 | callback = function() 50 | vim.highlight.on_yank{timeout=200} 51 | end, 52 | }) 53 | 54 | o.background = 'light' 55 | o.termguicolors = true 56 | 57 | -- gitgutter options 58 | g.gitgutter_override_sign_column_highlight = 0 59 | g.gitgutter_sign_added = '+' 60 | g.gitgutter_sign_modified = '±' 61 | g.gitgutter_sign_removed = '-' 62 | g.gitgutter_sign_removed_first_line = '^' 63 | g.gitgutter_sign_modified_removed = '#' 64 | 65 | -- window-local options 66 | o.number = false 67 | o.list = true 68 | o.wrap = false 69 | 70 | -- buffer-local options 71 | o.expandtab = true 72 | 73 | -- set statusline 74 | stl = require('statusline.line') 75 | o.statusline = '%!luaeval("stl.statusline()")' 76 | 77 | -- u.create_augroup({ 78 | -- { 'BufRead,BufNewFile', '/tmp/nail-*', 'setlocal', 'ft=mail' }, 79 | -- { 'BufRead,BufNewFile', '*s-nail-*', 'setlocal', 'ft=mail' }, 80 | -- }, 'ftmail') 81 | 82 | -- restore cursor 83 | autocmd('BufReadPost', { 84 | pattern = '*', 85 | callback = function() 86 | vim.fn.setpos(".", vim.fn.getpos("'\"")) 87 | end, 88 | }) 89 | 90 | -- unknown files are 'text' 91 | autocmd({'BufNewFile', 'BufRead'}, { 92 | pattern = '*', 93 | callback = function() 94 | if vim.bo.filetype == "" then 95 | vim.bo.filetype = 'text' 96 | end 97 | end, 98 | }) 99 | 100 | -- keymap files are dts 101 | autocmd({'BufEnter','BufNewFile','BufRead'}, { 102 | pattern = '*.keymap', 103 | callback = function() 104 | vim.bo.filetype = 'dts' 105 | end 106 | }) 107 | 108 | -- vim-textobj-quote only in ~/docs/writing 109 | autocmd({'BufEnter','BufNewFile','BufRead'}, { 110 | pattern = '*.md', 111 | callback = function() 112 | local cwd = vim.fn.expand('%:p') 113 | if cwd:find('/home/icy/docs/writing', 1, true) == 1 then 114 | vim.fn['textobj#quote#init']() 115 | vim.fn['pencil#init']({wrap = 'soft'}) 116 | vim.keymap.set('i', '--', '—', {silent = true}) 117 | vim.opt.breakindent = false 118 | vim.opt.shiftwidth = 4 119 | vim.opt.tabstop = 4 120 | end 121 | end 122 | }) 123 | 124 | -- mdx files are markdown 125 | autocmd({'BufEnter','BufNewFile','BufRead'}, { 126 | pattern = '*.mdx', 127 | callback = function() 128 | vim.bo.filetype = 'markdown' 129 | end 130 | }) 131 | 132 | -- filetype.nvim 133 | g.do_filetype_lua = 1 134 | g.did_load_filetypes = 0 135 | 136 | -- disable built-in plugins 137 | local disabled_built_ins = { 138 | 'gzip', 139 | 'shada_plugin', 140 | 'tarPlugin', 141 | 'tar', 142 | 'zipPlugin', 143 | 'zip', 144 | } 145 | 146 | for i, _ in ipairs(disabled_built_ins) do 147 | g['loaded_' .. disabled_built_ins[i]] = 1 148 | end 149 | 150 | -- tmp 151 | vim.g.gui_font_face = 'Noto Serif' 152 | -------------------------------------------------------------------------------- /nvim/lua/statusline/git.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local sep = package.config:sub(1,1) 4 | 5 | local function find_git_dir() 6 | local file_dir = vim.fn.expand('%:p:h') .. ';' 7 | local git_dir = vim.fn.finddir('.git', file_dir) 8 | if #git_dir > 0 then 9 | M.in_git = true 10 | end 11 | return git_dir 12 | end 13 | 14 | local function get_git_head(head_file) 15 | local f_head = io.open(head_file) 16 | if f_head then 17 | local HEAD = f_head:read() 18 | f_head:close() 19 | local branch = HEAD:match('ref: refs/heads/(.+)$') 20 | if branch then M.git_branch = branch 21 | else M.git_branch = HEAD:sub(1,7) end 22 | end 23 | return nil 24 | end 25 | 26 | -- event watcher to watch head file 27 | local file_changed = vim.loop.new_fs_event() 28 | local function watch_head() 29 | file_changed:stop() 30 | local git_dir = find_git_dir() 31 | if #git_dir > 0 then 32 | local head_file = git_dir..sep..'HEAD' 33 | get_git_head(head_file) 34 | file_changed:start(head_file, {}, vim.schedule_wrap(function() 35 | -- reset file-watch 36 | watch_head() 37 | end)) 38 | else 39 | M.git_branch = '' 40 | end 41 | end 42 | 43 | watch_head() 44 | 45 | return M 46 | -------------------------------------------------------------------------------- /nvim/lua/statusline/line.lua: -------------------------------------------------------------------------------- 1 | local git = require('statusline.git') 2 | local vd = require('vim.diagnostic') 3 | local M = {} 4 | 5 | local function diagnostic_highlight(diagnostics) 6 | local severity = { 7 | E = diagnostics[vd.severity.E], 8 | W = diagnostics[vd.severity.W], 9 | I = diagnostics[vd.severity.I], 10 | H = diagnostics[vd.severity.N], 11 | } 12 | local highlight = { 13 | E = '%#LineError#', 14 | W = '%#LineWarning#', 15 | I = '%#LineInfo#', 16 | H = '%#LineHint#', 17 | } 18 | local stl = {} 19 | for k, v in pairs(severity) do 20 | if v > 0 then 21 | table.insert(stl, ' '..highlight[k]..k..v) 22 | end 23 | end 24 | return table.concat(stl) 25 | end 26 | 27 | function M.statusline() 28 | local stl = {} 29 | if vim.bo.filetype ~= 'NvimTree' then 30 | stl = {''} 31 | end 32 | 33 | local diagnostics = vd.count(0) 34 | 35 | stl = { 36 | '%#LinePrimaryBlock#', 37 | '%f', 38 | '%#LineBlanks#', 39 | '%m', 40 | --'%#LineSecondaryBlock#', 41 | --' '..git.git_branch, 42 | '%=', 43 | diagnostic_highlight(diagnostics)..' ', 44 | '%#LineBlanks#', 45 | '%#LineSecondaryBlock#', 46 | '%l,%c ', 47 | '%#LinePrimaryBlock#', 48 | '%{&filetype}', 49 | } 50 | return table.concat(stl) 51 | end 52 | 53 | return M 54 | -------------------------------------------------------------------------------- /nvim/lua/tree.lua: -------------------------------------------------------------------------------- 1 | -- disable netrw at the very start of your init.lua 2 | vim.g.loaded_netrw = 1 3 | vim.g.loaded_netrwPlugin = 1 4 | 5 | -- empty setup using defaults 6 | require('nvim-tree').setup{ 7 | sort = { 8 | sorter = 'case_sensitive', 9 | }, 10 | renderer = { 11 | icons = { 12 | show = { 13 | file = false, 14 | folder = false, 15 | folder_arrow = false, 16 | git = true, 17 | modified = true, 18 | diagnostics = true, 19 | bookmarks = false, 20 | }, 21 | glyphs = { 22 | symlink = "L", 23 | git = { 24 | unstaged = "M", 25 | staged = "A", 26 | unmerged = "", 27 | renamed = "→", 28 | untracked = "?", 29 | deleted = "D", 30 | ignored = "", 31 | }, 32 | }, 33 | }, 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /nvim/lua/treesitter.lua: -------------------------------------------------------------------------------- 1 | require 'nvim-treesitter.configs'.setup { 2 | highlight = { 3 | enable = true, 4 | }, 5 | indent = { 6 | enable = true, 7 | }, 8 | textobjects = { 9 | select = { 10 | enable = true, 11 | lookahead = true, 12 | keymaps = { 13 | ["af"] = "@function.outer", 14 | ["if"] = "@function.inner", 15 | ["ac"] = "@class.outer", 16 | ["ic"] = "@class.inner", 17 | }, 18 | }, 19 | move = { 20 | enable = true, 21 | set_jumps = true, 22 | goto_next_start = { 23 | ["]m"] = "@function.outer", 24 | ["]]"] = "@class.outer", 25 | }, 26 | goto_next_end = { 27 | ["]M"] = "@function.outer", 28 | ["]["] = "@class.outer", 29 | }, 30 | goto_previous_start = { 31 | ["[m"] = "@function.outer", 32 | ["[["] = "@class.outer", 33 | }, 34 | goto_previous_end = { 35 | ["[M"] = "@function.outer", 36 | ["[]"] = "@class.outer", 37 | }, 38 | }, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /nvim/lua/utils.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local cmd = vim.cmd 3 | 4 | function M.create_augroup(autocmds, name) 5 | cmd('augroup ' .. name) 6 | cmd('autocmd!') 7 | for _, autocmd in ipairs(autocmds) do 8 | cmd('autocmd ' .. table.concat(autocmd, ' ')) 9 | end 10 | cmd('augroup END') 11 | end 12 | 13 | function M.iabbrev(a, b) 14 | cmd(string.format('iabbrev %s %s', a, b)) 15 | end 16 | 17 | return M 18 | 19 | -------------------------------------------------------------------------------- /programs/alacritty.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , lib 4 | , ... 5 | }: 6 | let 7 | isDarwin = lib.strings.hasSuffix "darwin" pkgs.stdenv.hostPlatform.system; 8 | 9 | fontConfig = 10 | if isDarwin then { 11 | normal = { family = "SF Mono"; style = "Light"; }; 12 | bold = { family = "SF Mono"; style = "Semibold"; }; 13 | italic = { family = "SF Mono"; style = "Light Italic"; }; 14 | size = 15.0; 15 | offset.y = 13; 16 | } 17 | else { 18 | normal = { family = "Input"; style = "Regular"; }; 19 | bold = { family = "Input"; style = "Bold"; }; 20 | italic = { family = "Input"; style = "Italic"; }; 21 | size = 12.0; 22 | offset.y = 10; 23 | }; 24 | in 25 | { 26 | programs.alacritty = { 27 | enable = true; 28 | settings = { 29 | env = { 30 | TERM = "xterm-256color"; 31 | }; 32 | window = { 33 | padding.x = 10; 34 | padding.y = 10; 35 | dynamic_padding = true; 36 | decorations = "Full"; 37 | startup_mode = "Maximized"; 38 | 39 | 40 | option_as_alt = "OnlyLeft"; 41 | }; 42 | 43 | font = fontConfig; 44 | cursor.style = "Beam"; 45 | 46 | 47 | colors = { 48 | primary = { 49 | background = "0xf4f4f4"; 50 | foreground = "0x676767"; 51 | }; 52 | normal = { 53 | black = "0xf4f4f4"; 54 | red = "0xdb7070"; 55 | green = "0x7c9f4b"; 56 | yellow = "0xd69822"; 57 | blue = "0x6587bf"; 58 | magenta = "0xb870ce"; 59 | cyan = "0x509c93"; 60 | white = "0x676767"; 61 | }; 62 | bright = { 63 | black = "0xaaaaaa"; 64 | red = "0xc66666"; 65 | green = "0x6d8b42"; 66 | yellow = "0xe7e7e7"; 67 | blue = "0x8a8a8a"; 68 | magenta = "0xa262b5"; 69 | cyan = "0x43827b"; 70 | white = "0x525252"; 71 | }; 72 | }; 73 | 74 | }; 75 | }; 76 | } 77 | -------------------------------------------------------------------------------- /programs/bash.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , ... 4 | }: 5 | let 6 | awk = "${pkgs.gawk}/bin/awk"; 7 | fzy = "${pkgs.fzy}/bin/fzy"; 8 | in 9 | { 10 | programs.bash = { 11 | enable = true; 12 | historyControl = [ "erasedups" "ignoredups" "ignorespace" ]; 13 | historyFile = "\$HOME/.bash_history"; 14 | historyFileSize = 40000; 15 | historyIgnore = [ "ls" "exit" "kill" ]; 16 | historySize = 40000; 17 | 18 | shellAliases = { 19 | o = "xdg-open"; 20 | gc = "git commit -v -S"; 21 | gst = "git status --short"; 22 | ga = "git add"; 23 | gd = "git diff --minimal"; 24 | gl = "git log --oneline --decorate --graph"; 25 | k = "kubectl"; 26 | n = "z"; 27 | }; 28 | 29 | shellOptions = [ 30 | "histappend" 31 | "autocd" 32 | "globstar" 33 | "checkwinsize" 34 | "cdspell" 35 | "dirspell" 36 | "expand_aliases" 37 | "dotglob" 38 | "gnu_errfmt" 39 | "histreedit" 40 | "nocasematch" 41 | ]; 42 | 43 | sessionVariables = { 44 | 45 | EDITOR = "nvim"; 46 | MANPAGER = "nvim +Man!"; 47 | PATH = "/etc/profiles/per-user/icy/bin:$PATH:$HOME/go/bin:$HOME/bin"; 48 | CLICOLOR = "1"; 49 | LANG = "en_US.UTF-8"; 50 | 51 | }; 52 | 53 | # TODO: nixify this 54 | bashrcExtra = '' 55 | refresh_tmux() { 56 | tmux refresh-client -S 57 | } 58 | 59 | PROMPT_COMMAND=refresh_tmux 60 | PS1="\n\001\002▲\001\002 "; 61 | PS2="> " 62 | 63 | ggp() { 64 | if [[ "$1" == "-f" ]]; then 65 | git push "$(git remote show)" -f "$(git branch --show-current)" 66 | else 67 | git push "$(git remote show)" "$(git branch --show-current)" 68 | fi 69 | } 70 | 71 | gpl() { 72 | if [[ "$1" != "" ]]; then 73 | branch="$1" 74 | else 75 | branch="$(git branch --show-current)" 76 | fi 77 | git pull -r "$(git remote show)" "$branch" 78 | } 79 | 80 | gco() { 81 | [[ "$1" == "" ]] && return 1 82 | 83 | git rev-parse --verify "$1" &> /dev/null 84 | if [ $? -eq 0 ]; then 85 | git checkout "$1" 86 | else 87 | git checkout -b "$1" 88 | fi 89 | } 90 | 91 | gaf() { 92 | git status --short | grep "^ M\|^ D\|^\?\?" | fzy | awk '{ print $2 }' | xargs git add 93 | } 94 | ''; 95 | 96 | initExtra = '' 97 | [[ $(HISTTIMEFORMAT="" builtin history 1) =~ [[:digit:]]+ ]] 98 | __fzy_history__() { 99 | ch="$(fc -rl 1 | ${awk} -F'\t' '{print $2}' | ${awk} '{!seen[$0]++};END{for(i in seen) if(seen[i]==1)print i}' | ${fzy})" 100 | ch="$(echo "$ch" | ${awk} '{$1=$1;print}')" 101 | READLINE_LINE=''${ch#*$'\t'} 102 | if [[ -z "$READLINE_POINT" ]]; then 103 | echo "$READLINE_LINE" 104 | else 105 | READLINE_POINT=0x7fffffff 106 | fi 107 | } 108 | 109 | bind -m emacs-standard -x '"\C-r": __fzy_history__' 110 | 111 | complete -cf doas 112 | 113 | if command -v kubectl &> /dev/null; then 114 | source <(kubectl completion bash) 115 | complete -F __start_kubectl k 116 | fi 117 | ''; 118 | 119 | }; 120 | } 121 | -------------------------------------------------------------------------------- /programs/chromium.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , ... 4 | }: 5 | 6 | { 7 | programs.chromium = { 8 | enable = true; 9 | extensions = [ 10 | "cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin 11 | "aapbdbdomjkkjkaonfhkkikfgjllcleb" # translate 12 | "aghfnjkcakhmadgdomlmlhhaocbkloab" # just black 13 | "pobhoodpcipjmedfenaigbeloiidbflp" # minimal twitter 14 | "ennpfpdlaclocpomkiablnmbppdnlhoh" # rust search extension 15 | ]; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /programs/common.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , self 4 | , ... 5 | }: 6 | 7 | { 8 | 9 | imports = [ 10 | ./git.nix 11 | ./tmux.nix 12 | ./readline.nix 13 | ./neovim.nix 14 | ./bash.nix 15 | ./ssh.nix 16 | ./alacritty.nix 17 | ./fish.nix 18 | ./zed/default.nix 19 | ./jujutsu.nix 20 | ]; 21 | 22 | programs = { 23 | home-manager.enable = true; 24 | direnv = { 25 | enable = true; 26 | enableBashIntegration = true; 27 | nix-direnv = { 28 | enable = true; 29 | }; 30 | }; 31 | zoxide = { 32 | enable = true; 33 | enableBashIntegration = true; 34 | }; 35 | htop = { 36 | enable = true; 37 | settings.color_scheme = 1; 38 | }; 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /programs/default.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , self 4 | , ... 5 | }: 6 | 7 | { 8 | 9 | imports = [ 10 | ./firefox.nix 11 | ./common.nix 12 | ]; 13 | 14 | programs = { 15 | gpg.enable = true; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /programs/firefox.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , ... 4 | }: 5 | 6 | 7 | # XXX: Make sure to enable toolkit.legacyUserProfileCustomizations.stylesheets in about:config. 8 | { 9 | programs.firefox = { 10 | enable = true; 11 | package = pkgs.wrapFirefox pkgs.firefox-unwrapped { 12 | extraPolicies = { 13 | ExtensionSettings = { }; 14 | }; 15 | }; 16 | profiles = { 17 | icy = { 18 | isDefault = true; 19 | path = "34x366wc.default"; 20 | userChrome = '' 21 | #sidebar-box[sidebarcommand="treestyletab_piro_sakura_ne_jp-sidebar-action"] #sidebar-header { 22 | display: none; 23 | } 24 | 25 | #sidebar-header{ display: none } 26 | 27 | #main-window[tabsintitlebar="true"]:not([extradragspace="true"]) #TabsToolbar > .toolbar-items { 28 | opacity: 0; 29 | pointer-events: none; 30 | } 31 | #main-window:not([tabsintitlebar="true"]) #TabsToolbar { 32 | visibility: collapse !important; 33 | } 34 | ''; 35 | }; 36 | }; 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /programs/fish.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , ... 4 | }: 5 | 6 | { 7 | programs.fish = { 8 | enable = true; 9 | interactiveShellInit = '' 10 | nix-your-shell fish | source 11 | set fish_greeting # Disable greeting 12 | ''; 13 | functions = { 14 | # fish_prompt = '' 15 | # printf '\n\001\002▲\001\002 ' 16 | # ''; 17 | ggp = '' 18 | if test "$argv[1]" = "-f" 19 | git push (git remote show) -f (git branch --show-current) 20 | else 21 | git push (git remote show) (git branch --show-current) 22 | end 23 | ''; 24 | 25 | gpl = '' 26 | if test -n "$argv[1]" 27 | set branch $argv[1] 28 | else 29 | set branch (git branch --show-current) 30 | end 31 | git pull -r (git remote show) $branch 32 | ''; 33 | 34 | gco = '' 35 | if test -z "$argv[1]" 36 | return 1 37 | end 38 | 39 | git rev-parse --verify $argv[1] > /dev/null 2>&1 40 | if test $status -eq 0 41 | git checkout $argv[1] 42 | else 43 | git checkout -b $argv[1] 44 | end 45 | ''; 46 | }; 47 | shellAbbrs = { 48 | gc = "git commit -v -S"; 49 | gst = "git status --short"; 50 | ga = "git add"; 51 | gd = "git diff --minimal"; 52 | gl = "git log --oneline --decorate --graph"; 53 | k = "kubectl"; 54 | }; 55 | shellAliases = { 56 | n = "z"; 57 | "..." = "cd ../.."; 58 | }; 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /programs/ghostty.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , lib 4 | , ... 5 | }: 6 | 7 | { 8 | programs.ghostty = { 9 | enable = true; 10 | enableFishIntegration = true; 11 | settings = { 12 | term = "xterm-256color"; 13 | font-family = "SF Mono"; 14 | font-size = 12.0; 15 | window-padding-x = 10; 16 | window-padding-y = 10; 17 | window-padding-balance = true; 18 | window-theme = "ghostty"; 19 | theme = "icy"; 20 | adjust-cell-height = 10; 21 | }; 22 | 23 | themes = { 24 | icy = { 25 | background = "f4f4f4"; 26 | foreground = "676767"; 27 | cursor-color = "676767"; # Fallback to foreground 28 | selection-background = "aaaaaa"; 29 | selection-foreground = "525252"; 30 | palette = [ 31 | "0=f4f4f4" # Black (Normal) 32 | "1=db7070" # Red (Normal) 33 | "2=7c9f4b" # Green (Normal) 34 | "3=d69822" # Yellow (Normal) 35 | "4=6587bf" # Blue (Normal) 36 | "5=b870ce" # Magenta (Normal) 37 | "6=509c93" # Cyan (Normal) 38 | "7=676767" # White (Normal) 39 | "8=aaaaaa" # Black (Bright) 40 | "9=c66666" # Red (Bright) 41 | "10=6d8b42" # Green (Bright) 42 | "11=e7e7e7" # Yellow (Bright) 43 | "12=8a8a8a" # Blue (Bright) 44 | "13=a262b5" # Magenta (Bright) 45 | "14=43827b" # Cyan (Bright) 46 | "15=525252" # White (Bright) 47 | ]; 48 | }; 49 | }; 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /programs/git.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , ... 4 | }: 5 | 6 | { 7 | programs.git = { 8 | enable = true; 9 | ignores = [ ".envrc" ]; 10 | userEmail = "x@icyphox.sh"; 11 | userName = "Anirudh Oppiliappan"; 12 | extraConfig = { 13 | commit.verbose = true; 14 | init.defaultBranch = "master"; 15 | pull.rebase = "true"; 16 | gpg.format = "ssh"; 17 | user.signingkey = "~/.ssh/id_ed25519.pub"; 18 | 19 | url."ssh://git@github.com/".insteadOf = "https://github.com/"; 20 | url."ssh://git@git.services.upcloud.com/".insteadOf = "https://git.services.upcloud.com/"; 21 | }; 22 | includes = [ 23 | { 24 | "path" = "~/code/upcloud/gitconfig"; 25 | "condition" = "gitdir:~/code/upcloud/"; 26 | } 27 | ]; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /programs/jujutsu.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , ... 4 | }: 5 | { 6 | programs.jujutsu = { 7 | enable = true; 8 | settings = { 9 | user = { 10 | name = "Anirudh Oppiliappan"; 11 | email = "anirudh@tangled.sh"; 12 | }; 13 | ui = { 14 | # paginate = "never"; 15 | default-command = "log"; 16 | pager = "${pkgs.delta}/bin/delta"; 17 | diff.format = "git"; 18 | graph.style = "curved"; 19 | should-sign-off = true; 20 | }; 21 | signing = { 22 | behavior = "own"; 23 | backend = "ssh"; 24 | key = "~/.ssh/id_ed25519.pub"; 25 | }; 26 | 27 | colors = { 28 | commit_id = "magenta"; 29 | change_id = "cyan"; 30 | "working_copy empty" = "green"; 31 | "working_copy placeholder" = "red"; 32 | "working_copy description placeholder" = "yellow"; 33 | "working_copy empty description placeholder" = "green"; 34 | prefix = { 35 | bold = true; 36 | fg = "cyan"; 37 | }; 38 | rest = { 39 | bold = false; 40 | fg = "bright black"; 41 | }; 42 | "node elided" = "yellow"; 43 | "node working_copy" = "green"; 44 | "node conflict" = "red"; 45 | "node immutable" = "red"; 46 | "node normal" = { bold = false; }; 47 | "node" = { bold = false; }; 48 | }; 49 | git = { 50 | sign-on-push = true; 51 | write-change-id-header = true; 52 | }; 53 | aliases = { 54 | d = [ "diff" ]; 55 | l = [ "log" ]; 56 | ll = [ "log" "-r" ".." ]; 57 | tug = [ "bookmark" "move" "--from" "heads(::@- & bookmarks())" "--to" "@-" ]; 58 | }; 59 | revsets = { 60 | log = "current_work"; 61 | }; 62 | revset-aliases = { 63 | "stack()" = "ancestors(reachable(@, mutable()), 2)"; 64 | "stack(x)" = "ancestors(reachable(x, mutable()), 2)"; 65 | "stack(x, n)" = "ancestors(reachable(x, mutable()), n)"; 66 | "current_work" = "trunk()..@ | @..trunk() | trunk() | @:: | fork_point(trunk() | @)"; 67 | }; 68 | template-aliases = { 69 | "format_short_id(id)" = "id.shortest()"; 70 | "abbreviate_timestamp_suffix(s, suffix, abbr)" = '' 71 | if( 72 | s.ends_with(suffix), 73 | s.remove_suffix(suffix) ++ label("timestamp", abbr) 74 | ) 75 | ''; 76 | "abbreviate_relative_timestamp(s)" = '' 77 | coalesce( 78 | abbreviate_timestamp_suffix(s, " millisecond", "ms"), 79 | abbreviate_timestamp_suffix(s, " second", "s"), 80 | abbreviate_timestamp_suffix(s, " minute", "m"), 81 | abbreviate_timestamp_suffix(s, " hour", "h"), 82 | abbreviate_timestamp_suffix(s, " day", "d"), 83 | abbreviate_timestamp_suffix(s, " week", "w"), 84 | abbreviate_timestamp_suffix(s, " month", "mo"), 85 | abbreviate_timestamp_suffix(s, " year", "y"), 86 | s 87 | ) 88 | ''; 89 | "format_timestamp(timestamp)" = '' 90 | coalesce( 91 | if(timestamp.after("1 minute ago"), label("timestamp", "<=1m")), 92 | abbreviate_relative_timestamp(timestamp.ago().remove_suffix(' ago').remove_suffix('s')) 93 | ) 94 | ''; 95 | }; 96 | templates = { 97 | log = '' 98 | if(root, 99 | format_root_commit(self), 100 | label(if(current_working_copy, "working_copy"), 101 | concat( 102 | separate(" ", 103 | pad_end(4, format_short_change_id_with_hidden_and_divergent_info(self)), 104 | if(empty, label("empty", "(empty)")), 105 | if(description, 106 | description.first_line(), 107 | label(if(empty, "empty"), description_placeholder), 108 | ), 109 | bookmarks, 110 | tags, 111 | working_copies, 112 | if(git_head, label("git_head", "HEAD")), 113 | if(conflict, label("conflict", "conflict")), 114 | if(config("ui.show-cryptographic-signatures").as_boolean(), 115 | format_short_cryptographic_signature(signature)), 116 | format_timestamp(commit_timestamp(self)), 117 | ) ++ "\n", 118 | ), 119 | ) 120 | ) 121 | ''; 122 | log_node = '' 123 | label("node", 124 | coalesce( 125 | if(!self, label("elided", "~")), 126 | if(current_working_copy, label("working_copy", "@")), 127 | if(conflict, label("conflict", "×")), 128 | 129 | if(immutable, label("immutable", "*")), 130 | label("normal", "·") 131 | ) 132 | ) 133 | ''; 134 | draft_commit_description = '' 135 | concat( 136 | coalesce(description, default_commit_description, "\n"), 137 | if( 138 | config("ui.should-sign-off").as_boolean() && !description.contains("Signed-off-by: " ++ author.name()), 139 | "\nSigned-off-by: " ++ author.name() ++ " <" ++ author.email() ++ ">", 140 | ), 141 | surround( 142 | "\nJJ: This commit contains the following changes:\n", "", 143 | indent("JJ: ", diff.stat(72)), 144 | ), 145 | "\nJJ: ignore-rest\n", 146 | diff.git(), 147 | ) 148 | ''; 149 | }; 150 | }; 151 | }; 152 | } 153 | -------------------------------------------------------------------------------- /programs/neovim.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , self 4 | , lib 5 | , ... 6 | }: 7 | 8 | { 9 | programs.neovim = { 10 | enable = true; 11 | withNodeJs = true; 12 | vimAlias = true; 13 | withPython3 = true; 14 | extraPackages = with pkgs; [ 15 | nixpkgs-fmt 16 | gotools 17 | gopls 18 | go 19 | sumneko-lua-language-server 20 | pyright 21 | 22 | tree-sitter-grammars.tree-sitter-bash 23 | tree-sitter-grammars.tree-sitter-yaml 24 | tree-sitter-grammars.tree-sitter-go 25 | tree-sitter-grammars.tree-sitter-make 26 | tree-sitter-grammars.tree-sitter-markdown 27 | tree-sitter-grammars.tree-sitter-lua 28 | tree-sitter-grammars.tree-sitter-html 29 | tree-sitter-grammars.tree-sitter-vim 30 | tree-sitter-grammars.tree-sitter-nix 31 | tree-sitter-grammars.tree-sitter-python 32 | 33 | zf 34 | delve 35 | ]; 36 | extraConfig = '' 37 | runtime _init.lua 38 | ''; 39 | plugins = with pkgs.vimPlugins; [ 40 | packer-nvim 41 | 42 | nvim-cmp 43 | cmp-buffer 44 | cmp_luasnip 45 | cmp-nvim-lsp 46 | cmp-treesitter 47 | cmp-path 48 | 49 | nvim-lspconfig 50 | luasnip 51 | playground 52 | vim-surround 53 | targets-vim 54 | vim-gitgutter 55 | vim-rsi 56 | nvim-treesitter-textobjects 57 | conflict-marker-vim 58 | vim-pencil 59 | nvim-tree-lua 60 | 61 | nvim-dap 62 | nvim-dap-ui 63 | nvim-dap-go 64 | vim-textobj-user 65 | ]; 66 | }; 67 | } 68 | -------------------------------------------------------------------------------- /programs/readline.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , ... 4 | }: 5 | 6 | { 7 | programs.readline = { 8 | enable = true; 9 | bindings = { 10 | "\\t" = "menu-complete"; 11 | "\\e[Z" = "menu-complete-backward"; 12 | "\\C-w" = "backward-kill-word"; 13 | }; 14 | variables = { 15 | "completion-ignore-case" = "on"; 16 | "show-all-if-ambiguous" = "on"; 17 | "colored-stats" = "on"; 18 | "completion-display-width" = 4; 19 | "enable-bracketed-paste" = "on"; 20 | }; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /programs/ssh.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , ... 4 | }: 5 | 6 | { 7 | programs.ssh = { 8 | enable = true; 9 | matchBlocks = { 10 | "*" = { 11 | serverAliveInterval = 180; 12 | serverAliveCountMax = 3; 13 | identityFile = [ "~/.ssh/id_ed25519" ]; 14 | }; 15 | "github.com" = { 16 | user = "git"; 17 | hostname = "github.com"; 18 | }; 19 | }; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /programs/tmux.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , ... 4 | }: 5 | 6 | { 7 | programs.tmux = { 8 | enable = true; 9 | plugins = with pkgs; [ 10 | { 11 | plugin = tmuxPlugins.resurrect; 12 | extraConfig = "set -g @resurrect-strategy-nvim 'session'"; 13 | } 14 | ]; 15 | extraConfig = '' 16 | set -g prefix C-q 17 | set -g set-titles on 18 | set-option -g set-titles-string "#T" 19 | unbind-key C-b 20 | bind-key C-q send-prefix 21 | set -g update-environment "KEYBOARD_LAYOUT" 22 | 23 | setw -g mode-keys vi 24 | 25 | bind r source-file ~/.config/tmux/tmux.conf 26 | 27 | # set-option -g default-terminal xterm-256color-italic 28 | # set -as terminal-overrides '*:Ss=\E[%p1%d q:Se=\E[2 q' 29 | set escape-time 20 30 | 31 | set -g mouse on 32 | 33 | set -g base-index 1 34 | setw -g pane-base-index 1 35 | 36 | # pane binds 37 | bind -n M-n select-pane -D 38 | bind -n M-e select-pane -U 39 | bind -n M-y select-pane -L 40 | bind -n M-o select-pane -R 41 | bind -n M-Up resize-pane -U 5 42 | bind -n M-Down resize-pane -D 5 43 | bind -n M-Left resize-pane -L 5 44 | bind -n M-Right resize-pane -R 5 45 | 46 | # window binds 47 | bind -n C-M-y previous-window 48 | bind -n C-M-o next-window 49 | bind-key \" split-window -v -c "#{pane_current_path}" 50 | bind-key c split-window -h -c "#{pane_current_path}" 51 | bind-key v new-window -c "#{pane_current_path}" 52 | bind-key s choose-session 53 | bind-key ) swap-window -t +2 54 | bind-key ( swap-window -t -1 55 | 56 | unbind -T copy-mode MouseDragEnd1Pane 57 | bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "wl-copy" 58 | bind-key -T copy-mode-vi v send-keys -X begin-selection 59 | bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "wl-copy" 60 | bind-key -T copy-mode-vi r send-keys -X rectangle-toggle 61 | bind P paste-buffer 62 | 63 | # pop-up pane to open urls 64 | bind-key u display-popup -E "xurls" 65 | 66 | # statusline on top 67 | set-option -g status-position top 68 | 69 | # statusline hide / unhide 70 | bind -n C-down set -q status off 71 | bind -n C-up set -q status on 72 | bind P paste-buffer 73 | 74 | set-window-option -g allow-rename off 75 | 76 | set -g pane-border-style fg=colour11 77 | set -g pane-active-border-style fg=colour8 78 | 79 | set -g status-justify right 80 | set -g status-right "" 81 | set -g status-left "" 82 | set -g status-style "bg=colour0" 83 | set -ag status-style "fg=colour7" 84 | 85 | set -g window-status-current-format "#[fg=colour15] #W" 86 | set -g window-status-format "#[fg=colour8] #W" 87 | 88 | set -g status-left-length 100 89 | 90 | # dim inactive pane 91 | set -g window-style 'fg=color8,bg=default' 92 | set -g window-active-style 'fg=color7,bg=default' 93 | 94 | set -g default-terminal "xterm-256color" 95 | set -ga terminal-overrides ',xterm-256color:Tc' 96 | set -sa terminal-features ",xterm-256color:RGB" 97 | set -as terminal-overrides ',xterm*:sitm=\E[3m' 98 | 99 | set -g default-shell "/etc/profiles/per-user/icy/bin/fish" 100 | set -g default-command "/etc/profiles/per-user/icy/bin/fish" 101 | ''; 102 | }; 103 | } 104 | -------------------------------------------------------------------------------- /programs/zed/default.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, ... }: 2 | 3 | let 4 | settings = import ./settings.nix; 5 | keymap = import ./keymap.nix; 6 | in 7 | { 8 | home.file.".config/zed/themes/icy.json".source = ./themes/icy.json; 9 | home.file.".config/zed/themes/icy-dusk.json".source = ./themes/icy-dusk.json; 10 | imports = [ settings keymap ]; 11 | } 12 | -------------------------------------------------------------------------------- /programs/zed/keymap.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | let 4 | keymap = [ 5 | { 6 | context = "Dock || Terminal || Editor"; 7 | bindings = { 8 | "alt-y" = [ "workspace::ActivatePaneInDirection" "Left" ]; 9 | "alt-o" = [ "workspace::ActivatePaneInDirection" "Right" ]; 10 | "alt-e" = [ "workspace::ActivatePaneInDirection" "Up" ]; 11 | "alt-n" = [ "workspace::ActivatePaneInDirection" "Down" ]; 12 | }; 13 | } 14 | { 15 | context = "VimControl && !VimWaiting && !menu"; 16 | bindings = { 17 | "space o" = "tab_switcher::Toggle"; 18 | "space t" = "workspace::NewCenterTerminal"; 19 | "space n" = "pane::ActivateNextItem"; 20 | "space p" = "pane::ActivatePrevItem"; 21 | "space e" = "file_finder::Toggle"; 22 | "space shift-e" = "workspace::NewSearch"; 23 | "space ?" = "workspace::ToggleRightDock"; 24 | "space shift-f" = "workspace::ToggleLeftDock"; 25 | }; 26 | } 27 | { 28 | context = "Workspace"; 29 | bindings = { 30 | "ctrl-q c" = "pane::SplitRight"; 31 | "ctrl-q \"" = "pane::SplitDown"; 32 | }; 33 | } 34 | ]; 35 | 36 | keymapFile = pkgs.writeText "keymap.json" (builtins.toJSON keymap); 37 | in 38 | { 39 | home.file.".config/zed/keymap.json".source = keymapFile; 40 | } 41 | -------------------------------------------------------------------------------- /programs/zed/settings.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, ... }: 2 | 3 | let 4 | isDarwin = lib.strings.hasSuffix "darwin" pkgs.stdenv.hostPlatform.system; 5 | zedSettings = { 6 | telemetry = { 7 | diagnostics = false; 8 | metrics = false; 9 | }; 10 | features = { 11 | edit_prediction_provider = "zed"; 12 | }; 13 | edit_predictions = { 14 | mode = "subtle"; 15 | }; 16 | languages = { 17 | HTML = { 18 | format_on_save = "off"; 19 | }; 20 | }; 21 | active_pane_modifiers = { 22 | inactive_opacity = 0.8; 23 | magnification = 1.5; 24 | }; 25 | base_keymap = "VSCode"; 26 | buffer_font_size = 15; 27 | theme = { 28 | mode = "system"; 29 | light = "Icy Light"; 30 | dark = "Icy Dark"; 31 | }; 32 | show_completions_on_input = true; 33 | buffer_font_family = "SF Mono"; 34 | buffer_font_weight = 500; 35 | ui_font_family = if isDarwin then "System Font" else "Inter"; 36 | ui_font_size = 18; 37 | vim_mode = true; 38 | vim = { 39 | use_system_clipboard = "never"; 40 | }; 41 | gutter = { 42 | line_numbers = false; 43 | runnables = false; 44 | folds = false; 45 | }; 46 | terminal = { 47 | button = false; 48 | working_directory = "current_project_directory"; 49 | option_as_meta = true; 50 | env = { 51 | EDITOR = if isDarwin then "zed --wait" else "zeditor --wait"; 52 | }; 53 | shell = { 54 | program = "fish"; 55 | }; 56 | }; 57 | outline_panel = { 58 | button = false; 59 | }; 60 | project_panel = { 61 | button = false; 62 | file_icons = false; 63 | folder_icons = false; 64 | indent_size = 10; 65 | }; 66 | chat_panel = { 67 | button = false; 68 | }; 69 | collaboration_panel = { 70 | button = false; 71 | }; 72 | notification_panel = { 73 | button = false; 74 | }; 75 | assistant = { 76 | default_model = { 77 | provider = "zed.dev"; 78 | model = "claude-3-7-sonnet-latest"; 79 | }; 80 | version = "2"; 81 | enabled = true; 82 | button = false; 83 | }; 84 | scrollbar = { 85 | show = "never"; 86 | }; 87 | toolbar = { 88 | breadcrumbs = true; 89 | quick_actions = false; 90 | selections_menu = false; 91 | }; 92 | tab_bar = { 93 | show = false; 94 | }; 95 | preview_tabs = { 96 | enable = false; 97 | }; 98 | }; 99 | 100 | zedSettingsFile = pkgs.writeText "settings.json" (builtins.toJSON zedSettings); 101 | in 102 | { 103 | home.file.".config/zed/settings.json".source = zedSettingsFile; 104 | } 105 | -------------------------------------------------------------------------------- /programs/zed/themes/icy-dusk.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://zed.dev/schema/themes/v0.1.0.json", 3 | "name": "Icy Dark", 4 | "author": "Anirudh Oppiliappan (icyphox)", 5 | "themes": [ 6 | { 7 | "name": "Icy Dark", 8 | "appearance": "dark", 9 | "style": { 10 | "border": "#4a443d", 11 | "border.variant": "#4a443d", 12 | "border.focused": "#4a443d", 13 | "border.selected": "#4a443d", 14 | "border.transparent": "#100f0f", 15 | "border.disabled": "#6b635a", 16 | "elevated_surface.background": "#100f0f", 17 | "surface.background": "#100f0f", 18 | "background": "#100f0f", 19 | "element.background": "#100f0f", 20 | "element.hover": "#509c933d", 21 | "element.active": "#4a443d", 22 | "element.selected": "#4a443d", 23 | "element.disabled": "#6b635a", 24 | "drop_target.background": "#6b635a", 25 | "ghost_element.background": "#100f0f", 26 | "ghost_element.hover": "#4a443ddd", 27 | "ghost_element.active": "#4a443d", 28 | "ghost_element.selected": "#4a443d", 29 | "ghost_element.disabled": "#6b635a", 30 | "text": "#fff6e3", 31 | "text.muted": "#d3cec1", 32 | "text.placeholder": "#6b635a", 33 | "text.disabled": "#6b635a", 34 | "text.accent": "#509c93", 35 | "icon": "#fff6e3", 36 | "icon.muted": "#d3cec1", 37 | "icon.disabled": "#6b635a", 38 | "icon.placeholder": "#6b635a", 39 | "icon.accent": "#509c93", 40 | "status_bar.background": "#100f0f", 41 | "title_bar.background": "#100f0f", 42 | "toolbar.background": "#100f0f", 43 | "tab_bar.background": "#100f0f", 44 | "tab.inactive_background": "#100f0f", 45 | "tab.active_background": "#2a261f", 46 | "search.match_background": "#509c933d", 47 | "panel.background": "#100f0f", 48 | "panel.focused_border": "#509c93", 49 | "pane.focused_border": "#509c93", 50 | "scrollbar_thumb.background": "#4a443d", 51 | "scrollbar.thumb.hover_background": "#509c93", 52 | "scrollbar.thumb.border": "#100f0f", 53 | "scrollbar.track.background": "#2a261f", 54 | "scrollbar.track.border": "#100f0f", 55 | "editor.foreground": "#fff6e3", 56 | "editor.background": "#100f0f", 57 | "editor.gutter.background": "#100f0f", 58 | "editor.subheader.background": "#2a261f", 59 | "editor.active_line.background": "#2a261f", 60 | "editor.highlighted_line.background": "#2a261f", 61 | "editor.line_number": "#6b635a", 62 | "editor.active_line_number": "#d3cec1", 63 | "editor.invisible": "#6b635a", 64 | "editor.wrap_guide": "#2a261f", 65 | "editor.active_wrap_guide": "#4a443d", 66 | "editor.document_highlight.read_background": "#509c9333", 67 | "editor.document_highlight.write_background": "#509c9333", 68 | "terminal.background": "#100f0f", 69 | "terminal.foreground": "#fff6e3", 70 | "terminal.bright_foreground": "#fff9eb", 71 | "terminal.dim_foreground": "#d3cec1", 72 | "terminal.ansi.black": "#2a261f", 73 | "terminal.ansi.bright_black": "#4a443d", 74 | "terminal.ansi.dim_black": "#2a261f", 75 | "terminal.ansi.red": "#db7070", 76 | "terminal.ansi.bright_red": "#c66666", 77 | "terminal.ansi.dim_red": "#6b635a", 78 | "terminal.ansi.green": "#7c9f4b", 79 | "terminal.ansi.bright_green": "#6d8b42", 80 | "terminal.ansi.dim_green": "#6b635a", 81 | "terminal.ansi.yellow": "#d69822", 82 | "terminal.ansi.bright_yellow": "#4a443d", 83 | "terminal.ansi.dim_yellow": "#6b635a", 84 | "terminal.ansi.blue": "#509c93", 85 | "terminal.ansi.bright_blue": "#6b635a", 86 | "terminal.ansi.dim_blue": "#2a261f", 87 | "terminal.ansi.magenta": "#b870ce", 88 | "terminal.ansi.bright_magenta": "#a262b5", 89 | "terminal.ansi.dim_magenta": "#6b635a", 90 | "terminal.ansi.cyan": "#509c93", 91 | "terminal.ansi.bright_cyan": "#43827b", 92 | "terminal.ansi.dim_cyan": "#6b635a", 93 | "terminal.ansi.white": "#fff6e3", 94 | "terminal.ansi.bright_white": "#fff9eb", 95 | "terminal.ansi.dim_white": "#d3cec1", 96 | "link_text.hover": "#509c933d", 97 | "conflict": "#db7070", 98 | "conflict.background": "#db70703d", 99 | "conflict.border": "#db7070", 100 | "created": "#7c9f4b", 101 | "created.background": "#7c9f4b3d", 102 | "created.border": "#7c9f4b", 103 | "deleted": "#db7070", 104 | "deleted.background": "#db70703d", 105 | "deleted.border": "#db7070", 106 | "error": "#db7070", 107 | "error.background": "#db70703d", 108 | "error.border": "#db7070", 109 | "hidden": "#d3cec1", 110 | "hidden.background": "#100f0f", 111 | "hidden.border": "#6b635a", 112 | "hint": "#fff6e3", 113 | "hint.background": "#fff6e33d", 114 | "hint.border": "#fff6e3", 115 | "ignored": "#fff6e3", 116 | "ignored.background": "#fff6e33d", 117 | "ignored.border": "#fff6e3", 118 | "info": "#509c93", 119 | "info.background": "#509c933d", 120 | "info.border": "#509c93", 121 | "modified": "#d69822", 122 | "modified.background": "#d698223d", 123 | "modified.border": "#d69822", 124 | "predictive": "#6b635a", 125 | "predictive.background": "#6b635a3d", 126 | "predictive.border": "#6b635a", 127 | "renamed": "#509c93", 128 | "renamed.background": "#509c933d", 129 | "renamed.border": "#509c93", 130 | "success": "#7c9f4b", 131 | "success.background": "#7c9f4b3d", 132 | "success.border": "#7c9f4b", 133 | "unreachable": "#db7070", 134 | "unreachable.background": "#db70703d", 135 | "unreachable.border": "#db7070", 136 | "warning": "#d69822", 137 | "warning.background": "#d698223d", 138 | "warning.border": "#d69822", 139 | "players": [ 140 | { 141 | "cursor": "#509c93", 142 | "background": "#509c93", 143 | "selection": "#509c933d" 144 | }, 145 | { 146 | "cursor": "#b870ce", 147 | "background": "#b870ce", 148 | "selection": "#509c933d" 149 | }, 150 | { 151 | "cursor": "#db7070", 152 | "background": "#db7070", 153 | "selection": "#509c933d" 154 | }, 155 | { 156 | "cursor": "#a262b5", 157 | "background": "#a262b5", 158 | "selection": "#509c933d" 159 | }, 160 | { 161 | "cursor": "#509c93", 162 | "background": "#509c93", 163 | "selection": "#509c933d" 164 | }, 165 | { 166 | "cursor": "#43827b", 167 | "background": "#43827b", 168 | "selection": "#509c933d" 169 | }, 170 | { 171 | "cursor": "#d69822", 172 | "background": "#d69822", 173 | "selection": "#509c933d" 174 | }, 175 | { 176 | "cursor": "#7c9f4b", 177 | "background": "#7c9f4b", 178 | "selection": "#509c933d" 179 | } 180 | ], 181 | "syntax": { 182 | "attribute": { 183 | "color": "#fff6e3", 184 | "font_style": "normal", 185 | "font_weight": 400 186 | }, 187 | "boolean": { 188 | "color": "#fff6e3", 189 | "font_style": "normal", 190 | "font_weight": 600 191 | }, 192 | "comment": { 193 | "color": "#6b635a", 194 | "font_style": "italic", 195 | "font_weight": 400 196 | }, 197 | "comment.doc": { 198 | "color": "#6b635a", 199 | "font_style": "italic", 200 | "font_weight": 400 201 | }, 202 | "constant": { 203 | "color": "#fff6e3", 204 | "font_style": "normal", 205 | "font_weight": 400 206 | }, 207 | "function": { 208 | "color": "#fff6e3", 209 | "font_style": "normal", 210 | "font_weight": 400 211 | }, 212 | "keyword": { 213 | "color": "#fff6e3", 214 | "font_style": "normal", 215 | "font_weight": 600 216 | }, 217 | "number": { 218 | "color": "#fff6e3", 219 | "font_style": "normal", 220 | "font_weight": 400 221 | }, 222 | "string": { 223 | "color": "#fff6e3", 224 | "font_style": "normal", 225 | "font_weight": 400 226 | }, 227 | "variable": { 228 | "color": "#fff6e3", 229 | "font_style": "normal", 230 | "font_weight": 400 231 | }, 232 | "operator": { 233 | "color": "#fff6e3", 234 | "font_style": "normal", 235 | "font_weight": 400 236 | }, 237 | "type": { 238 | "color": "#fff6e3", 239 | "font_style": "normal", 240 | "font_weight": 400 241 | }, 242 | "punctuation": { 243 | "color": "#fff6e3", 244 | "font_style": "normal", 245 | "font_weight": 400 246 | }, 247 | "error": { 248 | "color": "#db7070", 249 | "font_style": "normal", 250 | "font_weight": 600 251 | }, 252 | "warning": { 253 | "color": "#d69822", 254 | "font_style": "normal", 255 | "font_weight": 600 256 | }, 257 | "info": { 258 | "color": "#509c93", 259 | "font_style": "normal", 260 | "font_weight": 600 261 | }, 262 | "hint": { 263 | "color": "#7c9f4b", 264 | "font_style": "normal", 265 | "font_weight": 600 266 | } 267 | } 268 | } 269 | } 270 | ] 271 | } 272 | -------------------------------------------------------------------------------- /programs/zed/themes/icy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://zed.dev/schema/themes/v0.1.0.json", 3 | "name": "Icy Light", 4 | "author": "Anirudh Oppiliappan (icyphox)", 5 | "themes": [ 6 | { 7 | "name": "Icy Light", 8 | "appearance": "light", 9 | "style": { 10 | "border": "#fceccc", 11 | "border.variant": "#fceccc", 12 | "border.focused": "#fceccc", 13 | "border.selected": "#fff9eb", 14 | "border.transparent": "#fffdf5", 15 | "border.disabled": "#776e63", 16 | "elevated_surface.background": "#fffdf5", 17 | "surface.background": "#fffdf5", 18 | "background": "#fffdf5", 19 | "element.background": "#fffdf5", 20 | "element.hover": "#8e69d53d", 21 | "element.active": "#fff9eb", 22 | "element.selected": "#fceccc", 23 | "element.disabled": "#776e63", 24 | "drop_target.background": "#776e63", 25 | "ghost_element.background": "#fffdf5", 26 | "ghost_element.hover": "#fcecccdd", 27 | "ghost_element.active": "#fceccc", 28 | "ghost_element.selected": "#fff9eb", 29 | "ghost_element.disabled": "#776e63", 30 | "text": "#4a443d", 31 | "text.muted": "#4a443d", 32 | "text.placeholder": "#4a443d", 33 | "text.disabled": "#4a443d", 34 | "text.accent": "#4a443d", 35 | "icon": "#fffdf5", 36 | "icon.muted": "#2a261f", 37 | "icon.disabled": "#776e63", 38 | "icon.placeholder": "#776e63", 39 | "icon.accent": "#6587bf", 40 | "status_bar.background": "#fffdf5", 41 | "title_bar.background": "#fffdf5", 42 | "toolbar.background": "#fffdf5", 43 | "tab_bar.background": "#fffdf5", 44 | "tab.inactive_background": "#fffdf5", 45 | "tab.active_background": "#fceccc", 46 | "search.match_background": "#fadaa0", 47 | "panel.background": "#fffdf5", 48 | "panel.focused_border": "#db7070", 49 | "pane.focused_border": "#db7070", 50 | "scrollbar_thumb.background": "#fceccc", 51 | "scrollbar.thumb.hover_background": "#d69822", 52 | "scrollbar.thumb.border": "#fceccc", 53 | "scrollbar.track.background": "#fff9eb", 54 | "scrollbar.track.border": "#fffdf5", 55 | "editor.foreground": "#4a443d", 56 | "editor.background": "#fffdf5", 57 | "editor.gutter.background": "#fffdf5", 58 | "editor.subheader.background": "#fceccc", 59 | "editor.active_line.background": "#fffdf5", 60 | "editor.highlighted_line.background": "#fff9eb", 61 | "editor.line_number": "#4a443d", 62 | "editor.active_line_number": "#4a443d", 63 | "editor.invisible": "#776e63", 64 | "editor.wrap_guide": "#776e63", 65 | "editor.active_wrap_guide": "#d8cbbe", 66 | "editor.document_highlight.read_background": "#b870ce33", 67 | "editor.document_highlight.write_background": "#db707033", 68 | "terminal.background": "#fffdf5", 69 | "terminal.foreground": "#4a443d", 70 | "terminal.bright_foreground": "#2a261f", 71 | "terminal.dim_foreground": "#776e63", 72 | "terminal.ansi.black": "#4a443d", 73 | "terminal.ansi.bright_black": "#776e63", 74 | "terminal.ansi.dim_black": "#4a443d", 75 | "terminal.ansi.red": "#db7070", 76 | "terminal.ansi.bright_red": "#c66666", 77 | "terminal.ansi.dim_red": "#776e63", 78 | "terminal.ansi.green": "#7c9f4b", 79 | "terminal.ansi.bright_green": "#6d8b42", 80 | "terminal.ansi.dim_green": "#2a261f", 81 | "terminal.ansi.yellow": "#d69822", 82 | "terminal.ansi.bright_yellow": "#d8cbbe", 83 | "terminal.ansi.dim_yellow": "#776e63", 84 | "terminal.ansi.blue": "#6587bf", 85 | "terminal.ansi.bright_blue": "#776e63", 86 | "terminal.ansi.dim_blue": "#4a443d", 87 | "terminal.ansi.magenta": "#b870ce", 88 | "terminal.ansi.bright_magenta": "#a262b5", 89 | "terminal.ansi.dim_magenta": "#2a261f", 90 | "terminal.ansi.cyan": "#509c93", 91 | "terminal.ansi.bright_cyan": "#43827b", 92 | "terminal.ansi.dim_cyan": "#776e63", 93 | "terminal.ansi.white": "#4a443d", 94 | "terminal.ansi.bright_white": "#2a261f", 95 | "terminal.ansi.dim_white": "#776e63", 96 | "link_text.hover": "#509c933d", 97 | "conflict": "#db7070", 98 | "conflict.background": "#db707033", 99 | "conflict.border": "#db7070", 100 | "created": "#7c9f4b", 101 | "created.background": "#7c9f4b33", 102 | "created.border": "#7c9f4b", 103 | "deleted": "#db7070", 104 | "deleted.background": "#db707033", 105 | "deleted.border": "#db7070", 106 | "error": "#db7070", 107 | "error.background": "#db707033", 108 | "error.border": "#db7070", 109 | "hidden": "#2a261f", 110 | "hidden.background": "#fffdf5", 111 | "hidden.border": "#776e63", 112 | "hint": "#4a443d", 113 | "hint.background": "#4a443d33", 114 | "hint.border": "#4a443d", 115 | "ignored": "#4a443d", 116 | "ignored.background": "#4a443d33", 117 | "ignored.border": "#4a443d", 118 | "info": "#509c93", 119 | "info.background": "#509c9333", 120 | "info.border": "#509c93", 121 | "modified": "#7c9f4b", 122 | "modified.background": "#7c9f4b33", 123 | "modified.border": "#7c9f4b", 124 | "predictive": "#776e63", 125 | "predictive.background": "#d6982233", 126 | "predictive.border": "#d69822", 127 | "renamed": "#6587bf", 128 | "renamed.background": "#6587bf33", 129 | "renamed.border": "#6587bf", 130 | "success": "#7c9f4b", 131 | "success.background": "#7c9f4b33", 132 | "success.border": "#7c9f4b", 133 | "unreachable": "#db7070", 134 | "unreachable.background": "#db707033", 135 | "unreachable.border": "#db7070", 136 | "warning": "#d69822", 137 | "warning.background": "#d6982233", 138 | "warning.border": "#d69822", 139 | "players": [ 140 | { 141 | "cursor": "#509c93", 142 | "background": "#509c93", 143 | "selection": "#8e69d53d" 144 | }, 145 | { 146 | "cursor": "#b870ce", 147 | "background": "#b870ce", 148 | "selection": "#b870ce3d" 149 | }, 150 | { 151 | "cursor": "#db7070", 152 | "background": "#db7070", 153 | "selection": "#db70703d" 154 | }, 155 | { 156 | "cursor": "#a262b5", 157 | "background": "#a262b5", 158 | "selection": "#a262b53d" 159 | }, 160 | { 161 | "cursor": "#6587bf", 162 | "background": "#6587bf", 163 | "selection": "#6587bf3d" 164 | }, 165 | { 166 | "cursor": "#43827b", 167 | "background": "#43827b", 168 | "selection": "#43827b3d" 169 | }, 170 | { 171 | "cursor": "#d69822", 172 | "background": "#d69822", 173 | "selection": "#d698223d" 174 | }, 175 | { 176 | "cursor": "#7c9f4b", 177 | "background": "#7c9f4b", 178 | "selection": "#7c9f4b3d" 179 | } 180 | ], 181 | "syntax": { 182 | "attribute": { 183 | "color": "#4a443d", 184 | "font_style": "normal", 185 | "font_weight": 400 186 | }, 187 | "boolean": { 188 | "color": "#4a443d", 189 | "font_style": "normal", 190 | "font_weight": 400 191 | }, 192 | "comment": { 193 | "color": "#776e63", 194 | "font_style": "italic", 195 | "font_weight": 400 196 | }, 197 | "comment.doc": { 198 | "color": "#776e63", 199 | "font_style": "italic", 200 | "font_weight": 400 201 | }, 202 | "constant": { 203 | "color": "#4a443d", 204 | "font_style": "normal", 205 | "font_weight": 400 206 | }, 207 | "function": { 208 | "color": "#4a443d", 209 | "font_style": "normal", 210 | "font_weight": 400 211 | }, 212 | "keyword": { 213 | "color": "#4a443d", 214 | "font_style": "normal", 215 | "font_weight": 600 216 | }, 217 | "number": { 218 | "color": "#4a443d", 219 | "font_style": "normal", 220 | "font_weight": 400 221 | }, 222 | "string": { 223 | "color": "#4a443d", 224 | "font_style": "normal", 225 | "font_weight": 400 226 | }, 227 | "variable": { 228 | "color": "#4a443d", 229 | "font_style": "normal", 230 | "font_weight": 400 231 | }, 232 | "operator": { 233 | "color": "#4a443d", 234 | "font_style": "normal", 235 | "font_weight": 400 236 | }, 237 | "type": { 238 | "color": "#4a443d", 239 | "font_style": "normal", 240 | "font_weight": 400 241 | }, 242 | "punctuation": { 243 | "color": "#4a443d", 244 | "font_style": "normal", 245 | "font_weight": 400 246 | }, 247 | "error": { 248 | "color": "#db7070", 249 | "font_style": "normal", 250 | "font_weight": 600 251 | }, 252 | "warning": { 253 | "color": "#d69822", 254 | "font_style": "normal", 255 | "font_weight": 600 256 | }, 257 | "info": { 258 | "color": "#509c93", 259 | "font_style": "normal", 260 | "font_weight": 600 261 | }, 262 | "hint": { 263 | "color": "#7c9f4b", 264 | "font_style": "normal", 265 | "font_weight": 600 266 | } 267 | } 268 | } 269 | } 270 | ] 271 | } 272 | -------------------------------------------------------------------------------- /prompt/git.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | 7 | git "github.com/libgit2/git2go/v33" 8 | ) 9 | 10 | // Recursively traverse up until we find .git 11 | // and return the git repo path. 12 | func getGitDir(cwd string) string { 13 | for { 14 | dirs, _ := os.ReadDir(cwd) 15 | for _, d := range dirs { 16 | if ".git" == d.Name() { 17 | return cwd 18 | } else if cwd == "/" { 19 | return "" 20 | } 21 | } 22 | cwd = filepath.Dir(cwd) 23 | } 24 | } 25 | 26 | // Returns the current git branch or current ref sha. 27 | func getGitBranch(repo *git.Repository) string { 28 | ref, _ := repo.Head() 29 | // Quick hack to fix crash when ref is nil; 30 | // i.e., new repo with no commits. 31 | if ref == nil { 32 | return "no commit" 33 | } 34 | if ref.IsBranch() { 35 | name, _ := ref.Branch().Name() 36 | return name 37 | } else { 38 | return ref.Target().String()[:8] 39 | } 40 | } 41 | 42 | // Returns • if clean, else ×. 43 | func getGitStatus(repo *git.Repository, clean, dirty string) string { 44 | sl, _ := repo.StatusList(&git.StatusOptions{ 45 | Show: git.StatusShowIndexAndWorkdir, 46 | Flags: git.StatusOptIncludeUntracked, 47 | }) 48 | n, _ := sl.EntryCount() 49 | if n != 0 { 50 | return dirty 51 | } else { 52 | return clean 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /prompt/go.mod: -------------------------------------------------------------------------------- 1 | module git.icyphox.sh/dotfiles/prompt 2 | 3 | go 1.21 4 | 5 | toolchain go1.23.4 6 | 7 | require github.com/go-git/go-git/v5 v5.13.2 8 | 9 | require ( 10 | dario.cat/mergo v1.0.0 // indirect 11 | github.com/Microsoft/go-winio v0.6.1 // indirect 12 | github.com/ProtonMail/go-crypto v1.1.5 // indirect 13 | github.com/cloudflare/circl v1.3.7 // indirect 14 | github.com/cyphar/filepath-securejoin v0.3.6 // indirect 15 | github.com/emirpasic/gods v1.18.1 // indirect 16 | github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect 17 | github.com/go-git/go-billy/v5 v5.6.2 // indirect 18 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect 19 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect 20 | github.com/kevinburke/ssh_config v1.2.0 // indirect 21 | github.com/pjbgf/sha1cd v0.3.2 // indirect 22 | github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect 23 | github.com/skeema/knownhosts v1.3.0 // indirect 24 | github.com/xanzy/ssh-agent v0.3.3 // indirect 25 | golang.org/x/crypto v0.32.0 // indirect 26 | golang.org/x/mod v0.19.0 // indirect 27 | golang.org/x/net v0.34.0 // indirect 28 | golang.org/x/sync v0.10.0 // indirect 29 | golang.org/x/sys v0.29.0 // indirect 30 | golang.org/x/tools v0.23.0 // indirect 31 | gopkg.in/warnings.v0 v0.1.2 // indirect 32 | ) 33 | -------------------------------------------------------------------------------- /prompt/go.sum: -------------------------------------------------------------------------------- 1 | dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= 2 | dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= 3 | github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= 4 | github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= 5 | github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= 6 | github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= 7 | github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= 8 | github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= 9 | github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= 10 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= 11 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 12 | github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= 13 | github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= 14 | github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= 15 | github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= 16 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 17 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 18 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 19 | github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM= 20 | github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ= 21 | github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= 22 | github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= 23 | github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= 24 | github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= 25 | github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= 26 | github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= 27 | github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= 28 | github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= 29 | github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= 30 | github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= 31 | github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= 32 | github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= 33 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= 34 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 35 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 36 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 37 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= 38 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= 39 | github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= 40 | github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= 41 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 42 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 43 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 44 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 45 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 46 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 47 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 48 | github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= 49 | github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= 50 | github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= 51 | github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= 52 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 53 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 54 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 55 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 56 | github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= 57 | github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= 58 | github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= 59 | github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= 60 | github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 61 | github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= 62 | github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= 63 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 64 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 65 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 66 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 67 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 68 | github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= 69 | github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= 70 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 71 | golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= 72 | golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= 73 | golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= 74 | golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= 75 | golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= 76 | golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 77 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 78 | golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= 79 | golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= 80 | golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= 81 | golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 82 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 83 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 84 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 85 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 86 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 87 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 88 | golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= 89 | golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 90 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 91 | golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= 92 | golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= 93 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 94 | golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= 95 | golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= 96 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 97 | golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= 98 | golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= 99 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 100 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 101 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 102 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 103 | gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= 104 | gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= 105 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 106 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 107 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 108 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 109 | -------------------------------------------------------------------------------- /prompt/prompt.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | "strings" 8 | 9 | "github.com/go-git/go-git/v5" 10 | "github.com/go-git/go-git/v5/plumbing" 11 | "github.com/go-git/go-git/v5/plumbing/revlist" 12 | ) 13 | 14 | func main() { 15 | if len(os.Args) < 3 { 16 | return 17 | } 18 | 19 | command := os.Args[1] 20 | target := os.Args[2] 21 | 22 | switch command { 23 | case "cwd": 24 | fmt.Print(cwd(target)) 25 | case "vcs": 26 | if status := vcs(target); status != "" { 27 | fmt.Print(status) 28 | } 29 | } 30 | } 31 | 32 | func cwd(target string) string { 33 | home, _ := os.UserHomeDir() 34 | absTarget, _ := filepath.Abs(target) 35 | absHome, _ := filepath.Abs(home) 36 | 37 | // Replace home directory with ~ 38 | if strings.HasPrefix(absTarget, absHome) { 39 | if absTarget == absHome { 40 | return "~" 41 | } 42 | absTarget = "~" + strings.TrimPrefix(absTarget, absHome) 43 | } 44 | 45 | // Truncate path components 46 | parts := strings.Split(filepath.ToSlash(absTarget), "/") 47 | for i := 0; i < len(parts)-1; i++ { 48 | if parts[i] != "" && parts[i] != "~" { 49 | parts[i] = parts[i][:1] 50 | } 51 | } 52 | return strings.Join(parts, "/") 53 | } 54 | 55 | func vcs(target string) string { 56 | repo := findRepo(target) 57 | if repo == nil { 58 | return "" 59 | } 60 | 61 | status := &strings.Builder{} 62 | 63 | // Get branch information 64 | if branch, ok := getBranch(repo); ok { 65 | status.WriteString(fmt.Sprintf("#[fg=colour8]%s ", branch)) 66 | } 67 | 68 | // Get ahead/behind information 69 | if dist := getDistance(repo); dist != "" { 70 | status.WriteString(fmt.Sprintf("#[fg=colour8]%s", dist)) 71 | } 72 | 73 | // Get repository status 74 | statusSymbol, statusColor := getRepoStatus(repo) 75 | status.WriteString(fmt.Sprintf("%s%s#[fg=colour7]", statusColor, statusSymbol)) 76 | 77 | return status.String() 78 | } 79 | 80 | func findRepo(target string) *git.Repository { 81 | dir := filepath.Clean(target) 82 | for { 83 | repo, err := git.PlainOpen(dir) 84 | if err == nil { 85 | return repo 86 | } 87 | 88 | parent := filepath.Dir(dir) 89 | if parent == dir { 90 | return nil 91 | } 92 | dir = parent 93 | } 94 | } 95 | 96 | func getBranch(repo *git.Repository) (string, bool) { 97 | head, err := repo.Head() 98 | if err != nil { 99 | return "", false 100 | } 101 | 102 | if head.Name().IsBranch() { 103 | return head.Name().Short(), true 104 | } 105 | 106 | // Check for detached HEAD 107 | if commit, err := repo.CommitObject(head.Hash()); err == nil { 108 | return commit.Hash.String()[:7], true 109 | } 110 | 111 | return "", false 112 | } 113 | 114 | func getDistance(repo *git.Repository) string { 115 | head, err := repo.Head() 116 | if err != nil || !head.Name().IsBranch() { 117 | return "" 118 | } 119 | 120 | local := head.Hash() 121 | 122 | branch, err := repo.Branch(head.Name().Short()) 123 | if err != nil { 124 | return "" 125 | } 126 | 127 | remoteName := "origin" 128 | 129 | remote, err := repo.Remote(remoteName) 130 | if err != nil { 131 | return "" 132 | } 133 | 134 | err = remote.Fetch(&git.FetchOptions{RemoteName: remoteName}) 135 | if err != nil { 136 | return "" 137 | } 138 | 139 | refName := plumbing.Re 140 | 141 | ahead, _ := revlist.Objects(repo.Storer, []plumbing.Hash{local}, []plumbing.Hash{remote}) 142 | behind, _ := revlist.Objects(repo.Storer, []plumbing.Hash{remote}, []plumbing.Hash{local}) 143 | 144 | switch { 145 | case len(ahead) > 0 && len(behind) > 0: 146 | return "↑↓ " 147 | case len(ahead) > 0: 148 | return "↑ " 149 | case len(behind) > 0: 150 | return "↓ " 151 | default: 152 | return "" 153 | } 154 | } 155 | 156 | func getRepoStatus(repo *git.Repository) (string, string) { 157 | wt, _ := repo.Worktree() 158 | stat, _ := wt.Status() 159 | 160 | hasStaged := false 161 | hasUnstaged := false 162 | 163 | for _, s := range stat { 164 | 165 | if s.Staging != git.Unmodified { 166 | hasStaged = true 167 | } 168 | if s.Worktree != git.Unmodified { 169 | hasUnstaged = true 170 | } 171 | } 172 | 173 | switch { 174 | case hasUnstaged: 175 | return "×", "#[fg=colour1]" 176 | case hasStaged: 177 | return "±", "#[fg=colour3]" 178 | default: 179 | return "·", "#[fg=colour2]" 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /readme: -------------------------------------------------------------------------------- 1 | dotfiles 2 | -------- 3 | 4 | System configurations and dotfiles managed using Nix. 5 | 6 | Primary hosts: 7 | • wyndle: Asus ROG Flow X13 8 | NixOS, running GNOME. 9 | 10 | • kvothe: MacBook Pro 14 (M1 Pro) 11 | macOS 15.0 Sequoia, using nix-darwin. 12 | 13 | Homelab cluster: 14 | • sini: Dell OptiPlex 3040 15 | • iso: HP EliteDesk 800 G2 16 | • denna: MeLE Quieter 4C 17 | 18 | All running K3s on NixOS. 19 | 20 | 21 | Licensed under CC0 (Public Domain). 22 | -------------------------------------------------------------------------------- /services/default.nix: -------------------------------------------------------------------------------- 1 | { config 2 | , pkgs 3 | , ... 4 | }: 5 | 6 | { 7 | 8 | services = { 9 | gpg-agent = { 10 | enable = true; 11 | defaultCacheTtl = 60 * 60 * 24 * 7; 12 | maxCacheTtl = 60 * 60 * 24 * 7; 13 | pinentryPackage = pkgs.pinentry-gnome3; 14 | }; 15 | }; 16 | } 17 | --------------------------------------------------------------------------------