diff --git a/flake.nix b/flake.nix index cd38587..0a074a9 100644 --- a/flake.nix +++ b/flake.nix @@ -344,7 +344,9 @@ x86_64-linux.docs = mkDocs "x86_64-linux"; aarch64-linux.docs = mkDocs "aarch64-linux"; aarch64-darwin.docs = mkDocs "aarch64-darwin"; - aarch64-darwin.gp-menubar = nixpkgs.legacyPackages.aarch64-darwin.callPackage ./packages/gp-menubar.nix { }; + aarch64-darwin.gp-menubar = + nixpkgs.legacyPackages.aarch64-darwin.callPackage ./packages/gp-menubar.nix + { }; x86_64-linux.iso = self.nixosConfigurations.iso-x86_64.config.system.build.isoImage; aarch64-linux.iso = self.nixosConfigurations.iso-aarch64.config.system.build.isoImage; diff --git a/modules/darwin/defaults.nix b/modules/darwin/defaults.nix index 3560a21..4fc433b 100644 --- a/modules/darwin/defaults.nix +++ b/modules/darwin/defaults.nix @@ -186,42 +186,66 @@ "30" = { enabled = true; value = { - parameters = [ 52 21 1703936 ]; + parameters = [ + 52 + 21 + 1703936 + ]; type = "standard"; }; }; "31" = { enabled = true; value = { - parameters = [ 52 21 1179648 ]; + parameters = [ + 52 + 21 + 1179648 + ]; type = "standard"; }; }; "28" = { enabled = true; value = { - parameters = [ 51 20 1703936 ]; + parameters = [ + 51 + 20 + 1703936 + ]; type = "standard"; }; }; "29" = { enabled = true; value = { - parameters = [ 51 20 1179648 ]; + parameters = [ + 51 + 20 + 1179648 + ]; type = "standard"; }; }; "64" = { enabled = false; value = { - parameters = [ 32 49 1048576 ]; + parameters = [ + 32 + 49 + 1048576 + ]; type = "standard"; }; }; "65" = { enabled = false; value = { - parameters = [ 32 49 1572864 ]; + parameters = [ + 32 + 49 + 1572864 + ]; type = "standard"; }; }; diff --git a/modules/home/apps/helix.nix b/modules/home/apps/helix.nix index f69dcef..905a309 100644 --- a/modules/home/apps/helix.nix +++ b/modules/home/apps/helix.nix @@ -14,23 +14,25 @@ config = lib.mkIf config.atelier.apps.helix.enable { # Build tree-sitter-cdl grammar as a nix derivation so helix doesn't need # `hx --grammar build` after every rebuild. - xdg.configFile = let - tree-sitter-cdl-grammar = pkgs.stdenv.mkDerivation { - name = "tree-sitter-cdl"; - src = ../../../packages/tree-sitter-cdl; - buildPhase = '' - $CC -shared -fPIC -O2 -o cdl.so src/parser.c -I src - ''; - installPhase = '' - mkdir -p $out - cp cdl.so $out/ - ''; + xdg.configFile = + let + tree-sitter-cdl-grammar = pkgs.stdenv.mkDerivation { + name = "tree-sitter-cdl"; + src = ../../../packages/tree-sitter-cdl; + buildPhase = '' + $CC -shared -fPIC -O2 -o cdl.so src/parser.c -I src + ''; + installPhase = '' + mkdir -p $out + cp cdl.so $out/ + ''; + }; + in + { + "helix/runtime/grammars/cdl.so".source = "${tree-sitter-cdl-grammar}/cdl.so"; + "helix/runtime/queries/cdl/highlights.scm".source = + ../../../packages/tree-sitter-cdl/queries/highlights.scm; }; - in { - "helix/runtime/grammars/cdl.so".source = "${tree-sitter-cdl-grammar}/cdl.so"; - "helix/runtime/queries/cdl/highlights.scm".source = - ../../../packages/tree-sitter-cdl/queries/highlights.scm; - }; programs.helix = { enable = true; diff --git a/modules/home/system/shell.nix b/modules/home/system/shell.nix index 1f59b8f..162ba27 100644 --- a/modules/home/system/shell.nix +++ b/modules/home/system/shell.nix @@ -577,188 +577,188 @@ in vim = "nvim"; }; initContent = '' - bindkey -e - - # Instant prompt: print minimal prompt before heavy init (pre-compiled) - source ${instant-prompt}/instant-prompt.zsh - - # Impure prompt - source ${inputs.impure}/async.zsh - IMPURE_CMD_MAX_EXEC_TIME=3 - source ${inputs.impure}/impure.zsh - - zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}' - zstyle ':completion:*' list-colors "''${(s.:.)LS_COLORS}" - zstyle ':completion:*' menu no - zstyle ':fzf-tab:complete:cd:*' fzf-preview 'ls --color $realpath' - zstyle ':fzf-tab:complete:__zoxide_z:*' fzf-preview 'ls --color $realpath' - - ${lib.concatMapStringsSep "\n" (f: "source ${f}") shell-init} - - eval "$(command terminal-wakatime init)" - - # Edit command buffer in $EDITOR (Ctrl+X, Ctrl+E) - autoload -Uz edit-command-line - zle -N edit-command-line - bindkey '^X^E' edit-command-line - - # Magic space - expand history expressions like !! or !$ - bindkey ' ' magic-space - - # Suffix aliases - open files by extension - alias -s json=jless - alias -s md=bat - alias -s go='$EDITOR' - alias -s rs='$EDITOR' - alias -s txt=bat - alias -s log=bat - alias -s py='$EDITOR' - alias -s js='$EDITOR' - alias -s ts='$EDITOR' - ${if pkgs.stdenv.isDarwin then "alias -s html=open" else ""} - - ${lib.optionalString pkgs.stdenv.isDarwin '' - # Use Apple's toolchain for native builds. nix's cc/clang - # don't wire in the macOS SDK, so cgo/cargo/cmake links fail - # with "library not found" (e.g. -lresolv). Apple's cc - # handles SDK, frameworks, and code signing natively. - # Respected by cgo ($CC), cargo, cmake, etc. - export CC=/usr/bin/cc - export CXX=/usr/bin/c++ - ''} - - # Global aliases - alias -g NE='2>/dev/null' - alias -g NO='>/dev/null' - alias -g NUL='>/dev/null 2>&1' - alias -g J='| jq' - - # Override source to handle .env files safely - function source() { - if [[ "$1" == *.env ]]; then - [[ ! -f "$1" ]] && { echo "File not found: $1" >&2; return 1; } - while IFS= read -r line || [[ -n "$line" ]]; do - [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue - if [[ "$line" =~ ^([a-zA-Z_][a-zA-Z0-9_]*)=(.*)$ ]]; then - export "''${match[1]}=''${match[2]}" - fi - done < "$1" - else - builtin source "$1" - fi - } - - # OSC 52 clipboard (works over SSH) - function osc52copy() { - local data=$(cat "$@" | base64 | tr -d '\n') - printf "\033]52;c;%s\a" "$data" - } - alias -g C='| osc52copy' - - # zmv - advanced batch rename/move - autoload -Uz zmv - alias zcp='zmv -C' - alias zln='zmv -L' - - # Clear screen but keep current command buffer (Ctrl+X, Ctrl+L) - function clear-screen-and-scrollback() { - echoti civis >"$TTY" - printf '%b' '\e[H\e[2J\e[3J' >"$TTY" - echoti cnorm >"$TTY" - zle redisplay - } - zle -N clear-screen-and-scrollback - bindkey '^X^L' clear-screen-and-scrollback - - # Copy current command buffer to clipboard (Ctrl+X, Ctrl+C) - OSC 52 for SSH support - function copy-buffer-to-clipboard() { - local data=$(echo -n "$BUFFER" | base64 | tr -d '\n') - printf "\033]52;c;%s\a" "$data" - zle -M "Copied to clipboard" - } - zle -N copy-buffer-to-clipboard - bindkey '^X^C' copy-buffer-to-clipboard - - # Double-tap escape to prepend sudo (from oh-my-zsh sudo plugin) - __sudo-replace-buffer() { - local old=$1 new=$2 space=''${2:+ } - if [[ $CURSOR -le ''${#old} ]]; then - BUFFER="''${new}''${space}''${BUFFER#$old }" - CURSOR=''${#new} - else - LBUFFER="''${new}''${space}''${LBUFFER#$old }" - fi - } - sudo-command-line() { - [[ -z $BUFFER ]] && LBUFFER="$(fc -ln -1)" - local WHITESPACE="" - if [[ ''${LBUFFER:0:1} = " " ]]; then - WHITESPACE=" " - LBUFFER="''${LBUFFER:1}" - fi - { - local EDITOR=''${SUDO_EDITOR:-''${VISUAL:-$EDITOR}} - if [[ -z "$EDITOR" ]]; then - case "$BUFFER" in - sudo\ -e\ *) __sudo-replace-buffer "sudo -e" "" ;; - sudo\ *) __sudo-replace-buffer "sudo" "" ;; - *) LBUFFER="sudo $LBUFFER" ;; - esac - return - fi - local cmd="''${''${(Az)BUFFER}[1]}" - local realcmd="''${''${(Az)aliases[$cmd]}[1]:-$cmd}" - local editorcmd="''${''${(Az)EDITOR}[1]}" - if [[ "$realcmd" = (\$EDITOR|$editorcmd|''${editorcmd:c}) \ - || "''${realcmd:c}" = ($editorcmd|''${editorcmd:c}) ]] \ - || builtin which -a "$realcmd" | command grep -Fx -q "$editorcmd"; then - __sudo-replace-buffer "$cmd" "sudo -e" - return - fi - case "$BUFFER" in - $editorcmd\ *) __sudo-replace-buffer "$editorcmd" "sudo -e" ;; - \$EDITOR\ *) __sudo-replace-buffer '$EDITOR' "sudo -e" ;; - sudo\ -e\ *) __sudo-replace-buffer "sudo -e" "$EDITOR" ;; - sudo\ *) __sudo-replace-buffer "sudo" "" ;; - *) LBUFFER="sudo $LBUFFER" ;; - esac - } always { - LBUFFER="''${WHITESPACE}''${LBUFFER}" - zle && zle redisplay - } - } - zle -N sudo-command-line - bindkey -M emacs '\e\e' sudo-command-line - bindkey -M vicmd '\e\e' sudo-command-line - bindkey -M viins '\e\e' sudo-command-line - - # chpwd hooks - autoload -Uz add-zsh-hook - - # Tracks which venv we activated, so a venv you sourced by hand - # is never yanked out from under you. - typeset -g _auto_venv="" - - function auto_venv() { - local dir="$PWD" venv="" - while [[ "$dir" != "/" ]]; do - if [[ -f "$dir/.venv/bin/activate" ]]; then - venv="$dir/.venv" - break - fi - dir="''${dir:h}" - done - [[ "$VIRTUAL_ENV" == "$venv" ]] && return - [[ -n "$VIRTUAL_ENV" && "$VIRTUAL_ENV" != "$_auto_venv" ]] && return - (( $+functions[deactivate] )) && deactivate - _auto_venv="$venv" - [[ -n "$venv" ]] && source "$venv/bin/activate" - } - - add-zsh-hook chpwd auto_venv - - # zsh-patina: Rust-based syntax highlighting (must be last) - eval "$(${pkgs.unstable.zsh-patina}/bin/zsh-patina activate)" + bindkey -e + + # Instant prompt: print minimal prompt before heavy init (pre-compiled) + source ${instant-prompt}/instant-prompt.zsh + + # Impure prompt + source ${inputs.impure}/async.zsh + IMPURE_CMD_MAX_EXEC_TIME=3 + source ${inputs.impure}/impure.zsh + + zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}' + zstyle ':completion:*' list-colors "''${(s.:.)LS_COLORS}" + zstyle ':completion:*' menu no + zstyle ':fzf-tab:complete:cd:*' fzf-preview 'ls --color $realpath' + zstyle ':fzf-tab:complete:__zoxide_z:*' fzf-preview 'ls --color $realpath' + + ${lib.concatMapStringsSep "\n" (f: "source ${f}") shell-init} + + eval "$(command terminal-wakatime init)" + + # Edit command buffer in $EDITOR (Ctrl+X, Ctrl+E) + autoload -Uz edit-command-line + zle -N edit-command-line + bindkey '^X^E' edit-command-line + + # Magic space - expand history expressions like !! or !$ + bindkey ' ' magic-space + + # Suffix aliases - open files by extension + alias -s json=jless + alias -s md=bat + alias -s go='$EDITOR' + alias -s rs='$EDITOR' + alias -s txt=bat + alias -s log=bat + alias -s py='$EDITOR' + alias -s js='$EDITOR' + alias -s ts='$EDITOR' + ${if pkgs.stdenv.isDarwin then "alias -s html=open" else ""} + + ${lib.optionalString pkgs.stdenv.isDarwin '' + # Use Apple's toolchain for native builds. nix's cc/clang + # don't wire in the macOS SDK, so cgo/cargo/cmake links fail + # with "library not found" (e.g. -lresolv). Apple's cc + # handles SDK, frameworks, and code signing natively. + # Respected by cgo ($CC), cargo, cmake, etc. + export CC=/usr/bin/cc + export CXX=/usr/bin/c++ + ''} + + # Global aliases + alias -g NE='2>/dev/null' + alias -g NO='>/dev/null' + alias -g NUL='>/dev/null 2>&1' + alias -g J='| jq' + + # Override source to handle .env files safely + function source() { + if [[ "$1" == *.env ]]; then + [[ ! -f "$1" ]] && { echo "File not found: $1" >&2; return 1; } + while IFS= read -r line || [[ -n "$line" ]]; do + [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue + if [[ "$line" =~ ^([a-zA-Z_][a-zA-Z0-9_]*)=(.*)$ ]]; then + export "''${match[1]}=''${match[2]}" + fi + done < "$1" + else + builtin source "$1" + fi + } + + # OSC 52 clipboard (works over SSH) + function osc52copy() { + local data=$(cat "$@" | base64 | tr -d '\n') + printf "\033]52;c;%s\a" "$data" + } + alias -g C='| osc52copy' + + # zmv - advanced batch rename/move + autoload -Uz zmv + alias zcp='zmv -C' + alias zln='zmv -L' + + # Clear screen but keep current command buffer (Ctrl+X, Ctrl+L) + function clear-screen-and-scrollback() { + echoti civis >"$TTY" + printf '%b' '\e[H\e[2J\e[3J' >"$TTY" + echoti cnorm >"$TTY" + zle redisplay + } + zle -N clear-screen-and-scrollback + bindkey '^X^L' clear-screen-and-scrollback + + # Copy current command buffer to clipboard (Ctrl+X, Ctrl+C) - OSC 52 for SSH support + function copy-buffer-to-clipboard() { + local data=$(echo -n "$BUFFER" | base64 | tr -d '\n') + printf "\033]52;c;%s\a" "$data" + zle -M "Copied to clipboard" + } + zle -N copy-buffer-to-clipboard + bindkey '^X^C' copy-buffer-to-clipboard + + # Double-tap escape to prepend sudo (from oh-my-zsh sudo plugin) + __sudo-replace-buffer() { + local old=$1 new=$2 space=''${2:+ } + if [[ $CURSOR -le ''${#old} ]]; then + BUFFER="''${new}''${space}''${BUFFER#$old }" + CURSOR=''${#new} + else + LBUFFER="''${new}''${space}''${LBUFFER#$old }" + fi + } + sudo-command-line() { + [[ -z $BUFFER ]] && LBUFFER="$(fc -ln -1)" + local WHITESPACE="" + if [[ ''${LBUFFER:0:1} = " " ]]; then + WHITESPACE=" " + LBUFFER="''${LBUFFER:1}" + fi + { + local EDITOR=''${SUDO_EDITOR:-''${VISUAL:-$EDITOR}} + if [[ -z "$EDITOR" ]]; then + case "$BUFFER" in + sudo\ -e\ *) __sudo-replace-buffer "sudo -e" "" ;; + sudo\ *) __sudo-replace-buffer "sudo" "" ;; + *) LBUFFER="sudo $LBUFFER" ;; + esac + return + fi + local cmd="''${''${(Az)BUFFER}[1]}" + local realcmd="''${''${(Az)aliases[$cmd]}[1]:-$cmd}" + local editorcmd="''${''${(Az)EDITOR}[1]}" + if [[ "$realcmd" = (\$EDITOR|$editorcmd|''${editorcmd:c}) \ + || "''${realcmd:c}" = ($editorcmd|''${editorcmd:c}) ]] \ + || builtin which -a "$realcmd" | command grep -Fx -q "$editorcmd"; then + __sudo-replace-buffer "$cmd" "sudo -e" + return + fi + case "$BUFFER" in + $editorcmd\ *) __sudo-replace-buffer "$editorcmd" "sudo -e" ;; + \$EDITOR\ *) __sudo-replace-buffer '$EDITOR' "sudo -e" ;; + sudo\ -e\ *) __sudo-replace-buffer "sudo -e" "$EDITOR" ;; + sudo\ *) __sudo-replace-buffer "sudo" "" ;; + *) LBUFFER="sudo $LBUFFER" ;; + esac + } always { + LBUFFER="''${WHITESPACE}''${LBUFFER}" + zle && zle redisplay + } + } + zle -N sudo-command-line + bindkey -M emacs '\e\e' sudo-command-line + bindkey -M vicmd '\e\e' sudo-command-line + bindkey -M viins '\e\e' sudo-command-line + + # chpwd hooks + autoload -Uz add-zsh-hook + + # Tracks which venv we activated, so a venv you sourced by hand + # is never yanked out from under you. + typeset -g _auto_venv="" + + function auto_venv() { + local dir="$PWD" venv="" + while [[ "$dir" != "/" ]]; do + if [[ -f "$dir/.venv/bin/activate" ]]; then + venv="$dir/.venv" + break + fi + dir="''${dir:h}" + done + [[ "$VIRTUAL_ENV" == "$venv" ]] && return + [[ -n "$VIRTUAL_ENV" && "$VIRTUAL_ENV" != "$_auto_venv" ]] && return + (( $+functions[deactivate] )) && deactivate + _auto_venv="$venv" + [[ -n "$venv" ]] && source "$venv/bin/activate" + } + + add-zsh-hook chpwd auto_venv + + # zsh-patina: Rust-based syntax highlighting (must be last) + eval "$(${pkgs.unstable.zsh-patina}/bin/zsh-patina activate)" ''; history = { diff --git a/modules/nixos/services/gp-gateway.nix b/modules/nixos/services/gp-gateway.nix index e13099f..67a7f4d 100644 --- a/modules/nixos/services/gp-gateway.nix +++ b/modules/nixos/services/gp-gateway.nix @@ -35,7 +35,12 @@ let # traffic outside these prefixes. vpncScript = pkgs.writeShellScript "gp-vpnc-script" '' set -eu - export PATH=${lib.makeBinPath [ pkgs.iproute2 pkgs.coreutils ]}:$PATH + export PATH=${ + lib.makeBinPath [ + pkgs.iproute2 + pkgs.coreutils + ] + }:$PATH # This REPLACES openconnect's stock vpnc-script on purpose. The stock script # would install the gateway's pushed 0.0.0.0/0, routing prattle's own traffic # (and this SSH session) through campus. So we bring the interface up @@ -68,7 +73,7 @@ let # campus route set changed, then adjust cfg.routes. echo "gp-gateway: gateway pushed the following config:" env | grep -E '^(CISCO_SPLIT_INC|INTERNAL_IP4|CISCO_DEF_DOMAIN)' | sort || true - ${lib.optionalString cfg.dns.enable ''${dnsSwitch} up''} + ${lib.optionalString cfg.dns.enable "${dnsSwitch} up"} ;; disconnect) ${lib.concatMapStringsSep "\n" (r: '' @@ -76,7 +81,7 @@ let '') cfg.routes} [ -n "''${VPNGATEWAY:-}" ] && ip route del "$VPNGATEWAY/32" 2>/dev/null || true ip addr flush dev "$TUNDEV" 2>/dev/null || true - ${lib.optionalString cfg.dns.enable ''${dnsSwitch} down''} + ${lib.optionalString cfg.dns.enable "${dnsSwitch} down"} ;; esac exit 0 @@ -92,21 +97,30 @@ let dnsSwitch = pkgs.writeShellScript "gp-dns-switch" '' set -eu - export PATH=${lib.makeBinPath [ pkgs.coreutils pkgs.procps ]}:$PATH + export PATH=${ + lib.makeBinPath [ + pkgs.coreutils + pkgs.procps + ] + }:$PATH mode="''${1:-down}" [ "$mode" = "init" ] && { [ -e ${dnsServersFile} ] && exit 0; mode=down; } mkdir -p /run/gp-gateway tmp=$(mktemp ${dnsServersFile}.XXXX) if [ "$mode" = "up" ]; then - ${lib.concatMapStringsSep "\n" (d: + ${lib.concatMapStringsSep "\n" ( + d: lib.concatMapStringsSep "\n" (srv: '' echo "server=/${d}/${srv}" >> "$tmp" - '') cfg.dns.campusServers) cfg.dns.domains} + '') cfg.dns.campusServers + ) cfg.dns.domains} else - ${lib.concatMapStringsSep "\n" (d: + ${lib.concatMapStringsSep "\n" ( + d: lib.concatMapStringsSep "\n" (srv: '' echo "server=/${d}/${srv}" >> "$tmp" - '') cfg.dns.fallbackServers) cfg.dns.domains} + '') cfg.dns.fallbackServers + ) cfg.dns.domains} fi mv "$tmp" ${dnsServersFile} echo "gp-gateway: dns upstream -> $mode" @@ -311,7 +325,10 @@ in routes = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; - example = [ "10.0.0.0/8" "163.11.0.0/16" ]; + example = [ + "10.0.0.0/8" + "163.11.0.0/16" + ]; description = '' Campus CIDRs to install on the tunnel and advertise over Tailscale. Leave empty for the first connect: openconnect runs verbose and the @@ -347,13 +364,19 @@ in campusServers = lib.mkOption { type = lib.types.listOf lib.types.str; - default = [ "163.11.75.113" "163.11.75.119" ]; + default = [ + "163.11.75.113" + "163.11.75.119" + ]; description = "Internal campus resolvers, reachable only through the tunnel."; }; fallbackServers = lib.mkOption { type = lib.types.listOf lib.types.str; - default = [ "1.1.1.1" "9.9.9.9" ]; + default = [ + "1.1.1.1" + "9.9.9.9" + ]; description = '' Public resolvers used while the tunnel is down. Internal-only names then return NXDOMAIN quickly instead of hanging, and public @@ -395,7 +418,10 @@ in systemd.services.gp-receiver = { description = "GlobalProtect cookie receiver (tailnet-only)"; - after = [ "tailscaled.service" "systemd-tmpfiles-setup.service" ]; + after = [ + "tailscaled.service" + "systemd-tmpfiles-setup.service" + ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { ExecStart = receiver; @@ -417,8 +443,10 @@ in ''; }; - networking.firewall.interfaces.tailscale0.allowedTCPPorts = - [ cfg.receiverPort ] ++ lib.optional cfg.dns.enable 53; + networking.firewall.interfaces.tailscale0.allowedTCPPorts = [ + cfg.receiverPort + ] + ++ lib.optional cfg.dns.enable 53; networking.firewall.interfaces.tailscale0.allowedUDPPorts = lib.optional cfg.dns.enable 53; # Tailnet-facing resolver for the campus domains. Point Tailscale's split diff --git a/modules/nixos/services/kloe.nix b/modules/nixos/services/kloe.nix index e2fd32d..12b9fc4 100644 --- a/modules/nixos/services/kloe.nix +++ b/modules/nixos/services/kloe.nix @@ -109,13 +109,11 @@ in # inside dataDir where the unit can actually write it. systemd.tmpfiles.rules = [ "d ${cfg.dataDir}/.ssh 0700 kloe kloe -" - "L+ ${cfg.dataDir}/.ssh/config - - - - ${ - pkgs.writeText "kloe-ssh-config" '' - Host * - StrictHostKeyChecking accept-new - UserKnownHostsFile ${cfg.dataDir}/.ssh/known_hosts - '' - }" + "L+ ${cfg.dataDir}/.ssh/config - - - - ${pkgs.writeText "kloe-ssh-config" '' + Host * + StrictHostKeyChecking accept-new + UserKnownHostsFile ${cfg.dataDir}/.ssh/known_hosts + ''}" ]; }; }