feat: add script catalog and -h help for all dotfile scripts

Introduce ff script -h with auto descriptions, shared help.sh, and usage flags across script/*.sh.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-25 15:09:35 +08:00
parent 1f6b042b26
commit 67291a9a50
36 changed files with 1056 additions and 442 deletions
+17 -15
View File
@@ -65,22 +65,24 @@ complete -c ff -n "__fish_seen_subcommand_from ssh copy; and test (count (comman
# script 子命令的补全 - 动态列出 script 目录下的脚本
function __ff_list_scripts
set -l script_dir ~/.dotfile/script
if test -d $script_dir
# 列出 .sh 文件
for script in $script_dir/*.sh
if test -f $script
basename $script | string replace -r '\.sh$' ''
end
end
# 列出 .py 文件
for script in $script_dir/*.py
if test -f $script
basename $script | string replace -r '\.py$' ''
end
end
if not functions -q script-list-names
source ~/.dotfile/fish/functions/script-catalog.fish
end
script-list-names
end
function __ff_complete_scripts
if not functions -q script-extract-description
source ~/.dotfile/fish/functions/script-catalog.fish
end
for name in (script-list-names)
set -l path (script-resolve-path $name)
set -l desc (script-extract-description $path)
printf "%s\t%s\n" $name $desc
end
end
complete -c ff -n "__fish_seen_subcommand_from script" -a '(__ff_list_scripts)' -d "Script name"
complete -c ff -n "__fish_seen_subcommand_from script; and test (count (commandline -opc)) -eq 2" -s h -l help -d "List all scripts and descriptions"
complete -c ff -n "__fish_seen_subcommand_from script; and test (count (commandline -opc)) -eq 2" -a help -d "List all scripts and descriptions"
complete -c ff -n "__fish_seen_subcommand_from script; and not __fish_seen_subcommand_from help -h --help (__ff_list_scripts)" -a '(__ff_complete_scripts)' -d "Script name"
+27 -50
View File
@@ -1,65 +1,42 @@
# Execute script from script directory
function execute-script
# 执行 script 目录下的脚本
if not functions -q script-show-catalog
source ~/.dotfile/fish/functions/script-catalog.fish
end
set -l dotfile_dir ~/.dotfile
set -l script_dir $dotfile_dir/script
set -l script_name $argv[1]
if test -z "$script_name"
echo "Error: No script name specified"
echo "Usage: execute-script <script_name> [args...]"
echo ""
echo "Available scripts:"
if test -d $script_dir
for script in $script_dir/*.sh $script_dir/*.py
if test -f $script
set -l basename (basename $script)
echo " $basename"
end
end
# ff script -h / --help / help
if test -z "$script_name"; or contains -- $script_name -h --help help
if test -z "$script_name"; or test (count $argv) -eq 1
script-show-catalog
return 0
end
end
if test -z "$script_name"
script-show-catalog
return 1
end
# 尝试不同的扩展名
set -l script_path ""
for ext in sh py
set -l test_path $script_dir/$script_name.$ext
if test -f $test_path
set script_path $test_path
break
end
end
# 如果没找到,尝试直接使用提供的名称
if test -z "$script_path"
set script_path $script_dir/$script_name
end
if test -f $script_path
set -l script_path (script-resolve-path $script_name 2>/dev/null; or echo "")
if test -n "$script_path" -a -f "$script_path"
echo "Running: $script_path"
if test -x $script_path
$script_path $argv[2..-1]
else if string match -q "*.py" $script_path
python3 $script_path $argv[2..-1]
else
# 根据文件类型选择解释器
if string match -q "*.py" $script_path
python3 $script_path $argv[2..-1]
else
bash $script_path $argv[2..-1]
end
bash $script_path $argv[2..-1]
end
else
echo "Error: Script not found: $script_name"
echo "Available scripts:"
if test -d $script_dir
for script in $script_dir/*.sh $script_dir/*.py
if test -f $script
set -l basename (basename $script)
echo " $basename"
end
end
end
return 1
return $status
end
end
echo "Error: Script not found: $script_name"
echo ""
script-show-catalog
return 1
end
+126
View File
@@ -0,0 +1,126 @@
# 列举 ~/.dotfile/script 下脚本及从文件头注释提取的简短说明
function script-extract-description --argument filepath
if not test -f "$filepath"
echo "(无描述)"
return
end
set -l past_shebang 0
set -l candidates
for line in (cat "$filepath")
if string match -qr '^#!/' -- $line
set past_shebang 1
continue
end
if test $past_shebang -eq 0
continue
end
set line (string trim $line)
if test -z "$line"
if test (count $candidates) -gt 0
break
end
continue
end
if not string match -qr '^#' -- $line
break
end
set line (string replace -r '^#\s*' '' $line)
if string match -qr '^---' -- $line
continue
end
if string match -qr '^(用法|Usage|示例|Example)' -- $line
continue
end
if string match -qr '^\./' -- $line
continue
end
if string match -qr '^https?://' -- $line
continue
end
# 行内 “# 用法” 类注释
if string match -qr '#\s*(用法|Usage)' -- $line
continue
end
set candidates $candidates $line
if test (count $candidates) -ge 8
break
end
end
if test (count $candidates) -eq 0
echo "(无描述)"
return
end
for c in $candidates
if string match -qr '(脚本|安装|初始化|清理|扫描|切换|配置|用于|镜像|凭据|用户组|免密|Install|Init|Clean|Toggle)' -- $c
echo $c
return
end
end
for c in $candidates
if test (string length $c) -ge 10
echo $c
return
end
end
echo $candidates[1]
end
function script-list-names
set -l script_dir ~/.dotfile/script
set -l names
if not test -d $script_dir
return
end
for script in $script_dir/*.sh $script_dir/*.py
if test -f $script
set -l name (basename $script)
set name (string replace -r '\.(sh|py)$' '' $name)
set names $names $name
end
end
string join \n $names | sort
end
function script-resolve-path --argument name
set -l script_dir ~/.dotfile/script
for ext in sh py
set -l path "$script_dir/$name.$ext"
if test -f $path
echo $path
return 0
end
end
if test -f "$script_dir/$name"
echo "$script_dir/$name"
return 0
end
return 1
end
function script-show-catalog
set -l script_dir ~/.dotfile/script
echo "Usage: ff script <name> [args...]"
echo ""
echo "Scripts in $script_dir:"
echo ""
for name in (script-list-names)
set -l path (script-resolve-path $name)
set -l desc (script-extract-description $path)
printf " %-22s %s\n" $name $desc
end
echo ""
echo "提示: ff script <name> -h 查看单个脚本内的详细帮助"
end