|
| 1 | +# frozen_string_literal: true |
| 2 | + |
| 3 | +module Git |
| 4 | + module Pkgs |
| 5 | + module Commands |
| 6 | + class Completions |
| 7 | + COMMANDS = CLI::COMMANDS |
| 8 | + SUBCOMMAND_OPTIONS = { |
| 9 | + "hooks" => %w[--install --uninstall], |
| 10 | + "branch" => %w[--add --remove --list], |
| 11 | + "diff" => %w[--format], |
| 12 | + "list" => %w[--format --type], |
| 13 | + "tree" => %w[--format], |
| 14 | + "history" => %w[--format --limit], |
| 15 | + "search" => %w[--format --limit], |
| 16 | + "blame" => %w[--format], |
| 17 | + "stale" => %w[--days --format], |
| 18 | + "stats" => %w[--format], |
| 19 | + "log" => %w[--limit --format], |
| 20 | + "show" => %w[--format], |
| 21 | + "where" => %w[--format], |
| 22 | + "why" => %w[--format] |
| 23 | + }.freeze |
| 24 | + |
| 25 | + BASH_SCRIPT = <<~'BASH' |
| 26 | + _git_pkgs() { |
| 27 | + local cur prev commands |
| 28 | + COMPREPLY=() |
| 29 | + cur="${COMP_WORDS[COMP_CWORD]}" |
| 30 | + prev="${COMP_WORDS[COMP_CWORD-1]}" |
| 31 | +
|
| 32 | + commands="init update hooks info list tree history search where why blame stale stats diff branch show log upgrade schema completions" |
| 33 | +
|
| 34 | + if [[ ${COMP_CWORD} -eq 2 && ${COMP_WORDS[1]} == "pkgs" ]]; then |
| 35 | + COMPREPLY=( $(compgen -W "${commands}" -- ${cur}) ) |
| 36 | + return 0 |
| 37 | + fi |
| 38 | +
|
| 39 | + if [[ ${COMP_CWORD} -eq 1 ]]; then |
| 40 | + COMPREPLY=( $(compgen -W "${commands}" -- ${cur}) ) |
| 41 | + return 0 |
| 42 | + fi |
| 43 | +
|
| 44 | + case "${prev}" in |
| 45 | + hooks) |
| 46 | + COMPREPLY=( $(compgen -W "--install --uninstall --help" -- ${cur}) ) |
| 47 | + ;; |
| 48 | + branch) |
| 49 | + COMPREPLY=( $(compgen -W "--add --remove --list --help" -- ${cur}) ) |
| 50 | + ;; |
| 51 | + completions) |
| 52 | + COMPREPLY=( $(compgen -W "bash zsh install --help" -- ${cur}) ) |
| 53 | + ;; |
| 54 | + diff|list|tree|history|search|blame|stale|stats|log|show|where|why) |
| 55 | + COMPREPLY=( $(compgen -W "--format --help" -- ${cur}) ) |
| 56 | + ;; |
| 57 | + esac |
| 58 | +
|
| 59 | + return 0 |
| 60 | + } |
| 61 | +
|
| 62 | + # Support both 'git pkgs' and 'git-pkgs' invocations |
| 63 | + complete -F _git_pkgs git-pkgs |
| 64 | +
|
| 65 | + # For 'git pkgs' subcommand completion |
| 66 | + if declare -F _git >/dev/null 2>&1; then |
| 67 | + _git_pkgs_git_wrapper() { |
| 68 | + if [[ ${COMP_WORDS[1]} == "pkgs" ]]; then |
| 69 | + _git_pkgs |
| 70 | + fi |
| 71 | + } |
| 72 | + fi |
| 73 | + BASH |
| 74 | + |
| 75 | + ZSH_SCRIPT = <<~'ZSH' |
| 76 | + #compdef git-pkgs |
| 77 | +
|
| 78 | + _git-pkgs() { |
| 79 | + local -a commands |
| 80 | + commands=( |
| 81 | + 'init:Initialize the package database' |
| 82 | + 'update:Update the database with new commits' |
| 83 | + 'hooks:Manage git hooks for auto-updating' |
| 84 | + 'info:Show database size and row counts' |
| 85 | + 'branch:Manage tracked branches' |
| 86 | + 'list:List dependencies at a commit' |
| 87 | + 'tree:Show dependency tree grouped by type' |
| 88 | + 'history:Show the history of a package' |
| 89 | + 'search:Find a dependency across all history' |
| 90 | + 'where:Show where a package appears in manifest files' |
| 91 | + 'why:Explain why a dependency exists' |
| 92 | + 'blame:Show who added each dependency' |
| 93 | + 'stale:Show dependencies that have not been updated' |
| 94 | + 'stats:Show dependency statistics' |
| 95 | + 'diff:Show dependency changes between commits' |
| 96 | + 'show:Show dependency changes in a commit' |
| 97 | + 'log:List commits with dependency changes' |
| 98 | + 'upgrade:Upgrade database after git-pkgs update' |
| 99 | + 'schema:Show database schema' |
| 100 | + 'completions:Generate shell completions' |
| 101 | + ) |
| 102 | +
|
| 103 | + _arguments -C \ |
| 104 | + '1: :->command' \ |
| 105 | + '*:: :->args' |
| 106 | +
|
| 107 | + case $state in |
| 108 | + command) |
| 109 | + _describe -t commands 'git-pkgs commands' commands |
| 110 | + ;; |
| 111 | + args) |
| 112 | + case $words[1] in |
| 113 | + hooks) |
| 114 | + _arguments \ |
| 115 | + '--install[Install git hooks]' \ |
| 116 | + '--uninstall[Remove git hooks]' \ |
| 117 | + '--help[Show help]' |
| 118 | + ;; |
| 119 | + branch) |
| 120 | + _arguments \ |
| 121 | + '--add[Add a branch to track]' \ |
| 122 | + '--remove[Remove a tracked branch]' \ |
| 123 | + '--list[List tracked branches]' \ |
| 124 | + '--help[Show help]' |
| 125 | + ;; |
| 126 | + completions) |
| 127 | + _arguments '1:shell:(bash zsh install)' |
| 128 | + ;; |
| 129 | + diff|list|tree|history|search|blame|stale|stats|log|show|where|why) |
| 130 | + _arguments \ |
| 131 | + '--format[Output format]:format:(table json csv)' \ |
| 132 | + '--help[Show help]' |
| 133 | + ;; |
| 134 | + esac |
| 135 | + ;; |
| 136 | + esac |
| 137 | + } |
| 138 | +
|
| 139 | + _git-pkgs "$@" |
| 140 | + ZSH |
| 141 | + |
| 142 | + def initialize(args) |
| 143 | + @args = args |
| 144 | + end |
| 145 | + |
| 146 | + def run |
| 147 | + shell = @args.first |
| 148 | + |
| 149 | + case shell |
| 150 | + when "bash" |
| 151 | + puts BASH_SCRIPT |
| 152 | + when "zsh" |
| 153 | + puts ZSH_SCRIPT |
| 154 | + when "install" |
| 155 | + install_completions |
| 156 | + when "-h", "--help", nil |
| 157 | + print_help |
| 158 | + else |
| 159 | + $stderr.puts "Unknown shell: #{shell}" |
| 160 | + $stderr.puts "Supported: bash, zsh, install" |
| 161 | + exit 1 |
| 162 | + end |
| 163 | + end |
| 164 | + |
| 165 | + def install_completions |
| 166 | + shell = detect_shell |
| 167 | + |
| 168 | + case shell |
| 169 | + when "zsh" |
| 170 | + install_zsh_completions |
| 171 | + when "bash" |
| 172 | + install_bash_completions |
| 173 | + else |
| 174 | + $stderr.puts "Could not detect shell. Please run one of:" |
| 175 | + $stderr.puts " eval \"$(git pkgs completions bash)\"" |
| 176 | + $stderr.puts " eval \"$(git pkgs completions zsh)\"" |
| 177 | + exit 1 |
| 178 | + end |
| 179 | + end |
| 180 | + |
| 181 | + def detect_shell |
| 182 | + shell_env = ENV["SHELL"] || "" |
| 183 | + if shell_env.include?("zsh") |
| 184 | + "zsh" |
| 185 | + elsif shell_env.include?("bash") |
| 186 | + "bash" |
| 187 | + end |
| 188 | + end |
| 189 | + |
| 190 | + def install_bash_completions |
| 191 | + dir = File.expand_path("~/.local/share/bash-completion/completions") |
| 192 | + FileUtils.mkdir_p(dir) |
| 193 | + path = File.join(dir, "git-pkgs") |
| 194 | + File.write(path, BASH_SCRIPT) |
| 195 | + puts "Installed bash completions to #{path}" |
| 196 | + puts "Restart your shell or run: source #{path}" |
| 197 | + end |
| 198 | + |
| 199 | + def install_zsh_completions |
| 200 | + dir = File.expand_path("~/.zsh/completions") |
| 201 | + FileUtils.mkdir_p(dir) |
| 202 | + path = File.join(dir, "_git-pkgs") |
| 203 | + File.write(path, ZSH_SCRIPT) |
| 204 | + puts "Installed zsh completions to #{path}" |
| 205 | + puts "" |
| 206 | + puts "Add to your ~/.zshrc if not already present:" |
| 207 | + puts " fpath=(~/.zsh/completions $fpath)" |
| 208 | + puts " autoload -Uz compinit && compinit" |
| 209 | + puts "" |
| 210 | + puts "Then restart your shell or run: source ~/.zshrc" |
| 211 | + end |
| 212 | + |
| 213 | + def print_help |
| 214 | + puts <<~HELP |
| 215 | + Usage: git pkgs completions <shell> |
| 216 | +
|
| 217 | + Generate shell completion scripts. |
| 218 | +
|
| 219 | + Shells: |
| 220 | + bash Output bash completion script |
| 221 | + zsh Output zsh completion script |
| 222 | + install Auto-install completions for your shell |
| 223 | +
|
| 224 | + Examples: |
| 225 | + git pkgs completions bash > ~/.local/share/bash-completion/completions/git-pkgs |
| 226 | + git pkgs completions zsh > ~/.zsh/completions/_git-pkgs |
| 227 | + eval "$(git pkgs completions bash)" |
| 228 | + git pkgs completions install |
| 229 | + HELP |
| 230 | + end |
| 231 | + end |
| 232 | + end |
| 233 | + end |
| 234 | +end |
0 commit comments