Skip to content

Commit 7a4bf4f

Browse files
guohengccmywish
authored andcommitted
Add bash-autocompletion feature-linux test
1 parent 8c1efce commit 7a4bf4f

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed

tool/chsrc_completion.sh

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
# --------------------------------------------------------------
2+
# SPDX-License-Identifier: GPL-3.0-or-later
3+
# --------------------------------------------------------------
4+
# Build File : chsrc_completion.sh
5+
# File Authors : 郭恒 <2085471348@qq.com>
6+
#
7+
# Created On : <2026-03-19>
8+
# Last Modified : <2026-03-20>
9+
# ==============================================================================
10+
# chsrc 的 Bash 自动补全脚本(当前仅在Linux Ubuntu中测试过)
11+
#
12+
# 目标操作系统:Linux
13+
#
14+
# source chsrc_completion.sh # 当前终端立即生效
15+
# ==============================================================================
16+
17+
_chsrc() {
18+
19+
# 初始化部分
20+
21+
## 手动划分字符串
22+
local line="${COMP_LINE:0:$COMP_POINT}" # COMP_LINE的从0到光标的所有输入,作为一个字符串
23+
read -ra words <<< "$line" # 按IFS重新分词,默认分隔符是" \t\n"
24+
cword=$(( ${#words[@]} - 1 )) # 下表从0开始,当前词下标
25+
26+
### 如果行末是空格,说明需要补充新的词
27+
if [[ "${line: -1}" == " " ]]; then
28+
words+=("")
29+
cword=$(( ${#words[@]} - 1 ))
30+
fi
31+
32+
cur="${words[$cword]}"
33+
34+
## 定义具体target
35+
local targets_lang="gem ruby rb rubygem rubygems bundler
36+
python pypi py
37+
pip
38+
poetry
39+
pdm
40+
rye
41+
uv
42+
js javascript node nodejs
43+
bun
44+
npm
45+
yarn
46+
pnpm
47+
nvm
48+
perl cpan
49+
php composer
50+
lua luarocks
51+
go golang goproxy
52+
rust cargo crate crates
53+
rustup
54+
java maven mvn maven-daemon mvnd gradle
55+
clojure clojars cloj lein
56+
dart pub
57+
flutter
58+
nuget net .net dotnet
59+
haskell cabal stack hackage
60+
ocaml opam
61+
r cran
62+
julia"
63+
64+
local targets_os="ubuntu zorinos
65+
linuxmint
66+
debian
67+
fedora
68+
opensuse opensuse-leap opensuse-tumbleweed
69+
kali
70+
msys2 msys
71+
arch archlinux
72+
archlinuxcn archcn
73+
manjaro
74+
gentoo
75+
rocky rockylinux
76+
alma almalinux
77+
alpine
78+
voidlinux
79+
solus
80+
trisquel
81+
linuxlite
82+
ros ros2
83+
raspi raspberrypi
84+
armbian
85+
openwrt opkg LEDE
86+
termux
87+
openkylin
88+
openeuler
89+
anolis openanolis
90+
deepin
91+
freebsd
92+
netbsd
93+
openbsd"
94+
95+
local targets_ware="winget
96+
brew homebrew
97+
cocoa cocoapods cocoapod
98+
docker dockerhub
99+
flatpak flathub
100+
nix
101+
guix
102+
emacs elpa
103+
latex ctan tex texlive miktex tlmgr mpm
104+
conda anaconda"
105+
106+
local all_targets="$targets_lang $targets_os $targets_ware"
107+
local options="-dry -scope= -ipv6 -english -en -no-color -h --help"
108+
local scope_options="project user system"
109+
local commands="help issue list ls measure cesu get set reset"
110+
111+
# 逻辑部分
112+
113+
# 扫描已输入词,跳过选项,依次填入 cmd / second_arg,并计数
114+
# 找到第一个非选项词作为子命令
115+
local non_opts=()
116+
for w in "${words[@]:1:cword-1}"; do
117+
[[ $w != -* ]] && non_opts+=("$w")
118+
done
119+
# 若有non_opts[0]
120+
local cmd=${non_opts[0]}
121+
122+
if [[ -z "$cmd" ]]; then
123+
COMPREPLY=( $(compgen -W "$commands $options" -- "$cur") )
124+
return 0
125+
fi
126+
127+
local second_arg="${non_opts[1]:-}"
128+
local args_after=${#non_opts[@]}
129+
130+
131+
# 补全-scope=project这样的选项时,需要手动控制,先补全-scope=再补全后面的
132+
# 作为一个函数来实现
133+
_complete_options() {
134+
if [[ $cur == -scope=* ]]; then
135+
# cur="-scope=",匹配
136+
COMPREPLY=( $(compgen -W "$scope_options" -- "${cur#-scope=}") )
137+
elif [[ $cur == -* ]]; then
138+
COMPREPLY=( $(compgen -W "$options" -- "$cur") )
139+
# 补全 -scope 本身时不加尾部空格,让用户可以继续输入=
140+
if [[ ${COMPREPLY[0]} == "-scope=" ]]; then
141+
# 对已经补全的候选项做出调整,补全出-scope=后不跟空格,才能匹配scope_options
142+
compopt -o nospace
143+
fi
144+
fi
145+
}
146+
147+
# 主要的补全逻辑
148+
case "$cmd" in
149+
help|h|issue|i)
150+
COMPREPLY=( $(compgen -W "help issue" -- $cur))
151+
;;
152+
list|ls|l)
153+
if [[ $args_after -eq 1 ]]; then
154+
COMPREPLY=( $(compgen -W "mirror target os lang ware $all_targets " -- $cur) )
155+
else
156+
_complete_options
157+
fi
158+
;;
159+
measure|m|cesu)
160+
if [[ $args_after -eq 1 && $cur != -* ]]; then
161+
COMPREPLY=( $(compgen -W "$all_targets" -- "$cur") )
162+
else
163+
_complete_options
164+
fi
165+
;;
166+
get|g)
167+
if [[ $args_after -eq 1 && $cur != -* ]]; then
168+
COMPREPLY=( $(compgen -W "$all_targets" -- "$cur") )
169+
else
170+
COMPREPLY=( $(compgen -W "$options" -- $cur) )
171+
fi
172+
;;
173+
reset)
174+
if [[ $args_after -eq 1 ]]; then
175+
COMPREPLY=( $(compgen -W "$all_targets" -- $cur) )
176+
else
177+
COMPREPLY=( $(compgen -W "$options" -- $cur) )
178+
fi
179+
;;
180+
set|s)
181+
if [[ $args_after -eq 1 && $cur != -* ]]; then
182+
COMPREPLY=( $(compgen -W "$all_targets" -- "$cur") )
183+
elif [[ $args_after -eq 2 ]]; then
184+
COMPREPLY=( $(compgen -W "first" -- $cur) )
185+
else
186+
_complete_options
187+
fi
188+
;;
189+
*)
190+
_complete_options
191+
;;
192+
193+
esac
194+
return 0
195+
}
196+
197+
198+
# 注册, 作用于当前终端
199+
complete -F _chsrc chsrc

0 commit comments

Comments
 (0)