inital commit

This commit is contained in:
2026-03-23 23:50:58 +00:00
commit 503c232b30
110 changed files with 7218 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
#compdef biggest
# Completion for:
# biggest [-n COUNT|--number COUNT] [-p PATTERN|--pattern PATTERN]
_arguments -s \
'(-h --help)'{-h,--help}'[show help information]' \
'(-n --number)'{-n,--number}'[number of entries to display]:number of entries:(10 20 50 100 200)' \
'(-p --pattern)'{-p,--pattern}'[glob-style pattern to match]:glob pattern:_files' && return 0
+212
View File
@@ -0,0 +1,212 @@
#compdef colima
compdef _colima colima
# zsh completion for colima -*- shell-script -*-
__colima_debug()
{
local file="$BASH_COMP_DEBUG_FILE"
if [[ -n ${file} ]]; then
echo "$*" >> "${file}"
fi
}
_colima()
{
local shellCompDirectiveError=1
local shellCompDirectiveNoSpace=2
local shellCompDirectiveNoFileComp=4
local shellCompDirectiveFilterFileExt=8
local shellCompDirectiveFilterDirs=16
local shellCompDirectiveKeepOrder=32
local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder
local -a completions
__colima_debug "\n========= starting completion logic =========="
__colima_debug "CURRENT: ${CURRENT}, words[*]: ${words[*]}"
# The user could have moved the cursor backwards on the command-line.
# We need to trigger completion from the $CURRENT location, so we need
# to truncate the command-line ($words) up to the $CURRENT location.
# (We cannot use $CURSOR as its value does not work when a command is an alias.)
words=("${=words[1,CURRENT]}")
__colima_debug "Truncated words[*]: ${words[*]},"
lastParam=${words[-1]}
lastChar=${lastParam[-1]}
__colima_debug "lastParam: ${lastParam}, lastChar: ${lastChar}"
# For zsh, when completing a flag with an = (e.g., colima -n=<TAB>)
# completions must be prefixed with the flag
setopt local_options BASH_REMATCH
if [[ "${lastParam}" =~ '-.*=' ]]; then
# We are dealing with a flag with an =
flagPrefix="-P ${BASH_REMATCH}"
fi
# Prepare the command to obtain completions
requestComp="${words[1]} __complete ${words[2,-1]}"
if [ "${lastChar}" = "" ]; then
# If the last parameter is complete (there is a space following it)
# We add an extra empty parameter so we can indicate this to the go completion code.
__colima_debug "Adding extra empty parameter"
requestComp="${requestComp} \"\""
fi
__colima_debug "About to call: eval ${requestComp}"
# Use eval to handle any environment variables and such
out=$(eval ${requestComp} 2>/dev/null)
__colima_debug "completion output: ${out}"
# Extract the directive integer following a : from the last line
local lastLine
while IFS='\n' read -r line; do
lastLine=${line}
done < <(printf "%s\n" "${out[@]}")
__colima_debug "last line: ${lastLine}"
if [ "${lastLine[1]}" = : ]; then
directive=${lastLine[2,-1]}
# Remove the directive including the : and the newline
local suffix
(( suffix=${#lastLine}+2))
out=${out[1,-$suffix]}
else
# There is no directive specified. Leave $out as is.
__colima_debug "No directive found. Setting do default"
directive=0
fi
__colima_debug "directive: ${directive}"
__colima_debug "completions: ${out}"
__colima_debug "flagPrefix: ${flagPrefix}"
if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then
__colima_debug "Completion received error. Ignoring completions."
return
fi
local activeHelpMarker="_activeHelp_ "
local endIndex=${#activeHelpMarker}
local startIndex=$((${#activeHelpMarker}+1))
local hasActiveHelp=0
while IFS='\n' read -r comp; do
# Check if this is an activeHelp statement (i.e., prefixed with $activeHelpMarker)
if [ "${comp[1,$endIndex]}" = "$activeHelpMarker" ];then
__colima_debug "ActiveHelp found: $comp"
comp="${comp[$startIndex,-1]}"
if [ -n "$comp" ]; then
compadd -x "${comp}"
__colima_debug "ActiveHelp will need delimiter"
hasActiveHelp=1
fi
continue
fi
if [ -n "$comp" ]; then
# If requested, completions are returned with a description.
# The description is preceded by a TAB character.
# For zsh's _describe, we need to use a : instead of a TAB.
# We first need to escape any : as part of the completion itself.
comp=${comp//:/\\:}
local tab="$(printf '\t')"
comp=${comp//$tab/:}
__colima_debug "Adding completion: ${comp}"
completions+=${comp}
lastComp=$comp
fi
done < <(printf "%s\n" "${out[@]}")
# Add a delimiter after the activeHelp statements, but only if:
# - there are completions following the activeHelp statements, or
# - file completion will be performed (so there will be choices after the activeHelp)
if [ $hasActiveHelp -eq 1 ]; then
if [ ${#completions} -ne 0 ] || [ $((directive & shellCompDirectiveNoFileComp)) -eq 0 ]; then
__colima_debug "Adding activeHelp delimiter"
compadd -x "--"
hasActiveHelp=0
fi
fi
if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then
__colima_debug "Activating nospace."
noSpace="-S ''"
fi
if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then
__colima_debug "Activating keep order."
keepOrder="-V"
fi
if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
# File extension filtering
local filteringCmd
filteringCmd='_files'
for filter in ${completions[@]}; do
if [ ${filter[1]} != '*' ]; then
# zsh requires a glob pattern to do file filtering
filter="\*.$filter"
fi
filteringCmd+=" -g $filter"
done
filteringCmd+=" ${flagPrefix}"
__colima_debug "File filtering command: $filteringCmd"
_arguments '*:filename:'"$filteringCmd"
elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then
# File completion for directories only
local subdir
subdir="${completions[1]}"
if [ -n "$subdir" ]; then
__colima_debug "Listing directories in $subdir"
pushd "${subdir}" >/dev/null 2>&1
else
__colima_debug "Listing directories in ."
fi
local result
_arguments '*:dirname:_files -/'" ${flagPrefix}"
result=$?
if [ -n "$subdir" ]; then
popd >/dev/null 2>&1
fi
return $result
else
__colima_debug "Calling _describe"
if eval _describe $keepOrder "completions" completions $flagPrefix $noSpace; then
__colima_debug "_describe found some completions"
# Return the success of having called _describe
return 0
else
__colima_debug "_describe did not find completions."
__colima_debug "Checking if we should do file completion."
if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then
__colima_debug "deactivating file completion"
# We must return an error code here to let zsh know that there were no
# completions found by _describe; this is what will trigger other
# matching algorithms to attempt to find completions.
# For example zsh can match letters in the middle of words.
return 1
else
# Perform file completion
__colima_debug "Activating file completion"
# We must return the result of this command, so it must be the
# last command, or else we must store its result to return it.
_arguments '*:filename:_files'" ${flagPrefix}"
fi
fi
fi
}
# don't run the completion function when being source-ed or eval-ed
if [ "$funcstack[1]" = "_colima" ]; then
_colima
fi
+15
View File
@@ -0,0 +1,15 @@
#compdef compinit_doctor
local -a args
args=(
'(-h --help)'{-h,--help}'[Show help/usage]'
'(-s --status)'{-s,--status}'[Show current compinit/dump status (default)]'
'(-a --audit)'{-a,--audit}'[Run compaudit for insecure paths]'
'(-r --rebuild)'{-r,--rebuild}'[Force compinit -i -d and background zcompile]'
'(-S --snap)'{-S,--snap}'[Snapshot current $fpath to file]:snapshot file:_files'
'(-d --diff)'{-d,--diff}'[Diff current $fpath against a snapshot file]:snapshot file:_files'
'(-D --dump)'{-D,--dump}'[Override zcompdump path]:dump file:_files -g "*zcompdump(-.)"'
'(-j --json)'{-j,--json}'[Emit status as single JSON object]'
)
_arguments -s -S $args '*:file:_files'
+33
View File
@@ -0,0 +1,33 @@
#compdef confe
# Completion for the confe function
local -a topics opts
topics=(
alias
keybindings
options
path
packages
ssh
brewfile
)
opts=(
'--backup[Backup the file before editing]'
'-b[Backup the file before editing]'
'--staged[Stage the file into its git repo after editing]'
'-s[Stage the file into its git repo after editing]'
)
_arguments \
$opts \
'1:topic:->topic' \
'*:filename:_files' && return 0
case $state in
topic)
_describe 'topic' topics
;;
esac
+89
View File
@@ -0,0 +1,89 @@
#compdef copy_files
_copy_files() {
local -a dirs
local -a cp_hosts_default
local -a used_hosts avail_hosts
local _dotfiles="${DOTFILES:-$HOME/.dotfiles}"
local i host_mode=0 host_arg_index=0
cp_hosts_default=( $(_copy_files_ssh_hosts) )
[[ -d "$_dotfiles" ]] || return 1
dirs=(${(f)"$(print -rl -- $_dotfiles/*(/N:t))"})
for (( i = 2; i < CURRENT; i++ )); do
case "${words[i]}" in
-h|--hosts)
host_mode=1
host_arg_index=$i
;;
--)
(( host_mode )) && host_mode=0
;;
esac
done
if (( host_mode )); then
used_hosts=()
for (( i = host_arg_index + 1; i < CURRENT; i++ )); do
[[ "${words[i]}" == "--" ]] && break
used_hosts+=("${words[i]}")
done
avail_hosts=( "${(@)cp_hosts_default:|used_hosts}" )
compadd -S '' -- "${avail_hosts[@]}" --
return
fi
_describe -t dotfiles 'dotfiles subdirectory' dirs
compadd -S '' -- -h --hosts
}
_copy_files_ssh_hosts() {
local cfg="${HOME}/.ssh/config"
[[ -r "$cfg" ]] || return 0
awk '
BEGIN {
in_block = 0
has_hostname = 0
aliases = ""
}
/^[[:space:]]*#/ { next }
/^[[:space:]]*$/ { next }
tolower($1) == "host" {
if (in_block && has_hostname && aliases != "") {
print aliases
}
in_block = 1
has_hostname = 0
aliases = ""
for (i = 2; i <= NF; i++) {
if ($i ~ /[*?\[]/) {
continue
}
aliases = aliases $i "\n"
}
next
}
in_block && tolower($1) == "hostname" {
has_hostname = 1
next
}
END {
if (in_block && has_hostname && aliases != "") {
print aliases
}
}
' "$cfg" | awk '!seen[$0]++'
}
_copy_files "$@"
+11
View File
@@ -0,0 +1,11 @@
#compdef dcs
# dcs is a shim to dcsctl, so reuse the same completion.
# This ensures `dcs …` and `dcsctl …` behave identically.
_dcs() {
autoload -Uz _dcsctl
_dcsctl "$@"
}
_dcs "$@"
+445
View File
@@ -0,0 +1,445 @@
#compdef dcsctl
# --- helpers ---------------------------------------------------------------
_dcsctl__docker_contexts() {
local -a ctxs
ctxs=(${(f)"$(command docker context ls --format '{{.Name}}' 2>/dev/null)"})
_describe -t docker-contexts 'docker contexts' ctxs
}
_dcsctl__current_context() {
command docker context show 2>/dev/null
}
_dcsctl__control_plane_base() {
# Match dcsctl logic: base is $DCS_ROOT if set, else ~/.dcs
print -r -- "${DCS_ROOT:-$HOME/.dcs}"
}
_dcsctl__projects() {
local ctx base
ctx="$(_dcsctl__current_context)"
[[ -z "$ctx" ]] && return 0
base="$(_dcsctl__control_plane_base)/$ctx/compose"
[[ -d "$base" ]] || return 0
local -a ignored projects
ignored=(shared '@Recycle' '@Recently-Snapshot' '.DS_Store')
projects=()
local dir name
for dir in "$base"/*; do
[[ -d "$dir" ]] || continue
name="${dir:t}"
(( ${ignored[(I)$name]} )) && continue
projects+=("$name")
done
_describe -t dcs-projects 'projects' projects
}
_dcsctl__secret_names_from_dir() {
local ctx proj base projdir secretdir
ctx="$(_dcsctl__current_context)"
[[ -z "$ctx" ]] && return 1
proj="${words[4]}" # dcsctl secret add <project> <name>
[[ -z "$proj" ]] && return 1
base="$(_dcsctl__control_plane_base)/$ctx/compose"
projdir="$base/$proj"
secretdir="$projdir/secrets"
[[ -d "$secretdir" ]] || return 1
local -a names
names=()
local f n
for f in "$secretdir"/*.txt; do
[[ -f "$f" ]] || continue
n="${f:t}"
n="${n%.txt}"
names+=("$n")
done
(( ${#names} == 0 )) && return 1
_describe -t dcs-secrets 'secret names' names
}
# List service subdirectories in a swarm-mode project.
# Takes one argument: the project name.
_dcsctl__swarm_services() {
local ctx proj base projdir svcdir
ctx="$(_dcsctl__current_context)"
[[ -z "$ctx" ]] && return 1
proj="$1"
[[ -z "$proj" ]] && return 1
base="$(_dcsctl__control_plane_base)/$ctx/compose"
projdir="$base/$proj"
svcdir="$projdir/services"
[[ -d "$svcdir" ]] || return 1
local -a svcs
svcs=()
local dir name
for dir in "$svcdir"/*/; do
[[ -d "$dir" ]] || continue
name="${dir:t}"
svcs+=("$name")
done
(( ${#svcs} == 0 )) && return 1
_describe -t dcs-swarm-services 'services' svcs
}
# Detect whether a project is in swarm mode (has services/ dir).
_dcsctl__is_swarm() {
local ctx proj base projdir
ctx="$(_dcsctl__current_context)"
[[ -z "$ctx" ]] && return 1
proj="$1"
[[ -z "$proj" ]] && return 1
base="$(_dcsctl__control_plane_base)/$ctx/compose"
projdir="$base/$proj"
[[ -d "$projdir/services" ]]
}
# Fetch services for a given project by asking docker compose for the resolved config.
_dcsctl__services() {
local ctx proj base projdir
ctx="$(_dcsctl__current_context)"
[[ -z "$ctx" ]] && return 1
proj="${words[3]}" # dcsctl run <project> ...
[[ -z "$proj" ]] && return 1
base="$(_dcsctl__control_plane_base)/$ctx/compose"
projdir="$base/$proj"
[[ -d "$projdir" ]] || return 1
local env1 env2 env3
env1="$projdir/.env"
env2="$projdir/service.env"
env3="$projdir/service.secrets.env"
[[ -f "$env1" && -f "$env2" && -f "$env3" && -f "$projdir/docker-compose.yml" ]] || return 1
local -a svcs
svcs=(${(f)"$(
command docker --context "$ctx" compose \
--project-directory "$projdir" \
--project-name "$proj" \
--env-file "$env1" \
--env-file "$env2" \
--env-file "$env3" \
config --services 2>/dev/null
)"})
(( ${#svcs} == 0 )) && return 1
_describe -t dcs-services 'services' svcs
}
# Heuristic: decide if we are in a position where a service name is expected.
_dcsctl__maybe_complete_service() {
local subcmd cur
subcmd="${words[4]}" # dcsctl run <project> <subcmd> ...
cur="${words[CURRENT]}"
[[ "$cur" == -* ]] && return 1
case "$subcmd" in
logs|ps|stop|start|restart|up|pull|build|rm|kill|pause|unpause|top|exec)
_dcsctl__services
return $?
;;
esac
return 1
}
# Delegate completion to docker after we reconstruct words as docker compose ...
_dcsctl__docker_compose_delegate() {
local ctx proj base projdir
ctx="$(_dcsctl__current_context)"
[[ -z "$ctx" ]] && return 1
proj="${words[3]}"
[[ -z "$proj" ]] && return 1
base="$(_dcsctl__control_plane_base)/$ctx/compose"
projdir="$base/$proj"
local -a dc_words
dc_words=(docker --context "$ctx" compose --project-directory "$projdir" --project-name "$proj")
if (( ${#words} >= 4 )); then
dc_words+=("${words[@]:3}") # from 4th element
fi
local -a save_words
local save_cword
save_words=("${words[@]}")
save_cword=$CURRENT
words=("${dc_words[@]}")
CURRENT=${#words}
autoload -Uz _docker
_docker
words=("${save_words[@]}")
CURRENT=$save_cword
}
# Helper for edit --service completion: extract the project arg from the command
# line and complete swarm service names.
_dcsctl__swarm_services_for_edit() {
local proj=""
local i
for (( i=3; i <= ${#words}; i++ )); do
local w="${words[$i]}"
case "$w" in
-e|--env|-r|--runtime|-s|--secret) ;;
--service) (( i++ )) ;; # skip the next arg (the service value)
-*) ;;
*)
if [[ -z "$proj" ]]; then
proj="$w"
fi
;;
esac
done
[[ -z "$proj" ]] && return 1
_dcsctl__swarm_services "$proj"
}
# --- main completion -------------------------------------------------------
_dcsctl() {
local -a subcmds
subcmds=(
'new:Create a new project scaffold'
'verify:Verify and enforce host permissions for appdata bind mounts'
'run:Run docker compose for a project (compose mode)'
'up:Alias for run <project> up -d (compose mode)'
'down:Bring down a project (compose or swarm)'
'stop:Scale all services to 0 replicas (swarm projects only)'
'deploy:Merge service fragments and deploy as Docker Swarm stack'
'ls:Alias for docker compose ls'
'dir:Print the project directory, or a service directory in a swarm project'
'edit:Edit project files in $EDITOR'
'secret:Manage project secrets'
'service:Manage services within a swarm project'
'import:Import an existing docker-compose.yml into a DCS project'
'context:Manage DCS control-plane contexts'
'reload:Down, rebuild and up all containers within a DCS project'
'rename:Rename and update a DCS project'
'help:Show help for a command'
)
if (( CURRENT == 2 )); then
_describe -t commands 'dcsctl commands' subcmds
return
fi
local cmd
cmd="${words[2]}"
case "$cmd" in
new)
_arguments -C \
'(-v --verify)'{-v,--verify}'[Run verification after creating the project]' \
'--verbose[Verbose output for verification (used with --verify)]' \
'--compose[Create flat single-compose layout (legacy)]' \
'--service[Initial service name for swarm layout]:service name:' \
'1:project name:' \
&& return
;;
verify)
_arguments -C \
'--verbose[Show current vs expected ownership/mode while verifying (QNAP only)]' \
'1:project name:_dcsctl__projects' \
&& return
;;
run)
if (( CURRENT == 3 )); then
_dcsctl__projects
return
fi
if (( CURRENT >= 5 )); then
_dcsctl__maybe_complete_service && return
fi
_dcsctl__docker_compose_delegate
return
;;
up)
_arguments -C \
'(-v --verify)'{-v,--verify}'[Run `dcsctl verify` before running docker compose]' \
'1:project name:_dcsctl__projects' \
&& return
;;
down)
_arguments -C \
'1:project name:_dcsctl__projects' \
&& return
;;
stop)
_arguments -C \
'1:project name:_dcsctl__projects' \
&& return
;;
deploy)
_arguments -C \
'(-v --verify)'{-v,--verify}'[Run verification before deploying]' \
'--verbose[Verbose verification output]' \
'1:project name:_dcsctl__projects' \
&& return
;;
ls)
return
;;
dir)
if (( CURRENT == 3 )); then
_dcsctl__projects
return
fi
if (( CURRENT == 4 )); then
local proj="${words[3]}"
_dcsctl__swarm_services "$proj" && return
return 0
fi
;;
edit)
_arguments -C \
'(-e --env -r --runtime -s --secret)'{-e,--env}'[Edit .env]' \
'(-e --env -r --runtime -s --secret)'{-r,--runtime}'[Edit service.env]' \
'(-e --env -r --runtime -s --secret)'{-s,--secret}'[Edit service.secrets.env]' \
'--service[Target a specific service (swarm mode)]:service name:_dcsctl__swarm_services_for_edit' \
'1:project name:_dcsctl__projects' \
&& return
;;
secret)
if (( CURRENT == 3 )); then
_describe -t secret-subcmds 'secret commands' \
'add:Create/open secrets/<name>.txt in $EDITOR'
return
fi
local sub
sub="${words[3]}"
case "$sub" in
add)
if (( CURRENT == 4 )); then
_dcsctl__projects
return
fi
if (( CURRENT == 5 )); then
_dcsctl__secret_names_from_dir && return
return 0
fi
;;
esac
;;
service)
if (( CURRENT == 3 )); then
local -a service_subcmds
service_subcmds=(
'add:Add a new service to a swarm project'
'ls:List services in a swarm project'
)
_describe -t service-subcmds 'service commands' service_subcmds
return
fi
local sub
sub="${words[3]}"
case "$sub" in
add)
if (( CURRENT == 4 )); then
_dcsctl__projects
return
fi
# CURRENT == 5: free-form service name, no completions needed
;;
ls)
if (( CURRENT == 4 )); then
_dcsctl__projects
return
fi
;;
esac
;;
import)
_arguments -C \
'--env-file[Additional env file to ingest]:env file:_files' \
'--strict[Fail if compose violates template contract after import]' \
'--swarm[Import as swarm project, splitting services into per-service fragments]' \
'1:project name:_dcsctl__projects' \
'2:compose path:_files' \
&& return
;;
context)
if (( CURRENT == 3 )); then
_describe -t context-subcmds 'context commands' \
'init:Initialize ~/.dcs/<context> with env.system and compose/'
return
fi
local sub
sub="${words[3]}"
case "$sub" in
init)
if (( CURRENT == 4 )); then
_dcsctl__docker_contexts
return
fi
;;
esac
;;
reload)
_arguments -C \
'1:project name:_dcsctl__projects' \
&& return
;;
rename)
_arguments -C \
'1:project name:_dcsctl__projects' \
'2:new project name:' \
&& return
;;
help)
if (( CURRENT == 3 )); then
_describe -t commands 'dcsctl commands' subcmds
return
fi
;;
esac
_describe -t commands 'dcsctl commands' subcmds
}
_dcsctl "$@"
+12
View File
@@ -0,0 +1,12 @@
#compdef dot
_dot() {
local -a dirs
local _dotfiles="${DOTFILES:-$HOME/.dotfiles}"
[[ -d "$_dotfiles" ]] || return 1
dirs=(${(f)"$(print -rl -- $_dotfiles/*(/N:t))"})
_describe 'dotfiles subdirectory' dirs
}
+15
View File
@@ -0,0 +1,15 @@
#compdef dotfiles_doctor
# Zsh completion for dotfiles_doctor
# Supports: --timeline, --logfile=PATH (completes *.json)
# Usage: place this file on your $fpath, then compinit (or let your compinit.zsh rebuild)
local -a _args
_args=(
'--timeline[Show per-file start/end timeline with μs precision]'
'--logfile=[Path to NDJSON log (default: ~/zshrc-log.json)]:logfile:_files -g "*.json"'
'--help[Show usage]'
)
_arguments -s -S $_args \
'*:filename:_files'
+7
View File
@@ -0,0 +1,7 @@
#compdef find_dupes
_arguments \
'(-d --maxdepth)'{-d,--maxdepth}'[maximum recursion depth]:maxdepth (int):_guard "[0-9]#" "integer depth"' \
'(-r --regex)'{-r,--regex}'[POSIX extended regular expression]:regex (ERE)' \
'(-i --ignore-case)'{-i,--ignore-case}'[match regex case-insensitively]' \
'*: :->rest'
+228
View File
@@ -0,0 +1,228 @@
#compdef kubectl
compdef _kubectl kubectl
# Copyright 2016 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#compdef kubectl
compdef _kubectl kubectl
# zsh completion for kubectl -*- shell-script -*-
__kubectl_debug()
{
local file="$BASH_COMP_DEBUG_FILE"
if [[ -n ${file} ]]; then
echo "$*" >> "${file}"
fi
}
_kubectl()
{
local shellCompDirectiveError=1
local shellCompDirectiveNoSpace=2
local shellCompDirectiveNoFileComp=4
local shellCompDirectiveFilterFileExt=8
local shellCompDirectiveFilterDirs=16
local shellCompDirectiveKeepOrder=32
local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder
local -a completions
__kubectl_debug "\n========= starting completion logic =========="
__kubectl_debug "CURRENT: ${CURRENT}, words[*]: ${words[*]}"
# The user could have moved the cursor backwards on the command-line.
# We need to trigger completion from the $CURRENT location, so we need
# to truncate the command-line ($words) up to the $CURRENT location.
# (We cannot use $CURSOR as its value does not work when a command is an alias.)
words=("${=words[1,CURRENT]}")
__kubectl_debug "Truncated words[*]: ${words[*]},"
lastParam=${words[-1]}
lastChar=${lastParam[-1]}
__kubectl_debug "lastParam: ${lastParam}, lastChar: ${lastChar}"
# For zsh, when completing a flag with an = (e.g., kubectl -n=<TAB>)
# completions must be prefixed with the flag
setopt local_options BASH_REMATCH
if [[ "${lastParam}" =~ '-.*=' ]]; then
# We are dealing with a flag with an =
flagPrefix="-P ${BASH_REMATCH}"
fi
# Prepare the command to obtain completions
requestComp="${words[1]} __complete ${words[2,-1]}"
if [ "${lastChar}" = "" ]; then
# If the last parameter is complete (there is a space following it)
# We add an extra empty parameter so we can indicate this to the go completion code.
__kubectl_debug "Adding extra empty parameter"
requestComp="${requestComp} \"\""
fi
__kubectl_debug "About to call: eval ${requestComp}"
# Use eval to handle any environment variables and such
out=$(eval ${requestComp} 2>/dev/null)
__kubectl_debug "completion output: ${out}"
# Extract the directive integer following a : from the last line
local lastLine
while IFS='\n' read -r line; do
lastLine=${line}
done < <(printf "%s\n" "${out[@]}")
__kubectl_debug "last line: ${lastLine}"
if [ "${lastLine[1]}" = : ]; then
directive=${lastLine[2,-1]}
# Remove the directive including the : and the newline
local suffix
(( suffix=${#lastLine}+2))
out=${out[1,-$suffix]}
else
# There is no directive specified. Leave $out as is.
__kubectl_debug "No directive found. Setting do default"
directive=0
fi
__kubectl_debug "directive: ${directive}"
__kubectl_debug "completions: ${out}"
__kubectl_debug "flagPrefix: ${flagPrefix}"
if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then
__kubectl_debug "Completion received error. Ignoring completions."
return
fi
local activeHelpMarker="_activeHelp_ "
local endIndex=${#activeHelpMarker}
local startIndex=$((${#activeHelpMarker}+1))
local hasActiveHelp=0
while IFS='\n' read -r comp; do
# Check if this is an activeHelp statement (i.e., prefixed with $activeHelpMarker)
if [ "${comp[1,$endIndex]}" = "$activeHelpMarker" ];then
__kubectl_debug "ActiveHelp found: $comp"
comp="${comp[$startIndex,-1]}"
if [ -n "$comp" ]; then
compadd -x "${comp}"
__kubectl_debug "ActiveHelp will need delimiter"
hasActiveHelp=1
fi
continue
fi
if [ -n "$comp" ]; then
# If requested, completions are returned with a description.
# The description is preceded by a TAB character.
# For zsh's _describe, we need to use a : instead of a TAB.
# We first need to escape any : as part of the completion itself.
comp=${comp//:/\\:}
local tab="$(printf '\t')"
comp=${comp//$tab/:}
__kubectl_debug "Adding completion: ${comp}"
completions+=${comp}
lastComp=$comp
fi
done < <(printf "%s\n" "${out[@]}")
# Add a delimiter after the activeHelp statements, but only if:
# - there are completions following the activeHelp statements, or
# - file completion will be performed (so there will be choices after the activeHelp)
if [ $hasActiveHelp -eq 1 ]; then
if [ ${#completions} -ne 0 ] || [ $((directive & shellCompDirectiveNoFileComp)) -eq 0 ]; then
__kubectl_debug "Adding activeHelp delimiter"
compadd -x "--"
hasActiveHelp=0
fi
fi
if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then
__kubectl_debug "Activating nospace."
noSpace="-S ''"
fi
if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then
__kubectl_debug "Activating keep order."
keepOrder="-V"
fi
if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
# File extension filtering
local filteringCmd
filteringCmd='_files'
for filter in ${completions[@]}; do
if [ ${filter[1]} != '*' ]; then
# zsh requires a glob pattern to do file filtering
filter="\*.$filter"
fi
filteringCmd+=" -g $filter"
done
filteringCmd+=" ${flagPrefix}"
__kubectl_debug "File filtering command: $filteringCmd"
_arguments '*:filename:'"$filteringCmd"
elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then
# File completion for directories only
local subdir
subdir="${completions[1]}"
if [ -n "$subdir" ]; then
__kubectl_debug "Listing directories in $subdir"
pushd "${subdir}" >/dev/null 2>&1
else
__kubectl_debug "Listing directories in ."
fi
local result
_arguments '*:dirname:_files -/'" ${flagPrefix}"
result=$?
if [ -n "$subdir" ]; then
popd >/dev/null 2>&1
fi
return $result
else
__kubectl_debug "Calling _describe"
if eval _describe $keepOrder "completions" completions $flagPrefix $noSpace; then
__kubectl_debug "_describe found some completions"
# Return the success of having called _describe
return 0
else
__kubectl_debug "_describe did not find completions."
__kubectl_debug "Checking if we should do file completion."
if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then
__kubectl_debug "deactivating file completion"
# We must return an error code here to let zsh know that there were no
# completions found by _describe; this is what will trigger other
# matching algorithms to attempt to find completions.
# For example zsh can match letters in the middle of words.
return 1
else
# Perform file completion
__kubectl_debug "Activating file completion"
# We must return the result of this command, so it must be the
# last command, or else we must store its result to return it.
_arguments '*:filename:_files'" ${flagPrefix}"
fi
fi
fi
}
# don't run the completion function when being source-ed or eval-ed
if [ "$funcstack[1]" = "_kubectl" ]; then
_kubectl
fi
+28
View File
@@ -0,0 +1,28 @@
#compdef pdir
_pdir_projects() {
local ctx base
ctx="$(docker context show 2>/dev/null)"
[[ -z "$ctx" ]] && return 0
# Respect DOCKER_DIR override (same as your dcsctl behavior)
base="${DOCKER_DIR:-$HOME/.dcs}"
base="$base/$ctx/compose"
[[ -d "$base" ]] || return 0
local -a ignored projects
ignored=(shared '@Recycle' '@Recently-Snapshot' '.DS_Store')
projects=()
local dir name
for dir in "$base"/*; do
[[ -d "$dir" ]] || continue
name="${dir:t}"
(( ${ignored[(I)$name]} )) && continue
projects+=("$name")
done
_describe -t dcs-projects 'projects' projects
}
_arguments -C '1:project:_pdir_projects'