feat(cli): improve file discovery and completion
- Render remote files as an aligned table with JSON and TSV alternatives. - Add Bash and Zsh completion for commands, options, paths, and remote files. - Allow downloads by exact filename while rejecting ambiguous duplicate names. - Cover table formatting, completion scripts, and selector resolution with tests.
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
from __future__ import annotations
|
||||
|
||||
_ZSH = r'''# nanoshare zsh completion -- add to ~/.zshrc: eval "$(nanoshare completion zsh)"
|
||||
_nanoshare_files() {
|
||||
local id name size
|
||||
while IFS=$'\t' read -r id name size; do
|
||||
[[ -n $id ]] && printf '%s:%s\n' "$id" "$name"
|
||||
done < <(nanoshare list --format tsv 2>/dev/null)
|
||||
}
|
||||
|
||||
_nanoshare() {
|
||||
local -a commands common_opts login_opts sync_opts watch_opts download_opts
|
||||
commands=(login upload list download sync watch completion)
|
||||
common_opts=(--config --url --token --refresh-token --token-url --source --timeout --node)
|
||||
login_opts=(--config --node --source --scope --callback-host --callback-port --login-timeout --timeout --no-browser)
|
||||
sync_opts=($common_opts --note --expires --delete)
|
||||
watch_opts=($sync_opts --interval)
|
||||
download_opts=($common_opts --output -o)
|
||||
|
||||
if (( CURRENT == 2 )); then
|
||||
compadd -- $commands
|
||||
return
|
||||
fi
|
||||
|
||||
case ${words[2]} in
|
||||
login)
|
||||
compadd -- $login_opts
|
||||
;;
|
||||
upload)
|
||||
compadd -- $common_opts --name --note --expires
|
||||
_files
|
||||
;;
|
||||
list)
|
||||
compadd -- $common_opts --format
|
||||
;;
|
||||
download)
|
||||
if (( CURRENT == 3 )); then
|
||||
local -a remote_files
|
||||
remote_files=("${(@f)$(_nanoshare_files)}")
|
||||
_describe 'remote file' remote_files
|
||||
else
|
||||
compadd -- $download_opts
|
||||
_files
|
||||
fi
|
||||
;;
|
||||
sync|watch)
|
||||
compadd -- ${(P)${:-${words[2]}_opts}}
|
||||
_files -/
|
||||
;;
|
||||
completion)
|
||||
(( CURRENT == 3 )) && compadd -- zsh bash
|
||||
;;
|
||||
esac
|
||||
}
|
||||
compdef _nanoshare nanoshare
|
||||
'''
|
||||
|
||||
_BASH = r'''# nanoshare bash completion -- add to ~/.bashrc: eval "$(nanoshare completion bash)"
|
||||
_nanoshare_files() {
|
||||
nanoshare list --format tsv 2>/dev/null
|
||||
}
|
||||
|
||||
_nanoshare() {
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}" cmd="${COMP_WORDS[1]}"
|
||||
local commands="login upload list download sync watch completion"
|
||||
local common_opts="--config --url --token --refresh-token --token-url --source --timeout --node"
|
||||
local login_opts="--config --node --source --scope --callback-host --callback-port --login-timeout --timeout --no-browser"
|
||||
local sync_opts="$common_opts --note --expires --delete"
|
||||
local watch_opts="$sync_opts --interval"
|
||||
local download_opts="$common_opts --output -o"
|
||||
|
||||
if [ "$COMP_CWORD" -eq 1 ]; then
|
||||
COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
|
||||
return
|
||||
fi
|
||||
|
||||
case "$cmd" in
|
||||
login)
|
||||
COMPREPLY=( $(compgen -W "$login_opts" -- "$cur") ) ;;
|
||||
upload)
|
||||
COMPREPLY=( $(compgen -W "$common_opts --name --note --expires" -- "$cur") ) ;;
|
||||
list)
|
||||
COMPREPLY=( $(compgen -W "$common_opts --format" -- "$cur") ) ;;
|
||||
download)
|
||||
if [ "$COMP_CWORD" -eq 2 ]; then
|
||||
COMPREPLY=( $(compgen -W "$(_nanoshare_files | cut -f1)" -- "$cur") )
|
||||
else
|
||||
COMPREPLY=( $(compgen -W "$download_opts" -- "$cur") )
|
||||
fi ;;
|
||||
sync)
|
||||
COMPREPLY=( $(compgen -W "$sync_opts" -- "$cur") ) ;;
|
||||
watch)
|
||||
COMPREPLY=( $(compgen -W "$watch_opts" -- "$cur") ) ;;
|
||||
completion)
|
||||
[ "$COMP_CWORD" -eq 2 ] && COMPREPLY=( $(compgen -W "zsh bash" -- "$cur") ) ;;
|
||||
esac
|
||||
}
|
||||
complete -F _nanoshare nanoshare
|
||||
'''
|
||||
|
||||
|
||||
def script(shell: str) -> str:
|
||||
if shell == 'zsh':
|
||||
return _ZSH
|
||||
if shell == 'bash':
|
||||
return _BASH
|
||||
raise ValueError(f'unsupported shell: {shell}')
|
||||
Reference in New Issue
Block a user