1 | #!/usr/bin/env bash
|
2 | #
|
3 | # Usage:
|
4 | # ./complete.sh <function name>
|
5 |
|
6 | set -o nounset
|
7 | set -o pipefail
|
8 | set -o errexit
|
9 |
|
10 | readonly BASH_COMP=../bash-completion/bash_completion
|
11 |
|
12 | # This version is too new to run on my Ubuntu machine! Uses git --list-cmds.
|
13 | #readonly GIT_COMP=testdata/completion/git-completion.bash
|
14 |
|
15 | readonly GIT_COMP=testdata/completion/git
|
16 |
|
17 | grep-extglob() {
|
18 | grep -E --color '[@?!+*]\(' "$@"
|
19 | }
|
20 |
|
21 | # A very common case is something like:
|
22 | #
|
23 | # --host|-!(-*)h
|
24 | #
|
25 | # which matches --host, -h, -ah, but NOT --h.
|
26 | #
|
27 | # https://github.com/oilshell/oil/issues/192
|
28 | grep-extglob-negation() {
|
29 | grep -E --color '!\(' $BASH_COMP ../bash-completion/completions/*
|
30 | }
|
31 |
|
32 | audit() {
|
33 | local file=${1:-$GIT_COMP}
|
34 |
|
35 | echo
|
36 | echo --
|
37 | # Search for completion builtin usage
|
38 | grep -E -w --color 'complete|compgen|compopt' $file
|
39 |
|
40 | echo
|
41 | echo --
|
42 | # Search for special completion var usage
|
43 | grep -E --color 'COMP_[A-Z]+' $file
|
44 |
|
45 | echo
|
46 | echo --
|
47 | # Search for array usage
|
48 | grep -E --color ']=' $file
|
49 | grep -E --color ']+=' $file
|
50 |
|
51 | # extended glob
|
52 | grep-extglob $file
|
53 | }
|
54 |
|
55 | audit-git() {
|
56 | audit
|
57 | }
|
58 |
|
59 | readonly COMPLETION_FILES=($BASH_COMP ../bash-completion/completions/*)
|
60 |
|
61 | # EVERY plugin seems to use the _init_completion function. We can do this
|
62 | # ourselves!
|
63 | audit-plugin-init() {
|
64 | ls ../bash-completion/completions/* | wc -l
|
65 | #grep -c _init_completion ../bash-completion/completions/*
|
66 |
|
67 | # almost all calls are the same!
|
68 | # the -n changes delimiters. Why would you need that? Those need to be
|
69 | # rewritten?
|
70 | #
|
71 | # There is one instance of -o '@(diff|patch)
|
72 | # -s is for splitting longopt with --foo=
|
73 | # Oh OK maybe I should just implement that in Python in OSH?
|
74 | #
|
75 | # So everything is about the delimiters.
|
76 |
|
77 | grep --no-filename _init_completion "${COMPLETION_FILES[@]}" |
|
78 | sort | uniq -c | sort -n
|
79 | }
|
80 |
|
81 | audit-plugin-x() {
|
82 | echo
|
83 | echo '-X usage'
|
84 | echo
|
85 |
|
86 | grep --no-filename -- -X "${COMPLETION_FILES[@]}"
|
87 | }
|
88 |
|
89 | # Hm I guess you could implement these two? _get_cword and _get_pword can look
|
90 | # at COMP_ARGV or 'words'?
|
91 |
|
92 | # Yes they both take delimiters like -n. So just take COMP_ARGV and split, and
|
93 | # then get the last one or second to last.
|
94 |
|
95 | audit-plugin-funcs() {
|
96 | echo
|
97 | echo 'annoying functions'
|
98 | echo
|
99 |
|
100 | # _get_cword and _get_pword should be easy to implement. COMP_ARGV is split
|
101 | # with delimiters again. Should you try an oracle?
|
102 | grep --color -- '_get_.word' "${COMPLETION_FILES[@]}"
|
103 |
|
104 | # This calls __reassemble_comp_words_by_ref
|
105 | grep --color -w -- '_count_args' "${COMPLETION_FILES[@]}"
|
106 |
|
107 | # These call _get_comp_words_by_ref, which calls _get_cword_at_cursor_by_ref,
|
108 | # which calls __reassemble_comp_words_by_ref
|
109 | grep --color -w -- '_command' "${COMPLETION_FILES[@]}"
|
110 | grep --color -w -- '_command_offset' "${COMPLETION_FILES[@]}"
|
111 |
|
112 | # Should be replaced by compgen -A file?
|
113 | grep --color -w -- '_filedir' "${COMPLETION_FILES[@]}"
|
114 |
|
115 | # What's the difference between these two?
|
116 | grep --color -w -- '_expand' "${COMPLETION_FILES[@]}"
|
117 | grep --color -w -- '_tilde' "${COMPLETION_FILES[@]}"
|
118 | }
|
119 |
|
120 | audit-bashcomp() {
|
121 | local path=$BASH_COMP
|
122 |
|
123 | audit $path
|
124 |
|
125 | # Some of these are not cash variables.
|
126 | grep -E -o 'COMP_[A-Z]+' $path | hist
|
127 |
|
128 | grep-extglob ../bash-completion/completions/*
|
129 |
|
130 | #find /usr/share/bash-completion/ -type f | xargs grep -E --color ']\+?='
|
131 | }
|
132 |
|
133 | # Git completion is very big!
|
134 | #
|
135 | # 1528 /usr/share/bash-completion/completions/nmcli
|
136 | # 1529 /usr/share/bash-completion/completions/svn
|
137 | # 1995 /usr/share/bash-completion/bash_completion
|
138 | # 2774 /usr/share/bash-completion/completions/git
|
139 | # 39354 total
|
140 |
|
141 | list-distro() {
|
142 | find /usr/share/bash-completion/ -type f | xargs wc -l | sort -n
|
143 | }
|
144 |
|
145 | # After running this, source testdata/completion/git-completion.bash
|
146 | fresh-osh-with-dump() {
|
147 | env -i OILS_CRASH_DUMP_DIR=_tmp \
|
148 | bin/osh --debug-file _tmp/debug "$@"
|
149 | }
|
150 |
|
151 | osh-trace() {
|
152 | # $FUNCNAME displays the whole stack in osh (unlike bash), but ${FUNCNAME[0]}
|
153 | # displays the top.
|
154 |
|
155 | # NOTE: env -i disables $TERM, which breaks some things.
|
156 | #env -i
|
157 |
|
158 | OILS_CRASH_DUMP_DIR=_tmp \
|
159 | OILS_HIJACK_SHEBANG=bin/osh \
|
160 | PS4='+[${LINENO}:${FUNCNAME[0]}] ' \
|
161 | bin/osh -x --debug-file _tmp/debug --xtrace-to-debug-file "$@"
|
162 | }
|
163 |
|
164 | osh-debug() {
|
165 | OILS_CRASH_DUMP_DIR=_tmp \
|
166 | OILS_HIJACK_SHEBANG=bin/osh \
|
167 | bin/osh --debug-file _tmp/debug "$@"
|
168 | }
|
169 |
|
170 | bash-bash() {
|
171 | PS4='+[${LINENO}:${FUNCNAME}] ' bash -x $BASH_COMP
|
172 | }
|
173 |
|
174 | bash-completion() {
|
175 | # This is a patched version
|
176 | fresh-osh-with-dump $BASH_COMP
|
177 | }
|
178 |
|
179 | bash-completion-trace() {
|
180 | osh-trace $BASH_COMP
|
181 | }
|
182 |
|
183 | # This should do nothing
|
184 | git-completion() {
|
185 | fresh-osh-with-dump $GIT_COMP
|
186 | }
|
187 |
|
188 | git-completion-trace() {
|
189 | osh-trace $GIT_COMP
|
190 | }
|
191 |
|
192 | # See what completion is there by default. It looks like filename completion.
|
193 | # Actually it does complete variables with $ and ${.
|
194 | bare-bash() {
|
195 | bash --noprofile --norc "$@"
|
196 | }
|
197 |
|
198 | # TODO: This is a good use case
|
199 | npm-comp() {
|
200 | npm completion | bin/osh -n
|
201 | #npm-completion > _tmp/npm.sh
|
202 | #bin/osh -n _tmp/npm.sh
|
203 | }
|
204 |
|
205 | # NOTE: This package doesn't have git completion. That comes with the git package!
|
206 | download-bash-completion-xenial() {
|
207 | # binary package
|
208 | if false; then
|
209 | wget --directory _tmp \
|
210 | http://mirrors.kernel.org/ubuntu/pool/main/b/bash-completion/bash-completion_2.1-4.2ubuntu1_all.deb
|
211 | fi
|
212 |
|
213 | # source package
|
214 | wget --directory _tmp \
|
215 | http://archive.ubuntu.com/ubuntu/pool/main/b/bash-completion/bash-completion_2.1.orig.tar.bz2
|
216 | }
|
217 |
|
218 | # Conclusion: git-completion.bash is is unmodified. It's just renamed to
|
219 | # /usr/share/bash-completion/git. It seems to use the _git() and _gitk() entry
|
220 | # points.
|
221 | download-git-package() {
|
222 | true || wget --directory _tmp \
|
223 | http://archive.ubuntu.com/ubuntu/pool/main/g/git/git_2.7.4.orig.tar.xz
|
224 | wget --directory _tmp \
|
225 | http://security.ubuntu.com/ubuntu/pool/main/g/git/git_2.7.4-0ubuntu1.6_amd64.deb
|
226 | }
|
227 |
|
228 | "$@"
|