Skip to content
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
Expand Down
126 changes: 126 additions & 0 deletions lib/completions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
_u7_complete_entities() {
local verb="$1" cur="$2"
case "$verb" in
show|sh)
COMPREPLY=($(compgen -W "ip csv json line ssl files diff cpu memory disk processes port usage network git env http docker system definition functions --help" -- "$cur"))
;;
make|mk)
COMPREPLY=($(compgen -W "dir file password user copy link archive clone template sequence --help" -- "$cur"))
;;
drop|dr)
COMPREPLY=($(compgen -W "file dir dirs files line lines column duplicates process user docker --help" -- "$cur"))
;;
convert|cv)
COMPREPLY=($(compgen -W "archive files image video json yaml csv case spaces --help" -- "$cur"))
;;
move|mv)
COMPREPLY=($(compgen -W "file sync --help" -- "$cur"))
;;
set|st)
COMPREPLY=($(compgen -W "text slashes tabs perms owner --help" -- "$cur"))
;;
run|rn)
COMPREPLY=($(compgen -W "job script check terminal --help" -- "$cur"))
;;
esac
}

_u7_complete_args() {
local verb="$1" entity="$2" cur="$3"
case "$verb" in
show|sh)
case "$entity" in
ip) COMPREPLY=($(compgen -W "external internal connected" -- "$cur")) ;;
processes) COMPREPLY=($(compgen -W "running by" -- "$cur")) ;;
files) COMPREPLY=($(compgen -W "match by" -- "$cur")) ;;
usage) COMPREPLY=($(compgen -W "disk directories" -- "$cur")) ;;
git) COMPREPLY=($(compgen -W "authors branches tags log status diff remotes" -- "$cur")) ;;
env) COMPREPLY=($(compgen -W "match" -- "$cur")) ;;
http) COMPREPLY=($(compgen -W "get head headers" -- "$cur")) ;;
docker) COMPREPLY=($(compgen -W "containers images volumes networks all" -- "$cur")) ;;
*) _filedir ;;
esac
;;
Comment on lines +21 to +43
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 COMPREPLY word-splitting on special characters in $cur

Every COMPREPLY=($(compgen -W "..." -- "$cur")) assignment is subject to word-splitting and glob expansion on the result. If $cur contains spaces, tabs, or glob metacharacters the array can silently grow extra elements or collapse. The safe idiom is to use mapfile:

mapfile -t COMPREPLY < <(compgen -W "ip csv json line ssl ..." -- "$cur")

This applies throughout both _u7_complete_entities (every compgen call on lines 23, 26, 29, 32, 35, 38, 41) and _u7_complete_args (lines 51–98).

Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/completions.sh
Line: 21-43

Comment:
**`COMPREPLY` word-splitting on special characters in `$cur`**

Every `COMPREPLY=($(compgen -W "..." -- "$cur"))` assignment is subject to word-splitting and glob expansion on the result. If `$cur` contains spaces, tabs, or glob metacharacters the array can silently grow extra elements or collapse. The safe idiom is to use `mapfile`:

```bash
mapfile -t COMPREPLY < <(compgen -W "ip csv json line ssl ..." -- "$cur")
```

This applies throughout both `_u7_complete_entities` (every `compgen` call on lines 23, 26, 29, 32, 35, 38, 41) and `_u7_complete_args` (lines 51–98).

How can I resolve this? If you propose a fix, please make it concise.

make|mk)
case "$entity" in
copy|link) _filedir ;;
template) COMPREPLY=($(compgen -W "python node bash web" -- "$cur")) ;;
esac
;;
drop|dr)
case "$entity" in
dirs) COMPREPLY=($(compgen -W "if" -- "$cur")) ;;
files) COMPREPLY=($(compgen -W "but" -- "$cur")) ;;
lines) COMPREPLY=($(compgen -W "if" -- "$cur")) ;;
docker) COMPREPLY=($(compgen -W "container image volume prune" -- "$cur")) ;;
*) _filedir ;;
esac
;;
convert|cv)
case "$entity" in
archive|files) COMPREPLY=($(compgen -W "to" -- "$cur")) ;;
png|jpg|jpeg|gif) COMPREPLY=($(compgen -W "to" -- "$cur")) ;;
case) COMPREPLY=($(compgen -W "upper lower" -- "$cur")) ;;
spaces) COMPREPLY=($(compgen -W "to" -- "$cur")) ;;
*) _filedir ;;
esac
;;
set|st)
case "$entity" in
slashes) COMPREPLY=($(compgen -W "back forward" -- "$cur")) ;;
tabs) COMPREPLY=($(compgen -W "to" -- "$cur")) ;;
perms|owner) COMPREPLY=($(compgen -W "to" -- "$cur")) ;;
*) _filedir ;;
esac
;;
run|rn)
case "$entity" in
check) COMPREPLY=($(compgen -W "syntax" -- "$cur")) ; _filedir ;;
script) _filedir ;;
esac
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 image/video/json/csv entities never matched by completion rules

The png|jpg|jpeg|gif pattern matches the entity word (the second argument after the verb), but _u7_convert uses image as the entity name for image conversion — not the file extension. So u7 cv image foo.png <tab> falls through to *) _filedir ;; and never offers to as a completion.

The same gap applies to video, json, and csv which are also real entities in lib/convert.sh but are absent from this case statement.

Suggested change
esac
archive|files|image|video|json|csv) COMPREPLY=($(compgen -W "to" -- "$cur")) ;;

The old png|jpg|jpeg|gif pattern can be removed — those are never used as the entity word.

Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/completions.sh
Line: 80

Comment:
**`image`/`video`/`json`/`csv` entities never matched by completion rules**

The `png|jpg|jpeg|gif` pattern matches the *entity* word (the second argument after the verb), but `_u7_convert` uses `image` as the entity name for image conversion — not the file extension. So `u7 cv image foo.png <tab>` falls through to `*) _filedir ;;` and never offers `to` as a completion.

The same gap applies to `video`, `json`, and `csv` which are also real entities in `lib/convert.sh` but are absent from this case statement.

```suggestion
        archive|files|image|video|json|csv) COMPREPLY=($(compgen -W "to" -- "$cur")) ;;
```

The old `png|jpg|jpeg|gif` pattern can be removed — those are never used as the entity word.

How can I resolve this? If you propose a fix, please make it concise.

;;
esac
}

_u7_completions() {
local cur prev words cword
_init_completion 2>/dev/null || {
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
words=("${COMP_WORDS[@]}")
cword=$COMP_CWORD
}

local verbs="show sh make mk drop dr convert cv move mv set st run rn --help"
local opts="-n --dry-run"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 _filedir overwrites the syntax completion

_filedir replaces COMPREPLY entirely, so the syntax suggestion set on the same line is always discarded. A user typing u7 rn check <tab> will see only filenames, never syntax.

Suggested change
check) COMPREPLY=($(compgen -W "syntax" -- "$cur")) ;;

File-path completion is only needed at a deeper position (after syntax in file), and it already falls through to the *) _filedir ;; fallback there.

Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/completions.sh
Line: 96

Comment:
**`_filedir` overwrites the `syntax` completion**

`_filedir` replaces `COMPREPLY` entirely, so the `syntax` suggestion set on the same line is always discarded. A user typing `u7 rn check <tab>` will see only filenames, never `syntax`.

```suggestion
        check) COMPREPLY=($(compgen -W "syntax" -- "$cur")) ;;
```

File-path completion is only needed at a deeper position (after `syntax in file`), and it already falls through to the `*) _filedir ;;` fallback there.

How can I resolve this? If you propose a fix, please make it concise.

# Adjust for dry-run flag
local verb_idx=1
if [[ "${words[1]}" == "-n" || "${words[1]}" == "--dry-run" ]]; then
verb_idx=2
fi
local entity_idx=$((verb_idx + 1))

# Completing verb position
if [[ "$cword" -le "$verb_idx" ]]; then
if [[ "$cword" -eq 1 ]]; then
COMPREPLY=($(compgen -W "$verbs $opts" -- "$cur"))
else
COMPREPLY=($(compgen -W "$verbs" -- "$cur"))
fi
return
fi

# Completing entity position
if [[ "$cword" -eq "$entity_idx" ]]; then
_u7_complete_entities "${words[$verb_idx]}" "$cur"
return
fi

# Completing arguments
_u7_complete_args "${words[$verb_idx]}" "${words[$entity_idx]}" "$cur"
}

if [[ $- == *i* ]]; then
complete -F _u7_completions u7
fi
Loading
Loading