From f952e2d6b893b1dde32464d2cf92fc88f27a982c Mon Sep 17 00:00:00 2001
From: Oliver Davies <oliver@oliverdavies.dev>
Date: Sun, 9 Jun 2024 20:51:23 +0100
Subject: [PATCH] Refactor zsh configuration

* Move aliases into `programs.zsh.shellAliases` and
  `programs.shellGlobalAliases`.
* Use the `MenkeTechnologies/zsh-expand` plugin instead of using custom
  expansion code.

https://github.com/MenkeTechnologies/zsh-expand
---
 lib/shared/modules/zsh.nix | 284 +++++++++++++------------------------
 1 file changed, 99 insertions(+), 185 deletions(-)

diff --git a/lib/shared/modules/zsh.nix b/lib/shared/modules/zsh.nix
index c5c30054..0451d9d5 100644
--- a/lib/shared/modules/zsh.nix
+++ b/lib/shared/modules/zsh.nix
@@ -6,58 +6,76 @@
     enableCompletion = false;
     dotDir = ".config/zsh";
 
+    shellAliases = {
+      dea = "direnv allow";
+      dee = "direnv edit";
+      cat = "bat";
+      cs = "create-script";
+      daily = "run create-daily next";
+      ls = "lsd";
+      run = "./run";
+      s = "secrets";
+      secrets = "doppler --project \"$(whoami)\" run";
+      switch = "run nixos nixedo switch";
+      sz = "source ~/.config/zsh/.zshrc";
+      tag = "tag-release";
+      wt = "git worktree";
+      vss = "LC_ALL=C sort --unique ~/Code/personal/opdavies.nvim/spell/en.utf-8.add --output ~/Code/personal/opdavies.nvim/spell/en.utf-8.add";
+
+      # tmux
+      ta = "tmux attach";
+      tl = "tmux list-sessions";
+      tk = "tmux kill-session";
+
+      # Docker and Docker Compose.
+      dk = "docker";
+      dkp = "docker ps";
+      dkpa = "docker ps -a";
+      dkpaq = "docker ps -a -q";
+      dkb = "docker build -t";
+      dks = "docker start";
+      dkt = "docker stop";
+      dkrm = "docker rm";
+      dkri = "docker rmi";
+      dke = "docker exec -ti";
+      dkl = "docker logs -f";
+      dki = "docker images";
+      dkpu = "docker pull";
+      dkph = "docker push";
+      dkbnc = "docker build --no-cache -t";
+      dkr = "docker run --rm";
+      dkrti = "docker run --rm -ti";
+      dkc = "docker compose";
+      dkcb = "docker compose build";
+      dkcu = "docker compose up";
+      dkclean = "docker ps -q -a -f status=exited | xargs -r docker rm && docker images -q -f dangling=true | xargs -r docker rmi";
+
+      # run scripts.
+      r = "run";
+      rc = "run composer";
+      rd = "run drush";
+      rdcr = "run drush cr";
+      rdup = "run drush updb -y";
+      rdce = "run drush config:export -y";
+      rdci = "run drush config:import -y";
+      rduli = "run drush uli";
+    };
+
+    shellGlobalAliases = {
+      A1 = "| awk '{print \$1}'";
+      Fj = "| jq .";
+      Fy = "| yq .";
+      G = "| grep";
+      GH = "| grep HTTP";
+      Gi = "| grep -i";
+      H2 = "| head -n 20";
+      H = "| head";
+      L = "| less";
+      V = "| vim -";
+      X = "| xargs -I1";
+    };
+
     initExtra = ''
-      # Based on https://github.com/rwxrob/dot/blob/f4240010a82609da352b203103ab548f213a4328/.bashrc#L313.
-      clone() {
-        repo_url="$1"
-
-        # Extract the remote domain (e.g. github.com) from the repo URL.
-        domain="''${repo_url#*://}"
-        if [[ "''${domain}" == *@*:* ]]; then
-            # SSH repo URL: domain ends at the colon.
-            domain="''${domain#*@}"
-            domain="''${domain%%:*}"
-        else
-            # HTTPS repo URL: domain ends at the slash.
-            domain="''${domain%%/*}"
-        fi
-
-        # TODO: make it work with multi-level URLS - e.g. https://gitlab.com/a/b/c/d.git
-
-        user_and_repo_name="''${repo_url}"
-        user_and_repo_name="''${user_and_repo_name#git@bitbucket.org:}"
-        user_and_repo_name="''${user_and_repo_name#git@github.com:}"
-        user_and_repo_name="''${user_and_repo_name#git@gitlab.com:}"
-        user_and_repo_name="''${user_and_repo_name#https://bitbucket.org/}"
-        user_and_repo_name="''${user_and_repo_name#https://github.com/}"
-        user_and_repo_name="''${user_and_repo_name#https://gitlab.com/}"
-
-        if [[ "''${user_and_repo_name}" =~ / ]]; then
-          user="''${user_and_repo_name%%/*}"
-        else
-          user="$GITUSER"
-          [[ -z "$user" ]] && user="$USER"
-        fi
-
-        repo_name="''${user_and_repo_name##*/}"
-        repo_name="''${repo_name%.git}"
-
-        user_path="''${REPOS}/''${domain}/''${user}"
-
-        repo_path="''${user_path}/''${repo_name}"
-
-        [[ -d "''${repo_path}" ]] && t "''${repo_path}" && return
-
-        ${pkgs.coreutils}/bin/mkdir -p "''${user_path}"
-        pushd "''${user_path}"
-
-        echo ${pkgs.git}/bin/git clone "''${repo_url}" "''${repo_name}"
-        ${pkgs.git}/bin/git clone "''${repo_url}" "''${repo_name}"
-
-        popd
-        t "''${repo_path}"
-      }
-
       git() {
         if [[ "''${1}" == "root" ]]; then
           shift
@@ -105,6 +123,7 @@
       }
 
       # Plugins
+      source "''${ZPLUG_REPOS}/MenkeTechnologies/zsh-expand/zsh-expand.plugin.zsh"
       source "''${ZPLUG_REPOS}/joshskidmore/zsh-fzf-history-search/zsh-fzf-history-search.plugin.zsh"
       source "''${ZPLUG_REPOS}/robbyrussell/oh-my-zsh/plugins/git/git.plugin.zsh"
       source "''${ZPLUG_REPOS}/robbyrussell/oh-my-zsh/plugins/vi-mode/vi-mode.plugin.zsh"
@@ -144,140 +163,6 @@
       # bindkey '^J' clear-tree-2
       # bindkey '^K' clear-ls-all
 
-      # auto-completes aliases
-      # enables to define
-      # - normal aliases (completed with trailing space)
-      # - blank aliases (completed without space)
-      # - ignored aliases (not completed)
-
-      # ignored aliases
-      typeset -a ialiases
-      ialiases=()
-
-      ialias() {
-        alias $@
-        args="$@"
-        args=''${args%%\=*}
-        ialiases+=(''${args##* })
-      }
-
-      # blank aliases
-      typeset -a baliases
-      baliases=()
-
-      balias() {
-        alias $@
-        args="$@"
-        args=''${args%%\=*}
-        baliases+=(''${args##* })
-      }
-
-      expand-alias-space() {
-        [[ $LBUFFER =~ "\<(''${(j:|:)baliases})\$" ]]; insertBlank=$?
-        if [[ ! $LBUFFER =~ "\<(''${(j:|:)ialiases})\$" ]]; then
-          zle _expand_alias
-        fi
-
-        zle self-insert
-
-        if [[ "$insertBlank" = "0" ]]; then
-          zle backward-delete-char
-        fi
-      }
-
-      zle -N expand-alias-space
-
-      bindkey " " expand-alias-space
-      bindkey -M isearch " " magic-space
-
-      alias dea='direnv allow'
-      alias dee='direnv edit'
-
-      ialias cat="bat"
-      ialias cs="create-script"
-      ialias daily="run create-daily next"
-      ialias ls="lsd"
-      ialias run="./run"
-      ialias s="secrets"
-      ialias secrets="doppler --project \"$(whoami)\" run"
-      ialias switch="run nixos nixedo switch"
-      ialias sz="source ~/.config/zsh/.zshrc"
-      ialias tag="tag-release"
-      ialias uncommit="git reset --soft HEAD^";
-      ialias wt="git worktree"
-      ialias vss="LC_ALL=C sort --unique ~/Code/personal/opdavies.nvim/spell/en.utf-8.add --output ~/Code/personal/opdavies.nvim/spell/en.utf-8.add"
-      balias lh3="xdg-open http://localhost:3000"
-      balias lh8="xdg-open http://localhost:8000"
-
-      # tmux
-      alias ta="tmux attach"
-      alias tl="tmux list-sessions"
-      alias tk="tmux kill-session"
-
-      # Docker and Docker Compose.
-      alias dk="docker"
-      alias dkp="docker ps"
-      alias dkpa="docker ps -a"
-      alias dkpaq="docker ps -a -q"
-      alias dkb="docker build -t"
-      alias dks="docker start"
-      alias dkt="docker stop"
-      alias dkrm="docker rm"
-      alias dkri="docker rmi"
-      alias dke="docker exec -ti"
-      alias dkl="docker logs -f"
-      alias dki="docker images"
-      alias dkpu="docker pull"
-      alias dkph="docker push"
-      alias dkbnc="docker build --no-cache -t"
-      alias dkr="docker run --rm"
-      alias dkrti="docker run --rm -ti"
-      alias dkc="docker compose"
-      alias dkcb="docker compose build"
-      alias dkcu="docker compose up"
-      alias dkclean="docker ps -q -a -f status=exited | xargs -r docker rm && docker images -q -f dangling=true | xargs -r docker rmi"
-
-      # Nix and NixOS.
-      alias nx="nix"
-      alias nxb="nix build --json --no-link --print-build-logs"
-      alias nxd="nix develop"
-      alias nxf="nix flake"
-      alias nxfu="nix flake update"
-      alias nxs="nix shell"
-      ialias full-system-clean='nix-collect-garbage -d && sudo nix-collect-garbage -d'
-      ialias full-system-repair='nix-store --verify --check-contents --repair'
-      ialias full-system-upgrade="sudo nixos-rebuild switch --upgrade && nix-env -u '*'"
-      ialias list-system-configurations='\ls -l /nix/var/nix/profiles/system-*-link'
-      ialias local-upgrade="nix-channel --update nixpkgs && nix-env -u '*'"
-      ialias set-default-boot='/run/current-system/bin/switch-to-configuration boot'
-      ialias system-rebuild='sudo nixos-rebuild switch'
-      ialias system-repair='sudo nixos-rebuild switch --repair'
-      ialias system-upgrade-information='sudo nixos-rebuild switch --upgrade dry-build'
-
-      alias tf="terraform"
-
-      # run scripts.
-      alias r="run"
-      alias rc="run composer"
-      alias rd="run drush"
-      alias rdcr="run drush cr"
-      alias rdup="run drush updb -y"
-      alias rdce="run drush config:export -y"
-      alias rdci="run drush config:import -y"
-      alias rduli="run drush uli"
-
-      alias -g A1="| awk '{print \$1}'"
-      alias -g Fj='| jq .'
-      alias -g Fy='| yq .'
-      alias -g G='| grep'
-      alias -g GH='| grep HTTP'
-      alias -g Gi='| grep -i'
-      alias -g H2='| head -n 20'
-      alias -g H='| head'
-      alias -g L='| less'
-      alias -g V='| vim -'
-      alias -g X='| xargs -I1'
-
       setopt auto_cd
       setopt auto_pushd
       setopt pushd_ignore_dups
@@ -296,9 +181,38 @@
           name = "plugin/vi-mode";
           tags = [ "from:oh-my-zsh" ];
         }
+
+        { name = "MenkeTechnologies/zsh-expand"; }
         { name = "zsh-users/zsh-completions"; }
         { name = "zsh-users/zsh-syntax-highlighting"; }
       ];
     };
   };
+
+  programs.zsh.localVariables = {
+    ZPWR_EXPAND = true;
+    ZPWR_EXPAND_BLACKLIST = [
+      "cat"
+      "cs"
+      "daily"
+      "full-system-clean"
+      "full-system-repair"
+      "full-system-upgrade"
+      "list-system-configurations"
+      "set-default-boot"
+      "system-rebuld"
+      "system-repair"
+      "system-upgrade-information"
+      "ls"
+      "run"
+      "s"
+      "secrets"
+      "sz"
+      "tag"
+      "vss"
+      "wt"
+    ];
+    ZPWR_EXPAND_NATIVE = true;
+    ZPWR_EXPAND_SECOND_POSITION = true;
+  };
 }