diff options
1483 files changed, 50639 insertions, 0 deletions
diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..56279de --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,10 @@ +;;; Directory Local Variables +;;; For more information see (info "(emacs) Directory Variables") + +((python-mode + (eval add-hook 'before-save-hook 'blacken-buffer nil t)) + (sh-mode + (mode . shfmt-on-save) + (shfmt-arguments "-s") + (flycheck-sh-bash-args "-O" "extglob") + (sh-indent-comment . t))) diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..61f2dc9 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +**/__pycache__/ diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..85032d1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +[*] +indent_style = space +indent_size = 4 +tab_width = 8 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +max_line_length = 79 +# for shfmt +function_next_line = true +switch_case_indent = true + +[Makefile.am] +indent_style = tab + +[*.{yml,yaml}] +indent_size = 2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae29894 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +*.tar* +*.swp +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +config.log +config.status +configure +configure.lineno +install-sh +missing +doc/*.xml +*~ +doc/html* +bash_completion.sh +bash-completion.pc +bash-completion-config.cmake +bash-completion-config-version.cmake +__pycache__/ +.pytest_cache/ +.python-version +pytestdebug.log diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..0204e77 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,4 @@ +MD007: + false # for lists in FAQ/A +MD033: + allowed_elements: [kbd] diff --git a/.perltidyrc b/.perltidyrc new file mode 100644 index 0000000..9f681d2 --- /dev/null +++ b/.perltidyrc @@ -0,0 +1,6 @@ +--perl-best-practices +--maximum-line-length=79 +--paren-tightness=2 +--cuddled-else +--warning-output +--converge diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..57d1264 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,97 @@ +repos: + + - repo: local + hooks: + - id: shfmt + name: shfmt + language: golang + additional_dependencies: [mvdan.cc/sh/v3/cmd/shfmt@v3.1.2] + entry: shfmt + args: [-w, -s] + types: [text] + files: ^(bash_completion|completions/.+|test/(config/bashrc|update-test-cmd-list)|.+\.sh(\.in)?)$ + exclude: ^completions/(\.gitignore|Makefile.*)$ + + - repo: https://github.com/shellcheck-py/shellcheck-py + rev: v0.7.1.1 + hooks: + - id: shellcheck + args: [-f, gcc] + types: [text] + files: ^(bash_completion|completions/.+|test/(config/bashrc|update-test-cmd-list)|.+\.sh(\.in)?)$ + exclude: ^completions/(\.gitignore|Makefile.*)$ + require_serial: false # We disable SC1090 anyway, so parallel is ok + + - repo: local + hooks: + - id: update-test-cmd-list + name: update-test-cmd-list + language: script + entry: test/update-test-cmd-list + files: ^test/t/.+\.py$ + pass_filenames: false + + - repo: https://github.com/psf/black + rev: 19.10b0 + hooks: + - id: black + types: [text] + files: ^(helpers/python|.+\.py)$ + exclude: ^completions/ + + - repo: https://gitlab.com/pycqa/flake8 + rev: 3.8.3 + hooks: + - id: flake8 + args: [--config=test/setup.cfg] + additional_dependencies: [flake8-bugbear==20.1.4] + types: [text] + files: ^(helpers/python|.+\.py)$ + exclude: ^completions/ + + - repo: https://github.com/timothycrosley/isort + rev: 5.1.4 + hooks: + - id: isort + args: [--settings-path=test/setup.cfg] + types: [text] + files: ^(helpers/python|.+\.py)$ + exclude: ^completions/ + + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v0.782 + hooks: + - id: mypy + args: [--config-file=test/setup.cfg] + # Intentionally not run on helpers/python (support very old versions) + exclude: ^completions/|^test/fixtures/pytest/ + + - repo: https://github.com/asottile/pyupgrade + rev: v2.7.2 + hooks: + - id: pyupgrade + args: [--py3-plus, --keep-percent-format] + exclude: ^completions/ + + - repo: https://github.com/perltidy/perltidy + rev: "20200619" + hooks: + - id: perltidy + types: [text] + files: ^(helpers/perl|.+\.p[ml])$ + + - repo: local + hooks: + - id: perlcritic + name: perlcritic + language: perl + additional_dependencies: [PETDANCE/Perl-Critic-1.138.tar.gz] + entry: perlcritic + args: [--quiet, --verbose, "5"] + types: [text] + files: ^(helpers/perl|.+\.p[ml])$ + + - repo: https://github.com/igorshubovych/markdownlint-cli + rev: v0.23.2 + hooks: + - id: markdownlint diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000..cf5ed4b --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1,16 @@ +shell=bash +disable=SC1090 # not really fixable usually (ever?) +disable=SC2034 # for localizing variables set in called functions +disable=SC2128 # intentional style choice +disable=SC2206 # suggested alternatives fail in posix mode or use temp files +disable=SC2207 # suggested alternatives fail in posix mode or use temp files + +# These disables are to be investigated and decided + +disable=SC1004 +disable=SC2015 +disable=SC2016 +disable=SC2086 +disable=SC2155 +disable=SC2162 +disable=SC2231 diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..1ab73f5 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,56 @@ +language: generic + +dist: bionic + +services: + - docker + +jobs: + include: + - stage: lint + language: go + go: "1.14" + services: [] + cache: + directories: + - $HOME/.cache/pip + - $HOME/.cache/pre-commit + before_install: [] + script: + - pyenv shell 3.8 + - pip3 install "$(grep ^pre-commit test/requirements-dev.txt)" + - pre-commit run --all-files --color=always + - stage: test + env: DIST=alpine + - env: DIST=centos7 + - env: DIST=debian10 + - env: DIST=fedoradev + - env: DIST=ubuntu14 + - env: DIST=ubuntu14 BSD=true NETWORK=none + +before_install: + - docker build + --build-arg DIST=$DIST -t bash-completion:$DIST -f test/docker/Dockerfile . + +script: + - docker run --name bash-completion + -e CI=true -e DIST=$DIST -e BSD=$BSD -e NETWORK=$NETWORK + ${NETWORK:+--network $NETWORK} + -t bash-completion:$DIST + +before_deploy: + - docker start bash-completion + - docker exec bash-completion + sh -c "tar c bash-completion-$TRAVIS_TAG.tar.*" | tar xv + - docker kill bash-completion + +deploy: + provider: releases + api_key: + secure: MoK9nzmS6CBzPPIrhC0Ch6hIB3zEzLqZE6k4axoCyz/wmJFLJgX9OCq5K8zS4Jv8NuaA2C1YTcr+m56IO9N0RTmIWrS4q40fLIhKlYv6255u+wXMkGfqXbiFAZG5yndhUo8NE6QXAtixd3nQ/3/MOt2PdsOn+OdxTDmcPSXaW/ltkd/fMHynWzupdyRJ1v46IofPBrjsC1pTzW0iVqVHz64Ix3kPVjjPR9BMHzgKMJ8sPWBGZtF2ovjwsTHYPSpEyytVRecqrmEjM6QBCgfhQDqH87jOw6Y81xh1fWDCoxaZw7HlEcQ+HeHOkDdA24AYaxVoYXrKdIDXUXWt8w674Po7UWB6kIUn3J59Xaw60Sp4VaN88Y2eX9UKRcoDRHLWc8HKt4f9AUDR9YpFF08N+gKRmJFt9mCxqeJ+pyYD/coHGkGb8XvewTKihCSuH/qCWjM8XqM493DLDlJ5aELgMEcJXPXX4TmjsriOeErTY1qxRTRHJPmfUJ/kHtmpE+DxNXpwZOnyG+VoO5aEaIKbzHxX9QzWyyEhTflupdatZ2JFt1pmVDpwH9zcEifBwE0cUwhXk+LJuxHd5ePIIpvepAAnXKaxlYwchj4cFaJp7S9GZoAQughgQQkyfz0qr3J6hBhg360QAq4yjPOWjGgGz4iAG8kWd3MVXLvL+TtfBeY= + file: bash-completion-$TRAVIS_TAG.tar.xz + skip_cleanup: true + on: + repo: scop/bash-completion + condition: $DIST = alpine + tags: true @@ -0,0 +1,7 @@ +David Paleino (Debian) <d.paleino@gmail.com> +Freddy Vulto <fvulto@gmail.com> +Guillame Rousse (Mandriva) <Guillaume.Rousse@inria.fr> +Igor Murzov <e-mail@date.by> +Mike Kelly (Exherbo) <pioto@pioto.org> +Santiago M. Mola (Exherbo) <cooldwind@gmail.com> +Ville Skyttä <ville.skytta@iki.fi> @@ -0,0 +1,3141 @@ +bash-completion (2.11) + + [ Alexander Meshcheryakov ] + * _known_hosts_real: check that ruptime is present before calling + (#390) + + [ Andrew Gaul ] + * totem: reuse kaffeine completions (#372) + + [ Damien Nadé ] + * __reassemble_comp_words_by_ref: avoid triggering nounset on + indirect references + + [ Felix Lechner ] + * lintian: complete paths for Ubuntu's .ddeb and Debian's buildinfo + files (#397) + + [ Felix Yan ] + * ip: complete route add table arg + * ip: style fixes similar to ip-netns + * ip: add more completions for ip-rule + * ip: add support for netns (#391) + * ip: improve completion of route subcommands (#326) + + [ Hans-Christoph Steiner ] + * unzip, zipinfo: complete *.aar (#428) + + [ Jakub Jelen ] + * ssh: add new -Q completions in OpenSSH 8.2p1 (#400) + + [ Kevin Locke ] + * python: support executables with minor version (#389) + + [ Michal Suchánek ] + * insmod, modinfo, modprobe: support xz compressed modules (#401) + + [ Phan Duc Nhat Minh ] + * tshark: complete -r arg with all filenames (#422) + + [ Sebastian Jakubiak ] + * openssl: update -starttls completions (#403) + * _filedir*: update link to bug-bash discussion on -X (#404) + * test/python: add testcase for submodule completion + + [ Ville Skyttä ] + * Release 2.11 + * extra/make-changelog: check and output usage message + * pre-commit: anchor exclude patterns + * pytest: rewrite in bash, support toplevel funcs, avoid nondef ones + and classes + * test/xfreerdp: skip --help failure cases + * test/tshark: fix multiple -O completion with no http2 support + * test/ant: avoid complete-ant-cmd.pl interference with ANT_ARGS + * _xinetd_services: avoid nounset error on bash 4.2 + * pre-commit: upgrade isort to 5.1.4 + * pre-commit: upgrade pyupgrade to 2.7.2 + * pre-commit: add pyupgrade, run it + * test/ant: gitignore all target cache files + * _known_hosts_real: exclude Host negations + * pre-commit: upgrade isort to 5.0.7 + * pre-commit: update shellcheck-py URL + * test/inputrc: do not set print-completions-horizontally + * test/inputrc: comment typo fix + * pytest: complete async test class methods + * __get_cword_at_cursor_by_ref: fix regression on bash 4.2 + * test: upgrade markdownlint-cli to 0.23.2 + * _known_hosts_real: avoid errors in nounset mode on Ubuntu 14 and + 16 + * _longopt: exclude too many dashes, allow underscores, require ends + with alnum + * _included_ssh_config_files: support globs + * _known_hosts_real: prevent unwanted pathname expansion on host + entries + * test/shfmt: upgrade to 3.1.2, reformat with it + * test/_known_hosts_real: add explicit no globbing test case + * test: upgrade mypy to 0.782 + * CONTRIBUTING.md: add posix and nounset mode item + * test: upgrade mypy to 0.781 + * test: upgrade perltidy to 20200619 + * _known_hosts_real: fix completion of Host entries after a wildcard + etc + * _known_hosts_real: fix # handling in ssh configs + * test: upgrade flake8 to 3.8.3 + * test/xhost: multiple expected result handling fixes + * test/slapt-src: single expected result handling fixes + * test: partial hostname completion fixes + * test: simplify completion parsing + * test/dpkg-query: mark as xfail on non-Debian based systems + * .gitignore: clean up some no longer needed ignores + * test/lspci: skip -A arg test if lspci fails -A help, e.g. busybox + lspci + * test: regex escape our magic mark for completeness + * test: upgrade mypy to 0.780 + * test/_known_hosts_real: don't modify class scoped base expected + list + * test/_known_hosts_real: reset COMP_KNOWN_HOSTS_WITH_HOSTFILE + between tests + * test/_known_hosts_real: tolerate duplicates + * bash_completion: trivial cleanups + * gcc: avoid errors in nounset mode + * pytest: fix test class method completion with BSD awk + * man, mutt: avoid errors in nounset mode on Ubuntu 14 and 16 + * java, make: avoid errors in nounset mode on Ubuntu 14 and 16 + * README: document GNU make build requirement + * pytest: add test class method completion + * _known_hosts: avoid errors in nounset mode and no arguments + * bash_completion: fix array set checks with empty elements in them + * *: avoid more errors in nounset mode + * cfrun: fix $hostfile leak + * _command_offset, route: cleanups + * *: avoid more errors in nounset mode + * qemu: add -machine arg completion + * qemu, sbopkg: avoid unintentional globbing on option arg + completions + * test: enable shellcheck SC2035 + * *: drop support for bash 4.1 + * _init_completion: fix unassigned redirect completion in nounset + mode + * ip: route shfmt, arithmetic evaluation + * _filedir: avoid unbound variable error on Ubuntu 14 and 16 + * _pids, _pgids, _pnames: improve shfmt formatting + * scp, sftp, ssh: fix completion on options bundled with -4/-6 + * modprobe, tshark, _included_ssh_config_files: use [[ ]] instead of + [ ] + * test/runLint: warn about [ ] instead of [[ ]] use + * test: skip various tests if we don't get a useful usage message + * *: mark nounset mode as supported, issues with it are bugs now + * *: avoid more errors in nounset mode + * *: avoid more errors in nounset mode + * *: avoid more errors in nounset mode + * test/inputrc: comment and whitespace tweaks + * *: avoid more errors in nounset mode + * test/unit: sort files included in dist + * test/unit: include test_unit_known_hosts_real.py in dist + * bash_completion: line wrapping tweaks, NFC + * 7z: fix -o/-w attached arg completion + * postfix: try to arrange a fake tty so we can tickle the usage + message out + * _bashcomp_try_faketty: new function to try running command with a + fake tty + * mr: avoid herestrings, simplify command parsing + * test/mr: handle missing "clean" with skipif + * test: mark known non-ASCII issues with test suite as xfail + * dpkg-deb: add --raw-extract and -X arg completions + * test: add some dpkg-query test cases + * dpkg-deb: fix --show/-W completion + * test: upgrade markdownlint-cli to 0.23.1 + * *: use more arithmetic evaluation + * test: try harder to restore environment and cwd on failures + * *: use $ifs for storing/restoring $IFS + * test/irb: xfail options test if --help is not available + * test: upgrade flake8 to 3.8.1 + * test: pre-commit config cleanups, ordering + * test: upgrade pre-commit to 2.4.0+, drop shfmt kludge + * test: sync shfmt and shellcheck configs + * test: shfmt bashrc + * test: remove unused run-shellcheck, shellcheck is in pre-commit + now + * test: remove old test suite code no longer used \o/ + * test/_known_hosts_real: port remaining test cases to + pytest+pexpect + * test: remove more no longer needed old test suite code + * test/_known_hosts_real: port more test cases to pytest+pexpect + * test/_get_cword: port remaining test case to pytest+pexpect + * test: replace some echos with printfs + * test/_filedir: fix shutil.rmtree on Python < 3.6 + * test/_expand: port remaining test cases to pytest+pexpect + * test: drop some no longer needed old test suite code + * test/_filedir: port remaining test cases to pytest+pexpect + * test: run all Travis jobs on dist: bionic + * test: drop not needed sudo on Travis + * test/_filedir: port more test cases to pytest+pexpect + * test/__expand_tilde_by_ref: port remaining test cases to + pytest+pexpect + * test/_get_comp_words_by_ref: convert remaining test cases to + pytest+pexpect + * test: run pytest --verbose in docker + * lftp: use "bookmark list" command to list bookmarks + * test: drop some no longer needed old test suite code + * test/slapt-src: convert remaining test case to pytest+pexpect + * _xfunc: simplify + * apt-cache: avoid nonzero exit code from _apt_cache_packages + * test/slapt-get: convert remaining test case to pytest+pexpect + * test/secret-tool: add to test command list + * test/scp: port remaining test case to pytest+pexpect + * test/umount: convert remaining test case to pytest+pexpect + * secret-tool: new completion + * apt-get: complete build-dep with dirs + * travis: use golang 1.14 for shfmt + * *: run all shell code through shfmt -s + * pre-commit etc: add shfmt + * test: fix incorrect fixtures/shared/default xfails/expectations + * test: upgrade markdownlint to 0.23.0 + * nmap: simplify help scraping a bit, don't try to emit unnecessary + newlines + * test: prefix fake test commands with underscore + * test: port most umount test cases to pytest+pexpect + * test: add note about unescaped assert_complete single return + values + * editorconfig: apply yaml settings to .yaml too + * pre-commit: use local perlcritic hook + * *: doc and comment link updates + * pre-commit, *.md: add markdownlint, address findings + * README: clarify loading automatically on demand + * ssh-keygen: -O arg updates and improvements + * ssh-keygen: add -b arg completions according to specified -t + * ssh-keygen: option and arg completion updates for new versions + * _command: improve commentary + * reportbug, scp, sftp, svn: use compgen -c instead of _command + * find: fix -exec etc argument and its completion + * extra: trigger docker builds only on test-cmd-list.txt changes + * test: add script to maintain list of executables for full test + coverage + * test: run lint tests on Travis in a quickish separate first stage + * test/make: mark more cases as requiring command + * make: add bmake alias + * test: run pre-commit on host instead of docker + * test: add perlcritic to pre-commit, run on all perl + * *: remove some unused variables, thanks to shellcheck SC2034 + * *: various loop iteration improvements + * crontab: fix loop over already given args + * apt-cache: fix command mode handling + * doc: add loop variable naming guideline + * test: make at-point completion tests easier + * ssh, xsltproc: address shellcheck SC2006 + * scp: work around shellcheck SC1003 + * mutt: address shellchec SC2236 + * wget: address shellcheck SC2116 + * pytest: address shellcheck SC2002 + * bash_completion, java, tipc: for loop whitespace consistency + tweaks + * *: more arithmetic evaluation cleanups, thanks to shellcheck + SC2004 + * __reassemble_comp_words_by_ref, java: address and work around + shellcheck SC2102 + * test: enable parallel pre-commit shellcheck + * test: remove shellcheck severity filter, add explicit disables + instead + * doc: recommend arithmetic evaluation + * *: array subscript cleanups + * ssh-keygen: -s and -n completion improvements + * *: enable and address shellcheck SC2053 + * bash_completion, invoke-rc.d, svcadm: trivial cleanups + * *: replace various conditional expressions with arithmetic + evaluation + * carton: fix command parsing with BSD sed + * nmap: fix option parsing with BSD sed + * test/alias: port remaining test case to pytest+pexpect + * test: generalize complete at point test + * test/cd: fix test_dir_at_point for setups that repeat "trailer" + * pytest: add some option arg (non-)completions + * pytest: complete test classes + * pgrep, pkill: add --ns and --nslist arg completions + * test: run skipif and xfail commands without caring if they output + or not + * test: make it possible to not care whether command did output or + not + * test/xfreerdp: skip xfreerdp kbd test if kbd-list returns empty + * test: tolerate duplicates from compgen actions + * test: bump shellcheck severity to warning + some disables + * *: address shellcheck SC2046 + * test/lib/library.sh: address shellcheck SC2125 + * java, pkgadd, sysbench: address shellchec SC2124 + * scp: address shellcheck SC2089 and SC2090 + * _filedir_xspec: address shellcheck SC2140 + * rpm, ssh, umount.linux: address shellcheck SC2120 + * cvs, modprobe, sh: address shellcheck SC2209 + * mutt: address shellcheck SC2088 + * _upvar, _upvars, _variables, rpm: address shellcheck SC1083 + * test/run: address shellcheck SC2164 + * renice: address shellcheck SC2254 + * tipc: comment grammar and spelling fixes + * man, perl, route, tipc: address shellcheck SC2053 + * info, java: address shellcheck SC2153 + * quote_readline: fix $ret leak + * test: upgrade shellcheck to 0.7.1 + * test/printenv: xfail if --help doesn't contain options (e.g. + busybox) + * test/aptitude: require command where necessary + * _known_hosts_real, op: address shellcheck SC2184 + * test: don't run shellcheck on completions/.gitignore + * protoc: complete all --*_out without more specific handling with + dirs + * sysbench: add --test= deprecation TODO + * pkgadd: indentation fix + * chronyc, wvdial: address shellcheck SC2178 + * java, pkgadd, sysbench: address shellcheck SC2124 + * mplayer: address shellcheck SC1078 false positive + * smartctl: hush shellcheck SC2054 false positives + * *: address shellcheck SC2221 and SC2222 + * bash_completion: address shellcheck SC2220 + * crontab, wodim: silence shellcheck SC2191 and SC2192 + * aptitude: add some option arg (non)completions + * aptitude: parse options list from --help, hardcode less + * test/aptitude: add some test cases + * *: argument interation improvements + * *: whitespace tweaks + * apt-get etc: use _apt_cache_packages from apt-cache + * pre-commit: run most python checks on helpers/python too + * test/ldd: xfail if --help is not implemented + * test/printenv: require command for arg completion test + * printenv: indentation fixes + * test: upgrade mypy to 0.770 + * test: split dependencies requiring Python 3.6.1+ to requirements- + dev.txt + * git: trigger docker rebuild on pre-commit config change + * test: require openssl command for option argument tests + * test: move perltidy to pre-commit, run with --converge + * test: move shellcheck to pre-commit + * test: ignore flake8 messages that are in black's domain + * _xinetd_services: look up from $BASHCOMP_XINETDDIR, add some unit + tests + * printenv: new completion + * copyright: add 2020 + * test: fix CompletionResult.__eq__ UnboundLocalError + * test: run pre-commit in tools container + * test: shellcheck tweaks + * test: add isort to pre-commit, run it + * test: add flake8-bugbear + * test: install black for Python 3.6 too + * pre-commit: add config with black, flake8, and mypy + * test: drop redundant black args from docker runs + * *: python type hint fixes and improvements + * extra/make-changelog: run through black + * test/totem: add basic test case + * test/cd: remove unused import + * openssl: complete -writerand with filenames + * openssl: parse available options from $command -help + * openssl: support getting digest list from more recent openssl + versions + * nmap: handle options split on equals sign + * nmap: parse options from -h output + * test/cd: make dir_at_point produce better debuggable failures + * test/cd: convert remaining test case to pytest+pexpect + * test: remove some no longer needed old test suite code + * test/chown,sudo: parametrize special case test, improve xfail + targeting + * test/tsig-keygen: require command for test_options + * test/upgradepkg: port remaining test case to pytest+pexpect + * tsig-keygen: new completion + * test: host helper lint and usage fixes + * test: port some _known_hosts_real unit tests to pytest+pexpect + * test: remove some no longer needed tcl/expect code + * test: fix spurious hosts fixture failure without avahi-browse + installed + * test: port some scp test cases to pytest+pexpect + * test: port remaining finger, sftp, ssh, and xhost cases to + pytest+pexpect + * lilo: work around shellcheck false positive + * test/ipcalc: fix tests with busybox ipcalc + * chromium-browser, firefox: complete on *.txt (#379) + * README.md: add introduction + * ipcalc: new completion + * *: complete commands when prefixed with a backslash + * test/wol: don't fail MAC test if test system has /etc/ethers + entries + * test/dnssec-keygen: allow more alternatives in algorithm + completion + * lilo: don't complete on commented out labels + * lilo: honor -C when completing labels + * lilo: add -B and -E completions + + [ beantaxi ] + * Source user completion only if it's a file (#409) + + [ hugoziviani ] + * jarsigner: complete on *.apk too (#386) + * cryptsetup: add luksChangeKey arg completion (#380) + + -- Ville Skyttä <ville.skytta@iki.fi> Sat, 25 Jul 2020 11:25:09 +0300 + +bash-completion (2.10) + + [ Felix Lechner ] + * perltidy: associate *.t (#338) + + [ Gabriel F. T. Gomes ] + * perl: fix completion with space between option and argument + + [ Grisha Levit ] + * _variables: add TERM and LC_* completion (#353) + + [ Iñigo MartÃnez ] + * autotools: Replace pkgdatadir with datadir + * pkg-config: Relative paths + * pkg-config: generate Name from autotools PACKAGE + + [ Jakub Jelen ] + * ssh: option and argument completion updates (#332) + + [ MichaÅ‚ Górny ] + * test_arp: Skip if ARP tables are empty + * test_chromium_browser: Skip test_2 if 'chromium-browser --help' + fails + * test_rpm2tgz: Fix expected output + + [ Sebastian ] + * cppcheck: Add new standards to --std option. (#356) + + [ Tomasz N ] + * apt-get: fix pkg version completion if it contains a colon (#351) + + [ Ville Skyttä ] + * test: bump black to >=19.10b0 + * ssh, scp, sftp, ssh-copy-id, curl: improve identity file + completion + * update-rc.d: indentation fix + * update-rc.d: remove dead code + * screen: add serial device basic arg (non)completion + * screen: add //telnet completion + * test: add some trivial perl -E/-e cases + * perl: indentation fixes + * curl: make @filename completion do the right thing with dirs + * _filedir: avoid duplicate dirs internally, and a compgen -d call + for files + * _filedir: remove unused $x + * bash_completion.sh: shellcheck SC2086 fixes + * test: shellcheck config cleanups + * shellcheck: add some option arg (non)completions + * test: fix cpio users test in presence of usernames with whitespace + * test: python typing fixes + * test: add minimal mypy config + * .gitignore: mypy cache + * makepkg: fix option completion + * test: mark dcop and mr testcases requiring the cmd as such + * CONTRIBUTING: disable e-mail bug gateway due to spam + * carton: new completion + * op: direct command parsing stderr to /dev/null + * test: adjust java expectations based on whether jars can be listed + * valgrind: look tool names from lib/*-linux-gnu dirs too + * test: xfail locale-gen option completion if --help is not + available + * _sysvdirs: always return 0 + * java: don't assume jar is installed + * travis: test with Debian 10 + * wine: install for wine-development and wine-stable too + * travis: generate dist tarball on alpine + * dmypy: new completion + * test: add require_longopt xfail helper, use it + * test: mark more tests that parse command output as requiring + command + * sysctl: invoke completed sysctl instead of one from path to get + variables + * screen, smartctl, update-alternatives: _parse_help, drop hardcoded + option list + * lintian-info: _parse_help, add more option arg (non)completions + * gprof: _parse_usage, drop hardcoded option list + * test: fix retrieving command to test from request + * travis: pass NETWORK as env var, so we can actually use it + * test: xfail MAC address completion without networking + * test: ignore _makepkg_bootstrap in makepkg test env + * test: hush flake8-bugbear B010 + * test: don't sort expected completion lists under the hood + * test: add bunch of basic option parsing test cases + * test: always run tests which don't require tested command + * test: explodepkg and upgradepkg test fixes + * test: mark sbcl-mt xfail due to whitespace split issues + * _terms: search directly from various terminfo dirs + * _terms: combine and simplify somewhat + * pkg-get: fix $i leak + * pkgutil: fix $i leak + * test: portinstall/upgrade test case and setup fixes + * lvm pv*, vg*: parse help instead of hardcoding option list + * ipv6calc: parse help instead of hardcoding option list + * test: avoid some sed -r/-E runLint false positives + * test: use sh +* as ccache command test case + * java: make jar/zip listing work with unzip + * test: installpkg test fixes + * test: fix acroread fixture dir + * test: remove unnecessary returns after pytest.skip + * test: avoid gnome-mplayer core dump on Ubuntu 14 + * xvfb-run: new completion + * test: skip gssdp-discover --message-type when option not available + * test: expect failures for bc without --help useful with _longopt + * test: don't expect a .tox dir in fixture + * test: drop sourcing our no longer existing profile.d script + * tox: include -- in option completions + * tox: complete defaults after a -- + * gssdp-discover: new completion + * test: register our pytest markers to hush warnings from 4.5+ + * test: fix required pytest version + * ip: invoke the tool as $1 + * README: drop distro badges, link to Repology instead + * chromium-browser: add --proxy-server arg completion + * test: source our profile.d test env script in docker + * influx: new completion + * README: badge title tweaks + * tox: do simple parse on tox.ini if --listenvs* yields nothing + * test: add basic tox fixture + * man: fall back to _parse_usage for _parse_help + * test_wsimport: xfail options test on unparseable -help + * test: don't try to install black on Python < 3.6 + * pgrep: fix fallback to _parse_usage + * test: xfail unparseable mock and munin-node-configure --help cases + * test_pwdx: xfail more unparseable help cases + * build: make pytest executable configurable, look for pytest-3 too + * test: enforce minimum pytest version + * test: zopflipng flake8 fix + * test: xfail getent and pwdx option completions with unparseable + --help + * test: add more basic _parse_help use test cases + * test: add bunch of basic _parse_help use test cases + * .gitignore: add configure.lineno + * badblocks: fix $i leak + * postfix: option completion is expected to fail at the moment + * cal: try _parse_help before _parse_usage + * test: add bunch of basic _parse_usage use test cases + * chsh, pwck: try _parse_help before _parse_usage + * test: add basic autossh test + * test: convert more _filedir unit tests to pytest+pexpect + * test: flake8 fix + * test: convert bunch of _filedir unit tests to pytest+pexpect + * test: convert finger partial test case to pytest+pexpect + * README: add some badges, tweak existing + * test: port _variables unit tests to pytest+pexpect + * test: port compgen and quote tests to pytest+pexpect + * iconv, lz4, tipc, xsltproc: replace some seds with compgen -X + * test: disallow Alpine failure on Travis + * _pnames: adapt for busybox ps, rewrite in pure bash + * test: run our docker script in test containers by default + * test: use one Dockerfile for all dists + * test_ifup: accept short option completions too + * timeout: fallback to _parse_usage from _parse_help + * test_wget: test --s instead of --h + * test_lsusb: xfail with unparseable --help + * test: expect failures for various completions without useful + --help + * test: support xfail in our markers like skipif, use it a lot + * test: add Alpine Linux container, allow failures for now + * iconv: weed out ... from encoding completions + * test_iconv: add basic file completion test + * test_iconv: skip option completion if --help fails + * test_getconf: skip if -a doesn't output any POSIX_V* + * test_feh, test_makepkg: invoke grep as "command grep" + * test: generalize check whether we're being run in a container + * tar: simplify locating tarball from command line + * pkg_delete: don't limit to FreeBSD + * test: reformat test_chromium_browser.py source + * test: set up BASH_COMPLETION_COMPAT_DIR in bashrc (only) + * test: more thorough system location interference avoidance + * test: bashrc comment and whitespace tweaks + * build: makefile whitespace tweaks + * build: really reset return value before completions check + * build: simplify symlink setup + * tar: add missing bsdtar, gtar, and star symlinks + * README: use light gray badges for unknown versions + * README: link to cygwin package + + [ Wolf ] + * ri: hush some warnings + + [ andreabravetti ] + * unrar: complete on *.exe (#337) + + [ ezr ] + * chromium-browser: Add support for .mhtml files + + [ jerkey ] + * screen: complete first arg with serial devices + + [ marxin ] + * gcc: support new --completion option (#222) + + [ pcc ] + * unzip, zipinfo: complete *.aab (#340) + + [ versat ] + * cppcheck: Remove deprecated option 'posix' for '--std=' + + -- Ville Skyttä <ville.skytta@iki.fi> Thu, 05 Dec 2019 17:04:26 +0200 + +bash-completion (2.9) + + [ Antonio Terceiro ] + * dpkg-source: Add --before-build --after-build --commit, and + --print-format + + [ Gabriel F. T. Gomes ] + * xm: Deprecate completion for obsolete command (#284) + * _filedir_xspec: Fallback to suggesting all files if requested + (#260) + * tar: Support completions for zstd compression extensions (#255) + * dpkg: List held packages (#250) + * cvs: Add completion for the log command + + [ Guillaume Mella ] + * unzip, zipinfo: Associate with *.xar (eXist-db application + package) (#257) + + [ Igor Susman ] + * mplayer: Associate with *.w64 + + [ Jaak Ristioja ] + * okular: Added support for xz-compressed files. + + [ John Swinbank ] + * _xspecs: Declare as global on bash >= 4.2 + + [ Kevin Locke ] + * test: Increase expect pty to 160 columns + * test: avoid interrupting magic mark output + + [ Per Lundberg ] + * 7z: add .msi support + + [ Peter Wu ] + * tshark: speed up tshark -O completion + * tshark: fix completion of -Xlua_script option + * tshark: Support preferences (-o) completion with memoization + * test: fix misinterpretation of completion output in tests + * test: fix flake8 complaints about unused imports + * conftest: fix RemovedInPytest4Warning due to use of + node.get_marker + * chromium-browser: consider chrome and chromium as aliases + * tshark: support .gz and .cap files for -r expansion + * tshark: prevent a single-character file from breaking -G + completion + * tshark: update -T and -t completions + + [ Russell Davis ] + * man: Fix completion when failglob option is enabled (#225) + + [ Timo Taipalus ] + * mplayer: Add common supported module music formats + + [ Tomasz N ] + * _longopt: pick first long option on a line, not last + + [ Ville Skyttä ] + * *: avoid shellcheck SC1007 and SC1010 + * 7z: add some TODO notes on parsing "i" output for extensions + * ssh: make -o protocol completion less hardcoded + * ssh: make option completion case insensitive + * ssh: fix suboption completion with combined -*o + * xvnc4viewer: code cleanups + * doc/testing: remove lots of legacy info, add some new + * CONTRIBUTING: add upstream vs bash-completion considerations + * CONTRIBUTING: note runLint and run-shellcheck + * __parse_options, 7z: avoid herestrings + * arp, ccze, ifstat, inotifywait, makepkg: invoke sed with "command" + * shellcheck: disable bunch of warnings when in "-S warning" mode + * test: move default shell option from run-shellcheck to + .shellcheckrc + * test: make runLint search for herestrings + * tar, valgrind: avoid some herestrings + * travis: run shellcheck on bash_completion.sh.in too + * travis: fail on shellcheck errors + * make: quote eval array definitions to work around shellcheck + SC1036 bug + * test: add make -C test case + * *: shellcheck error fixes + * _included_ssh_config_files: store found included files in an array + * _included_ssh_config_files: doc grammar fixes + * test: add invoke-rc.d test case for not repeating already given + options + * ebtables: improve existing table arg parsing + * test: add script to run shellcheck, run it in Travis, allowing + failure for now + * iptables: improve existing table arg parsing + * test: shorten long gdb test core file name so tar doesn't croak on + it + * AUTHORS: remove unrelated project association from my entry + * apt-get: protect source against regex specials + * mypy, mysql, xmms: don't complete unknown split long option args + * synclient: remove unused local variable "split" + * test: adjust _get_comp_words_by_ref test to changed error output + * apt-cache: protect showsrc against regex specials + * test: improve tshark -O arg completion test + * tshark: ignore stderr when parsing -G, -L, and -h output + * *: error output consistency, use bash_completion prefix + * _upvar: deprecate in favor of _upvars + * *: add missing "ex: filetype=sh" + * phing: fix getting just a tab for options on CentOS 6 + * phing: don't complete -l with files + * various: apply file vs dir special cases also when invoked with + full path + * *: whitespace tweaks + * ssh: don't offer protocol v1 specific options if it's not + supported + * test: add some gdb non-core files + * _parse_help: look for long options somewhat more eagerly + * gdb: relax core filename pattern + * test/tools: fix exit status incrementation + * *: arithmetic expression related cleanups + * test/tools: run all tools, don't stop at first failure + * test: check for perltidy errors and warnings + * *: format Perl code with perltidy + * *: format Python code with black + * .dir-locals.el: use flycheck-sh-bash-args + * valgrind: look up tools from libexec dirs too + * *: make _parse_usage fallbacks more concise + * svn, svk, wget: use _iconv_charsets + * *: spelling fixes + * msynctool: code cleanups + * *: remove whitespace after redirections + * *: remove spaces immediately within $() + * bzip2: recognize *.tbz2 as bzipped + * modprobe: module parameter boolean values + * ping, tracepath: parse options primarily with _parse_help + * ulimit: new completion + * shellcheck: new completion + * dnssec-keygen: new completion + * modprobe: append = to module parameter completions + * test: include test_unit_longopt.py in dist + * test: add some _longopt unit tests + * _longopt: simplify regex, use printf instead of echo, drop + unnecessary sort + * nsupdate: new completion + * _longopt: don't complete --no-* with file/dirname arg + * copyright: add 2019 + * pytest: complete --pythonwarnings/-W arg + * python: make warning action list reusable + * test: use pytest-xdist + * extra: add git pre-push hook for triggering Docker Hub builds + * post-commit: trigger on test/requirements.txt too + * pytest: complete pytest-xdist --dist, --numprocesses, and + --rsyncdir + * test: remove no longer needed completion/*.exp + * xfreerdp: reinstate support for old versions with dash option + syntax + * test: rewrite "generate" in Python, fix trailing backslash in + EXTRA_DIST + * test: sort t/Makefile.am EXTRA_DIST in C locale + * ssh: support RemoteCommand and SyslogFacility options + * test: Expect failure for chown all users test as non-root + * test: Fix declare test case with bash 5.0 + * adb: Deprecate in favor of one shipped with the Android SDK + * xfreerdp: Update for more modern xfreerdp + * jsonschema: New completion + * test: Remove unnecessary ri xfail + * test: Clean up man tmp dir + * .gitignore: Add .python-version (for pyenv) + * test: Remove unnecessary autouse=True from fixtures + * ifstat: Make work with iproute2 version + * iperf, iperf3: Add some option arg (non-)completions + * test: Fix test generation wrt results checking improvements + * ifstat: New completion + * __parse_options: Avoid non-zero exit status + * test: Refactor/improve completion results checking + * test: Match Python's default locale unaware sort in bash setup + * test: Rename completion.line to .output + * test: Add man failglob test case + * test: Add pre_cmds support for completion fixture + * inotifywatch: New completion, common with inotifywait + * inotifywait: Fix -e completion with BSD sed + * inotifywait: Avoid some false positive event names + * test: extend _ip_addresses unit tests some + * _ip_addresses: Avoid completing ipv4 ones with -6 + * inotifywait: New completion + * test: Mark some xfails based on if in docker instead of in CI + * test: Skip ifup options test if it doesn't grok --help, not in CI + * test: Clean up and docker-ignore __pycache__ dirs + * build: Include test/t in dist tarball + * test/t: Avoid trailing backslash in Makefile.am's to appease + automake + * test: Remove some no longer used old test suite code + * _xspecs: Simplify bash version check + * chmod: Fix "-" completion + * sysctl: Treat -f as alias for -p/--load + * .gitignore: Add pytestdebug.log + * chmod: Fix file completion after modes starting with a dash + * _count_args: Add 3rd arg for treating option-like things as args + * test: Fix _count_args test_7 to test intended case + * pydocstyle: New completion + * Travis: Remove unused PYTEST env var + * doc: Note email issues gateway + * tcpdump: Various option and their arg completion updates + * test: Fix arp CI (non)expectations, remove redundant test case + * test: Be more consistent with "CI" env var examination and xfails + * arp: New completion, somewhat incomplete + * test: Expect failure in gkrellm if there's no X display + * doc: Update docs on generating simple tests + * doc: Some test dependency doc updates + * test: Add requirements.txt for installing dependencies + * grpck: Parse options with _parse_help, falling back to + _parse_usage + * grpck: Add --root/-R arg completion + * test suite: Ignore _scp_path_esc in env for ssh-copy-id + * ssh-copy-id: Add -i and -o arg (non-)completions + * tar: Clean up some redundant code + * cancel: Split long line + * cancel: Add some option arg (non-)completions + * locale-gen: New completion + * makepkg: Don't apply to other than Slackware makepkg + * test: Allow unknowns options in makepkg option completion + * makepkg: Use _parse_help instead of hardcoding option list + * mypy: New completion + * op: New completion + * hunspell: New completion + * xmllint: Improve --encode, --pretty, and --xpath arg + (non-)completions + * test: Remove leftover completion/ls.exp + * gcc: Add g++, gcc, gccgo, and gfortran *-[568] aliases + * perlcritic: New completion + * gnome-screenshot: New completion + * isort: New completion + * freeciv: Option and arg completion updates + * freeciv-gtk2: Install for freeciv and freeciv-gtk3, rename to + freeciv + * mplayer etc: Complete on *.crdownload partial downloads in + addition to *.part + * chromium-browser, google-chrome*: New non-xspec completion + * firefox etc: New non-xspec completion + * Merge branch 'master' into wip-pexpect + * nc: Add some more option (non-)completions + * test: Mark MANPATH without leading/trailing colons test an xfail + on CI CentOS 6 + * test: Remove kill, killall remnants + * test: Make case specific env entries shell code, not escaped + * Merge branch 'master' into wip-pexpect + * unzip, zipinfo: Associate with *.whl + * __load_completion: Avoid unnecessary lookups from nonexistent dirs + * Merge branch 'master' into wip-pexpect + * gcc: Add g++, gcc, gccgo, and gfortran *-7 aliases + * test: Use test_unit_* prefix for unit tests, to avoid name clashes + * test: Support setting cmd=None to require no command, for unit + tests + * test: Misc test suite fixes + * test: Fix jq and scrub skipif commands + * test: Don't require complete marker on test methods + * test: Add support for per-test env modifications + * test: Use more conventional Python file names for tests + * test: Sort completion results in Python for ease of use in Python + tests + * test: Allow __load_completion to fail + * test: chdir to fixtures dir in Python as well + * test: Mark xfreerdp as expected failure for now + * test: Replace + with Plus in test class names + * test: Implement load_completion_for using assert_bash_exec + * test: Add ability to selectively ignore diffs in environment + * test: Fixture reorganization + * test: Pass through $HOME and $DISPLAY to test bash + * test: Log pexpect interaction to $BASHCOMP_TEST_LOGFILE if set + * test: Rename BASHCOMP_* test env variables to BASHCOMP_TEST_* + * test: Add python3 test case + * test: Add class level skipif based on bash exec result + * test: Include command name in test class name, use numbered test + method names + * test: Fix some regressions introduced in recent test conversions + * test: Add support for running test case in a specified dir + * test: Add support for skipping individual tests based on shell + command status + * test: Make test base work with Python 3.3+ + * test: Add some iperf, iperf3 and xmodmap test cases + * xmodmap: Use _parse_help instead of hardcoded option list + * iperf: Improve client/server specific option parsing + * iperf: Install for iperf3 too + * iperf: Add g/G to --format completions + * xmodmap: Use _parse_help instead of hardcoded option list + * iperf: Improve client/server specific option parsing + * iperf: Install for iperf3 too + * iperf: Add g/G to --format completions + * test: Use /root/.local/bin/pytest on ubuntu14 by default + * test: Add generated test files to t/Makefile.am automatically + * test: Add new test files to EXTRA_DIST + * test: Use /root/.local/bin/pytest on centos6 by default + * test: Use make pytest docker executable env-configurable, default + pytest-3 + * test: Update generate for pytest+pexpect + * test: Convert majority of test cases to pytest+pexpect + * tox: Fall back to --listenvs for env list if --listenvs-all fails + * git-post-commit: Avoid some error trash when HEAD is not a + symbolic ref + * test: Add pylint-3 test case + * test: Limit number of pylint option completions + * pydoc, pylint: Determine python2/3 based on command basename only + * pylint: Bring -f/--format arg completion up to date with pylint + 1.9.2 + * pylint: Implement comma separated --confidence arg completion + * test: Fix buffer size option listing in run --help + * test: Bump expect's match_max to 20000 by default + * test: Run docker tests with --verbose + * _services: Try systemctl list-unit-files if systemctl list-units + fails + * extra/git-post-commit.sh: Add git post-commit Docker Hub trigger + hook + * gpgv: New completion + * pydoc, pylint: Skip module completion if current looks like a path + * travis: Run ubuntu14/bsd with no network + * travis: Split long lines in script + * test: Limit number of wget option completions to avoid unresolved + result + * test: Mark flake8 untested if it seems broken + * pylint: Option arg completion improvements + * tshark: Get available interfaces from -D output + * ngrep: Add "any" to -d arg completions + * fio: New completion + * test: Fix iwspy test case + * uscan: Use _parse_help instead of hardcoded option list + * urlsnarf: Add -p arg completion + * tracepath: Add -m and -p arg non-completions + * tracepath: Actually use our separate completion instead of + _known_hosts + * test: Skip jq option completion test if its --help doesn't list + them + * xdg-settings: Make help parsing work on BSD + * test: Support running with local BSD binaries, do it w/ ubuntu14 + in CI + * jq, sqlite3: Protect against negative array subscripts + * sudo: Improve long option arg handling + * sysctl: Recognize --pattern/-r and --load options + * test: Add sysctl option parsing test case + * sudo: Parse options from help/usage output, add some long option + support + * strace: Use _parse_help instead of hardcoded option list + * sshow: Add -p arg completion + * sqlite3: Add some option arg (non-)completions + * tune2fs: Update -o/-O argument lists + * jq: New completion + * reportbug: Run _parse_help and apt-cache more selectively + * querybts: Use _parse_help, not hardcoded option list, misc + improvements + * pyvenv: Support versioned 3.6-3.8 executables + * passwd: Try _parse_help before _parse_usage to parse options + * profile.d: Avoid tested variable values being confused as [ ] + operators + * cryptsetup: Add some option arg (non-)completions + * cryptsetup, nc, sh: Skip option args when counting arguments + * modinfo: Fall back to _parse_usage if _parse_help yields no + results + * mysql, mysqladmin: Complete --ssl-{ca,cert,key} option arg + * mysqladmin: Reuse --default-character-set completion from mysql + * modinfo: Use _parse_help instead of hardcoded option list + * minicom: Use _parse_help instead of hardcoded option list + * mplayer: Associate with *.S[3T]M, *.med, *.MED + * completions/Makefile.am: Use install-data-hook, not install-data- + local + * ifup etc: Add option and option argument completion + * _count_args: Add support for not counting specified option args + * ifquery: New ifup alias completion + * ngrep, tshark: Complete on *.pcapng too + * rpm: Complete --licensefiles with -q + * pytest: Rename from py.test to follow upstream recommended name + * README: Add instructions for overriding completions system wide + * README: Note $BASH_COMPLETION_USER_DIR + * test: Mark psql etc test cases untested if --help doesn't work + * aclocal, automake: Support versioned 1.16 executables + * __load_completion: Avoid bad array subscript on "commands" ending + with slash + * lzma: Use _parse_help instead of hardcoded option list + * test: Run perlcritic and flake8 on perl and python helpers in + Travis + * build: Improve cleanup of test/log and test/tmp dirs + * pkg-config: Complete on *.pc files + * build: Use AC_PROG_SED to locate sed + * build: Do cmake, pc, and profile variable replacements in Makefile + * README: Add Q/A on overriding a completion, modernize local + install answer + * json_xs: New completion + * chmod: New completion + * iperf, nc: Include IPv6 addresses in bind address completions + * links: Major rework, parse options from --help, add option arg + completion + * _ip_addresses: Add option to complete all/v4/v6 addresses, add + unit test + * wget: Remove nonexistent arg to _ip_addresses + * _filedir: Drop unnecessary evals + * iconv: Split charset completion to _iconv_charsets, add test case + * links: Install completion for links2 too + * xgamma: Comment spelling fix + * lftp: handle -s + * test: Skip scrub -p test when its --help doesn't list available + patterns + * ecryptfs-migrate-home: New completion + * scrub: New completion + * ether-wake: Install for etherwake as well + * *: Support completing arg of last bundled short option + * dselect: Parse options with _parse_help + * dhclient: Add some option arg (non-)completions + * dhclient: Parse options with _parse_usage + * chage, chpasswd: Add -R/--root arg completion + * reportbug: Add bunch of option arg (non-)completions + * .dir-locals.el: Set -O extglob for flycheck bash checks + * mount, umount: Deprecate on Linux in favor of util-linux >= 2.28 + ones + * _known_hosts_real: Reimplement known hosts file parsing in pure + bash + * test: Add comment line to fixtures/_known_hosts_real/known_hosts + * ssh: Complete all *File option args with _filedir + * README: Point Debian and openSUSE badges towards unstable and + Tumbleweed + * README: Link to various distro packages + * apt-get: Add -h/-v/-o non-completions + * apt-get: Sync option list with apt 1.5.1 + * apt-get: Simplify -t and friends completion, support Ubuntu + * apt-get: Add indextargets to list of suggested commands + * apt-get: Complete install package=versions + * ssh: Sync config option lists with OpenSSH 7.5p1, add some value + completions + * ssh: Sync query type list with OpenSSH 7.5p1 + * ssh: Order various switch cases closer to alphabetical + * completions/Makefile: Fix check-local in VPATH builds + + [ dmerge ] + * _filedir: Refactor to remove heredoc-dependent loop + + [ marxin ] + * gccgo: Add as a GCC completion target (#227) + + [ ovf ] + * xrandr: match the output name exactly for --mode + + -- Ville Skyttä <ville.skytta@iki.fi> Sat, 27 Apr 2019 11:50:12 +0300 + +bash-completion (2.8) + + [ Andrea Dari ] + * dpkg: Add -V/--verify arg completion + + [ Ben Wiederhake ] + * Add support for .lz4 extension to file-roller (#158) + + [ Eric A. Zarko ] + * unzip, zipinfo: Associate *.gar (#165) + + [ Gabriel F. T. Gomes ] + * openssl: Add completion for the genpkey, pkey, pkeyparam, and + pkeyutl commands + + [ Gonzalo TornarÃa ] + * test: run bash with --norc to avoid system bashrc + + [ Gábor Bernát ] + * tox: New completion (#163) + + [ Halt ] + * mplayer: Disable user config when parsing options + + [ Henry-Joseph Audéoud ] + * ebtables: new completion (#150) + + [ Jakub Jelen ] + * ssh,ssh-add,ssh-keygen: Complete pkcs11 options with *.so + + [ Kevin Pulo ] + * mkdir: Complete on files in addition to dirs + + [ Luca Capello ] + * dpkg-query: Fix -W/--show completion + + [ Mark Friedenbach ] + * Add support for .lzo extension (--lzop) to tar (#155) + + [ Martin d'Anjou ] + * java: Complete *.war + + [ Mateusz Piotrowski ] + * kldunload: Increase robustness of compgen filters (#185) + * kldunload: Show modules with digits + + [ MichaÅ‚ Górny ] + * lftp: Support ~/.local/... bookmark location (#144) + * test suite: Support overriding default match buffer size (#141) + + [ Pawel ] + * man: Don't use $MANPATH directly (#161) + + [ Uwe Storbeck ] + * dpkg: Complete --vextract on deb files + * dpkg: Fix man page section in comment + + [ Ville Skyttä ] + * make-changelog.py: Use python3 + * test: Fix getting username in non-login shells + * test/unit: Whitespace tweaks + * info, man, rsync: Defer _expand invocation + * _expand: Reuse __expand_tilde_by_ref and _tilde logic, clean up + * test: Add some _expand unit tests + * bzip2, gzip, and other compressors: Use _tilde instead of _expand + * test: Add assert_complete_homedir, use in dpkg and ls + * dd, find, gcc: Remove unnecessary tilde expansion + * dd: Omit space only when offering one completion ending with = + * __expand_tilde_by_ref: Eval tilde expansion only, simplify + * Bump copyright years to -2018 + * mkdir: Complete files without appending space + * __load_completion: Load "xspec" completions dynamically too + * __load_completion: Code cleanup + * _available_interfaces: Get rid of eval + * make: Pass script to sed as parameter instead of using process + substitution + * ccze: New completion + * *: Comma separated opt arg completion improvements + * test suite: Some more mplayer and mencoder coverage + * tox: Complete comma separated -e arguments + * xdg-mime,xdg-settings: Fix inclusion in tarball + * geoiplookup: New completion + * ping*,ssh,scp,sftp,tracepath6: Filter IPv4/IPv6 literal addresses + * _known_hosts_real: Add option to filter IPv4 and IPv6 addresses + * radvdump: New completion + * lsscsi: New completion + * python: Support completing dotted module hierarchies + * test/docker: Tweak work dir, add bash as default cmd + * test: Try to skip postconf variable test on broken postfix configs + altogether + * Revert "travis: Don't build local docker images, use vskytta/bash- + completion ones" + * test: Add "postconf -" test case + * test: Work around broken centos/fedora postfix config in non-IPv6 + setup + * travis: Don't build local docker images, use vskytta/bash- + completion ones + * pycodestyle: New completion + * flake8: Various option arg completion improvements + * perltidy: New completion + * lowriter,localc etc: Use corresponding oo* completions + * cryptsetup: Update option lists + * pv: New completion + * getconf: New completion + * nproc: New completion + * _known_hosts_real: Document -a better + * ssh: Add -J/ProxyJump completion + * ssh: Declare $prefix closer to use + * test: Ignore duplicates in find_unique_completion_pair list + * test: dpkg,ls,_tilde: Skip gracefully if no uniq user for + completion is found + * xdg-mime: New completion + * ssh-keygen: Add -E arg completion + * reportbug: Don't hardcode option lists, split option args at = + * reportbug: Add -A/--attach arg completion + * apt-get: Complete *.deb on install if argument contains a slash + * ri: Fix integrated ri 1.8 class completion + * test: Add files to test older ri with + * Whitespace + * test: Remove things moved to library.exp from bashrc + * test: Add some comments regarding bash init in library.exp + * xdg-settings: New completion + * tox: Remove spurious executable bits + * tox: Include ALL in -e completions + * tox: Avoid stderr spewage when -e invoked without tox.ini + * pylint: Invoke python3 to search for modules if command contains 3 + * pylint: Install for pylint-2 and pylint-3 too + * test suite: Add bunch of man and MANPATH test cases + * test suite: Make man test subject names less generic + * test suite: man cleanup + * rfkill: Rename to _rfkill to avoid conflict with util-linux >= + 2.31 + * test: Use prebuilt docker hub bash-completion images + * README.md: Whitespace cleanup + * iptables: Use invoked command instead of hardcoded "iptables" + * iptables: Avoid stderr trashing when invoked as non-root + * iptables: Parse options from --help output + * vpnc: Add some option argument (non)completions + * vpnc: Improve config completions + * test suite: Drop no longer needed fedoradev /usr/bin/which + workaround + * test suite: Skip fedoradev GPG checks at least for now + * lspci: New completion + * lsusb: New completion + * oggdec: New completion + * alias: Fix completion followed by = (#146) + * *: Protect shopt reset from non-default $IFS + * test suite: Limit amount of info and pinfo test output + * test suite: Add info and pinfo option test cases + * test suite: Add basic hid2hci and munin-node-configure test cases + * aptitude: Add keep to commands list (Debian: #867587) + * *: Protect _known_hosts_real from user input treated as options + * curl: Fix -x etc option argument hostname completion + * groupdel: Parse and handle long options + * aptitude-curses: Use aptitude completion + * test suite: Install aptitude in ubuntu14 container + * test suite: Enable wine in ubuntu14 + * xm: Don't leak args and commands environment variables + * uscan: Don't leak cword and words environment variables + * test suite: Add bunch of missing basic test cases + * ktutil: Don't leak i and command environment variables + * test suite: Limit amount of output from process name completion + * test suite: Limit number of screen -T completion matches + + [ j^ ] + * xine etc, ogg123, mplayer -audiofile: Associate with *.oga + + -- Ville Skyttä <ville.skytta@iki.fi> Sat, 17 Mar 2018 10:30:07 +0200 + +bash-completion (2.7) + + [ Eli Young ] + * Makefile: update default compatdir (#132) + + [ Ville Skyttä ] + * Make user completion file configurable, disable in tests + * test suite: Generalize xspec completion install check + * pyflakes: Remove redundant xspec completion + * test suite: Fix __expand_tilde_by_ref test expectation output + * pdfunite: New *.pdf completion + + -- Ville Skyttä <ville.skytta@iki.fi> Sat, 01 Jul 2017 14:08:43 +0300 + +bash-completion (2.6) + + [ Björn Kautler ] + * Add missing sidedoor to .gitignore (#114) + + [ Ville Skyttä ] + * test suite: Mark expected centos6 CI _filedir failures as such + * Expose version in BASH_COMPLETION_VERSINFO, use it in profile.d + script + * test suite: Skip an expected make test case failure in centos6 CI + * test suite: Fix ifdown and ifup CI test skipping + * test suite: Ignore env var pulled in by use of scp in tests + * test suite: If colon trim doesn't do anything, trim as usual + * tar: Comment spelling fixes + * test suite: Mark dpkg -L test case untested if no packages + installed + * test suite: Cosmetic tweaks + * dpkg: Fix dpkg -i home dir completion + * test suite: Improve ls home dir test descriptions + * python: Split module completion to separate helper + * micropython: New completion, aliased from python + * test suite: Add Python module completion test case + * python: Fix traceback avoidance on module completion error + * openssl: Parse available digests from dgst -h + * openssl: Add sha2 commands + * gm: New completion, commands only for now + * (test suite): Test screen -T completions + * (test suite): Set TERM to dumb, not dummy + * Revert "(test suite): Fix alias and cd cursor position tests" + * mplayer: Remove duplicate *.m4a and *.m4v associations + * mplayer, xine, etc: Associate *.mp4a and *.mp4v + * xine etc: Fix *.m4a association + * bind: Add option and argument (non-)completions + * _user_at_host: Set nospace only when completing username part + * _user_at_host: Append @ suffix to username part completions + * man: Don't check OSTYPE or GNU userland, just enable on all + systems + * (test suite): Set dcop result to untested if dcop server is not + running + * (test suite): Don't insist on loading all completions dynamically + * _configured_interfaces: Parse from /etc/network/interfaces.d/* on + Debian + * py.test: New completion + * oowriter: Associate with *.pdf + * Don't define BASH_COMPLETION_COMPAT_DIR + * ri: Add option and arg completions + * (test suite): Add our own dummy ri test fixture + * (test suite): Info test needs docs, don't exclude from CentOS + * (test suite): Fix CentOS 6 tcllib setup + * (test suite): Simplify renice test, fix with only one completion + * (test suite): Don't assume configured interfaces in CI setups + * Don't offer * as configured interface when there are none + * (test suite): Add basic CentOS 6 container for bash 4.1 coverage + * (test suite): Ignore runtime loaded env function changes + * (test suite): Add mailman bin dir to PATH for arch test + * arch: Parse options from --help + * (test suite): Load tested completions dynamically + * (test suite): Accept non-whitespace single word in + assert_complete_any + * (test suite): Avoid interference from user and system dirs (#87) + * (test suite): Install some things N/A in ubuntu14 to fedoradev + * (test suite): Add unrar to ubuntu14 container + * (test suite): Fix alias and cd cursor position tests + * (test suite): Add basic alpine test case + * alpine: Parse opts from -h output, add some opt arg completions + * (test suite): Install jshint globally in ubuntu14 + * (test suite): Add mailman bin dir to PATH for some mailman tools + * (test suite): Install jshint to ubuntu14 container with npm + * unshunt: Parse options from --help + * (test suite): Test lsof on ubuntu14 + * (test suite): Add basic hping3 test case + * (test suite): Add our ./configure to PATH to test it, test opts + * (test suite): Add bunch of packages to ubuntu14 container + * (test suite): Ensure /usr/(local/)games is in $PATH + * (test suite): Fix perl -d* test cases with no Devel::* installed + * (test suite): curl has lots of options, add more test prefix + * (test suite): Fix tar test case for ones having --owner-map + * (test suite): Unsupport various kill, renice cases if ps is N/A + * (test suite): Make chkconfig test behave better in container + * (test suite): Don't assume mounted filesystems in quota* tests + * newlist: Parse options from --help, add some arg non-completions + * (test suite): Delete trailing whitespace + * (test suite): Don't assume lists set up in newlist test cases + * (docker): Pull in missing fedoradev xvfb-run which dependency + * mr: Avoid stderr trash and test suite failure if man is N/A + * (test suite): Fix mmsitepass completion test + * tshark -G: Avoid stderr noise when running as superuser + * (docker): Run completion tests with xvfb-run, e.g. for gkrellm + * ssh-keygen: Make option parsing work with OpenSSH < 7 + * synclient, udevadm: Avoid use of posix char classes for awk + * test suite: Add WIP Fedora dev config + * Travis: Switch tests to docker, update to Ubuntu 14 + * xv: Associate with *.j2c, *.j2k, *.jp2, *.jpf, and *.jpg2 (Debian: + #859774) + * eog: Associate with *.j2c and *.jpg2 + * Bump copyright years + * xine etc: Associate uppercase *.WM[AV] + * mplayer: Associate *.weba (#112) + * xine etc: Associate *.webm and *.weba (#112) + + -- Ville Skyttä <ville.skytta@iki.fi> Tue, 27 Jun 2017 12:29:33 +0300 + +bash-completion (2.5) + + [ BartDeWaal ] + * Support for python gui source files (#91) + + [ Ben Webber ] + * mr: New completion + + [ Christian Kujau ] + * ssh-keygen: support ed25519 keys (#79) + + [ Dara Adib ] + * Add sidedoor to _ssh() completion (#106) + + [ George Kola ] + * .ipa is just a zip file and we should let unzip handle it (#71) + + [ Miroslav Å ustek ] + * ant: parse targets in imported buildfiles (#84) + + [ Reuben Thomas ] + * Add more tests for ccache + * ccache: fix completing compiler's flags + + [ Ville Skyttä ] + * test suite: Add java/javac non-completion fixture + * javac: Complete -cp like -classpath + * travis: Skip bluez and nis for now due to post-install script + issues + * test/config/*: Delete trailing whitespace + * (test suite): Avoid loading user's ~/.bash_completion, fixes #87 + * ip: Recognize a as alias for address and l for link + * ip: Recognize address in addition to addr + * mr: Disable "clean" test case, command N/A before mr 1.20141023 + * ssh-keygen: Parse switches with _parse_usage, not _parse_help + * mplayer: Associate with *.mjpg, *.mjpeg (Debian: #837779) + * dd: Sync completions with coreutils 8.24 + * travis: Add mr + * perl: Remove full path to cat in PERLDOC_PAGER call + * deja-dup: New completion + * CONTRIBUTING: Reorder sections + * *: Move indentation settings to .editorconfig + * make: Declare _make_target_extract_script like other functions + * Travis: zopfli is AWOL? + * *: Whitespace fixes + + [ Zearin ] + * Minor edits to README.md (mostly formatting) (#110) + + [ l3nticular ] + * Fix bug in 'make' completion when using BSD sed (#108) + + [ osu ] + * Add support for Include in ssh config (#70) (#80) + + -- Ville Skyttä <ville.skytta@iki.fi> Sat, 04 Feb 2017 18:07:27 +0200 + +bash-completion (2.4) + + [ Arash Esbati ] + * xetex, xelatex, luatex, lualatex: Associate with tex files + + [ Gene Pavlovsky ] + * Use shell globbing instead of ls to source files in compat dir + + [ Grisha Levit ] + * Support completing array variables and expansions + * Add tests for declare/typeset + * Better handling of typeset/declare + + [ Kylie McClain ] + * tar: silence --version's stderr output + + [ Paul M. Lambert ] + * Support pod document files for perldoc (#39) + + [ Richard Alpe ] + * tipc: fix missing last char in link name completion + * tipc: handle complete words without trailing space + * tipc: suppress tipc error messages + * tipc: use double brackets in if conditions + * tipc: make loop variables local + * tipc: remove unnecessary return values + * tipc: readd call to complete command + * tipc: use cur variable for flag completion + * tipc: add command prefix to link sed + * tipc: remove unnecessary function _tipc_get_val() + * tipc: use bash here string instead of echo + * tipc: merge functions into main + * tipc: add test framework + * tipc: add tipc completions + + [ Ville Skyttä ] + * Release 2.4 + * rpm: Offer --filetriggers with -q + * javadoc: Add bunch of option arg (non)completions + * lrzip: Add -m arg noncompletion + * pkg-get: Don't use hyphens in function names + * jarsigner: Add some option arg (non)completions + * pkg-get,pkgrm: Drop unnecessary _have calls + * *: Trivial cleanups + * *: Remove redundant return 0's + * pypy*: Add basic --jit arg completion + * pypy3: Alias to python + * hcitool,svcadm,tar: Spelling fixes + * Travis: Install more packages for more test coverage + * (test suite): Pass assert_complete_any for exact/only given arg + completed + * tipc: Invoke ls with "command" + * tipc: Indentation fix + * (test suite): Fix fallout from + fec077d555f112b9f455c45860f90a3b47392fcf + * (test suite): Remove Bash::Completion.3pm.gz from git, create on + the fly + * (test suite): Remove test/fixtures/_filedir/a"b from git, create + on the fly + * CONTRIBUTING: Note patch preferences if not using GitHub pull + requests + * python: Support -Q and -W arg completion without space + * apache2ctl, aspell, make: Don't hardcode completion generator + command + * mysql: Avoid --default-character-set error with failglob, fixes + #46 + * test suite: Add perldoc module+pod completion test case + * perl: Remove some duplicated code + * pushd: Use _cd completion for CDPATH support, closes #38 + * test suite: Add basic pushd test case + * abook: Parse long options from command including full path + * pyvenv: New completion + * chroot: New (generic long options) completion, see #38 + * Travis: First steps toward testing with OS X + * test suite: Add bashcomp_bash env var for better control on tested + bash + * aptitude: List packages using _apt_cache_packages, fixes #33 + * vncviewer: Cleanup shopt use, drop an eval + * make: Avoid a grep + * rpm: Fix --whatenhances arg completion + * aspell, minicom, mysql: Replace use of ls with printf + * cppcheck: Complete filenames too for --platform + * man: Prioritize MANPATH, simplify, add fallback e.g. for busybox, + fixes #28 + * aclocal: Install completion for 1.14 and 1.15, fixes #25 + * mpv: Don't install symlink for it, fixes #24 + * test suite: Add function and declare test cases + * CONTRIBUTING: Highlight request for test cases + + [ Wayne Scott ] + * The BitKeeper completion used the wrong set of commands + + -- Ville Skyttä <ville.skytta@iki.fi> Fri, 12 Aug 2016 22:43:27 +0300 + +bash-completion (2.3) + + [ Daniel Milde ] + * Completion for python zip archives + + [ Liuhua Wang ] + * lvm: pvcreate should be able to use all block devcices + * lvm: fix all commands that should get all PVs + + [ Ville Skyttä ] + * Release 2.3 + * make-changelog: Don't output "Merge pull request" entries + * make: Use <<< instead of printf + pipe + * gnokii: Use <<< instead of echo + pipe + * *: Use [:blank:] instead of $'\t ' tricks where appropriate, fixes + #19 + * test suite: Fix abook test case + * test suite: Don't insist on property completions if synclient -l + fails + * test suite: Tolerate "See 'man feh'" feh --help output + * test suite: Fix tar failure caused by previous tar change + * tar: Detect GNU/other from --version only once per session + * tar: Remove unused variable + * tar: Fix GNU tar help output parsing regex, fixes #15 + * test suite: Add tar xvf filename test case + * tar: Don't write to /tmp/jetel + * python: Simplify code + * python: Complete all files also after -m + * python: Don't offer options after -c + * python: Complete all files only if -c is before current word + * test suite: Add some python test cases + * unzip, zipinfo: Complete on *.pyz + * travis: configure and run completions syntax check + * make check: Test syntax of all completion files + * CONTRIBUTING.md: Ask for test cases + + -- Ville Skyttä <ville.skytta@iki.fi> Mon, 28 Mar 2016 18:32:47 +0300 + +bash-completion (2.2) + + [ Barry Warsaw ] + * _init_completion: Handle cword < 0 (LP: #1289597) + + [ Damien Nadé ] + * (testsuite) Use 'set' command posix behaviour when saving env + (Alioth: #314720) + * Added test/site.{bak,exp} to .gitignore + * _parse_help: Fix failglob failures (Alioth: #314707) + * _lvm: using a single-pattern case and invoking function according + to words[1] + * lvm: _lvm_count_args parameter must be quoted in order to failglob + not to complain + * gendiff: Quoting suffix pattern to avoid triggering failglob + + [ Dams Nadé ] + * ssh-add, ssh-keygen: -? needs to be quoted under failglob (Alioth: + #314709) + * Quote unset array element to avoid globbing interference (Alioth: + #314708) + + [ David Paleino ] + * Refactor bts and uscan, since they use common functions + * uscan: New completion, thanks to Federico Ceratto + * bts: New completion, thanks to Federico Ceratto. + + [ Guillaume Rousse ] + * complete on freerdp-specific known hosts list + * nmcli completion was integrated upstream + + [ Igor Murzov ] + * isql: Fix failglob failure + * ssh-add, ssh-keygen: -? needs to be quoted under failglob (take 2) + (Alioth: #314709) + * (testsuite): move testing of _linux_fstab() to umount.exp + * umount: Fix mount points escaping/unescaping with Bash-4.3 + * slapt-src: Handle --config=FILE option properly + * sbopkg, slapt-{get,src}: expand tilde in config file name + * slapt-{get,src}: Fix issue with sed not being able to handle some + characters + * slapt-src: split options from their arguments + * Quote _filedir arguments when appropriate to prevent failglob + failures + * psql: Tell psql to not load .psqlrc as it may change output format + (Alioth: #314636) + * testsuite: Add basic tests for portsnap and freebsd-update + * mplayer: -dvd-devices takes dvd devices, dirs and .iso files as + argument + * 7z: Improve completion + * f77, f95: Use the same completion as for g77, g95 if they are + links to gfortran + * aptitude: safe-upgrade accepts package name as parameters (Alioth: + #313638, Debian: 673235) + * _longopt: Run commands in C locale. + * make: Use only posix basic regexps with sed (Alioth: #314345) + * cppcheck: Add new --enable option argument and --library argument + completion + * dpkg: Suppress unwanted error messages (Debian: #706502) + * perl: -d/-dt option argument is optional (Alioth: #314242) + * Add config for cmake to bash-completion. + * kcov: Add new sort types, complete --replace-src-path arguments + * feh: Add new sort type + + [ Mathieu Parent ] + * Puppet: describe: update options list, accordind to 'puppet help + describe' + * Puppet: cert: update options list, accordind to 'puppet help cert' + * Puppet: apply: update options list, accordind to 'puppet help + apply' + * Puppet: agent: update options list, accordind to 'puppet help + agent' + * Puppet: puppet parser support + * Puppet: puppet -* doesn't imply 'puppet apply' + * Puppet: use puppet terminology + + [ Matthew Gamble ] + * Modify all usages of 'sed' to be run with command bash builtin + * Use command built-in to run sed to avoid any custom aliases + + [ Matthieu Crapet ] + * man: Use -w instead of --path + + [ Michael Gold ] + * profile.d: Avoid some warnings from shells in "nounset" mode + (Debian: #776160) + + [ Miroslav Lichvar ] + * chronyc: Update help text parsing + * chronyc: Add missing subcommands + * chronyc: Add -6 option + + [ Nevo Hed ] + * minicom: Recognize user ~/.minirc.* as config files + + [ Ondrej Oprala ] + * __get_cword: avoid $index < 0 (Alioth: #315107) + + [ Patrick Monnerat ] + * rpmbuild: Complete *.spec on --clean (RedHat: #1132959) + + [ Pavel Raiskup ] + * tar: rework the completion completely + + [ Peter Cordes ] + * upstart support for service completion + + [ Peter Dave Hello ] + * freebsd-update: New completion. + * portsnap: New completion. + + [ Peter Wu ] + * modprobe: fix params with multi-line descriptions + * gdb: support --args style completion (Alioth: #314664) + + [ Rainer Müller ] + * make: Fix basic regex for portability (Alioth: #314345) + + [ Raphaël Droz ] + * gnokii: New completion + + [ Rune Schjellerup Philosof (Olberd) ] + * dpkg: Add support in dpkg completion for .ddeb (LP: #568404) + + [ Shaun McCance ] + * xmllint, xmlwf, xsltproc: Complete on Mallard *.page files + + [ Stefano Rivera ] + * pypy: New completion identical to python (Alioth: #314501) + + [ Thilo Six ] + * Use more straightforward way to check bash version + * _mac_addresses: Use explicit C locale for ifconfig (Debian: + #704832). + + [ Tristan Wibberley ] + * make: Don't pick up variables when makefile is reloaded + * make: Offer hidden targets when it is clear that the user is + trying to complete one of them + * make: Fix detection of intermediate targets where make has changed + its database whitespace + * make: Add __BASH_MAKE_COMPLETION__ variable + * make: completion shouldn't be confused by the output of $(info + confuse: make) + + [ Uwe Kleine-König ] + * Don't complete hostnames found after Hostname in ~/.ssh/config + + [ Ville Skyttä ] + * Release 2.2 + * README.md: Note autoreconf need only in unprepared tarball + * make-changelog.py: Set myself in footer + * make-changelog.py: Fix footer line output + * make-changelog.py: flake8 fixes + * make-changelog.py: Make work with Python 3 + * README.md: More markdown tweaks + * README.md: Markdown tweaks + * zopflipng: New completion + * README.md: Not need for autoreconf, fixes #11 + * README: Expand troubleshooting section somewhat + * Merge pull request #9 from shaunix/master + * ssh: Extract duplicate code to _ssh_configfile + * Remove various comments related to bash versions we don't support + * travis: Install more packages for [xyz]* test coverage + * travis: Install more packages for [stuvw]* test coverage + * travis: Install more packages for [qr]* test coverage + * travis: Install more packages for [op]* test coverage + * travis: Install more packages for m* test coverage + * travis: Install more packages for [jkl]* test coverage + * Merge pull request #7 from ukleinek/master + * indent: Remove generic long option completion + * Update copyright year + * travis: Install more packages for [hi]* test coverage + * travis: Install more packages for [fg]* test coverage + * mysql: Fix --default-character-set completion with mariadb + * mysql, puppet: sed portability fixes + * gnokii, minicom: Use grep through "command" + * lint: Check for sed without "command" + * Merge pull request #2 from djmattyg007/avoid_sed_alias + * travis: Install more packages for [de]* test coverage + * travis: Install more packages for c* test coverage + * travis: Add note about (currently) N/A packages + * test suite: Mark unsupported look test case as such, not + unresolved + * test suite: Use unsupported instead of xfail for modinfo/modprobe + cases + * travis: Install more packages for [0-9][ab]* test coverage + * travis: Run tests with --all to get some more useful output + * test suite: Fix ssh partial hostname completion test + * README: Split contributing to separate CONTRIBUTING doc + * README: Convert to markdown + * Drop references to bash-completion-devel@lists.alioth.debian.org + * build system: Switch to xz compressed tarball + * aclocal, automake: Install for versioned 1.14 and 1.15 executables + * Update URLs and various instructions to GitHub + * README: Update POSIX spec link + * travis: Avoid Travis default ri, use distro one instead + * test suite: Make apt-get test less sensitive to available commands + * test suite: Output tool log on failure in CI + * Set up Travis + * test suite: Expect failure in modinfo/modprobe if there are no + modules + * test suite: Fix ssh-copy-id test on old setups with no identities + * cppcheck: Add native to --platform completions + * ssh: Avoid completing commands before hostname + * chronyc: Parse command args from help output + * chronyc: Wrap long lines + * Load completions also from $XDG_DATA_DIRS (RedHat: #1264094) + * (testsuite) Ignore files generated by complete-ant-cmd.pl + * scp, sftp: Complete -S on commands + * scp, sftp: Fix querying ssh options + * sftp: Add -l arg non-completion + * ssh-copy-id: Offer only *.pub to -i + * mpv: Remove mplayer-aliased completion + * __load_completion: New function, use in _completion_loader and + _xfunc + * modplug*: Associate *.oct and *.okt + * rpm: Add --whatenhances/recommends/suggests/supplements and + --recommends/supplements completions + * pgrep, pidof, pkill, pwdx, vmstat: Add support for procps-ng + * pdftotext: New completion + * checksec: New completion + * ssh: Complete HostbasedKeyTypes,HostKeyAlgorithms,KexAlgorithms + values + * ssh: Query ciphers and macs from ssh before hardcoded fallback + * ssh: Add -Q argument completion + * sysctl: Return early on --help, --version + * sysctl: Try parsing options from help before usage + * Document how to avoid command_not_found_handler interference + * eog: Complete on *.ppm (RedHat: #1090481) + * tar: Plug $line var leak + * tar: Style tweaks + * (testsuite) Add required "empty" dir for tar + * bsdtar, tar: Remove symlinks from git, have make create them + * jshint: New completion + * gnokii: Include and install it + * gnokii: Fix completions of options that are prefixes for others + * gnokii: Drop dead code + * (testsuite): Add basic gnokii test case + * gnokii: Various minor and cosmetic fixes + * _filedir: Avoid some unnecessary work with -d + * _filedir: Remove unused variable + * _filedir: Fix overquoted argument to compgen -d (RedHat: #1171396) + * 2015 + * Load user completions from $BASH_COMPLETION_USER_DIR/completions + * Revert "README: Don't hardcode /etc in cmake fallback dir" + * README: Don't hardcode /etc in cmake fallback dir + * README: Add cmake usage example + * README: Add autotools and cmake tips + * Drop reference to no longer used sysconf_DATA + * synclient: New completion + * tune2fs: Add missing return in -M arg completion + * reptyr: Rename file to _reptyr to avoid conflict with upstreamed + completion + * cppcheck: Option argument (non-)completion update + * dropuser: New completion + * createuser: New completion + * createdb, dropdb: Drop -o default, it does not appear to do + anything good here + * tshark: Simplify cut usage + * mcrypt: Simplify -m arg completion + * (testsuite): Add mcrypt -a and -m argument completion tests + * strings: Fix -T/--target arg completion with non-English locale + * chrome, firefox etc: Complete on *.pdf + * ccache: Add -o/--set-config arg name completion + * gphoto2: Replace tail with awk + * *: Invoke command to be completed, not its basename + * gphoto2: Fix split argument handing, and colon treatment in --port + args + * _completion_loader: Protect compgen from -* leakage (Debian: + #769399) + * Actually install the lz4 completion + * _pnames: Add -s for producing (possibly) truncated names (RedHat: + #744406) + * (testsuite) Add cd in dir without subdirs or CDPATH test case + * Protect various compgen invocations from -* leakage (Debian: + #766163) + * pigz, unpigz: Handle *.zz + * _completion_loader: Set empty command to _EmptycmD_ for cross + version compat + * Comment update + * rpmbuild: Complete *.spec on --nobuild + * mplayer, *xine: Complete on *.mts (Debian: #759219) + * ant: Support buildfile set in $ANT_ARGS (Alioth: #314735) + * (testsuite) Add ant -f <buildfile> test case + * ant: Don't offer more completions after options that exit + * 7z, adb: Trivial cleanups + * python(3): Add -X argument non-completion + * xsltproc. TODO fix for previous commit + * xmllint, xmlwf, xsltproc: Complete on *.dbk and *.docbook (Alioth: + #314770) + * xz: Complete -T/--threads argument + * (testsuite) Save shell variables when saving env (Alioth: #314720) + * adb: New completion + * modprobe: Try parsing help before using hardcoding option list + * (testsuite) Add vgcreate test case for _lvm_count_args with + failglob on + * _filedir_xspec: Fix with failglob on + * Various mostly array element unsetting fixes under failglob + * __reassemble_comp_words_by_ref: Make work with failglob on + (Alioth: #312741) + * _services: README in sysv init dir is not a service + * mpv: New completion alias + adjustments for mplayer (Debian: + #749115) + * (testsuite) Add puppet subcommand option test case + * puppet: Recognize some short options + * puppet: Parse most subcommand options from "help subcommand" + output + * puppet: Exit early on -h|-V|--version in addition to --help + * hostname: New completion + * nslookup: complete on hosts (Alioth: #314673) + * eog: Complete on *.pgm (RedHat: #1090481) + * pngfix: New completion + * qemu: Fix -balloon arg completion + * qemu: Apply completion to qemu-kvm/-system-i386/-system-x86_64 too + * xrandr: Use the invoked command internally, not hardcoded "xrandr" + * xrandr: Add (some) --setprovider* arg completion support + * profile.d: Don't return from a sourced script (Debian: #741657) + * FAQ: Clarify that we mean the bash man page for M-/ + * (testsuite) Avoid complete-ant-cmd.pl errors with our build.xml + * ri: Fix class completion with ri >= 3. + * ri: Fix colon handling in class completion. + * flake8: New completion + * pyflakes: New completion + * cal,chfn,chsh,dmesg,eject,hexdump,look,newgrp,renice,runuser,su,wr + ite: Deprecate on Linux in favor of util-linux ones (Debian: + #737672) + * testsuite: Add basic newgrp test case + * testsuite: Add basic test cases for deprecated completions + * _*: Install our deprecated completions too, try loading them + secondarily + * hwclock,ionice,rtcwake: Deprecate in favor of util-linux ones + (Debian: #737672) + * ssh-keygen: New completion + * Bump copyright years to 2014. + * jpegoptim: New completion + * ip: Add some addr, addrlabel, and route arg completions + * aptitude, dpkg: Replace some grep+cuts with awk + * gcc, lintian, make, pkgadd, slackpkg: grep -> "command grep" + (Debian: #734095) + * lintian: Replace some grep+cuts with awk + * (testsuite) Check for grep and ls invoked without "command", see + README + * lz4: New completion. + * optipng: New completion. + * cppcheck: Include - in --file-list completions. + * (testsuite): Limit wtf completions to A* to keep expect happier. + * wtf: Look for acronym db from /usr/share/games/bsdgames/acronyms + too. + * wtf: Don't offer -f if it was already specified. + * wtf: Hush stderr when db file doesn't exist. + * appdata-validate: New completion. + * timeout: New completion. + * _known_hosts_real: Exclude %h HostName entries (RedHat: #1015935). + * cc, c++: Check path to binary when finding out if it's gcc + (Alioth: #314417). + * cc, c++: Install minimal completion for non-gcc ones (Alioth: + #314417). + * abook, kldunload: Pre-expand \t instead of relying on sed + supporting it. + * dict: Trivial regex cleanup. + * _known_hosts_real: Pre-expand \t instead of relying on sed + supporting it (Alioth: #314393). + * zopfli: New completion. + * bzip2, gzip, lzma: Cleanups. + * Cosmetics. + * export, _variables: Do TZ= completion (Redhat: #994646). + * 2to3: New completion. + * file-roller: Reuse unzip's xspec. + * 7z: New completion. + * hcitool, rfcomm, ciptool, hciconfig: Don't leak $args. + * perl: Fix -dt: completion. + * perl*: Fix handling of relative paths in @INC. + * wget: Add --accept-regex/--reject-regex/--regex-type arg + (non)completions. + * wget: Drop incorrect -nv arg completion. + * wget: Stop completing after --help/--version. + * Clean up/compact various globs. + * cvs: Fix checkout -j non-completion. + * sh: Complete script arguments with all filenames (Alioth: + #314226). + * nmcli: Deprecate our completion, upstream has one in 0.9.8.0. + * Revert "nmcli completion was integrated upstream" + * Use == instead of =. + * cvs rm: Don't filter existing files with -f (RedHat: #949479). + * aclocal, automake: Install for *-1.10, *-1.12, and *-1.13 too. + + -- Ville Skyttä <ville.skytta@iki.fi> Thu, 03 Mar 2016 17:22:50 +0200 + +bash-completion (2.1) + + [ AllKind ] + * Fix __ltrim_colon_completions() fail on parameter (\$1) containing + a glob. + + [ Andreas Müller ] + * completions/Makefile.am: symlinks depends on $(DATA) to avoid race + conditions + + [ Christian von Roques ] + * Fix __reassemble_comp_words_by_ref for $COMP_CWORD == ${#COMP_WORDS[@]} + + [ David Paleino ] + * Fix helper script to create changelogs + + [ Guillaume Rousse ] + * New completions: nmcli, gphoto2 + * Improved completions: + - dsniff: add -p option completion + - dsniff: fix interface completion + + + [ Igor Murzov ] + * _command_offset: Restore compopts properly (Alioth: #313890) + * _parse_help, _parse_usage: Run commands in C locale. + * New completions: wget, zathura + * Improved completions: + - cppcheck: Add new standards to --std option. + - evince: Evince supports opening .pdf.xz files (Alioth: #313739). + - feh: Add new options introduced in feh-2.7. + - feh: Fix list of background styles. + - fusermount: Complete curlftpfs-mounts for "fusermount -u" (Debian: + #685377) + - kcov: Add new sort types (introduced in kcov-9). + - kcov: Complete arguments of --limits option. + - lvm: Fix typo in option name: s/continguous/contiguous/. + - make: Do not append space if target is a filepath. + - mount: Fix parsing /etc/fstab on *BSD. + - mount.linux: Add some new mount options intoduced in Linux 3.5 and 3.7 + - mount.linux: Add options completion for nfs and davfs. + - mount.linux: Clean up mount options, remove duplicates. + - mplayer: Add opus to the list of supported formats. + - mplayer: Add -subcp argument completion. + - opera: Handle options. + - slackpkg, slapt-get: Update the list of package sets. + - tar: Fix detection if the $prev is a tar file. + - valgrind: Add --soname-synonyms option arguments completion. + * Testsuite: + - _filedir: Remove the cruft from the a\$b->h unit test (Alioth: #313480) + + [ Jeroen Hoek ] + * Improved completions: + - unzip: Add support for OpenDocument formats. + + [ Ken Sharp ] + * Improved completions: + - wine: add .msi completion + + [ Martin Ueding ] + * Stylistic cleanup + + [ Tristan Wibberley ] + * Improved completions: + - make: incremental completion for make with compact display + - make: convert make completion to use smarter parser + + [ Ville Skyttä ] + * Avoid sourcing dirs in completion loader to avoid fd leaks (RedHat: #903540) + * Ignore colormake symlink. + * Line continuation, whitespace, and compgen -W ... -- "$cur" + quoting cleanups. + * _available_interfaces: Try with "ip link" if ifconfig is not available. + * _ip_addresses: Try with "ip addr" if ifconfig is not available. + * _known_hosts_real: Filter ruptime stdout error spewage (Alioth: #313893). + * _mac_addresses: Try local interfaces with "ip link" if ifconfig not + available. + * _mac_addresses: Try ARP cache with "ip neigh" if arp is not available. + * _mac_addresses: Fix with net-tools' ifconfig that outputs ether, not HWaddr. + * New completions: chronyc, eject, eog, file-roller, hexdump, interdiff, lua, + luac, luseradd, luserdel, lusermod, mussh, nc, ngrep, patch, pydoc, + pyflakes, pylint, ss, strings, tshark, wsimport, xxd + * Improved completions: + - acpi, chpasswd, dmesg, gkrellm, groupmems, hwclock, lastlog, pwd, vipw: + Complete options even without "-" given. + - arpspoof, dsniff, ether-wake, nmap: Offer active interfaces only. + - clzip, pdlzip, plzip: New lzip alias completions. + - colormake: New make alias completion (LP: #743208, Debian: #682557) + - cpio: Recognize pass thru when -p is bundled w/other options + (RedHat: #912113). + - cppcheck: Add --language/-x argument completion. + - cppcheck: Complete --include= with filenames. + - dnsspoof, filesnarf, macof, sshow, tcpkill, tcpnice, urlsnarf: Fix -i + completion. + - genisoimage: Use _parse_help instead of hardcoding options, add basic test + case. + - groupmems: Add -R/--root arg completion. + - hexdump: Actually install for hd as well. + - host: Complete with known hosts. + - ip: Improve addr show and link show completions. + - ip: Remove some stale TODOs. + - jar: Reuse unzip's xspec (RedHat: #928253). + - koji: Complete on build targets when --target is given to wait-repo. + - lv{create,resize,extend}, vg{create,reduce,extend,split}: Fix variable + leaks. + - lvm: Add _lvm prefix to helper functions. + - lvm: Take option args into account when counting args (RedHat: #860510). + - lvm volumes: Complete on /dev/mapper/* (RedHat: #851787). + - lzip: Do not append space after equal sign in long options. + - make: Convert internal variable names to lowercase, indentation fix. + - make: Don't leak $mode. + - make: Make work in POSIX mode. + - man: Add support for .lz man pages (RedHat: #839310). + - man: Don't expand man page extensions too early. + - man: Fix -P/--pager full path arg completion. + - modinfo: Use ,, for lowercasing instead of tr in a subshell. + - modprobe: Don't suggest installing already installed modules. + - ncftp: Add option completion. + - pkg-config: Try to complete --variable= if package name is already given. + - pydoc: Complete on keywords and topics. + - python, pydoc: Add module completion. + - scp: Treat strings with slash before colon or starting with [.~] as local. + - ssh: Add some -o and related arg completions. + - ssh: Add -O argument completion (Debian: #680652). + - tar: Don't take -I to mean bzip2. + - tar: Fix completing files inside *.tlz when J is explicitly given. + - tar: Simplify bzip patterns. + - tar: Support *.tar.lz (Debian: #703599). + - tar: Recognize taz and tb2 as compressed tarballs. + - tcpdump: Fix -z full path arg completion. + - unzip/zipinfo: Associate with more StarOffice extensions. + - useradd, userdel, usermod: Add -R/--root arg completion. + - useradd, usermod: Support comma separated -G/--groups arg completion. + - useradd: Fix -k, -K, and --home-dir argument completions. + - userdel: Add -h/--help non-completion. + - valgrind: Fix full path <command> arg completion. + - vgcreate: Add missing symlink. + - vipw: Add -R/--root arg completion. + - vpnc: Add bunch of option arg (non)completions. + - vpnc: Use _parse_help instead of hardcoding options, add basic test case. + - wget: Use == instead of =. + - wine: Fix extension glob to work on its own. + - wol: Try "ip addr" before ifconfig for finding out broadcast addresses. + - xrandr: Add bunch of option arg non-completions. + - xrandr: Use _parse_help. + - xrandr --mode: Clean up one awk call. + - xrandr: Avoid --mode completion error when --output is not given. + - xrandr: Don't leak $i when completing --mode. + * Deprecated completions: + - udevadm: one is shipped in systemd >= 196 (RedHat: #919246). + * Testsuite: + - Make pydoc test more likely to work with our limited expect buffer size. + - Fix pwd unit test + + [ Yann Rouillard ] + * New completions: pkgutil, pkgrm, pkgadd, pkg-get, svcadm. + + [ wonder.mice ] + * Fixed tilde expanding in _filedir_xspec + + -- David Paleino <d.paleino@gmail.com> Fri, 05 Apr 2013 12:05:15 +0200 + +bash-completion (2.0) + + [ Anthony Ramine ] + * Properly declare 'symlinks' dependencies + + [ David Paleino ] + * apt-get: add 'changelog' to completed commands + + [ Guillaume Rousse ] + * Add xz compression extension for kernel modules + + [ Igor Murzov ] + * sudo: Handle options (Alioth: #311414). + * sudoedit: New completion. + * _command_offset: Properly quote arguments of eval (Alioth: + #313499). + * mount.linux: Add some new mount options intoduced in Linux 3.0-3.2 + * _modules: Ignore error messages. + * modprobe, modinfo, insmod: Move modprobe and modinfo completions + to their own files. + * sbopkg: Use _parse_help. + * sbopkg, slackpkg, slapt-{get,src}: Use shorter form of the check + if file exists. + * _filedir: Properly quote paths to avoid unexpected expansion. + * su: Add linux-specific completion + * insmod, modprobe: Don't hardcode path to modinfo (Alioth: #313569) + * man: --path option is supported on Darwin (Alioth: #313584) + * man: Move variable declaration to the right place. + * feh: Update option argument completions. + * fbi, feh: Complete more supported file formats. + * fbgs: Add new options introduced in fbida-2.09. + * cppcheck: Complete new --relative-paths option arguments + * _expand: Suppress unwanted bash error messages (Alioth: #313497) + + [ Itaï BEN YAACOV ] + * scp: Recognise symlinks to directories as directories (Debian: + #666055). + + [ Jonathan Nieder ] + * ri: Rename ri_get_methods helper to add leading underscore + + [ Ville Skyttä ] + * rmmod: Add option completions. + * testsuite/generate: Generate less linefeeds. + * insmod: Install for insmod.static too. + * mplayer: Add -monitoraspect arg completion. + * mplayer: Add generic handling of options that take arguments. + * testsuite: Fix spurious modinfo and modprobe test failures on + systems that have /lib and /lib64 dirs. + * pigz: Add -p/--processes arg completion. + * testsuite: Add basic su test case. + * su: Fix long option handling. + * su: Add --session-command arg completion. + * su: Complete -s/--shell with shells instead of all files. + * lyx: Remove simple completion, upstream has more complete one + (Debian: #662203) + * testsuite/generate: Tweak linefeeds. + * make: Add generic variable completion. + * man: Recognize 3gl as man page filename extension -- at least Mesa + uses it. + * _realcommand: Try greadlink before readlink (Alioth: #313659). + * Comment spelling fix. + * qiv: Add *.svg. + * xmllint: Add *.svgz. + * autotools: Use MKDIR_P instead of mkdir_p (Alioth: #313671). + * lbzip2: Add -n argument completion. + * *_tilde*: Escape tilde in [[ $1 == \~* ]] tests (RedHat: #817902). + * New completions: + - acpi, hwclock, pwd, ssh-add, vmstat + + [ Sung Pae ] + * Workaround bash bug that fails to complete <, > + + -- David Paleino <d.paleino@gmail.com> Sun, 17 Jun 2012 20:01:36 +0200 + +bash-completion (1.99) + + * Hopefully the last 2.0 preview. + + [ David Paleino ] + * Correctly list purgeable packages for dpkg --listfiles and dpkg + --purge (Debian: #647684) + * Fix bash_completion paths in README (Debian: #647941) + + [ Florian Hubold ] + * xv: Add *.eps and *.ps to filename completions (Alioth: #313477) + + [ Igor Murzov ] + * Add and use _sysvdirs() function that sets correct SysV init + directory. + * cppcheck: Add new options introduced in cppcheck-1.52. + * cppcheck: Several ids separated by commas can be given for + --enable=. + * _known_hosts_real: Add some quotes (Alioth #313158) + * Merge completions/service into the bash_completion script. + * _modules: Follow symlinks in /lib/modules/$(uname -r) (Alioth: + #313461) + * mount, umount: Add linux-specific completions. + * mount: Don't suggest short options. + * pidof: Don't check OS type (Alioth #311403) + * removepkg: Make it possible to complete filenames. + * umount: Fix for completion of relative paths. + * upgradepkg: Support oldpackage%newpackage notation. + * wine: Complete all files after an .exe (Alioth #313131) + * New completions: + - htop, nethogs. + + [ Jan Kratochvil ] + * rpm: Treat -r as --root (RedHat: #759224). + + [ Raphaël Droz ] + * Added a word about compopt -o nospace in styleguide.txt. + * _ip_addresses: Make it locale agnostic. + + [ Ville Skyttä ] + * cc, c++: Install gcc completion if compiler looks like GCC + (Alioth: #311408). + * cppcheck: Offer header filename completions too. + * curl: Add bunch of new option argument completions. + * dequote: Use printf instead of echo (Alioth: #312163). + * dict: Speed up word completion with common use cases and large + word lists. + * dmesg: Adapt to versions returning long options. + * Document $split && return. + * _filedir, _tilde: Ignore compopt stderr for direct invocations in + unit tests. + * Include doc/ in dist tarball. + * _known_hosts_real: Handle more than two hostnames per known hosts + line (Debian: #647352). + * _known_hosts_real: Include hosts reported by ruptime (Alioth: + #313308). + * _known_hosts_real: Support > 1 files per *KnownHostsFile line + (Debian: #650514). + * lintian: Use <<< instead of echo and a pipe (Alioth: #312163). + * lrzip: -T no longer takes an argument since version 0.570. + * _mac_addresses: Grab addresses from FreeBSD's ifconfig -a output + too. + * make: Add -j/--jobs completion, complete up to number of CPUs * 2. + * _muttconffiles: Use printf instead of echo (Alioth: #312163). + * _parse_help, _parse_usage: If first arg is "-", read from stdin. + * rpm: Add --delsign completion, don't suggest --resign (identical + to --addsign). + * _variables: New function split from _init_completion. + * vi and friends: Fix /etc/ld.so.conf.d/* completion (Alioth: + #312409). + * New completions: + - plague-client, desktop-file-validate, valgrind, ccache, iperf, + koji, lzip, udevadm. + + -- David Paleino <d.paleino@gmail.com> Sat, 07 Jan 2012 23:52:36 +0100 + +bash-completion (1.90) + + * bash-completion 2 preview: dynamic loading of completions. + + [ David Paleino ] + * If _filedir 'ext' returns nothing, just fallback to generic file + completion. It is optional, and off by default. Patch by Clint Byrum + (Debian: #619014, LP: #533985) + * Fix __get_cword_at_cursor_by_ref: check for $index when completing with a + cword+1 argument already present (Debian: #622383) + * Layout change: everything is now in /usr/share/bash-completion/, rather + than in /etc/. + * Get rid of BASH_COMPLETION_DIR, BASH_COMPLETION_HELPERS_DIR, BASH_COMPLETION + * Fix autotools to use pkgdatadir instead of redefining datadir, get rid of + helpersdir. + * Implemented a blacklist for unwanted third-parties completions + * New completions: + - epdfview, lpr and lpq (Raphaël Droz), mysql (Raphaël Droz) + * Improved completions: + - ant: handle "extension-point" the same as "target" tag (Petr Kozelka, + Alioth: #313105) + - apt: add 'download' to subcommands (Debian: #625234, Ubuntu: #720541) + - aptitude: add 'versions' command (Debian: #604393) + - dpkg-query: use the 'dpkg' completion (Debian: #642526) + - lintian: remove --unpack-level (Debian: #623680) + - {shadow,coreutils}: fix broken _allowed_groups usage + - rrdtool: complete filenames after commands (Debian: #577933) + - sitecopy: fixed a bug with grep and brackets: use sitecopy -v to fetch + sites (Raphaël Droz). + + [ Freddy Vulto ] + * Improve __reassemble_comp_words_by_ref() (Alioth #313057) + * Testsuite: + - add -unsorted option to _get_hosts() + + [ Guillaume Rousse ] + * Use $() for subshell, instead of backquotes + * Use simple quotes for constant strings + * Drop -o filenames, as suggested by Ville + * New completions: puppet + + [ Igor Murzov ] + * Abort completion file loading earlier if required commands are not + available. + * docs: Improve tester's manual + * Make completions that use _command also work with file names + * _command_offset: Restore compopts used by called command. + * New completions: + - pkgtool, makepkg, rmp2tgz, slapt-get, slapt-src, slackpkg, kcov, feh, + xgamma, fbi, fbgs + * Improved completions: + - file: ddd few missing --exclude arguments completions + - host, nslookup: Remove completions for bind utils from bash_completion. + - {install,upgrade,explode}pkg: use -o plusdirs instead of -o dirnames + - makepkg: should complete filenames + - removepkg, upgradepkg, installpkg: add option completion + - xrandr: Add more option completions. + - overall clean up of different slackware-specific completions + * Testsuite: + - add basic tests for pkgtools, rpm2tgz, slapt, sbopkg, slackpkg + - fix broken tests for finger and xhost + - remove unused -expect-cmd-full option from assert_complete* + + [ Sergey V ] + * New completions: sbopkg + + [ Ville Skyttä ] + * Load completions in separate files dynamically, get rid of have() + * Drop unnecessary $USERLAND checks + * Try /usr/sbin before /sbin in have() + * Try both full path and basename completions for sudo etc (Alioth: #313065) + * Add _init_completion() for common completion initialization and generic + redirection handling + * Replace actual sysconfdir in bash_completion on install (Alioth: #313081) + * Drop support for bash < 4.1 + * Drop no longer needed _compopt_o_filenames() + * Drop no longer needed "type compopt" checks + * docs: Update "simply sourcing" instructions to match new layout, check + $PS1. + * Get rid of bash_completion self-parsing from _filedir_xspec + (RedHat: #479936). + * Provide profile.d hook for per user disabling of bash_completion + (Debian: #593835) + * New completions: + - a2x, arping, asciidoc, base64, cal, chrpath, cppcheck, curl, dmesg, + dot, file, gnome-mplayer, gprof, hddtemp, host, htpasswd, idn, ionice, + jps, lbunzip2, lbzip2, lbzcat, prelink, protoc, pwdx, pwgen, reptyr, + sum (RedHat: #717341), watch + - phing: reuse ant completion (Elan Ruusamäe, Alioth: #312910) + - pinfo: reuse info completion + * Improved completions: + - bluez, e2fsprogs, grpck, java (Mattias Ulbrich), passwd, pwck, route, + rsync, smartctl + - ant: improve -lib, -find/-s, and -D argument completions; rewrite build + target parsing in plain bash, add build file test case + - aspell: add --add-filter|--rem-filter completions; get --mode completions + from 'aspell modes' output + - bzip2, gzip, python, sysbench: quote command argument to _parse_help() + - chsh: use _allowed_users instead of plain compgen -u + - cksfv: add -g argument completion + - cpan2dist: don't hang if no package list files exist + - crontab: use /sys/fs/selinux and /selinux instead of /etc/selinux to + find out if SELinux is around + - cvs: (diff) parse options from cvs diff instead of plain diff; drop -o + default to fix CVS root completions; (commit) complete on entries + instead of default if COMP_CVS_REMOTE is not set; improve CVS + controlled file completions; add CVS controlled file completions for + admin and update; list "primary" command names first in mode switch; + recognize some additional commands and synonyms; add editors/watchers + completion; sort mode completions alphabetically + - freeciv: complete freeciv-* in addition to civclient/civserver + - gdb: improve filename completion + - gendiff: do file completion after output redirection + - getent: add gshadow to known databases; allow multiple completions from + same db, add option completion + - info: add option completion support + - ipsec (Tobias Brunner): drop uname check, add strongSwan specific + completion with fallback, complete connection names for 'up', 'down' and + other commands + - jar: complete on *.sar (JBoss service archive) + - java, javac: add -X* completions + - javadoc: implement -linkoffline two argument completion + - killall: activate completion on Darwin (Alioth: #312350) + - (la)tex (Ted Pavlic): add *.dbj to filename completions (RedHat: #678122) + - man: add option parsing and completion + - modplug*: add more extensions for files supported by libmodplug + - mutt: support tildes when recursively sourcing muttrc files + (Debian: #615134); expand tilde in mutt query command (Alioth: #312759) + - ntpdate: add some option argument (non)completions + - oo{writer,impress,calc,draw} (Matej Cepl): complete on LibreOffice + FlatXML extensions (RedHat: #692548) + - perldoc (Scott Bronson): override MANPAGER when generating perldoc + completions (RedHat: #689180); don't parse man page when we know it'll + produce no completions; use perldoc itself instead of man + - pgrep: add option and option argument completions + - rpm: make rpm --queryformat use more consistent; drop rpm query support + for rpm < 4.1 + - rpmbuild: add --buildpolicy completion + - rpmcheck: drop reference to undefined $files variable (Alioth: #313270) + - screen: add _terms() and -T completion; add commands completion + (Alioth: #312164, RedHat: #547852) + - _services: avoid bogus completions when init or xinetd dirs exist but are + empty; include systemd services + - smartctl: fix short alternative for --tolerance + - ssh, scp, sftp, ssh-copy-id: add some option argument (non)completions + - strace: don't append space for -e *= completions; don't try to extract + syscall names if they're not going to be used; rewrite arch specific + syscall extraction in plain bash + - svn*: don't suggest short options + - tar: fix completion of files inside *.tar.bz2 archives when [Ijy] is not + given; added option completions; improve tar *[cr]*f completions + (Debian: #618734) + - unzip: complete on *.sar (JBoss service archive) + - xmllint, xmlwf: complete on *.tld (tag library descriptor) + - xmlwf: add -v non-completion + - xmms: add some option argument completions + - xz: apply xz completion to pxz too; non-complete + --memlimit{,-compress,-decompress} + * Testsuite: + - add basic tests for gendiff, mdadm, puppet, xzdec, mii-diag, mii-tool, + grpck, passwd, pwck, samba, rdesktop, fusermount, tcpdump, l2ping, + ssh-copy-id, postfix, qemu, ldap*, medusa, mdtool, monodevelop, + msynctool, cfagent, lpr, lpq, mysql, nslookup, compare, conjure, + import, stream + - fix tests for ri + - fix get_hosts option docs. + - add test case for Debian: #622383. + - add chown foo: and :foo test cases, should complete files + (RedHat: #710714) + + -- David Paleino <d.paleino@gmail.com> Thu, 03 Nov 2011 09:53:55 +0000 + +bash-completion (1.3) + + [ Guillaume Rousse ] + * added pure-perl perldoc completion helper, using work from Aristotle + Pagaltzis (pagaltzis@gmx.de) + * added completions for xfreerdp and iscsiadm + * updated xm subcommands list + + [ David Paleino ] + * Fixed "service" completion, thanks to John Hedges (Debian: #586210) + * Complete on all files for mplayer's -dvd-device + * Fixed typo in openssl completion (Debian: #609552) + + [ Ville Skyttä ] + * Activate hping2 completion also for hping and hping3. + * Add badblocks, compgen, crontab, dumpe2fs, e2freefrag, e2label, ether-wake, + filefrag, gendiff, growisofs, iftop, ip (Debian: #600617), javaws, kid3, + lrzip, lsof, mktemp, portecle, POSIX sh, sha{,224,256,384,512}sum, + sysbench, tune2fs, xmodmap, and xrdb completions. + * Add *.gif (Alioth: #312512), *.m2t (Alioth: #312770), *.3gpp, *.3gpp2, + *.awb, and *.iso (Alioth: #311420) to mplayer filename completions. + * Add "short" tarball extensions to unxz, unlzma etc completions. + * Improve /etc/init.d/*, ipmitool, jar, java, javadoc, man, mencoder, mkdir, + mplayer, pack200, povray, python, rpmbuild, sqlite3, tar, wodim, and + general help parsing completions. + * Fix p4 and povray completions (Alioth: #312625). + * Add *.xsd, *.xsl, *.rng, *.wsdl, and *.jnlp to xmllint and xmlwf filename + completions, and *.gz versions of all of the supported ones for xmllint. + * Recognize rpm query mode based on the --file, --group, --package, and + --all long options (RedHat: #630328). + * Improve rpm query option completions. + * Drop bad kompare filename completion (Alioth: #312708). + * Make _filedir and _filedir_xspec complete uppercase versions of their + filename extension arguments in addition to exact case matches. + * IPv6 known hosts completion fixes (Alioth: #312695, RedHat: #630658). + * Fixes to completions for filenames containing tabs (RedHat: #629518). + * Add *.iso (Alioth: #311420), *.m2t and *.m2ts (Alioth: #312770) to + xine-based player filename completions. + * Add /etc/ethers to MAC address completion sources. + * Add *.gem and *.spkg to tar filename completions. + * Complete known hosts from avahi-browse only if $COMP_KNOWN_HOSTS_WITH_AVAHI + is non-empty (Alioth: #312691, RedHat: #630326). + * Improve relevance of many user/group completions, depending on context. + * Remove most "-o filenames" options to "complete", turn "-o filenames" on + dynamically when needed instead. + * Add/improve various autotools completions. + * Add *.apk to unzip and jar filename completions. + * Do not load bash_completion in profile.d script if progcomp is not enabled. + * Ignore muttrc source entries that are not files (Alioth: #312881). + * Re-enable postgresql database and user completion (Alioth: #312914, + Ubuntu: #164772). + * Add *.fdf to various PDF viewer completions. + + [ Freddy Vulto ] + * Added _tilde(), fix ~username completion (Alioth: #312613, Debian: #587095) + * Speed up `compopt' availability detection + * Fix _filedir `-o filenames' detection on bash-3 (Alioth: #312646) + * Fix __reassemble_comp_words_by_ref (Alioth #312740) + + [ Anton Khirnov ] + * Improve mplayer and mencoder completions. + + [ Paul Walmsley ] + * Add *.webm to mplayer file completions (Debian: #588079). + + [ Miklos Vajna ] + * Add *.amr to mplayer file completions (Alioth: #312634). + + [ Andrej Gelenberg ] + * Add *.part (partially downloaded) to mplayer and xine-based player + completions (Alioth: #312657). + + [ Stephen Gildea ] + * Fix false posives for non-option words in _parse_help (Alioth: #312750). + + [ Andrey G. Grozin ] + * Add *.fb2 to okular filename completions. + + -- David Paleino <d.paleino@gmail.com> Sun, 06 Feb 2011 19:03:46 +0100 + +bash-completion (1.2) + + [ David Paleino ] + * Don't use pidof in _known_hosts_real() to detect whether Avahi is + available, since it's not available on MacOS X. Thanks to Rainer + Müller <raimue@codingfarm.de> (bash-completion MacPorts maintainer) + * Fixed "freq" and "rate" completion for iwconfig + * contrib/munin-node fixed (Debian: #550943) + * contrib/dpkg fixed -W and --show completing on .?(u)deb's (Debian: #552109) + * contrib/aptitude: add @(add|remove)-user-tag + * Added munindoc completion to contrib/munin-node, thanks to Tom + Feiner (Debian: #553371) + * Added colordiff completion, same as diff + * contrib/cpio: added missing completions for -?, --help, --license, --usage, + --version and (-p) --to-stdout (Debian: #557436) + * Style policy: don't use fancy globbing in case labels + * Added .fdf completion to okular and evince + * Added .okular completion to okular (Debian: #545530) + * Added lintian completion + * Refreshed reportbug completion, added --from-buildd (Debian: #579471) + * Special-case "apt-get source" (Debian: #572000) + * Added lintian completion (Debian: #547361) + * contrib/dpkg: update completion to current API + * Styleguide: establish line wrapping and $() instead of `` + + [ Ville Skyttä ] + * Create bz2 dist tarball too. + * Include CHANGES in dist tarball. + * Include profile snippet in tarball, install it. + * Rename contrib/bluez-utils to contrib/bluez to follow bluez 4.x naming. + * Apply cardctl completion to pccardctl too. + * Apply pine completion to alpine too. + * Remove many unnecessary short option completions where long ones exist. + * Improve chsh, chgrp, chown, configure, curl, cvs, find, gkrellm, gzip, + iconv, lftp, look, lzma, make, man, mdadm, modprobe, mount, mplayer, + mysqladmin, perldoc, rsync, screen, service, scp, ssh, sshfs, unzip, + update-alternatives, vncviewer, wget, yp-tools, xine based players' and + general hostname completions. + * Add abook and wtf completion, based on work by Raphaël Droz. + * Add cvsps, dragon, fusermount, jarsigner, k3b, lftpget, modplug123, + pm-utils, rtcwake, pack200, unpack200, pbzip2, pbunzip2, pbzcat, pigz, + unpigz, and wol completions. + * Don't overwrite other host completions when completing from multiple + SSH known hosts files. + * Speed up installed rpm package completion on SUSE, based on work by + Marco Poletti (Alioth: #312021). + * Improve sourcing snippets from completion dirs. + * Drop support for bash < 3. The compatibility global variables $bashN, + $default, $dirnames, $filenames, $compopt, $nospace, $bashdefault, and + $plusdirs have been dropped too. 3rd party completions should switch + to using the complete/compgen features directly, and BASH_VERSINFO + for bash version checks. + * Protect various completions from unusual user input by not embedding the + input in external command arguments (Debian: #552631). + * Add /sbin to $PATH when invoking ifconfig and iwconfig. + * Combine dcop and qdbus completions into the latter. + * awk and sed usage portability fixes (Alioth: #311393, Debian: #501479). + * Fix leaking local variables from various completions. + * Turn on -o filenames in _filedir on bash >= 4. + * Deprecate modules completion, upstream modules >= 3.2.7 ships one. + * Protect grep invocations from user aliases (Alioth: #312143). + * Split sshfs completion from contrib/ssh into contrib/sshfs. + * Split mount and umount completion into contrib/mount. + * Split service completion into contrib/service. + * Split chown, chgrp, and id completions into contrib/coreutils. + * Split kill, look, and renice completions into contrib/util-linux. + * Split killall, pkill, pgrep and related completions into contrib/procps. + * Split ipsec completion into contrib/ipsec. + * Split ifup and ifdown completions into contrib/ifupdown. + * Do basic HTML file completion with Firefox and Chrome and friends, + and Epiphany. + * Do basic diff/patch completion with cdiff and kompare. + * Don't install mock completion by default, it's in upstream mock > 1.1.0. + * Do basic text editor completion with xemacs, sxemacs, kate, and kwrite. + * Do meta-command completion for aoss and padsp. + + [ Freddy Vulto ] + * Prevent root PATH expansion prolifering in _root_command (bash >= 4.1.4) + * Only complete xhost if (_)xhost is available. + * Added _get_comp_words_by_ref to replace both _get_cword & _get_pword. + Also additional variables `words' and `cword' can be returned. + * Added _upvar & _upvars helper functions to aid in passing variables + by reference. + * Make _filedir emulate `-o filenames' + * Fixed completion perl modules containing colons. + * Merged __get_cword3 & __get_cword4 to _get_cword. + * Added __expand_tilde_by_ref helper function. + * Added __ltrim_colon_completions to fix completions containing colons + * Improved mutt completion + * Added _get_pword helper function, thanks to Sung Pae (Alioth: #312030) + + [ Ted Stern ] + * Fix modules completion for "(default)" entries. + + [ Jeremie Lasalle Ratelle ] + * Fix rsync remote path completion (Alioth: #312173, Gentoo: #297818). + + [ Leonard Crestez ] + * Improve ssh -o suboption completion (Alioth: #312122). + * Fix NFS mounts completion (Alioth: #312285). + * Fix completion of usernames (Alioth: #311396, Debian: #511788). + * Fix chown test crashing on systems with no root group (Alioth: #312306). + * Fixed tests when BASH_COMPLETION or TESTDIR contain spaces. + * Fix mount handling of escapes (Alioth: #311410, Launchpad: #219971, + Debian: #511149). + * Cleanup scripts to run tests. Make runUnit and runCompletion use test/run. + Make it possible to run tests from any directory. + * Add a --debug-xtrace option to test/run using BASH_XTRACEFD from bash-4.1. + * Add a --timeout option to test/run to override the default expect timeout. + + [ Raphaël Droz ] + * Add xsltproc completion (Alioth: #311843). + + [ Adrian Friedli ] + * Add ipv6calc completion. + + [ Ildar Mulyukov ] + * Add showmount completion (Alioth: #312285). + + [ Neville Gao ] + * Fix mount completion error "bash: [: too many arguments" (Alioth #312381). + + [ Austin English ] + * Make lookup of wine file completions case insensitive. + + [ Igor Murzov ] + * Improve xz completion (Alioth: #312466). + + [ Mario Schwalbe ] + * Update find completion (Alioth: #312491, Launchpad: #570113). + + [ Mark van Rossum ] + * Add basic lyx completion. + + -- David Paleino <d.paleino@gmail.com> Wed, 16 Jun 2010 17:44:59 +0200 + +bash-completion (1.1) + + [ David Paleino ] + * Permit .gz files concatenation (Debian: #514377) + * Fix svk completion using $filenames instead of $default (Debian: #524961) + * Really add build-dep to aptitude's completion (Debian: #495883) + * Fix checks for GNUish userland, thanks to Robert Millan (Debian: #529510) + * Fix typo in .ass subtitles completion for mplayer (Debian: #531337) + * Fix regression on man(1) completion: also complete on local .3pm files + (Debian: #531343) + * Split mutt completion to contrib/mutt + * Split iconv completion to contrib/iconv + * Split dict completion to contrib/dict + * Split {update,invoke}-rc.d completions to contrib/sysv-rc + * Don't install _subversion anymore, upstream completion is better than + ours. Added to EXTRA_DIST in Makefile.am + * Split autorpm completion to contrib/autorpm + * Split jar completion to contrib/jar + * Split chkconfig completion to contrib/chkconfig + * Split chsh completion to contrib/chsh + * Split apt_build completion to contrib/apt-build + * Split aptitude-related completions to contrib/aptitude + * Split apt-cache and apt-get completions to contrib/apt + * Split rpm-related completions to contrib/rpm + * Split cvs-related completions to contrib/cvs + * Split man completion to contrib/man + * Split bash builtins completions to contrib/bash-builtins + * Split dpkg-related completions to contrib/dpkg (and re-enable usage + of grep-status if available) + * Split gcc completion to contrib/gcc + * Split dselect completion to contrib/dselect + * Split cardctl completion to contrib/cardctl + * Split pineaddr completion to contrib/pine + * Added avahi-discovered hosts to _known_hosts_real() (Debian: #518561) + * Added m4v completion to mplayer (Debian: #504213) + * Improve qemu completion (Debian: #534901) + * Added sshfs completion (shares the same as scp) (Debian: #545978) + * Fixed obvious brokenness (typos) in contrib/mdadm + * Clean [1.2.3.4]:port format in known_hosts, thanks to + Xuefer (Gentoo: #284563) + * Added --no-generate to "apt-cache pkgnames" calls, make it faster + on certain configurations (Debian: #547550) + * Split okular from evince filename extension completion, needed to add + okular-specific completions: xps, epub, odt, fb, mobi, g3 and chm. + Also, okular can read any of its formats also in .gz/.bz2 compressed + format, so change the regular expression to match this. + * Remove --with-suggests and --without-suggests from aptitude completion + * Patches from PLD Linux (thanks to Elan Ruusamäe): + - avoid sed pipe as ps itself can omit the headers + - improve service(8) completion, also look for "msg_usage" + + [ Ville Skyttä ] + * Split yum completion to contrib/_yum (no longer installed by default, the + intent is to move it to yum upstream soon). + * Split yum-arch completion into contrib/yum-arch, load completion only if + yum-arch is installed. + * Update list of yum commands and options. + * Add yum repolist, --enable/disablerepo, --disableexcludes, -d, -e, --color, + and --enable/disableplugin completions. + * Add chkconfig --override and resetpriorities completions. + * Split mplayer and friends completions to contrib/mplayer. + * Parse top level mplayer and friends option completions from -list-options. + * Fix dir-only completion for make to include only dirs, not files. + * Remove unused variable RELEASE. + * Improve aspell dictionary completion: don't hardcode data-dir, get + canonical dicts from "aspell dicts". + * Always use /etc/shells for chsh -s completion, don't complete on comment + lines in it. + * Fix rpm --whatrequires/--whatprovides completions with spaces and other + unusual characters, add filename based --whatrequires completions. + * Add modplugplay filename completion. + * Add more mod-like audio file extensions for xine-based players and timidity. + * Complete on plain alternatives like update-alternatives. + * Rename installed_alternatives() to _installed_alternatives(). + * Add /etc/pki/tls/openssl.cnf to list of default openssl config files, + search for default ones only if -config is not given. + * Use POSIX compliant arguments to tail in mkisofs completion. + * Protect various completions from unusual user input by not embedding the + input in external command arguments. + * Add _split_longopt() helper for improved handling of long options that + take arguments in both "--foo bar" and "--foo=bar" formats. + * Use _split_longopt to improve and clean up aspell, bluez-utils, chgrp, + chown, chkconfig, cpio, dpkg, heimdal, iptables, mailman, make, mc, + mii-diag, mii-tool, mkinitrd, pkg-config, postgresql, quota, reportbug, + samba, smartctl, yum, and generic long option completion (Alioth: #311398). + * Add chown --from and --reference value completions. + * Add chgrp --reference value completion. + * Do not assume all --foo= options take filenames in generic long option + completion, assume only that --*file*= does, and that --*dir*= takes dirs. + * Add make --old/new-file, --assume-old/new, --what-if value completions. + * Add smartctl -n/--nocheck completion, add more other value completions. + * Fix leaking $prev from cpio, dsniff, freeciv, gkrellm, mkinitrd, service, + and tcpdump completions. + * Split ant completion to contrib/ant, improve the built in one. + * Improve postfix completion. + * Improve samba completion. + * Split lilo completion to contrib/lilo. + * Split reportbug and querybts completions to contrib/reportbug. + * Remove debug output noise from quotaon completion. + * Split Linux wireless tools completion to contrib/wireless-tools. + * Add mock completion. + * Split FreeBSD kld(un)load completion to contrib/kldload. + * Split FreeBSD pkg_* completion to contrib/pkg_install. + * Split FreeBSD portupgrade and friends completion to contrib/portupgrade. + * Split Slackware pkgtools completion to contrib/pkgtools. + * Improve rpm group completion (displayed completions are still wrong). + * Change many completions to load in memory only if the completed commands + are available. + * Invoke the actual mplayer/mencoder command being completed (with full path) + to get various completions instead of simply "mplayer" or "mencoder". + * Associate OOXML/MS Office 2007 extensions with OpenOffice applications. + * Associate .tsv with oocalc. + * Add xmlwf completion. + * Associate *.po with poedit, gtranslator, kbabel, and lokalize. + * Add xz, xzcat, xzdec, and unxz completion. + * Add lzcat, lz*grep, lzless, lzmore, and unlzma completion. + * Load "modules" completion if /etc/profile.d/modules.sh exists even if + the "module" alias has not been defined (yet). + * Add *.ogv to xine-based players (Debian: #540033). + * Add $compopt (":" i.e. no-op with bash < 4, "compopt" with >= 4). + * Complete bzcat and zcat only on compressed files. + * Do not require a dot in bzcmp, bzdiff, bz*grep, zcmp, zdiff, z*grep, zless, + and zmore filename completions. + * Add xz and compress support and more tarball filename extensions to + rpmbuild -t*/--tarbuild completion. + * Don't hardcode path to lsmod. + * Fix sbcl file/dirname completion (Debian: #545743). + * Add /sbin to $PATH when invoking lspci and lsusb. + * Support .xz suffix in info page completions. + * Prevent rpm --define/-D completions from falling through. + * Add more common options to rpm option completions. + + [ Todd Zullinger ] + * Make yum complete on filenames after install, deplist, update and upgrade + when the following argument contains a slash. + + [ Mike Kelly ] + * Fix _filedir on bash 4. + * Add support for xz to tar completion. + * Fix _quote_readline on bash 4 (Debian: #544024). + + [ Guillaume Rousse ] + * Split mkinitrd completion to contrib/mkinitrd, improve it. + * Split smartctl completion to contrib/smartctl. + * Better ssh and sftp completion + * Better xhost completion + * Split _known_hosts completion in two parts, to avoid parsing command line + twice + * Added strace completion + * Added xm completion + * Added rpcdebug completion + * Added msynctool completion + * Added openldap completion + * Added ldapvi completion + * Added heimdal completion + * Added vpnc completion + * Added rpmcheck completion + * Added munin-node completion + * Added bluez-utils completion + * Added samba completion + * Added cfengine completion + * Added xmllint completion, contributed by Ville + * Added shadow completion, contributed by Ville + * Added repomanage completion, contributed by Ville + * Splitted and enhanced openssl completion + * Added rfkill, mdadm and resolvconf completions + + [ Raphaël Droz ] + * Add mount -L and -U completion. + + [ Philipp Weis ] + * Add .dvi.{gz,bz2} completion for evince/okular (Debian: #522656) + + [ Freddy Vulto ] + * Patched _known_hosts() to support multiple {Global,User}KnownHosts in SSH + config files, thanks to Thomas Nilsson (Alioth: #311595) (Debian: #524190) + * Fix leaking $i from info, man and python completions. + * Added setting COMP_KNOWN_HOSTS_WITH_HOSTFILE. _known_hosts_real() will add + hosts from HOSTFILE, unless COMP_KNOWN_HOSTS_WITH_HOSTFILE is set to an + empty value (Alioth: #311821) + * Quoted $cur to prevent globbing - thanks to Eric Blake (Alioth #311614) + * Fix leaking $muttcmd from mutt completion + * Fix completing multiple hosts (Debian: #535585) + + [ Michele Ballabio ] + + * Add more extensions to pkgtools completion. + + -- David Paleino <d.paleino@gmail.com> Sat, 03 Oct 2009 15:41:49 +0200 + +bash-completion (1.0) + + [ Guillaume Rousse ] + * Make bibtex complete on .aux files + * Add .xvid and .XVID to player completion + * Added cowsay/cowthink completion + * Added brctl completion + * Added cpan2dist completion + * Added qemu completion + * Added net-tools (mii-tool and mii-diag) completions + * Added minicom completion + * Added quota-tools completion + * Added rdesktop completion + * Added tightvncviewer completion + * Cleanup screen completion, and make it completes on options + + [ David Paleino ] + * Added .kar to Timidity completion. + * Fix killall completion, remove trailing ":" on certain process + names + * Fix man -l completing filenames (Debian: #497074) + * (Partly) fixed java classes completion (Debian: #496828). Look for + FIXME in source. + * Dump to /dev/null error message from look(1) with no arguments + (Debian: #495142) + * Set ssh as default for rsync (was rsh) (Debian: #492328) + * Added .oga, .ogv, .ogx to mplayer completion (Debian: #496162) + * Added .epub to unzip|zipinfo completion (Debian: #492476) + * Added ssh-copy-id completion (Debian: #491856) + * Moved ssh completion to separate file (Debian: #360628) + * Bogus completion when mounting subdirs fixed (Debian: #322238) + * Fix `apt-cache showsrc` completing only on source package names + (Debian: #361535) + * Fixed bugs with gdb completion: + - when an empty directory is in $PATH (thanks to Morita Sho) + (Debian: #497597) + - when a non-existing directory is in $PATH (Debian: #499780) + * Fix missing completion for "-n" and "-e" (we were using echo, now + using printf) (thanks to Morita Sho) (Debian: #498105) + * Fixed gpg completion: + - --@(export|@(?(l|nr|nrl)sign|edit)-key)) (Debian: #500316) + - -@(r|-recipient)) + * Fixed .cb[rz] completion for evince (Debian: #502885) + * Added gksudo, gksu, kdesudo completion + * Added apache2ctl completion + * Added gpg2 completion (Debian: #489927) + * Fixed mplayer -skin completion (Debian: #501473) + * Fixed errors with POSIX enabled (Debian: #502804) + * Fixed dpkg-source wrong exit() with return() (Debian: #) + * Added --schedule-only to aptitude's completion (Debian: #502664) + * Added build-dep to aptitude's completion (Debian: #495883) + * Added support for `-F configfile' to _known_hosts(), ssh, scp and + sftp, thanks to Freddy Vulto (Debian: #504141) + * Fixed sed quoting bug in _known_hosts(), thanks to Freddy Vulto + (Debian: #504650) + * Allow `Host(Name)' in ssh config file to be indented + * Allow `Host(Name)' in ssh config file to have trailing comment. + * Allow for comments in known_hosts files (Debian: #511789) + * Fixed perl -I/-x completion, thanks to Freddy Vulto + (Debian: #504547) + * README updated: explain how to use bash-completion correctly. + (Debian: #506560) + * TODO updated: the Alioth team is now upstream. + * Added qdbus completion, thanks to Terence Simpson (Ubuntu: #257903) + * Added monodevelop and mdtool completions. + * Split subversion-related completions to contrib/_subversion + (prefixed with _ to avoid file conflicts with upstream's one) + * Fixed completion of environment variables, thanks to Morita Sho + (Debian: #272660) + * Fix dpkg completion bug: it listed only non-Essential packages + (Debian: #511790) + * Fixed _dpkg_source completion (Debian: #503317) + * Added _parse_help() to try to parse options listed in $command + --help + * Fixed gzip completion to use _parse_help(), since the available + options vary with distributions + * Added to_review/ directory, where completions needing a review would + go. After it gets accepted, the completion would go into contrib/. + * Remove unused UNAME local variable in _info() (Debian: #501843) + * AUTHORS added + * Make _alias() use _get_cword + * Added .zip to jar completions (Debian: #521041) + * Merge from Gentoo: + - fix 'find' completion so that it properly completes on -?(i)whilename. + Patch by Ciaran McCreesh. + - use make -qp to parse the Makefile for us, so we get proper completion + on things like pattern rules. Patch by Mike Kelly <pioto@exherbo.org>. + - complete on gkrellm2 as well. Patch by Aaron Walker. + - fix CVS completion + * Merge from Ubuntu: + - consume error messages in configure completion (Ubuntu: #223882) + (Mika Fischer) + - quote $xspec in _filedir_xspec in case it is empty, which would + cause errors if there was no match under failglob. (Ubuntu: #194419) + (Mika Fischer) + * debian/links fixed (Debian: #494292) + * debian/control: + - fixed typo in the long description + - added Vcs-* fields + * debian/install: + - correctly install contrib/* under /etc/bash_completion.d/ + * debian/copyright updated + * extra/dh_bash-completion: + - updated to support a list of files in debian/<package>.bash-completion + (Debian: #512917) + + [ Ville Skyttä ] + * Added JPEG 2000 files to display completion, thanks to Bastien Nocera + (RedHat: #304771) + * Improved rpm macro completion. + * Added -E to rpm completion. + * Improved rpm backup file avoidance. + * Improved /var/log/rpmpkgs based rpm installed package completion. + * Improved performance of rpm -qa based rpm installed package completion. + * Improved features and performance of yum completion. + * Added support for p (POSIX) and x (x.org) man sections. + * Improved filename based man page completion. + * Added minimal sqlite3 completion. + * Improved getent completion (Ville Skyttä, Guillaume Rousse). + * (Re)fix gzip and bzip2 options completion. + * Improved svn filename completion (RedHat: #430059). + * Add lzma completion (Per Øyvind Karlsen, Ville Skyttä). + * Add .mp2 and .vdr to mplayer completion (RedHat: #444467). + * Add .mkv, .mp2 and .vdr to *xine completion (RedHat: #444467). + * Added lzop completion. + * Fix scp metacharacter escaping. + * Remove duplicate cpio completion, thanks to Freddy Vulto (Debian: #512823) + * Fix awk error in "modprobe -r /" completion (Debian: #512556). + * Expand ~foo to dir name more eagerly to avoid quoting issues. + * Fix -sourcepath handling in javadoc packages completion. + * Extract process name completion from _killall to _pnames, make it work + for others than Linux and FreeBSD. + * Fix process name completion with relative paths (RedHat: #484578). + * Use improved process name completion in pgrep in addition to killall. + * Enable pgrep and pkill completion if the commands are available, not just + on Linux and FreeBSD. + * Drop hg completion, an improved version is shipped with Mercurial + (contrib/bash_completion in the tarball). + * Make okular complete on same files as evince, thanks to Mary Ellen Foster + (RedHat: #486998). + * Apply ps2pdf completion to ps2pdf{12,13,14,wr} too. + * Simplify bash_completion.sh, return earlier in non-applicable environments. + * Remove obsolete --buildarch and --buildos rpm(build) completions. + * Add rpmbuild --target completion. + * Use "-profile help" to get mplayer and friends -profile completions. + * Fix local array initialization under bash 3.0, prevents "()" occurring in + file and dir name completions. + + [ Freddy Vulto ] + * Restored `_display()' completion for `display' by removing + completion-by-extension for `display' (Alioth#311429) + * Removed duplicate completion option `-borderwidth' for `display' + * Prevent completion dir from being sourced twice if + BASH_COMPLETION_DIR and BASH_COMPLETION_COMPAT_DIR are equal (Alioth#311433) + * Make `_mii-tool()' and `_mii-diag()' POSIX-compliant + * Fix _isql completion waiting for grep input if $ODBCINI not set; handle + whitespace in $ODBCINI. + * Split vncviewer completion in _tightvncviewer() and _xvnc4viewer() + Added _realcommand() global function. + + [ Jakob Unterwurzacher ] + * ps2pdf can run on .pdf files as well. (Debian: #516614, Ubuntu: #316943) + + [ Santiago M. Mola ] + * Add .ape to mplayer supported extensions (Alioth#311510). + + -- David Paleino <d.paleino@gmail.com> Wed, 25 Mar 2009 23:18:24 +0100 + +bash-completion (20080705) unstable; urgency=low + + [ David Paleino ] + * Added more completions to imagemagick (thanks to Nelson A. de + Oliveira) (Debian: #487786) + * Added xrandr completion (thanks to Anton Khirnov) (Debian: #487825) + * Improving _gdb completion: + - $filenames to $default (Debian: #463969) + - also show directory names (i.e. compgen -d) in COMPREPLY. + - added . to $PATH, to allow debugging "local" executables. + - do not complete Bash's builtins (thanks to Morita Sho) + + [ Luk Claes ] + * Remove use of ucf for /etc/bash-completion (Debian: #488171). + + -- Luk Claes <luk@debian.org> Sat, 05 Jul 2008 16:14:15 +0200 + +bash-completion (20080617.5) unstable; urgency=medium + + * Revert way of setting environment variables (Debian: #487774). + * Add equals sign to _get_cword for mutt_aliases (Debian: #482635). + * Enhance mlayer completion (Debian: #487826, #487838). + + -- Luk Claes <luk@debian.org> Tue, 24 Jun 2008 19:50:57 +0200 + +bash-completion (20080617.4) experimental; urgency=low + + [ David Paleino ] + * Merged Ubuntu changes: + - added quote(), quote_readline(), dequote() helper functions. + - added _remove_word() + - fixed _get_cword() + - refactored _filedir using quote_readline() + - refactored _filedir_xspec using quote_readline() + - fixed COMPREPLY's in _iwconfig + - fixed _cvs() + - _known_hosts(): use files from UserKnownHostsFile options in + addition to standard ones. + - fixed _command() to correctly prune the command line + - disabled completion of PostgreSQL users and databases (Ubuntu: #164772) + - fixed _java_packages() + - fixed _muttquery() + - added flv/FLV completion to mplayer + - added --installed to apt-cache + - only complete on filenames for aspell + - fixed code for exclusions compspecs + - added code to gracefully handle debug options (set +/-v) + + -- Luk Claes <luk@debian.org> Mon, 23 Jun 2008 19:25:25 +0200 + +bash-completion (20080617.3) unstable; urgency=low + + [ David Paleino ] + * Fixed IFS for filedir_xspec - Thanks to Stefan Lippers-Hollmann + (Debian: #487571) + + [ Luk Claes ] + * Install dh-bash-completion to ease installation of completions. + + -- Luk Claes <luk@debian.org> Mon, 23 Jun 2008 07:24:21 +0200 + +bash-completion (20080617.2) unstable; urgency=low + + [ David Paleino ] + * New upstream release + - provide a manpage for extra/dh_bash-completion + - fix semi-serious problem with _filedir() (Debian: #487449) + * debian/rules: + - added rule to generate dh_bash-completion's manpage + * debian/install, debian/dirs: + - installing dh_bash-completion into /usr/bin + * debian/control: + - new package dh-bash-completion + + [ Luk Claes ] + * Comment new package to make sure current fix gets in the archive first. + * Add compression completion for vi(m). + + -- Luk Claes <luk@debian.org> Sun, 22 Jun 2008 19:47:23 +0200 + +bash-completion (20080617.1) unstable; urgency=medium + + [ David Paleino ] + * Urgency set to medium because the package is currently unusable. + * New upstream sub-release + - fixed some typos here and there which prevented bash completions + at all (Debian: #487441). + - really closing Debian bug #455510. + + -- Luk Claes <luk@debian.org> Sun, 22 Jun 2008 00:22:53 +0200 + +bash-completion (20080617) unstable; urgency=low + + [ David Paleino ] + * New upstream release + - add more completions to aptitude (Debian: #432289) + - fixed UTF-8 problem with _get_cword(), thanks to + Andrei Paskevich (Debian: #472132) + - fixed autoremove completion, thanks to Flavio Visentin + (Debian: #474974) + - cmf and CMF added to playmidi completion (Debian: #365658) + - added rrdtool completion, thanks to Justin Pryzby (Debian: #428641) + - added OpenDocument completion for unzip/zipinfo (.od{f,g,p,s,t}) + (Debian: #472940) + - fixed escaping problems with job control (i.e. disown, jobs, bg, + fg): the argument is now surrounded by "" (Debian: #347316) + - make mkdir complete also on filenames (Debian: #376433) + - {bz,z}{cat,cmp,diff,egrep,fgrep,grep,less,more} now should complete + on all filenames, not just compressed archives (just commented out) + (Debian: #455510) + - fixes Perl completion (Debian: #470742) + - fixes get_cword -> _get_cword typo (Debian: #478596) + - fixes _get_cword() function to properly handle filenames with + whitespaces (Debian: #394636, #468254, #474094) + - added .pdf.bz2 completion to evince (Debian: #424736) + - added .svg completion to display (Debian: #441017) + - added .m2ts completion to mplayer (Debian: #480879) + - added extra/dh_bash-completion to ease future rewrite of bc. + * debian/copyright - now in a fancier machine-parsable format. + * debian/control: + - added myself to Uploaders + - debhelper Build-Depends updated to >= 6. + * debian/watch: + - improved current watch line regex + - added (commented out) probable future watch line + * debian/compat bumped to 6 + * debian/dirs, debian/install and debian/links added + * debian/rules: + - refactored to make use of debian/{dirs,install,links} + + [ Steve Kemp ] + * Applied patch to fix completion of umount command. + (Debian: #470539) + * Fixed the completion of Perl manpages. + (Debian: #404976) + * Added 'aif' to the filenames offed for completion for mplayer. + (Debian: #474517) + * Allow tsocks completion. + (Debian: #409423) + * Update mutt completion to handle local usernames. + (Debian: #416655) + * Update apt-get completion to include the flag "--no-install-recommends" + (Debian: #475242) + + -- Luk Claes <luk@debian.org> Sat, 21 Jun 2008 21:59:43 +0200 + +bash-completion (20060301-4) unstable; urgency=low + + * Add some fixes from Ubuntu: + * Fix completion of filenames with spaces (Debian: #468254). + * Fix parsing of SSH config files (Debian: #435117). + * Change priority to standard (Debian: #471666). + * Add some more completions for xine (Debian: #452083, #471249). + * Fix completion of gzip (Debian: #351913). + * Also use $HOSTFILE in hostname completion (Debian: #400380). + + -- Luk Claes <luk@debian.org> Sat, 22 Mar 2008 23:10:30 +0000 + +bash-completion (20060301-3) unstable; urgency=low + + * Fix kpdf completion (Debian: #468163, #413374). + * Fix completion of - or -- with _command (Debian: #415276). + * Add sux to the complete -u list (Debian: #466089). + * Add dvipdfm to the list of dvi programs (Debian: #396644). + * Add --purge-unused option completion for aptitude (Debian: #438471). + * Add divx extension completion for mplayer (Debian: #444294). + * Add pdf.gz completion for evince (Debian: #456887). + * Add --remove-all completion for update-alternatives (Debian: #269173). + + -- Luk Claes <luk@debian.org> Wed, 05 Mar 2008 22:57:27 +0100 + +bash-completion (20060301-2) unstable; urgency=low + + * Take over the package. + + -- Luk Claes <luk@debian.org> Wed, 27 Feb 2008 19:22:03 +0100 + +bash-completion (20060301-1) unstable; urgency=low + + * Upload to unstable. + + -- Matthias Klose <doko@debian.org> Sat, 09 Feb 2008 23:18:20 +0100 + +bash-completion (20060301-0ubuntu2) hardy; urgency=low + + * Replace bash (<< 3.1dfsg-9), handle upgrade in preinst. + * Exclude hashed hostnames from ssh host completion results. Debian: #428085. + * Fix: ifup/down don't really complete. Debian: #463756. + * Allow perl completion to complete filenames, complete -I and -x arguments. + Debian: #443394. + * Add find -wholename completion. Debian: #431220. + * Handle whitespaces in $HOME for _known_hosts() completion. Debian: #414821. + * dpkg -L: complete for removed-but-not-purged packages. Debian: #372156. + * Complete for apt-get autoremove. Debian: #433542, #443816, #445332. + * Update completion for mplayer (mka/flac). Debian: #340452. + * Add ping6/fping6 completion. Debian: #413170. + * Handle whitespace in paths for mount/umount completion. Debian: #367957. + * apt-get: Support --auto-remove. Ubuntu: #60666. + + -- Matthias Klose <doko@ubuntu.com> Sat, 09 Feb 2008 23:11:32 +0100 + +bash-completion (20060301-0ubuntu1) hardy; urgency=low + + * Initial release, split out from the bash package. + The software currently is unsupported upstream. + * Don't try to set a readonly variable. Ubuntu: #149527. + * Support purge in apt-get auto completion (Mathias Gug). Ubuntu: #151677. + * evince: Autocomplete on cbr/cbz/djvu files. Ubuntu: #156200, #175220. + Debian: #400678. + * kdvi: complete .*\.dvi\.(gz|bz2). Ubuntu: #128234. + * kpdf: Complete postscript files. Ubuntu: #162319. + * Make completion working in the middle of a word (Adam Simpkins). + Ubuntu: #139666. + + -- Matthias Klose <doko@ubuntu.com> Fri, 08 Feb 2008 16:46:34 +0100 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..9c8292c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,191 @@ +# Contributing to bash-completion + +Contributions to the bash completion project are more than +welcome. Fixes, clean-ups and improvements of existing code are much +appreciated, as are completion functions for new commands. + +However, before submitting a completion to us, first consider submitting it to +the project that ships the commands your completion is for. Having the +completion shipped along with the command opens up some liberties we don't have +if the completion is included with bash-completion. For example, we generally +do not want to hardcode lists of available command options and their +completions, because they quite probably vary between versions of the completed +command, and therefore resort to scraping --help output and the like. While we +do fairly well there, depending on the command, this can be fragile or +expensive, or just not possible. If the completion is shipped alongside the +command, they can be kept in sync and use more hardcoding etc. They are also +more likely to be maintained and/or watched by people intimately familiar with +the completed commands. See instructions in README.md how to install completion +files from other projects so they are automatically enabled and dynamically +loaded by bash-completion. + +On the other hand, we do have a pretty nice test suite and a bunch of helper +functions that you may find useful. And a whole slew of completions in one +package. Our functions can be used from "external" completions as well, just +make sure you test for their existence and/or fail gracefully if you intend +your completion to be usable without having bash-completion installed. + +It's nowhere near clear cut always what is the best place for the completion, +upstream project or us. Even if it would seem to be upstream, not all upstreams +are interested in shipping completions, or their install systems might not +easily support installing completion files properly. But give it some thought, +and ask if unsure. + +If you wish to contribute code to us, volunteering for long term maintainership +of your code within bash-completion is welcome. When exactly you will be asked +to do that depends on the case; don't be disappointed if it does or doesn't +happen instantly. + +Also, please bare the following coding guidelines in mind: + +- Do not use Perl, Ruby, Python etc. to do text processing unless the + command for which you are writing the completion code implies the + presence of one of those languages. + + For example, if you were writing completion code for perldoc(1), the + use of Perl to achieve your goal would be acceptable. irb(1) + completion would similarly make the use of Ruby acceptable. + + Even so, please consider alternatives to these large and slow to + start interpreters. Use lightweight programs such as grep(1), awk(1) + and sed(1). + +- Use the full power of bash >= 4.2. We no longer support earlier bash + versions, so you may as well use all the features of that version of + bash to optimise your code. However, be careful when using features + added since bash 4.2, since not everyone will be able to use them. + + For example, extended globs often enable you to avoid the use of + external programs, which are expensive to fork and execute, so do + make full use of those: + + `?(pattern-list)` - match zero or one occurrences of patterns + `*(pattern-list)` - match zero or more occurrences of patterns + `+(pattern-list)` - match one or more occurrences of patterns + `@(pattern-list)` - match exactly one of the given patterns + `!(pattern-list)` - match anything except one of the given patterns + +- Following on from the last point, be sparing with the use of + external processes whenever you can. Completion functions need to be + fast, so sacrificing some code legibility for speed is acceptable. + + For example, judicious use of sed(1) can save you from having to + call grep(1) and pipe the output to cut(1), which saves a fork(2) + and exec(3). + + Sometimes you don't even need sed(1) or other external programs at + all, though. Use of constructs such as `${parameter#word}`, + `${parameter%word}` and `${parameter/pattern/string}` can provide + you a lot of power without having to leave the shell. + + For example, if `$foo` contains the path to an executable, + `${foo##*/}` will give you the basename of the program, without + having to call basename(1). Similarly, `${foo%/*}` will give you the + dirname, without having to call dirname(1). + + As another example, + + ```shell + bar=$(echo $foo | command sed -e 's/bar/baz/g') + ``` + + can be replaced by: + + ```shell + bar=${foo//bar/baz} + ``` + + These forms of parameter substitutions can also be used on arrays, + which makes them very powerful (if a little slow). + +- We want our completions to work in `posix` and `nounset` modes. + + Unfortunately due to a bash < 5.1 bug, toggling POSIX mode interferes + with keybindings and should not be done. This rules out use of + process substitution which causes syntax errors in POSIX mode. + + Instead of toggling `nounset` mode, make sure to test whether + variables are set (e.g. with `[[ -v varname ]]`) or use default + expansion (e.g. `${varname-}`). + +- Prefer `compgen -W '...' -- $cur` over embedding `$cur` in external + command arguments (often e.g. sed, grep etc) unless there's a good + reason to embed it. Embedding user input in command lines can result + in syntax errors and other undesired behavior, or messy quoting + requirements when the input contains unusual characters. Good + reasons for embedding include functionality (if the thing does not + sanely work otherwise) or performance (if it makes a big difference + in speed), but all embedding cases should be documented with + rationale in comments in the code. + +- When completing available options, offer only the most descriptive + ones as completion results if there are multiple options that do the + same thing. Usually this means that long options should be preferred + over the corresponding short ones. This way the user is more likely + to find what she's looking for and there's not too much noise to + choose from, and there are less situations where user choice would + be needed in the first place. Note that this concerns only display + of available completions; argument processing/completion for options + that take an argument should be made to work with all known variants + for the functionality at hand. For example if `-s`, `-S`, and + `--something` do the same thing and require an argument, offer only + `--something` as a completion when completing option names starting + with a dash, but do implement required argument processing for all + `-s`, `-S`, and `--something`. Note that GNU versions of various + standard commands tend to have long options while other userland + implementations of the same commands may not have them, and it would + be good to have the completions work for as many userlands as + possible so things aren't always that simple. + +- Do not write to the file-system under any circumstances. This can + create race conditions, is inefficient, violates the principle of + least surprise and lacks robustness. + +- Use printf(1) instead of echo(1) for portability reasons, and be + sure to invoke commands that are often found aliased (such as `ls` + or `grep` etc) using the `command` (or `builtin`) command as + appropriate. + +- Make small, incremental commits that do one thing. Don't cram + unrelated changes into a single commit. + +- If your code was written for a particular platform, try to make it + portable to other platforms, so that everyone may enjoy it. If your + code works only with the version of a binary on a particular + platform, ensure that it will not be loaded on other platforms that + have a command with the same name. + + In particular, do not use GNU extensions to commands like sed and + awk if you can write your code another way. If you really, REALLY must + use them, do so if there's no other sane way to do what you're doing. + The "Shell and Utilities" volume of the POSIX specification is a good + starting reference for portable use of various utilities, see + <https://pubs.opengroup.org/onlinepubs/9699919799/>. + +- Use an editor that supports EditorConfig, see <https://editorconfig.org/>, + and format source code according to our settings. + +- Read the existing source code for examples of how to solve + particular problems. Read the bash man page for details of all the + programming tools available to you within the shell. + +- Please test your code thoroughly before sending it to us. We don't + have access to all the commands for which we are sent completion + functions, so we are unable to test them all personally. If your + code is accepted into the distribution, a lot of people will try it + out, so try to do a thorough job of eradicating all the bugs before + you send it to us. If at all practical, **add test cases** to our + test suite (in the test/ dir) that verify that the code does what it + is intended to do, fixes issues it intends to fix, etc. + +- In addition to running the test suite, there are a few scripts in the test/ + dir that catch some common issues, see and use for example runLint. + +- File bugs, enhancement, and pull requests at GitHub, + <https://github.com/scop/bash-completion>. + Sending them to the developers might work too, but is really strongly + discouraged as bits are more likely to fall through the cracks that + way compared to the tracker. Just use GitHub. If that's not an + option for some reason and you want to use email to send patches, + send them as attachments formatted by `git format-patch` or directly + with `git send-email`. @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..26f3c7c --- /dev/null +++ b/Makefile.am @@ -0,0 +1,41 @@ +SUBDIRS = completions doc helpers test + +pkgdata_DATA = bash_completion + +# Empty, but here just to get the compat dir created with install +compatdir = $(sysconfdir)/bash_completion.d +compat_DATA = + +profiledir = $(sysconfdir)/profile.d +profile_DATA = bash_completion.sh + +pkgconfigdir = $(datadir)/pkgconfig +pkgconfig_DATA = bash-completion.pc + +cmakeconfigdir = $(datadir)/cmake/$(PACKAGE)/ +cmakeconfig_DATA = bash-completion-config.cmake \ + bash-completion-config-version.cmake + +%: %.in Makefile + $(SED) \ + -e 's|@prefix[@]|$(prefix)|' \ + -e 's|@datadir[@]|$(datadir)|' \ + -e 's|@sysconfdir[@]|$(sysconfdir)|' \ + -e 's|@PACKAGE[@]|$(PACKAGE)|' \ + -e 's|@VERSION[@]|$(VERSION)|' \ + <$(srcdir)/$@.in >$@ + +CLEANFILES = bash_completion.sh bash-completion.pc \ + bash-completion-config.cmake bash-completion-config-version.cmake + +EXTRA_DIST = CHANGES $(pkgdata_DATA) bash_completion.sh.in .dir-locals.el \ + .editorconfig README.md CONTRIBUTING.md pyproject.toml .perltidyrc \ + .shellcheckrc bash-completion.pc.in bash-completion-config.cmake.in \ + bash-completion-config-version.cmake.in setup-symlinks.sh + +install-data-hook: + tmpfile=`mktemp $${TMPDIR:-/tmp}/bash_completion.XXXXXX` && \ + $(SED) -e 's|-/etc/bash_completion\.d|-$(compatdir)|' \ + $(DESTDIR)$(datadir)/$(PACKAGE)/bash_completion >$$tmpfile && \ + cat $$tmpfile >$(DESTDIR)$(datadir)/$(PACKAGE)/bash_completion && \ + rm $$tmpfile diff --git a/README.md b/README.md new file mode 100644 index 0000000..11d2940 --- /dev/null +++ b/README.md @@ -0,0 +1,347 @@ +# bash-completion + +[![Build Status](https://travis-ci.org/scop/bash-completion.svg?branch=master)](https://travis-ci.org/scop/bash-completion) + +## Introduction + +bash-completion is a collection of command line command completions for the +[Bash shell](https://www.gnu.org/software/bash/), collection of helper +functions to assist in creating new completions, and set of facilities for +loading completions automatically on demand, as well as installing them. + +## Installation + +The easiest way to install this software is to use a package; refer to +[Repology](https://repology.org/project/bash-completion) for a comprehensive +list of operating system distributions, package names, and available versions. + +Depending on the package, you may still +need to source it from either `/etc/bashrc` or `~/.bashrc` (or any +other file sourcing those). You can do this by simply using: + +```shell +# Use bash-completion, if available +[[ $PS1 && -f /usr/share/bash-completion/bash_completion ]] && \ + . /usr/share/bash-completion/bash_completion +``` + +(if you happen to have *only* bash >= 4.2 installed, see further if not) + +If you don't have the package readily available for your distribution, or +you simply don't want to use one, you can install bash completion using the +standard commands for GNU autotools packages: + +```shell +autoreconf -i # if not installing from prepared release tarball +./configure +make # GNU make required +make check # optional, requires python3 with pytest >= 3.6, pexpect +make install # as root +``` + +These commands install the completions and helpers, as well as a +`profile.d` script that loads `bash_completion` where appropriate. + +If your system does not use the `profile.d` directory (usually below +`/etc`) mechanism—i.e. does not automatically source shell scripts in +it—you can source the `$sysconfdir/profile.d/bash_completion.sh` +script in `/etc/bashrc` or `~/.bashrc`. + +The `profile.d` script provides a configuration file hook that can be +used to prevent loading `bash_completion` on per user basis when it's +installed system wide. To do this: + +1. Turn off programmable completion with `shopt -u progcomp` in + `$XDG_CONFIG_HOME/bash_completion` (or `~/.config/bash_completion` + if `$XDG_CONFIG_HOME` is not set) +2. Turn it back on (for example in `~/.bashrc`) if you want to use + programmable completion for other purposes. + +### macOS (OS X) + +If you're using macOS (formerly OS X), `/etc/bashrc` is apparently not sourced at +all. In that case, you can put the `bash_completion` file in `/sw/etc` +and add the following code to `~/.bash_profile`: + +```shell +if [ -f /sw/etc/bash_completion ]; then + . /sw/etc/bash_completion +fi +``` + +## Troubleshooting + +If you find that a given function is producing errors or does not work +as it should under certain circumstances when you attempt completion, +try running `set -v` or `set -x` prior to attempting the completion +again. This will produce useful debugging output that will aid us in +fixing the problem if you are unable to do so yourself. Turn off the +trace output by running either `set +v` or `set +x`. + +To debug dynamic loading of a completion, tracing needs to be turned +on before the debugged completion is attempted the first time. The +easiest way to do this is to start a new shell session, and to turn +tracing on in it before doing anything else there. + +## Known problems + +1. There seems to be some issue with using the bash built-in `cd` within + Makefiles. When invoked as `/bin/sh` within `Makefile`s, bash seems + to have a problem changing directory via the `cd` command. A + work-around for this is to define `SHELL=/bin/bash` within your + `Makefile`. This is believed to be a bug in bash. + +2. Many of the completion functions assume GNU versions of the various + text utilities that they call (e.g. `grep`, `sed`, and `awk`). Your + mileage may vary. + +## FAQ + +**Q. The bash completion code inhibits some commands from completing on + files with extensions that are legitimate in my environment. Do I + have to disable completion for that command in order to complete on + the files that I need to?** + +A. No. Use `M-/` to (in the words of the bash man page) attempt file + name completion on the text to the left of the cursor. This will + circumvent any file type restrictions put in place by the bash + completion code. + +**Q. How can I override a completion shipped by bash-completion?** + +A. Install a local completion of your own appropriately for the desired + command, and it will take precedence over the one shipped by us. See the + next answer for details where to install it, if you are doing it on per + user basis. If you want to do it system wide, you can install eagerly + loaded files in `compatdir` (see a couple of questions further down for + more info) and install a completion for the commands to override our + completion for in them. + + If you want to use bash's default completion instead of one of ours, + something like this should work (where `$cmd` is the command to override + completion for): `complete -o default -o bashdefault $cmd` + +**Q. Where should I install my own local completions?** + +A. Put them in the `completions` subdir of `$BASH_COMPLETION_USER_DIR` + (defaults to `$XDG_DATA_HOME/bash-completion` or + `~/.local/share/bash-completion` + if `$XDG_DATA_HOME` is not set) to have them loaded automatically + on demand when the respective command is being completed. + See also the next question's answer for considerations for these + files' names, they apply here as well. Alternatively, you can write + them directly in `~/.bash_completion` which is loaded eagerly by + our main script. + +**Q. I author/maintain package X and would like to maintain my own + completion code for this package. Where should I put it to be sure + that interactive bash shells will find it and source it?** + +A. Install it in one of the directories pointed to by + bash-completion's `pkgconfig` file variables. There are two + alternatives: + + - The recommended directory is `completionsdir`, which you can get with + `pkg-config --variable=completionsdir bash-completion`. From this + directory, completions are automatically loaded on demand based on invoked + commands' names, so be sure to name your completion file accordingly, and + to include (for example) symbolic links in case the file provides + completions for more than one command. + - The other directory (which only present for backwards compatibility) + is `compatdir` (get it with + `pkg-config --variable=compatdir bash-completion`) from which files + are loaded when `bash_completion` is loaded. + + For packages using GNU autotools the installation can be handled + for example like this in `configure.ac`: + + ```m4 + PKG_CHECK_VAR(bashcompdir, [bash-completion], [completionsdir], , + bashcompdir="${sysconfdir}/bash_completion.d") + AC_SUBST(bashcompdir) + ``` + + ...accompanied by this in `Makefile.am`: + + ```makefile + bashcompdir = @bashcompdir@ + dist_bashcomp_DATA = # completion files go here + ``` + + For cmake we ship the `bash-completion-config.cmake` and + `bash-completion-config-version.cmake` files. Example usage: + + ```cmake + find_package(bash-completion) + if(BASH_COMPLETION_FOUND) + message(STATUS + "Using bash completion dir ${BASH_COMPLETION_COMPLETIONSDIR}") + else() + set (BASH_COMPLETION_COMPLETIONSDIR "/etc/bash_completion.d") + message (STATUS + "Using fallback bash completion dir ${BASH_COMPLETION_COMPLETIONSDIR}") + endif() + + install(FILES your-completion-file DESTINATION + ${BASH_COMPLETION_COMPLETIONSDIR}) + ``` + +**Q. I use CVS in combination with passwordless SSH access to my remote + repository. How can I have the `cvs` command complete on remotely + checked-out files where relevant?** + +A. Define `$COMP_CVS_REMOTE`. Setting this to anything will result in + the behaviour you would like. + +**Q. When I'm running a `./configure` script and completion returns a list + of long options to me, some of these take a parameter, + e.g. `--this-option=DESCRIPTION`.** + + **Running `./configure --help` lists these descriptions, but + everything after the `=` is stripped when returning completions, so + I don't know what kind of data is expected as a given option's + parameter.** + + **Is there a way of getting `./configure` completion to return the + entire option string, so that I can see what kind of data is + required and then simply delete the descriptive text and add my own + data?** + +A. Define `$COMP_CONFIGURE_HINTS`. Setting this to anything will + result in the behaviour you would like. + +**Q. When doing tar completion on a file within a tar file like this:** + + ```shell + tar tzvf foo.tar.gz <Tab> + ``` + + **the pathnames contained in the tar file are not displayed + correctly. The slashes are removed, and everything looks like it's + in a single directory. Why is this?** + +A. It's a choice we had to make. bash's programmable completion is + limited in how it handles the list of possible completions it + returns. + + Because the paths returned from within the tar file are likely not + existing paths on the file system, `-o dirnames` must be passed to + the `complete` built-in to make it treat them as such. However, + then bash will append a space when completing on directories during + pathname completion to the tar files themselves. + + It's more important to have proper completion of paths to tar files + than it is to have completion for their contents, so this sacrifice + was made and `-o filenames` is used with complete instead. + + If you would rather have correct path completion for tar file + contents, define `$COMP_TAR_INTERNAL_PATHS` *before* sourcing + `bash_completion`. + +**Q. When completing on a symlink to a directory, bash does not append + the trailing `/` and I have to hit <kbd><Tab></kbd> again. + I don't like this.** + +A. This has nothing to do with `bash_completion`. It's the default for + completing symlinks to directories since bash 2.05a, and was added + because sometimes you want to operate on the symlink itself, rather + than what it points to. + + You can get the pre-2.05a behaviour back by putting `set + mark-symlinked-directories on` in your `/etc/inputrc` or + `~/.inputrc` file. + +**Q. Completion goes awry when I try to complete on something that contains + a colon.** + +A. This is actually a 'feature' of bash. bash recognises a colon as + starting a new completion token, which is often what you want when + completing something like a `PATH` variable: + + ```shell + export PATH=/bin:/sbin:/usr<Tab> + ``` + + Without the special treatment of the colon, the above wouldn't work + without programmable completion, so it has long been a feature of + the shell. + + Unfortunately, you don't want the colon to be treated as a special + case when doing something like: + + ```shell + man File::B<Tab> + ``` + + Here, the colons make bash think that it's completing a new token + that begins with 'B'. + + Unfortunately, there's no way to turn this off. The only thing you + can do is escape the colons with a backslash. + +**Q. Why is `rpm` completion so slow with `-q`?** + +A. Probably because the database is being queried every time and this uses a + lot of memory. + + You can make this faster by pregenerating the list of installed + packages on the system. Make sure you have a readable file called + `/var/log/rpmpkgs`. It's generated by `/etc/cron.daily/rpm` on + some Red Hat and Mandrake and derivative Linux systems. + + If you don't have such a cron job, make one: + + ```shell + #!/bin/sh + + rpm -qa --qf '%{name}-%{version}-%{release}.%{arch}.rpm\n' 2>&1 \ + | sort >/var/log/rpmpkgs + ``` + + rpm completion will use this flat text file instead of the RPM database, + unless it detects that the database has changed since the file was created, + in which case it will still use the database to ensure accuracy. + +**Q. bash-completion interferes with my `command_not_found_handler` function!** + +A. If your `command_not_found_handler` function is not intended to + address (possibly missing) commands invoked during bash + programmable completion functions, you can account for this + by, for example, testing if the `$COMP_`\* variables are set and + taking appropriate bypass or other action. + +**Q. Can tab completion be made even easier?** + +A. The `readline(3)` library offers a few settings that can make tab + completion easier (or at least different) to use. + + For example, try putting the following in either `/etc/inputrc` or + `~/.inputrc`: + + ```inputrc + set show-all-if-ambiguous on + ``` + + This will allow single tab completion as opposed to requiring a + double tab. This makes things much more pleasant, in our opinion. + + ```inputrc + set visible-stats on + ``` + + This will suffix each returned file completion with a character + denoting its type, in a similar way to `ls(1)` with `-F` or `--classify`. + + ```inputrc + set page-completions off + ``` + + This turns off the use of the internal pager when returning long + completion lists. + +**Q. Is bash the be-all-and-end-all of completion as far as shells go?** + +A. Absolutely not. zsh has an extremely sophisticated completion system + that offers many features absent from the bash implementation. Its + users often cannot resist pointing this out. More information can + be found at <https://www.zsh.org/>. diff --git a/bash-completion-config-version.cmake.in b/bash-completion-config-version.cmake.in new file mode 100644 index 0000000..265e075 --- /dev/null +++ b/bash-completion-config-version.cmake.in @@ -0,0 +1,7 @@ +set (PACKAGE_VERSION "@VERSION@") +if (NOT ${PACKAGE_FIND_VERSION} VERSION_GREATER ${PACKAGE_VERSION}) + set (PACKAGE_VERSION_COMPATIBLE 1) + if (${PACKAGE_FIND_VERSION} VERSION_EQUAL ${PACKAGE_VERSION}) + set (PACKAGE_VERSION_EXACT 1) + endif () +endif () diff --git a/bash-completion-config.cmake.in b/bash-completion-config.cmake.in new file mode 100644 index 0000000..2b7de6c --- /dev/null +++ b/bash-completion-config.cmake.in @@ -0,0 +1,12 @@ +# config file for bash-completion +# https://github.com/scop/bash-completion + +set (BASH_COMPLETION_VERSION "@VERSION@") + +set (BASH_COMPLETION_PREFIX "@prefix@") + +set (BASH_COMPLETION_COMPATDIR "@sysconfdir@/bash_completion.d") +set (BASH_COMPLETION_COMPLETIONSDIR "@datadir@/@PACKAGE@/completions") +set (BASH_COMPLETION_HELPERSDIR "@datadir@/@PACKAGE@/helpers") + +set (BASH_COMPLETION_FOUND "TRUE") diff --git a/bash-completion.pc.in b/bash-completion.pc.in new file mode 100644 index 0000000..f0a3572 --- /dev/null +++ b/bash-completion.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +datadir=@datadir@ +sysconfdir=@sysconfdir@ + +compatdir=${sysconfdir}/bash_completion.d +completionsdir=${datadir}/@PACKAGE@/completions +helpersdir=${datadir}/@PACKAGE@/helpers + +Name: @PACKAGE@ +Description: programmable completion for the bash shell +URL: https://github.com/scop/bash-completion +Version: @VERSION@ diff --git a/bash_completion b/bash_completion new file mode 100644 index 0000000..1a7f563 --- /dev/null +++ b/bash_completion @@ -0,0 +1,2266 @@ +# -*- shell-script -*- +# +# bash_completion - programmable completion functions for bash 4.2+ +# +# Copyright © 2006-2008, Ian Macdonald <ian@caliban.org> +# © 2009-2020, Bash Completion Maintainers +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# The latest version of this software can be obtained here: +# +# https://github.com/scop/bash-completion + +BASH_COMPLETION_VERSINFO=(2 11) + +if [[ $- == *v* ]]; then + BASH_COMPLETION_ORIGINAL_V_VALUE="-v" +else + BASH_COMPLETION_ORIGINAL_V_VALUE="+v" +fi + +if [[ ${BASH_COMPLETION_DEBUG-} ]]; then + set -v +else + set +v +fi + +# Blacklisted completions, causing problems with our code. +# +_blacklist_glob='@(acroread.sh)' + +# Turn on extended globbing and programmable completion +shopt -s extglob progcomp + +# A lot of the following one-liners were taken directly from the +# completion examples provided with the bash 2.04 source distribution + +# start of section containing compspecs that can be handled within bash + +# user commands see only users +complete -u groups slay w sux + +# bg completes with stopped jobs +complete -A stopped -P '"%' -S '"' bg + +# other job commands +complete -j -P '"%' -S '"' fg jobs disown + +# readonly and unset complete with shell variables +complete -v readonly unset + +# set completes with set options +complete -A setopt set + +# shopt completes with shopt options +complete -A shopt shopt + +# helptopics +complete -A helptopic help + +# unalias completes with aliases +complete -a unalias + +# type and which complete on commands +complete -c command type which + +# builtin completes on builtins +complete -b builtin + +# start of section containing completion functions called by other functions + +# Check if we're running on the given userland +# @param $1 userland to check for +_userland() +{ + local userland=$(uname -s) + [[ $userland == @(Linux|GNU/*) ]] && userland=GNU + [[ $userland == "$1" ]] +} + +# This function sets correct SysV init directories +# +_sysvdirs() +{ + sysvdirs=() + [[ -d /etc/rc.d/init.d ]] && sysvdirs+=(/etc/rc.d/init.d) + [[ -d /etc/init.d ]] && sysvdirs+=(/etc/init.d) + # Slackware uses /etc/rc.d + [[ -f /etc/slackware-version ]] && sysvdirs=(/etc/rc.d) + return 0 +} + +# This function checks whether we have a given program on the system. +# +_have() +{ + # Completions for system administrator commands are installed as well in + # case completion is attempted via `sudo command ...'. + PATH=$PATH:/usr/sbin:/sbin:/usr/local/sbin type $1 &>/dev/null +} + +# Backwards compatibility for compat completions that use have(). +# @deprecated should no longer be used; generally not needed with dynamically +# loaded completions, and _have is suitable for runtime use. +have() +{ + unset -v have + _have $1 && have=yes +} + +# This function checks whether a given readline variable +# is `on'. +# +_rl_enabled() +{ + [[ "$(bind -v)" == *$1+([[:space:]])on* ]] +} + +# This function shell-quotes the argument +quote() +{ + local quoted=${1//\'/\'\\\'\'} + printf "'%s'" "$quoted" +} + +# @see _quote_readline_by_ref() +quote_readline() +{ + local ret + _quote_readline_by_ref "$1" ret + printf %s "$ret" +} # quote_readline() + +# This function shell-dequotes the argument +dequote() +{ + eval printf %s "$1" 2>/dev/null +} + +# Assign variable one scope above the caller +# Usage: local "$1" && _upvar $1 "value(s)" +# Param: $1 Variable name to assign value to +# Param: $* Value(s) to assign. If multiple values, an array is +# assigned, otherwise a single value is assigned. +# NOTE: For assigning multiple variables, use '_upvars'. Do NOT +# use multiple '_upvar' calls, since one '_upvar' call might +# reassign a variable to be used by another '_upvar' call. +# See: https://fvue.nl/wiki/Bash:_Passing_variables_by_reference +_upvar() +{ + echo "bash_completion: $FUNCNAME: deprecated function," \ + "use _upvars instead" >&2 + if unset -v "$1"; then # Unset & validate varname + if (($# == 2)); then + eval $1=\"\$2\" # Return single value + else + eval $1=\(\"\$"{@:2}"\"\) # Return array + fi + fi +} + +# Assign variables one scope above the caller +# Usage: local varname [varname ...] && +# _upvars [-v varname value] | [-aN varname [value ...]] ... +# Available OPTIONS: +# -aN Assign next N values to varname as array +# -v Assign single value to varname +# Return: 1 if error occurs +# See: https://fvue.nl/wiki/Bash:_Passing_variables_by_reference +_upvars() +{ + if ! (($#)); then + echo "bash_completion: $FUNCNAME: usage: $FUNCNAME" \ + "[-v varname value] | [-aN varname [value ...]] ..." >&2 + return 2 + fi + while (($#)); do + case $1 in + -a*) + # Error checking + [[ ${1#-a} ]] || { + echo "bash_completion: $FUNCNAME:" \ + "\`$1': missing number specifier" >&2 + return 1 + } + printf %d "${1#-a}" &>/dev/null || { + echo bash_completion: \ + "$FUNCNAME: \`$1': invalid number specifier" >&2 + return 1 + } + # Assign array of -aN elements + [[ "$2" ]] && unset -v "$2" && eval $2=\(\"\$"{@:3:${1#-a}}"\"\) && + shift $((${1#-a} + 2)) || { + echo bash_completion: \ + "$FUNCNAME: \`$1${2+ }$2': missing argument(s)" \ + >&2 + return 1 + } + ;; + -v) + # Assign single value + [[ "$2" ]] && unset -v "$2" && eval $2=\"\$3\" && + shift 3 || { + echo "bash_completion: $FUNCNAME: $1:" \ + "missing argument(s)" >&2 + return 1 + } + ;; + *) + echo "bash_completion: $FUNCNAME: $1: invalid option" >&2 + return 1 + ;; + esac + done +} + +# Reassemble command line words, excluding specified characters from the +# list of word completion separators (COMP_WORDBREAKS). +# @param $1 chars Characters out of $COMP_WORDBREAKS which should +# NOT be considered word breaks. This is useful for things like scp where +# we want to return host:path and not only path, so we would pass the +# colon (:) as $1 here. +# @param $2 words Name of variable to return words to +# @param $3 cword Name of variable to return cword to +# +__reassemble_comp_words_by_ref() +{ + local exclude i j line ref + # Exclude word separator characters? + if [[ $1 ]]; then + # Yes, exclude word separator characters; + # Exclude only those characters, which were really included + exclude="[${1//[^$COMP_WORDBREAKS]/}]" + fi + + # Default to cword unchanged + printf -v "$3" %s "$COMP_CWORD" + # Are characters excluded which were former included? + if [[ -v exclude ]]; then + # Yes, list of word completion separators has shrunk; + line=$COMP_LINE + # Re-assemble words to complete + for ((i = 0, j = 0; i < ${#COMP_WORDS[@]}; i++, j++)); do + # Is current word not word 0 (the command itself) and is word not + # empty and is word made up of just word separator characters to + # be excluded and is current word not preceded by whitespace in + # original line? + while [[ $i -gt 0 && ${COMP_WORDS[i]} == +($exclude) ]]; do + # Is word separator not preceded by whitespace in original line + # and are we not going to append to word 0 (the command + # itself), then append to current word. + [[ $line != [[:blank:]]* ]] && ((j >= 2)) && ((j--)) + # Append word separator to current or new word + ref="$2[$j]" + printf -v "$ref" %s "${!ref-}${COMP_WORDS[i]}" + # Indicate new cword + ((i == COMP_CWORD)) && printf -v "$3" %s "$j" + # Remove optional whitespace + word separator from line copy + line=${line#*"${COMP_WORDS[i]}"} + # Start new word if word separator in original line is + # followed by whitespace. + [[ $line == [[:blank:]]* ]] && ((j++)) + # Indicate next word if available, else end *both* while and + # for loop + ((i < ${#COMP_WORDS[@]} - 1)) && ((i++)) || break 2 + done + # Append word to current word + ref="$2[$j]" + printf -v "$ref" %s "${!ref-}${COMP_WORDS[i]}" + # Remove optional whitespace + word from line copy + line=${line#*"${COMP_WORDS[i]}"} + # Indicate new cword + ((i == COMP_CWORD)) && printf -v "$3" %s "$j" + done + ((i == COMP_CWORD)) && printf -v "$3" %s "$j" + else + # No, list of word completions separators hasn't changed; + for i in "${!COMP_WORDS[@]}"; do + printf -v "$2[i]" %s "${COMP_WORDS[i]}" + done + fi +} # __reassemble_comp_words_by_ref() + +# @param $1 exclude Characters out of $COMP_WORDBREAKS which should NOT be +# considered word breaks. This is useful for things like scp where +# we want to return host:path and not only path, so we would pass the +# colon (:) as $1 in this case. +# @param $2 words Name of variable to return words to +# @param $3 cword Name of variable to return cword to +# @param $4 cur Name of variable to return current word to complete to +# @see __reassemble_comp_words_by_ref() +__get_cword_at_cursor_by_ref() +{ + local cword words=() + __reassemble_comp_words_by_ref "$1" words cword + + local i cur="" index=$COMP_POINT lead=${COMP_LINE:0:COMP_POINT} + # Cursor not at position 0 and not leaded by just space(s)? + if [[ $index -gt 0 && ($lead && ${lead//[[:space:]]/}) ]]; then + cur=$COMP_LINE + for ((i = 0; i <= cword; ++i)); do + # Current word fits in $cur, and $cur doesn't match cword? + while [[ ${#cur} -ge ${#words[i]} && \ + ${cur:0:${#words[i]}} != "${words[i]-}" ]]; do + # Strip first character + cur="${cur:1}" + # Decrease cursor position, staying >= 0 + ((index > 0)) && ((index--)) + done + + # Does found word match cword? + if ((i < cword)); then + # No, cword lies further; + local old_size=${#cur} + cur="${cur#"${words[i]}"}" + local new_size=${#cur} + ((index -= old_size - new_size)) + fi + done + # Clear $cur if just space(s) + [[ $cur && ! ${cur//[[:space:]]/} ]] && cur= + # Zero $index if negative + ((index < 0)) && index=0 + fi + + local "$2" "$3" "$4" && _upvars -a${#words[@]} $2 ${words+"${words[@]}"} \ + -v $3 "$cword" -v $4 "${cur:0:index}" +} + +# Get the word to complete and optional previous words. +# This is nicer than ${COMP_WORDS[COMP_CWORD]}, since it handles cases +# where the user is completing in the middle of a word. +# (For example, if the line is "ls foobar", +# and the cursor is here --------> ^ +# Also one is able to cross over possible wordbreak characters. +# Usage: _get_comp_words_by_ref [OPTIONS] [VARNAMES] +# Available VARNAMES: +# cur Return cur via $cur +# prev Return prev via $prev +# words Return words via $words +# cword Return cword via $cword +# +# Available OPTIONS: +# -n EXCLUDE Characters out of $COMP_WORDBREAKS which should NOT be +# considered word breaks. This is useful for things like scp +# where we want to return host:path and not only path, so we +# would pass the colon (:) as -n option in this case. +# -c VARNAME Return cur via $VARNAME +# -p VARNAME Return prev via $VARNAME +# -w VARNAME Return words via $VARNAME +# -i VARNAME Return cword via $VARNAME +# +# Example usage: +# +# $ _get_comp_words_by_ref -n : cur prev +# +_get_comp_words_by_ref() +{ + local exclude flag i OPTIND=1 + local cur cword words=() + local upargs=() upvars=() vcur vcword vprev vwords + + while getopts "c:i:n:p:w:" flag "$@"; do + case $flag in + c) vcur=$OPTARG ;; + i) vcword=$OPTARG ;; + n) exclude=$OPTARG ;; + p) vprev=$OPTARG ;; + w) vwords=$OPTARG ;; + *) + echo "bash_completion: $FUNCNAME: usage error" >&2 + return 1 + ;; + esac + done + while [[ $# -ge $OPTIND ]]; do + case ${!OPTIND} in + cur) vcur=cur ;; + prev) vprev=prev ;; + cword) vcword=cword ;; + words) vwords=words ;; + *) + echo "bash_completion: $FUNCNAME: \`${!OPTIND}':" \ + "unknown argument" >&2 + return 1 + ;; + esac + ((OPTIND += 1)) + done + + __get_cword_at_cursor_by_ref "${exclude-}" words cword cur + + [[ -v vcur ]] && { + upvars+=("$vcur") + upargs+=(-v $vcur "$cur") + } + [[ -v vcword ]] && { + upvars+=("$vcword") + upargs+=(-v $vcword "$cword") + } + [[ -v vprev && $cword -ge 1 ]] && { + upvars+=("$vprev") + upargs+=(-v $vprev "${words[cword - 1]}") + } + [[ -v vwords ]] && { + upvars+=("$vwords") + upargs+=(-a${#words[@]} $vwords ${words+"${words[@]}"}) + } + + ((${#upvars[@]})) && local "${upvars[@]}" && _upvars "${upargs[@]}" +} + +# Get the word to complete. +# This is nicer than ${COMP_WORDS[COMP_CWORD]}, since it handles cases +# where the user is completing in the middle of a word. +# (For example, if the line is "ls foobar", +# and the cursor is here --------> ^ +# @param $1 string Characters out of $COMP_WORDBREAKS which should NOT be +# considered word breaks. This is useful for things like scp where +# we want to return host:path and not only path, so we would pass the +# colon (:) as $1 in this case. +# @param $2 integer Index number of word to return, negatively offset to the +# current word (default is 0, previous is 1), respecting the exclusions +# given at $1. For example, `_get_cword "=:" 1' returns the word left of +# the current word, respecting the exclusions "=:". +# @deprecated Use `_get_comp_words_by_ref cur' instead +# @see _get_comp_words_by_ref() +_get_cword() +{ + local LC_CTYPE=C + local cword words + __reassemble_comp_words_by_ref "${1-}" words cword + + # return previous word offset by $2 + if [[ ${2-} && ${2//[^0-9]/} ]]; then + printf "%s" "${words[cword - $2]}" + elif ((${#words[cword]} == 0 && COMP_POINT == ${#COMP_LINE})); then + : # nothing + else + local i + local cur="$COMP_LINE" + local index="$COMP_POINT" + for ((i = 0; i <= cword; ++i)); do + # Current word fits in $cur, and $cur doesn't match cword? + while [[ ${#cur} -ge ${#words[i]} && \ + ${cur:0:${#words[i]}} != "${words[i]}" ]]; do + # Strip first character + cur="${cur:1}" + # Decrease cursor position, staying >= 0 + ((index > 0)) && ((index--)) + done + + # Does found word match cword? + if ((i < cword)); then + # No, cword lies further; + local old_size="${#cur}" + cur="${cur#${words[i]}}" + local new_size="${#cur}" + ((index -= old_size - new_size)) + fi + done + + if [[ ${words[cword]:0:${#cur}} != "$cur" ]]; then + # We messed up! At least return the whole word so things + # keep working + printf "%s" "${words[cword]}" + else + printf "%s" "${cur:0:index}" + fi + fi +} # _get_cword() + +# Get word previous to the current word. +# This is a good alternative to `prev=${COMP_WORDS[COMP_CWORD-1]}' because bash4 +# will properly return the previous word with respect to any given exclusions to +# COMP_WORDBREAKS. +# @deprecated Use `_get_comp_words_by_ref cur prev' instead +# @see _get_comp_words_by_ref() +# +_get_pword() +{ + if ((COMP_CWORD >= 1)); then + _get_cword "${@:-}" 1 + fi +} + +# If the word-to-complete contains a colon (:), left-trim COMPREPLY items with +# word-to-complete. +# With a colon in COMP_WORDBREAKS, words containing +# colons are always completed as entire words if the word to complete contains +# a colon. This function fixes this, by removing the colon-containing-prefix +# from COMPREPLY items. +# The preferred solution is to remove the colon (:) from COMP_WORDBREAKS in +# your .bashrc: +# +# # Remove colon (:) from list of word completion separators +# COMP_WORDBREAKS=${COMP_WORDBREAKS//:} +# +# See also: Bash FAQ - E13) Why does filename completion misbehave if a colon +# appears in the filename? - https://tiswww.case.edu/php/chet/bash/FAQ +# @param $1 current word to complete (cur) +# @modifies global array $COMPREPLY +# +__ltrim_colon_completions() +{ + if [[ $1 == *:* && $COMP_WORDBREAKS == *:* ]]; then + # Remove colon-word prefix from COMPREPLY items + local colon_word=${1%"${1##*:}"} + local i=${#COMPREPLY[*]} + while ((i-- > 0)); do + COMPREPLY[i]=${COMPREPLY[i]#"$colon_word"} + done + fi +} # __ltrim_colon_completions() + +# This function quotes the argument in a way so that readline dequoting +# results in the original argument. This is necessary for at least +# `compgen' which requires its arguments quoted/escaped: +# +# $ ls "a'b/" +# c +# $ compgen -f "a'b/" # Wrong, doesn't return output +# $ compgen -f "a\'b/" # Good +# a\'b/c +# +# See also: +# - https://lists.gnu.org/archive/html/bug-bash/2009-03/msg00155.html +# - https://www.mail-archive.com/bash-completion-devel@lists.alioth.debian.org/msg01944.html +# @param $1 Argument to quote +# @param $2 Name of variable to return result to +_quote_readline_by_ref() +{ + if [[ $1 == \'* ]]; then + # Leave out first character + printf -v $2 %s "${1:1}" + else + printf -v $2 %q "$1" + fi + + # If result becomes quoted like this: $'string', re-evaluate in order to + # drop the additional quoting. See also: + # https://www.mail-archive.com/bash-completion-devel@lists.alioth.debian.org/msg01942.html + [[ ${!2} == \$* ]] && eval $2=${!2} +} # _quote_readline_by_ref() + +# This function performs file and directory completion. It's better than +# simply using 'compgen -f', because it honours spaces in filenames. +# @param $1 If `-d', complete only on directories. Otherwise filter/pick only +# completions with `.$1' and the uppercase version of it as file +# extension. +# +_filedir() +{ + local IFS=$'\n' + + _tilde "${cur-}" || return + + local -a toks + local reset arg=${1-} + + if [[ $arg == -d ]]; then + reset=$(shopt -po noglob) + set -o noglob + toks=($(compgen -d -- "${cur-}")) + IFS=' ' + $reset + IFS=$'\n' + else + local quoted + _quote_readline_by_ref "${cur-}" quoted + + # Munge xspec to contain uppercase version too + # https://lists.gnu.org/archive/html/bug-bash/2010-09/msg00036.html + # news://news.gmane.io/4C940E1C.1010304@case.edu + local xspec=${arg:+"!*.@($arg|${arg^^})"} plusdirs=() + + # Use plusdirs to get dir completions if we have a xspec; if we don't, + # there's no need, dirs come along with other completions. Don't use + # plusdirs quite yet if fallback is in use though, in order to not ruin + # the fallback condition with the "plus" dirs. + local opts=(-f -X "$xspec") + [[ $xspec ]] && plusdirs=(-o plusdirs) + [[ ${COMP_FILEDIR_FALLBACK-} || -z ${plusdirs-} ]] || + opts+=("${plusdirs[@]}") + + reset=$(shopt -po noglob) + set -o noglob + toks+=($(compgen "${opts[@]}" -- $quoted)) + IFS=' ' + $reset + IFS=$'\n' + + # Try without filter if it failed to produce anything and configured to + [[ -n ${COMP_FILEDIR_FALLBACK-} && -n $arg && ${#toks[@]} -lt 1 ]] && { + reset=$(shopt -po noglob) + set -o noglob + toks+=($(compgen -f ${plusdirs+"${plusdirs[@]}"} -- $quoted)) + IFS=' ' + $reset + IFS=$'\n' + } + fi + + if ((${#toks[@]} != 0)); then + # 2>/dev/null for direct invocation, e.g. in the _filedir unit test + compopt -o filenames 2>/dev/null + COMPREPLY+=("${toks[@]}") + fi +} # _filedir() + +# This function splits $cur=--foo=bar into $prev=--foo, $cur=bar, making it +# easier to support both "--foo bar" and "--foo=bar" style completions. +# `=' should have been removed from COMP_WORDBREAKS when setting $cur for +# this to be useful. +# Returns 0 if current option was split, 1 otherwise. +# +_split_longopt() +{ + if [[ $cur == --?*=* ]]; then + # Cut also backslash before '=' in case it ended up there + # for some reason. + prev="${cur%%?(\\)=*}" + cur="${cur#*=}" + return 0 + fi + + return 1 +} + +# Complete variables. +# @return True (0) if variables were completed, +# False (> 0) if not. +_variables() +{ + if [[ $cur =~ ^(\$(\{[!#]?)?)([A-Za-z0-9_]*)$ ]]; then + # Completing $var / ${var / ${!var / ${#var + if [[ $cur == '${'* ]]; then + local arrs vars + vars=($(compgen -A variable -P ${BASH_REMATCH[1]} -S '}' -- ${BASH_REMATCH[3]})) + arrs=($(compgen -A arrayvar -P ${BASH_REMATCH[1]} -S '[' -- ${BASH_REMATCH[3]})) + if ((${#vars[@]} == 1 && ${#arrs[@]} != 0)); then + # Complete ${arr with ${array[ if there is only one match, and that match is an array variable + compopt -o nospace + COMPREPLY+=(${arrs[*]}) + else + # Complete ${var with ${variable} + COMPREPLY+=(${vars[*]}) + fi + else + # Complete $var with $variable + COMPREPLY+=($(compgen -A variable -P '$' -- "${BASH_REMATCH[3]}")) + fi + return 0 + elif [[ $cur =~ ^(\$\{[#!]?)([A-Za-z0-9_]*)\[([^]]*)$ ]]; then + # Complete ${array[i with ${array[idx]} + local IFS=$'\n' + COMPREPLY+=($(compgen -W '$(printf %s\\n "${!'${BASH_REMATCH[2]}'[@]}")' \ + -P "${BASH_REMATCH[1]}${BASH_REMATCH[2]}[" -S ']}' -- "${BASH_REMATCH[3]}")) + # Complete ${arr[@ and ${arr[* + if [[ ${BASH_REMATCH[3]} == [@*] ]]; then + COMPREPLY+=("${BASH_REMATCH[1]}${BASH_REMATCH[2]}[${BASH_REMATCH[3]}]}") + fi + __ltrim_colon_completions "$cur" # array indexes may have colons + return 0 + elif [[ $cur =~ ^\$\{[#!]?[A-Za-z0-9_]*\[.*\]$ ]]; then + # Complete ${array[idx] with ${array[idx]} + COMPREPLY+=("$cur}") + __ltrim_colon_completions "$cur" + return 0 + else + case ${prev-} in + TZ) + cur=/usr/share/zoneinfo/$cur + _filedir + for i in "${!COMPREPLY[@]}"; do + if [[ ${COMPREPLY[i]} == *.tab ]]; then + unset 'COMPREPLY[i]' + continue + elif [[ -d ${COMPREPLY[i]} ]]; then + COMPREPLY[i]+=/ + compopt -o nospace + fi + COMPREPLY[i]=${COMPREPLY[i]#/usr/share/zoneinfo/} + done + return 0 + ;; + TERM) + _terms + return 0 + ;; + LANG | LC_*) + COMPREPLY=($(compgen -W '$(locale -a 2>/dev/null)' \ + -- "$cur")) + return 0 + ;; + esac + fi + return 1 +} + +# Initialize completion and deal with various general things: do file +# and variable completion where appropriate, and adjust prev, words, +# and cword as if no redirections exist so that completions do not +# need to deal with them. Before calling this function, make sure +# cur, prev, words, and cword are local, ditto split if you use -s. +# +# Options: +# -n EXCLUDE Passed to _get_comp_words_by_ref -n with redirection chars +# -e XSPEC Passed to _filedir as first arg for stderr redirections +# -o XSPEC Passed to _filedir as first arg for other output redirections +# -i XSPEC Passed to _filedir as first arg for stdin redirections +# -s Split long options with _split_longopt, implies -n = +# @return True (0) if completion needs further processing, +# False (> 0) no further processing is necessary. +# +_init_completion() +{ + local exclude="" flag outx errx inx OPTIND=1 + + while getopts "n:e:o:i:s" flag "$@"; do + case $flag in + n) exclude+=$OPTARG ;; + e) errx=$OPTARG ;; + o) outx=$OPTARG ;; + i) inx=$OPTARG ;; + s) + split=false + exclude+== + ;; + *) + echo "bash_completion: $FUNCNAME: usage error" >&2 + return 1 + ;; + esac + done + + COMPREPLY=() + local redir="@(?([0-9])<|?([0-9&])>?(>)|>&)" + _get_comp_words_by_ref -n "$exclude<>&" cur prev words cword + + # Complete variable names. + _variables && return 1 + + # Complete on files if current is a redirect possibly followed by a + # filename, e.g. ">foo", or previous is a "bare" redirect, e.g. ">". + # shellcheck disable=SC2053 + if [[ $cur == $redir* || ${prev-} == $redir ]]; then + local xspec + case $cur in + 2'>'*) xspec=${errx-} ;; + *'>'*) xspec=${outx-} ;; + *'<'*) xspec=${inx-} ;; + *) + case $prev in + 2'>'*) xspec=${errx-} ;; + *'>'*) xspec=${outx-} ;; + *'<'*) xspec=${inx-} ;; + esac + ;; + esac + cur="${cur##$redir}" + _filedir $xspec + return 1 + fi + + # Remove all redirections so completions don't have to deal with them. + local i skip + for ((i = 1; i < ${#words[@]}; )); do + if [[ ${words[i]} == $redir* ]]; then + # If "bare" redirect, remove also the next word (skip=2). + # shellcheck disable=SC2053 + [[ ${words[i]} == $redir ]] && skip=2 || skip=1 + words=("${words[@]:0:i}" "${words[@]:i+skip}") + ((i <= cword)) && ((cword -= skip)) + else + ((i++)) + fi + done + + ((cword <= 0)) && return 1 + prev=${words[cword - 1]} + + [[ ${split-} ]] && _split_longopt && split=true + + return 0 +} + +# Helper function for _parse_help and _parse_usage. +__parse_options() +{ + local option option2 i IFS=$' \t\n,/|' + + # Take first found long option, or first one (short) if not found. + option= + local -a array=($1) + for i in "${array[@]}"; do + case "$i" in + ---*) break ;; + --?*) + option=$i + break + ;; + -?*) [[ $option ]] || option=$i ;; + *) break ;; + esac + done + [[ $option ]] || return 0 + + IFS=$' \t\n' # affects parsing of the regexps below... + + # Expand --[no]foo to --foo and --nofoo etc + if [[ $option =~ (\[((no|dont)-?)\]). ]]; then + option2=${option/"${BASH_REMATCH[1]}"/} + option2=${option2%%[<{().[]*} + printf '%s\n' "${option2/=*/=}" + option=${option/"${BASH_REMATCH[1]}"/"${BASH_REMATCH[2]}"} + fi + + option=${option%%[<{().[]*} + printf '%s\n' "${option/=*/=}" +} + +# Parse GNU style help output of the given command. +# @param $1 command; if "-", read from stdin and ignore rest of args +# @param $2 command options (default: --help) +# +_parse_help() +{ + eval local cmd="$(quote "$1")" + local line + { + case $cmd in + -) cat ;; + *) LC_ALL=C "$(dequote "$cmd")" ${2:---help} 2>&1 ;; + esac + } | + while read -r line; do + + [[ $line == *([[:blank:]])-* ]] || continue + # transform "-f FOO, --foo=FOO" to "-f , --foo=FOO" etc + while [[ $line =~ \ + ((^|[^-])-[A-Za-z0-9?][[:space:]]+)\[?[A-Z0-9]+([,_-]+[A-Z0-9]+)?(\.\.+)?\]? ]]; do + line=${line/"${BASH_REMATCH[0]}"/"${BASH_REMATCH[1]}"} + done + __parse_options "${line// or /, }" + + done +} + +# Parse BSD style usage output (options in brackets) of the given command. +# @param $1 command; if "-", read from stdin and ignore rest of args +# @param $2 command options (default: --usage) +# +_parse_usage() +{ + eval local cmd="$(quote "$1")" + local line match option i char + { + case $cmd in + -) cat ;; + *) LC_ALL=C "$(dequote "$cmd")" ${2:---usage} 2>&1 ;; + esac + } | + while read -r line; do + + while [[ $line =~ \[[[:space:]]*(-[^]]+)[[:space:]]*\] ]]; do + match=${BASH_REMATCH[0]} + option=${BASH_REMATCH[1]} + case $option in + -?(\[)+([a-zA-Z0-9?])) + # Treat as bundled short options + for ((i = 1; i < ${#option}; i++)); do + char=${option:i:1} + [[ $char != '[' ]] && printf '%s\n' -$char + done + ;; + *) + __parse_options "$option" + ;; + esac + line=${line#*"$match"} + done + + done +} + +# This function completes on signal names (minus the SIG prefix) +# @param $1 prefix +_signals() +{ + local -a sigs=($(compgen -P "${1-}" -A signal "SIG${cur#${1-}}")) + COMPREPLY+=("${sigs[@]/#${1-}SIG/${1-}}") +} + +# This function completes on known mac addresses +# +_mac_addresses() +{ + local re='\([A-Fa-f0-9]\{2\}:\)\{5\}[A-Fa-f0-9]\{2\}' + local PATH="$PATH:/sbin:/usr/sbin" + + # Local interfaces + # - ifconfig on Linux: HWaddr or ether + # - ifconfig on FreeBSD: ether + # - ip link: link/ether + COMPREPLY+=($( + { + LC_ALL=C ifconfig -a || ip link show + } 2>/dev/null | command sed -ne \ + "s/.*[[:space:]]HWaddr[[:space:]]\{1,\}\($re\)[[:space:]].*/\1/p" -ne \ + "s/.*[[:space:]]HWaddr[[:space:]]\{1,\}\($re\)[[:space:]]*$/\1/p" -ne \ + "s|.*[[:space:]]\(link/\)\{0,1\}ether[[:space:]]\{1,\}\($re\)[[:space:]].*|\2|p" -ne \ + "s|.*[[:space:]]\(link/\)\{0,1\}ether[[:space:]]\{1,\}\($re\)[[:space:]]*$|\2|p" + )) + + # ARP cache + COMPREPLY+=($({ + arp -an || ip neigh show + } 2>/dev/null | command sed -ne \ + "s/.*[[:space:]]\($re\)[[:space:]].*/\1/p" -ne \ + "s/.*[[:space:]]\($re\)[[:space:]]*$/\1/p")) + + # /etc/ethers + COMPREPLY+=($(command sed -ne \ + "s/^[[:space:]]*\($re\)[[:space:]].*/\1/p" /etc/ethers 2>/dev/null)) + + COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur")) + __ltrim_colon_completions "$cur" +} + +# This function completes on configured network interfaces +# +_configured_interfaces() +{ + if [[ -f /etc/debian_version ]]; then + # Debian system + COMPREPLY=($(compgen -W "$(command sed -ne 's|^iface \([^ ]\{1,\}\).*$|\1|p' \ + /etc/network/interfaces /etc/network/interfaces.d/* 2>/dev/null)" \ + -- "$cur")) + elif [[ -f /etc/SuSE-release ]]; then + # SuSE system + COMPREPLY=($(compgen -W "$(printf '%s\n' \ + /etc/sysconfig/network/ifcfg-* | + command sed -ne 's|.*ifcfg-\([^*].*\)$|\1|p')" -- "$cur")) + elif [[ -f /etc/pld-release ]]; then + # PLD Linux + COMPREPLY=($(compgen -W "$(command ls -B \ + /etc/sysconfig/interfaces | + command sed -ne 's|.*ifcfg-\([^*].*\)$|\1|p')" -- "$cur")) + else + # Assume Red Hat + COMPREPLY=($(compgen -W "$(printf '%s\n' \ + /etc/sysconfig/network-scripts/ifcfg-* | + command sed -ne 's|.*ifcfg-\([^*].*\)$|\1|p')" -- "$cur")) + fi +} + +# Local IP addresses. +# -4: IPv4 addresses only (default) +# -6: IPv6 addresses only +# -a: All addresses +# +_ip_addresses() +{ + local n + case ${1-} in + -a) n='6\?' ;; + -6) n='6' ;; + *) n= ;; + esac + local PATH=$PATH:/sbin + local addrs=$({ + LC_ALL=C ifconfig -a || ip addr show + } 2>/dev/null | + command sed -e 's/[[:space:]]addr:/ /' -ne \ + "s|.*inet${n}[[:space:]]\{1,\}\([^[:space:]/]*\).*|\1|p") + COMPREPLY+=($(compgen -W "$addrs" -- "${cur-}")) +} + +# This function completes on available kernels +# +_kernel_versions() +{ + COMPREPLY=($(compgen -W '$(command ls /lib/modules)' -- "$cur")) +} + +# This function completes on all available network interfaces +# -a: restrict to active interfaces only +# -w: restrict to wireless interfaces only +# +_available_interfaces() +{ + local PATH=$PATH:/sbin + + COMPREPLY=($({ + if [[ ${1:-} == -w ]]; then + iwconfig + elif [[ ${1:-} == -a ]]; then + ifconfig || ip link show up + else + ifconfig -a || ip link show + fi + } 2>/dev/null | awk \ + '/^[^ \t]/ { if ($1 ~ /^[0-9]+:/) { print $2 } else { print $1 } }')) + + COMPREPLY=($(compgen -W '${COMPREPLY[@]/%[[:punct:]]/}' -- "$cur")) +} + +# Echo number of CPUs, falling back to 1 on failure. +_ncpus() +{ + local var=NPROCESSORS_ONLN + [[ $OSTYPE == *linux* ]] && var=_$var + local n=$(getconf $var 2>/dev/null) + printf %s ${n:-1} +} + +# Perform tilde (~) completion +# @return True (0) if completion needs further processing, +# False (> 0) if tilde is followed by a valid username, completions +# are put in COMPREPLY and no further processing is necessary. +_tilde() +{ + local result=0 + if [[ ${1-} == \~* && $1 != */* ]]; then + # Try generate ~username completions + COMPREPLY=($(compgen -P '~' -u -- "${1#\~}")) + result=${#COMPREPLY[@]} + # 2>/dev/null for direct invocation, e.g. in the _tilde unit test + ((result > 0)) && compopt -o filenames 2>/dev/null + fi + return $result +} + +# Expand variable starting with tilde (~) +# We want to expand ~foo/... to /home/foo/... to avoid problems when +# word-to-complete starting with a tilde is fed to commands and ending up +# quoted instead of expanded. +# Only the first portion of the variable from the tilde up to the first slash +# (~../) is expanded. The remainder of the variable, containing for example +# a dollar sign variable ($) or asterisk (*) is not expanded. +# Example usage: +# +# $ v="~"; __expand_tilde_by_ref v; echo "$v" +# +# Example output: +# +# v output +# -------- ---------------- +# ~ /home/user +# ~foo/bar /home/foo/bar +# ~foo/$HOME /home/foo/$HOME +# ~foo/a b /home/foo/a b +# ~foo/* /home/foo/* +# +# @param $1 Name of variable (not the value of the variable) to expand +__expand_tilde_by_ref() +{ + if [[ ${!1-} == \~* ]]; then + eval $1="$(printf ~%q "${!1#\~}")" + fi +} # __expand_tilde_by_ref() + +# This function expands tildes in pathnames +# +_expand() +{ + # Expand ~username type directory specifications. We want to expand + # ~foo/... to /home/foo/... to avoid problems when $cur starting with + # a tilde is fed to commands and ending up quoted instead of expanded. + + case ${cur-} in + ~*/*) + __expand_tilde_by_ref cur + ;; + ~*) + _tilde "$cur" || + eval COMPREPLY[0]="$(printf ~%q "${COMPREPLY[0]#\~}")" + return ${#COMPREPLY[@]} + ;; + esac +} + +# Process ID related functions. +# for AIX and Solaris we use X/Open syntax, BSD for others. +if [[ $OSTYPE == *@(solaris|aix)* ]]; then + # This function completes on process IDs. + _pids() + { + COMPREPLY=($(compgen -W '$(command ps -efo pid | command sed 1d)' -- "$cur")) + } + + _pgids() + { + COMPREPLY=($(compgen -W '$(command ps -efo pgid | command sed 1d)' -- "$cur")) + } + _pnames() + { + COMPREPLY=($(compgen -X '<defunct>' -W '$(command ps -efo comm | \ + command sed -e 1d -e "s:.*/::" -e "s/^-//" | sort -u)' -- "$cur")) + } +else + _pids() + { + COMPREPLY=($(compgen -W '$(command ps axo pid=)' -- "$cur")) + } + _pgids() + { + COMPREPLY=($(compgen -W '$(command ps axo pgid=)' -- "$cur")) + } + # @param $1 if -s, don't try to avoid truncated command names + _pnames() + { + local -a procs + if [[ ${1-} == -s ]]; then + procs=($(command ps axo comm | command sed -e 1d)) + else + local line i=-1 ifs=$IFS + IFS=$'\n' + local -a psout=($(command ps axo command=)) + IFS=$ifs + for line in "${psout[@]}"; do + if ((i == -1)); then + # First line, see if it has COMMAND column header. For example + # the busybox ps does that, i.e. doesn't respect axo command= + if [[ $line =~ ^(.*[[:space:]])COMMAND([[:space:]]|$) ]]; then + # It does; store its index. + i=${#BASH_REMATCH[1]} + else + # Nope, fall through to "regular axo command=" parsing. + break + fi + else + # + line=${line:i} # take command starting from found index + line=${line%% *} # trim arguments + procs+=($line) + fi + done + if ((i == -1)); then + # Regular axo command= parsing + for line in "${psout[@]}"; do + if [[ $line =~ ^[[(](.+)[])]$ ]]; then + procs+=(${BASH_REMATCH[1]}) + else + line=${line%% *} # trim arguments + line=${line##@(*/|-)} # trim leading path and - + procs+=($line) + fi + done + fi + fi + COMPREPLY=($(compgen -X "<defunct>" -W '${procs[@]}' -- "$cur")) + } +fi + +# This function completes on user IDs +# +_uids() +{ + if type getent &>/dev/null; then + COMPREPLY=($(compgen -W '$(getent passwd | cut -d: -f3)' -- "$cur")) + elif type perl &>/dev/null; then + COMPREPLY=($(compgen -W '$(perl -e '"'"'while (($uid) = (getpwent)[2]) { print $uid . "\n" }'"'"')' -- "$cur")) + else + # make do with /etc/passwd + COMPREPLY=($(compgen -W '$(cut -d: -f3 /etc/passwd)' -- "$cur")) + fi +} + +# This function completes on group IDs +# +_gids() +{ + if type getent &>/dev/null; then + COMPREPLY=($(compgen -W '$(getent group | cut -d: -f3)' -- "$cur")) + elif type perl &>/dev/null; then + COMPREPLY=($(compgen -W '$(perl -e '"'"'while (($gid) = (getgrent)[2]) { print $gid . "\n" }'"'"')' -- "$cur")) + else + # make do with /etc/group + COMPREPLY=($(compgen -W '$(cut -d: -f3 /etc/group)' -- "$cur")) + fi +} + +# Glob for matching various backup files. +# +_backup_glob='@(#*#|*@(~|.@(bak|orig|rej|swp|dpkg*|rpm@(orig|new|save))))' + +# Complete on xinetd services +# +_xinetd_services() +{ + local xinetddir=${BASHCOMP_XINETDDIR:-/etc/xinetd.d} + if [[ -d $xinetddir ]]; then + local IFS=$' \t\n' reset=$(shopt -p nullglob) + shopt -s nullglob + local -a svcs=($(printf '%s\n' $xinetddir/!($_backup_glob))) + $reset + ((!${#svcs[@]})) || + COMPREPLY+=($(compgen -W '${svcs[@]#$xinetddir/}' -- "${cur-}")) + fi +} + +# This function completes on services +# +_services() +{ + local sysvdirs + _sysvdirs + + local IFS=$' \t\n' reset=$(shopt -p nullglob) + shopt -s nullglob + COMPREPLY=( + $(printf '%s\n' ${sysvdirs[0]}/!($_backup_glob|functions|README))) + $reset + + COMPREPLY+=($({ + systemctl list-units --full --all || + systemctl list-unit-files + } 2>/dev/null | + awk '$1 ~ /\.service$/ { sub("\\.service$", "", $1); print $1 }')) + + if [[ -x /sbin/upstart-udev-bridge ]]; then + COMPREPLY+=($(initctl list 2>/dev/null | cut -d' ' -f1)) + fi + + COMPREPLY=($(compgen -W '${COMPREPLY[@]#${sysvdirs[0]}/}' -- "$cur")) +} + +# This completes on a list of all available service scripts for the +# 'service' command and/or the SysV init.d directory, followed by +# that script's available commands +# +_service() +{ + local cur prev words cword + _init_completion || return + + # don't complete past 2nd token + ((cword > 2)) && return + + if [[ $cword -eq 1 && $prev == ?(*/)service ]]; then + _services + [[ -e /etc/mandrake-release ]] && _xinetd_services + else + local sysvdirs + _sysvdirs + COMPREPLY=($(compgen -W '`command sed -e "y/|/ /" \ + -ne "s/^.*\(U\|msg_u\)sage.*{\(.*\)}.*$/\2/p" \ + ${sysvdirs[0]}/${prev##*/} 2>/dev/null` start stop' -- "$cur")) + fi +} && + complete -F _service service +_sysvdirs +for svcdir in "${sysvdirs[@]}"; do + for svc in $svcdir/!($_backup_glob); do + [[ -x $svc ]] && complete -F _service $svc + done +done +unset svc svcdir sysvdirs + +# This function completes on modules +# +_modules() +{ + local modpath + modpath=/lib/modules/$1 + COMPREPLY=($(compgen -W "$(command ls -RL $modpath 2>/dev/null | + command sed -ne 's/^\(.*\)\.k\{0,1\}o\(\.[gx]z\)\{0,1\}$/\1/p')" -- "$cur")) +} + +# This function completes on installed modules +# +_installed_modules() +{ + COMPREPLY=($(compgen -W "$(PATH="$PATH:/sbin" lsmod | + awk '{if (NR != 1) print $1}')" -- "$1")) +} + +# This function completes on user or user:group format; as for chown and cpio. +# +# The : must be added manually; it will only complete usernames initially. +# The legacy user.group format is not supported. +# +# @param $1 If -u, only return users/groups the user has access to in +# context of current completion. +_usergroup() +{ + if [[ $cur == *\\\\* || $cur == *:*:* ]]; then + # Give up early on if something seems horribly wrong. + return + elif [[ $cur == *\\:* ]]; then + # Completing group after 'user\:gr<TAB>'. + # Reply with a list of groups prefixed with 'user:', readline will + # escape to the colon. + local prefix + prefix=${cur%%*([^:])} + prefix=${prefix//\\/} + local mycur="${cur#*[:]}" + if [[ ${1-} == -u ]]; then + _allowed_groups "$mycur" + else + local IFS=$'\n' + COMPREPLY=($(compgen -g -- "$mycur")) + fi + COMPREPLY=($(compgen -P "$prefix" -W "${COMPREPLY[@]}")) + elif [[ $cur == *:* ]]; then + # Completing group after 'user:gr<TAB>'. + # Reply with a list of unprefixed groups since readline with split on : + # and only replace the 'gr' part + local mycur="${cur#*:}" + if [[ ${1-} == -u ]]; then + _allowed_groups "$mycur" + else + local IFS=$'\n' + COMPREPLY=($(compgen -g -- "$mycur")) + fi + else + # Completing a partial 'usernam<TAB>'. + # + # Don't suffix with a : because readline will escape it and add a + # slash. It's better to complete into 'chown username ' than 'chown + # username\:'. + if [[ ${1-} == -u ]]; then + _allowed_users "$cur" + else + local IFS=$'\n' + COMPREPLY=($(compgen -u -- "$cur")) + fi + fi +} + +_allowed_users() +{ + if _complete_as_root; then + local IFS=$'\n' + COMPREPLY=($(compgen -u -- "${1:-$cur}")) + else + local IFS=$'\n ' + COMPREPLY=($(compgen -W \ + "$(id -un 2>/dev/null || whoami 2>/dev/null)" -- "${1:-$cur}")) + fi +} + +_allowed_groups() +{ + if _complete_as_root; then + local IFS=$'\n' + COMPREPLY=($(compgen -g -- "$1")) + else + local IFS=$'\n ' + COMPREPLY=($(compgen -W \ + "$(id -Gn 2>/dev/null || groups 2>/dev/null)" -- "$1")) + fi +} + +# This function completes on valid shells +# +_shells() +{ + local shell rest + while read -r shell rest; do + [[ $shell == /* && $shell == "$cur"* ]] && COMPREPLY+=($shell) + done 2>/dev/null </etc/shells +} + +# This function completes on valid filesystem types +# +_fstypes() +{ + local fss + + if [[ -e /proc/filesystems ]]; then + # Linux + fss="$(cut -d$'\t' -f2 /proc/filesystems) + $(awk '! /\*/ { print $NF }' /etc/filesystems 2>/dev/null)" + else + # Generic + fss="$(awk '/^[ \t]*[^#]/ { print $3 }' /etc/fstab 2>/dev/null) + $(awk '/^[ \t]*[^#]/ { print $3 }' /etc/mnttab 2>/dev/null) + $(awk '/^[ \t]*[^#]/ { print $4 }' /etc/vfstab 2>/dev/null) + $(awk '{ print $1 }' /etc/dfs/fstypes 2>/dev/null) + $([[ -d /etc/fs ]] && command ls /etc/fs)" + fi + + [[ -n $fss ]] && COMPREPLY+=($(compgen -W "$fss" -- "$cur")) +} + +# Get real command. +# - arg: $1 Command +# - stdout: Filename of command in PATH with possible symbolic links resolved. +# Empty string if command not found. +# - return: True (0) if command found, False (> 0) if not. +_realcommand() +{ + type -P "$1" >/dev/null && { + if type -p realpath >/dev/null; then + realpath "$(type -P "$1")" + elif type -p greadlink >/dev/null; then + greadlink -f "$(type -P "$1")" + elif type -p readlink >/dev/null; then + readlink -f "$(type -P "$1")" + else + type -P "$1" + fi + } +} + +# This function returns the first argument, excluding options +# @param $1 chars Characters out of $COMP_WORDBREAKS which should +# NOT be considered word breaks. See __reassemble_comp_words_by_ref. +_get_first_arg() +{ + local i + + arg= + for ((i = 1; i < COMP_CWORD; i++)); do + if [[ ${COMP_WORDS[i]} != -* ]]; then + arg=${COMP_WORDS[i]} + break + fi + done +} + +# This function counts the number of args, excluding options +# @param $1 chars Characters out of $COMP_WORDBREAKS which should +# NOT be considered word breaks. See __reassemble_comp_words_by_ref. +# @param $2 glob Options whose following argument should not be counted +# @param $3 glob Options that should be counted as args +_count_args() +{ + local i cword words + __reassemble_comp_words_by_ref "${1-}" words cword + + args=1 + for ((i = 1; i < cword; i++)); do + # shellcheck disable=SC2053 + if [[ ${words[i]} != -* && ${words[i - 1]} != ${2-} || \ + ${words[i]} == ${3-} ]]; then + ((args++)) + fi + done +} + +# This function completes on PCI IDs +# +_pci_ids() +{ + COMPREPLY+=($(compgen -W \ + "$(PATH="$PATH:/sbin" lspci -n | awk '{print $3}')" -- "$cur")) +} + +# This function completes on USB IDs +# +_usb_ids() +{ + COMPREPLY+=($(compgen -W \ + "$(PATH="$PATH:/sbin" lsusb | awk '{print $6}')" -- "$cur")) +} + +# CD device names +_cd_devices() +{ + COMPREPLY+=($(compgen -f -d -X "!*/?([amrs])cd*" -- "${cur:-/dev/}")) +} + +# DVD device names +_dvd_devices() +{ + COMPREPLY+=($(compgen -f -d -X "!*/?(r)dvd*" -- "${cur:-/dev/}")) +} + +# TERM environment variable values +_terms() +{ + COMPREPLY+=($(compgen -W "$({ + command sed -ne 's/^\([^[:space:]#|]\{2,\}\)|.*/\1/p' /etc/termcap + { + toe -a || toe + } | awk '{ print $1 }' + find /{etc,lib,usr/lib,usr/share}/terminfo/? -type f -maxdepth 1 | + awk -F/ '{ print $NF }' + } 2>/dev/null)" -- "$cur")) +} + +_bashcomp_try_faketty() +{ + if type unbuffer &>/dev/null; then + unbuffer -p "$@" + elif script --version 2>&1 | command grep -qF util-linux; then + # BSD and Solaris "script" do not seem to have required features + script -qaefc "$*" /dev/null + else + "$@" # no can do, fallback + fi +} + +# a little help for FreeBSD ports users +[[ $OSTYPE == *freebsd* ]] && complete -W 'index search fetch fetch-list + extract patch configure build install reinstall deinstall clean + clean-depends kernel buildworld' make + +# This function provides simple user@host completion +# +_user_at_host() +{ + local cur prev words cword + _init_completion -n : || return + + if [[ $cur == *@* ]]; then + _known_hosts_real "$cur" + else + COMPREPLY=($(compgen -u -S @ -- "$cur")) + compopt -o nospace + fi +} +shopt -u hostcomplete && complete -F _user_at_host talk ytalk finger + +# NOTE: Using this function as a helper function is deprecated. Use +# `_known_hosts_real' instead. +_known_hosts() +{ + local cur prev words cword + _init_completion -n : || return + + # NOTE: Using `_known_hosts' as a helper function and passing options + # to `_known_hosts' is deprecated: Use `_known_hosts_real' instead. + local options + [[ ${1-} == -a || ${2-} == -a ]] && options=-a + [[ ${1-} == -c || ${2-} == -c ]] && options+=" -c" + _known_hosts_real ${options-} -- "$cur" +} # _known_hosts() + +# Helper function to locate ssh included files in configs +# This function looks for the "Include" keyword in ssh config files and +# includes them recursively, adding each result to the config variable. +_included_ssh_config_files() +{ + (($# < 1)) && + echo "bash_completion: $FUNCNAME: missing mandatory argument CONFIG" >&2 + local configfile i f + configfile=$1 + + local reset=$(shopt -po noglob) + set -o noglob + local included=($(command sed -ne 's/^[[:blank:]]*[Ii][Nn][Cc][Ll][Uu][Dd][Ee][[:blank:]]\(.*\)$/\1/p' "${configfile}")) + $reset + + [[ ${included-} ]] || return + for i in "${included[@]}"; do + # Check the origin of $configfile to complete relative included paths on included + # files according to ssh_config(5): + # "[...] Files without absolute paths are assumed to be in ~/.ssh if included in a user + # configuration file or /etc/ssh if included from the system configuration file.[...]" + if ! [[ $i =~ ^\~.*|^\/.* ]]; then + if [[ $configfile =~ ^\/etc\/ssh.* ]]; then + i="/etc/ssh/$i" + else + i="$HOME/.ssh/$i" + fi + fi + __expand_tilde_by_ref i + # In case the expanded variable contains multiple paths + set +o noglob + for f in $i; do + if [[ -r $f ]]; then + config+=("$f") + # The Included file is processed to look for Included files in itself + _included_ssh_config_files $f + fi + done + $reset + done +} # _included_ssh_config_files() + +# Helper function for completing _known_hosts. +# This function performs host completion based on ssh's config and known_hosts +# files, as well as hostnames reported by avahi-browse if +# COMP_KNOWN_HOSTS_WITH_AVAHI is set to a non-empty value. Also hosts from +# HOSTFILE (compgen -A hostname) are added, unless +# COMP_KNOWN_HOSTS_WITH_HOSTFILE is set to an empty value. +# Usage: _known_hosts_real [OPTIONS] CWORD +# Options: -a Use aliases from ssh config files +# -c Use `:' suffix +# -F configfile Use `configfile' for configuration settings +# -p PREFIX Use PREFIX +# -4 Filter IPv6 addresses from results +# -6 Filter IPv4 addresses from results +# Return: Completions, starting with CWORD, are added to COMPREPLY[] +_known_hosts_real() +{ + local configfile flag prefix="" ifs=$IFS + local cur suffix="" aliases i host ipv4 ipv6 + local -a kh tmpkh=() khd=() config=() + + # TODO remove trailing %foo from entries + + local OPTIND=1 + while getopts "ac46F:p:" flag "$@"; do + case $flag in + a) aliases='yes' ;; + c) suffix=':' ;; + F) configfile=$OPTARG ;; + p) prefix=$OPTARG ;; + 4) ipv4=1 ;; + 6) ipv6=1 ;; + *) + echo "bash_completion: $FUNCNAME: usage error" >&2 + return 1 + ;; + esac + done + if (($# < OPTIND)); then + echo "bash_completion: $FUNCNAME: missing mandatory argument CWORD" >&2 + return 1 + fi + cur=${!OPTIND} + ((OPTIND += 1)) + if (($# >= OPTIND)); then + echo "bash_completion: $FUNCNAME($*): unprocessed arguments:" \ + "$(while (($# >= OPTIND)); do + printf '%s ' ${!OPTIND} + shift + done)" >&2 + return 1 + fi + + [[ $cur == *@* ]] && prefix=$prefix${cur%@*}@ && cur=${cur#*@} + kh=() + + # ssh config files + if [[ -v configfile ]]; then + [[ -r $configfile ]] && config+=("$configfile") + else + for i in /etc/ssh/ssh_config ~/.ssh/config ~/.ssh2/config; do + [[ -r $i ]] && config+=("$i") + done + fi + + local reset=$(shopt -po noglob) + set -o noglob + + # "Include" keyword in ssh config files + if ((${#config[@]} > 0)); then + for i in "${config[@]}"; do + _included_ssh_config_files "$i" + done + fi + + # Known hosts files from configs + if ((${#config[@]} > 0)); then + local IFS=$'\n' + # expand paths (if present) to global and user known hosts files + # TODO(?): try to make known hosts files with more than one consecutive + # spaces in their name work (watch out for ~ expansion + # breakage! Alioth#311595) + tmpkh=($(awk 'sub("^[ \t]*([Gg][Ll][Oo][Bb][Aa][Ll]|[Uu][Ss][Ee][Rr])[Kk][Nn][Oo][Ww][Nn][Hh][Oo][Ss][Tt][Ss][Ff][Ii][Ll][Ee][ \t]+", "") { print $0 }' "${config[@]}" | sort -u)) + IFS=$ifs + fi + if ((${#tmpkh[@]} != 0)); then + local j + for i in "${tmpkh[@]}"; do + # First deal with quoted entries... + while [[ $i =~ ^([^\"]*)\"([^\"]*)\"(.*)$ ]]; do + i=${BASH_REMATCH[1]}${BASH_REMATCH[3]} + j=${BASH_REMATCH[2]} + __expand_tilde_by_ref j # Eval/expand possible `~' or `~user' + [[ -r $j ]] && kh+=("$j") + done + # ...and then the rest. + for j in $i; do + __expand_tilde_by_ref j # Eval/expand possible `~' or `~user' + [[ -r $j ]] && kh+=("$j") + done + done + fi + + if [[ ! -v configfile ]]; then + # Global and user known_hosts files + for i in /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2 \ + /etc/known_hosts /etc/known_hosts2 ~/.ssh/known_hosts \ + ~/.ssh/known_hosts2; do + [[ -r $i ]] && kh+=("$i") + done + for i in /etc/ssh2/knownhosts ~/.ssh2/hostkeys; do + [[ -d $i ]] && khd+=("$i"/*pub) + done + fi + + # If we have known_hosts files to use + if ((${#kh[@]} + ${#khd[@]} > 0)); then + if ((${#kh[@]} > 0)); then + # https://man.openbsd.org/sshd.8#SSH_KNOWN_HOSTS_FILE_FORMAT + for i in "${kh[@]}"; do + while read -ra tmpkh; do + ((${#tmpkh[@]} == 0)) && continue + set -- "${tmpkh[@]}" + # Skip entries starting with | (hashed) and # (comment) + [[ $1 == [\|\#]* ]] && continue + # Ignore leading @foo (markers) + [[ $1 == @* ]] && shift + # Split entry on commas + local IFS=, + for host in $1; do + # Skip hosts containing wildcards + [[ $host == *[*?]* ]] && continue + # Remove leading [ + host="${host#[}" + # Remove trailing ] + optional :port + host="${host%]?(:+([0-9]))}" + # Add host to candidates + COMPREPLY+=($host) + done + IFS=$ifs + done <"$i" + done + COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur")) + fi + if ((${#khd[@]} > 0)); then + # Needs to look for files called + # .../.ssh2/key_22_<hostname>.pub + # dont fork any processes, because in a cluster environment, + # there can be hundreds of hostkeys + for i in "${khd[@]}"; do + if [[ $i == *key_22_$cur*.pub && -r $i ]]; then + host=${i/#*key_22_/} + host=${host/%.pub/} + COMPREPLY+=($host) + fi + done + fi + + # apply suffix and prefix + for i in ${!COMPREPLY[*]}; do + COMPREPLY[i]=$prefix${COMPREPLY[i]}$suffix + done + fi + + # append any available aliases from ssh config files + if [[ ${#config[@]} -gt 0 && -v aliases ]]; then + local -a hosts=($(command sed -ne 's/^[[:blank:]]*[Hh][Oo][Ss][Tt][[:blank:]]\(.*\)$/\1/p' "${config[@]}")) + if ((${#hosts[@]} != 0)); then + COMPREPLY+=($(compgen -P "$prefix" \ + -S "$suffix" -W '${hosts[@]%%[*?%]*}' -X '\!*' -- "$cur")) + fi + fi + + # Add hosts reported by avahi-browse, if desired and it's available. + if [[ ${COMP_KNOWN_HOSTS_WITH_AVAHI-} ]] && + type avahi-browse &>/dev/null; then + # The original call to avahi-browse also had "-k", to avoid lookups + # into avahi's services DB. We don't need the name of the service, and + # if it contains ";", it may mistify the result. But on Gentoo (at + # least), -k wasn't available (even if mentioned in the manpage) some + # time ago, so... + COMPREPLY+=($(compgen -P "$prefix" -S "$suffix" -W \ + "$(avahi-browse -cpr _workstation._tcp 2>/dev/null | + awk -F';' '/^=/ { print $7 }' | sort -u)" -- "$cur")) + fi + + # Add hosts reported by ruptime. + if type ruptime &>/dev/null; then + COMPREPLY+=($(compgen -W \ + "$(ruptime 2>/dev/null | awk '!/^ruptime:/ { print $1 }')" \ + -- "$cur")) + fi + + # Add results of normal hostname completion, unless + # `COMP_KNOWN_HOSTS_WITH_HOSTFILE' is set to an empty value. + if [[ -n ${COMP_KNOWN_HOSTS_WITH_HOSTFILE-1} ]]; then + COMPREPLY+=( + $(compgen -A hostname -P "$prefix" -S "$suffix" -- "$cur")) + fi + + $reset + + if [[ -v ipv4 ]]; then + COMPREPLY=("${COMPREPLY[@]/*:*$suffix/}") + fi + if [[ -v ipv6 ]]; then + COMPREPLY=("${COMPREPLY[@]/+([0-9]).+([0-9]).+([0-9]).+([0-9])$suffix/}") + fi + if [[ -v ipv4 || -v ipv6 ]]; then + for i in "${!COMPREPLY[@]}"; do + [[ ${COMPREPLY[i]} ]] || unset -v "COMPREPLY[i]" + done + fi + + __ltrim_colon_completions "$prefix$cur" + +} # _known_hosts_real() +complete -F _known_hosts traceroute traceroute6 \ + fping fping6 telnet rsh rlogin ftp dig mtr ssh-installkeys showmount + +# This meta-cd function observes the CDPATH variable, so that cd additionally +# completes on directories under those specified in CDPATH. +# +_cd() +{ + local cur prev words cword + _init_completion || return + + local IFS=$'\n' i j k + + compopt -o filenames + + # Use standard dir completion if no CDPATH or parameter starts with /, + # ./ or ../ + if [[ -z ${CDPATH:-} || $cur == ?(.)?(.)/* ]]; then + _filedir -d + return + fi + + local -r mark_dirs=$(_rl_enabled mark-directories && echo y) + local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories && echo y) + + # we have a CDPATH, so loop on its contents + for i in ${CDPATH//:/$'\n'}; do + # create an array of matched subdirs + k="${#COMPREPLY[@]}" + for j in $(compgen -d -- $i/$cur); do + if [[ ($mark_symdirs && -L $j || $mark_dirs && ! -L $j) && ! -d ${j#$i/} ]]; then + j+="/" + fi + COMPREPLY[k++]=${j#$i/} + done + done + + _filedir -d + + if ((${#COMPREPLY[@]} == 1)); then + i=${COMPREPLY[0]} + if [[ $i == "$cur" && $i != "*/" ]]; then + COMPREPLY[0]="${i}/" + fi + fi + + return +} +if shopt -q cdable_vars; then + complete -v -F _cd -o nospace cd pushd +else + complete -F _cd -o nospace cd pushd +fi + +# A _command_offset wrapper function for use when the offset is unknown. +# Only intended to be used as a completion function directly associated +# with a command, not to be invoked from within other completion functions. +# +_command() +{ + local offset i + + # find actual offset, as position of the first non-option + offset=1 + for ((i = 1; i <= COMP_CWORD; i++)); do + if [[ ${COMP_WORDS[i]} != -* ]]; then + offset=$i + break + fi + done + _command_offset $offset +} + +# A meta-command completion function for commands like sudo(8), which need to +# first complete on a command, then complete according to that command's own +# completion definition. +# +_command_offset() +{ + # rewrite current completion context before invoking + # actual command completion + + # find new first word position, then + # rewrite COMP_LINE and adjust COMP_POINT + local word_offset=$1 i j + for ((i = 0; i < word_offset; i++)); do + for ((j = 0; j <= ${#COMP_LINE}; j++)); do + [[ $COMP_LINE == "${COMP_WORDS[i]}"* ]] && break + COMP_LINE=${COMP_LINE:1} + ((COMP_POINT--)) + done + COMP_LINE=${COMP_LINE#"${COMP_WORDS[i]}"} + ((COMP_POINT -= ${#COMP_WORDS[i]})) + done + + # shift COMP_WORDS elements and adjust COMP_CWORD + for ((i = 0; i <= COMP_CWORD - word_offset; i++)); do + COMP_WORDS[i]=${COMP_WORDS[i + word_offset]} + done + for ((i; i <= COMP_CWORD; i++)); do + unset 'COMP_WORDS[i]' + done + ((COMP_CWORD -= word_offset)) + + COMPREPLY=() + local cur + _get_comp_words_by_ref cur + + if ((COMP_CWORD == 0)); then + local IFS=$'\n' + compopt -o filenames + COMPREPLY=($(compgen -d -c -- "$cur")) + else + local cmd=${COMP_WORDS[0]} compcmd=${COMP_WORDS[0]} + local cspec=$(complete -p $cmd 2>/dev/null) + + # If we have no completion for $cmd yet, see if we have for basename + if [[ ! $cspec && $cmd == */* ]]; then + cspec=$(complete -p ${cmd##*/} 2>/dev/null) + [[ $cspec ]] && compcmd=${cmd##*/} + fi + # If still nothing, just load it for the basename + if [[ ! $cspec ]]; then + compcmd=${cmd##*/} + _completion_loader $compcmd + cspec=$(complete -p $compcmd 2>/dev/null) + fi + + if [[ -n $cspec ]]; then + if [[ ${cspec#* -F } != "$cspec" ]]; then + # complete -F <function> + + # get function name + local func=${cspec#*-F } + func=${func%% *} + + if ((${#COMP_WORDS[@]} >= 2)); then + $func $cmd "${COMP_WORDS[-1]}" "${COMP_WORDS[-2]}" + else + $func $cmd "${COMP_WORDS[-1]}" + fi + + # restore initial compopts + local opt + while [[ $cspec == *" -o "* ]]; do + # FIXME: should we take "+o opt" into account? + cspec=${cspec#*-o } + opt=${cspec%% *} + compopt -o $opt + cspec=${cspec#$opt} + done + else + cspec=${cspec#complete} + cspec=${cspec%%$compcmd} + COMPREPLY=($(eval compgen "$cspec" -- '$cur')) + fi + elif ((${#COMPREPLY[@]} == 0)); then + # XXX will probably never happen as long as completion loader loads + # *something* for every command thrown at it ($cspec != empty) + _minimal + fi + fi +} +complete -F _command aoss command "do" else eval exec ltrace nice nohup padsp \ + "then" time tsocks vsound xargs + +_root_command() +{ + local PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin + local root_command=$1 + _command +} +complete -F _root_command fakeroot gksu gksudo kdesudo really + +# Return true if the completion should be treated as running as root +_complete_as_root() +{ + [[ $EUID -eq 0 || ${root_command:-} ]] +} + +_longopt() +{ + local cur prev words cword split + _init_completion -s || return + + case "${prev,,}" in + --help | --usage | --version) + return + ;; + --!(no-*)dir*) + _filedir -d + return + ;; + --!(no-*)@(file|path)*) + _filedir + return + ;; + --+([-a-z0-9_])) + local argtype=$(LC_ALL=C $1 --help 2>&1 | command sed -ne \ + "s|.*$prev\[\{0,1\}=[<[]\{0,1\}\([-A-Za-z0-9_]\{1,\}\).*|\1|p") + case ${argtype,,} in + *dir*) + _filedir -d + return + ;; + *file* | *path*) + _filedir + return + ;; + esac + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$(LC_ALL=C $1 --help 2>&1 | + while read -r line; do + [[ $line =~ --[A-Za-z0-9]+([-_][A-Za-z0-9]+)*=? ]] && + printf '%s\n' ${BASH_REMATCH[0]} + done)" -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + elif [[ $1 == *@(rmdir|chroot) ]]; then + _filedir -d + else + [[ $1 == *mkdir ]] && compopt -o nospace + _filedir + fi +} +# makeinfo and texi2dvi are defined elsewhere. +complete -F _longopt a2ps awk base64 bash bc bison cat chroot colordiff cp \ + csplit cut date df diff dir du enscript env expand fmt fold gperf \ + grep grub head irb ld ldd less ln ls m4 md5sum mkdir mkfifo mknod \ + mv netstat nl nm objcopy objdump od paste pr ptx readelf rm rmdir \ + sed seq sha{,1,224,256,384,512}sum shar sort split strip sum tac tail tee \ + texindex touch tr uname unexpand uniq units vdir wc who + +declare -Ag _xspecs + +_filedir_xspec() +{ + local cur prev words cword + _init_completion || return + + _tilde "$cur" || return + + local IFS=$'\n' xspec=${_xspecs[${1##*/}]} tmp + local -a toks + + toks=($( + compgen -d -- "$(quote_readline "$cur")" | { + while read -r tmp; do + printf '%s\n' $tmp + done + } + )) + + # Munge xspec to contain uppercase version too + # https://lists.gnu.org/archive/html/bug-bash/2010-09/msg00036.html + # news://news.gmane.io/4C940E1C.1010304@case.edu + eval xspec="${xspec}" + local matchop=! + if [[ $xspec == !* ]]; then + xspec=${xspec#!} + matchop=@ + fi + xspec="$matchop($xspec|${xspec^^})" + + toks+=($( + eval compgen -f -X "'!$xspec'" -- '$(quote_readline "$cur")' | { + while read -r tmp; do + [[ -n $tmp ]] && printf '%s\n' $tmp + done + } + )) + + # Try without filter if it failed to produce anything and configured to + [[ -n ${COMP_FILEDIR_FALLBACK:-} && ${#toks[@]} -lt 1 ]] && { + local reset=$(shopt -po noglob) + set -o noglob + toks+=($(compgen -f -- "$(quote_readline "$cur")")) + IFS=' ' + $reset + IFS=$'\n' + } + + if ((${#toks[@]} != 0)); then + compopt -o filenames + COMPREPLY=("${toks[@]}") + fi +} + +_install_xspec() +{ + local xspec=$1 cmd + shift + for cmd in "$@"; do + _xspecs[$cmd]=$xspec + done +} +# bzcmp, bzdiff, bz*grep, bzless, bzmore intentionally not here, see Debian: #455510 +_install_xspec '!*.?(t)bz?(2)' bunzip2 bzcat pbunzip2 pbzcat lbunzip2 lbzcat +_install_xspec '!*.@(zip|[aegjswx]ar|exe|pk3|wsz|zargo|xpi|s[tx][cdiw]|sx[gm]|o[dt][tspgfc]|od[bm]|oxt|epub|apk|aab|ipa|do[ct][xm]|p[op]t[mx]|xl[st][xm]|pyz|whl)' unzip zipinfo +_install_xspec '*.Z' compress znew +# zcmp, zdiff, z*grep, zless, zmore intentionally not here, see Debian: #455510 +_install_xspec '!*.@(Z|[gGd]z|t[ag]z)' gunzip zcat +_install_xspec '!*.@(Z|[gGdz]z|t[ag]z)' unpigz +_install_xspec '!*.Z' uncompress +# lzcmp, lzdiff intentionally not here, see Debian: #455510 +_install_xspec '!*.@(tlz|lzma)' lzcat lzegrep lzfgrep lzgrep lzless lzmore unlzma +_install_xspec '!*.@(?(t)xz|tlz|lzma)' unxz xzcat +_install_xspec '!*.lrz' lrunzip +_install_xspec '!*.@(gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx)' ee +_install_xspec '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm|svg)' qiv +_install_xspec '!*.@(gif|jp?(e)g?(2)|j2[ck]|jp[2f]|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm|?(e)ps)' xv +_install_xspec '!*.@(@(?(e)ps|?(E)PS|pdf|PDF)?(.gz|.GZ|.bz2|.BZ2|.Z))' gv ggv kghostview +_install_xspec '!*.@(dvi|DVI)?(.@(gz|Z|bz2))' xdvi kdvi +_install_xspec '!*.dvi' dvips dviselect dvitype dvipdf advi dvipdfm dvipdfmx +_install_xspec '!*.[pf]df' acroread gpdf xpdf +_install_xspec '!*.@(?(e)ps|pdf)' kpdf +_install_xspec '!*.@(okular|@(?(e|x)ps|?(E|X)PS|[pf]df|[PF]DF|dvi|DVI|cb[rz]|CB[RZ]|djv?(u)|DJV?(U)|dvi|DVI|gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx|GIF|JP?(E)G|MIFF|TIF?(F)|PN[GM]|P[BGP]M|BMP|XPM|ICO|XWD|TGA|PCX|epub|EPUB|odt|ODT|fb?(2)|FB?(2)|mobi|MOBI|g3|G3|chm|CHM)?(.?(gz|GZ|bz2|BZ2|xz|XZ)))' okular +_install_xspec '!*.pdf' epdfview pdfunite +_install_xspec '!*.@(cb[rz7t]|djv?(u)|?(e)ps|pdf)' zathura +_install_xspec '!*.@(?(e)ps|pdf)' ps2pdf ps2pdf12 ps2pdf13 ps2pdf14 ps2pdfwr +_install_xspec '!*.texi*' makeinfo texi2html +_install_xspec '!*.@(?(la)tex|texi|dtx|ins|ltx|dbj)' tex latex slitex jadetex pdfjadetex pdftex pdflatex texi2dvi xetex xelatex luatex lualatex +_install_xspec '!*.mp3' mpg123 mpg321 madplay +_install_xspec '!*@(.@(mp?(e)g|MP?(E)G|wm[av]|WM[AV]|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|fxm|FXM|viv|rm|ram|yuv|mov|MOV|qt|QT|web[am]|WEB[AM]|mp[234]|MP[234]|m?(p)4[av]|M?(P)4[AV]|mkv|MKV|og[agmv]|OG[AGMV]|t[ps]|T[PS]|m2t?(s)|M2T?(S)|mts|MTS|wav|WAV|flac|FLAC|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM)|+([0-9]).@(vdr|VDR))?(.@(crdownload|part))' xine aaxine fbxine +_install_xspec '!*@(.@(mp?(e)g|MP?(E)G|wm[av]|WM[AV]|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|fxm|FXM|viv|rm|ram|yuv|mov|MOV|qt|QT|web[am]|WEB[AM]|mp[234]|MP[234]|m?(p)4[av]|M?(P)4[AV]|mkv|MKV|og[agmv]|OG[AGMV]|t[ps]|T[PS]|m2t?(s)|M2T?(S)|mts|MTS|wav|WAV|flac|FLAC|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM|iso|ISO)|+([0-9]).@(vdr|VDR))?(.@(crdownload|part))' kaffeine dragon totem +_install_xspec '!*.@(avi|asf|wmv)' aviplay +_install_xspec '!*.@(rm?(j)|ra?(m)|smi?(l))' realplay +_install_xspec '!*.@(mpg|mpeg|avi|mov|qt)' xanim +_install_xspec '!*.@(og[ag]|m3u|flac|spx)' ogg123 +_install_xspec '!*.@(mp3|ogg|pls|m3u)' gqmpeg freeamp +_install_xspec '!*.fig' xfig +_install_xspec '!*.@(mid?(i)|cmf)' playmidi +_install_xspec '!*.@(mid?(i)|rmi|rcp|[gr]36|g18|mod|xm|it|x3m|s[3t]m|kar)' timidity +_install_xspec '!*.@(669|abc|am[fs]|d[bs]m|dmf|far|it|mdl|m[eo]d|mid?(i)|mt[2m]|oct|okt?(a)|p[st]m|s[3t]m|ult|umx|wav|xm)' modplugplay modplug123 +_install_xspec '*.@([ao]|so|so.!(conf|*/*)|[rs]pm|gif|jp?(e)g|mp3|mp?(e)g|avi|asf|ogg|class)' vi vim gvim rvim view rview rgvim rgview gview emacs xemacs sxemacs kate kwrite +_install_xspec '!*.@(zip|z|gz|tgz)' bzme +# konqueror not here on purpose, it's more than a web/html browser +_install_xspec '!*.@(?([xX]|[sS])[hH][tT][mM]?([lL]))' netscape mozilla lynx galeon dillo elinks amaya epiphany +_install_xspec '!*.@(sxw|stw|sxg|sgl|doc?([mx])|dot?([mx])|rtf|txt|htm|html|?(f)odt|ott|odm|pdf)' oowriter lowriter +_install_xspec '!*.@(sxi|sti|pps?(x)|ppt?([mx])|pot?([mx])|?(f)odp|otp)' ooimpress loimpress +_install_xspec '!*.@(sxc|stc|xls?([bmx])|xlw|xlt?([mx])|[ct]sv|?(f)ods|ots)' oocalc localc +_install_xspec '!*.@(sxd|std|sda|sdd|?(f)odg|otg)' oodraw lodraw +_install_xspec '!*.@(sxm|smf|mml|odf)' oomath lomath +_install_xspec '!*.odb' oobase lobase +_install_xspec '!*.[rs]pm' rpm2cpio +_install_xspec '!*.aux' bibtex +_install_xspec '!*.po' poedit gtranslator kbabel lokalize +_install_xspec '!*.@([Pp][Rr][Gg]|[Cc][Ll][Pp])' harbour gharbour hbpp +_install_xspec '!*.[Hh][Rr][Bb]' hbrun +_install_xspec '!*.ly' lilypond ly2dvi +_install_xspec '!*.@(dif?(f)|?(d)patch)?(.@([gx]z|bz2|lzma))' cdiff +_install_xspec '!@(*.@(ks|jks|jceks|p12|pfx|bks|ubr|gkr|cer|crt|cert|p7b|pkipath|pem|p10|csr|crl)|cacerts)' portecle +_install_xspec '!*.@(mp[234c]|og[ag]|@(fl|a)ac|m4[abp]|spx|tta|w?(a)v|wma|aif?(f)|asf|ape)' kid3 kid3-qt +unset -f _install_xspec + +# Minimal completion to use as fallback in _completion_loader. +_minimal() +{ + local cur prev words cword split + _init_completion -s || return + $split && return + _filedir +} +# Complete the empty string to allow completion of '>', '>>', and '<' on < 4.3 +# https://lists.gnu.org/archive/html/bug-bash/2012-01/msg00045.html +complete -F _minimal '' + +__load_completion() +{ + local -a dirs=(${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions) + local ifs=$IFS IFS=: dir cmd="${1##*/}" compfile + [[ -n $cmd ]] || return 1 + for dir in ${XDG_DATA_DIRS:-/usr/local/share:/usr/share}; do + dirs+=($dir/bash-completion/completions) + done + IFS=$ifs + + if [[ $BASH_SOURCE == */* ]]; then + dirs+=("${BASH_SOURCE%/*}/completions") + else + dirs+=(./completions) + fi + + local backslash= + if [[ $cmd == \\* ]]; then + cmd="${cmd:1}" + # If we already have a completion for the "real" command, use it + $(complete -p "$cmd" 2>/dev/null || echo false) "\\$cmd" && return 0 + backslash=\\ + fi + + for dir in "${dirs[@]}"; do + [[ -d $dir ]] || continue + for compfile in "$cmd" "$cmd.bash" "_$cmd"; do + compfile="$dir/$compfile" + # Avoid trying to source dirs; https://bugzilla.redhat.com/903540 + if [[ -f $compfile ]] && . "$compfile" &>/dev/null; then + [[ $backslash ]] && $(complete -p "$cmd") "\\$cmd" + return 0 + fi + done + done + + # Look up simple "xspec" completions + [[ -v _xspecs[$cmd] ]] && + complete -F _filedir_xspec "$cmd" "$backslash$cmd" && return 0 + + return 1 +} + +# set up dynamic completion loading +_completion_loader() +{ + # $1=_EmptycmD_ already for empty cmds in bash 4.3, set to it for earlier + local cmd="${1:-_EmptycmD_}" + + __load_completion "$cmd" && return 124 + + # Need to define *something*, otherwise there will be no completion at all. + complete -F _minimal -- "$cmd" && return 124 +} && + complete -D -F _completion_loader + +# Function for loading and calling functions from dynamically loaded +# completion files that may not have been sourced yet. +# @param $1 completion file to load function from in case it is missing +# @param $2... function and its arguments +_xfunc() +{ + set -- "$@" + local srcfile=$1 + shift + declare -F $1 &>/dev/null || __load_completion "$srcfile" + "$@" +} + +# source compat completion directory definitions +compat_dir=${BASH_COMPLETION_COMPAT_DIR:-/etc/bash_completion.d} +if [[ -d $compat_dir && -r $compat_dir && -x $compat_dir ]]; then + for i in "$compat_dir"/*; do + [[ ${i##*/} != @($_backup_glob|Makefile*|$_blacklist_glob) && -f \ + $i && -r $i ]] && . "$i" + done +fi +unset compat_dir i _blacklist_glob + +# source user completion file +user_completion=${BASH_COMPLETION_USER_FILE:-~/.bash_completion} +[[ ${BASH_SOURCE[0]} != "$user_completion" && -r $user_completion && -f $user_completion ]] && + . $user_completion +unset user_completion + +unset -f have +unset have + +set $BASH_COMPLETION_ORIGINAL_V_VALUE +unset BASH_COMPLETION_ORIGINAL_V_VALUE + +# ex: filetype=sh diff --git a/bash_completion.sh.in b/bash_completion.sh.in new file mode 100644 index 0000000..b2a527e --- /dev/null +++ b/bash_completion.sh.in @@ -0,0 +1,16 @@ +# shellcheck shell=sh disable=SC1091,SC2039,SC2166 +# Check for interactive bash and that we haven't already been sourced. +if [ "x${BASH_VERSION-}" != x -a "x${PS1-}" != x -a "x${BASH_COMPLETION_VERSINFO-}" = x ]; then + + # Check for recent enough version of bash. + if [ "${BASH_VERSINFO[0]}" -gt 4 ] || + [ "${BASH_VERSINFO[0]}" -eq 4 -a "${BASH_VERSINFO[1]}" -ge 2 ]; then + [ -r "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion" ] && + . "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion" + if shopt -q progcomp && [ -r @datadir@/@PACKAGE@/bash_completion ]; then + # Source completion code. + . @datadir@/@PACKAGE@/bash_completion + fi + fi + +fi diff --git a/completions/.gitignore b/completions/.gitignore new file mode 100644 index 0000000..5edc172 --- /dev/null +++ b/completions/.gitignore @@ -0,0 +1,235 @@ +7za +aclocal-1.1[0123456] +alpine +alternatives +animate +apropos +aptitude-curses +arm-koji +asciidoc.py +autoheader +automake-1.1[0123456] +autossh +autoupdate +bmake +bsdtar +btdownloadcurses.py +btdownloadgui.py +c++ +cc +cdrecord +chrome +chromium +ci +ciptool +civclient +civserver +clzip +co +colormake +compare +compgen +composite +conjure +cowthink +createdb +createuser +dcop +declare +dfutool +display +dpkg-deb +dpkg-query +dpkg-reconfigure +dropdb +dropuser +edquota +etherwake +f77 +f95 +filebucket +freeciv-gtk2 +freeciv-gtk3 +freeciv-sdl +freeciv-xaw +g++ +g++-[5678] +g4 +g77 +g95 +gcc-[5678] +gccgo +gccgo-[5678] +gcj +geoiplookup6 +gfortran +gfortran-[5678] +gkrellm2 +gmake +gmplayer +gnumake +google-chrome +google-chrome-stable +gpc +gpgv2 +gtar +hciattach +hciconfig +hd +host +hping +hping3 +iceweasel +identify +ifdown +ifquery +ifstatus +import +inotifywatch +insmod.static +iperf3 +javac +javadoc +kplayer +l2ping +lbzip2 +ldapadd +ldapcompare +ldapdelete +ldapmodify +ldapmodrdn +ldappasswd +ldapwhoami +links2 +lintian-info +lusermod +lvchange +lvcreate +lvdisplay +lvextend +lvmdiskscan +lvreduce +lvremove +lvrename +lvresize +lvs +lvscan +lz4c +mailsnarf +mdecrypt +mencoder +micropython +mkisofs +mogrify +montage +mozilla-firefox +mplayer2 +msgsnarf +muttng +ncal +pbzip2 +pccardctl +pdlzip +perldoc +phing +pigz +pinfo +ping6 +pkg_deinstall +pkg_info +pkill +plzip +pm-suspend +pm-suspend-hybrid +pmake +postalias +ppc-koji +puppetca +puppetd +puppetdoc +puppetmasterd +puppetqd +puppetrun +pvchange +pvcreate +pvdisplay +pvmove +pvremove +pvs +pvscan +pxz +py.test +py.test-[23] +pydoc3 +pylint-[23] +pytest-[23] +python2 +python2.7 +python3 +python3.[345678] +pypy +pypy3 +pyvenv-3.[45678] +qemu-kvm +qemu-system-i386 +qemu-system-x86_64 +quotacheck +quotaoff +quotaon +ralsh +rcsdiff +rdict +repquota +rfcomm +rlog +rpm2targz +rpm2txz +rpmbuild +rpmbuild-md5 +s390-koji +sbcl-mt +scp +sdptool +setquota +sftp +sidedoor +slogin +smbcacls +smbcquotas +smbget +smbpasswd +smbtar +smbtree +sparc-koji +spovray +star +stream +sudoedit +tightvncviewer +tracepath6 +typeset +vgcfgbackup +vgcfgrestore +vgchange +vgck +vgconvert +vgcreate +vgdisplay +vgexport +vgextend +vgimport +vgmerge +vgmknodes +vgreduce +vgremove +vgrename +vgs +vgscan +vgsplit +vigr +whatis +wine-development +wine-stable +xpovray +xvnc4viewer +ypcat diff --git a/completions/2to3 b/completions/2to3 new file mode 100644 index 0000000..7c5b330 --- /dev/null +++ b/completions/2to3 @@ -0,0 +1,39 @@ +# bash completion for 2to3 -*- shell-script -*- + +_2to3() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -h | --help | --add-suffix) + return + ;; + -f | --fix | -x | --nofix) + COMPREPLY=($(compgen -W \ + "$($1 --list-fixes 2>/dev/null | command sed -e 1d)" -- "$cur")) + return + ;; + -j | --processes) + COMPREPLY=($(compgen -W "{1..$(_ncpus)}" -- "$cur")) + return + ;; + -o | --output-dir) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir py +} && + complete -F _2to3 2to3 + +# ex: filetype=sh diff --git a/completions/7z b/completions/7z new file mode 100644 index 0000000..a8acbc5 --- /dev/null +++ b/completions/7z @@ -0,0 +1,128 @@ +# 7z(1) completion -*- shell-script -*- + +_7z() +{ + local cur prev words cword + _init_completion -n = || return + + if ((cword == 1)); then + COMPREPLY=($(compgen -W 'a b d e l t u x' -- "$cur")) + return + fi + + local mode + [[ ${words[1]} == [adu] ]] && mode=w || mode=r + + case $cur in + -ao*) + COMPREPLY=($(compgen -P${cur:0:3} -W 'a s t u' -- "${cur:3}")) + return + ;; + -?(a)[ix]*) + local opt + if [[ $cur == -a[ix]* ]]; then + opt=${cur:0:3} cur=${cur:3} + else + opt=${cur:0:2} cur=${cur:2} + fi + if [[ $cur != *[@\!]* ]]; then + COMPREPLY=($(compgen -P$opt -W '@ ! r@ r-@ r0@ r! r-! r0!' \ + -- "$cur")) + elif [[ $cur == ?(r@(-|0|))@* ]]; then + local IFS=$' \t\n' reset=$(shopt -po noglob) + set -o noglob + COMPREPLY=($(compgen -P"${opt}${cur%%@*}@" -f -- "${cur#*@}")) + $reset + compopt -o filenames + fi + return + ;; + -mhe=* | -mhc=* | -ms=* | -mt=*) + COMPREPLY=($(compgen -W 'on off' -- "${cur#*=}")) + return + ;; + -mx=*) + COMPREPLY=($(compgen -W '0 1 3 5 7 9' -- "${cur#*=}")) + return + ;; + -o* | -w?*) + local reset=$(shopt -po noglob) + set -o noglob + compopt -o filenames + local ifs=$IFS IFS=$'\n' + COMPREPLY=($(compgen -d -P${cur:0:2} -S/ -- "${cur:2}")) + IFS=$ifs + $reset + compopt -o nospace + return + ;; + -r?*) + COMPREPLY=($(compgen -P${cur:0:2} -W '- 0' -- "${cur:2}")) + return + ;; + -scs*) + COMPREPLY=($(compgen -P${cur:0:4} -W 'UTF-8 WIN DOS' \ + -- "${cur:4}")) + return + ;; + -ssc?*) + COMPREPLY=($(compgen -P${cur:0:4} -W '-' -- "${cur:4}")) + return + ;; + -t*) + if [[ $mode == w ]]; then + COMPREPLY=($(compgen -P${cur:0:2} -W '7z bzip2 gzip swfc + tar wim xz zip' -- "${cur:2}")) + else + COMPREPLY=($(compgen -P${cur:0:2} -W '7z apm arj bzip2 cab + chm cpio cramfs deb dmg elf fat flv gzip hfs iso lzh lzma + lzma86 macho mbr mslz mub nsis ntfs pe ppmd rar rpm + squashfs swf swfc tar udf vhd wim xar xz z zip' \ + -- "${cur:2}")) + fi + return + ;; + -m*=* | -p* | -u* | -v*) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-ai -an -ao -ax -bd -i -m{x,s,f,he,hc,mt}= + -o -p -r -scs -sfx -si -slp -slt -so -ssc -t -u -v -w -x -y' \ + -- "$cur")) + [[ ${COMPREPLY-} == -@(an|bd|sfx|si|slt|so|ssc|[rwy]) ]] || + compopt -o nospace + return + fi + + local args + _count_args = + if ((args == 2)); then + _filedir_xspec unzip + # TODO: parsing 7z i output? + # - how to figure out if the format is input or output? + # - find string Formats:, read until next empty line + # - extensions start from column 26 + # - ignore everything in parens + # - terminate on two spaces + # - terminate on token containing anything [^a-z0-9] + # (assumption: extensions are all lowercase) + [[ $mode == w ]] && + _filedir '@(7z|bz2|swf|?(g)tar|?(t)[bglx]z|tb?(z)2|wim)' || + _filedir '@(7z|arj|bz2|cab|chm|cpio|deb|dmg|flv|gem|img|iso|lz[ah]|lzma?(86)|msi|pmd|[rx]ar|rpm|sw[fm]|?(g)tar|taz|?(t)[bglx]z|tb?(z)2|vhd|wim|Z)' + else + if [[ ${words[1]} == d ]]; then + local IFS=$'\n' + COMPREPLY=($(compgen -W "$(printf '%s\n' "$($1 l ${words[2]} \ + -slt 2>/dev/null | command sed -n '/^Path =/s/^Path = \(.*\)$/\1/p' \ + 2>/dev/null | tail -n+2)")" -- "$cur")) + compopt -o filenames + else + _filedir + fi + fi +} && + complete -F _7z 7z 7za + +# ex: filetype=sh diff --git a/completions/Makefile.am b/completions/Makefile.am new file mode 100644 index 0000000..723b42f --- /dev/null +++ b/completions/Makefile.am @@ -0,0 +1,950 @@ +bashcompdir = $(datadir)/$(PACKAGE)/completions +bashcomp_DATA = 2to3 \ + 7z \ + a2x \ + abook \ + aclocal \ + acpi \ + _adb \ + add_members \ + alias \ + ant \ + apache2ctl \ + appdata-validate \ + apt-build \ + apt-cache \ + apt-get \ + aptitude \ + arch \ + arp \ + arping \ + arpspoof \ + asciidoc \ + aspell \ + autoconf \ + automake \ + autoreconf \ + autorpm \ + autoscan \ + avctrl \ + badblocks \ + bind \ + bk \ + brctl \ + btdownloadheadless.py \ + bts \ + bzip2 \ + _cal \ + cancel \ + cardctl \ + carton \ + ccache \ + ccze \ + cfagent \ + cfrun \ + chage \ + change_pw \ + check_db \ + check_perms \ + checksec \ + _chfn \ + chgrp \ + chkconfig \ + chmod \ + chown \ + chpasswd \ + chromium-browser \ + chronyc \ + chrpath \ + _chsh \ + cksfv \ + cleanarch \ + clisp \ + clone_member \ + complete \ + config_list \ + configure \ + convert \ + cowsay \ + cpan2dist \ + cpio \ + cppcheck \ + crontab \ + cryptsetup \ + curl \ + cvs \ + cvsps \ + dd \ + deja-dup \ + desktop-file-validate \ + dhclient \ + dict \ + _dmesg \ + dmypy \ + dnssec-keygen \ + dnsspoof \ + dot \ + dpkg \ + dpkg-source \ + dselect \ + dsniff \ + dumpdb \ + dumpe2fs \ + e2freefrag \ + e2label \ + ebtables \ + ecryptfs-migrate-home \ + _eject \ + eog \ + ether-wake \ + evince \ + explodepkg \ + export \ + faillog \ + fbgs \ + fbi \ + feh \ + file \ + file-roller \ + filefrag \ + filesnarf \ + find \ + find_member \ + fio \ + firefox \ + flake8 \ + freebsd-update \ + freeciv \ + freeciv-server \ + function \ + fusermount \ + gcc \ + gcl \ + gdb \ + genaliases \ + gendiff \ + genisoimage \ + geoiplookup \ + getconf \ + getent \ + gkrellm \ + gm \ + gnatmake \ + gnokii \ + gnome-mplayer \ + gnome-screenshot \ + gpasswd \ + gpg \ + gpg2 \ + gpgv \ + gphoto2 \ + gprof \ + groupadd \ + groupdel \ + groupmems \ + groupmod \ + growisofs \ + grpck \ + gssdp-discover \ + gzip \ + hcitool \ + hddtemp \ + _hexdump \ + hid2hci \ + hostname \ + hping2 \ + htop \ + htpasswd \ + hunspell \ + _hwclock \ + iconv \ + id \ + idn \ + ifstat \ + iftop \ + ifup \ + influx \ + info \ + inject \ + inotifywait \ + insmod \ + installpkg \ + interdiff \ + invoke-rc.d \ + _ionice \ + ip \ + ipcalc \ + iperf \ + ipmitool \ + ipsec \ + iptables \ + ipv6calc \ + iscsiadm \ + isort \ + isql \ + iwconfig \ + iwlist \ + iwpriv \ + iwspy \ + jar \ + jarsigner \ + java \ + javaws \ + jq \ + jpegoptim \ + jps \ + jshint \ + json_xs \ + jsonschema \ + k3b \ + kcov \ + kill \ + killall \ + kldload \ + kldunload \ + koji \ + ktutil \ + larch \ + lastlog \ + ldapsearch \ + ldapvi \ + lftp \ + lftpget \ + lilo \ + links \ + lintian \ + lisp \ + list_admins \ + list_lists \ + list_members \ + list_owners \ + _look \ + locale-gen \ + lpq \ + lpr \ + lrzip \ + lsof \ + lsscsi \ + lsusb \ + lua \ + luac \ + luseradd \ + luserdel \ + lvm \ + lz4 \ + lzip \ + lzma \ + lzop \ + macof \ + mailmanctl \ + make \ + makepkg \ + man \ + mc \ + mcrypt \ + mdadm \ + mdtool \ + medusa \ + mii-diag \ + mii-tool \ + minicom \ + mkinitrd \ + mktemp \ + mmsitepass \ + _mock \ + modinfo \ + modprobe \ + _modules \ + monodevelop \ + _mount \ + _mount.linux \ + mplayer \ + mr \ + msynctool \ + mtx \ + munindoc \ + munin-node-configure \ + munin-run \ + munin-update \ + mussh \ + mutt \ + mypy \ + mysql \ + mysqladmin \ + nc \ + ncftp \ + nethogs \ + _newgrp \ + newlist \ + newusers \ + ngrep \ + nmap \ + _nmcli \ + nproc \ + nslookup \ + nsupdate \ + ntpdate \ + oggdec \ + op \ + openssl \ + opera \ + optipng \ + p4 \ + pack200 \ + passwd \ + patch \ + pdftotext \ + perl \ + perlcritic \ + perltidy \ + pgrep \ + pidof \ + pine \ + ping \ + pkg-config \ + pkg-get \ + pkg_delete \ + pkgadd \ + pkgrm \ + pkgtool \ + pkgutil \ + plague-client \ + pm-hibernate \ + pm-is-supported \ + pm-powersave \ + pngfix \ + portinstall \ + portsnap \ + portupgrade \ + postcat \ + postconf \ + postfix \ + postmap \ + postsuper \ + povray \ + prelink \ + printenv \ + protoc \ + psql \ + puppet \ + pv \ + pwck \ + pwd \ + pwdx \ + pwgen \ + pycodestyle \ + pydoc \ + pydocstyle \ + pyflakes \ + pylint \ + pytest \ + python \ + pyvenv \ + qdbus \ + qemu \ + qrunner \ + querybts \ + quota \ + radvdump \ + rcs \ + rdesktop \ + remove_members \ + removepkg \ + _renice \ + _repomanage \ + reportbug \ + _reptyr \ + resolvconf \ + _rfkill \ + ri \ + rmlist \ + rmmod \ + route \ + rpcdebug \ + rpm \ + rpm2tgz \ + rpmcheck \ + rrdtool \ + rsync \ + _rtcwake \ + _runuser \ + sbcl \ + sbopkg \ + screen \ + scrub \ + secret-tool \ + sh \ + shellcheck \ + sitecopy \ + slackpkg \ + slapt-get \ + slapt-src \ + smartctl \ + smbclient \ + snownews \ + sqlite3 \ + ss \ + ssh \ + ssh-add \ + ssh-copy-id \ + ssh-keygen \ + sshfs \ + sshmitm \ + sshow \ + strace \ + strings \ + _su \ + sudo \ + svcadm \ + svk \ + _svn \ + _svnadmin \ + _svnlook \ + sync_members \ + synclient \ + sysbench \ + sysctl \ + tar \ + tcpdump \ + tcpkill \ + tcpnice \ + timeout \ + tipc \ + tox \ + tracepath \ + tshark \ + tsig-keygen \ + tune2fs \ + _udevadm \ + ulimit \ + _umount \ + _umount.linux \ + unace \ + unpack200 \ + unrar \ + unshunt \ + update-alternatives \ + update-rc.d \ + upgradepkg \ + urlsnarf \ + useradd \ + userdel \ + usermod \ + valgrind \ + vipw \ + vmstat \ + vncviewer \ + vpnc \ + watch \ + webmitm \ + wget \ + wine \ + withlist \ + wodim \ + wol \ + _write \ + wsimport \ + wtf \ + wvdial \ + xdg-mime \ + xdg-settings \ + xfreerdp \ + xgamma \ + xhost \ + _xm \ + xmllint \ + xmlwf \ + xmms \ + xmodmap \ + xrandr \ + xrdb \ + xsltproc \ + xvfb-run \ + xxd \ + xz \ + xzdec \ + ypmatch \ + _yum \ + yum-arch \ + zopfli \ + zopflipng + +EXTRA_DIST = $(bashcomp_DATA) + +CLEANFILES = \ + 7za \ + aclocal-1.10 \ + aclocal-1.11 \ + aclocal-1.12 \ + aclocal-1.13 \ + aclocal-1.14 \ + aclocal-1.15 \ + aclocal-1.16 \ + alpine \ + alternatives \ + animate \ + apropos \ + aptitude-curses \ + arm-koji \ + asciidoc.py \ + autoheader \ + automake-1.10 \ + automake-1.11 \ + automake-1.12 \ + automake-1.13 \ + automake-1.14 \ + automake-1.15 \ + automake-1.16 \ + autossh \ + autoupdate \ + bmake \ + bsdtar \ + btdownloadcurses.py \ + btdownloadgui.py \ + c++ \ + cc \ + cdrecord \ + chrome \ + chromium \ + ci \ + ciptool \ + civclient \ + civserver \ + clzip \ + co \ + colormake \ + compare \ + compgen \ + composite \ + conjure \ + cowthink \ + createdb \ + createuser \ + dcop \ + declare \ + dfutool \ + display \ + dpkg-deb \ + dpkg-query \ + dpkg-reconfigure \ + dropdb \ + dropuser \ + edquota \ + etherwake \ + f77 \ + f95 \ + filebucket \ + freeciv-gtk2 \ + freeciv-gtk3 \ + freeciv-sdl \ + freeciv-xaw \ + g++ \ + g++-5 \ + g++-6 \ + g++-7 \ + g++-8 \ + g4 \ + g77 \ + g95 \ + gcc-5 \ + gcc-6 \ + gcc-7 \ + gcc-8 \ + gccgo \ + gccgo-5 \ + gccgo-6 \ + gccgo-7 \ + gccgo-8 \ + gcj \ + geoiplookup6 \ + gfortran \ + gfortran-5 \ + gfortran-6 \ + gfortran-7 \ + gfortran-8 \ + gkrellm2 \ + gmake \ + gmplayer \ + gnumake \ + google-chrome \ + google-chrome-stable \ + gpc \ + gpgv2 \ + gtar \ + hciattach \ + hciconfig \ + hd \ + host \ + hping \ + hping3 \ + iceweasel \ + identify \ + ifdown \ + ifquery \ + ifstatus \ + import \ + inotifywatch \ + insmod.static \ + iperf3 \ + javac \ + javadoc \ + kplayer \ + l2ping \ + lbzip2 \ + ldapadd \ + ldapcompare \ + ldapdelete \ + ldapmodify \ + ldapmodrdn \ + ldappasswd \ + ldapwhoami \ + links2 \ + lintian-info \ + lusermod \ + lvchange \ + lvcreate \ + lvdisplay \ + lvextend \ + lvmdiskscan \ + lvreduce \ + lvremove \ + lvrename \ + lvresize \ + lvs \ + lvscan \ + lz4c \ + mailsnarf \ + mdecrypt \ + mencoder \ + micropython \ + mkisofs \ + mogrify \ + montage \ + mozilla-firefox \ + mplayer2 \ + msgsnarf \ + muttng \ + ncal \ + pbzip2 \ + pccardctl \ + pdlzip \ + perldoc \ + phing \ + pigz \ + pinfo \ + ping6 \ + pkg_deinstall \ + pkg_info \ + pkill \ + plzip \ + pm-suspend \ + pm-suspend-hybrid \ + pmake \ + postalias \ + ppc-koji \ + puppetca \ + puppetd \ + puppetdoc \ + puppetmasterd \ + puppetqd \ + puppetrun \ + pvchange \ + pvcreate \ + pvdisplay \ + pvmove \ + pvremove \ + pvs \ + pvscan \ + pxz \ + py.test \ + py.test-2 \ + py.test-3 \ + pydoc3 \ + pylint-2 \ + pylint-3 \ + pypy \ + pypy3 \ + pytest-2 \ + pytest-3 \ + python2 \ + python2.7 \ + python3 \ + python3.3 \ + python3.4 \ + python3.5 \ + python3.6 \ + python3.7 \ + python3.8 \ + pyvenv-3.4 \ + pyvenv-3.5 \ + pyvenv-3.6 \ + pyvenv-3.7 \ + pyvenv-3.8 \ + qemu-kvm \ + qemu-system-i386 \ + qemu-system-x86_64 \ + quotacheck \ + quotaoff \ + quotaon \ + ralsh \ + rcsdiff \ + rdict \ + repquota \ + rfcomm \ + rlog \ + rpm2targz \ + rpm2txz \ + rpmbuild \ + rpmbuild-md5 \ + s390-koji \ + sbcl-mt \ + scp \ + sdptool \ + setquota \ + sftp \ + sidedoor \ + slogin \ + smbcacls \ + smbcquotas \ + smbget \ + smbpasswd \ + smbtar \ + smbtree \ + sparc-koji \ + spovray \ + star \ + stream \ + sudoedit \ + tightvncviewer \ + tracepath6 \ + typeset \ + vgcfgbackup \ + vgcfgrestore \ + vgchange \ + vgck \ + vgconvert \ + vgcreate \ + vgdisplay \ + vgexport \ + vgextend \ + vgimport \ + vgmerge \ + vgmknodes \ + vgreduce \ + vgremove \ + vgrename \ + vgs \ + vgscan \ + vgsplit \ + vigr \ + whatis \ + xpovray \ + xvnc4viewer \ + ypcat + +symlinks: $(DATA) + $(ss) 7z \ + 7za + $(ss) aclocal \ + aclocal-1.10 aclocal-1.11 aclocal-1.12 aclocal-1.13 \ + aclocal-1.14 aclocal-1.15 aclocal-1.16 + $(ss) ant \ + phing + $(ss) aptitude \ + aptitude-curses + $(ss) asciidoc \ + asciidoc.py + $(ss) automake \ + automake-1.10 automake-1.11 automake-1.12 automake-1.13 \ + automake-1.14 automake-1.15 automake-1.16 + $(ss) autoreconf \ + autoheader + $(ss) autoscan \ + autoupdate + $(ss) btdownloadheadless.py \ + btdownloadcurses.py btdownloadgui.py + $(ss) bzip2 \ + lbzip2 pbzip2 + $(ss) _cal \ + ncal + $(ss) cardctl \ + pccardctl + $(ss) chromium-browser \ + chrome chromium google-chrome google-chrome-stable + $(ss) complete \ + compgen + $(ss) convert \ + animate compare composite conjure display identify import \ + mogrify montage stream + $(ss) cowsay \ + cowthink + $(ss) dict \ + rdict + $(ss) dpkg \ + dpkg-deb dpkg-query dpkg-reconfigure + $(ss) ether-wake \ + etherwake + $(ss) filesnarf \ + mailsnarf msgsnarf + $(ss) firefox \ + iceweasel mozilla-firefox + $(ss) freeciv \ + civclient freeciv-gtk2 freeciv-gtk3 freeciv-sdl freeciv-xaw + $(ss) freeciv-server \ + civserver + $(ss) function \ + declare typeset + $(ss) gcc \ + c++ cc f77 f95 g++ g++-5 g++-6 g++-7 g++-8 g77 g95 gcc-5 \ + gcc-6 gcc-7 gcc-8 gccgo gccgo-5 gccgo-6 gccgo-7 gccgo-8 gcj \ + gfortran gfortran-5 gfortran-6 gfortran-7 gfortran-8 gpc + $(ss) genisoimage \ + mkisofs + $(ss) geoiplookup \ + geoiplookup6 + $(ss) gkrellm \ + gkrellm2 + $(ss) gpgv \ + gpgv2 + $(ss) gzip \ + pigz + $(ss) hcitool \ + ciptool dfutool hciattach hciconfig l2ping rfcomm sdptool + $(ss) _hexdump \ + hd + $(ss) hping2 \ + hping hping3 + $(ss) ifup \ + ifdown ifquery ifstatus + $(ss) info \ + pinfo + $(ss) inotifywait \ + inotifywatch + $(ss) insmod \ + insmod.static + $(ss) iperf \ + iperf3 + $(ss) java \ + javac javadoc + $(ss) koji \ + arm-koji ppc-koji s390-koji sparc-koji + $(ss) ldapsearch \ + ldapadd ldapcompare ldapdelete ldapmodify ldapmodrdn \ + ldappasswd ldapwhoami + $(ss) links \ + links2 + $(ss) lintian \ + lintian-info + $(ss) luseradd \ + lusermod + $(ss) lvm \ + lvchange lvcreate lvdisplay lvextend lvmdiskscan lvreduce \ + lvremove lvrename lvresize lvs lvscan pvchange pvcreate \ + pvdisplay pvmove pvremove pvs pvscan vgcfgbackup vgcfgrestore \ + vgchange vgck vgconvert vgcreate vgdisplay vgexport vgextend \ + vgimport vgmerge vgmknodes vgreduce vgremove vgrename vgs \ + vgscan vgsplit + $(ss) lz4 \ + lz4c + $(ss) lzip \ + clzip pdlzip plzip + $(ss) make \ + bmake colormake gmake gnumake pmake + $(ss) man \ + apropos whatis + $(ss) mcrypt \ + mdecrypt + $(ss) mplayer \ + gmplayer kplayer mencoder mplayer2 + $(ss) mutt \ + muttng + $(ss) nslookup \ + host + $(ss) p4 \ + g4 + $(ss) perl \ + perldoc + $(ss) pine \ + alpine + $(ss) ping \ + ping6 + $(ss) pkg_delete \ + pkg_deinstall pkg_info + $(ss) pgrep \ + pkill + $(ss) pm-hibernate \ + pm-suspend pm-suspend-hybrid + $(ss) psql \ + createdb createuser dropdb dropuser + $(ss) postmap \ + postalias + $(ss) povray \ + spovray xpovray + $(ss) puppet \ + filebucket puppetca puppetd puppetdoc puppetmasterd puppetqd \ + puppetrun ralsh + $(ss) pytest \ + py.test py.test-2 py.test-3 pytest-2 pytest-3 + $(ss) pydoc \ + pydoc3 + $(ss) pylint \ + pylint-2 pylint-3 + $(ss) python \ + micropython pypy pypy3 python2 python2.7 python3 python3.3 python3.4 python3.5 python3.6 python3.7 python3.8 + $(ss) pyvenv \ + pyvenv-3.4 pyvenv-3.5 pyvenv-3.6 pyvenv-3.7 pyvenv-3.8 + $(ss) qdbus \ + dcop + $(ss) qemu \ + qemu-kvm qemu-system-i386 qemu-system-x86_64 + $(ss) quota \ + edquota quotacheck quotaoff quotaon repquota setquota + $(ss) rcs \ + ci co rcsdiff rlog + $(ss) rpm \ + rpmbuild rpmbuild-md5 + $(ss) rpm2tgz \ + rpm2targz rpm2txz + $(ss) smbclient \ + smbcacls smbcquotas smbget smbpasswd smbtar smbtree + $(ss) sbcl \ + sbcl-mt + $(ss) ssh \ + autossh scp sftp sidedoor slogin + $(ss) sudo \ + sudoedit + $(ss) tar \ + bsdtar gtar star + $(ss) tracepath \ + tracepath6 + $(ss) update-alternatives \ + alternatives + $(ss) vipw \ + vigr + $(ss) vncviewer \ + tightvncviewer xvnc4viewer + $(ss) wine \ + wine-development wine-stable + $(ss) wodim \ + cdrecord + $(ss) xz \ + pxz + $(ss) ypmatch \ + ypcat +.PHONY: symlinks + +SETUP_SYMLINKS = $(srcdir)/../setup-symlinks.sh + +all-local: ss = $(SETUP_SYMLINKS) . +all-local: symlinks + +install-data-hook: ss = $(SETUP_SYMLINKS) $(DESTDIR)$(bashcompdir) +install-data-hook: symlinks + +check-local: + ret=0; \ + for file in $(bashcomp_DATA); do \ + $${bashcomp_bash:-$${BASH:-bash}} \ + -O extglob -n $(srcdir)/$$file || ret=$$?; \ + done; \ + exit $$ret diff --git a/completions/_adb b/completions/_adb new file mode 100644 index 0000000..e8ebab1 --- /dev/null +++ b/completions/_adb @@ -0,0 +1,69 @@ +# adb completion -*- shell-script -*- + +# Use of this file is deprecated. Upstream completion is available in +# the Android SDK, use that instead. + +_adb_command_usage() +{ + COMPREPLY=($(compgen -W \ + '$("$1" help 2>&1 | command grep "^ *\(adb \)\? *$2 " \ + | command sed -e "s/[]|[]/\n/g" | _parse_help -)' -- "$cur")) +} + +_adb() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -s | -p | --algo | --key | --iv) + return + ;; + -f) + _filedir + return + ;; + esac + + local cmd i + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} != -* && ${words[i - 1]} != -[sp] ]]; then + cmd="${words[i]}" + break + fi + done + + if [[ ! -v cmd ]]; then + local tmp=() + if [[ ! $cur || $cur == -* ]]; then + tmp+=($(compgen -W '$(_parse_help "$1" help)' -- "$cur")) + fi + if [[ ! $cur || $cur != -* ]]; then + tmp+=($($1 help 2>&1 | awk '$1 == "adb" { print $2 }')) + tmp+=(devices connect disconnect sideload) + fi + COMPREPLY=($(compgen -W '${tmp[@]}' -- "$cur")) + return + fi + + # TODO: more and better command completions + + _adb_command_usage "$1" $cmd + + case $cmd in + push | restore | sideload) + _filedir + ;; + forward) + COMPREPLY=($(compgen -W \ + '$("$1" help 2>&1 | command sed -ne "s/^ *adb *forward *-/-/p" | \ + _parse_help -)' -- "$cur")) + ;; + reboot) + COMPREPLY=($(compgen -W 'bootloader recovery' -- "$cur")) + ;; + esac +} && + complete -F _adb adb + +# ex: filetype=sh diff --git a/completions/_cal b/completions/_cal new file mode 100644 index 0000000..1eec267 --- /dev/null +++ b/completions/_cal @@ -0,0 +1,38 @@ +# cal(1) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.23, use that instead. + +_cal() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -m) + if [[ $OSTYPE == *bsd* ]]; then + COMPREPLY=($(compgen -W '{1..12}' -- "$cur")) + return + fi + ;; + -s) + [[ $OSTYPE == *bsd* ]] && return + ;; + -A | -B | -d | -H) + return + ;; + esac + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + return + fi + + local args + _count_args + ((args == 1)) && COMPREPLY=($(compgen -W '{1..12}' -- "$cur")) +} && + complete -F _cal cal ncal + +# ex: filetype=sh diff --git a/completions/_chfn b/completions/_chfn new file mode 100644 index 0000000..334967f --- /dev/null +++ b/completions/_chfn @@ -0,0 +1,8 @@ +# chfn(1) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.23, use that instead. + +complete -u chfn + +# ex: filetype=sh diff --git a/completions/_chsh b/completions/_chsh new file mode 100644 index 0000000..8f8a807 --- /dev/null +++ b/completions/_chsh @@ -0,0 +1,31 @@ +# chsh(1) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.23, use that instead. + +_chsh() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --list-shells | --help | -v | --version) + return + ;; + -s | --shell) + _shells + return + ;; + esac + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + else + _allowed_users + fi + +} && + complete -F _chsh chsh + +# ex: filetype=sh diff --git a/completions/_dmesg b/completions/_dmesg new file mode 100644 index 0000000..8306654 --- /dev/null +++ b/completions/_dmesg @@ -0,0 +1,33 @@ +# dmesg(1) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.23, use that instead. + +_dmesg() +{ + [[ $OSTYPE == *solaris* ]] && return # no args there + + local cur prev words cword + _init_completion || return + + case $prev in + -h | --help | -V | --version | -s | --buffer-size | -M | -N) + return + ;; + -f | --facility) + COMPREPLY=($(compgen -W 'kern user mail daemon auth syslog lpr + news' -- "$cur")) + return + ;; + -l | --level | -n | --console-level) + COMPREPLY=($(compgen -W '{1..8}' -- "$cur")) + return + ;; + esac + + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) +} && + complete -F _dmesg dmesg + +# ex: filetype=sh diff --git a/completions/_eject b/completions/_eject new file mode 100644 index 0000000..52168f7 --- /dev/null +++ b/completions/_eject @@ -0,0 +1,33 @@ +# bash completion for eject(1) -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.23, use that instead. + +_eject() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h | --help | -V | --version | -c | --changerslot | -x | --cdspeed) + return + ;; + -a | --auto | -i | --manualeject) + COMPREPLY=($(compgen -W 'on off' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + elif [[ $prev == @(-d|--default) ]]; then + return + fi + + _cd_devices + _dvd_devices +} && + complete -F _eject eject + +# ex: filetype=sh diff --git a/completions/_hexdump b/completions/_hexdump new file mode 100644 index 0000000..785f597 --- /dev/null +++ b/completions/_hexdump @@ -0,0 +1,31 @@ +# hexdump(1) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.23, use that instead. + +_hexdump() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -V | -e | -n | -s) + return + ;; + -f) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + local opts="$(_parse_help "$1")" + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + return + fi + + _filedir +} && + complete -F _hexdump hexdump hd + +# ex: filetype=sh diff --git a/completions/_hwclock b/completions/_hwclock new file mode 100644 index 0000000..ef437a2 --- /dev/null +++ b/completions/_hwclock @@ -0,0 +1,26 @@ +# hwclock(8) completion -*- shell-script -*- + +# Use of this file is deprecated. Upstream completion is available in +# util-linux >= 2.23, use that instead. + +_hwclock() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h | --help | -V | --version | --date | --epoch) + return + ;; + -f | --rtc | --adjfile) + _filedir + return + ;; + esac + + COMPREPLY=( + $(PATH="$PATH:/sbin" compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _hwclock hwclock + +# ex: filetype=sh diff --git a/completions/_ionice b/completions/_ionice new file mode 100644 index 0000000..b0d96a1 --- /dev/null +++ b/completions/_ionice @@ -0,0 +1,60 @@ +# ionice(1) completion -*- shell-script -*- + +# Use of this file is deprecated. Upstream completion is available in +# util-linux >= 2.23, use that instead. + +_ionice() +{ + local cur prev words cword + _init_completion || return + + local offset=0 i + for ((i = 1; i <= cword; i++)); do + case ${words[i]} in + -h) + return + ;; + -p) + offset=0 + break + ;; + -c | -n) + ((i++)) + continue + ;; + -*) + continue + ;; + esac + offset=$i + break + done + + if ((offset > 0)); then + _command_offset $offset + return + fi + + case $prev in + -c) + COMPREPLY=($(compgen -W '{0..3}' -- "$cur")) + return + ;; + -n) + COMPREPLY=($(compgen -W '{0..7}' -- "$cur")) + return + ;; + -p) + _pids + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + return + fi +} && + complete -F _ionice ionice + +# ex: filetype=sh diff --git a/completions/_look b/completions/_look new file mode 100644 index 0000000..9788dec --- /dev/null +++ b/completions/_look @@ -0,0 +1,17 @@ +# look(1) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.23, use that instead. + +_look() +{ + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + COMPREPLY=($(compgen -W '$(look "$cur" 2>/dev/null)' -- "$cur")) + fi +} && + complete -F _look -o default look + +# ex: filetype=sh diff --git a/completions/_mock b/completions/_mock new file mode 100644 index 0000000..b468148 --- /dev/null +++ b/completions/_mock @@ -0,0 +1,69 @@ +# bash completion for mock -*- shell-script -*- + +# Use of this file is deprecated. Upstream completion is available in +# mock > 1.1.0, use that instead. + +_mock() +{ + local cur prev words cword split + _init_completion -s || return + + local plugins='tmpfs root_cache yum_cache bind_mount ccache' + local cfgdir=/etc/mock count=0 i + + for i in "${words[@]}"; do + ((count == cword)) && break + if [[ $i == --configdir ]]; then + cfgdir="${words[count + 1]}" + elif [[ $i == --configdir=* ]]; then + cfgdir=${i/*=/} + fi + ((count++)) + done + + case $prev in + -h | --help | --copyin | --copyout | --arch | -D | --define | --with | --without | \ + --uniqueext | --rpmbuild_timeout | --sources | --cwd) + return + ;; + -r | --root) + COMPREPLY=($(compgen -W "$(command ls $cfgdir)" -- "$cur")) + COMPREPLY=(${COMPREPLY[@]/%.cfg/}) + return + ;; + --configdir | --resultdir) + _filedir -d + return + ;; + --spec) + _filedir spec + return + ;; + --target) + # Yep, compatible archs, not compatible build archs + # (e.g. ix86 chroot builds in x86_64 mock host) + # This would actually depend on what the target root + # can be used to build for... + COMPREPLY=($(compgen -W "$(command rpm --showrc | + command sed -ne 's/^\s*compatible\s\s*archs\s*:\s*\(.*\)/\1/i p')" \ + -- "$cur")) + return + ;; + --enable-plugin | --disable-plugin) + COMPREPLY=($(compgen -W "$plugins" -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _filedir '@(?(no)src.r|s)pm' + fi +} && + complete -F _mock mock + +# ex: filetype=sh diff --git a/completions/_modules b/completions/_modules new file mode 100644 index 0000000..4f7c4d4 --- /dev/null +++ b/completions/_modules @@ -0,0 +1,85 @@ +# module completion by Ted Stern <stern@cray.com> -*- shell-script -*- +# +# Use of this file is deprecated, upstream completion is available in +# modules >= 3.2.7, use that instead. +# +# Completion for Environment Modules `module' alias. +# +# See https://sourceforge.net/projects/modules/ +# https://modules.sourceforge.net/ +# +# There are several versions of modules that are commonly used. Older +# Cray UNICOS systems and many other sites use 2.2.2b. The latest GPL'd +# version is 3.1.6. But the module alias is somewhat self-documenting +# via the `module help' command, so use that to print the options. +# +# Programmable completion might be more difficult under tcsh since the +# module command is an alias, and the `module avail' command returns +# its output as stderr. + +# Test for existence of /etc/profile.d/modules.sh too because we may end up +# being sourced before it and thus before the `module' alias has been defined. +[ -f /etc/profile.d/modules.sh ] || return 1 + +_module_list() +{ + local modules="$(command sed 's/:/ /g' <<<$LOADEDMODULES | sort)" + compgen -W "$modules" -- $1 +} + +_module_path() +{ + local modules="$(command sed 's/:/ /g' <<<$MODULEPATH | sort)" + compgen -W "$modules" -- $1 +} + +_module_avail() +{ + local modules="$( + module avail 2>&1 | + command grep -E -v '^(-|$)' | + xargs printf '%s\n' | command sed -e 's/(default)//g' | sort + )" + + compgen -W "$modules" -- $1 +} + +# A completion function for the module alias +_module() +{ + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + # First parameter on line -- we expect it to be a mode selection + + local options + options="$(module help 2>&1 | command grep -E '^[[:space:]]*\+' | + awk '{print $2}' | command sed -e 's/|/ /g' | sort)" + + COMPREPLY=($(compgen -W "$options" -- "$cur")) + + elif ((cword == 2)); then + case $prev in + add | display | help | load | show | whatis) + COMPREPLY=($(_module_avail "$cur")) + ;; + rm | switch | swap | unload | update) + COMPREPLY=($(_module_list "$cur")) + ;; + unuse) + COMPREPLY=($(_module_path "$cur")) + ;; + esac + elif ((cword == 3)); then + case ${words[1]} in + swap | switch) + COMPREPLY=($(_module_avail "$cur")) + ;; + esac + fi + +} && + complete -F _module -o default module + +# ex: filetype=sh diff --git a/completions/_mount b/completions/_mount new file mode 100644 index 0000000..85f5490 --- /dev/null +++ b/completions/_mount @@ -0,0 +1,65 @@ +# mount(8) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.28, use that instead. + +if [[ $OSTYPE == *linux* ]]; then + . "$BASH_SOURCE.linux" + return +fi + +# This will pull a list of possible mounts out of +# /etc/{,v}fstab, unless the word being completed contains a ':', which +# would indicate the specification of an NFS server. In that case, we +# query the server for a list of all available exports and complete on +# that instead. +# +_mount() +{ + local cur prev words cword + _init_completion -n : || return + + local sm host + + case $prev in + -t | --types) + _fstypes + return + ;; + esac + + [[ $cur == \\ ]] && cur="/" + + if [[ $cur == *:* ]]; then + for sm in "$(type -P showmount)" {,/usr}/{,s}bin/showmount; do + [[ -x $sm ]] || continue + COMPREPLY=($(compgen -W "$("$sm" -e ${cur%%:*} | + awk 'NR>1 {print $1}')" -- "${cur#*:}")) + return + done + fi + + if [[ $cur == //* ]]; then + host=${cur#//} + host=${host%%/*} + if [[ -n $host ]]; then + COMPREPLY=($(compgen -P "//$host" -W \ + "$(smbclient -d 0 -NL $host 2>/dev/null | + command sed -ne '/^[[:blank:]]*Sharename/,/^$/p' | + command sed -ne '3,$s|^[^A-Za-z]*\([^[:blank:]]*\).*$|/\1|p')" \ + -- "${cur#//$host}")) + fi + elif [[ -r /etc/vfstab ]]; then + # Solaris + COMPREPLY=($(compgen -W "$(awk '! /^[ \t]*#/ {if ($3 ~ /\//) print $3}' /etc/vfstab)" -- "$cur")) + elif [[ ! -e /etc/fstab ]]; then + # probably Cygwin + COMPREPLY=($(compgen -W "$($1 | awk '! /^[ \t]*#/ {if ($3 ~ /\//) print $3}')" -- "$cur")) + else + # probably BSD + COMPREPLY=($(compgen -W "$(awk '! /^[ \t]*#/ {if ($2 ~ /\//) print $2}' /etc/fstab)" -- "$cur")) + fi +} && + complete -F _mount -o default -o dirnames mount + +# ex: filetype=sh diff --git a/completions/_mount.linux b/completions/_mount.linux new file mode 100644 index 0000000..f40865e --- /dev/null +++ b/completions/_mount.linux @@ -0,0 +1,252 @@ +# mount(8) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.28, use that instead. + +_mount() +{ + local cur prev words cword + _init_completion -n =: || return + + local split=false + case "$prev" in + -t | --types) + # find /lib/modules/$(uname -r)/ -type f -path '*/fs/*.ko' -printf '%f\n' | cut -d. -f1 + # FIXME: no<fstype> + if [[ $cur == ?*,* ]]; then + prev="${cur%,*}" + cur="${cur##*,}" + split=true + fi + COMPREPLY=($(compgen -W 'auto adfs affs autofs btrfs cifs coda + cramfs davfs debugfs devpts efs ext2 ext3 ext4 fuse hfs hfsplus + hpfs iso9660 jffs2 jfs minix msdos ncpfs nfs nfs4 ntfs ntfs-3g + proc qnx4 ramfs reiserfs romfs squashfs smbfs sysv tmpfs ubifs + udf ufs umsdos usbfs vfat xfs' -- "$cur")) + _fstypes + $split && COMPREPLY=(${COMPREPLY[@]/#/$prev,}) + return + ;; + --bind | -B | --rbind | -R) + _filedir -d + return + ;; + -p | --pass-fd) + COMPREPLY=($(compgen -W '{0..9}')) + compopt -o nospace + return + ;; + -L) + COMPREPLY=($( + cd "/dev/disk/by-label/" 2>/dev/null || return + compgen -f -- "$cur" + )) + return + ;; + -U) + COMPREPLY=($( + cd "/dev/disk/by-uuid/" 2>/dev/null || return + compgen -f -- "$cur" + )) + return + ;; + -O | --test-opts) + # argument required but no completions available + return + ;; + -o | --options) + local fstype=auto # default fstype + for ((i = ${#words[@]} - 1; i > 0; i--)); do + if [[ ${words[i]} == -@(t|-types)* ]]; then + if [[ ${words[i]} == *=* ]]; then + [[ ${words[i]} == ?*,* ]] && break + fstype="${words[i]#-*=}" + else + [[ ${words[i + 1]} == ?*,* ]] && break + fstype="${words[i + 1]}" + fi + break + fi + done + # no<fstype> is not a real fstype, reset to "auto" + [[ $fstype == no?* ]] && fstype=auto + # split options list + if [[ $cur == ?*,* ]]; then + prev="${cur%,*}" + cur="${cur##*,}" + split=true + fi + # no completion if $cur is opt=smth + [[ $cur == *=* ]] && return + # mount options + COMPREPLY=($(compgen -W 'loop {,a}sync {,no}atime {,no}auto + {,fs,def,root}context= defaults {,no}dev {,no}diratime dirsync + {,no}exec group {,no}iversion {,no}mand _netdev nofail + {,no}relatime {,no}strictatime {,no}suid owner remount ro rw + {,no}user users' -- "$cur")) + case "$fstype" in + adfs | auto) + COMPREPLY+=($(compgen -W '{u,g}id= {own,oth}mask=' -- "$cur")) + ;;& + affs | auto) + COMPREPLY+=($(compgen -W '{u,g}id= set{u,g}id= mode= protect + usemp verbose prefix= volume= reserved= root= bs= + {,no,usr,grp}quota' -- "$cur")) + ;;& + btrfs | auto) + COMPREPLY+=($(compgen -W 'degraded subvol= subvolid= device= + nodatasum nodatacow nobarrier max_inline= alloc_start= + thread_pool= compress= compress-force= ssd noacl notreelog + flushoncommit metadata_ratio= {,no}space_cache clear_cache + user_subvol_rm_allowed autodefrag inode_cache' -- "$cur")) + ;;& + cifs | auto) + COMPREPLY+=($(compgen -W 'user= password= credentials= {u,g}id= + force{u,g}id port= servern= netbiosname= {file,dir}_mode= + ip= domain= guest iocharset {,no}setuids {,no,dyn}perm + directio {,no}mapchars {,no}intr hard soft noacl nocase sec= + nobrl sfu {,no}serverino nounix nouser_xattr {r,w}size= + rwpidforward backup{u,g}id cache=' -- "$cur")) + ;;& + davfs | auto) + COMPREPLY+=($(compgen -W 'conf= {file,dir}_mode= {u,g}id= + username=' -- "$cur")) + ;;& + ext[2-4] | auto) + COMPREPLY+=($(compgen -W '{,no}acl bsddf minixdf check= debug + errors= {,no}grpid {bsd,sysv}groups {,no,usr,grp}quota + nobh nouid32 oldalloc orlov res{u,g}id= sb= + {,no}user_xattr' -- "$cur")) + ;;& + ext[34] | auto) + COMPREPLY+=($(compgen -W 'journal= journal_dev= norecovery + noload data= barrier= commit=' -- "$cur")) + ;;& + ext4 | auto) + COMPREPLY+=($(compgen -W 'journal_checksum journal_async_commit + nobarrier inode_readahead= stripe= {,no}delalloc abort + {max,min}_batch_time= journal_ioprio= {,no}auto_da_alloc + {,no}discard nouid32 resize {,no}block_validity + dioread_{,no}lock max_dir_size_kb= i_version' -- "$cur")) + ;;& + msdos | umsdos | vfat | auto) + COMPREPLY+=($(compgen -W 'blocksize= {u,g}id= {u,d,f}mask= + allow_utime= check= codepage= conv= cvf_format= cvf_option= + debug fat= iocharset= tz= quiet showexec sys_immutable flush + usefree {,no}dots dotsOK=' -- "$cur")) + ;;& + vfat | auto) + COMPREPLY+=($(compgen -W 'uni_xlate posix nonumtail utf8 + shortname=' -- "$cur")) + ;;& + iso9660 | auto) + COMPREPLY+=($(compgen -W 'norock nojoliet check= {u,g}id= map= + mode= unhide block= conv= cruft session= sbsector= + iocharset= utf8' -- "$cur")) + ;;& + jffs2 | auto) + COMPREPLY+=($(compgen -W 'compr= rp_size=' -- "$cur")) + ;;& + jfs | auto) + COMPREPLY+=($(compgen -W 'iocharset= resize= {,no}integrity + errors= {,no,usr,grp}quota' -- "$cur")) + ;;& + nfs | nfs4 | auto) + COMPREPLY+=($(compgen -W 'soft hard timeo= retrans= {r,w}size= + {,no}ac acreg{min,max}= acdir{min,max}= actimeo= bg fg + retry= sec= {,no}sharecache {,no}resvport lookupcache= + proto= port= {,no}intr {,no}cto {,nfs}vers= ' -- "$cur")) + ;;& + nfs | auto) + COMPREPLY+=($(compgen -W 'udp tcp rdma mount{port,proto,host}= + mountvers= namlen={,no}lock {,no}acl {,no}rdirplus + {,no}fsc' -- "$cur")) + ;;& + nfs4 | auto) + COMPREPLY+=($(compgen -W 'clientaddr= {,no}migration' \ + -- "$cur")) + ;;& + ntfs-3g) + COMPREPLY+=($(compgen -W '{u,g}id= {u,f,d}mask= usermapping= + permissions inherit locale= force {,no}recover + ignore_case remove_hiberfile show_sys_files + hide_{hid,dot}_files windows_names allow_other max_read= + silent no_def_opts streams_interface= user_xattr efs_raw + {,no}compression debug no_detach' -- "$cur")) + ;;& + proc | auto) + COMPREPLY+=($(compgen -W '{u,g}id=' -- "$cur")) + ;;& + reiserfs | auto) + COMPREPLY+=($(compgen -W 'conv hash= {,no_un}hashed_relocation + noborder nolog notail replayonly resize= user_xattr acl + barrier=' -- "$cur")) + ;;& + tmpfs | auto) + COMPREPLY+=($(compgen -W 'size= nr_blocks= nr_inodes= mode= + {u,g}id= mpol=' -- "$cur")) + ;;& + udf | auto) + COMPREPLY+=($(compgen -W '{u,g}id= umask= unhide undelete + nostrict iocharset bs= novrs session= anchor= volume= + partition= lastblock= fileset= rootdir=' -- "$cur")) + ;;& + usbfs | auto) + COMPREPLY+=($(compgen -W 'dev{u,g}id= devmode= bus{u,g}id= + busmode= list{u,g}id= listmode=' -- "$cur")) + ;;& + xfs | auto) + COMPREPLY+=($(compgen -W 'allocsize= {,no}attr2 barrier dmapi + {,no}grpid {bsd,sysv}groups ihashsize= {,no}ikeep + inode{32,64} {,no}largeio logbufs= logbsize= logdev= + rtdev= mtpt= noalign norecovery nouuid osyncisosync + {u,g,p}qnoenforce {,u,usr,g,grp,p,prj}quota sunit= swidth= + swalloc' -- "$cur")) + ;;& + esac + # COMP_WORDBREAKS is a real pain in the ass + prev="${prev##*[$COMP_WORDBREAKS]}" + $split && COMPREPLY=(${COMPREPLY[@]/#/"$prev,"}) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--version --help --verbose --all --fork + --fake --internal-only -l --no-mtab --no-canonicalize --pass-fd -s + --read-only --rw -L -U --types --test-opts --options --bind --rbind + --move' -- "$cur")) + [[ ${COMPREPLY-} ]] && return + fi + + [[ $cur == \\ ]] && cur="/" + + local sm host + + if [[ $cur == *:* ]]; then + for sm in "$(type -P showmount)" {,/usr}/{,s}bin/showmount; do + [[ -x $sm ]] || continue + COMPREPLY=($(compgen -W "$("$sm" -e ${cur%%:*} | + awk 'NR>1 {print $1}')" -- "${cur#*:}")) + return + done + fi + + if [[ $cur == //* ]]; then + host=${cur#//} + host=${host%%/*} + if [[ -n $host ]]; then + COMPREPLY=($(compgen -P "//$host" -W \ + "$(smbclient -d 0 -NL $host 2>/dev/null | + command sed -ne '/^[[:blank:]]*Sharename/,/^$/p' | + command sed -ne '3,$s|^[^A-Za-z]*\([^[:blank:]]*\).*$|/\1|p')" \ + -- "${cur#//$host}")) + fi + fi + + _filedir +} && + complete -F _mount mount + +# ex: filetype=sh diff --git a/completions/_newgrp b/completions/_newgrp new file mode 100644 index 0000000..a2dc3ed --- /dev/null +++ b/completions/_newgrp @@ -0,0 +1,19 @@ +# newgrp(1) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.23, use that instead. + +_newgrp() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == "-" ]]; then + COMPREPLY=(-) + else + _allowed_groups "$cur" + fi +} && + complete -F _newgrp newgrp + +# ex: filetype=sh diff --git a/completions/_nmcli b/completions/_nmcli new file mode 100644 index 0000000..eac285b --- /dev/null +++ b/completions/_nmcli @@ -0,0 +1,201 @@ +# nmcli completion -*- shell-script -*- + +# Use of this file is deprecated. Upstream completion is available in +# NetworkManager >= 0.9.8.0, use that instead. + +_nmcli_list() +{ + COMPREPLY=($(compgen -W '$1' -- "$cur")) +} + +_nmcli_con_id() +{ + local IFS=$'\n' + COMPREPLY=($(compgen -W "$(nmcli con list 2>/dev/null | + tail -n +2 | awk -F ' {2,}' '{print $1 }')" -- "$cur")) +} + +_nmcli_con_uuid() +{ + COMPREPLY=($(compgen -W "$(nmcli con list 2>/dev/null | + tail -n +2 | awk -F ' {2,}' '{print $2}')" -- "$cur")) +} + +_nmcli_ap_ssid() +{ + local IFS=$'\n' + COMPREPLY=($(compgen -W "$(nmcli dev wifi list 2>/dev/null | + tail -n +2 | awk -F ' {2,}' '{print $1}')" -- "$cur")) +} + +_nmcli_ab_bssid() +{ + COMPREPLY=($(compgen -W "$(nmcli dev wifi list 2>/dev/null | + tail -n +2 | awk -F ' {2,}' '{print $2}')" -- "$cur")) +} + +_nmcli() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -m | --mode) + COMPREPLY=($(compgen -W 'tabular multiline' -- "$cur")) + return + ;; + -f | --fields) + COMPREPLY=($(compgen -W 'all common' -- "$cur")) + return + ;; + -e | --escape) + _nmcli_list "yes no" + return + ;; + id) + _nmcli_con_id + return + ;; + uuid) + _nmcli_con_uuid + return + ;; + iface) + _available_interfaces + return + ;; + bssid) + _nmcli_ab_bssid + return + ;; + wep-key-type) + _nmcli_list "key phrase" + return + ;; + esac + + if ((cword == 1)); then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--terse --pretty --mode --fields + --escape --version --help' -- "$cur")) + else + COMPREPLY=($(compgen -W "nm con dev" -- "$cur")) + fi + else + local object=${words[1]} + local command=${words[2]} + + case $object in + nm) + case $command in + enable) + _nmcli_list "true false" + return + ;; + sleep) + _nmcli_list "true false" + return + ;; + wifi) + _nmcli_list "on off" + return + ;; + wwan) + _nmcli_list "on off" + return + ;; + wimax) + _nmcli_list "on off" + return + ;; + esac + + COMPREPLY=($(compgen -W 'status permissions enable sleep + wifi wwan wimax' -- "$cur")) + ;; + con) + case $command in + list) + COMPREPLY=($(compgen -W 'id uuid' -- "$cur")) + return + ;; + up) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--nowait --timeout' \ + -- "$cur")) + else + COMPREPLY=($(compgen -W 'id uuid iface ap nsp' \ + -- "$cur")) + fi + return + ;; + down) + COMPREPLY=($(compgen -W 'id uuid' -- "$cur")) + return + ;; + delete) + COMPREPLY=($(compgen -W 'id uuid' -- "$cur")) + return + ;; + esac + + COMPREPLY=($(compgen -W 'list status up down delete' \ + -- "$cur")) + ;; + dev) + case $command in + list) + COMPREPLY=($(compgen -W 'iface' -- "$cur")) + return + ;; + disconnect) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--nowait --timeout' \ + -- "$cur")) + else + COMPREPLY=($(compgen -W 'iface' -- "$cur")) + fi + return + ;; + wifi) + local subcommand=${words[3]} + + case $subcommand in + list) + COMPREPLY=($(compgen -W 'iface bssid' \ + -- "$cur")) + return + ;; + connect) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--private + --nowait --timeout' -- "$cur")) + else + if [[ $prev == "connect" ]]; then + _nmcli_ap_ssid + else + COMPREPLY=($(compgen -W 'password + wep-key-type iface bssid name' \ + -- "$cur")) + fi + fi + return + ;; + esac + + COMPREPLY=($(compgen -W 'list connect' -- "$cur")) + return + ;; + esac + + COMPREPLY=($(compgen -W 'status list disconnect wifi' \ + -- "$cur")) + ;; + esac + + fi + +} && + complete -F _nmcli nmcli + +# ex: filetype=sh diff --git a/completions/_renice b/completions/_renice new file mode 100644 index 0000000..a416744 --- /dev/null +++ b/completions/_renice @@ -0,0 +1,32 @@ +# renice(8) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.23, use that instead. + +_renice() +{ + local cur prev words cword + _init_completion || return + + local command=$1 curopt i=0 + + # walk back through command line and find last option + while ((i <= cword && ${#COMPREPLY[@]} == 0)); do + curopt=${words[cword - i]} + case "$curopt" in + -u) + _allowed_users + ;; + -g) + _pgids + ;; + -p | "$command") + _pids + ;; + esac + ((i++)) + done +} && + complete -F _renice renice + +# ex: filetype=sh diff --git a/completions/_repomanage b/completions/_repomanage new file mode 100644 index 0000000..ba0787e --- /dev/null +++ b/completions/_repomanage @@ -0,0 +1,24 @@ +# bash completion for repomanage -*- shell-script -*- + +# Use of this file is deprecated. Upstream completion is available in +# yum-utils >= 1.1.24, use that instead. + +_repomanage() +{ + local cur prev words cword split + _init_completion -s || return + + [[ $prev == -@([hk]|-help|-keep) ]] && return + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _filedir -d + fi +} && + complete -F _repomanage repomanage + +# ex: filetype=sh diff --git a/completions/_reptyr b/completions/_reptyr new file mode 100644 index 0000000..01d61b2 --- /dev/null +++ b/completions/_reptyr @@ -0,0 +1,26 @@ +# bash completion for reptyr(1) -*- shell-script -*- + +# Use of this file is deprecated. Upstream completion is available in +# reptyr > 0.6.2, use that instead. + +_reptyr() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -l) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + [[ $prev != +([0-9]) ]] && _pids +} && + complete -F _reptyr reptyr + +# ex: filetype=sh diff --git a/completions/_rfkill b/completions/_rfkill new file mode 100644 index 0000000..96a6c09 --- /dev/null +++ b/completions/_rfkill @@ -0,0 +1,31 @@ +# bash completion for rfkill -*- shell-script -*- + +# Use of this file is deprecated on systems with util-linux >= 2.31, which +# ships completion for the rfkill included with it. + +_rfkill() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--version' -- "$cur")) + else + case $cword in + 1) + COMPREPLY=($(compgen -W "help event list block unblock" \ + -- "$cur")) + ;; + 2) + if [[ $prev == block || $prev == unblock ]]; then + COMPREPLY=($(compgen -W "$($1 list | awk -F: \ + '/^[0-9]/ {print $1}') all wifi bluetooth uwb wimax \ + wwan gps" -- "$cur")) + fi + ;; + esac + fi +} && + complete -F _rfkill rfkill + +# ex: filetype=sh diff --git a/completions/_rtcwake b/completions/_rtcwake new file mode 100644 index 0000000..4ca452d --- /dev/null +++ b/completions/_rtcwake @@ -0,0 +1,32 @@ +# bash completion for rtcwake -*- shell-script -*- + +# Use of this file is deprecated. Upstream completion is available in +# util-linux >= 2.23, use that instead. + +_rtcwake() +{ + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + --help | -h | --version | -V | --seconds | -s | --time | -t) + return + ;; + --mode | -m) + COMPREPLY=($(compgen -W 'standby mem disk on no off' -- "$cur")) + return + ;; + --device | -d) + COMPREPLY=($(command ls -d /dev/rtc?* 2>/dev/null)) + COMPREPLY=($(compgen -W '${COMPREPLY[@]#/dev/}' -- "$cur")) + return + ;; + esac + + $split && return + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _rtcwake rtcwake + +# ex: filetype=sh diff --git a/completions/_runuser b/completions/_runuser new file mode 100644 index 0000000..95cf930 --- /dev/null +++ b/completions/_runuser @@ -0,0 +1,8 @@ +# runuser(1) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.23, use that instead. + +complete -u runuser + +# ex: filetype=sh diff --git a/completions/_su b/completions/_su new file mode 100644 index 0000000..1a03c8f --- /dev/null +++ b/completions/_su @@ -0,0 +1,41 @@ +# bash completion for su(1) -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.23, use that instead. + +if [[ $OSTYPE != *linux* ]]; then + complete -u su # default completion + return +fi + +_su() +{ # linux-specific completion + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + -s | --shell) + _shells + return + ;; + -c | --command | --session-command) + local IFS=$'\n' + compopt -o filenames + COMPREPLY=($(compgen -d -c -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --help)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + COMPREPLY=($(compgen -u -- "$cur")) +} && + complete -F _su su + +# ex: filetype=sh diff --git a/completions/_svn b/completions/_svn new file mode 100644 index 0000000..5d85c2b --- /dev/null +++ b/completions/_svn @@ -0,0 +1,210 @@ +# svn completion -*- shell-script -*- + +# Use of this file is deprecated. Upstream completion is available in +# subversion >= 0.12.0, use that instead. + +_svn() +{ + local cur prev words cword + _init_completion || return + + local commands + commands='add blame praise annotate ann cat checkout co cleanup commit \ + ci copy cp delete del remove rm diff di export help ? h import \ + info list ls lock log merge mkdir move mv rename ren \ + propdel pdel pd propedit pedit pe propget pget pg \ + proplist plist pl propset pset ps resolved revert \ + status stat st switch sw unlock update up' + + if ((cword == 1)); then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--version' -- "$cur")) + else + COMPREPLY=($(compgen -W "$commands" -- "$cur")) + fi + else + + case $prev in + --config-dir) + _filedir -d + return + ;; + -F | --file | --targets) + _filedir + return + ;; + --encoding) + _xfunc iconv _iconv_charsets + return + ;; + --editor-cmd | --diff-cmd | --diff3-cmd) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + esac + + local command=${words[1]} + + if [[ $cur == -* ]]; then + # possible options for the command + local options + case $command in + add) + options='--auto-props --no-auto-props --force --targets + --no-ignore --non-recursive --quiet' + ;; + blame | annotate | ann | praise) + options='--revision --username --password --no-auth-cache + --non-interactive --verbose --incremental --xml' + ;; + cat) + options='--revision --username --password --no-auth-cache + --non-interactive' + ;; + checkout | co) + options='--revision --quiet --non-recursive --username + --password --no-auth-cache --non-interactive + --ignore-externals' + ;; + cleanup) + options='--diff3-cmd' + ;; + commit | ci) + options='--message --file --encoding --force-log --quiet + --non-recursive --targets --editor-cmd --username + --password --no-auth-cache --non-interactive + --no-unlock' + ;; + copy | cp) + options='--message --file --encoding --force-log --revision + --quiet --editor-cmd -username --password + --no-auth-cache --non-interactive' + ;; + delete | del | remove | rm) + options='--force --message --file --encoding --force-log + --quiet --targets --editor-cmd --username + --password --no-auth-cache --non-interactive' + ;; + diff | di) + options='--revision --extensions --diff-cmd + --no-diff-deleted --non-recursive --username + --password --no-auth-cache --non-interactive + --force --old --new --notice-ancestry' + ;; + export) + options='--revision --quiet --username --password + --no-auth-cache --non-interactive --non-recursive + --force --native-eol --ignore-externals' + ;; + import) + options='--auto-props --no-auto-props --message --file + --encoding --force-log --quiet --non-recursive + --no-ignore --editor-cmd --username --password + --no-auth-cache --non-interactive' + ;; + info) + options='--username --password --no-auth-cache + --non-interactive --revision --xml --targets + --recursive --incremental' + ;; + list | ls) + options='--revision --verbose --recursive --username + --password --no-auth-cache --non-interactive + --incremental --xml' + ;; + lock) + options='--message --file --encoding --force-log --targets + --force --username --password --no-auth-cache + --non-interactive' + ;; + log) + options='--revision --verbose --targets --username + --password --no-auth-cache --non-interactive + --stop-on-copy --incremental --xml --quiet + --limit' + ;; + merge) + options='--revision --non-recursive --quiet --force + --dry-run --diff3-cmd --username --password + --no-auth-cache --non-interactive + --ignore-ancestry' + ;; + mkdir) + options='--message --file --encoding --force-log --quiet + --editor-cmd --username --password --no-auth-cache + --non-interactive' + ;; + move | mv | rename | ren) + options='--message --file --encoding --force-log --revision + --quiet --force --editor-cmd --username --password + --no-auth-cache --non-interactive' + ;; + propdel | pdel | pd) + options='--quiet --recursive --revision --revprop + --username --password --no-auth-cache + --non-interactive' + ;; + propedit | pedit | pe) + options='--revision --revprop --encoding --editor-cmd + --username --password --no-auth-cache + --non-interactive --force' + ;; + propget | pget | pg) + options='--recursive --revision --revprop --strict + --username --password --no-auth-cache + --non-interactive' + ;; + proplist | plist | pl) + options='--verbose --recursive --revision --revprop --quiet + --username --password --no-auth-cache + --non-interactive' + ;; + propset | pset | ps) + options='--file --quiet --targets --recursive --revprop + --encoding --username --password --no-auth-cache + --non-interactive --revision --force' + ;; + resolved) + options='--targets --recursive --quiet' + ;; + revert) + options='--targets --recursive --quiet' + ;; + status | stat | st) + options='--show-updates --verbose --non-recursive --quiet + --username --password --no-auth-cache + --non-interactive --no-ignore --ignore-externals + --incremental --xml' + ;; + switch | sw) + options='--relocate --revision --non-recursive --quiet + --username --password --no-auth-cache + --non-interactive --diff3-cmd' + ;; + unlock) + options='--targets --force --username --password + --no-auth-cache --non-interactive' + ;; + update | up) + options='--revision --non-recursive --quiet --username + --password --no-auth-cache --non-interactive + --diff3-cmd --ignore-externals' + ;; + esac + options+=" --help --config-dir" + + COMPREPLY=($(compgen -W "$options" -- "$cur")) + else + if [[ $command == @(help|[h?]) ]]; then + COMPREPLY=($(compgen -W "$commands" -- "$cur")) + else + _filedir + fi + fi + fi + +} && + complete -F _svn svn + +# ex: filetype=sh diff --git a/completions/_svnadmin b/completions/_svnadmin new file mode 100644 index 0000000..654fd3e --- /dev/null +++ b/completions/_svnadmin @@ -0,0 +1,78 @@ +# svnadmin completion -*- shell-script -*- + +# Use of this file is deprecated. Upstream completion is available in +# subversion >= 0.12.0, use that instead. + +_svnadmin() +{ + local cur prev words cword + _init_completion || return + + local commands + commands='create deltify dump help ? hotcopy list-dblogs list-unused-dblogs + load lslocks lstxns recover rmlocks rmtxns setlog verify' + + if ((cword == 1)); then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--version' -- "$cur")) + else + COMPREPLY=($(compgen -W "$commands" -- "$cur")) + fi + else + case $prev in + --config-dir) + _filedir -d + return + ;; + --fs-type) + COMPREPLY=($(compgen -W 'fsfs bdb' -- "$cur")) + return + ;; + esac + + local command=${words[1]} + + if [[ $cur == -* ]]; then + # possible options for the command + local options + case $command in + create) + options='--bdb-txn-nosync --bdb-log-keep --config-dir + --fs-type' + ;; + deltify) + options='--revision --quiet' + ;; + dump) + options='--revision --incremental --quiet --deltas' + ;; + hotcopy) + options='--clean-logs' + ;; + load) + options='--ignore-uuid --force-uuid --parent-dir --quiet + --use-pre-commit-hook --use-post-commit-hook' + ;; + rmtxns) + options='--quiet' + ;; + setlog) + options='--revision --bypass-hooks' + ;; + esac + + options+=" --help" + COMPREPLY=($(compgen -W "$options" -- "$cur")) + else + if [[ $command == @(help|[h?]) ]]; then + COMPREPLY=($(compgen -W "$commands" -- "$cur")) + else + _filedir + fi + fi + fi + +} && + complete -F _svnadmin -o default svnadmin + +# ex: filetype=sh diff --git a/completions/_svnlook b/completions/_svnlook new file mode 100644 index 0000000..36188a5 --- /dev/null +++ b/completions/_svnlook @@ -0,0 +1,63 @@ +# svnlook completion -*- shell-script -*- + +# Use of this file is deprecated. Upstream completion is available in +# subversion >= 0.12.0, use that instead. + +_svnlook() +{ + local cur prev words cword + _init_completion || return + + local commands + commands='author cat changed date diff dirs-changed help ? h history info + lock log propget pget pg proplist plist pl tree uuid youngest' + + if ((cword == 1)); then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--version' -- "$cur")) + else + COMPREPLY=($(compgen -W "$commands" -- "$cur")) + fi + else + local command=${words[1]} + + if [[ $cur == -* ]]; then + # possible options for the command + local options + case $command in + author | cat | date | dirs-changed | info | log) + options='--revision --transaction' + ;; + changed) + options='--revision --transaction --copy-info' + ;; + diff) + options='--revision --transaction --no-diff-deleted + --no-diff-added --diff-copy-from' + ;; + history) + options='--revision --show-ids' + ;; + propget | proplist) + options='--revision --transaction --revprop' + ;; + tree) + options='--revision --transaction --show-ids --full-paths' + ;; + esac + + options+=" --help" + COMPREPLY=($(compgen -W "$options" -- "$cur")) + else + if [[ $command == @(help|[h?]) ]]; then + COMPREPLY=($(compgen -W "$commands" -- "$cur")) + else + _filedir + fi + fi + fi + +} && + complete -F _svnlook -o default svnlook + +# ex: filetype=sh diff --git a/completions/_udevadm b/completions/_udevadm new file mode 100644 index 0000000..19624be --- /dev/null +++ b/completions/_udevadm @@ -0,0 +1,77 @@ +# udevadm(8) completion -*- shell-script -*- + +# Use of this file is deprecated. Upstream completion is available in +# systemd >= 196, use that instead. + +_udevadm() +{ + local cur prev words cword split + _init_completion -s || return + + local i udevcmd + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} != -* ]]; then + udevcmd=${words[i]} + break + fi + done + + case $prev in + --help | --version | --property | --children-max | --timeout | --seq-start | \ + --seq-end | --attr-match | --attr-nomatch | --parent-match | --property-match | \ + --tag-match | --subsystem-match | --subsystem-nomatch | --sysname-match | \ + --path) + return + ;; + --log-priority) + COMPREPLY=($(compgen -W 'err info debug' -- "$cur")) + return + ;; + --query) + COMPREPLY=($(compgen -W 'name symlink path property all' \ + -- "$cur")) + return + ;; + --name) + cur=${cur:=/dev/} + _filedir + return + ;; + --device-id-of-file | --exit-if-exists) + _filedir + return + ;; + --action) + COMPREPLY=($(compgen -W 'add change remove' -- "$cur")) + return + ;; + --type) + COMPREPLY=($(compgen -W 'devices subsystems failed' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ ! -v udevcmd ]]; then + case $cur in + -*) + COMPREPLY=($(compgen -W '--help --version --debug' -- "$cur")) + ;; + *) + COMPREPLY=($(compgen -W "$("$1" --help 2>/dev/null | + awk '/^[ \t]/ { print $1 }')" -- "$cur")) + ;; + esac + return + fi + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W \ + '$("$1" ${udevcmd-} --help 2>/dev/null | _parse_help -)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _udevadm udevadm + +# ex: filetype=sh diff --git a/completions/_umount b/completions/_umount new file mode 100644 index 0000000..36d5703 --- /dev/null +++ b/completions/_umount @@ -0,0 +1,24 @@ +# umount(8) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.28, use that instead. + +if [[ $OSTYPE == *linux* ]]; then + . "$BASH_SOURCE.linux" + return +fi + +# umount(8) completion. This relies on the mount point being the third +# space-delimited field in the output of mount(8) +# +_umount() +{ + local cur prev words cword + _init_completion || return + + local IFS=$'\n' + COMPREPLY=($(compgen -W '$(mount | cut -d" " -f 3)' -- "$cur")) +} && + complete -F _umount -o dirnames umount + +# ex: filetype=sh diff --git a/completions/_umount.linux b/completions/_umount.linux new file mode 100644 index 0000000..cf8a259 --- /dev/null +++ b/completions/_umount.linux @@ -0,0 +1,145 @@ +# umount(8) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.28, use that instead. + +# Just like COMPREPLY=(`compgen -W "${COMPREPLY[*]}" -- "$cur"`), only better! +# +# This will correctly escape special characters in COMPREPLY. +_reply_compgen_array() +{ + # Create the argument for compgen -W by escaping twice. + # + # One round of escape is because we want to reply with escaped arguments. A + # second round is required because compgen -W will helpfully expand it's + # argument. + local i wlist + for i in ${!COMPREPLY[*]}; do + local q=$(quote "$(printf %q "${COMPREPLY[i]}")") + wlist+=$q$'\n' + done + + # We also have to add another round of escaping to $cur. + local ecur="$cur" + ecur=${ecur//\\/\\\\} + ecur=${ecur//\'/\\\'} + + # Actually generate completions. + local ifs=$IFS + IFS=$'\n' eval 'COMPREPLY=(`compgen -W "$wlist" -- "${ecur}"`)' + IFS=$ifs +} + +# Unescape strings in the linux fstab(5) format (with octal escapes). +__linux_fstab_unescape() +{ + eval $1="'${!1//\'/\\047}'" + eval $1="'${!1/%\\/\\\\}'" + eval "$1=$'${!1}'" +} + +# Complete linux fstab entries. +# +# Reads a file from stdin in the linux fstab(5) format; as used by /etc/fstab +# and /proc/mounts. With 1st arg -L, look for entries by label. +# shellcheck disable=SC2120 +_linux_fstab() +{ + COMPREPLY=() + + # Read and unescape values into COMPREPLY + local fs_spec fs_file fs_other + local ifs="$IFS" + while read -r fs_spec fs_file fs_other; do + if [[ $fs_spec == [#]* ]]; then continue; fi + if [[ ${1-} == -L ]]; then + local fs_label=${fs_spec/#LABEL=/} + if [[ $fs_label != "$fs_spec" ]]; then + __linux_fstab_unescape fs_label + IFS=$'\0' + COMPREPLY+=("$fs_label") + IFS=$ifs + fi + else + __linux_fstab_unescape fs_spec + __linux_fstab_unescape fs_file + IFS=$'\0' + [[ $fs_spec == */* ]] && COMPREPLY+=("$fs_spec") + [[ $fs_file == */* ]] && COMPREPLY+=("$fs_file") + IFS=$ifs + fi + done + + # Add relative paths to COMPREPLY + if [[ $cur && $cur != /* ]]; then + local realcur + [[ $cur == */ ]] && # don't let readlink drop last / from path + realcur="$(readlink -f "$cur." 2>/dev/null)/" || + realcur=$(readlink -f "$cur" 2>/dev/null) + if [[ $realcur ]]; then + local dirrealcur="" dircur="" basecur + if [[ $cur == */* ]]; then + dirrealcur="${realcur%/*}/" + dircur="${cur%/*}/" + fi + basecur=${cur#"$dircur"} + local i + for i in ${!COMPREPLY[*]}; do + [[ ${COMPREPLY[i]} == "$realcur"* ]] && + COMPREPLY+=($(cd "$dircur" 2>/dev/null && + compgen -f -d -P "$dircur" \ + -X "!${COMPREPLY[i]##"$dirrealcur"}" -- "$basecur")) + done + fi + fi + + _reply_compgen_array +} + +_umount() +{ + local cur prev words cword + _init_completion || return + + case "$prev" in + -t) + # FIXME: no<fstype> + local split=false + if [[ $cur == ?*,* ]]; then + prev="${cur%,*}" + cur="${cur##*,}" + split=true + fi + COMPREPLY=($(compgen -W 'adfs affs autofs btrfs cifs coda + cramfs debugfs devpts efs ext2 ext3 ext4 fuse hfs hfsplus hpfs + iso9660 jfs minix msdos ncpfs nfs nfs4 ntfs ntfs-3g proc qnx4 + ramfs reiserfs romfs squashfs smbfs sysv tmpfs ubifs udf ufs + umsdos usbfs vfat xfs' -- "$cur")) + _fstypes + $split && COMPREPLY=(${COMPREPLY[@]/#/$prev,}) + return + ;; + -O) + # argument required but no completions available + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-V -h -v -n -r -d -i -a -t -O -f -l + --no-canonicalize --fake' -- "$cur")) + [[ ${COMPREPLY-} ]] && return + fi + + if [[ -r /proc/mounts ]]; then + # Linux /proc/mounts is properly quoted. This is important when + # unmounting usb devices with pretty names. + _linux_fstab </proc/mounts + else + local IFS=$'\n' + COMPREPLY=($(compgen -W '$(mount | cut -d" " -f 3)' -- "$cur")) + fi +} && + complete -F _umount -o dirnames umount + +# ex: filetype=sh diff --git a/completions/_write b/completions/_write new file mode 100644 index 0000000..49e56ff --- /dev/null +++ b/completions/_write @@ -0,0 +1,8 @@ +# write(1) completion -*- shell-script -*- + +# Use of this file is deprecated on Linux. Upstream completion is +# available in util-linux >= 2.23, use that instead. + +complete -u write + +# ex: filetype=sh diff --git a/completions/_xm b/completions/_xm new file mode 100644 index 0000000..06b25d3 --- /dev/null +++ b/completions/_xm @@ -0,0 +1,224 @@ +# bash completion for xm -*- shell-script -*- + +# Use of this file is deprecated. The 'xm' command itself is no longer +# provided by upstream. It has been replaced with the 'xl' command, for +# which upstream provides completion, use that instead. + +_xen_domain_names() +{ + COMPREPLY=($(compgen -W "$(xm list 2>/dev/null | + awk '!/Name|Domain-0/ { print $1 }')" -- "$cur")) +} + +_xen_domain_ids() +{ + COMPREPLY=($(compgen -W "$(xm list 2>/dev/null | + awk '!/Name|Domain-0/ { print $2 }')" -- "$cur")) +} + +_xm() +{ + local cur prev words cword + _init_completion || return + + # TODO: _split_longopt + + local args command commands options + + commands='console vncviewer create new delete destroy domid domname + dump-core list mem-max mem-set migrate pause reboot rename reset + restore resume save shutdown start suspend sysrq trigger top unpause + uptime usb-add usb-del vcpu-list vcpu-pin vcpu-set debug-keys dmesg + info log serve sched-credit sched-sedf block-attach block-detach + block-list block-configure network-attach network-detach network-list + vtpm-list pci-attach pci-detach pci-list pci-list-assignable-devices + scsi-attach scsi-detach scsi-list vnet-list vnet-create vnet-delete + labels addlabel rmlabel getlabel dry-run resources dumppolicy setpolicy + resetpolicy getpolicy shell help' + + if ((cword == 1)); then + COMPREPLY=($(compgen -W "$commands" -- "$cur")) + else + if [[ $cur == *=* ]]; then + prev=${cur/=*/} + cur=${cur/*=/} + fi + + command=${words[1]} + if [[ $cur == -* ]]; then + # possible options for the command + case $command in + create) + options='-c' + ;; + dmesg) + options='--clear' + ;; + list) + options='--long' + ;; + reboot) + options='-w -a' + ;; + shutdown) + options='-w -a -R -H' + ;; + sched-credit) + options='-d -w -c' + ;; + block-list | network-list | vtpm-list | vnet-list) + options='-l --long' + ;; + getpolicy) + options='--dumpxml' + ;; + new) + options='-h --help --help_config -q --quiet --path= -f= + --defconfig= -F= --config= -b --dryrun -x --xmldryrun + -s --skipdtd -p --paused -c --console_autoconnect' + ;; + esac + COMPREPLY=($(compgen -W "$options" -- "$cur")) + else + case $command in + console | destroy | domname | domid | list | mem-set | mem-max | \ + pause | reboot | rename | shutdown | unpause | vcpu-list | vcpu-pin | \ + vcpu-set | block-list | network-list | vtpm-list) + _count_args + case $args in + 2) + _xen_domain_names + ;; + esac + ;; + migrate) + _count_args + case $args in + 2) + _xen_domain_names + ;; + 3) + _known_hosts_real -- "$cur" + ;; + esac + ;; + restore | dry-run | vnet-create) + _filedir + ;; + save) + _count_args + case $args in + 2) + _xen_domain_names + ;; + 3) + _filedir + ;; + esac + ;; + sysrq) + _count_args + case $args in + 2) + _xen_domain_names + ;; + 3) + COMPREPLY=($(compgen -W "r s e i u b" -- "$cur")) + ;; + esac + ;; + block-attach) + _count_args + case $args in + 2) + _xen_domain_names + ;; + 3) + COMPREPLY=($(compgen -W "phy: file:" -- "$cur")) + ;; + 5) + COMPREPLY=($(compgen -W "w r" -- "$cur")) + ;; + 6) + _xen_domain_names + ;; + esac + ;; + block-detach) + _count_args + case $args in + 2) + _xen_domain_names + ;; + 3) + COMPREPLY=($(compgen -W "$(xm block-list $prev \ + 2>/dev/null | awk '!/Vdev/ { print $1 }')" \ + -- "$cur")) + ;; + esac + ;; + network-attach) + _count_args + case $args in + 2) + _xen_domain_names + ;; + *) + COMPREPLY=($(compgen -W "script= ip= mac= bridge= + backend=" -- "$cur")) + ;; + esac + ;; + network-detach) + _count_args + case $args in + 2) + _xen_domain_names + ;; + 3) + COMPREPLY=($(compgen -W "$(xm network-list $prev \ + 2>/dev/null | awk '!/Idx/ { print $1 }')" \ + -- "$cur")) + ;; + esac + ;; + sched-credit) + case $prev in + -d) + _xen_domain_names + return + ;; + esac + ;; + create) + _filedir + COMPREPLY+=( + $(compgen -W '$(command ls /etc/xen 2>/dev/null)' \ + -- "$cur")) + ;; + new) + case $prev in + -f | -F | --defconfig | --config) + _filedir + return + ;; + --path) + _filedir -d + return + ;; + esac + + _count_args + case $args in + 2) + _xen_domain_names + ;; + esac + ;; + esac + fi + fi +} && + complete -F _xm xm + +# ex: filetype=sh diff --git a/completions/_yum b/completions/_yum new file mode 100644 index 0000000..224ea25 --- /dev/null +++ b/completions/_yum @@ -0,0 +1,144 @@ +# yum(8) completion -*- shell-script -*- + +# Use of this file is deprecated. Upstream completion is available in +# yum > 3.2.25, use that instead. + +_yum_list() +{ + if [[ $1 == all ]]; then + # Try to strip in between headings like "Available Packages" + # This will obviously only work for English :P + COMPREPLY=($(yum -d 0 -C list $1 "$cur*" 2>/dev/null | + command sed -ne '/^Available /d' -e '/^Installed /d' -e '/^Updated /d' \ + -e 's/[[:space:]].*//p')) + else + # Drop first line (e.g. "Updated Packages") + COMPREPLY=($(yum -d 0 -C list $1 "$cur*" 2>/dev/null | + command sed -ne 1d -e 's/[[:space:]].*//p')) + fi +} + +_yum_repolist() +{ + # -d 0 causes repolist to output nothing as of yum 3.2.22: + # http://yum.baseurl.org/ticket/83 + # Drop first ("repo id repo name") and last ("repolist: ...") rows + yum --noplugins -C repolist $1 2>/dev/null | + command sed -ne '/^repo\s\s*id/d' -e '/^repolist:/d' -e 's/[[:space:]].*//p' +} + +_yum_plugins() +{ + command ls /usr/lib/yum-plugins/*.py{,c,o} 2>/dev/null | + command sed -ne 's|.*/\([^./]*\)\.py[co]\{0,1\}$|\1|p' | sort -u +} + +_yum() +{ + local cur prev words cword split + _init_completion -s || return + + local special i + for ((i = 1; i < ${#words[@]} - 1; i++)); do + if [[ ${words[i]} == @(install|update|upgrade|remove|erase|deplist|info) ]]; then + special=${words[i]} + break + fi + done + + if [[ -v special ]]; then + # TODO: install|update|upgrade should not match *src.rpm + if [[ $cur == @(*/|[.~])* && \ + $special == @(deplist|install|update|upgrade) ]]; then + _filedir rpm + return + fi + case $special in + install) + _yum_list available + return + ;; + deplist | info) + _yum_list all + return + ;; + upgrade | update) + _yum_list updates + return + ;; + remove | erase) + # _rpm_installed_packages is not arch-qualified + _yum_list installed + return + ;; + esac + fi + + case $prev in + list) + COMPREPLY=($(compgen -W 'all available updates installed extras + obsoletes recent' -- "$cur")) + ;; + clean) + COMPREPLY=($(compgen -W 'packages headers metadata cache dbcache + all' -- "$cur")) + ;; + repolist) + COMPREPLY=($(compgen -W 'all enabled disabled' -- "$cur")) + ;; + localinstall | localupdate) + # TODO: should not match *src.rpm + _filedir rpm + ;; + -d | -e) + COMPREPLY=($(compgen -W '{0..10}' -- "$cur")) + ;; + -c) + _filedir + ;; + --installroot) + _filedir -d + ;; + --enablerepo) + COMPREPLY=($(compgen -W '$(_yum_repolist disabled)' -- "$cur")) + ;; + --disablerepo) + COMPREPLY=($(compgen -W '$(_yum_repolist enabled)' -- "$cur")) + ;; + --disableexcludes) + COMPREPLY=($(compgen -W '$(_yum_repolist all) all main' \ + -- "$cur")) + ;; + --enableplugin | --disableplugin) + COMPREPLY=($(compgen -W '$(_yum_plugins)' -- "$cur")) + ;; + --color) + COMPREPLY=($(compgen -W 'always auto never' -- "$cur")) + ;; + -R | -x | --exclude) + # argument required but no completions available + return + ;; + -h | --help | --version) + # no other options useful with these + return + ;; + *) + COMPREPLY=($(compgen -W 'install update check-update upgrade + remove erase list info provides whatprovides clean makecache + groupinstall groupupdate grouplist groupremove groupinfo + search shell resolvedep localinstall localupdate deplist + repolist help' -- "$cur")) + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _yum yum + +# ex: filetype=sh diff --git a/completions/a2x b/completions/a2x new file mode 100644 index 0000000..b59c786 --- /dev/null +++ b/completions/a2x @@ -0,0 +1,39 @@ +# a2x(1) completion -*- shell-script -*- + +_a2x() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --attribute | --asciidoc-opts | --dblatex-opts | --fop-opts | --help | \ + --version | --xsltproc-opts | -!(-*)[ah]) + return + ;; + --destination-dir | --icons-dir | -!(-*)D) + _filedir -d + return + ;; + --doctype | -!(-*)d) + _xfunc asciidoc _asciidoc_doctype + return + ;; + --stylesheet) + _filedir css + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --help)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir +} && + complete -F _a2x a2x + +# ex: filetype=sh diff --git a/completions/abook b/completions/abook new file mode 100644 index 0000000..42197d1 --- /dev/null +++ b/completions/abook @@ -0,0 +1,49 @@ +# abook(1) completion -*- shell-script -*- + +_abook() +{ + local cur prev words cword + _init_completion || return + + # abook only takes options, tabbing after command name adds a single dash + [[ $cword -eq 1 && -z $cur ]] && + { + compopt -o nospace + COMPREPLY=("-") + return + } + + case $cur in + -*) + _longopt "$1" + return + ;; + esac + + case $prev in + --informat) + COMPREPLY=($(compgen -W "$($1 --formats | + command sed -n -e 's/^'$'\t''\([a-z]*\).*/\1/p' -e '/^$/q')" \ + -- "$cur")) + ;; + --outformat) + COMPREPLY=($(compgen -W "$($1 --formats | + command sed -n -e '/^$/,$s/^'$'\t''\([a-z]*\).*/\1/p')" \ + -- "$cur")) + ;; + --infile) + COMPREPLY=($(compgen -W stdin -- "$cur")) + _filedir + ;; + --outfile) + COMPREPLY=($(compgen -W stdout -- "$cur")) + _filedir + ;; + --config | --datafile) + _filedir + ;; + esac +} && + complete -F _abook abook + +# ex: filetype=sh diff --git a/completions/aclocal b/completions/aclocal new file mode 100644 index 0000000..010862f --- /dev/null +++ b/completions/aclocal @@ -0,0 +1,35 @@ +# aclocal(1) completion -*- shell-script -*- + +_aclocal() +{ + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + --help | --print-ac-dir | --version) + return + ;; + --acdir | -I) + _filedir -d + return + ;; + --output) + _filedir + return + ;; + --warnings | -W) + local cats=(syntax unsupported) + COMPREPLY=($(compgen -W \ + '${cats[@]} ${cats[@]/#/no-} all none error' -- "$cur")) + return + ;; + esac + + $split && return + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace +} && + complete -F _aclocal aclocal aclocal-1.1{0..6} + +# ex: filetype=sh diff --git a/completions/acpi b/completions/acpi new file mode 100644 index 0000000..f2c38b2 --- /dev/null +++ b/completions/acpi @@ -0,0 +1,22 @@ +# acpi(1) completion -*- shell-script -*- + +_acpi() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | -!(-*)[hv]) + return + ;; + --directory | -!(-*)d) + _filedir -d + return + ;; + esac + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _acpi acpi + +# ex: filetype=sh diff --git a/completions/add_members b/completions/add_members new file mode 100644 index 0000000..efa4f1e --- /dev/null +++ b/completions/add_members @@ -0,0 +1,31 @@ +# mailman add_members completion -*- shell-script -*- + +_add_members() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -r | -d | --regular-members-file | --digest-members-file) + _filedir + return + ;; + -w | -a | --welcome-msg | --admin-notify) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--regular-members-file --digest-members-file + --welcome-msg --admin-notify --help' -- "$cur")) + else + _xfunc list_lists _mailman_lists + fi + +} && + complete -F _add_members add_members + +# ex: filetype=sh diff --git a/completions/alias b/completions/alias new file mode 100644 index 0000000..92211d8 --- /dev/null +++ b/completions/alias @@ -0,0 +1,20 @@ +# bash alias completion -*- shell-script -*- + +_alias() +{ + local cur prev words cword + _init_completion -n = || return + + case ${words[@]} in + *[^=]) + COMPREPLY=($(compgen -A alias -- "$cur")) + ;; + *=) + COMPREPLY=("$(alias ${cur%=} 2>/dev/null | command sed \ + -e 's|^alias '"$cur"'\(.*\)$|\1|')") + ;; + esac +} && + complete -F _alias -o nospace alias + +# ex: filetype=sh diff --git a/completions/ant b/completions/ant new file mode 100644 index 0000000..197c0e9 --- /dev/null +++ b/completions/ant @@ -0,0 +1,102 @@ +# bash completion for ant and phing -*- shell-script -*- + +_ant_parse_targets() +{ + local line basedir + + [[ $1 == */* ]] && basedir=${1%/*} || basedir=. + + # parse buildfile for targets + while read -rd '>' line; do + if [[ $line =~ \<(target|extension-point)[[:space:]].*name=[\"\']([^\"\']+) ]]; then + targets+=" ${BASH_REMATCH[2]}" + fi + done <$1 + + # parse imports + while read -rd '>' line; do + if [[ $line =~ \<import[[:space:]].*file=[\"\']([^\"\']+) ]]; then + local imported_buildfile + imported_buildfile="${basedir}/${BASH_REMATCH[1]}" + if [[ -f $imported_buildfile ]]; then + _ant_parse_targets $imported_buildfile + fi + fi + done <$1 +} + +_ant() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h | -help | --h | --help | -projecthelp | -p | -version | -diagnostics) + return + ;; + -buildfile | -file | -f) + _filedir 'xml' + return + ;; + -logfile | -l) + [[ $1 != *phing || $prev != -l ]] && _filedir + return + ;; + -propertyfile) + _filedir properties + return + ;; + -nice) + COMPREPLY=($(compgen -W '{1..10}' -- "$cur")) + return + ;; + -lib) + _filedir -d + return + ;; + -logger | -listener | -inputhandler | -main | -find | -s) + return + ;; + esac + + if [[ $cur == -D* ]]; then + return + elif [[ $cur == -* ]]; then + # The </dev/null prevents "phing -" weirdness/getting just a literal + # tab displayed on complete on CentOS 6 with phing 2.6.1. + COMPREPLY=( + $(compgen -W '$(_parse_help "$1" -h </dev/null)' -- "$cur")) + else + # available targets completion + # find which buildfile to use + local buildfile=build.xml i + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == -@(?(build)file|f) ]]; then + buildfile=${words[i + 1]} + break + fi + done + if ((i == cword)); then + for i in ${ANT_ARGS-}; do + if [[ $prev == -@(?(build)file|f) ]]; then + buildfile=$i + break + fi + prev=$i + done + fi + [[ ! -f $buildfile ]] && return + + local targets + + # fill targets + _ant_parse_targets $buildfile + + COMPREPLY=($(compgen -W '$targets' -- "$cur")) + fi +} && + complete -F _ant ant phing +type complete-ant-cmd.pl &>/dev/null && + complete -C complete-ant-cmd.pl -F _ant ant || : + +# ex: filetype=sh diff --git a/completions/apache2ctl b/completions/apache2ctl new file mode 100644 index 0000000..980b3c5 --- /dev/null +++ b/completions/apache2ctl @@ -0,0 +1,16 @@ +# apache2ctl(1) completion -*- shell-script -*- + +_apache2ctl() +{ + local cur prev words cword + _init_completion || return + + local APWORDS + APWORDS=$($1 2>&1 >/dev/null | awk 'NR<2 { print $3; exit }' | + tr "|" " ") + + COMPREPLY=($(compgen -W "$APWORDS" -- "$cur")) +} && + complete -F _apache2ctl apache2ctl + +# ex: filetype=sh diff --git a/completions/appdata-validate b/completions/appdata-validate new file mode 100644 index 0000000..03d8cc9 --- /dev/null +++ b/completions/appdata-validate @@ -0,0 +1,32 @@ +# appdata-validate(1) completion -*- shell-script -*- + +_appdata_validate() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -h | --help | --version) + return + ;; + --output-format) + COMPREPLY=($(compgen -W "$($1 --help | + command sed -ne 's/--output-format.*\[\(.*\)\]/\1/' -e 's/|/ /gp')" \ + -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir appdata.xml +} && + complete -F _appdata_validate appdata-validate + +# ex: filetype=sh diff --git a/completions/apt-build b/completions/apt-build new file mode 100644 index 0000000..713f4c3 --- /dev/null +++ b/completions/apt-build @@ -0,0 +1,54 @@ +# Debian apt-build(1) completion -*- shell-script -*- + +_apt_build() +{ + local cur prev words cword + _init_completion || return + + local special i + for ((i = 1; i < ${#words[@]} - 1; i++)); do + if [[ ${words[i]} == @(install|remove|source|info|clean) ]]; then + special=${words[i]} + break + fi + done + + if [[ -v special ]]; then + case $special in + install | source | info) + COMPREPLY=($(_xfunc apt-cache _apt_cache_packages)) + ;; + remove) + COMPREPLY=( + $(_xfunc dpkg _comp_dpkg_installed_packages "$cur")) + ;; + esac + return + fi + + case $prev in + --patch | --build-dir | --repository-dir) + _filedir + return + ;; + -h | --help) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--help --show-upgraded -u --build-dir + --repository-dir --build-only --build-command --reinstall --rebuild + --remove-builddep --no-wrapper --purge --patch --patch-strip -p + --yes -y --version -v --no-source' -- "$cur")) + + else + COMPREPLY=($(compgen -W 'update upgrade install remove source + dist-upgrade world clean info clean-build update-repository' \ + -- "$cur")) + fi + +} && + complete -F _apt_build apt-build + +# ex: filetype=sh diff --git a/completions/apt-cache b/completions/apt-cache new file mode 100644 index 0000000..61aa07b --- /dev/null +++ b/completions/apt-cache @@ -0,0 +1,85 @@ +# Debian apt-cache(8) completion -*- shell-script -*- + +# List APT binary packages +_apt_cache_packages() +{ + apt-cache --no-generate pkgnames "$cur" 2>/dev/null || : +} + +# List APT source packages +_apt_cache_sources() +{ + compgen -W "$(apt-cache dumpavail | + awk '$1 == "Source:" { print $2 }' | sort -u)" -- "$1" +} + +# List APT source packages +_apt_cache_src_packages() +{ + compgen -W '$(_apt_cache_sources "$cur")' -- "$cur" +} + +_apt_cache() +{ + local cur prev words cword + _init_completion || return + + local special ispecial + if [[ $cur != show ]]; then + for ((ispecial = 1; ispecial < ${#words[@]} - 1; ispecial++)); do + if [[ ${words[ispecial]} == @(add|depends|dotty|madison|policy|rdepends|show?(pkg|src|)) ]]; then + special=${words[ispecial]} + break + fi + done + fi + + if [[ -v special && $ispecial -lt $cword ]]; then + case $special in + add) + _filedir + ;; + + showsrc) + COMPREPLY=($(_apt_cache_sources "$cur")) + ;; + + *) + COMPREPLY=($(_apt_cache_packages)) + ;; + + esac + return + fi + + case $prev in + --config-file | --pkg-cache | --src-cache | -!(-*)[cps]) + _filedir + return + ;; + search) + if [[ $cur != -* ]]; then + return + fi + ;; + esac + + if [[ $cur == -* ]]; then + + COMPREPLY=($(compgen -W '-h -v -p -s -q -i -f -a -g -c -o --help + --version --pkg-cache --src-cache --quiet --important --full + --all-versions --no-all-versions --generate --no-generate + --names-only --all-names --recurse --config-file --option + --installed' -- "$cur")) + elif [[ ! -v special ]]; then + + COMPREPLY=($(compgen -W 'add gencaches show showpkg showsrc stats + dump dumpavail unmet search search depends rdepends pkgnames + dotty xvcg policy madison' -- "$cur")) + + fi + +} && + complete -F _apt_cache apt-cache + +# ex: filetype=sh diff --git a/completions/apt-get b/completions/apt-get new file mode 100644 index 0000000..4aee263 --- /dev/null +++ b/completions/apt-get @@ -0,0 +1,104 @@ +# Debian apt-get(8) completion -*- shell-script -*- + +_apt_get() +{ + local cur prev words cword package + _init_completion -n ':=' || return + + local special i + for ((i = 1; i < ${#words[@]} - 1; i++)); do + if [[ ${words[i]} == @(install|remove|autoremove|purge|source|build-dep|download|changelog) ]]; then + special=${words[i]} + break + fi + done + + if [[ -v special ]]; then + case $special in + remove | autoremove | purge) + if [[ -f /etc/debian_version ]]; then + # Debian system + COMPREPLY=($( + _xfunc dpkg _comp_dpkg_installed_packages $cur + )) + else + # assume RPM based + _xfunc rpm _rpm_installed_packages + fi + ;; + source) + COMPREPLY=($(_xfunc apt-cache _apt_cache_packages) + $(compgen -W "$(apt-cache dumpavail | + awk '$1 == "Source:" { print $2 }' | sort -u)" -- "$cur")) + ;; + install) + if [[ $cur == */* ]]; then + _filedir deb + return + elif [[ $cur == *=* ]]; then + package="${cur%%=*}" + cur="${cur#*=}" + COMPREPLY=($(IFS=$'\n' compgen -W "$( + apt-cache --no-generate madison "$package" 2>/dev/null | + while IFS=' |' read -r _ version _; do + echo "$version" + done + )" \ + -- "$cur")) + __ltrim_colon_completions "$cur" + return + fi + ;;& + build-dep) + _filedir -d + [[ $cur != */* ]] || return + ;;& + *) + COMPREPLY+=($(_xfunc apt-cache _apt_cache_packages)) + ;; + esac + return + fi + + case $prev in + --help | --version | --option | -!(-*)[hvo]) + return + ;; + --config-file | -!(-*)c) + _filedir + return + ;; + --target-release | --default-release | -!(-*)t) + COMPREPLY=($(compgen -W "$(apt-cache policy | command sed -ne \ + 's/^ *release.*[ ,]o=\(Debian\|Ubuntu\),a=\(\w*\).*/\2/p')" \ + -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--no-install-recommends --install-suggests + --download-only --fix-broken --ignore-missing --fix-missing + --no-download --quiet --simulate --just-print --dry-run --recon + --no-act --yes --assume-yes --assume-no --no-show-upgraded + --verbose-versions --host-architecture --build-profiles --compile + --build --ignore-hold --with-new-pkgs --no-upgrade --only-upgrade + --allow-downgrades --allow-remove-essential + --allow-change-held-packages --force-yes --print-uris --purge + --reinstall --list-cleanup --target-release --default-release + --trivial-only --no-remove --auto-remove --autoremove --only-source + --diff-only --dsc-only --tar-only --arch-only --indep-only + --allow-unauthenticated --no-allow-insecure-repositories + --allow-releaseinfo-change --show-progress --with-source --help + --version --config-file --option' -- "$cur")) + else + COMPREPLY=($(compgen -W 'update upgrade dist-upgrade + dselect-upgrade install remove purge source build-dep check + download clean autoclean autoremove changelog indextargets' \ + -- "$cur")) + fi + +} && + complete -F _apt_get apt-get + +# ex: filetype=sh diff --git a/completions/aptitude b/completions/aptitude new file mode 100644 index 0000000..e5ea163 --- /dev/null +++ b/completions/aptitude @@ -0,0 +1,119 @@ +# Debian aptitude(1) completion -*- shell-script -*- + +_have grep-status && { + _comp_dpkg_hold_packages() + { + grep-status -P -e "^$1" -a -FStatus 'hold' -n -s Package + } +} || { + _comp_dpkg_hold_packages() + { + command grep -B 2 'hold' /var/lib/dpkg/status | + awk "/Package: $1/ { print \$2 }" + } +} + +_aptitude() +{ + local cur prev words cword + _init_completion || return + + local special i + for ((i = 1; i < ${#words[@]} - 1; i++)); do + if [[ ${words[i]} == @(@(|re)install|@(|un)hold|@(|un)markauto|@(dist|full|safe)-upgrade|download|show|forbid-version|purge|remove|changelog|why@(|-not)|keep@(|-all)|build-dep|@(add|remove)-user-tag|versions) ]]; then + special=${words[i]} + break + fi + done + + if [[ -v special ]]; then + case $special in + install | hold | markauto | unmarkauto | dist-upgrade | full-upgrade | \ + safe-upgrade | download | show | changelog | why | why-not | build-dep | \ + add-user-tag | remove-user-tag | versions) + COMPREPLY=($(_xfunc apt-cache _apt_cache_packages)) + return + ;; + purge | remove | reinstall | forbid-version) + COMPREPLY=( + $(_xfunc dpkg _comp_dpkg_installed_packages "$cur")) + return + ;; + unhold) + COMPREPLY=($(_comp_dpkg_hold_packages "$cur")) + return + ;; + esac + fi + + case $prev in + # don't complete anything if these options are found + autoclean | clean | forget-new | search | upgrade | update | keep-all) + return + ;; + -!(-*)S) + _filedir + return + ;; + --display-format | --width | -!(-*)[wFo]) + return + ;; + --sort | -!(-*)O) + COMPREPLY=($(compgen -W 'installsize installsizechange debsize + name priority version' -- "$cur")) + return + ;; + --target-release | --default-release | -!(-*)t) + COMPREPLY=($(apt-cache policy | + command grep "release.o=Debian,a=$cur" | + command sed -e "s/.*a=\(\w*\).*/\1/" | uniq 2>/dev/null)) + return + ;; + esac + + if [[ $cur == -* ]]; then + local opts=" $($1 --help 2>&1 | command sed -e \ + 's/--with(out)-recommends/--without-recommends\n--with-recommends/' | + _parse_help - | tr '\n' ' ') " + + # Exclude some mutually exclusive options + for i in "${words[@]}"; do + [[ $i == -u ]] && opts=${opts/ -i / } + [[ $i == -i ]] && opts=${opts/ -u / } + done + + # Do known short -> long replacements; at least up to 0.8.12, --help + # outputs mostly only short ones. + COMPREPLY=($opts) + for i in "${!COMPREPLY[@]}"; do + case ${COMPREPLY[i]} in + -h) COMPREPLY[i]=--help ;; + -s) COMPREPLY[i]=--simulate ;; + -d) COMPREPLY[i]=--download-only ;; + -P) COMPREPLY[i]=--prompt ;; + -y) COMPREPLY[i]=--assume-yes ;; + -F) COMPREPLY[i]=--display-format ;; + -O) COMPREPLY[i]=--sort ;; + -W) COMPREPLY[i]=--show-why ;; + -w) COMPREPLY[i]=--width ;; + -V) COMPREPLY[i]=--show-versions ;; + -D) COMPREPLY[i]=--show-deps ;; + -v) COMPREPLY[i]=--verbose ;; + -t) COMPREPLY[i]=--target-release ;; + -q) COMPREPLY[i]=--quiet ;; + esac + done + + COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur")) + else + COMPREPLY=($(compgen -W 'update upgrade safe-upgrade forget-new + clean autoclean install reinstall remove hold unhold purge markauto + unmarkauto why why-not dist-upgrade full-upgrade download search + show forbid-version changelog keep keep-all build-dep add-user-tag + remove-user-tag versions' -- "$cur")) + fi + +} && + complete -F _aptitude -o default aptitude aptitude-curses + +# ex: filetype=sh diff --git a/completions/arch b/completions/arch new file mode 100644 index 0000000..afeed05 --- /dev/null +++ b/completions/arch @@ -0,0 +1,46 @@ +# mailman arch completion -*- shell-script -*- + +# Try to detect whether this is the mailman "arch" to avoid installing +# it for the coreutils/util-linux-ng one. +_have mailmanctl && + _arch() + { + local cur prev words cword split + _init_completion -s || return + + case $prev in + -w | -g | -d | --welcome-msg | --goodbye-msg | --digest) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + --file) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + local args=$cword + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == -* ]]; then + ((args--)) + fi + done + case $args in + 1) + _xfunc list_lists _mailman_lists + ;; + 2) + _filedir + ;; + esac + fi + + } && + complete -F _arch arch + +# ex: filetype=sh diff --git a/completions/arp b/completions/arp new file mode 100644 index 0000000..922e800 --- /dev/null +++ b/completions/arp @@ -0,0 +1,59 @@ +# arp(8) completion -*- shell-script -*- + +_arp() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --device | -!(-*)i) + _available_interfaces -a + return + ;; + --protocol | -!(-*)[Ap]) + # TODO protocol/address family + return + ;; + --file | -!(-*)f) + _filedir + return + ;; + --hw-type | -!(-*)[Ht]) + # TODO: parse from --help output? + COMPREPLY=($(compgen -W 'ash ether ax25 netrom rose arcnet \ + dlci fddi hippi irda x25 eui64' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + local args + _count_args "" "@(--device|--protocol|--file|--hw-type|-!(-*)[iApfHt])" + case $args in + 1) + local ips=$("$1" -an | command sed -ne \ + 's/.*(\([0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}\)).*/\1/p') + COMPREPLY=($(compgen -W '$ips' -- "$cur")) + ;; + 2) + # TODO if -d mode: "pub"; if not -f mode: hw_addr + # TODO hw_addr is a configured interface with --use-device/-*D* + ;; + 3) + # TODO netmask|pub|temp if -s mode + ;; + 4) + # TODO netmask value if previous was "netmask" + ;; + 5) + # TODO "pub" if 3rd was "netmask" + ;; + esac +} && + complete -F _arp arp + +# ex: filetype=sh diff --git a/completions/arping b/completions/arping new file mode 100644 index 0000000..57e1e19 --- /dev/null +++ b/completions/arping @@ -0,0 +1,31 @@ +# arping(8) completion -*- shell-script -*- + +_arping() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*c | -*w) + return + ;; + -*I) + _available_interfaces -a + return + ;; + -*s) + _ip_addresses + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + return + fi + + _known_hosts_real -- "$cur" +} && + complete -F _arping arping + +# ex: filetype=sh diff --git a/completions/arpspoof b/completions/arpspoof new file mode 100644 index 0000000..d1a1373 --- /dev/null +++ b/completions/arpspoof @@ -0,0 +1,28 @@ +# arpspoof completion -*- shell-script -*- + +_arpspoof() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -i) + _available_interfaces -a + return + ;; + -t) + _known_hosts_real -- "$cur" + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + else + _known_hosts_real -- "$cur" + fi + +} && + complete -F _arpspoof arpspoof + +# ex: filetype=sh diff --git a/completions/asciidoc b/completions/asciidoc new file mode 100644 index 0000000..1ea4abf --- /dev/null +++ b/completions/asciidoc @@ -0,0 +1,52 @@ +# asciidoc(1) completion -*- shell-script -*- + +_asciidoc_doctype() +{ + COMPREPLY+=($(compgen -W 'article book manpage' -- "$cur")) +} + +_asciidoc() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --attribute | -!(-*)a) + return + ;; + --backend | -!(-*)b) + COMPREPLY=($(compgen -W 'docbook html4 xhtml11' -- "$cur")) + return + ;; + --conf-file | -!(-*)f) + _filedir conf + return + ;; + --doctype | -!(-*)d) + _asciidoc_doctype + return + ;; + --help | -!(-*)h) + COMPREPLY=($(compgen -W 'manpage syntax topics' -- "$cur")) + return + ;; + --out-file | -!(-*)o) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" "--help manpage")' \ + -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir +} && + complete -F _asciidoc asciidoc asciidoc.py + +# ex: filetype=sh diff --git a/completions/aspell b/completions/aspell new file mode 100644 index 0000000..e080a07 --- /dev/null +++ b/completions/aspell @@ -0,0 +1,88 @@ +# bash completion for aspell -*- shell-script -*- + +_aspell_dictionary() +{ + local datadir aspell=${1:-aspell} + datadir=$($aspell config data-dir 2>/dev/null || echo /usr/lib/aspell) + # First, get aliases (dicts dump does not list them) + COMPREPLY=($(printf '%s\n' $datadir/*.alias)) + COMPREPLY=("${COMPREPLY[@]%.alias}") + COMPREPLY=("${COMPREPLY[@]#$datadir/}") + # Then, add the canonical dicts + COMPREPLY+=($($aspell dicts 2>/dev/null)) + COMPREPLY=($(compgen -X '\*' -W '${COMPREPLY[@]}' -- "$cur")) +} + +_aspell() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -c | -p | check | --conf | --personal | --repl | --per-conf) + _filedir + return + ;; + --conf-dir | --data-dir | --dict-dir | --home-dir | --local-data-dir | --prefix) + _filedir -d + return + ;; + dump | create | merge) + COMPREPLY=($(compgen -W 'master personal repl' -- "$cur")) + return + ;; + --mode) + COMPREPLY=($(compgen -W "$($1 modes 2>/dev/null | + awk '{ print $1 }')" -- "$cur")) + return + ;; + --sug-mode) + COMPREPLY=($(compgen -W 'ultra fast normal bad-speller' \ + -- "$cur")) + return + ;; + --keymapping) + COMPREPLY=($(compgen -W 'aspell ispell' -- "$cur")) + return + ;; + -d | --master) + _aspell_dictionary "$1" + return + ;; + --add-filter | --rem-filter) + COMPREPLY=($(compgen -W "$($1 filters 2>/dev/null | + awk '{ print $1 }')" -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--conf= --conf-dir= --data-dir= --dict-dir= + --encoding= --add-filter= --rem-filter= --mode= --add-extra-dicts= + --rem-extra-dicts= --home-dir= --ignore= --ignore-accents + --dont-ignore-accents --ignore-case --dont-ignore-case + --ignore-repl --dont-ignore-repl --jargon --keyboard= --lang= + --language-tag --local-data-dir= --master= --module + --add-module-search-order --rem-module-search-order --per-conf= + --personal= --prefix= --repl= --run-together --dont-run-together + --run-together-limit= --run-together-min= --save-repl + --dont-save-repl --set-prefix --dont-set-prefix --size= --spelling + --strip-accents --dont-strip-accents --sug-mode= + --add-word-list-path --rem-word-list-path --backup --dont-backup + --reverse --dont-reverse --time --dont-time --keymapping= + --add-email-quote= --rem-email-quote= --email-margin= + --add-tex-command= --rem-tex-command= --tex-check-comments + --dont-tex-check-comments --add-tex-extension --rem-tex-extension + --add-sgml-check= --rem-sgml-check= --add-sgml-extension + --rem-sgml-extension' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + COMPREPLY=($(compgen -W 'usage help check pipe list config soundslike + filter version dump create merge' -- "$cur")) + fi +} && + complete -F _aspell aspell + +# ex: filetype=sh diff --git a/completions/autoconf b/completions/autoconf new file mode 100644 index 0000000..b51e797 --- /dev/null +++ b/completions/autoconf @@ -0,0 +1,40 @@ +# autoconf(1) completion -*- shell-script -*- + +_autoconf() +{ + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + --help | -h | --version | -V | --trace | -t) + return + ;; + --output | -o) + _filedir + return + ;; + --warnings | -W) + local cats=(cross obsolete syntax) + COMPREPLY=($(compgen -W \ + '${cats[@]} ${cats[@]/#/no-} all none error' -- "$cur")) + return + ;; + --prepend-include | -B | --include | -I) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir '@(ac|in)' +} && + complete -F _autoconf autoconf + +# ex: filetype=sh diff --git a/completions/automake b/completions/automake new file mode 100644 index 0000000..5fe5f4f --- /dev/null +++ b/completions/automake @@ -0,0 +1,36 @@ +# automake(1) completion -*- shell-script -*- + +_automake() +{ + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + --help | --version) + return + ;; + --warnings | -W) + local cats=(gnu obsolete override portability syntax unsupported) + COMPREPLY=($(compgen -W \ + '${cats[@]} ${cats[@]/#/no-} all none error' -- "$cur")) + return + ;; + --libdir) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir +} && + complete -F _automake automake automake-1.1{0..6} + +# ex: filetype=sh diff --git a/completions/autoreconf b/completions/autoreconf new file mode 100644 index 0000000..9b0f0dc --- /dev/null +++ b/completions/autoreconf @@ -0,0 +1,41 @@ +# autoreconf(1) completion -*- shell-script -*- + +_autoreconf() +{ + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + --help | -h | --version | -V) + return + ;; + --warnings | -W) + local cats=(cross gnu obsolete override portability syntax + unsupported) + COMPREPLY=($(compgen -W \ + '${cats[@]} ${cats[@]/#/no-} all none error' -- "$cur")) + return + ;; + --prepend-include | -B | --include | -I) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + if [[ $1 == *autoheader ]]; then + _filedir '@(ac|in)' + else + _filedir -d + fi +} && + complete -F _autoreconf autoreconf autoheader + +# ex: filetype=sh diff --git a/completions/autorpm b/completions/autorpm new file mode 100644 index 0000000..d55322a --- /dev/null +++ b/completions/autorpm @@ -0,0 +1,14 @@ +# autorpm(8) completion -*- shell-script -*- + +_autorpm() +{ + local cur prev words cword + _init_completion || return + + COMPREPLY=($(compgen -W '--notty --debug --help --version auto add + fullinfo info help install list remove set' -- "$cur")) + +} && + complete -F _autorpm autorpm + +# ex: filetype=sh diff --git a/completions/autoscan b/completions/autoscan new file mode 100644 index 0000000..e007143 --- /dev/null +++ b/completions/autoscan @@ -0,0 +1,34 @@ +# autoscan(1) completion -*- shell-script -*- + +_autoscan() +{ + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + --help | --version | -!(-*)[hV]) + return + ;; + --prepend-include | --include | -!(-*)[BI]) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + if [[ $1 == *autoupdate ]]; then + _filedir '@(ac|in)' + else + _filedir -d + fi +} && + complete -F _autoscan autoscan autoupdate + +# ex: filetype=sh diff --git a/completions/avctrl b/completions/avctrl new file mode 100644 index 0000000..89c24e4 --- /dev/null +++ b/completions/avctrl @@ -0,0 +1,20 @@ +# avctrl completion -*- shell-script -*- + +_avctrl() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--help --quiet' -- "$cur")) + else + local args + _count_args + if ((args == 1)); then + COMPREPLY=($(compgen -W 'discover switch' -- "$cur")) + fi + fi +} && + complete -F _avctrl avctrl + +# ex: filetype=sh diff --git a/completions/badblocks b/completions/badblocks new file mode 100644 index 0000000..29c4e00 --- /dev/null +++ b/completions/badblocks @@ -0,0 +1,29 @@ +# badblocks(8) completion -*- shell-script -*- + +_badblocks() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*[bcedpt]) + return + ;; + -*[io]) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + # Filter out -w (dangerous) and -X (internal use) + COMPREPLY=($(compgen -X -[wX] -W '$(_parse_usage "$1")' -- "$cur")) + return + fi + + cur=${cur:=/dev/} + _filedir +} && + complete -F _badblocks badblocks + +# ex: filetype=sh diff --git a/completions/bind b/completions/bind new file mode 100644 index 0000000..2ee428b --- /dev/null +++ b/completions/bind @@ -0,0 +1,36 @@ +# bash bind completion -*- shell-script -*- + +_bind() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*[lpPsSvVrxX]) + return + ;; + -*m) + COMPREPLY=($(compgen -W "emacs emacs-standard emacs-meta + emacs-ctlx vi vi-move vi-command vi-insert" -- "$cur")) + return + ;; + -*f) + _filedir + return + ;; + -*[qu]) + COMPREPLY=($(compgen -W '$("$1" -l)' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + return + fi + + COMPREPLY=($(compgen -A binding -- "$cur")) +} && + complete -F _bind bind + +# ex: filetype=sh diff --git a/completions/bk b/completions/bk new file mode 100644 index 0000000..4e4d140 --- /dev/null +++ b/completions/bk @@ -0,0 +1,18 @@ +# BitKeeper completion -*- shell-script -*- +# adapted from code by Bart Trojanowski <bart@jukie.net> + +_bk() +{ + local cur prev words cword + _init_completion || return + + local BKCMDS="$(bk help topics 2>/dev/null | + awk '/^ bk/ { print $2 }' | xargs printf '%s ')" + + COMPREPLY=($(compgen -W "$BKCMDS" -- "$cur")) + _filedir + +} && + complete -F _bk bk + +# ex: filetype=sh diff --git a/completions/brctl b/completions/brctl new file mode 100644 index 0000000..14569b6 --- /dev/null +++ b/completions/brctl @@ -0,0 +1,40 @@ +# bash completion for brctl -*- shell-script -*- + +_brctl() +{ + local cur prev words cword + _init_completion || return + + local command=${words[1]} + + case $cword in + 1) + COMPREPLY=($(compgen -W "addbr delbr addif delif setageing + setbridgeprio setfd sethello setmaxage setpathcost setportprio + show showmacs showstp stp" -- "$cur")) + ;; + 2) + case $command in + show) ;; + + *) + COMPREPLY=($(compgen -W "$($1 show | + awk 'NR>1 {print $1}')" -- "$cur")) + ;; + esac + ;; + 3) + case $command in + addif | delif) + _configured_interfaces + ;; + stp) + COMPREPLY=($(compgen -W 'on off' -- "$cur")) + ;; + esac + ;; + esac +} && + complete -F _brctl -o default brctl + +# ex: filetype=sh diff --git a/completions/btdownloadheadless.py b/completions/btdownloadheadless.py new file mode 100644 index 0000000..a470e53 --- /dev/null +++ b/completions/btdownloadheadless.py @@ -0,0 +1,32 @@ +# btdownloadheadless(1) completion -*- shell-script -*- + +_btdownload() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --responsefile | --saveas) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--max_uploads --keepalive_interval + --download_slice_size --request_backlog --max_message_length + --ip --minport --maxport --responsefile --url --saveas --timeout + --timeout_check_interval --max_slice_length --max_rate_period + --bind --upload_rate_fudge --display_interval --rerequest_interval + --min_peers --http_timeout --max_initiate --max_allow_in + --check_hashes --max_upload_rate --snub_time --spew + --rarest_first_cutoff --min_uploads --report_hash_failures' \ + -- "$cur")) + else + _filedir + fi +} && + complete -F _btdownload btdownloadheadless.py btdownloadcurses.py \ + btdownloadgui.py + +# ex: filetype=sh diff --git a/completions/bts b/completions/bts new file mode 100644 index 0000000..d535d13 --- /dev/null +++ b/completions/bts @@ -0,0 +1,112 @@ +# bts completion -*- shell-script -*- + +# List bug numbers from bugs cache in ~/.devscripts_cache/bts +_cached_bugs() +{ + [[ -d $HOME/.devscripts_cache/bts ]] && + find $HOME/.devscripts_cache/bts -maxdepth 1 -name "${cur}[0-9]*.html" \ + -printf "%f\n" | cut -d'.' -f1 +} + +# List APT source packages prefixed with "src:" +_src_packages_with_prefix() +{ + ppn=${cur:4} # partial package name, after stripping "src:" + compgen -P "src:" -W '$(_xfunc apt-cache _apt_cache_sources "$ppn")' \ + -- "$ppn" +} + +_bts() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + show | bugs) + COMPREPLY=($(compgen -W 'release-critical RC from: tag: + usertag:' -- "$cur") $(_cached_bugs) + $(_src_packages_with_prefix)) + return + ;; + select) + COMPREPLY=($(compgen -W 'package: source: maintainer: submitter: + severity: status: tag: owner: correspondent: affects: bugs: + users: archive:' -- "$cur")) + return + ;; + status) + COMPREPLY=($(compgen -W 'file: fields: verbose' -- "$cur") + $(_cached_bugs)) + return + ;; + block | unblock) + COMPREPLY=($(compgen -W 'by with' -- "$cur")) + return + ;; + severity) + COMPREPLY=($(compgen -W 'wishlist minor normal important serious + grave critical' -- "$cur")) + return + ;; + limit) + COMPREPLY=($(compgen -W 'submitter date subject msgid package + source tag severity owner affects archive' -- "$cur")) + return + ;; + clone | "done" | reopen | archive | unarchive | retitle | summary | submitter | found | notfound | fixed | notfixed | merge | forcemerge | unmerge | claim | unclaim | forwarded | notforwarded | owner | noowner | subscribe | unsubscribe | reportspam | spamreport | affects | usertag | usertags | reassign | tag | tags) + COMPREPLY=($(_cached_bugs)) + return + ;; + package) + COMPREPLY=($(_xfunc apt-cache _apt_cache_packages)) + return + ;; + cache) + COMPREPLY=($(_xfunc apt-cache _apt_cache_packages) + $(_src_packages_with_prefix) + $(compgen -W 'from: release-critical RC' -- "$cur")) + return + ;; + cleancache) + COMPREPLY=($(_xfunc apt-cache _apt_cache_packages) + $(_src_packages_with_prefix) + $(compgen -W 'from: tag: usertag: ALL' -- "$cur")) + return + ;; + user) + # non-predicible arguments + COMPREPLY=() + return + ;; + :) + # Chances are that "src:<src_package>" is being completed + # COMP_WORDS would be: "bts cleancache src : <partial_pkg_name>" + pos=$((COMP_CWORD - 2)) + if [[ $pos -gt 0 && ${COMP_WORDS[pos]} == "src" ]]; then + COMPREPLY=($(_xfunc apt-cache _apt_cache_src_packages)) + return + fi + ;; + esac + + $split && return + + COMPREPLY=($(compgen -W '--offline --online --no-offline + --no-action --cache --no-cache --cache-mode --cache-delay --mbox + --mailreader --cc-addr --use-default-cc --no-use-default-cc + --sendmail --mutt --no-mutt --smtp-host --smtp-username + --smtp-helo --bts-server --force-refresh --no-force-refresh + --only-new --include-resolved --no-include-resolved --no-ack --ack + --interactive --force-interactive --no-interactive --quiet + --no-conf --noconf + show bugs select status clone done reopen archive unarchive retitle + summary submitter reassign found notfound fixed notfixed block unblock + merge forcemerge unmerge tag tags affects user usertag usertags claim + unclaim severity forwarded notforwarded package limit owner noowner + subscribe unsubscribe reportspam spamreport cache cleancache version + help' -- "$cur")) + +} && + complete -F _bts bts + +# ex: filetype=sh diff --git a/completions/bzip2 b/completions/bzip2 new file mode 100644 index 0000000..40e50fe --- /dev/null +++ b/completions/bzip2 @@ -0,0 +1,42 @@ +# bash completion for bzip2 -*- shell-script -*- + +_bzip2() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | -!(-*)[bhp]) + return + ;; + -!(-*)n) + COMPREPLY=($(compgen -W "{1..$(_ncpus)}" -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + local helpopts=$(_parse_help "$1") + COMPREPLY=($(compgen -W "${helpopts//#/} -2 -3 -4 -5 -6 -7 -8 -9" \ + -- "$cur")) + return + fi + + local IFS=$'\n' xspec="*.?(t)bz2" + + if [[ $prev == --* ]]; then + [[ $prev == --@(decompress|list|test) ]] && xspec="!"$xspec + [[ $prev == --compress ]] && xspec= + elif [[ $prev == -* ]]; then + [[ $prev == -*[dt]* ]] && xspec="!"$xspec + [[ $prev == -*z* ]] && xspec= + fi + + _tilde "$cur" || return + + compopt -o filenames + COMPREPLY=($(compgen -f -X "$xspec" -- "$cur") $(compgen -d -- "$cur")) +} && + complete -F _bzip2 bzip2 pbzip2 lbzip2 + +# ex: filetype=sh diff --git a/completions/cancel b/completions/cancel new file mode 100644 index 0000000..3e0c1d5 --- /dev/null +++ b/completions/cancel @@ -0,0 +1,27 @@ +# cancel(1) completion -*- shell-script -*- + +_cancel() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h) + _known_hosts_real -- "$cur" + return + ;; + -U) + return + ;; + -u) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + esac + + COMPREPLY=($(compgen -W \ + "$(lpstat 2>/dev/null | cut -d' ' -f1)" -- "$cur")) +} && + complete -F _cancel cancel + +# ex: filetype=sh diff --git a/completions/cardctl b/completions/cardctl new file mode 100644 index 0000000..bb3a0db --- /dev/null +++ b/completions/cardctl @@ -0,0 +1,15 @@ +# Linux cardctl(8) completion -*- shell-script -*- + +_cardctl() +{ + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + COMPREPLY=($(compgen -W 'status config ident suspend resume reset + eject insert scheme' -- "$cur")) + fi +} && + complete -F _cardctl cardctl pccardctl + +# ex: filetype=sh diff --git a/completions/carton b/completions/carton new file mode 100644 index 0000000..5d700c8 --- /dev/null +++ b/completions/carton @@ -0,0 +1,81 @@ +# carton(3pm) completion -*- shell-script -*- + +_carton_commands() +{ + local cmds=$("${1:-carton}" usage 2>&1 | + command sed -ne '/.*command.* is one of/{n;p;q;}') + COMPREPLY+=($(IFS="$IFS," compgen -W "$cmds" -- "$cur")) +} + +_carton_command_help() +{ + local help=$(PERLDOC_PAGER=cat PERLDOC=-otext "${1:-carton}" -h $2 2>&1) + COMPREPLY+=($(compgen -W '$help' -- "$cur")) +} + +_carton() +{ + local cur prev words cword split + _init_completion -s || return + + local i command + for ((i = 1; i < cword; i++)); do + case ${words[i]} in + -*) ;; + *) + command=${words[i]} + break + ;; + esac + done + + if [[ ! -v command ]]; then + _carton_commands "$1" + return + fi + + case $prev in + --version | -v) + return + ;; + --help | -h) + [[ -n $command ]] || _carton_commands "$1" + return + ;; + --cpanfile) + if [[ $command == install ]]; then + _filedir + return + fi + ;; + --path) + if [[ $command == install ]]; then + _filedir -d + return + fi + ;; + --without) + if [[ $command == install ]]; then + local phases="configure build test runtime develop" + COMPREPLY+=($(compgen -W '$phases' -- "$cur")) + return + fi + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + [[ $command == @(help|usage) ]] || COMPREPLY=(--help) + _carton_command_help "$1" $command + fi + + case $command in + show | update) + : # TODO modules completion + ;; + esac +} && + complete -F _carton carton + +# ex: filetype=sh diff --git a/completions/ccache b/completions/ccache new file mode 100644 index 0000000..80c39de --- /dev/null +++ b/completions/ccache @@ -0,0 +1,38 @@ +# ccache(1) completion -*- shell-script -*- + +_ccache() +{ + local cur prev words cword split + _init_completion -s || return + + local i + for ((i = 1; i <= COMP_CWORD; i++)); do + if [[ ${COMP_WORDS[i]} != -* ]]; then + _command_offset $i + return + fi + [[ ${COMP_WORDS[i]} == -*[oFM] ]] && ((i++)) + done + + case $prev in + --help | --version | --max-files | --max-size | -!(-*)[hVFM]) + return + ;; + --set-config | -!(-*)o) + if [[ $cur != *=* ]]; then + COMPREPLY=($(compgen -S = -W "$($1 -p 2>/dev/null | + awk '$3 = "=" { print $2 }')" -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi + return + ;; + esac + + $split && return + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace +} && + complete -F _ccache ccache + +# ex: filetype=sh diff --git a/completions/ccze b/completions/ccze new file mode 100644 index 0000000..35f4c3f --- /dev/null +++ b/completions/ccze @@ -0,0 +1,44 @@ +# ccze(1) completion -*- shell-script -*- + +_ccze() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -'?' | --help | --usage | -V | --version) + return + ;; + --argument | --color | -!(-*)[ac]) + # TODO? + return + ;; + --rcfile | -!(-*)F) + _filedir + return + ;; + --mode | -!(-*)m) + COMPREPLY=($(compgen -W "curses ansi html" -- "$cur")) + return + ;; + --option | -!(-*)o) + local -a opts=(scroll wordcolor lookups transparent cssfile) + COMPREPLY=($(compgen -W '${opts[@]} ${opts[@]/#/no}' -- "$cur")) + return + ;; + --plugin | -!(-*)p) + COMPREPLY=($(compgen -W '$("$1" --list-plugins | command \ + sed -ne "s/^\([a-z0-9]\{1,\}\)[[:space:]]\{1,\}|.*/\1/p")' \ + -- "$cur")) + return + ;; + esac + + $split && return + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace +} && + complete -F _ccze ccze + +# ex: filetype=sh diff --git a/completions/cfagent b/completions/cfagent new file mode 100644 index 0000000..e7ba04d --- /dev/null +++ b/completions/cfagent @@ -0,0 +1,21 @@ +# cfagent completion -*- shell-script -*- + +_cfagent() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -f | --file) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + fi +} && + complete -F _cfagent cfagent + +# ex: filetype=sh diff --git a/completions/cfrun b/completions/cfrun new file mode 100644 index 0000000..72b6138 --- /dev/null +++ b/completions/cfrun @@ -0,0 +1,47 @@ +# cfrun completion -*- shell-script -*- + +_cfrun() +{ + local cur prev words cword + _init_completion || return + + local i section=1 + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == -- ]]; then + ((section++)) + fi + done + + case $section in + 1) + case $prev in + -f) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-f -h -d -S -T -v' -- "$cur")) + else + local hostfile=${CFINPUTS:-/var/lib/cfengine/inputs}/cfrun.hosts + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == -f ]]; then + hostfile=${words[i + 1]} + break + fi + done + [[ ! -f $hostfile ]] && return + + COMPREPLY=($(compgen -W "$(command grep -v \ + -E '(=|^$|^#)' $hostfile)" -- "$cur")) + fi + ;; + 2) + COMPREPLY=($(compgen -W '$(_parse_help cfagent)' -- "$cur")) + ;; + esac +} && + complete -F _cfrun cfrun + +# ex: filetype=sh diff --git a/completions/chage b/completions/chage new file mode 100644 index 0000000..fcf87cd --- /dev/null +++ b/completions/chage @@ -0,0 +1,30 @@ +# chage(1) completion -*- shell-script -*- + +_chage() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --lastday | --expiredate | --help | --inactive | --mindays | --maxdays | \ + --warndays | -!(-*)[dEhImMW]) + return + ;; + --root | -!(-*)R) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + COMPREPLY=($(compgen -u -- "$cur")) +} && + complete -F _chage chage + +# ex: filetype=sh diff --git a/completions/change_pw b/completions/change_pw new file mode 100644 index 0000000..04837ea --- /dev/null +++ b/completions/change_pw @@ -0,0 +1,25 @@ +# mailman change_pw completion -*- shell-script -*- + +_change_pw() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -l | --listname) + _xfunc list_lists _mailman_lists + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--all --domain --listname --password --quiet + --help' -- "$cur")) + fi + +} && + complete -F _change_pw change_pw + +# ex: filetype=sh diff --git a/completions/check_db b/completions/check_db new file mode 100644 index 0000000..aaec99f --- /dev/null +++ b/completions/check_db @@ -0,0 +1,17 @@ +# mailman check_db completion -*- shell-script -*- + +_check_db() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--all --verbose --help' -- "$cur")) + else + _xfunc list_lists _mailman_lists + fi + +} && + complete -F _check_db check_db + +# ex: filetype=sh diff --git a/completions/check_perms b/completions/check_perms new file mode 100644 index 0000000..8ff276e --- /dev/null +++ b/completions/check_perms @@ -0,0 +1,15 @@ +# mailman check_perms completion -*- shell-script -*- + +_check_perms() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-f -v -h' -- "$cur")) + fi + +} && + complete -F _check_perms check_perms + +# ex: filetype=sh diff --git a/completions/checksec b/completions/checksec new file mode 100644 index 0000000..fc2fef7 --- /dev/null +++ b/completions/checksec @@ -0,0 +1,37 @@ +# bash completion for checksec -*- shell-script -*- + +_checksec() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --version | --help) + return + ;; + --file | --fortify-file) + _filedir + return + ;; + --dir) + _filedir -d + return + ;; + --proc) + _pnames + return + ;; + --proc-libs | --fortify-proc) + _pids + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi +} && + complete -F _checksec checksec + +# ex: filetype=sh diff --git a/completions/chgrp b/completions/chgrp new file mode 100644 index 0000000..4793a45 --- /dev/null +++ b/completions/chgrp @@ -0,0 +1,39 @@ +# chgrp(1) completion -*- shell-script -*- + +_chgrp() +{ + local cur prev words cword split + _init_completion -s || return + + cur=${cur//\\\\/} + + if [[ $prev == --reference ]]; then + _filedir + return + fi + + $split && return + + # options completion + if [[ $cur == -* ]]; then + local w opts + for w in "${words[@]}"; do + [[ $w == -@(R|-recursive) ]] && opts="-H -L -P" && break + done + COMPREPLY=($(compgen -W '-c -h -f -R -v --changes --dereference + --no-dereference --silent --quiet --reference --recursive --verbose + --help --version $opts' -- "$cur")) + return + fi + + # first parameter on line or first since an option? + if [[ $cword -eq 1 && $cur != -* || $prev == -* ]]; then + _allowed_groups "$cur" + else + _filedir + fi + +} && + complete -F _chgrp chgrp + +# ex: filetype=sh diff --git a/completions/chkconfig b/completions/chkconfig new file mode 100644 index 0000000..8ff6637 --- /dev/null +++ b/completions/chkconfig @@ -0,0 +1,37 @@ +# chkconfig(8) completion -*- shell-script -*- + +_chkconfig() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --level=[1-6] | [1-6] | --list | --add | --del | --override) + _services + _xinetd_services + return + ;; + --level) + COMPREPLY=($(compgen -W '{1..6}' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--list --add --del --override --level' \ + -- "$cur")) + else + if ((cword == 2 || cword == 4)); then + COMPREPLY=($(compgen -W 'on off reset resetpriorities' \ + -- "$cur")) + else + _services + _xinetd_services + fi + fi +} && + complete -F _chkconfig chkconfig + +# ex: filetype=sh diff --git a/completions/chmod b/completions/chmod new file mode 100644 index 0000000..d3fc349 --- /dev/null +++ b/completions/chmod @@ -0,0 +1,41 @@ +# chmod(1) completion -*- shell-script -*- + +_chmod() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version) + return + ;; + --reference) + _filedir + return + ;; + esac + + $split && return + + # Adapted from coreutils 8.28 chmod man page + local modearg="-@(@(+([rwxXst])|[ugo])|+([0-7]))" + + # shellcheck disable=SC2053 + if [[ $cur == -* && $cur != $modearg ]]; then + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + local args + _count_args "" "" "$modearg" + + case $args in + 1) ;; # mode + *) _filedir ;; + esac +} && + complete -F _chmod chmod + +# ex: filetype=sh diff --git a/completions/chown b/completions/chown new file mode 100644 index 0000000..1d746b7 --- /dev/null +++ b/completions/chown @@ -0,0 +1,46 @@ +# chown(1) completion -*- shell-script -*- + +_chown() +{ + local cur prev words cword split + # Don't treat user:group as separate words. + _init_completion -s -n : || return + + case "$prev" in + --from) + _usergroup + return + ;; + --reference) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + # Complete -options + local w opts + for w in "${words[@]}"; do + [[ $w == -@(R|-recursive) ]] && opts="-H -L -P" && break + done + COMPREPLY=($(compgen -W '-c -h -f -R -v --changes --dereference + --no-dereference --from --silent --quiet --reference --recursive + --verbose --help --version $opts' -- "$cur")) + else + local args + + # The first argument is an usergroup; the rest are filedir. + _count_args : + + if ((args == 1)); then + _usergroup -u + else + _filedir + fi + fi +} && + complete -F _chown chown + +# ex: filetype=sh diff --git a/completions/chpasswd b/completions/chpasswd new file mode 100644 index 0000000..3abea99 --- /dev/null +++ b/completions/chpasswd @@ -0,0 +1,30 @@ +# chpasswd(8) completion -*- shell-script -*- + +_chpasswd() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --crypt | -!(-*)c) + COMPREPLY=($(compgen -W 'DES MD5 NONE SHA256 SHA512' \ + -- "$cur")) + return + ;; + --sha-rounds | -!(-*)s) + return + ;; + --root | -!(-*)R) + _filedir -d + return + ;; + esac + + $split && return + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace +} && + complete -F _chpasswd chpasswd + +# ex: filetype=sh diff --git a/completions/chromium-browser b/completions/chromium-browser new file mode 100644 index 0000000..9ee9896 --- /dev/null +++ b/completions/chromium-browser @@ -0,0 +1,50 @@ +# chromium-browser completion -*- shell-script -*- + +_chromium_browser() +{ + local cur prev words cword split + _init_completion -s -n : || return + + case $prev in + --help | --app | --proxy-pac-url | -h) + return + ;; + --user-data-dir) + _filedir -d + return + ;; + --proxy-server) + case $cur in + *://*) + local prefix="${cur%%://*}://" + _known_hosts_real -- "${cur#*://}" + COMPREPLY=("${COMPREPLY[@]/#/$prefix}") + __ltrim_colon_completions "$cur" + ;; + *) + compopt -o nospace + COMPREPLY=($(compgen -S :// -W 'http socks socks4 socks5' -- "$cur")) + ;; + esac + return + ;; + --password-store) + COMPREPLY=($(compgen -W 'basic gnome kwallet' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir "@(?([mxs])htm?(l)|pdf|txt)" +} && + complete -F _chromium_browser chromium-browser google-chrome \ + google-chrome-stable chromium chrome + +# ex: filetype=sh diff --git a/completions/chronyc b/completions/chronyc new file mode 100644 index 0000000..e6bb8e9 --- /dev/null +++ b/completions/chronyc @@ -0,0 +1,61 @@ +# chronyc(1) completion -*- shell-script -*- + +_chronyc_command_args() +{ + local -a args + args=($(compgen -W "$($1 help 2>/dev/null | + awk '/^'$prev'\s[^ []/ { gsub("\\|", " ", $2); print $2 }')")) + case $args in + \<address\>) _known_hosts_real -- "$cur" ;; + \<*) ;; + *) COMPREPLY+=($(compgen -W '${args[@]}' -- "$cur")) ;; + esac +} + +_chronyc() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | -*p) + return + ;; + -*h) + _known_hosts_real -- "$cur" + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1") -6' -- "$cur")) + return + fi + + local i args + args=0 + for ((i = 1; i < cword; i++)); do + [[ ${words[i]} != -* && ${words[i - 1]} != @(-p|-h) ]] && ((args++)) + done + + case $args in + 0) + COMPREPLY=($(compgen -W "$($1 help 2>/dev/null | + awk '!/(^ |: *$)/ { sub("\\|", " ", $1); print $1 }')" \ + -- "$cur")) + ;; + 1) + _chronyc_command_args "$1" + if [[ ! ${COMPREPLY-} && $prev == sources?(tats) ]]; then + # [-v] not handled by _chronyc_command_args yet + COMPREPLY=($(compgen -W '-v' -- "$cur")) + fi + ;; + 2) + [[ $prev == @(peer|server) ]] && _known_hosts_real -- "$cur" + ;; + esac +} && + complete -F _chronyc chronyc + +# ex: filetype=sh diff --git a/completions/chrpath b/completions/chrpath new file mode 100644 index 0000000..2883967 --- /dev/null +++ b/completions/chrpath @@ -0,0 +1,27 @@ +# chrpath(1) completion -*- shell-script -*- + +_chrpath() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --version | --help | -!(-*)[vh]) + return + ;; + --replace | -!(-*)r) + _filedir -d + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + _filedir +} && + complete -F _chrpath chrpath + +# ex: filetype=sh diff --git a/completions/cksfv b/completions/cksfv new file mode 100644 index 0000000..da404dd --- /dev/null +++ b/completions/cksfv @@ -0,0 +1,29 @@ +# cksfv completion by Chris <xris@forevermore.net> -*- shell-script -*- + +_cksfv() +{ + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + case "$prev" in + -*C | -*g) + _filedir -d + return + ;; + -*f) + _filedir 'sfv' + return + ;; + esac + + _filedir + +} && + complete -F _cksfv cksfv + +# ex: filetype=sh diff --git a/completions/cleanarch b/completions/cleanarch new file mode 100644 index 0000000..0f7d5f5 --- /dev/null +++ b/completions/cleanarch @@ -0,0 +1,16 @@ +# mailman cleanarch completion -*- shell-script -*- + +_cleanarch() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--status --dry-run --quiet --help' \ + -- "$cur")) + fi + +} && + complete -F _cleanarch cleanarch + +# ex: filetype=sh diff --git a/completions/clisp b/completions/clisp new file mode 100644 index 0000000..c4259a0 --- /dev/null +++ b/completions/clisp @@ -0,0 +1,22 @@ +# -*- shell-script -*- +# bash brogrammable completion for various Common Lisp implementations by +# Nikodemus Siivola <nikodemus@random-state.net> + +_clisp() +{ + local cur prev words cword + _init_completion || return + + # completing an option (may or may not be separated by a space) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-h --help --version --license -B -K -M -m -L + -N -E -q --quiet --silent -w -I -ansi -traditional -p -C -norc -i + -c -l -o -x ' -- "$cur")) + else + _filedir + fi + +} && + complete -F _clisp -o default clisp + +# ex: filetype=sh diff --git a/completions/clone_member b/completions/clone_member new file mode 100644 index 0000000..a3ca2b3 --- /dev/null +++ b/completions/clone_member @@ -0,0 +1,25 @@ +# mailman clone_member completion -*- shell-script -*- + +_clone_member() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -l | --listname) + _xfunc list_lists _mailman_lists + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--listname --remove --admin --quiet + --nomodify --help' -- "$cur")) + fi + +} && + complete -F _clone_member clone_member + +# ex: filetype=sh diff --git a/completions/complete b/completions/complete new file mode 100644 index 0000000..a57f366 --- /dev/null +++ b/completions/complete @@ -0,0 +1,49 @@ +# bash complete completion -*- shell-script -*- + +_complete() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*o) + COMPREPLY=($(compgen -W 'bashdefault default dirnames filenames + nospace plusdirs' -- "$cur")) + return + ;; + + -*A) + COMPREPLY=($(compgen -W 'alias arrayvar binding builtin command + directory disabled enabled export file function group helptopic + hostname job keyword running service setopt shopt signal + stopped user variable' -- "$cur")) + return + ;; + + -*C) + COMPREPLY=($(compgen -A command -- "$cur")) + return + ;; + -*F) + COMPREPLY=($(compgen -A function -- "$cur")) + return + ;; + -*p | -*r) + COMPREPLY=($(complete -p | command sed -e 's|.* ||')) + COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + # relevant options completion + local opts="-a -b -c -d -e -f -g -j -k -o -s -u -v -A -G -W -P -S -X" + [[ $1 != compgen ]] && opts+=" -F -C" + COMPREPLY=($(compgen -W "$opts" -- "$cur")) + else + COMPREPLY=($(compgen -A command -- "$cur")) + fi +} && + complete -F _complete compgen complete + +# ex: filetype=sh diff --git a/completions/config_list b/completions/config_list new file mode 100644 index 0000000..1807e33 --- /dev/null +++ b/completions/config_list @@ -0,0 +1,27 @@ +# mailman config_list completion -*- shell-script -*- + +_config_list() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -i | -o | --inputfile | --outputfile) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--inputfile --outputfile --checkonly + --verbose --help' -- "$cur")) + else + _xfunc list_lists _mailman_lists + fi + +} && + complete -F _config_list config_list + +# ex: filetype=sh diff --git a/completions/configure b/completions/configure new file mode 100644 index 0000000..3f59a01 --- /dev/null +++ b/completions/configure @@ -0,0 +1,42 @@ +# bash completion for configure -*- shell-script -*- + +_configure() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -h | --help | -V | --version | --program-prefix | --program-suffix | \ + --program-transform-name) + return + ;; + --*file) + _filedir + return + ;; + --*prefix | --*dir) + _filedir -d + return + ;; + esac + + $split && return + + # if $COMP_CONFIGURE_HINTS is not null, then completions of the form + # --option=SETTING will include 'SETTING' as a contextual hint + [[ $cur != -* ]] && return + + if [[ ${COMP_CONFIGURE_HINTS-} ]]; then + COMPREPLY=($(compgen -W "$($1 --help 2>&1 | + awk '/^ --[A-Za-z]/ { print $1; \ + if ($2 ~ /--[A-Za-z]/) print $2 }' | command sed -e 's/[[,].*//g')" \ + -- "$cur")) + [[ ${COMPREPLY-} == *=* ]] && compopt -o nospace + else + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _configure configure + +# ex: filetype=sh diff --git a/completions/convert b/completions/convert new file mode 100644 index 0000000..ef7baea --- /dev/null +++ b/completions/convert @@ -0,0 +1,324 @@ +# bash completion for ImageMagick -*- shell-script -*- + +_ImageMagick() +{ + case $prev in + -channel) + COMPREPLY=($(compgen -W 'Red Green Blue Opacity Matte Cyan + Magenta Yellow Black' -- "$cur")) + return + ;; + -colormap) + COMPREPLY=($(compgen -W 'shared private' -- "$cur")) + return + ;; + -colorspace) + COMPREPLY=($(compgen -W 'GRAY OHTA RGB Transparent XYZ YCbCr YIQ + YPbPr YUV CMYK' -- "$cur")) + return + ;; + -compose) + COMPREPLY=($(compgen -W 'Over In Out Atop Xor Plus Minus Add + Subtract Difference Multiply Bumpmap Copy CopyRed CopyGreen + CopyBlue CopyOpacity' -- "$cur")) + return + ;; + -compress) + COMPREPLY=($(compgen -W 'None BZip Fax Group4 JPEG Lossless LZW + RLE Zip' -- "$cur")) + return + ;; + -dispose) + COMPREPLY=($(compgen -W 'Undefined None Background Previous' \ + -- "$cur")) + return + ;; + -encoding) + COMPREPLY=($(compgen -W 'AdobeCustom AdobeExpert AdobeStandard + AppleRoman BIG5 GB2312 Latin2 None SJIScode Symbol Unicode + Wansung' -- "$cur")) + return + ;; + -endian) + COMPREPLY=($(compgen -W 'MSB LSB' -- "$cur")) + return + ;; + -filter) + COMPREPLY=($(compgen -W 'Point Box Triangle Hermite Hanning + Hamming Blackman Gaussian Quadratic Cubic Catrom Mitchell + Lanczos Bessel Sinc' -- "$cur")) + return + ;; + -format) + COMPREPLY=($(compgen -W "$(convert -list format | awk \ + '/ [r-][w-][+-] / { sub("[*]$","",$1); print tolower($1) }')" \ + -- "$cur")) + return + ;; + -gravity) + COMPREPLY=($(compgen -W 'Northwest North NorthEast West Center + East SouthWest South SouthEast' -- "$cur")) + return + ;; + -intent) + COMPREPLY=($(compgen -W 'Absolute Perceptual Relative + Saturation' -- "$cur")) + return + ;; + -interlace) + COMPREPLY=($(compgen -W 'None Line Plane Partition' -- "$cur")) + return + ;; + -limit) + COMPREPLY=($(compgen -W 'Disk File Map Memory' -- "$cur")) + return + ;; + -list) + COMPREPLY=($(compgen -W 'Delegate Format Magic Module Resource + Type' -- "$cur")) + return + ;; + -map) + COMPREPLY=($(compgen -W 'best default gray red green blue' \ + -- "$cur")) + _filedir + return + ;; + -noise) + COMPREPLY=($(compgen -W 'Uniform Gaussian Multiplicative + Impulse Laplacian Poisson' -- "$cur")) + return + ;; + -preview) + COMPREPLY=($(compgen -W 'Rotate Shear Roll Hue Saturation + Brightness Gamma Spiff Dull Grayscale Quantize Despeckle + ReduceNoise AddNoise Sharpen Blur Treshold EdgeDetect Spread + Shade Raise Segment Solarize Swirl Implode Wave OilPaint + CharcoalDrawing JPEG' -- "$cur")) + return + ;; + -mask | -profile | -texture | -tile | -write) + _filedir + return + ;; + -type) + COMPREPLY=($(compgen -W 'Bilevel Grayscale Palette PaletteMatte + TrueColor TrueColorMatte ColorSeparation ColorSeparationlMatte + Optimize' -- "$cur")) + return + ;; + -units) + COMPREPLY=($(compgen -W 'Undefined PixelsPerInch + PixelsPerCentimeter' -- "$cur")) + return + ;; + -virtual-pixel) + COMPREPLY=($(compgen -W 'Constant Edge mirror tile' -- "$cur")) + return + ;; + -visual) + COMPREPLY=($(compgen -W 'StaticGray GrayScale StaticColor + PseudoColor TrueColor DirectColor defaut visualid' \ + -- "$cur")) + return + ;; + esac + + return 1 +} + +_convert() +{ + local cur prev words cword + _init_completion || return + + _ImageMagick && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + elif [[ $cur == +* ]]; then + COMPREPLY=($(compgen -W '+adjoin +append +compress +contrast +debug + +dither +endian +gamma +label +map +mask +matte +negate +noise + +page +raise +render +write' -- "$cur")) + else + _filedir + fi +} && + complete -F _convert convert + +_mogrify() +{ + local cur prev words cword + _init_completion || return + + _ImageMagick && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + elif [[ $cur == +* ]]; then + COMPREPLY=($(compgen -W '+compress +contrast +debug +dither +endian + +gamma +label +map +mask +matte +negate +page +raise' -- "$cur")) + else + _filedir + fi +} && + complete -F _mogrify mogrify + +_display() +{ + local cur prev words cword + _init_completion || return + + _ImageMagick && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + elif [[ $cur == +* ]]; then + COMPREPLY=($(compgen -W '+compress +contrast +debug +dither +endian + +gamma +label +map +matte +negate +page +raise +write' -- "$cur")) + else + _filedir + fi +} && + complete -F _display display + +_animate() +{ + local cur prev words cword + _init_completion || return + + _ImageMagick && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + elif [[ $cur == +* ]]; then + COMPREPLY=($(compgen -W '+debug +dither +gamma +map +matte' \ + -- "$cur")) + else + _filedir + fi +} && + complete -F _animate animate + +_identify() +{ + local cur prev words cword + _init_completion || return + + _ImageMagick && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + elif [[ $cur == +* ]]; then + COMPREPLY=($(compgen -W '+debug' -- "$cur")) + else + _filedir + fi +} && + complete -F _identify identify + +_montage() +{ + local cur prev words cword + _init_completion || return + + _ImageMagick && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + elif [[ $cur == +* ]]; then + COMPREPLY=($(compgen -W '+adjoin +compress +debug +dither +endian + +gamma +label +matte +page' -- "$cur")) + else + _filedir + fi +} && + complete -F _montage montage + +_composite() +{ + local cur prev words cword + _init_completion || return + + _ImageMagick && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + elif [[ $cur == +* ]]; then + COMPREPLY=($(compgen -W '+compress +debug +dither +endian +label + +matte +negate +page +write' -- "$cur")) + else + _filedir + fi +} && + complete -F _composite composite + +_compare() +{ + local cur prev words cword + _init_completion || return + + _ImageMagick && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + elif [[ $cur == +* ]]; then + COMPREPLY=($(compgen -W '+debug' -- "$cur")) + else + _filedir + fi +} && + complete -F _compare compare + +_conjure() +{ + local cur prev words cword + _init_completion || return + + _ImageMagick && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + elif [[ $cur == +* ]]; then + COMPREPLY=($(compgen -W '+debug' -- "$cur")) + else + _filedir + fi +} && + complete -F _conjure conjure + +_import() +{ + local cur prev words cword + _init_completion || return + + _ImageMagick && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + elif [[ $cur == +* ]]; then + COMPREPLY=($(compgen -W '+debug' -- "$cur")) + else + _filedir + fi +} && + complete -F _import import + +_stream() +{ + local cur prev words cword + _init_completion || return + + _ImageMagick && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + elif [[ $cur == +* ]]; then + COMPREPLY=($(compgen -W '+debug' -- "$cur")) + else + _filedir + fi +} && + complete -F _stream stream + +# ex: filetype=sh diff --git a/completions/cowsay b/completions/cowsay new file mode 100644 index 0000000..6ba1d0f --- /dev/null +++ b/completions/cowsay @@ -0,0 +1,23 @@ +# bash completion for cowsay -*- shell-script -*- + +_cowsay() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -f) + COMPREPLY=($(compgen -W \ + '$(cowsay -l 2>/dev/null | tail -n +2)' -- "$cur")) + return + ;; + esac + + # relevant options completion + COMPREPLY=($(compgen -W '-b -d -g -p -s -t -w -y -e -f -h -l -n -T -W' \ + -- "$cur")) + +} && + complete -F _cowsay -o default cowsay cowthink + +# ex: filetype=sh diff --git a/completions/cpan2dist b/completions/cpan2dist new file mode 100644 index 0000000..b5e59da --- /dev/null +++ b/completions/cpan2dist @@ -0,0 +1,37 @@ +# bash completion for cpan2dist -*- shell-script -*- + +_cpan2dist() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --format) + # should remove ":" from COMP_WORDBREAKS, but doesn't work (?) + COMPREPLY=($(compgen -W '$(perl -MCPANPLUS::Dist -e \ + "print map { \"\$_\n\" } CPANPLUS::Dist->dist_types")' \ + -- "$cur")) + return + ;; + --banlist | --ignorelist | --modulelist | --logfile) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + local cpandirs=("$HOME/.cpanplus/" "$HOME/.cpan/source/modules/") + local packagelist + for dir in "${cpandirs[@]}"; do + [[ -d $dir && -r "$dir/02packages.details.txt.gz" ]] && + packagelist="$dir/02packages.details.txt.gz" + done + [[ -v packagelist ]] && COMPREPLY=($(zgrep "^${cur//-/::}" \ + $packagelist 2>/dev/null | awk '{print $1}' | command sed -e 's/::/-/g')) + fi +} && + complete -F _cpan2dist -o default cpan2dist + +# ex: filetype=sh diff --git a/completions/cpio b/completions/cpio new file mode 100644 index 0000000..d6fde0c --- /dev/null +++ b/completions/cpio @@ -0,0 +1,78 @@ +# bash completion for cpio -*- shell-script -*- + +_cpio() +{ + local cur prev words cword split + _init_completion -s -n : || return + + # --name value style option + case $prev in + --format | -!(-*)H) + COMPREPLY=($(compgen -W \ + 'bin odc newc crc tar ustar hpbin hpodc' -- "$cur")) + return + ;; + --file | --pattern-file | -!(-*)[EFI]) + _filedir + return + ;; + --owner | -!(-*)R) + _usergroup + return + ;; + --rsh-command) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + esac + + $split && return + + if ((cword == 1)); then + COMPREPLY=($(compgen -W '-o --create -i --extract -p --pass-through + -? --help --license --usage --version' -- "$cur")) + else + case ${words[1]} in + -o | --create) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-0 -a -c -v -A -B -L -V -C -H -M + -O -F --file --format --message --null + --reset-access-time --verbose --dot --append + --block-size --dereference --io-size --quiet + --force-local --rsh-command --help --version' \ + -- "$cur")) + fi + ;; + -i | --extract) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-b -c -d -f -m -n -r -t -s -u -v + -B -S -V -C -E -H -M -R -I -F --file --make-directories + --nonmatching --preserve-modification-time + --numeric-uid-gid --rename --list --swap-bytes --swap + --dot --unconditional --verbose --block-size + --swap-halfwords --io-size --pattern-file --format + --owner --no-preserve-owner --message --force-local + --no-absolute-filenames --sparse --only-verify-crc + --quiet --rsh-command --help --to-stdout --version' \ + -- "$cur")) + fi + ;; + -p* | --pass-through) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-0 -a -d -l -m -u -v -L -V -R + --null --reset-access-time --make-directories --link + --quiet --preserve-modification-time --unconditional + --verbose --dot --dereference --owner + --no-preserve-owner --sparse --help --version' \ + -- "$cur")) + else + _filedir -d + fi + ;; + esac + fi +} && + complete -F _cpio cpio + +# ex: filetype=sh diff --git a/completions/cppcheck b/completions/cppcheck new file mode 100644 index 0000000..8ea9571 --- /dev/null +++ b/completions/cppcheck @@ -0,0 +1,91 @@ +# bash completion for cppcheck(1) -*- shell-script -*- + +_cppcheck() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --append | --exitcode-suppressions | --rule-file | --config-excludes-file | \ + --suppressions-list | --includes-file | --include | -i) + _filedir + return + ;; + -D | -U | --rule | --suppress | --template | --max-configs | -h | --help | --version | \ + --errorlist | --config-exclude | -l) + return + ;; + --enable) + # split comma-separated list + split=false + if [[ $cur == ?*,* ]]; then + prev="${cur%,*}" + cur="${cur##*,}" + split=true + fi + COMPREPLY=($(compgen -W 'all warning style performance + portability information unusedFunction missingInclude' \ + -- "$cur")) + $split && COMPREPLY=(${COMPREPLY[@]/#/"$prev,"}) + return + ;; + --error-exitcode) + COMPREPLY=($(compgen -W '{0..255}' -- "$cur")) + return + ;; + --file-list) + _filedir + [[ -z $cur || $cur == - ]] && COMPREPLY+=(-) + return + ;; + -I) + _filedir -d + return + ;; + -j) + COMPREPLY=($(compgen -W "{2..$(_ncpus)}" -- "$cur")) + return + ;; + --language | -x) + COMPREPLY=($(compgen -W 'c c++' -- "$cur")) + return + ;; + --std) + COMPREPLY=($(compgen -W 'c89 c99 c11 c++03 c++11 c++14 c++17 + c++20' -- "$cur")) + return + ;; + --platform) + _filedir + COMPREPLY+=($(compgen -W 'unix32 unix64 win32A win32W win64 + native' -- "$cur")) + return + ;; + -rp | --relative-paths) + if $split; then # -rp without argument is allowed + _filedir -d + return + fi + ;; + --library) + _filedir cfg + return + ;; + --xml-version) + COMPREPLY=($(compgen -W '1 2' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _filedir '@([cht]pp|[cht]xx|cc|[ch]++|[ch])' + fi +} && + complete -F _cppcheck cppcheck + +# ex: filetype=sh diff --git a/completions/crontab b/completions/crontab new file mode 100644 index 0000000..cac7853 --- /dev/null +++ b/completions/crontab @@ -0,0 +1,48 @@ +# crontab(1) completion -*- shell-script -*- + +_crontab() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*u) + _allowed_users + return + ;; + esac + + local -A opts=([-u]="" [-l]="" [-r]="" [-e]="") + [[ $OSTYPE == *linux* ]] && opts[-i]= + [[ -d /sys/fs/selinux || -d /selinux ]] && opts[-s]= + + local i + for i in "${!words[@]}"; do + [[ ${words[i]} && $i -ne $cword ]] && unset "opts[${words[i]}]" + case "${words[i]}" in + -l) + unset 'opts[-r]' 'opts[-e]' 'opts[-i]' 'opts[-s]' + ;; + -e) + unset 'opts[-l]' 'opts[-r]' 'opts[-i]' + ;; + -r) + unset 'opts[-l]' 'opts[-e]' + ;; + -u) + unset 'opts[-i]' + ;; + esac + done + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '${!opts[@]}' -- "$cur")) + return + fi + + # do filenames only if we did not have -l, -r, or -e + [[ ${words[*]} == *\ -[lre]* ]] || _filedir +} && + complete -F _crontab crontab + +# ex: filetype=sh diff --git a/completions/cryptsetup b/completions/cryptsetup new file mode 100644 index 0000000..e73e165 --- /dev/null +++ b/completions/cryptsetup @@ -0,0 +1,103 @@ +# bash completion for cryptsetup -*- shell-script -*- + +_cryptsetup_name() +{ + COMPREPLY=($(compgen -X control -W '$(command ls /dev/mapper)' -- "$cur")) +} + +_cryptsetup_device() +{ + cur=${cur:=/dev/} + _filedir +} + +_cryptsetup() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | --cipher | --hash | --*-size | --key-slot | --size | --offset | \ + --skip | --iter-time | --timeout | --tries | -!(-*)[chslSbopitT]) + return + ;; + --key-file | --master-key-file | --header-backup-file | -!(-*)d) + _filedir + return + ;; + --type | -!(-*)M) + COMPREPLY=($(compgen -W "luks plain loopaes tcrypt" -- "$cur")) + return + ;; + esac + + $split && return + + local arg + _get_first_arg + if [[ -z $arg ]]; then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + COMPREPLY=($(compgen -W 'open close resize status benchmark + repair erase luksFormat luksAddKey luksRemoveKey luksChangeKey + luksKillSlot luksUUID isLuks luksDump tcryptDump luksSuspend + luksResume luksHeaderBackup luksHeaderRestore' -- "$cur")) + fi + else + local args + _count_args "" "-!(-*)[chslSbopitTdM]" + case $arg in + open | create | luksOpen | loopaesOpen | tcryptOpen) + case $args in + 2) + _cryptsetup_device + ;; + 3) + _cryptsetup_name + ;; + esac + ;; + close | remove | luksClose | loopaesClose | tcryptClose | status | resize | \ + luksSuspend | luksResume) + case $args in + 2) + _cryptsetup_name + ;; + esac + ;; + luksFormat | luksAddKey | luksRemoveKey | luksChangeKey) + case $args in + 2) + _cryptsetup_device + ;; + 3) + _filedir + ;; + esac + ;; + luksKillSlot | luksDelKey | luksUUID | isLuks | luksDump) + case $args in + 2) + _cryptsetup_device + ;; + esac + ;; + luksHeaderBackup | luksHeaderRestore) + case $args in + 2) + _cryptsetup_device + ;; + 3) + COMPREPLY=('--header-backup-file') + ;; + esac + ;; + esac + fi + +} && + complete -F _cryptsetup cryptsetup + +# ex: filetype=sh diff --git a/completions/curl b/completions/curl new file mode 100644 index 0000000..6e84269 --- /dev/null +++ b/completions/curl @@ -0,0 +1,99 @@ +# curl(1) completion -*- shell-script -*- + +_curl() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --ciphers | --connect-timeout | --continue-at | --form | --form-string | \ + --ftp-account | --ftp-alternative-to-user | --ftp-port | --header | --help | \ + --hostpubmd5 | --keepalive-time | --krb | --limit-rate | --local-port | \ + --mail-from | --mail-rcpt | --max-filesize | --max-redirs | --max-time | --pass | \ + --proto | --proto-redir | --proxy-user | --proxy1.0 | --quote | --range | \ + --request | --retry | --retry-delay | --retry-max-time | \ + --socks5-gssapi-service | --telnet-option | --tftp-blksize | --time-cond | \ + --url | --user | --user-agent | --version | --write-out | --resolve | --tlsuser | \ + --tlspassword | -!(-*)[CFPHhmQrXtzuAVw]) + return + ;; + --config | --cookie | --cookie-jar | --dump-header | --egd-file | \ + --key | --libcurl | --output | --random-file | --upload-file | --trace | \ + --trace-ascii | --netrc-file | -!(-*)[KbcDoT]) + _filedir + return + ;; + --cacert | --cert | -!(-*)E) + _filedir '@(c?(e)rt|cer|pem|der)' + return + ;; + --capath) + _filedir -d + return + ;; + --cert-type | --key-type) + COMPREPLY=($(compgen -W 'DER PEM ENG' -- "$cur")) + return + ;; + --crlfile) + _filedir crl + return + ;; + --data | --data-ascii | --data-binary | --data-urlencode | -!(-*)d) + if [[ $cur == \@* ]]; then + cur=${cur:1} + _filedir + if [[ ${#COMPREPLY[@]} -eq 1 && -d ${COMPREPLY[0]} ]]; then + COMPREPLY[0]+=/ + compopt -o nospace + fi + COMPREPLY=("${COMPREPLY[@]/#/@}") + fi + return + ;; + --delegation) + COMPREPLY=($(compgen -W 'none policy always' -- "$cur")) + return + ;; + --engine) + COMPREPLY=($(compgen -W 'list' -- "$cur")) + return + ;; + --ftp-method) + COMPREPLY=($(compgen -W 'multicwd nocwd singlecwd' -- "$cur")) + return + ;; + --ftp-ssl-ccc-mode) + COMPREPLY=($(compgen -W 'active passive' -- "$cur")) + return + ;; + --interface) + _available_interfaces -a + return + ;; + --proxy | --socks4 | --socks4a | --socks5 | --socks5-hostname | -!(-*)x) + _known_hosts_real -- "$cur" + return + ;; + --pubkey) + _xfunc ssh _ssh_identityfile pub + return + ;; + --stderr) + COMPREPLY=($(compgen -W '-' -- "$cur")) + _filedir + return + ;; + --tlsauthtype) + COMPREPLY=($(compgen -W 'SRP' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + fi +} && + complete -F _curl curl + +# ex: filetype=sh diff --git a/completions/cvs b/completions/cvs new file mode 100644 index 0000000..ba1f062 --- /dev/null +++ b/completions/cvs @@ -0,0 +1,398 @@ +# cvs(1) completion -*- shell-script -*- + +_cvs_entries() +{ + local prefix=${cur%/*}/ IFS=$'\n' + [[ -e ${prefix:-}CVS/Entries ]] || prefix="" + entries=($(cut -d/ -f2 -s ${prefix:-}CVS/Entries 2>/dev/null)) + if [[ $entries ]]; then + entries=("${entries[@]/#/${prefix:-}}") + compopt -o filenames + fi +} + +_cvs_modules() +{ + if [[ -n $prefix ]]; then + COMPREPLY=($(command ls -d ${cvsroot}/${prefix}/!(CVSROOT))) + else + COMPREPLY=($(command ls -d ${cvsroot}/!(CVSROOT))) + fi +} + +_cvs_commands() +{ + cvs --help-commands 2>&1 | awk '/^( *|\t)/ { print $1 }' +} + +_cvs_command_options() +{ + COMPREPLY=($(compgen -W '$(_parse_help "$1" "--help $2")' -- "$cur")) +} + +_cvs_kflags() +{ + COMPREPLY=($(compgen -W 'kv kvl k o b v' -- "$cur")) +} + +_cvs_roots() +{ + local -a cvsroots + [[ -v CVSROOT ]] && cvsroots=("$CVSROOT") + [[ -r ~/.cvspass ]] && cvsroots+=($(awk '{ print $2 }' ~/.cvspass)) + [[ -r CVS/Root ]] && mapfile -tO ${#cvsroots[@]} cvsroots <CVS/Root + COMPREPLY=($(compgen -W '${cvsroots[@]}' -- "$cur")) + __ltrim_colon_completions "$cur" +} + +_cvs() +{ + local cur prev words cword + _init_completion -n : || return + + local count mode i cvsroot cvsroots pwd + local -a flags files entries changed newremoved + + count=0 + for i in "${words[@]}"; do + ((count == cword)) && break + # Last parameter was the CVSROOT, now go back to mode selection + if [[ ${words[count]} == "${cvsroot-}" && ${mode-} == cvsroot ]]; then + mode="" + fi + if [[ ! -v mode ]]; then + case $i in + --help | -!(-*)H) + COMPREPLY=($(compgen -W "$(_cvs_commands)" -- "$cur")) + return + ;; + -!(-*)d) + mode=cvsroot + cvsroot=${words[count + 1]} + ;; + add | ad | new) + mode=add + ;; + admin | adm | rcs) + mode="admin" + ;; + annotate | ann | blame | rannotate | rann | ra) + mode=annotate + ;; + checkout | co | get) + mode=checkout + ;; + commit | ci | com) + mode=commit + ;; + diff | di | dif) + mode="diff" + ;; + export | ex | exp) + mode="export" + ;; + edit | unedit | editors | logout | pserver | server | watch | watchers) + mode=$i + ;; + history | hi | his) + mode=history + ;; + import | im | imp) + mode=import + ;; + log | lo | rlog | rl) + mode=log + ;; + login | logon | lgn) + mode=login + ;; + rdiff | patch | pa) + mode=rdiff + ;; + release | re | rel) + mode=release + ;; + remove | rm | delete) + mode=remove + ;; + rtag | rt | rfreeze) + mode=rtag + ;; + status | st | stat) + mode=status + ;; + tag | ta | freeze) + mode=tag + ;; + update | up | upd) + mode=update + ;; + version | ve | ver) + mode=version + ;; + esac + elif [[ $i == -* ]]; then + flags+=($i) + fi + ((count++)) + done + + case ${mode-} in + add) + case $prev in + --*) ;; + -*m) + return + ;; + -*k) + _cvs_kflags + return + ;; + esac + + if [[ $cur != -* ]]; then + _cvs_entries + [[ -z $cur ]] && files=(!(CVS)) || + files=($(command ls -d ${cur}* 2>/dev/null)) + local f + for i in "${!files[@]}"; do + if [[ ${files[i]} == ?(*/)CVS ]]; then + unset 'files[i]' + else + for f in "${entries[@]}"; do + if [[ ${files[i]} == "$f" && ! -d $f ]]; then + unset 'files[i]' + break + fi + done + fi + done + COMPREPLY=($(compgen -X "$_backup_glob" -W '${files[@]}' \ + -- "$cur")) + else + _cvs_command_options "$1" $mode + fi + ;; + admin) + case $prev in + --*) ;; + -*@([aAbcelmnNosu]|t-)) + return + ;; + -*t) + _filedir + return + ;; + -*k) + _cvs_kflags + return + ;; + esac + + if [[ $cur == -* ]]; then + _cvs_command_options "$1" $mode + else + _cvs_entries + COMPREPLY=($(compgen -W '${entries[@]}' -- "$cur")) + fi + ;; + annotate) + [[ $prev == -[rD] ]] && return + + if [[ $cur == -* ]]; then + _cvs_command_options "$1" $mode + else + _cvs_entries + COMPREPLY=($(compgen -W '${entries[@]}' -- "$cur")) + fi + ;; + checkout) + case $prev in + --*) ;; + -*[rDj]) + return + ;; + -*d) + _filedir -d + return + ;; + -*k) + _cvs_kflags + return + ;; + esac + + if [[ $cur != -* ]]; then + [[ ! -v cvsroot ]] && cvsroot=${CVSROOT-} + COMPREPLY=($(cvs -d "$cvsroot" co -c 2>/dev/null | + awk '{print $1}')) + COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur")) + else + _cvs_command_options "$1" $mode + fi + ;; + commit) + case $prev in + --*) ;; + -*[mr]) + return + ;; + -*F) + _filedir + return + ;; + esac + + if [[ $cur != -* ]]; then + # if $COMP_CVS_REMOTE is not null, 'cvs commit' will + # complete on remotely checked-out files (requires + # passwordless access to the remote repository + if [[ -n ${COMP_CVS_REMOTE:-} ]]; then + # this is the least computationally intensive way found so + # far, but other changes (something other than + # changed/removed/new) may be missing + changed=($(cvs -q diff --brief 2>&1 | + command sed -ne 's/^Files [^ ]* and \([^ ]*\) differ$/\1/p')) + newremoved=($(cvs -q diff --brief 2>&1 | + command sed -ne 's/^cvs diff: \([^ ]*\) .*, no comparison available$/\1/p')) + COMPREPLY=($(compgen -W '${changed[@]:-} \ + ${newremoved[@]:-}' -- "$cur")) + else + _cvs_entries + COMPREPLY=($(compgen -W '${entries[@]}' -- "$cur")) + fi + else + _cvs_command_options "$1" $mode + fi + ;; + cvsroot) + _cvs_roots + ;; + diff | log) + if [[ $cur == -* ]]; then + _cvs_command_options "$1" $mode + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _cvs_entries + COMPREPLY=($(compgen -W '${entries[@]:-}' -- "$cur")) + fi + ;; + editors | watchers) + if [[ $cur == -* ]]; then + _cvs_command_options "$1" $mode + else + _cvs_entries + COMPREPLY=($(compgen -W '${entries[@]}' -- "$cur")) + fi + ;; + export) + case $prev in + --*) ;; + -*[rD]) + return + ;; + -*d) + _filedir -d + return + ;; + -*k) + _cvs_kflags + return + ;; + esac + + if [[ $cur != -* ]]; then + [[ ! -v cvsroot ]] && cvsroot=${CVSROOT-} + COMPREPLY=($(cvs -d "$cvsroot" co -c | awk '{print $1}')) + COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur")) + else + _cvs_command_options "$1" $mode + fi + ;; + import) + case $prev in + --*) ;; + -*[IbmW]) + return + ;; + -*k) + _cvs_kflags + return + ;; + esac + + if [[ $cur != -* ]]; then + # starts with same algorithm as checkout + [[ ! -v cvsroot ]] && cvsroot=${CVSROOT-} + local prefix=${cur%/*} + if [[ -r ${cvsroot}/${prefix} ]]; then + _cvs_modules + COMPREPLY=(${COMPREPLY[@]#$cvsroot}) + COMPREPLY=(${COMPREPLY[@]#\/}) + fi + pwd=$(pwd) + pwd=${pwd##*/} + COMPREPLY=($(compgen -W '${COMPREPLY[@]} $pwd' -- "$cur")) + else + _cvs_command_options "$1" $mode + fi + ;; + remove) + if [[ $cur != -* ]]; then + _cvs_entries + if [[ $prev != -f ]]; then + # find out what files are missing + for i in "${!entries[@]}"; do + [[ -r ${entries[i]} ]] && unset 'entries[i]' + done + fi + COMPREPLY=($(compgen -W '${entries[@]:-}' -- "$cur")) + else + _cvs_command_options "$1" $mode + fi + ;; + update) + case $prev in + --*) ;; + -*[rDjIW]) + return + ;; + -*k) + _cvs_kflags + return + ;; + esac + + if [[ $cur == -* ]]; then + _cvs_command_options "$1" $mode + else + _cvs_entries + COMPREPLY=($(compgen -W '${entries[@]}' -- "$cur")) + fi + ;; + "") + case $prev in + --*) ;; + -*T) + _filedir -d + return + ;; + -*[es]) + return + ;; + -*z) + COMPREPLY=($(compgen -W '{1..9}' -- "$cur")) + return + ;; + esac + + COMPREPLY=($(compgen -W '$(_cvs_commands) + $(_parse_help "$1" --help-options) --help --help-commands + --help-options --version' -- "$cur")) + ;; + esac + +} && + complete -F _cvs cvs + +# ex: filetype=sh diff --git a/completions/cvsps b/completions/cvsps new file mode 100644 index 0000000..4fdfefc --- /dev/null +++ b/completions/cvsps @@ -0,0 +1,58 @@ +# bash completion for cvsps -*- shell-script -*- + +_cvsps() +{ + local cur prev words cword + _init_completion -n : || return + + case $prev in + -h | -z | -f | -d | -l | --diff-opts | --debuglvl) + return + ;; + -s) + COMPREPLY=($(compgen -W "$($1 2>/dev/null | + awk '/^PatchSet:?[ \t]/ { print $2 }')" -- "$cur")) + return + ;; + -a) + COMPREPLY=($(compgen -W "$($1 2>/dev/null | + awk '/^Author:[ \t]/ { print $2 }')" -- "$cur")) + return + ;; + -b) + COMPREPLY=($(compgen -W "$($1 2>/dev/null | + awk '/^Branch:[ \t]/ { print $2 }')" -- "$cur")) + return + ;; + -r) + COMPREPLY=($(compgen -W "$($1 2>/dev/null | + awk '/^Tag:[ \t]+[^(]/ { print $2 }')" -- "$cur")) + return + ;; + -p) + _filedir -d + return + ;; + --test-log) + _filedir + return + ;; + -Z) + COMPREPLY=($(compgen -W '{1..9}' -- "$cur")) + return + ;; + --root) + _xfunc cvs _cvs_roots + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + else + _xfunc cvs _cvs_roots + fi +} && + complete -F _cvsps cvsps + +# ex: filetype=sh diff --git a/completions/dd b/completions/dd new file mode 100644 index 0000000..04d876a --- /dev/null +++ b/completions/dd @@ -0,0 +1,42 @@ +# bash completion for dd -*- shell-script -*- + +_dd() +{ + local cur prev words cword + _init_completion -n = || return + + case $cur in + if=* | of=*) + cur=${cur#*=} + _filedir + return + ;; + conv=*) + cur=${cur#*=} + COMPREPLY=($(compgen -W 'ascii ebcdic ibm block unblock lcase + ucase sparse swab sync excl nocreat notrunc noerror fdatasync + fsync' -- "$cur")) + return + ;; + iflag=* | oflag=*) + cur=${cur#*=} + COMPREPLY=($(compgen -W 'append direct directory dsync sync + fullblock nonblock noatime nocache noctty nofollow count_bytes + skip_bytes seek_bytes' -- "$cur")) + return + ;; + status=*) + cur=${cur#*=} + COMPREPLY=($(compgen -W 'none noxfer progress' -- "$cur")) + return + ;; + esac + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur") + $(compgen -W 'bs cbs conv count ibs if iflag obs of oflag + seek skip status' -S '=' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace +} && + complete -F _dd dd + +# ex: filetype=sh diff --git a/completions/deja-dup b/completions/deja-dup new file mode 100644 index 0000000..1854d6a --- /dev/null +++ b/completions/deja-dup @@ -0,0 +1,32 @@ +# bash completion for deja-dup(1) -*- shell-script -*- + +_deja_dup() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -'?' | --help | --help-*) + return + ;; + --restore) + _filedir + return + ;; + --restore-missing) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --help-all)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi +} && + complete -F _deja_dup deja-dup + +# ex: filetype=sh diff --git a/completions/desktop-file-validate b/completions/desktop-file-validate new file mode 100644 index 0000000..8f4e139 --- /dev/null +++ b/completions/desktop-file-validate @@ -0,0 +1,23 @@ +# desktop-file-validate completion -*- shell-script -*- + +_desktop_file_validate() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + _filedir desktop +} && + complete -F _desktop_file_validate desktop-file-validate + +# ex: filetype=sh diff --git a/completions/dhclient b/completions/dhclient new file mode 100644 index 0000000..ce4b745 --- /dev/null +++ b/completions/dhclient @@ -0,0 +1,34 @@ +# bash completion for dhclient -*- shell-script -*- + +_dhclient() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -p | -e) + return + ;; + -D) + COMPREPLY=($(compgen -W 'LL LLT' -- "$cur")) + return + ;; + -*f) + _filedir + return + ;; + -s) + _known_hosts_real -- "$cur" + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + else + _available_interfaces + fi +} && + complete -F _dhclient dhclient + +# ex: filetype=sh diff --git a/completions/dict b/completions/dict new file mode 100644 index 0000000..f3426ff --- /dev/null +++ b/completions/dict @@ -0,0 +1,64 @@ +# dict(1) completion -*- shell-script -*- + +_dictdata() +{ + dict $host $port $1 2>/dev/null | command sed -ne \ + 's/^[[:blank:]]\{1,\}\([^[:blank:]]*\).*$/\1/p' +} + +_dict() +{ + local cur prev words cword + _init_completion || return + + local host port db i + + for ((i = 1; i < cword; i++)); do + case ${words[i]} in + --host | -!(-*)h) + host=${words[++i]} + [[ -n $host ]] && host="-h $host" + ;; + --port | -!(-*)p) + port=${words[++i]} + [[ -n $port ]] && port="-p $port" + ;; + --database | -!(-*)d) + db=${words[++i]} + [[ -n $db ]] && host="-d $db" + ;; + esac + done + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + case $prev in + --database | -info | -!(-*)[di]) + COMPREPLY=($(compgen -W '$(_dictdata -D)' -- "$cur")) + return + ;; + --strategy | -!(-*)s) + COMPREPLY=($(compgen -W '$(_dictdata -S)' -- "$cur")) + return + ;; + esac + + local dictfile=/usr/share/dict/words + if [[ -r $dictfile ]]; then + # Dictfile may be too large for practical compgen -W usage, so narrow + # it down with grep if $cur looks like something that's safe to embed + # in a pattern instead. + if [[ $cur == +([-A-Za-z0-9/.]) ]]; then + COMPREPLY=($(compgen -W \ + '$(command grep "^${cur//./\\.}" $dictfile)' -- "$cur")) + else + COMPREPLY=($(compgen -W '$(cat $dictfile)' -- "$cur")) + fi + fi +} && + complete -F _dict -o default dict rdict + +# ex: filetype=sh diff --git a/completions/dmypy b/completions/dmypy new file mode 100644 index 0000000..5abe37d --- /dev/null +++ b/completions/dmypy @@ -0,0 +1,48 @@ +# dmypy completion -*- shell-script -*- + +_dmypy() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | -[hV]) + return + ;; + --status-file) + _filedir + return + ;; + esac + + local cmd i + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} != -* && ${words[i - 1]} != --status-file ]]; then + cmd=${words[i]} + break + fi + done + + case ${cmd-} in + check | run) + _filedir '@(py|pyi)' + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + if [[ ! -v cmd ]]; then + local cmds=$($1 --help 2>&1 | + command sed -ne '/positional arguments/{p;n;p;q}' | + command sed -ne 's/{\(.*\)}/\1/p') + COMPREPLY=($(IFS="," compgen -W '$cmds' -- "$cur")) + return + fi +} && + complete -F _dmypy dmypy + +# ex: filetype=sh diff --git a/completions/dnssec-keygen b/completions/dnssec-keygen new file mode 100644 index 0000000..3f68a68 --- /dev/null +++ b/completions/dnssec-keygen @@ -0,0 +1,48 @@ +# bash completion for dnssec-keygen(8) -*- shell-script -*- + +_dnssec_keygen_optarg() +{ + local args=$("$1" -h 2>&1 | + command sed -e 's/|/ /g' -e 's/(.*//' \ + -ne '/^[[:space:]]*'$2'/,/^[[:space:]]*[(-]/p' | + command sed -e 's/^[[:space:]]*'$2'.*://' -e '/^[[:space:]]*-/d') + COMPREPLY+=($(compgen -W '$args' -- "$cur")) +} + +_dnssec_keygen() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -[hbEgLpsPARIDSi]) + return + ;; + -K) + _filedir -d + return + ;; + -[ancdfTtm]) + _dnssec_keygen_optarg "$1" $prev + return + ;; + -r) + cur=${cur:=/dev/} + _filedir + return + ;; + -v) + COMPREPLY=($(compgen -W '{0..10}' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" | \ + command sed -e "s/:\$//")' -- "$cur")) + return + fi +} && + complete -F _dnssec_keygen dnssec-keygen + +# ex: filetype=sh diff --git a/completions/dnsspoof b/completions/dnsspoof new file mode 100644 index 0000000..86ade91 --- /dev/null +++ b/completions/dnsspoof @@ -0,0 +1,26 @@ +# dnsspoof completion -*- shell-script -*- + +_dnsspoof() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -i) + _available_interfaces -a + return + ;; + -f) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + fi + +} && + complete -F _dnsspoof dnsspoof + +# ex: filetype=sh diff --git a/completions/dot b/completions/dot new file mode 100644 index 0000000..8122229 --- /dev/null +++ b/completions/dot @@ -0,0 +1,45 @@ +# dot(1) completion -*- shell-script -*- + +_dot() +{ + local cur prev words cword + _init_completion -n := || return + + [[ $prev == -[V?] ]] && return + + case $cur in + -G* | -N* | -E* | -l?* | -q?* | -s?* | -Ln* | -LU* | -LC* | -LT*) + return + ;; + -T*) + local langs=($("$1" -TNON_EXISTENT 2>&1 | + command sed -ne 's/.*one of://p')) + COMPREPLY=($(compgen -P -T -W '${langs[@]}' -- "${cur#-T}")) + return + ;; + -K*) + local layouts=($("$1" -KNON_EXISTENT 2>&1 | + command sed -ne 's/.*one of://p')) + COMPREPLY=($(compgen -P -K -W '${layouts[@]}' -- "${cur#-K}")) + return + ;; + -o*) + cur=${cur#-o} + _filedir + COMPREPLY=($(compgen -P -o -W '${COMPREPLY[@]}' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-V -v -G -N -E -T -K -l -o -O -P -q -s -y -n + -n1 -n2 -x -Lg -LO -Ln -LU -LC -LT -m -c -?' -- "$cur")) + [[ ${COMPREPLY-} == -@([GNETKo]|L[nUCT]) ]] && compopt -o nospace + return + fi + + _filedir dot +} && + complete -F _dot dot + +# ex: filetype=sh diff --git a/completions/dpkg b/completions/dpkg new file mode 100644 index 0000000..0b90b14 --- /dev/null +++ b/completions/dpkg @@ -0,0 +1,126 @@ +# This function is required by _dpkg and _dpkg-reconfigure -*- shell-script -*- + +_have grep-status && { + _comp_dpkg_installed_packages() + { + grep-status -P -e "^$1" -a -FStatus 'ok installed' -n -s Package + } +} || { + _comp_dpkg_installed_packages() + { + command grep -A 1 "Package: $1" /var/lib/dpkg/status 2>/dev/null | + command grep -B 1 -Ee "ok installed|half-installed|unpacked| \ + half-configured" \ + -Ee "^Essential: yes" | + awk "/Package: $1/ { print \$2 }" 2>/dev/null + } +} + +_have grep-status && { + _comp_dpkg_purgeable_packages() + { + grep-status -P -e "^$1" -a -FStatus 'ok installed' -o -FStatus 'ok config-files' -n -s Package + } +} || { + _comp_dpkg_purgeable_packages() + { + command grep -A 1 "Package: $1" /var/lib/dpkg/status 2>/dev/null | + command grep -B 1 -Ee "ok installed|half-installed|unpacked| \ + half-configured|config-files" \ + -Ee "^Essential: yes" | + awk "/Package: $1/ { print \$2 }" 2>/dev/null + } +} + +# Debian dpkg(1) completion +# +_dpkg() +{ + local cur prev words cword split + _init_completion -s || return + + local i=$cword + + # find the last option flag + if [[ $cur != -* ]]; then + while [[ $prev != -* && $i -ne 1 ]]; do + prev=${words[--i - 1]} + done + fi + + case $prev in + --install | --unpack | --record-avail | --contents | --info | --fsys-tarfile | \ + --field | --control | --extract | --vextract | --raw-extract | -!(-*)[ciAIfexX]) + _filedir '?(u|d)deb' + return + ;; + --build | -!(-*)b) + _filedir -d + return + ;; + --status | --print-avail | --list | -!(-*)[spl]) + COMPREPLY=($(_xfunc apt-cache _apt_cache_packages)) + return + ;; + --show | -!(-*)W) + if [[ $1 == *dpkg-query ]]; then + COMPREPLY=($(_xfunc apt-cache _apt_cache_packages)) + else + _filedir '?(u|d)deb' + fi + return + ;; + --search | -!(-*)S) + _filedir + return + ;; + --remove | --verify | -!(-*)[rV]) + COMPREPLY=($(_comp_dpkg_installed_packages "$cur")) + return + ;; + --listfiles | --purge | -!(-*)[LP]) + COMPREPLY=($(_comp_dpkg_purgeable_packages "$cur")) + return + ;; + esac + + $split && return + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace +} && + complete -F _dpkg dpkg dpkg-deb dpkg-query + +# Debian GNU dpkg-reconfigure(8) completion +# +_dpkg_reconfigure() +{ + local cur prev words cword + _init_completion || return + + local opt + + case $prev in + --frontend | -!(-*)f) + opt=($(printf '%s\n' /usr/share/perl5/Debconf/FrontEnd/*)) + opt=(${opt[@]##*/}) + opt=(${opt[@]%.pm}) + COMPREPLY=($(compgen -W '${opt[@]}' -- "$cur")) + return + ;; + --priority | -!(-*)p) + COMPREPLY=($(compgen -W 'low medium high critical' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--frontend --priority --all --unseen-only + --help --showold --force --terse' -- "$cur")) + else + COMPREPLY=($(_comp_dpkg_installed_packages "$cur")) + fi +} && + complete -F _dpkg_reconfigure -o default dpkg-reconfigure + +# ex: filetype=sh diff --git a/completions/dpkg-source b/completions/dpkg-source new file mode 100644 index 0000000..05fa3a1 --- /dev/null +++ b/completions/dpkg-source @@ -0,0 +1,98 @@ +# Debian dpkg-source completion -*- shell-script -*- + +_dpkg_source() +{ + local cur prev words cword + _init_completion || return + + local options word action packopts unpackopts fields + + packopts="-c -l -F -V -T -D -U -W -E -sa -i -I -sk -sr -ss -sA -sK -sP \ + -sU -sR" + unpackopts="-sp -sn -su" + options="-x -b --print-format --before-build --after-build --commit $packopts $unpackopts" + fields="Format Source Version Binary Maintainer Uploader Architecture \ + Standards-Version Build-Depends Files" + + action=options + for word in "${words[@]:1}"; do + if [[ $word == -x ]]; then + action=unpack + elif [[ $word == -b ]]; then + action=pack + elif [[ $word == -h ]]; then + action=help + fi + done + + case $action in + unpack) + case $prev in + -x) + _filedir -d + _filedir 'dsc' + ;; + *) + COMPREPLY=($(compgen -W "$unpackopts" -- "$cur")) + _filedir -d + _filedir + ;; + esac + return + ;; + pack) + case $prev in + -b) + _filedir -d + ;; + -c | -l | -T | -i | -I) + # -c: get controlfile + # -l: get per-version info from this file + # -T: read variables here, not debian/substvars + # -i: <regexp> filter out files to ignore diffs of. + # -I: filter out files when building tarballs. + # return directory names and file names + _filedir -d + _filedir + ;; + -F) + # -F: force change log format + COMPREPLY=($(command ls /usr/lib/dpkg/parsechangelog)) + ;; + -V) + # -V: set a substitution variable + # we don't know anything about possible variables or values + # so we don't try to suggest any completion. + COMPREPLY=() + ;; + -D) + # -D: override or add a .dsc field and value + # if $cur doesn't contain a = yet, suggest variable names + if [[ $cur == *=* ]]; then + # $cur contains a "=" + COMPREPLY=() + else + COMPREPLY=($(compgen -W "$fields" -- "$cur")) + fi + ;; + -U) + # -U: remove a field + # Suggest possible fieldnames + COMPREPLY=($(compgen -W "$fields" -- "$cur")) + ;; + *) + COMPREPLY=($(compgen -W "$packopts $unpackopts" \ + -- "$cur")) + ;; + esac + return + ;; + *) + COMPREPLY=($(compgen -W "$options" -- "$cur")) + return + ;; + esac +} && + complete -F _dpkg_source dpkg-source + +# ex: filetype=sh diff --git a/completions/dselect b/completions/dselect new file mode 100644 index 0000000..4c18026 --- /dev/null +++ b/completions/dselect @@ -0,0 +1,29 @@ +# Debian Linux dselect(8) completion -*- shell-script -*- + +_dselect() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --admindir) + _filedir -d + return + ;; + -D | -debug) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + COMPREPLY=($(compgen -W 'access update select install config remove + quit' -- "$cur")) + fi + +} && + complete -F _dselect dselect + +# ex: filetype=sh diff --git a/completions/dsniff b/completions/dsniff new file mode 100644 index 0000000..749c533 --- /dev/null +++ b/completions/dsniff @@ -0,0 +1,26 @@ +# dsniff completion -*- shell-script -*- + +_dsniff() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -r | -w | -f | -p) + _filedir + return + ;; + -i) + _available_interfaces -a + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1") -r -w -p' -- "$cur")) + fi + +} && + complete -F _dsniff dsniff + +# ex: filetype=sh diff --git a/completions/dumpdb b/completions/dumpdb new file mode 100644 index 0000000..eb1927f --- /dev/null +++ b/completions/dumpdb @@ -0,0 +1,18 @@ +# mailman dumpdb completion -*- shell-script -*- + +_dumpdb() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--marshal --pickle --noprint --help' \ + -- "$cur")) + else + _filedir + fi + +} && + complete -F _dumpdb dumpdb + +# ex: filetype=sh diff --git a/completions/dumpe2fs b/completions/dumpe2fs new file mode 100644 index 0000000..413a5bf --- /dev/null +++ b/completions/dumpe2fs @@ -0,0 +1,28 @@ +# dumpe2fs(8) completion -*- shell-script -*- + +_dumpe2fs() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*[oV]) + return + ;; + -*i) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + return + fi + + cur=${cur:=/dev/} + _filedir +} && + complete -F _dumpe2fs dumpe2fs + +# ex: filetype=sh diff --git a/completions/e2freefrag b/completions/e2freefrag new file mode 100644 index 0000000..c89dc9c --- /dev/null +++ b/completions/e2freefrag @@ -0,0 +1,24 @@ +# e2freefrag(8) completion -*- shell-script -*- + +_e2freefrag() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -c | -h) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" -h)' -- "$cur")) + return + fi + + cur=${cur:=/dev/} + _filedir +} && + complete -F _e2freefrag e2freefrag + +# ex: filetype=sh diff --git a/completions/e2label b/completions/e2label new file mode 100644 index 0000000..ac8e4b5 --- /dev/null +++ b/completions/e2label @@ -0,0 +1,15 @@ +# e2label(8) completion -*- shell-script -*- + +_e2label() +{ + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + cur=${cur:=/dev/} + _filedir + fi +} && + complete -F _e2label e2label + +# ex: filetype=sh diff --git a/completions/ebtables b/completions/ebtables new file mode 100644 index 0000000..de6bc54 --- /dev/null +++ b/completions/ebtables @@ -0,0 +1,78 @@ +# bash completion for ebtables -*- shell-script -*- + +_ebtables() +{ + local cur prev words cword split + _init_completion -s || return + + local table chain='s/^Bridge chain: \([^ ,]\{1,\}\).*$/\1/p' \ + targets='ACCEPT DROP CONTINUE RETURN' + + [[ ${words[*]} =~ [[:space:]]-(t|-table=?)[[:space:]]*([^[:space:]]+) ]] && + table="-t ${BASH_REMATCH[2]}" + + case $prev in + -!(-*)[AIDPFXLZ]) + COMPREPLY=($(compgen -W '`"$1" $table -L 2>/dev/null | \ + command sed -ne "$chain"`' -- "$cur")) + ;; + -!(-*)t) + COMPREPLY=($(compgen -W 'nat filter broute' -- "$cur")) + ;; + -!(-*)j) + if [[ $table == "-t filter" || -z $table ]]; then + COMPREPLY=($(compgen -W '$targets + $("$1" $table -L 2>/dev/null | \ + command sed -n -e "s/INPUT\|OUTPUT\|FORWARD//" \ + -e "$chain")' \ + -- "$cur")) + elif [[ $table == "-t nat" ]]; then + COMPREPLY=($(compgen -W '$targets + $("$1" $table -L 2>/dev/null | \ + command sed -n -e "s/OUTPUT|PREROUTING|POSTROUTING//" \ + -e "$chain")' \ + -- "$cur")) + elif [[ $table == "-t broute" ]]; then + COMPREPLY=($(compgen -W 'ACCEPT DROP + $("$1" $table -L 2>/dev/null | \ + command sed -n -e "s/BROUTING//" -e "$chain")' \ + -- "$cur")) + fi + ;; + *) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--802_3-sap --802_3-type --among-dst + --among-dst-file --among-src --among-src-file --append + --arp-gratuitous --arp-htype --arp-ip-dst --arp-ip-src + --arp-mac-dst --arp-mac-src --arp-opcode --arp-ptype --arpreply-mac + --arpreply-target --atomic-commit --atomic-file --atomic-init + --atomic-save --change-counters --concurrent --delete + --delete-chain --destination --dnat-target --dst --flush --help + --in-if --in-interface --init-table --insert --ip6-destination + --ip6-destination-port --ip6-dport --ip6-dst --ip6-icmp-type + --ip6-prococol --ip6-proto --ip6-protocol --ip6-source + --ip6-source-port --ip6-sport --ip6-src --ip6-tclass + --ip-destination --ip-destination-port --ip-dport --ip-dst + --ip-proto --ip-protocol --ip-source --ip-source-port --ip-sport + --ip-src --ip-tos --jump --Lc --limit --limit-burst --list --Lmac2 + --Ln --log --log-arp --logical-in --logical-out --log-ip --log-ip6 + --log-level --log-prefix --Lx --mark --mark-and --mark-or + --mark-set --mark-target --mark-xor --modprobe --new-chain --nflog + --nflog-group --nflog-prefix --nflog-range --nflog-threshold + --out-if --out-interface --pkttype-type --policy --proto --protocol + --redirect-target --rename-chain --set-counter --snat-arp + --snat-target --source --src --stp-flags --stp-forward-delay + --stp-hello-time --stp-max-age --stp-msg-age --stp-port + --stp-root-addr --stp-root-cost --stp-root-prio --stp-sender-addr + --stp-sender-prio --stp-type --table --to-destination --to-dst + --to-source --to-src --ulog --ulog-cprange --ulog-nlgroup + --ulog-prefix --ulog-qthreshold --version --vlan-encap --vlan-id + --vlan-prio --zero' -- "$cur")) + fi + ;; + esac + +} && + complete -F _ebtables ebtables + +# ex: filetype=sh diff --git a/completions/ecryptfs-migrate-home b/completions/ecryptfs-migrate-home new file mode 100644 index 0000000..d2eeb38 --- /dev/null +++ b/completions/ecryptfs-migrate-home @@ -0,0 +1,22 @@ +# ecryptfs-migrate-home(8) completion -*- shell-script -*- + +_ecryptfs_migrate_home() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help) + return + ;; + --user | -u) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + esac + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _ecryptfs_migrate_home ecryptfs-migrate-home + +# ex: filetype=sh diff --git a/completions/eog b/completions/eog new file mode 100644 index 0000000..2330e1a --- /dev/null +++ b/completions/eog @@ -0,0 +1,26 @@ +# eog(1) completion -*- shell-script -*- + +_eog() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -'?' | --help | --help-all | --help-gtk) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --help-all)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir '@(ani|?(w)bmp|gif|ico|j2[ck]|jp[cefgx2]|jpeg|jpg2|pcx|p[gp]m|pn[gm]|ras|svg?(z)|tga|tif?(f)|x[bp]m)' +} && + complete -F _eog eog + +# ex: filetype=sh diff --git a/completions/ether-wake b/completions/ether-wake new file mode 100644 index 0000000..d952673 --- /dev/null +++ b/completions/ether-wake @@ -0,0 +1,27 @@ +# ether-wake(8) completion -*- shell-script -*- + +_ether_wake() +{ + local cur prev words cword + _init_completion -n : || return + + case $prev in + -i) + _available_interfaces -a + return + ;; + -p) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -u) -V' -- "$cur")) + return + fi + + _mac_addresses +} && + complete -F _ether_wake ether-wake etherwake + +# ex: filetype=sh diff --git a/completions/evince b/completions/evince new file mode 100644 index 0000000..1c97dd9 --- /dev/null +++ b/completions/evince @@ -0,0 +1,32 @@ +# evince(1) completion -*- shell-script -*- + +_evince() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help* | --sm-client-id | --class | --name | --screen | --gdk-debug | \ + --gdk-no-debug | --gtk-module | --gtk-debug | --gtk-no-debug | --page-label | \ + --page-index | --find | --display | -!(-*)[hpil]) + return + ;; + --sm-client-state-file) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --help-all)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir '@(@(?(e)ps|?(E)PS|[pf]df|[PF]DF|dvi|DVI)?(.gz|.GZ|.bz2|.BZ2|.xz|.XZ)|cb[rz]|djv?(u)|gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx)' +} && + complete -F _evince evince + +# ex: filetype=sh diff --git a/completions/explodepkg b/completions/explodepkg new file mode 100644 index 0000000..a281f81 --- /dev/null +++ b/completions/explodepkg @@ -0,0 +1,5 @@ +# Slackware Linux explodepkg completion -*- shell-script -*- + +complete -o plusdirs -f -X '!*.t[bglx]z' explodepkg + +# ex: filetype=sh diff --git a/completions/export b/completions/export new file mode 100644 index 0000000..8d82361 --- /dev/null +++ b/completions/export @@ -0,0 +1,65 @@ +# bash export completion -*- shell-script -*- + +_export() +{ + local cur prev words cword + _init_completion -n = || return + + local i action=variable remove=false + for ((i = 1; i < cword; i++)); do + case ${words[i]} in + -p) + return + ;; + -*f*) + action=function + ;;& + -*n*) + remove=true + ;; + -*) + continue + ;; + esac + break + done + + if [[ $cur == *=* ]]; then + local ocur=$cur oprev=$prev + prev=${cur%%=*} cur=${cur#*=} + _variables && return + cur=$ocur prev=$oprev + fi + + case $cur in + *=) + local pval=$(quote "$(eval printf %s \"\$\{${cur%=}-\}\")") + # Complete previous value if it's not empty. + if [[ $pval != \'\' ]]; then + COMPREPLY=("$pval") + else + cur=${cur#*=} + _filedir + fi + ;; + *=*) + cur=${cur#*=} + _filedir + ;; + *) + if [[ $cword -eq 1 && $cur == -* ]]; then + COMPREPLY=($(compgen -W '-p $(_parse_usage "$1")' -- "$cur")) + return + fi + local suffix="" + if ! $remove; then + suffix="=" + compopt -o nospace + fi + COMPREPLY=($(compgen -A $action -S "$suffix" -- "$cur")) + ;; + esac +} && + complete -F _export export + +# ex: filetype=sh diff --git a/completions/faillog b/completions/faillog new file mode 100644 index 0000000..c8b81bd --- /dev/null +++ b/completions/faillog @@ -0,0 +1,27 @@ +# faillog(8) completion -*- shell-script -*- + +_faillog() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --lock-time | --maximum | --time | -!(-*)[hlmt]) + return + ;; + --user | -!(-*)u) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _faillog faillog + +# ex: filetype=sh diff --git a/completions/fbgs b/completions/fbgs new file mode 100644 index 0000000..1947b87 --- /dev/null +++ b/completions/fbgs @@ -0,0 +1,50 @@ +# bash completion for fbgs(1) -*- shell-script -*- + +_fbgs() +{ + local cur prev words cword + _init_completion || return + + case "$prev" in + -f | --font) + local IFS=$'\n' + COMPREPLY=($(compgen -W '$(fc-list 2>/dev/null)' -- "$cur")) + return + ;; + -m | --mode) + COMPREPLY=($(compgen -W '$(command sed \ + -n "/^mode/{s/^mode \{1,\}\"\([^\"]\{1,\}\)\"/\1/g;p}" \ + /etc/fb.modes 2>/dev/null)' -- "$cur")) + return + ;; + -d | --device) + COMPREPLY=($(compgen -f -d -- "${cur:-/dev/}")) + return + ;; + -fp | --firstpage | -lp | --lastpage | -r | --resolution | -s | --scroll | -t | \ + --timeout) + # expect integer value + COMPREPLY+=($(compgen -W '{0..9}')) + compopt -o nospace + return + ;; + -T | --vt | -p | --password | -g | --gamma) + # argument required but no completions available + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--bell --help --password -fp --firstpage + -lp --lastpage --color -l -xl -xxl --resolution --autozoom + --{,no}autoup --{,no}autodown --{,no}fitwidth --{,no}verbose + --{,no}random --vt --scroll --timeout --{,no}once --gamma --font + --device --mode' -- "$cur")) + [[ ${COMPREPLY-} ]] && return + fi + + _filedir '?(e)ps|pdf' +} && + complete -F _fbgs fbgs + +# ex: filetype=sh diff --git a/completions/fbi b/completions/fbi new file mode 100644 index 0000000..455887a --- /dev/null +++ b/completions/fbi @@ -0,0 +1,54 @@ +# bash completion for fbi(1) -*- shell-script -*- + +_fbi() +{ + local cur prev words cword + _init_completion || return + + case "$prev" in + -l | --list) + _filedir + return + ;; + -r | --resolution) + COMPREPLY+=($(compgen -W '{1..5}')) + return + ;; + -f | --font) + local IFS=$'\n' + COMPREPLY=($(compgen -W '$(fc-list 2>/dev/null)' -- "$cur")) + return + ;; + -m | --mode) + COMPREPLY=($(compgen -W '$(command sed \ + -n "/^mode/{s/^mode \{1,\}\"\([^\"]\{1,\}\)\"/\1/g;p}" \ + /etc/fb.modes 2>/dev/null)' -- "$cur")) + return + ;; + -d | --device) + COMPREPLY=($(compgen -f -d -- "${cur:-/dev/}")) + return + ;; + --cachemem | --blend | -T | --vt | -s | --scroll | -t | --timeout | -g | --gamma) + # argument required but no completions available + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--help --version --store --list --text + --autozoom --{,no}autoup --{,no}autodown --{,no}fitwidth + --{,no}verbose --{,no}random --{,no}comments --{,no}edit + --{,no}backup --{,no}preserve --{,no}readahead --cachemem --blend + --vt --scroll --timeout --{,no}once --resolution --gamma --font + --device --mode' -- "$cur")) + [[ ${COMPREPLY-} ]] && return + fi + + # FIXME: It is hard to determine correct supported extensions. + # fbi can handle any format that imagemagick can plus some others + _filedir 'bmp|gif|jp?(e)g|pcd|png|p[pgb]m|tif?(f)|webp|xpm|xwd|?(e)ps|pdf|dvi|txt|svg?(z)|cdr|[ot]tf' +} && + complete -F _fbi fbi + +# ex: filetype=sh diff --git a/completions/feh b/completions/feh new file mode 100644 index 0000000..f1d4b18 --- /dev/null +++ b/completions/feh @@ -0,0 +1,120 @@ +# bash completion for feh(1) -*- shell-script -*- + +_feh() +{ + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + --image-bg | -B) + COMPREPLY=($(compgen -W 'checks white black' -- "$cur")) + return + ;; + --filelist | --output | --output-only | --start-at | -!(-*)[foO\|]) + _filedir + return + ;; + --caption-path | --fontpath | --output-dir | -!(-*)[KCj]) + _filedir -d + return + ;; + --font | --menu-font | --title-font | -!(-*)[eM@]) + # expect string like "dejavu.ttf/12" + if [[ $cur == */* ]]; then # expect integer value + COMPREPLY=($(compgen -P "$cur" -W '{0..9}')) + compopt -o nospace + return + fi + local font_path + # font_path="$(imlib2-config --prefix 2>/dev/null)/share/imlib2/data/fonts" + # COMPREPLY=( $(cd "$font_path" 2>/dev/null; compgen -f \ + # -X "!*.@([tT][tT][fF])" -S / -- "$cur") ) + for ((i = ${#words[@]} - 1; i > 0; i--)); do + if [[ ${words[i]} == -@(C|-fontpath) ]]; then + font_path="${words[i + 1]}" + COMPREPLY+=($( + cd "$font_path" 2>/dev/null + compgen -f \ + -X "!*.@([tT][tT][fF])" -S / -- "$cur" + )) + fi + done + compopt -o nospace + return + ;; + --theme | -!(-*)T) + local conf_path=~/.config/feh/themes + local theme_name theme_opts + [[ -r $conf_path ]] || return + while read theme_name theme_opts; do + if [[ $theme_name == '#'* || $theme_name == "" ]]; then + continue + fi + COMPREPLY+=($(compgen -W "$theme_name" -- "$cur")) + done <"$conf_path" + return + ;; + --sort | -!(-*)S) + COMPREPLY=($(compgen -W 'name filename mtime width height + pixels size format' -- "$cur")) + return + ;; + --reload | --limit-height | --limit-width | --thumb-height | --thumb-width | \ + --thumb-redraw | --magick-timeout | -!(-*)[RHWEyJ]) + # expect integer value + COMPREPLY+=($(compgen -W '{0..9}')) + compopt -o nospace + return + ;; + --zoom) + # expect integer value or "max", "fill" + COMPREPLY=($(compgen -W 'max fill' -- "$cur")) + if [[ ! $cur || ! ${COMPREPLY-} ]]; then + COMPREPLY+=($(compgen -W '{0..9}')) + compopt -o nospace + fi + return + ;; + --alpha | -!(-*)a) + COMPREPLY=($(compgen -W '{0..255}' -- "$cur")) + return + ;; + --bg | -!(-*)b) + _filedir + COMPREPLY+=($(compgen -W 'trans' -- "$cur")) + return + ;; + --geometry | --max-dimension | --min-dimension | -!(-*)g) + # expect string like 640x480 + if [[ $cur && $cur != *x* ]]; then + COMPREPLY=(x) + fi + COMPREPLY+=($(compgen -W "{0..9}")) + compopt -o nospace + return + ;; + --customlist | --index-info | --info | --slideshow-delay | --thumb-title | \ + --title | -!(-*)[LD~^]) + # argument required but no completions available + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + # Some versions of feh just output "See 'man feh'" for --help :( + COMPREPLY=($(compgen -W '$(_parse_help "$1" --help)' -- "$cur")) + if [[ ${COMPREPLY-} ]]; then + [[ $COMPREPLY == *= ]] && compopt -o nospace + return + fi + fi + + # FIXME: It is hard to determine correct supported extensions. + # feh can handle any format that imagemagick can plus some others + _filedir 'xpm|tif?(f)|png|p[npgba]m|iff|?(i)lbm|jp?(e)g|jfi?(f)|gif|bmp|arg?(b)|tga|xcf|ani|ico|?(e)ps|pdf|dvi|txt|svg?(z)|cdr|[ot]tf' +} && + complete -F _feh feh + +# ex: filetype=sh diff --git a/completions/file b/completions/file new file mode 100644 index 0000000..21fbd16 --- /dev/null +++ b/completions/file @@ -0,0 +1,32 @@ +# file(1) completion -*- shell-script -*- + +_file() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | --separator | -!(-*)[vF]) + return + ;; + --magic-file | --files-from | -!(-*)[mf]) + _filedir + return + ;; + --exclude | -!(-*)e) + COMPREPLY=($(compgen -W 'apptype ascii cdf compress elf encoding + soft tar text tokens troff' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + _filedir +} && + complete -F _file file + +# ex: filetype=sh diff --git a/completions/file-roller b/completions/file-roller new file mode 100644 index 0000000..1d223fd --- /dev/null +++ b/completions/file-roller @@ -0,0 +1,42 @@ +# file-roller(1) completion -*- shell-script -*- + +_file_roller() +{ + local cur prev words cword split + _init_completion -s || return + + local exts='@(7z|ace|alz|ar|arj|[bglx]z|bz2|tb?(z)2|cab|cb[rz]|iso?(9660)|Z|t[abglx]z|cpio|deb|rar|?(g)tar|gem|lh[az]|lz[4h]|?(t)lrz|lzma|lzo|wim|swm|rpm|sit|zoo)' + + case $prev in + --help | --help-all | --help-gtk | --help-sm-client | -!(-*)'?') + return + ;; + --sm-client-state-file) + _filedir + return + ;; + --add-to | -!(-*)a) + _filedir_xspec unzip + _filedir "$exts" + return + ;; + --extract-to | --default-dir | -!(-*)e) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --help-all)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir_xspec unzip + _filedir "$exts" +} && + complete -F _file_roller file-roller + +# ex: filetype=sh diff --git a/completions/filefrag b/completions/filefrag new file mode 100644 index 0000000..d26e8c8 --- /dev/null +++ b/completions/filefrag @@ -0,0 +1,17 @@ +# filefrag(8) completion -*- shell-script -*- + +_filefrag() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + return + fi + + _filedir +} && + complete -F _filefrag filefrag + +# ex: filetype=sh diff --git a/completions/filesnarf b/completions/filesnarf new file mode 100644 index 0000000..f959d80 --- /dev/null +++ b/completions/filesnarf @@ -0,0 +1,22 @@ +# filesnarf etc completion -*- shell-script -*- + +_snarf() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -i) + _available_interfaces -a + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + fi + +} && + complete -F _snarf filesnarf mailsnarf msgsnarf + +# ex: filetype=sh diff --git a/completions/find b/completions/find new file mode 100644 index 0000000..64121ed --- /dev/null +++ b/completions/find @@ -0,0 +1,113 @@ +# bash completion for GNU find -*- shell-script -*- +# This makes heavy use of ksh style extended globs and contains Linux specific +# code for completing the parameter to the -fstype option. + +_find() +{ + local cur prev words cword + _init_completion || return + + local i + for i in ${!words[*]}; do + if [[ ${words[i]} == -@(exec|ok)?(dir) ]]; then + _command_offset $((i + 1)) + return + fi + done + + case $prev in + -maxdepth | -mindepth) + COMPREPLY=($(compgen -W '{0..9}' -- "$cur")) + return + ;; + -newer | -anewer | -cnewer | -fls | -fprint | -fprint0 | -fprintf | -name | -[il]name | \ + -ilname | -wholename | -[il]wholename | -samefile) + _filedir + return + ;; + -fstype) + _fstypes + [[ $OSTYPE == *bsd* ]] && + COMPREPLY+=($(compgen -W 'local rdonly' -- "$cur")) + return + ;; + -gid) + _gids + return + ;; + -group) + COMPREPLY=($(compgen -g -- "$cur" 2>/dev/null)) + return + ;; + -xtype | -type) + COMPREPLY=($(compgen -W 'b c d p f l s' -- "$cur")) + return + ;; + -uid) + _uids + return + ;; + -user) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + -[acm]min | -[acm]time | -inum | -path | -ipath | -regex | -iregex | -links | -perm | \ + -size | -used | -printf | -context) + # do nothing, just wait for a parameter to be given + return + ;; + -regextype) + COMPREPLY=($(compgen -W 'emacs posix-awk posix-basic posix-egrep + posix-extended' -- "$cur")) + return + ;; + esac + + local i exprfound=false + # set exprfound to true if there is already an expression present + for i in "${words[@]}"; do + [[ $i == [-\(\),\!]* ]] && exprfound=true && break + done + + # handle case where first parameter is not a dash option + if ! $exprfound && [[ $cur != [-\(\),\!]* ]]; then + _filedir -d + return + fi + + # complete using basic options + COMPREPLY=($(compgen -W '-daystart -depth -follow -help + -ignore_readdir_race -maxdepth -mindepth -mindepth -mount + -noignore_readdir_race -noleaf -regextype -version -warn -nowarn -xdev + -amin -anewer -atime -cmin -cnewer -ctime -empty -executable -false + -fstype -gid -group -ilname -iname -inum -ipath -iregex -iwholename + -links -lname -mmin -mtime -name -newer -nogroup -nouser -path -perm + -readable -regex -samefile -size -true -type -uid -used -user + -wholename -writable -xtype -context -delete -exec -execdir -fls + -fprint -fprint0 -fprintf -ls -ok -okdir -print -print0 -printf -prune + -quit' -- "$cur")) + + if ((${#COMPREPLY[@]} != 0)); then + # this removes any options from the list of completions that have + # already been specified somewhere on the command line, as long as + # these options can only be used once (in a word, "options", in + # opposition to "tests" and "actions", as in the find(1) manpage). + local -A onlyonce=([-daystart]=1 [-depth]=1 [-follow]=1 [-help]=1 + [-ignore_readdir_race]=1 [-maxdepth]=1 [-mindepth]=1 [-mount]=1 + [-noignore_readdir_race]=1 [-noleaf]=1 [-nowarn]=1 [-regextype]=1 + [-version]=1 [-warn]=1 [-xdev]=1) + local j + for i in "${words[@]}"; do + [[ $i && -v onlyonce["$i"] ]] || continue + for j in "${!COMPREPLY[@]}"; do + [[ ${COMPREPLY[j]} == "$i" ]] && unset 'COMPREPLY[j]' + done + done + fi + + _filedir + +} && + complete -F _find find + +# ex: filetype=sh diff --git a/completions/find_member b/completions/find_member new file mode 100644 index 0000000..cf30c70 --- /dev/null +++ b/completions/find_member @@ -0,0 +1,25 @@ +# mailman find_member completion -*- shell-script -*- + +_find_member() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -l | -x | --listname | --exclude) + _xfunc list_lists _mailman_lists + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--listname --exclude --owners --help' \ + -- "$cur")) + fi + +} && + complete -F _find_member find_member + +# ex: filetype=sh diff --git a/completions/fio b/completions/fio new file mode 100644 index 0000000..f81a4da --- /dev/null +++ b/completions/fio @@ -0,0 +1,90 @@ +# fio(1) completion -*- shell-script -*- + +_fio() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version) + return + ;; + --debug) + local prefix= + [[ $cur == *,* ]] && prefix="${cur%,*}," + COMPREPLY=($(compgen -W "process file io mem blktrace verify + random parse diskutil job mutex profile time net rate compress + steadystate helperthread" -- "${cur##*,}")) + ((${#COMPREPLY[@]} == 1)) && COMPREPLY=(${COMPREPLY/#/$prefix}) + return + ;; + --output-format) + COMPREPLY=($(compgen -W "terse json json+ normal" -- "$cur")) + return + ;; + --terse-version) + COMPREPLY=($(compgen -W "2 3" -- "$cur")) + return + ;; + --cmdhelp) + # TODO more commands? + COMPREPLY=($(compgen -W "all" -- "$cur")) + return + ;; + --enghelp) + # TODO print ioengine help, or list available ioengines + # TODO engine,help arg + return + ;; + --eta) + COMPREPLY=($(compgen -W "always never auto" -- "$cur")) + return + ;; + --daemonize) + _filedir pid + return + ;; + --client) + _known_hosts_real -- "$cur" + return + ;; + --remote-config) + _filedir job + return + ;; + --idle-prof) + COMPREPLY=($(compgen -W "system percpu calibrate" -- "$cur")) + return + ;; + --inflate-log) + _filedir log + return + ;; + --trigger-file) + _filedir + return + ;; + --trigger | --trigger-remote) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + --aux-path) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir job +} && + complete -F _fio fio + +# ex: filetype=sh diff --git a/completions/firefox b/completions/firefox new file mode 100644 index 0000000..4656f8d --- /dev/null +++ b/completions/firefox @@ -0,0 +1,46 @@ +# firefox completion -*- shell-script -*- + +_firefox() +{ + local cur prev words cword split + _init_completion -s || return + + [[ $cur == -MOZ_LOG*=* ]] && prev=${cur%%=*} cur=${cur#*=} + + case $prev in + --help | --version | --display | --UILocale | -MOZ_LOG | --new-window | --new-tab | \ + --private-window | --window-size | --search | --start-debugger-server | \ + --recording | --debugger-args | -[hvPa]) + return + ;; + --profile | --screenshot) + _filedir -d + return + ;; + -MOZ_LOG_FILE) + _filedir log + return + ;; + --recording-file) + _filedir + return + ;; + --debugger | -d) + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir "@(?([xs])htm?(l)|pdf|txt)" +} && + complete -F _firefox firefox mozilla-firefox iceweasel + +# ex: filetype=sh diff --git a/completions/flake8 b/completions/flake8 new file mode 100644 index 0000000..045c409 --- /dev/null +++ b/completions/flake8 @@ -0,0 +1,42 @@ +# flake8 completion -*- shell-script -*- + +_flake8() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | -!(-*)h) + return + ;; + --format) + COMPREPLY=($(compgen -W 'default pylint' -- "$cur")) + return + ;; + --jobs | -!(-*)j) + COMPREPLY=($(compgen -W "auto {1..$(_ncpus)}" -- "$cur")) + return + ;; + --output-file | --append-config | --config) + _filedir + return + ;; + --include-in-doctest | --exclude-from-doctest) + _filedir py + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir py +} && + complete -F _flake8 flake8 + +# ex: filetype=sh diff --git a/completions/freebsd-update b/completions/freebsd-update new file mode 100644 index 0000000..d5be861 --- /dev/null +++ b/completions/freebsd-update @@ -0,0 +1,29 @@ +# bash completion for FreeBSD update tool - freebsd-update -*- shell-script -*- + +[[ $OSTYPE == *freebsd* ]] || return 1 + +_freebsd_update() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -b | -d) + _filedir -d + return + ;; + -f) + _filedir + return + ;; + -k | -r | -s | -t) + return + ;; + esac + + COMPREPLY=($(compgen -W "fetch cron upgrade install rollback IDS" -- \ + $cur)) +} && + complete -F _freebsd_update freebsd-update + +# ex: filetype=sh diff --git a/completions/freeciv b/completions/freeciv new file mode 100644 index 0000000..01af311 --- /dev/null +++ b/completions/freeciv @@ -0,0 +1,41 @@ +# freeciv client completions -*- shell-script -*- + +_freeciv() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | --name | --port | -[hvnp]) + return + ;; + --file | --log | --music | --read | --Sound | --tiles | -[flmrSt]) + _filedir + return + ;; + --Announce | -A) + COMPREPLY=($(compgen -W 'IPv4 IPv6 none' -- "$cur")) + return + ;; + --debug | -d) + COMPREPLY=($(compgen -W '{0..3}' -- "$cur")) + return + ;; + --Meta | --server | -[Ms]) + _known_hosts_real -- "$cur" + return + ;; + --Plugin | -P) + COMPREPLY=($(compgen -W 'none esd sdl' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + fi + +} && + complete -F _freeciv freeciv{,-{gtk{2,3},sdl,xaw}} civclient + +# ex: filetype=sh diff --git a/completions/freeciv-server b/completions/freeciv-server new file mode 100644 index 0000000..a34b5a2 --- /dev/null +++ b/completions/freeciv-server @@ -0,0 +1,22 @@ +# freeciv-server completion -*- shell-script -*- + +_civserver() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -f | -g | -l | -r | --file | --log | --gamelog | --read) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + fi + +} && + complete -F _civserver civserver freeciv-server + +# ex: filetype=sh diff --git a/completions/function b/completions/function new file mode 100644 index 0000000..6ae5271 --- /dev/null +++ b/completions/function @@ -0,0 +1,37 @@ +# bash shell function completion -*- shell-script -*- + +_function() +{ + local cur prev words cword + _init_completion || return + + if [[ $1 == @(declare|typeset) ]]; then + if [[ $cur == [-+]* ]]; then + local opts + opts=($(_parse_usage "$1")) + # Most options also have a '+' form. We'll exclude the ones that don't with compgen. + opts+=(${opts[*]/-/+}) + COMPREPLY=($(compgen -W "${opts[*]}" -X '+[Ffgp]' -- "$cur")) + else + local i=1 + while [[ ${words[i]} == [-+]* ]]; do + if [[ ${words[i]} == -*[fF]* ]]; then + COMPREPLY=($(compgen -A function -- "$cur")) + return + fi + ((i++)) + done + if ((i > 1)); then + # There was at least one option and it was not one that limited operations to functions + COMPREPLY=($(compgen -A variable -- "$cur")) + fi + fi + elif ((cword == 1)); then + COMPREPLY=($(compgen -A function -- "$cur")) + else + COMPREPLY=("() $(type -- ${words[1]} | command sed -e 1,2d)") + fi +} && + complete -F _function function declare typeset + +# ex: filetype=sh diff --git a/completions/fusermount b/completions/fusermount new file mode 100644 index 0000000..7e48922 --- /dev/null +++ b/completions/fusermount @@ -0,0 +1,28 @@ +# fusermount completion -*- shell-script -*- + +_fusermount() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*[hVo]) + return + ;; + -*u) + COMPREPLY=($(compgen -W "$(awk \ + '{ if ($3 ~ /^fuse(\.|$)/) print $2 }' /etc/mtab \ + 2>/dev/null)" -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + else + _filedir -d + fi +} && + complete -F _fusermount fusermount + +# ex: filetype=sh diff --git a/completions/gcc b/completions/gcc new file mode 100644 index 0000000..fa95274 --- /dev/null +++ b/completions/gcc @@ -0,0 +1,75 @@ +# gcc(1) completion -*- shell-script -*- + +_gcc() +{ + local cur prev prev2 words cword argument prefix prefix_length + _init_completion || return + + # Test that GCC is recent enough and if not fallback to + # parsing of --completion option. + if ! $1 --completion=" " 2>/dev/null; then + if [[ $cur == -* ]]; then + local cc=$($1 -print-prog-name=cc1 2>/dev/null) + [[ $cc ]] || return + COMPREPLY=($(compgen -W "$($cc --help 2>/dev/null | tr '\t' ' ' | + command sed -e '/^ *-/!d' -e 's/ *-\([^][ <>]*\).*/-\1/')" \ + -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _filedir + fi + return + fi + + # extract also for situations like: -fsanitize=add + if ((cword > 2)); then + prev2="${COMP_WORDS[cword - 2]}" + fi + + # sample: -fsan + if [[ $cur == -* ]]; then + argument=$cur + prefix="" + # sample: -fsanitize= + elif [[ $cur == "=" && $prev == -* ]]; then + argument=$prev$cur + prefix=$prev$cur + # sample: -fsanitize=add + elif [[ $prev == "=" && $prev2 == -* ]]; then + argument=$prev2$prev$cur + prefix=$prev2$prev + # sample: --param lto- + elif [[ $prev == --param ]]; then + argument="$prev $cur" + prefix="$prev " + fi + + if [[ ! -v argument ]]; then + _filedir + else + # In situation like '-fsanitize=add' $cur is equal to last token. + # Thus we need to strip the beginning of suggested option. + prefix_length=$((${#prefix} + 1)) + local flags=$($1 --completion="$argument" | cut -c $prefix_length-) + [[ ${flags} == "=*" ]] && compopt -o nospace 2>/dev/null + COMPREPLY=($(compgen -W "$flags" -- "")) + fi +} && + complete -F _gcc gcc{,-5,-6,-7,-8} g++{,-5,-6,-7,-8} g77 g95 \ + gccgo{,-5,-6,-7,-8} gcj gfortran{,-5,-6,-7,-8} gpc && + { + cc --version 2>/dev/null | command grep -q GCC || + [[ $(_realcommand cc) == *gcc* ]] && + complete -F _gcc cc || complete -F _minimal cc + c++ --version 2>/dev/null | command grep -q GCC || + [[ $(_realcommand c++) == *g++* ]] && + complete -F _gcc c++ || complete -F _minimal c++ + f77 --version 2>/dev/null | command grep -q GCC || + [[ $(_realcommand f77) == *gfortran* ]] && + complete -F _gcc f77 || complete -F _minimal f77 + f95 --version 2>/dev/null | command grep -q GCC || + [[ $(_realcommand f95) == *gfortran* ]] && + complete -F _gcc f95 || complete -F _minimal f95 + } + +# ex: filetype=sh diff --git a/completions/gcl b/completions/gcl new file mode 100644 index 0000000..73a18b2 --- /dev/null +++ b/completions/gcl @@ -0,0 +1,21 @@ +# -*- shell-script -*- +# bash programmable completion for various Common Lisp implementations by +# Nikodemus Siivola <nikodemus@random-state.net> + +_gcl() +{ + local cur prev words cword + _init_completion || return + + # completing an option (may or may not be separated by a space) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-eval -load -f -batch -dir -libdir -compile + -o-file -c-file -h-file -data-file -system-p' -- "$cur")) + else + _filedir + fi + +} && + complete -F _gcl -o default gcl + +# ex: filetype=sh diff --git a/completions/gdb b/completions/gdb new file mode 100644 index 0000000..f78f8a5 --- /dev/null +++ b/completions/gdb @@ -0,0 +1,47 @@ +# bash completion for gdb -*- shell-script -*- + +_gdb() +{ + local cur prev words cword i + _init_completion || return + + # gdb [options] --args executable-file [inferior-arguments ...] + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == --args ]]; then + _command_offset $((i + 1)) + return $? + fi + done + + # gdb [options] [executable-file [core-file or process-id]] + if ((cword == 1)); then + local IFS + compopt -o filenames + if [[ $cur == */* ]]; then + # compgen -c works as expected if $cur contains any slashes. + IFS=$'\n' + COMPREPLY=($(PATH="$PATH:." compgen -d -c -- "$cur")) + else + # otherwise compgen -c contains Bash's built-in commands, + # functions and aliases. Thus we need to retrieve the program + # names manually. + IFS=":" + local path_array=($( + command sed -e 's/:\{2,\}/:/g' -e 's/^://' -e 's/:$//' <<<"$PATH" + )) + IFS=$'\n' + COMPREPLY=($(compgen -d -W '$(find "${path_array[@]}" . \ + -mindepth 1 -maxdepth 1 -not -type d -executable \ + -printf "%f\\n" 2>/dev/null)' -- "$cur")) + fi + elif ((cword == 2)); then + COMPREPLY=($(compgen -W "$(command ps axo comm,pid | + awk '{if ($1 ~ /^'"${prev##*/}"'/) print $2}')" -- "$cur")) + compopt -o filenames + COMPREPLY+=($(compgen -f -X '!?(*/)core?(.?*)' -o plusdirs \ + -- "$cur")) + fi +} && + complete -F _gdb gdb + +# ex: filetype=sh diff --git a/completions/genaliases b/completions/genaliases new file mode 100644 index 0000000..5953b9e --- /dev/null +++ b/completions/genaliases @@ -0,0 +1,15 @@ +# mailman genaliases completion -*- shell-script -*- + +_genaliases() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--quiet --help' -- "$cur")) + fi + +} && + complete -F _genaliases genaliases + +# ex: filetype=sh diff --git a/completions/gendiff b/completions/gendiff new file mode 100644 index 0000000..d37793f --- /dev/null +++ b/completions/gendiff @@ -0,0 +1,12 @@ +# gendiff(1) completion -*- shell-script -*- + +_gendiff() +{ + local cur prev words cword + _init_completion -o '@(diff|patch)' || return + + ((cword == 1)) && _filedir -d +} && + complete -F _gendiff gendiff + +# ex: filetype=sh diff --git a/completions/genisoimage b/completions/genisoimage new file mode 100644 index 0000000..dfa39c0 --- /dev/null +++ b/completions/genisoimage @@ -0,0 +1,38 @@ +# bash completion for mkisofs/genisoimage -*- shell-script -*- + +_mkisofs() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -o | -abstract | -biblio | -check-session | -copyright | -log-file | \ + -root-info | -prep-boot | -*-list) + _filedir + return + ;; + -*-charset) + COMPREPLY=($(compgen -W '$(mkisofs -input-charset \ + help 2>&1 | tail -n +3)' -- "$cur")) + return + ;; + -uid) + _uids + return + ;; + -gid) + _gids + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + else + _filedir + fi + +} && + complete -F _mkisofs mkisofs genisoimage + +# ex: filetype=sh diff --git a/completions/geoiplookup b/completions/geoiplookup new file mode 100644 index 0000000..c60be89 --- /dev/null +++ b/completions/geoiplookup @@ -0,0 +1,33 @@ +# geoiplookup(1) completion -*- shell-script -*- + +_geoiplookup() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h | -'?' | -v) + return + ;; + -d) + _filedir -d + return + ;; + -f) + _filedir dat + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" -h)' -- "$cur")) + return + fi + + local ipvx + [[ $1 == *6 ]] && ipvx=-6 || ipvx=-4 + _known_hosts_real $ipvx -- "$cur" +} && + complete -F _geoiplookup geoiplookup geoiplookup6 + +# ex: filetype=sh diff --git a/completions/getconf b/completions/getconf new file mode 100644 index 0000000..de1ad2d --- /dev/null +++ b/completions/getconf @@ -0,0 +1,32 @@ +# getconf(1) completion -*- shell-script -*- + +_getconf() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -a) + _filedir + return + ;; + -v) + COMPREPLY=($(compgen -W \ + '$("$1" -a 2>/dev/null | awk "{ print \$1 }")' -- \ + "${cur:-POSIX_V}")) + return + ;; + esac + + if [[ $prev == PATH_MAX ]]; then # TODO more path vars, better handling + _filedir + elif [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-a -v' -- "$cur")) + else + COMPREPLY=($(compgen -W \ + '$("$1" -a 2>/dev/null | awk "{ print \$1 }")' -- "$cur")) + fi +} && + complete -F _getconf getconf + +# ex: filetype=sh diff --git a/completions/getent b/completions/getent new file mode 100644 index 0000000..4c54a24 --- /dev/null +++ b/completions/getent @@ -0,0 +1,77 @@ +# bash completion for getent -*- shell-script -*- + +_getent() +{ + local cur prev words cword split + _init_completion -s || return + + local i db + for ((i = 1; i < cword; i++)); do + case ${words[i]} in + --version | --usage | --help | -!(-*)[V?]) + return + ;; + --service | -!(-*)s) + ((i++)) + ;; + -*) ;; + + *) + # First non-option value is the db + db=${words[i]} + break + ;; + esac + done + + case ${db-} in + passwd) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + group) + COMPREPLY=($(compgen -g -- "$cur")) + return + ;; + services) + COMPREPLY=($(compgen -s -- "$cur")) + return + ;; + hosts) + COMPREPLY=($(compgen -A hostname -- "$cur")) + return + ;; + protocols | networks | ahosts | ahostsv4 | ahostsv6 | rpc) + COMPREPLY=($(compgen -W "$($1 $db | + awk '{ print $1 }')" -- "$cur")) + return + ;; + aliases | shadow | gshadow) + COMPREPLY=($(compgen -W "$($1 $db | cut -d: -f1)" -- "$cur")) + return + ;; + ethers | netgroup) + return + ;; + esac + + case $prev in + -s | --service) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + elif [[ ! -v db ]]; then + COMPREPLY=($(compgen -W 'passwd group hosts services protocols + networks ahosts ahostsv4 ahostsv6 aliases ethers netgroup rpc + shadow gshadow' -- "$cur")) + fi +} && + complete -F _getent getent + +# ex: filetype=sh diff --git a/completions/gkrellm b/completions/gkrellm new file mode 100644 index 0000000..c38c5ae --- /dev/null +++ b/completions/gkrellm @@ -0,0 +1,39 @@ +# gkrellm(1) completion -*- shell-script -*- + +_gkrellm() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -t | --theme) + _filedir -d + return + ;; + -p | --plugin) + _filedir so + return + ;; + -s | --server) + _known_hosts_real -- "$cur" + return + ;; + -l | --logfile) + _filedir + return + ;; + -g | --geometry | -c | --config | -P | --port | -d | --debug-level) + # Argument required but no completions available + return + ;; + -h | --help | -v | --version) + # All other options are noop with these + return + ;; + esac + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _gkrellm gkrellm gkrellm2 + +# ex: filetype=sh diff --git a/completions/gm b/completions/gm new file mode 100644 index 0000000..b86c9cc --- /dev/null +++ b/completions/gm @@ -0,0 +1,40 @@ +# bash completion for gm(1) -*- shell-script -*- + +_gm_commands() +{ + COMPREPLY+=($(compgen -W '$("$1" help | + awk "/^ +[^ ]+ +- / { print \$1 }")' -- "$cur")) +} + +_gm() +{ + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + _gm_commands "$1" + return + elif [[ $cword -eq 2 && ${words[1]} == time ]]; then + _gm_commands "$1" + return + fi + + local gmcmd=${words[1]} + [[ $gmcmd == time ]] && gmcmd=${words[2]} + + case $gmcmd in + help) + [[ $prev == help ]] && _gm_commands "$1" + return + ;; + version) + return + ;; + esac + + # TODO... defer some commnds to the imagemagick "gm"less completions etc? + compopt -o default +} && + complete -F _gm gm + +# ex: filetype=sh diff --git a/completions/gnatmake b/completions/gnatmake new file mode 100644 index 0000000..5f4b963 --- /dev/null +++ b/completions/gnatmake @@ -0,0 +1,26 @@ +# Gnatmake completion -*- shell-script -*- +# by Ralf_Schroth@t-online.de (Ralf Schroth) + +_gnatmake() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + # relevant (and less relevant ;-) )options completion + COMPREPLY=($(compgen -W '-a -c -f -i -j -k -m -M -n -o -q -s -v -z + -aL -A -aO -aI -I -I- -L -nostdinc -nostdlib -cargs -bargs -largs + -fstack-check -fno-inline -g -O1 -O0 -O2 -O3 -gnata -gnatA -gnatb + -gnatc -gnatd -gnatD -gnate -gnatE -gnatf -gnatF -gnatg -gnatG + -gnath -gnati -gnatk -gnatl -gnatL -gnatm -gnatn -gnato -gnatO + -gnatp -gnatP -gnatq -gnatR -gnats -gnatt -gnatT -gnatu -gnatU + -gnatv -gnatws -gnatwe -gnatwl -gnatwu -gnatW -gnatx -gnatX -gnaty + -gnatz -gnatZ -gnat83' -- "$cur")) + else + # source file completion + _filedir '@(adb|ads)' + fi +} && + complete -F _gnatmake gnatmake + +# ex: filetype=sh diff --git a/completions/gnokii b/completions/gnokii new file mode 100644 index 0000000..039141a --- /dev/null +++ b/completions/gnokii @@ -0,0 +1,237 @@ +# gnokii(1) completion -*- shell-script -*- + +_gnokii_memory_type() +{ + # TODO: reduce the number of choices + COMPREPLY=($(compgen -W "IN OU SM ME MT" -- "$cur")) +} + +_gnokii() +{ + local cur prev words cword pprev tprev fprev + _init_completion || return + + case $prev in + --config) + _filedir + return + ;; + --phone) + local config_file + for config_file in "$XDG_CONFIG_HOME/gnokii/config" \ + "$HOME/.config/gnokii/config" "$HOME/.gnokiirc" \ + "$XDG_CONFIG_DIRS/gnokii/config" /etc/gnokiirc; do + [[ -f $config_file ]] && break + done + [[ ! -f $config_file ]] && return + COMPREPLY=($(compgen -W \ + "$(command sed -n 's/^\[phone_\(.*\)\]/\1/p' $config_file)" \ + -- "$cur")) + return + ;; + --help) + COMPREPLY=($(compgen -W 'all monitor sms mms phonebook calendar + todo dial profile settings wap logo ringtone security file + other' -- "$cur")) + return + ;; + --version | --shell | ping) + return + ;; + + # MONITOR + --monitor) + COMPREPLY=($(compgen -W 'delay once' -- "$cur")) + return + ;; + --getdisplaystatus | --displayoutput) + return + ;; + --netmonitor) + COMPREPLY=($(compgen -W 'reset off field devel next nr' \ + -- "$cur")) + return + ;; + + # SMS + --sendsms) + # (how)TODO ? + return + ;; + --savesms) + COMPREPLY=($(compgen -W '--sender --smsc --smscno --folder + --location --sent --read --deliver --datetime' -- "$cur")) + return + ;; + --memory-type | --memory | --getsms | --deletesms | --getmms | --deletemms | \ + --getphonebook | --deletephonebook) + _gnokii_memory_type + return + ;; + --getsmsc | --getcalendarnote | --deletecalendarnote | --gettodo | \ + --getspeeddial) + # TODO: grab a specific entry ID + return + ;; + --setsmsc | --smsreader | --createsmsfolder | --deletealltodos | \ + --showsmsfolderstatus) + return + ;; + --deletesmsfolder | --folder) + # TODO: folderid + return + ;; + --writephonebook) + COMPREPLY=($(compgen -W '--overwrite --find-free --memory-type + --location --vcard --ldif' -- "$cur")) + return + ;; + --writecalendarnote | --writetodo) + _filedir vcf + return + ;; + + # DIAL + --setspeeddial | --dialvoice | --senddtmf | --answercall | --hangup) + # TODO + return + ;; + --divert) + COMPREPLY=($(compgen -W '--op' -- "$cur")) + return + ;; + + # PROFILE + --getprofile | --setactiveprofile) + # TODO + return + ;; + --setprofile | --getactiveprofile) + return + ;; + + # SETTINGS + --reset) + COMPREPLY=($(compgen -W 'soft hard' -- "$cur")) + return + ;; + --setdatetime | --setalarm) + # TODO + return + ;; + --getdatetime | --getalarm) + return + ;; + + # WAP + --getwapbookmark | --writewapbookmark | --deletewapbookmark | \ + --getwapsetting | --writewapsetting | --activatewapsetting) + return + ;; + + # LOGOS + --sendlogo) + COMPREPLY=($(compgen -W 'caller op picture' -- "$cur")) + return + ;; + --setlogo | --getlogo) + COMPREPLY=($(compgen -W 'op startup caller dealer text' \ + -- "$cur")) + return + ;; + --viewlogo) + # TODO: logofile + return + ;; + + --entersecuritycode) + COMPREPLY=($(compgen -W 'PIN PIN2 PUK PUK2 SEC' -- "$cur")) + return + ;; + + # TODO: RINGTONES + esac + + # second level completion + if [[ $((cword - 2)) -ge 1 && ${words[cword - 2]} =~ --* ]]; then + pprev=${words[cword - 2]} + case $pprev in + --setspeeddial) + _gnokii_memory_type + return + ;; + --getsms | --deletesms | --getmms | --deletemms | --getphonebook | \ + --writetodo | --writecalendarnote) + # TODO: start number + return + ;; + --gettodo | --getcalendarnote) + COMPREPLY=($(compgen -W '{1..9} end --vCal' -- "$cur")) + return + ;; + --deletecalendarnote) + COMPREPLY=($(compgen -W '{1..9} end' -- "$cur")) + return + ;; + --divert) + COMPREPLY=($(compgen -W 'register enable query disable + erasure' -- "$cur")) + return + ;; + esac + fi + + # third level completion + if [[ $((cword - 3)) -ge 1 && ${words[cword - 3]} =~ --* ]]; then + tprev=${words[cword - 3]} + case $tprev in + --deletesms | --deletemms) + COMPREPLY=($(compgen -W 'end' -- "$cur")) + return + ;; + --getphonebook | --writetodo | --writecalendarnote) + COMPREPLY=($(compgen -W '{1..9} end' -- "$cur")) + return + ;; + --gettodo | --getcalendarnote) + [[ ${words[cword - 1]} == end ]] && + COMPREPLY=($(compgen -W '--vCal' -- "$cur")) + return + ;; + --divert) + COMPREPLY=($(compgen -W '--type' -- "$cur")) + return + ;; + esac + fi + + # fourth level completion + if [[ $((cword - 4)) -ge 1 && ${words[cword - 4]} =~ --* ]]; then + fprev=${words[cword - 4]} + case $fprev in + --getphonebook) + COMPREPLY=($(compgen -W '--raw --vcard --ldif' -- "$cur")) + return + ;; + --divert) + COMPREPLY=($(compgen -W 'all busy noans outofreach notavail' \ + -- "$cur")) + return + ;; + esac + fi + + # safer to use LANG=C + local all_cmd="$(LANG=C _parse_help $1 "--help all")" + # these 2 below are allowed in combination with others + local main_cmd=$(command grep -v -- '--config\|--phone' <<<"$all_cmd") + + # don't provide main command completions if one is + # already on the command line + [[ $COMP_LINE =~ $(tr ' ' '\b|' <<<$main_cmd) ]] && return + + COMPREPLY=($(compgen -W "$all_cmd" -- "$cur")) +} && + complete -F _gnokii gnokii + +# ex: filetype=sh diff --git a/completions/gnome-mplayer b/completions/gnome-mplayer new file mode 100644 index 0000000..32d93fc --- /dev/null +++ b/completions/gnome-mplayer @@ -0,0 +1,38 @@ +# gnome-mplayer(1) completion -*- shell-script -*- + +_gnome_mplayer() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -'?' | --help | --help-all | --help-gtk) + return + ;; + --showcontrols | --showsubtitles | --autostart) + COMPREPLY=($(compgen -w '0 1' -- "$cur")) + return + ;; + --subtitle) + _filedir '@(srt|sub|txt|utf|rar|mpsub|smi|js|ssa|ass)' + return + ;; + --tvdriver) + COMPREPLY=($(compgen -W 'v4l v4l2' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --help-all)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir +} && + complete -F _gnome_mplayer gnome-mplayer + +# ex: filetype=sh diff --git a/completions/gnome-screenshot b/completions/gnome-screenshot new file mode 100644 index 0000000..b3594d2 --- /dev/null +++ b/completions/gnome-screenshot @@ -0,0 +1,31 @@ +# gnome-screenshot(1) completion -*- shell-script -*- + +_gnome_screenshot() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --help-* | --version | --delay | --display | -!(-*)[hd]) + return + ;; + --border-effect | -!(-*)e) + COMPREPLY=($(compgen -W 'shadow border vintage none' -- "$cur")) + return + ;; + --file | -!(-*)f) + _filedir '@(jp?(e)|pn)g' + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _gnome_screenshot gnome-screenshot + +# ex: filetype=sh diff --git a/completions/gpasswd b/completions/gpasswd new file mode 100644 index 0000000..f1f2200 --- /dev/null +++ b/completions/gpasswd @@ -0,0 +1,25 @@ +# gpasswd(1) completion -*- shell-script -*- + +_gpasswd() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --add | --delete | --administrators | --members | -!(-*)[adAM]) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + # TODO: only -A and -M can be combined + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + COMPREPLY=($(compgen -g -- "$cur")) +} && + complete -F _gpasswd gpasswd + +# ex: filetype=sh diff --git a/completions/gpg b/completions/gpg new file mode 100644 index 0000000..f0ca884 --- /dev/null +++ b/completions/gpg @@ -0,0 +1,38 @@ +# bash completion for gpg -*- shell-script -*- + +_gpg() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --sign | --clearsign | --decrypt-files | --load-extension | -!(-*)s) + _filedir + return + ;; + --export | --sign-key | --lsign-key | --nrsign-key | --nrlsign-key | --edit-key) + # return list of public keys + COMPREPLY=($(compgen -W "$($1 --list-keys 2>/dev/null | command sed -ne \ + 's@^pub.*/\([^ ]*\).*$@\1@p' -ne \ + 's@^.*\(<\([^>]*\)>\).*$@\2@p')" -- "$cur")) + return + ;; + --recipient | -!(-*)r) + COMPREPLY=($(compgen -W "$($1 --list-keys 2>/dev/null | command sed -ne \ + 's@^.*<\([^>]*\)>.*$@\1@p')" -- "$cur")) + if [[ -e ~/.gnupg/gpg.conf ]]; then + COMPREPLY+=($(compgen -W "$(command sed -ne \ + 's@^[ \t]*group[ \t][ \t]*\([^=]*\).*$@\1@p' \ + ~/.gnupg/gpg.conf)" -- "$cur")) + fi + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$($1 --dump-options)' -- "$cur")) + fi +} && + complete -F _gpg -o default gpg + +# ex: filetype=sh diff --git a/completions/gpg2 b/completions/gpg2 new file mode 100644 index 0000000..cfa4023 --- /dev/null +++ b/completions/gpg2 @@ -0,0 +1,42 @@ +# gpg2(1) completion -*- shell-script -*- + +_gpg2() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --homedir) + _filedir -d + return + ;; + --sign | --clearsign | --options | --decrypt | -!(-*)s) + _filedir + return + ;; + --export | --sign-key | --lsign-key | --nrsign-key | --nrlsign-key | --edit-key) + # return list of public keys + COMPREPLY=($(compgen -W "$($1 --list-keys 2>/dev/null | command sed -ne \ + 's@^pub.*/\([^ ]*\).*$@\1@p' -ne \ + 's@^.*\(<\([^>]*\)>\).*$@\2@p')" -- "$cur")) + return + ;; + --recipient | -!(-*)r) + COMPREPLY=($(compgen -W "$($1 --list-keys 2>/dev/null | + command sed -ne 's@^.*<\([^>]*\)>.*$@\1@p')" -- "$cur")) + if [[ -e ~/.gnupg/gpg.conf ]]; then + COMPREPLY+=($(compgen -W "$(command sed -ne \ + 's@^[ \t]*group[ \t][ \t]*\([^=]*\).*$@\1@p' \ + ~/.gnupg/gpg.conf)" -- "$cur")) + fi + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$($1 --dump-options)' -- "$cur")) + fi +} && + complete -F _gpg2 -o default gpg2 + +# ex: filetype=sh diff --git a/completions/gpgv b/completions/gpgv new file mode 100644 index 0000000..29315c9 --- /dev/null +++ b/completions/gpgv @@ -0,0 +1,46 @@ +# gpgv(1) completion -*- shell-script -*- + +_gpgv() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | --weak-digest | --*-fd | -!(-*)[?h]*) + return + ;; + --keyring) + _filedir "@(gpg|kbx)" + return + ;; + --homedir) + _filedir -d + return + ;; + esac + + local args + _count_args "" "--@(weak-digest|*-fd|keyring|homedir)" + + if [[ $cur == -* && $args -eq 1 ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + if ((args > 1)); then + if [[ ${COMP_LINE,,} == *.@(asc|sig|sign)\ * ]]; then + # Detached signature, only complete one arbitrary file arg and - + if ((args == 2)); then + COMPREPLY=($(compgen -W '-' -- "$cur")) + _filedir + fi + else + _filedir gpg + fi + else + _filedir "@(asc|gpg|sig|sign)" + fi +} && + complete -F _gpgv gpgv gpgv2 + +# ex: filetype=sh diff --git a/completions/gphoto2 b/completions/gphoto2 new file mode 100644 index 0000000..cbf84c0 --- /dev/null +++ b/completions/gphoto2 @@ -0,0 +1,55 @@ +# bash completion for gphoto2(1) -*- shell-script -*- + +_gphoto2() +{ + local cur prev words cword split + _init_completion -s -n : || return + + case $prev in + --debug-logfile) + _filedir + return + ;; + --hook-script) + _filedir + return + ;; + --filename) + _filedir + return + ;; + -u | --upload-file) + _filedir + return + ;; + --port) + COMPREPLY=($(compgen -W "$($1 --list-ports 2>/dev/null | + awk 'NR>3 { print $1 }')" -- "$cur")) + __ltrim_colon_completions "$cur" + return + ;; + --camera) + local IFS=$'\n' + COMPREPLY=($(compgen -W "$($1 --list-cameras 2>/dev/null | + awk -F'"' 'NR>2 { print $2 }')" -- "$cur")) + return + ;; + --get-config | --set-config | --set-config-index | --set-config-value) + COMPREPLY=($(compgen -W "$( + $1 --list-config 2>/dev/null + )" -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi + +} && + complete -F _gphoto2 gphoto2 + +# ex: filetype=sh diff --git a/completions/gprof b/completions/gprof new file mode 100644 index 0000000..5a4ab2d --- /dev/null +++ b/completions/gprof @@ -0,0 +1,56 @@ +# gprof(1) completion -*- shell-script -*- + +_gprof() +{ + local cur prev words cword split + _init_completion -s || return + + case $cur in + -A* | -C* | -J* | -p* | -P* | -q* | -Q* | -n* | -N* | -d*) + return + ;; + -S*) + cur=${cur:2} + _filedir + COMPREPLY=("${COMPREPLY[@]/#/-S}") + return + ;; + -O*) + cur=${cur:2} + COMPREPLY=($(compgen -P -O -W 'auto bsd 4.4bsd magic prof' \ + -- "$cur")) + return + ;; + esac + + case $prev in + -I | --directory-path) + _filedir -d + return + ;; + -R | --file-ordering | --external-symbol-table) + _filedir + return + ;; + -w | --width | -k | -m | --min-count | -h | --help | -e | -E | -f | -F) + return + ;; + --file-format) + COMPREPLY=($(compgen -W 'auto bsd 4.4bsd magic prof' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir +} && + complete -F _gprof gprof + +# ex: filetype=sh diff --git a/completions/groupadd b/completions/groupadd new file mode 100644 index 0000000..5f67f29 --- /dev/null +++ b/completions/groupadd @@ -0,0 +1,26 @@ +# groupadd(8) completion -*- shell-script -*- + +_groupadd() +{ + local cur prev words cword split + _init_completion -s || return + + # TODO: if -o/--non-unique is given, could complete on existing gids + # with -g/--gid + + case $prev in + --gid | --key | --password | -!(-*)[gKp]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _groupadd groupadd + +# ex: filetype=sh diff --git a/completions/groupdel b/completions/groupdel new file mode 100644 index 0000000..4d8ca7f --- /dev/null +++ b/completions/groupdel @@ -0,0 +1,27 @@ +# groupdel(8) completion -*- shell-script -*- + +_groupdel() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h | --help) + return + ;; + -R | --root) + _filedir -d + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + COMPREPLY=($(compgen -g -- "$cur")) +} && + complete -F _groupdel groupdel + +# ex: filetype=sh diff --git a/completions/groupmems b/completions/groupmems new file mode 100644 index 0000000..2e89a5a --- /dev/null +++ b/completions/groupmems @@ -0,0 +1,27 @@ +# groupmems(8) completion -*- shell-script -*- + +_groupmems() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -a | --add | -d | --delete) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + -g | --group) + COMPREPLY=($(compgen -g -- "$cur")) + return + ;; + -R | --root) + _filedir -d + return + ;; + esac + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _groupmems groupmems + +# ex: filetype=sh diff --git a/completions/groupmod b/completions/groupmod new file mode 100644 index 0000000..5516d31 --- /dev/null +++ b/completions/groupmod @@ -0,0 +1,29 @@ +# groupmod(8) completion -*- shell-script -*- + +_groupmod() +{ + local cur prev words cword split + _init_completion -s || return + + # TODO: if -o/--non-unique is given, could complete on existing gids + # with -g/--gid + + case $prev in + --gid | --help | --new-name | --password | -!(-*)[ghnp]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + COMPREPLY=($(compgen -g -- "$cur")) +} && + complete -F _groupmod groupmod + +# ex: filetype=sh diff --git a/completions/growisofs b/completions/growisofs new file mode 100644 index 0000000..ee09fe6 --- /dev/null +++ b/completions/growisofs @@ -0,0 +1,39 @@ +# growisofs(1) completion -*- shell-script -*- + +_growisofs() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -version | -speed) + return + ;; + -Z | -M) + compopt -o nospace + _dvd_devices + return + ;; + /?(r)dev/*) + if [[ $cur == =* ]]; then + # e.g. /dev/dvd=foo.iso, /dev/dvdrw=/dev/zero + cur="${cur#=}" + _filedir + return + fi + ;; + esac + + if [[ $cur == -* ]]; then + # TODO: mkisofs options + COMPREPLY=($(compgen -W '-dvd-compat -overburn -speed= -Z -M' \ + -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir +} && + complete -F _growisofs growisofs + +# ex: filetype=sh diff --git a/completions/grpck b/completions/grpck new file mode 100644 index 0000000..0fadbed --- /dev/null +++ b/completions/grpck @@ -0,0 +1,25 @@ +# grpck(8) completion -*- shell-script -*- + +_grpck() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --root | -!(-*)R) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + return + fi + + _filedir +} && + complete -F _grpck grpck + +# ex: filetype=sh diff --git a/completions/gssdp-discover b/completions/gssdp-discover new file mode 100644 index 0000000..8454f52 --- /dev/null +++ b/completions/gssdp-discover @@ -0,0 +1,34 @@ +# bash completion for gssdp-discover -*- shell-script -*- + +_gssdp_discover() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --target | --timeout | --rescan-interval | -[htnr]) + return + ;; + --interface | -i) + _available_interfaces -a + return + ;; + --message-type | -m) + local types=$($1 --help 2>&1 | + command sed -ne 's/^.*--message-type=.*(\([^)]*\))$/\1/p') + COMPREPLY=($( + IFS+=, + compgen -W "$types" -- "$cur" + )) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _gssdp_discover gssdp-discover + +# ex: filetype=sh diff --git a/completions/gzip b/completions/gzip new file mode 100644 index 0000000..0144c3a --- /dev/null +++ b/completions/gzip @@ -0,0 +1,43 @@ +# bash completion for gzip -*- shell-script -*- + +_gzip() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --blocksize | --suffix | --help | --version | -!(-*)[bShV]) + return + ;; + --processes | -!(-*)p) + COMPREPLY=($(compgen -W "{1..$(_ncpus)}" -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1") {-1..-9}' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + local IFS=$'\n' xspec="*.@(gz|t[ag]z)" + [[ ${1##*/} == pigz ]] && xspec="*.@([gz]z|t[ag]z)" + + if [[ $prev == --* ]]; then + [[ $prev == --@(decompress|list|test) ]] && xspec="!"$xspec + [[ $prev == --force ]] && xspec= + elif [[ $prev == -* ]]; then + [[ $prev == -*[dlt]* ]] && xspec="!"$xspec + [[ $prev == -*f* ]] && xspec= + fi + + _tilde "$cur" || return + + compopt -o filenames + COMPREPLY=($(compgen -f -X "$xspec" -- "$cur") + $(compgen -d -- "$cur")) +} && + complete -F _gzip gzip pigz + +# ex: filetype=sh diff --git a/completions/hcitool b/completions/hcitool new file mode 100644 index 0000000..58bf5a7 --- /dev/null +++ b/completions/hcitool @@ -0,0 +1,380 @@ +# bash completion for bluez utils -*- shell-script -*- + +_bluetooth_addresses() +{ + if [[ -n ${COMP_BLUETOOTH_SCAN:-} ]]; then + COMPREPLY+=($(compgen -W "$(hcitool scan | + awk '/^\t/{print $1}')" -- "$cur")) + fi +} + +_bluetooth_devices() +{ + COMPREPLY+=($(compgen -W "$(hcitool dev | + awk '/^\t/{print $1}')" -- "$cur")) +} + +_bluetooth_services() +{ + COMPREPLY=($(compgen -W 'DID SP DUN LAN FAX OPUSH FTP HS HF HFAG SAP NAP + GN PANU HCRP HID CIP A2SRC A2SNK AVRCT AVRTG UDIUE UDITE SYNCML' \ + -- "$cur")) +} + +_bluetooth_packet_types() +{ + COMPREPLY=($(compgen -W 'DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3' \ + -- "$cur")) +} + +_hcitool() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -i) + _bluetooth_devices + return + ;; + --role) + COMPREPLY=($(compgen -W 'm s' -- "$cur")) + return + ;; + --pkt-type) + _bluetooth_packet_types + return + ;; + esac + + $split && return + + local arg + _get_first_arg + if [[ -z $arg ]]; then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + COMPREPLY=($(compgen -W 'dev inq scan name info spinq epinq cmd + con cc dc sr cpt rssi lq tpl afh lst auth enc key clkoff + clock' -- "$cur")) + fi + else + local args + case $arg in + name | info | dc | rssi | lq | afh | auth | key | clkoff | lst) + _count_args + if ((args == 2)); then + _bluetooth_addresses + fi + ;; + cc) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--role --pkt-type' -- "$cur")) + else + _count_args + if ((args == 2)); then + _bluetooth_addresses + fi + fi + ;; + sr) + _count_args + if ((args == 2)); then + _bluetooth_addresses + else + COMPREPLY=($(compgen -W 'master slave' -- "$cur")) + fi + ;; + cpt) + _count_args + if ((args == 2)); then + _bluetooth_addresses + else + _bluetooth_packet_types + fi + ;; + tpl | enc | clock) + _count_args + if ((args == 2)); then + _bluetooth_addresses + else + COMPREPLY=($(compgen -W '0 1' -- "$cur")) + fi + ;; + esac + fi +} && + complete -F _hcitool hcitool + +_sdptool() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --bdaddr) + _bluetooth_addresses + return + ;; + esac + + $split && return + + local arg + _get_first_arg + if [[ -z $arg ]]; then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + COMPREPLY=($(compgen -W 'search browse records add del get + setattr setseq' -- "$cur")) + fi + else + case $arg in + search) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--bdaddr --tree --raw --xml' \ + -- "$cur")) + else + _bluetooth_services + fi + ;; + browse | records) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--tree --raw --xml' -- "$cur")) + else + _bluetooth_addresses + fi + ;; + add) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--handle --channel' -- "$cur")) + else + _bluetooth_services + fi + ;; + get) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--bdaddr --tree --raw --xml' \ + -- "$cur")) + fi + ;; + esac + fi +} && + complete -F _sdptool sdptool + +_l2ping() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -i) + _bluetooth_devices + return + ;; + -s | -c | -t | -d) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + else + _bluetooth_addresses + fi +} && + complete -F _l2ping l2ping + +_rfcomm() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -f | --config) + _filedir + return + ;; + -i) + _bluetooth_devices + _bluetooth_addresses + return + ;; + esac + + local arg + _get_first_arg + if [[ -z $arg ]]; then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + COMPREPLY=($(compgen -W 'show connect listen watch bind + release' -- "$cur")) + fi + else + local args + _count_args + if ((args == 2)); then + _bluetooth_devices + else + case $arg in + connect | bind) + if ((args == 3)); then + _bluetooth_addresses + fi + ;; + esac + fi + fi +} && + complete -F _rfcomm rfcomm + +_ciptool() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -i) + _bluetooth_devices + _bluetooth_addresses + return + ;; + esac + + local arg + _get_first_arg + if [[ -z $arg ]]; then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + COMPREPLY=($(compgen -W 'show search connect release loopback' \ + -- "$cur")) + fi + else + local args + case $arg in + connect | release | loopback) + _count_args + if ((args == 2)); then + _bluetooth_addresses + fi + ;; + esac + fi +} && + complete -F _ciptool ciptool + +_dfutool() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -d | --device) + _bluetooth_devices + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + local args + _count_args + case $args in + 1) + COMPREPLY=($(compgen -W 'verify modify upgrade archive' \ + -- "$cur")) + ;; + 2) + _filedir + ;; + esac + fi +} && + complete -F _dfutool dfutool + +_hciconfig() +{ + local cur prev words cword + _init_completion || return + + local arg + _get_first_arg + if [[ -z $arg ]]; then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--help --all' -- "$cur")) + else + COMPREPLY=($(compgen -W 'up down reset rstat auth noauth encrypt + noencrypt secmgr nosecmgr piscan noscan iscan pscan ptype name + class voice iac inqmode inqdata inqtype inqparams pageparms + pageto afhmode aclmtu scomtu putkey delkey commands features + version revision lm' -- "$cur")) + fi + else + local args + case $arg in + putkey | delkey) + _count_args + if ((args == 2)); then + _bluetooth_addresses + fi + ;; + lm) + _count_args + if ((args == 2)); then + COMPREPLY=($(compgen -W 'MASTER SLAVE NONE ACCEPT' \ + -- "$cur")) + fi + ;; + ptype) + _count_args + if ((args == 2)); then + _bluetooth_packet_types + fi + ;; + esac + fi +} && + complete -F _hciconfig hciconfig + +_hciattach() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-n -p -t -b -s -l' -- "$cur")) + else + local args + _count_args + case $args in + 1) + COMPREPLY=($(printf '%s\n' /dev/tty*)) + COMPREPLY=($(compgen -W '${COMPREPLY[@]} + ${COMPREPLY[@]#/dev/}' -- "$cur")) + ;; + 2) + COMPREPLY=($(compgen -W 'any ericsson digi xircom csr bboxes + swave bcsp 0x0105 0x080a 0x0160 0x0002' -- "$cur")) + ;; + 3) + COMPREPLY=($(compgen -W '9600 19200 38400 57600 115200 230400 + 460800 921600' -- "$cur")) + ;; + 4) + COMPREPLY=($(compgen -W 'flow noflow' -- "$cur")) + ;; + 5) + _bluetooth_addresses + ;; + esac + fi +} && + complete -F _hciattach hciattach + +# ex: filetype=sh diff --git a/completions/hddtemp b/completions/hddtemp new file mode 100644 index 0000000..7b95f0e --- /dev/null +++ b/completions/hddtemp @@ -0,0 +1,38 @@ +# hddtemp(8) completion -*- shell-script -*- + +_hddtemp() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --file | -!(-*)f) + _filedir db + return + ;; + --listen | -!(-*)l) + _ip_addresses + return + ;; + --unit | -!(-*)u) + COMPREPLY=($(compgen -W 'C F' -- "$cur")) + return + ;; + --port | --separator | --syslog | --version | --help | -!(-*)[psSvh?]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1") --help' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + cur=${cur:=/dev/} + _filedir + fi +} && + complete -F _hddtemp hddtemp + +# ex: filetype=sh diff --git a/completions/hid2hci b/completions/hid2hci new file mode 100644 index 0000000..f33a495 --- /dev/null +++ b/completions/hid2hci @@ -0,0 +1,15 @@ +# hid2hci completion -*- shell-script -*- + +_hid2hci() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--help --quiet -0 --tohci -1 --tohid' \ + -- "$cur")) + fi +} && + complete -F _hid2hci hid2hci + +# ex: filetype=sh diff --git a/completions/hostname b/completions/hostname new file mode 100644 index 0000000..ce1b32e --- /dev/null +++ b/completions/hostname @@ -0,0 +1,23 @@ +# hostname(1) completion -*- shell-script -*- + +_hostname() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | -!(-*)[hV]) + return + ;; + --file | -!(-*)F) + _filedir + return + ;; + esac + + [[ $cur == -* ]] && + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _hostname hostname + +# ex: filetype=sh diff --git a/completions/hping2 b/completions/hping2 new file mode 100644 index 0000000..666838b --- /dev/null +++ b/completions/hping2 @@ -0,0 +1,35 @@ +# bash completion for hping2 -*- shell-script -*- + +_hping2() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --interface | -!(-*)I) + _available_interfaces + return + ;; + --spoof | -!(-*)a) + _known_hosts_real -- "$cur" + return + ;; + --tos | -!(-*)o) + COMPREPLY=($(compgen -W '02 04 08 10')) + return + ;; + --file | -!(-*)E) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + _known_hosts_real -- "$cur" + fi +} && + complete -F _hping2 hping hping2 hping3 + +# ex: filetype=sh diff --git a/completions/htop b/completions/htop new file mode 100644 index 0000000..b4916d5 --- /dev/null +++ b/completions/htop @@ -0,0 +1,33 @@ +# htop(1) completion -*- shell-script -*- + +_htop() +{ + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + --sort-key | -!(-*)s) + COMPREPLY=($(compgen -W '$("$1" -s help)' -- "$cur")) + return + ;; + --user | -!(-*)u) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + --delay | -!(-*)d) + # argument required but no completions available + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --help)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi +} && + complete -F _htop htop + +# ex: filetype=sh diff --git a/completions/htpasswd b/completions/htpasswd new file mode 100644 index 0000000..527684b --- /dev/null +++ b/completions/htpasswd @@ -0,0 +1,36 @@ +# htpasswd(1) completion -*- shell-script -*- + +_htpasswd() +{ + local cur prev words cword + _init_completion || return + + local i o=0 # $o is index of first non-option argument + for ((i = 1; i <= cword; i++)); do + case ${words[i]} in + -*n*) return ;; + -*) ;; + *) + o=$i + break + ;; + esac + done + + if ((o == 0 || o == cword)); then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + # Password file (first non-option argument) + _filedir + + elif ((o == cword - 1)); then + # Username (second non-option argument) + COMPREPLY=($(compgen -W \ + '$(cut -d: -f1 "${words[o]}" 2>/dev/null)' -- "$cur")) + fi +} && + complete -F _htpasswd htpasswd + +# ex: filetype=sh diff --git a/completions/hunspell b/completions/hunspell new file mode 100644 index 0000000..92b4fe8 --- /dev/null +++ b/completions/hunspell @@ -0,0 +1,43 @@ +# hunspell(1) completion -*- shell-script -*- + +_hunspell() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | -vv | -[hPv]) + return + ;; + -d) + local IFS=$' \t\n' reset=$(shopt -p nullglob) + shopt -s nullglob + local -a dicts=(/usr/share/hunspell/*.dic + /usr/local/share/hunspell/*.dic) + dicts=("${dicts[@]##*/}") + dicts=("${dicts[@]%.dic}") + $reset + IFS=$'\n' + COMPREPLY=($(compgen -W '${dicts[@]}' -- "$cur")) + return + ;; + -i) + _xfunc iconv _iconv_charsets + return + ;; + -p) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + _filedir +} && + complete -F _hunspell hunspell + +# ex: filetype=sh diff --git a/completions/iconv b/completions/iconv new file mode 100644 index 0000000..81ae01b --- /dev/null +++ b/completions/iconv @@ -0,0 +1,38 @@ +# iconv(1) completion -*- shell-script -*- + +_iconv_charsets() +{ + COMPREPLY+=($(compgen -X ... -W '$(${1:-iconv} -l | \ + command sed -e "s@/*\$@@" -e "s/[,()]//g")' -- "$cur")) +} + +_iconv() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --usage | --version | --unicode-subst | --byte-subst | \ + --widechar-subst | -!(-*)[?V]) + return + ;; + --from-code | --to-code | -!(-*)[ft]) + _iconv_charsets $1 + return + ;; + --output | -!(-*)o) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _iconv -o default iconv + +# ex: filetype=sh diff --git a/completions/id b/completions/id new file mode 100644 index 0000000..a07e51d --- /dev/null +++ b/completions/id @@ -0,0 +1,18 @@ +# id(1) completion -*- shell-script -*- + +_id() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1") + [[ $opts ]] || opts="-G -g -u" # POSIX fallback + COMPREPLY=($(compgen -W "$opts" -- "$cur")) + else + COMPREPLY=($(compgen -u "$cur")) + fi +} && + complete -F _id id + +# ex: filetype=sh diff --git a/completions/idn b/completions/idn new file mode 100644 index 0000000..8023f8f --- /dev/null +++ b/completions/idn @@ -0,0 +1,26 @@ +# idn(1) completion -*- shell-script -*- + +_idn() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | -!(-*)[hV]) + return + ;; + --profile | -!(-*)p) + COMPREPLY=($(compgen -W 'Nameprep iSCSI Nodeprep Resourceprep + trace SASLprep' -- "$cur")) + return + ;; + esac + + if ! $split && [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _idn idn + +# ex: filetype=sh diff --git a/completions/ifstat b/completions/ifstat new file mode 100644 index 0000000..629786e --- /dev/null +++ b/completions/ifstat @@ -0,0 +1,68 @@ +# bash completion for ifstat(1) -*- shell-script -*- + +_ifstat() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | --scan | --interval | -!(-*)[hvV]) + return + ;; + -!(-*)i) + # TODO comma separated + _available_interfaces -a + return + ;; + -!(-*)d) + # iproute2: no completion (scan delay) + # traditional: parse driver + if ! { + "$1" --help 2>&1 || : + } | + command grep -q -- '-d.*--scan'; then + COMPREPLY=($(compgen -W '$("$1" -v | command \ + sed -e "s/[,.]//g" -ne "s/^.*drivers://p")' -- "$cur")) + fi + return + ;; + --noupdate | -!(-*)s) + # iproute2: pass through (skip history update) + # traditional: hostnames (snmp) + if ! { + "$1" --help 2>&1 || : + } | + command grep -q -- '-s.*--noupdate'; then + _known_hosts_real -- "$cur" + return + fi + ;; + -!(-*)t) + # iproute2: no completion (interval) + # traditional: pass through (add timestamp) + ! { + "$1" --help 2>&1 || : + } | + command grep -q -- '-t.*--interval' || return + ;; + --extended | -!(-*)x) + # iproute2: parse xstat types + COMPREPLY=($(compgen -W '$("$1" -x nonexistent-xstat 2>&1 | + awk "found { print \$1 } /supported xstats:/ { found=1 }")' \ + -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi +} && + complete -F _ifstat ifstat + +# ex: filetype=sh diff --git a/completions/iftop b/completions/iftop new file mode 100644 index 0000000..b73f4b6 --- /dev/null +++ b/completions/iftop @@ -0,0 +1,26 @@ +# iftop(8) completion -*- shell-script -*- + +_iftop() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h | -f | -F | -m) + return + ;; + -i) + _available_interfaces -a + return + ;; + -c) + _filedir + return + ;; + esac + + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) +} && + complete -F _iftop iftop + +# ex: filetype=sh diff --git a/completions/ifup b/completions/ifup new file mode 100644 index 0000000..5b35bfb --- /dev/null +++ b/completions/ifup @@ -0,0 +1,39 @@ +# Red Hat & Debian GNU/Linux if{up,down} completion -*- shell-script -*- + +_userland GNU || return 1 + +_ifupdown() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | --allow | --exclude | --option | -!(-*)[hVXo]) + return + ;; + --interfaces | -!(-*)i) + _filedir + return + ;; + --state-dir) + _filedir -d + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + local args + _count_args "" "@(--allow|-i|--interfaces|--state-dir|-X|--exclude|-o)" + + if ((args == 1)); then + _configured_interfaces + COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur")) + fi +} && + complete -F _ifupdown ifup ifdown ifquery ifstatus + +# ex: filetype=sh diff --git a/completions/influx b/completions/influx new file mode 100644 index 0000000..e9362e7 --- /dev/null +++ b/completions/influx @@ -0,0 +1,35 @@ +# bash completion for influx(8) -*- shell-script -*- + +_influx() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -version | -port | -database | -password | -username | -execute | -pps) + return + ;; + -host) + _known_hosts_real -- "$cur" + return + ;; + -format | -precision | -consistency) + local args=$($1 --help 2>&1 | awk "\$1 == \"$prev\" { print \$2 }") + COMPREPLY=($( + IFS+="\"'|" + compgen -W "$args" -- "$cur" + )) + return + ;; + -import | -path) + _filedir + return + ;; + esac + + [[ $cur == -* ]] && + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _influx influx + +# ex: filetype=sh diff --git a/completions/info b/completions/info new file mode 100644 index 0000000..f50f842 --- /dev/null +++ b/completions/info @@ -0,0 +1,74 @@ +# bash completion for info -*- shell-script -*- + +_info() +{ + local cur prev words cword split + _init_completion -s || return + + # default completion if parameter looks like a path + if [[ $cur == @(*/|[.~])* ]]; then + _filedir + return + fi + + case $prev in + --apropos | --index-search | --node | --help | --version | -!(-*)[knhv]) + return + ;; + -!(-*)d) + if [[ ${1##*/} == info ]]; then + _filedir -d + return + fi + ;; + --directory) + _filedir -d + return + ;; + --dribble | --file | --output | --restore | --raw-filename | --rcfile | -!(-*)[for]) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + local i infopath=/usr/share/info + + if [[ ${INFOPATH-} == *: ]]; then + infopath=${INFOPATH}${infopath} + elif [[ ${INFOPATH:+set} ]]; then + infopath=$INFOPATH + fi + + _expand || return + + infopath=$infopath: + if [[ -n $cur ]]; then + infopath="${infopath//://$cur* }" + else + infopath="${infopath//:// }" + fi + + # redirect stderr for when path doesn't exist + COMPREPLY=($(eval command ls "$infopath" 2>/dev/null)) + # weed out directory path names and paths to info pages + COMPREPLY=(${COMPREPLY[@]##*/?(:)}) + # weed out info dir file + for i in ${!COMPREPLY[*]}; do + [[ ${COMPREPLY[i]} == dir ]] && unset "COMPREPLY[i]" + done + # strip suffix from info pages + COMPREPLY=(${COMPREPLY[@]%.@(gz|bz2|xz|lzma)}) + COMPREPLY=($(compgen -W '${COMPREPLY[@]%.*}' -- "${cur//\\\\/}")) + +} && + complete -F _info info pinfo + +# ex: filetype=sh diff --git a/completions/inject b/completions/inject new file mode 100644 index 0000000..fad73a1 --- /dev/null +++ b/completions/inject @@ -0,0 +1,26 @@ +# mailman inject completion -*- shell-script -*- + +_inject() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -l | --listname) + _xfunc list_lists _mailman_lists + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--listname --queue --help' -- "$cur")) + else + _filedir + fi + +} && + complete -F _inject inject + +# ex: filetype=sh diff --git a/completions/inotifywait b/completions/inotifywait new file mode 100644 index 0000000..e5608fc --- /dev/null +++ b/completions/inotifywait @@ -0,0 +1,47 @@ +# bash completion for inotifywait(1) and inotifywatch(1) -*- shell-script -*- + +_inotifywait_events() +{ + # Expecting line with "Events:", followed by ones starting with one + # tab. Word following the tab is event name, others are line + # wrapped explanations. + COMPREPLY+=($(compgen -W "$($1 --help 2>/dev/null | + command sed -e '/^Events:/,/^[^'$'\t'']/!d' \ + -ne 's/^'$'\t''\([^ '$'\t'']\{1,\}\)[ '$'\t''].*/\1/p')" \ + -- "$cur")) +} + +_inotifywait() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --exclude | --excludei | --format | --timefmt | --timeout | -!(-*)[ht]) + return + ;; + --fromfile | --outfile | -!(-*)o) + _filedir + return + ;; + --event | -!(-*)e) + _inotifywait_events "$1" + return + ;; + --ascending | --descending) + COMPREPLY=($(compgen -W 'total' -- "$cur")) + _inotifywait_events "$1" + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + _filedir +} && + complete -F _inotifywait inotifywait inotifywatch + +# ex: filetype=sh diff --git a/completions/insmod b/completions/insmod new file mode 100644 index 0000000..a59e753 --- /dev/null +++ b/completions/insmod @@ -0,0 +1,18 @@ +# Linux insmod(8) completion -*- shell-script -*- + +_insmod() +{ + local cur prev words cword + _init_completion || return + + # do filename completion for first argument + if ((cword == 1)); then + _filedir '@(?(k)o?(.[gx]z))' + else # do module parameter completion + COMPREPLY=($(compgen -W "$(PATH="$PATH:/sbin" modinfo \ + -p ${words[1]} 2>/dev/null | cut -d: -f1)" -- "$cur")) + fi +} && + complete -F _insmod insmod insmod.static + +# ex: filetype=sh diff --git a/completions/installpkg b/completions/installpkg new file mode 100644 index 0000000..7455eb1 --- /dev/null +++ b/completions/installpkg @@ -0,0 +1,33 @@ +# Slackware Linux installpkg completion -*- shell-script -*- + +_installpkg() +{ + local cur prev words cword + _init_completion || return + + case "$prev" in + --root) + _filedir -d + return + ;; + --priority) + COMPREPLY=($(compgen -W 'ADD REC OPT SKP' -- "$cur")) + return + ;; + --tagfile) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--warn --md5sum --root --infobox --terse + --menu --ask --priority --tagfile' -- "$cur")) + return + fi + + _filedir 't[bglx]z' +} && + complete -F _installpkg installpkg + +# ex: filetype=sh diff --git a/completions/interdiff b/completions/interdiff new file mode 100644 index 0000000..9933d15 --- /dev/null +++ b/completions/interdiff @@ -0,0 +1,33 @@ +# interdiff(1) completion -*- shell-script -*- + +_interdiff() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --unified | --strip-match | --drop-context | -!(-*)[Upd]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + local exts='@(?(d)patch|dif?(f))' word + for word in "${words[@]}"; do + if [[ $word == -@(z|-decompress) ]]; then + exts+='?(.@(gz|bz2))' + break + fi + done + _filedir "$exts" +} && + complete -F _interdiff interdiff + +# ex: filetype=sh diff --git a/completions/invoke-rc.d b/completions/invoke-rc.d new file mode 100644 index 0000000..4a5045a --- /dev/null +++ b/completions/invoke-rc.d @@ -0,0 +1,38 @@ +# invoke-rc.d(8) completion -*- shell-script -*- +# +# Copyright (C) 2004 Servilio Afre Puentes <servilio@gmail.com> + +_invoke_rc_d() +{ + local cur prev words cword + _init_completion || return + + local sysvdir services options valid_options + + [[ -d /etc/rc.d/init.d ]] && sysvdir=/etc/rc.d/init.d || + sysvdir=/etc/init.d + + services=($(printf '%s ' $sysvdir/!(README*|*.sh|$_backup_glob))) + services=(${services[@]#$sysvdir/}) + options=(--help --quiet --force --try-anyway --disclose-deny --query + --no-fallback) + + if [[ $cword -eq 1 || $prev == --* ]]; then + valid_options=($( + tr " " "\n" <<<"${words[*]} ${options[*]}" | + command sed -ne "/$(command sed 's/ /\\|/g' <<<"${options[*]}")/p" | + sort | uniq -u + )) + COMPREPLY=($(compgen -W '${valid_options[@]} ${services[@]}' -- "$cur")) + elif [[ -x $sysvdir/$prev ]]; then + COMPREPLY=($(compgen -W '`command sed -e "y/|/ /" \ + -ne "s/^.*Usage:[ ]*[^ ]*[ ]*{*\([^}\"]*\).*$/\1/p" \ + $sysvdir/$prev`' -- "$cur")) + else + COMPREPLY=() + fi + +} && + complete -F _invoke_rc_d invoke-rc.d + +# ex: filetype=sh diff --git a/completions/ip b/completions/ip new file mode 100644 index 0000000..12ad9aa --- /dev/null +++ b/completions/ip @@ -0,0 +1,378 @@ +# ip(8) completion -*- shell-script -*- + +_iproute2_etc() +{ + COMPREPLY+=($(compgen -W \ + "$(awk '!/#/ { print $2 }' /etc/iproute2/$1 2>/dev/null)" \ + -- "$cur")) +} + +_ip() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -V | -Version | -rc | -rcvbuf) + return + ;; + -f | -family) + COMPREPLY=($(compgen -W 'inet inet6 ipx dnet link' -- "$cur")) + return + ;; + -b | -batch) + _filedir + return + ;; + -force) + COMPREPLY=($(compgen -W '-batch' -- "$cur")) + return + ;; + esac + + local subcword cmd subcmd="" + for ((subcword = 1; subcword < ${#words[@]} - 1; subcword++)); do + [[ ${words[subcword]} == -b?(atch) ]] && return + [[ -v cmd ]] && subcmd=${words[subcword]} && break + [[ ${words[subcword]} != -* && \ + ${words[subcword - 1]} != -@(f?(amily)|rc?(vbuf)) ]] && + cmd=${words[subcword]} + done + + if [[ ! -v cmd ]]; then + case $cur in + -*) + local c="-Version -statistics -details -resolve -family + -oneline -timestamp -batch -rcvbuf" + ((cword == 1)) && c+=" -force" + COMPREPLY=($(compgen -W "$c" -- "$cur")) + ;; + *) + COMPREPLY=($(compgen -W "help $($1 help 2>&1 | command sed -e \ + '/OBJECT := /,/}/!d' -e \ + 's/.*{//' -e \ + 's/}.*//' -e \ + 's/|//g')" -- "$cur")) + ;; + esac + return + fi + + [[ $subcmd == help ]] && return + + case $cmd in + l | link) + case $subcmd in + add) + # TODO + ;; + delete) + case $((cword - subcword)) in + 1) + _available_interfaces + ;; + 2) + COMPREPLY=($(compgen -W 'type' -- "$cur")) + ;; + 3) + [[ $prev == type ]] && + COMPREPLY=($(compgen -W 'vlan veth vcan dummy + ifb macvlan can' -- "$cur")) + ;; + esac + ;; + set) + if ((cword - subcword == 1)); then + _available_interfaces + else + case $prev in + arp | dynamic | multicast | allmulticast | promisc | \ + trailers) + COMPREPLY=($(compgen -W 'on off' -- "$cur")) + ;; + txqueuelen | name | address | broadcast | mtu | netns | alias) ;; + + *) + local c="arp dynamic multicast allmulticast + promisc trailers txqueuelen name address + broadcast mtu netns alias" + [[ $prev != @(up|down) ]] && c+=" up down" + COMPREPLY=($(compgen -W "$c" -- "$cur")) + ;; + esac + fi + ;; + show) + if ((cword == subcword + 1)); then + _available_interfaces + COMPREPLY+=($(compgen -W 'dev group up' -- "$cur")) + elif [[ $prev == dev ]]; then + _available_interfaces + elif [[ $prev == group ]]; then + _iproute2_etc group + fi + ;; + *) + ((cword == subcword)) && + COMPREPLY=($(compgen -W 'help add delete set show' \ + -- "$cur")) + ;; + esac + ;; + + a | addr | address) + case $subcmd in + add | change | replace) + if [[ $prev == dev ]]; then + _available_interfaces + elif [[ $prev == scope ]]; then + _iproute2_etc rt_scopes + else + : # TODO + fi + ;; + del) + if [[ $prev == dev ]]; then + _available_interfaces + elif [[ $prev == scope ]]; then + _iproute2_etc rt_scopes + else + : # TODO + fi + ;; + show | flush) + if ((cword == subcword + 1)); then + _available_interfaces + COMPREPLY+=($(compgen -W 'dev scope to label dynamic + permanent tentative deprecated dadfailed temporary + primary secondary up' -- "$cur")) + elif [[ $prev == dev ]]; then + _available_interfaces + elif [[ $prev == scope ]]; then + _iproute2_etc rt_scopes + fi + ;; + *) + ((cword == subcword)) && + COMPREPLY=($(compgen -W 'help add change replace del + show flush' -- "$cur")) + ;; + esac + ;; + + addrlabel) + case $subcmd in + list | add | del | flush) + if [[ $prev == dev ]]; then + _available_interfaces + else + : # TODO + fi + ;; + *) + ((cword == subcword)) && + COMPREPLY=($(compgen -W 'help list add del flush' \ + -- "$cur")) + ;; + esac + ;; + + r | route) + case $subcmd in + list | flush) + if [[ $prev == proto ]]; then + _iproute2_etc rt_protos + else + : # TODO + fi + ;; + get) + # TODO + ;; + a | add | d | del | change | append | r | replace | monitor) + if [[ $prev == via ]]; then + COMPREPLY=($(compgen -W "$($1 r | command sed -ne \ + 's/.*via \([0-9.]*\).*/\1/p')" -- "$cur")) + elif [[ $prev == "$subcmd" ]]; then + COMPREPLY=($(compgen -W "table default \ + $($1 r | cut -d ' ' -f 1)" -- "$cur")) + elif [[ $prev == dev ]]; then + _available_interfaces -a + elif [[ $prev == table ]]; then + COMPREPLY=($(compgen -W 'local main default' -- "$cur")) + else + COMPREPLY=($(compgen -W 'via dev weight' -- "$cur")) + fi + ;; + *) + ((cword == subcword)) && + COMPREPLY=($(compgen -W 'help list flush get add del + change append replace monitor' -- "$cur")) + ;; + esac + ;; + + rule) + case $subcmd in + add | del | list | lst) + case $prev in + from | to | tos | dsfield | fwmark | uidrange | ipproto | sport | \ + dport | priority | protocol | suppress_prefixlength | \ + suppress_ifgroup | realms | nat | goto) ;; + + iif | oif) + _available_interfaces -a + ;; + table | lookup) + COMPREPLY=($(compgen -W 'local main default' -- "$cur")) + ;; + *) + COMPREPLY=($(compgen -W 'from to tos dsfield fwmark + uidrange ipproto sport dport priority table lookup + protocol suppress_prefixlength suppress_ifgroup realms + nat goto iif oif not' -- "$cur")) + ;; + esac + ;; + flush | save) + if [[ $prev == protocol ]]; then + : + else + COMPREPLY=($(compgen -W 'protocol' -- "$cur")) + fi + ;; + restore | show) ;; + *) + ((cword == subcword)) && + COMPREPLY=($(compgen -W 'help add del list flush save + restore show' -- "$cur")) + ;; + esac + ;; + + neigh) + case $subcmd in + add | del | change | replace) + # TODO + ;; + show | flush) + # TODO + ;; + *) + ((cword == subcword)) && + COMPREPLY=($(compgen -W 'help add del change replace + show flush' -- "$cur")) + ;; + esac + ;; + + ntable) + case $subcmd in + change) + # TODO + ;; + show) + # TODO + ;; + *) + ((cword == subcword)) && + COMPREPLY=($(compgen -W 'help change show' \ + -- "$cur")) + ;; + esac + ;; + + tunnel) + case $subcmd in + show) ;; + + add | change | del | prl | 6rd) + # TODO + ;; + *) + ((cword == subcword)) && + COMPREPLY=($(compgen -W 'help add change del show prl + 6rd' -- "$cur")) + ;; + esac + ;; + + maddr) + case $subcmd in + add | del) + # TODO + ;; + show) + if [[ $cword -eq $subcword+1 || $prev == dev ]]; then + _available_interfaces + [[ $prev != dev ]] && + COMPREPLY=($(compgen -W '${COMPREPLY[@]} dev' \ + -- "$cur")) + fi + ;; + *) + ((cword == subcword)) && + COMPREPLY=($(compgen -W 'help add del show' \ + -- "$cur")) + ;; + esac + ;; + + mroute) + case $subcmd in + show) + # TODO + ;; + *) + ((cword == subcword)) && + COMPREPLY=($(compgen -W 'help show' -- "$cur")) + ;; + esac + ;; + + monitor) + case $subcmd in + all) ;; + *) + ((cword == subcword)) && + COMPREPLY=($(compgen -W 'help all' -- "$cur")) + ;; + esac + ;; + + netns) + case $subcmd in + list | monitor) ;; + + add | identify | list-id) + # TODO + ;; + delete | exec | pids | set) + [[ $prev == "$subcmd" ]] && + COMPREPLY=($(compgen -W "$($1 netns list)" -- "$cur")) + ;; + *) + ((cword == subcword)) && + COMPREPLY=($(compgen -W 'help add delete exec + identify list list-id monitor pids set' -- "$cur")) + ;; + esac + ;; + + xfrm) + case $subcmd in + state | policy | monitor) + # TODO + ;; + *) + ((cword == subcword)) && + COMPREPLY=($(compgen -W 'state policy monitor' \ + -- "$cur")) + ;; + esac + ;; + esac +} && + complete -F _ip ip + +# ex: filetype=sh diff --git a/completions/ipcalc b/completions/ipcalc new file mode 100644 index 0000000..5603c26 --- /dev/null +++ b/completions/ipcalc @@ -0,0 +1,25 @@ +# ipcalc(1) completion -*- shell-script -*- + +_ipcalc() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | --split | -[hs]) + return + ;; + esac + + # --split takes 3 args + local i + for i in {1..3}; do + [[ ${words[cword - i]} == -@(-split|s) ]] && return + done + + [[ $cur != -* ]] || + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _ipcalc ipcalc + +# ex: filetype=sh diff --git a/completions/iperf b/completions/iperf new file mode 100644 index 0000000..6347fe0 --- /dev/null +++ b/completions/iperf @@ -0,0 +1,69 @@ +# iperf(1) completion -*- shell-script -*- + +_iperf() +{ + local cur prev words cword split + _init_completion -s -n : || return + + case $prev in + --help | --version | --interval | --len | --port | --window | --mss | --bandwidth | \ + --num | --time | --listenport | --parallel | --ttl | --linux-congestion | --omit | \ + --congestion | --bytes | --blockcount | --cport | --set-mss | --flowlabel | \ + --title | --tos | --affinity | -!(-*)[hvilpwMbntLPTZCkOSA]) + return + ;; + --format | -!(-*)f) + COMPREPLY=($(compgen -W 'k m g K M G' -- "$cur")) + return + ;; + --output | --fileinput | -!(-*)[oF]) + _filedir + return + ;; + --bind | -!(-*)B) + _available_interfaces -a + _ip_addresses -a + __ltrim_colon_completions "$cur" + return + ;; + --client | -!(-*)c) + _known_hosts_real -- "$cur" + return + ;; + --reportexclude | -!(-*)x) + COMPREPLY=($(compgen -W 'C D M S V' -- "$cur")) + return + ;; + --reportstyle | -!(-*)y) + COMPREPLY=($(compgen -W 'C' -- "$cur")) + return + ;; + --logfile) + _filedir log + return + ;; + esac + + $split && return + + # Filter mode specific options + local i filter=cat + for i in "${words[@]}"; do + case $i in + -s | --server) + filter='command sed -e /^Client.specific/,/^\(Server.specific.*\)\?$/d' + ;; + -c | --client) + filter='command sed -e /^Server.specific/,/^\(Client.specific.*\)\?$/d' + ;; + esac + done + [[ $filter != cat ]] && filter+=' -e /--client/d -e /--server/d' + + COMPREPLY=($(compgen -W \ + '$("$1" --help 2>&1 | $filter | _parse_help -)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace +} && + complete -F _iperf iperf iperf3 + +# ex: filetype=sh diff --git a/completions/ipmitool b/completions/ipmitool new file mode 100644 index 0000000..920287d --- /dev/null +++ b/completions/ipmitool @@ -0,0 +1,199 @@ +# bash completion for ipmitool -*- shell-script -*- + +_ipmitool_singleline_help() +{ + COMPREPLY=($(compgen -W "$($1 $2 2>&1 | + command sed -ne 's/[,\r]//g' -e 's/^.*[Cc]ommands://p')" -- "$cur")) +} + +_ipmitool() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*[hVpUekyPmbtBTl]) + return + ;; + -*d) + COMPREPLY=($(compgen -W "$( + command ls -d /dev/ipmi* /dev/ipmi/* /dev/ipmidev/* \ + 2>/dev/null | command sed -ne 's/^[^0-9]*\([0-9]\{1,\}\)/\1/p' + )" \ + -- "$cur")) + return + ;; + -*I) + COMPREPLY=($(compgen -W "$($1 -h 2>&1 | + command sed -e '/^Interfaces:/,/^[[:space:]]*$/!d' \ + -ne 's/^[[:space:]]\{1,\}\([^[:space:]]\{1,\}\).*/\1/p')" \ + -- "$cur")) + return + ;; + -*H) + _known_hosts_real -- "$cur" + return + ;; + -*[fSO]) + _filedir + return + ;; + -*C) + COMPREPLY=($(compgen -W '{0..14}' -- "$cur")) + return + ;; + -*L) + COMPREPLY=($(compgen -W 'CALLBACK USER OPERATOR ADMINISTRATOR' \ + -- "$cur")) + return + ;; + -*A) + COMPREPLY=($(compgen -W 'NONE PASSWORD MD2 MD5 OEM' -- "$cur")) + return + ;; + -*o) + COMPREPLY=($(compgen -W "$($1 -o list 2>&1 | + awk '/^[ \t]+/ { print $1 }') list" -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + return + fi + + # Find out command and subcommand + + local cmds=(raw i2c spd lan chassis power event mc sdr sensor fru gendev + sel pef sol tsol isol user channel session sunoem kontronoem picmg fwum + firewall shell exec set hpm ekanalyzer) + local i c cmd subcmd + for ((i = 1; i < ${#words[@]} - 1; i++)); do + [[ -v cmd ]] && subcmd=${words[i]} && break + for c in "${cmds[@]}"; do + [[ ${words[i]} == "$c" ]] && cmd=$c && break + done + done + + if [[ ! -v cmd ]]; then + COMPREPLY=($(compgen -W '${cmds[@]}' -- "$cur")) + return + fi + + # Command/subcommand completions + + case $cmd in + + shell) ;; + + \ + exec) + _filedir + ;; + + chassis | power | kontronoem | fwum) + _ipmitool_singleline_help $1 $cmd + ;; + + lan) + case $subcmd in + print | set) ;; + + alert) + [[ $prev == alert ]] && + COMPREPLY=($(compgen -W 'print set' -- "$cur")) + ;; + stats) + [[ $prev == stats ]] && + COMPREPLY=($(compgen -W 'print set' -- "$cur")) + ;; + *) + COMPREPLY=($(compgen -W 'print set alert stats' \ + -- "$cur")) + ;; + esac + ;; + + sdr) + case $subcmd in + get | info | type | list | entity) ;; + + elist) + COMPREPLY=($(compgen -W 'all full compact event mclog fru + generic' -- "$cur")) + ;; + dump) + _filedir + ;; + fill) + case $prev in + fill) + COMPREPLY=($(compgen -W 'sensors file' -- "$cur")) + ;; + file) + _filedir + ;; + esac + ;; + *) + COMPREPLY=($(compgen -W 'get info type list elist entity + dump fill' -- "$cur")) + ;; + esac + ;; + + sensor) + case $subcmd in + list | get | thresh) ;; + + *) + COMPREPLY=($(compgen -W 'list get thresh' -- "$cur")) + ;; + esac + ;; + + sel) + case $subcmd in + info | clear | list | elist | delete) ;; + + add | save | writeraw | readraw) + _filedir + ;; + time) + [[ $prev == time ]] && + COMPREPLY=($(compgen -W 'get set' -- "$cur")) + ;; + *) + COMPREPLY=($(compgen -W 'info clear list elist delete add + get save writeraw readraw time' -- "$cur")) + ;; + esac + ;; + + user) + case $subcmd in + summary | list | disable | enable | priv | test) ;; + + set) + [[ $prev == set ]] && + COMPREPLY=($(compgen -W 'name password' -- "$cur")) + ;; + *) + COMPREPLY=($(compgen -W 'summary list set disable enable + priv test' -- "$cur")) + ;; + esac + ;; + + set) + [[ $prev == set ]] && + COMPREPLY=($(compgen -W 'hostname username password privlvl + authtype localaddr targetaddr port csv verbose' -- "$cur")) + ;; + + esac +} && + complete -F _ipmitool ipmitool + +# ex: filetype=sh diff --git a/completions/ipsec b/completions/ipsec new file mode 100644 index 0000000..4bc8cdf --- /dev/null +++ b/completions/ipsec @@ -0,0 +1,102 @@ +# Linux ipsec(8) completion (for FreeS/WAN and strongSwan) -*- shell-script -*- + +# Complete ipsec.conf conn entries. +# +# Reads a file from stdin in the ipsec.conf(5) format. +_ipsec_connections() +{ + local keyword name + while read -r keyword name; do + if [[ $keyword == [#]* ]]; then continue; fi + [[ $keyword == conn && $name != '%default' ]] && COMPREPLY+=("$name") + done + COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur")) +} + +_ipsec_freeswan() +{ + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + COMPREPLY=($(compgen -W 'auto barf eroute klipsdebug look manual + pluto ranbits rsasigkey setup showdefaults showhostkey spi spigrp + tncfg whack' -- "$cur")) + return + fi + + case ${words[1]} in + auto) + COMPREPLY=($(compgen -W '--asynchronous --up --add --delete + --replace --down --route --unroute --ready --status + --rereadsecrets' -- "$cur")) + ;; + manual) + COMPREPLY=($(compgen -W '--up --down --route --unroute --union' \ + -- "$cur")) + ;; + ranbits) + COMPREPLY=($(compgen -W '--quick --continuous --bytes' -- "$cur")) + ;; + setup) + COMPREPLY=($(compgen -W '--start --stop --restart' -- "$cur")) + ;; + *) ;; + + esac +} + +_ipsec_strongswan() +{ + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + COMPREPLY=($(compgen -W 'down irdumm leases listaacerts listacerts + listalgs listall listcacerts listcainfos listcards listcerts + listcrls listgroups listocsp listocspcerts listpubkeys openac pki + pluto pool purgecerts purgecrls purgeike purgeocsp ready reload + rereadaacerts rereadacerts rereadall rereadcacerts rereadcrls + rereadgroups rereadocspcerts rereadsecrets restart route scdecrypt + scencrypt scepclient secrets start starter status statusall stop + stroke unroute uci up update version whack --confdir --copyright + --directory --help --version --versioncode' -- "$cur")) + return + fi + + case ${words[1]} in + down | route | status | statusall | unroute | up) + local confdir=$(ipsec --confdir) + _ipsec_connections <"$confdir/ipsec.conf" + ;; + list*) + COMPREPLY=($(compgen -W '--utc' -- "$cur")) + ;; + restart | start) + COMPREPLY=($(compgen -W '--attach-gdb --auto-update --debug + --debug-all --debug-more --nofork' -- "$cur")) + ;; + pki) + COMPREPLY=($(compgen -W '--gen --issue --keyid --print --pub + --req --self --signcrl --verify' -- "$cur")) + ;; + pool) ;; + + irdumm) + _filedir 'rb' + ;; + *) ;; + + esac +} + +case "$(ipsec --version 2>/dev/null)" in + *strongSwan*) + complete -F _ipsec_strongswan ipsec + ;; + *) + complete -F _ipsec_freeswan ipsec + ;; +esac + +# ex: filetype=sh diff --git a/completions/iptables b/completions/iptables new file mode 100644 index 0000000..ffb905b --- /dev/null +++ b/completions/iptables @@ -0,0 +1,51 @@ +# bash completion for iptables -*- shell-script -*- + +_iptables() +{ + local cur prev words cword split + _init_completion -s || return + + local table chain='s/^Chain \([^ ]\{1,\}\).*$/\1/p' + + [[ ${words[*]} =~ [[:space:]]-(t|-table=?)[[:space:]]*([^[:space:]]+) ]] && + table="-t ${BASH_REMATCH[2]}" + + case $prev in + -*[AIDRPFXLZ]) + COMPREPLY=($(compgen -W '`"$1" $table -nL 2>/dev/null | \ + command sed -ne "s/^Chain \([^ ]\{1,\}\).*$/\1/p"`' -- "$cur")) + ;; + -*t) + COMPREPLY=($(compgen -W 'nat filter mangle' -- "$cur")) + ;; + -j) + if [[ $table == "-t filter" || -z $table ]]; then + COMPREPLY=($(compgen -W 'ACCEPT DROP LOG ULOG REJECT + `"$1" $table -nL 2>/dev/null | command sed -ne "$chain" \ + -e "s/INPUT|OUTPUT|FORWARD|PREROUTING|POSTROUTING//"`' -- \ + "$cur")) + elif [[ $table == "-t nat" ]]; then + COMPREPLY=($(compgen -W 'ACCEPT DROP LOG ULOG REJECT MIRROR SNAT + DNAT MASQUERADE `"$1" $table -nL 2>/dev/null | \ + command sed -ne "$chain" -e "s/OUTPUT|PREROUTING|POSTROUTING//"`' \ + -- "$cur")) + elif [[ $table == "-t mangle" ]]; then + COMPREPLY=($(compgen -W 'ACCEPT DROP LOG ULOG REJECT MARK TOS + `"$1" $table -nL 2>/dev/null | command sed -ne "$chain" \ + -e "s/INPUT|OUTPUT|FORWARD|PREROUTING|POSTROUTING//"`' -- \ + "$cur")) + fi + ;; + *) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$("$1" --help 2>&1 | + command sed -e "s/^\[\!\]//" | _parse_help -)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi + ;; + esac + +} && + complete -F _iptables iptables + +# ex: filetype=sh diff --git a/completions/ipv6calc b/completions/ipv6calc new file mode 100644 index 0000000..c452c15 --- /dev/null +++ b/completions/ipv6calc @@ -0,0 +1,38 @@ +# ipv6calc completion -*- shell-script -*- + +_ipv6calc() +{ + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + --debug | -!(-*)d) + return + ;; + --in | --out | --action | -!(-*)[IOA]) + # With ipv6calc < 0.73.0, -m does nothing here, so use sed instead. + COMPREPLY=($(compgen -W "$($1 "$prev" -h 2>&1 | + command sed -ne 's/^[[:space:]]\{1,\}\([^[:space:]:]\{1,\}\)[[:space:]]*:.*/\1/p')" \ + -- "$cur")) + return + ;; + --db-geoip | --db-ip2location-ipv4 | --db-ip2location-ipv6) + _filedir + return + ;; + --printstart | --printend) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$("$1" -h 2>&1 | + command sed -e "s/[][]//g" | _parse_help -)' -- "$cur")) + fi + +} && + complete -F _ipv6calc ipv6calc + +# ex: filetype=sh diff --git a/completions/iscsiadm b/completions/iscsiadm new file mode 100644 index 0000000..7786ddc --- /dev/null +++ b/completions/iscsiadm @@ -0,0 +1,66 @@ +# iscsiadm(1) completion -*- shell-script -*- + +_iscsiadm() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --mode | -!(-*)m) + COMPREPLY=($(compgen -W 'discovery node session iface fw host' \ + -- "$cur")) + return + ;; + --op | -!(-*)o) + COMPREPLY=($(compgen -W 'new delete update show' -- "$cur")) + return + ;; + --type | -!(-*)t) + COMPREPLY=($(compgen -W 'sendtargets st slp isns fw' -- "$cur")) + return + ;; + --loginall | --logoutall | -!(-*)[LU]) + COMPREPLY=($(compgen -W 'all manual automatic' -- "$cur")) + return + ;; + esac + + $split && return + + local options + if ((cword > 1)); then + + case ${words[2]} in + discovery) + options='--help --version --debug --print --interface --type \ + --portal --login --op --name --value' + ;; + node) + options='--help --version --debug --print --loginall \ + --logoutall--show -T --portal --interface --login \ + --logout --rescan --stats --op --name --value' + ;; + session) + options='--help --version --debug --print --sid --logout \ + --rescan --stats' + ;; + iface) + options='--help --version --debug --print --interface --op \ + --name --value' + ;; + fw) + options='--login' + ;; + host) + options='--print -H' + ;; + esac + else + options='--mode' + fi + + COMPREPLY=($(compgen -W "$options" -- "$cur")) +} && + complete -F _iscsiadm iscsiadm + +# ex: filetype=sh diff --git a/completions/isort b/completions/isort new file mode 100644 index 0000000..2a84e25 --- /dev/null +++ b/completions/isort @@ -0,0 +1,41 @@ +# isort completion -*- shell-script -*- + +_isort() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --add-import | --builtin | --future | --from-first | -ff | \ + --force-grid-wrap | -fgw | --indent | --lines | --lines-after-imports | -lai | \ + --lines-between-types | -lbt | --line-ending | -le | --no-lines-before | -nlb | \ + --dont-skip | -ns | --thirdparty | --project | --remove-import | --skip | \ + --skip-glob | -sg | --settings-path | -sp | --top | --virtual-env | --line-width | \ + --wrap-length | -wl | -[habfiloprstw]) + return + ;; + --jobs | -j) + COMPREPLY=($(compgen -W "{1..$(_ncpus)}" -- "$cur")) + return + ;; + --multi-line | -m) + COMPREPLY=($(compgen -W '{0..5}' -- "$cur")) + return + ;; + --section-default | -sd) + COMPREPLY=($(compgen -W 'FUTURE STDLIB THIRDPARTY FIRSTPARTY + LOCALFOLDER' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + _filedir '@(py|pyi)' +} && + complete -F _isort isort + +# ex: filetype=sh diff --git a/completions/isql b/completions/isql new file mode 100644 index 0000000..4258c51 --- /dev/null +++ b/completions/isql @@ -0,0 +1,14 @@ +# isql completion -*- shell-script -*- +# by Victor Bogado da Silva Lins <victor@bogado.net> + +_isql() +{ + local cur prev words cword + _init_completion || return + + [[ -f $ODBCINI ]] && + COMPREPLY=($(command grep "\[$cur" "$ODBCINI" | tr -d \[\])) +} && + complete -F _isql isql + +# ex: filetype=sh diff --git a/completions/iwconfig b/completions/iwconfig new file mode 100644 index 0000000..aa8fbf3 --- /dev/null +++ b/completions/iwconfig @@ -0,0 +1,90 @@ +# iwconfig completion -*- shell-script -*- + +_iwconfig() +{ + local cur prev words cword + _init_completion || return + + case $prev in + mode) + COMPREPLY=($(compgen -W 'managed ad-hoc master repeater secondary + monitor' -- "$cur")) + return + ;; + essid) + COMPREPLY=($(compgen -W 'on off any' -- "$cur")) + if [[ -n ${COMP_IWLIST_SCAN:-} ]]; then + COMPREPLY+=($(compgen -W \ + "$(iwlist ${words[1]} scan | + awk -F'\"' '/ESSID/ {print $2}')" -- "$cur")) + fi + return + ;; + nwid) + COMPREPLY=($(compgen -W 'on off' -- "$cur")) + return + ;; + channel) + COMPREPLY=($(compgen -W "$(iwlist ${words[1]} channel | + awk '/^[ \t]*Channel/ {print $2}')" -- "$cur")) + return + ;; + + freq) + COMPREPLY=($(compgen -W "$(iwlist ${words[1]} channel | + awk '/^[ \t]*Channel/ {print $4"G"}')" -- "$cur")) + return + ;; + ap) + COMPREPLY=($(compgen -W 'on off any' -- "$cur")) + if [[ -n ${COMP_IWLIST_SCAN:-} ]]; then + COMPREPLY+=($(compgen -W \ + "$(iwlist ${words[1]} scan | + awk -F ': ' '/Address/ {print $2}')" -- "$cur")) + fi + return + ;; + rate) + COMPREPLY=($(compgen -W 'auto fixed' -- "$cur")) + COMPREPLY+=($(compgen -W \ + "$(iwlist ${words[1]} rate | + awk '/^[ \t]*[0-9]/ {print $1"M"}')" -- "$cur")) + return + ;; + rts | frag) + COMPREPLY=($(compgen -W 'auto fixed off' -- "$cur")) + return + ;; + key | enc) + COMPREPLY=($(compgen -W 'off on open restricted' -- "$cur")) + return + ;; + power) + COMPREPLY=($(compgen -W 'period timeout off on' -- "$cur")) + return + ;; + txpower) + COMPREPLY=($(compgen -W 'off on auto' -- "$cur")) + return + ;; + retry) + COMPREPLY=($(compgen -W 'limit lifetime' -- "$cur")) + return + ;; + esac + + if ((cword == 1)); then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--help --version' -- "$cur")) + else + _available_interfaces -w + fi + else + COMPREPLY=($(compgen -W 'essid nwid mode freq channel sens mode ap + nick rate rts frag enc key power txpower commit' -- "$cur")) + fi + +} && + complete -F _iwconfig iwconfig + +# ex: filetype=sh diff --git a/completions/iwlist b/completions/iwlist new file mode 100644 index 0000000..16aa39c --- /dev/null +++ b/completions/iwlist @@ -0,0 +1,22 @@ +# iwlist completion -*- shell-script -*- + +_iwlist() +{ + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--help --version' -- "$cur")) + else + _available_interfaces -w + fi + else + COMPREPLY=($(compgen -W 'scan scanning freq frequency channel rate + bit bitrate key enc encryption power txpower retry ap accesspoint + peers event' -- "$cur")) + fi +} && + complete -F _iwlist iwlist + +# ex: filetype=sh diff --git a/completions/iwpriv b/completions/iwpriv new file mode 100644 index 0000000..4e38246 --- /dev/null +++ b/completions/iwpriv @@ -0,0 +1,31 @@ +# iwpriv completion -*- shell-script -*- + +_iwpriv() +{ + local cur prev words cword + _init_completion || return + + case $prev in + roam) + COMPREPLY=($(compgen -W 'on off' -- "$cur")) + return + ;; + port) + COMPREPLY=($(compgen -W 'ad-hoc managed' -- "$cur")) + return + ;; + esac + + if ((cword == 1)); then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--help --version' -- "$cur")) + else + _available_interfaces -w + fi + else + COMPREPLY=($(compgen -W '--all roam port' -- "$cur")) + fi +} && + complete -F _iwpriv iwpriv + +# ex: filetype=sh diff --git a/completions/iwspy b/completions/iwspy new file mode 100644 index 0000000..38b7868 --- /dev/null +++ b/completions/iwspy @@ -0,0 +1,20 @@ +# iwspy completion -*- shell-script -*- + +_iwspy() +{ + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--help --version' -- "$cur")) + else + _available_interfaces -w + fi + else + COMPREPLY=($(compgen -W 'setthr getthr off' -- "$cur")) + fi +} && + complete -F _iwspy iwspy + +# ex: filetype=sh diff --git a/completions/jar b/completions/jar new file mode 100644 index 0000000..2289491 --- /dev/null +++ b/completions/jar @@ -0,0 +1,27 @@ +# jar(1) completion -*- shell-script -*- + +_jar() +{ + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + COMPREPLY=($(compgen -W 'c t x u' -- "$cur")) + return + fi + + case ${words[1]} in + *c*f) + _filedir + ;; + *f) + _filedir_xspec unzip + ;; + *) + _filedir + ;; + esac +} && + complete -F _jar jar + +# ex: filetype=sh diff --git a/completions/jarsigner b/completions/jarsigner new file mode 100644 index 0000000..1f26c9c --- /dev/null +++ b/completions/jarsigner @@ -0,0 +1,57 @@ +# jarsigner(1) completion -*- shell-script -*- + +_jarsigner() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -keystore) + COMPREPLY=($(compgen -W 'NONE' -- "$cur")) + _filedir '@(jks|ks|p12|pfx)' + return + ;; + -storepass | -keypass | -sigfile | -digestalg | -sigalg | -tsacert | -tsapolicyid | \ + -tsadigestalg | -altsigner | -altsignerpath | -providerName | -providerClass | \ + -providerArg) + return + ;; + -certchain | -tsa) + _filedir + return + ;; + -storetype) + COMPREPLY=($(compgen -W 'JKS PKCS11 PKCS12' -- "$cur")) + return + ;; + -signedjar) + _filedir '@(jar|apk)' + return + ;; + esac + + # Check if a jar was already given. + local i jar=false + for ((i = 1; i < ${#words[@]} - 1; i++)); do + if [[ ${words[i]} == *.@(jar|apk) && \ + ${words[i - 1]} != -signedjar ]]; then + jar=true + break + fi + done + + if ! $jar; then + if [[ $cur == -* ]]; then + # Documented as "should not be used": -internalsf, -sectionsonly + COMPREPLY=($(compgen -W '-keystore -storepass -storetype + -keypass -sigfile -signedjar -digestalg -sigalg -verify + -verbose -certs -tsa -tsacert -altsigner -altsignerpath + -protected -providerName -providerClass -providerArg' \ + -- "$cur")) + fi + _filedir '@(jar|apk)' + fi +} && + complete -F _jarsigner jarsigner + +# ex: filetype=sh diff --git a/completions/java b/completions/java new file mode 100644 index 0000000..d0f70ae --- /dev/null +++ b/completions/java @@ -0,0 +1,333 @@ +# bash completion for java, javac and javadoc -*- shell-script -*- + +# available path elements completion +_java_path() +{ + cur=${cur##*:} + _filedir '@(jar|zip)' +} + +# exact classpath determination +_java_find_classpath() +{ + local i + + # search first in current options + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == -@(cp|classpath) ]]; then + classpath=${words[i + 1]} + break + fi + done + + # default to environment + [[ ! -v classpath ]] && classpath=${CLASSPATH-} + + # default to current directory + [[ -z $classpath ]] && classpath=. +} + +# exact sourcepath determination +_java_find_sourcepath() +{ + local i + + # search first in current options + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == -sourcepath ]]; then + sourcepath=${words[i + 1]} + break + fi + done + + # default to classpath + if [[ ! -v sourcepath ]]; then + local classpath + _java_find_classpath + sourcepath=$classpath + fi +} + +# available classes completion +_java_classes() +{ + local classpath i + + # find which classpath to use + _java_find_classpath + + # convert package syntax to path syntax + cur=${cur//.//} + # parse each classpath element for classes + for i in ${classpath//:/ }; do + if [[ $i == *.@(jar|zip) && -r $i ]]; then + if type zipinfo &>/dev/null; then + COMPREPLY+=($(zipinfo -1 "$i" "$cur*" 2>/dev/null | + command grep '^[^$]*\.class$')) + elif type unzip &>/dev/null; then + # Last column, between entries consisting entirely of dashes + COMPREPLY+=($(unzip -lq "$i" "$cur*" 2>/dev/null | + awk '$NF ~ /^-+$/ { flag=!flag; next }; + flag && $NF ~ /^[^$]*\.class/ { print $NF }')) + elif type jar &>/dev/null; then + COMPREPLY+=($(jar tf "$i" "$cur" | + command grep '^[^$]*\.class$')) + fi + + elif [[ -d $i ]]; then + COMPREPLY+=( + $(compgen -d -- "$i/$cur" | command sed -e "s|^$i/\(.*\)|\1.|") + $(compgen -f -X '!*.class' -- "$i/$cur" | + command sed -e '/\$/d' -e "s|^$i/||") + ) + [[ ${COMPREPLY-} == *.class ]] || compopt -o nospace + + # FIXME: if we have foo.class and foo/, the completion + # returns "foo/"... how to give precedence to files + # over directories? + fi + done + + if ((${#COMPREPLY[@]} != 0)); then + # remove class extension + COMPREPLY=(${COMPREPLY[@]%.class}) + # convert path syntax to package syntax + COMPREPLY=(${COMPREPLY[@]//\//.}) + fi +} + +# available packages completion +_java_packages() +{ + local sourcepath i + + # find which sourcepath to use + _java_find_sourcepath + + # convert package syntax to path syntax + cur=${cur//.//} + # parse each sourcepath element for packages + for i in ${sourcepath//:/ }; do + if [[ -d $i ]]; then + COMPREPLY+=($(command ls -F -d $i/$cur* 2>/dev/null | + command sed -e 's|^'$i'/||')) + fi + done + if ((${#COMPREPLY[@]} != 0)); then + # keep only packages + COMPREPLY=($(tr " " "\n" <<<"${COMPREPLY[@]}" | command grep "/$")) + # remove packages extension + COMPREPLY=(${COMPREPLY[@]%/}) + # convert path syntax to package syntax + cur="${COMPREPLY[*]//\//.}" + fi +} + +# java completion +# +_java() +{ + local cur prev words cword + _init_completion -n : || return + + local i + + for ((i = 1; i < cword; i++)); do + case ${words[i]} in + -cp | -classpath) + ((i++)) # skip the classpath string. + ;; + -*) + # this is an option, not a class/jarfile name. + ;; + *) + # once we've seen a class, just do filename completion + _filedir + return + ;; + esac + done + + case $cur in + # standard option completions + -verbose:*) + COMPREPLY=($(compgen -W 'class gc jni' -- "${cur#*:}")) + return + ;; + -javaagent:*) + cur=${cur#*:} + _filedir '@(jar|zip)' + return + ;; + -agentpath:*) + cur=${cur#*:} + _filedir so + return + ;; + # various non-standard option completions + -splash:*) + cur=${cur#*:} + _filedir '@(gif|jp?(e)g|png)' + return + ;; + -Xbootclasspath*:*) + _java_path + return + ;; + -Xcheck:*) + COMPREPLY=($(compgen -W 'jni' -- "${cur#*:}")) + return + ;; + -Xgc:*) + COMPREPLY=($(compgen -W 'singlecon gencon singlepar genpar' \ + -- "${cur#*:}")) + return + ;; + -Xgcprio:*) + COMPREPLY=($(compgen -W 'throughput pausetime deterministic' \ + -- "${cur#*:}")) + return + ;; + -Xloggc:* | -Xverboselog:*) + cur=${cur#*:} + _filedir + return + ;; + -Xshare:*) + COMPREPLY=($(compgen -W 'auto off on' -- "${cur#*:}")) + return + ;; + -Xverbose:*) + COMPREPLY=($(compgen -W 'memory load jni cpuinfo codegen opt + gcpause gcreport' -- "${cur#*:}")) + return + ;; + -Xverify:*) + COMPREPLY=($(compgen -W 'all none remote' -- "${cur#*:}")) + return + ;; + # the rest that we have no completions for + -D* | -*:*) + return + ;; + esac + + case $prev in + -cp | -classpath) + _java_path + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + [[ $cur == -X* ]] && + COMPREPLY+=($(compgen -W '$(_parse_help "$1" -X)' -- "$cur")) + else + if [[ $prev == -jar ]]; then + # jar file completion + _filedir '[jw]ar' + else + # classes completion + _java_classes + fi + fi + + [[ ${COMPREPLY-} == -*[:=] ]] && compopt -o nospace + + __ltrim_colon_completions "$cur" +} && + complete -F _java java + +_javadoc() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -overview | -helpfile) + _filedir '?(x)htm?(l)' + return + ;; + -doclet | -exclude | -subpackages | -source | -locale | -encoding | -windowtitle | \ + -doctitle | -header | -footer | -top | -bottom | -group | -noqualifier | -tag | \ + -charset | -sourcetab | -docencoding) + return + ;; + -stylesheetfile) + _filedir css + return + ;; + -d | -link | -linkoffline) + _filedir -d + return + ;; + -classpath | -cp | -bootclasspath | -docletpath | -sourcepath | -extdirs | \ + -excludedocfilessubdir) + _java_path + return + ;; + esac + + # -linkoffline takes two arguments + if [[ $cword -gt 2 && ${words[cword - 2]} == -linkoffline ]]; then + _filedir -d + return + fi + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + else + # source files completion + _filedir java + # packages completion + _java_packages + fi +} && + complete -F _javadoc javadoc + +_javac() +{ + local cur prev words cword + _init_completion -n : || return + + case $prev in + -d) + _filedir -d + return + ;; + -cp | -classpath | -bootclasspath | -sourcepath | -extdirs) + _java_path + return + ;; + esac + + if [[ $cur == -+([a-zA-Z0-9-_]):* ]]; then + # Parse required options from -foo:{bar,quux,baz} + local helpopt=-help + [[ $cur == -X* ]] && helpopt=-X + # For some reason there may be -g:none AND -g:{lines,source,vars}; + # convert the none case to the curly brace format so it parses like + # the others. + local opts=$("$1" $helpopt 2>&1 | command sed -e 's/-g:none/-g:{none}/' -ne \ + "s/^[[:space:]]*${cur%%:*}:{\([^}]\{1,\}\)}.*/\1/p") + COMPREPLY=($(compgen -W "${opts//,/ }" -- "${cur#*:}")) + return + fi + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + [[ $cur == -X* ]] && + COMPREPLY+=($(compgen -W '$(_parse_help "$1" -X)' -- "$cur")) + else + # source files completion + _filedir java + fi + + [[ ${COMPREPLY-} == -*[:=] ]] && compopt -o nospace + + __ltrim_colon_completions "$cur" +} && + complete -F _javac javac + +# ex: filetype=sh diff --git a/completions/javaws b/completions/javaws new file mode 100644 index 0000000..f42a1e5 --- /dev/null +++ b/completions/javaws @@ -0,0 +1,34 @@ +# javaws(1) completion -*- shell-script -*- + +_javaws() +{ + local cur prev words cword + _init_completion -n = || return + + case $prev in + -help | -license | -about | -viewer | -arg | -param | -property | -update | -umask) + return + ;; + -basedir | -codebase) + _filedir -d + return + ;; + -uninstall | -import) + _filedir jnlp + return + ;; + esac + + if [[ $cur == *= ]]; then + return + elif [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$(_parse_help "$1" -help) " -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir jnlp +} && + complete -F _javaws javaws + +# ex: filetype=sh diff --git a/completions/jpegoptim b/completions/jpegoptim new file mode 100644 index 0000000..c366972 --- /dev/null +++ b/completions/jpegoptim @@ -0,0 +1,38 @@ +# jpegoptim(1) completion -*- shell-script -*- + +_jpegoptim() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | -!(-*)[hV]*) + return + ;; + --dest | -!(-*)d) + _filedir -d + return + ;; + --max | --threshold | -!(-*)[mT]) + COMPREPLY=($(compgen -W '{0..100}' -- "$cur")) + return + ;; + --size | -!(-*)S) + COMPREPLY=($(compgen -W '{1..99}%' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir 'jp?(e)g' +} && + complete -F _jpegoptim jpegoptim + +# ex: filetype=sh diff --git a/completions/jps b/completions/jps new file mode 100644 index 0000000..a451eec --- /dev/null +++ b/completions/jps @@ -0,0 +1,25 @@ +# jps(1) completion -*- shell-script -*- + +_jps() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -J* | -help) + return + ;; + esac + + if [[ $cur == -* ]]; then + # Not using _parse_usage because output has [-help] which does not + # mean -h, -e, -l, -p... + COMPREPLY=($(compgen -W "-q -m -l -v -V -J -help" -- "$cur")) + [[ ${COMPREPLY-} == -J* ]] && compopt -o nospace + else + _known_hosts_real -- "$cur" + fi +} && + complete -F _jps jps + +# ex: filetype=sh diff --git a/completions/jq b/completions/jq new file mode 100644 index 0000000..2d99c39 --- /dev/null +++ b/completions/jq @@ -0,0 +1,54 @@ +# jq(1) completion -*- shell-script -*- + +_jq() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | --arg | --argjson | --slurpfile | --argfile) + return + ;; + --indent) + COMPREPLY=($(compgen -W '{1..8}' -- "$cur")) + return + ;; + --from-file | --run-tests | -!(-*)f) + _filedir + return + ;; + -!(-*)L) + _filedir -d + return + ;; + esac + + ((cword > 2)) && + case ${words[cword - 2]} in + --arg | --argjson) + return + ;; + --slurpfile | --argfile) + _filedir json + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + local args + # TODO: DTRT with args taking 2 options + _count_args "" "@(--arg|--arg?(json|file)|--?(slurp|from-)file|--indent|--run-tests|-!(-*)[fL])" + + # 1st arg is filter + ((args == 1)) && return + # 2... are input files + _filedir json + +} && + complete -F _jq jq + +# ex: filetype=sh diff --git a/completions/jshint b/completions/jshint new file mode 100644 index 0000000..3622cec --- /dev/null +++ b/completions/jshint @@ -0,0 +1,38 @@ +# bash completion for jshint -*- shell-script -*- + +_jshint() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -v | --version | -h | --help | --exclude | --filename | -e | --extra-ext) + return + ;; + -c | --config) + _filedir + return + ;; + --reporter) + COMPREPLY=($(compgen -W "jslint checkstyle unix" -- "$cur")) + return + ;; + --extract) + COMPREPLY=($(compgen -W "auto always never" -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir js +} && + complete -F _jshint jshint + +# ex: filetype=sh diff --git a/completions/json_xs b/completions/json_xs new file mode 100644 index 0000000..c93ba86 --- /dev/null +++ b/completions/json_xs @@ -0,0 +1,31 @@ +# json_xs completion -*- shell-script -*- + +_json_xs() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*f) + COMPREPLY=($(compgen -W 'json cbor storable storable-file bencode + clzf eval yaml string none' -- "$cur")) + return + ;; + -*t) + COMPREPLY=($(compgen -W 'json json-utf-8 json-pretty + json-utf-16le json-utf-16be json-utf-32le json-utf-32be + cbor storable storable-file bencode clzf yaml dump dumper + string none' -- "$cur")) + return + ;; + -*e) + return + ;; + esac + + [[ $cur == -* ]] && + COMPREPLY=($(compgen -W '$(_parse_usage "$1") -f' -- "$cur")) +} && + complete -F _json_xs json_xs + +# ex: filetype=sh diff --git a/completions/jsonschema b/completions/jsonschema new file mode 100644 index 0000000..8a36ed3 --- /dev/null +++ b/completions/jsonschema @@ -0,0 +1,30 @@ +# bash completion for jsonschema -*- shell-script -*- + +_jsonschema() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --error-format | --validator | -[hFV]) + return + ;; + --instance | -i) + _filedir json + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + local args + _count_args "" "-*" + ((args == 1)) || return + _filedir '@(json|schema)' +} && + complete -F _jsonschema jsonschema + +# ex: filetype=sh diff --git a/completions/k3b b/completions/k3b new file mode 100644 index 0000000..87d26cd --- /dev/null +++ b/completions/k3b @@ -0,0 +1,48 @@ +# bash completion for k3b -*- shell-script -*- + +_k3b() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help* | --author | -v | --version | --license | --lang) + return + ;; + --datacd | --audiocd | --videocd | --mixedcd | --emovixcd | --videodvd) + _filedir + return + ;; + --copydvd | --formatdvd | --videodvdrip) + _dvd_devices + return + ;; + --copycd | --erasecd | --cddarip | --videocdrip) + _cd_devices + _dvd_devices + return + ;; + --cdimage | --image) + _filedir '@(cue|iso|toc)' + return + ;; + --dvdimage) + _filedir iso + return + ;; + --ao) + COMPREPLY=($(compgen -W 'alsa arts' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$(_parse_help "$1")" -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _filedir + fi +} && + complete -F _k3b k3b + +# ex: filetype=sh diff --git a/completions/kcov b/completions/kcov new file mode 100644 index 0000000..672967a --- /dev/null +++ b/completions/kcov @@ -0,0 +1,64 @@ +# kcov(1) completion -*- shell-script -*- + +_kcov() +{ + local cur prev words cword split + _init_completion -s -n : || return + + case "$prev" in + --pid | -p) + _pids + return + ;; + --sort-type | -s) + COMPREPLY=($(compgen -W 'filename percent reverse lines + uncovered' -- "$cur")) + return + ;; + --include-path | --exclude-path) + _filedir + return + ;; + --replace-src-path) + if [[ $cur == ?*:* ]]; then + cur="${cur##*:}" + _filedir + else + _filedir + compopt -o nospace + fi + return + ;; + --limits | -l) + if [[ $cur == ?*,* ]]; then + prev="${cur%,*}" + cur="${cur##*,}" + COMPREPLY=($(compgen -W "{0..100}" -- "$cur")) + ((${#COMPREPLY[@]} == 1)) && + COMPREPLY=(${COMPREPLY/#/$prev,}) + else + COMPREPLY=($(compgen -W "{0..100}" -- "$cur")) + ((${#COMPREPLY[@]} == 1)) && COMPREPLY=(${COMPREPLY/%/,}) + compopt -o nospace + fi + return + ;; + --title | -t | --include-pattern | --exclude-pattern | --path-strip-level) + # argument required but no completions available + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --help)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir +} && + complete -F _kcov kcov + +# ex: filetype=sh diff --git a/completions/kill b/completions/kill new file mode 100644 index 0000000..25cddba --- /dev/null +++ b/completions/kill @@ -0,0 +1,29 @@ +# kill(1) completion -*- shell-script -*- + +_kill() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -s) + _signals + return + ;; + -l) + return + ;; + esac + + if [[ $cword -eq 1 && $cur == -* ]]; then + # return list of available signals + _signals - + COMPREPLY+=($(compgen -W "-s -l" -- "$cur")) + else + # return list of available PIDs + _pids + fi +} && + complete -F _kill kill + +# ex: filetype=sh diff --git a/completions/killall b/completions/killall new file mode 100644 index 0000000..c7c0b0f --- /dev/null +++ b/completions/killall @@ -0,0 +1,36 @@ +# killall(1) completion -*- shell-script -*- + +[[ $OSTYPE == *@(linux|freebsd|darwin)* ]] || return 1 + +_killall() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --context | --older-than | --younger-than | --version | -!(-*)@([Zoy]|V*)) + return + ;; + --signal | -!(-*)s) + _signals + return + ;; + --user | -!(-*)u) + _allowed_users + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + ((cword == 1)) && _signals - + return + fi + + _pnames +} && + complete -F _killall killall + +# ex: filetype=sh diff --git a/completions/kldload b/completions/kldload new file mode 100644 index 0000000..f511158 --- /dev/null +++ b/completions/kldload @@ -0,0 +1,21 @@ +# FreeBSD kldload completion -*- shell-script -*- + +[[ $OSTYPE == *freebsd* ]] || return 1 + +_kldload() +{ + local cur prev words cword + _init_completion || return + + local moddir=/modules/ + [[ -d $moddir ]] || moddir=/boot/kernel/ + + compopt -o filenames + COMPREPLY=($(compgen -f "$moddir$cur")) + COMPREPLY=(${COMPREPLY[@]#$moddir}) + COMPREPLY=(${COMPREPLY[@]%.ko}) + +} && + complete -F _kldload kldload + +# ex: filetype=sh diff --git a/completions/kldunload b/completions/kldunload new file mode 100644 index 0000000..2e12282 --- /dev/null +++ b/completions/kldunload @@ -0,0 +1,15 @@ +# FreeBSD kldunload completion -*- shell-script -*- + +[[ $OSTYPE == *freebsd* ]] || return 1 + +_kldunload() +{ + local cur prev words cword + _init_completion || return + + COMPREPLY=($(compgen -W '$(kldstat)' -X 'kernel' -X '!*.ko' -- "$cur")) + COMPREPLY=(${COMPREPLY[@]%.ko}) +} && + complete -F _kldunload kldunload + +# ex: filetype=sh diff --git a/completions/koji b/completions/koji new file mode 100644 index 0000000..8efef9a --- /dev/null +++ b/completions/koji @@ -0,0 +1,245 @@ +# koji completion -*- shell-script -*- + +_koji_search() +{ + COMPREPLY+=($(compgen -W \ + '$("$1" -q search $2 "$cur*" 2>/dev/null)' -- "$cur")) +} + +_koji_build() +{ + _koji_search "$1" build +} + +_koji_package() +{ + _koji_search "$1" package +} + +_koji_user() +{ + _koji_search "$1" user +} + +_koji_tag() +{ + COMPREPLY+=($(compgen -W '$("$1" -q list-tags 2>/dev/null)' -- "$cur")) +} + +_koji_target() +{ + COMPREPLY+=($(compgen -W '$("$1" -q list-targets 2>/dev/null | + awk "{ print \$1 }")' -- "$cur")) +} + +_koji() +{ + local cur prev words cword split + _init_completion -s || return + + local commandix command + for ((commandix = 1; commandix < cword; commandix++)); do + if [[ ${words[commandix]} != -* ]]; then + command=${words[commandix]} + break + fi + done + + case $prev in + --help | --help-commands | -!(-*)h*) + return + ;; + --config | --keytab | -!(-*)[co]) + _filedir + return + ;; + --runas | --user | --editor | --by) + _koji_user "$1" + return + ;; + --authtype) + COMPREPLY=($(compgen -W 'noauth ssl password kerberos' -- "$cur")) + return + ;; + --topdir) + _filedir -d + return + ;; + --type) + case ${command-} in + latest-pkg | list-tagged) + COMPREPLY=($(compgen -W 'maven' -- "$cur")) + ;; + esac + return + ;; + --name) + case ${command-} in + list-targets) + _koji_target "$1" + ;; + esac + return + ;; + --owner) + _koji_user "$1" + return + ;; + --tag | --latestfrom) + _koji_tag "$1" + return + ;; + --package) + _koji_package "$1" + return + ;; + --build) + _koji_build "$1" + return + ;; + --build-target) + _koji_target "$1" + return + ;; + esac + + $split && return + + if [[ -v command ]]; then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W \ + '$(_parse_help "$1" "$command --help")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + # How many'th non-option arg (1-based) for $command are we completing? + local i nth=1 + for ((i = commandix + 1; i < cword; i++)); do + [[ ${words[i]} == -* ]] || ((nth++)) + done + + case $command in + build | maven-build | win-build) + case $nth in + 1) + _koji_target "$1" + ;; + 2) + _filedir src.rpm + ;; + esac + ;; + cancel) + _koji_build "$1" + ;; + chain-build) + case $nth in + 1) + _koji_target "$1" + ;; + esac + ;; + download-build) + case $nth in + 1) + _koji_build "$1" + ;; + esac + ;; + import-comps) + case $nth in + 1) + _filedir xml + ;; + 2) + _koji_tag "$1" + ;; + esac + ;; + latest-by-tag) + _koji_package "$1" + ;; + latest-pkg | list-groups | list-tag-inheritance | show-groups) + case $nth in + 1) + _koji_tag "$1" + ;; + esac + ;; + list-tagged) + case $nth in + 1) + _koji_tag "$1" + ;; + 2) + _koji_package "$1" + ;; + esac + ;; + list-untagged) + case $nth in + 1) + _koji_package "$1" + ;; + esac + ;; + move-pkg) + case $nth in + 1 | 2) + _koji_tag "$1" + ;; + *) + _koji_package "$1" + ;; + esac + ;; + search) + case $nth in + 1) + COMPREPLY=($(compgen -W 'package build tag target + user host rpm' -- "$cur")) + ;; + esac + ;; + tag-pkg | untag-pkg) + case $nth in + 1) + _koji_tag "$1" + ;; + *) + _koji_package "$1" + ;; + esac + ;; + taginfo) + _koji_tag "$1" + ;; + wait-repo) + case $nth in + 1) + for ((i = commandix + 1; i < cword; i++)); do + if [[ ${words[i]} == --target ]]; then + _koji_target "$1" + return + fi + done + _koji_tag "$1" + ;; + esac + ;; + esac + return + fi + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + elif [[ ! -v command ]]; then + COMPREPLY=($(compgen -W '$("$1" --help-commands 2>/dev/null | \ + awk "/^( +|\t)/ { print \$1 }")' -- "$cur")) + fi +} && + complete -F _koji koji arm-koji ppc-koji s390-koji sparc-koji + +# ex: filetype=sh diff --git a/completions/ktutil b/completions/ktutil new file mode 100644 index 0000000..6030a47 --- /dev/null +++ b/completions/ktutil @@ -0,0 +1,120 @@ +# ktutil completion -*- shell-script -*- + +_heimdal_principals() +{ + COMPREPLY=($(compgen -W "$(kadmin -l dump 2>/dev/null | + awk '{print $1}')" -- "$cur")) +} + +_heimdal_realms() +{ + COMPREPLY=($(compgen -W "$(kadmin -l dump 2>/dev/null | + awk '{print $1}' | awk -F@ '{print $2}')" -- "$cur")) +} + +_heimdal_encodings() +{ + COMPREPLY=($(compgen -W 'des-cbc-mcrc des-cbc-md4 des-cbc-md5 + des3-cbc-sha1 arcfour-hmac-md5 aes128-cts-hmac-sha1-96 + aes256-cts-hmac-sha1-96' -- "$cur")) +} + +_ktutil() +{ + local cur prev words cword split + _init_completion -s || return + + local command commands i options + + case $prev in + -p | --principal) + _heimdal_principals + return + ;; + -e | --enctype) + _heimdal_encodings + return + ;; + -a | --admin-server) + _known_hosts_real -- "$cur" + return + ;; + -r | --realm) + _heimdal_realms + return + ;; + -s | -k | --srvtab | --keytab) + _filedir + return + ;; + esac + + $split && return + + commands='add change copy get list remove rename purge srvconvert + srv2keytab srvcreate key2srvtab' + + for ((i = 1; i < cword; i++)); do + case ${words[i]} in + -k | --keytab) + ((i++)) + ;; + -*) ;; + + *) + command=${words[i]} + break + ;; + esac + done + + if [[ $cur == -* ]]; then + case ${command-} in + add) + options='-p --principal -V -e --enctype -w --password -r + --random -s --no-salt -h --hex' + ;; + change) + options='-r --realm -a --admin-server -s --server-port' + ;; + get) + options='-p --principal -e --enctype -r --realm -a + --admin-server -s server --server-port' + ;; + list) + options='--keys --timestamp' + ;; + remove) + options='-p --principal -V --kvno -e --enctype' + ;; + purge) + options='--age' + ;; + srv2keytab | key2srvtab) + options='-s --srvtab' + ;; + *) + options='-k --keytab -v --verbose --version -v --help' + ;; + esac + COMPREPLY=($(compgen -W "$options" -- "$cur")) + else + case ${command-} in + copy) + _filedir + ;; + get) + _heimdal_principals + ;; + rename) + _heimdal_principals + ;; + *) + COMPREPLY=($(compgen -W "$commands" -- "$cur")) + ;; + esac + fi +} && + complete -F _ktutil ktutil + +# ex: filetype=sh diff --git a/completions/larch b/completions/larch new file mode 100644 index 0000000..7ed9ca2 --- /dev/null +++ b/completions/larch @@ -0,0 +1,39 @@ +# larch(1) completion -*- shell-script -*- +# by Alex Shinn <foof@synthcode.com> + +_larch() +{ + local cur prev words cword + _init_completion || return + + if [[ $cword -eq 1 || $prev == -* ]]; then + COMPREPLY=($(compgen -W ' \ + my-id my-default-archive register-archive whereis-archive archives \ + init-tree tree-root tree-version set-tree-version inventory \ + tagging-method tree-lint missing-tags add delete \ + move explicit-default set-manifest manifest check-manifest mkpatch \ + dopatch patch-report empty-patch make-archive make-category \ + make-branch make-version categories branches versions revisions \ + cat-archive-log archive-cache-revision archive-cached-revisions \ + archive-uncache-revision category-readme branch-readme \ + version-readme make-log logs add-log log-ls cat-log \ + log-header-field changelog log-for-merge merge-points \ + new-on-branch import commit get get-patch lock-branch \ + lock-revision push-mirror build-config update-config replay-config \ + record-config show-config config-history update replay delta-patch \ + star-merge tag prepare-branch finish-branch join-branch \ + whats-missing what-changed file-diffs pristines lock-pristine \ + my-revision-library library-find library-add library-remove \ + library-archives library-categories library-branches \ + library-versions library-revisions library-log library-file \ + touched-files-prereqs patch-set-web update-distributions \ + distribution-name notify my-notifier mail-new-categories \ + mail-new-branches mail-new-versions mail-new-revisions \ + notify-library notify-browser push-new-revisions sendmail-mailx' \ + "$cur")) + fi + +} && + complete -F _larch -o default larch + +# ex: filetype=sh diff --git a/completions/lastlog b/completions/lastlog new file mode 100644 index 0000000..214a174 --- /dev/null +++ b/completions/lastlog @@ -0,0 +1,25 @@ +# lastlog(8) completion -*- shell-script -*- + +_lastlog() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --before | --help | --time | -!(-*)@([bt]|h*)) + return + ;; + --user | -!(-*)u) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + esac + + $split && return + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace +} && + complete -F _lastlog lastlog + +# ex: filetype=sh diff --git a/completions/ldapsearch b/completions/ldapsearch new file mode 100644 index 0000000..6dc415e --- /dev/null +++ b/completions/ldapsearch @@ -0,0 +1,231 @@ +# bash completion for openldap -*- shell-script -*- + +_ldap_uris() +{ + COMPREPLY=($(compgen -W 'ldap:// ldaps://' -- "$cur")) +} + +_ldap_protocols() +{ + COMPREPLY=($(compgen -W '2 3' -- "$cur")) +} + +_ldapsearch() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*h) + _known_hosts_real -- "$cur" + return + ;; + -*H) + _ldap_uris + return + ;; + -*T) + _filedir -d + return + ;; + -*[fy]) + _filedir + return + ;; + -*s) + COMPREPLY=($(compgen -W 'base one sub children' -- "$cur")) + return + ;; + -*a) + COMPREPLY=($(compgen -W 'never always search find' -- "$cur")) + return + ;; + -*P) + _ldap_protocols + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1") -MM -ZZ' -- "$cur")) + fi +} && + complete -F _ldapsearch ldapsearch + +_ldapaddmodify() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*h) + _known_hosts_real -- "$cur" + return + ;; + -*H) + _ldap_uris + return + ;; + -*[Sfy]) + _filedir + return + ;; + -*P) + _ldap_protocols + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1") -MM -ZZ' -- "$cur")) + fi +} && + complete -F _ldapaddmodify ldapadd ldapmodify + +_ldapdelete() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*h) + _known_hosts_real -- "$cur" + return + ;; + -*H) + _ldap_uris + return + ;; + -*[fy]) + _filedir + return + ;; + -*P) + _ldap_protocols + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1") -MM -ZZ' -- "$cur")) + fi +} && + complete -F _ldapdelete ldapdelete + +_ldapcompare() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*h) + _known_hosts_real -- "$cur" + return + ;; + -*H) + _ldap_uris + return + ;; + -*y) + _filedir + return + ;; + -*P) + _ldap_protocols + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1") -MM -ZZ' -- "$cur")) + fi +} && + complete -F _ldapcompare ldapcompare + +_ldapmodrdn() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*h) + _known_hosts_real -- "$cur" + return + ;; + -*H) + _ldap_uris + return + ;; + -*[fy]) + _filedir + return + ;; + -*P) + _ldap_protocols + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1") -ZZ -MM' -- "$cur")) + fi +} && + complete -F _ldapmodrdn ldapmodrdn + +_ldapwhoami() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*h) + _known_hosts_real -- "$cur" + return + ;; + -*H) + _ldap_uris + return + ;; + -*[fy]) + _filedir + return + ;; + -*P) + _ldap_protocols + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1") -MM -ZZ' -- "$cur")) + fi +} && + complete -F _ldapwhoami ldapwhoami + +_ldappasswd() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*h) + _known_hosts_real -- "$cur" + return + ;; + -*H) + _ldap_uris + return + ;; + -*[tTy]) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1") -MM -ZZ' -- "$cur")) + fi +} && + complete -F _ldappasswd ldappasswd + +# ex: filetype=sh diff --git a/completions/ldapvi b/completions/ldapvi new file mode 100644 index 0000000..cb01ac8 --- /dev/null +++ b/completions/ldapvi @@ -0,0 +1,51 @@ +# bash completion for ldapvi -*- shell-script -*- + +_ldapvi() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --host | -!(-*)h) + _known_hosts_real -- "$cur" + return + ;; + --sasl-mech | -!(-*)Y) + COMPREPLY=($(compgen -W 'EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 + PLAIN ANONYMOUS' -- "$cur")) + return + ;; + --bind) + COMPREPLY=($(compgen -W 'simple sasl' -- "$cur")) + return + ;; + --bind-dialog) + COMPREPLY=($(compgen -W 'never auto always' -- "$cur")) + return + ;; + --scope) + COMPREPLY=($(compgen -W 'base one sub' -- "$cur")) + return + ;; + --deref) + COMPREPLY=($(compgen -W 'never searching finding always' \ + -- "$cur")) + return + ;; + --encoding) + COMPREPLY=($(compgen -W 'ASCII UTF-8 binary' -- "$cur")) + return + ;; + --tls) + COMPREPLY=($(compgen -W 'never allow try strict' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + fi +} && + complete -F _ldapvi ldapvi + +# ex: filetype=sh diff --git a/completions/lftp b/completions/lftp new file mode 100644 index 0000000..72dedb4 --- /dev/null +++ b/completions/lftp @@ -0,0 +1,28 @@ +# lftp(1) completion -*- shell-script -*- + +_lftp() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -!(-*)f) + _filedir + return + ;; + --help | --version | -!(-*)[chveups]) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + COMPREPLY=($(compgen -W '$("$1" -c "bookmark list" 2>/dev/null)' -- "$cur")) + _known_hosts_real -- "$cur" +} && + complete -F _lftp lftp + +# ex: filetype=sh diff --git a/completions/lftpget b/completions/lftpget new file mode 100644 index 0000000..d21622e --- /dev/null +++ b/completions/lftpget @@ -0,0 +1,14 @@ +# lftpget(1) completion -*- shell-script -*- + +_lftpget() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-c -d -v' -- "$cur")) + fi +} && + complete -F _lftpget lftpget + +# ex: filetype=sh diff --git a/completions/lilo b/completions/lilo new file mode 100644 index 0000000..af8539a --- /dev/null +++ b/completions/lilo @@ -0,0 +1,66 @@ +# bash completion for lilo(8) -*- shell-script -*- + +_lilo_labels() +{ + COMPREPLY=($(compgen -W "$(awk -F= '$1 ~ /^[ \t]*label$/ {print $2}' \ + ${1:-/etc/lilo.conf} 2>/dev/null | command sed -e 's/\"//g')" \ + -- "$cur")) +} + +_lilo() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -C | -i | -m | -s | -S) + _filedir + return + ;; + -r) + _filedir -d + return + ;; + -I | -D | -R) + # label completion + local i conf + for i in "${!words[@]}"; do + if [[ ${words[i]} == -C ]]; then + conf=${words[i + 1]} + break + fi + done + _lilo_labels $conf + return + ;; + -A | -b | -M | -u | -U) + # device completion + cur=${cur:=/dev/} + _filedir + return + ;; + -T) + # topic completion + COMPREPLY=($(compgen -W 'help ChRul EBDA geom geom= table= + video' -- "$cur")) + return + ;; + -B) + _filedir bmp + return + ;; + -E) + _filedir '@(bmp|dat)' + return + ;; + esac + + if [[ $cur == -* ]]; then + # relevant options completion + COMPREPLY=($(compgen -W '-A -B -b -c -C -d -E -f -g -i -I -l -L -m -M + -p -P -q -r -R -s -S -t -T -u -U -v -V -w -x -z' -- "$cur")) + fi +} && + complete -F _lilo lilo + +# ex: filetype=sh diff --git a/completions/links b/completions/links new file mode 100644 index 0000000..e0c28e2 --- /dev/null +++ b/completions/links @@ -0,0 +1,100 @@ +# bash completion for links -*- shell-script -*- + +_links() +{ + local cur prev words cword + _init_completion -n : || return + + case $prev in + -html-t-text-color | -html-t-link-color) + COMPREPLY=($(compgen -W '{0..15}' -- "$cur")) + return + ;; + -http.fake-firefox | -html-[gt]-ignore-document-color) + COMPREPLY=($(compgen -W '0 1' -- "$cur")) + return + ;; + --help | -help | -mode | -display | -source | -dump | -width | -max-connections | \ + -max-connections-to-host | -retries | -receive-timeout | \ + -unrestartable-receive-timeout | -*-size | -*-proxy | \ + -append-text-to-dns-lookups | -ssl.client-cert-passwd | -http.fake-* | \ + -http.extra-header | -ftp.anonymous-passwd | -*-color | -*-gamma | \ + -bfu-aspect | -html-image-scale | -html-margin) + return + ;; + -lookup) + _known_hosts_real -- "$cur" + return + ;; + -driver) + local drivers=$("$1" -driver foo 2>&1 | + command sed -ne '$!d' -e '/^[a-z0-9, ]\{1,\}$/s/,/ /gp') + [[ $drivers ]] || drivers='x svgalib fb directfb pmshell atheos' + COMPREPLY=($(compgen -W "$drivers" -- "$cur")) + return + ;; + -codepage | -bookmarks-codepage | -http-assume-codepage) + _xfunc iconv _iconv_charsets + return + ;; + -download-dir) + _filedir -d + return + ;; + -bind-address) + _ip_addresses + return + ;; + -bind-address-ipv6) + _ip_addresses -6 + __ltrim_colon_completions "$cur" + return + ;; + -async-dns | -download-utime | -aggressive-cache | -only-proxies | \ + -http-bugs.* | -http.do-not-track | -ftp.use-* | -ftp.fast | -ftp.set-iptos | \ + -smb.allow-hyperlinks-to-smb | -save-url-history | -dither-letters | \ + -dither-images | -overwrite-instead-of-scroll | -html-*) + COMPREPLY=($(compgen -W '0 1' -- "$cur")) + return + ;; + -address-preference | -http.referer) + COMPREPLY=($(compgen -W '{0..4}' -- "$cur")) + return + ;; + -ssl-certificates | -display-optimize | -gamma-correction) + COMPREPLY=($(compgen -W '{0..2}' -- "$cur")) + return + ;; + -ssl.client-cert-key) + _filedir '@(key|pem)' + return + ;; + -ssl.client-cert-crt) + _filedir '@(c?(e)rt|cer|pem|der)' + return + ;; + -bookmarks-file) + _filedir html + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" | + command grep -vF -- "->")' -- "$cur")) + return + fi + + local dir + for dir in .links .links2; do + if [[ -r ~/$dir/links.his ]]; then + COMPREPLY+=($(compgen -W '$(cat ~/$dir/links.his)' -- "$cur")) + __ltrim_colon_completions "$cur" + fi + done + _filedir '@(htm|html)' + +} && + complete -F _links links links2 + +# ex: filetype=sh diff --git a/completions/lintian b/completions/lintian new file mode 100644 index 0000000..9343832 --- /dev/null +++ b/completions/lintian @@ -0,0 +1,176 @@ +# bash completion for lintian(1) and lintian-info(1) -*- shell-script -*- + +_lintian_tags() +{ + local match search tags + + tags=$(awk '/^Tag/ { print $2 }' /usr/share/lintian/checks/*.desc) + if [[ $cur == *, ]]; then + search=${cur//,/ } + for item in $search; do + match=$(command grep -nE "^Tag: $item$" \ + /usr/share/lintian/checks/*.desc | cut -d: -f1) + tags=$(command sed -e "s/\<$item\>//g" <<<$tags) + done + COMPREPLY+=($(compgen -W "$tags")) + elif [[ $cur == *,* ]]; then + COMPREPLY+=($(compgen -P "${cur%,*}," -W "$tags" -- "${cur##*,}")) + else + COMPREPLY+=($(compgen -W "$tags" -- "$cur")) + fi +} + +_lintian_checks() +{ + local match search todisable checks + + checks=$(awk '/^(Check-Script|Abbrev)/ { print $2 }' \ + /usr/share/lintian/checks/*.desc) + if [[ $cur == *, ]]; then + search=${cur//,/ } + for item in $search; do + match=$(command grep -nE "^(Check-Script|Abbrev): $item$" \ + /usr/share/lintian/checks/*.desc | cut -d: -f1) + todisable=$(awk '/^(Check-Script|Abbrev)/ { print $2 }' $match) + for name in $todisable; do + checks=$(command sed -e "s/\<$name\>//g" <<<$checks) + done + done + COMPREPLY+=($(compgen -W "$checks")) + elif [[ $cur == *,* ]]; then + COMPREPLY+=($(compgen -P "${cur%,*}," -W "$checks" -- "${cur##*,}")) + else + COMPREPLY+=($(compgen -W "$checks" -- "$cur")) + fi +} + +_lintian_infos() +{ + local match search infos + + infos=$(awk '/^Collector/ { print $2 }' \ + /usr/share/lintian/collection/*.desc) + if [[ $cur == *, ]]; then + search=${cur//,/ } + for item in $search; do + match=$(command grep -nE "^Collector: $item$" \ + /usr/share/lintian/collection/*.desc | cut -d: -f1) + infos=$(command sed -e "s/\<$item\>//g" <<<$infos) + done + COMPREPLY+=($(compgen -W "$infos")) + elif [[ $cur == *,* ]]; then + COMPREPLY+=($(compgen -P "${cur%,*}," -W "$infos" -- "${cur##*,}")) + else + COMPREPLY+=($(compgen -W "$infos" -- "$cur")) + fi +} + +_lintian() +{ + local cur prev words cword + _init_completion || return + + local lint_actions general_opts behaviour_opts configuration_opts + + lint_actions="--setup-lab --remove-lab --check --check-part --tags + --tags-from-file --ftp-master-rejects --dont-check-part --unpack + --remove" + general_opts="--help --version --print-version --verbose --debug --quiet" + behaviour_opts="--info --display-info --display-experimental --pedantic + --display-level --suppress-tags --suppress-tags-from-file --no-override + --show-overrides --color --unpack-info --md5sums --checksums + --allow-root --fail-on-warnings --keep-lab" + configuration_opts="--cfg --lab --archivedir --dist --area --section --arch + --root" + + if [[ $prev == -* ]]; then + case $prev in + -C | --check-part | -X | --dont-check-part) + _lintian_checks + ;; + -T | --tags | --suppress-tags) + _lintian_tags + ;; + --tags-from-file | --suppress-tags-from-file | --cfg | -p | \ + --packages-file) + _filedir + ;; + --lab | --archivedir | --dist | --root) + _filedir -d + ;; + --color) + COMPREPLY=($(compgen -W "never always auto html" -- "$cur")) + ;; + -U | --unpack-info) + _lintian_infos + ;; + --area | --section) + COMPREPLY=($(compgen -W "main contrib non-free" -- "$cur")) + ;; + --arch) ;; + + esac + fi + + case "$cur" in + --*) + COMPREPLY=($(compgen -W "$lint_actions $general_opts + $behaviour_opts $configuration_opts" -- "$cur")) + ;; + *,) + # If we're here, the user is trying to complete on + # --action tag,tag,<TAB> + # Only few actions permit that, re-complete them now. + case "$prev" in + -C | --check-part | -X | --dont-check-part) + _lintian_checks + ;; + -T | --tags | --suppress-tags) + _lintian_tags + ;; + -U | --unpack-info) + _lintian_infos + ;; + esac + ;; + *) + # in Ubuntu, dbgsym packages end in .ddeb, lintian >= 2.57.0 groks + _filedir '@(?(u|d)deb|changes|dsc|buildinfo)' + ;; + esac + return 0 +} && + complete -F _lintian lintian + +_lintian_info() +{ + local cur prev words cword + _init_completion || return + + case "$prev" in + --help | --profile) + return + ;; + -t | --tags) + _lintian_tags + return + ;; + --include-dir) + _filedir -d + return + ;; + esac + + case "$cur" in + --*) + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + ;; + *) + _filedir + ;; + esac + return 0 +} && + complete -F _lintian_info lintian-info + +# ex: filetype=sh diff --git a/completions/lisp b/completions/lisp new file mode 100644 index 0000000..098567b --- /dev/null +++ b/completions/lisp @@ -0,0 +1,22 @@ +# -*- shell-script -*- +# bash programmable completion for various Common Lisp implementations by +# Nikodemus Siivola <nikodemus@random-state.net> + +_lisp() +{ + local cur prev words cword + _init_completion || return + + # completing an option (may or may not be separated by a space) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-core -lib -batch -quit -edit -eval -init + -dynamic-space-size -hinit -noinit -nositeinit -load -slave' \ + -- "$cur")) + else + _filedir + fi + +} && + complete -F _lisp -o default lisp + +# ex: filetype=sh diff --git a/completions/list_admins b/completions/list_admins new file mode 100644 index 0000000..5708179 --- /dev/null +++ b/completions/list_admins @@ -0,0 +1,17 @@ +# mailman list_admins completion -*- shell-script -*- + +_list_admins() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--all-vhost --all --help' -- "$cur")) + else + _xfunc list_lists _mailman_lists + fi + +} && + complete -F _list_admins list_admins + +# ex: filetype=sh diff --git a/completions/list_lists b/completions/list_lists new file mode 100644 index 0000000..c5b9ba7 --- /dev/null +++ b/completions/list_lists @@ -0,0 +1,21 @@ +# mailman list_lists completion -*- shell-script -*- + +_mailman_lists() +{ + COMPREPLY=($(compgen -W '$(list_lists -b 2>/dev/null)' -- "$cur")) +} + +_list_lists() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--advertised --virtual-host-overview --bare + --help' -- "$cur")) + fi + +} && + complete -F _list_lists list_lists + +# ex: filetype=sh diff --git a/completions/list_members b/completions/list_members new file mode 100644 index 0000000..639344c --- /dev/null +++ b/completions/list_members @@ -0,0 +1,36 @@ +# mailman list_members completion -*- shell-script -*- + +_list_members() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -o | --output) + _filedir + return + ;; + -d | --digest) + COMPREPLY=($(compgen -W 'mime plain' -- "$cur")) + return + ;; + -n | --nomail) + COMPREPLY=($(compgen -W 'byadmin byuser bybounce unknown' \ + -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--output --regular --digest --nomail + --fullnames --preserve --help' -- "$cur")) + else + _xfunc list_lists _mailman_lists + fi + +} && + complete -F _list_members list_members + +# ex: filetype=sh diff --git a/completions/list_owners b/completions/list_owners new file mode 100644 index 0000000..445be0b --- /dev/null +++ b/completions/list_owners @@ -0,0 +1,18 @@ +# mailman list_owners completion -*- shell-script -*- + +_list_owners() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--with-listnames --moderators --help' \ + -- "$cur")) + else + _xfunc list_lists _mailman_lists + fi + +} && + complete -F _list_owners list_owners + +# ex: filetype=sh diff --git a/completions/locale-gen b/completions/locale-gen new file mode 100644 index 0000000..4068201 --- /dev/null +++ b/completions/locale-gen @@ -0,0 +1,32 @@ +# locale-gen(8) completion -*- shell-script -*- + +_locale_gen() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | -h) + return + ;; + --aliases) + _filedir alias + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + COMPREPLY=($(compgen -W \ + '$(awk "{ print \$1 }" /usr/share/i18n/SUPPORTED 2>/dev/null)' \ + -- "$cur")) +} && + complete -F _locale_gen locale-gen + +# ex: filetype=sh diff --git a/completions/lpq b/completions/lpq new file mode 100644 index 0000000..36729d2 --- /dev/null +++ b/completions/lpq @@ -0,0 +1,28 @@ +# lpq(1) completion -*- shell-script -*- + +_lpq() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -P) + COMPREPLY=($(compgen -W "$(lpstat -a 2>/dev/null | cut -d' ' -f1)" -- "$cur")) + return + ;; + -U) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + esac + + if [[ $cur == - ]]; then + COMPREPLY=($(compgen -W '-E -P -U -a -h -l' -- "$cur")) + return + fi + + _filedir +} && + complete -F _lpq lpq + +# ex: filetype=sh diff --git a/completions/lpr b/completions/lpr new file mode 100644 index 0000000..554f053 --- /dev/null +++ b/completions/lpr @@ -0,0 +1,33 @@ +# lpr(1) completion -*- shell-script -*- + +_lpr() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -P) + COMPREPLY=($(compgen -W "$(lpstat -a 2>/dev/null | cut -d' ' -f1)" -- "$cur")) + return + ;; + -U) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + -o) + COMPREPLY=($(compgen -W "media= landscape orientation-requested= sides= fitplot number-up= scaling= cpi= lpi= page-bottom= page-top= page-left= page-right=" -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + ;; + esac + + if [[ $cur == - ]]; then + COMPREPLY=($(compgen -W '-E -H -C -J -T -P -U -h -l -m -o -p -q -r' -- "$cur")) + return + fi + + _filedir +} && + complete -F _lpr lpr + +# ex: filetype=sh diff --git a/completions/lrzip b/completions/lrzip new file mode 100644 index 0000000..eb2904c --- /dev/null +++ b/completions/lrzip @@ -0,0 +1,52 @@ +# lrzip(1) completion -*- shell-script -*- + +_lrzip() +{ + local cur prev words cword + _init_completion || return + + local xspec="*.lrz" + + case $prev in + -*@([wSm]|[Vh?]*)) + return + ;; + -*d) + xspec="!"$xspec + ;; + -*o) + _filedir + return + ;; + -*O) + _filedir -d + return + ;; + -*L) + COMPREPLY=($(compgen -W '{1..9}' -- "$cur")) + return + ;; + -*N) + COMPREPLY=($(compgen -W '{-20..19}' -- "$cur")) + return + ;; + -*p) + COMPREPLY=($(compgen -W "{1..$(_ncpus)}" -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + _tilde "$cur" || return + + local IFS=$'\n' + compopt -o filenames + COMPREPLY=($(compgen -f -X "$xspec" -- "$cur") $(compgen -d -- "$cur")) +} && + complete -F _lrzip lrzip + +# ex: filetype=sh diff --git a/completions/lsof b/completions/lsof new file mode 100644 index 0000000..eb1e967 --- /dev/null +++ b/completions/lsof @@ -0,0 +1,56 @@ +# lsof(8) completion -*- shell-script -*- + +_lsof() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -'?' | -h | +c | -c | -d | -F | -i | +r | -r | -s | -S | -T) + return + ;; + -A | -k | -m | +m | -o) + _filedir + return + ;; + +d | +D) + _filedir -d + return + ;; + -D) + COMPREPLY=($(compgen -W '? b i r u' -- "$cur")) + return + ;; + -f) + COMPREPLY=($(compgen -W 'c f g G n' -- "$cur")) + return + ;; + -g) + # TODO: handle ^foo exclusions, comma separated lists + _pgids + return + ;; + -p) + # TODO: handle ^foo exclusions, comma separated lists + _pids + return + ;; + -u) + # TODO: handle ^foo exclusions, comma separated lists + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + esac + + if [[ $cur == [-+]* ]]; then + COMPREPLY=($(compgen -W '-h -a -A -b -c +c -C +d -d +D -D +f -f -F -g + -i -k -l +L -L +m -m +M -M -n -N -o -O -p -P +r -r -R -s -S -T -t + -u -U -v -V +w -w -x -X -z -Z' -- "$cur")) + return + fi + + _filedir +} && + complete -F _lsof lsof + +# ex: filetype=sh diff --git a/completions/lspci b/completions/lspci new file mode 100644 index 0000000..d50783c --- /dev/null +++ b/completions/lspci @@ -0,0 +1,41 @@ +# lspci(8) completion -*- shell-script -*- + +_lspci() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*[sDO]) + return + ;; + -*i) + _filedir ids + return + ;; + -*p) + _filedir pcimap + return + ;; + -*A) + COMPREPLY+=($(compgen -W '$($1 -A help | command grep -vF :)' \ + -- "$cur")) + return + ;; + -*H) + COMPREPLY+=($(compgen -W "1 2" -- "$cur")) + return + ;; + -*F) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + fi +} && + complete -F _lspci lspci + +# ex: filetype=sh diff --git a/completions/lsscsi b/completions/lsscsi new file mode 100644 index 0000000..bcbc430 --- /dev/null +++ b/completions/lsscsi @@ -0,0 +1,27 @@ +# lsscsi(8) completion -*- shell-script -*- + +_lsscsi() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | -!(-*)[hV]*) + return + ;; + --sysfsroot | -!(-*)y) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _lsscsi lsscsi + +# ex: filetype=sh diff --git a/completions/lsusb b/completions/lsusb new file mode 100644 index 0000000..63cff54 --- /dev/null +++ b/completions/lsusb @@ -0,0 +1,20 @@ +# lsusb(8) completion -*- shell-script -*- + +_lsusb() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | -!(-*)@([sD]|[hV]*)) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + fi +} && + complete -F _lsusb lsusb + +# ex: filetype=sh diff --git a/completions/lua b/completions/lua new file mode 100644 index 0000000..3c4df90 --- /dev/null +++ b/completions/lua @@ -0,0 +1,23 @@ +# lua(1) completion -*- shell-script -*- + +_lua() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -e | -l | -v | -) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$(_parse_help "$1")" -- "$cur")) + return + fi + + _filedir 'l@(ua|?(ua)c)' +} && + complete -F _lua lua + +# ex: filetype=sh diff --git a/completions/luac b/completions/luac new file mode 100644 index 0000000..c763deb --- /dev/null +++ b/completions/luac @@ -0,0 +1,27 @@ +# luac(1) completion -*- shell-script -*- + +_luac() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -v | -) + return + ;; + -o) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$(_parse_help "$1")" -- "$cur")) + return + fi + + _filedir lua +} && + complete -F _luac luac + +# ex: filetype=sh diff --git a/completions/luseradd b/completions/luseradd new file mode 100644 index 0000000..4d66385 --- /dev/null +++ b/completions/luseradd @@ -0,0 +1,40 @@ +# luseradd(1) and lusermod(1) completion -*- shell-script -*- + +_luseradd() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --usage | --gecos | --uid | --login | --plainpassword | --password | \ + --commonname | --givenname | --surname | --roomnumber | --telephonenumber | \ + --homephone | -!(-*)@([culPp]|[?]*)) + return + ;; + --directory | --skeleton | -!(-*)[dk]) + _filedir -d + return + ;; + --shell | -!(-*)s) + _shells + return + ;; + --gid | -!(-*)g) + _gids + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + [[ ${1##*/} == luseradd ]] || COMPREPLY=($(compgen -u -- "$cur")) +} && + complete -F _luseradd luseradd lusermod + +# ex: filetype=sh diff --git a/completions/luserdel b/completions/luserdel new file mode 100644 index 0000000..e36bda9 --- /dev/null +++ b/completions/luserdel @@ -0,0 +1,23 @@ +# luserdel(1) completion -*- shell-script -*- + +_luserdel() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --usage | -!(-*)[?]*) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + COMPREPLY=($(compgen -u -- "$cur")) +} && + complete -F _luserdel luserdel + +# ex: filetype=sh diff --git a/completions/lvm b/completions/lvm new file mode 100644 index 0000000..e70ecc3 --- /dev/null +++ b/completions/lvm @@ -0,0 +1,861 @@ +# bash completion for lvm -*- shell-script -*- + +_lvm_filedir() +{ + cur=${cur:-/dev/} + _filedir +} + +_lvm_volumegroups() +{ + COMPREPLY=($(compgen -W "$(vgscan 2>/dev/null | + command sed -n -e 's|.*Found.*"\(.*\)".*$|\1|p')" -- "$cur")) +} + +_lvm_physicalvolumes_all() +{ + COMPREPLY=($(compgen -W "$(pvscan 2>/dev/null | + command sed -n -e 's|^.*PV \([^ ]*\) .*|\1|p')" -- "$cur")) +} + +_lvm_physicalvolumes() +{ + COMPREPLY=($(compgen -W "$(pvscan 2>/dev/null | + command sed -n -e 's|^.*PV \(.*\) VG.*$|\1|p')" -- "$cur")) +} + +_lvm_logicalvolumes() +{ + COMPREPLY=($(compgen -W "$(lvscan 2>/dev/null | + command sed -n -e "s|^.*'\(.*\)'.*$|\1|p")" -- "$cur")) + if [[ $cur == /dev/mapper/* ]]; then + _filedir + local i + for i in "${!COMPREPLY[@]}"; do + [[ ${COMPREPLY[i]} == */control ]] && unset 'COMPREPLY[i]' + done + fi +} + +_lvm_units() +{ + COMPREPLY=($(compgen -W 'h s b k m g t H K M G T' -- "$cur")) +} + +_lvm_sizes() +{ + COMPREPLY=($(compgen -W 'k K m M g G t T' -- "$cur")) +} + +# @param $1 glob matching args known to take an argument +_lvm_count_args() +{ + args=0 + local offset=1 + if [[ ${words[0]} == lvm ]]; then + offset=2 + fi + local i prev=${words[offset - 1]} + for ((i = offset; i < cword; i++)); do + # shellcheck disable=SC2053 + if [[ ${words[i]} != -* && $prev != $1 ]]; then + ((args++)) + fi + prev=${words[i]} + done +} + +_lvmdiskscan() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + fi +} && + complete -F _lvmdiskscan lvmdiskscan + +_pvscan() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + fi +} && + complete -F _pvscan pvscan + +_pvs() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --options | --sort | -!(-*)[oO]) + COMPREPLY=($(compgen -W 'pv_fmt pv_uuid pv_size pv_free pv_used + pv_name pv_attr pv_pe_count pv_pe_alloc_count' -- "$cur")) + return + ;; + --units) + _lvm_units + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_physicalvolumes_all + fi +} && + complete -F _pvs pvs + +_pvdisplay() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --units) + _lvm_units + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_physicalvolumes_all + fi +} && + complete -F _pvdisplay pvdisplay + +_pvchange() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | --allocatable | -!(-*)[Ax]) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_physicalvolumes_all + fi +} && + complete -F _pvchange pvchange + +_pvcreate() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --restorefile) + _filedir + return + ;; + --metadatatype | -!(-*)M) + COMPREPLY=($(compgen -W '1 2' -- "$cur")) + return + ;; + --metadatacopies) + COMPREPLY=($(compgen -W '0 1 2' -- "$cur")) + return + ;; + --metadatasize | --setphysicalvolumesize) + _lvm_sizes + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_filedir + fi +} && + complete -F _pvcreate pvcreate + +_pvmove() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | -!(-*)A) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + --name | -!(-*)n) + _lvm_logicalvolumes + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_physicalvolumes + fi +} && + complete -F _pvmove pvmove + +_pvremove() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_physicalvolumes_all + fi +} && + complete -F _pvremove pvremove + +_vgscan() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + fi +} && + complete -F _vgscan vgscan + +_vgs() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --options | --sort | -!(-*)[oO]) + COMPREPLY=($(compgen -W 'vg_fmt vg_uuid vg_name vg_attr vg_size + vg_free vg_sysid vg_extent_size vg_extent_count vg_free_count + max_lv max_pv pv_count lv_count snap_count vg_seqno' \ + -- "$cur")) + return + ;; + --units) + _lvm_units + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_volumegroups + fi +} && + complete -F _vgs vgs + +_vgdisplay() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --units) + _lvm_units + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_volumegroups + fi +} && + complete -F _vgdisplay vgdisplay + +_vgchange() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --available | --autobackup | --resizeable | -!(-*)[aAx]) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_volumegroups + fi +} && + complete -F _vgchange vgchange + +_vgcreate() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | -!(-*)A) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + --metadatatype | -!(-*)M) + COMPREPLY=($(compgen -W '1 2' -- "$cur")) + return + ;; + --physicalextentsize | -!(-*)s) + _lvm_sizes + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + local args + _lvm_count_args '@(-A|--autobackup|-M|--metadatatype|-s|--physicalextentsize)' + if ((args == 0)); then + _lvm_volumegroups + else + _lvm_physicalvolumes_all + fi + fi +} && + complete -F _vgcreate vgcreate + +_vgremove() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_volumegroups + fi +} && + complete -F _vgremove vgremove + +_vgrename() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | -!(-*)A) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_volumegroups + fi +} && + complete -F _vgrename vgrename + +_vgreduce() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | -!(-*)A) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + + else + local args + _lvm_count_args '@(-A|--autobackup)' + if ((args == 0)); then + _lvm_volumegroups + else + _lvm_physicalvolumes + fi + fi +} && + complete -F _vgreduce vgreduce + +_vgextend() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | -!(-*)A) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + --size | -!(-*)L) + _lvm_sizes + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + local args + _lvm_count_args '@(-A|--autobackup|-L|--size)' + if ((args == 0)); then + _lvm_volumegroups + else + _lvm_physicalvolumes_all + fi + fi +} && + complete -F _vgextend vgextend + +_vgport() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_volumegroups + fi +} && + complete -F _vgport vgimport vgexport + +_vgck() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_volumegroups + fi +} && + complete -F _vgck vgck + +_vgconvert() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --metadatatype | -!(-*)M) + COMPREPLY=($(compgen -W '1 2' -- "$cur")) + return + ;; + --metadatacopies) + COMPREPLY=($(compgen -W '0 1 2' -- "$cur")) + return + ;; + --metadatasize) + _lvm_sizes + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_volumegroups + fi +} && + complete -F _vgconvert vgconvert + +_vgcfgbackup() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --file | -!(-*)f) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_volumegroups + fi +} && + complete -F _vgcfgbackup vgcfgbackup + +_vgcfgrestore() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --file | -!(-*)f) + _filedir + return + ;; + --metadatatype | -!(-*)M) + COMPREPLY=($(compgen -W '1 2' -- "$cur")) + return + ;; + --name | -!(-*)n) + _lvm_volumegroups + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_volumegroups + fi +} && + complete -F _vgcfgrestore vgcfgrestore + +_vgmerge() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | -!(-*)A) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_volumegroups + fi +} && + complete -F _vgmerge vgmerge + +_vgsplit() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | -!(-*)A) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + --metadatatype | -!(-*)M) + COMPREPLY=($(compgen -W '1 2' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + local args + _lvm_count_args '@(-A|--autobackup|-M|--metadatatype)' + if ((args == 0 || args == 1)); then + _lvm_volumegroups + else + _lvm_physicalvolumes + fi + fi +} && + complete -F _vgsplit vgsplit + +_vgmknodes() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_volumegroups + fi +} && + complete -F _vgmknodes vgmknodes + +_lvscan() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + fi +} && + complete -F _lvscan lvscan + +_lvs() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --options | --sort | -!(-*)[oO]) + COMPREPLY=($(compgen -W 'lv_uuid lv_name lv_attr lv_minor lv_size + seg_count origin snap_percent segtype stripes stripesize + chunksize seg_start seg_size' -- "$cur")) + return + ;; + --units) + _lvm_units + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_logicalvolumes + fi +} && + complete -F _lvs lvs + +_lvdisplay() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --units) + _lvm_units + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_logicalvolumes + fi +} && + complete -F _lvdisplay lvdisplay + +_lvchange() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --available | --autobackup | --contiguous | --persistent | -!(-*)[aACM]) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + --permission | -!(-*)p) + COMPREPLY=($(compgen -W 'r rw' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_logicalvolumes + fi +} && + complete -F _lvchange lvchange + +_lvcreate() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | --contiguous | --persistent | --zero | -!(-*)[ACMZ]) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + --size | -!(-*)L) + _lvm_sizes + return + ;; + --permission | -!(-*)p) + COMPREPLY=($(compgen -W 'r rw' -- "$cur")) + return + ;; + --name | -!(-*)n) + _lvm_logicalvolumes + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + local args + _lvm_count_args '@(-A|-C|-M|-Z|--autobackup|--contiguous|--persistent|--zero|-L|--size|-p|--permission|-n|--name)' + if ((args == 0)); then + _lvm_volumegroups + else + _lvm_physicalvolumes + fi + fi +} && + complete -F _lvcreate lvcreate + +_lvremove() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | -!(-*)A) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_logicalvolumes + fi +} && + complete -F _lvremove lvremove + +_lvrename() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | -!(-*)A) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_logicalvolumes + fi +} && + complete -F _lvrename lvrename + +_lvreduce() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | -!(-*)A) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + --size | -!(-*)L) + _lvm_sizes + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _lvm_logicalvolumes + fi +} && + complete -F _lvreduce lvreduce + +_lvresize() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | -!(-*)A) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + --size | -!(-*)L) + _lvm_sizes + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + local args + _lvm_count_args '@(-A|--autobackup|-L|--size)' + if ((args == 0)); then + _lvm_logicalvolumes + else + _lvm_physicalvolumes + fi + fi +} && + complete -F _lvresize lvresize + +_lvextend() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --autobackup | -!(-*)A) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + --size | -!(-*)L) + _lvm_sizes + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + local args + _lvm_count_args '@(-A|--autobackup|-L|--size)' + if ((args == 0)); then + _lvm_logicalvolumes + else + _lvm_physicalvolumes + fi + fi +} && + complete -F _lvextend lvextend + +_lvm() +{ + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + COMPREPLY=($(compgen -W 'dumpconfig help lvchange lvcreate lvdisplay + lvextend lvmchange lvmdiskscan lvmsadc lvmsar lvreduce lvremove + lvrename lvresize lvs lvscan pvchange pvcreate pvdata pvdisplay + pvmove pvremove pvresize pvs pvscan vgcfgbackup vgcfgrestore + vgchange vgck vgconvert vgcreate vgdisplay vgexport vgextend + vgimport vgmerge vgmknodes vgreduce vgremove vgrename vgs vgscan + vgsplit version' -- "$cur")) + else + case "${words[1]}" in + pvchange | pvcreate | pvdisplay | pvmove | pvremove | pvresize | pvs | pvscan | \ + vgcfgbackup | vgcfgrestore | vgchange | vgck | vgconvert | vgcreate | \ + vgdisplay | vgexport | vgextend | vgimport | vgmerge | vgmknodes | vgreduce | \ + vgremove | vgrename | vgs | vgscan | vgsplit | lvchange | lvcreate | lvdisplay | \ + lvextend | lvreduce | lvremove | lvrename | lvresize | lvscan) + _${words[1]} + ;; + esac + fi +} && + complete -F _lvm lvm + +# ex: filetype=sh diff --git a/completions/lz4 b/completions/lz4 new file mode 100644 index 0000000..f297b5d --- /dev/null +++ b/completions/lz4 @@ -0,0 +1,52 @@ +# lz4 completion -*- shell-script -*- + +_lz4() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -b) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -X '-*#*' -W \ + '$(_parse_help "$1" -h) -B{4..7} -i{1..9}' -- "$cur")) + return + fi + + local args word xspec="*.?(t)lz4" + _count_args + ((args > 2)) && return + + for word in "${words[@]}"; do + case $word in + -*[dt]*) + case $args in + 1) xspec="!"$xspec ;; + 2) [[ $word == *t* ]] && return ;; + esac + break + ;; + -z) + case $args in + 1) xspec= ;; + 2) xspec="!"$xspec ;; + esac + break + ;; + esac + done + + _tilde "$cur" || return + + local IFS=$'\n' + compopt -o filenames + COMPREPLY=($(compgen -f -X "$xspec" -- "$cur") $(compgen -d -- "$cur")) +} && + complete -F _lz4 lz4 lz4c + +# ex: filetype=sh diff --git a/completions/lzip b/completions/lzip new file mode 100644 index 0000000..05f169c --- /dev/null +++ b/completions/lzip @@ -0,0 +1,47 @@ +# lzip(1) completion -*- shell-script -*- + +_lzip() +{ + local cur prev words cword split + _init_completion -s || return + + local decompress=false + + case $prev in + --help | --version | --member-size | --match-length | --dictionary-size | \ + --volume-size | --data-size | -!(-*)@([bmsSB]|[hV]*)) + return + ;; + --decompress-!(-*)d) + decompress=true + ;; + --threads-!(-*)n) + COMPREPLY=($(compgen -W "{1..$(_ncpus)}" -- "$cur")) + return + ;; + --output-!(-*)o) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1") {-1..-9}' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + if $decompress; then + _filedir lz + return + fi + + local IFS=$'\n' + compopt -o filenames + COMPREPLY=($(compgen -f -X "*.lz" -- "$cur") $(compgen -d -- "$cur")) +} && + complete -F _lzip clzip lzip pdlzip plzip + +# ex: filetype=sh diff --git a/completions/lzma b/completions/lzma new file mode 100644 index 0000000..34fba89 --- /dev/null +++ b/completions/lzma @@ -0,0 +1,34 @@ +# lzma(1) completion -*- shell-script -*- +# by Per Øyvind Karlsen <peroyvind@mandriva.org> + +_lzma() +{ + local cur prev words cword split + _init_completion -s || return + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1") -{1..9}' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + local IFS=$'\n' xspec="*.@(lzma|tlz)" + + if [[ $prev == --* ]]; then + [[ $prev == --@(decompress|list|test) ]] && xspec="!"$xspec + [[ $prev == --compress ]] && xspec= + elif [[ $prev == -* ]]; then + [[ $prev == -*[dt]* ]] && xspec="!"$xspec + [[ $prev == -*z* ]] && xspec= + fi + + _tilde "$cur" || return + + compopt -o filenames + COMPREPLY=($(compgen -f -X "$xspec" -- "$cur") $(compgen -d -- "$cur")) +} && + complete -F _lzma lzma + +# ex: filetype=sh diff --git a/completions/lzop b/completions/lzop new file mode 100644 index 0000000..2642742 --- /dev/null +++ b/completions/lzop @@ -0,0 +1,59 @@ +# lzop(1) completion -*- shell-script -*- + +_lzop() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --output | -!(-*)o) + _filedir + return + ;; + --path) + _filedir -d + return + ;; + --suffix | -!(-*)S) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-1 -2 -3 -4 -5 -6 -7 -8 -9 -P + --fast --best --decompress --extract --test --list --ls --info + --sysinfo --license --help --version --stdout --output --path + --force --no-checksum --no-name --name --no-mode --no-time --suffix + --keep --delete --crc32 --no-warn --ignore-warn --quiet --verbose + --no-stdin --filter --checksum --no-color --mono --color' \ + -- "$cur")) + return + fi + + local xspec="*.?(t)lzo" + case $prev in + --decompress | --uncompress | --extract | --list | --ls | --info | --test) + xspec="!"$xspec + ;; + --force) + xspec= + ;; + --*) ;; + + -*f*) + xspec= + ;; + -*[dltx]*) + xspec="!"$xspec + ;; + esac + + _tilde "$cur" || return + + local IFS=$'\n' + compopt -o filenames + COMPREPLY=($(compgen -f -X "$xspec" -- "$cur") $(compgen -d -- "$cur")) +} && + complete -F _lzop lzop + +# ex: filetype=sh diff --git a/completions/macof b/completions/macof new file mode 100644 index 0000000..ad29f58 --- /dev/null +++ b/completions/macof @@ -0,0 +1,22 @@ +# macof completion -*- shell-script -*- + +_macof() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -i) + _available_interfaces -a + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + fi + +} && + complete -F _macof macof + +# ex: filetype=sh diff --git a/completions/mailmanctl b/completions/mailmanctl new file mode 100644 index 0000000..3bbc2f2 --- /dev/null +++ b/completions/mailmanctl @@ -0,0 +1,18 @@ +# mailmanctl completion -*- shell-script -*- + +_mailmanctl() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--no-restart --run-as-user + --stale-lock-cleanup --quiet --help' -- "$cur")) + else + COMPREPLY=($(compgen -W 'start stop restart reopen' -- "$cur")) + fi + +} && + complete -F _mailmanctl mailmanctl + +# ex: filetype=sh diff --git a/completions/make b/completions/make new file mode 100644 index 0000000..96517c2 --- /dev/null +++ b/completions/make @@ -0,0 +1,170 @@ +# bash completion for GNU make -*- shell-script -*- + +_make_target_extract_script() +{ + local mode="$1" + shift + + local prefix="$1" + local prefix_pat=$(command sed 's/[][\,.*^$(){}?+|/]/\\&/g' <<<"$prefix") + local basename=${prefix##*/} + local dirname_len=$((${#prefix} - ${#basename})) + + if [[ $mode == -d ]]; then + # display mode, only output current path component to the next slash + local output="\2" + else + # completion mode, output full path to the next slash + local output="\1\2" + fi + + cat <<EOF + 1,/^# * Make data base/ d; # skip any makefile output + /^# * Finished Make data base/,/^# * Make data base/{ + d; # skip any makefile output + } + /^# * Variables/,/^# * Files/ d; # skip until files section + /^# * Not a target/,/^$/ d; # skip not target blocks + /^${prefix_pat}/,/^$/! d; # skip anything user dont want + + # The stuff above here describes lines that are not + # explicit targets or not targets other than special ones + # The stuff below here decides whether an explicit target + # should be output. + + /^# * File is an intermediate prerequisite/ { + s/^.*$//;x; # unhold target + d; # delete line + } + + /^$/ { # end of target block + x; # unhold target + /^$/d; # dont print blanks + s|^\(.\{${dirname_len}\}\)\(.\{${#basename}\}[^:/]*/\{0,1\}\)[^:]*:.*$|${output}|p; + d; # hide any bugs + } + + # This pattern includes a literal tab character as \t is not a portable + # representation and fails with BSD sed + /^[^# :%]\{1,\}:/ { # found target block + /^\.PHONY:/ d; # special target + /^\.SUFFIXES:/ d; # special target + /^\.DEFAULT:/ d; # special target + /^\.PRECIOUS:/ d; # special target + /^\.INTERMEDIATE:/ d; # special target + /^\.SECONDARY:/ d; # special target + /^\.SECONDEXPANSION:/ d; # special target + /^\.DELETE_ON_ERROR:/ d; # special target + /^\.IGNORE:/ d; # special target + /^\.LOW_RESOLUTION_TIME:/ d; # special target + /^\.SILENT:/ d; # special target + /^\.EXPORT_ALL_VARIABLES:/ d; # special target + /^\.NOTPARALLEL:/ d; # special target + /^\.ONESHELL:/ d; # special target + /^\.POSIX:/ d; # special target + /^\.NOEXPORT:/ d; # special target + /^\.MAKE:/ d; # special target +EOF + + # don't complete with hidden targets unless we are doing a partial completion + if [[ -z ${prefix_pat} || ${prefix_pat} == */ ]]; then + cat <<EOF + /^${prefix_pat}[^a-zA-Z0-9]/d; # convention for hidden tgt +EOF + fi + + cat <<EOF + h; # hold target + d; # delete line + } + +EOF +} + +_make() +{ + local cur prev words cword split + _init_completion -s || return + + local makef makef_dir=("-C" ".") i + + case $prev in + --file | --makefile | --old-file | --assume-old | --what-if | --new-file | \ + --assume-new | -!(-*)[foW]) + _filedir + return + ;; + --include-dir | --directory | -!(-*)[ICm]) + _filedir -d + return + ;; + -!(-*)E) + COMPREPLY=($(compgen -v -- "$cur")) + return + ;; + --eval | -!(-*)[DVx]) + return + ;; + --jobs | -!(-*)j) + COMPREPLY=($(compgen -W "{1..$(($(_ncpus) * 2))}" -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + local opts="$(_parse_help "$1")" + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + elif [[ $cur == *=* ]]; then + prev=${cur%%=*} + cur=${cur#*=} + local diropt + [[ ${prev,,} == *dir?(ectory) ]] && diropt=-d + _filedir $diropt + else + # before we check for makefiles, see if a path was specified + # with -C/--directory + for ((i = 1; i < ${#words[@]}; i++)); do + if [[ ${words[i]} == -@(C|-directory) ]]; then + # eval for tilde expansion + eval "makef_dir=( -C \"${words[i + 1]}\" )" + break + fi + done + + # before we scan for targets, see if a Makefile name was + # specified with -f/--file/--makefile + for ((i = 1; i < ${#words[@]}; i++)); do + if [[ ${words[i]} == -@(f|-?(make)file) ]]; then + # eval for tilde expansion + eval "makef=( -f \"${words[i + 1]}\" )" + break + fi + done + + # recognise that possible completions are only going to be displayed + # so only the base name is shown + local mode=-- + if ((COMP_TYPE != 9)); then + mode=-d # display-only mode + fi + + local IFS=$' \t\n' script=$(_make_target_extract_script $mode "$cur") + COMPREPLY=($(LC_ALL=C \ + $1 -npq __BASH_MAKE_COMPLETION__=1 \ + ${makef+"${makef[@]}"} "${makef_dir[@]}" .DEFAULT 2>/dev/null | + command sed -ne "$script")) + + if [[ $mode != -d ]]; then + # Completion will occur if there is only one suggestion + # so set options for completion based on the first one + [[ ${COMPREPLY-} == */ ]] && compopt -o nospace + fi + + fi +} && + complete -F _make make gmake gnumake pmake colormake bmake + +# ex: filetype=sh diff --git a/completions/makepkg b/completions/makepkg new file mode 100644 index 0000000..23ac784 --- /dev/null +++ b/completions/makepkg @@ -0,0 +1,48 @@ +# makepkg completion -*- shell-script -*- + +# Slackware Linux variant +_makepkg_slackware() +{ + local cur prev words cword + _init_completion || return + + case "$prev" in + -l | --linkadd | -c | --chown) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W \ + '$($1 | command sed -e "s/^options://" | _parse_help -)' \ + -- "$cur")) + return + fi + + _filedir +} + +_makepkg_bootstrap() +{ + local fname help + + # Use --help to detect variant; the Slackware one starts making + # a package for unknown args, including --version :P + help=$("$1" --help 2>&1) + case ${help,,} in + *slackware*) + fname=_makepkg_slackware + ;; + *) + fname=_minimal + ;; + esac + + unset -f _makepkg_bootstrap + complete -F $fname makepkg + $fname +} && + complete -F _makepkg_bootstrap makepkg + +# ex: filetype=sh diff --git a/completions/man b/completions/man new file mode 100644 index 0000000..81d06f5 --- /dev/null +++ b/completions/man @@ -0,0 +1,101 @@ +# man(1) completion -*- shell-script -*- + +_man() +{ + local cur prev words cword split + _init_completion -s -n : || return + + local comprsuffix=".@([glx]z|bz2|lzma|Z)" + local manext="@([0-9lnp]|[0-9][px]|man|3?(gl|pm))?($comprsuffix)" + local mansect="@([0-9lnp]|[0-9][px]|3?(gl|pm))" + + case $prev in + --config-file | -!(-*)C) + _filedir conf + return + ;; + --local-file | -!(-*)l) + _filedir "$manext" + return + ;; + --manpath | -!(-*)M) + _filedir -d + return + ;; + --pager | -!(-*)P) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + --preprocessor | -!(-*)p) + COMPREPLY=($(compgen -W 'e p t g r v' -- "$cur")) + return + ;; + --locale | --systems | --extension | --prompt | --recode | --encoding | \ + -!(-*)[LmerRE]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1" -h) + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + # file based completion if parameter looks like a path + if [[ $cur == @(*/|[.~])* ]]; then + _filedir "$manext" + return + fi + + local manpath=$(manpath 2>/dev/null || command man -w 2>/dev/null) + [[ -z $manpath ]] && manpath="/usr/share/man:/usr/local/share/man" + + # determine manual section to search + local sect + # shellcheck disable=SC2053 + [[ $prev == $mansect ]] && sect=$prev || sect='*' + + _expand || return + + manpath=$manpath: + if [[ -n $cur ]]; then + manpath="${manpath//://*man$sect/$cur* } ${manpath//://*cat$sect/$cur* }" + else + manpath="${manpath//://*man$sect/ } ${manpath//://*cat$sect/ }" + fi + + local IFS=$' \t\n' reset=$(shopt -p failglob) + shopt -u failglob + # redirect stderr for when path doesn't exist + COMPREPLY=($(eval command ls "$manpath" 2>/dev/null)) + $reset + + if ((${#COMPREPLY[@]} != 0)); then + # weed out directory path names and paths to man pages + COMPREPLY=(${COMPREPLY[@]##*/?(:)}) + # strip suffix from man pages + COMPREPLY=(${COMPREPLY[@]%$comprsuffix}) + COMPREPLY=($(compgen -W '${COMPREPLY[@]%.*}' -- "${cur//\\\\/}")) + fi + + # shellcheck disable=SC2053 + if [[ $prev != $mansect ]]; then + # File based completion for the rest, prepending ./ if needed + # (man 1.6f needs that for man pages in current dir) + local i start=${#COMPREPLY[@]} + _filedir "$manext" + for ((i = start; i < ${#COMPREPLY[@]}; i++)); do + [[ ${COMPREPLY[i]} == */* ]] || COMPREPLY[i]=./${COMPREPLY[i]} + done + fi + + __ltrim_colon_completions "$cur" +} && + complete -F _man man apropos whatis + +# ex: filetype=sh diff --git a/completions/mc b/completions/mc new file mode 100644 index 0000000..cf38821 --- /dev/null +++ b/completions/mc @@ -0,0 +1,29 @@ +# bash completion for mc -*- shell-script -*- + +_mc() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --edit | --view | --ftplog | --printwd | -!(-*)[evlP]) + _filedir + return + ;; + --help | --help-* | --version | --colors | --debuglevel | -!(-*)[hVCD]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --help-all)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _filedir -d + fi +} && + complete -F _mc mc + +# ex: filetype=sh diff --git a/completions/mcrypt b/completions/mcrypt new file mode 100644 index 0000000..0c3ab5e --- /dev/null +++ b/completions/mcrypt @@ -0,0 +1,67 @@ +# mcrypt(1) completion -*- shell-script -*- +# by Ariel Fermani <the_end@bbs.frc.utn.edu.ar> + +_mcrypt() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -g | --openpgp-z) + COMPREPLY=($(compgen -W '{0..9}' -- "$cur")) + return + ;; + -o | --keymode) + COMPREPLY=($(compgen -W '$($1 --list-keymodes 2>/dev/null )' \ + -- "$cur")) + return + ;; + -m | --mode) + COMPREPLY=($(compgen -W "$($1 --list 2>/dev/null | cut -d: -f2-)" \ + -- "$cur")) + return + ;; + -a | --algorithm) + COMPREPLY=($(compgen -W "$($1 --list 2>/dev/null | + awk '{print $1}')" -- "$cur")) + return + ;; + -h | --hash) + COMPREPLY=($(compgen -W '$($1 --list-hash 2>/dev/null | \ + command sed -e 1d)' -- "$cur")) + return + ;; + -k | -s | --key | --keysize) + return + ;; + -f | -c | --keyfile | --config) + _filedir + return + ;; + --algorithms-directory | --modes-directory) + _filedir -d + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + elif [[ ${words[0]} == mdecrypt ]]; then + _filedir nc + else + local i decrypt=0 + for ((i = 1; i < ${#words[@]} - 1; i++)); do + if [[ ${words[i]} == -@(d|-decrypt) ]]; then + _filedir nc + decrypt=1 + break + fi + done + if ((decrypt == 0)); then + _filedir + fi + fi +} && + complete -F _mcrypt mcrypt mdecrypt + +# ex: filetype=sh diff --git a/completions/mdadm b/completions/mdadm new file mode 100644 index 0000000..37effd9 --- /dev/null +++ b/completions/mdadm @@ -0,0 +1,149 @@ +# bash completion for mdadm -*- shell-script -*- + +_mdadm_raid_level() +{ + local mode + + for ((i = 1; i < cword; i++)); do + case ${words[i]} in + -!(-*)C* | --create) + mode=create + break + ;; + -!(-*)B* | --build) + mode=build + break + ;; + esac + done + + case $mode in + create) + COMPREPLY=($(compgen -W 'linear raid0 0 stripe raid1 1 mirror + raid4 4 raid5 5 raid6 6 raid10 10 multipath mp faulty' \ + -- "$cur")) + ;; + build) + COMPREPLY=($(compgen -W 'linear stripe raid0 0 raid1 multipath mp + faulty' -- "$cur")) + ;; + esac +} + +_mdadm_raid_layout() +{ + local level + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == -@(l|-level) ]]; then + level=${words[i + 1]} + break + fi + done + + case $level in + raid5) + COMPREPLY=($(compgen -W 'left-asymmetric left-symmetric + right-asymmetric right-symmetric la ra ls rs' -- "$cur")) + ;; + raid10) + COMPREPLY=($(compgen -W 'n o p' -- "$cur")) + ;; + faulty) + COMPREPLY=($(compgen -W 'write-transient wt read-transient rt + write-persistent wp read-persistent rp write-all read-fixable + rf clear flush none' -- "$cur")) + ;; + esac +} + +_mdadm_auto_flag() +{ + COMPREPLY=($(compgen -W 'no yes md mdp part p' -- "$cur")) +} + +_mdadm_update_flag() +{ + COMPREPLY=($(compgen -W 'sparc2.2 summaries uuid name homehost resync + byteorder super-minor' -- "$cur")) +} + +_mdadm() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --config | --bitmap | --backup-file | -!(-*)[cb]) + _filedir + return + ;; + --level | -!(-*)l) + _mdadm_raid_level + return + ;; + --layout | --parity | -!(-*)p) + _mdadm_raid_layout + return + ;; + --auto | -!(-*)a) + _mdadm_auto_flag + return + ;; + --update | -!(-*)U) + _mdadm_update_flag + return + ;; + esac + + $split && return + + local options='--help --help-options --version --verbose --quiet --brief + --force --config= --scan --metadata= --homehost=' + + if [[ $cur == -* ]]; then + if ((cword == 1)); then + COMPREPLY=($(compgen -W "$options --assemble --build --create + --monitor --grow" -- "$cur")) + else + case ${words[cword - 1]} in + --assemble | -!(-*)A*) + COMPREPLY=($(compgen -W "$options --uuid= --super-minor= + --name= --force --run --no-degraded --auto= --bitmap= + --backup-file= --update= --auto-update-homehost" \ + -- "$cur")) + ;; + --build | --create | --grow | -!(-*)[BCG]*) + COMPREPLY=($(compgen -W "$options --raid-devices= + --spare-devices= --size= --chunk= --rounding= --level= + --layout= --parity= --bitmap= --bitmap-chunk= + --write-mostly --write-behind= --assume-clean + --backup-file= --name= --run --force --auto=" \ + -- "$cur")) + ;; + --follow | --monitor | -!(-*)F) + COMPREPLY=($(compgen -W "$options --mail --program + --alert --syslog --delay --daemonise --pid-file + --oneshot --test" -- "$cur")) + + ;; + /dev/* | --add | --fail | --remove) + COMPREPLY=($(compgen -W "$options --add --re-add + --remove --fail --set-faulty" -- "$cur")) + ;; + *) + COMPREPLY=($(compgen -W "$options --query --detail + --examine --sparc2.2 --examine-bitmap --run --stop + --readonly --readwrite --zero-superblock --test" \ + -- "$cur")) + ;; + esac + fi + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + cur=${cur:=/dev/} + _filedir + fi +} && + complete -F _mdadm mdadm + +# ex: filetype=sh diff --git a/completions/mdtool b/completions/mdtool new file mode 100644 index 0000000..428e33b --- /dev/null +++ b/completions/mdtool @@ -0,0 +1,62 @@ +# mdtool completion -*- shell-script -*- + +_mdtool() +{ + local cur prev words cword + _init_completion || return + + local command i + + for ((i = 1; i < ${#words[@]} - 1; i++)); do + if [[ ${words[i]} == @(build|generate-makefiles|setup) ]]; then + command=${words[i]} + break + fi + done + + if [[ -v command ]]; then + case $command in + "build") + COMPREPLY=($(compgen -W '--f --buildfile --p --project' \ + -S":" -- "$cur")) + # TODO: This does not work :( + #if [[ "$prev" == *: ]]; then + # case $prev in + # @(--p:|--project:)) + # COMPREPLY=( $(compgen -f -G "*.mdp" -- "$cur") ) + # ;; + # @(--f:|--buildfile:)) + # COMPREPLY=( $(compgen -f -G "*.mdp" -G "*.mds" -- "$cur") ) + # ;; + # esac + #fi + return + ;; + "generate-makefiles") + compopt -o filenames + COMPREPLY=($(compgen -o filenames -G"*.mds" -- "$cur")) + if [[ $prev == *mds ]]; then + COMPREPLY=($(compgen -W '--simple-makefiles --s --d:' \ + -- "$cur")) + fi + return + ;; + "setup") + # TODO: at least return filenames after these options. + COMPREPLY=($(compgen -W 'install i uninstall u check-install + ci update up list l list-av la list-update lu rep-add ra + rep-remove rr rep-update ru rep-list rl reg-update + reg-build rgu info rep-build rb pack p help h dump-file' \ + -- "$cur")) + return + ;; + esac + fi + + COMPREPLY=($(compgen -W 'gsetup build dbgen project-export + generate-makefiles gettext-update setup -q' -- "$cur")) + +} && + complete -F _mdtool mdtool + +# ex: filetype=sh diff --git a/completions/medusa b/completions/medusa new file mode 100644 index 0000000..4512987 --- /dev/null +++ b/completions/medusa @@ -0,0 +1,30 @@ +# bash completion for medusa -*- shell-script -*- + +_medusa() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*h) + _known_hosts_real -- "$cur" + return + ;; + -*[HUPCO]) + _filedir + return + ;; + -*M) + COMPREPLY=($(compgen -W "$($1 -d | awk '/^ +\+/ {print $2}' | + command sed -e 's/\.mod$//')")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + fi +} && + complete -F _medusa medusa + +# ex: filetype=sh diff --git a/completions/mii-diag b/completions/mii-diag new file mode 100644 index 0000000..c433a7a --- /dev/null +++ b/completions/mii-diag @@ -0,0 +1,26 @@ +# mii-diag(8) completion -*- shell-script -*- + +_mii_diag() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -F | -A | --advertise | --fixed-speed) + COMPREPLY=($(compgen -W '100baseT4 100baseTx 100baseTx-FD + 100baseTx-HD 10baseT 10baseT-FD 10baseT-HD' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + _available_interfaces -a + fi +} && + complete -F _mii_diag -o default mii-diag + +# ex: filetype=sh diff --git a/completions/mii-tool b/completions/mii-tool new file mode 100644 index 0000000..1b80202 --- /dev/null +++ b/completions/mii-tool @@ -0,0 +1,32 @@ +# mii-tool(8) completion -*- shell-script -*- + +_mii_tool() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --force | -!(-*)F) + COMPREPLY=($(compgen -W '100baseTx-FD 100baseTx-HD 10baseT-FD + 10baseT-HD' -- "$cur")) + return + ;; + --advertise | -!(-*)A) + COMPREPLY=($(compgen -W '100baseT4 100baseTx-FD 100baseTx-HD + 10baseT-FD 10baseT-HD' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _available_interfaces -a + fi +} && + complete -F _mii_tool -o default mii-tool + +# ex: filetype=sh diff --git a/completions/minicom b/completions/minicom new file mode 100644 index 0000000..57510e9 --- /dev/null +++ b/completions/minicom @@ -0,0 +1,40 @@ +# bash completion for minicom -*- shell-script -*- + +_minicom() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --attrib | --color | -!(-*)[ac]) + COMPREPLY=($(compgen -W 'on off' -- "$cur")) + return + ;; + --script | --capturefile | -!(-*)[SC]) + _filedir + return + ;; + --ptty | -!(-*)p) + COMPREPLY=($(printf '%s\n' /dev/tty*)) + COMPREPLY=($(compgen -W '${COMPREPLY[@]} ${COMPREPLY[@]#/dev/}' \ + -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + COMPREPLY=( + $(printf '%s\n' /etc/minirc.* /etc/minicom/minirc.* ~/.minirc.* | + command sed -e '/\*$/d' -e 's/^.*minirc\.//' | + command grep "^${cur}")) +} && + complete -F _minicom -o default minicom + +# ex: filetype=sh diff --git a/completions/mkinitrd b/completions/mkinitrd new file mode 100644 index 0000000..bcb7e07 --- /dev/null +++ b/completions/mkinitrd @@ -0,0 +1,50 @@ +# bash completion for mkinitrd -*- shell-script -*- + +_mkinitrd() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --preload | --with | --builtin) + _modules + return + ;; + --fstab | --dsdt) + _filedir + return + ;; + --net-dev) + _available_interfaces + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--version --help -v -f --preload \ + --force-scsi-probe --omit-scsi-modules \ + --omit-ide-modules --image-version --force-raid-probe \ + --omit-raid-modules --with= --force-lvm-probe \ + --omit-lvm-modules --builtin --omit-dmraid --net-dev \ + --fstab --nocompress --dsdt --bootchart' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + local args + _count_args + + case $args in + 1) + _filedir + ;; + 2) + _kernel_versions + ;; + esac + fi + +} && + complete -F _mkinitrd mkinitrd + +# ex: filetype=sh diff --git a/completions/mktemp b/completions/mktemp new file mode 100644 index 0000000..e063810 --- /dev/null +++ b/completions/mktemp @@ -0,0 +1,29 @@ +# mktemp(1) completion -*- shell-script -*- + +_mktemp() +{ + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + --help | --version | --suffix) + return + ;; + --tmpdir | -!(-*)p) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1") + [[ $opts ]] || opts="-d -u -q -p -t" # non-GNU fallback + COMPREPLY=($(compgen -W "$opts" -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _mktemp mktemp + +# ex: filetype=sh diff --git a/completions/mmsitepass b/completions/mmsitepass new file mode 100644 index 0000000..49daae6 --- /dev/null +++ b/completions/mmsitepass @@ -0,0 +1,15 @@ +# mailman mmsitepass completion -*- shell-script -*- + +_mmsitepass() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--listcreator --help' -- "$cur")) + fi + +} && + complete -F _mmsitepass mmsitepass + +# ex: filetype=sh diff --git a/completions/modinfo b/completions/modinfo new file mode 100644 index 0000000..009bcf3 --- /dev/null +++ b/completions/modinfo @@ -0,0 +1,47 @@ +# Linux modinfo(8) completion -*- shell-script -*- + +_modinfo() +{ + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + --field | -!(-*)F) + COMPREPLY=($(compgen -W 'alias author depends description + filename firmware license parm srcversion staging vermagic + version' -- "${cur,,}")) + return + ;; + --set-version | -!(-*)k) + _kernel_versions + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + local i version=$(uname -r) + for ((i = ${#words[@]} - 1; i > 0; i--)); do + if [[ ${words[i]} == -@(!(-*)k*|-set-version) ]]; then + version=${words[i + 1]} + break + fi + done + + # do filename completion if we're giving a path to a module + if [[ $cur == @(*/|[.~])* ]]; then + _filedir '@(?(k)o?(.[gx]z))' + else + _modules $version + fi +} && + complete -F _modinfo modinfo + +# ex: filetype=sh diff --git a/completions/modprobe b/completions/modprobe new file mode 100644 index 0000000..36cb588 --- /dev/null +++ b/completions/modprobe @@ -0,0 +1,123 @@ +# Linux modprobe(8) completion -*- shell-script -*- + +_modprobe() +{ + local cur prev words cword split + _init_completion -s || return + + case "$prev" in + --help | --version | -!(-*)[hV]) + return + ;; + --config | -!(-*)C) + _filedir + return + ;; + --dirname | --type | -!(-*)[dt]) + _filedir -d + return + ;; + --set-version | -!(-*)S) + _kernel_versions + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + if [[ ! ${COMPREPLY-} ]]; then + COMPREPLY=($(compgen -W '-a --all -b --use-blacklist -C --config + -c --showconfig --dump-modversions -d --dirname --first-time + --force-vermagic --force-modversion -f --force -i + --ignore-install --ignore-remove -l --list -n --dry-run -q + --quiet -R --resolve-alias -r --remove -S --set-version + --show-depends -s --syslog -t --type -V --version -v + --verbose' -- "$cur")) + fi + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + local i mode=insert module="" version=$(uname -r) + for ((i = 1; i < cword; i++)); do + case "${words[i]}" in + --remove | -!(-*)r*) + mode=remove + ;; + --list | -!(-*)l*) + mode=list + ;; + --dump-modversions) + mode="file" + ;; + --set-version | -!(-*)S) + version=${words[i + 1]} # -S is not $prev and not $cur + ;; + --config | --dirname | --type | -!(-*)[Cdt]) + ((i++)) # skip option and its argument + ;; + -*) + # skip all other options + ;; + *) + [[ -z $module ]] && module=${words[i]} + ;; + esac + done + + case $mode in + remove) + _installed_modules "$cur" + ;; + list) + # no completion available + ;; + file) + _filedir + ;; + insert) + # do filename completion if we're giving a path to a module + if [[ $cur == @(*/|[.~])* ]]; then + _filedir '@(?(k)o?(.[gx]z))' + elif [[ -n $module ]]; then + # do module parameter completion + if [[ $cur == *=* ]]; then + prev=${cur%%=*} + cur=${cur#*=} + if PATH="$PATH:/sbin" modinfo -p "$module" 2>/dev/null | + command grep -q "^$prev:.*(bool)"; then + local choices="on off" + [[ $cur ]] && choices="1 0 y Y n N on off" + COMPREPLY=($(compgen -W "$choices" -- "$cur")) + fi + else + COMPREPLY=($(compgen -S = -W "$(PATH="$PATH:/sbin" \ + modinfo -p "$module" 2>/dev/null | + awk -F: '!/^[ \t]/ { print $1 }')" -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi + else + _modules $version + if [[ ${COMPREPLY-} ]]; then + # filter out already installed modules + local -a mods=("${COMPREPLY[@]}") + _installed_modules "$cur" + for i in "${!mods[@]}"; do + for module in "${COMPREPLY[@]}"; do + if [[ ${mods[i]} == "$module" ]]; then + unset 'mods[i]' + break + fi + done + done + COMPREPLY=("${mods[@]}") + fi + fi + ;; + esac +} && + complete -F _modprobe modprobe + +# ex: filetype=sh diff --git a/completions/monodevelop b/completions/monodevelop new file mode 100644 index 0000000..1c5b5ba --- /dev/null +++ b/completions/monodevelop @@ -0,0 +1,19 @@ +# monodevelop completion -*- shell-script -*- + +_monodevelop() +{ + local cur prev words cword split + _init_completion -s || return + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _filedir + fi +} && + complete -F _monodevelop monodevelop + +# ex: filetype=sh diff --git a/completions/mplayer b/completions/mplayer new file mode 100644 index 0000000..d71ebb8 --- /dev/null +++ b/completions/mplayer @@ -0,0 +1,287 @@ +# mplayer(1) completion -*- shell-script -*- + +_mplayer_options_list() +{ + cur=${cur%\\} + COMPREPLY=($(compgen -W "$($1 -noconfig all $2 help 2>/dev/null | + command sed -e '/^Available/,/^$/!d' -e '/^Available/d' | awk '{print $1}' | + command sed -e 's/:$//' -e 's/^'${2#-}'$//' -e 's/<.*//')" -- "$cur")) +} + +_mplayer() +{ + local cur prev words cword + _init_completion -n : || return + + local cmd=${words[0]} i j k=0 + + case $prev in + -[av][cfo] | -[av]fm | -vop | -fstype | -demuxer | -o[av]c | -of | -profile | \ + -audio-demuxer | -sub-demuxer) + _mplayer_options_list $cmd $prev + return + ;; + -show-profile) + _mplayer_options_list $cmd -profile + return + ;; + -audiofile | -audio-file) + _filedir '@(mp3|mpg|og[ag]|w?(a)v|mid|flac|mka|ac3|ape)' + return + ;; + -font | -subfont) + if [[ $prev == -font ]]; then + _filedir '@(desc|ttf)' + else + _filedir ttf + fi + local IFS=$'\n' + COMPREPLY+=($(compgen -W '$(fc-list 2>/dev/null)' -- "$cur")) + return + ;; + -sub | -sub-file) + _filedir '@(srt|sub|txt|utf|rar|mpsub|smi|js|ssa|ass)' + return + ;; + -vobsub) + _filedir '@(idx|ifo|sub)' + local IFS=$'\n' + COMPREPLY=($(for i in "${COMPREPLY[@]}"; do + if [[ -f $i && -r $i ]]; then + printf '%s\n' ${i%.*} + else + printf '%s\n' $i + fi + done)) + return + ;; + -subcp | -msgcharset) + local cp + cp=($(iconv --list 2>/dev/null | command sed -e "s@//@@;" 2>/dev/null)) + if [[ $cur == "${cur,,}" ]]; then + COMPREPLY=($(compgen -W '${cp[@],,}' -- "$cur")) + else + COMPREPLY=($(compgen -W '${cp[@]^^}' -- "$cur")) + fi + return + ;; + -ifo) + _filedir ifo + return + ;; + -cuefile) + _filedir '@(bin|cue)' + return + ;; + -skin) + # if you don't have installed mplayer in /usr you + # may want to set the MPLAYER_SKINS_DIR global variable + local -a dirs + if [[ -n $MPLAYER_SKINS_DIR ]]; then + dirs=($MPLAYER_SKINS_DIR) + else + dirs=(/usr/share/mplayer/skins /usr/local/share/mplayer/skins) + fi + + local IFS=$'\n' + for i in ~/.mplayer/skins "${dirs[@]}"; do + if [[ -d $i && -r $i ]]; then + for j in $(compgen -d -- $i/$cur); do + COMPREPLY[k++]=${j#$i/} + done + fi + done + return + ;; + -cdrom-device) + _cd_devices + _dvd_devices + return + ;; + -dvd-device) + _dvd_devices + _filedir iso + return + ;; + -bluray-device) + _filedir -d + return + ;; + -mixer | -dvdauth | -fb | -zrdev) + cur=${cur:=/dev/} + _filedir + return + ;; + -edl | -edlout | -lircconf | -menu-cfg | -playlist | -csslib | -dumpfile | \ + -subfile | -aofile | -fbmodeconfig | -include | -o | -dvdkey | -passlogfile) + _filedir + return + ;; + -autoq | -autosync | -loop | -menu-root | -speed | -sstep | -aid | -alang | \ + -bandwidth | -bluray-angle | -bluray-chapter | -cache | -chapter | -dvd-speed | \ + -dvdangle | -fps | -frames | -mc | -passwd | -user | -sb | -srate | -ss | -vcd | \ + -vi | -vid | -vivo | -ffactor | -sid | -slang | -spualign | -spuaa | -spugauss | \ + -vobsubid | -delay | -bpp | -brightness | -contrast | -dfbopts | -display | \ + -fbmode | -geometry | -guiwid | -hue | -icelayer | -screen[wh] | -wid | \ + -monitor-dotclock | -monitor-[hv]freq | -panscan | \ + -saturation | -xineramascreen | -zrcrop | -zrnorm | -zrquality | \ + -zr[xy]doff | -zr[vh]dec | -pp | -x | -y | -xy | -z | -stereo | \ + -audio-density | -audio-delay | -audio-preload | -endpos | -osdlevel | \ + -ffourcc | -sws | -skiplimit | -format | -ofps | -aadriver | \ + -aaosdcolor | -aasubcolor | -vobsubout | -vobsuboutid | -vobsuboutindex | \ + -sub-bg-alpha | -sub-bg-color | -subdelay | -subfps | -subpos | \ + -subalign | -subwidth | -subfont-blur | -subfont-outline | \ + -subfont-autoscale | -subfont-encoding | -subfont-osd-scale | \ + -subfont-text-scale) + return + ;; + -channels) + COMPREPLY=($(compgen -W '2 4 6 8' -- "$cur")) + return + ;; + -aspect | -monitoraspect) + COMPREPLY=($(compgen -W '1:1 3:2 4:3 5:4 14:9 14:10 16:9 16:10 + 2.35:1' -- "$cur")) + __ltrim_colon_completions "$cur" + return + ;; + -lavdopts) + COMPREPLY=($(compgen -W 'bitexact bug= debug= ec= er= fast gray + idct= lowres= sb= st= skiploopfilter= skipidct= skipframe= + threads= vismv= vstats' -- "$cur")) + return + ;; + -lavcopts) + COMPREPLY=($(compgen -W 'vcodec= vqmin= vqscale= vqmax= mbqmin= + mbqmax= vqdiff= vmax_b_frames= vme= vhq v4mv keyint= + vb_strategy= vpass= aspect= vbitrate= vratetol= vrc_maxrate= + vrc_minrate= vrc_buf_size= vb_qfactor= vi_qfactor= vb_qoffset= + vi_qoffset= vqblur= vqcomp= vrc_eq= vrc_override= + vrc_init_cplx= vqsquish= vlelim= vcelim= vstrict= vdpart + vpsize= gray vfdct= idct= lumi_mask= dark_mask= tcplx_mask= + scplx_mask= naq ildct format= pred qpel precmp= cmp= subcmp= + predia= dia= trell last_pred= preme= subq= psnr mpeg_quant aic + umv' -- "$cur")) + return + ;; + -ssf) + COMPREPLY=($(compgen -W 'lgb= cgb= ls= cs= chs= cvs=' -- "$cur")) + return + ;; + -jpeg) + COMPREPLY=($(compgen -W 'noprogressive progressive nobaseline + baseline optimize= smooth= quality= outdir=' -- "$cur")) + return + ;; + -xvidopts) + COMPREPLY=($(compgen -W 'dr2 nodr2' -- "$cur")) + return + ;; + -xvidencopts) + COMPREPLY=($(compgen -W 'pass= bitrate= fixed_quant= me_quality= + 4mv rc_reaction_delay_factor= rc_averaging_period= rc_buffer= + quant_range= min_key_interval= max_key_interval= mpeg_quant + mod_quant lumi_mask hintedme hintfile debug keyframe_boost= + kfthreshold= kfreduction=' -- "$cur")) + return + ;; + -divx4opts) + COMPREPLY=($(compgen -W 'br= key= deinterlace q= min_quant= + max_quant= rc_period= rc_reaction_period= crispness= + rc_reaction_ratio= pass= vbrpass= help' -- "$cur")) + return + ;; + -info) + COMPREPLY=($(compgen -W 'name= artist= genre= subject= + copyright= srcform= comment= help' -- "$cur")) + return + ;; + -lameopts) + COMPREPLY=($(compgen -W 'vbr= abr cbr br= q= aq= ratio= vol= + mode= padding= fast preset= help' -- "$cur")) + return + ;; + -rawaudio) + COMPREPLY=($(compgen -W 'on channels= rate= samplesize= format=' \ + -- "$cur")) + return + ;; + -rawvideo) + COMPREPLY=($(compgen -W 'on fps= sqcif qcif cif 4cif pal ntsc w= + h= y420 yv12 yuy2 y8 format= size=' -- "$cur")) + return + ;; + -aop) + COMPREPLY=($(compgen -W 'list= delay= format= fout= volume= mul= + softclip' -- "$cur")) + return + ;; + -dxr2) + COMPREPLY=($(compgen -W 'ar-mode= iec958-encoded iec958-decoded + mute ucode= 75ire bw color interlaced macrovision= norm= + square-pixel ccir601-pixel cr-left= cr-right= cr-top= cr-bot= + ck-rmin= ck-gmin= ck-bmin= ck-rmax= ck-gmax= ck-bmax= ck-r= + ck-g= ck-b= ignore-cache= ol-osd= olh-cor= olw-cor= olx-cor= + oly-cor= overlay overlay-ratio= update-cache' -- "$cur")) + return + ;; + -tv) + COMPREPLY=($(compgen -W 'on noaudio driver= device= input= freq= + outfmt= width= height= buffersize= norm= channel= chanlist= + audiorate= forceaudio alsa amode= forcechan= adevice= audioid= + volume= bass= treble= balance= fps= channels= immediatemode=' \ + -- "$cur")) + return + ;; + -mf) + COMPREPLY=($(compgen -W 'on w= h= fps= type=' -- "$cur")) + return + ;; + -cdda) + COMPREPLY=($(compgen -W 'speed= paranoia= generic-dev= + sector-size= overlap= toc-bias toc-offset= skip noskip' \ + -- "$cur")) + return + ;; + -input) + COMPREPLY=($(compgen -W 'conf= ar-delay ar-rate keylist cmdlist + js-dev file' -- "$cur")) + return + ;; + -af-adv) + COMPREPLY=($(compgen -W 'force= list=' -- "$cur")) + return + ;; + -noconfig) + COMPREPLY=($(compgen -W 'all gui system user' -- "$cur")) + return + ;; + -*) + # Assume arg is required for everything else except options + # for which -list-options says Type is Flag or Print. + $cmd -noconfig all -list-options 2>/dev/null | + while read -r i j k; do + if [[ $i == "${prev#-}" ]]; then + [[ ${j,,} != @(flag|print) ]] && return 1 + break + fi + done || return + ;; + esac + + case $cur in + -*) + COMPREPLY=($(compgen -W '$($cmd -noconfig all -list-options 2>/dev/null | \ + command sed -ne "1,/^[[:space:]]*Name/d" \ + -e "s/^[[:space:]]*/-/" -e "s/[[:space:]:].*//" \ + -e "/^-\(Total\|.*\*\)\{0,1\}$/!p")' -- "$cur")) + ;; + *) + _filedir '@(m?(j)p?(e)g|M?(J)P?(E)G|wm[av]|WM[AV]|avi|AVI|asf|ASF|vob|VOB|bin|BIN|dat|DAT|vcd|VCD|ps|PS|pes|PES|fl[iv]|FL[IV]|fxm|FXM|viv|VIV|rm?(j)|RM?(J)|ra?(m)|RA?(M)|yuv|YUV|mov|MOV|qt|QT|mp[234]|MP[234]|m?(p)4[av]|M?(P)4[AV]|og[gmavx]|OG[GMAVX]|w?(a)v|W?(A)V|dump|DUMP|mk[av]|MK[AV]|aac|AAC|m2v|M2V|dv|DV|rmvb|RMVB|mid|MID|t[ps]|T[PS]|3g[p2]|3gpp?(2)|mpc|MPC|flac|FLAC|vro|VRO|divx|DIVX|aif?(f)|AIF?(F)|m2t?(s)|M2T?(S)|mts|MTS|vdr|VDR|xvid|XVID|ape|APE|gif|GIF|nut|NUT|bik|BIK|web[am]|WEB[AM]|amr|AMR|awb|AWB|iso|ISO|opus|OPUS|m[eo]d|M[EO]D|xm|XM|it|IT|s[t3]m|S[T3]M|mtm|MTM|w64|W64)?(.@(crdownload|part))' + ;; + esac + +} && + complete -F _mplayer mplayer mplayer2 mencoder gmplayer kplayer + +# ex: filetype=sh diff --git a/completions/mr b/completions/mr new file mode 100644 index 0000000..930e3c9 --- /dev/null +++ b/completions/mr @@ -0,0 +1,91 @@ +# mr completion -*- shell-script -*- + +_mr() +{ + local cur prev words cword + _init_completion || return + + local help commands options + + help="$(PERLDOC_PAGER=cat PERLDOC=-otext "${1}" help 2>/dev/null)" + + commands="$( + printf %s "$help" | while read -r _ options cmd _; do + [[ $options != "[options]" ]] || printf "%s\n" "$cmd" + done + )" + # Split [online|offline] and remove `action` placeholder. + commands="${commands//@(action|[\[\|\]])/$'\n'}" + # Add standard aliases. + commands="${commands} ci co ls" + + # Determine if user has entered an `mr` command. Used to block top-level + # (option and command) completions. + local cmd i + for ((i = 1; i < ${#words[@]} - 1; i++)); do + if [[ $commands == *"${words[i]}"* ]]; then + cmd="${words[i]}" + break + fi + done + + # Complete options for specific commands. + if [[ -v cmd ]]; then + case $cmd in + bootstrap) + _filedir + # Also complete stdin (-) as a potential bootstrap source. + if [[ -z ${cur} || $cur == - ]] && [[ $prev != - ]]; then + COMPREPLY+=(-) + fi + return + ;; + clean) + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W '-f' -- "${cur}")) + fi + return + ;; + commit | ci | record) + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W '-m' -- "${cur}")) + fi + return + ;; + run) + COMPREPLY=($(compgen -c -- "${cur}")) + return + ;; + *) + # Do not complete any other command. + return + ;; + esac + fi + + # Complete top-level options and commands. + case $prev in + --config | -!(-*)c) + _filedir + return + ;; + --directory | -!(-*)d) + _filedir -d + return + ;; + esac + + if [[ $cur == -* ]]; then + options="$(printf '%s\n' "$help" | _parse_help -)" + # Remove short options (all have compatible long options). + options="${options//-[a-z]$'\n'/}" + # Remove deprecated options. + options="${options//--path/}" + COMPREPLY=($(compgen -W "${options}" -- "${cur}")) + else + COMPREPLY=($(compgen -W "${commands}" -- "${cur}")) + fi +} && + complete -F _mr mr + +# ex: filetype=sh diff --git a/completions/msynctool b/completions/msynctool new file mode 100644 index 0000000..4de37f5 --- /dev/null +++ b/completions/msynctool @@ -0,0 +1,42 @@ +# bash completion for msynctool -*- shell-script -*- + +_msynctool() +{ + local cur prev words cword + _init_completion || return + + case $words in + --configure) + COMPREPLY=($(compgen -W "$($1 --showgroup \ + $prev | awk '/^Member/ {print $2}' | command sed \ + -e 's/:$//')" -- "$cur")) + return + ;; + --addmember) + COMPREPLY=($(compgen -W '$($1 --listplugins \ + | command sed -e 1d)' -- "$cur")) + return + ;; + esac + + case $prev in + --configure | --addgroup | --delgroup | --showgroup | --sync | --addmember) + COMPREPLY=($(compgen -W '$($1 --listgroups \ + | command sed -e 1d)' -- "$cur")) + return + ;; + --showformats | --filter-objtype | --slow-sync) + COMPREPLY=($(compgen -W '$($1 --listobjects \ + | command sed -e 1d)' -- "$cur")) + return + ;; + esac + + COMPREPLY=($(compgen -W '--listgroups --listplugins --listobjects + --showformats --showgroup --sync --filter-objtype --slow-sync --wait + --multi --addgroup --delgroup --addmember --configure --manual + --configdir --conflict' -- "$cur")) +} && + complete -F _msynctool msynctool + +# ex: filetype=sh diff --git a/completions/mtx b/completions/mtx new file mode 100644 index 0000000..b5c270b --- /dev/null +++ b/completions/mtx @@ -0,0 +1,44 @@ +# mtx completion -*- shell-script -*- +# by Jon Middleton <jjm@ixtab.org.uk> + +_mtx() +{ + local cur prev words cword + _init_completion || return + + local options tapes drives + + options="-f nobarcode invert noattach --version inquiry noattach \ + inventory status load unload eepos first last next" + + tapes=$(mtx status 2>/dev/null | + awk '/Storage Element [0-9]+:Full/ { printf "%s ", $3 }') + tapes=${tapes//:Full/} + + drives=$(mtx status 2>/dev/null | + awk '/Data Transfer Element [0-9]+:(Full|Empty)/ { printf "%s ", $4 }') + drives=${drives//:Full/} + drives=${drives//:Empty/} + + if ((cword > 1)); then + case $prev in + load) + COMPREPLY=($(compgen -W "$tapes" -- "$cur")) + ;; + unload | first | last | next) + COMPREPLY=($(compgen -W "$drives" -- "$cur")) + ;; + -f) + true + ;; + *) + true + ;; + esac + else + COMPREPLY=($(compgen -W "$options" -- "$cur")) + fi +} && + complete -F _mtx mtx + +# ex: filetype=sh diff --git a/completions/munin-node-configure b/completions/munin-node-configure new file mode 100644 index 0000000..39d8d64 --- /dev/null +++ b/completions/munin-node-configure @@ -0,0 +1,33 @@ +# munin-node-configure completion -*- shell-script -*- + +_munin_node_configure() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --config) + _filedir + return + ;; + --servicedir | --libdir) + _filedir -d + return + ;; + --snmp) + _known_hosts_real -- "$cur" + return + ;; + --snmpversion) + COMPREPLY=($(compgen -W '1 2c 3' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + fi +} && + complete -F _munin_node_configure munin-node-configure + +# ex: filetype=sh diff --git a/completions/munin-run b/completions/munin-run new file mode 100644 index 0000000..97e526a --- /dev/null +++ b/completions/munin-run @@ -0,0 +1,28 @@ +# munin-run completion -*- shell-script -*- + +_munin_run() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --config | --sconffile) + _filedir + return + ;; + --servicedir | --sconfdir) + _filedir -d + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + COMPREPLY=($(compgen -W \ + '$(command ls /etc/munin/plugins 2>/dev/null)' -- "$cur")) + fi +} && + complete -F _munin_run munin-run + +# ex: filetype=sh diff --git a/completions/munin-update b/completions/munin-update new file mode 100644 index 0000000..8766eae --- /dev/null +++ b/completions/munin-update @@ -0,0 +1,27 @@ +# munin-update completion -*- shell-script -*- + +_munin_update() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --config) + _filedir + return + ;; + --host) + _known_hosts_real -- "$cur" + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--force-root --noforce-root --service --host + --config --help --debug --nodebug --fork --nofork --stdout + --nostdout --timeout' -- "$cur")) + fi +} && + complete -F _munin_update munin-update + +# ex: filetype=sh diff --git a/completions/munindoc b/completions/munindoc new file mode 100644 index 0000000..5c7644a --- /dev/null +++ b/completions/munindoc @@ -0,0 +1,13 @@ +# munindoc completion -*- shell-script -*- + +_munindoc() +{ + local cur prev words cword + _init_completion || return + + COMPREPLY=($(compgen -W \ + '$(command ls /usr/share/munin/plugins 2>/dev/null)' -- "$cur")) +} && + complete -F _munindoc munindoc + +# ex: filetype=sh diff --git a/completions/mussh b/completions/mussh new file mode 100644 index 0000000..c2f7a52 --- /dev/null +++ b/completions/mussh @@ -0,0 +1,52 @@ +# mussh(1) completion -*- shell-script -*- + +_mussh() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | -V | -m | -t) + return + ;; + -d) + COMPREPLY=($(compgen -W '{0..2}' -- "$cur")) + return + ;; + -v) + COMPREPLY=($(compgen -W '{0..3}' -- "$cur")) + return + ;; + -i | -H | -C) + _filedir + return + ;; + -o | -po) + _xfunc ssh _ssh_options + return + ;; + -l | -L) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + -s) + _shells + return + ;; + -p | -h) + [[ $cur == *@* ]] && _user_at_host || _known_hosts_real -a -- "$cur" + return + ;; + -c) + compopt -o filenames + COMPREPLY+=($(compgen -c -- "$cur")) + return + ;; + esac + + [[ $cur != -* ]] || + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _mussh mussh + +# ex: filetype=sh diff --git a/completions/mutt b/completions/mutt new file mode 100644 index 0000000..1161487 --- /dev/null +++ b/completions/mutt @@ -0,0 +1,160 @@ +# mutt completion -*- shell-script -*- +# +# Mutt doesn't have an "addressbook" like Pine, but it has aliases and +# a "query" function to retrieve addresses, so that's what we use here. + +# @param $1 (cur) Current word to complete +_muttaddr() +{ + _muttaliases "$1" + _muttquery "$1" + + COMPREPLY+=($(compgen -u -- "$1")) +} + +# Find muttrc to use +# @output muttrc filename +_muttrc() +{ + # Search COMP_WORDS for '-F muttrc' or '-Fmuttrc' argument + set -- "${words[@]}" + while (($# > 0)); do + if [[ $1 == -F* ]]; then + if ((${#1} > 2)); then + muttrc="$(dequote "${1:2}")" + else + shift + [[ $1 ]] && muttrc="$(dequote "$1")" + fi + break + fi + shift + done + + if [[ ! -v muttrc ]]; then + if [[ -f ~/.${muttcmd}rc ]]; then + muttrc=\~/.${muttcmd}rc + elif [[ -f ~/.${muttcmd}/${muttcmd}rc ]]; then + muttrc=\~/.${muttcmd}/${muttcmd}rc + fi + fi + printf "%s" "${muttrc-}" +} + +# Recursively build list of sourced config files +# @param $1 List of config files found so far +# @param $2 Config file to process +# @output List of config files +_muttconffiles() +{ + local file sofar + local -a newconffiles + + sofar=" $1 " + shift + while [[ ${1-} ]]; do + newconffiles=($(command sed -n 's|^source[[:space:]]\{1,\}\([^[:space:]]\{1,\}\).*$|\1|p' "$(eval printf %s $1)")) + for file in ${newconffiles+"${newconffiles[@]}"}; do + __expand_tilde_by_ref file + [[ ! -f $file || $sofar == *\ $file\ * ]] && continue + sofar+=" $file" + sofar=" $(eval _muttconffiles \"$sofar\" $file) " + done + shift + done + printf '%s\n' $sofar +} + +# @param $1 (cur) Current word to complete +_muttaliases() +{ + local cur=$1 muttrc muttcmd=${words[0]} + local -a conffiles aliases + + muttrc=$(_muttrc) + [[ -z $muttrc ]] && return + + conffiles=($(eval _muttconffiles $muttrc $muttrc)) + # shellcheck disable=SC2046 + aliases=("$(command sed -n 's|^alias[[:space:]]\{1,\}\([^[:space:]]\{1,\}\).*$|\1|p' \ + $(eval echo "${conffiles[@]}"))") + COMPREPLY+=($(compgen -W "${aliases[*]}" -- "$cur")) +} + +# @param $1 (cur) Current word to complete +_muttquery() +{ + local cur=$1 querycmd muttcmd=${words[0]} + local -a queryresults + + querycmd="$($muttcmd -Q query_command 2>/dev/null | command sed -e 's|^query_command=\"\(.*\)\"$|\1|' -e 's|%s|'$cur'|')" + if [[ -z $cur || -z $querycmd ]]; then + queryresults=() + else + __expand_tilde_by_ref querycmd + queryresults=($($querycmd | + command sed -n '2,$s|^\([^[:space:]]\{1,\}\).*|\1|p')) + fi + + COMPREPLY+=($(compgen -W "${queryresults[*]}" -- "$cur")) +} + +# @param $1 (cur) Current word to complete +_muttfiledir() +{ + local cur=$1 folder muttrc spoolfile muttcmd=${words[0]} + + muttrc=$(_muttrc) + if [[ $cur == [=+]* ]]; then + folder="$($muttcmd -F "$muttrc" -Q folder 2>/dev/null | command sed -e 's|^folder=\"\(.*\)\"$|\1|')" + : folder:=~/Mail + + # Match any file in $folder beginning with $cur + # (minus the leading '=' sign). + compopt -o filenames + COMPREPLY=($(compgen -f -- "$folder/${cur:1}")) + COMPREPLY=(${COMPREPLY[@]#$folder/}) + return + elif [[ $cur == !* ]]; then + spoolfile="$($muttcmd -F "$muttrc" -Q spoolfile 2>/dev/null | + command sed -e 's|^spoolfile=\"\(.*\)\"$|\1|')" + [[ -n $spoolfile ]] && eval cur="${cur/^!/$spoolfile}" + fi + _filedir +} + +_mutt() +{ + local cur prev words cword + _init_completion -n =+! || return + + case $cur in + -*) + COMPREPLY=($(compgen -W '-A -a -b -c -e -f -F -H -i -m -n -p -Q -R -s + -v -x -y -z -Z -h' -- "$cur")) + return + ;; + *) + case $prev in + -*[afFHi]) + _muttfiledir "$cur" + return + ;; + -*A) + _muttaliases "$cur" + return + ;; + -*[emQshpRvyzZ]) + return + ;; + *) + _muttaddr "$cur" + return + ;; + esac + ;; + esac +} && + complete -F _mutt -o default mutt muttng + +# ex: filetype=sh diff --git a/completions/mypy b/completions/mypy new file mode 100644 index 0000000..534d575 --- /dev/null +++ b/completions/mypy @@ -0,0 +1,57 @@ +# mypy completion -*- shell-script -*- + +_mypy() +{ + local cur prev words cword split + _init_completion -s || return + + [[ $cword -gt 2 && ${words[cword - 2]} == --shadow-file ]] && + prev=--shadow-file # hack; takes two args + + case $prev in + --help | --version | --python-version | --platform | --always-true | \ + --always-false | --find-occurrences | --package | --command | -!(-*)[hVpc]) + return + ;; + --config-file) + _filedir + return + ;; + --follow-imports) + COMPREPLY=($(compgen -W 'normal silent skip error' -- "$cur")) + return + ;; + --python-executable) + COMPREPLY=($(compgen -c -- "${cur:-py}")) + return + ;; + --*-dir | --*-report) + _filedir -d + return + ;; + --custom-typing | --module | -!(-*)m) + _xfunc python _python_modules + return + ;; + --shadow-file) + _filedir '@(py|pyi)' + return + ;; + --junit-xml) + _filedir xml + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + _filedir '@(py|pyi)' +} && + complete -F _mypy mypy + +# ex: filetype=sh diff --git a/completions/mysql b/completions/mysql new file mode 100644 index 0000000..9363133 --- /dev/null +++ b/completions/mysql @@ -0,0 +1,99 @@ +# mysql(1) completion -*- shell-script -*- + +_mysql_character_sets() +{ + local IFS=$' \t\n' reset=$(shopt -p failglob) + shopt -u failglob + local -a charsets=(/usr/share/m{ariadb,ysql}/charsets/*.xml) + $reset + charsets=("${charsets[@]##*/}") + charsets=("${charsets[@]%%?(Index|\*).xml}" utf8) + COMPREPLY+=($(compgen -W '${charsets[@]}' -- "$cur")) +} + +_mysql() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --user | -!(-*)u) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + --database | -!(-*)D) + COMPREPLY=($(compgen -W "$(mysqlshow 2>/dev/null | command sed -ne '2d' -e 's/^|.\([^|]*\)|.*/\1/p')" -- "$cur")) + return + ;; + + --host | -!(-*)h) + _known_hosts_real -- "$cur" + return + ;; + --default-character-set) + _mysql_character_sets + return + ;; + + --character-sets-dir | --ssl-capath) + _filedir -d + return + ;; + --socket | -!(-*)S) + _filedir sock + return + ;; + --protocol) + COMPREPLY=($(compgen -W 'tcp socket pipe memory' -- "$cur")) + return + ;; + --defaults-file | --defaults-extra-file | --tee) + _filedir + return + ;; + --ssl-ca | --ssl-cert) + _filedir '@(pem|cer|c?(e)rt)' + return + ;; + --ssl-key) + _filedir '@(pem|key)' + return + ;; + --port | --set-variable | --ssl-cipher | --connect_timeout | \ + --max_allowed_packet | --prompt | --net_buffer_length | --select_limit | \ + --max_join_size | --server-arg | --debug | --delimiter | --execute | --pager | \ + -!(-*)[Pe]) + return + ;; + --help | --version | -!(-*)[?IV]) + return + ;; + esac + + $split && return + + case $cur in + --*) + local help=$(_parse_help "$1") + help+=" --skip-comments --skip-ssl" + + COMPREPLY=($(compgen -W "$help" -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + ;; + + # only complete long options + -) + compopt -o nospace + COMPREPLY=(--) + return + ;; + esac + + COMPREPLY=($(compgen -W \ + "$(mysqlshow 2>/dev/null | command sed -ne '2d' -e 's/^|.\([^|]*\)|.*/\1/p')" \ + -- "$cur")) +} && + complete -F _mysql mysql + +# ex: filetype=sh diff --git a/completions/mysqladmin b/completions/mysqladmin new file mode 100644 index 0000000..5329534 --- /dev/null +++ b/completions/mysqladmin @@ -0,0 +1,63 @@ +# bash completion for mysqladmin -*- shell-script -*- + +_mysqladmin() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --user | -!(-*)u) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + --host | -!(-*)h) + _known_hosts_real -- "$cur" + return + ;; + --character-sets-dir | --ssl-capath) + _filedir -d + return + ;; + --default-character-set) + _xfunc mysql _mysql_character_sets + return + ;; + --socket | -!(-*)S) + _filedir sock + return + ;; + --defaults-file | --defaults-extra-file) + _filedir + return + ;; + --ssl-ca | --ssl-cert) + _filedir '@(pem|cer|c?(e)rt)' + return + ;; + --ssl-key) + _filedir '@(pem|key)' + return + ;; + --count | --port | --set-variable | --sleep | --ssl-cipher | --wait | \ + --connect_timeout | --shutdown_timeout | -!(-*)[cPOiw]) + return + ;; + --help | --version | -!(-*)[?V]) + return + ;; + esac + + $split && return + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + + COMPREPLY+=($(compgen -W 'create debug drop extended-status flush-hosts + flush-logs flush-status flush-tables flush-threads flush-privileges + kill password old-password ping processlist reload refresh shutdown + status start-slave stop-slave variables version' -- "$cur")) + + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace +} && + complete -F _mysqladmin mysqladmin + +# ex: filetype=sh diff --git a/completions/nc b/completions/nc new file mode 100644 index 0000000..6fb0994 --- /dev/null +++ b/completions/nc @@ -0,0 +1,51 @@ +# nc(1) completion -*- shell-script -*- + +_nc() +{ + local cur prev words cword + _init_completion -n : || return + + case $prev in + -*[hIiMmOPpqVWw]) + return + ;; + -*s) + if [[ ${words[*]} == *-6* ]]; then + _ip_addresses -6 + __ltrim_colon_completions "$cur" + else + _ip_addresses + fi + return + ;; + -*T) + COMPREPLY=($(compgen -W 'critical inetcontrol lowcost lowdelay + netcontrol throughput reliability ef af{11..43} cs{0..7}' \ + -- "$cur")) + return + ;; + -*X) + COMPREPLY=($(compgen -W '4 5 connect' -- "$cur")) + return + ;; + -*x) + _known_hosts_real -- "$cur" + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + return + fi + + # Complete 1st non-option arg only + local args + _count_args "" "-*[IiMmOPpqsTVWwXx]" + ((args == 1)) || return + + _known_hosts_real -- "$cur" +} && + complete -F _nc nc + +# ex: filetype=sh diff --git a/completions/ncftp b/completions/ncftp new file mode 100644 index 0000000..c3f2cf1 --- /dev/null +++ b/completions/ncftp @@ -0,0 +1,27 @@ +# bash completion for ncftp -*- shell-script -*- + +_ncftp() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -u | -p | -P | -j | -F) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + return + fi + + if [[ $cword -eq 1 && -f ~/.ncftp/bookmarks ]]; then + COMPREPLY=($(compgen -W '$(command sed -ne "s/^\([^,]\{1,\}\),.*$/\1/p" \ + ~/.ncftp/bookmarks)' -- "$cur")) + fi + +} && + complete -F _ncftp -o default ncftp + +# ex: filetype=sh diff --git a/completions/nethogs b/completions/nethogs new file mode 100644 index 0000000..5cd3650 --- /dev/null +++ b/completions/nethogs @@ -0,0 +1,26 @@ +# bash completion for nethogs(8) -*- shell-script -*- + +_nethogs() +{ + local cur prev words cword + _init_completion || return + + case "$prev" in + -d) + # expect integer value + COMPREPLY+=($(compgen -W '{0..9}')) + compopt -o nospace + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" -h)' -- "$cur")) + return + fi + + _available_interfaces -a +} && + complete -F _nethogs nethogs + +# ex: filetype=sh diff --git a/completions/newlist b/completions/newlist new file mode 100644 index 0000000..f1f6cf8 --- /dev/null +++ b/completions/newlist @@ -0,0 +1,25 @@ +# mailman newlist completion -*- shell-script -*- + +_newlist() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -l | --language | -u | --urlhost | -e | --emailhost | --help) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _xfunc list_lists _mailman_lists + fi +} && + complete -F _newlist newlist + +# ex: filetype=sh diff --git a/completions/newusers b/completions/newusers new file mode 100644 index 0000000..890a5fc --- /dev/null +++ b/completions/newusers @@ -0,0 +1,30 @@ +# newusers(8) completion -*- shell-script -*- + +_newusers() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -c | --crypt) + COMPREPLY=($(compgen -W 'DES MD5 NONE SHA256 SHA512' -- "$cur")) + return + ;; + -s | --sha-rounds) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir +} && + complete -F _newusers newusers + +# ex: filetype=sh diff --git a/completions/ngrep b/completions/ngrep new file mode 100644 index 0000000..7d16c8d --- /dev/null +++ b/completions/ngrep @@ -0,0 +1,38 @@ +# ngrep(8) completion -*- shell-script -*- + +_ngrep() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h | -V | -n | -A | -s | -S | -c | -P) + return + ;; + -I | -O) + _filedir 'pcap?(ng)' + return + ;; + -d) + _available_interfaces -a + COMPREPLY+=($(compgen -W 'any' -- "$cur")) + return + ;; + -W) + COMPREPLY=($(compgen -W 'normal byline single none' -- "$cur")) + return + ;; + -F) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + return + fi +} && + complete -F _ngrep ngrep + +# ex: filetype=sh diff --git a/completions/nmap b/completions/nmap new file mode 100644 index 0000000..482148e --- /dev/null +++ b/completions/nmap @@ -0,0 +1,56 @@ +# bash completion for nmap -*- shell-script -*- + +_nmap() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -iL | -oN | -oX | -oS | -oG | ---excludefile | --resume | --stylesheet) + _filedir + return + ;; + -oA | --datadir) + _filedir -d + return + ;; + -e) + _available_interfaces -a + return + ;; + -b | --dns-servers) + _known_hosts_real -- "$cur" + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + # strip everything following a :, inclusive + # strip everything following a =, exclusive + # expand -X; -Y to -X -Y + # expand -X/-Y/-Z to -X -Y -Z + # expand -X/Y/Z to -X -Y -Z + # expand --foo/bar to --foo --bar + # strip everything following a non-option name or = char + # TODO: should expand -T<0-5> to -T0 ... -T5 + COMPREPLY=($(compgen -W "$( + "$1" --help 2>&1 | command sed \ + -e "s/:.*$//" \ + -e "s/=.*$/=/" \ + -e "s/;[[:space:]]*-/ -/g" \ + -e "s/\/-/ -/g" \ + -e "/^[[:space:]]*-[^-]/s/\/\([^-]\)/ -\1/g" \ + -e "/^[[:space:]]*--/s/\/\([^-]\)/ --\1/g" \ + -e "s/[^[:space:]a-zA-Z0-9=-].*$//" + )" \ + -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _known_hosts_real -- "$cur" + fi +} && + complete -F _nmap nmap + +# ex: filetype=sh diff --git a/completions/nproc b/completions/nproc new file mode 100644 index 0000000..50273f0 --- /dev/null +++ b/completions/nproc @@ -0,0 +1,23 @@ +# nproc(1) completion -*- shell-script -*- + +_nproc() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | --ignore) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _nproc nproc + +# ex: filetype=sh diff --git a/completions/nslookup b/completions/nslookup new file mode 100644 index 0000000..3341b1f --- /dev/null +++ b/completions/nslookup @@ -0,0 +1,86 @@ +# bash completion for nslookup -*- shell-script -*- + +_bind_queryclass() +{ + COMPREPLY+=($(compgen -W 'IN CH HS ANY' -- "$cur")) +} + +_bind_querytype() +{ + # https://en.wikipedia.org/wiki/List_of_DNS_record_types + COMPREPLY+=($(compgen -W 'A AAAA AFSDB APL CERT CNAME DHCID DLV DNAME + DNSKEY DS HIP IPSECKEY KEY KX LOC MX NAPTR NS NSEC NSEC3 NSEC3PARAM PTR + RRSIG RP SIG SOA SPF SRV SSHFP TXT' -- "$cur")) +} + +_nslookup() +{ + local cur prev words cword + _init_completion -n = || return + + case $cur in + -class=* | -cl=*) + cur=${cur#*=} + _bind_queryclass + return + ;; + -querytype=* | -type=* | -q=* | -ty=*) + cur=${cur#*=} + _bind_querytype + return + ;; + -?*=*) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-all -class= -debug -nodebug -d2 -nod2 + -domain= -search -nosearch -port= -querytype= -recurse -norecurse + -retry= -timeout= -vc -novc -fail -nofail' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + local args + _count_args = + if ((args <= 2)); then + _known_hosts_real -- "$cur" + [[ $args -eq 1 && $cur == @(|-) ]] && COMPREPLY+=(-) + fi +} && + complete -F _nslookup nslookup + +_host() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -c) + _bind_queryclass + return + ;; + -t) + _bind_querytype + return + ;; + -m) + COMPREPLY=($(compgen -W 'trace record usage' -- "$cur")) + return + ;; + -N | -R | -W) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + return + fi + + _known_hosts_real -- "$cur" +} && + complete -F _host host + +# ex: filetype=sh diff --git a/completions/nsupdate b/completions/nsupdate new file mode 100644 index 0000000..68df333 --- /dev/null +++ b/completions/nsupdate @@ -0,0 +1,40 @@ +# bash completion for nsupdate(1) -*- shell-script -*- + +_nsupdate() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*[VLprtu]) + return + ;; + -*k) + _filedir key + return + ;; + -*R) + cur=${cur:=/dev/} + _filedir + return + ;; + -*y) + if [[ $cur == h* ]]; then + COMPREPLY=($(compgen -W "hmac-{md5,sha{1,224,256,384,512}}" \ + -S : -- "$cur")) + [[ ${COMPREPLY-} == *: ]] && compopt -o nospace + fi + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + return + fi + + _filedir +} && + complete -F _nsupdate nsupdate + +# ex: filetype=sh diff --git a/completions/ntpdate b/completions/ntpdate new file mode 100644 index 0000000..f6ee8f5 --- /dev/null +++ b/completions/ntpdate @@ -0,0 +1,35 @@ +# bash completion for ntpdate -*- shell-script -*- + +_ntpdate() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*k) + _filedir + return + ;; + -*U) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + -*p) + COMPREPLY=($(compgen -W '{1..8}' -- "$cur")) + return + ;; + + -*[aeot]) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + else + _known_hosts_real -- "$cur" + fi +} && + complete -F _ntpdate ntpdate + +# ex: filetype=sh diff --git a/completions/oggdec b/completions/oggdec new file mode 100644 index 0000000..97bde20 --- /dev/null +++ b/completions/oggdec @@ -0,0 +1,38 @@ +# bash completion for oggdec(1) -*- shell-script -*- + +_oggdec() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | -!(-*)[hV]*) + return + ;; + --bits | -!(-*)b) + COMPREPLY=($(compgen -W "8 16" -- "$cur")) + return + ;; + --endianness | --sign | -!(-*)[es]) + COMPREPLY=($(compgen -W "0 1" -- "$cur")) + return + ;; + --output | -!(-*)o) + _filedir wav + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir ogg +} && + complete -F _oggdec oggdec + +# ex: filetype=sh diff --git a/completions/op b/completions/op new file mode 100644 index 0000000..31d6475 --- /dev/null +++ b/completions/op @@ -0,0 +1,59 @@ +# op (1Password CLI) completion -*- shell-script -*- + +_op_commands() +{ + "$@" --help 2>/dev/null | + awk '/^(Available |Sub)commands/{flag=1;next}/^ /&&flag{print $1}' +} + +_op_command_options() +{ + case $cur in + -*) + for i in "${!words[@]}"; do + [[ ${words[i]} == -* || $i -eq 0 ]] && unset "words[i]" + done + COMPREPLY=($(compgen -W \ + '$(_parse_usage "$1" "${words[*]} --help") --help' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return 0 + ;; + esac + return 1 +} + +_op() +{ + local cur prev words cword split + _init_completion -s || return + + local command i + for ((i = 1; i < cword; i++)); do + case ${words[i]} in + --help | --version) return ;; + -*) ;; + *) + command=${words[i]} + break + ;; + esac + done + + if [[ ! -v command && $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + [[ -v command ]] && _op_command_options "$1" && return + + if [[ ! -v command || $command == "$prev" ]]; then + COMPREPLY=($(compgen -W '$(_op_commands "$1" ${command-})' -- "$cur")) + [[ ${COMPREPLY-} ]] && return + fi + + # TODO specific command and subcommand completions +} && + complete -F _op op + +# ex: filetype=sh diff --git a/completions/openssl b/completions/openssl new file mode 100644 index 0000000..dd77092 --- /dev/null +++ b/completions/openssl @@ -0,0 +1,138 @@ +# bash completion for openssl -*- shell-script -*- + +_openssl_sections() +{ + local config f + + # check if a specific configuration file is used + for ((i = 2; i < cword; i++)); do + if [[ ${words[i]} == -config ]]; then + config=${words[i + 1]} + break + fi + done + + # if no config given, check some usual default locations + if [[ -z $config ]]; then + for f in /etc/ssl/openssl.cnf /etc/pki/tls/openssl.cnf \ + /usr/share/ssl/openssl.cnf; do + [[ -f $f ]] && config=$f && break + done + fi + + [[ ! -f $config ]] && return + + COMPREPLY=($(compgen -W "$(awk '/\[.*\]/ {print $2}' $config)" -- "$cur")) +} + +_openssl_digests() +{ + "$1" dgst -h 2>&1 | + awk '/^-.*[ \t]to use the .* message digest algorithm/ { print $1 }' + local -a digests=($("$1" help 2>&1 | + command sed -ne '/^Message Digest commands/,/^[[:space:]]*$/p' | + command sed -e 1d)) + printf "%s\n" "${digests[@]/#/-}" +} + +_openssl() +{ + local cur prev words cword + _init_completion || return + + local commands command options formats + + commands='asn1parse ca ciphers crl crl2pkcs7 dgst dh dhparam dsa dsaparam + ec ecparam enc engine errstr gendh gendsa genrsa nseq ocsp passwd + pkcs12 pkcs7 pkcs8 prime rand req rsa rsautl s_client s_server s_time + sess_id smime speed spkac verify version x509 md2 md4 md5 rmd160 sha + sha1 aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb aes-256-cbc + aes-256-ecb base64 bf bf-cbc bf-cfb bf-ecb bf-ofb camellia-128-cbc + camellia-128-ecb camellia-192-cbc camellia-192-ecb camellia-256-cbc + camellia-256-ecb cast cast-cbc cast5-cbc cast5-cfb cast5-ecb cast5-ofb + des des-cbc des-cfb des-ecb des-ede des-ede-cbc des-ede-cfb des-ede-ofb + des-ede3 des-ede3-cbc des-ede3-cfb des-ede3-ofb des-ofb des3 desx rc2 + rc2-40-cbc rc2-64-cbc rc2-cbc rc2-cfb rc2-ecb rc2-ofb rc4 rc4-40 + sha224 sha256 sha384 sha512 genpkey pkey pkeyparam pkeyutl' + + if ((cword == 1)); then + COMPREPLY=($(compgen -W "$commands" -- "$cur")) + else + command=${words[1]} + case $prev in + -CA | -CAfile | -CAkey | -CAserial | -cert | -certfile | -config | -content | \ + -dcert | -dkey | -dhparam | -extfile | -in | -inkey | -kfile | -key | -keyout | \ + -out | -oid | -paramfile | -peerkey | -prvrify | -rand | -recip | -revoke | \ + -sess_in | -sess_out | -spkac | -sigfile | -sign | -signkey | -signer | \ + -signature | -ss_cert | -untrusted | -verify | -writerand) + _filedir + return + ;; + -outdir | -CApath) + _filedir -d + return + ;; + -name | -crlexts | -extensions) + _openssl_sections + return + ;; + -inform | -outform | -keyform | -certform | -CAform | -CAkeyform | -dkeyform | \ + -dcertform | -peerform) + formats='DER PEM' + case $command in + x509) + formats+=" NET" + ;; + smime) + formats+=" SMIME" + ;; + pkeyutl) + formats+=" ENGINE" + ;; + esac + COMPREPLY=($(compgen -W "$formats" -- "$cur")) + return + ;; + -connect) + _known_hosts_real -- "$cur" + return + ;; + -starttls) + COMPREPLY=($(compgen -W ' + smtp pop3 imap ftp xmpp xmpp-server telnet irc mysql + postgres lmtp nntp sieve ldap + ' -- "$cur")) + return + ;; + -cipher) + COMPREPLY=($(IFS=: compgen -W "$($1 ciphers)" -- "$cur")) + return + ;; + -kdf) + COMPREPLY=($(compgen -W 'TLS1-PRF HKDF' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + # possible options for the command + options=$(_parse_help "$1" "$command -help" 2>/dev/null) + case $command in + dgst | req | x509) options+=" $(_openssl_digests $1)" ;; + esac + COMPREPLY=($(compgen -W "$options" -- "$cur")) + else + if [[ $command == speed ]]; then + COMPREPLY=($(compgen -W 'md2 mdc2 md5 hmac sha1 rmd160 + idea-cbc rc2-cbc rc5-cbc bf-cbc des-cbc des-ede3 rc4 + rsa512 rsa1024 rsa2048 rsa4096 dsa512 dsa1024 dsa2048 idea + rc2 des rsa blowfish' -- "$cur")) + else + _filedir + fi + fi + fi +} && + complete -F _openssl -o default openssl + +# ex: filetype=sh diff --git a/completions/opera b/completions/opera new file mode 100644 index 0000000..f2bc8c3 --- /dev/null +++ b/completions/opera @@ -0,0 +1,47 @@ +# opera(1) completion -*- shell-script -*- + +_opera() +{ + local cur prev words cword + _init_completion || return + + case "$prev" in + ?(-)-widget | ?(-)-urllist | ?(-)-uiparserlog | ?(-)-uiwidgetsparserlog | \ + ?(-)-profilinglog) + _filedir + return + ;; + ?(-)-[psb]d) + _filedir -d + return + ;; + ?(-)-remote) + COMPREPLY=($(compgen -W 'openURL\\( openFile\\( openM2\\( + openComposer\\( addBookmark\\( raise\\(\\) lower\\(\\)' \ + -- "$cur")) + [[ ${COMPREPLY-} == *\( ]] && compopt -o nospace + return + ;; + ?(-)-windowname) + COMPREPLY=($(compgen -W 'first last opera{1..9}' -- "$cur")) + return + ;; + ?(-)-geometry | ?(-)-window | ?(-)-display | ?(-)-urllistloadtimeout | \ + ?(-)-delaycustomizations | ?(-)-dialogtest | ?(-)-inidialogtest | \ + ?(-)-gputest) + # argument required but no completions available + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir '@(?([xX]|[sS])[hH][tT][mM]?([lL]))' +} && + complete -F _opera opera + +# ex: filetype=sh diff --git a/completions/optipng b/completions/optipng new file mode 100644 index 0000000..0f6b40e --- /dev/null +++ b/completions/optipng @@ -0,0 +1,52 @@ +# optipng(1) completion -*- shell-script -*- + +_optipng() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -'?' | -h | --help | -f) + return + ;; + -o) + COMPREPLY=($(compgen -W '{0..7}' -- "$cur")) + return + ;; + -out | -log) + _filedir + return + ;; + -dir) + _filedir -d + return + ;; + -i) + COMPREPLY=($(compgen -W '0 1' -- "$cur")) + return + ;; + -zc | -zm) + COMPREPLY=($(compgen -W '{1..9}' -- "$cur")) + return + ;; + -zw) + COMPREPLY=($(compgen -W '256 512 1k 2k 4k 8k 16k 32k' \ + -- "$cur")) + return + ;; + -strip) + COMPREPLY=($(compgen -W 'all' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + _filedir '@(png|bmp|gif|pnm|tif?(f))' +} && + complete -F _optipng optipng + +# ex: filetype=sh diff --git a/completions/p4 b/completions/p4 new file mode 100644 index 0000000..ed5f20c --- /dev/null +++ b/completions/p4 @@ -0,0 +1,51 @@ +# Perforce completion -*- shell-script -*- +# by Frank Cusack <frank@google.com> + +_p4() +{ + local cur prev words cword + _init_completion || return + + local p4commands p4filetypes + + # rename isn't really a command + p4commands="$(p4 help commands 2>/dev/null | awk 'NF>3 {print $1}')" + p4filetypes="ctext cxtext ktext kxtext ltext tempobj ubinary \ + uresource uxbinary xbinary xltext xtempobj xtext \ + text binary resource" + + if ((cword == 1)); then + COMPREPLY=($(compgen -W "$p4commands" -- "$cur")) + elif ((cword == 2)); then + case $prev in + help) + COMPREPLY=($(compgen -W "simple commands environment + filetypes jobview revisions usage views $p4commands" \ + -- "$cur")) + ;; + admin) + COMPREPLY=($(compgen -W "checkpoint stop" -- "$cur")) + ;; + *) ;; + + esac + elif ((cword > 2)); then + case $prev in + -t) + case ${words[cword - 2]} in + add | edit | reopen) + COMPREPLY=($(compgen -W "$p4filetypes" -- "$cur")) + ;; + *) ;; + + esac + ;; + *) ;; + + esac + fi + +} && + complete -F _p4 -o default p4 g4 + +# ex: filetype=sh diff --git a/completions/pack200 b/completions/pack200 new file mode 100644 index 0000000..1a6ded7 --- /dev/null +++ b/completions/pack200 @@ -0,0 +1,74 @@ +# pack200(1) completion -*- shell-script -*- + +_pack200() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -S | --segment-limit | -P | --pass-file | -C | --class-attribute | \ + -F | --field-attribute | -M | --method-attribute | -D | --code-attribute | \ + '-?' | -h | --help | -V | --version | -J) + return + ;; + -E | --effort) + COMPREPLY=($(compgen -W '{0..9}' -- "$cur")) + return + ;; + -H | --deflate-hint) + COMPREPLY=($(compgen -W 'true false keep' -- "$cur")) + return + ;; + -m | --modification-time) + COMPREPLY=($(compgen -W 'latest keep' -- "$cur")) + return + ;; + -U | --unknown-attribute) + COMPREPLY=($(compgen -W 'error strip pass' -- "$cur")) + return + ;; + -f | --config-file) + _filedir properties + return + ;; + -l | --log-file) + COMPREPLY=($(compgen -W '-' -- "$cur")) + _filedir log + return + ;; + -r | --repack) + _filedir jar + return + ;; + esac + + $split && return + + # Check if a pack or a jar was already given. + local i pack=false jar=false + for ((i = 1; i < ${#words[@]} - 1; i++)); do + case ${words[i]} in + *.pack | *.pack.gz) pack=true ;; + *.jar) jar=true ;; + esac + done + + if ! $pack; then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--no-gzip --gzip --strip-debug + --no-keep-file-order --segment-limit= --effort= --deflate-hint= + --modification-time= --pass-file= --unknown-attribute= + --class-attribute= --field-attribute= --method-attribute= + --code-attribute= --config-file= --verbose --quiet --log-file= + --help --version -J --repack' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _filedir 'pack?(.gz)' + fi + elif ! $jar; then + _filedir jar + fi +} && + complete -F _pack200 pack200 + +# ex: filetype=sh diff --git a/completions/passwd b/completions/passwd new file mode 100644 index 0000000..652a41e --- /dev/null +++ b/completions/passwd @@ -0,0 +1,24 @@ +# passwd(1) completion -*- shell-script -*- + +_passwd() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --minimum | --maximum | --warning | --inactive | --help | --usage | -!(-*)[nxwi?]) + return + ;; + esac + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + return + fi + + _allowed_users +} && + complete -F _passwd passwd + +# ex: filetype=sh diff --git a/completions/patch b/completions/patch new file mode 100644 index 0000000..e883d9c --- /dev/null +++ b/completions/patch @@ -0,0 +1,70 @@ +# patch(1) completion -*- shell-script -*- + +_patch() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --strip | --ifdef | --prefix | --basename-prefix | --suffix | --get | \ + -!(-*)[pDBYzg]) + return + ;; + --fuzz | -!(-*)F) + COMPREPLY=($(compgen -W '{0..3}' -- "$cur")) + return + ;; + --input | -!(-*)i) + _filedir '@(?(d)patch|dif?(f))' + return + ;; + --output | --reject-file | -!(-*)[or]) + [[ ! $cur || $cur == - ]] && COMPREPLY=(-) + _filedir + return + ;; + --quoting-style) + COMPREPLY=($(compgen -W 'literal shell shell-always c escape' \ + -- "$cur")) + return + ;; + --version-control | -!(-*)V) + COMPREPLY=($(compgen -W 'simple numbered existing' -- "$cur")) + return + ;; + --directory | -!(-*)d) + _filedir -d + return + ;; + --reject-format) + COMPREPLY=($(compgen -W 'context unified' -- "$cur")) + return + ;; + --read-only) + COMPREPLY=($(compgen -W 'ignore warn fail' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + local args + _count_args + case $args in + 1) + _filedir + ;; + 2) + _filedir '@(?(d)patch|dif?(f))' + ;; + esac +} && + complete -F _patch patch + +# ex: filetype=sh diff --git a/completions/pdftotext b/completions/pdftotext new file mode 100644 index 0000000..a3501ba --- /dev/null +++ b/completions/pdftotext @@ -0,0 +1,39 @@ +# bash completion for pdftotext(1) -*- shell-script -*- + +_pdftotext() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h | -help | --help | -'?' | -f | -l | -r | -x | -y | -W | -H | -fixed | -opw | -upw) + return + ;; + -enc) + COMPREPLY=($(compgen -W '$("$1" -listenc 2>/dev/null | + command sed -e 1d)' -- "$cur")) + return + ;; + -eol) + COMPREPLY=($(compgen -W "unix dos mac" -- "$cur")) + return + ;; + esac + + if [[ $cur == -* && ${prev,,} != *.pdf ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + case ${prev,,} in + - | *.txt) ;; + *.pdf) + COMPREPLY=($(compgen -W '-' -- "$cur")) + _filedir txt + ;; + *) _filedir pdf ;; + esac +} && + complete -F _pdftotext pdftotext + +# ex: filetype=sh diff --git a/completions/perl b/completions/perl new file mode 100644 index 0000000..9823d73 --- /dev/null +++ b/completions/perl @@ -0,0 +1,146 @@ +# bash completion for perl -*- shell-script -*- + +_perl_helper() +{ + COMPREPLY=($(compgen -P "$prefix" -W \ + "$(${2:-perl} ${BASH_SOURCE[0]%/*}/../helpers/perl $1 $cur)" \ + -- "$cur")) + [[ $1 == functions ]] || __ltrim_colon_completions "$prefix$cur" +} + +_perl() +{ + local cur prev words cword + _init_completion -n : || return + + local prefix="" temp optPrefix optSuffix + + # If option not followed by whitespace, reassign prev and cur + if [[ $cur == -?* ]]; then + temp=$cur + prev=${temp:0:2} + cur=${temp:2} + if [[ $prev == -d && $cur == t* ]]; then + prev=-dt + cur=${cur:1} + fi + optPrefix=-P$prev + optSuffix=-S/ + prefix=$prev + + case $prev in + -*[DeEiFl]) + return + ;; + -*[Ix]) + local IFS=$'\n' + compopt -o filenames + COMPREPLY=($(compgen -d $optPrefix $optSuffix -- "$cur")) + return + ;; + -*[mM]) + temp="${cur#-}" + prefix+="${cur%$temp}" + cur="$temp" + _perl_helper modules $1 + return + ;; + -*V) + if [[ $cur == :* ]]; then + temp="${cur##+(:)}" + prefix+="${cur%$temp}" + local IFS=$'\n' + COMPREPLY=($(compgen -P "$prefix" -W \ + '$($1 -MConfig -e "print join \"\\n\", + keys %Config::Config" 2>/dev/null)' -- "$temp")) + __ltrim_colon_completions "$prefix$temp" + fi + return + ;; + -*d | -*dt) + if [[ $cur == :* ]]; then + temp="${cur#:}" + prefix="$prefix${cur%$temp}" + cur="Devel::$temp" + _perl_helper modules $1 + fi + ;; + esac + + # Unlike other perl options, having a space between the `-e' and + # `-E' options and their arguments, e.g. `perl -e "exit 2"', is + # valid syntax. However, the argument is neither a filename nor a + # directory, but one line of perl program, thus do not suggest + # _filedir completion. + elif [[ $prev == -e ]] || [[ $prev == -E ]]; then + return + + # Likewise, `-I' also accepts a space between option and argument + # and it takes a directory as value. + elif [[ $prev == -I ]]; then + local IFS=$'\n' + compopt -o filenames + COMPREPLY=($(compgen -d ${optPrefix-} ${optSuffix-} -- "$cur")) + return + + elif [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-C -s -T -u -U -W -X -h -v -V -c -w -d -D -p + -n -a -F -l -0 -I -m -M -P -S -x -i -e' -- "$cur")) + else + _filedir + fi +} && + complete -F _perl perl + +_perldoc() +{ + local cur prev words cword + _init_completion -n : || return + + local prefix="" temp + + # completing an option (may or may not be separated by a space) + if [[ $cur == -?* ]]; then + temp=$cur + prev=${temp:0:2} + cur=${temp:2} + prefix=$prev + fi + + local perl="${1%doc}" + [[ $perl == "$1" ]] || ! type $perl &>/dev/null && perl= + + case $prev in + -*[hVnoMwL]) + return + ;; + -*d) + _filedir + return + ;; + -*f) + _perl_helper functions $perl + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + else + # return available modules (unless it is clearly a file) + if [[ $cur != @(*/|[.~])* ]]; then + _perl_helper perldocs $perl + if [[ $cur == p* ]]; then + COMPREPLY+=($(compgen -W \ + '$(PERLDOC_PAGER=cat "$1" -u perl | \ + command sed -ne "/perl.*Perl overview/,/perlwin32/p" | \ + awk "\$NF=2 && \$1 ~ /^perl/ { print \$1 }")' \ + -- "$cur")) + fi + fi + _filedir 'p@([lm]|od)' + fi +} && + complete -F _perldoc -o bashdefault perldoc + +# ex: filetype=sh diff --git a/completions/perlcritic b/completions/perlcritic new file mode 100644 index 0000000..7843549 --- /dev/null +++ b/completions/perlcritic @@ -0,0 +1,51 @@ +# perlcritic(1) completion -*- shell-script -*- + +_perlcritic() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | --top | --include | --exclude | --single-policy | \ + --colo?(u)r-severity-* | --program-extensions | -[?HVs]) + return + ;; + --severity) + COMPREPLY=($(compgen -W "{1..5} brutal cruel harsh stern gentle" \ + -- "$cur")) + return + ;; + --profile | -p) + _filedir perlcriticrc + return + ;; + --theme) + COMPREPLY=($(compgen -W '$("$1" --list-themes 2>/dev/null)' \ + -- "$cur")) + return + ;; + --profile-strictness) + COMPREPLY=($(compgen -W 'warn fatal quiet' -- "$cur")) + return + ;; + --verbose) + COMPREPLY=($(compgen -W '{1..11}' -- "$cur")) + return + ;; + --pager) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + return + fi + + _filedir 'p[lm]' +} && + complete -F _perlcritic perlcritic + +# ex: filetype=sh diff --git a/completions/perltidy b/completions/perltidy new file mode 100644 index 0000000..4404cf8 --- /dev/null +++ b/completions/perltidy @@ -0,0 +1,55 @@ +# perltidy(1) completion -*- shell-script -*- + +_perltidy() +{ + local cur prev words cword + _init_completion -n = || return + + case $prev in + -h | --help) + return + ;; + -o) + _filedir + return + ;; + esac + + case $cur in + -pro=*) + cur="${cur#*=}" + _filedir + return + ;; + -ole=*) + COMPREPLY=($(compgen -W 'dos win mac unix' -- "${cur#*=}")) + return + ;; + -bt=* | -pt=* | -sbt=* | -bvt=* | -pvt=* | -sbvt=* | -bvtc=* | -pvtc=* | -sbvtc=* | \ + -cti=* | -kbl=* | -vt=*) + COMPREPLY=($(compgen -W '0 1 2' -- "${cur#*=}")) + return + ;; + -vtc=*) + COMPREPLY=($(compgen -W '0 1' -- "${cur#*=}")) + return + ;; + -cab=*) + COMPREPLY=($(compgen -W '0 1 2 3' -- "${cur#*=}")) + return + ;; + -*=) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _filedir 'p[lm]|t' + fi +} && + complete -F _perltidy perltidy + +# ex: filetype=sh diff --git a/completions/pgrep b/completions/pgrep new file mode 100644 index 0000000..62dbb65 --- /dev/null +++ b/completions/pgrep @@ -0,0 +1,62 @@ +# pgrep(1) and pkill(1) completion -*- shell-script -*- + +_pgrep() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --delimiter | --pgroup | --session | --terminal | -!(-*)[cdgJMNstTz]) + return + ;; + --signal) + _signals + return + ;; + --pidfile | -!(-*)F) + _filedir + return + ;; + --group | -!(-*)G) + _gids + return + ;; + -j) + COMPREPLY=($(compgen -W 'any none' -- "$cur")) + return + ;; + --parent | --ns | -!(-*)P) + _pids + return + ;; + --euid | --uid | -!(-*)[uU]) + _uids + return + ;; + --nslist) + local prefix= + [[ $cur == *,* ]] && prefix="${cur%,*}," + COMPREPLY=( + $(IFS="$IFS," compgen -W '$($1 --help 2>&1 | + command sed -ne "s/^[[:space:]]*Available namespaces://p")' \ + -- "${cur##*,}")) + ((${#COMPREPLY[@]} == 1)) && COMPREPLY=(${COMPREPLY/#/$prefix}) + return + ;; + esac + + if [[ $cur == -* ]]; then + local help=$(_parse_help "$1") + [[ $help ]] || help='$("$1" --usage 2>&1 | + command sed -e "s/\[-signal\]//" -e "s/\[-SIGNAL\]//" | + _parse_usage -)' + COMPREPLY=($(compgen -W "$help" -- "$cur")) + [[ $cword -eq 1 && $1 == *pkill ]] && _signals - + return + fi + + _pnames -s +} && + complete -F _pgrep pgrep pkill + +# ex: filetype=sh diff --git a/completions/pidof b/completions/pidof new file mode 100644 index 0000000..a11b432 --- /dev/null +++ b/completions/pidof @@ -0,0 +1,27 @@ +# pidof(8) completion -*- shell-script -*- + +_pidof() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | -V | --version | -!(-*)[hV]*) + return + ;; + --omit-pid | -!(-*)o) + _pids + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + _pnames +} && + complete -F _pidof pidof + +# ex: filetype=sh diff --git a/completions/pine b/completions/pine new file mode 100644 index 0000000..319c8d5 --- /dev/null +++ b/completions/pine @@ -0,0 +1,32 @@ +# pine/alpine completion -*- shell-script -*- + +_pine() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -help | -d | -f | -c | -I | -n | -url | -copy_pinerc | -copy_abook) + return + ;; + -attach | -attachlist | -attach_and_delete | -p | -P | -pinerc | -passfile | -x) + _filedir + return + ;; + -sort) + COMPREPLY=($(compgen -W 'arrival subject threaded orderedsubject + date from size score to cc' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + else + COMPREPLY=($(compgen -W '$(awk "{print \$1}" ~/.addressbook \ + 2>/dev/null)' -- "$cur")) + fi +} && + complete -F _pine pine alpine + +# ex: filetype=sh diff --git a/completions/ping b/completions/ping new file mode 100644 index 0000000..446f026 --- /dev/null +++ b/completions/ping @@ -0,0 +1,71 @@ +# ping(8) completion -*- shell-script -*- + +_ping() +{ + local cur prev words cword + _init_completion -n = || return + + local ipvx + + case $prev in + -*[cFGghilmPpstVWwz]) + return + ;; + -*I) + _available_interfaces -a + return + ;; + -*M) + # Path MTU strategy in Linux, mask|time in FreeBSD + local opts="do want dont" + [[ $OSTYPE == *bsd* ]] && opts="mask time" + COMPREPLY=($(compgen -W '$opts' -- "$cur")) + return + ;; + -*N) + if [[ $cur != *= ]]; then + COMPREPLY=($(compgen -W 'name ipv6 ipv6-global ipv6-sitelocal + ipv6-linklocal ipv6-all ipv4 ipv4-all subject-ipv6= + subject-ipv4= subject-name= subject-fqdn=' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi + return + ;; + -*Q) + # TOS in Linux, "somewhat quiet" (no args) in FreeBSD + if [[ $OSTYPE != *bsd* ]]; then + COMPREPLY=($(compgen -W '{0..7}' -- "$cur")) + return + fi + ;; + -*S) + # Socket sndbuf in Linux, source IP in FreeBSD + [[ $OSTYPE == *bsd* ]] && _ip_addresses + return + ;; + -*T) + # Timestamp option in Linux, TTL in FreeBSD + [[ $OSTYPE == *bsd* ]] || + COMPREPLY=($(compgen -W 'tsonly tsandaddr' -- "$cur")) + return + ;; + -*4*) + ipvx=-4 + ;; + -*6*) + ipvx=-6 + ;; + esac + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + return + fi + + [[ $1 == *6 ]] && ipvx=-6 + _known_hosts_real ${ipvx-} -- "$cur" +} && + complete -F _ping ping ping6 + +# ex: filetype=sh diff --git a/completions/pkg-config b/completions/pkg-config new file mode 100644 index 0000000..b9db167 --- /dev/null +++ b/completions/pkg-config @@ -0,0 +1,45 @@ +# bash completion for pkgconfig -*- shell-script -*- + +_pkg_config() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --define-variable | --atleast-version | --atleast-pkgconfig-version | \ + --exact-version | --max-version) + # argument required but no completions available + return + ;; + --variable) + local word + for word in "${words[@]:1}"; do + if [[ $word != -* ]]; then + COMPREPLY=($(compgen -W \ + '$("$1" $word --print-variables 2>/dev/null)' \ + -- "$cur")) + break + fi + done + return + ;; + -\? | --help | --version | --usage) + # all other arguments are noop with these + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + COMPREPLY=($(compgen -W "$($1 --list-all \ + 2>/dev/null | awk '{print $1}')" -- "$cur")) + _filedir pc + fi +} && + complete -F _pkg_config pkg-config + +# ex: filetype=sh diff --git a/completions/pkg-get b/completions/pkg-get new file mode 100644 index 0000000..72bd0a0 --- /dev/null +++ b/completions/pkg-get @@ -0,0 +1,72 @@ +# pkg-get.completion completion -*- shell-script -*- +# +# Copyright 2006 Yann Rouillard <yann@opencsw.org> + +_pkg_get_get_catalog_file() +{ + local url="$1" + local catalog_file i conffile + + for file in /etc/opt/csw/pkg-get.conf /opt/csw/etc/pkg-get.conf /etc/pkg-get.conf; do + if [[ -f $file ]]; then + conffile="$file" + break + fi + done + conffile="${conffile:-/opt/csw/etc/pkg-get.conf}" + + if [[ -z $url ]]; then + url=$(awk -F= ' $1=="url" { print $2 }' $conffile) + fi + + catalog_file="${url##*//}" + catalog_file="${catalog_file%%/*}" + catalog_file="/var/pkg-get/catalog-$catalog_file" + + echo "$catalog_file" +} && + _pkg_get() + { + local cur prev file catalog_file url command + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD - 1]}" + + if [[ ${prev} == "-s" ]]; then + return 1 + fi + + local i=${#COMP_WORDS[*]} + while ((i > 0)); do + if [[ ${COMP_WORDS[--i]} == -s ]]; then + url="${COMP_WORDS[i + 1]}" + fi + if [[ ${COMP_WORDS[i]} == @(-[aDdiUu]|available|describe|download|install|list|updatecatalog|upgrade) ]]; then + command="${COMP_WORDS[i]}" + fi + done + + if [[ -v command ]]; then + if [[ $command == @(-[Ddi]|describe|download|install) ]]; then + catalog_file=$(_pkg_get_get_catalog_file "$url") + if [[ -f $catalog_file ]]; then + local packages_list=$(awk ' $0 ~ /BEGIN PGP SIGNATURE/ { exit } $1 ~ /^Hash:/ || $1 ~ /^ *(-|#|$)/ { next } { print $1 }' $catalog_file) + COMPREPLY=($(compgen -W "${packages_list}" -- ${cur})) + fi + fi + return + fi + + if [[ ${cur} == -* ]]; then + local opts="-c -d -D -f -i -l -s -S -u -U -v" + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + return + fi + + local commands="available describe download install list \ + updatecatalog upgrade" + COMPREPLY=($(compgen -W "${commands}" -- ${cur})) + } && + complete -F _pkg_get pkg-get + +# ex: filetype=sh diff --git a/completions/pkg_delete b/completions/pkg_delete new file mode 100644 index 0000000..2abb671 --- /dev/null +++ b/completions/pkg_delete @@ -0,0 +1,18 @@ +# bash completion for *BSD package management tools -*- shell-script -*- + +_pkg_delete() +{ + local cur prev words cword + _init_completion || return + + local pkgdir=${PKG_DBDIR:-/var/db/pkg}/ + + [[ $prev == -o || $prev == -p || $prev == -W ]] && return + + COMPREPLY=($(compgen -d -- "$pkgdir$cur")) + ((${#COMPREPLY[@]} == 0)) || COMPREPLY=(${COMPREPLY[@]#$pkgdir}) + +} && + complete -F _pkg_delete -o dirnames pkg_delete pkg_info pkg_deinstall + +# ex: filetype=sh diff --git a/completions/pkgadd b/completions/pkgadd new file mode 100644 index 0000000..3f5b6a1 --- /dev/null +++ b/completions/pkgadd @@ -0,0 +1,62 @@ +# pkgadd completion -*- shell-script -*- +# +# Copyright 2006 Yann Rouillard <yann@opencsw.org> + +_pkgadd() +{ + local cur prev words cword + _init_completion -n : || return + + # if a device directory was given + # we must complete with the package + # available in this directory + local device=/var/spool/pkg + local i=$cword + while ((i-- > 0)); do + case "${words[i]}" in + -d) + device="${words[i + 1]}" + break + ;; + esac + done + + case $prev in + -d) + _filedir pkg + _filedir -d + ;; + -a | -r | -V) + _filedir + ;; + -k | -s | -R) + _filedir -d + ;; + -P | -x) ;; + + *) + if [[ ${cur} == -* ]]; then + local opts="-a -A -d -k -n -M -P -r -R -s -v -V -x" + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + else + local pkginst_list + if [[ -d $device ]]; then + local -a tmplist + for filedir in $(/bin/ls -1 $device); do + if [[ -d "$device/$filedir" ]] && [[ -f "$device/$filedir/pkginfo" ]]; then + tmplist+=(${tmplist[@]:-} "$filedir") + fi + done + pkginst_list="${tmplist[*]}" + else + pkginst_list="$(strings "$(dequote $device)" | + command grep ^PKG= | sort -u | cut -d= -f2)" + fi + COMPREPLY=($(compgen -W "$pkginst_list" -- ${cur})) + fi + ;; + esac +} && + complete -F _pkgadd pkgadd + +# ex: filetype=sh diff --git a/completions/pkgrm b/completions/pkgrm new file mode 100644 index 0000000..2449d34 --- /dev/null +++ b/completions/pkgrm @@ -0,0 +1,46 @@ +# pkgrm completion -*- shell-script -*- +# +# Copyright 2006 Yann Rouillard <yann@opencsw.org> + +_pkgrm() +{ + local cur prev words cword + _init_completion || return + + # if a spool directory was given + # we must complete with the package + # available in this directory + local spool=/var/sadm/pkg + local i=$cword + while ((i-- > 0)); do + ((i--)) + case "${words[i]}" in + -s) + spool="${words[i + 1]}" + break + ;; + esac + done + + case $prev in + -a | -V) + _filedir + ;; + -s | -R) + _filedir -d + ;; + -Y) ;; + + *) + if [[ ${cur} == -* ]]; then + local opts="-a -A -n -M -R -s -v -V -Y" + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) + else + COMPREPLY=($(compgen -W "$(/bin/ls -1 $spool)" -- ${cur})) + fi + ;; + esac +} && + complete -F _pkgrm pkgrm + +# ex: filetype=sh diff --git a/completions/pkgtool b/completions/pkgtool new file mode 100644 index 0000000..951bae4 --- /dev/null +++ b/completions/pkgtool @@ -0,0 +1,35 @@ +# Slackware Linux pkgtool completion -*- shell-script -*- + +_pkgtool() +{ + local cur prev words cword + _init_completion || return + + case "$prev" in + --source_dir | --target_dir) + _filedir -d + return + ;; + --sets) + # argument required but no completions available + return + ;; + --source_device) + COMPREPLY=($(compgen -f -d -- "${cur:-/dev/}")) + return + ;; + --tagfile) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--sets --ignore-tagfiles --tagfile + --source-mounted --source_dir --target_dir --source_device' \ + -- "$cur")) + fi +} && + complete -F _pkgtool pkgtool + +# ex: filetype=sh diff --git a/completions/pkgutil b/completions/pkgutil new file mode 100644 index 0000000..91d8748 --- /dev/null +++ b/completions/pkgutil @@ -0,0 +1,95 @@ +# pkgutil completion -*- shell-script -*- +# Copyright 2006 Yann Rouillard <yann@opencsw.org> + +_pkgutil_url2catalog() +{ + local filename="$1" + + filename="${filename##*://}" + filename="${filename//\//_}" + filename="/var/opt/csw/pkgutil/catalog.${filename}_$(uname -p)_$(uname -r)" + + echo "$filename" +} + +_pkgutil() +{ + local cur prev words cword + _init_completion -n : || return + + local command catalog_files configuration_files + declare -a configuration_files=("/opt/csw/etc/pkgutil.conf" "/etc/opt/csw/pkgutil.conf") + declare -a catalog_files=() + + local i=$cword + while ((i-- > 1)); do + if [[ ${words[i]} == -@(t|-temp) ]]; then + local url="${words[i + 1]}" + local catalog=$(_pkgutil_url2catalog "$url") + catalog_files=("$catalog") + elif [[ ${words[i]} == --config ]]; then + configuration_files=("$(dequote ${words[i + 1]})") + elif [[ ${words[i]} == -@([iurdacUS]|-install|-upgrade|-remove|-download|-available|-compare|-catalog|-stream) ]]; then + command="${words[i]}" + fi + done + + if [[ $prev == -@([WPR]|-workdir|-pkgdir|-rootpath) ]]; then + _filedir -d + return + fi + + if [[ $prev == -@(o|-output|-config) ]]; then + _filedir + return + fi + + if [[ $prev == -@(p|-param) ]]; then + compopt -o nospace + COMPREPLY=($(compgen -W "mirror: pkgaddopts: pkgrmopts: wgetopts: use_gpg: use_md5: pkgliststyle: maxpkglist: noncsw: stop_on_hook_soft_error: exclude_pattern: gpg_homedir: root_path: deptree_filter_common: show_current: catalog_not_cached: catalog_update:" -- $cur)) + return + fi + + if [[ $prev == @(-T|--target) ]]; then + # Work-around bash_completion issue where bash interprets a colon + # as a separator, borrowed from maven completion code which borrowed + # it from darcs completion code :) + local colonprefixes=${cur%"${cur##*:}"} + COMPREPLY=($(compgen -W "sparc:5.9 sparc:5.10 sparc:5.11 i386:5.9 i386:5.10 i386:5.11" -- $cur)) + local i=${#COMPREPLY[*]} + while ((i-- > 0)); do + COMPREPLY[i]=${COMPREPLY[i]#"$colonprefixes"} + done + return + fi + + if [[ -v command && $cur != -* ]]; then + + local mirrors mirror_url + mirrors=$(awk -F= ' $1 ~ /^ *mirror *$/ { print $2 }' "${configuration_files[@]}") + mirrors=${mirrors:-http://mirror.opencsw.org/opencsw/testing} + for mirror_url in $mirrors; do + local catalog=$(_pkgutil_url2catalog "$mirror_url") + catalog_files=("${catalog_files[@]}" "$catalog") + done + + if [[ $command == -@([dius]|-download|-install|-upgrade|-stream) ]]; then + local packages_list=$(awk ' $0 ~ /BEGIN PGP SIGNATURE/ { exit } $1 ~ /^Hash:/ || $1 ~ /^ *(-|#|$)/ { next } { print $1 }' "${catalog_files[@]}") + COMPREPLY=($(compgen -W "${packages_list}" -- $cur)) + + elif [[ $command == @(-r|--remove) ]]; then + local packages_list=$(pkginfo | awk ' $2 ~ /^CSW/ { printf ("%s|",$2) }') + packages_list=${packages_list%|} + packages_list=$(nawk " \$3 ~ /^$packages_list\$/ { print \$1 }" "${catalog_files[@]}") + COMPREPLY=($(compgen -W "${packages_list}" -- $cur)) + fi + return + fi + + local commands="-i --install -u --upgrade -r --remove -d --download -U --catalog -a --available --describe -c --compare -C --compare-diff -A --compare-avail -e --email -t --temp -x --exclude -W --workdir -P --pkgdir -R --rootpath --config -y --yes -f --force -n --nomod -N --nodeps -D --debug --trace -h --help -v --version -V --syscheck -l --list -L --listfile -F --findfile --deptree --extract -s --stream -o --output -T --target --single -p --param --parse --cleanup --catinfo" + COMPREPLY=($(compgen -W "${commands}" -- $cur)) + +} && + complete -F _pkgutil pkgutil + +# ex: filetype=sh diff --git a/completions/plague-client b/completions/plague-client new file mode 100644 index 0000000..4e98206 --- /dev/null +++ b/completions/plague-client @@ -0,0 +1,14 @@ +# bash completion for plague-client -*- shell-script -*- + +_plague_client() +{ + local cur prev words cword + _init_completion || return + + ((cword == 1)) && + COMPREPLY=($(compgen -W 'build detail finish help is_paused kill list + list_builders pause requeue unpause update_builders' -- "$cur")) +} && + complete -F _plague_client plague-client + +# ex: filetype=sh diff --git a/completions/pm-hibernate b/completions/pm-hibernate new file mode 100644 index 0000000..ea3b0aa --- /dev/null +++ b/completions/pm-hibernate @@ -0,0 +1,12 @@ +# bash completion for pm-utils -*- shell-script -*- + +_pm_action() +{ + local cur prev words cword + _init_completion || return + + COMPREPLY=($(compgen -W "--help $(_parse_help "$1")" -- "$cur")) +} && + complete -F _pm_action pm-hibernate pm-suspend pm-suspend-hybrid + +# ex: filetype=sh diff --git a/completions/pm-is-supported b/completions/pm-is-supported new file mode 100644 index 0000000..adc7fde --- /dev/null +++ b/completions/pm-is-supported @@ -0,0 +1,13 @@ +# pm-is-supported(1) completion -*- shell-script -*- + +_pm_is_supported() +{ + local cur prev words cword + _init_completion || return + + COMPREPLY=($(compgen -W '--help --suspend --hibernate --suspend-hybrid' \ + -- "$cur")) +} && + complete -F _pm_is_supported pm-is-supported + +# ex: filetype=sh diff --git a/completions/pm-powersave b/completions/pm-powersave new file mode 100644 index 0000000..affb195 --- /dev/null +++ b/completions/pm-powersave @@ -0,0 +1,12 @@ +# pm-powersave(8) completion -*- shell-script -*- + +_pm_powersave() +{ + local cur prev words cword + _init_completion || return + + COMPREPLY=($(compgen -W "true false" -- "$cur")) +} && + complete -F _pm_powersave pm-powersave + +# ex: filetype=sh diff --git a/completions/pngfix b/completions/pngfix new file mode 100644 index 0000000..64b5481 --- /dev/null +++ b/completions/pngfix @@ -0,0 +1,36 @@ +# pngfix completion -*- shell-script -*- + +_pngfix() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --suffix | --prefix) + return + ;; + --output) + _filedir + return + ;; + --strip) + COMPREPLY=($(IFS='|' compgen -W '$("$1" --help 2>&1 | + command sed -ne "s/.*--strip=\[\([^]]*\)\].*/\1/p")' \ + -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir png +} && + complete -F _pngfix pngfix + +# ex: filetype=sh diff --git a/completions/portinstall b/completions/portinstall new file mode 100644 index 0000000..8033740 --- /dev/null +++ b/completions/portinstall @@ -0,0 +1,31 @@ +# bash completion for FreeBSD portinstall -*- shell-script -*- + +_portinstall() +{ + local cur prev words cword + _init_completion || return + + local portsdir indexfile + local -a COMPREPLY2 + + portsdir=${PORTSDIR:-/usr/ports}/ + + # First try INDEX-5 + indexfile=$portsdir/INDEX-5 + # Then INDEX if INDEX-5 does not exist or system is not FreeBSD 5.x + [[ ${OSTYPE%.*} == freebsd5 && -f $indexfile ]] || + indexfile=$portsdir/INDEX + + [[ $prev == -l || $prev == -L || $prev == -o ]] && return + + COMPREPLY=($(command grep -E "^$cur" 2>/dev/null <$indexfile | + cut -d'|' -f1)) + COMPREPLY2=($(command grep -E "^[^\|]+\|$portsdir$cur" 2>/dev/null \ + <$indexfile | cut -d'|' -f2)) + COMPREPLY2=(${COMPREPLY2[@]#$portsdir}) + COMPREPLY+=("${COMPREPLY2[@]}") + +} && + complete -F _portinstall -o dirnames portinstall + +# ex: filetype=sh diff --git a/completions/portsnap b/completions/portsnap new file mode 100644 index 0000000..a2f0a93 --- /dev/null +++ b/completions/portsnap @@ -0,0 +1,25 @@ +# bash completion for Portsnap -*- shell-script -*- + +[[ $OSTYPE == *freebsd* ]] || return 1 + +_portsnap() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -d | -p) + _filedir -d + return + ;; + -l | -f) + _filedir + return + ;; + esac + + COMPREPLY=($(compgen -W "fetch cron extract update" -- $cur)) +} && + complete -F _portsnap portsnap + +# ex: filetype=sh diff --git a/completions/portupgrade b/completions/portupgrade new file mode 100644 index 0000000..ffe6305 --- /dev/null +++ b/completions/portupgrade @@ -0,0 +1,19 @@ +# bash completion for FreeBSD portupgrade -*- shell-script -*- + +_portupgrade() +{ + local cur prev words cword + _init_completion || return + + [[ $prev == -l || $prev == -L || $prev == -o ]] && return + + local pkgdir=${PKG_DBDIR:-/var/db/pkg}/ + + COMPREPLY=($(compgen -d -- "$pkgdir$cur")) + COMPREPLY=(${COMPREPLY[@]#$pkgdir}) + COMPREPLY=(${COMPREPLY[@]%-*}) + +} && + complete -F _portupgrade -o dirnames portupgrade + +# ex: filetype=sh diff --git a/completions/postcat b/completions/postcat new file mode 100644 index 0000000..a58b0e5 --- /dev/null +++ b/completions/postcat @@ -0,0 +1,39 @@ +# postcat(1) completion -*- shell-script -*- + +_postcat() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -c) + _filedir -d + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + return + fi + + local idx qfile=0 + for idx in "${words[@]}"; do + [[ $idx == -q ]] && qfile=1 && break + done + if ((qfile == 1)); then + local len=${#cur} pval + for pval in $(mailq 2>/dev/null | + command sed -e '1d; $d; /^[^0-9A-Z]/d; /^$/d; s/[* !].*$//'); do + if [[ $cur == "${pval:0:len}" ]]; then + COMPREPLY+=($pval) + fi + done + return + fi + + _filedir +} && + complete -F _postcat postcat + +# ex: filetype=sh diff --git a/completions/postconf b/completions/postconf new file mode 100644 index 0000000..4cb324c --- /dev/null +++ b/completions/postconf @@ -0,0 +1,39 @@ +# postconf(1) completion -*- shell-script -*- + +_postconf() +{ + local cur prev words cword + _init_completion || return + + local eqext + + case $prev in + -b | -t) + _filedir + return + ;; + -c) + _filedir -d + return + ;; + -e) + cur=${cur#[\"\']} + eqext='=' + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + return + fi + + local len=${#cur} pval + for pval in $(/usr/sbin/postconf 2>/dev/null | cut -d ' ' -f 1); do + if [[ $cur == "${pval:0:len}" ]]; then + COMPREPLY+=("$pval${eqext-}") + fi + done +} && + complete -F _postconf postconf + +# ex: filetype=sh diff --git a/completions/postfix b/completions/postfix new file mode 100644 index 0000000..f960550 --- /dev/null +++ b/completions/postfix @@ -0,0 +1,33 @@ +# postfix(1) completion -*- shell-script -*- + +_postfix() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -c) + _filedir -d + return + ;; + -D) + COMPREPLY=($(compgen -W 'start' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($( + compgen -W \ + '$(_bashcomp_try_faketty "$1" --help 2>&1 | _parse_usage -)' \ + -- "$cur" + )) + return + fi + + COMPREPLY=($(compgen -W 'check start stop abort flush reload status + set-permissions upgrade-configuration' -- "$cur")) +} && + complete -F _postfix postfix + +# ex: filetype=sh diff --git a/completions/postmap b/completions/postmap new file mode 100644 index 0000000..35c4ada --- /dev/null +++ b/completions/postmap @@ -0,0 +1,41 @@ +# postalias(1) and postmap(1) completion -*- shell-script -*- + +_postmap() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -c) + _filedir -d + return + ;; + -[dq]) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + return + fi + + if [[ $cur == *:* ]]; then + compopt -o filenames + COMPREPLY=($(compgen -f -- "${cur#*:}")) + else + local len=${#cur} pval + for pval in $(/usr/sbin/postconf -m 2>/dev/null); do + if [[ $cur == "${pval:0:len}" ]]; then + COMPREPLY+=("$pval:") + fi + done + if [[ ! ${COMPREPLY-} ]]; then + compopt -o filenames + COMPREPLY=($(compgen -f -- "$cur")) + fi + fi +} && + complete -F _postmap postmap postalias + +# ex: filetype=sh diff --git a/completions/postsuper b/completions/postsuper new file mode 100644 index 0000000..559449a --- /dev/null +++ b/completions/postsuper @@ -0,0 +1,56 @@ +# postsuper(1) completion -*- shell-script -*- + +_postsuper() +{ + local cur prev words cword + _init_completion || return + + local pval len + + case $prev in + -c) + _filedir -d + return + ;; + -[dr]) + len=${#cur} + for pval in ALL $(mailq 2>/dev/null | + command sed -e '1d; $d; /^[^0-9A-Z]/d; /^$/d; s/[* !].*$//'); do + if [[ $cur == "${pval:0:len}" ]]; then + COMPREPLY+=($pval) + fi + done + return + ;; + -h) + len=${#cur} + for pval in ALL $(mailq 2>/dev/null | + command sed -e '1d; $d; /^[^0-9A-Z]/d; /^$/d; s/[* ].*$//; /!$/d'); do + if [[ $cur == "${pval:0:len}" ]]; then + COMPREPLY+=($pval) + fi + done + return + ;; + -H) + len=${#cur} + for pval in ALL $(mailq 2>/dev/null | + command sed -e '1d; $d; /^[^0-9A-Z]/d; /^$/d; /^[0-9A-Z]*[* ]/d; s/!.*$//'); do + if [[ $cur == "${pval:0:len}" ]]; then + COMPREPLY+=($pval) + fi + done + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + COMPREPLY=($(compgen -W 'hold incoming active deferred' -- "$cur")) +} && + complete -F _postsuper postsuper + +# ex: filetype=sh diff --git a/completions/povray b/completions/povray new file mode 100644 index 0000000..56dfd94 --- /dev/null +++ b/completions/povray @@ -0,0 +1,64 @@ +# povray completion -*- shell-script -*- +# by "David Necas (Yeti)" <yeti@physics.muni.cz> + +_povray() +{ + local cur prev words cword + _init_completion || return + + local povcur=$cur pfx oext defoext + defoext=png # default output extension, if cannot be determined FIXME + + _expand || return + + case $povcur in + [-+]I*) + cur="${povcur#[-+]I}" # to confuse _filedir + pfx="${povcur%"$cur"}" + _filedir pov + COMPREPLY=(${COMPREPLY[@]/#/$pfx}) + return + ;; + [-+]O*) + # guess what output file type user may want + case $( + IFS=$'\n' + command grep '^[-+]F' <<<"${words[*]}" + ) in + [-+]FN) oext=png ;; + [-+]FP) oext=ppm ;; + [-+]F[CT]) oext=tga ;; + *) oext=$defoext ;; + esac + # complete filename corresponding to previously specified +I + COMPREPLY=($( + IFS=$'\n' + command grep '^[-+]I' <<<"${words[*]}" + )) + COMPREPLY=(${COMPREPLY[@]#[-+]I}) + COMPREPLY=(${COMPREPLY[@]/%.pov/.$oext}) + cur="${povcur#[-+]O}" # to confuse _filedir + pfx="${povcur%"$cur"}" + _filedir $oext + COMPREPLY=(${COMPREPLY[@]/#/$pfx}) + return + ;; + *.ini\[ | *.ini\[*[^]]) # sections in .ini files + cur="${povcur#*\[}" + pfx="${povcur%\["$cur"}" # prefix == filename + [[ -r $pfx ]] || return + COMPREPLY=($(command sed -e 's/^[[:space:]]*\[\('"$cur"'[^]]*\]\).*$/\1/' \ + -e 't' -e 'd' -- "$pfx")) + # to prevent [bar] expand to nothing. can be done more easily? + COMPREPLY=("${COMPREPLY[@]/#/${pfx}[}") + return + ;; + *) + _filedir '@(ini|pov)' + return + ;; + esac +} && + complete -F _povray povray xpovray spovray + +# ex: filetype=sh diff --git a/completions/prelink b/completions/prelink new file mode 100644 index 0000000..1c39611 --- /dev/null +++ b/completions/prelink @@ -0,0 +1,42 @@ +# prelink(8) completion -*- shell-script -*- + +_prelink() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -'?' | --help | --usage | -V | --version | -r | --reloc-only) + return + ;; + -b | --black-list | --dynamic-linker | --undo-output) + _filedir + return + ;; + -c | --config-file) + _filedir conf + return + ;; + -C | --cache) + _filedir cache + return + ;; + --ld-library-path) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir +} && + complete -F _prelink prelink + +# ex: filetype=sh diff --git a/completions/printenv b/completions/printenv new file mode 100644 index 0000000..3553e83 --- /dev/null +++ b/completions/printenv @@ -0,0 +1,23 @@ +# printenv(1) completion -*- shell-script -*- + +_printenv() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + COMPREPLY=($(compgen -v -- "$cur")) +} && + complete -F _printenv printenv + +# ex: filetype=sh diff --git a/completions/protoc b/completions/protoc new file mode 100644 index 0000000..fdd77be --- /dev/null +++ b/completions/protoc @@ -0,0 +1,63 @@ +# protoc completion -*- shell-script -*- + +_protoc() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --version | -h | --help | --encode | --decode) + return + ;; + --descriptor_set_out) + _filedir + return + ;; + --error_format) + COMPREPLY=($(compgen -W 'gcc msvs' -- "$cur")) + return + ;; + --plugin) + if [[ $cur != *=* ]]; then + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + fi + return + ;; + --proto_path | --*_out) + _filedir -d + return + ;; + esac + + $split && return + + case $cur in + -o*) + cur=${cur:2} + _filedir + COMPREPLY=("${COMPREPLY[@]/#/-o}") + return + ;; + -I*) + cur=${cur:2} + _filedir -d + COMPREPLY=("${COMPREPLY[@]/#/-I}") + return + ;; + -*) + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + local i + for i in "${!COMPREPLY[@]}"; do + [[ ${COMPREPLY[i]} == -oFILE ]] && unset 'COMPREPLY[i]' + done + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + ;; + esac + + _filedir proto +} && + complete -F _protoc protoc + +# ex: filetype=sh diff --git a/completions/psql b/completions/psql new file mode 100644 index 0000000..4bc6049 --- /dev/null +++ b/completions/psql @@ -0,0 +1,188 @@ +# bash completion for Postgresql -*- shell-script -*- + +_pg_databases() +{ + # -w was introduced in 8.4, https://launchpad.net/bugs/164772 + # "Access privileges" in output may contain linefeeds, hence the NF > 1 + COMPREPLY=($(compgen -W "$(psql -XAtqwlF $'\t' 2>/dev/null | + awk 'NF > 1 { print $1 }')" -- "$cur")) +} + +_pg_users() +{ + # -w was introduced in 8.4, https://launchpad.net/bugs/164772 + COMPREPLY=($(compgen -W "$(psql -XAtqwc 'select usename from pg_user' \ + template1 2>/dev/null)" -- "$cur")) + ((${#COMPREPLY[@]} == 0)) && COMPREPLY=($(compgen -u -- "$cur")) +} + +# createdb(1) completion +# +_createdb() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --host | -!(-*)h) + _known_hosts_real -- "$cur" + return + ;; + --username | --owner | -!(-*)[UO]) + _pg_users + return + ;; + --help | --version | --port | --tablespace | --encoding | --template | -!(-*)[pDET]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _pg_databases + fi +} && + complete -F _createdb createdb + +# createuser(1) completion +# +_createuser() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | --port | --connection-limit | -!(-*)[pc]) + return + ;; + --host | -!(-*)h) + _known_hosts_real -- "$cur" + return + ;; + --username | -!(-*)U) + _pg_users + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _createuser createuser + +# dropdb(1) completion +# +_dropdb() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --host | -!(-*)h) + _known_hosts_real -- "$cur" + return + ;; + --username | -!(-*)U) + _pg_users + return + ;; + --help | --version) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _pg_databases + fi +} && + complete -F _dropdb dropdb + +# dropuser(1) completion +# +_dropuser() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | --port | -!(-*)p) + return + ;; + --host | -!(-*)h) + _known_hosts_real -- "$cur" + return + ;; + --username | -!(-*)U) + _pg_users + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _pg_users + fi +} && + complete -F _dropuser dropuser + +# psql(1) completion +# +_psql() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --host | -!(-*)h) + _known_hosts_real -- "$cur" + return + ;; + --username | -!(-*)U) + _pg_users + return + ;; + --dbname | -!(-*)d) + _pg_databases + return + ;; + --output | --file | --log-file | -!(-*)[ofL]) + _filedir + return + ;; + --help | --version | --command | --field-separator | --port | --pset | \ + --record-separator | --table-attr | --set | --variable | -!(-*)[?VcFpPRTv]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + # return list of available options + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + # return list of available databases + _pg_databases + fi +} && + complete -F _psql psql + +# ex: filetype=sh diff --git a/completions/puppet b/completions/puppet new file mode 100644 index 0000000..e8767de --- /dev/null +++ b/completions/puppet @@ -0,0 +1,338 @@ +# bash completion for puppet -*- shell-script -*- + +_puppet_logdest() +{ + if [[ -z $cur ]]; then + COMPREPLY=($(compgen -W 'syslog console /' -- "$cur")) + else + COMPREPLY=($(compgen -W 'syslog console' -- "$cur")) + _filedir + fi +} + +_puppet_digest() +{ + COMPREPLY=($(compgen -W 'MD5 MD2 SHA1 SHA256' -- "$cur")) +} + +_puppet_certs() +{ + local puppetca="puppet cert" + PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type puppetca &>/dev/null && + puppetca=puppetca + + if [[ $1 == --all ]]; then + cert_list=$($puppetca --list --all | command sed -e 's/^[+-]\{0,1\}\s*\(\S\+\)\s\+.*$/\1/') + else + cert_list=$($puppetca --list) + fi + COMPREPLY+=($(compgen -W "$cert_list" -- "$cur")) +} + +_puppet_types() +{ + puppet_types=$(puppet describe --list | command sed -e 's/^\(\S\{1,\}\).*$/\1/') + COMPREPLY+=($(compgen -W "$puppet_types" -- "$cur")) +} + +_puppet_references() +{ + local puppetdoc="puppet doc" + PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type puppetdoc &>/dev/null && + puppetdoc=puppetdoc + + puppet_doc_list=$($puppetdoc --list | command sed -e 's/^\(\S\{1,\}\).*$/\1/') + COMPREPLY+=($(compgen -W "$puppet_doc_list" -- "$cur")) +} + +_puppet_subcmd_opts() +{ + # puppet cmd help is somewhat slow, avoid if possible + [[ -z $cur || $cur == -* ]] && + COMPREPLY+=($(compgen -W \ + '$(_parse_usage "$1" "help $2")' -- "$cur")) +} + +_puppet() +{ + local cur prev words cword + _init_completion || return + + local subcommand action + + case $prev in + -h | --help | -V | --version) + return + ;; + esac + + case ${words[0]} in + puppetmasterd) + subcommand=master + ;; + puppetd) + subcommand=agent + ;; + puppetca) + subcommand=cert + ;; + ralsh) + subcommand=resource + ;; + puppetrun) + subcommand=kick + ;; + puppetqd) + subcommand=queue + ;; + filebucket) + subcommand=filebucket + ;; + puppetdoc) + subcommand=doc + ;; + pi) + subcommand=describe + ;; + puppet) + case ${words[1]} in + agent | apply | cert | describe | doc | filebucket | kick | master | parser | queue | resource) + subcommand=${words[1]} + ;; + *.pp | *.rb) + subcommand=apply + ;; + *) + COMPREPLY=($(compgen -W 'agent apply cert describe doc + filebucket kick master parser queue resource' \ + -- "$cur")) + return + ;; + esac + ;; + esac + + case $subcommand in + agent) + case $prev in + --certname) + _known_hosts_real -- "$cur" + return + ;; + --digest) + _puppet_digest + return + ;; + --fqdn) + _known_hosts_real -- "$cur" + return + ;; + -l | --logdest) + _puppet_logdest + return + ;; + --masterport) + COMPREPLY=($(compgen -W '8140' -- "$cur")) + return + ;; + -w | --waitforcert) + COMPREPLY=($(compgen -W '0 15 30 60 120' -- "$cur")) + return + ;; + *) + _puppet_subcmd_opts "$1" $subcommand + # _parse_usage doesn't grok [-D|--daemonize|--no-daemonize] + COMPREPLY+=($(compgen -W '--no-daemonize' -- "$cur")) + return + ;; + esac + ;; + apply) + case $prev in + --catalog) + COMPREPLY=($(compgen -W '-' -- "$cur")) + _filedir json + return + ;; + --execute) + return + ;; + -l | --logdest) + _puppet_logdest + return + ;; + *) + if [[ $cur == -* ]]; then + _puppet_subcmd_opts "$1" $subcommand + else + _filedir + fi + return + ;; + esac + ;; + cert) + case $prev in + --digest) + _puppet_digest + return + ;; + *) + action=$prev + COMPREPLY=($(compgen -W '--digest --debug --help --verbose --version' \ + -- "$cur")) + case $action in + fingerprint | list | verify | --fingerprint | --list | --verify) + COMPREPLY+=($(compgen -W '--all' -- "$cur")) + _puppet_certs --all + return + ;; + generate | --generate) + _known_hosts_real -- "$cur" + return + ;; + clean | print | revoke | --clean | --print | --revoke) + _puppet_certs --all + return + ;; + sign | --sign) + COMPREPLY+=($(compgen -W '--all' -- "$cur")) + _puppet_certs + return + ;; + *) + COMPREPLY+=($(compgen -W 'clean fingerprint generate + list print revoke sign verify reinventory' -- "$cur")) + return + ;; + esac + ;; + esac + ;; + describe) + _puppet_subcmd_opts "$1" $subcommand + if [[ $cur != -* ]]; then + _puppet_types + fi + return + ;; + doc) + case $prev in + -o | --outputdir) + _filedir -d + return + ;; + -m | --mode) + COMPREPLY=($(compgen -W 'text trac pdf rdoc' -- "$cur")) + return + ;; + -r | --reference) + _puppet_references + return + ;; + *) + if [[ $cur == -* ]]; then + _puppet_subcmd_opts "$1" $subcommand + else + _filedir + fi + return + ;; + esac + ;; + filebucket) + case $prev in + -s | --server) + _known_hosts_real -- "$cur" + return + ;; + -b | --bucket) + _filedir -d + return + ;; + *) + if [[ $cur == -* ]]; then + _puppet_subcmd_opts "$1" $subcommand + else + COMPREPLY=($(compgen -W 'backup get restore' \ + -- "$cur")) + _filedir + fi + return + ;; + esac + ;; + kick) + case $prev in + -c | --class) + return + ;; + --host) + _known_hosts_real -- "$cur" + return + ;; + -t | --tag) + return + ;; + *) + if [[ $cur == -* ]]; then + _puppet_subcmd_opts "$1" $subcommand + else + _known_hosts_real -- "$cur" + fi + return + ;; + esac + ;; + master) + case $prev in + -l | --logdest) + _puppet_logdest + return + ;; + *) + _puppet_subcmd_opts "$1" $subcommand + # _parse_usage doesn't grok [-D|--daemonize|--no-daemonize] + COMPREPLY+=($(compgen -W '--no-daemonize' -- "$cur")) + return + ;; + esac + ;; + parser) + action=$prev + case $action in + validate) + _filedir pp + return + ;; + *) + COMPREPLY=($(compgen -W 'validate' -- "$cur")) + return + ;; + esac + ;; + queue) + case $prev in + -l | --logdest) + _puppet_logdest + return + ;; + *) + if [[ $cur == -* ]]; then + _puppet_subcmd_opts "$1" $subcommand + else + _filedir + fi + return + ;; + esac + ;; + resource | *) + _puppet_subcmd_opts "$1" $subcommand + return + ;; + esac +} && + complete -F _puppet puppetmasterd puppetd puppetca ralsh puppetrun puppetqd filebucket puppetdoc puppet + +# ex: filetype=sh diff --git a/completions/pv b/completions/pv new file mode 100644 index 0000000..99933f2 --- /dev/null +++ b/completions/pv @@ -0,0 +1,31 @@ +# pv(1) completion -*- shell-script -*- + +_pv() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | --last-written | --format | --delay-start | --interval | \ + --width | --height | --name | --rate-limit | --buffer-size | -!(-*)[hVAFDiwHNLB]) + return + ;; + --remote | -!(-*)R) + _pids + return + ;; + --pidfile | --watchfd | -!(-*)[Pd]) + _filedir pid + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + _filedir + fi +} && + complete -F _pv pv + +# ex: filetype=sh diff --git a/completions/pwck b/completions/pwck new file mode 100644 index 0000000..fa07b0e --- /dev/null +++ b/completions/pwck @@ -0,0 +1,18 @@ +# pwck(8) completion -*- shell-script -*- + +_pwck() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + return + fi + + _filedir +} && + complete -F _pwck pwck + +# ex: filetype=sh diff --git a/completions/pwd b/completions/pwd new file mode 100644 index 0000000..b9c4fbc --- /dev/null +++ b/completions/pwd @@ -0,0 +1,20 @@ +# pwd(1) completion -*- shell-script -*- + +_pwd() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version) + return + ;; + esac + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} ]] || + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) +} && + complete -F _pwd pwd + +# ex: filetype=sh diff --git a/completions/pwdx b/completions/pwdx new file mode 100644 index 0000000..25a1a1e --- /dev/null +++ b/completions/pwdx @@ -0,0 +1,24 @@ +# pwdx(1) completion -*- shell-script -*- + +_pwdx() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h | --help | -V | --version) + return + ;; + esac + + if [[ $cur == -* ]]; then + local help='$(_parse_help "$1")' + [[ $help ]] || help=-V + COMPREPLY=($(compgen -W "$help" -- "$cur")) + else + _pids + fi +} && + complete -F _pwdx pwdx + +# ex: filetype=sh diff --git a/completions/pwgen b/completions/pwgen new file mode 100644 index 0000000..50d31d5 --- /dev/null +++ b/completions/pwgen @@ -0,0 +1,28 @@ +# pwgen(1) completion -*- shell-script -*- + +_pwgen() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --num-passwords | --help | -!(-*)[Nh]) + return + ;; + --sha1 | -!(-*)H) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi +} && + complete -F _pwgen pwgen + +# ex: filetype=sh diff --git a/completions/pycodestyle b/completions/pycodestyle new file mode 100644 index 0000000..dec6f37 --- /dev/null +++ b/completions/pycodestyle @@ -0,0 +1,34 @@ +# pycodestyle completion -*- shell-script -*- + +_pycodestyle() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -h | --help | --version) + return + ;; + --format) + COMPREPLY=($(compgen -W 'default pylint' -- "$cur")) + return + ;; + --config) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir py +} && + complete -F _pycodestyle pycodestyle + +# ex: filetype=sh diff --git a/completions/pydoc b/completions/pydoc new file mode 100644 index 0000000..e7b1178 --- /dev/null +++ b/completions/pydoc @@ -0,0 +1,42 @@ +# pydoc completion -*- shell-script -*- + +_pydoc() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -k | -p) + return + ;; + -w) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W \ + '$("$1" | command sed -e "s/^pydoc3\{0,1\} //" | _parse_help -)' \ + -- "$cur")) + return + fi + + COMPREPLY=($(compgen -W 'keywords topics modules' -- "$cur")) + + if [[ $cur != @(.|*/)* ]]; then + local python=python + [[ ${1##*/} == *3* ]] && python=python3 + _xfunc python _python_modules $python + fi + + # Note that we don't do "pydoc modules" as it is known to hang on + # some systems; _python_modules tends to work better and faster. + COMPREPLY+=($(compgen -W \ + '$($1 keywords topics | command sed -e /^Here/d)' -- "$cur")) + + _filedir py +} && + complete -F _pydoc pydoc pydoc3 + +# ex: filetype=sh diff --git a/completions/pydocstyle b/completions/pydocstyle new file mode 100644 index 0000000..acbf1ec --- /dev/null +++ b/completions/pydocstyle @@ -0,0 +1,35 @@ +# bash completion for pydocstyle -*- shell-script -*- + +_pydocstyle() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | --match | --ignore-decorators | --select | --ignore | \ + --add-select | --add-ignore | -!(-*)h) + return + ;; + --config) + _filedir xml + return + ;; + --convention) + COMPREPLY=($(compgen -W "pep257 numpy" -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir py +} && + complete -F _pydocstyle pydocstyle + +# ex: filetype=sh diff --git a/completions/pyflakes b/completions/pyflakes new file mode 100644 index 0000000..0a4e977 --- /dev/null +++ b/completions/pyflakes @@ -0,0 +1,23 @@ +# pyflakes(1) completion -*- shell-script -*- + +_pyflakes() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h | --help | --version) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + _filedir py +} && + complete -F _pyflakes pyflakes + +# ex: filetype=sh diff --git a/completions/pylint b/completions/pylint new file mode 100644 index 0000000..8726f8b --- /dev/null +++ b/completions/pylint @@ -0,0 +1,87 @@ +# pylint(1) completion -*- shell-script -*- + +_pylint() +{ + local cur prev words cword split + _init_completion -s || return + + local python=python + [[ ${1##*/} == *3* ]] && python=python3 + + case $prev in + --version | --help | --long-help | --help-msg | --init-hook | --ignore | --enable | \ + --evaluation | --max-line-length | --max-module-lines | \ + --indent-string | --min-similarity-lines | --max-args | \ + --ignored-argument-names | --max-locals | --max-returns | --max-branchs | \ + --max-statements | --max-parents | --max-attributes | --min-public-methods | \ + --max-public-methods | --required-attributes | --bad-functions | \ + --module-rgx | --const-rgx | --class-rgx | --function-rgx | --method-rgx | \ + --attr-rgx | --argument-rgx | --variable-rgx | --inlinevar-rgx | --good-names | \ + --bad-names | --no-docstring-rgx | --dummy-variables-rgx | \ + --additional-builtins | --notes | --ignored-classes | --generated-members | \ + --overgeneral-exceptions | --ignore-iface-methods | \ + --defining-attr-methods | --valid-classmethod-first-arg | \ + --valid-metaclass-classmethod-first-arg | -!(-*)[he]) + return + ;; + --disable | -!(-*)d) + COMPREPLY=($(compgen -W 'all' -- "$cur")) + return + ;; + --rcfile) + _filedir + return + ;; + --persistent | --include-ids | --symbols | --files-output | --reports | \ + --comment | --ignore-comments | --ignore-docstrings | --ignore-imports | \ + --init-import | --ignore-mixin-members | --zope | --suggestion-mode | \ + -!(-*)[isr]) + COMPREPLY=($(compgen -W 'yes no' -- "$cur")) + return + ;; + --load-plugins | --deprecated-modules) + local prefix= + [[ $cur == *,* ]] && prefix="${cur%,*}," + cur="${cur##*,}" + _xfunc python _python_modules $python + ((${#COMPREPLY[@]} == 1)) && COMPREPLY=(${COMPREPLY/#/$prefix}) + return + ;; + --jobs | -!(-*)j) + COMPREPLY=($(compgen -W "{1..$(_ncpus)}" -- "$cur")) + return + ;; + --confidence) + local prefix= + [[ $cur == *,* ]] && prefix="${cur%,*}," + COMPREPLY=($(compgen -W "HIGH INFERENCE INFERENCE_FAILURE + UNDEFINED" -- "${cur##*,}")) + ((${#COMPREPLY[@]} == 1)) && COMPREPLY=(${COMPREPLY/#/$prefix}) + return + ;; + --format | -!(-*)f) + COMPREPLY=($(compgen -W 'text parseable colorized json msvs' \ + -- "$cur")) + return + ;; + --import-graph | --ext-import-graph | --int-import-graph) + _filedir dot + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W \ + '$(_parse_help "$1" --long-help)' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + [[ $cur == @(.|*/)* ]] || _xfunc python _python_modules $python + _filedir py +} && + complete -F _pylint pylint pylint-2 pylint-3 + +# ex: filetype=sh diff --git a/completions/pytest b/completions/pytest new file mode 100644 index 0000000..7457a84 --- /dev/null +++ b/completions/pytest @@ -0,0 +1,134 @@ +# bash completion for pytest(1) -*- shell-script -*- + +_pytest() +{ + local cur prev words cword split + _init_completion -s -n : || return + + case $prev in + --help | --maxfail | --report | --junit-prefix | --doctest-glob | -!(-*)[hkmorp]) + return + ;; + --import-mode) + COMPREPLY=($(compgen -W "prepend append" -- "$cur")) + return + ;; + --capture) + COMPREPLY=($(compgen -W "fd sys no tee-sys" -- "$cur")) + return + ;; + --lfnf | --last-failed-no-failures) + COMPREPLY=($(compgen -W "all none" -- "$cur")) + return + ;; + --tb) + COMPREPLY=($(compgen -W "auto long short line native no" \ + -- "$cur")) + return + ;; + --show-capture) + COMPREPLY=($(compgen -W "no stdout stderr log all" -- "$cur")) + return + ;; + --color) + COMPREPLY=($(compgen -W "yes no auto" -- "$cur")) + return + ;; + --pastebin) + COMPREPLY=($(compgen -W "failed all" -- "$cur")) + return + ;; + --junit-xml) + _filedir xml + return + ;; + --result-log | --log-file) + _filedir log + return + ;; + --ignore) + _filedir + return + ;; + --confcutdir | --basetemp | --rsyncdir | --rootdir) + _filedir -d + return + ;; + --doctest-report) + COMPREPLY=($(compgen -W "none cdiff ndiff udiff only_first_failure" -- "$cur")) + return + ;; + --assert) + COMPREPLY=($(compgen -W "plain reinterp rewrite" -- "$cur")) + return + ;; + --genscript) + _filedir py + return + ;; + --pythonwarnings | -!(-*)W) + _xfunc python _python_warning_actions + return + ;; + --numprocesses | -!(-*)n) + COMPREPLY=($(compgen -W "{1..$(_ncpus)} auto" -- "$cur")) + return + ;; + --dist) + local modes=$("$1" --dist=nonexistent-distmode 2>&1 | + command sed -e 's/[^[:space:][:alnum:]-]\{1,\}//g' \ + -ne 's/.*choose from //p') + COMPREPLY=($(compgen -W '$modes' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + if [[ $cur == *.py::*:* ]]; then + local file=${cur/.py:*/.py} + local class=${cur#*.py::} in_class=false + local line + class=${class%%:*} + while IFS= read -r line; do + if [[ $line =~ ^class[[:space:]]+${class}[[:space:]:\(] ]]; then + in_class=true + elif [[ $line =~ ^class[[:space:]] ]]; then + in_class=false + fi + if $in_class && [[ $line =~ ^[[:space:]]+(async[[:space:]]+)?def[[:space:]]+(test_[A-Za-z0-9_]+) ]]; then + COMPREPLY+=(${BASH_REMATCH[2]}) + fi + done 2>/dev/null <"$file" + ((!${#COMPREPLY[@]})) || + COMPREPLY=($(compgen -P "$file::$class::" -W '${COMPREPLY[@]}' \ + -- "${cur##*:?(:)}")) + __ltrim_colon_completions "$cur" + return + elif [[ $cur == *.py:* ]]; then + local file="${cur/.py:*/.py}" line + while IFS= read -r line; do + if [[ $line =~ ^class[[:space:]]+(Test[A-Za-z0-9_]+) ]]; then + COMPREPLY+=(${BASH_REMATCH[1]}) + elif [[ $line =~ ^(async[[:space:]]+)?def[[:space:]]+(test_[A-Za-z0-9_]+) ]]; then + COMPREPLY+=(${BASH_REMATCH[2]}) + fi + done 2>/dev/null <"$file" + ((!${#COMPREPLY[@]})) || + COMPREPLY=($(compgen -P "$file::" -W '${COMPREPLY[@]}' \ + -- "${cur##*.py:?(:)}")) + __ltrim_colon_completions "$cur" + return + fi + + _filedir py +} && + complete -F _pytest pytest pytest-2 pytest-3 py.test py.test-2 py.test-3 + +# ex: filetype=sh diff --git a/completions/python b/completions/python new file mode 100644 index 0000000..d50c18f --- /dev/null +++ b/completions/python @@ -0,0 +1,67 @@ +# bash completion for python -*- shell-script -*- + +_python_modules() +{ + COMPREPLY+=($(compgen -W \ + "$(${1:-python} ${BASH_SOURCE[0]%/*}/../helpers/python $cur \ + 2>/dev/null)" -- "$cur")) +} + +_python_warning_actions() +{ + COMPREPLY+=($(compgen -W "ignore default all module once error" \ + ${prefix:+-P "$prefix"} -- "$cur")) +} + +_python() +{ + local cur prev words cword prefix + _init_completion || return + + case $cur in + -[QWX]?*) + prefix=${cur:0:2} + prev=$prefix + cur=${cur:2} + ;; + esac + + case $prev in + --help | --version | -!(-*)[?hVcX]) + return + ;; + -!(-*)m) + _python_modules "$1" + return + ;; + -!(-*)Q) + COMPREPLY=($(compgen -W "old new warn warnall" -P "$prefix" \ + -- "$cur")) + return + ;; + -!(-*)W) + _python_warning_actions + return + ;; + --jit) + # TODO: quite a few others, parse from "--jit help" output? + COMPREPLY=($(compgen -W "help off" -- "$cur")) + return + ;; + !(?(*/)python*([0-9.])|?(*/)pypy*([0-9.])|-?)) + [[ $cword -lt 2 || ${words[cword - 2]} != -[QWX] ]] && _filedir + ;; + esac + + # if -c or -m is already given, complete all kind of files. + if [[ ${words[*]::cword} == *\ -[cm]\ * ]]; then + _filedir + elif [[ $cur != -* ]]; then + _filedir 'py?([cowz])' + else + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + fi +} && + complete -F _python python python2 python2.7 python3 python3.{3..8} pypy pypy3 micropython + +# ex: filetype=sh diff --git a/completions/pyvenv b/completions/pyvenv new file mode 100644 index 0000000..527a384 --- /dev/null +++ b/completions/pyvenv @@ -0,0 +1,25 @@ +# bash completion for pyvenv -*- shell-script -*- + +_pyvenv() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -h | --help) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + _longopt "$1" + return + fi + + _filedir -d +} && + complete -F _pyvenv pyvenv pyvenv-3.{4..8} + +# ex: filetype=sh diff --git a/completions/qdbus b/completions/qdbus new file mode 100644 index 0000000..5b5a5e3 --- /dev/null +++ b/completions/qdbus @@ -0,0 +1,14 @@ +# Qt qdbus, dcop completion -*- shell-script -*- + +_qdbus() +{ + local cur prev words cword + _init_completion || return + + [[ -n $cur ]] && unset "words[$((${#words[@]} - 1))]" + COMPREPLY=($(compgen -W '$(command ${words[@]} 2>/dev/null | \ + command sed "s/(.*)//")' -- "$cur")) +} && + complete -F _qdbus qdbus dcop + +# ex: filetype=sh diff --git a/completions/qemu b/completions/qemu new file mode 100644 index 0000000..8382981 --- /dev/null +++ b/completions/qemu @@ -0,0 +1,108 @@ +# bash completion for qemu -*- shell-script -*- + +_qemu() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -fd[ab] | -hd[abcd] | -cdrom | -option-rom | -kernel | -initrd | -bootp | -pidfile | \ + -loadvm | -mtdblock | -sd | -pflash | -bios) + _filedir + return + ;; + -tftp | -smb | -L | -chroot) + _filedir -d + return + ;; + -boot) + COMPREPLY=($(compgen -W 'a c d n' -- "$cur")) + return + ;; + -k) + COMPREPLY=($(compgen -W 'ar de-ch es fo fr-ca hu ja mk no pt-br + sv da en-gb et fr fr-ch is lt nl pl ru th de en-us fi fr-be hr + it lv nl-be pt sl tr' -- "$cur")) + return + ;; + -soundhw) + COMPREPLY=($(compgen -W "$($1 -soundhw help | awk \ + '/^[[:lower:]]/ {print $1}') all" -- "$cur")) + return + ;; + -machine | -M) + COMPREPLY=($(compgen -W "$($1 $prev help | awk \ + '/^[[:lower:]]/ {print $1}')" -- "$cur")) + return + ;; + -cpu) + COMPREPLY=($(compgen -W "$($1 -cpu help | awk '{print $2}')" \ + -- "$cur")) + return + ;; + -usbdevice) + COMPREPLY=($(compgen -W 'mouse tablet disk: host: serial: braille + net' -- "$cur")) + return + ;; + -net) + COMPREPLY=($(compgen -W 'nic user tap socket vde none dump' \ + -- "$cur")) + return + ;; + -serial | -parallel | -monitor) + COMPREPLY=($(compgen -W 'vc pty none null /dev/ file: stdio pipe: + COM udp: tcp: telnet: unix: mon: braille' -- "$cur")) + return + ;; + -redir) + COMPREPLY=($(compgen -S":" -W 'tcp udp' -- "$cur")) + return + ;; + -bt) + COMPREPLY=($(compgen -W 'hci vhci device' -- "$cur")) + return + ;; + -vga) + COMPREPLY=($(compgen -W 'cirrus std vmware xenfb none' -- "$cur")) + return + ;; + -drive) + COMPREPLY=($(compgen -S"=" -W 'file if bus unit index media cyls + snapshot cache format serial addr' -- "$cur")) + return + ;; + -balloon) + COMPREPLY=($(compgen -W 'none virtio' -- "$cur")) + return + ;; + -smbios) + COMPREPLY=($(compgen -W 'file type' -- "$cur")) + return + ;; + -watchdog) + COMPREPLY=($(compgen -W "$($1 -watchdog help 2>&1 | + awk '{print $1}')" -- "$cur")) + return + ;; + -watchdog-action) + COMPREPLY=($(compgen -W 'reset shutdown poweroff pause debug + none' -- "$cur")) + return + ;; + -runas) + _allowed_users + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help) -fd{a,b} + -hd{a..d}' -- "$cur")) + else + _filedir + fi +} && + complete -F _qemu qemu qemu-kvm qemu-system-i386 qemu-system-x86_64 + +# ex: filetype=sh diff --git a/completions/qrunner b/completions/qrunner new file mode 100644 index 0000000..3919ea2 --- /dev/null +++ b/completions/qrunner @@ -0,0 +1,18 @@ +# mailman qrunner completion -*- shell-script -*- + +_qrunner() +{ + local cur prev words cword split + _init_completion -s || return + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--runner --once --list --verbose --subproc + --help' -- "$cur")) + fi + +} && + complete -F _qrunner qrunner + +# ex: filetype=sh diff --git a/completions/querybts b/completions/querybts new file mode 100644 index 0000000..edeba96 --- /dev/null +++ b/completions/querybts @@ -0,0 +1,40 @@ +# querybts completion -*- shell-script -*- + +_querybts() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --bts | -!(-*)B) + COMPREPLY=($(compgen -W "debian guug kde mandrake help" \ + -- "$cur")) + return + ;; + --ui | --interface | -!(-*)u) + COMPREPLY=($(compgen -W "newt text gnome" -- "$cur")) + return + ;; + --mbox-reader-cmd) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + COMPREPLY=($(compgen -W 'wnpp boot-floppies kernel bugs.debian.org + cdimage.debian.org general installation-reports listarchives + lists.debian.org mirrors nm.debian.org press project qa.debian.org + release-notes security.debian.org tech-ctte upgrade-reports + www.debian.org $(_xfunc apt-cache _apt_cache_packages)' -- "$cur")) + fi +} && + complete -F _querybts querybts + +# ex: filetype=sh diff --git a/completions/quota b/completions/quota new file mode 100644 index 0000000..f5f9cc8 --- /dev/null +++ b/completions/quota @@ -0,0 +1,191 @@ +# bash completion for quota-tools -*- shell-script -*- + +_user_or_group() +{ + local i + + # complete on groups if -g was given + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == -@(g|-group) ]]; then + COMPREPLY=($(compgen -g -- "$cur")) + return + fi + done + + # otherwise complete on users + COMPREPLY=($(compgen -u -- "$cur")) +} + +_quota_parse_help() +{ + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace +} + +_quota_formats() +{ + COMPREPLY=($(compgen -W 'vfsold vfsv0 rpc xfs' -- "$cur")) +} + +_filesystems() +{ + # Only list filesystems starting with "/", otherwise we also get + #+ "binfmt_misc", "proc", "tmpfs", ... + COMPREPLY=($(compgen -W "$(awk '/^\// {print $1}' /etc/mtab)" \ + -- "$cur")) +} + +_quota() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -F | --format) + _quota_formats + return + ;; + -h | --help | -V | --version) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + _quota_parse_help "$1" + else + _user_or_group + fi +} && + complete -F _quota -o default quota + +_setquota() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -F | --format) + _quota_formats + return + ;; + -p | --prototype) + _user_or_group + return + ;; + -h | --help | -V | --version) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + _quota_parse_help "$1" + else + local args + _count_args + + case $args in + 1) + _user_or_group + ;; + 2) + _filesystems + ;; + esac + + fi +} && + complete -F _setquota -o default setquota + +_edquota() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -F | --format) + _quota_formats + return + ;; + -f | --filesystem) + _filesystems + return + ;; + -p | --prototype) + _user_or_group + return + ;; + -h | --help | -V | --version) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + _quota_parse_help "$1" + else + _user_or_group + fi +} && + complete -F _edquota -o default edquota + +_quotacheck() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -F | --format) + _quota_formats + return + ;; + -h | --help | -V | --version) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + _quota_parse_help "$1" + else + _filesystems + fi +} && + complete -F _quotacheck -o default quotacheck repquota + +_quotaon() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -F | --format) + _quota_formats + return + ;; + -x | --xfs-command) + COMPREPLY=($(compgen -W 'delete enforce' -- "$cur")) + return + ;; + -h | --help | -V | --version) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + _quota_parse_help "$1" + else + _filesystems + fi +} && + complete -F _quotaon -o default quotaon quotaoff + +# ex: filetype=sh diff --git a/completions/radvdump b/completions/radvdump new file mode 100644 index 0000000..850628f --- /dev/null +++ b/completions/radvdump @@ -0,0 +1,22 @@ +# radvdump(8) completion -*- shell-script -*- + +_radvdump() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h | --help | -v | --version) + return + ;; + -d | --debug) + COMPREPLY=($(compgen -W '{1..4}' -- "$cur")) + return + ;; + esac + + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) +} && + complete -F _radvdump radvdump + +# ex: filetype=sh diff --git a/completions/rcs b/completions/rcs new file mode 100644 index 0000000..c04d89d --- /dev/null +++ b/completions/rcs @@ -0,0 +1,36 @@ +# bash completion for rcs -*- shell-script -*- + +_rcs() +{ + local cur prev words cword + _init_completion || return + + local file dir i + + file=${cur##*/} + dir=${cur%/*} + + # deal with relative directory + [[ $file == "$dir" ]] && dir=. + + COMPREPLY=($(compgen -f -- "$dir/RCS/$file")) + + for i in ${!COMPREPLY[*]}; do + file=${COMPREPLY[i]##*/} + dir=${COMPREPLY[i]%RCS/*} + COMPREPLY[i]=$dir$file + done + + COMPREPLY+=($(compgen -G "$dir/$file*,v")) + + for i in ${!COMPREPLY[*]}; do + COMPREPLY[i]=${COMPREPLY[i]%,v} + done + + # default to files if nothing returned and we're checking in. + # otherwise, default to directories + [[ ${#COMPREPLY[@]} -eq 0 && $1 == *ci ]] && _filedir || _filedir -d +} && + complete -F _rcs ci co rlog rcs rcsdiff + +# ex: filetype=sh diff --git a/completions/rdesktop b/completions/rdesktop new file mode 100644 index 0000000..54c1ae6 --- /dev/null +++ b/completions/rdesktop @@ -0,0 +1,57 @@ +# bash completion for rdesktop -*- shell-script -*- + +_rdesktop() +{ + local cur prev words cword + _init_completion -n : || return + + case $prev in + -*k) + COMPREPLY=($(command ls \ + /usr/share/rdesktop/keymaps 2>/dev/null | + command grep -E -v '(common|modifiers)')) + COMPREPLY+=($(command ls $HOME/.rdesktop/keymaps 2>/dev/null)) + COMPREPLY+=($(command ls ./keymaps 2>/dev/null)) + COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur")) + return + ;; + -*a) + COMPREPLY=($(compgen -W '8 15 16 24' -- "$cur")) + return + ;; + -*x) + COMPREPLY=($(compgen -W 'broadband modem lan' -- "$cur")) + return + ;; + -*r) + case $cur in + sound:*) + COMPREPLY=($(compgen -W 'local off remote' \ + -- "${cur#sound:}")) + ;; + *:*) ;; + + *) + COMPREPLY=($(compgen -W 'comport: disk: lptport: + printer: sound: lspci scard' -- "$cur")) + [[ ${COMPREPLY-} == *: ]] && compopt -o nospace + ;; + esac + return + ;; + -*[udscpngSTX]) + return + ;; + esac + + if [[ $cur == -* ]]; then + local opts=($(_parse_help "$1")) + COMPREPLY=($(compgen -W '${opts[@]%:}' -- "$cur")) + else + _known_hosts_real -- "$cur" + fi + +} && + complete -F _rdesktop rdesktop + +# ex: filetype=sh diff --git a/completions/remove_members b/completions/remove_members new file mode 100644 index 0000000..db7ad0b --- /dev/null +++ b/completions/remove_members @@ -0,0 +1,27 @@ +# mailman remove_members completion -*- shell-script -*- + +_remove_members() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -f | --file) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--file --all --fromall --nouserack + --noadminack --help' -- "$cur")) + else + _xfunc list_lists _mailman_lists + fi + +} && + complete -F _remove_members remove_members + +# ex: filetype=sh diff --git a/completions/removepkg b/completions/removepkg new file mode 100644 index 0000000..a56beb0 --- /dev/null +++ b/completions/removepkg @@ -0,0 +1,25 @@ +# Slackware Linux removepkg completion -*- shell-script -*- + +_removepkg() +{ + local cur prev words cword + _init_completion || return + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-copy -keep -preserve -warn' -- "$cur")) + return + fi + + if [[ $cur == */* ]]; then + _filedir + return + fi + + local root=${ROOT:-/} + COMPREPLY=($( + cd "$root/var/log/packages" 2>/dev/null || return 1 + compgen -f -- "$cur" + )) +} && + complete -F _removepkg removepkg + +# ex: filetype=sh diff --git a/completions/reportbug b/completions/reportbug new file mode 100644 index 0000000..69b12e9 --- /dev/null +++ b/completions/reportbug @@ -0,0 +1,96 @@ +# bash completion for (Debian) reportbug -*- shell-script -*- + +_reportbug() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --class | --header | --pseudo-header | --mirror | --list-cc | --subject | \ + --http_proxy | --proxy | --email | --realname | --smtpuser | --smtppasswd | \ + --replyto | --reply-to | --justification | --package-version | --body | \ + --body-file | --timeout | --max-attachment-size | --envelope-from | \ + -!(-*)[CHPsjV]) + return + ;; + --filename | --include | --mta | --output | --attach | -[fioA]) + _filedir + return + ;; + --keyid | -!(-*)K) + COMPREPLY=($(compgen -W '$(IFS=: ; \ + gpg --list-keys --with-colons 2>/dev/null \ + | while read -ra row ; do + [[ "${row[0]}" == [ps]ub && ${row[11]} == *s* ]] && \ + printf "%s\n" "${row[4]}" + done)' -- "$cur")) + return + ;; + --bts | -!(-*)B) + COMPREPLY=($(compgen -W "debian guug kde mandrake help" -- \ + "$cur")) + return + ;; + --editor | --mua | --mbox-reader-cmd | -!(-*)e) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + --mode) + COMPREPLY=($(compgen -W "novice standard expert" -- "$cur")) + return + ;; + --severity | -!(-*)S) + COMPREPLY=($(compgen -W "grave serious important normal minor + wishlist" -- "$cur")) + return + ;; + --ui | --interface | -!(-*)u) + COMPREPLY=($(compgen -W "newt text gnome" -- "$cur")) + return + ;; + --type | -!(-*)t) + COMPREPLY=($(compgen -W "gnats debbugs" -- "$cur")) + return + ;; + --tag | -!(-*)T) + COMPREPLY=($(compgen -W "none woody potato sarge sarge-ignore + etch etch-ignore lenny lenny-ignore sid experimental confirmed + d-i fixed fixed-in-experimental fixed-upstream help l10n + moreinfo patch pending security unreproducible upstream wontfix + ipv6 lfs" -- "$cur")) + return + ;; + --from-buildd) + COMPREPLY=($(compgen -S "_" -W '$(apt-cache dumpavail | \ + command grep "^Source: $cur" | sort -u | cut -f2 -d" ")')) + return + ;; + --smtphost) + _known_hosts_real -- "$cur" + return + ;; + --draftpath) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == -*= ]] && compopt -o nospace + return + fi + + COMPREPLY=($(compgen -W 'wnpp boot-floppies kernel bugs.debian.org + cdimage.debian.org general installation-reports listarchives + lists.debian.org mirrors nm.debian.org press project qa.debian.org + release-notes security.debian.org tech-ctte upgrade-reports + www.debian.org $(_xfunc apt-cache _apt_cache_packages)' -- "$cur")) + _filedir +} && + complete -F _reportbug reportbug + +# ex: filetype=sh diff --git a/completions/resolvconf b/completions/resolvconf new file mode 100644 index 0000000..b407488 --- /dev/null +++ b/completions/resolvconf @@ -0,0 +1,21 @@ +# bash completion for resolvconf -*- shell-script -*- + +_resolvconf() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -a | -d) + _available_interfaces + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-a -d -u' -- "$cur")) + fi +} && + complete -F _resolvconf resolvconf + +# ex: filetype=sh diff --git a/completions/ri b/completions/ri new file mode 100644 index 0000000..9c34b27 --- /dev/null +++ b/completions/ri @@ -0,0 +1,120 @@ +# ri completion for Ruby documentation -*- shell-script -*- +# by Ian Macdonald <ian@caliban.org> + +_ri_get_methods() +{ + local regex + + if [[ $ri_version == integrated ]]; then + if [[ -z $separator ]]; then + regex="(Instance|Class)" + elif [[ $separator == "#" ]]; then + regex=Instance + else + regex=Class + fi + + COMPREPLY+=( + "$(ri "${classes[@]}" 2>/dev/null | ruby -ane \ + 'if /^'"$regex"' methods:/.../^------------------|^$/ and \ + /^ / then print $_.split(/, |,$/).grep(/^[^\[]*$/).join("\n"); \ + end' 2>/dev/null | sort -u)") + else + # older versions of ri didn't distinguish between class/module and + # instance methods + COMPREPLY+=( + "$(ruby -W0 $ri_path "${classes[@]}" 2>/dev/null | ruby -ane \ + 'if /^-/.../^-/ and ! /^-/ and ! /^ +(class|module): / then \ + print $_.split(/, |,$| +/).grep(/^[^\[]*$/).join("\n"); \ + end' | sort -u)") + fi + COMPREPLY=($(compgen $prefix -W '${COMPREPLY[@]}' -- $method)) +} + +# needs at least Ruby 1.8.0 in order to use -W0 +_ri() +{ + local cur prev words cword split + _init_completion -s -n : || return + + case $prev in + --help | --width | -!(-*)[hw]) + return + ;; + --format | -!(-*)f) + COMPREPLY=($(compgen -W 'ansi bs html rdoc' -- "$cur")) + return + ;; + --doc-dir | -!(-*)d) + _filedir -d + return + ;; + --dump) + _filedir ri + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + local class method prefix ri_path ri_version ri_major separator IFS + local -a classes + + ri_path=$(type -p ri) + # which version of ri are we using? + # -W0 is required here to stop warnings from older versions of ri + # from being captured when used with Ruby 1.8.1 and later + ri_version="$(ruby -W0 $ri_path -v 2>&1)" || ri_version=integrated + [[ $ri_version != "${ri_version%200*}" ]] && ri_version=integrated + [[ $ri_version =~ ri[[:space:]]v?([0-9]+) ]] && ri_major=${BASH_REMATCH[1]} + + # need to also split on commas + IFS=$', \n\t' + if [[ $cur == [A-Z]*[#.]* ]]; then + [[ $cur == *#* ]] && separator=# || separator=. + # we're completing on class and method + class=${cur%$separator*} + method=${cur#*$separator} + classes=($class) + prefix="-P $class$separator" + _ri_get_methods + return + fi + + if [[ $ri_version == integrated ]]; then + # integrated ri from Ruby 1.9 + classes=($(ri -c 2>/dev/null | ruby -ne 'if /^\s*$/..$stdin.eof then \ + if /^ +[A-Z]/ then print; end; end' 2>/dev/null)) + elif [[ $ri_major && $ri_major -ge 3 ]]; then + classes=($(ri -l 2>/dev/null)) + elif [[ $ri_version == "ri 1.8a" ]]; then + classes=($(ruby -W0 $ri_path | + ruby -ne 'if /^'"'"'ri'"'"' has/..$stdin.eof then \ + if /^ .*[A-Z]/ then print; end; end')) + else + classes=($(ruby -W0 $ri_path | + ruby -ne 'if /^I have/..$stdin.eof then \ + if /^ .*[A-Z]/ then print; end; end')) + fi + + COMPREPLY=($(compgen -W '${classes[@]}' -- "$cur")) + __ltrim_colon_completions "$cur" + + if [[ $cur == [A-Z]* ]]; then + # we're completing on class or module alone + return + fi + + # we're completing on methods + method=$cur + _ri_get_methods +} && + complete -F _ri ri + +# ex: filetype=sh diff --git a/completions/rmlist b/completions/rmlist new file mode 100644 index 0000000..0cc473a --- /dev/null +++ b/completions/rmlist @@ -0,0 +1,17 @@ +# mailman rmlist completion -*- shell-script -*- + +_rmlist() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--archives --help' -- "$cur")) + else + _xfunc list_lists _mailman_lists + fi + +} && + complete -F _rmlist rmlist + +# ex: filetype=sh diff --git a/completions/rmmod b/completions/rmmod new file mode 100644 index 0000000..7ec29e6 --- /dev/null +++ b/completions/rmmod @@ -0,0 +1,24 @@ +# Linux rmmod(8) completion. -*- shell-script -*- +# This completes on a list of all currently installed kernel modules. + +_rmmod() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h | --help | -V | --version) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + _installed_modules "$cur" +} && + complete -F _rmmod rmmod + +# ex: filetype=sh diff --git a/completions/route b/completions/route new file mode 100644 index 0000000..f9b3196 --- /dev/null +++ b/completions/route @@ -0,0 +1,30 @@ +# Linux route(8) completion -*- shell-script -*- + +[[ $OSTYPE == *linux* ]] || return 1 + +_route() +{ + local cur prev words cword + _init_completion || return + + if [[ $prev == dev ]]; then + _available_interfaces + return + fi + + # Remove already given options from completions + local opt found i + for opt in add del -host -net netmask metric mss window irtt reject mod \ + dyn reinstate dev default gw; do + found=false + for ((i = 1; i < ${#words[@]} - 1; i++)); do + [[ ${words[i]} == "$opt" ]] && found=true && break + done + $found || COMPREPLY+=("$opt") + done + + COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur")) +} && + complete -F _route route + +# ex: filetype=sh diff --git a/completions/rpcdebug b/completions/rpcdebug new file mode 100644 index 0000000..6e2b88c --- /dev/null +++ b/completions/rpcdebug @@ -0,0 +1,46 @@ +# bash completion for rpcdebug -*- shell-script -*- + +_rpcdebug_flags() +{ + local i module + + for ((i = 1; i < ${#words[@]}; i++)); do + if [[ ${words[i]} == -m ]]; then + module=${words[i + 1]} + break + fi + done + + if [[ -n $module ]]; then + COMPREPLY=($(compgen -W "$(rpcdebug -vh 2>&1 | + command sed -ne 's/^'$module'[[:space:]]\{1,\}//p')" -- "$cur")) + fi +} + +_rpcdebug() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*s) + _rpcdebug_flags + return + ;; + -*c) + _rpcdebug_flags + return + ;; + -*m) + COMPREPLY=($(compgen -W 'rpc nfs nfsd nlm' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" -h) -s -c' -- "$cur")) + fi +} && + complete -F _rpcdebug rpcdebug + +# ex: filetype=sh diff --git a/completions/rpm b/completions/rpm new file mode 100644 index 0000000..8299a37 --- /dev/null +++ b/completions/rpm @@ -0,0 +1,302 @@ +# bash completion for rpm -*- shell-script -*- + +# helper functions + +_rpm_installed_packages() +{ + if [[ -r /var/log/rpmpkgs && \ + /var/log/rpmpkgs -nt /var/lib/rpm/Packages ]]; then + # using RHL 7.2 or later - this is quicker than querying the DB + COMPREPLY=($(compgen -W "$(command sed -ne \ + 's|^\([^[:space:]]\{1,\}\)-[^[:space:]-]\{1,\}-[^[:space:]-]\{1,\}\.rpm$|\1|p' \ + /var/log/rpmpkgs)" -- "$cur")) + elif type rpmqpack &>/dev/null; then + # SUSE's rpmqpack is faster than rpm -qa + COMPREPLY=($(compgen -W '$(rpmqpack)' -- "$cur")) + else + COMPREPLY=($(${1:-rpm} -qa --nodigest --nosignature \ + --queryformat='%{NAME} ' "$cur*" 2>/dev/null)) + fi +} + +_rpm_groups() +{ + local IFS=$'\n' + COMPREPLY=($(compgen -W "$(${1:-rpm} -qa --nodigest --nosignature \ + --queryformat='%{GROUP}\n' 2>/dev/null)" -- "$cur")) +} + +_rpm_macros() +{ + # get a list of macros + COMPREPLY=($(compgen -W "$(${1:-rpm} --showrc | command sed -ne \ + 's/^-\{0,1\}[0-9]\{1,\}[:=][[:space:]]\{1,\}\([^[:space:](]\{3,\}\).*/%\1/p')" \ + -- "$cur")) +} + +_rpm_buildarchs() +{ + COMPREPLY=($(compgen -W "$(${1:-rpm} --showrc | command sed -ne \ + 's/^\s*compatible\s\s*build\s\s*archs\s*:\s*\(.*\)/\1/ p')" \ + -- "$cur")) +} + +# rpm(8) completion +# +_rpm() +{ + local cur prev words cword split + _init_completion -s || return + + if ((cword == 1)); then + # first parameter on line + case $cur in + --*) + COMPREPLY=($(compgen -W '--help --version --initdb + --checksig --addsign --delsign --rebuilddb --showrc + --setperms --setugids --eval --install --upgrade --query + --freshen --erase --verify --querytags --import' \ + -- "$cur")) + ;; + *) + COMPREPLY=($(compgen -W '-e -E -F -i -q -t -U -V' -- "$cur")) + ;; + esac + return + fi + + case $prev in + --dbpath | --excludepath | --prefix | --relocate | --root | -!(-*)r) + _filedir -d + return + ;; + --eval | -!(-*)E) + _rpm_macros $1 + return + ;; + --pipe) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + --rcfile) + _filedir + return + ;; + --specfile) + # complete on .spec files + _filedir spec + return + ;; + --whatenhances | --whatprovides | --whatrecommends | --whatrequires | \ + --whatsuggests | --whatsupplements) + if [[ $cur == */* ]]; then + _filedir + else + # complete on capabilities + local IFS=$'\n' fmt + case $prev in + *enhances) fmt="%{ENHANCENAME}" ;; + *provides) fmt="%{PROVIDENAME}" ;; + *recommends) fmt="%{RECOMMENDNAME}" ;; + *requires) fmt="%{REQUIRENAME}" ;; + *suggests) fmt="%{SUGGESTNAME}" ;; + *supplements) fmt="%{SUPPLEMENTNAME}" ;; + esac + COMPREPLY=($(compgen -W "$($1 -qa --nodigest --nosignature \ + --queryformat=\"$fmt\\n\" 2>/dev/null | + command grep -vF '(none)')" -- "$cur")) + fi + return + ;; + --define | --fileid | --hdrid | --pkgid | -!(-*)D) + # argument required but no completions available + return + ;; + esac + + $split && return + + # options common to all modes + local opts="--define= --eval= --macros= --nodigest --nosignature --rcfile= + --quiet --pipe --verbose" + + case ${words[1]} in + -[iFU]* | --install | --freshen | --upgrade) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$opts --percent --force --test + --replacepkgs --replacefiles --root --excludedocs --includedocs + --noscripts --ignorearch --dbpath --prefix= --ignoreos --nodeps + --allfiles --ftpproxy --ftpport --justdb --httpproxy --httpport + --noorder --relocate= --badreloc --notriggers --excludepath= + --ignoresize --oldpackage --queryformat --repackage + --nosuggests" -- "$cur")) + else + _filedir '[rs]pm' + fi + ;; + -e | --erase) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$opts --allmatches --noscripts + --notriggers --nodeps --test --repackage" -- "$cur")) + else + _rpm_installed_packages $1 + fi + ;; + -q* | --query) + # options common to all query types + opts+=" --changelog --configfiles --conflicts --docfiles --dump + --enhances --filesbypkg --filecaps --fileclass --filecolor + --fileprovide --filerequire --filesbypkg --info --list + --obsoletes --pipe --provides --queryformat= --requires + --scripts --suggests --triggers --xml --recommends + --supplements --filetriggers --licensefiles" + + if [[ ${words[*]} == *\ -@(*([^ -])f|-file )* ]]; then + # -qf completion + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$opts --dbpath --fscontext + --last --root --state" -- "$cur")) + else + _filedir + fi + elif [[ ${words[*]} == *\ -@(*([^ -])g|-group )* ]]; then + # -qg completion + _rpm_groups $1 + elif [[ ${words[*]} == *\ -@(*([^ -])p|-package )* ]]; then + # -qp; uninstalled package completion + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$opts --ftpport --ftpproxy + --httpport --httpproxy --nomanifest" -- "$cur")) + else + _filedir '[rs]pm' + fi + else + # -q; installed package completion + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$opts --all --file --fileid + --dbpath --fscontext --ftswalk --group --hdrid --last + --package --pkgid --root= --specfile --state + --triggeredby --whatenhances --whatprovides + --whatrecommends --whatrequires --whatsuggests + --whatsupplements" \ + -- "$cur")) + elif [[ ${words[*]} != *\ -@(*([^ -])a|-all )* ]]; then + _rpm_installed_packages $1 + fi + fi + ;; + -K* | --checksig) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$opts --nopgp --nogpg --nomd5" \ + -- "$cur")) + else + _filedir '[rs]pm' + fi + ;; + -[Vy]* | --verify) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$opts --root= --dbpath --nodeps + --nogroup --nolinkto --nomode --nomtime --nordev --nouser + --nofiles --noscripts --nomd5 --querytags --specfile + --whatenhances --whatprovides --whatrecommends + --whatrequires --whatsuggests --whatsupplements" \ + -- "$cur")) + # check whether we're doing file completion + elif [[ ${words[*]} == *\ -@(*([^ -])f|-file )* ]]; then + _filedir + elif [[ ${words[*]} == *\ -@(*([^ -])g|-group )* ]]; then + _rpm_groups $1 + elif [[ ${words[*]} == *\ -@(*([^ -])p|-package )* ]]; then + _filedir '[rs]pm' + else + _rpm_installed_packages $1 + fi + ;; + --resign | --addsign | --delsign) + _filedir '[rs]pm' + ;; + --setperms | --setgids) + _rpm_installed_packages $1 + ;; + --import | --dbpath | --root) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--import --dbpath --root=' \ + -- "$cur")) + else + _filedir + fi + ;; + esac + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace +} && + complete -F _rpm rpm + +_rpmbuild() +{ + local cur prev words cword split + _init_completion -s || return + + local rpm="${1%build*}" + [[ $rpm == "$1" ]] || ! type $rpm &>/dev/null && rpm= + + case $prev in + --buildroot | --root | --dbpath | -!(-*)r) + _filedir -d + return + ;; + --target) + _rpm_buildarchs $rpm + return + ;; + --eval | -!(-*)E) + _rpm_macros $rpm + return + ;; + --macros | --rcfile) + _filedir + return + ;; + --buildpolicy) + local cfgdir=$($rpm --eval '%{_rpmconfigdir}' 2>/dev/null) + if [[ $cfgdir ]]; then + COMPREPLY=($(compgen -W "$(command ls $cfgdir 2>/dev/null | + command sed -ne 's/^brp-//p')" -- "$cur")) + fi + ;; + --define | --with | --without | -!(-*)D) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$(_parse_help "$1")" -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + # Figure out file extensions to complete + local word ext + for word in "${words[@]}"; do + case $word in + -b? | --clean | --nobuild) + ext=spec + break + ;; + -t? | --tarbuild) + ext='@(t?(ar.)@([gx]z|bz?(2))|tar?(.@(lzma|Z)))' + break + ;; + --rebuild | --recompile) + ext='@(?(no)src.r|s)pm' + break + ;; + esac + done + [[ -n $ext ]] && _filedir $ext +} && + complete -F _rpmbuild rpmbuild rpmbuild-md5 + +# ex: filetype=sh diff --git a/completions/rpm2tgz b/completions/rpm2tgz new file mode 100644 index 0000000..5ddcfd5 --- /dev/null +++ b/completions/rpm2tgz @@ -0,0 +1,17 @@ +# Slackware rpm2tgz completion -*- shell-script -*- + +_rpm2tgz() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-s -S -n -r -d -c' -- "$cur")) + return + fi + + _filedir "rpm" +} && + complete -F _rpm2tgz rpm2tgz rpm2txz rpm2targz + +# ex: filetype=sh diff --git a/completions/rpmcheck b/completions/rpmcheck new file mode 100644 index 0000000..cf4ed95 --- /dev/null +++ b/completions/rpmcheck @@ -0,0 +1,24 @@ +# bash completion for rpmcheck -*- shell-script -*- + +_rpmcheck() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -base) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-explain -failures -successes -dump + -dump-all -base -help -compressed-input' -- "$cur")) + else + _filedir + fi +} && + complete -F _rpmcheck rpmcheck + +# ex: filetype=sh diff --git a/completions/rrdtool b/completions/rrdtool new file mode 100644 index 0000000..dcb9ce6 --- /dev/null +++ b/completions/rrdtool @@ -0,0 +1,17 @@ +# bash completion for rrdtool -*- shell-script -*- + +_rrdtool() +{ + local cur prev words cword + _init_completion || return + + if ((${#words[@]} == 2)); then + COMPREPLY=($(compgen -W 'create update updatev graph dump restore + last lastupdate first info fetch tune resize xport' -- "$cur")) + else + _filedir rrd + fi +} && + complete -F _rrdtool rrdtool + +# ex: filetype=sh diff --git a/completions/rsync b/completions/rsync new file mode 100644 index 0000000..0bf5389 --- /dev/null +++ b/completions/rsync @@ -0,0 +1,86 @@ +# bash completion for rsync -*- shell-script -*- + +_rsync() +{ + local cur prev words cword split + _init_completion -s -n : || return + + case $prev in + --config | --password-file | --include-from | --exclude-from | --files-from | \ + --log-file | --write-batch | --only-write-batch | --read-batch) + compopt +o nospace + _filedir + return + ;; + --temp-dir | --compare-dest | --backup-dir | --partial-dir | --copy-dest | \ + --link-dest | -!(-*)T) + compopt +o nospace + _filedir -d + return + ;; + --rsh | -!(-*)e) + compopt +o nospace + COMPREPLY=($(compgen -W 'rsh ssh' -- "$cur")) + return + ;; + --compress-level) + compopt +o nospace + COMPREPLY=($(compgen -W '{1..9}' -- "$cur")) + return + ;; + esac + + $split && return + + _expand || return + + case $cur in + -*) + COMPREPLY=($(compgen -W '--verbose --quiet --no-motd --checksum + --archive --recursive --relative --no-implied-dirs + --backup --backup-dir= --suffix= --update --inplace --append + --append-verify --dirs --old-dirs --links --copy-links + --copy-unsafe-links --safe-links --copy-dirlinks + --keep-dirlinks --hard-links --perms --executability --chmod= + --acls --xattrs --owner --group --devices --copy-devices + --specials --times --omit-dir-times --super --fake-super + --sparse --dry-run --whole-file --no-whole-file + --one-file-system --block-size= --rsh= --rsync-path= + --existing --ignore-existing --remove-source-files --delete + --delete-before --delete-during --delete-delay --delete-after + --delete-excluded --ignore-errors --force --max-delete= + --max-size= --min-size= --partial --partial-dir= + --delay-updates --prune-empty-dirs --numeric-ids --timeout= + --contimeout= --ignore-times --size-only --modify-window= + --temp-dir= --fuzzy --compare-dest= --copy-dest= --link-dest= + --compress --compress-level= --skip-compress= --cvs-exclude + --filter= --exclude= --exclude-from= --include= --include-from= + --files-from= --from0 --protect-args --address= --port= + --sockopts= --blocking-io --no-blocking-io --stats + --8-bit-output --human-readable --progress --itemize-changes + --out-format= --log-file= --log-file-format= --password-file= + --list-only --bwlimit= --write-batch= --only-write-batch= + --read-batch= --protocol= --iconv= --ipv4 --ipv6 --version + --help --daemon --config= --no-detach' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] || compopt +o nospace + ;; + *:*) + # find which remote shell is used + local i shell=ssh + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == -@(e|-rsh) ]]; then + shell=${words[i + 1]} + break + fi + done + [[ $shell == ssh ]] && _xfunc ssh _scp_remote_files + ;; + *) + _known_hosts_real -c -a -- "$cur" + _xfunc ssh _scp_local_files + ;; + esac +} && + complete -F _rsync -o nospace rsync + +# ex: filetype=sh diff --git a/completions/sbcl b/completions/sbcl new file mode 100644 index 0000000..22a93e4 --- /dev/null +++ b/completions/sbcl @@ -0,0 +1,21 @@ +# -*- shell-script -*- +# bash programmable completion for various Common Lisp implementations by +# Nikodemus Siivola <nikodemus@random-state.net> + +_sbcl() +{ + local cur prev words cword + _init_completion || return + + # completing an option (may or may not be separated by a space) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--core --noinform --help --version + --sysinit --userinit --eval --noprint --disable-debugger + --end-runtime-options --end-toplevel-options ' -- "$cur")) + else + _filedir + fi +} && + complete -F _sbcl sbcl sbcl-mt + +# ex: filetype=sh diff --git a/completions/sbopkg b/completions/sbopkg new file mode 100644 index 0000000..16bd58f --- /dev/null +++ b/completions/sbopkg @@ -0,0 +1,73 @@ +# bash completion for sbopkg(8) -*- shell-script -*- + +_sbopkg() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + [[ ${COMPREPLY-} ]] && return + fi + + case "$prev" in + -e) + COMPREPLY=($(compgen -W 'ask continue stop' -- "$cur")) + return + ;; + -f) + _filedir + return + ;; + -d) + _filedir -d + return + ;; + -V) + COMPREPLY=($(compgen -W "? + $(sbopkg -V '?' 2>&1 | cut -s -f1)" -- "$cur")) + return + ;; + -i | -b) ;; + + *) + return + ;; + esac + + local i config + config="/etc/sbopkg/sbopkg.conf" + for ((i = ${#words[@]} - 1; i > 0; i--)); do + if [[ ${words[i]} == -f ]]; then + config="${words[i + 1]}" + __expand_tilde_by_ref config + break + fi + done + + [[ -r $config ]] || return + . $config + + for ((i = 1; i < ${#words[@]}; i++)); do + case "${words[i]}" in + -V) + REPO_NAME="${words[i + 1]%%/*}" + REPO_BRANCH="${words[i + 1]#*/}" + ;; + -d) + REPO_ROOT="${words[i + 1]}" + ;; + esac + done + [[ -r $REPO_ROOT/$REPO_NAME/$REPO_BRANCH/SLACKBUILDS.TXT ]] || return + + COMPREPLY=($(command sed -ne "/^SLACKBUILD NAME: $cur/{s/^SLACKBUILD NAME: //;p}" \ + $REPO_ROOT/$REPO_NAME/$REPO_BRANCH/SLACKBUILDS.TXT) + $( + cd $QUEUEDIR + compgen -f -X "!*.sqf" -- "$cur" + )) +} && + complete -F _sbopkg sbopkg + +# ex: filetype=sh diff --git a/completions/screen b/completions/screen new file mode 100644 index 0000000..651ca2c --- /dev/null +++ b/completions/screen @@ -0,0 +1,123 @@ +# bash completion for screen -*- shell-script -*- + +_screen_sessions() +{ + local sessions=($(command screen -ls | command sed -ne \ + 's|^\t\{1,\}\([0-9]\{1,\}\.[^\t]\{1,\}\).*'"$1"'.*$|\1|p')) + if [[ $cur == +([0-9])?(.*) ]]; then + # Complete sessions including pid prefixes + COMPREPLY=($(compgen -W '${sessions[@]}' -- "$cur")) + else + # Create unique completions, dropping pids where possible + local -A res + local i tmp + for i in "${sessions[@]}"; do + res[${i/#+([0-9])./}]+=" $i" + done + for i in "${!res[@]}"; do + [[ ${res[i]} == \ *\ * ]] && tmp+=" ${res[i]}" || tmp+=" $i" + done + COMPREPLY=($(compgen -W '$tmp' -- "$cur")) + fi +} && + _screen() + { + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + if [[ $cur == /dev* ]]; then + COMPREPLY=($(compgen -W "$( + shopt -s nullglob + printf '%s\n' \ + /dev/serial/by-id/* /dev/ttyUSB* /dev/ttyACM* 2>/dev/null + )" \ + -- "$cur")) + return + fi + if [[ $cur == //* ]]; then + COMPREPLY=($(compgen -W '//telnet' -- "$cur")) + return + fi + fi + + case ${words[1]} in + /dev*) + if ((cword == 2)); then + COMPREPLY=($(compgen -W '110 300 600 1200 2400 4800 9600 \ + 14400 19200 38400 57600 115200 128000 256000' -- "$cur")) + # TODO more, comma separated options + fi + return + ;; + //telnet) + ((cword == 2)) && _known_hosts_real -- "$cur" + return + ;; + esac + + if ((cword > 2)); then + case ${words[cword - 2]} in + -*[dD]) + _screen_sessions + return + ;; + esac + fi + + local i + for ((i = 1; i <= cword; i++)); do + case ${words[i]} in + -*[rRdDxscTehpSt]) + ((i++)) + continue + ;; + -*) + continue + ;; + esac + + _command_offset $i + return + done + + case $prev in + -*[rR]) + # list detached + _screen_sessions 'Detached' + return + ;; + -*[dD]) + # list attached + _screen_sessions 'Attached' + return + ;; + -*x) + # list both + _screen_sessions + return + ;; + -*s) + _shells + return + ;; + -*c) + _filedir + return + ;; + -T) + _terms + return + ;; + -*[ehpSt]) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + fi + } && + complete -F _screen screen + +# ex: filetype=sh diff --git a/completions/scrub b/completions/scrub new file mode 100644 index 0000000..bbb37be --- /dev/null +++ b/completions/scrub @@ -0,0 +1,36 @@ +# scrub(1) completion -*- shell-script -*- + +_scrub() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --version | --help | --blocksize | --device-size | --dirent | -!(-*)[vhbsD]) + return + ;; + --pattern | -!(-*)p) + COMPREPLY=($(compgen -W '$("$1" --help 2>&1 | + awk "/^Available/{flag=1;next}/^ /&&flag{print \$1}")' \ + -- "$cur")) + return + ;; + --freespace | -!(-*)X) + _filedir -d + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir +} && + complete -F _scrub scrub + +# ex: filetype=sh diff --git a/completions/secret-tool b/completions/secret-tool new file mode 100644 index 0000000..5462fc0 --- /dev/null +++ b/completions/secret-tool @@ -0,0 +1,50 @@ +# bash completion for secret-tool(1) -*- shell-script -*- + +_secret_tool() +{ + local cur prev words cword split + _init_completion -s || return + + $split && return + + local -i i + local mode word + for i in ${!words[*]}; do + if [[ $i -gt 0 && ${words[i]} != -* ]]; then + ((i != cword)) && mode=${words[i]} + break + fi + done + if [[ ! -v mode ]]; then + local -a modes + modes=($("$1" nonexistent-mode 2>&1 | + while read -r first second third rest; do + if [[ $first == "${1##*/}" ]]; then + printf "%s\n" "$second" + elif [[ $first == usage: && $second == "${1##*/}" ]]; then + printf "%s\n" "$third" + fi + done)) + COMPREPLY=($(compgen -W '${modes[@]}' -- "$cur")) + return + fi + + case $mode in + store) + if [[ ${words[*]} != *\ --label[\ =]* ]]; then + COMPREPLY=($(compgen -W "--label=" -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi + ;; + search) + local -A opts=([--all]="" [--unlock]="") + for word in "${words[@]:2}"; do + [[ $word ]] && unset opts["$word"] + done + COMPREPLY=($(compgen -W '${opts[@]}' -- "$cur")) + ;; + esac +} && + complete -F _secret_tool secret-tool + +# ex: filetype=sh diff --git a/completions/sh b/completions/sh new file mode 100644 index 0000000..5624ffa --- /dev/null +++ b/completions/sh @@ -0,0 +1,36 @@ +# POSIX sh(1) completion -*- shell-script -*- + +_sh() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -c) + return + ;; + -o | +o) + COMPREPLY=($(compgen -W 'allexport errexit ignoreeof monitor + noclobber noglob noexec nolog notify nounset verbose vi + xtrace' -- "$cur")) + return + ;; + esac + + local opts="-a -b -C -e -f -h -i -m -n -o -u -v -x" + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W "$opts -c -s" -- "$cur")) + return + elif [[ $cur == +* ]]; then + COMPREPLY=($(compgen -W "${opts//-/+}" -- "$cur")) + return + fi + + local args ext= + _count_args "" "@(-c|[-+]o)" + ((args == 1)) && ext="sh" + _filedir $ext +} && + complete -F _sh sh + +# ex: filetype=sh diff --git a/completions/shellcheck b/completions/shellcheck new file mode 100644 index 0000000..6421d7b --- /dev/null +++ b/completions/shellcheck @@ -0,0 +1,63 @@ +# bash completion for shellcheck(1) -*- shell-script -*- + +_shellcheck_optarg() +{ + local args=$("$1" --help 2>&1 | + command sed -e 's/,/ /g' -ne 's/^.*'$2'\>.*(\([^)]*\)).*/\1/p') + COMPREPLY+=($(compgen -W '$args' -- "$cur")) +} + +_shellcheck() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --version | -!(-*)V*) + return + ;; + --exclude | --include | -!(-*)[ei]) + return + ;; + --format | -!(-*)f) + local args=$("$1" --format=nonexistent-format /dev/null 2>&1 | + command sed -ne '/^Supported formats/,//p' | + command sed -ne '/^[[:space:]]/p') + COMPREPLY=($(compgen -W '$args' -- "$cur")) + return + ;; + --color | -!(-*)C) + _shellcheck_optarg "$1" --color + return + ;; + --shell | -!(-*)s) + _shellcheck_optarg "$1" --shell + return + ;; + --enable | -!(-*)o) + COMPREPLY=($(compgen -W 'all' -- "$cur")) # TODO others? + return + ;; + --source-path | -!(-*)P) + _filedir -d + COMPREPLY+=($(compgen -W 'SCRIPTDIR' -- "$cur")) + return + ;; + --wiki-link-count | -!(-*)W) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir +} && + complete -F _shellcheck shellcheck + +# ex: filetype=sh diff --git a/completions/sitecopy b/completions/sitecopy new file mode 100644 index 0000000..8515687 --- /dev/null +++ b/completions/sitecopy @@ -0,0 +1,50 @@ +# sitecopy(1) completion -*- shell-script -*- +# Copyright 2003 Eelco Lempsink <eelcolempsink@gmx.net> +# 2011 Raphaël Droz <raphael.droz+floss@gmail.com> +# License: GNU GPL v2 or later + +_sitecopy() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --debug | -!(-*)d) + COMPREPLY=($(compgen -W "socket files rcfile ftp http httpbody + rsh sftp xml xmlparse cleartext" -- "$cur")) + compopt -o nospace + return + ;; + --logfile | --rcfile | -!(-*)[gr]) + _filedir + return + ;; + --storepath | -!(-*)p) + _filedir -d + return + ;; + esac + + case $cur in + --*) + COMPREPLY=($(compgen -W "$(_parse_help $1)" -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + ;; + + # only complete long options + -) + compopt -o nospace + COMPREPLY=(--) + return + ;; + esac + + if [[ -r ~/.sitecopyrc ]]; then + COMPREPLY=($(compgen -W "$($1 -v | + command sed -n '/^Site:/s/Site: //p')" -- "$cur")) + fi +} && + complete -F _sitecopy -o default sitecopy + +# ex: filetype=sh diff --git a/completions/slackpkg b/completions/slackpkg new file mode 100644 index 0000000..1d87928 --- /dev/null +++ b/completions/slackpkg @@ -0,0 +1,112 @@ +# bash completion for slackpkg(8) -*- shell-script -*- +# options list is based on `grep '\-.*\=.*)' /usr/sbin/slackpkg | cut -f1 -d\)` + +_slackpkg() +{ + local cur prev words cword + _init_completion -n = || return + + local split=false + if [[ $cur == -?*=* ]]; then + prev="${cur%%?(\\)=*}" + cur="${cur#*=}" + split=true + fi + + case "$prev" in + -delall | -checkmd5 | -checkgpg | -checksize | -postinst | -onoff | -download_all | \ + -dialog | -batch | -only_new_dotnew | -use_includes | -spinning) + COMPREPLY=($(compgen -W 'on off' -- "$cur")) + return + ;; + -default_answer) + COMPREPLY=($(compgen -W 'yes no' -- "$cur")) + return + ;; + -dialog_maxargs | -mirror) + # argument required but no completions available + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + compopt -o nospace + COMPREPLY=($(compgen -W '-delall= -checkmd5= -checkgpg= + -checksize= -postinst= -onoff= -download_all= -dialog= + -dialog_maxargs= -batch= -only_new_dotnew= -use_includes= + -spinning= -default_answer= -mirror=' -- "$cur")) + return + fi + + local confdir="/etc/slackpkg" + local config="$confdir/slackpkg.conf" + + [[ -r $config ]] || return + . "$config" + + local i action + for ((i = 1; i < ${#words[@]}; i++)); do + if [[ ${words[i]} != -* ]]; then + action="${words[i]}" + break + fi + done + + case "$action" in + generate-template | search | file-search) + # argument required but no completions available + return + ;; + install-template | remove-template) + if [[ -e $confdir/templates ]]; then + COMPREPLY=($( + cd "$confdir/templates" + compgen -f -X "!*.template" -- "$cur" + )) + COMPREPLY=(${COMPREPLY[@]%.template}) + fi + return + ;; + remove) + _filedir + COMPREPLY+=($(compgen -W 'a ap d e f k kde kdei l n t tcl x + xap xfce y' -- "$cur")) + COMPREPLY+=($( + cd /var/log/packages + compgen -f -- "$cur" + )) + return + ;; + install | reinstall | upgrade | blacklist | download) + _filedir + COMPREPLY+=($(compgen -W 'a ap d e f k kde kdei l n t tcl x + xap xfce y' -- "$cur")) + COMPREPLY+=($(cut -f 6 -d\ "${WORKDIR}/pkglist" 2>/dev/null | + command grep "^$cur")) + return + ;; + info) + COMPREPLY=($(cut -f 6 -d\ "${WORKDIR}/pkglist" 2>/dev/null | + command grep "^$cur")) + return + ;; + update) + # we should complete the same as the next `list` + "gpg" + COMPREPLY=($(compgen -W 'gpg' -- "$cur")) + ;& + *) + COMPREPLY+=($(compgen -W 'install reinstall upgrade remove + blacklist download update install-new upgrade-all + clean-system new-config check-updates help generate-template + install-template remove-template search file-search info' -- \ + "$cur")) + return + ;; + esac + +} && + complete -F _slackpkg slackpkg + +# ex: filetype=sh diff --git a/completions/slapt-get b/completions/slapt-get new file mode 100644 index 0000000..14c2dbe --- /dev/null +++ b/completions/slapt-get @@ -0,0 +1,86 @@ +# slapt-get(8) completion -*- shell-script -*- + +_slapt_get() +{ + local cur prev words cword + _init_completion || return + + case "$prev" in + --config | -c) + _filedir + return + ;; + --retry | --search) + # argument required but no completions available + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --help)' -- "$cur")) + if [[ ${COMPREPLY-} ]]; then + [[ $COMPREPLY == *= ]] && compopt -o nospace + return + fi + fi + + local i t + # search for last action (--install|--install-set|--remove|--show|--filelist) + for ((i = ${#words[@]} - 1; i > 0; i--)); do + if [[ ${words[i]} == --show ]]; then + t="all" + break + elif [[ ${words[i]} == -@(i|-install) ]]; then + t="avl" + break + elif [[ ${words[i]} == --install-set ]]; then + t="set" + break + elif [[ ${words[i]} == --@(remove|filelist) ]]; then + t="ins" + break + fi + done + + local config="/etc/slapt-get/slapt-getrc" # default config location + # search for config + for ((i = ${#words[@]} - 1; i > 0; i--)); do + if [[ ${words[i]} == -@(c|-config) ]]; then + config="${words[i + 1]}" + __expand_tilde_by_ref config + break + fi + done + [[ -r $config ]] || return + + case $t in + all) # --show + # slapt-get will fail to search for "^name-version" + # it can search for names only + local name=${cur%%-*} + COMPREPLY=($(LC_ALL=C "$1" -c "$config" --search "^$name" \ + 2>/dev/null | LC_ALL=C command sed -ne "/^$cur/{s/ .*$//;p}")) + return + ;; + avl) # --install|-i| + COMPREPLY=($(LC_ALL=C "$1" -c "$config" --available \ + 2>/dev/null | LC_ALL=C command sed -ne "/^$cur/{s/ .*$//;p}")) + return + ;; + ins) # --remove|--filelist + COMPREPLY=($( + cd /var/log/packages + compgen -f -- "$cur" + )) + return + ;; + set) # --install-set + COMPREPLY=($(compgen -W 'a ap d e f k kde kdei l n t tcl x + xap xfce y' -- "$cur")) + return + ;; + esac +} && + complete -F _slapt_get slapt-get + +# ex: filetype=sh diff --git a/completions/slapt-src b/completions/slapt-src new file mode 100644 index 0000000..1e3828c --- /dev/null +++ b/completions/slapt-src @@ -0,0 +1,68 @@ +# slapt-src(8) completion -*- shell-script -*- + +_slapt_src() +{ + local cur prev words cword split + _init_completion -s -n : || return + + case "$prev" in + --config | -c) + _filedir + return + ;; + --search | -s | --postprocess | -p) + # argument required but no completions available + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --help)' -- "$cur")) + if [[ ${COMPREPLY-} ]]; then + [[ $COMPREPLY == *= ]] && compopt -o nospace + return + fi + fi + + local i t + # search for last action (-i|-w|-b|-f) + for ((i = ${#words[@]} - 1; i > 0; i--)); do + if [[ ${words[i]} == -@([iwfb]|-install|-show|-build|-fetch) ]]; then + t="all" + break + fi + done + if [[ $t != all ]]; then + return + fi + + local config="/etc/slapt-get/slapt-srcrc" # default config location + # search for config + for ((i = ${#words[@]} - 1; i > 0; i--)); do + if [[ ${words[i]} == -@(c|-config) ]]; then + config="${words[i + 1]}" + __expand_tilde_by_ref config + break + fi + if [[ ${words[i]} == --config=?* ]]; then + config="${words[i]#*=}" + break + fi + done + [[ -r $config ]] || return + + if [[ $cur == *:* ]]; then + local name=${cur%:*} + COMPREPLY=($(LC_ALL=C "$1" --config "$config" --search "^$name" \ + 2>/dev/null | LC_ALL=C command sed -ne \ + "/^$cur/{s/^$name:\([^ ]*\) .*$/\1/;p}")) + else + COMPREPLY=($(LC_ALL=C "$1" --config "$config" --search "^$cur" \ + 2>/dev/null | LC_ALL=C command sed -ne "/^$cur/{s/ .*$//;p}")) + fi +} && + complete -F _slapt_src slapt-src + +# ex: filetype=sh diff --git a/completions/smartctl b/completions/smartctl new file mode 100644 index 0000000..ee45a7c --- /dev/null +++ b/completions/smartctl @@ -0,0 +1,165 @@ +# bash completion for smartctl(8) -*- shell-script -*- + +_smartctl_quietmode() +{ + COMPREPLY=($(compgen -W 'errorsonly silent noserial' -- "$cur")) +} +_smartctl_device() +{ + case $cur in + areca* | 3ware* | megaraid* | cciss*) + # shellcheck disable=SC2054 + COMPREPLY+=(${cur%%,*},{0..31}) + COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur")) + ;; + hpt*) + # shellcheck disable=SC2054 + COMPREPLY+=(hpt,{1..4}/{1..8} hpt,{1..4}/{1..8}/{1..5}) + COMPREPLY=($(compgen -W '"${COMPREPLY[@]}"' -- "$cur")) + ;; + *) + COMPREPLY=($(compgen -W "ata scsi sat usbcypress usbjmicron + usbsunplus marvell areca 3ware hpt megaraid cciss auto test" \ + -- "$cur")) + case "${COMPREPLY[@]}" in + areca | 3ware | hpt | megaraid | cciss) + compopt -o nospace + ;; + esac + ;; + esac +} +_smartctl_tolerance() +{ + COMPREPLY=($(compgen -W 'normal conservative permissive verypermissive' \ + -- "$cur")) +} +_smartctl_badsum() +{ + COMPREPLY=($(compgen -W 'warn exit ignore' -- "$cur")) +} +_smartctl_report() +{ + COMPREPLY=($(compgen -W 'ioctl ataioctl scsiioctl' -- "$cur")) +} +_smartctl_powermode() +{ + COMPREPLY=($(compgen -W 'never sleep standby idle' -- "$cur")) +} +_smartctl_feature() +{ + COMPREPLY=($(compgen -W 'on off' -- "$cur")) +} +_smartctl_log() +{ + COMPREPLY=($(compgen -W 'error selftest selective directory background + sasphy sasphy,reset sataphy sataphy,reset scttemp scttempsts + scttemphist scterc gplog smartlog xerror xselftest' -- "$cur")) +} +_smartctl_vendorattribute() +{ + COMPREPLY=($(compgen -W 'help 9,minutes 9,seconds 9,halfminutes 9,temp + 192,emergencyretractcyclect 193,loadunload 194,10xCelsius 194,unknown + 198,offlinescanuncsectorct 200,writeerrorcount 201,detectedtacount + 220,temp' -- "$cur")) +} +_smartctl_firmwarebug() +{ + COMPREPLY=($(compgen -W 'none samsung samsung2 samsung3 swapid' \ + -- "$cur")) +} +_smartctl_presets() +{ + COMPREPLY=($(compgen -W 'use ignore show showall' -- "$cur")) +} +_smartctl_test() +{ + [[ $cur == @(pending|scttempint|vendor), ]] && return + COMPREPLY=($(compgen -W 'offline short long conveyance select, + select,redo select,next afterselect,on afterselect,off pending, + scttempint, vendor,' -- "$cur")) + [[ ${COMPREPLY-} == *, ]] && compopt -o nospace +} +_smartctl_drivedb() +{ + local prefix= + if [[ $cur == +* ]]; then + prefix=+ + cur="${cur#+}" + fi + _filedir h + [[ -n $prefix ]] && COMPREPLY=("${COMPREPLY[@]/#/$prefix}") +} + +_smartctl() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --quietmode | -!(-*)q) + _smartctl_quietmode + ;; + --device | -!(-*)d) + _smartctl_device + return + ;; + --tolerance | -!(-*)T) + _smartctl_tolerance + return + ;; + --badsum | -!(-*)b) + _smartctl_badsum + return + ;; + --report | -!(-*)r) + _smartctl_report + return + ;; + --nocheck | -!(-*)n) + _smartctl_powermode + return + ;; + --smart | --offlineauto | --saveauto | -!(-*)[soS]) + _smartctl_feature + return + ;; + --log | -!(-*)l) + _smartctl_log + return + ;; + --vendorattribute | -!(-*)v) + _smartctl_vendorattribute + return + ;; + --firmwarebug | -!(-*)F) + _smartctl_firmwarebug + return + ;; + --presets | -!(-*)P) + _smartctl_presets + return + ;; + --drivedb | -!(-*)B) + _smartctl_drivedb + return + ;; + --test | -!(-*)t) + _smartctl_test + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + cur=${cur:=/dev/} + _filedir + fi +} && + complete -F _smartctl smartctl + +# ex: filetype=sh diff --git a/completions/smbclient b/completions/smbclient new file mode 100644 index 0000000..cea2107 --- /dev/null +++ b/completions/smbclient @@ -0,0 +1,322 @@ +# bash completion for samba -*- shell-script -*- + +_samba_resolve_order() +{ + COMPREPLY=($(compgen -W 'lmhosts host wins bcast' -- "$cur")) +} + +_samba_domains() +{ + if [[ -n ${COMP_SAMBA_SCAN:-} ]]; then + COMPREPLY=($(compgen -W '$(smbtree -N -D)' -- "$cur")) + fi +} + +_samba_hosts() +{ + if [[ -n ${COMP_SAMBA_SCAN:-} ]]; then + COMPREPLY=($(compgen -W "$( + smbtree -N -S | + command sed -ne 's/^[[:space:]]*\\\\*\([^[:space:]]*\).*/\1/p' + )" -- "$cur")) + fi +} + +_samba_debuglevel() +{ + COMPREPLY=($(compgen -W '{0..10}' -- "$cur")) +} + +_samba_sockopts() +{ + COMPREPLY=($(compgen -W 'SO_KEEPALIVE SO_REUSEADDR SO_BROADCAST + TCP_NODELAY IPTOS_LOWDELAY IPTOS_THROUGHPUT SO_SNDBUF SO_RCVBUF + SO_SNDLOWAT SO_RCVLOWAT' -- "$cur")) +} + +_samba_signing() +{ + COMPREPLY=($(compgen -W 'on off required' -- "$cur")) +} + +_smbclient() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --name-resolve | -!(-*)R) + _samba_resolve_order + return + ;; + -!(-*)t) + COMPREPLY=($(compgen -W 'SJIS EUC JIS7 JIS8 JUNET HEX CAP' \ + -- "$cur")) + return + ;; + --configfile | --authentication-file | -!(-*)[sA]) + _filedir + return + ;; + --log-basename | --directory | -!(-*)[lD]) + _filedir -d + return + ;; + --socket-options | -!(-*)O) + _samba_sockopts + return + ;; + -!(-*)T) + COMPREPLY=($(compgen -W 'c x I X F b g q r N a' -- "$cur")) + return + ;; + --workgroup | -!(-*)W) + _samba_domains + return + ;; + --debuglevel | -!(-*)d) + _samba_debuglevel + return + ;; + --list | -!(-*)L) + _samba_hosts + return + ;; + --signing | -!(-*)S) + _samba_signing + return + ;; + --port | --message | --ip-address | --send-buffer | --user | --netbiosname | \ + --scope | --tar | --command | --max-protocol | -!(-*)[pMIbUniTcm]) + return + ;; + --help | --version | -!(-*)[?V]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _smbclient smbclient + +_smbget() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --outputfile | --rcfile | -!(-*)[of]) + _filedir + return + ;; + --debuglevel | -!(-*)d) + _samba_debuglevel + return + ;; + --workgroup | -!(-*)w) + _samba_domains + return + ;; + --username | --password | --blocksize | -!(-*)[upb]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _smbget smbget + +_smbcacls() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --configfile | --authentication-file | -!(-*)[As]) + _filedir + return + ;; + --log-basename | -!(-*)l) + _filedir -d + return + ;; + --debuglevel | -!(-*)d) + _samba_debuglevel + return + ;; + --signing) + _samba_signing + return + ;; + --socket-options | -!(-*)O) + _samba_sockopts + return + ;; + --workgroup | -!(-*)W) + _samba_domains + return + ;; + --help | --usage | --delete | --modify | --add | --set | --chown | --chgrp | \ + --netbiosname | --scope | --user | -!(-*)[?DMaSCGniU]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _smbcacls smbcacls + +_smbcquotas() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --configfile | --authentication-file | -!(-*)[sA]) + _filedir + return + ;; + --log-basename | -!(-*)l) + _filedir -d + return + ;; + --debuglevel | -!(-*)d) + _samba_debuglevel + return + ;; + --signing) + _samba_signing + return + ;; + --help | --usage | --user | --set | -!(-*)[?UuS]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _smbcquotas smbcquotas + +_smbpasswd() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*r) + _samba_hosts + return + ;; + -*R) + _samba_resolve_order + return + ;; + -*c) + _filedir + return + ;; + -*D) + _samba_debuglevel + return + ;; + -*[Uhw]) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + fi +} && + complete -F _smbpasswd smbpasswd + +_smbtar() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*[rt]) + _filedir tar + return + ;; + -*s) + _samba_hosts + return + ;; + -*l) + _samba_debuglevel + return + ;; + -*N) + _filedir + return + ;; + -*[pxbdu]) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + fi +} && + complete -F _smbtar smbtar + +_smbtree() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --configfile | --authentication-file | -!(-*)[sA]) + _filedir + return + ;; + --log-basename | -!(-*)l) + _filedir -d + return + ;; + --debuglevel | -!(-*)d) + _samba_debuglevel + return + ;; + --signing | -!(-*)S) + _samba_signing + return + ;; + --help | --usage | --user | -!(-*)[?U]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _smbtree smbtree + +# ex: filetype=sh diff --git a/completions/snownews b/completions/snownews new file mode 100644 index 0000000..5b585d9 --- /dev/null +++ b/completions/snownews @@ -0,0 +1,15 @@ +# snownews(1) completion -*- shell-script -*- + +_snownews() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + # return list of available options + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + fi +} && + complete -F _snownews snownews + +# ex: filetype=sh diff --git a/completions/sqlite3 b/completions/sqlite3 new file mode 100644 index 0000000..26d38a1 --- /dev/null +++ b/completions/sqlite3 @@ -0,0 +1,38 @@ +# sqlite3(1) completion -*- shell-script -*- + +_sqlite3() +{ + local cur prev words cword + _init_completion || return + + local dbexts='@(sqlite?(3)|?(s?(3))db)' + + case $prev in + -help | -version | -lookaside | -mmap | -newline | -nullvalue | -pagecache | \ + -scratch | -separator | *.$dbexts) + return + ;; + -init) + _filedir + return + ;; + -cmd) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + esac + + [[ $cword -gt 2 && ${words[cword - 2]} == -@(lookaside|pagecache|scratch) ]] && + return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + return + fi + + _filedir "$dbexts" +} && + complete -F _sqlite3 sqlite3 + +# ex: filetype=sh diff --git a/completions/ss b/completions/ss new file mode 100644 index 0000000..4a27d51 --- /dev/null +++ b/completions/ss @@ -0,0 +1,41 @@ +# ss(8) completion -*- shell-script -*- + +_ss() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | -!(-*)[hV]) + return + ;; + --family | -!(-*)f) + COMPREPLY=($(compgen -W 'unix inet inet6 link netlink' \ + -- "$cur")) + return + ;; + --query | -!(-*)A) + local prefix= + [[ $cur == *,* ]] && prefix="${cur%,*}," + COMPREPLY=($(compgen -W '$("$1" --help | \ + command sed -e "s/|/ /g" -ne "s/.*QUERY := {\([^}]*\)}.*/\1/p")' \ + -- "${cur##*,}")) + ((${#COMPREPLY[@]} == 1)) && COMPREPLY=(${COMPREPLY/#/$prefix}) + return + ;; + --diag | --filter | -!(-*)[DF]) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _ss ss + +# ex: filetype=sh diff --git a/completions/ssh b/completions/ssh new file mode 100644 index 0000000..907c039 --- /dev/null +++ b/completions/ssh @@ -0,0 +1,563 @@ +# ssh(1) completion -*- shell-script -*- + +_ssh_queries() +{ + COMPREPLY+=($(compgen -W \ + "cipher cipher-auth help mac kex key key-cert key-plain key-sig + protocol-version compression sig + ciphers macs kexalgorithms pubkeyacceptedkeytypes + hostkeyalgorithms hostbasedkeytypes hostbasedacceptedkeytypes" \ + -- "${cur,,}")) +} + +_ssh_query() +{ + ${1:-ssh} -Q $2 2>/dev/null +} + +_ssh_ciphers() +{ + local ciphers='$(_ssh_query "$1" cipher)' + [[ $ciphers ]] || ciphers="3des-cbc aes128-cbc aes192-cbc aes256-cbc + aes128-ctr aes192-ctr aes256-ctr arcfour128 arcfour256 arcfour + blowfish-cbc cast128-cbc" + COMPREPLY+=($(compgen -W "$ciphers" -- "$cur")) +} + +_ssh_macs() +{ + local macs='$(_ssh_query "$1" mac)' + [[ $macs ]] || macs="hmac-md5 hmac-sha1 umac-64@openssh.com hmac-ripemd160 + hmac-sha1-96 hmac-md5-96" + COMPREPLY+=($(compgen -W "$macs" -- "$cur")) +} + +_ssh_options() +{ + local opts=( + AddKeysToAgent AddressFamily BatchMode BindAddress CanonicalDomains + CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots + CanonicalizePermittedCNAMEs CASignatureAlgorithms CertificateFile + ChallengeResponseAuthentication CheckHostIP Ciphers ClearAllForwardings + Compression ConnectionAttempts ConnectTimeout ControlMaster ControlPath + ControlPersist DynamicForward EnableSSHKeysign EscapeChar + ExitOnForwardFailure FingerprintHash ForwardAgent ForwardX11 + ForwardX11Timeout ForwardX11Trusted GatewayPorts GlobalKnownHostsFile + GSSAPIAuthentication GSSAPIClientIdentity GSSAPIDelegateCredentials + GSSAPIKeyExchange GSSAPIRenewalForcesRekey GSSAPIServerIdentity + GSSAPITrustDns HashKnownHosts Host HostbasedAuthentication + HostbasedKeyTypes HostKeyAlgorithms HostKeyAlias HostName + IdentitiesOnly IdentityAgent IdentityFile IgnoreUnknown Include IPQoS + KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms + LocalCommand LocalForward LogLevel MACs + NoHostAuthenticationForLocalhost NumberOfPasswordPrompts + PasswordAuthentication PermitLocalCommand PKCS11Provider Port + PreferredAuthentications ProxyCommand ProxyJump ProxyUseFdpass + PubkeyAcceptedKeyTypes PubkeyAuthentication RekeyLimit RemoteCommand + RemoteForward RequestTTY RevokedHostKeys SendEnv ServerAliveCountMax + ServerAliveInterval SmartcardDevice StreamLocalBindMask + StreamLocalBindUnlink StrictHostKeyChecking SyslogFacility TCPKeepAlive + Tunnel TunnelDevice UpdateHostKeys UsePrivilegedPort User + UserKnownHostsFile VerifyHostKeyDNS VisualHostKey XAuthLocation) + local protocols=$(_ssh_query "$1" protocol-version) + if [[ -z $protocols || $protocols == *1* ]]; then + opts+=(Cipher CompressionLevel Protocol RhostsRSAAuthentication + RSAAuthentication) + fi + + compopt -o nospace + local IFS=$' \t\n' reset=$(shopt -p nocasematch) + shopt -s nocasematch + local option + COMPREPLY=($(for option in "${opts[@]}"; do + [[ $option == "$cur"* ]] && printf '%s=\n' "$option" + done)) + $reset +} + +# Complete a ssh suboption (like ForwardAgent=y<tab>) +# Two parameters: the string to complete including the equal sign, and +# the ssh executable to invoke (optional). +# Not all suboptions are completed. +# Doesn't handle comma-separated lists. +_ssh_suboption() +{ + # Split into subopt and subval + local prev=${1%%=*} cur=${1#*=} + + case ${prev,,} in + batchmode | canonicaldomains | canonicalizefallbacklocal | \ + challengeresponseauthentication | checkhostip | \ + clearallforwardings | controlpersist | compression | enablesshkeysign | \ + exitonforwardfailure | forwardagent | forwardx11 | forwardx11trusted | \ + gatewayports | gssapiauthentication | gssapikeyexchange | \ + gssapidelegatecredentials | gssapirenewalforcesrekey | gssapitrustdns | \ + hashknownhosts | hostbasedauthentication | identitiesonly | \ + kbdinteractiveauthentication | kbdinteractivedevices | \ + nohostauthenticationforlocalhost | passwordauthentication | permitlocalcommand | \ + proxyusefdpass | pubkeyauthentication | rhostsrsaauthentication | \ + rsaauthentication | streamlocalbindunlink | \ + tcpkeepalive | useprivilegedport | visualhostkey) + COMPREPLY=($(compgen -W 'yes no' -- "$cur")) + ;; + addkeystoagent) + COMPREPLY=($(compgen -W 'yes ask confirm no' -- "$cur")) + ;; + addressfamily) + COMPREPLY=($(compgen -W 'any inet inet6' -- "$cur")) + ;; + bindaddress) + _ip_addresses + ;; + canonicalizehostname) + COMPREPLY=($(compgen -W 'yes no always' -- "$cur")) + ;; + identityfile) + _ssh_identityfile + ;; + *file | identityagent | include | controlpath | revokedhostkeys | xauthlocation) + _filedir + ;; + casignaturealgorithms) + COMPREPLY=($(compgen -W '$(_ssh_query "$2" sig)' -- "$cur")) + ;; + cipher) + COMPREPLY=($(compgen -W 'blowfish des 3des' -- "$cur")) + ;; + ciphers) + _ssh_ciphers "$2" + ;; + controlmaster) + COMPREPLY=($(compgen -W 'yes ask auto autoask no' -- "$cur")) + ;; + compressionlevel) + COMPREPLY=($(compgen -W '{1..9}' -- "$cur")) + ;; + fingerprinthash) + COMPREPLY=($(compgen -W 'md5 sha256' -- "$cur")) + ;; + ipqos) + COMPREPLY=($(compgen -W 'af1{1..4} af2{2..3} af3{1..3} af4{1..3} + cs{0..7} ef lowdelay throughput reliability' -- "$cur")) + ;; + hostbasedkeytypes | hostkeyalgorithms) + COMPREPLY=($(compgen -W '$(_ssh_query "$2" key)' -- "$cur")) + ;; + kexalgorithms) + COMPREPLY=($(compgen -W '$(_ssh_query "$2" kex)' -- "$cur")) + ;; + loglevel) + COMPREPLY=($(compgen -W 'QUIET FATAL ERROR INFO VERBOSE DEBUG{,1,2,3}' -- "$cur")) + ;; + macs) + _ssh_macs "$2" + ;; + pkcs11provider) + _filedir so + ;; + preferredauthentications) + COMPREPLY=($(compgen -W 'gssapi-with-mic host-based publickey + keyboard-interactive password' -- "$cur")) + ;; + protocol) + local protocols=($(_ssh_query "$2" protocol-version)) + [[ $protocols ]] || protocols=(1 2) + if ((${#protocols[@]} > 1)); then + COMPREPLY=($(compgen -W '${protocols[@]}' -- "$cur")) + fi + ;; + proxyjump) + _known_hosts_real -a ${configfile:+-F "$configfile"} -- "$cur" + ;; + proxycommand | remotecommand | localcommand) + COMPREPLY=($(compgen -c -- "$cur")) + ;; + pubkeyacceptedkeytypes) + COMPREPLY=($(compgen -W '$(_ssh_query "$2" key)' -- "$cur")) + ;; + requesttty) + COMPREPLY=($(compgen -W 'no yes force auto' -- "$cur")) + ;; + stricthostkeychecking) + COMPREPLY=($(compgen -W 'accept-new ask no off' -- "$cur")) + ;; + syslogfacility) + COMPREPLY=($(compgen -W 'DAEMON USER AUTH LOCAL{0..7}' -- "$cur")) + ;; + tunnel) + COMPREPLY=($(compgen -W 'yes no point-to-point ethernet' \ + -- "$cur")) + ;; + updatehostkeys | verifyhostkeydns) + COMPREPLY=($(compgen -W 'yes no ask' -- "$cur")) + ;; + esac + return 0 +} + +# Try to complete -o SubOptions= +# +# Returns 0 if the completion was handled or non-zero otherwise. +_ssh_suboption_check() +{ + # Get prev and cur words without splitting on = + local cureq=$(_get_cword :=) preveq=$(_get_pword :=) + if [[ $cureq == *=* && $preveq == -*o ]]; then + _ssh_suboption $cureq "$1" + return $? + fi + return 1 +} + +# Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument +_ssh_configfile() +{ + set -- "${words[@]}" + while (($# > 0)); do + if [[ $1 == -F* ]]; then + if ((${#1} > 2)); then + configfile="$(dequote "${1:2}")" + else + shift + [[ ${1-} ]] && configfile="$(dequote "$1")" + fi + break + fi + shift + done +} + +# With $1 set, look for public key files, else private +# shellcheck disable=SC2120 +_ssh_identityfile() +{ + [[ -z $cur && -d ~/.ssh ]] && cur=~/.ssh/id + _filedir + if ((${#COMPREPLY[@]} > 0)); then + COMPREPLY=($(compgen -W '${COMPREPLY[@]}' \ + -X "${1:+!}*.pub" -- "$cur")) + fi +} + +_ssh() +{ + local cur prev words cword + _init_completion -n : || return + + local configfile + _ssh_configfile + + _ssh_suboption_check "$1" && return + + local ipvx + + case $prev in + -*b) + _ip_addresses + return + ;; + -*c) + _ssh_ciphers "$1" + return + ;; + -*[DeLpRW]) + return + ;; + -*[EFS]) + _filedir + return + ;; + -*i) + _ssh_identityfile + return + ;; + -*I) + _filedir so + return + ;; + -*J) + _known_hosts_real -a ${configfile:+-F "$configfile"} -- "$cur" + return + ;; + -*l) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + -*m) + _ssh_macs "$1" + return + ;; + -*O) + COMPREPLY=($(compgen -W 'check forward cancel exit stop' -- "$cur")) + return + ;; + -*o) + _ssh_options "$1" + return + ;; + -*Q) + _ssh_queries "$1" + return + ;; + -*w) + _available_interfaces + return + ;; + -*4*) + ipvx=-4 + ;; + -*6*) + ipvx=-6 + ;; + esac + + if [[ $cur == -F* ]]; then + cur=${cur#-F} + _filedir + # Prefix completions with '-F' + COMPREPLY=("${COMPREPLY[@]/#/-F}") + cur=-F$cur # Restore cur + elif [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + else + _known_hosts_real ${ipvx-} -a ${configfile:+-F "$configfile"} -- "$cur" + + local args + _count_args + if ((args > 1)); then + compopt -o filenames + COMPREPLY+=($(compgen -c -- "$cur")) + fi + fi +} && + shopt -u hostcomplete && complete -F _ssh ssh slogin autossh sidedoor + +# sftp(1) completion +# +_sftp() +{ + local cur prev words cword + _init_completion || return + + local configfile + _ssh_configfile + + _ssh_suboption_check && return + + local ipvx + + case $prev in + -*[BDlPRs]) + return + ;; + -*[bF]) + _filedir + return + ;; + -*i) + _ssh_identityfile + return + ;; + -*c) + _ssh_ciphers + return + ;; + -*J) + _known_hosts_real -a ${configfile:+-F "$configfile"} -- "$cur" + return + ;; + -*o) + _ssh_options + return + ;; + -*S) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + -*4*) + ipvx=-4 + ;; + -*6*) + ipvx=-6 + ;; + esac + + if [[ $cur == -F* ]]; then + cur=${cur#-F} + _filedir + # Prefix completions with '-F' + COMPREPLY=("${COMPREPLY[@]/#/-F}") + cur=-F$cur # Restore cur + elif [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + else + _known_hosts_real ${ipvx-} -a ${configfile:+-F "$configfile"} -- "$cur" + fi +} && + shopt -u hostcomplete && complete -F _sftp sftp + +# things we want to backslash escape in scp paths +# shellcheck disable=SC2089 +_scp_path_esc='[][(){}<>"'"'"',:;^&!$=?`\\|[:space:]]' + +# Complete remote files with ssh. If the first arg is -d, complete on dirs +# only. Returns paths escaped with three backslashes. +# shellcheck disable=SC2120 +_scp_remote_files() +{ + local IFS=$'\n' + + # remove backslash escape from the first colon + cur=${cur/\\:/:} + + local userhost=${cur%%?(\\):*} + local path=${cur#*:} + + # unescape (3 backslashes to 1 for chars we escaped) + # shellcheck disable=SC2090 + path=$(command sed -e 's/\\\\\\\('$_scp_path_esc'\)/\\\1/g' <<<"$path") + + # default to home dir of specified user on remote host + if [[ -z $path ]]; then + path=$(ssh -o 'Batchmode yes' $userhost pwd 2>/dev/null) + fi + + local files + if [[ $1 == -d ]]; then + # escape problematic characters; remove non-dirs + # shellcheck disable=SC2090 + files=$(ssh -o 'Batchmode yes' $userhost \ + command ls -aF1dL "$path*" 2>/dev/null | + command sed -e 's/'$_scp_path_esc'/\\\\\\&/g' -e '/[^\/]$/d') + else + # escape problematic characters; remove executables, aliases, pipes + # and sockets; add space at end of file names + # shellcheck disable=SC2090 + files=$(ssh -o 'Batchmode yes' $userhost \ + command ls -aF1dL "$path*" 2>/dev/null | + command sed -e 's/'$_scp_path_esc'/\\\\\\&/g' -e 's/[*@|=]$//g' \ + -e 's/[^\/]$/& /g') + fi + COMPREPLY+=($files) +} + +# This approach is used instead of _filedir to get a space appended +# after local file/dir completions, and -o nospace retained for others. +# If first arg is -d, complete on directory names only. The next arg is +# an optional prefix to add to returned completions. +_scp_local_files() +{ + local IFS=$'\n' + + local dirsonly=false + if [[ ${1-} == -d ]]; then + dirsonly=true + shift + fi + + if $dirsonly; then + COMPREPLY+=($(command ls -aF1dL $cur* 2>/dev/null | + command sed -e "s/$_scp_path_esc/\\\\&/g" -e '/[^\/]$/d' -e "s/^/${1-}/")) + else + COMPREPLY+=($(command ls -aF1dL $cur* 2>/dev/null | + command sed -e "s/$_scp_path_esc/\\\\&/g" -e 's/[*@|=]$//g' \ + -e 's/[^\/]$/& /g' -e "s/^/${1-}/")) + fi +} + +# scp(1) completion +# +_scp() +{ + local cur prev words cword + _init_completion -n : || return + + local configfile + _ssh_configfile + + _ssh_suboption_check && { + COMPREPLY=("${COMPREPLY[@]/%/ }") + return + } + + local ipvx + + case $prev in + -*c) + _ssh_ciphers + COMPREPLY=("${COMPREPLY[@]/%/ }") + return + ;; + -*F) + _filedir + compopt +o nospace + return + ;; + -*i) + _ssh_identityfile + compopt +o nospace + return + ;; + -*J) + _known_hosts_real -a ${configfile:+-F "$configfile"} -- "$cur" + return + ;; + -*[lP]) + return + ;; + -*o) + _ssh_options + return + ;; + -*S) + compopt +o nospace -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + -*4*) + ipvx=-4 + ;; + -*6*) + ipvx=-6 + ;; + esac + + _expand || return + + case $cur in + !(*:*)/* | [.~]*) ;; # looks like a path + *:*) + _scp_remote_files + return + ;; + esac + + local prefix + + if [[ $cur == -F* ]]; then + cur=${cur#-F} + prefix=-F + else + case $cur in + -*) + COMPREPLY=($(compgen -W '$(_parse_usage "${words[0]}")' \ + -- "$cur")) + COMPREPLY=("${COMPREPLY[@]/%/ }") + return + ;; + */* | [.~]*) + # not a known host, pass through + ;; + *) + _known_hosts_real ${ipvx-} -c -a \ + ${configfile:+-F "$configfile"} -- "$cur" + ;; + esac + fi + + _scp_local_files "${prefix-}" +} && + complete -F _scp -o nospace scp + +# ex: filetype=sh diff --git a/completions/ssh-add b/completions/ssh-add new file mode 100644 index 0000000..d8f7492 --- /dev/null +++ b/completions/ssh-add @@ -0,0 +1,35 @@ +# ssh-add(1) completion -*- shell-script -*- + +_ssh_add() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*E) + COMPREPLY=($(compgen -W 'md5 sha256' -- "$cur")) + return + ;; + -*t) + return + ;; + -*T) + _filedir + return + ;; + -*[se]) + _filedir so + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" "-\?")' -- "$cur")) + return + fi + + _filedir +} && + complete -F _ssh_add ssh-add + +# ex: filetype=sh diff --git a/completions/ssh-copy-id b/completions/ssh-copy-id new file mode 100644 index 0000000..f628194 --- /dev/null +++ b/completions/ssh-copy-id @@ -0,0 +1,32 @@ +# ssh-copy-id(1) completion -*- shell-script -*- + +_ssh_copy_id() +{ + local cur prev words cword + _init_completion || return + + _xfunc ssh _ssh_suboption_check "$1" && return + + case $prev in + -i) + _xfunc ssh _ssh_identityfile pub + return + ;; + -p) + return + ;; + -o) + _xfunc ssh _ssh_options + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1" --help)' -- "$cur")) + else + _known_hosts_real -a -- "$cur" + fi +} && + complete -F _ssh_copy_id ssh-copy-id + +# ex: filetype=sh diff --git a/completions/ssh-keygen b/completions/ssh-keygen new file mode 100644 index 0000000..0e629a5 --- /dev/null +++ b/completions/ssh-keygen @@ -0,0 +1,123 @@ +# ssh-keygen(1) completion -*- shell-script -*- + +_ssh_keygen() +{ + local cur prev words cword + _init_completion -n := || return + + case $prev in + -*[aCIJjMNPSVWz]) + return + ;; + -*b) + local -a sizes + case "${words[*]}" in + *" -t dsa"?( *)) + sizes=(1024) + ;; + *" -t ecdsa"?( *)) + sizes=(256 384 521) + ;; + *" -t rsa"?( *)) + sizes=(1024 2048 3072 4096) + ;; + esac + COMPREPLY=($(compgen -W '${sizes[@]}' -- "$cur")) + return + ;; + -*E) + COMPREPLY=($(compgen -W 'md5 sha256' -- "$cur")) + return + ;; + -*[FR]) + # TODO: trim this down to actual entries in known hosts files + _known_hosts_real -- "$cur" + return + ;; + -*[Dw]) + _filedir so + return + ;; + -*[fGKsT]) + _filedir + return + ;; + -*m) + COMPREPLY=($(compgen -W 'PEM PKCS8 RFC4716' -- "$cur")) + return + ;; + -*n) + [[ ${words[*]} != *\ -*Y\ * ]] || return + local prefix= + [[ $cur == *,* ]] && prefix="${cur%,*}," + if [[ ${words[*]} == *\ -*h\ * ]]; then + _known_hosts_real -- "${cur##*,}" + else + COMPREPLY=($(compgen -u -- "${cur##*,}")) + fi + ((${#COMPREPLY[@]} == 1)) && COMPREPLY=(${COMPREPLY/#/$prefix}) + return + ;; + -*O) + if [[ $cur != *=* ]]; then + COMPREPLY=($(compgen -W ' + clear critical: extension: force-command= + no-agent-forwarding no-port-forwarding no-pty no-user-rc + no-x11-forwarding permit-agent-forwarding + permit-port-forwarding permit-pty permit-user-rc + permit-X11-forwarding no-touch-required source-address= + + lines= start-line= checkpoint= memory= start= generator= + + application challenge= device resident user + write-attestation-path + ' -- "$cur")) + [[ ${COMPREPLY-} == *[:=] ]] && compopt -o nospace + __ltrim_colon_completions "$cur" + else + case $cur in + force-command=*) + compopt -o filenames + COMPREPLY=($(compgen -c -- "${cur#*=}")) + ;; + checkpoint=* | challenge=*) + cur=${cur#*=} + _filedir + ;; + esac + fi + return + ;; + -*r) + [[ ${words[*]} != *\ -*Y\ * ]] || _filedir + return + ;; + -*t) + local protocols=$(_xfunc ssh _ssh_query "$1" protocol-version) + local types='dsa ecdsa ecdsa-sk ed25519 ed25519-sk rsa' + if [[ $protocols == *1* ]]; then + types+=' rsa1' + fi + COMPREPLY=($(compgen -W "$types" -- "$cur")) + return + ;; + -*Y) + COMPREPLY=($(compgen -W 'find-principals check-novalidate sign + verify' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + local opts=$(_parse_usage "$1" "-?") + [[ -z $opts ]] && opts=$(_parse_help "$1" "-?") # OpenSSH < 7 + COMPREPLY=($(compgen -W "$opts" -- "$cur")) + fi + + if [[ ${words[*]} == *\ -*s\ * ]]; then + _filedir pub + fi +} && + complete -F _ssh_keygen ssh-keygen + +# ex: filetype=sh diff --git a/completions/sshfs b/completions/sshfs new file mode 100644 index 0000000..223d029 --- /dev/null +++ b/completions/sshfs @@ -0,0 +1,23 @@ +# sshfs(1) completion -*- shell-script -*- + +_sshfs() +{ + local cur prev words cword + _init_completion -n : || return + + _expand || return + + if [[ $cur == *:* ]]; then + _xfunc ssh _scp_remote_files -d + # unlike scp and rsync, sshfs works with 1 backslash instead of 3 + COMPREPLY=("${COMPREPLY[@]//\\\\\\/\\}") + return + fi + + [[ $cur == @(*/|[.~])* ]] || _known_hosts_real -c -a -- "$cur" + + _xfunc ssh _scp_local_files -d +} && + complete -F _sshfs -o nospace sshfs + +# ex: filetype=sh diff --git a/completions/sshmitm b/completions/sshmitm new file mode 100644 index 0000000..ee893e5 --- /dev/null +++ b/completions/sshmitm @@ -0,0 +1,17 @@ +# sshmitm completion -*- shell-script -*- + +_sshmitm() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + else + _known_hosts_real -- "$cur" + fi + +} && + complete -F _sshmitm sshmitm + +# ex: filetype=sh diff --git a/completions/sshow b/completions/sshow new file mode 100644 index 0000000..917444e --- /dev/null +++ b/completions/sshow @@ -0,0 +1,26 @@ +# sshow completion -*- shell-script -*- + +_sshow() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*i) + _available_interfaces -a + return + ;; + -*p) + _filedir pcap + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + fi + +} && + complete -F _sshow sshow + +# ex: filetype=sh diff --git a/completions/strace b/completions/strace new file mode 100644 index 0000000..2b46ce8 --- /dev/null +++ b/completions/strace @@ -0,0 +1,99 @@ +# bash completion for strace -*- shell-script -*- + +_strace() +{ + local cur prev words cword + _init_completion -n = || return + + # check if we're still completing strace + local offset=0 i + for ((i = 1; i <= cword; i++)); do + case ${words[i]} in + -o | -e | -p) + ((i++)) + continue + ;; + -*) + continue + ;; + esac + offset=$i + break + done + + if ((offset > 0)); then + _command_offset $offset + else + + case $prev in + -*e) + if [[ $cur == *=* ]]; then + prev=${cur/=*/} + cur=${cur/*=/} + + case $prev in + trace) + # Import arch-specific syscalls + #+ -- not foolproof IMHO --David Paleino + local define syscall rest + local -A syscalls + while read -r define syscall rest; do + [[ $define == "#define" && \ + $syscall =~ ^__NR_(.+) ]] && + syscalls[${BASH_REMATCH[1]}]=1 + done 2>/dev/null </usr/include/asm/unistd.h + if [[ ! $syscalls ]]; then + local unistd arch=$(command uname -m) + if [[ $arch == *86 ]]; then + unistd=/usr/include/asm/unistd_32.h + else + unistd=/usr/include/asm/unistd_64.h + fi + while read -r define syscall rest; do + [[ $define == "#define" && \ + $syscall =~ ^__NR_(.+) ]] && + syscalls[${BASH_REMATCH[1]}]=1 + done 2>/dev/null <$unistd + fi + + COMPREPLY=($(compgen -W '${!syscalls[@]} file + process network signal ipc desc all none' \ + -- "$cur")) + return + ;; + esac + else + compopt -o nospace + COMPREPLY=($(compgen -S"=" -W 'trace abbrev verbose raw + signal read write' -- "$cur")) + fi + return + ;; + -*o) + _filedir + return + ;; + -*p) + _pids + return + ;; + -*S) + COMPREPLY=($(compgen -W 'time calls name nothing' -- "$cur")) + return + ;; + -*u) + _allowed_users + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + else + COMPREPLY=($(compgen -c -- "$cur")) + fi + fi +} && + complete -F _strace -o default strace + +# ex: filetype=sh diff --git a/completions/strings b/completions/strings new file mode 100644 index 0000000..059f557 --- /dev/null +++ b/completions/strings @@ -0,0 +1,45 @@ +# strings(1) completion -*- shell-script -*- + +_strings() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | --bytes | -!(-*)[hvVn]) + return + ;; + --radix | -!(-*)t) + COMPREPLY=($(compgen -W 'o d x' -- "$cur")) + return + ;; + --target | -!(-*)T) + COMPREPLY=($(compgen -W '$(LC_ALL=C "$1" --help 2>/dev/null | \ + command sed -ne "s/: supported targets: \(.*\)/\1/p")' \ + -- "$cur")) + return + ;; + --encoding | -!(-*)e) + COMPREPLY=($(compgen -W 's S b l B L' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + elif [[ $cur == @* ]]; then + cur=${cur:1} + _filedir + COMPREPLY=("${COMPREPLY[@]/#/@}") + return + fi + + _filedir +} && + complete -F _strings strings + +# ex: filetype=sh diff --git a/completions/sudo b/completions/sudo new file mode 100644 index 0000000..c9a806b --- /dev/null +++ b/completions/sudo @@ -0,0 +1,56 @@ +# bash completion for sudo(8) -*- shell-script -*- + +_sudo() +{ + local cur prev words cword split + _init_completion -s || return + + local i mode=normal + [[ $1 == *sudoedit ]] && mode=edit + + [[ $mode == normal ]] && + for ((i = 1; i <= cword; i++)); do + if [[ ${words[i]} != -* ]]; then + local PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin + local root_command=${words[i]} + _command_offset $i + return + fi + if [[ ${words[i]} == -@(!(-*)e*|-edit) ]]; then + mode=edit + break + fi + [[ ${words[i]} == \ + -@(user|other-user|group|close-from|prompt|!(-*)[uUgCp]) ]] && + ((i++)) + done + + case "$prev" in + --user | --other-user | -!(-*)[uU]) + COMPREPLY=($(compgen -u -- "$cur")) + return + ;; + --group | -!(-*)g) + COMPREPLY=($(compgen -g -- "$cur")) + return + ;; + --close-from | --prompt | -!(-*)[Cp]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + if [[ $mode == edit ]]; then + _filedir + fi +} && + complete -F _sudo sudo sudoedit + +# ex: filetype=sh diff --git a/completions/svcadm b/completions/svcadm new file mode 100644 index 0000000..5269c7b --- /dev/null +++ b/completions/svcadm @@ -0,0 +1,150 @@ +# svcadm completion -*- shell-script -*- +# +# Copyright 2006 Yann Rouillard <yann@opencsw.org> + +# +# svcadm accept any complete FMRI or abbreviated FMRI +# - a complete FMRI is svc:/foo/bar/bar/baz +# - abbreviated FMRI are foo/bar/bar/baz, bar/bar/baz, bar/baz or baz +# +# The goal of this function is to be able to propose all alternatives, +# but to not clutter the interface with all completions, we will only +# cut every completion alternative at the next slash. +# +# For example, if the user types <nothing><tab>, we will propose for svc://foo/bar/bar/baz +# the following completion: foo/, bar/ and baz +# If the user types <b><tab>, we will propose: bar/ and baz +# If the user types <bar/><tab>, we will propose: bar/bar/ and bar/baz +# +# By default, the function proproses only abbreviated completions except if the user already +# began to type svc:. In that case we will propose only the complete FMRI beginning with the +# pattern +# +_smf_complete_fmri() +{ + local cur="$1" prefix="$2" + local cur_prefix fmri fmri_list="" + local exact_mode pattern + + if [[ $cur == $prefix* ]]; then + [[ $cur == "$prefix" ]] && cur+="/" + pattern="$cur*" + exact_mode=1 + else + pattern="$prefix*/$cur*" + fi + + cur_prefix="${cur%"${cur##*/}"}" + + for fmri in $(svcs -H -o FMRI "$pattern" 2>/dev/null); do + local fmri_part_list fmri_part + if [[ -z $exact_mode ]]; then + fmri=${fmri#$prefix/} + + # we generate all possibles abbrevations for the FMRI + # no need to have a generic loop as we will have a finite + # number of components + local ifs="$IFS" + IFS="/" + set -- $fmri + IFS=$ifs + case $# in + 1) fmri_part_list=" $1" ;; + 2) fmri_part_list=" $2 $1/$2" ;; + 3) fmri_part_list=" $3 $2/$3 $1/$2/$3" ;; + 4) fmri_part_list=" $4 $3/$4 $2/$3/$4 $1/$2/$3/$4" ;; + esac + else + fmri_part_list="$fmri" + fi + + # Here we make sure the completions begins with the pattern and + # we cut them at the first slash + for fmri_part in $fmri_part_list; do + [[ $fmri_part == $cur* ]] || continue + local first_part=${fmri_part#$cur_prefix} + first_part=$cur_prefix${first_part%%/*} + [[ $first_part != "$fmri_part" ]] && first_part+="/" + fmri_list+=" $first_part" + done + done + + COMPREPLY=($fmri_list) + + # here we want to detect if there only one completion proposed and that + # it ends with a slash. That means the users will still have to complete + # after, so we gain him one tab keystroke by immediately proposing the + # next completion alternatives + local i=${#COMPREPLY[*]} + if [[ $i -gt 0 && ${COMPREPLY[--i]} == */ ]]; then + # we have to iterate through the list as we may have duplicate + while ((i != 0)); do + [[ ${COMPREPLY[i]} != "${COMPREPLY[i - 1]}" ]] && break + ((i--)) + done + if ((i == 0)); then + _smf_complete_fmri "${COMPREPLY[0]}" "$prefix" + return + fi + fi + + # Work-around bash_completion issue where bash interprets a colon + # as a separator, borrowed from maven completion code which borrowed + # it from darcs completion code :) + local colonprefixes=${cur%"${cur##*:}"} + local i=${#COMPREPLY[*]} + while ((i-- > 0)); do + COMPREPLY[i]=${COMPREPLY[i]#"$colonprefixes"} + done +} + +_svcadm() +{ + local cur prev words cword + _init_completion -n : || return + + local command_list="enable disable restart refresh clear mark milestone" + local command i + + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == @(enable|disable|restart|refresh|clear|mark|milestone) ]]; then + command=${words[i]} + fi + done + + if [[ ! -v command ]]; then + if [[ ${cur} == -* ]]; then + COMPREPLY=($(compgen -W "-v" -- ${cur})) + else + COMPREPLY=($(compgen -W "$command_list" -- ${cur})) + fi + else + if [[ ${cur} == -* ]]; then + case "$command" in + enable) + COMPREPLY=($(compgen -W "-r -s -t" -- ${cur})) + ;; + disable) + COMPREPLY=($(compgen -W "-s -t" -- ${cur})) + ;; + mark) + COMPREPLY=($(compgen -W "-I -t" -- ${cur})) + ;; + milestone) + COMPREPLY=($(compgen -W "-d" -- ${cur})) + ;; + esac + else + if [[ $command == "mark" ]] && [[ $prev != @(degraded|maintenance) ]]; then + COMPREPLY=($(compgen -W "degraded maintenance" -- ${cur})) + elif [[ $command == "milestone" ]]; then + _smf_complete_fmri "${cur}" "svc:/milestone" + else + _smf_complete_fmri "${cur}" "svc:" + fi + fi + fi +} && + complete -F _svcadm svcadm + +# ex: filetype=sh diff --git a/completions/svk b/completions/svk new file mode 100644 index 0000000..9079df1 --- /dev/null +++ b/completions/svk @@ -0,0 +1,214 @@ +# svk(1) completion -*- shell-script -*- + +_svk() +{ + local cur prev words cword + _init_completion || return + + local commands options command + + commands='add admin annotate ann blame praise cat checkout co cleanup + cmerge cm commit ci copy cp delete del remove rm depotmap depot + describe desc diff di help h ? import info list ls log merge mirror mi + mkdir move mv ren rename patch propdel pd pdel propedit pe pedit + propget pg pget proplist pl plist propset ps pset pull push resolved + revert smerge sm status st stat switch sw sync sy update up verify' + + if ((cword == 1)); then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--version' -- "$cur")) + else + COMPREPLY=($(compgen -W "$commands" -- "$cur")) + fi + else + case $prev in + -F | --file | --targets) + _filedir + return + ;; + --encoding) + _xfunc iconv _iconv_charsets + return + ;; + esac + + command=${words[1]} + + if [[ $cur == -* ]]; then + # possible options for the command + case $command in + add) + options=' --non-recursive -N -q --quiet' + ;; + blame | annotate | ann | praise) + options='-r --revisions -x --cross' + ;; + cat) + options='-r --revision' + ;; + checkout | co) + options='-r --revision -q --quiet -N --non-recursive -l + --list -d --detach --export --relocate --purge' + ;; + cleanup) + options='-a --all' + ;; + cmerge | cm) + options='-c --change -l --log -r --revision -a --auto + --verbatim --no-ticket -m --message -F --file + --template --encoding -P --patch -S --sign -C + --check-only --direct' + ;; + commit | ci) + options='--import -m --message -F --file --encoding + --template -P --patch -S --sign -C --check-only -N + --non-recursive --direct' + ;; + copy | cp) + options='-r --revision -p --parent -q --quiet -m --message + -F --file --template --encoding -P --patch -S --sign -C + --check-only --direct' + ;; + delete | del | remove | rm) + options='-k --keep-local -m --message -F --file --encoding + --template -P --patch -S --sign -C --check-only + --direct' + ;; + depotmap | depot) + options='-i --init -l --list -d --detach --relocate' + ;; + diff | di) + options='-r --revision -s --summarize -b --verbose -N + --non-recursive' + ;; + import) + options='-f --from-checkout -t --to-checkout -m --message + -F --file --template --encoding -P --patch -S --sign -C + --check-only -N --non-recursive --direct' + ;; + list | ls) + options='-r --revision -v --verbose -R --recursive -d + --depth -f --full-path' + ;; + log) + options='-r --revision -l --limit -q --quiet -x --cross -v + --verbose' + ;; + merge) + options='-r --revision -c --change -I --incremental -a + --auto -l --log -s --sync -t --to -f --from --verbatim + --no-ticket --track-rename -m --message -F --file + --template --encoding -P --patch -S --sign -C + --check-only --direct' + ;; + mirror | mi) + options='-l --list -d --detach --relocate --recover + --unlock --upgrade' + ;; + mkdir) + options='-p --parent -m --message -F --file --template + --encoding -P --patch -S --sign -C --check-only + --direct' + ;; + move | mv | rename | ren) + options='-r --revision -p --parent -q --quiet -m --message + -F --file --encoding --template -P --patch -S --sign -C + --check-only --direct' + ;; + patch) + options='--depot' + ;; + propdel | propset | pdel | pset | pd | ps) + options='-R --recursive -r --revision --revprop -m + --message -F --file --template --encoding -P --patch -S + --sign -C --check-only -q --quiet --direct' + ;; + propedit | pedit | pe) + options='-R --recursive -r --revision --revprop -m + --message -F --file --template --encoding -P --patch + -S --sign -C --check-only --direct' + ;; + propget | pget | pg) + options='-R --recursive -r --revision --revprop --strict' + ;; + proplist | plist | pl) + options='-R --recursive -v --verbose -r --revision + --revprop' + ;; + pull) + options='-a --all -l --lump' + ;; + push) + options='-f --from -l --lump -C --check -P --patch -S + --sign --verbatim' + ;; + resolved) + options='-R --recursive' + ;; + revert) + options='-R --recursive -q --quiet' + ;; + smerge | sm) + options='-I --incremental -l --log -B --baseless -b --base + -s --sync -t --to -f --from --verbatim --no-ticket + --track-rename --host --remoterev -m --message -F + --file --template --encoding -P --patch -S --sign -C + --check-only --direct' + ;; + status | stat | st) + options='-q --quiet --no-ignore -N --non-recursive -v + --verbose' + ;; + switch | sw) + options='-r --revision -d --detach -q --quiet' + ;; + sync | sy) + options='-a --all -s --skipto -t --torev' + ;; + update | up) + options='-r --revision -N --non-recursive -C --check-only + -s --sync -m --merge -q --quiet' + ;; + esac + options+=" --help -h" + + COMPREPLY=($(compgen -W "$options" -- "$cur")) + else + case $command in + help | h | \?) + COMPREPLY=($(compgen -W "$commands environment commands + intro" -- "$cur")) + ;; + admin) + COMPREPLY=($(compgen -W 'help deltify dump hotcopy + list-dblogs list-unused-dblogs load lstxns recover + rmtxns setlog verify rmcache' -- "$cur")) + ;; + patch) + COMPREPLY=($(compgen -W '--ls --list --cat --view + --regen --regenerate --up --update --apply --rm + --delete' -- "$cur")) + ;; + sync) + COMPREPLY=($(compgen -W "$($1 mirror --list \ + 2>/dev/null | awk '/^\//{print $1}')" -- "$cur")) + ;; + co | checkout | push | pull) + if [[ $cur == //*/* ]]; then + path=${cur%/*}/ + else + path=// + fi + COMPREPLY=($(compgen -W "$($1 list $path 2>/dev/null | + command sed -e 's|\(.*\)|'$path'\1|')" -- "$cur")) + ;; + *) + _filedir + ;; + esac + fi + fi +} && + complete -F _svk svk + +# ex: filetype=sh diff --git a/completions/sync_members b/completions/sync_members new file mode 100644 index 0000000..397f8b0 --- /dev/null +++ b/completions/sync_members @@ -0,0 +1,31 @@ +# mailman sync_members completion -*- shell-script -*- + +_sync_members() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -w | -g | -d | --welcome-msg | --goodbye-msg | --digest) + COMPREPLY=($(compgen -W 'y n' -- "$cur")) + return + ;; + --file) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--no-change --welcome-msg --goodbye-msg + --digest --notifyadmin --file --help' -- "$cur")) + else + _xfunc list_lists _mailman_lists + fi + +} && + complete -F _sync_members sync_members + +# ex: filetype=sh diff --git a/completions/synclient b/completions/synclient new file mode 100644 index 0000000..c4a0d42 --- /dev/null +++ b/completions/synclient @@ -0,0 +1,24 @@ +# bash completion for synclient(1) -*- shell-script -*- + +_synclient() +{ + local cur prev words cword + _init_completion -n = || return + + case $prev in + -\? | -h | -V) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + elif [[ $cur != *=?* ]]; then + COMPREPLY=($(compgen -S = -W '$($1 -l 2>/dev/null | \ + awk "/^[ \t]/ { print \$1 }")' -- "$cur")) + compopt -o nospace + fi +} && + complete -F _synclient synclient + +# ex: filetype=sh diff --git a/completions/sysbench b/completions/sysbench new file mode 100644 index 0000000..0af7cc3 --- /dev/null +++ b/completions/sysbench @@ -0,0 +1,132 @@ +# bash completion for sysbench -*- shell-script -*- + +_sysbench() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --num-threads | --max-requests | --max-time | --thread-stack-size | \ + --help | --version | help | version) + return + ;; + --init-rng | --debug | --validate) + COMPREPLY=($(compgen -W 'on off' -- "$cur")) + return + ;; + --test) + COMPREPLY=($(compgen -W 'fileio cpu memory threads mutex oltp' \ + -- "$cur")) + return + ;; + --cpu-max-prime) + return + ;; + --file-test-mode) + COMPREPLY=($(compgen -W 'seqwr seqrewr seqrd rndrd rndwr rndrw' \ + -- "$cur")) + return + ;; + --file-io-mode) + COMPREPLY=($(compgen -W 'sync async fastmmap slowmmap' -- "$cur")) + return + ;; + --file-extra-flags) + COMPREPLY=($(compgen -W 'sync dsync direct' -- "$cur")) + return + ;; + --file-fsync-all | --file-fsync-end) + COMPREPLY=($(compgen -W 'on off' -- "$cur")) + return + ;; + --file-fsync-mode) + COMPREPLY=($(compgen -W 'fsync fdatasync' -- "$cur")) + return + ;; + --memory-scope) + COMPREPLY=($(compgen -W 'global local' -- "$cur")) + return + ;; + --memory-hugetlb) + COMPREPLY=($(compgen -W 'on off' -- "$cur")) + return + ;; + --memory-oper) + COMPREPLY=($(compgen -W 'read write none' -- "$cur")) + return + ;; + --memory-access-mode) + COMPREPLY=($(compgen -W 'seq rnd' -- "$cur")) + return + ;; + --oltp-test-mode) + COMPREPLY=($(compgen -W 'simple complex nontrx sp' -- "$cur")) + return + ;; + --oltp-read-only | --oltp-skip-trx | --oltp-quto-inc | --mysql-ssl) + COMPREPLY=($(compgen -W 'on off' -- "$cur")) + return + ;; + --oltp-nontrx-mode) + COMPREPLY=($(compgen -W 'select update_key update_nokey insert + delete' -- "$cur")) + return + ;; + --oltp-dist-type) + COMPREPLY=($(compgen -W 'uniform gaussian special' -- "$cur")) + return + ;; + --db-driver) + COMPREPLY=($(compgen -W "$($1 --test=oltp help 2>/dev/null | + command sed -e '/^.*database drivers:/,/^$/!d' \ + -ne 's/^ *\([^ ]*\) .*/\1/p')" -- "$cur")) + return + ;; + --db-ps-mode) + COMPREPLY=($(compgen -W 'auto disable' -- "$cur")) + return + ;; + --mysql-socket) + _filedir sock + return + ;; + --mysql-table-engine) + COMPREPLY=($(compgen -W 'myisam innodb bdb heap ndbcluster + federated' -- "$cur")) + return + ;; + --mysql-engine-trx) + COMPREPLY=($(compgen -W 'yes no auto' -- "$cur")) + return + ;; + --*) + $split && return + ;; + esac + + # find out which test we're running + local i test + for ((i = 1; i < ${#words[@]} - 1; i++)); do + # TODO --test= is deprecated, bare test name preferred + if [[ ${words[i]} == --test* ]]; then + test=${words[i]#*=} + break + fi + done + + local opts=$(_parse_help "$1") + if [[ -v test ]]; then + local help=($(_parse_help "$1" "--test=$test help")) + opts="${opts/--test=/} ${help[*]} prepare run cleanup help version" + fi + + if [[ $cur == -* || ! -v test ]]; then + COMPREPLY=($(compgen -W "$opts" -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + COMPREPLY=($(compgen -W "prepare run cleanup help version" -- "$cur")) + fi +} && + complete -F _sysbench sysbench + +# ex: filetype=sh diff --git a/completions/sysctl b/completions/sysctl new file mode 100644 index 0000000..005452d --- /dev/null +++ b/completions/sysctl @@ -0,0 +1,31 @@ +# bash completion for sysctl -*- shell-script -*- + +_sysctl() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | --pattern | -!(-*)[hVr]) + return + ;; + --load | -!(-*)[pf]) + _filedir conf + return + ;; + esac + + if [[ $cur == -* ]]; then + local opts="$(_parse_help "$1")" + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + else + local suffix= + [[ $prev == -w ]] && suffix="=" + COMPREPLY=($(compgen -S "$suffix" -W \ + "$(PATH="$PATH:/sbin" $1 -N -a 2>/dev/null)" -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _sysctl sysctl + +# ex: filetype=sh diff --git a/completions/tar b/completions/tar new file mode 100644 index 0000000..04b7fc0 --- /dev/null +++ b/completions/tar @@ -0,0 +1,711 @@ +# bash completion for GNU tar -*- shell-script -*- +# +# General info +# ============ +# +# The "old" style arguments +# ------------------------- +# +# We don't "advice" the old tar option format by default for GNU tar, example: +# +# 'tar czfT /tmp/archive.tar patterns.txt' +# +# We rather advice the 'tar -czf /tmp/archive.tar -T patterns.txt' format of +# arguments. Though, if user starts the 'first' tar argument without leading +# dash, we treat the command line apropriately. +# +# +# long/short options origin +# ------------------------- +# +# For GNU tar, everything is parsed from `tar --help` output so not so much +# per-distribution work should be needed. The _parse_help does not seem to be +# good enough so parsed here directly. +# +# +# FIXME: --starting-file (-K) (should be matched for extraction only) +# FIXME: handle already used (at least short) options +# FIXME: Test-cases for make check. +# - check for no global variable pollution +# FIXME: why PS4='$BASH_SOURCE:$LINENO: ' shows sometimes negative lines? +# FIXME: timeout on tarball listing +# FIXME: cache 'tar --help' parsing results into global variables +# FIXME: at least 'tar -<tab>' should show some helping text (apart from just +# pure option advices) +# FIXME: short option completion should be more intuitive +# - verbose mode option should be advised multiple times +# - mode option should be advised only once +# - format option should be advised only once +# ... + +__gtar_parse_help_opt() +{ + local opttype arg opt separator optvar + opttype=long + arg="$2" + opt="$1" + separator=" " + + case "$opt" in + --*) ;; + + -\?) + return + ;; + -*) + opttype=short + opt=${opt##-} + separator= + ;; + *) + echo "bash_completion: $FUNCNAME: unknown option $opt" >&2 + return 1 + ;; + esac + + # Remove arguments. + opt=${opt//\[*/} + opt=${opt//=*/=} + + # Basic sanity. + opt=${opt//\"*/} + opt=${opt//\'*/} + opt=${opt//\;*/} + + optvar=$opttype'_arg_'$arg + + eval "$optvar=\"\$$optvar$separator\"\"$opt\"" +} + +__gtar_parse_help_line() +{ + local i + + for i in $1; do + case "$i" in + # regular options + --* | -*) + __gtar_parse_help_opt "$i" "$2" + ;; + + # end once there is single non-option word + *) + break + ;; + esac + done +} + +__gnu_tar_parse_help() +{ + local str line arg + while IFS= read line; do + # Ok, this requires some comment probably. The GNU help output prints + # options on lines beginning with spaces. After that, there is one + # or more options separated by ', ' separator string. We are matching + # like this then: ^<spaces>(<separator>?<option>)+<whatever>$ + if [[ $line =~ \ + ^[[:blank:]]{1,10}(((,[[:blank:]])?(--?([\]\[a-zA-Z0-9?=-]+))(,[[:space:]])?)+).*$ ]]; then + + line=${BASH_REMATCH[1]} + str="${line//,/ }" + + # Detect that all options on this line accept arguments (and whether + # the arguments are required or not). Note that only long option + # description in GNU help output mentions arguments. So the $line + # variable may contain e.g. '-X, --XXX[=NAME], -XXX2[=NAME]'. + arg=none + if [[ $line =~ --[A-Za-z0-9-]+(\[?)= ]]; then + [[ -n ${BASH_REMATCH[1]} ]] && arg=opt || arg=req + fi + + __gtar_parse_help_line "$str" "$arg" + fi + done <<<"$(tar --help)" + + long_opts="\ + $long_arg_none $long_arg_opt $long_arg_req" + + short_opts="$short_arg_none$short_arg_opt$short_arg_req" +} + +# Hack: parse --warning keywords from tar's error output +__gtar_parse_warnings() +{ + local line + LC_ALL=C tar --warning= 2>&1 | while IFS= read line; do + if [[ $line =~ ^[[:blank:]]*-[[:blank:]]*[\`\']([a-zA-Z0-9-]+)\'$ ]]; then + echo "${BASH_REMATCH[1]} no-${BASH_REMATCH[1]}" + fi + done +} + +# Helper to obtain last character of string. +__tar_last_char() +{ + echo "${1:$((${#1} - 1))}" +} + +__tar_parse_old_opt() +{ + local first_word char + + # current word is the first word + [[ $cword -eq 1 && -n $cur && ${cur:0:1} != '-' ]] && + old_opt_progress=1 + + # check that first argument does not begin with "-" + first_word=${words[1]} + [[ -n $first_word && ${first_word:0:1} != "-" ]] && + old_opt_used=1 + + # parse the old option (if present) contents to allow later code expect + # corresponding arguments + if ((old_opt_used == 1)); then + char=${first_word:0:1} + while [[ -n $char ]]; do + if __tar_is_argreq "$char"; then + old_opt_parsed+=("$char") + fi + first_word=${first_word##$char} + char=${first_word:0:1} + done + fi +} + +# Make the analysis of whole command line. +__tar_preparse_cmdline() +{ + local first_arg i modes="ctxurdA" + + shift # progname + + __tar_parse_old_opt + + first_arg=1 + for i in "$@"; do + case "$i" in + --delete | --test-label) + tar_mode=${i:2:100} + tar_mode_arg=$i + break + ;; + --*) + # skip + ;; + -*[$modes]*) + tar_mode=${i//[^$modes]/} + tar_mode=${tar_mode:0:1} + tar_mode_arg=$i + break + ;; + *[$modes]*) + # Only the first arg may be "MODE" without leading dash + if ((first_arg == 1)); then + tar_mode=${i//[^$modes]/} + tar_mode=${tar_mode:0:1} + tar_mode_arg=$i + fi + ;; + esac + first_arg=0 + done +} + +# Generate completions for -f/--file. +__tar_file_option() +{ + local ext="$1" + + case "$tar_mode" in + c) + # no need to advise user to re-write existing tarball + _filedir -d + ;; + *) + _filedir "$ext" + ;; + esac +} + +# Returns truth if option requires argument. No equal sign must be pasted. +# Accepts option in format: 'c', '-c', '--create' +__tar_is_argreq() +{ + local opt + opt=$1 + case "$opt" in + -[A-Za-z0-9?]) + [[ $short_arg_req =~ ${opt##-} ]] && return 0 + ;; + [A-Za-z0-9?]) + [[ $short_arg_req =~ ${opt} ]] && return 0 + ;; + --*) + [[ $long_arg_req =~ [[:blank:]]$opt=[[:blank:]] ]] && return 0 + ;; + esac + + return 1 +} + +# Called only for short parameter +__tar_complete_mode() +{ + local short_modes rawopt generated \ + allshort_raw_unused allshort_raw \ + filler i + + short_modes="ctx" + [[ ! -v basic_tar ]] && short_modes="ctxurdA" + + # Remove prefix when needed + rawopt=${cur#-} + + # -c -z -x ... => czx + allshort_raw=${short_opts//[- ]/} + + # init the 'mode' option if no option is in ${cur} + if [[ $tar_mode == none ]]; then + + # when user passed something like 'tar cf' do not put the '-' before + filler= + if [[ -z $cur && ! -v basic_tar ]]; then + filler=- + fi + + generated="" + for ((i = 0; 1; i++)); do + local c="${short_modes:i:1}" + [[ -z $c ]] && break + generated+=" $filler$cur$c" + done + + COMPREPLY=($(compgen -W "$generated")) + return 0 + fi + + # The last short option requires argument, like '-cf<TAB>'. Cut the + # completion here to enforce argument processing. + if ((old_opt_progress == 0)) && + __tar_is_argreq "$(__tar_last_char "$cur")"; then + COMPREPLY=("$cur") && return 0 + fi + + allshort_raw_unused=${allshort_raw//[$rawopt]/} + if [[ $tar_mode != none ]]; then + allshort_raw_unused=${allshort_raw_unused//[$short_modes]/} + fi + + generated= + for ((i = 0; 1; i++)); do + local c="${allshort_raw_unused:i:1}" + [[ -z $c ]] && break + generated+=" $cur$c" + done + + COMPREPLY=($(compgen -W "$generated")) + + return 0 +} + +__gtar_complete_lopts() +{ + local rv + COMPREPLY=($(compgen -W "$long_opts" -- "$cur")) + rv=$? + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return $rv +} + +__gtar_complete_sopts() +{ + local generated short_mode_opts i c + short_mode_opts="ctxurdA" + generated=${short_opts//[$short_mode_opts]/} + + for ((i = 0; 1; i++)); do + c="${allshort_raw_unused:i:1}" + [[ -z $c ]] && break + generated+=" $cur$c" + done + + COMPREPLY=($(compgen -W "$generated" -- "$cur")) +} + +__tar_try_mode() +{ + case "$cur" in + --*) + # posix tar does not support long opts + [[ -v basic_tar ]] && return 0 + __gtar_complete_lopts + return $? + ;; + + -*) + # posix tar does not support short optios + [[ -v basic_tar ]] && return 0 + + __tar_complete_mode && return 0 + ;; + + *) + if [[ $cword -eq 1 || $tar_mode == none ]]; then + __tar_complete_mode && return 0 + fi + ;; + esac + return 1 +} + +__tar_adjust_PREV_from_old_option() +{ + # deal with old style arguments here + # $ tar cfTC # expects this sequence of arguments: + # $ tar cfTC ARCHIVE_FILE PATTERNS_FILE CHANGE_DIR + if ((old_opt_used == 1 && cword > 1 && \ + cword < ${#old_opt_parsed[@]} + 2)); then + # make e.g. 'C' option from 'cffCT' + prev="-${old_opt_parsed[cword - 2]}" + fi +} + +__tar_extract_like_mode() +{ + local i + for i in x d t delete; do + [[ $tar_mode == "$i" ]] && return 0 + done + return 1 +} + +__tar_try_list_archive() +{ + local tarball tarbin untar i + + __tar_extract_like_mode || return 1 + + # This all is just to approach directory completion from "virtual" + # directory structure in tarball (for which the _filedir is unusable) + + set -- "${words[@]}" + tarbin=$1 + untar="tf" + shift + + for i in "$@"; do + if [[ $i == *.$ext ]]; then + tarball=$i + break + fi + done + if [[ -n $tarball ]]; then + local IFS=$'\n' + COMPREPLY=($(compgen -o filenames -W "$( + $tarbin $untar "$tarball" 2>/dev/null | + while read line; do + printf "%q\n" "$(printf %q"\n" "$line")" + done + )" -- "$(printf "%q\n" "$cur")")) + return 0 + fi +} + +__tar_cleanup_prev() +{ + if [[ $prev =~ ^-[a-zA-Z0-9?]*$ ]]; then + # transform '-caf' ~> '-f' + prev="-$(__tar_last_char "$prev")" + fi +} + +__tar_detect_ext() +{ + local tars='@(@(tar|gem|spkg)?(.@(Z|[bgx]z|bz2|lz?(ma|o)|zst))|t@([abglx]z|b?(z)2|zst))' + ext="$tars" + + case "$tar_mode_arg" in + --*) + # Should never happen? + ;; + ?(-)*[cr]*f) + ext='@(tar|gem|spkg)' + case ${words[1]} in + *a*) ext="$tars" ;; + *z*) ext='t?(ar.)gz' ;; + *Z*) ext='ta@(r.Z|z)' ;; + *[jy]*) ext='t@(?(ar.)bz?(2)|b2)' ;; + *J*) ext='t?(ar.)xz' ;; + esac + ;; + +([^ZzJjy])f) + # Pass through using defaults above + ;; + *[Zz]*f) + ext='@(@(t?(ar.)|gem.|spkg.)@(gz|Z)|taz)' + ;; + *[jy]*f) + ext='@(@(t?(ar.)|gem.)bz?(2)|spkg|tb2)' + ;; + *[J]*f) + ext='@(@(tar|gem|spkg).@(lzma|xz)|t[lx]z)' + ;; + esac +} + +_gtar() +{ + local long_opts short_opts \ + long_arg_none="" long_arg_opt="" long_arg_req="" \ + short_arg_none="" short_arg_opt="" short_arg_req="" \ + tar_mode tar_mode_arg old_opt_progress=0 \ + old_opt_used=0 old_opt_parsed=() + + # Main mode, e.g. -x or -c (extract/creation) + local tar_mode=none + + # The mode argument, e.g. -cpf or -c + # FIXME: handle long options + local tar_mode_arg= + + if [[ -v BASHCOMP_TAR_OPT_DEBUG ]]; then + set -x + PS4='$BASH_SOURCE:$LINENO: ' + fi + + local cur prev words cword split + + _init_completion -s || return + + # Fill the {long,short}_{opts,arg*} + __gnu_tar_parse_help + + __tar_preparse_cmdline "${words[@]}" + + local ext + + __tar_detect_ext + + while true; do # just-for-easy-break while, not looping + __tar_adjust_PREV_from_old_option + __tar_posix_prev_handle && break + __tar_cleanup_prev + + # Handle all options *REQUIRING* argument. Optional arguments are up to + # user (TODO: is there any sane way to deal with this?). This case + # statement successes only if there already is PREV. + case $prev in + --directory | -!(-*)C) + _filedir -d + break + ;; + --atime-preserve) + COMPREPLY=($(compgen -W 'replace system' -- "$cur")) + break + ;; + --group) + COMPREPLY=($(compgen -g -- "$cur")) + break + ;; + --owner) + COMPREPLY=($(compgen -u -- "$cur")) + break + ;; + --info-script | --new-volume-script | --rmt-command | --rsh-command | \ + --use-compress-program | -!(-*)[FI]) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + break + ;; + --volno-file | --add-file | --files-from | --exclude-from | \ + --index-file | --listed-incremental | -!(-*)[TXg]) + _filedir + break + ;; + --format | -!(-*)H) + COMPREPLY=($(compgen -W 'gnu oldgnu pax posix ustar v7' \ + -- "$cur")) + break + ;; + --quoting-style) + COMPREPLY=($(compgen -W 'literal shell shell-always c c-maybe + escape locale clocale' -- "$cur")) + break + ;; + --totals) + COMPREPLY=($(compgen -W 'SIGHUP SIGQUIT SIGINT SIGUSR1 SIGUSR2' \ + -- "$cur")) + break + ;; + --warning) + COMPREPLY=($(compgen -W "$(__gtar_parse_warnings)" -- "$cur")) + break + ;; + --file | -!(-*)f) + __tar_file_option "$ext" + break + ;; + --*) + # parameter with required argument but no completion yet + [[ " $long_arg_req " =~ \ $prev=\ ]] && break + + # parameter with optional argument passed with =, something like + # --occurrence=*<TAB> which is not handled above + [[ " $long_arg_opt " =~ \ $prev\ ]] && break + + # if there is some unknown option with '=', for example + # (literally) user does --nonexistent=<TAB>, we do not want + # continue also + $split && break + + # Most probably, when code goes here, the PREV variable contains + # some string from "$long_arg_none" and we want continue. + ;; + -!(-*)[a-zA-Z0-9?]) + # argument required but no completion yet + [[ $short_arg_req =~ ${prev##-} ]] && break + ;; + esac + + # safety belts + case "$cur" in + -[a-zA-Z0-9]=*) + # e.g. 'tar -c -f=sth' does not what user could expect + break + ;; + esac + + # Handle the main operational mode of tar. We should do it as soon as + # possible. + __tar_try_mode && break + + # handle others + case "$cur" in + --*) + __gtar_complete_lopts + break + ;; + -*) + # called only if it is *not* first parameter + __gtar_complete_sopts + break + ;; + esac + + # the first argument must be "mode" argument or --param, if any of those + # was truth - the 'break' statement would have been already called + ((cword == 1)) && break + + __tar_try_list_archive && break + + # file completion on relevant files + if [[ $tar_mode != none ]]; then + _filedir + fi + + break + done # just-for-easy-break while + + if [[ -v BASHCOMP_TAR_OPT_DEBUG ]]; then + set +x + unset PS4 + fi +} + +__tar_posix_prev_handle() +{ + case "$prev" in + -f) + __tar_file_option "$ext" + return 0 + ;; + -b) + return 0 + ;; + esac + + return 1 +} + +_posix_tar() +{ + local long_opts short_opts basic_tar \ + long_arg_none="" long_arg_opt long_arg_req="" \ + short_arg_none short_arg_opt short_arg_req \ + tar_mode tar_mode_arg old_opt_progress=0 \ + old_opt_used=1 old_opt_parsed=() + + # Main mode, e.g. -x or -c (extract/creation) + local tar_mode=none + + # The mode argument, e.g. -cpf or -c + local tar_mode_arg= + + local cur prev words cword split + + _init_completion -s || return + + basic_tar=yes + tar_mode=none + + # relatively compatible modes are {c,t,x} + # relatively compatible options {b,f,m,v,w} + short_arg_req="fb" + short_arg_none="wmv" + short_opts="$short_arg_req$short_arg_none" + + __tar_preparse_cmdline "${words[@]}" + + local ext + + __tar_detect_ext + + __tar_adjust_PREV_from_old_option + + __tar_posix_prev_handle && return + + __tar_try_mode && return + + __tar_try_list_archive && return + + # file completion on relevant files + _filedir +} + +_tar() +{ + local cmd=${COMP_WORDS[0]} func line + line="$($cmd --version 2>/dev/null)" + case "$line" in + *GNU*) + func=_gtar + ;; + *) + func=_posix_tar + ;; + esac + $func "$@" + + # Install real completion for subsequent completions + if [[ ${COMP_TAR_INTERNAL_PATHS-} ]]; then + complete -F $func -o dirnames tar + else + complete -F $func tar + fi + unset -f _tar +} + +if [[ ${COMP_TAR_INTERNAL_PATHS-} ]]; then + complete -F _tar -o dirnames tar + complete -F _gtar -o dirnames gtar + complete -F _posix_tar -o dirnames bsdtar + complete -F _posix_tar -o dirnames star +else + complete -F _tar tar + complete -F _gtar gtar + complete -F _posix_tar bsdtar + complete -F _posix_tar star +fi + +# ex: filetype=sh diff --git a/completions/tcpdump b/completions/tcpdump new file mode 100644 index 0000000..9a7c2e9 --- /dev/null +++ b/completions/tcpdump @@ -0,0 +1,64 @@ +# bash completion for tcpdump -*- shell-script -*- + +_tcpdump() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -!(-*)[rwFV]) + _filedir + return + ;; + --interface | -!(-*)i) + _available_interfaces -a + return + ;; + -!(-*)m) + _filedir mib + return + ;; + -!(-*)T) + COMPREPLY=($(compgen -W 'aodv carp cnfp lmp pgm pgm_zmtp1 radius + resp rpc rtcp rtp rtcp snmp tftp vat vxlan wb zmtp1' \ + -- "$cur")) + return + ;; + -!(-*)z) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + --relinquish-privileges | -!(-*)Z) + _allowed_users + return + ;; + -!(-*)[BcCDEGMsWy]) + return + ;; + --time-stamp-type | -!(-*)j) + COMPREPLY=($(compgen -W 'host host_lowprec host_hiprec adapter + adapter_unsynced' -- "$cur")) + return + ;; + --direction | -!(-*)Q) + COMPREPLY=($(compgen -W 'in out inout' -- "$cur")) + return + ;; + --time-stamp-precision) + COMPREPLY=($(compgen -W 'micro nano' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi + +} && + complete -F _tcpdump tcpdump + +# ex: filetype=sh diff --git a/completions/tcpkill b/completions/tcpkill new file mode 100644 index 0000000..189d928 --- /dev/null +++ b/completions/tcpkill @@ -0,0 +1,22 @@ +# tcpkill completion -*- shell-script -*- + +_tcpkill() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*i) + _available_interfaces -a + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-i -1 -2 -3 -4 -5 -6 -7 -8 -9' -- "$cur")) + fi + +} && + complete -F _tcpkill tcpkill + +# ex: filetype=sh diff --git a/completions/tcpnice b/completions/tcpnice new file mode 100644 index 0000000..c6a94d6 --- /dev/null +++ b/completions/tcpnice @@ -0,0 +1,22 @@ +# tcpnice completion -*- shell-script -*- + +_tcpnice() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*i) + _available_interfaces -a + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + fi + +} && + complete -F _tcpnice tcpnice + +# ex: filetype=sh diff --git a/completions/timeout b/completions/timeout new file mode 100644 index 0000000..32ff2e3 --- /dev/null +++ b/completions/timeout @@ -0,0 +1,39 @@ +# timeout(1) completion -*- shell-script -*- + +_timeout() +{ + local cur prev words cword split i found=false + _init_completion -s || return + + for ((i = 1; i <= COMP_CWORD; i++)); do + if [[ ${COMP_WORDS[i]} != -* && ${COMP_WORDS[i - 1]} != = ]]; then + if $found; then + _command_offset $i + return + fi + found=true + fi + [[ ${COMP_WORDS[i]} == -@(-kill-after|-signal|!(-*)[ks]) ]] && ((i++)) + done + + case $prev in + --help | --version | --kill-after | -!(-*)k) + return + ;; + --signal | -!(-*)s) + _signals + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _timeout timeout + +# ex: filetype=sh diff --git a/completions/tipc b/completions/tipc new file mode 100644 index 0000000..44ade36 --- /dev/null +++ b/completions/tipc @@ -0,0 +1,289 @@ +# tipc(8) completion -*- shell-script -*- + +_tipc_media() +{ + local optind=$1 + + if ((cword == optind)); then + COMPREPLY=($(compgen -W 'media' -- $cur)) + return 0 + elif ((cword == optind + 1)); then + COMPREPLY=($(compgen -W 'udp eth ib' -- $cur)) + return 0 + fi + + return 1 +} + +_tipc_bearer() +{ + local optind=$1 + local media i + + if _tipc_media $optind; then + return + fi + + for ((i = 0; i < cword; i++)); do + if [[ ${words[i]} == 'media' ]]; then + media=${words[i + 1]} + fi + done + + if ((cword == optind + 2)); then + case "$media" in + "udp") + COMPREPLY=($(compgen -W 'name' -- $cur)) + ;; + "eth" | "ib") + COMPREPLY=($(compgen -W 'device' -- $cur)) + ;; + esac + elif ((cword == optind + 3)); then + case "$media" in + "udp") + local names=$(tipc bearer list 2>/dev/null | awk -F: '/^udp:/ {print $2}') + COMPREPLY=($(compgen -W '$names' -- $cur)) + ;; + "eth") + local interfaces=$(command ls /sys/class/net/) + COMPREPLY=($(compgen -W '$interfaces' -- $cur)) + ;; + esac + fi +} + +_tipc_link_opts() +{ + COMPREPLY=($(compgen -W 'priority tolerance window' -- $cur)) +} + +_tipc_link() +{ + local optind=$1 + local filter=$2 + + if ((cword == optind)); then + COMPREPLY=($(compgen -W 'link' -- $cur)) + elif ((cword == optind + 1)); then + # awk drops link state and last trailing : + local links=$(tipc link list 2>/dev/null | + awk '{print substr($1, 0, length($1))}') + local -a exclude + [[ $filter == peers ]] && exclude=(-X broadcast-link) + COMPREPLY=($(compgen "${exclude[@]}" -W '$links' -- $cur)) + fi +} + +_tipc() +{ + local cur prev words cword optind i p + _init_completion || return + + optind=1 + COMPREPLY=() + + # Flags can be placed anywhere in the commandline + case "$cur" in + -*) + COMPREPLY=($(compgen -W '-h --help' -- $cur)) + return + ;; + esac + + if ((cword == 1)); then + COMPREPLY=($(compgen -W 'bearer link media nametable node socket' -- $cur)) + return + fi + + case "${words[optind]}" in + bearer) + ((optind++)) + + if ((cword == optind)); then + COMPREPLY=($(compgen -W 'enable disable set get list' -- $cur)) + return + fi + + case "${words[optind]}" in + enable) + local media params + ((optind++)) + + if ((cword < optind + 4)); then + _tipc_bearer $optind + return + fi + + for ((i = 0; i < cword; i++)); do + if [[ ${words[i]} == 'media' ]]; then + media=${words[i + 1]} + fi + done + case "$media" in + "udp") + declare -a params=("localip" "localport" "remoteip" + "remoteport" "domain" "priority") + ;; + "eth" | "ib") + declare -a params=("domain" "priority") + ;; + *) + return + ;; + esac + + # If the previous word was a known parameter, we assume a value for + # that key. Note that this would break if the user attempts to use + # a known key as value. + for i in "${params[@]}"; do + if [[ $prev == "$i" ]]; then + return + fi + done + + # In order not to print already used options, we remove them + for p in "${words[@]}"; do + for i in "${params[@]}"; do + if [[ $p == "$i" ]]; then + params=("${params[@]/$i/}") + fi + done + done + + COMPREPLY=($(compgen -W '${params[@]}' -- $cur)) + ;; + disable) + ((optind++)) + + _tipc_bearer $optind + ;; + get) + ((optind++)) + + if ((cword == optind)); then + _tipc_link_opts + elif ((cword >= optind + 1)); then + _tipc_bearer $((optind + 1)) + fi + ;; + set) + ((optind++)) + + if ((cword == optind)); then + _tipc_link_opts + elif ((cword >= optind + 2)); then + _tipc_bearer $((optind + 2)) + fi + ;; + esac + ;; + link) + ((optind++)) + + if ((cword == optind)); then + COMPREPLY=($(compgen -W 'get set list statistics' -- $cur)) + return + fi + + case "${words[optind]}" in + get) + ((optind++)) + + if ((cword == optind)); then + _tipc_link_opts + elif ((cword >= optind + 1)); then + _tipc_link $((optind + 1)) "peers" + fi + ;; + set) + ((optind++)) + + if ((cword == optind)); then + _tipc_link_opts + elif ((cword >= optind + 2)); then + _tipc_link $((optind + 2)) "peers" + fi + ;; + statistics) + ((optind++)) + + if ((cword == optind)); then + COMPREPLY=($(compgen -W 'show reset' -- $cur)) + return + fi + + case "${words[optind]}" in + show | reset) + _tipc_link $((optind + 1)) + ;; + esac + ;; + esac + ;; + media) + ((optind++)) + + if ((cword == optind)); then + COMPREPLY=($(compgen -W 'get set list' -- $cur)) + return + fi + + case "${words[optind]}" in + get) + ((optind++)) + + if ((cword == optind)); then + _tipc_link_opts + elif ((cword >= optind + 1)); then + _tipc_media $((optind + 1)) + fi + ;; + set) + ((optind++)) + + if ((cword == optind)); then + _tipc_link_opts + elif ((cword >= optind + 2)); then + _tipc_media $((optind + 2)) + fi + ;; + esac + ;; + nametable) + ((optind++)) + + if ((cword == optind)); then + COMPREPLY=($(compgen -W 'show' -- $cur)) + fi + ;; + node) + ((optind++)) + + if ((cword == optind)); then + COMPREPLY=($(compgen -W 'list get set' -- $cur)) + return + fi + + case "${words[optind]}" in + get | set) + ((optind++)) + + if ((cword == optind)); then + COMPREPLY=($(compgen -W 'address netid' -- $cur)) + fi + ;; + esac + ;; + socket) + ((optind++)) + + if ((cword == optind)); then + COMPREPLY=($(compgen -W 'list' -- $cur)) + fi + ;; + esac +} && + complete -F _tipc tipc + +# ex: filetype=sh diff --git a/completions/tox b/completions/tox new file mode 100644 index 0000000..0ea656e --- /dev/null +++ b/completions/tox @@ -0,0 +1,51 @@ +# tox completion -*- shell-script -*- + +_tox() +{ + local cur prev words cword + _init_completion || return + + # Complete defaults following a "--" + if [[ "${words[*]:0:cword} " == *\ --\ * && $cur != -- ]]; then + compopt -o bashdefault -o default + return + fi + + case $prev in + --help | --version | --num | --index-url | --hashseed | --force-dep | -!(-*)[hni]) + return + ;; + -!(-*)c) + _filedir ini + return + ;; + --installpkg | --result-json | --workdir) + _filedir + return + ;; + -!(-*)e) + local envs=$( + { + "$1" --listenvs-all || "$1" --listenvs + } 2>/dev/null + ) + [[ $envs ]] || envs=$( + command sed -e 's/,/ /g' -ne 's/^envlist[[:space:]]*=//p' \ + tox.ini 2>/dev/null + ) + local prefix="" + [[ $cur == *,* ]] && prefix="${cur%,*}," + COMPREPLY=($(compgen -X '*[{}]*' -W "$envs ALL" -- "${cur##*,}")) + ((${#COMPREPLY[@]} == 1)) && COMPREPLY=(${COMPREPLY/#/$prefix}) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1") --' -- "$cur")) + return + fi +} && + complete -F _tox tox + +# ex: filetype=sh diff --git a/completions/tracepath b/completions/tracepath new file mode 100644 index 0000000..176534f --- /dev/null +++ b/completions/tracepath @@ -0,0 +1,26 @@ +# tracepath(8) completion -*- shell-script -*- + +_tracepath() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*[lmp]) + return + ;; + esac + + if [[ $cur == -* ]]; then + local opts=$(_parse_help "$1") + COMPREPLY=($(compgen -W '${opts:-$(_parse_usage "$1")}' -- "$cur")) + return + fi + + local ipvx + [[ $1 == *6 ]] && ipvx=-6 + _known_hosts_real ${ipvx-} -- "$cur" +} && + complete -F _tracepath tracepath tracepath6 + +# ex: filetype=sh diff --git a/completions/tshark b/completions/tshark new file mode 100644 index 0000000..396fbcb --- /dev/null +++ b/completions/tshark @@ -0,0 +1,136 @@ +# tshark(1) completion -*- shell-script -*- + +_tshark() +{ + local cur prev words cword prefix + _init_completion -n : || return + + case $cur in + -o*) + prefix=-o + ;; + -X*) + prefix=-X + ;; + esac + + case ${prefix:-$prev} in + --*) + # Fallback to completion of long options below. + ;; + -o*) + if [[ $cur == *:* ]]; then + cur=${cur#*:} + _filedir + else + [[ -v _tshark_prefs ]] || + _tshark_prefs="$("$1" -G defaultprefs 2>/dev/null | command sed -ne 's/^#\{0,1\}\([a-z0-9_.-]\{1,\}:\).*/\1/p' | + tr '\n' ' ')" + : ${prefix:=} + COMPREPLY=($(compgen -P "$prefix" -W "$_tshark_prefs" \ + -- "${cur:${#prefix}}")) + [[ ${COMPREPLY-} == *: ]] && compopt -o nospace + fi + return + ;; + -*[fsBDLcRNdCeEzhvoK]) + return + ;; + -*i) + COMPREPLY=($(compgen -W \ + "$("$1" -D 2>/dev/null | awk '{print $2}')" -- "$cur")) + return + ;; + -*y) + local opts i + for ((i = ${#words[@]} - 1; i > 0; i--)); do + if [[ ${words[i]} == -i ]]; then + opts+="-i ${words[i + 1]}" + break + fi + done + COMPREPLY=($(compgen -W "$("$1" $opts -L 2>/dev/null | + awk '/^ / { print $1 }')" -- "$cur")) + return + ;; + -*[ab]) + COMPREPLY=($(compgen -W 'duration: filesize: files:' -- "$cur")) + [[ ${COMPREPLY-} == *: ]] && compopt -o nospace + return + ;; + -*[rH]) + # -r accepts a lot of different file types + _filedir + return + ;; + -*w) + _filedir + [[ $cur == @(|-) ]] && COMPREPLY+=(-) + return + ;; + -*F) + COMPREPLY=($(compgen -W "$("$1" -F 2>&1 | + awk '/^ / { print $1 }')" -- "$cur")) + return + ;; + -*O) + local prefix= + [[ $cur == *,* ]] && prefix="${cur%,*}," + [[ -v _tshark_protocols ]] || + _tshark_protocols="$("$1" -G protocols 2>/dev/null | + cut -f 3 | tr '\n' ' ')" + COMPREPLY=($(compgen -W "$_tshark_protocols" -- "${cur##*,}")) + ((${#COMPREPLY[@]} == 1)) && COMPREPLY=(${COMPREPLY/#/$prefix}) + return + ;; + -*T) + # Parse from: tshark -T . 2>&1 | awk -F \" '/^\t*"/ { print $2 }' + COMPREPLY=($(compgen -W \ + 'pdml ps psml json jsonraw ek tabs text fields' -- "$cur")) + return + ;; + -*t) + # Parse from: tshark -t . 2>&1 | awk -F \" '/^\t*"/ { print $2 }' + COMPREPLY=($(compgen -W \ + 'a ad adoy d dd e r u ud udoy' -- "$cur")) + return + ;; + -*u) + # TODO: could be parsed from "-u ." output + COMPREPLY=($(compgen -W 's hms' -- "$cur")) + return + ;; + -*W) + COMPREPLY=($(compgen -W 'n' -- "$cur")) + return + ;; + -*X) + if [[ ${cur:${#prefix}} == lua_script:* ]]; then + cur=${cur#*:} + _filedir lua + else + COMPREPLY=($(compgen -P "$prefix" -W 'lua_script:' -- \ + "${cur:${#prefix}}")) + [[ ${COMPREPLY-} == *: ]] && compopt -o nospace + fi + return + ;; + -*G) + COMPREPLY=($(compgen -W "$("$1" -G \? 2>/dev/null | + awk '/^[ \t]*-G / \ + { sub("^[[]","",$2); sub("[]]$","",$2); print $2 }')" \ + -- "$cur")) + return + ;; + + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h 2>/dev/null)' \ + -- "$cur")) + return + fi +} && + complete -F _tshark tshark + +# ex: filetype=sh diff --git a/completions/tsig-keygen b/completions/tsig-keygen new file mode 100644 index 0000000..017e9d8 --- /dev/null +++ b/completions/tsig-keygen @@ -0,0 +1,28 @@ +# tsig-keygen(8) completion -*- shell-script -*- + +_tsig_keygen() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h) + return + ;; + -a) + COMPREPLY=($(compgen -W 'hmac-{md5,sha{1,224,256,384,512}}' -- "$cur")) + return + ;; + -r) + COMPREPLY=($(compgen -W keyboard -- "$cur")) + _filedir + return + ;; + esac + + [[ $cur != -* ]] || + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _tsig_keygen tsig-keygen + +# ex: filetype=sh diff --git a/completions/tune2fs b/completions/tune2fs new file mode 100644 index 0000000..66d629c --- /dev/null +++ b/completions/tune2fs @@ -0,0 +1,61 @@ +# tune2fs(8) completion -*- shell-script -*- + +_tune2fs() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*[cCEiJLmrT]) + return + ;; + -*e) + COMPREPLY=($(compgen -W 'continue remount-ro panic' -- "$cur")) + return + ;; + -*g) + _gids + COMPREPLY=($(compgen -g -W '${COMPREPLY[@]}' -- "$cur")) + return + ;; + -*M) + _filedir -d + return + ;; + -*o) + local -a opts=(^debug ^bsdgroups ^user_xattr ^acl ^uid16 + ^journal_data ^journal_data_ordered ^journal_data_writeback + ^nobarrier ^block_validity ^discard ^nodelalloc) + COMPREPLY=($(compgen -W '${opts[@]} ${opts[@]#^}' -- "$cur")) + return + ;; + -*O) + local -a opts=(^dir_index ^dir_nlink ^encrypt ^extent ^extra_isize + ^filetype ^flex_bg ^has_journal ^huge_file ^large_file + ^metadata_csum ^mmp ^project ^quota ^read-only ^resize_inode + ^sparse_super ^uninit_bg) + COMPREPLY=($(compgen -W '${opts[@]} ${opts[@]#^}' -- "$cur")) + return + ;; + -*u) + _uids + COMPREPLY=($(compgen -u -W '${COMPREPLY[@]}' -- "$cur")) + return + ;; + -*U) + COMPREPLY=($(compgen -W 'clear random time' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + return + fi + + cur=${cur:=/dev/} + _filedir +} && + complete -F _tune2fs tune2fs + +# ex: filetype=sh diff --git a/completions/ulimit b/completions/ulimit new file mode 100644 index 0000000..e596bf7 --- /dev/null +++ b/completions/ulimit @@ -0,0 +1,42 @@ +# bash completion for ulimit -*- shell-script -*- + +_ulimit() +{ + local cur prev words cword + _init_completion || return + + # TODO combined option support (-aH, -Sc etc) + + local mode + case $prev in + -a) + COMPREPLY=($(compgen -W "-S -H" -- "$cur")) + return + ;; + -[SH]) ;; + + -*) + mode=$prev + ;; + esac + + if [[ ! -v mode ]]; then + local word + for word in "${words[@]}"; do + [[ $word == -*a* ]] && return + done + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + return + fi + fi + + local args + _count_args + ((args == 1)) && + COMPREPLY=($(compgen -W "soft hard unlimited" -- "$cur")) +} && + complete -F _ulimit ulimit + +# ex: filetype=sh diff --git a/completions/unace b/completions/unace new file mode 100644 index 0000000..7d6bd42 --- /dev/null +++ b/completions/unace @@ -0,0 +1,20 @@ +# unace(1) completion -*- shell-script -*- + +_unace() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-c -c- -f -f- -o -o- -p -y -y-' -- "$cur")) + else + if ((cword == 1)); then + COMPREPLY=($(compgen -W 'e l t v x' -- "$cur")) + else + _filedir ace + fi + fi +} && + complete -F _unace unace + +# ex: filetype=sh diff --git a/completions/unpack200 b/completions/unpack200 new file mode 100644 index 0000000..8814259 --- /dev/null +++ b/completions/unpack200 @@ -0,0 +1,48 @@ +# unpack200(1) completion -*- shell-script -*- + +_unpack200() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | -!(-*)[?hVJ]) + return + ;; + --deflate-hint | -!(-*)H) + COMPREPLY=($(compgen -W 'true false keep' -- "$cur")) + return + ;; + --log-file | -!(-*)l) + COMPREPLY=($(compgen -W '-' -- "$cur")) + _filedir log + return + ;; + esac + + $split && return + + # Check if a pack or a jar was already given. + local word pack=false jar=false + for word in "${words[@]:1}"; do + case $word in + *.pack | *.pack.gz) pack=true ;; + *.jar) jar=true ;; + esac + done + + if ! $pack; then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--deflate-hint= --remove-pack-file + --verbose --quiet --log-file= --help --version' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _filedir 'pack?(.gz)' + fi + elif ! $jar; then + _filedir jar + fi +} && + complete -F _unpack200 unpack200 + +# ex: filetype=sh diff --git a/completions/unrar b/completions/unrar new file mode 100644 index 0000000..4cbac8f --- /dev/null +++ b/completions/unrar @@ -0,0 +1,23 @@ +# unrar(1) completion -*- shell-script -*- + +_unrar() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-ad -ap -av- -c- -cfg- -cl -cu -dh -ep -f + -idp -ierr -inul -kb -o+ -o- -ow -p -p- -r -ta -tb -tn -to -u -v + -ver -vp -x -x@ -y' -- "$cur")) + else + if ((cword == 1)); then + COMPREPLY=($(compgen -W 'e l lb lt p t v vb vt x' -- "$cur")) + else + _filedir '@(rar|exe)' + fi + fi + +} && + complete -F _unrar unrar + +# ex: filetype=sh diff --git a/completions/unshunt b/completions/unshunt new file mode 100644 index 0000000..95a1601 --- /dev/null +++ b/completions/unshunt @@ -0,0 +1,17 @@ +# mailman unshunt completion -*- shell-script -*- + +_unshunt() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + _filedir -d + fi + +} && + complete -F _unshunt unshunt + +# ex: filetype=sh diff --git a/completions/update-alternatives b/completions/update-alternatives new file mode 100644 index 0000000..25d2ce6 --- /dev/null +++ b/completions/update-alternatives @@ -0,0 +1,92 @@ +# bash completion for update-alternatives -*- shell-script -*- + +_installed_alternatives() +{ + local admindir + # find the admin dir + for i in alternatives dpkg/alternatives rpm/alternatives; do + [[ -d /var/lib/$i ]] && admindir=/var/lib/$i && break + done + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == --admindir ]]; then + admindir=${words[i + 1]} + break + fi + done + COMPREPLY=($(compgen -W '$(command ls $admindir)' -- "$cur")) +} + +_update_alternatives() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --altdir | --admindir) + _filedir -d + return + ;; + --help | --usage | --version) + return + ;; + esac + + local mode args i + + # find which mode to use and how many real args used so far + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == --@(install|remove|auto|display|config|remove-all|set) ]]; then + mode=${words[i]} + args=$((cword - i)) + break + fi + done + + case ${mode-} in + --install) + case $args in + 1 | 3) + _filedir + ;; + 2) + _installed_alternatives + ;; + 4) + # priority - no completions + ;; + *) + case $((args % 4)) in + 0 | 2) + _filedir + ;; + 1) + COMPREPLY=($(compgen -W '--slave' -- "$cur")) + ;; + 3) + _installed_alternatives + ;; + esac + ;; + esac + ;; + --remove | --set) + case $args in + 1) + _installed_alternatives + ;; + 2) + _filedir + ;; + esac + ;; + --auto | --remove-all | --display | --config) + _installed_alternatives + ;; + *) + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + ;; + esac +} && + complete -F _update_alternatives update-alternatives alternatives + +# ex: filetype=sh diff --git a/completions/update-rc.d b/completions/update-rc.d new file mode 100644 index 0000000..9b281d5 --- /dev/null +++ b/completions/update-rc.d @@ -0,0 +1,58 @@ +# update-rc.d(8) completion -*- shell-script -*- +# +# Copyright (C) 2004 Servilio Afre Puentes <servilio@gmail.com> + +_update_rc_d() +{ + local cur prev words cword + _init_completion || return + + local sysvdir services options + + [[ -d /etc/rc.d/init.d ]] && sysvdir=/etc/rc.d/init.d || + sysvdir=/etc/init.d + + services=($(printf '%s ' $sysvdir/!(README*|*.sh|$_backup_glob))) + services=(${services[@]#$sysvdir/}) + options=(-f -n) + + if [[ $cword -eq 1 || $prev == -* ]]; then + COMPREPLY=($(compgen -W '${options[@]} ${services[@]}' \ + -X '$(tr " " "|" <<<${words[@]})' -- "$cur")) + elif [[ $prev == ?($(tr " " "|" <<<"${services[*]}")) ]]; then + COMPREPLY=($(compgen -W 'remove defaults start stop' -- "$cur")) + elif [[ $prev == defaults && $cur == [0-9] ]]; then + COMPREPLY=(0 1 2 3 4 5 6 7 8 9) + elif [[ $prev == defaults && $cur == [sk]?([0-9]) ]]; then + COMPREPLY=(0 1 2 3 4 5 6 7 8 9) + elif [[ $prev == defaults && -z $cur ]]; then + COMPREPLY=(0 1 2 3 4 5 6 7 8 9 s k) + elif [[ $prev == ?(start|stop) ]]; then + if [[ $cur == [0-9] || -z $cur ]]; then + COMPREPLY=(0 1 2 3 4 5 6 7 8 9) + elif [[ $cur == [0-9][0-9] ]]; then + COMPREPLY=($cur) + else + COMPREPLY=() + fi + elif [[ $prev == ?([0-9][0-9]|[0-6S]) ]]; then + if [[ -z $cur ]]; then + if [[ $prev == [0-9][0-9] ]]; then + COMPREPLY=(0 1 2 3 4 5 6 S) + else + COMPREPLY=(0 1 2 3 4 5 6 S .) + fi + elif [[ $cur == [0-6S.] ]]; then + COMPREPLY=($cur) + else + COMPREPLY=() + fi + elif [[ $prev == "." ]]; then + COMPREPLY=($(compgen -W "start stop" -- "$cur")) + else + COMPREPLY=() + fi +} && + complete -F _update_rc_d update-rc.d + +# ex: filetype=sh diff --git a/completions/upgradepkg b/completions/upgradepkg new file mode 100644 index 0000000..d3ce608 --- /dev/null +++ b/completions/upgradepkg @@ -0,0 +1,30 @@ +# Slackware Linux upgradepkg completion -*- shell-script -*- + +_upgradepkg() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--dry-run --install-new --reinstall + --verbose' -- "$cur")) + return + fi + + if [[ $cur == ?*%* ]]; then + prev="${cur%%?(\\)%*}" + cur="${cur#*%}" + local nofiles IFS=$'\n' + compopt -o filenames + COMPREPLY=($(compgen -P "$prev%" -f -X "!*.@(t[bgxl]z)" -- "$cur")) + [[ ${COMPREPLY-} ]] || nofiles=1 + COMPREPLY+=($(compgen -P "$prev%" -S '/' -d -- "$cur")) + [[ -v nofiles ]] && compopt -o nospace + return + fi + + _filedir 't[bglx]z' +} && + complete -F _upgradepkg upgradepkg + +# ex: filetype=sh diff --git a/completions/urlsnarf b/completions/urlsnarf new file mode 100644 index 0000000..e327076 --- /dev/null +++ b/completions/urlsnarf @@ -0,0 +1,26 @@ +# urlsnarf completion -*- shell-script -*- + +_urlsnarf() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*i) + _available_interfaces -a + return + ;; + -*p) + _filedir pcap + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + fi + +} && + complete -F _urlsnarf urlsnarf + +# ex: filetype=sh diff --git a/completions/uscan b/completions/uscan new file mode 100644 index 0000000..441bae3 --- /dev/null +++ b/completions/uscan @@ -0,0 +1,33 @@ +# uscan completion -*- shell-script -*- + +_uscan() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --package) + COMPREPLY=($(_xfunc apt-cache _apt_cache_src_packages)) + return + ;; + --watchfile) + _filedir + return + ;; + --destdir) + _filedir -d + return + ;; + --timeout | --upstream-version | --download-version | --check-dirname-level | --check-dirname-regex) + COMPREPLY=() + return + ;; + esac + + $split && return + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _uscan uscan + +# ex: filetype=sh diff --git a/completions/useradd b/completions/useradd new file mode 100644 index 0000000..ceeca91 --- /dev/null +++ b/completions/useradd @@ -0,0 +1,46 @@ +# useradd(8) completion -*- shell-script -*- + +_useradd() +{ + local cur prev words cword split + _init_completion -s || return + + # TODO: if -o/--non-unique is given, could complete on existing uids + # with -u/--uid + + case $prev in + --comment | --help | --expiredate | --inactive | --key | --password | --uid | \ + --selinux-user | -!(-*)[chefKpuZ]) + return + ;; + --base-dir | --home-dir | --skel | --root | -!(-*)[bdkR]) + _filedir -d + return + ;; + --gid | -!(-*)g) + _gids + COMPREPLY=($(compgen -W '${COMPREPLY[@]} $(compgen -g)' \ + -- "$cur")) + return + ;; + --groups | -!(-*)G) + local prefix= + [[ $cur == *,* ]] && prefix="${cur%,*}," + COMPREPLY=($(compgen -g -- "${cur##*,}")) + ((${#COMPREPLY[@]} == 1)) && COMPREPLY=(${COMPREPLY/#/$prefix}) + return + ;; + --shell | -!(-*)s) + _shells + return + ;; + esac + + $split && return + + [[ $cur == -* ]] && + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _useradd useradd + +# ex: filetype=sh diff --git a/completions/userdel b/completions/userdel new file mode 100644 index 0000000..ed98447 --- /dev/null +++ b/completions/userdel @@ -0,0 +1,27 @@ +# userdel(8) completion -*- shell-script -*- + +_userdel() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | -!(-*)h) + return + ;; + --root | -!(-*)R) + _filedir -d + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + COMPREPLY=($(compgen -u -- "$cur")) +} && + complete -F _userdel userdel + +# ex: filetype=sh diff --git a/completions/usermod b/completions/usermod new file mode 100644 index 0000000..77ab33c --- /dev/null +++ b/completions/usermod @@ -0,0 +1,51 @@ +# usermod(8) completion -*- shell-script -*- + +_usermod() +{ + local cur prev words cword split + _init_completion -s || return + + # TODO: if -o/--non-unique is given, could complete on existing uids + # with -u/--uid + + case $prev in + --comment | --home | --expiredate | --inactive | --help | --login | --password | \ + --uid | --selinux-user | -!(-*)[cdefhlpuZ]) + return + ;; + --gid | -!(-*)g) + _gids + COMPREPLY=($(compgen -W '${COMPREPLY[@]} $(compgen -g)' \ + -- "$cur")) + return + ;; + --groups | -!(-*)G) + local prefix= + [[ $cur == *,* ]] && prefix="${cur%,*}," + COMPREPLY=($(compgen -g -- "${cur##*,}")) + ((${#COMPREPLY[@]} == 1)) && COMPREPLY=(${COMPREPLY/#/$prefix}) + return + ;; + --root | -!(-*)R) + _filedir -d + return + ;; + --shell | -!(-*)s) + _shells + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + # TODO: -U/--unlock, -p/--password, -L/--lock mutually exclusive + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + COMPREPLY=($(compgen -u -- "$cur")) +} && + complete -F _usermod usermod + +# ex: filetype=sh diff --git a/completions/valgrind b/completions/valgrind new file mode 100644 index 0000000..f541161 --- /dev/null +++ b/completions/valgrind @@ -0,0 +1,111 @@ +# valgrind(1) completion -*- shell-script -*- + +_valgrind() +{ + local cur prev words cword split + _init_completion -s || return + + local i + # Note: intentionally using COMP_WORDS and COMP_CWORD instead of + # words and cword here due to splitting on = causing index differences + # (_command_offset assumes the former). + for ((i = 1; i <= COMP_CWORD; i++)); do + if [[ ${COMP_WORDS[i]} != @([-=])* && ${COMP_WORDS[i - 1]} != = ]]; then + _command_offset $i + return + fi + done + + local word tool + for word in "${words[@]:1}"; do + if [[ $word == --tool=?* ]]; then + tool=$word + break + fi + done + + case $prev in + -h | --help | --help-debug | --version) + return + ;; + --tool) + # Tools seem to be named e.g. like memcheck-amd64-linux from which + # we want to grab memcheck. + COMPREPLY=($(compgen -W '$( + for f in /usr{,/local}/lib{,64,exec}{/*-linux-gnu,}/valgrind/* + do + [[ $f != *.so && -x $f && $f =~ ^.*/(.*)-[^-]+-[^-]+ ]] && + printf "%s\n" "${BASH_REMATCH[1]}" + done)' -- "$cur")) + return + ;; + --sim-hints) + COMPREPLY=($(compgen -W 'lax-ioctls enable-outer' -- "$cur")) + return + ;; + --soname-synonyms) + COMPREPLY=($(compgen -W 'somalloc' -S = -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + ;; + --kernel-variant) + COMPREPLY=($(compgen -W 'bproc' -- "$cur")) + return + ;; + # callgrind: + --callgrind-out-file) + _filedir + return + ;; + # exp-dhat: + --sort-by) + COMPREPLY=($(compgen -W 'max-bytes-live tot-bytes-allocd + max-blocks-live' -- "$cur")) + return + ;; + # massif: + --time-unit) + COMPREPLY=($(compgen -W 'i ms B' -- "$cur")) + return + ;; + # generic cases parsed from --help output + --+([-A-Za-z0-9_])) + local value=$($1 --help-debug ${tool-} 2>/dev/null | + command sed -ne "s|^[[:blank:]]*$prev=\([^[:blank:]]\{1,\}\).*|\1|p") + case $value in + \<file*\>) + _filedir + return + ;; + \<command\>) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + \<+([0-9])..+([0-9])\>) + COMPREPLY=($(compgen -W "{${value:1:${#value}-2}}" \ + -- "$cur")) + return + ;; + # "yes", "yes|no", etc (but not "string", "STR", + # "hint1,hint2,...") + yes | +([-a-z0-9])\|+([-a-z0-9\|])) + COMPREPLY=($(IFS='|' compgen -W '$value' -- "$cur")) + return + ;; + esac + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" "--help ${tool-}")' \ + -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi +} && + complete -F _valgrind valgrind + +# ex: filetype=sh diff --git a/completions/vipw b/completions/vipw new file mode 100644 index 0000000..b3a7415 --- /dev/null +++ b/completions/vipw @@ -0,0 +1,22 @@ +# vipw(8) and vigr completion -*- shell-script -*- + +_vipw() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | -!(-*)h) + return + ;; + --root | -!(-*)R) + _filedir -d + return + ;; + esac + + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) +} && + complete -F _vipw vipw vigr + +# ex: filetype=sh diff --git a/completions/vmstat b/completions/vmstat new file mode 100644 index 0000000..e36934a --- /dev/null +++ b/completions/vmstat @@ -0,0 +1,27 @@ +# vmstat(8) completion -*- shell-script -*- + +_vmstat() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --version | --partition | -!(-*)[hVcMNnwp]) + return + ;; + --unit | -!(-*)S) + [[ $OSTYPE == *linux* ]] && + COMPREPLY=($(compgen -W 'k K m M' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} ]] || + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + fi +} && + complete -F _vmstat vmstat + +# ex: filetype=sh diff --git a/completions/vncviewer b/completions/vncviewer new file mode 100644 index 0000000..ba55226 --- /dev/null +++ b/completions/vncviewer @@ -0,0 +1,99 @@ +# bash completion for vncviewer -*- shell-script -*- + +_vncviewer_bootstrap() +{ + local fname + case $(_realcommand vncviewer) in + *xvnc4viewer) fname=_xvnc4viewer ;; + *tightvncviewer) fname=_tightvncviewer ;; + *) fname=_known_hosts ;; + esac + + # Install real completion for subsequent completions + complete -F $fname vncviewer + $fname # Generate completions once for now + unset -f _vncviewer_bootstrap +} && + complete -F _vncviewer_bootstrap vncviewer + +_tightvncviewer() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -passwd) + _filedir + return + ;; + -encodings) + COMPREPLY=($(compgen -W 'copyrect tight hextile zlib corre rre + raw' -- "$cur")) + return + ;; + -via) + _known_hosts_real -- "$cur" + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-help -listen -via -shared -noshared + -viewonly -fullscreen -noraiseonbeep -passwd -encodings -bgr233 + -owncmap -truecolour -truecolor -depth -compresslevel -quality + -nojpeg -nocursorshape -x11cursor' -- "$cur")) + else + _known_hosts_real -- "$cur" + fi +} && + complete -F _tightvncviewer tightvncviewer + +# NOTE: - VNC Viewer options are case insensitive. +# Preferred case is taken from -help. +_xvnc4viewer() +{ + local cur prev words cword + _init_completion || return + + # Both single dash (-) and double dash (--) are allowed as option prefix + local opt=${prev/#--/-} + case ${opt,,} in + # -passwd, -PasswordFile + -passwd | -passwordfile) + _filedir + return + ;; + -preferredencoding) + COMPREPLY=($(compgen -W 'zrle hextile raw' -- "$cur")) + return + ;; + -via) + _known_hosts_real -- "$cur" + return + ;; + esac + + if [[ $cur == -* || $cur == --* ]]; then + # Default to vncviewer camelcase options, see `vncviewer -help' + local dash options=(AcceptClipboard AutoSelect DebugDelay display + DotWhenNoCursor FullColor FullColour FullScreen geometry help + listen Log LowColourLevel MenuKey name Parent passwd PasswordFile + PointerEventInterval PreferredEncoding SendClipboard SendPrimary + Shared UseLocalCursor via ViewOnly WMDecorationHeight + WMDecorationWidth ZlibLevel) + [[ $cur == --* ]] && dash=-- || dash=- + + local IFS=$' \t\n' reset=$(shopt -p nocasematch) + shopt -s nocasematch + local option + COMPREPLY=($(for option in "${options[@]}"; do + [[ $dash$option == "$cur"* ]] && printf '%s\n' $dash$option + done)) + $reset + else + _known_hosts_real -- "$cur" + fi +} && + complete -F _xvnc4viewer xvnc4viewer + +# ex: filetype=sh diff --git a/completions/vpnc b/completions/vpnc new file mode 100644 index 0000000..bbdb8ee --- /dev/null +++ b/completions/vpnc @@ -0,0 +1,82 @@ +# bash completion for vpnc -*- shell-script -*- + +_vpnc() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --long-help | --version | --id | --username | --domain | --ifname | \ + --application-version | --local-addr | --local-port | --udp-port | --dpd-idle | \ + --target-network | --ifmtu) + return + ;; + --gateway) + _known_hosts_real -- "$cur" + return + ;; + --vendor) + COMPREPLY=($(compgen -W 'cisco netscreen' -- "$cur")) + return + ;; + --natt-mode) + COMPREPLY=($(compgen -W 'natt none force-natt cisco-udp' \ + -- "$cur")) + return + ;; + --script | --pid-file | --ca-file) + _filedir + return + ;; + --dh) + COMPREPLY=($(compgen -W 'dh1 dh2 dh5' -- "$cur")) + return + ;; + --pfs) + COMPREPLY=($(compgen -W 'nopfs dh1 dh2 dh5 server' -- "$cur")) + return + ;; + --ifmode) + COMPREPLY=($(compgen -W 'tun tap' -- "$cur")) + return + ;; + --debug) + COMPREPLY=($(compgen -W '0 1 2 3 99' -- "$cur")) + return + ;; + --auth-mode) + COMPREPLY=($(compgen -W 'psk cert hybrid' -- "$cur")) + return + ;; + --ca-dir) + _filedir -d + return + ;; + --password-helper) + compopt -o filenames + COMPREPLY=($(compgen -c -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --long-help)' -- "$cur")) + elif [[ $cur == */* ]]; then + # explicit filename + _filedir conf + else + # config name, /etc/vpnc/<name>.conf + local IFS=$' \t\n' reset=$(shopt -p nullglob) + shopt -s nullglob + local -a configs=(/etc/vpnc/*.conf) + configs=("${configs[@]##*/}") + configs=("${configs[@]%.conf}") + $reset + IFS=$'\n' + compopt -o filenames + COMPREPLY=($(compgen -W '${configs[@]}' -- "$cur")) + fi +} && + complete -F _vpnc vpnc + +# ex: filetype=sh diff --git a/completions/watch b/completions/watch new file mode 100644 index 0000000..efc0a98 --- /dev/null +++ b/completions/watch @@ -0,0 +1,54 @@ +# watch(1) completion -*- shell-script -*- + +[[ $OSTYPE == *linux* ]] || return 1 + +_watch() +{ + local cur prev words cword split + _init_completion -s || return + + local offset=0 i + for ((i = 1; i <= cword; i++)); do + case ${words[i]} in + --help | --version | -!(-*)h) + return + ;; + --interval | -!(-*)n) + ((i++)) + continue + ;; + -*) + continue + ;; + esac + offset=$i + break + done + + if ((offset > 0)); then + _command_offset $offset + return + fi + + case $prev in + --differences | -!(-*)d) + [[ $cur != -* ]] && + COMPREPLY=($(compgen -W 'cumulative' -- "$cur")) + return + ;; + --interval | -!(-*)n) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi +} && + complete -F _watch watch + +# ex: filetype=sh diff --git a/completions/webmitm b/completions/webmitm new file mode 100644 index 0000000..549c5ef --- /dev/null +++ b/completions/webmitm @@ -0,0 +1,17 @@ +# webmitm completion -*- shell-script -*- + +_webmitm() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + else + _known_hosts_real -- "$cur" + fi + +} && + complete -F _webmitm webmitm + +# ex: filetype=sh diff --git a/completions/wget b/completions/wget new file mode 100644 index 0000000..d6a2fe9 --- /dev/null +++ b/completions/wget @@ -0,0 +1,174 @@ +# wget(1) completion -*- shell-script -*- + +_wget() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --version | --help | -!(-*)[hV]) + return + ;; + --progress) + COMPREPLY=($(compgen -W 'bar dot' -- "$cur")) + return + ;; + --bind-address) + _ip_addresses + return + ;; + --domains | --exclude-domains | -!(-*)D) + _known_hosts_real -- "$cur" + return + ;; + --restrict-file-names) + local excludes=() + case $cur in + *unix* | *windows*) + excludes=(windows unix) + ;;& + *lowercase* | *uppercase*) + excludes+=(lowercase uppercase) + ;;& + *nocontrol*) + excludes+=(nocontrol) + ;;& + *ascii*) + excludes+=(ascii) + ;; + esac + local excludes_str=$( + export IFS='|' + echo "${excludes[*]}" + ) + + # prevopt is the previous options string used as a prefix + # to avoid COMPREPLY replacing them with the $lastopt completion + local lastopt=${cur/*,/} prevopt= + [[ $cur == *,* ]] && prevopt=${cur%,*}, + + COMPREPLY=($(compgen -P "$prevopt" -X "@($excludes_str)" \ + -W 'unix windows nocontrol ascii lowercase uppercase' \ + -- "$lastopt")) + + # +o nospace when no more valid option is possible (= append a space) + local opt_as_arr=(${COMPREPLY[0]//,/ }) + ((${#opt_as_arr[@]} < 4)) && compopt -o nospace + return + ;; + --prefer-family) + COMPREPLY=($(compgen -W 'IPv4 IPv6 none' -- "$cur")) + return + ;; + --directory-prefix | --ca-directory | --warc-tempdir | -!(-*)P) + _filedir -d + return + ;; + --output-file | --append-output | --config | --load-cookies | --save-cookies | \ + --post-file | --certificate | --ca-certificate | --private-key | \ + --random-file | --egd-file | --warc-file | --warc-dedup | -!(-*)[oa]) + _filedir + return + ;; + --output-document | --input-file | -!(-*)[Oi]) + _filedir && [[ $cur == - || -z $cur ]] && COMPREPLY+=(-) + return + ;; + --secure-protocol) + COMPREPLY=($(compgen -W 'auto SSLv2 SSLv3 TLSv1' -- "$cur")) + return + ;; + --certificate-type | --private-key-type) + COMPREPLY=($(compgen -W 'PEM DER' -- "$cur")) + return + ;; + --follow-tags | --ignore-tags) + local lastopt=${cur/*,/} prevopt= + [[ $cur == *,* ]] && prevopt=${cur%,*}, + + COMPREPLY=($(compgen -P "$prevopt" -W 'a abbr acronym address + applet area b base basefont bdo big blockquote body br button + caption center cite code col colgroup dd del dir div dfn dl dt + em fieldset font form frame frameset h6 head hr html i iframe + img input ins isindex kbd label legend li link map menu meta + noframes noscript object ol optgroup option p param pre q s + samp script select small span strike strong style sub sup table + tbody td textarea tfoot th thead title tr tt u ul var xmp' \ + -- "$lastopt")) + return + ;; + --tries | --timeout | --dns-timeout | --connect-timeout | --read-timeout | \ + --wait | --waitretry | --cut-dirs | --max-redirect | --level | -!(-*)[tTwl]) + # expect integer number + COMPREPLY+=($(compgen -P "$cur" -W "{0..9}")) + compopt -o nospace + return + ;; + --quota | --limit-rate | --warc-max-size | -!(-*)Q) + # expect size + if [[ $cur == *[km] ]]; then + COMPREPLY=($(compgen -W "$cur")) + elif [[ $cur ]]; then + COMPREPLY=($(compgen -P "$cur" -W "{0..9} k m")) + compopt -o nospace + else + COMPREPLY=($(compgen -W "{0..9}")) + compopt -o nospace + fi + return + ;; + --user | --http-user | --proxy-user | --ftp-user) + COMPREPLY=($(compgen -W "$(command sed -n \ + '/^login/s/^[[:blank:]]*login[[:blank:]]//p' ~/.netrc \ + 2>/dev/null)" -- "$cur")) + return + ;; + --header) + COMPREPLY=($(compgen -W 'Accept Accept-Charset Accept-Encoding + Accept-Language Accept-Ranges Age Allow Authorization + Cache-Control Connection Content-Encoding Content-Language + Content-Length Content-Location Content-MD5 Content-Range + Content-Type Date ETag Expect Expires From Host If-Match + If-Modified-Since If-None-Match If-Range If-Unmodified-Since + Last-Modified Location Max-Forwards Pragma Proxy-Authenticate + Proxy-Authorization Range Referer Retry-After Server TE Trailer + Transfer-Encoding Upgrade User-Agent Vary Via Warning + WWW-Authenticate' -- "$cur")) + compopt -o nospace + return + ;; + --local-encoding | --remote-encoding) + type -P xauth &>/dev/null && _xfunc iconv _iconv_charsets + return + ;; + --execute | -!(-*)e) + return # TODO base=STR + ;; + --report-speed) + COMPREPLY=($(compgen -W 'bits' -- "$cur")) + return + ;; + --regex-type) + COMPREPLY=($(compgen -W 'posix' -- "$cur")) + return + ;; + --base | --password | --ftp-password | --http-password | --proxy-password | \ + --default-page | --referer | --user-agent | --post-data | --warc-header | \ + --accept | --reject | --accept-regex | --reject-regex | --include-directories | \ + --exclude-directories | -!(-*)[BUARIX]) + # argument required but no completions available + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi + +} && + complete -F _wget wget + +# ex: filetype=sh diff --git a/completions/wine b/completions/wine new file mode 100644 index 0000000..429fede --- /dev/null +++ b/completions/wine @@ -0,0 +1,20 @@ +# bash completion for wine(1) -*- shell-script -*- + +_wine() +{ + local cur prev words cword + _init_completion || return + + if ((cword == 1)); then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--help --version' -- "$cur")) + [[ ${COMPREPLY-} ]] && return + fi + _filedir '@([eE][xX][eE]?(.[sS][oO])|[cC][oO][mM]|[sS][cC][rR]|[mM][sS][iI])' + else + _filedir + fi +} && + complete -F _wine wine wine-development wine-stable + +# ex: filetype=sh diff --git a/completions/withlist b/completions/withlist new file mode 100644 index 0000000..4142471 --- /dev/null +++ b/completions/withlist @@ -0,0 +1,18 @@ +# mailman withlist completion -*- shell-script -*- + +_withlist() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--lock --interactive --run --all --quiet + --help' -- "$cur")) + else + _xfunc list_lists _mailman_lists + fi + +} && + complete -F _withlist withlist + +# ex: filetype=sh diff --git a/completions/wodim b/completions/wodim new file mode 100644 index 0000000..b308291 --- /dev/null +++ b/completions/wodim @@ -0,0 +1,96 @@ +# bash completion for cdrecord/wodim -*- shell-script -*- + +_cdrecord() +{ + local cur prev words cword + _init_completion -n = || return + + local generic_options track_options track_mode + + # foo=bar style option + if [[ $cur == *=* ]]; then + prev=${cur%%=*} + cur=${cur#*=} + case $prev in + textfile | cuefile | msifile) + _filedir + ;; + blank) + COMPREPLY=($(compgen -W 'help all fast track unreserve trtail + unclose session' -- "$cur")) + ;; + driveropts) + if [[ $cur == *=* ]]; then + prev=${cur%%=*} + cur=${cur#*=} + case $prev in + varirec) + COMPREPLY=($(compgen -W "-2 -1 0 1 2" -- "$cur")) + ;; + gigarec) + COMPREPLY=($(compgen -W "0.6 0.7 0.8 1.0 1.2 1.3 + 1.4" -- "$cur")) + ;; + tattoofile) + _filedir + ;; + esac + else + COMPREPLY=($(compgen -W 'burnfree noburnfree varirec= + gigarec= audiomaster forcespeed noforcespeed speedread + nospeedread singlesession nosinglesession hidecdr + nohidecdr tattooinfo tattoofile=' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi + ;; + driver) + COMPREPLY=($(compgen -W "$($1 driver=help 2>&1 | + awk 'NR > 1 { print $1 }') help" -- "$cur")) + ;; + minbuf) + COMPREPLY=($(compgen -W '{25..95}' -- "$cur")) + ;; + esac + return + fi + + generic_options=(-version -v -V -d -silent -force -immed -dummy -clone + -dao -sao -tao -raw -raw96r -raw96p -raw16 -multi -msinfo -toc -atip + -fix -nofix -waiti -load -lock -eject -format -setdropts -checkdrive + -prcap -inq -scanbus --devices -reset -abort -overburn -ignsize + -useinfo -packet -noclose -text "debug=" "kdebug=" "minbuf=" + "msifile=" "speed=" "blank=" "fs=" "ts=" "dev=" "gracetime=" + "timeout=" "driver=" "driveropts=" "defpregap=" "pktsize=" "mcn=" + "textfile=" "cuefile=") + track_options=(-audio -swab -data -mode2 -xa -xa1 -xa2 -xamix -cdi + -isosize -pad -nopad -shorttrack -noshorttrack -preemp -nopreemp + -copy -nocopy -scms "isrc=" "index=" "padsize=" "pregap=" "tsize=") + # look if previous was either a file or a track option + track_mode=0 + if ((cword > 1)); then + if [[ -f $prev ]]; then + track_mode=1 + else + local opt + for opt in "${track_options[@]}"; do + if [[ $opt == "$prev" ]]; then + track_mode=1 + break + fi + done + fi + fi + + # files are always eligible completion + _filedir + # track options are always available + COMPREPLY+=($(compgen -W '${track_options[@]}' -- "$cur")) + # general options are no more available after file or track option + if ((track_mode == 0)); then + COMPREPLY+=($(compgen -W '${generic_options[@]}' -- "$cur")) + fi + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace +} && + complete -F _cdrecord cdrecord wodim + +# ex: filetype=sh diff --git a/completions/wol b/completions/wol new file mode 100644 index 0000000..eada070 --- /dev/null +++ b/completions/wol @@ -0,0 +1,42 @@ +# wol(1) completion -*- shell-script -*- + +_wol() +{ + local cur prev words cword split + _init_completion -s -n : || return + + case $prev in + --version | --help | --port | --passwd | --wait | -!(-*)[Vpw]) + return + ;; + --host | --ipaddr | -!(-*)[hi]) + # Broadcast addresses + local PATH=$PATH:/sbin + COMPREPLY=($({ + ip addr show || ifconfig -a + } 2>/dev/null | + command sed -ne 's/.*[[:space:]]Bcast:\([^[:space:]]*\).*/\1/p' -ne \ + 's/.*inet.*[[:space:]]brd[[:space:]]\([^[:space:]]*\).*/\1/p' -ne \ + 's/.*[[:space:]]broadcast[[:space:]]\{1,\}\([^[:space:]]*\).*/\1/p')) + _known_hosts_real -- "$cur" + return + ;; + --file | -!(-*)f) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _mac_addresses +} && + complete -F _wol wol + +# ex: filetype=sh diff --git a/completions/wsimport b/completions/wsimport new file mode 100644 index 0000000..d5bec9f --- /dev/null +++ b/completions/wsimport @@ -0,0 +1,48 @@ +# wsimport(1) completion -*- shell-script -*- + +_wsimport() +{ + local cur prev words cword + _init_completion -n : || return + + case $prev in + -help | -version | -B | -p | -wsdllocation) + return + ;; + -b) + _filedir '@(xml|xjb)' + return + ;; + -catalog) + _filedir '@(xml|soc|catalog)' + return + ;; + -d | –s) + _filedir -d + return + ;; + -target) + COMPREPLY=($(compgen -W '2.0 2.1 2.2' -- "$cur")) + return + ;; + -clientjar) + _filedir jar + return + ;; + esac + + if [[ $cur == -httpproxy:* ]]; then + _known_hosts_real -- "${cur#-httpproxy:}" + return + elif [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + [[ ${COMPREPLY-} == *: ]] && compopt -o nospace + __ltrim_colon_completions "$cur" + return + fi + + _filedir wsdl +} && + complete -F _wsimport wsimport + +# ex: filetype=sh diff --git a/completions/wtf b/completions/wtf new file mode 100644 index 0000000..27fc10a --- /dev/null +++ b/completions/wtf @@ -0,0 +1,42 @@ +# wtf completion -*- shell-script -*- +# Raphael Droz, 25/09/2009 + +_wtf() +{ + local cur prev words cword addf + _init_completion || return + + [[ $prev == -f ]] && _filedir && return + [[ ${words[*]} == *\ -f* ]] && addf= || addf=-f + if [[ $cur == -* ]]; then + COMPREPLY=($addf) + return + fi + + local db + + set -- "${words[@]}" + while (($# > 0)); do + if [[ $1 == -f ]]; then + shift + db=$1 + break + fi + shift + done + + if [[ ! -v db ]]; then + local f + for f in "${ACRONYMDB-}" /usr/share/misc/acronyms \ + /usr/share/games/bsdgames/acronyms; do + [[ -f $f ]] && db="$f" && break + done + [[ -v db ]] || return + fi + + COMPREPLY=($(compgen -W "$(cut -f 1 -s $db* 2>/dev/null) $addf" \ + -- "${cur^^}")) +} && + complete -F _wtf wtf + +# ex: filetype=sh diff --git a/completions/wvdial b/completions/wvdial new file mode 100644 index 0000000..8667400 --- /dev/null +++ b/completions/wvdial @@ -0,0 +1,46 @@ +# bash completion for wvdial -*- shell-script -*- + +_wvdial() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --config) + _filedir + return + ;; + esac + + $split && return + + local config i IFS=$'\n' + + case $cur in + -*) + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + ;; + *) + # start with global and personal config files + config="/etc/wvdial.conf"$'\n'"$HOME/.wvdialrc" + # replace with command line config file if present + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == "--config" ]]; then + config=${words[i + 1]} + break + fi + done + # parse config files for sections and + # remove default section + COMPREPLY=($(command sed -ne "s|^\[Dialer \($cur.*\)\]$|\1|p" $config \ + 2>/dev/null | command grep -v '^Defaults$')) + # escape spaces + COMPREPLY=(${COMPREPLY[@]// /\\ }) + ;; + esac + +} && + complete -F _wvdial wvdial + +# ex: filetype=sh diff --git a/completions/xdg-mime b/completions/xdg-mime new file mode 100644 index 0000000..74c26c4 --- /dev/null +++ b/completions/xdg-mime @@ -0,0 +1,74 @@ +# xdg-mime(1) completion -*- shell-script -*- + +_xdg_mime_mimetype() +{ + COMPREPLY+=($(compgen -S / -W 'application audio font image message model + multipart text video' -- "$cur")) + [[ ${COMPREPLY-} == */ ]] && compopt -o nospace +} + +_xdg_mime() +{ + local cur prev words cword + _init_completion || return + + local args + _count_args + + if ((args == 1)); then + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--help --manual --version' -- "$cur")) + return + fi + COMPREPLY=($(compgen -W \ + 'query default install uninstall' -- "$cur")) + return + fi + + case ${words[1]} in + query) + if ((args == 2)); then + COMPREPLY=($(compgen -W 'filetype default' -- "$cur")) + return + fi + case ${words[2]} in # TODO and args == 3 (takes only one arg!) + filetype) _filedir ;; + default) _xdg_mime_mimetype ;; + esac + ;; + default) + if ((args == 2)); then + local IFS=$' \t\n' reset=$(shopt -p nullglob) + shopt -s nullglob + local -a desktops=(/usr/share/applications/*.desktop) + desktops=("${desktops[@]##*/}") + $reset + IFS=$'\n' + COMPREPLY=($(compgen -W '${desktops[@]}' -- "$cur")) + else + _xdg_mime_mimetype + fi + ;; + install) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--mode --novendor' -- "$cur")) + elif [[ $prev == --mode ]]; then + COMPREPLY=($(compgen -W 'user system' -- "$cur")) + else + _filedir xml + fi + ;; + uninstall) + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '--mode' -- "$cur")) + elif [[ $prev == --mode ]]; then + COMPREPLY=($(compgen -W 'user system' -- "$cur")) + else + _filedir xml + fi + ;; + esac +} && + complete -F _xdg_mime xdg-mime + +# ex: filetype=sh diff --git a/completions/xdg-settings b/completions/xdg-settings new file mode 100644 index 0000000..abd9246 --- /dev/null +++ b/completions/xdg-settings @@ -0,0 +1,31 @@ +# xdg-settings completion -*- shell-script -*- + +_xdg_settings() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --help | --list | --manual | --version) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$("$1" --help | + tr "{|" "\n" | _parse_help -)' -- "$cur")) + return + fi + + local args + _count_args + if ((args == 1)); then + COMPREPLY=($(compgen -W "get check set" -- "$cur")) + elif ((args == 2)); then + COMPREPLY=($(compgen -W \ + '$("$1" --list | awk "!/^Known/ { print \$1 }")' -- "$cur")) + fi +} && + complete -F _xdg_settings xdg-settings + +# ex: filetype=sh diff --git a/completions/xfreerdp b/completions/xfreerdp new file mode 100644 index 0000000..f17414f --- /dev/null +++ b/completions/xfreerdp @@ -0,0 +1,67 @@ +# xfreerdp completion -*- shell-script -*- + +_xfreerdp() +{ + local cur prev words cword + _init_completion -n : || return + + case $prev in # old/dash syntax + -k) + COMPREPLY=($(compgen -W '$("$1" --kbd-list | + awk "/^0x/ { print \$1 }")' -- "$cur")) + return + ;; + -a) + COMPREPLY=($(compgen -W '8 15 16 24 32' -- "$cur")) + return + ;; + -x) + COMPREPLY=($(compgen -W 'broadband modem lan' -- "$cur")) + return + ;; + --plugin) + COMPREPLY=($(compgen -W 'cliprdr rdpsnd rdpdr' -- "$cur")) + return + ;; + esac + + case $cur in # new/slash syntax + /kbd:*) + COMPREPLY=($(compgen -W '$("$1" /kbd-list | + awk "/^0x/ { print \$1 }")' -- "${cur#/kbd:}")) + return + ;; + /bpp:*) + COMPREPLY=($(compgen -W '8 15 16 24 32' -- "${cur#/bpp:}")) + return + ;; + /*:* | /help | /version | -h | --help | --version) + return + ;; + esac + + if [[ $cur == /* ]]; then + COMPREPLY=($(compgen -W '$("$1" --help | + awk "\$1 ~ /^\\// && \$1 !~ /^.(flag\$|option:)/ { sub(\":.*\",\":\",\$1); print \$1 }")' \ + -- "$cur")) + [[ ${COMPREPLY-} == *: ]] && compopt -o nospace + elif [[ $cur == [+-]* ]]; then + local char=${cur:0:1} + local help="$($1 --help)" + if [[ $help == */help* ]]; then # new/slash syntax + COMPREPLY=($(compgen -W '$(awk " + \$1 ~ /^[+-]/ && \$1 !~ /^.toggle\$/ { sub(\"^.\",\"$char\",\$1); print \$1 } + " <<<"$help")' -- "$cur")) + else # old/dash syntax + COMPREPLY=($(_parse_help - <<<"$help")) + COMPREPLY=($(compgen -W '${COMPREPLY[@]%:}' -- "$cur")) + fi + else + COMPREPLY=($(compgen -W "$(awk '{print $1}' ~/.freerdp/known_hosts \ + 2>/dev/null)" -- "$cur")) + fi + +} && + complete -F _xfreerdp xfreerdp + +# ex: filetype=sh diff --git a/completions/xgamma b/completions/xgamma new file mode 100644 index 0000000..8d77ba3 --- /dev/null +++ b/completions/xgamma @@ -0,0 +1,61 @@ +# bash completion for xgamma(1) -*- shell-script -*- + +_xgamma() +{ + local cur prev words cword + _init_completion -n : || return + + case "$prev" in + -screen) + local screens=$(xrandr --query 2>/dev/null | command sed -n \ + '/^Screen /s|^Screen \{1,\}\(.*\):.*$|\1|p' 2>/dev/null) + COMPREPLY=($(compgen -W "$screens" -- "$cur")) + return + ;; + -gamma | -rgamma | -ggamma | -bgamma) + # expect f.f + if [[ $cur && $cur != *.* ]]; then + COMPREPLY=(.) + fi + COMPREPLY+=($(compgen -W "{0..9}")) + compopt -o nospace + return + ;; + -display) + # expect hostname:displaynumber.screennumber + if [[ $cur == :* && $cur != :*.* ]]; then + # FIXME: where to get local display numbers? + local display=${cur#:} + COMPREPLY=($(compgen -W "${display:-0}.")) + compopt -o nospace + elif [[ $cur == :*.* ]]; then + # local screen numbers + local t screens=$(xrandr --query 2>/dev/null | command sed -ne \ + '/^Screen /s|^Screen \{1,\}\(.*\):.*$|\1|p' 2>/dev/null) + t="${cur#:}" + COMPREPLY=($(compgen -P "${t%.*}." -W "$screens" -- \ + "${cur##*.}")) + elif [[ $cur != *:* ]]; then + # complete hostnames + _known_hosts_real -c -- "$cur" + if [[ ! $cur ]]; then + COMPREPLY+=(:) + fi + compopt -o nospace + fi + # no display completion for remote hosts + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + if [[ ${COMPREPLY-} ]]; then + [[ $COMPREPLY == *= ]] && compopt -o nospace + return + fi + fi +} && + complete -F _xgamma xgamma + +# ex: filetype=sh diff --git a/completions/xhost b/completions/xhost new file mode 100644 index 0000000..648ae4f --- /dev/null +++ b/completions/xhost @@ -0,0 +1,16 @@ +# xhost(1) completion -*- shell-script -*- + +_xhost() +{ + local cur prev words cword + _init_completion || return + + case $cur in + +*) _known_hosts_real -p+ -- "${cur:1}" ;; + -*) _known_hosts_real -p- -- "${cur:1}" ;; + *) _known_hosts_real -- "$cur" ;; + esac +} && + complete -F _xhost xhost + +# ex: filetype=sh diff --git a/completions/xmllint b/completions/xmllint new file mode 100644 index 0000000..a6ef38f --- /dev/null +++ b/completions/xmllint @@ -0,0 +1,53 @@ +# bash completion for xmllint(1) -*- shell-script -*- + +_xmllint() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -o | --output) + _filedir + return + ;; + --path | --dtdvalidfpi | --maxmem | --pattern | --xpath) + # argument required but no completions available + return + ;; + --dtdvalid) + _filedir 'dtd?(.gz)' + return + ;; + --relaxng) + _filedir 'rng?(.gz)' + return + ;; + --schema) + _filedir 'xsd?(.gz)' + return + ;; + --schematron) + _filedir 'sch?(.gz)' + return + ;; + --encode) + _xfunc iconv _iconv_charsets + return + ;; + --pretty) + COMPREPLY=($(compgen -W '{0..2}' -- "$cur")) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + COMPREPLY=("${COMPREPLY[@]%:}") + return + fi + + _filedir '@(*ml|htm|svg?(z)|xs[dl]|rng|wsdl|jnlp|tld|dbk|docbook|page)?(.gz)' +} && + complete -F _xmllint xmllint + +# ex: filetype=sh diff --git a/completions/xmlwf b/completions/xmlwf new file mode 100644 index 0000000..b397af9 --- /dev/null +++ b/completions/xmlwf @@ -0,0 +1,32 @@ +# bash completion for xmlwf(1) -*- shell-script -*- + +_xmlwf() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -*d) + _filedir -d + return + ;; + -*e) + COMPREPLY=($(compgen -W 'US-ASCII UTF-8 UTF-16 ISO-8859-1' \ + -- "$cur")) + return + ;; + -*v) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_usage "$1")' -- "$cur")) + return + fi + + _filedir '@(*ml|htm|svg|xs[dl]|rng|wsdl|jnlp|tld|dbk|docbook|page)' +} && + complete -F _xmlwf xmlwf + +# ex: filetype=sh diff --git a/completions/xmms b/completions/xmms new file mode 100644 index 0000000..af4aefe --- /dev/null +++ b/completions/xmms @@ -0,0 +1,29 @@ +# bash completion for xmms -*- shell-script -*- + +_xmms() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --help | --version | -!(-*)[hv]) + return + ;; + --toggle-shuffle | --toggle-repeat | --toggle-advance | -!(-*)[SRA]) + COMPREPLY=($(compgen -W 'on off' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + else + _filedir '@(mp[23]|ogg|wav|pls|m3u|xm|mod|s[3t]m|it|mtm|ult|flac)' + fi + +} && + complete -F _xmms xmms + +# ex: filetype=sh diff --git a/completions/xmodmap b/completions/xmodmap new file mode 100644 index 0000000..7cfa230 --- /dev/null +++ b/completions/xmodmap @@ -0,0 +1,23 @@ +# xmodmap(1) completion -*- shell-script -*- + +_xmodmap() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -display | -e) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -help)' -- "$cur")) + return + fi + + _filedir +} && + complete -F _xmodmap xmodmap + +# ex: filetype=sh diff --git a/completions/xrandr b/completions/xrandr new file mode 100644 index 0000000..16704e3 --- /dev/null +++ b/completions/xrandr @@ -0,0 +1,63 @@ +# bash completion for xrandr -*- shell-script -*- + +_xrandr() +{ + local cur prev words cword + _init_completion || return + + case "$prev" in + -display | -d | -help | -s | --size | -r | --rate | --refresh | --screen | --fb | --fbmm | \ + --dpi | --pos | --set | --scale | --transform | --crtc | --panning | --gamma | \ + --newmode | --rmmode | --addmode | --delmode) + return + ;; + --output | --left-of | --right-of | --above | --below | --same-as) + local outputs=$("$1" | awk '/connected/ {print $1}') + COMPREPLY=($(compgen -W "$outputs" -- "$cur")) + return + ;; + --mode) + local i output + for ((i = 1; i < cword; i++)); do + if [[ ${words[i]} == --output ]]; then + output=${words[i + 1]} + break + fi + done + if [[ -v output ]]; then + local modes=$("$1" | command sed -e "1,/^$output / d" \ + -e "/connected/,$ d" \ + -e "s/\([^[:space:]]\)[[:space:]].*/\1/") + COMPREPLY=($(compgen -W "$modes" -- "$cur")) + fi + return + ;; + -o | --orientation) + COMPREPLY=($(compgen -W 'normal inverted left right 0 1 2 3' -- \ + "$cur")) + return + ;; + --reflect) + COMPREPLY=($(compgen -W 'normal x y xy' -- "$cur")) + return + ;; + --rotate) + COMPREPLY=($(compgen -W 'normal inverted left right' -- "$cur")) + return + ;; + --setprovideroutputsource | --setprovideroffloadsink) + local providers=$("$1" --listproviders 2>/dev/null | + command sed -ne 's/.* name:\([^ ]*\).*/\1/p') + COMPREPLY=($(compgen -W "$providers" -- "$cur")) + # TODO 2nd arg needed, is that a provider as well? + return + ;; + esac + + COMPREPLY=($(compgen -W '$("$1" -help 2>&1 | + command sed -e "s/ or / /g" -e "s/<[^>]*>]//g" | _parse_help -)' \ + -- "$cur")) +} && + complete -F _xrandr xrandr + +# ex: filetype=sh diff --git a/completions/xrdb b/completions/xrdb new file mode 100644 index 0000000..f46f90b --- /dev/null +++ b/completions/xrdb @@ -0,0 +1,27 @@ +# xrdb(1) completion -*- shell-script -*- + +_xrdb() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -backup | -display | -help) + return + ;; + -cpp | -edit) + _filedir + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + return + fi + + _filedir +} && + complete -F _xrdb xrdb + +# ex: filetype=sh diff --git a/completions/xsltproc b/completions/xsltproc new file mode 100644 index 0000000..4cb7071 --- /dev/null +++ b/completions/xsltproc @@ -0,0 +1,49 @@ +# xsltproc(1) completion -*- shell-script -*- + +_xsltproc() +{ + local cur prev words cword + _init_completion || return + + case $prev in + --output | -o) + _filedir + return + ;; + # TODO : number only + --maxdepth) + return + ;; + --encoding) + # some aliases removed + COMPREPLY=($(compgen -X '@(UTF[1378]|8859|ISO[0-9_])*' \ + -W "$(iconv -l | command sed -e 's/\/.*//')" -- "$cur")) + return + ;; + --param | --stringparam) + return + ;; + # not really like --writesubtree + --path) + _filedir -d + return + ;; + --writesubtree) + _filedir -d + return + ;; + esac + + [[ $cword -gt 2 && $(_get_cword '' 2) == --?(string)param ]] && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + COMPREPLY=("${COMPREPLY[@]%:}") + else + # TODO: 1st file xsl|xslt, 2nd XML + _filedir '@(xsl|xslt|xml|dbk|docbook|page)' + fi +} && + complete -F _xsltproc xsltproc + +# ex: filetype=sh diff --git a/completions/xvfb-run b/completions/xvfb-run new file mode 100644 index 0000000..ed2788a --- /dev/null +++ b/completions/xvfb-run @@ -0,0 +1,36 @@ +# bash completion for xvfb-run -*- shell-script -*- + +_xvfb_run() +{ + local cur prev words cword split + _init_completion -s || return + + local i + for ((i = 1; i <= COMP_CWORD; i++)); do + if [[ ${COMP_WORDS[i]} != -* ]]; then + _command_offset $i + return + fi + [[ ${COMP_WORDS[i]} == -!(-*)[npsef] ]] && ((i++)) + done + + case $prev in + --help | --server-num | --xauth-protocol | --server-args | -!(-*)[hnps]) + return + ;; + --error-file | --auth-file | -!(-*)[ef]) + _filedir + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + fi +} && + complete -F _xvfb_run xvfb-run + +# ex: filetype=sh diff --git a/completions/xxd b/completions/xxd new file mode 100644 index 0000000..a470bb0 --- /dev/null +++ b/completions/xxd @@ -0,0 +1,23 @@ +# xxd(1) completion -*- shell-script -*- + +_xxd() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h | -help | -c | -cols | -g | -groupsize | -l | -len | -s | -seek | -v | -version) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" -h)' -- "$cur")) + return + fi + + _filedir +} && + complete -F _xxd xxd + +# ex: filetype=sh diff --git a/completions/xz b/completions/xz new file mode 100644 index 0000000..73958c5 --- /dev/null +++ b/completions/xz @@ -0,0 +1,56 @@ +# xz(1) completion -*- shell-script -*- + +_xz() +{ + local cur prev words cword split + _init_completion -s || return + + local xspec="*.@(xz|lzma|txz|tlz)" + + case $prev in + --decompress | --list | --test | -!(-*)[dlt]*) + xspec="!"$xspec + ;; + --files | --files0) + _filedir + return + ;; + --check | -!(-*)C) + COMPREPLY=($(compgen -W 'crc32 crc64 sha256 none' -- "$cur")) + return + ;; + --format | -!(-*)F) + COMPREPLY=($(compgen -W 'auto xz lzma raw' -- "$cur")) + return + ;; + --threads | -!(-*)T) + COMPREPLY=($(compgen -W "{0..$(_ncpus)}" -- "$cur")) + return + ;; + --memlimit | --memlimit-compress | --memlimit-decompress | --memory | \ + --suffix | --delta | --lzma1 | --lzma2 | -!(-*)[MS]) + return + ;; + --help | --long-help | --version | --info-memory | -!(-*)[hHV]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1" --long-help) {-1..-9}' \ + -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _tilde "$cur" || return + + local IFS=$'\n' + compopt -o filenames + COMPREPLY=($(compgen -f -X "$xspec" -- "$cur") $(compgen -d -- "$cur")) +} && + complete -F _xz xz pxz + +# ex: filetype=sh diff --git a/completions/xzdec b/completions/xzdec new file mode 100644 index 0000000..993bd2b --- /dev/null +++ b/completions/xzdec @@ -0,0 +1,29 @@ +# xzdec(1) completion -*- shell-script -*- + +_xzdec() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + --memory | -!(-*)M) + return + ;; + --help | --version | -!(-*)[hV]) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + _filedir xz # no lzma support here as of xz 4.999.9beta +} && + complete -F _xzdec xzdec + +# ex: filetype=sh diff --git a/completions/ypmatch b/completions/ypmatch new file mode 100644 index 0000000..13249f0 --- /dev/null +++ b/completions/ypmatch @@ -0,0 +1,26 @@ +# bash completion for yp-tools -*- shell-script -*- + +_ypmatch() +{ + local cur prev words cword + _init_completion || return + + local map cmd=${1##*/} + + [[ $cmd == ypcat && $cword -gt 1 ]] && return + [[ $cmd == ypmatch && $cword -gt 2 ]] && return + + if [[ $cmd == ypmatch && $cword -eq 1 && ${#words[@]} -eq 3 ]]; then + map=${words[2]} + COMPREPLY=($(compgen -W '$(ypcat $map 2>/dev/null | \ + cut -d':' -f 1)' -- "$cur")) + else + [[ $cmd == ypmatch && $cword -ne 2 ]] && return + COMPREPLY=($(compgen -W \ + '$(printf "%s\n" $(ypcat -x 2>/dev/null | \ + cut -d"\"" -f 2))' -- "$cur")) + fi +} && + complete -F _ypmatch ypmatch ypcat + +# ex: filetype=sh diff --git a/completions/yum-arch b/completions/yum-arch new file mode 100644 index 0000000..883c77e --- /dev/null +++ b/completions/yum-arch @@ -0,0 +1,16 @@ +# yum-arch(8) completion -*- shell-script -*- + +_yum_arch() +{ + local cur prev words cword + _init_completion || return + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W '-d -v -vv -n -c -z -s -l -q' -- "$cur")) + else + _filedir -d + fi +} && + complete -F _yum_arch yum-arch + +# ex: filetype=sh diff --git a/completions/zopfli b/completions/zopfli new file mode 100644 index 0000000..8c02885 --- /dev/null +++ b/completions/zopfli @@ -0,0 +1,29 @@ +# bash completion for zopfli -*- shell-script -*- + +_zopfli() +{ + local cur prev words cword + _init_completion || return + + case $prev in + -h) + return + ;; + esac + + if [[ $cur == -* ]]; then + COMPREPLY=($(compgen -W \ + '$(_parse_help "$1" -h | command sed -e "s/#$//")' -- "$cur")) + [[ ${COMPREPLY-} == --i ]] && compopt -o nospace + return + fi + + _tilde "$cur" || return + + local IFS=$'\n' xspec="*.@(gz|t[ag]z)" + compopt -o filenames + COMPREPLY=($(compgen -f -X "$xspec" -- "$cur") $(compgen -d -- "$cur")) +} && + complete -F _zopfli zopfli + +# ex: filetype=sh diff --git a/completions/zopflipng b/completions/zopflipng new file mode 100644 index 0000000..4526cd9 --- /dev/null +++ b/completions/zopflipng @@ -0,0 +1,39 @@ +# bash completion for zopflipng -*- shell-script -*- + +_zopflipng() +{ + local cur prev words cword split + _init_completion -s || return + + case $prev in + -h | --help) + return + ;; + --splitting) + COMPREPLY=($(compgen -W '{0..3}' -- "$cur")) + return + ;; + esac + + $split && return + + if [[ $cur == -* ]]; then + COMPREPLY=($(_parse_help "$1" -h)) + COMPREPLY=($(compgen -W '${COMPREPLY[@]%:}' -- "$cur")) + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + return + fi + + if [[ ${words[*]} != *\ --prefix=* ]]; then + # 2 png args only if --prefix not given + local args + _count_args + ((args < 3)) && _filedir png + else + # otherwise arbitrary number of png args + _filedir png + fi +} && + complete -F _zopflipng zopflipng + +# ex: filetype=sh diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..9f1abc2 --- /dev/null +++ b/configure.ac @@ -0,0 +1,20 @@ +AC_PREREQ([2.60]) +AC_INIT([bash-completion], [2.11]) +AM_INIT_AUTOMAKE([foreign dist-xz no-dist-gzip -Wall -Wno-portability -Werror]) +AC_PROG_LN_S +AC_PROG_MKDIR_P +AC_PROG_SED +AC_ARG_WITH([pytest],[ --with-pytest=executable],[PYTEST="$withval"]) +if test -z "$PYTEST"; then + AC_CHECK_PROGS([PYTEST],[pytest pytest-3],[pytest]) +fi +AC_CONFIG_FILES([ +Makefile +completions/Makefile +doc/Makefile +helpers/Makefile +test/Makefile +test/t/Makefile +test/t/unit/Makefile +]) +AC_OUTPUT diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..6930b9c --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,8 @@ +EXTRA_DIST = \ + bash_completion.txt \ + bashrc \ + inputrc \ + main.txt \ + makeHtml.sh \ + styleguide.txt \ + testing.txt diff --git a/doc/bash_completion.txt b/doc/bash_completion.txt new file mode 100644 index 0000000..e67f98b --- /dev/null +++ b/doc/bash_completion.txt @@ -0,0 +1,66 @@ +Bash completion +=============== + +Configuration files +------------------- + +*$BASH_COMPLETION_USER_FILE*:: + Sourced late by bash_completion, pretty much after everything else. + Use this file for example to load additional completions, and to remove + and override ones installed by bash_completion. Defaults to + `~/.bash_completion` if unset or null. + +*$XDG_CONFIG_HOME/bash_completion*:: + Sourced by the bash_completion.sh profile.d script. This file is + suitable for definitions of all `COMP_*` environment variables + below. If `$XDG_CONFIG_HOME` is unset or null, `~/.config` is + used instead of it. + +Environment variables +--------------------- + +*BASH_COMPLETION_COMPAT_DIR*:: + Directory for pre-dynamic loading era (pre-2.0) backwards compatibility + completion files that are loaded eagerly from `bash_completion` when it is + loaded. If unset or null, the default compatibility directory to use is + `/etc/bash_completion.d`. + +*COMP_CONFIGURE_HINTS*:: + If set and not null, `configure` completion will return the entire option + string (e.g. `--this-option=DESCRIPTION`) so one can see what kind of data + is required and then simply delete the descriptive text and add one's own + data. If unset or null (default), `configure` completion will strip + everything after the '=' when returning completions. + +*COMP_CVS_REMOTE*:: + If set and not null, `cvs commit` completion will try to complete on + remotely checked-out files. This requires passwordless access to the + remote repository. Default is unset. + +*COMP_FILEDIR_FALLBACK*:: + If set and not null, completions that look for filenames based on their + "extensions" will fall back to suggesting all files if there are none + matching the sought ones. + +*COMP_IWLIST_SCAN*:: + If set and not null, `iwconfig` completion will try to complete on + available wireless networks identifiers. Default is unset. + +*COMP_KNOWN_HOSTS_WITH_HOSTFILE*:: + If set and not null (default), known hosts completion will complement + hostnames from ssh's known_hosts files with hostnames taken from the file + specified by the HOSTFILE shell variable (compgen -A hostname). If null, + known hosts completion will omit hostnames from HOSTFILE. Omitting + hostnames from HOSTFILE is useful if HOSTFILE contains many entries for + local web development or ad-blocking. + +*COMP_KNOWN_HOSTS_WITH_AVAHI*:: + If set and not null, known hosts completion will try to use `avahi-browse` + for additional completions. This may be a slow operation in some setups. + Default is unset. + +*COMP_TAR_INTERNAL_PATHS*:: + If set and not null *before* sourcing bash_completion, `tar` completion + will do correct path completion for tar file contents. If unset or null, + `tar' completion will do correct completion for paths to tar files. See + also README. diff --git a/doc/bashrc b/doc/bashrc new file mode 120000 index 0000000..e22ec0e --- /dev/null +++ b/doc/bashrc @@ -0,0 +1 @@ +../test/config/bashrc
\ No newline at end of file diff --git a/doc/inputrc b/doc/inputrc new file mode 120000 index 0000000..b6f22e6 --- /dev/null +++ b/doc/inputrc @@ -0,0 +1 @@ +../test/config/inputrc
\ No newline at end of file diff --git a/doc/main.txt b/doc/main.txt new file mode 100644 index 0000000..d8a3076 --- /dev/null +++ b/doc/main.txt @@ -0,0 +1,18 @@ +Bash-completion +=============== +Freddy Vulto (FVu) +v1.0, Mar 2009 + +Preface +======= +Bash completion extends bashs standard completion behavior to achieve +complex command lines with just a few keystrokes. This project was +conceived to produce programmable completion routines for the most +common Linux/UNIX commands, reducing the amount of typing sysadmins +and programmers need to do on a daily basis. + +// include::intro.txt[] +include::bash_completion.txt[] + +include::styleguide.txt[] +include::testing.txt[] diff --git a/doc/makeHtml.sh b/doc/makeHtml.sh new file mode 100755 index 0000000..79780eb --- /dev/null +++ b/doc/makeHtml.sh @@ -0,0 +1,4 @@ +#!/bin/bash -eu + +[ -d html~ ] || mkdir html~ +a2x -D html~ -d book -f xhtml --asciidoc-opts="--unsafe" main.txt diff --git a/doc/styleguide.txt b/doc/styleguide.txt new file mode 100644 index 0000000..2251e77 --- /dev/null +++ b/doc/styleguide.txt @@ -0,0 +1,134 @@ +Coding Style Guide +================== + +Introduction +------------ +This document attempts to explain the basic styles and patterns that +are used in the bash completion. New code should try to conform to +these standards so that it is as easy to maintain as existing code. +Of course every rule has an exception, but it's important to know +the rules nonetheless! + +This is particularly directed at people new to the bash completion +codebase, who are in the process of getting their code reviewed. +Before getting a review, please read over this document and make +sure your code conforms to the recommendations here. + +Indentation +----------- +Indent step should be 4 spaces, no tabs. + +Globbing in case labels +----------------------- + +Avoid "fancy" globbing in case labels, just use traditional style when +possible. For example, do "--foo|--bar)" instead of "--@(foo|bar))". +Rationale: the former is easier to read, often easier to grep, and +doesn't confuse editors as bad as the latter, and is concise enough. + +[[ ]] vs [ ] +---------------- + +Always use [[ ]] instead of [ ]. Rationale: the former is less error +prone, more featureful, and slightly faster. + +Line wrapping +------------- + +Try to wrap lines at 79 characters. Never go past this limit, unless +you absolutely need to (example: a long sed regular expression, or the +like). This also holds true for the documentation and the testsuite. +Other files, like ChangeLog, or COPYING, are exempt from this rule. + +$(...) vs \`...` +---------------- + +When you need to do some code substitution in your completion script, +you *MUST* use the $(...) construct, rather than the \`...`. The former +is preferable because anyone, with any keyboard layout, is able to +type it. Backticks aren't always available, without doing strange +key combinations. + +-o filenames +------------ + +As a rule of thumb, do not use "complete -o filenames". Doing it makes +it take effect for all completions from the affected function, which +may break things if some completions from the function must not be +escaped as filenames. Instead, use "compopt -o filenames" to turn on +"-o filenames" behavior dynamically when returning completions that +need that kind of processing (e.g. file and command names). The +_filedir and _filedir_xspec helpers do this automatically whenever +they return some completions. + +[[ ${COMPREPLY-} == *= ]] && compopt -o nospace +------------------------------------------------ + +The above is functionally a shorthand for: +---- +if [[ ${#COMPREPLY[@]} -eq 1 && ${COMPREPLY[0]} == *= ]]; then + compopt -o nospace +fi +---- +It is used to ensure that long options' name won't get a space +appended after the equal sign. Calling compopt -o nospace makes sense +in case completion actually occurs: when only one completion is +available in COMPREPLY. + +$split && return +---------------- + +Should be used in completions using the -s flag of _init_completion, +or other similar cases where _split_longopt has been invoked, after +$prev has been managed but before $cur is considered. If $cur of the +form --foo=bar was split into $prev=--foo and $cur=bar and the $prev +block did not process the option argument completion, it makes sense +to return immediately after the $prev block because --foo obviously +takes an argument and the remainder of the completion function is +unlikely to provide meaningful results for the required argument. +Think of this as a catch-all for unknown options requiring an +argument. + +Note that even when using this, options that are known to require an +argument but for which we don't have argument completion should be +explicitly handled (non-completed) in the $prev handling block because +--foo=bar options can often be written without the equals sign, and in +that case the long option splitting does not occur. + +Use arithmetic evaluation +------------------------- + +When dealing with numeric data, take advantage of arithmetic evaluation. +In essence, use (( ... )) whenever it can replace [[ ... ]] because the +syntax is more readable; no need for $-prefixes, numeric comparison etc +operators are more familiar and easier on the eye. + +Array subscript access +---------------------- + +Array subscripts are arithmetic expressions, take advantage of that. +E.g. write ${foo[bar]}, not ${foo[$bar]}, and similarly ${foo[bar+1]} +vs ${foo[((bar+1))]} or ${foo[$((bar+1))]}, ${foo[--i]} vs ${foo[((--i))]}. + +Loop variable names +------------------- + +Use i, j, k for loop-local indices; n and m for lengths; some other descriptive +name typically based on array name but in singular when looping over actual +values. If an index or value is to be accessed later on instead of being just +locally for looping, use a more descriptive and specific name for it. + +///////////////////////////////////////// +case/esac vs if +--------------- + +quoting +------- + +awk vs cut for simple cases +--------------------------- + +variable and function naming +---------------------------- + +///////////////////////////////////////// diff --git a/doc/testing.txt b/doc/testing.txt new file mode 100644 index 0000000..3ec7c97 --- /dev/null +++ b/doc/testing.txt @@ -0,0 +1,112 @@ +Automated testing +================= + +Introduction +------------ +The bash-completion package contains an automated test suite. Running the +tests should help verifying that bash-completion works as expected. The tests +are also very helpful in uncovering software regressions at an early stage. + +The test suite is written in Python, using https://pytest.org/[pytest] +and https://pexpect.readthedocs.io/[pexpect]. + + +Coding Style Guide +------------------ + +For the Python part, all of it is formatted using +https://github.com/ambv/black[Black], and we also run +https://flake8.pycqa.org/[Flake8] on it. + + +Installing dependencies +----------------------- + +Installing dependencies should be easy using your local package manager or +`pip`. Python 3.4 or newer is required, and the rest of the Python package +dependencies are specified in the `test/requirements.txt` file. If using `pip`, +this file can be fed directly to it, e.g. like: +------------------------------------ +pip install -r test/requirements.txt +------------------------------------ + + +Debian/Ubuntu +~~~~~~~~~~~~~ + +On Debian/Ubuntu you can use `apt-get`: +------------- +sudo apt-get install python3-pytest python3-pexpect +------------- +This should also install the necessary dependencies. Only Debian testing +(buster) and Ubuntu 18.10 (cosmic) and later have an appropriate version +of pytest in the repositories. + +Fedora/RHEL/CentOS +~~~~~~~~~~~~~~~~~~ + +On Fedora and RHEL/CentOS (with EPEL) you can try `yum` or `dnf`: +------------- +sudo yum install python3-pytest python3-pexpect +------------- +This should also install the necessary dependencies. At time of writing, only +Fedora 29 comes with recent enough pytest. + + + +Structure +--------- + +Tests are in the `t/` subdirectory, with `t/test_\*.py` being completion +tests, and `t/unit/test_unit_\*.py` unit tests. + + +Running the tests +----------------- + +Tests are run by calling `pytest` on the desired test directories or +individual files, for example in the project root directory: +----------------------- +pytest test/t +----------------------- + +See `test/docker/docker-script.sh` for how and what we run and test in CI. + + +Specifying bash binary +~~~~~~~~~~~~~~~~~~~~~~ + +The test suite standard uses `bash` as found in PATH. Export the +`bashcomp_bash` environment variable with a path to another bash executable if +you want to test against something else. + + +Maintenance +----------- + + +Adding a completion test +~~~~~~~~~~~~~~~~~~~~~~~~ + +You can run `cd test && ./generate cmd` to add a test for the `cmd` +command. Additional arguments will be passed to the first generated test case. +This will add the `test/t/test_cmd.py` file with a very basic test, and add it +to `test/t/Makefile.am`. Add additional tests to the generated file. + +Rationale +--------- + + +Naming conventions +~~~~~~~~~~~~~~~~~~ + +Test suite or testsuite +^^^^^^^^^^^^^^^^^^^^^^^ +The primary Wikipedia page is called +https://en.wikipedia.org/wiki/Test_suite[test suite] and not testsuite, so +that's what this document sticks to. + +script/generate +^^^^^^^^^^^^^^^ +The name and location of this code generation script come from Ruby on Rails' +https://en.wikibooks.org/wiki/Ruby_on_Rails/Tools/Generators[script/generate]. diff --git a/extra/git-post-commit.sh b/extra/git-post-commit.sh new file mode 100755 index 0000000..e74c294 --- /dev/null +++ b/extra/git-post-commit.sh @@ -0,0 +1,23 @@ +#!/bin/sh -e + +# Post-commit hook for triggering bash-completion Docker Hub test image +# builds at https://hub.docker.com/r/vskytta/bash-completion/ +# +# To enable: ln -s ../../extra/git-post-commit.sh .git/hooks/post-commit +# +# The bash-completion.docker-hub-trigger-url config option must be set to +# the full Docker Hub build trigger URL to hit. + +url=$(git config bash-completion.docker-hub-trigger-url) + +test "$(git symbolic-ref --short HEAD 2>/dev/null)" = master + +git diff-tree -r --name-only --no-commit-id HEAD | + grep -qxE 'test/test-cmd-list\.txt' + +curl \ + --silent --show-error \ + --max-time 30 \ + --header Content-Type:application/json \ + --data '{"build":true}' \ + $url >/dev/null diff --git a/extra/git-pre-push.sh b/extra/git-pre-push.sh new file mode 100755 index 0000000..52d990e --- /dev/null +++ b/extra/git-pre-push.sh @@ -0,0 +1,44 @@ +#!/bin/sh -e + +# Pre-push hook for triggering bash-completion Docker Hub test image +# builds at https://hub.docker.com/r/vskytta/bash-completion/ +# +# To enable: ln -s ../../extra/git-pre-push.sh .git/hooks/pre-push +# +# The bash-completion.docker-hub-trigger-url config option must be set to +# the full Docker Hub build trigger URL to hit. + +url=$(git config bash-completion.docker-hub-trigger-url) || exit 0 + +branch=master +files="test/test-cmd-list\.txt" + +trigger=false +z40=0000000000000000000000000000000000000000 + +while read local_ref local_sha remote_ref remote_sha; do + case $remote_ref in */$branch) ;; *) continue ;; esac + [ $local_sha != $z40 ] || continue # delete not handled (yet?) + if [ $remote_sha = $z40 ]; then + list_files="git ls-tree -r --name-only $local_sha" + else + list_files="git diff --name-only $remote_sha..$local_sha" + fi + ! $list_files | grep -qEx $files || { + trigger=true + break + } +done + +if $trigger; then + cat <<EOF | at -M now + sleep 15 + curl \ + --silent --show-error \ + --max-time 30 \ + --header Content-Type:application/json \ + --data '{"build":true}' \ + $url 2>&1 \ + | logger -e --tag bash-completion-pre-push +EOF +fi diff --git a/extra/make-changelog.py b/extra/make-changelog.py new file mode 100755 index 0000000..c66b704 --- /dev/null +++ b/extra/make-changelog.py @@ -0,0 +1,38 @@ +#!/usr/bin/python3 + +import sys +from collections import defaultdict +from email.utils import formatdate +from textwrap import wrap +from typing import Dict, List + +import git + +repo = git.Repo(".") +changelog = defaultdict(list) # type: Dict[str, List[str]] + +if len(sys.argv) != 2: + print("Usage: %s SINCE-TAG" % __file__, file=sys.stderr) + sys.exit(2) + +for id in repo.iter_commits("%s..HEAD" % sys.argv[1]): + commit = repo.commit(id) + if not commit.summary.startswith("Merge pull request "): + changelog[commit.author.name].append(commit.summary) + +print("bash-completion (X.Y)") +print("") + +for author in sorted(changelog.keys()): + print(" [ %s ]" % author) + for log in changelog[author]: + print( + "\n".join( + wrap(log, initial_indent=" * ", subsequent_indent=" ") + ) + ) + print("") + +print( + " -- Ville Skyttä <ville.skytta@iki.fi> %s" % formatdate(localtime=True) +) diff --git a/helpers/Makefile.am b/helpers/Makefile.am new file mode 100644 index 0000000..2a0a18d --- /dev/null +++ b/helpers/Makefile.am @@ -0,0 +1,4 @@ +helpersdir = $(datadir)/$(PACKAGE)/helpers +helpers_DATA = perl python + +EXTRA_DIST = $(helpers_DATA) diff --git a/helpers/perl b/helpers/perl new file mode 100644 index 0000000..83ab1a1 --- /dev/null +++ b/helpers/perl @@ -0,0 +1,98 @@ +# -*- perl -*- + +use strict; +use Config; +use Cwd; +use File::Spec::Functions; + +my %seen; + +sub print_modules_real { + my ($base, $dir, $word, $include_pod) = @_; + + # return immediately if potential completion doesn't match current word + # a double comparison is used to avoid dealing with string lengths + # (the shorter being the pattern to be used as the regexp) + # word 'Fi', base 'File' -> match 'File' against 'Fi' + # word 'File::Sp', base 'File' -> match 'File::Sp' against 'File' + return + if $base + && $word + && $base !~ /^\Q$word/ + && $word !~ /^\Q$base/; + + chdir($dir) or return; + + # print each file + foreach my $file (sort(glob('*.pm'), glob('*.pod'))) { + next if ($file =~ /\.pod$/ and not $include_pod); + $file =~ s/\.(?:pm|pod)$//; + my $module = $base . $file; + next if $module !~ /^\Q$word/; + next if $seen{$module}++; + print $module, "\n"; + } + + # recurse in each subdirectory + foreach my $directory (grep {-d} glob('*')) { + my $subdir = $dir . '/' . $directory; + if ($directory =~ /^(?:[.\d]+|$Config{archname}|auto)$/) { + + # exclude subdirectory name from base + print_modules_real(undef, $subdir, $word, $include_pod); + } else { + + # add subdirectory name to base + print_modules_real($base . $directory . '::', + $subdir, $word, $include_pod); + } + } +} + +sub print_modules { + my ($word, $include_pod) = @_; + + my $origdir = getcwd; + foreach my $directory (@INC) { + print_modules_real(undef, $directory, $word, $include_pod); + chdir $origdir; + } +} + +sub print_functions { + my ($word) = @_; + + my $perlfunc; + for (@INC, undef) { + return if not defined; + $perlfunc = catfile $_, qw( pod perlfunc.pod ); + last if -r $perlfunc; + } + + open my $fh, '<', $perlfunc or return; + + my $nest_level = -1; + while (<$fh>) { + next if 1 .. /^=head2 Alphabetical Listing of Perl Functions$/; + ++$nest_level if /^=over/; + --$nest_level if /^=back/; + next if $nest_level; + next unless /^=item (-?\w+)/; + my $function = $1; + next if $function !~ /^\Q$word/; + next if $seen{$function}++; + print $function, "\n"; + } + +} + +my $type = shift; +my $word = shift; + +if ($type eq 'functions') { + print_functions($word); +} elsif ($type eq 'modules') { + print_modules($word); +} elsif ($type eq 'perldocs') { + print_modules($word, 1); +} diff --git a/helpers/python b/helpers/python new file mode 100644 index 0000000..a74387f --- /dev/null +++ b/helpers/python @@ -0,0 +1,14 @@ +# -*- python -*- + +import pkgutil +import sys + +# walk_packages() is much slower than iter_modules(), use it only when +# completing something with a dot in it. +if len(sys.argv) > 1 and "." in sys.argv[1]: + walker = pkgutil.walk_packages +else: + walker = pkgutil.iter_modules + +for mod in walker(): + print(mod[1]) # noqa: E211 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..2581528 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[tool.black] +line-length = 79 +target-version = ["py34", "py35", "py36", "py37", "py38"] diff --git a/setup-symlinks.sh b/setup-symlinks.sh new file mode 100755 index 0000000..806de81 --- /dev/null +++ b/setup-symlinks.sh @@ -0,0 +1,11 @@ +#!/bin/sh -eu + +targetdir="$1" +shift +target="$1" +shift + +for file in "$@"; do + rm -f "$targetdir/$file" + ln -s "$target" "$targetdir/$file" +done diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..c428b94 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,2 @@ +tmp/ +pytestdebug.log diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..591c8f7 --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,14 @@ +SUBDIRS = t + +EXTRA_DIST = config \ + fixtures \ + setup.cfg + +all: + $(MKDIR_P) tmp + +CLEANFILES = \ + fixtures/make/extra_makefile + +clean-local: + $(RM) -rf tmp diff --git a/test/config/bashrc b/test/config/bashrc new file mode 100644 index 0000000..141dddc --- /dev/null +++ b/test/config/bashrc @@ -0,0 +1,62 @@ +# bashrc file for bash-completion test suite + +# Note that we do some initialization that would be too late to do here in +# conftest.py. + +# Use emacs key bindings +set -o emacs + +# Use bash strict mode +set -o posix + +# Raise error on uninitialized variables +set -o nounset + +# Unset `command_not_found_handle' as defined on Debian/Ubuntu, because this +# troubles and slows down testing +unset -f command_not_found_handle + +TESTDIR=$(pwd) + +export PS2='> ' + +# Also test completions of system administrator commands, which are +# installed via the same PATH expansion in `bash_completion.have()' +export PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin + +# ...as well as games on some systems not in PATH by default: +export PATH=$PATH:/usr/games:/usr/local/games + +# For clean test state, avoid sourcing user's ~/.bash_completion +export BASH_COMPLETION_USER_FILE=/dev/null + +# ...and avoid stuff in BASH_COMPLETION_USER_DIR and system install locations +# overriding in-tree completions. Setting the user dir would otherwise suffice, +# but simple xspec completions are only installed if a separate one is not +# found in any completion dirs. Therefore we also point the "system" dirs to +# locations that should not yield valid completions and helpers paths either. +export BASH_COMPLETION_USER_DIR=$( + cd "$SRCDIR/.." || exit 1 + pwd +) +# /var/empty isn't necessarily actually always empty :P +export BASH_COMPLETION_COMPAT_DIR=/var/empty/bash_completion.d +export XDG_DATA_DIRS=/var/empty + +# Make sure default settings are in effect +unset -v \ + COMP_CONFIGURE_HINTS \ + COMP_CVS_REMOTE \ + COMP_KNOWN_HOSTS_WITH_HOSTFILE \ + COMP_TAR_INTERNAL_PATHS + +# @param $1 Char to add to $COMP_WORDBREAKS +add_comp_wordbreak_char() +{ + [[ "${COMP_WORDBREAKS//[^$1]/}" ]] || COMP_WORDBREAKS+=$1 +} + +# Local variables: +# mode: shell-script +# End: +# ex: filetype=sh diff --git a/test/config/inputrc b/test/config/inputrc new file mode 100644 index 0000000..da896f5 --- /dev/null +++ b/test/config/inputrc @@ -0,0 +1,22 @@ +# Readline init file for bash-completion test suite +# See: info readline + +# Press TAB once (instead of twice) to auto-complete +set show-all-if-ambiguous on + +# No bell. No ^G in output +set bell-style none + +# Don't query user about viewing the number of possible completions +set completion-query-items -1 + +# Don't use pager when showing completions +set page-completions off + +# Print each completion on its own line +set completion-display-width 0 + +# Local variables: +# mode: shell-script +# End: +# ex: filetype=sh diff --git a/test/docker/Dockerfile b/test/docker/Dockerfile new file mode 100644 index 0000000..200f918 --- /dev/null +++ b/test/docker/Dockerfile @@ -0,0 +1,6 @@ +ARG DIST +FROM vskytta/bash-completion:$DIST + +WORKDIR /work +COPY . . +CMD ["test/docker/docker-script.sh"] diff --git a/test/docker/docker-script.sh b/test/docker/docker-script.sh new file mode 100755 index 0000000..b3f351f --- /dev/null +++ b/test/docker/docker-script.sh @@ -0,0 +1,16 @@ +#!/bin/sh -ex + +if [ "$BSD" ]; then + PATH=/usr/local/lib/bsd-bin:$PATH + export PATH +fi + +export bashcomp_bash=bash +env + +autoreconf -i +./configure +make -j + +xvfb-run make distcheck \ + PYTESTFLAGS="--verbose --numprocesses=auto --dist=loadfile" diff --git a/test/fixtures/7z/a.7z b/test/fixtures/7z/a.7z Binary files differnew file mode 100644 index 0000000..3357064 --- /dev/null +++ b/test/fixtures/7z/a.7z diff --git a/test/fixtures/7z/f.txt b/test/fixtures/7z/f.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/fixtures/7z/f.txt @@ -0,0 +1 @@ + diff --git a/test/fixtures/_filedir/a b/i b/test/fixtures/_filedir/a b/i new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_filedir/a b/i diff --git a/test/fixtures/_filedir/a$b/h b/test/fixtures/_filedir/a$b/h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_filedir/a$b/h diff --git a/test/fixtures/_filedir/a&b/f b/test/fixtures/_filedir/a&b/f new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_filedir/a&b/f diff --git a/test/fixtures/_filedir/a'b/c b/test/fixtures/_filedir/a'b/c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_filedir/a'b/c diff --git a/test/fixtures/_filedir/ab/e b/test/fixtures/_filedir/ab/e new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_filedir/ab/e diff --git a/test/fixtures/_filedir/aé/g b/test/fixtures/_filedir/aé/g new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_filedir/aé/g diff --git a/test/fixtures/_filedir/brackets/[x] b/test/fixtures/_filedir/brackets/[x] new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/fixtures/_filedir/brackets/[x] @@ -0,0 +1 @@ + diff --git a/test/fixtures/_filedir/brackets/x b/test/fixtures/_filedir/brackets/x new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/fixtures/_filedir/brackets/x @@ -0,0 +1 @@ + diff --git a/test/fixtures/_filedir/ext/ee.e1 b/test/fixtures/_filedir/ext/ee.e1 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_filedir/ext/ee.e1 diff --git a/test/fixtures/_filedir/ext/ff.e2 b/test/fixtures/_filedir/ext/ff.e2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_filedir/ext/ff.e2 diff --git a/test/fixtures/_filedir/ext/foo/.gitignore b/test/fixtures/_filedir/ext/foo/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_filedir/ext/foo/.gitignore diff --git a/test/fixtures/_filedir/ext/gg.e1 b/test/fixtures/_filedir/ext/gg.e1 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_filedir/ext/gg.e1 diff --git a/test/fixtures/_filedir/ext/hh.e2 b/test/fixtures/_filedir/ext/hh.e2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_filedir/ext/hh.e2 diff --git a/test/fixtures/_filedir/ext/ii.E1 b/test/fixtures/_filedir/ext/ii.E1 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_filedir/ext/ii.E1 diff --git a/test/fixtures/_get_cword/sea b/test/fixtures/_get_cword/sea new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_get_cword/sea diff --git a/test/fixtures/_get_cword/seb b/test/fixtures/_get_cword/seb new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_get_cword/seb diff --git a/test/fixtures/_get_cword/sec b/test/fixtures/_get_cword/sec new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_get_cword/sec diff --git a/test/fixtures/_get_cword/ääää§ b/test/fixtures/_get_cword/ääää§ new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_get_cword/ääää§ diff --git a/test/fixtures/_known_hosts_real/.ssh/config_asterisk_1 b/test/fixtures/_known_hosts_real/.ssh/config_asterisk_1 new file mode 100644 index 0000000..fc09eb0 --- /dev/null +++ b/test/fixtures/_known_hosts_real/.ssh/config_asterisk_1 @@ -0,0 +1 @@ +Host asterisk_1 diff --git a/test/fixtures/_known_hosts_real/.ssh/config_asterisk_2 b/test/fixtures/_known_hosts_real/.ssh/config_asterisk_2 new file mode 100644 index 0000000..42243ad --- /dev/null +++ b/test/fixtures/_known_hosts_real/.ssh/config_asterisk_2 @@ -0,0 +1 @@ +Host asterisk_2 diff --git a/test/fixtures/_known_hosts_real/.ssh/config_question_mark b/test/fixtures/_known_hosts_real/.ssh/config_question_mark new file mode 100644 index 0000000..08e1201 --- /dev/null +++ b/test/fixtures/_known_hosts_real/.ssh/config_question_mark @@ -0,0 +1 @@ +Host question_mark diff --git a/test/fixtures/_known_hosts_real/.ssh/config_relative_path b/test/fixtures/_known_hosts_real/.ssh/config_relative_path new file mode 100644 index 0000000..a7ad4d1 --- /dev/null +++ b/test/fixtures/_known_hosts_real/.ssh/config_relative_path @@ -0,0 +1 @@ +Host relative_path diff --git a/test/fixtures/_known_hosts_real/config b/test/fixtures/_known_hosts_real/config new file mode 100644 index 0000000..fe3fb54 --- /dev/null +++ b/test/fixtures/_known_hosts_real/config @@ -0,0 +1,7 @@ + UserKnownHostsFile _known_hosts_real/known_hosts + + # Unindented +Host gee* jar?this-part-we-do-not-complete-at-least-yet + HostName %h.example.com + # Indented + Host hus%%eth0 !negated #not-a-comment diff --git a/test/fixtures/_known_hosts_real/config_full_path b/test/fixtures/_known_hosts_real/config_full_path new file mode 100644 index 0000000..a91649b --- /dev/null +++ b/test/fixtures/_known_hosts_real/config_full_path @@ -0,0 +1 @@ +Include ~/config_include_recursion diff --git a/test/fixtures/_known_hosts_real/config_include b/test/fixtures/_known_hosts_real/config_include new file mode 100644 index 0000000..a1ae763 --- /dev/null +++ b/test/fixtures/_known_hosts_real/config_include @@ -0,0 +1,7 @@ +#$HOME set to fixtures/_known_hosts_real in unit test +# Include with full path (recursive one) +Include ~/config_full_path +# Include with relative path +Include config_relative_path +# Include with wildcards, and more than one on same row +Include config_asterisk* config_?uestion_mark diff --git a/test/fixtures/_known_hosts_real/config_include_recursion b/test/fixtures/_known_hosts_real/config_include_recursion new file mode 100644 index 0000000..2777069 --- /dev/null +++ b/test/fixtures/_known_hosts_real/config_include_recursion @@ -0,0 +1 @@ +Host recursion diff --git a/test/fixtures/_known_hosts_real/config_tilde b/test/fixtures/_known_hosts_real/config_tilde new file mode 100644 index 0000000..4181aaf --- /dev/null +++ b/test/fixtures/_known_hosts_real/config_tilde @@ -0,0 +1,4 @@ +# With quotes and tilde +UserKnownHostsFile "~/_known_hosts_real/known_hosts2" +# Without quotes, with tilde, and another on the same line +UserKnownHostsFile ~/_known_hosts_real/known_hosts3 _known_hosts_real/known_hosts4 diff --git a/test/fixtures/_known_hosts_real/gee-filename-canary b/test/fixtures/_known_hosts_real/gee-filename-canary new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/_known_hosts_real/gee-filename-canary diff --git a/test/fixtures/_known_hosts_real/known_hosts b/test/fixtures/_known_hosts_real/known_hosts new file mode 100644 index 0000000..646b5b6 --- /dev/null +++ b/test/fixtures/_known_hosts_real/known_hosts @@ -0,0 +1,14 @@ +|1|abc +|1|def +doo +# this is a comment +ike ssh-rsa qwerty1234/Qwerty+1234== +jub,10.0.0.1 +@cert-authority kyl,100.0.0.2 xxxfoo +[10.10.0.3]:10022 +[blah]:1234 +fd00:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:5555 +fe80::123:0xff:dead:beef%eth0 +1111:2222:3333:4444:5555:6666:xxxx:abab +11xx:2222:3333:4444:5555:6666:xxxx:abab +::42 diff --git a/test/fixtures/_known_hosts_real/known_hosts2 b/test/fixtures/_known_hosts_real/known_hosts2 new file mode 100644 index 0000000..2eb4d4f --- /dev/null +++ b/test/fixtures/_known_hosts_real/known_hosts2 @@ -0,0 +1 @@ +two,two2,two3,two*,t?o,two4 diff --git a/test/fixtures/_known_hosts_real/known_hosts3 b/test/fixtures/_known_hosts_real/known_hosts3 new file mode 100644 index 0000000..2bdf67a --- /dev/null +++ b/test/fixtures/_known_hosts_real/known_hosts3 @@ -0,0 +1 @@ +three diff --git a/test/fixtures/_known_hosts_real/known_hosts4 b/test/fixtures/_known_hosts_real/known_hosts4 new file mode 100644 index 0000000..8510665 --- /dev/null +++ b/test/fixtures/_known_hosts_real/known_hosts4 @@ -0,0 +1 @@ +four diff --git a/test/fixtures/_known_hosts_real/localhost_config b/test/fixtures/_known_hosts_real/localhost_config new file mode 100644 index 0000000..30b6623 --- /dev/null +++ b/test/fixtures/_known_hosts_real/localhost_config @@ -0,0 +1 @@ +UserKnownHostsFile _known_hosts_real/localhost_hosts diff --git a/test/fixtures/_known_hosts_real/localhost_hosts b/test/fixtures/_known_hosts_real/localhost_hosts new file mode 100644 index 0000000..ff752c2 --- /dev/null +++ b/test/fixtures/_known_hosts_real/localhost_hosts @@ -0,0 +1,3 @@ +localhost +127.0.0.1 +::1 diff --git a/test/fixtures/_known_hosts_real/spaced conf b/test/fixtures/_known_hosts_real/spaced conf new file mode 100644 index 0000000..566b92c --- /dev/null +++ b/test/fixtures/_known_hosts_real/spaced conf @@ -0,0 +1,8 @@ + + # Unindented +Host gee + UserKnownHostsFile "_known_hosts_real/spaced known_hosts" + + # Indented + Host hus #not-a-comment + UserKnownHostsFile "_known_hosts_real/known_hosts2" diff --git a/test/fixtures/_known_hosts_real/spaced known_hosts b/test/fixtures/_known_hosts_real/spaced known_hosts new file mode 100644 index 0000000..d54a04d --- /dev/null +++ b/test/fixtures/_known_hosts_real/spaced known_hosts @@ -0,0 +1,4 @@ +|1|abc +|1|def +doo +ike ssh-rsa qwerty1234/Qwerty+1234== diff --git a/test/fixtures/_longopt/grep--help.txt b/test/fixtures/_longopt/grep--help.txt new file mode 100644 index 0000000..9266256 --- /dev/null +++ b/test/fixtures/_longopt/grep--help.txt @@ -0,0 +1,70 @@ +Usage: grep [OPTION]... PATTERN [FILE]... +Search for PATTERN in each FILE. +Example: grep -i 'hello world' menu.h main.c + +Pattern selection and interpretation: + -E, --extended-regexp PATTERN is an extended regular expression + -F, --fixed-strings PATTERN is a set of newline-separated strings + -G, --basic-regexp PATTERN is a basic regular expression (default) + -P, --perl-regexp PATTERN is a Perl regular expression + -e, --regexp=PATTERN use PATTERN for matching + -f, --file=FILE obtain PATTERN from FILE + -i, --ignore-case ignore case distinctions + -w, --word-regexp force PATTERN to match only whole words + -x, --line-regexp force PATTERN to match only whole lines + -z, --null-data a data line ends in 0 byte, not newline + +Miscellaneous: + -s, --no-messages suppress error messages + -v, --invert-match select non-matching lines + -V, --version display version information and exit + --help display this help text and exit + +Output control: + -m, --max-count=NUM stop after NUM selected lines + -b, --byte-offset print the byte offset with output lines + -n, --line-number print line number with output lines + --line-buffered flush output on every line + -H, --with-filename print file name with output lines + -h, --no-filename suppress the file name prefix on output + --label=LABEL use LABEL as the standard input file name prefix + -o, --only-matching show only the part of a line matching PATTERN + -q, --quiet, --silent suppress all normal output + --binary-files=TYPE assume that binary files are TYPE; + TYPE is 'binary', 'text', or 'without-match' + -a, --text equivalent to --binary-files=text + -I equivalent to --binary-files=without-match + -d, --directories=ACTION how to handle directories; + ACTION is 'read', 'recurse', or 'skip' + -D, --devices=ACTION how to handle devices, FIFOs and sockets; + ACTION is 'read' or 'skip' + -r, --recursive like --directories=recurse + -R, --dereference-recursive likewise, but follow all symlinks + --include=FILE_PATTERN search only files that match FILE_PATTERN + --exclude=FILE_PATTERN skip files and directories matching FILE_PATTERN + --exclude-from=FILE skip files matching any file pattern from FILE + --exclude-dir=PATTERN directories that match PATTERN will be skipped. + -L, --files-without-match print only names of FILEs with no selected lines + -l, --files-with-matches print only names of FILEs with selected lines + -c, --count print only a count of selected lines per FILE + -T, --initial-tab make tabs line up (if needed) + -Z, --null print 0 byte after FILE name + +Context control: + -B, --before-context=NUM print NUM lines of leading context + -A, --after-context=NUM print NUM lines of trailing context + -C, --context=NUM print NUM lines of output context + -NUM same as --context=NUM + --color[=WHEN], + --colour[=WHEN] use markers to highlight the matching strings; + WHEN is 'always', 'never', or 'auto' + -U, --binary do not strip CR characters at EOL (MSDOS/Windows) + +When FILE is '-', read standard input. With no FILE, read '.' if +recursive, '-' otherwise. With fewer than two FILEs, assume -h. +Exit status is 0 if any line is selected, 1 otherwise; +if any error occurs and -q is not given, the exit status is 2. + +Report bugs to: bug-grep@gnu.org +GNU grep home page: <http://www.gnu.org/software/grep/> +General help using GNU software: <http://www.gnu.org/gethelp/> diff --git a/test/fixtures/_longopt/various.txt b/test/fixtures/_longopt/various.txt new file mode 100644 index 0000000..04c2c25 --- /dev/null +++ b/test/fixtures/_longopt/various.txt @@ -0,0 +1,5 @@ +--- +----nonono +--foo_bar +--foo- +--foo=bar diff --git a/test/fixtures/acroread/bar b/test/fixtures/acroread/bar new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/acroread/bar diff --git a/test/fixtures/acroread/foo.d/.gitignore b/test/fixtures/acroread/foo.d/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/acroread/foo.d/.gitignore diff --git a/test/fixtures/acroread/t.pdf b/test/fixtures/acroread/t.pdf new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/acroread/t.pdf diff --git a/test/fixtures/ant/.gitignore b/test/fixtures/ant/.gitignore new file mode 100644 index 0000000..3a08258 --- /dev/null +++ b/test/fixtures/ant/.gitignore @@ -0,0 +1 @@ +.ant-targets-*.xml diff --git a/test/fixtures/ant/build-with-import.xml b/test/fixtures/ant/build-with-import.xml new file mode 100644 index 0000000..881981a --- /dev/null +++ b/test/fixtures/ant/build-with-import.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project default="build-with-import" name="bash-completion"> + <import file="imported-build.xml" /> + + <target name="build-with-import"> + <!-- ... --> + </target> +</project> diff --git a/test/fixtures/ant/build.xml b/test/fixtures/ant/build.xml new file mode 100644 index 0000000..09b4cd2 --- /dev/null +++ b/test/fixtures/ant/build.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project basedir="." default="build" name="bash-completion"> + <target name="clean"> + <!-- ... --> + </target> +<target + name="realclean" depends="clean"> + <!-- ... --> + </target> + + <target description="bar" name="init"></target> +<target +description="bar" +name='bashcomp' > +<!-- ... --> +</target> +</project> diff --git a/test/fixtures/ant/imported-build.xml b/test/fixtures/ant/imported-build.xml new file mode 100644 index 0000000..0cc438f --- /dev/null +++ b/test/fixtures/ant/imported-build.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project default="imported-build" name="bash-completion"> + <target name="imported-build"> + <!-- ... --> + </target> +</project> diff --git a/test/fixtures/ant/named-build.xml b/test/fixtures/ant/named-build.xml new file mode 100644 index 0000000..e61386d --- /dev/null +++ b/test/fixtures/ant/named-build.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project basedir="." default="named-build" name="bash-completion"> + <target name="named-build"> + <!-- ... --> + </target> +</project> diff --git a/test/fixtures/compgen/a'b/c b/test/fixtures/compgen/a'b/c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/compgen/a'b/c diff --git a/test/fixtures/compgen/t1.txt b/test/fixtures/compgen/t1.txt new file mode 100644 index 0000000..322a14d --- /dev/null +++ b/test/fixtures/compgen/t1.txt @@ -0,0 +1,121 @@ +BASH=/bin/bash +BASH_ARGC=() +BASH_ARGV=() +BASH_LINENO=() +BASH_SOURCE=() +BASH_VERSINFO=([0]="3" [1]="2" [2]="39" [3]="1" [4]="release" [5]="i486-pc-linux-gnu") +BASH_VERSION='3.2.39(1)-release' +CDPL_DIRS=([0]="/home/freddy/proj") +CDPM_DIRS= +CDP_DIRS=([0]="/home/freddy/proj" [1]="") +COLUMNS=130 +COMP_CACHE=/home/freddy/.bash_completion_lib.d/cache~ +COMP_DIR=/etc/bash_completion_lib +COMP_PATH=/home/freddy/.bash_completion_lib.d:/etc/bash_completion_lib +COMP_RESTRICT_BY_EXTENSION=0 +COMP_VERSION=bash_completion_lib-1.3.1 +DIRSTACK=() +EDITOR=/usr/bin/vim +EUID=1000 +GPGKEY=10A575C3 +GPG_AGENT_INFO=/tmp/gpg-Pg6JXR/S.gpg-agent:4129:1 +GPG_TTY=/dev/pts/0 +GREP_OPTIONS='--exclude '\''distrib/*'\'' --exclude tags' +GROUPS=() +HISTCONTROL=ignoreboth +HISTFILE=/home/freddy/.bash_history +HISTFILESIZE=500 +HISTIGNORE=exit +HISTSIZE=500 +HOME=/home/freddy +HOSTNAME=blondy +HOSTTYPE=i486 +IFS=$' \t\n' +LANG=en_US +LANGUAGE=en_NL:en_US:en_GB:en +LINES=49 +LOGNAME=freddy +MACHTYPE=i486-pc-linux-gnu +MAIL=/var/mail/freddy +MAILCHECK=60 +OLDPWD=/home/freddy/.bash_completion_lib.d +OPTERR=1 +OPTIND=1 +OSTYPE=linux-gnu +PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/freddy/proj/rc/bin +PIPESTATUS=([0]="0") +PPID=29352 +PS1=$'\\[\E[0;34m\\]\\!\\[\E[0m\\]\\[\E[1;32m\\]$(stoppedjobs)\\[\E[0m\\]:\\u@\\h:\\w> \\[\E[m\\]' +PS2='> ' +PS4='+ ' +PWD=/home/freddy/proj/bashCompletion/bash-completion.git/test/fixtures/compgen +SHELL=/bin/bash +SHELLOPTS=braceexpand:hashall:histexpand:interactive-comments:monitor:vi +SHLVL=1 +SSH_AUTH_SOCK=/tmp/ssh-xhQbo29352/agent.29352 +SSH_CLIENT='192.168.123.143 37670 4822' +SSH_CONNECTION='192.168.123.143 37670 192.168.123.8 4822' +SSH_TTY=/dev/pts/0 +TERM=xterm +UID=1000 +USER=freddy +VIM=/home/freddy/.vim +VIMRUNTIME=/usr/share/vim/vimcurrent +_=GPG_AGENT_INFO +bash205='3.2.39(1)-release' +bash205b='3.2.39(1)-release' +bash3='3.2.39(1)-release' +cdots () +{ + [ -d "$1$2" ] && cd "$1$2" || eval cd "$1$2" +} +comp_load () +{ + local cmd=${COMP_WORDS[0]} dir globs OLDIFS=$IFS; + IFS=:; + local -a aPaths=($COMP_PATH); + IFS=' +'; + globs=($( + for dir in "${aPaths[@]}"; do + echo \"$dir\"/complete\*/\*.$cmd + echo \"$dir\"/complete\*/$cmd\! + echo \"$dir\"/complete\*/$cmd + done + )); + IFS=$OLDIFS; + if ! declare -F comp_include >&/dev/null; then + for dir in "${aPaths[@]}"; + do + [ -r "$dir/include/comp_include" ] && . "$dir/include/comp_include" && break; + done; + fi; + comp_include comp_load_init; + comp_load_init; + local script="$(eval find "${globs[@]}" 2> /dev/null | head -1)"; + local link comp=${script##*/}; + [[ ${comp: -1:1} == ! ]] || { + link=${comp#*.}; + comp=${comp%.$link} + }; + local path=${script%/*}; + [ "$script" -a -r "$path/$comp" ] && . "$path/$comp" && declare -F _$comp >&/dev/null && { + [ ${COMP_INSTALL:-1} -eq 0 ] || _comp_install $comp "$path" + } && _$comp $link; + comp_load_deinit +} +nameTerminal () +{ + [ "${TERM:0:5}" = "xterm" ] && local ansiNrTab=0; + [ "$TERM" = "rxvt" ] && local ansiNrTab=61; + [ "$TERM" = "konsole" ] && local ansiNrTab=30 ansiNrWindow=0; + [ $ansiNrTab ] && echo -n ''"]$ansiNrTab;$1"''; + [ $ansiNrWindow -a "$2" ] && echo -n ''"]$ansiNrWindow;$2"'' +} +stoppedjobs () +{ + if [ "$(jobs -s)" ]; then + echo -n "%"; + jobs -s | wc -l; + fi +} diff --git a/test/fixtures/compgen/t2.txt b/test/fixtures/compgen/t2.txt new file mode 100644 index 0000000..371ab2b --- /dev/null +++ b/test/fixtures/compgen/t2.txt @@ -0,0 +1,121 @@ +BASH=/bin/bash +BASH_ARGC=() +BASH_ARGV=() +BASH_LINENO=() +BASH_SOURCE=() +BASH_VERSINFO=([0]="3" [1]="2" [2]="39" [3]="1" [4]="release" [5]="i486-pc-linux-gnu") +BASH_VERSION='3.2.39(1)-release' +CDPL_DIRS=([0]="/home/freddy/proj") +CDPM_DIRS= +CDP_DIRS=([0]="/home/freddy/proj" [1]="") +COLUMNS=130 +COMP_CACHE=/home/freddy/.bash_completion_lib.d/cache~ +COMP_DIR=/etc/bash_completion_lib +COMP_PATH=/home/freddy/.bash_completion_lib.d:/etc/bash_completion_lib +COMP_RESTRICT_BY_EXTENSION=0 +COMP_VERSION=bash_completion_lib-1.3.1 +DIRSTACK=() +EDITOR=/usr/bin/vim +EUID=1000 +GPGKEY=10A575C3 +GPG_AGENT_INFO=/tmp/gpg-Pg6JXR/S.gpg-agent:4129:1 +GPG_TTY=/dev/pts/0 +GREP_OPTIONS='--exclude '\''distrib/*'\'' --exclude tags' +GROUPS=() +HISTCONTROL=ignoreboth +HISTFILE=/home/freddy/.bash_history +HISTFILESIZE=500 +HISTIGNORE=exit +HISTSIZE=500 +HOME=/home/freddy +HOSTNAME=blondy +HOSTTYPE=i486 +IFS=$' \t\n' +LANG=en_US +LANGUAGE=en_NL:en_US:en_GB:en +LINES=49 +LOGNAME=freddy +MACHTYPE=i486-pc-linux-gnu +MAIL=/var/mail/freddy +MAILCHECK=60 +OLDPWD=/home/freddy/.bash_completion_lib.d +OPTERR=1 +OPTIND=1 +OSTYPE=linux-gnu +PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/freddy/proj/rc/bin +PIPESTATUS=([0]="0") +PPID=29352 +PS1=$'\\[\E[0;34m\\]\\!\\[\E[0m\\]\\[\E[1;32m\\]$(stoppedjobs)\\[\E[0m\\]:\\u@\\h:\\w> \\[\E[m\\]' +PS2='> ' +PS4='+ ' +PWD=/home/freddy/proj/bashCompletion/bash-completion.git/test/fixtures/compgen +SHELL=/bin/bash +SHELLOPTS=braceexpand:hashall:histexpand:interactive-comments:monitor:vi +SHLVL=1 +SSH_AUTH_SOCK=/tmp/ssh-xhQbo29352/agent.29352 +SSH_CLIENT='192.168.123.143 37670 4822' +SSH_CONNECTION='192.168.123.143 37670 192.168.123.8 4822' +SSH_TTY=/dev/pts/0 +TERM=xterm +UID=1000 +USER=freddy +VIM=/home/freddy/.vim +VIMRUNTIME=/usr/share/vim/vimcurrent +_='a\\\'\''b/' +bash205='3.2.39(1)-release' +bash205b='3.2.39(1)-release' +bash3='3.2.39(1)-release' +cdots () +{ + [ -d "$1$2" ] && cd "$1$2" || eval cd "$1$2" +} +comp_load () +{ + local cmd=${COMP_WORDS[0]} dir globs OLDIFS=$IFS; + IFS=:; + local -a aPaths=($COMP_PATH); + IFS=' +'; + globs=($( + for dir in "${aPaths[@]}"; do + echo \"$dir\"/complete\*/\*.$cmd + echo \"$dir\"/complete\*/$cmd\! + echo \"$dir\"/complete\*/$cmd + done + )); + IFS=$OLDIFS; + if ! declare -F comp_include >&/dev/null; then + for dir in "${aPaths[@]}"; + do + [ -r "$dir/include/comp_include" ] && . "$dir/include/comp_include" && break; + done; + fi; + comp_include comp_load_init; + comp_load_init; + local script="$(eval find "${globs[@]}" 2> /dev/null | head -1)"; + local link comp=${script##*/}; + [[ ${comp: -1:1} == ! ]] || { + link=${comp#*.}; + comp=${comp%.$link} + }; + local path=${script%/*}; + [ "$script" -a -r "$path/$comp" ] && . "$path/$comp" && declare -F _$comp >&/dev/null && { + [ ${COMP_INSTALL:-1} -eq 0 ] || _comp_install $comp "$path" + } && _$comp $link; + comp_load_deinit +} +nameTerminal () +{ + [ "${TERM:0:5}" = "xterm" ] && local ansiNrTab=0; + [ "$TERM" = "rxvt" ] && local ansiNrTab=61; + [ "$TERM" = "konsole" ] && local ansiNrTab=30 ansiNrWindow=0; + [ $ansiNrTab ] && echo -n ''"]$ansiNrTab;$1"''; + [ $ansiNrWindow -a "$2" ] && echo -n ''"]$ansiNrWindow;$2"'' +} +stoppedjobs () +{ + if [ "$(jobs -s)" ]; then + echo -n "%"; + jobs -s | wc -l; + fi +} diff --git a/test/fixtures/compgen/t3.txt b/test/fixtures/compgen/t3.txt new file mode 100644 index 0000000..371ab2b --- /dev/null +++ b/test/fixtures/compgen/t3.txt @@ -0,0 +1,121 @@ +BASH=/bin/bash +BASH_ARGC=() +BASH_ARGV=() +BASH_LINENO=() +BASH_SOURCE=() +BASH_VERSINFO=([0]="3" [1]="2" [2]="39" [3]="1" [4]="release" [5]="i486-pc-linux-gnu") +BASH_VERSION='3.2.39(1)-release' +CDPL_DIRS=([0]="/home/freddy/proj") +CDPM_DIRS= +CDP_DIRS=([0]="/home/freddy/proj" [1]="") +COLUMNS=130 +COMP_CACHE=/home/freddy/.bash_completion_lib.d/cache~ +COMP_DIR=/etc/bash_completion_lib +COMP_PATH=/home/freddy/.bash_completion_lib.d:/etc/bash_completion_lib +COMP_RESTRICT_BY_EXTENSION=0 +COMP_VERSION=bash_completion_lib-1.3.1 +DIRSTACK=() +EDITOR=/usr/bin/vim +EUID=1000 +GPGKEY=10A575C3 +GPG_AGENT_INFO=/tmp/gpg-Pg6JXR/S.gpg-agent:4129:1 +GPG_TTY=/dev/pts/0 +GREP_OPTIONS='--exclude '\''distrib/*'\'' --exclude tags' +GROUPS=() +HISTCONTROL=ignoreboth +HISTFILE=/home/freddy/.bash_history +HISTFILESIZE=500 +HISTIGNORE=exit +HISTSIZE=500 +HOME=/home/freddy +HOSTNAME=blondy +HOSTTYPE=i486 +IFS=$' \t\n' +LANG=en_US +LANGUAGE=en_NL:en_US:en_GB:en +LINES=49 +LOGNAME=freddy +MACHTYPE=i486-pc-linux-gnu +MAIL=/var/mail/freddy +MAILCHECK=60 +OLDPWD=/home/freddy/.bash_completion_lib.d +OPTERR=1 +OPTIND=1 +OSTYPE=linux-gnu +PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/freddy/proj/rc/bin +PIPESTATUS=([0]="0") +PPID=29352 +PS1=$'\\[\E[0;34m\\]\\!\\[\E[0m\\]\\[\E[1;32m\\]$(stoppedjobs)\\[\E[0m\\]:\\u@\\h:\\w> \\[\E[m\\]' +PS2='> ' +PS4='+ ' +PWD=/home/freddy/proj/bashCompletion/bash-completion.git/test/fixtures/compgen +SHELL=/bin/bash +SHELLOPTS=braceexpand:hashall:histexpand:interactive-comments:monitor:vi +SHLVL=1 +SSH_AUTH_SOCK=/tmp/ssh-xhQbo29352/agent.29352 +SSH_CLIENT='192.168.123.143 37670 4822' +SSH_CONNECTION='192.168.123.143 37670 192.168.123.8 4822' +SSH_TTY=/dev/pts/0 +TERM=xterm +UID=1000 +USER=freddy +VIM=/home/freddy/.vim +VIMRUNTIME=/usr/share/vim/vimcurrent +_='a\\\'\''b/' +bash205='3.2.39(1)-release' +bash205b='3.2.39(1)-release' +bash3='3.2.39(1)-release' +cdots () +{ + [ -d "$1$2" ] && cd "$1$2" || eval cd "$1$2" +} +comp_load () +{ + local cmd=${COMP_WORDS[0]} dir globs OLDIFS=$IFS; + IFS=:; + local -a aPaths=($COMP_PATH); + IFS=' +'; + globs=($( + for dir in "${aPaths[@]}"; do + echo \"$dir\"/complete\*/\*.$cmd + echo \"$dir\"/complete\*/$cmd\! + echo \"$dir\"/complete\*/$cmd + done + )); + IFS=$OLDIFS; + if ! declare -F comp_include >&/dev/null; then + for dir in "${aPaths[@]}"; + do + [ -r "$dir/include/comp_include" ] && . "$dir/include/comp_include" && break; + done; + fi; + comp_include comp_load_init; + comp_load_init; + local script="$(eval find "${globs[@]}" 2> /dev/null | head -1)"; + local link comp=${script##*/}; + [[ ${comp: -1:1} == ! ]] || { + link=${comp#*.}; + comp=${comp%.$link} + }; + local path=${script%/*}; + [ "$script" -a -r "$path/$comp" ] && . "$path/$comp" && declare -F _$comp >&/dev/null && { + [ ${COMP_INSTALL:-1} -eq 0 ] || _comp_install $comp "$path" + } && _$comp $link; + comp_load_deinit +} +nameTerminal () +{ + [ "${TERM:0:5}" = "xterm" ] && local ansiNrTab=0; + [ "$TERM" = "rxvt" ] && local ansiNrTab=61; + [ "$TERM" = "konsole" ] && local ansiNrTab=30 ansiNrWindow=0; + [ $ansiNrTab ] && echo -n ''"]$ansiNrTab;$1"''; + [ $ansiNrWindow -a "$2" ] && echo -n ''"]$ansiNrWindow;$2"'' +} +stoppedjobs () +{ + if [ "$(jobs -s)" ]; then + echo -n "%"; + jobs -s | wc -l; + fi +} diff --git a/test/fixtures/cvs/.cvspass b/test/fixtures/cvs/.cvspass new file mode 100644 index 0000000..e7e0dce --- /dev/null +++ b/test/fixtures/cvs/.cvspass @@ -0,0 +1,2 @@ +/1 :pserver:anonymous@cvs.savannah.nongnu.org:2401/sources/cvs A +/1 :pserver:anonymous@cvs.fedoraproject.org:2401/cvs/pkgs A diff --git a/test/fixtures/cvs/foo/CVS/Entries b/test/fixtures/cvs/foo/CVS/Entries new file mode 100644 index 0000000..6462f98 --- /dev/null +++ b/test/fixtures/cvs/foo/CVS/Entries @@ -0,0 +1,2 @@ +/bar/1.1/Tue Jan 29 05:52:29 2008// +D diff --git a/test/fixtures/cvs/foo/bar b/test/fixtures/cvs/foo/bar new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/cvs/foo/bar diff --git a/test/fixtures/cvs/foo/quux b/test/fixtures/cvs/foo/quux new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/cvs/foo/quux diff --git a/test/fixtures/dnssec-keygen/dnssec-keygen b/test/fixtures/dnssec-keygen/dnssec-keygen new file mode 100755 index 0000000..882cd97 --- /dev/null +++ b/test/fixtures/dnssec-keygen/dnssec-keygen @@ -0,0 +1,76 @@ +#!/bin/sh + +cat <<\EOF >&2 +Usage: + dnssec-keygen [options] name + +Version: 9.11.3-1ubuntu1.5-Ubuntu + name: owner of the key +Options: + -K <directory>: write keys into directory + -a <algorithm>: + RSA | RSAMD5 | DSA | RSASHA1 | NSEC3RSASHA1 | NSEC3DSA | + RSASHA256 | RSASHA512 | ECCGOST | + ECDSAP256SHA256 | ECDSAP384SHA384 | + ED25519 | ED448 | DH | + HMAC-MD5 | HMAC-SHA1 | HMAC-SHA224 | HMAC-SHA256 | + HMAC-SHA384 | HMAC-SHA512 + (default: RSASHA1, or NSEC3RSASHA1 if using -3) + -3: use NSEC3-capable algorithm + -b <key size in bits>: + RSAMD5: [512..4096] + RSASHA1: [512..4096] + NSEC3RSASHA1: [512..4096] + RSASHA256: [512..4096] + RSASHA512: [1024..4096] + DH: [128..4096] + DSA: [512..1024] and divisible by 64 + NSEC3DSA: [512..1024] and divisible by 64 + ECCGOST: ignored + ECDSAP256SHA256: ignored + ECDSAP384SHA384: ignored + ED25519: ignored + ED448: ignored + HMAC-MD5: [1..512] + HMAC-SHA1: [1..160] + HMAC-SHA224: [1..224] + HMAC-SHA256: [1..256] + HMAC-SHA384: [1..384] + HMAC-SHA512: [1..512] + (if using the default algorithm, key size + defaults to 2048 for KSK, or 1024 for all others) + -n <nametype>: ZONE | HOST | ENTITY | USER | OTHER + (DNSKEY generation defaults to ZONE) + -c <class>: (default: IN) + -d <digest bits> (0 => max, default) + -E <engine>: + name of an OpenSSL engine to use + -f <keyflag>: KSK | REVOKE + -g <generator>: use specified generator (DH only) + -L <ttl>: default key TTL + -p <protocol>: (default: 3 [dnssec]) + -r <randomdev>: a file containing random data + -s <strength>: strength value this key signs DNS records with (default: 0) + -T <rrtype>: DNSKEY | KEY (default: DNSKEY; use KEY for SIG(0)) + -t <type>: AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF (default: AUTHCONF) + -h: print usage and exit + -m <memory debugging mode>: + usage | trace | record | size | mctx + -v <level>: set verbosity level (0 - 10) + -V: print version information +Timing options: + -P date/[+-]offset/none: set key publication date (default: now) + -P sync date/[+-]offset/none: set CDS and CDNSKEY publication date + -A date/[+-]offset/none: set key activation date (default: now) + -R date/[+-]offset/none: set key revocation date + -I date/[+-]offset/none: set key inactivation date + -D date/[+-]offset/none: set key deletion date + -D sync date/[+-]offset/none: set CDS and CDNSKEY deletion date + -G: generate key only; do not set -P or -A + -C: generate a backward-compatible key, omitting all dates + -S <key>: generate a successor to an existing key + -i <interval>: prepublication interval for successor key (default: 30 days) +Output: + K<name>+<alg>+<id>.key, K<name>+<alg>+<id>.private +EOF +exit 255 diff --git a/test/fixtures/dpkg/bash-completion-test-nonsubject.txt b/test/fixtures/dpkg/bash-completion-test-nonsubject.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/dpkg/bash-completion-test-nonsubject.txt diff --git a/test/fixtures/dpkg/bash-completion-test-subject.deb b/test/fixtures/dpkg/bash-completion-test-subject.deb new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/dpkg/bash-completion-test-subject.deb diff --git a/test/fixtures/evince/.BMP b/test/fixtures/evince/.BMP new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.BMP diff --git a/test/fixtures/evince/.CBR b/test/fixtures/evince/.CBR new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.CBR diff --git a/test/fixtures/evince/.CBZ b/test/fixtures/evince/.CBZ new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.CBZ diff --git a/test/fixtures/evince/.DJV b/test/fixtures/evince/.DJV new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.DJV diff --git a/test/fixtures/evince/.DJVU b/test/fixtures/evince/.DJVU new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.DJVU diff --git a/test/fixtures/evince/.DVI b/test/fixtures/evince/.DVI new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.DVI diff --git a/test/fixtures/evince/.DVI.BZ2 b/test/fixtures/evince/.DVI.BZ2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.DVI.BZ2 diff --git a/test/fixtures/evince/.DVI.GZ b/test/fixtures/evince/.DVI.GZ new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.DVI.GZ diff --git a/test/fixtures/evince/.DVI.bz2 b/test/fixtures/evince/.DVI.bz2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.DVI.bz2 diff --git a/test/fixtures/evince/.DVI.gz b/test/fixtures/evince/.DVI.gz new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.DVI.gz diff --git a/test/fixtures/evince/.EPS b/test/fixtures/evince/.EPS new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.EPS diff --git a/test/fixtures/evince/.EPS.BZ2 b/test/fixtures/evince/.EPS.BZ2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.EPS.BZ2 diff --git a/test/fixtures/evince/.EPS.GZ b/test/fixtures/evince/.EPS.GZ new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.EPS.GZ diff --git a/test/fixtures/evince/.EPS.bz2 b/test/fixtures/evince/.EPS.bz2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.EPS.bz2 diff --git a/test/fixtures/evince/.EPS.gz b/test/fixtures/evince/.EPS.gz new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.EPS.gz diff --git a/test/fixtures/evince/.GIF b/test/fixtures/evince/.GIF new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.GIF diff --git a/test/fixtures/evince/.ICO b/test/fixtures/evince/.ICO new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.ICO diff --git a/test/fixtures/evince/.JPEG b/test/fixtures/evince/.JPEG new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.JPEG diff --git a/test/fixtures/evince/.JPG b/test/fixtures/evince/.JPG new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.JPG diff --git a/test/fixtures/evince/.MIFF b/test/fixtures/evince/.MIFF new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.MIFF diff --git a/test/fixtures/evince/.PBM b/test/fixtures/evince/.PBM new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PBM diff --git a/test/fixtures/evince/.PCX b/test/fixtures/evince/.PCX new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PCX diff --git a/test/fixtures/evince/.PDF b/test/fixtures/evince/.PDF new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PDF diff --git a/test/fixtures/evince/.PDF.BZ2 b/test/fixtures/evince/.PDF.BZ2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PDF.BZ2 diff --git a/test/fixtures/evince/.PDF.GZ b/test/fixtures/evince/.PDF.GZ new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PDF.GZ diff --git a/test/fixtures/evince/.PDF.bz2 b/test/fixtures/evince/.PDF.bz2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PDF.bz2 diff --git a/test/fixtures/evince/.PDF.gz b/test/fixtures/evince/.PDF.gz new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PDF.gz diff --git a/test/fixtures/evince/.PGM b/test/fixtures/evince/.PGM new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PGM diff --git a/test/fixtures/evince/.PNG b/test/fixtures/evince/.PNG new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PNG diff --git a/test/fixtures/evince/.PNM b/test/fixtures/evince/.PNM new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PNM diff --git a/test/fixtures/evince/.PPM b/test/fixtures/evince/.PPM new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PPM diff --git a/test/fixtures/evince/.PS b/test/fixtures/evince/.PS new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PS diff --git a/test/fixtures/evince/.PS.BZ2 b/test/fixtures/evince/.PS.BZ2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PS.BZ2 diff --git a/test/fixtures/evince/.PS.GZ b/test/fixtures/evince/.PS.GZ new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PS.GZ diff --git a/test/fixtures/evince/.PS.bz2 b/test/fixtures/evince/.PS.bz2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PS.bz2 diff --git a/test/fixtures/evince/.PS.gz b/test/fixtures/evince/.PS.gz new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.PS.gz diff --git a/test/fixtures/evince/.TGA b/test/fixtures/evince/.TGA new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.TGA diff --git a/test/fixtures/evince/.TIF b/test/fixtures/evince/.TIF new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.TIF diff --git a/test/fixtures/evince/.TIFF b/test/fixtures/evince/.TIFF new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.TIFF diff --git a/test/fixtures/evince/.XPM b/test/fixtures/evince/.XPM new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.XPM diff --git a/test/fixtures/evince/.XWD b/test/fixtures/evince/.XWD new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.XWD diff --git a/test/fixtures/evince/.bmp b/test/fixtures/evince/.bmp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.bmp diff --git a/test/fixtures/evince/.cbr b/test/fixtures/evince/.cbr new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.cbr diff --git a/test/fixtures/evince/.cbz b/test/fixtures/evince/.cbz new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.cbz diff --git a/test/fixtures/evince/.djv b/test/fixtures/evince/.djv new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.djv diff --git a/test/fixtures/evince/.djvu b/test/fixtures/evince/.djvu new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.djvu diff --git a/test/fixtures/evince/.dvi b/test/fixtures/evince/.dvi new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.dvi diff --git a/test/fixtures/evince/.dvi.BZ2 b/test/fixtures/evince/.dvi.BZ2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.dvi.BZ2 diff --git a/test/fixtures/evince/.dvi.GZ b/test/fixtures/evince/.dvi.GZ new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.dvi.GZ diff --git a/test/fixtures/evince/.dvi.bz2 b/test/fixtures/evince/.dvi.bz2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.dvi.bz2 diff --git a/test/fixtures/evince/.dvi.gz b/test/fixtures/evince/.dvi.gz new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.dvi.gz diff --git a/test/fixtures/evince/.eps b/test/fixtures/evince/.eps new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.eps diff --git a/test/fixtures/evince/.eps.BZ2 b/test/fixtures/evince/.eps.BZ2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.eps.BZ2 diff --git a/test/fixtures/evince/.eps.GZ b/test/fixtures/evince/.eps.GZ new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.eps.GZ diff --git a/test/fixtures/evince/.eps.bz2 b/test/fixtures/evince/.eps.bz2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.eps.bz2 diff --git a/test/fixtures/evince/.eps.gz b/test/fixtures/evince/.eps.gz new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.eps.gz diff --git a/test/fixtures/evince/.gif b/test/fixtures/evince/.gif new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.gif diff --git a/test/fixtures/evince/.ico b/test/fixtures/evince/.ico new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.ico diff --git a/test/fixtures/evince/.jpeg b/test/fixtures/evince/.jpeg new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.jpeg diff --git a/test/fixtures/evince/.jpg b/test/fixtures/evince/.jpg new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.jpg diff --git a/test/fixtures/evince/.miff b/test/fixtures/evince/.miff new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.miff diff --git a/test/fixtures/evince/.pbm b/test/fixtures/evince/.pbm new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.pbm diff --git a/test/fixtures/evince/.pcx b/test/fixtures/evince/.pcx new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.pcx diff --git a/test/fixtures/evince/.pdf b/test/fixtures/evince/.pdf new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.pdf diff --git a/test/fixtures/evince/.pdf.BZ2 b/test/fixtures/evince/.pdf.BZ2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.pdf.BZ2 diff --git a/test/fixtures/evince/.pdf.GZ b/test/fixtures/evince/.pdf.GZ new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.pdf.GZ diff --git a/test/fixtures/evince/.pdf.bz2 b/test/fixtures/evince/.pdf.bz2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.pdf.bz2 diff --git a/test/fixtures/evince/.pdf.gz b/test/fixtures/evince/.pdf.gz new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.pdf.gz diff --git a/test/fixtures/evince/.pgm b/test/fixtures/evince/.pgm new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.pgm diff --git a/test/fixtures/evince/.png b/test/fixtures/evince/.png new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.png diff --git a/test/fixtures/evince/.pnm b/test/fixtures/evince/.pnm new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.pnm diff --git a/test/fixtures/evince/.ppm b/test/fixtures/evince/.ppm new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.ppm diff --git a/test/fixtures/evince/.ps b/test/fixtures/evince/.ps new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.ps diff --git a/test/fixtures/evince/.ps.BZ2 b/test/fixtures/evince/.ps.BZ2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.ps.BZ2 diff --git a/test/fixtures/evince/.ps.GZ b/test/fixtures/evince/.ps.GZ new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.ps.GZ diff --git a/test/fixtures/evince/.ps.bz2 b/test/fixtures/evince/.ps.bz2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.ps.bz2 diff --git a/test/fixtures/evince/.ps.gz b/test/fixtures/evince/.ps.gz new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.ps.gz diff --git a/test/fixtures/evince/.tga b/test/fixtures/evince/.tga new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.tga diff --git a/test/fixtures/evince/.tif b/test/fixtures/evince/.tif new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.tif diff --git a/test/fixtures/evince/.tiff b/test/fixtures/evince/.tiff new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.tiff diff --git a/test/fixtures/evince/.txt b/test/fixtures/evince/.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.txt diff --git a/test/fixtures/evince/.xpm b/test/fixtures/evince/.xpm new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.xpm diff --git a/test/fixtures/evince/.xwd b/test/fixtures/evince/.xwd new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/.xwd diff --git a/test/fixtures/evince/foo/.gitignore b/test/fixtures/evince/foo/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/evince/foo/.gitignore diff --git a/test/fixtures/gdb/core b/test/fixtures/gdb/core new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/gdb/core diff --git a/test/fixtures/gdb/core-NOT b/test/fixtures/gdb/core-NOT new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/gdb/core-NOT diff --git a/test/fixtures/gdb/core.12345 b/test/fixtures/gdb/core.12345 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/gdb/core.12345 diff --git a/test/fixtures/gdb/core.weston.1000.deadbeef.5308.1555362132000000 b/test/fixtures/gdb/core.weston.1000.deadbeef.5308.1555362132000000 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/gdb/core.weston.1000.deadbeef.5308.1555362132000000 diff --git a/test/fixtures/gdb/corenot b/test/fixtures/gdb/corenot new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/gdb/corenot diff --git a/test/fixtures/htpasswd/htpasswd b/test/fixtures/htpasswd/htpasswd new file mode 100644 index 0000000..5279c7c --- /dev/null +++ b/test/fixtures/htpasswd/htpasswd @@ -0,0 +1,2 @@ +foo:bar +quux:baz diff --git a/test/fixtures/info/bash-completion.info b/test/fixtures/info/bash-completion.info new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/info/bash-completion.info diff --git a/test/fixtures/isql/odbc.ini b/test/fixtures/isql/odbc.ini new file mode 100644 index 0000000..96319f3 --- /dev/null +++ b/test/fixtures/isql/odbc.ini @@ -0,0 +1,3 @@ +[foo] + +[bar] diff --git a/test/fixtures/java/a/b$c.class b/test/fixtures/java/a/b$c.class new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/java/a/b$c.class diff --git a/test/fixtures/java/a/b.class b/test/fixtures/java/a/b.class new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/java/a/b.class diff --git a/test/fixtures/java/a/c/README.txt b/test/fixtures/java/a/c/README.txt new file mode 100644 index 0000000..e5e6d0b --- /dev/null +++ b/test/fixtures/java/a/c/README.txt @@ -0,0 +1,2 @@ +When CLASSPATH is set to the fixtures/java/a dir, we do *not* expect +*.class in subdirs to be included in completions, see Debian bug #496828. diff --git a/test/fixtures/java/a/c/d.class b/test/fixtures/java/a/c/d.class new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/java/a/c/d.class diff --git a/test/fixtures/java/a/d.txt b/test/fixtures/java/a/d.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/java/a/d.txt diff --git a/test/fixtures/java/bashcomp.jar b/test/fixtures/java/bashcomp.jar Binary files differnew file mode 100644 index 0000000..d9c2779 --- /dev/null +++ b/test/fixtures/java/bashcomp.jar diff --git a/test/fixtures/java/bashcomp.war b/test/fixtures/java/bashcomp.war new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/java/bashcomp.war diff --git a/test/fixtures/java/no-complete.txt b/test/fixtures/java/no-complete.txt new file mode 100644 index 0000000..8ca1ef6 --- /dev/null +++ b/test/fixtures/java/no-complete.txt @@ -0,0 +1 @@ +This file should not be included in classpath etc completions. diff --git a/test/fixtures/kdvi/.DVI b/test/fixtures/kdvi/.DVI new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kdvi/.DVI diff --git a/test/fixtures/kdvi/.DVI.Z b/test/fixtures/kdvi/.DVI.Z new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kdvi/.DVI.Z diff --git a/test/fixtures/kdvi/.DVI.bz2 b/test/fixtures/kdvi/.DVI.bz2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kdvi/.DVI.bz2 diff --git a/test/fixtures/kdvi/.DVI.gz b/test/fixtures/kdvi/.DVI.gz new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kdvi/.DVI.gz diff --git a/test/fixtures/kdvi/.dvi b/test/fixtures/kdvi/.dvi new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kdvi/.dvi diff --git a/test/fixtures/kdvi/.dvi.Z b/test/fixtures/kdvi/.dvi.Z new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kdvi/.dvi.Z diff --git a/test/fixtures/kdvi/.dvi.bz2 b/test/fixtures/kdvi/.dvi.bz2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kdvi/.dvi.bz2 diff --git a/test/fixtures/kdvi/.dvi.gz b/test/fixtures/kdvi/.dvi.gz new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kdvi/.dvi.gz diff --git a/test/fixtures/kdvi/.txt b/test/fixtures/kdvi/.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kdvi/.txt diff --git a/test/fixtures/kdvi/foo/.gitignore b/test/fixtures/kdvi/foo/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kdvi/foo/.gitignore diff --git a/test/fixtures/kpdf/.EPS b/test/fixtures/kpdf/.EPS new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kpdf/.EPS diff --git a/test/fixtures/kpdf/.PDF b/test/fixtures/kpdf/.PDF new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kpdf/.PDF diff --git a/test/fixtures/kpdf/.PS b/test/fixtures/kpdf/.PS new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kpdf/.PS diff --git a/test/fixtures/kpdf/.eps b/test/fixtures/kpdf/.eps new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kpdf/.eps diff --git a/test/fixtures/kpdf/.pdf b/test/fixtures/kpdf/.pdf new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kpdf/.pdf diff --git a/test/fixtures/kpdf/.ps b/test/fixtures/kpdf/.ps new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kpdf/.ps diff --git a/test/fixtures/kpdf/.txt b/test/fixtures/kpdf/.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kpdf/.txt diff --git a/test/fixtures/kpdf/foo/.gitignore b/test/fixtures/kpdf/foo/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/kpdf/foo/.gitignore diff --git a/test/fixtures/lftp/.lftp/bookmarks b/test/fixtures/lftp/.lftp/bookmarks new file mode 100644 index 0000000..074f812 --- /dev/null +++ b/test/fixtures/lftp/.lftp/bookmarks @@ -0,0 +1,3 @@ +lftptest ftp://ftp.funet.fi/ +spacetest ftp://ftp.sunet.se/ +badbookmark diff --git a/test/fixtures/lilo/lilo.conf b/test/fixtures/lilo/lilo.conf new file mode 100644 index 0000000..c890175 --- /dev/null +++ b/test/fixtures/lilo/lilo.conf @@ -0,0 +1,34 @@ +# global options: +boot=/dev/hda +prompt +timeout=150 +lba32 +compact +vga=normal +root=/dev/hda1 +read-only +menu-title=" John's Computer " +# +### bootable kernel images ### +image=/boot/vmlinuz-2.6.29-1-i386 + label=try + initrd=/boot/initrd.img-2.6.29-1-i386 +#image=/boot/vmlinuz-2.4.33-1-i386 +# label=2.4.33 +image=/tamu/vmlinuz + label=tamu + initrd=/tamu/initrd.img + root=/dev/hdb2 + vga=ask +# +### other operating systems ### +other=/dev/hda3 + label=PCDOS + boot-as=0x80 # must be C: +other=/dev/hdb1 + label=WinXP + boot-as=0x80 # must be C: +other=/dev/hdb5 + label=oldDOS + loader=chain + table=/dev/hdb5 diff --git a/test/fixtures/make/.gitignore b/test/fixtures/make/.gitignore new file mode 100644 index 0000000..3d1325c --- /dev/null +++ b/test/fixtures/make/.gitignore @@ -0,0 +1 @@ +extra_makefile diff --git a/test/fixtures/make/Makefile b/test/fixtures/make/Makefile new file mode 100644 index 0000000..b04a6eb --- /dev/null +++ b/test/fixtures/make/Makefile @@ -0,0 +1,46 @@ +$(info confuse: make) + +CFLAGS=-MMD -MP +NAME := sample + +.PHONY: all +all: $(NAME) + +$(NAME): sample.o + +.INTERMEDIATE: sample.o +sample.o: sample.c + +.PHONY: install +install: all + mkdir -p /usr/bin + install -m 755 $(NAME) /usr/bin + +.PHONY: clean +clean: + -rm -f $(NAME) + +.test_passes: + ./sample >/dev/null + touch ^@ + +.cache/.1: + touch $@ + +.cache/.2: + touch $@ + +.cache/1: + touch $@ + +.cache/2: + touch $@ + +ifndef __BASH_MAKE_COMPLETION__ +-include sample.d +endif + +VARIABLE_LOOKS_A_BIT_LIKE_A_TARGET := fooled-you +extra_makefile: + touch $@ +include extra_makefile diff --git a/test/fixtures/make/sample.c b/test/fixtures/make/sample.c new file mode 100644 index 0000000..4212596 --- /dev/null +++ b/test/fixtures/make/sample.c @@ -0,0 +1,8 @@ +#include <stdio.h> +#include "sample.h" + +int main(void) +{ + puts("Hello, world!"); + return 0; +} diff --git a/test/fixtures/make/sample.d b/test/fixtures/make/sample.d new file mode 100644 index 0000000..27979ff --- /dev/null +++ b/test/fixtures/make/sample.d @@ -0,0 +1,3 @@ +sample.o: sample.c sample.h + +sample.h: diff --git a/test/fixtures/make/sample.h b/test/fixtures/make/sample.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/make/sample.h diff --git a/test/fixtures/man/man/quux.8 b/test/fixtures/man/man/quux.8 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/man/man/quux.8 diff --git a/test/fixtures/man/man1/bash-completion-testcase.1.bz2 b/test/fixtures/man/man1/bash-completion-testcase.1.bz2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/man/man1/bash-completion-testcase.1.bz2 diff --git a/test/fixtures/man/man1/foo.1 b/test/fixtures/man/man1/foo.1 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/man/man1/foo.1 diff --git a/test/fixtures/mount/bin/showmount b/test/fixtures/mount/bin/showmount new file mode 100755 index 0000000..2751c4b --- /dev/null +++ b/test/fixtures/mount/bin/showmount @@ -0,0 +1,12 @@ +#!/bin/sh + +if [ "$1" = -e ] && [ "$2" = mocksrv ]; then + echo "Header line" + echo "/test/path" + echo "/test/path2" + echo "/second/path" + exit 0 +fi + +echo "Usage: 'showmount -e mocksrv'; nothing else works." +exit 1 diff --git a/test/fixtures/mount/test-fstab b/test/fixtures/mount/test-fstab new file mode 100644 index 0000000..b243417 --- /dev/null +++ b/test/fixtures/mount/test-fstab @@ -0,0 +1,24 @@ +proc /proc proc defaults 0 0 +none /debug debugfs defaults,noauto 0 0 + +# Simple obvious test. +/mnt/nice-test-path /dev/null auto ro,noauto 0 0 + +# Test octal escapes +# Contains ' ' and '-' +/mnt/nice\040test\055path /dev/null auto ro,noauto 0 0 +# Contains '$' and '-' +/mnt/nice\044test\055path /dev/null auto ro,noauto 0 0 +# Contains ' ' and '\\' +/mnt/nice\040test\134path /dev/null auto ro,noauto 0 0 +# Contains '\n' and '\ ' +/mnt/nice\012test\040path /dev/null auto ro,noauto 0 0 + +# Test apostrophe +/mnt/nice'test-path /dev/null auto ro,noauto 0 0 +/mnt/other'test\040path /dev/null auto ro,noauto 0 0 + +# Test some labels +LABEL=Ubuntu\040Karmic /mnt/ubuntu auto no,noauto 0 0 +LABEL=Fedora /mnt/fedora auto ro,noauto 0 0 +LABEL=Debian-it's\040awesome /mnt/debian auto ro,noauto 0 0 diff --git a/test/fixtures/mplayer/.mplayer/config b/test/fixtures/mplayer/.mplayer/config new file mode 100644 index 0000000..8af74ee --- /dev/null +++ b/test/fixtures/mplayer/.mplayer/config @@ -0,0 +1,2 @@ +# https://github.com/scop/bash-completion/issues/182 +msglevel=all=3 diff --git a/test/fixtures/mplayer/.mplayer/mencoder.conf b/test/fixtures/mplayer/.mplayer/mencoder.conf new file mode 100644 index 0000000..9f5aa0f --- /dev/null +++ b/test/fixtures/mplayer/.mplayer/mencoder.conf @@ -0,0 +1 @@ +# mencoder test config file diff --git a/test/fixtures/mutt/bar/.gitignore b/test/fixtures/mutt/bar/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/mutt/bar/.gitignore diff --git a/test/fixtures/mutt/bar/muttrc_b b/test/fixtures/mutt/bar/muttrc_b new file mode 100644 index 0000000..f4a0493 --- /dev/null +++ b/test/fixtures/mutt/bar/muttrc_b @@ -0,0 +1 @@ +source ~/foo/muttrc_f diff --git a/test/fixtures/mutt/foo/.gitignore b/test/fixtures/mutt/foo/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/mutt/foo/.gitignore diff --git a/test/fixtures/mutt/foo/muttrc_f b/test/fixtures/mutt/foo/muttrc_f new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/mutt/foo/muttrc_f diff --git a/test/fixtures/mutt/muttrc b/test/fixtures/mutt/muttrc new file mode 100644 index 0000000..d26c8bc --- /dev/null +++ b/test/fixtures/mutt/muttrc @@ -0,0 +1,4 @@ +set folder=. +alias a1 a1@example.com +alias a2 a2@example.com +source ~/bar/muttrc_b diff --git a/test/fixtures/nmap/nmap-h.txt b/test/fixtures/nmap/nmap-h.txt new file mode 100644 index 0000000..0301d37 --- /dev/null +++ b/test/fixtures/nmap/nmap-h.txt @@ -0,0 +1,114 @@ +Nmap 7.60 ( https://nmap.org ) +Usage: nmap [Scan Type(s)] [Options] {target specification} +TARGET SPECIFICATION: + Can pass hostnames, IP addresses, networks, etc. + Ex: scanme.nmap.org, microsoft.com/24, 192.168.0.1; 10.0.0-255.1-254 + -iL <inputfilename>: Input from list of hosts/networks + -iR <num hosts>: Choose random targets + --exclude <host1[,host2][,host3],...>: Exclude hosts/networks + --excludefile <exclude_file>: Exclude list from file +HOST DISCOVERY: + -sL: List Scan - simply list targets to scan + -sn: Ping Scan - disable port scan + -Pn: Treat all hosts as online -- skip host discovery + -PS/PA/PU/PY[portlist]: TCP SYN/ACK, UDP or SCTP discovery to given ports + -PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes + -PO[protocol list]: IP Protocol Ping + -n/-R: Never do DNS resolution/Always resolve [default: sometimes] + --dns-servers <serv1[,serv2],...>: Specify custom DNS servers + --system-dns: Use OS's DNS resolver + --traceroute: Trace hop path to each host +SCAN TECHNIQUES: + -sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans + -sU: UDP Scan + -sN/sF/sX: TCP Null, FIN, and Xmas scans + --scanflags <flags>: Customize TCP scan flags + -sI <zombie host[:probeport]>: Idle scan + -sY/sZ: SCTP INIT/COOKIE-ECHO scans + -sO: IP protocol scan + -b <FTP relay host>: FTP bounce scan +PORT SPECIFICATION AND SCAN ORDER: + -p <port ranges>: Only scan specified ports + Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9 + --exclude-ports <port ranges>: Exclude the specified ports from scanning + -F: Fast mode - Scan fewer ports than the default scan + -r: Scan ports consecutively - don't randomize + --top-ports <number>: Scan <number> most common ports + --port-ratio <ratio>: Scan ports more common than <ratio> +SERVICE/VERSION DETECTION: + -sV: Probe open ports to determine service/version info + --version-intensity <level>: Set from 0 (light) to 9 (try all probes) + --version-light: Limit to most likely probes (intensity 2) + --version-all: Try every single probe (intensity 9) + --version-trace: Show detailed version scan activity (for debugging) +SCRIPT SCAN: + -sC: equivalent to --script=default + --script=<Lua scripts>: <Lua scripts> is a comma separated list of + directories, script-files or script-categories + --script-args=<n1=v1,[n2=v2,...]>: provide arguments to scripts + --script-args-file=filename: provide NSE script args in a file + --script-trace: Show all data sent and received + --script-updatedb: Update the script database. + --script-help=<Lua scripts>: Show help about scripts. + <Lua scripts> is a comma-separated list of script-files or + script-categories. +OS DETECTION: + -O: Enable OS detection + --osscan-limit: Limit OS detection to promising targets + --osscan-guess: Guess OS more aggressively +TIMING AND PERFORMANCE: + Options which take <time> are in seconds, or append 'ms' (milliseconds), + 's' (seconds), 'm' (minutes), or 'h' (hours) to the value (e.g. 30m). + -T<0-5>: Set timing template (higher is faster) + --min-hostgroup/max-hostgroup <size>: Parallel host scan group sizes + --min-parallelism/max-parallelism <numprobes>: Probe parallelization + --min-rtt-timeout/max-rtt-timeout/initial-rtt-timeout <time>: Specifies + probe round trip time. + --max-retries <tries>: Caps number of port scan probe retransmissions. + --host-timeout <time>: Give up on target after this long + --scan-delay/--max-scan-delay <time>: Adjust delay between probes + --min-rate <number>: Send packets no slower than <number> per second + --max-rate <number>: Send packets no faster than <number> per second +FIREWALL/IDS EVASION AND SPOOFING: + -f; --mtu <val>: fragment packets (optionally w/given MTU) + -D <decoy1,decoy2[,ME],...>: Cloak a scan with decoys + -S <IP_Address>: Spoof source address + -e <iface>: Use specified interface + -g/--source-port <portnum>: Use given port number + --proxies <url1,[url2],...>: Relay connections through HTTP/SOCKS4 proxies + --data <hex string>: Append a custom payload to sent packets + --data-string <string>: Append a custom ASCII string to sent packets + --data-length <num>: Append random data to sent packets + --ip-options <options>: Send packets with specified ip options + --ttl <val>: Set IP time-to-live field + --spoof-mac <mac address/prefix/vendor name>: Spoof your MAC address + --badsum: Send packets with a bogus TCP/UDP/SCTP checksum +OUTPUT: + -oN/-oX/-oS/-oG <file>: Output scan in normal, XML, s|<rIpt kIddi3, + and Grepable format, respectively, to the given filename. + -oA <basename>: Output in the three major formats at once + -v: Increase verbosity level (use -vv or more for greater effect) + -d: Increase debugging level (use -dd or more for greater effect) + --reason: Display the reason a port is in a particular state + --open: Only show open (or possibly open) ports + --packet-trace: Show all packets sent and received + --iflist: Print host interfaces and routes (for debugging) + --append-output: Append to rather than clobber specified output files + --resume <filename>: Resume an aborted scan + --stylesheet <path/URL>: XSL stylesheet to transform XML output to HTML + --webxml: Reference stylesheet from Nmap.Org for more portable XML + --no-stylesheet: Prevent associating of XSL stylesheet w/XML output +MISC: + -6: Enable IPv6 scanning + -A: Enable OS detection, version detection, script scanning, and traceroute + --datadir <dirname>: Specify custom Nmap data file location + --send-eth/--send-ip: Send using raw ethernet frames or IP packets + --privileged: Assume that the user is fully privileged + --unprivileged: Assume the user lacks raw socket privileges + -V: Print version number + -h: Print this help summary page. +EXAMPLES: + nmap -v -A scanme.nmap.org + nmap -v -sn 192.168.0.0/16 10.0.0.0/8 + nmap -v -iR 10000 -Pn -p 80 +SEE THE MAN PAGE (https://nmap.org/book/man.html) FOR MORE OPTIONS AND EXAMPLES diff --git a/test/fixtures/perl/Devel/BashCompletion.pm b/test/fixtures/perl/Devel/BashCompletion.pm new file mode 100644 index 0000000..f8e829d --- /dev/null +++ b/test/fixtures/perl/Devel/BashCompletion.pm @@ -0,0 +1,3 @@ +use strict; +use warnings; +1; diff --git a/test/fixtures/perldoc/BashCompletionDoc.pod b/test/fixtures/perldoc/BashCompletionDoc.pod new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/perldoc/BashCompletionDoc.pod diff --git a/test/fixtures/perldoc/BashCompletionModule.pm b/test/fixtures/perldoc/BashCompletionModule.pm new file mode 100644 index 0000000..b9208f3 --- /dev/null +++ b/test/fixtures/perldoc/BashCompletionModule.pm @@ -0,0 +1,4 @@ +package BashCompletionModule; +use strict; +use warnings; +1; diff --git a/test/fixtures/pkgtools/db/a-1.0,1/.gitignore b/test/fixtures/pkgtools/db/a-1.0,1/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/pkgtools/db/a-1.0,1/.gitignore diff --git a/test/fixtures/pkgtools/db/b-c-d-2.0_2/.gitignore b/test/fixtures/pkgtools/db/b-c-d-2.0_2/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/pkgtools/db/b-c-d-2.0_2/.gitignore diff --git a/test/fixtures/pkgtools/ports/.gitignore b/test/fixtures/pkgtools/ports/.gitignore new file mode 100644 index 0000000..71d2c0c --- /dev/null +++ b/test/fixtures/pkgtools/ports/.gitignore @@ -0,0 +1,2 @@ +INDEX +INDEX-5 diff --git a/test/fixtures/pkgtools/ports/INDEX.dist b/test/fixtures/pkgtools/ports/INDEX.dist new file mode 100644 index 0000000..76957d4 --- /dev/null +++ b/test/fixtures/pkgtools/ports/INDEX.dist @@ -0,0 +1,3 @@ +bash-3.1.17|PORTSDIR/shells/bash|/usr/local|The GNU Project's Bourne Again SHell|PORTSDIR/shells/bash/pkg-descr|obrien@FreeBSD.org|shells|expat-2.0.0_1 gettext-0.14.5_2 ldconfig_compat-1.0_8 libiconv-1.9.2_2 rc_subr-1.31_1|expat-2.0.0_1 gettext-0.14.5_2 ldconfig_compat-1.0_8 libiconv-1.9.2_2 rc_subr-1.31_1|http://cnswww.cns.cwru.edu/~chet/bash/bashtop.html||| +bash-completion-20060301_2|PORTSDIR/shells/bash-completion|/usr/local|Programmable completion library for Bash 2.04 and up|PORTSDIR/shells/bash-completion/pkg-descr|kirk@strauser.com|shells||bash-3.1.17 expat-2.0.0_1 gettext-0.14.5_2 ldconfig_compat-1.0_8 libiconv-1.9.2_2 rc_subr-1.31_1|http://www.caliban.org/bash/index.shtml||| +bash-2.05b.007_6|PORTSDIR/shells/bash2|/usr/local|The GNU Bourne Again Shell|PORTSDIR/shells/bash2/pkg-descr|ports@FreeBSD.org|shells|||http://www.gnu.org/software/bash/||| diff --git a/test/fixtures/pytest/test_async.py b/test/fixtures/pytest/test_async.py new file mode 100644 index 0000000..48f91e0 --- /dev/null +++ b/test/fixtures/pytest/test_async.py @@ -0,0 +1,17 @@ +"""Async function pytest completion fixture.""" + + +async def test_positive(): + pass + + +async def non_test_negative(): + pass + + +class Testing: + async def test_positive(self): + pass + + async def non_test_negative(self): + pass diff --git a/test/fixtures/ri/BashCompletion/cdesc-BashCompletion.ri b/test/fixtures/ri/BashCompletion/cdesc-BashCompletion.ri Binary files differnew file mode 100644 index 0000000..7263da8 --- /dev/null +++ b/test/fixtures/ri/BashCompletion/cdesc-BashCompletion.ri diff --git a/test/fixtures/ri/BashCompletion/cdesc-BashCompletion.yaml b/test/fixtures/ri/BashCompletion/cdesc-BashCompletion.yaml new file mode 100644 index 0000000..bc064a8 --- /dev/null +++ b/test/fixtures/ri/BashCompletion/cdesc-BashCompletion.yaml @@ -0,0 +1,15 @@ +--- !ruby/object:RI::ClassDescription +attributes: [] + +class_methods: [] + +comment: +constants: [] + +full_name: BashCompletion +includes: [] + +instance_methods: [] + +name: BashCompletion +superclass: diff --git a/test/fixtures/ri/bashcompletion.rb b/test/fixtures/ri/bashcompletion.rb new file mode 100644 index 0000000..0e075d2 --- /dev/null +++ b/test/fixtures/ri/bashcompletion.rb @@ -0,0 +1,2 @@ +module BashCompletion +end diff --git a/test/fixtures/ri/cache.ri b/test/fixtures/ri/cache.ri Binary files differnew file mode 100644 index 0000000..4a8fc66 --- /dev/null +++ b/test/fixtures/ri/cache.ri diff --git a/test/fixtures/ri/created.rid b/test/fixtures/ri/created.rid new file mode 100644 index 0000000..1392d20 --- /dev/null +++ b/test/fixtures/ri/created.rid @@ -0,0 +1 @@ +Mon, 09 Oct 2017 21:45:15 +0000 diff --git a/test/fixtures/scp/config b/test/fixtures/scp/config new file mode 100644 index 0000000..9f94b9e --- /dev/null +++ b/test/fixtures/scp/config @@ -0,0 +1,8 @@ +UserKnownHostsFile known_hosts + + # Unindented +Host gee + # Indented, multiple hosts + HostName hus ike + +Host hut diff --git a/test/fixtures/scp/known_hosts b/test/fixtures/scp/known_hosts new file mode 100644 index 0000000..2dfa4b6 --- /dev/null +++ b/test/fixtures/scp/known_hosts @@ -0,0 +1,5 @@ +|1|abc +|1|def +doo +ike ssh-rsa qwerty1234/Qwerty+1234== +[blah]:1234 diff --git a/test/fixtures/scp/spaced conf b/test/fixtures/scp/spaced conf new file mode 100644 index 0000000..7ad64bc --- /dev/null +++ b/test/fixtures/scp/spaced conf @@ -0,0 +1,6 @@ + UserKnownHostsFile known_hosts + + # Unindented +Host gee jar + # Indented, multiple hosts + HostName hus diff --git a/test/fixtures/sftp/config b/test/fixtures/sftp/config new file mode 100644 index 0000000..9f94b9e --- /dev/null +++ b/test/fixtures/sftp/config @@ -0,0 +1,8 @@ +UserKnownHostsFile known_hosts + + # Unindented +Host gee + # Indented, multiple hosts + HostName hus ike + +Host hut diff --git a/test/fixtures/sftp/known_hosts b/test/fixtures/sftp/known_hosts new file mode 100644 index 0000000..6538eb4 --- /dev/null +++ b/test/fixtures/sftp/known_hosts @@ -0,0 +1,5 @@ +|1|abc +|1|def +doo +ike ssh-rsa qwerty1234/Qwerty+1234== +[10.10.10.10]:2222 diff --git a/test/fixtures/sftp/spaced conf b/test/fixtures/sftp/spaced conf new file mode 100644 index 0000000..7ad64bc --- /dev/null +++ b/test/fixtures/sftp/spaced conf @@ -0,0 +1,6 @@ + UserKnownHostsFile known_hosts + + # Unindented +Host gee jar + # Indented, multiple hosts + HostName hus diff --git a/test/fixtures/shared/.ssh/known_hosts b/test/fixtures/shared/.ssh/known_hosts new file mode 100644 index 0000000..03d444a --- /dev/null +++ b/test/fixtures/shared/.ssh/known_hosts @@ -0,0 +1 @@ +bash-completion-canary-host.local diff --git a/test/fixtures/shared/bin/arp b/test/fixtures/shared/bin/arp new file mode 100755 index 0000000..49f4296 --- /dev/null +++ b/test/fixtures/shared/bin/arp @@ -0,0 +1,16 @@ +#!/bin/sh + +# Dummy "arp -an" emulator + +# Linux +echo "? (0.0.0.0) at 00:00:00:00:00:00 [ether] on eth0" + +# FreeBSD +echo "? (0.0.0.0) at 11:11:11:11:11:11 on bge0 expires in 5 seconds [ethernet]" + +# Solaris +cat <<EOF +Device IP Address Mask Flags Phys Addr +------ -------------------- --------------- -------- --------------- +ce0 0.0.0.0 255.255.255.255 o 22:22:22:22:22:22 +EOF diff --git a/test/fixtures/shared/bin/ifconfig b/test/fixtures/shared/bin/ifconfig new file mode 100755 index 0000000..59c9140 --- /dev/null +++ b/test/fixtures/shared/bin/ifconfig @@ -0,0 +1,24 @@ +#!/bin/sh + +# Dummy "ifconfig -a" emulator + +cat <<EOF +eth0 Link encap:Ethernet HWaddr 33:33:33:33:33:33 + inet addr:192.168.80.11 Bcast:192.168.80.255 Mask:255.255.255.0 + inet6 addr: fe80::000:0000:0000:0000/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:855946 errors:42 dropped:0 overruns:0 frame:42 + TX packets:477196 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:1000 + RX bytes:1142133425 (1.0 GiB) TX bytes:47621718 (45.4 MiB) + Interrupt:23 Base address:0xc000 + +lo Link encap:Local Loopback + inet addr:127.0.0.1 Mask:255.0.0.0 + inet6 addr: ::1/128 Scope:Host + UP LOOPBACK RUNNING MTU:16436 Metric:1 + RX packets:129059 errors:0 dropped:0 overruns:0 frame:0 + TX packets:129059 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:0 + RX bytes:7456154 (7.1 MiB) TX bytes:7456154 (7.1 MiB) +EOF diff --git a/test/fixtures/shared/default/bar b/test/fixtures/shared/default/bar new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/shared/default/bar diff --git a/test/fixtures/shared/default/bar bar.d/foo b/test/fixtures/shared/default/bar bar.d/foo new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/shared/default/bar bar.d/foo diff --git a/test/fixtures/shared/default/foo b/test/fixtures/shared/default/foo new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/test/fixtures/shared/default/foo @@ -0,0 +1 @@ +foo diff --git a/test/fixtures/shared/default/foo.d/foo b/test/fixtures/shared/default/foo.d/foo new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/shared/default/foo.d/foo diff --git a/test/fixtures/shared/empty_dir/.nothing_here b/test/fixtures/shared/empty_dir/.nothing_here new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/shared/empty_dir/.nothing_here diff --git a/test/fixtures/shared/ld.so.conf.d/foo.txt b/test/fixtures/shared/ld.so.conf.d/foo.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/shared/ld.so.conf.d/foo.txt diff --git a/test/fixtures/shared/ld.so.conf.d/libfoo.conf b/test/fixtures/shared/ld.so.conf.d/libfoo.conf new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/shared/ld.so.conf.d/libfoo.conf diff --git a/test/fixtures/shared/ld.so.conf.d/libfoo.so b/test/fixtures/shared/ld.so.conf.d/libfoo.so new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/shared/ld.so.conf.d/libfoo.so diff --git a/test/fixtures/shared/ld.so.conf.d/libfoo.so.1 b/test/fixtures/shared/ld.so.conf.d/libfoo.so.1 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/shared/ld.so.conf.d/libfoo.so.1 diff --git a/test/fixtures/slackware/home/abc-4-i686-1.txz b/test/fixtures/slackware/home/abc-4-i686-1.txz new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/fixtures/slackware/home/abc-4-i686-1.txz @@ -0,0 +1 @@ + diff --git a/test/fixtures/slackware/home/opq-1.0-2.i386.rpm b/test/fixtures/slackware/home/opq-1.0-2.i386.rpm new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/fixtures/slackware/home/opq-1.0-2.i386.rpm @@ -0,0 +1 @@ + diff --git a/test/fixtures/slackware/home/tcl.d/tcl.tgz b/test/fixtures/slackware/home/tcl.d/tcl.tgz new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/fixtures/slackware/home/tcl.d/tcl.tgz @@ -0,0 +1 @@ + diff --git a/test/fixtures/slackware/usr/src/slapt-src/slackbuilds_data b/test/fixtures/slackware/usr/src/slapt-src/slackbuilds_data new file mode 100644 index 0000000..0f4ee44 --- /dev/null +++ b/test/fixtures/slackware/usr/src/slapt-src/slackbuilds_data @@ -0,0 +1,20 @@ +SLACKBUILD NAME: abc +SLACKBUILD SOURCEURL: http://www.slackware.org.uk/slackbuilds.org/13.37/ +SLACKBUILD LOCATION: libraries/abc/ +SLACKBUILD FILES: abc.SlackBuild slack-desc +SLACKBUILD VERSION: 4 +SLACKBUILD DOWNLOAD: http://www.ufl.edu/abc-4.tar.gz +SLACKBUILD MD5SUM: b3e9679ba20635ac4847f01c01d6e992 +SLACKBUILD REQUIRES: +SLACKBUILD SHORT DESCRIPTION: abc is a small utility + +SLACKBUILD NAME: qwe +SLACKBUILD SOURCEURL: http://www.slackware.org.uk/slackbuilds.org/13.37/ +SLACKBUILD LOCATION: network/qwe/ +SLACKBUILD FILES: qwe.SlackBuild +SLACKBUILD VERSION: 2.1 +SLACKBUILD DOWNLOAD: http://php.net/qwe-2.1.tgz +SLACKBUILD MD5SUM: 1f7a58f850e795b0958a3f99ae8c2cc4 +SLACKBUILD REQUIRES: +SLACKBUILD SHORT DESCRIPTION: qwe is a program + diff --git a/test/fixtures/slackware/var/log/packages/radeontool-1.6.1-i486-1 b/test/fixtures/slackware/var/log/packages/radeontool-1.6.1-i486-1 new file mode 100644 index 0000000..7f53326 --- /dev/null +++ b/test/fixtures/slackware/var/log/packages/radeontool-1.6.1-i486-1 @@ -0,0 +1,24 @@ +PACKAGE NAME: radeontool-1.6.1-i486-1 +COMPRESSED PACKAGE SIZE: 48K +UNCOMPRESSED PACKAGE SIZE: 150K +PACKAGE LOCATION: ./radeontool-1.6.1-i486-1.txz +PACKAGE DESCRIPTION: +radeontool: radeontool (small utility for ati radeon-based laptops) +radeontool: +radeontool: Radeontool is a small utility to control ATI Radeon-based +radeontool: laptops' backlight and external output functions +radeontool: +radeontool: Homepage: http://fdd.com/software/radeon/ +radeontool: +radeontool: +radeontool: +radeontool: +radeontool: +FILE LIST: +./ +usr/ +usr/bin/ +usr/bin/radeontool +usr/bin/avivotool +install/ +install/slack-desc diff --git a/test/fixtures/slackware/var/log/packages/rzip-2.1-i486-1 b/test/fixtures/slackware/var/log/packages/rzip-2.1-i486-1 new file mode 100644 index 0000000..0fa71f4 --- /dev/null +++ b/test/fixtures/slackware/var/log/packages/rzip-2.1-i486-1 @@ -0,0 +1,29 @@ +PACKAGE NAME: rzip-2.1-i486-1 +COMPRESSED PACKAGE SIZE: 20K +UNCOMPRESSED PACKAGE SIZE: 50K +PACKAGE LOCATION: ./rzip-2.1-i486-1.txz +PACKAGE DESCRIPTION: +rzip: rzip (a large-file compression program) +rzip: +rzip: rzip is a file compression program designed to do particularly well +rzip: on very large files containing long distance redundancy. +rzip: +rzip: rzip was written by Andrew Tridgell. +rzip: +rzip: +rzip: +rzip: +rzip: +FILE LIST: +./ +bin/ +bin/rzip +usr/ +usr/doc/ +usr/doc/rzip-2.1/ +usr/doc/rzip-2.1/COPYING +usr/man/ +usr/man/man1/ +usr/man/man1/rzip.1.gz +install/ +install/slack-desc diff --git a/test/fixtures/slackware/var/slapt-get/package_data b/test/fixtures/slackware/var/slapt-get/package_data new file mode 100644 index 0000000..410fc3d --- /dev/null +++ b/test/fixtures/slackware/var/slapt-get/package_data @@ -0,0 +1,47 @@ +PACKAGE NAME: abc-4-i686-1.txz +PACKAGE MIRROR: http://slackware.com/ +PACKAGE PRIORITY: 2 +PACKAGE LOCATION: ./slackware/ap +PACKAGE SIZE (compressed): 48 K +PACKAGE SIZE (uncompressed): 150 K +PACKAGE REQUIRED: +PACKAGE CONFLICTS: +PACKAGE SUGGESTS: +PACKAGE MD5SUM: 53e873df10b9e343a5c58721f10b9131 +PACKAGE DESCRIPTION: +abc: abc (small utility) +abc: +abc: abc is a small utility +abc: + +PACKAGE NAME: ran-1.2-noarch-1.txz +PACKAGE MIRROR: http://slackware.com/ +PACKAGE PRIORITY: 2 +PACKAGE LOCATION: ./slackware/x +PACKAGE SIZE (compressed): 36 K +PACKAGE SIZE (uncompressed): 160 K +PACKAGE REQUIRED: +PACKAGE CONFLICTS: +PACKAGE SUGGESTS: +PACKAGE MD5SUM: cefa3f087e10f8371d68bea94a829ef8 +PACKAGE DESCRIPTION: +ran: ran +ran: +ran: ran is part of X11. +ran: + +PACKAGE NAME: qwe-2.1-i486-1.txz +PACKAGE MIRROR: http://slackware.com/ +PACKAGE PRIORITY: 1 +PACKAGE LOCATION: ./slackware/ap +PACKAGE SIZE (compressed): 20 K +PACKAGE SIZE (uncompressed): 50 K +PACKAGE REQUIRED: +PACKAGE CONFLICTS: +PACKAGE SUGGESTS: +PACKAGE MD5SUM: 1a8fe22cb924cde3dc95c89689b20ee3 +PACKAGE DESCRIPTION: +qwe: qwe +qwe: +qwe: qwe is a program +qwe: diff --git a/test/fixtures/ssh-copy-id/.ssh/id_rsa b/test/fixtures/ssh-copy-id/.ssh/id_rsa new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/ssh-copy-id/.ssh/id_rsa diff --git a/test/fixtures/ssh-copy-id/.ssh/id_rsa.pub b/test/fixtures/ssh-copy-id/.ssh/id_rsa.pub new file mode 100644 index 0000000..4c656eb --- /dev/null +++ b/test/fixtures/ssh-copy-id/.ssh/id_rsa.pub @@ -0,0 +1 @@ +ssh-rsa meh comment diff --git a/test/fixtures/ssh/config b/test/fixtures/ssh/config new file mode 100644 index 0000000..806f405 --- /dev/null +++ b/test/fixtures/ssh/config @@ -0,0 +1 @@ +UserKnownHostsFile known_hosts diff --git a/test/fixtures/ssh/known_hosts b/test/fixtures/ssh/known_hosts new file mode 100644 index 0000000..13b2f0f --- /dev/null +++ b/test/fixtures/ssh/known_hosts @@ -0,0 +1,5 @@ +|1|abc +|1|def +doo +ike ssh-rsa qwerty1234/Qwerty+1234== +ls_known_host diff --git a/test/fixtures/ssh/spaced conf b/test/fixtures/ssh/spaced conf new file mode 100644 index 0000000..7ad64bc --- /dev/null +++ b/test/fixtures/ssh/spaced conf @@ -0,0 +1,6 @@ + UserKnownHostsFile known_hosts + + # Unindented +Host gee jar + # Indented, multiple hosts + HostName hus diff --git a/test/fixtures/tar/archive.tar.xz b/test/fixtures/tar/archive.tar.xz Binary files differnew file mode 100644 index 0000000..c8d2725 --- /dev/null +++ b/test/fixtures/tar/archive.tar.xz diff --git a/test/fixtures/tar/dir/fileA b/test/fixtures/tar/dir/fileA new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/tar/dir/fileA diff --git a/test/fixtures/tar/dir/fileB b/test/fixtures/tar/dir/fileB new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/tar/dir/fileB diff --git a/test/fixtures/tar/dir/fileC b/test/fixtures/tar/dir/fileC new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/tar/dir/fileC diff --git a/test/fixtures/tar/dir/hello b/test/fixtures/tar/dir/hello new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/tar/dir/hello diff --git a/test/fixtures/tar/dir2/.nothing_here b/test/fixtures/tar/dir2/.nothing_here new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/tar/dir2/.nothing_here diff --git a/test/fixtures/tar/escape.tar b/test/fixtures/tar/escape.tar Binary files differnew file mode 100644 index 0000000..7af7e9f --- /dev/null +++ b/test/fixtures/tar/escape.tar diff --git a/test/fixtures/tox/tox.ini b/test/fixtures/tox/tox.ini new file mode 100644 index 0000000..a64454f --- /dev/null +++ b/test/fixtures/tox/tox.ini @@ -0,0 +1,6 @@ +[tox] +envlist = py37 + +[testenv] +deps = pytest +commands = pytest diff --git a/test/fixtures/xz/a/b b/test/fixtures/xz/a/b new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/xz/a/b diff --git a/test/fixtures/xz/bashcomp.lzma b/test/fixtures/xz/bashcomp.lzma new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/xz/bashcomp.lzma diff --git a/test/fixtures/xz/bashcomp.tar b/test/fixtures/xz/bashcomp.tar new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/xz/bashcomp.tar diff --git a/test/fixtures/xz/bashcomp.tar.xz b/test/fixtures/xz/bashcomp.tar.xz Binary files differnew file mode 100644 index 0000000..b2274e6 --- /dev/null +++ b/test/fixtures/xz/bashcomp.tar.xz diff --git a/test/fixtures/xz/bashcomp.tlz b/test/fixtures/xz/bashcomp.tlz new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/xz/bashcomp.tlz diff --git a/test/fixtures/xz/bashcomp.xz b/test/fixtures/xz/bashcomp.xz new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixtures/xz/bashcomp.xz diff --git a/test/generate b/test/generate new file mode 100755 index 0000000..59f525b --- /dev/null +++ b/test/generate @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 + +# Generate skeleton files for completion of specified command + +import fileinput +import re +import sys + + +def main(): + if len(sys.argv) < 2: + print("Usage: %s command [args...]" % sys.argv[0], file=sys.stderr) + sys.exit(1) + + cmd = testfile = sys.argv[1] + args = " ".join(sys.argv[2:]) if len(sys.argv) > 2 else "" + marker = "" + if re.search("[.+-]", cmd): + testfile = re.sub("[.-]", "_", cmd).replace("+", "plus") + marker = '\n@pytest.mark.bashcomp(\n cmd="%s",\n)' % cmd + testfile = "test_%s.py" % testfile + name = re.sub("(^|[_-]+)(.)", lambda m: m.group(2).upper(), cmd) + name = name.replace("+", "Plus") + + with open("t/%s" % testfile, "w") as f: + print( + """\ +import pytest + +%s +class Test%s: + @pytest.mark.complete("%s %s") + def test_1(self, completion): + assert completion""" + % (marker, name, cmd, args), + file=f, + ) + + in_extra_dist = False + extra_dist_lines = set() + with fileinput.input(files=("t/Makefile.am"), inplace=True) as f: + for line in f: + if line.startswith("EXTRA_DIST "): + in_extra_dist = True + elif in_extra_dist: + if line.startswith("\t"): + line = line.strip() + if not line.endswith("\\"): + line += " \\" + extra_dist_lines.add(line) + continue + extra_dist_lines.add("%s \\" % testfile) + sys.stdout.write("\t") + print("\n\t".join(sorted(extra_dist_lines))[:-2]) + in_extra_dist = False + sys.stdout.write(line) + + +if __name__ == "__main__": + main() diff --git a/test/requirements-dev.txt b/test/requirements-dev.txt new file mode 100644 index 0000000..f34f10f --- /dev/null +++ b/test/requirements-dev.txt @@ -0,0 +1,4 @@ +# Python >= 3.6.1 required here +-r requirements.txt +black==19.10b0 +pre-commit>=2.4.0 diff --git a/test/requirements.txt b/test/requirements.txt new file mode 100644 index 0000000..df56f4e --- /dev/null +++ b/test/requirements.txt @@ -0,0 +1,5 @@ +# Python >= 3.4 required here +pexpect>=4 +pytest>=3.6 +pytest-xdist +typing;python_version<"3.5" diff --git a/test/runLint b/test/runLint new file mode 100755 index 0000000..95c3887 --- /dev/null +++ b/test/runLint @@ -0,0 +1,51 @@ +#!/bin/bash -u + +gitgrep() +{ + local out=$(git grep -I -P -n "$1" | + grep -E '^(bash_completion|completions/|test/)' | + grep -Ev "^test/runLint\>${filter_out:+|$filter_out}") + if [ -n "$out" ]; then + printf '***** %s\n' "$2" + printf '%s\n\n' "$out" + fi +} + +unset CDPATH +cd $(dirname "$0")/.. + +cmdstart='(^|[[:space:]]|\()' +filter_out= + +gitgrep $cmdstart"awk\b.*-F([[:space:]]|[[:space:]]*[\"'][^\"']{2,})" \ + 'awk with -F char or -F ERE, use -Fchar instead (Solaris)' + +gitgrep $cmdstart"awk\b.*\[:[a-z]*:\]" \ + 'awk with POSIX character class not supported in mawk (Debian/Ubuntu)' + +gitgrep $cmdstart'sed\b.*\\[?+]' \ + 'sed with ? or +, use POSIX BRE instead (\{m,n\})' + +gitgrep $cmdstart'sed\b.*\\\|' \ + "sed with \|, use POSIX BRE (possibly multiple sed invocations) or another tool instead" + +# TODO: really nonportable? appears to work fine in Linux, FreeBSD, Solaris +#gitgrep $cmdstart'sed\b.*;' \ +# 'sed with ;, use multiple -e options instead (POSIX?) (false positives?)' + +gitgrep $cmdstart'sed\b.*[[:space:]]-[^[:space:]]*[rE]' \ + 'sed with -r or -E, drop and use POSIX BRE instead' + +gitgrep $cmdstart'[ef]grep\b' \ + '[ef]grep, use grep -[EF] instead (historical/deprecated)' + +# TODO: $ in sed subexpression used as an anchor (POSIX BRE optional, not in +# Solaris/FreeBSD) + +gitgrep '(?<!command)'$cmdstart'(grep|ls|sed)(\s|$)' \ + 'invoke grep, ls, and sed through "command", e.g. "command grep"' + +gitgrep '<<<' 'herestrings use temp files, use some other way' + +filter_out='^(test/|bash_completion\.sh)' gitgrep ' \[ ' \ + 'use [[ ]] instead of [ ]' diff --git a/test/setup.cfg b/test/setup.cfg new file mode 100644 index 0000000..6abd7d3 --- /dev/null +++ b/test/setup.cfg @@ -0,0 +1,18 @@ +[tool:pytest] +minversion = 3.6 +markers = + bashcomp + complete + +[mypy] +python_version = 3.4 +ignore_missing_imports = true + +[isort] +known_first_party = conftest +known_third_party = pexpect,pytest +profile = black +line_length = 79 + +[flake8] +extend-ignore = D202,E203,E501 diff --git a/test/t/Makefile.am b/test/t/Makefile.am new file mode 100644 index 0000000..801841f --- /dev/null +++ b/test/t/Makefile.am @@ -0,0 +1,698 @@ +SUBDIRS = unit + +EXTRA_DIST = \ + conftest.py \ + test_2to3.py \ + test_7z.py \ + test_a2ps.py \ + test_a2x.py \ + test_abook.py \ + test_aclocal.py \ + test_acpi.py \ + test_acroread.py \ + test_adb.py \ + test_add_members.py \ + test_alias.py \ + test_alpine.py \ + test_animate.py \ + test_ant.py \ + test_apache2ctl.py \ + test_appdata_validate.py \ + test_apt_build.py \ + test_apt_cache.py \ + test_apt_get.py \ + test_aptitude.py \ + test_arch.py \ + test_arp.py \ + test_arping.py \ + test_arpspoof.py \ + test_asciidoc.py \ + test_aspell.py \ + test_autoconf.py \ + test_autoheader.py \ + test_automake.py \ + test_autoreconf.py \ + test_autorpm.py \ + test_autoscan.py \ + test_autossh.py \ + test_autoupdate.py \ + test_avctrl.py \ + test_awk.py \ + test_badblocks.py \ + test_base64.py \ + test_bash.py \ + test_bc.py \ + test_bind.py \ + test_bison.py \ + test_bk.py \ + test_bmake.py \ + test_brctl.py \ + test_btdownloadcurses_py.py \ + test_btdownloadgui_py.py \ + test_btdownloadheadless_py.py \ + test_bts.py \ + test_bzip2.py \ + test_cal.py \ + test_cancel.py \ + test_cardctl.py \ + test_carton.py \ + test_cat.py \ + test_cc.py \ + test_ccache.py \ + test_ccze.py \ + test_cd.py \ + test_cdrecord.py \ + test_cfagent.py \ + test_cfrun.py \ + test_chage.py \ + test_change_pw.py \ + test_check_db.py \ + test_check_perms.py \ + test_checksec.py \ + test_chfn.py \ + test_chgrp.py \ + test_chkconfig.py \ + test_chmod.py \ + test_chown.py \ + test_chpasswd.py \ + test_chromium_browser.py \ + test_chronyc.py \ + test_chroot.py \ + test_chrpath.py \ + test_chsh.py \ + test_ci.py \ + test_ciptool.py \ + test_civclient.py \ + test_civserver.py \ + test_cksfv.py \ + test_cleanarch.py \ + test_clisp.py \ + test_clone_member.py \ + test_co.py \ + test_colordiff.py \ + test_compare.py \ + test_compgen.py \ + test_complete.py \ + test_composite.py \ + test_config_list.py \ + test_configure.py \ + test_conjure.py \ + test_convert.py \ + test_cowsay.py \ + test_cp.py \ + test_cpan2dist.py \ + test_cpio.py \ + test_cplusplus.py \ + test_cppcheck.py \ + test_createdb.py \ + test_createuser.py \ + test_crontab.py \ + test_cryptsetup.py \ + test_csplit.py \ + test_curl.py \ + test_cut.py \ + test_cvs.py \ + test_cvsps.py \ + test_date.py \ + test_dcop.py \ + test_dd.py \ + test_declare.py \ + test_deja_dup.py \ + test_desktop_file_validate.py \ + test_df.py \ + test_dfutool.py \ + test_dhclient.py \ + test_dict.py \ + test_diff.py \ + test_dir.py \ + test_display.py \ + test_dmesg.py \ + test_dmypy.py \ + test_dnssec_keygen.py \ + test_dnsspoof.py \ + test_dot.py \ + test_dpkg.py \ + test_dpkg_deb.py \ + test_dpkg_query.py \ + test_dpkg_reconfigure.py \ + test_dpkg_source.py \ + test_dropdb.py \ + test_dropuser.py \ + test_dselect.py \ + test_dsniff.py \ + test_du.py \ + test_dumpdb.py \ + test_dumpe2fs.py \ + test_e2freefrag.py \ + test_e2label.py \ + test_ebtables.py \ + test_ecryptfs_migrate_home.py \ + test_eject.py \ + test_enscript.py \ + test_env.py \ + test_eog.py \ + test_ether_wake.py \ + test_etherwake.py \ + test_evince.py \ + test_expand.py \ + test_explodepkg.py \ + test_export.py \ + test_faillog.py \ + test_fbgs.py \ + test_fbi.py \ + test_feh.py \ + test_file.py \ + test_file_roller.py \ + test_filefrag.py \ + test_filesnarf.py \ + test_find.py \ + test_find_member.py \ + test_finger.py \ + test_fio.py \ + test_firefox.py \ + test_flake8.py \ + test_fmt.py \ + test_fold.py \ + test_freebsd_update.py \ + test_freeciv.py \ + test_freeciv_server.py \ + test_function.py \ + test_fusermount.py \ + test_g4.py \ + test_g77.py \ + test_gcc.py \ + test_gcj.py \ + test_gcl.py \ + test_gdb.py \ + test_genaliases.py \ + test_gendiff.py \ + test_genisoimage.py \ + test_geoiplookup.py \ + test_getconf.py \ + test_getent.py \ + test_gkrellm.py \ + test_gm.py \ + test_gmplayer.py \ + test_gnatmake.py \ + test_gnokii.py \ + test_gnome_mplayer.py \ + test_gnome_screenshot.py \ + test_gpasswd.py \ + test_gpc.py \ + test_gperf.py \ + test_gpg.py \ + test_gpg2.py \ + test_gpgv.py \ + test_gphoto2.py \ + test_gplusplus.py \ + test_gprof.py \ + test_grep.py \ + test_groupadd.py \ + test_groupdel.py \ + test_groupmems.py \ + test_groupmod.py \ + test_growisofs.py \ + test_grpck.py \ + test_grub.py \ + test_gssdp_discover.py \ + test_gzip.py \ + test_hciattach.py \ + test_hciconfig.py \ + test_hcitool.py \ + test_hddtemp.py \ + test_head.py \ + test_hexdump.py \ + test_hid2hci.py \ + test_host.py \ + test_hostname.py \ + test_hping2.py \ + test_hping3.py \ + test_htop.py \ + test_htpasswd.py \ + test_hunspell.py \ + test_hwclock.py \ + test_iconv.py \ + test_id.py \ + test_identify.py \ + test_idn.py \ + test_ifdown.py \ + test_ifstat.py \ + test_iftop.py \ + test_ifup.py \ + test_import.py \ + test_influx.py \ + test_info.py \ + test_inject.py \ + test_inotifywait.py \ + test_inotifywatch.py \ + test_insmod.py \ + test_installpkg.py \ + test_interdiff.py \ + test_invoke_rc_d.py \ + test_ionice.py \ + test_ip.py \ + test_ipcalc.py \ + test_iperf.py \ + test_ipmitool.py \ + test_ipsec.py \ + test_iptables.py \ + test_ipv6calc.py \ + test_irb.py \ + test_iscsiadm.py \ + test_isort.py \ + test_isql.py \ + test_iwconfig.py \ + test_iwlist.py \ + test_iwpriv.py \ + test_iwspy.py \ + test_jar.py \ + test_jarsigner.py \ + test_java.py \ + test_javac.py \ + test_javadoc.py \ + test_javaws.py \ + test_jpegoptim.py \ + test_jps.py \ + test_jq.py \ + test_jshint.py \ + test_json_xs.py \ + test_jsonschema.py \ + test_k3b.py \ + test_kcov.py \ + test_kdvi.py \ + test_kill.py \ + test_killall.py \ + test_kldload.py \ + test_kldunload.py \ + test_koji.py \ + test_kpdf.py \ + test_kplayer.py \ + test_ktutil.py \ + test_l2ping.py \ + test_larch.py \ + test_lastlog.py \ + test_ld.py \ + test_ldapadd.py \ + test_ldapcompare.py \ + test_ldapdelete.py \ + test_ldapmodrdn.py \ + test_ldappasswd.py \ + test_ldapsearch.py \ + test_ldapvi.py \ + test_ldapwhoami.py \ + test_ldd.py \ + test_less.py \ + test_lftp.py \ + test_lftpget.py \ + test_lilo.py \ + test_links.py \ + test_lintian.py \ + test_lintian_info.py \ + test_lisp.py \ + test_list_admins.py \ + test_list_lists.py \ + test_list_members.py \ + test_list_owners.py \ + test_ln.py \ + test_locale_gen.py \ + test_look.py \ + test_lpq.py \ + test_lpr.py \ + test_lrzip.py \ + test_ls.py \ + test_lsof.py \ + test_lspci.py \ + test_lsscsi.py \ + test_lsusb.py \ + test_lua.py \ + test_luac.py \ + test_luseradd.py \ + test_luserdel.py \ + test_lusermod.py \ + test_lvchange.py \ + test_lvcreate.py \ + test_lvdisplay.py \ + test_lvextend.py \ + test_lvm.py \ + test_lvmdiskscan.py \ + test_lvreduce.py \ + test_lvremove.py \ + test_lvrename.py \ + test_lvresize.py \ + test_lvs.py \ + test_lvscan.py \ + test_lz4.py \ + test_lzip.py \ + test_lzma.py \ + test_lzop.py \ + test_m4.py \ + test_macof.py \ + test_mailmanctl.py \ + test_mailsnarf.py \ + test_make.py \ + test_makepkg.py \ + test_man.py \ + test_mc.py \ + test_mcrypt.py \ + test_md5sum.py \ + test_mdadm.py \ + test_mdecrypt.py \ + test_mdtool.py \ + test_medusa.py \ + test_mencoder.py \ + test_mii_diag.py \ + test_mii_tool.py \ + test_minicom.py \ + test_mkdir.py \ + test_mkfifo.py \ + test_mkinitrd.py \ + test_mkisofs.py \ + test_mknod.py \ + test_mktemp.py \ + test_mmsitepass.py \ + test_mock.py \ + test_modinfo.py \ + test_modprobe.py \ + test_module.py \ + test_mogrify.py \ + test_monodevelop.py \ + test_montage.py \ + test_mount.py \ + test_mplayer.py \ + test_mr.py \ + test_msgsnarf.py \ + test_msynctool.py \ + test_mtx.py \ + test_munin_node_configure.py \ + test_munin_run.py \ + test_munindoc.py \ + test_mussh.py \ + test_mutt.py \ + test_muttng.py \ + test_mv.py \ + test_mypy.py \ + test_mysql.py \ + test_mysqladmin.py \ + test_nc.py \ + test_ncftp.py \ + test_nethogs.py \ + test_netstat.py \ + test_newgrp.py \ + test_newlist.py \ + test_newusers.py \ + test_ngrep.py \ + test_nl.py \ + test_nm.py \ + test_nmap.py \ + test_nmcli.py \ + test_nproc.py \ + test_nslookup.py \ + test_nsupdate.py \ + test_ntpdate.py \ + test_objcopy.py \ + test_objdump.py \ + test_od.py \ + test_oggdec.py \ + test_op.py \ + test_openssl.py \ + test_opera.py \ + test_optipng.py \ + test_p4.py \ + test_pack200.py \ + test_passwd.py \ + test_paste.py \ + test_patch.py \ + test_pdftotext.py \ + test_perl.py \ + test_perlcritic.py \ + test_perldoc.py \ + test_perltidy.py \ + test_pgrep.py \ + test_phing.py \ + test_pidof.py \ + test_pine.py \ + test_pinfo.py \ + test_ping.py \ + test_pkg_config.py \ + test_pkg_deinstall.py \ + test_pkg_delete.py \ + test_pkg_get.py \ + test_pkg_info.py \ + test_pkgadd.py \ + test_pkgrm.py \ + test_pkgtool.py \ + test_pkgutil.py \ + test_pkill.py \ + test_plague_client.py \ + test_pm_hibernate.py \ + test_pm_is_supported.py \ + test_pm_powersave.py \ + test_pngfix.py \ + test_portinstall.py \ + test_portsnap.py \ + test_portupgrade.py \ + test_postcat.py \ + test_postconf.py \ + test_postfix.py \ + test_postmap.py \ + test_postsuper.py \ + test_povray.py \ + test_pr.py \ + test_prelink.py \ + test_printenv.py \ + test_protoc.py \ + test_psql.py \ + test_ptx.py \ + test_puppet.py \ + test_pushd.py \ + test_pv.py \ + test_pvchange.py \ + test_pvcreate.py \ + test_pvdisplay.py \ + test_pvmove.py \ + test_pvremove.py \ + test_pvs.py \ + test_pvscan.py \ + test_pwck.py \ + test_pwd.py \ + test_pwdx.py \ + test_pwgen.py \ + test_pycodestyle.py \ + test_pydoc.py \ + test_pydocstyle.py \ + test_pyflakes.py \ + test_pylint.py \ + test_pylint_3.py \ + test_pytest.py \ + test_python.py \ + test_python3.py \ + test_pyvenv.py \ + test_qemu.py \ + test_qrunner.py \ + test_querybts.py \ + test_quota.py \ + test_quotacheck.py \ + test_quotaon.py \ + test_radvdump.py \ + test_rcs.py \ + test_rcsdiff.py \ + test_rdesktop.py \ + test_rdict.py \ + test_readelf.py \ + test_readonly.py \ + test_remove_members.py \ + test_removepkg.py \ + test_renice.py \ + test_repomanage.py \ + test_reportbug.py \ + test_reptyr.py \ + test_resolvconf.py \ + test_rfcomm.py \ + test_rfkill.py \ + test_ri.py \ + test_rlog.py \ + test_rm.py \ + test_rmdir.py \ + test_rmlist.py \ + test_rmmod.py \ + test_route.py \ + test_rpcdebug.py \ + test_rpm.py \ + test_rpm2tgz.py \ + test_rpmbuild.py \ + test_rrdtool.py \ + test_rsync.py \ + test_rtcwake.py \ + test_runuser.py \ + test_sbcl.py \ + test_sbcl_mt.py \ + test_sbopkg.py \ + test_scp.py \ + test_screen.py \ + test_scrub.py \ + test_sdptool.py \ + test_secret_tool.py \ + test_sed.py \ + test_seq.py \ + test_service.py \ + test_set.py \ + test_setquota.py \ + test_sftp.py \ + test_sh.py \ + test_sha1sum.py \ + test_shar.py \ + test_shellcheck.py \ + test_sitecopy.py \ + test_slackpkg.py \ + test_slapt_get.py \ + test_slapt_src.py \ + test_smartctl.py \ + test_smbcacls.py \ + test_smbclient.py \ + test_smbcquotas.py \ + test_smbget.py \ + test_smbpasswd.py \ + test_smbtar.py \ + test_smbtree.py \ + test_snownews.py \ + test_sort.py \ + test_split.py \ + test_spovray.py \ + test_sqlite3.py \ + test_ss.py \ + test_ssh.py \ + test_ssh_add.py \ + test_ssh_copy_id.py \ + test_ssh_keygen.py \ + test_sshfs.py \ + test_sshmitm.py \ + test_sshow.py \ + test_strace.py \ + test_stream.py \ + test_strings.py \ + test_strip.py \ + test_su.py \ + test_sudo.py \ + test_sum.py \ + test_svcadm.py \ + test_svk.py \ + test_svn.py \ + test_svnadmin.py \ + test_svnlook.py \ + test_sync_members.py \ + test_synclient.py \ + test_sysbench.py \ + test_sysctl.py \ + test_tac.py \ + test_tail.py \ + test_tar.py \ + test_tcpdump.py \ + test_tcpkill.py \ + test_tcpnice.py \ + test_tee.py \ + test_texindex.py \ + test_tightvncviewer.py \ + test_time.py \ + test_timeout.py \ + test_tipc.py \ + test_totem.py \ + test_touch.py \ + test_tox.py \ + test_tr.py \ + test_tracepath.py \ + test_tshark.py \ + test_tsig_keygen.py \ + test_tune2fs.py \ + test_udevadm.py \ + test_ulimit.py \ + test_umount.py \ + test_unace.py \ + test_uname.py \ + test_unexpand.py \ + test_uniq.py \ + test_units.py \ + test_unpack200.py \ + test_unrar.py \ + test_unset.py \ + test_unshunt.py \ + test_update_alternatives.py \ + test_update_rc_d.py \ + test_upgradepkg.py \ + test_urlsnarf.py \ + test_uscan.py \ + test_useradd.py \ + test_userdel.py \ + test_usermod.py \ + test_valgrind.py \ + test_vdir.py \ + test_vgcfgbackup.py \ + test_vgcfgrestore.py \ + test_vgchange.py \ + test_vgck.py \ + test_vgconvert.py \ + test_vgcreate.py \ + test_vgdisplay.py \ + test_vgexport.py \ + test_vgextend.py \ + test_vgimport.py \ + test_vgmerge.py \ + test_vgmknodes.py \ + test_vgreduce.py \ + test_vgremove.py \ + test_vgrename.py \ + test_vgs.py \ + test_vgscan.py \ + test_vgsplit.py \ + test_vi.py \ + test_vipw.py \ + test_vmstat.py \ + test_vncviewer.py \ + test_vpnc.py \ + test_watch.py \ + test_wc.py \ + test_webmitm.py \ + test_wget.py \ + test_who.py \ + test_wine.py \ + test_withlist.py \ + test_wodim.py \ + test_wol.py \ + test_write.py \ + test_wsimport.py \ + test_wtf.py \ + test_wvdial.py \ + test_xdg_mime.py \ + test_xdg_settings.py \ + test_xfreerdp.py \ + test_xgamma.py \ + test_xhost.py \ + test_xm.py \ + test_xmllint.py \ + test_xmlwf.py \ + test_xmms.py \ + test_xmodmap.py \ + test_xpovray.py \ + test_xrandr.py \ + test_xrdb.py \ + test_xsltproc.py \ + test_xvfb_run.py \ + test_xvnc4viewer.py \ + test_xxd.py \ + test_xz.py \ + test_xzdec.py \ + test_ypcat.py \ + test_ypmatch.py \ + test_yum.py \ + test_yum_arch.py \ + test_zopfli.py \ + test_zopflipng.py + +all: + +PYTEST = @PYTEST@ + +check-local: + $(PYTEST) $(PYTESTFLAGS) $(srcdir) + +clean-local: + $(RM) -R __pycache__ diff --git a/test/t/conftest.py b/test/t/conftest.py new file mode 100644 index 0000000..5c1603d --- /dev/null +++ b/test/t/conftest.py @@ -0,0 +1,637 @@ +import difflib +import os +import re +import shlex +import subprocess +import time +from typing import Callable, Iterable, Iterator, List, Optional, Tuple + +import pexpect +import pytest + +PS1 = "/@" +MAGIC_MARK = "__MaGiC-maRKz!__" + + +def find_unique_completion_pair( + items: Iterable[str], +) -> Optional[Tuple[str, str]]: + result = None + bestscore = 0 + sitems = sorted(set(items)) + for i in range(len(sitems)): + cur = sitems[i] + curlen = len(cur) + prv = sitems[i - 1] if i != 0 else "" + prvlen = len(prv) + nxt = sitems[i + 1] if i < len(sitems) - 1 else "" + nxtlen = len(nxt) + diffprv = prv == "" + diffnxt = nxt == "" + # Analyse each item of the list and look for the minimum length of the + # partial prefix which is distinct from both nxt and prv. The list + # is sorted so the prefix will be unique in the entire list. + for j in range(curlen): + curchar = cur[j] + if not diffprv and (j >= prvlen or prv[j] != curchar): + diffprv = True + if not diffnxt and (j >= nxtlen or nxt[j] != curchar): + diffnxt = True + if diffprv and diffnxt: + break + # At the end of the loop, j is the index of last character of + # the unique partial prefix. The length is one plus that. + parlen = j + 1 + if parlen >= curlen: + continue + # Try to find the most "readable pair"; look for a long pair where + # part is about half of full. + if parlen < curlen / 2: + parlen = int(curlen / 2) + score = curlen - parlen + if score > bestscore: + bestscore = score + result = (cur[:parlen], cur) + return result + + +@pytest.fixture(scope="class") +def output_sort_uniq(bash: pexpect.spawn) -> Callable[[str], List[str]]: + def _output_sort_uniq(command: str) -> List[str]: + return sorted( + set( # weed out possible duplicates + assert_bash_exec(bash, command, want_output=True).split() + ) + ) + + return _output_sort_uniq + + +@pytest.fixture(scope="class") +def part_full_user( + bash: pexpect.spawn, output_sort_uniq: Callable[[str], List[str]] +) -> Optional[Tuple[str, str]]: + res = output_sort_uniq("compgen -u") + pair = find_unique_completion_pair(res) + if not pair: + pytest.skip("No suitable test user found") + return pair + + +@pytest.fixture(scope="class") +def part_full_group( + bash: pexpect.spawn, output_sort_uniq: Callable[[str], List[str]] +) -> Optional[Tuple[str, str]]: + res = output_sort_uniq("compgen -g") + pair = find_unique_completion_pair(res) + if not pair: + pytest.skip("No suitable test user found") + return pair + + +@pytest.fixture(scope="class") +def hosts(bash: pexpect.spawn) -> List[str]: + output = assert_bash_exec(bash, "compgen -A hostname", want_output=True) + return sorted(set(output.split() + _avahi_hosts(bash))) + + +@pytest.fixture(scope="class") +def avahi_hosts(bash: pexpect.spawn) -> List[str]: + return _avahi_hosts(bash) + + +def _avahi_hosts(bash: pexpect.spawn) -> List[str]: + output = assert_bash_exec( + bash, + "! type avahi-browse &>/dev/null || " + "avahi-browse -cpr _workstation._tcp 2>/dev/null " + "| command grep ^= | cut -d';' -f7", + want_output=None, + ) + return sorted(set(output.split())) + + +@pytest.fixture(scope="class") +def known_hosts(bash: pexpect.spawn) -> List[str]: + output = assert_bash_exec( + bash, + '_known_hosts_real ""; ' + r'printf "%s\n" "${COMPREPLY[@]}"; unset COMPREPLY', + want_output=True, + ) + return sorted(set(output.split())) + + +@pytest.fixture(scope="class") +def user_home(bash: pexpect.spawn) -> Tuple[str, str]: + user = assert_bash_exec( + bash, 'id -un 2>/dev/null || echo "$USER"', want_output=True + ).strip() + home = assert_bash_exec(bash, 'echo "$HOME"', want_output=True).strip() + return (user, home) + + +def partialize( + bash: pexpect.spawn, items: Iterable[str] +) -> Tuple[str, List[str]]: + """ + Get list of items starting with the first char of first of items. + + Disregard items starting with a COMP_WORDBREAKS character + (e.g. a colon ~ IPv6 address), they are special cases requiring + special tests. + """ + first_char = None + comp_wordbreaks = assert_bash_exec( + bash, + 'printf "%s" "$COMP_WORDBREAKS"', + want_output=True, + want_newline=False, + ) + partial_items = [] + for item in sorted(items): + if first_char is None: + if item[0] not in comp_wordbreaks: + first_char = item[0] + partial_items.append(item) + elif item.startswith(first_char): + partial_items.append(item) + else: + break + if first_char is None: + pytest.skip("Could not generate partial items list from %s" % items) + # superfluous/dead code to assist mypy; pytest.skip always raises + assert first_char is not None + return first_char, partial_items + + +@pytest.fixture(scope="class") +def bash(request) -> pexpect.spawn: + + logfile = None + if os.environ.get("BASHCOMP_TEST_LOGFILE"): + logfile = open(os.environ["BASHCOMP_TEST_LOGFILE"], "w") + testdir = os.path.abspath( + os.path.join(os.path.dirname(__file__), os.pardir) + ) + env = os.environ.copy() + env.update( + dict( + SRCDIR=testdir, # TODO needed at least by bashrc + SRCDIRABS=testdir, # TODO needed? + PS1=PS1, + INPUTRC="%s/config/inputrc" % testdir, + TERM="dumb", + LC_COLLATE="C", # to match Python's default locale unaware sort + ) + ) + + fixturesdir = os.path.join(testdir, "fixtures") + os.chdir(fixturesdir) + + # Start bash + bash = pexpect.spawn( + "%s --norc" % os.environ.get("BASHCOMP_TEST_BASH", "bash"), + maxread=os.environ.get("BASHCOMP_TEST_PEXPECT_MAXREAD", 20000), + logfile=logfile, + cwd=fixturesdir, + env=env, + encoding="utf-8", # TODO? or native or...? + # FIXME: Tests shouldn't depend on dimensions, but it's difficult to + # expect robustly enough for Bash to wrap lines anywhere (e.g. inside + # MAGIC_MARK). Increase window width to reduce wrapping. + dimensions=(24, 160), + # TODO? codec_errors="replace", + ) + bash.expect_exact(PS1) + + # Load bashrc and bash_completion + assert_bash_exec(bash, "source '%s/config/bashrc'" % testdir) + assert_bash_exec(bash, "source '%s/../bash_completion'" % testdir) + + # Use command name from marker if set, or grab from test filename + cmd = None # type: Optional[str] + cmd_found = False + marker = request.node.get_closest_marker("bashcomp") + if marker: + cmd = marker.kwargs.get("cmd") + cmd_found = "cmd" in marker.kwargs + # Run pre-test commands, early so they're usable in skipif + for pre_cmd in marker.kwargs.get("pre_cmds", []): + assert_bash_exec(bash, pre_cmd) + # Process skip and xfail conditions + skipif = marker.kwargs.get("skipif") + if skipif: + try: + assert_bash_exec(bash, skipif, want_output=None) + except AssertionError: + pass + else: + bash.close() + pytest.skip(skipif) + xfail = marker.kwargs.get("xfail") + if xfail: + try: + assert_bash_exec(bash, xfail, want_output=None) + except AssertionError: + pass + else: + pytest.xfail(xfail) + if not cmd_found: + match = re.search( + r"^test_(.+)\.py$", os.path.basename(str(request.fspath)) + ) + if match: + cmd = match.group(1) + + request.cls.cmd = cmd + + if (cmd_found and cmd is None) or is_testable(bash, cmd): + before_env = get_env(bash) + yield bash + # Not exactly sure why, but some errors leave bash in state where + # getting the env here would fail and trash our test output. So + # reset to a good state first (Ctrl+C, expect prompt). + bash.sendintr() + bash.expect_exact(PS1) + diff_env( + before_env, + get_env(bash), + marker.kwargs.get("ignore_env") if marker else "", + ) + + if marker: + for post_cmd in marker.kwargs.get("post_cmds", []): + assert_bash_exec(bash, post_cmd) + + # Clean up + bash.close() + if logfile: + logfile.close() + + +def is_testable(bash: pexpect.spawn, cmd: Optional[str]) -> bool: + if not cmd: + pytest.fail("Could not resolve name of command to test") + return False + if not load_completion_for(bash, cmd): + pytest.skip("No completion for command %s" % cmd) + return True + + +def is_bash_type(bash: pexpect.spawn, cmd: Optional[str]) -> bool: + if not cmd: + return False + typecmd = "type %s &>/dev/null && echo -n 0 || echo -n 1" % cmd + bash.sendline(typecmd) + bash.expect_exact(typecmd + "\r\n") + result = bash.expect_exact(["0", "1"]) == 0 + bash.expect_exact(PS1) + return result + + +def load_completion_for(bash: pexpect.spawn, cmd: str) -> bool: + try: + # Allow __load_completion to fail so we can test completions + # that are directly loaded in bash_completion without a separate file. + assert_bash_exec(bash, "__load_completion %s || :" % cmd) + assert_bash_exec(bash, "complete -p %s &>/dev/null" % cmd) + except AssertionError: + return False + return True + + +def assert_bash_exec( + bash: pexpect.spawn, + cmd: str, + want_output: Optional[bool] = False, + want_newline=True, +) -> str: + """ + :param want_output: if None, don't care if got output or not + """ + + # Send command + bash.sendline(cmd) + bash.expect_exact(cmd) + + # Find prompt, output is before it + bash.expect_exact("%s%s" % ("\r\n" if want_newline else "", PS1)) + output = bash.before + + # Retrieve exit status + echo = "echo $?" + bash.sendline(echo) + got = bash.expect( + [ + r"^%s\r\n(\d+)\r\n%s" % (re.escape(echo), re.escape(PS1)), + PS1, + pexpect.EOF, + pexpect.TIMEOUT, + ] + ) + status = bash.match.group(1) if got == 0 else "unknown" + + assert status == "0", 'Error running "%s": exit status=%s, output="%s"' % ( + cmd, + status, + output, + ) + if want_output is not None: + if output: + assert want_output, ( + 'Unexpected output from "%s": exit status=%s, output="%s"' + % (cmd, status, output) + ) + else: + assert not want_output, ( + 'Expected output from "%s": exit status=%s, output="%s"' + % (cmd, status, output) + ) + + return output + + +def get_env(bash: pexpect.spawn) -> List[str]: + return ( + assert_bash_exec( + bash, + "{ (set -o posix ; set); declare -F; shopt -p; set -o; }", + want_output=True, + ) + .strip() + .splitlines() + ) + + +def diff_env(before: List[str], after: List[str], ignore: str): + diff = [ + x + for x in difflib.unified_diff(before, after, n=0, lineterm="") + # Remove unified diff markers: + if not re.search(r"^(---|\+\+\+|@@ )", x) + # Ignore variables expected to change: + and not re.search("^[-+](_|PPID|BASH_REMATCH|OLDPWD)=", x) + # Ignore likely completion functions added by us: + and not re.search(r"^\+declare -f _.+", x) + # ...and additional specified things: + and not re.search(ignore or "^$", x) + ] + # For some reason, COMP_WORDBREAKS gets added to the list after + # saving. Remove its changes, and note that it may take two lines. + for i in range(0, len(diff)): + if re.match("^[-+]COMP_WORDBREAKS=", diff[i]): + if i < len(diff) and not re.match(r"^\+[\w]+=", diff[i + 1]): + del diff[i + 1] + del diff[i] + break + assert not diff, "Environment should not be modified" + + +class CompletionResult(Iterable[str]): + """ + Class to hold completion results. + """ + + def __init__(self, output: Optional[str] = None): + """ + :param output: All completion output as-is. + """ + self.output = output or "" + + def endswith(self, suffix: str) -> bool: + return self.output.endswith(suffix) + + def startswith(self, prefix: str) -> bool: + return self.output.startswith(prefix) + + def _items(self) -> List[str]: + return [x.strip() for x in self.output.strip().splitlines()] + + def __eq__(self, expected: object) -> bool: + """ + Returns True if completion contains expected items, and no others. + + Defining __eq__ this way is quite ugly, but facilitates concise + testing code. + """ + if isinstance(expected, str): + expiter = [expected] # type: Iterable + elif not isinstance(expected, Iterable): + return False + else: + expiter = expected + return self._items() == expiter + + def __contains__(self, item: str) -> bool: + return item in self._items() + + def __iter__(self) -> Iterator[str]: + return iter(self._items()) + + def __len__(self) -> int: + return len(self._items()) + + def __repr__(self) -> str: + return "<CompletionResult %s>" % self._items() + + +def assert_complete( + bash: pexpect.spawn, cmd: str, **kwargs +) -> CompletionResult: + skipif = kwargs.get("skipif") + if skipif: + try: + assert_bash_exec(bash, skipif, want_output=None) + except AssertionError: + pass + else: + pytest.skip(skipif) + xfail = kwargs.get("xfail") + if xfail: + try: + assert_bash_exec(bash, xfail, want_output=None) + except AssertionError: + pass + else: + pytest.xfail(xfail) + cwd = kwargs.get("cwd") + if cwd: + assert_bash_exec(bash, "cd '%s'" % cwd) + env_prefix = "_BASHCOMP_TEST_" + env = kwargs.get("env", {}) + if env: + # Back up environment and apply new one + assert_bash_exec( + bash, + " ".join('%s%s="${%s-}"' % (env_prefix, k, k) for k in env.keys()), + ) + assert_bash_exec( + bash, + "export %s" % " ".join("%s=%s" % (k, v) for k, v in env.items()), + ) + try: + bash.send(cmd + "\t") + # Sleep a bit if requested, to avoid `.*` matching too early + time.sleep(kwargs.get("sleep_after_tab", 0)) + bash.expect_exact(cmd) + bash.send(MAGIC_MARK) + got = bash.expect( + [ + # 0: multiple lines, result in .before + r"\r\n" + re.escape(PS1 + cmd) + ".*" + re.escape(MAGIC_MARK), + # 1: no completion + r"^" + re.escape(MAGIC_MARK), + # 2: on same line, result in .match + r"^([^\r]+)%s$" % re.escape(MAGIC_MARK), + pexpect.EOF, + pexpect.TIMEOUT, + ] + ) + if got == 0: + output = bash.before + if output.endswith(MAGIC_MARK): + output = bash.before[: -len(MAGIC_MARK)] + result = CompletionResult(output) + elif got == 2: + output = bash.match.group(1) + result = CompletionResult(output) + else: + # TODO: warn about EOF/TIMEOUT? + result = CompletionResult() + finally: + bash.sendintr() + bash.expect_exact(PS1) + if env: + # Restore environment, and clean up backup + # TODO: Test with declare -p if a var was set, backup only if yes, and + # similarly restore only backed up vars. Should remove some need + # for ignore_env. + assert_bash_exec( + bash, + "export %s" + % " ".join( + '%s="$%s%s"' % (k, env_prefix, k) for k in env.keys() + ), + ) + assert_bash_exec( + bash, + "unset -v %s" + % " ".join("%s%s" % (env_prefix, k) for k in env.keys()), + ) + if cwd: + assert_bash_exec(bash, "cd - >/dev/null") + return result + + +@pytest.fixture +def completion(request, bash: pexpect.spawn) -> CompletionResult: + marker = request.node.get_closest_marker("complete") + if not marker: + return CompletionResult() + for pre_cmd in marker.kwargs.get("pre_cmds", []): + assert_bash_exec(bash, pre_cmd) + cmd = getattr(request.cls, "cmd", None) + if marker.kwargs.get("require_longopt"): + # longopt completions require both command presence and that it + # responds something useful to --help + if "require_cmd" not in marker.kwargs: + marker.kwargs["require_cmd"] = True + if "xfail" not in marker.kwargs: + marker.kwargs["xfail"] = ( + "! %s --help &>/dev/null || " + "! %s --help 2>&1 | command grep -qF -- --help" + ) % ((cmd,) * 2) + if marker.kwargs.get("require_cmd") and not is_bash_type(bash, cmd): + pytest.skip("Command not found") + + if "trail" in marker.kwargs: + return assert_complete_at_point( + bash, cmd=marker.args[0], trail=marker.kwargs["trail"] + ) + + return assert_complete(bash, marker.args[0], **marker.kwargs) + + +def assert_complete_at_point( + bash: pexpect.spawn, cmd: str, trail: str +) -> CompletionResult: + # TODO: merge to assert_complete + fullcmd = "%s%s%s" % ( + cmd, + trail, + "\002" * len(trail), + ) # \002 = ^B = cursor left + bash.send(fullcmd + "\t") + bash.send(MAGIC_MARK) + bash.expect_exact(fullcmd.replace("\002", "\b")) + + got = bash.expect_exact( + [ + # 0: multiple lines, result in .before + PS1 + fullcmd.replace("\002", "\b"), + # 1: no completion + MAGIC_MARK, + pexpect.EOF, + pexpect.TIMEOUT, + ] + ) + if got == 0: + output = bash.before + result = CompletionResult(output) + + # At this point, something weird happens. For most test setups, as + # expected (pun intended!), MAGIC_MARK follows as is. But for some + # others (e.g. CentOS 6, Ubuntu 14 test containers), we get MAGIC_MARK + # one character a time, followed each time by trail and the corresponding + # number of \b's. Don't know why, but accept it until/if someone finds out. + # Or just be fine with it indefinitely, the visible and practical end + # result on a terminal is the same anyway. + repeat = "(%s%s)?" % (re.escape(trail), "\b" * len(trail)) + fullexpected = "".join( + "%s%s" % (re.escape(x), repeat) for x in MAGIC_MARK + ) + bash.expect(fullexpected) + else: + # TODO: warn about EOF/TIMEOUT? + result = CompletionResult() + + return result + + +def in_container() -> bool: + try: + container = subprocess.check_output( + "virt-what || systemd-detect-virt --container", + stderr=subprocess.DEVNULL, + shell=True, + ).strip() + except subprocess.CalledProcessError: + container = b"" + if container and container != b"none": + return True + if os.path.exists("/.dockerenv"): + return True + try: + with open("/proc/1/environ", "rb") as f: + # LXC, others? + if any( + x.startswith(b"container=") for x in f.readline().split(b"\0") + ): + return True + except OSError: + pass + return False + + +class TestUnitBase: + def _test_unit( + self, func, bash, comp_words, comp_cword, comp_line, comp_point, arg="" + ): + assert_bash_exec( + bash, + "COMP_WORDS=%s COMP_CWORD=%d COMP_LINE=%s COMP_POINT=%d" + % (comp_words, comp_cword, shlex.quote(comp_line), comp_point), + ) + output = assert_bash_exec(bash, func % arg, want_output=True) + return output.strip() diff --git a/test/t/test_2to3.py b/test/t/test_2to3.py new file mode 100644 index 0000000..4bce44e --- /dev/null +++ b/test/t/test_2to3.py @@ -0,0 +1,11 @@ +import pytest + + +class Test2to3: + @pytest.mark.complete("2to3 ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("2to3 -", require_cmd=True, require_longopt=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_7z.py b/test/t/test_7z.py new file mode 100644 index 0000000..d4308d9 --- /dev/null +++ b/test/t/test_7z.py @@ -0,0 +1,33 @@ +import pytest + + +class Test7z: + @pytest.mark.complete("7z ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("7z a ar -tzi") + def test_2(self, completion): + assert completion == "p" + + @pytest.mark.complete(r"7z x -wa\ ", cwd="_filedir") + def test_3(self, completion): + assert completion == "b/" + assert not completion.endswith(" ") + + @pytest.mark.complete("7z x ", cwd="7z") + def test_4(self, completion): + assert completion == "a.7z" + + @pytest.mark.complete("7z d a.7z ", cwd="7z", require_cmd=True) + def test_5(self, completion): + assert completion == "abc" + + @pytest.mark.complete("7z a -air@", cwd="7z") + def test_6(self, completion): + assert completion == sorted("-air@a.7z -air@f.txt".split()) + + @pytest.mark.complete("7z a -o") + def test_7(self, completion): + assert "-o7z/" in completion + assert all(x.endswith("/") for x in completion) diff --git a/test/t/test_a2ps.py b/test/t/test_a2ps.py new file mode 100644 index 0000000..38365f0 --- /dev/null +++ b/test/t/test_a2ps.py @@ -0,0 +1,11 @@ +import pytest + + +class TestA2ps: + @pytest.mark.complete("a2ps ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("a2ps -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_a2x.py b/test/t/test_a2x.py new file mode 100644 index 0000000..4bfb428 --- /dev/null +++ b/test/t/test_a2x.py @@ -0,0 +1,11 @@ +import pytest + + +class TestA2x: + @pytest.mark.complete("a2x ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("a2x -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_abook.py b/test/t/test_abook.py new file mode 100644 index 0000000..9542a4c --- /dev/null +++ b/test/t/test_abook.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAbook: + @pytest.mark.complete("abook -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_aclocal.py b/test/t/test_aclocal.py new file mode 100644 index 0000000..ad28b42 --- /dev/null +++ b/test/t/test_aclocal.py @@ -0,0 +1,11 @@ +import pytest + + +class TestAclocal: + @pytest.mark.complete("aclocal ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("aclocal -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_acpi.py b/test/t/test_acpi.py new file mode 100644 index 0000000..bd06d93 --- /dev/null +++ b/test/t/test_acpi.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAcpi: + @pytest.mark.complete("acpi -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_acroread.py b/test/t/test_acroread.py new file mode 100644 index 0000000..22d6024 --- /dev/null +++ b/test/t/test_acroread.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAcroread: + @pytest.mark.complete("acroread ", cwd="acroread") + def test_1(self, completion): + assert completion == "foo.d/ t.pdf".split() diff --git a/test/t/test_adb.py b/test/t/test_adb.py new file mode 100644 index 0000000..74b0d37 --- /dev/null +++ b/test/t/test_adb.py @@ -0,0 +1,11 @@ +import pytest + + +class TestAdb: + @pytest.mark.complete("adb ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("adb -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_add_members.py b/test/t/test_add_members.py new file mode 100644 index 0000000..095a5de --- /dev/null +++ b/test/t/test_add_members.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAddMembers: + @pytest.mark.complete("add_members -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_alias.py b/test/t/test_alias.py new file mode 100644 index 0000000..cc592a8 --- /dev/null +++ b/test/t/test_alias.py @@ -0,0 +1,21 @@ +import pytest + + +@pytest.mark.bashcomp( + pre_cmds=("unalias -a", "alias foo=bar", "alias bar='foo foo'"), + post_cmds=("unalias -a",), +) +class TestAlias: + @pytest.mark.complete("alias ") + def test_1(self, completion): + assert completion == "bar foo".split() + + @pytest.mark.xfail # TODO: Would like this completion to work + @pytest.mark.complete("alias foo=") + def test_2(self, completion): + assert completion == "foo='bar'" + assert not completion.endswith(" ") + + @pytest.mark.complete("alias ", trail="foo") + def test_alias_at_point(self, completion): + assert completion == "bar foo".split() diff --git a/test/t/test_alpine.py b/test/t/test_alpine.py new file mode 100644 index 0000000..dcc05d3 --- /dev/null +++ b/test/t/test_alpine.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAlpine: + @pytest.mark.complete("alpine -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_animate.py b/test/t/test_animate.py new file mode 100644 index 0000000..2103606 --- /dev/null +++ b/test/t/test_animate.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAnimate: + @pytest.mark.complete("animate ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ant.py b/test/t/test_ant.py new file mode 100644 index 0000000..94acea1 --- /dev/null +++ b/test/t/test_ant.py @@ -0,0 +1,35 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(ignore_env=r"^\+ANT_ARGS=") +class TestAnt: + @pytest.mark.complete("ant -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ant ", cwd="ant") + def test_2(self, completion): + assert completion == "bashcomp clean init realclean".split() + + @pytest.mark.complete("ant -f build-with-import.xml ", cwd="ant") + def test_3(self, completion): + assert completion == "build-with-import imported-build".split() + + @pytest.mark.complete( + "ant ", cwd="ant", env=dict(ANT_ARGS="'-f named-build.xml'") + ) + def test_4(self, bash, completion): + output = assert_bash_exec(bash, "complete -p ant", want_output=True) + if "complete-ant-cmd.pl" in output: + # Some versions of complete-ant-cmd.pl don't treat ANT_ARGS right; + # in those cases we get the correct completion produced by _ant + # plus whatever complete-ant-cmd.pl was able to get from build.xml + assert "named-build" in completion + else: + assert completion == "named-build" + + @pytest.mark.complete("ant -l ") + def test_5(self, completion): + assert completion diff --git a/test/t/test_apache2ctl.py b/test/t/test_apache2ctl.py new file mode 100644 index 0000000..856a0e4 --- /dev/null +++ b/test/t/test_apache2ctl.py @@ -0,0 +1,7 @@ +import pytest + + +class TestApache2ctl: + @pytest.mark.complete("apache2ctl ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_appdata_validate.py b/test/t/test_appdata_validate.py new file mode 100644 index 0000000..8166cf8 --- /dev/null +++ b/test/t/test_appdata_validate.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="appdata-validate") +class TestAppdataValidate: + @pytest.mark.complete("appdata-validate ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("appdata-validate -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_apt_build.py b/test/t/test_apt_build.py new file mode 100644 index 0000000..8346e11 --- /dev/null +++ b/test/t/test_apt_build.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="apt-build") +class TestAptBuild: + @pytest.mark.complete("apt-build ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_apt_cache.py b/test/t/test_apt_cache.py new file mode 100644 index 0000000..f9329f2 --- /dev/null +++ b/test/t/test_apt_cache.py @@ -0,0 +1,17 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="apt-cache") +class TestAptCache: + @pytest.mark.complete("apt-cache ") + def test_1(self, completion): + assert "search" in completion + + @pytest.mark.complete("apt-cache showsrc [", require_cmd=True) + def test_2(self, completion): + # Doesn't actually fail on grep errors, but takes a long time. + assert not completion + + @pytest.mark.complete("apt-cache ", trail=" add foo") + def test_special_at_point(self, completion): + assert not completion diff --git a/test/t/test_apt_get.py b/test/t/test_apt_get.py new file mode 100644 index 0000000..dc8299a --- /dev/null +++ b/test/t/test_apt_get.py @@ -0,0 +1,16 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="apt-get") +class TestAptGet: + @pytest.mark.complete("apt-get ") + def test_1(self, completion): + assert all(x in completion for x in "install update".split()) + + @pytest.mark.complete("apt-get install ./", cwd="dpkg") + def test_2(self, completion): + assert completion == "bash-completion-test-subject.deb" + + @pytest.mark.complete("apt-get build-dep ") + def test_build_dep_dirs(self, completion): + assert "dpkg/" in completion diff --git a/test/t/test_aptitude.py b/test/t/test_aptitude.py new file mode 100644 index 0000000..29569f1 --- /dev/null +++ b/test/t/test_aptitude.py @@ -0,0 +1,23 @@ +import pytest + + +class TestAptitude: + @pytest.mark.complete("aptitude ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("aptitude -", require_cmd=True) + def test_options(self, completion): + assert completion + + @pytest.mark.complete("aptitude --", require_cmd=True) + def test_long_options(self, completion): + assert completion + + @pytest.mark.complete("aptitude -u -") + def test_no_i_with_u(self, completion): + assert "-i" not in completion + + @pytest.mark.complete("aptitude -i -") + def test_no_u_with_i(self, completion): + assert "-u" not in completion diff --git a/test/t/test_arch.py b/test/t/test_arch.py new file mode 100644 index 0000000..7a0f447 --- /dev/null +++ b/test/t/test_arch.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("PATH=/usr/lib/mailman/bin:$PATH",)) +class TestArch: + @pytest.mark.complete("arch -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_arp.py b/test/t/test_arp.py new file mode 100644 index 0000000..cd038bd --- /dev/null +++ b/test/t/test_arp.py @@ -0,0 +1,13 @@ +import pytest + + +class TestArp: + @pytest.mark.complete( + "arp ", require_cmd=True, skipif='test -z "$(arp 2>/dev/null)"' + ) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("arp -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_arping.py b/test/t/test_arping.py new file mode 100644 index 0000000..0eef5c9 --- /dev/null +++ b/test/t/test_arping.py @@ -0,0 +1,11 @@ +import pytest + + +class TestArping: + @pytest.mark.complete("arping ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("arping -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_arpspoof.py b/test/t/test_arpspoof.py new file mode 100644 index 0000000..74c09a4 --- /dev/null +++ b/test/t/test_arpspoof.py @@ -0,0 +1,12 @@ +import pytest + + +class TestArpspoof: + @pytest.mark.complete( + "arpspoof -", + require_cmd=True, + # May require privileges even for outputting the usage message + skipif="arpspoof 2>&1 | command grep -qF libnet_open_link", + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_asciidoc.py b/test/t/test_asciidoc.py new file mode 100644 index 0000000..b748dcd --- /dev/null +++ b/test/t/test_asciidoc.py @@ -0,0 +1,11 @@ +import pytest + + +class TestAsciidoc: + @pytest.mark.complete("asciidoc ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("asciidoc -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_aspell.py b/test/t/test_aspell.py new file mode 100644 index 0000000..b7a03c4 --- /dev/null +++ b/test/t/test_aspell.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAspell: + @pytest.mark.complete("aspell ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_autoconf.py b/test/t/test_autoconf.py new file mode 100644 index 0000000..9b98b62 --- /dev/null +++ b/test/t/test_autoconf.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAutoconf: + @pytest.mark.complete("autoconf ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_autoheader.py b/test/t/test_autoheader.py new file mode 100644 index 0000000..57ad8af --- /dev/null +++ b/test/t/test_autoheader.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAutoheader: + @pytest.mark.complete("autoheader ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_automake.py b/test/t/test_automake.py new file mode 100644 index 0000000..2174e02 --- /dev/null +++ b/test/t/test_automake.py @@ -0,0 +1,11 @@ +import pytest + + +class TestAutomake: + @pytest.mark.complete("automake ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("automake -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_autoreconf.py b/test/t/test_autoreconf.py new file mode 100644 index 0000000..10e2a2e --- /dev/null +++ b/test/t/test_autoreconf.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAutoreconf: + @pytest.mark.complete("autoreconf ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_autorpm.py b/test/t/test_autorpm.py new file mode 100644 index 0000000..185585e --- /dev/null +++ b/test/t/test_autorpm.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAutorpm: + @pytest.mark.complete("autorpm ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_autoscan.py b/test/t/test_autoscan.py new file mode 100644 index 0000000..d3d45a1 --- /dev/null +++ b/test/t/test_autoscan.py @@ -0,0 +1,11 @@ +import pytest + + +class TestAutoscan: + @pytest.mark.complete("autoscan ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("autoscan -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_autossh.py b/test/t/test_autossh.py new file mode 100644 index 0000000..8640712 --- /dev/null +++ b/test/t/test_autossh.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAutossh: + @pytest.mark.complete("autossh -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_autoupdate.py b/test/t/test_autoupdate.py new file mode 100644 index 0000000..13fd8d4 --- /dev/null +++ b/test/t/test_autoupdate.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAutoupdate: + @pytest.mark.complete("autoupdate ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_avctrl.py b/test/t/test_avctrl.py new file mode 100644 index 0000000..6ff1ec3 --- /dev/null +++ b/test/t/test_avctrl.py @@ -0,0 +1,7 @@ +import pytest + + +class TestAvctrl: + @pytest.mark.complete("avctrl ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_awk.py b/test/t/test_awk.py new file mode 100644 index 0000000..9fd7380 --- /dev/null +++ b/test/t/test_awk.py @@ -0,0 +1,11 @@ +import pytest + + +class TestAwk: + @pytest.mark.complete("awk ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("awk -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_badblocks.py b/test/t/test_badblocks.py new file mode 100644 index 0000000..58130b3 --- /dev/null +++ b/test/t/test_badblocks.py @@ -0,0 +1,12 @@ +import pytest + + +class TestBadblocks: + @pytest.mark.complete("badblocks ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("badblocks -", require_cmd=True) + def test_2(self, completion): + assert completion + assert all(x not in completion for x in "-w -X".split()) diff --git a/test/t/test_base64.py b/test/t/test_base64.py new file mode 100644 index 0000000..957f5a3 --- /dev/null +++ b/test/t/test_base64.py @@ -0,0 +1,11 @@ +import pytest + + +class TestBase64: + @pytest.mark.complete("base64 ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("base64 -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_bash.py b/test/t/test_bash.py new file mode 100644 index 0000000..97a3b8d --- /dev/null +++ b/test/t/test_bash.py @@ -0,0 +1,7 @@ +import pytest + + +class TestBash: + @pytest.mark.complete("bash --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_bc.py b/test/t/test_bc.py new file mode 100644 index 0000000..7f8056e --- /dev/null +++ b/test/t/test_bc.py @@ -0,0 +1,7 @@ +import pytest + + +class TestBc: + @pytest.mark.complete("bc --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_bind.py b/test/t/test_bind.py new file mode 100644 index 0000000..97a5044 --- /dev/null +++ b/test/t/test_bind.py @@ -0,0 +1,11 @@ +import pytest + + +class TestBind: + @pytest.mark.complete("bind -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("bind k") + def test_2(self, completion): + assert completion diff --git a/test/t/test_bison.py b/test/t/test_bison.py new file mode 100644 index 0000000..a4a481a --- /dev/null +++ b/test/t/test_bison.py @@ -0,0 +1,7 @@ +import pytest + + +class TestBison: + @pytest.mark.complete("bison --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_bk.py b/test/t/test_bk.py new file mode 100644 index 0000000..8ab44b6 --- /dev/null +++ b/test/t/test_bk.py @@ -0,0 +1,7 @@ +import pytest + + +class TestBk: + @pytest.mark.complete("bk ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_bmake.py b/test/t/test_bmake.py new file mode 100644 index 0000000..bc885d3 --- /dev/null +++ b/test/t/test_bmake.py @@ -0,0 +1,7 @@ +import pytest + + +class TestBmake: + @pytest.mark.complete("bmake -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_brctl.py b/test/t/test_brctl.py new file mode 100644 index 0000000..7c773e9 --- /dev/null +++ b/test/t/test_brctl.py @@ -0,0 +1,7 @@ +import pytest + + +class TestBrctl: + @pytest.mark.complete("brctl ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_btdownloadcurses_py.py b/test/t/test_btdownloadcurses_py.py new file mode 100644 index 0000000..0b65519 --- /dev/null +++ b/test/t/test_btdownloadcurses_py.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="btdownloadcurses.py") +class TestBtdownloadcursesPy: + @pytest.mark.complete("btdownloadcurses.py ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_btdownloadgui_py.py b/test/t/test_btdownloadgui_py.py new file mode 100644 index 0000000..c1b1b38 --- /dev/null +++ b/test/t/test_btdownloadgui_py.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="btdownloadgui.py") +class TestBtdownloadguiPy: + @pytest.mark.complete("btdownloadgui.py ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_btdownloadheadless_py.py b/test/t/test_btdownloadheadless_py.py new file mode 100644 index 0000000..f84592f --- /dev/null +++ b/test/t/test_btdownloadheadless_py.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="btdownloadheadless.py") +class TestBtdownloadheadlessPy: + @pytest.mark.complete("btdownloadheadless.py ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_bts.py b/test/t/test_bts.py new file mode 100644 index 0000000..53dd62f --- /dev/null +++ b/test/t/test_bts.py @@ -0,0 +1,11 @@ +import pytest + + +class TestBts: + @pytest.mark.complete("bts ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("bts -") + def test_2(self, completion): + assert completion diff --git a/test/t/test_bzip2.py b/test/t/test_bzip2.py new file mode 100644 index 0000000..3b501ea --- /dev/null +++ b/test/t/test_bzip2.py @@ -0,0 +1,15 @@ +import pytest + + +class TestBzip2: + @pytest.mark.complete("bzip2 ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("bzip2 ~") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("bzip2 -") + def test_3(self, completion): + assert completion diff --git a/test/t/test_cal.py b/test/t/test_cal.py new file mode 100644 index 0000000..83d17ff --- /dev/null +++ b/test/t/test_cal.py @@ -0,0 +1,11 @@ +import pytest + + +class TestCal: + @pytest.mark.complete("cal ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("cal -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_cancel.py b/test/t/test_cancel.py new file mode 100644 index 0000000..4aeafd2 --- /dev/null +++ b/test/t/test_cancel.py @@ -0,0 +1,34 @@ +import pytest + +from conftest import assert_bash_exec + + +class TestCancel: + @pytest.fixture(scope="class") + def added_job(self, request, bash): + try: + got = ( + assert_bash_exec( + bash, "lp -H hold shared/default/foo", want_output=True + ) + .strip() + .split() + ) + except AssertionError: + pytest.skip("Could not add test print job") + return + if len(got) > 3: + request.addfinalizer( + lambda: assert_bash_exec(bash, "cancel %s" % got[3]) + ) + + @pytest.mark.complete("cancel ") + def test_1(self, bash, completion, added_job): + got = ( + assert_bash_exec( + bash, "lpstat | awk '{print $1}'", want_output=True + ) + .strip() + .split() + ) + assert completion == sorted(got) diff --git a/test/t/test_cardctl.py b/test/t/test_cardctl.py new file mode 100644 index 0000000..df28b6b --- /dev/null +++ b/test/t/test_cardctl.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCardctl: + @pytest.mark.complete("cardctl ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_carton.py b/test/t/test_carton.py new file mode 100644 index 0000000..1c2e453 --- /dev/null +++ b/test/t/test_carton.py @@ -0,0 +1,11 @@ +import pytest + + +class TestCarton: + @pytest.mark.complete("carton ", require_cmd=True) + def test_commands(self, completion): + assert all(x in completion for x in "help install".split()) + + @pytest.mark.complete("carton install -", require_cmd=True) + def test_install_options(self, completion): + assert all(x in completion for x in "--cached --help".split()) diff --git a/test/t/test_cat.py b/test/t/test_cat.py new file mode 100644 index 0000000..5fa4c8f --- /dev/null +++ b/test/t/test_cat.py @@ -0,0 +1,11 @@ +import pytest + + +class TestCat: + @pytest.mark.complete("cat ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("cat -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_cc.py b/test/t/test_cc.py new file mode 100644 index 0000000..12f6b2b --- /dev/null +++ b/test/t/test_cc.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCc: + @pytest.mark.complete("cc ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ccache.py b/test/t/test_ccache.py new file mode 100644 index 0000000..ef55d0d --- /dev/null +++ b/test/t/test_ccache.py @@ -0,0 +1,27 @@ +import pytest + + +class TestCcache: + @pytest.mark.complete("ccache -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ccache --clea", require_cmd=True) + def test_2(self, completion): + assert all(x in completion for x in "--cleanup --clear".split()) + + @pytest.mark.complete("ccache stt") + def test_3(self, completion): + assert completion == "y" or "stty" in completion + + @pytest.mark.complete("ccache --zero-stats stt") + def test_4(self, completion): + assert completion == "y" or "stty" in completion + + @pytest.mark.complete("ccache --hel", require_cmd=True) + def test_5(self, completion): + assert completion == "p" or "--help" in completion + + @pytest.mark.complete("ccache --zero-stats sh +") + def test_6(self, completion): + assert "+x" in completion diff --git a/test/t/test_ccze.py b/test/t/test_ccze.py new file mode 100644 index 0000000..abf1234 --- /dev/null +++ b/test/t/test_ccze.py @@ -0,0 +1,19 @@ +import pytest + + +class TestCcze: + @pytest.mark.complete("ccze ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ccze -? ") + def test_2(self, completion): + assert not completion + + @pytest.mark.complete("ccze -o ") + def test_3(self, completion): + assert completion + + @pytest.mark.complete("ccze --plugin=", require_cmd=True) + def test_4(self, completion): + assert completion diff --git a/test/t/test_cd.py b/test/t/test_cd.py new file mode 100644 index 0000000..5b7789a --- /dev/null +++ b/test/t/test_cd.py @@ -0,0 +1,26 @@ +import pytest + + +@pytest.mark.bashcomp(ignore_env=r"^\+CDPATH=$") +class TestCd: + @pytest.mark.complete("cd shared/default/") + def test_1(self, completion): + assert completion == ["bar bar.d/", "foo.d/"] + + @pytest.mark.complete("cd fo", env=dict(CDPATH="shared/default")) + def test_2(self, completion): + assert completion == "o.d/" + + @pytest.mark.complete("cd fo") + def test_3(self, completion): + assert not completion + + @pytest.mark.complete( + "cd ", cwd="shared/default/foo.d", env=dict(CDPATH="") + ) + def test_4(self, completion): + assert not completion # No subdirs nor CDPATH + + @pytest.mark.complete("cd shared/default/", trail="foo") + def test_dir_at_point(self, completion): + assert completion == ["bar bar.d/", "foo.d/"] diff --git a/test/t/test_cdrecord.py b/test/t/test_cdrecord.py new file mode 100644 index 0000000..d9d2da1 --- /dev/null +++ b/test/t/test_cdrecord.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCdrecord: + @pytest.mark.complete("cdrecord -d") + def test_1(self, completion): + assert completion diff --git a/test/t/test_cfagent.py b/test/t/test_cfagent.py new file mode 100644 index 0000000..990fc62 --- /dev/null +++ b/test/t/test_cfagent.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCfagent: + @pytest.mark.complete("cfagent -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_cfrun.py b/test/t/test_cfrun.py new file mode 100644 index 0000000..a647d76 --- /dev/null +++ b/test/t/test_cfrun.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCfrun: + @pytest.mark.complete("cfrun -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_chage.py b/test/t/test_chage.py new file mode 100644 index 0000000..3957ae3 --- /dev/null +++ b/test/t/test_chage.py @@ -0,0 +1,11 @@ +import pytest + + +class TestChage: + @pytest.mark.complete("chage ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("chage -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_change_pw.py b/test/t/test_change_pw.py new file mode 100644 index 0000000..69909af --- /dev/null +++ b/test/t/test_change_pw.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("PATH=/usr/lib/mailman/bin:$PATH",)) +class TestChangePw: + @pytest.mark.complete("change_pw -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_check_db.py b/test/t/test_check_db.py new file mode 100644 index 0000000..a9f4844 --- /dev/null +++ b/test/t/test_check_db.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCheckDb: + @pytest.mark.complete("check_db -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_check_perms.py b/test/t/test_check_perms.py new file mode 100644 index 0000000..813ae4c --- /dev/null +++ b/test/t/test_check_perms.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCheckPerms: + @pytest.mark.complete("check_perms -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_checksec.py b/test/t/test_checksec.py new file mode 100644 index 0000000..5a11037 --- /dev/null +++ b/test/t/test_checksec.py @@ -0,0 +1,7 @@ +import pytest + + +class TestChecksec: + @pytest.mark.complete("checksec -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_chfn.py b/test/t/test_chfn.py new file mode 100644 index 0000000..ca719b8 --- /dev/null +++ b/test/t/test_chfn.py @@ -0,0 +1,7 @@ +import pytest + + +class TestChfn: + @pytest.mark.complete("chfn ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_chgrp.py b/test/t/test_chgrp.py new file mode 100644 index 0000000..87a583e --- /dev/null +++ b/test/t/test_chgrp.py @@ -0,0 +1,7 @@ +import pytest + + +class TestChgrp: + @pytest.mark.complete("chgrp ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_chkconfig.py b/test/t/test_chkconfig.py new file mode 100644 index 0000000..08e9827 --- /dev/null +++ b/test/t/test_chkconfig.py @@ -0,0 +1,15 @@ +import pytest + + +class TestChkconfig: + @pytest.mark.complete("chkconfig -") + def test_1(self, completion): + assert completion + + # systemd may not be running e.g. in a docker container, and listing + # services will then fail. + @pytest.mark.complete( + "chkconfig ", xfail="! systemctl list-units &>/dev/null" + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_chmod.py b/test/t/test_chmod.py new file mode 100644 index 0000000..3838b55 --- /dev/null +++ b/test/t/test_chmod.py @@ -0,0 +1,25 @@ +import pytest + + +class TestChmod: + + # No completion here until mode completion is implemented + @pytest.mark.complete("chmod ") + def test_1(self, completion): + assert not completion + + @pytest.mark.complete("chmod 755 ") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("chmod -", require_cmd=True) + def test_3(self, completion): + assert completion + + @pytest.mark.complete("chmod -x ") + def test_4(self, completion): + assert completion + + @pytest.mark.complete("chmod -77 ") + def test_5(self, completion): + assert completion diff --git a/test/t/test_chown.py b/test/t/test_chown.py new file mode 100644 index 0000000..9643f3e --- /dev/null +++ b/test/t/test_chown.py @@ -0,0 +1,82 @@ +import getpass + +import pytest + +from conftest import assert_complete + + +@pytest.mark.bashcomp( + pre_cmds=( + # Fake root command to get all users/groups completed at least for now + "root_command=sudo", + ) +) +class TestChown: + @pytest.mark.xfail( + getpass.getuser() != "root", reason="Only root can chown to all users" + ) + @pytest.mark.complete("chown ") + def test_1(self, bash, completion, output_sort_uniq): + users = output_sort_uniq("compgen -u") + assert completion == users + + @pytest.mark.complete("chown foo: shared/default/") + def test_2(self, completion): + assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"] + + @pytest.mark.complete("chown :foo shared/default/") + def test_3(self, completion): + assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"] + + def test_4(self, bash, part_full_user): + part, full = part_full_user + completion = assert_complete(bash, "chown %s" % part) + assert completion == full[len(part) :] + assert completion.endswith(" ") + + def test_5(self, bash, part_full_user, part_full_group): + _, user = part_full_user + partgroup, fullgroup = part_full_group + completion = assert_complete(bash, "chown %s:%s" % (user, partgroup)) + assert completion == fullgroup[len(partgroup) :] + assert completion.output.endswith(" ") + + def test_6(self, bash, part_full_group): + part, full = part_full_group + completion = assert_complete(bash, "chown dot.user:%s" % part) + assert completion == full[len(part) :] + assert completion.output.endswith(" ") + + @pytest.mark.parametrize( + "prefix", + [ + r"funky\ user:", + "funky.user:", + r"funky\.user:", + r"fu\ nky.user:", + r"f\ o\ o\.\bar:", + r"foo\_b\ a\.r\ :", + ], + ) + def test_7(self, bash, part_full_group, prefix): + """Test preserving special chars in $prefix$partgroup<TAB>.""" + part, full = part_full_group + completion = assert_complete(bash, "chown %s%s" % (prefix, part)) + assert completion == full[len(part) :] + assert completion.output.endswith(" ") + + def test_8(self, bash, part_full_user, part_full_group): + """Test giving up on degenerate cases instead of spewing junk.""" + _, user = part_full_user + partgroup, _ = part_full_group + for x in range(2, 5): + completion = assert_complete( + bash, "chown %s%s:%s" % (user, x * "\\", partgroup) + ) + assert not completion + + def test_9(self, bash, part_full_group): + """Test graceful fail on colon in user/group name.""" + part, _ = part_full_group + completion = assert_complete(bash, "chown foo:bar:%s" % part) + assert not completion diff --git a/test/t/test_chpasswd.py b/test/t/test_chpasswd.py new file mode 100644 index 0000000..ebb292f --- /dev/null +++ b/test/t/test_chpasswd.py @@ -0,0 +1,7 @@ +import pytest + + +class TestChpasswd: + @pytest.mark.complete("chpasswd -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_chromium_browser.py b/test/t/test_chromium_browser.py new file mode 100644 index 0000000..b0b19b2 --- /dev/null +++ b/test/t/test_chromium_browser.py @@ -0,0 +1,25 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="chromium-browser") +class TestChromiumBrowser: + @pytest.mark.complete("chromium-browser ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "chromium-browser -", xfail="! chromium-browser --help &>/dev/null" + ) + def test_2(self, completion): + assert completion + assert not completion.endswith(" ") + + @pytest.mark.complete("chromium-browser --proxy-server=") + def test_proxy_server_scheme(self, completion): + assert completion + assert not completion.endswith(" ") + assert all(x.endswith("://") for x in completion) + + @pytest.mark.complete("chromium-browser --proxy-server=http://") + def test_proxy_server_host(self, completion): + assert completion diff --git a/test/t/test_chronyc.py b/test/t/test_chronyc.py new file mode 100644 index 0000000..1fee246 --- /dev/null +++ b/test/t/test_chronyc.py @@ -0,0 +1,11 @@ +import pytest + + +class TestChronyc: + @pytest.mark.complete("chronyc ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("chronyc -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_chroot.py b/test/t/test_chroot.py new file mode 100644 index 0000000..08ace86 --- /dev/null +++ b/test/t/test_chroot.py @@ -0,0 +1,16 @@ +import pytest + + +class TestChroot: + @pytest.mark.complete("chroot ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("/bin/chroot shared/default/") + def test_2(self, completion): + """Should complete dirs only, also when invoked using full path.""" + assert completion == ["bar bar.d/", "foo.d/"] + + @pytest.mark.complete("chroot -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_chrpath.py b/test/t/test_chrpath.py new file mode 100644 index 0000000..8e94dcb --- /dev/null +++ b/test/t/test_chrpath.py @@ -0,0 +1,11 @@ +import pytest + + +class TestChrpath: + @pytest.mark.complete("chrpath ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("chrpath -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_chsh.py b/test/t/test_chsh.py new file mode 100644 index 0000000..fe1c7f6 --- /dev/null +++ b/test/t/test_chsh.py @@ -0,0 +1,15 @@ +import pytest + + +class TestChsh: + @pytest.mark.complete("chsh ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("chsh -s ") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("chsh -", require_cmd=True) + def test_3(self, completion): + assert completion diff --git a/test/t/test_ci.py b/test/t/test_ci.py new file mode 100644 index 0000000..f941b2c --- /dev/null +++ b/test/t/test_ci.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCi: + @pytest.mark.complete("ci ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ciptool.py b/test/t/test_ciptool.py new file mode 100644 index 0000000..0ff5444 --- /dev/null +++ b/test/t/test_ciptool.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCiptool: + @pytest.mark.complete("ciptool ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_civclient.py b/test/t/test_civclient.py new file mode 100644 index 0000000..bf0c8d8 --- /dev/null +++ b/test/t/test_civclient.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCivclient: + @pytest.mark.complete("civclient -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_civserver.py b/test/t/test_civserver.py new file mode 100644 index 0000000..0b8e5d5 --- /dev/null +++ b/test/t/test_civserver.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCivserver: + @pytest.mark.complete("civserver -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_cksfv.py b/test/t/test_cksfv.py new file mode 100644 index 0000000..b365659 --- /dev/null +++ b/test/t/test_cksfv.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCksfv: + @pytest.mark.complete("cksfv -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_cleanarch.py b/test/t/test_cleanarch.py new file mode 100644 index 0000000..95b268e --- /dev/null +++ b/test/t/test_cleanarch.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("PATH=/usr/lib/mailman/bin:$PATH",)) +class TestCleanarch: + @pytest.mark.complete("cleanarch -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_clisp.py b/test/t/test_clisp.py new file mode 100644 index 0000000..3fcb259 --- /dev/null +++ b/test/t/test_clisp.py @@ -0,0 +1,7 @@ +import pytest + + +class TestClisp: + @pytest.mark.complete("clisp ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_clone_member.py b/test/t/test_clone_member.py new file mode 100644 index 0000000..8f54298 --- /dev/null +++ b/test/t/test_clone_member.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCloneMember: + @pytest.mark.complete("clone_member -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_co.py b/test/t/test_co.py new file mode 100644 index 0000000..0404b45 --- /dev/null +++ b/test/t/test_co.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCo: + @pytest.mark.complete("co ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_colordiff.py b/test/t/test_colordiff.py new file mode 100644 index 0000000..f0e0a29 --- /dev/null +++ b/test/t/test_colordiff.py @@ -0,0 +1,11 @@ +import pytest + + +class TestColordiff: + @pytest.mark.complete("colordiff ") + def test_basic(self, completion): + assert completion + + @pytest.mark.complete("colordiff -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_compare.py b/test/t/test_compare.py new file mode 100644 index 0000000..172c8da --- /dev/null +++ b/test/t/test_compare.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCompare: + @pytest.mark.complete("compare ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_compgen.py b/test/t/test_compgen.py new file mode 100644 index 0000000..893abdf --- /dev/null +++ b/test/t/test_compgen.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCompgen: + @pytest.mark.complete(r"compgen -f a\'b/", cwd="compgen") + def test_1(self, completion): + assert not completion diff --git a/test/t/test_complete.py b/test/t/test_complete.py new file mode 100644 index 0000000..7ff56b4 --- /dev/null +++ b/test/t/test_complete.py @@ -0,0 +1,11 @@ +import pytest + + +class TestComplete: + @pytest.mark.complete("complete -") + def test_1(self, completion): + assert completion + + @pytest.mark.complete(r"\complete -") + def test_2(self, completion): + assert completion diff --git a/test/t/test_composite.py b/test/t/test_composite.py new file mode 100644 index 0000000..58f4e39 --- /dev/null +++ b/test/t/test_composite.py @@ -0,0 +1,7 @@ +import pytest + + +class TestComposite: + @pytest.mark.complete("composite ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_config_list.py b/test/t/test_config_list.py new file mode 100644 index 0000000..d17fadc --- /dev/null +++ b/test/t/test_config_list.py @@ -0,0 +1,7 @@ +import pytest + + +class TestConfigList: + @pytest.mark.complete("config_list -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_configure.py b/test/t/test_configure.py new file mode 100644 index 0000000..0fc6117 --- /dev/null +++ b/test/t/test_configure.py @@ -0,0 +1,17 @@ +import pytest + + +@pytest.mark.bashcomp( + pre_cmds=( + # Make sure our own ./configure is in PATH + "PATH=$PWD/../..:$PATH", + ) +) +class TestConfigure: + @pytest.mark.complete("configure --", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("configure --prefix ") + def test_2(self, completion): + assert completion diff --git a/test/t/test_conjure.py b/test/t/test_conjure.py new file mode 100644 index 0000000..3dcc0db --- /dev/null +++ b/test/t/test_conjure.py @@ -0,0 +1,7 @@ +import pytest + + +class TestConjure: + @pytest.mark.complete("conjure ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_convert.py b/test/t/test_convert.py new file mode 100644 index 0000000..c903ea0 --- /dev/null +++ b/test/t/test_convert.py @@ -0,0 +1,15 @@ +import pytest + + +class TestConvert: + @pytest.mark.complete("convert ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("convert -format ") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("convert -", require_cmd=True) + def test_3(self, completion): + assert completion diff --git a/test/t/test_cowsay.py b/test/t/test_cowsay.py new file mode 100644 index 0000000..2920d9e --- /dev/null +++ b/test/t/test_cowsay.py @@ -0,0 +1,7 @@ +import pytest + + +class TestCowsay: + @pytest.mark.complete("cowsay ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_cp.py b/test/t/test_cp.py new file mode 100644 index 0000000..7634df7 --- /dev/null +++ b/test/t/test_cp.py @@ -0,0 +1,11 @@ +import pytest + + +class TestCp: + @pytest.mark.complete("cp ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("cp -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_cpan2dist.py b/test/t/test_cpan2dist.py new file mode 100644 index 0000000..1ab5de1 --- /dev/null +++ b/test/t/test_cpan2dist.py @@ -0,0 +1,9 @@ +import pytest + + +class TestCpan2dist: + @pytest.mark.complete( + "cpan2dist -", require_cmd=True, require_longopt=True + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_cpio.py b/test/t/test_cpio.py new file mode 100644 index 0000000..0b73966 --- /dev/null +++ b/test/t/test_cpio.py @@ -0,0 +1,12 @@ +import pytest + + +class TestCpio: + @pytest.mark.complete("cpio --") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("cpio -R ") + def test_2(self, bash, completion, output_sort_uniq): + users = output_sort_uniq("compgen -u") + assert completion == users diff --git a/test/t/test_cplusplus.py b/test/t/test_cplusplus.py new file mode 100644 index 0000000..a2dd3ed --- /dev/null +++ b/test/t/test_cplusplus.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="c++") +class TestCPlusPlus: + @pytest.mark.complete("c++ ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_cppcheck.py b/test/t/test_cppcheck.py new file mode 100644 index 0000000..73e64f5 --- /dev/null +++ b/test/t/test_cppcheck.py @@ -0,0 +1,31 @@ +import pytest + + +class TestCppcheck: + @pytest.mark.complete("cppcheck ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("cppcheck -", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("cppcheck -DFOO=BAR ") + def test_3(self, completion): + assert completion + + @pytest.mark.complete("cppcheck -D ") + def test_4(self, completion): + assert not completion + + @pytest.mark.complete("cppcheck --enable=al") + def test_5(self, completion): + assert completion == "l" + + @pytest.mark.complete("cppcheck --enable=xx,styl") + def test_6(self, completion): + assert completion == "e" + + @pytest.mark.complete("cppcheck --enable=xx,yy,styl") + def test_7(self, completion): + assert completion == "e" diff --git a/test/t/test_createdb.py b/test/t/test_createdb.py new file mode 100644 index 0000000..030338a --- /dev/null +++ b/test/t/test_createdb.py @@ -0,0 +1,11 @@ +import pytest + + +class TestCreatedb: + + # --help can fail due to missing package dependencies, e.g. on Ubuntu 14 + @pytest.mark.complete( + "createdb -", require_cmd=True, xfail="! createdb --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_createuser.py b/test/t/test_createuser.py new file mode 100644 index 0000000..ea8d0e3 --- /dev/null +++ b/test/t/test_createuser.py @@ -0,0 +1,11 @@ +import pytest + + +class TestCreateuser: + + # --help can fail due to missing package dependencies, e.g. on Ubuntu 14 + @pytest.mark.complete( + "createuser -", xfail="! createuser --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_crontab.py b/test/t/test_crontab.py new file mode 100644 index 0000000..a476694 --- /dev/null +++ b/test/t/test_crontab.py @@ -0,0 +1,16 @@ +import pytest + + +class TestCrontab: + @pytest.mark.complete("crontab ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("crontab -l -") + def test_only_u_with_l(self, completion): + assert completion == "u" + + @pytest.mark.complete("crontab -r -") + def test_no_l_with_r(self, completion): + assert completion + assert "-l" not in completion diff --git a/test/t/test_cryptsetup.py b/test/t/test_cryptsetup.py new file mode 100644 index 0000000..fdc981b --- /dev/null +++ b/test/t/test_cryptsetup.py @@ -0,0 +1,11 @@ +import pytest + + +class TestCryptsetup: + @pytest.mark.complete("cryptsetup ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("cryptsetup -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_csplit.py b/test/t/test_csplit.py new file mode 100644 index 0000000..609c7e5 --- /dev/null +++ b/test/t/test_csplit.py @@ -0,0 +1,11 @@ +import pytest + + +class TestCsplit: + @pytest.mark.complete("csplit ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("csplit -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_curl.py b/test/t/test_curl.py new file mode 100644 index 0000000..63e969f --- /dev/null +++ b/test/t/test_curl.py @@ -0,0 +1,28 @@ +import pytest + + +class TestCurl: + @pytest.mark.complete("curl --h", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("curl -o f", cwd="shared/default/foo.d") + def test_2(self, completion): + assert completion == "oo" + + @pytest.mark.complete("curl -LRo f", cwd="shared/default/foo.d") + def test_3(self, completion): + assert completion == "oo" + + @pytest.mark.complete("curl --o f") + def test_4(self, completion): + assert not completion + + @pytest.mark.complete("curl --data @", cwd="shared/default/foo.d") + def test_data_atfile(self, completion): + assert completion == "foo" + + @pytest.mark.complete("curl --data @foo.", cwd="shared/default") + def test_data_atfile_dir(self, completion): + assert completion == "d/" + assert not completion.endswith(" ") diff --git a/test/t/test_cut.py b/test/t/test_cut.py new file mode 100644 index 0000000..b0faca6 --- /dev/null +++ b/test/t/test_cut.py @@ -0,0 +1,11 @@ +import pytest + + +class TestCut: + @pytest.mark.complete("cut ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("cut -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_cvs.py b/test/t/test_cvs.py new file mode 100644 index 0000000..97361e9 --- /dev/null +++ b/test/t/test_cvs.py @@ -0,0 +1,20 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("HOME=$PWD/cvs",)) +class TestCvs: + @pytest.mark.complete("cvs ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("cvs -d ") + def test_2(self, completion): + assert [x for x in completion if ":pserver:" in x] + + @pytest.mark.complete("cvs diff foo/", cwd="cvs") + def test_3(self, completion): + assert completion == "bar" + + @pytest.mark.complete("cvs -", require_cmd=True) + def test_4(self, completion): + assert completion diff --git a/test/t/test_cvsps.py b/test/t/test_cvsps.py new file mode 100644 index 0000000..4039893 --- /dev/null +++ b/test/t/test_cvsps.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("HOME=$PWD/cvs",)) +class TestCvsps: + @pytest.mark.complete("cvsps -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("cvsps ") + def test_2(self, completion): + assert [x for x in completion if ":pserver:" in x] diff --git a/test/t/test_date.py b/test/t/test_date.py new file mode 100644 index 0000000..57d61b8 --- /dev/null +++ b/test/t/test_date.py @@ -0,0 +1,11 @@ +import pytest + + +class TestDate: + @pytest.mark.complete("date ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("date -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_dcop.py b/test/t/test_dcop.py new file mode 100644 index 0000000..5c3c04d --- /dev/null +++ b/test/t/test_dcop.py @@ -0,0 +1,7 @@ +import pytest + + +class TestDcop: + @pytest.mark.complete("dcop ", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_dd.py b/test/t/test_dd.py new file mode 100644 index 0000000..e082faa --- /dev/null +++ b/test/t/test_dd.py @@ -0,0 +1,17 @@ +import pytest + + +class TestDd: + @pytest.mark.complete( + "dd --", + xfail=( + "! dd --help &>/dev/null || " + "! dd --help 2>&1 | command grep -qF -- --help" + ), + ) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("dd bs") + def test_2(self, completion): + assert completion == "=" diff --git a/test/t/test_declare.py b/test/t/test_declare.py new file mode 100644 index 0000000..a61d926 --- /dev/null +++ b/test/t/test_declare.py @@ -0,0 +1,20 @@ +import pytest + + +class TestDeclare: + @pytest.mark.complete("declare -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("declare +", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("declare -p BASH_ARG") + def test_3(self, completion): + # bash 5.0 has BASH_ARGV0 too + assert all(x in completion for x in "BASH_ARGC BASH_ARGV".split()) + + @pytest.mark.complete("declare -f _parse_") + def test_4(self, completion): + assert "_parse_help" in completion diff --git a/test/t/test_deja_dup.py b/test/t/test_deja_dup.py new file mode 100644 index 0000000..56e59f9 --- /dev/null +++ b/test/t/test_deja_dup.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="deja-dup") +class TestDejaDup: + @pytest.mark.complete("deja-dup -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("deja-dup --help ") + def test_2(self, completion): + assert not completion diff --git a/test/t/test_desktop_file_validate.py b/test/t/test_desktop_file_validate.py new file mode 100644 index 0000000..ed4b55b --- /dev/null +++ b/test/t/test_desktop_file_validate.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="desktop-file-validate") +class TestDesktopFileValidate: + @pytest.mark.complete("desktop-file-validate ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("desktop-file-validate -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_df.py b/test/t/test_df.py new file mode 100644 index 0000000..be28e6c --- /dev/null +++ b/test/t/test_df.py @@ -0,0 +1,11 @@ +import pytest + + +class TestDf: + @pytest.mark.complete("df ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("df -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_dfutool.py b/test/t/test_dfutool.py new file mode 100644 index 0000000..7b450bd --- /dev/null +++ b/test/t/test_dfutool.py @@ -0,0 +1,7 @@ +import pytest + + +class TestDfutool: + @pytest.mark.complete("dfutool ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_dhclient.py b/test/t/test_dhclient.py new file mode 100644 index 0000000..c6a1af4 --- /dev/null +++ b/test/t/test_dhclient.py @@ -0,0 +1,7 @@ +import pytest + + +class TestDhclient: + @pytest.mark.complete("dhclient -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_dict.py b/test/t/test_dict.py new file mode 100644 index 0000000..99c4a21 --- /dev/null +++ b/test/t/test_dict.py @@ -0,0 +1,7 @@ +import pytest + + +class TestDict: + @pytest.mark.complete("dict -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_diff.py b/test/t/test_diff.py new file mode 100644 index 0000000..eb81506 --- /dev/null +++ b/test/t/test_diff.py @@ -0,0 +1,7 @@ +import pytest + + +class TestDiff: + @pytest.mark.complete("diff --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_dir.py b/test/t/test_dir.py new file mode 100644 index 0000000..f8568fb --- /dev/null +++ b/test/t/test_dir.py @@ -0,0 +1,11 @@ +import pytest + + +class TestDir: + @pytest.mark.complete("dir ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("dir -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_display.py b/test/t/test_display.py new file mode 100644 index 0000000..4f076b8 --- /dev/null +++ b/test/t/test_display.py @@ -0,0 +1,11 @@ +import pytest + + +class TestDisplay: + @pytest.mark.complete("display ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("display -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_dmesg.py b/test/t/test_dmesg.py new file mode 100644 index 0000000..a081fb6 --- /dev/null +++ b/test/t/test_dmesg.py @@ -0,0 +1,7 @@ +import pytest + + +class TestDmesg: + @pytest.mark.complete("dmesg -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_dmypy.py b/test/t/test_dmypy.py new file mode 100644 index 0000000..4c031dd --- /dev/null +++ b/test/t/test_dmypy.py @@ -0,0 +1,14 @@ +import pytest + + +class TestDmypy: + @pytest.mark.complete( + "dmypy ", require_cmd=True, xfail="! dmypy --help &>/dev/null" + ) + def test_commands(self, completion): + assert "help" in completion + assert not any("," in x for x in completion) + + @pytest.mark.complete("dmypy -", require_cmd=True, require_longopt=True) + def test_options(self, completion): + assert "--help" in completion diff --git a/test/t/test_dnssec_keygen.py b/test/t/test_dnssec_keygen.py new file mode 100644 index 0000000..f8bd6fb --- /dev/null +++ b/test/t/test_dnssec_keygen.py @@ -0,0 +1,80 @@ +import pytest + + +@pytest.mark.bashcomp( + cmd="dnssec-keygen", pre_cmds=("PATH=$PATH:$PWD/dnssec-keygen",) +) +class TestDnssecKeygen: + @pytest.mark.complete("dnssec-keygen -") + def test_1(self, completion): + assert completion + assert not any(x.endswith(":") for x in completion) + + @pytest.mark.complete("dnssec-keygen -a ") + def test_2(self, completion): + assert completion + assert any(x in completion for x in ("HMAC-MD5", "RSASHA1", "ED25519")) + assert "|" not in completion + assert not any(x.startswith("-") for x in completion) + + @pytest.mark.complete("dnssec-keygen -n ") + def test_3(self, completion): + assert completion + assert "HOST" in completion + assert "|" not in completion + assert not any(x.startswith("-") for x in completion) + + @pytest.mark.complete("dnssec-keygen -f ") + def test_4(self, completion): + assert completion + assert "|" not in completion + assert not any(x.startswith("-") for x in completion) + + @pytest.mark.complete("dnssec-keygen ") + def test_5(self, completion): + assert not completion + + @pytest.mark.complete( + "dnssec-keygen -a ", env=dict(PATH="$PWD/dnssec-keygen:$PATH") + ) + def test_6(self, completion): + assert completion == sorted( + "RSA RSAMD5 DSA RSASHA1 NSEC3RSASHA1 NSEC3DSA " + "RSASHA256 RSASHA512 ECCGOST " + "ECDSAP256SHA256 ECDSAP384SHA384 " + "ED25519 ED448 DH " + "HMAC-MD5 HMAC-SHA1 HMAC-SHA224 HMAC-SHA256 " + "HMAC-SHA384 HMAC-SHA512".split() + ) + + @pytest.mark.complete( + "dnssec-keygen -n ", env=dict(PATH="$PWD/dnssec-keygen:$PATH") + ) + def test_7(self, completion): + assert completion == sorted("ZONE HOST ENTITY USER OTHER".split()) + + @pytest.mark.complete( + "dnssec-keygen -f ", env=dict(PATH="$PWD/dnssec-keygen:$PATH") + ) + def test_8(self, completion): + assert completion == sorted("KSK REVOKE".split()) + + @pytest.mark.complete( + "dnssec-keygen -T ", env=dict(PATH="$PWD/dnssec-keygen:$PATH") + ) + def test_9(self, completion): + assert completion == sorted("DNSKEY KEY".split()) + + @pytest.mark.complete( + "dnssec-keygen -t ", env=dict(PATH="$PWD/dnssec-keygen:$PATH") + ) + def test_10(self, completion): + assert completion == sorted( + "AUTHCONF NOAUTHCONF NOAUTH NOCONF".split() + ) + + @pytest.mark.complete( + "dnssec-keygen -m ", env=dict(PATH="$PWD/dnssec-keygen:$PATH") + ) + def test_11(self, completion): + assert completion == sorted("usage trace record size mctx".split()) diff --git a/test/t/test_dnsspoof.py b/test/t/test_dnsspoof.py new file mode 100644 index 0000000..b3380d1 --- /dev/null +++ b/test/t/test_dnsspoof.py @@ -0,0 +1,7 @@ +import pytest + + +class TestDnsspoof: + @pytest.mark.complete("dnsspoof -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_dot.py b/test/t/test_dot.py new file mode 100644 index 0000000..a4aa674 --- /dev/null +++ b/test/t/test_dot.py @@ -0,0 +1,7 @@ +import pytest + + +class TestDot: + @pytest.mark.complete("dot ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_dpkg.py b/test/t/test_dpkg.py new file mode 100644 index 0000000..eb1228b --- /dev/null +++ b/test/t/test_dpkg.py @@ -0,0 +1,15 @@ +import pytest + + +class TestDpkg: + @pytest.mark.complete("dpkg --c", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("dpkg -L ", xfail='test -z "$(dpkg -l 2>/dev/null)"') + def test_2(self, completion): + assert completion + + @pytest.mark.complete("dpkg -i ~") + def test_3(self, completion): + assert completion diff --git a/test/t/test_dpkg_deb.py b/test/t/test_dpkg_deb.py new file mode 100644 index 0000000..9be85eb --- /dev/null +++ b/test/t/test_dpkg_deb.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="dpkg-deb") +class TestDpkgDeb: + @pytest.mark.complete("dpkg-deb --c", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("dpkg-deb --show b", cwd="dpkg") + def test_show(self, completion): + assert completion == "ash-completion-test-subject.deb" diff --git a/test/t/test_dpkg_query.py b/test/t/test_dpkg_query.py new file mode 100644 index 0000000..37c5621 --- /dev/null +++ b/test/t/test_dpkg_query.py @@ -0,0 +1,18 @@ +import os.path + +import pytest + + +@pytest.mark.bashcomp(cmd="dpkg-query",) +class TestDpkgQuery: + @pytest.mark.complete("dpkg-query --", require_cmd=True) + def test_options(self, completion): + assert completion + + @pytest.mark.xfail( + not os.path.exists("/etc/debian_version"), + reason="Likely fails on systems not based on Debian", + ) + @pytest.mark.complete("dpkg-query -W dpk", require_cmd=True) + def test_show(self, completion): + assert "dpkg" in completion diff --git a/test/t/test_dpkg_reconfigure.py b/test/t/test_dpkg_reconfigure.py new file mode 100644 index 0000000..46347b3 --- /dev/null +++ b/test/t/test_dpkg_reconfigure.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="dpkg-reconfigure") +class TestDpkgReconfigure: + @pytest.mark.complete("dpkg-reconfigure --") + def test_1(self, completion): + assert completion diff --git a/test/t/test_dpkg_source.py b/test/t/test_dpkg_source.py new file mode 100644 index 0000000..f2d5f19 --- /dev/null +++ b/test/t/test_dpkg_source.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="dpkg-source") +class TestDpkgSource: + @pytest.mark.complete("dpkg-source -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_dropdb.py b/test/t/test_dropdb.py new file mode 100644 index 0000000..2f65857 --- /dev/null +++ b/test/t/test_dropdb.py @@ -0,0 +1,11 @@ +import pytest + + +class TestDropdb: + + # --help can fail due to missing package dependencies, e.g. on Ubuntu 14 + @pytest.mark.complete( + "dropdb -", require_cmd=True, xfail="! dropdb --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_dropuser.py b/test/t/test_dropuser.py new file mode 100644 index 0000000..83a99d9 --- /dev/null +++ b/test/t/test_dropuser.py @@ -0,0 +1,7 @@ +import pytest + + +class TestDropuser: + @pytest.mark.complete("dropuser ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_dselect.py b/test/t/test_dselect.py new file mode 100644 index 0000000..8e9d24e --- /dev/null +++ b/test/t/test_dselect.py @@ -0,0 +1,11 @@ +import pytest + + +class TestDselect: + @pytest.mark.complete("dselect ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("dselect -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_dsniff.py b/test/t/test_dsniff.py new file mode 100644 index 0000000..978c436 --- /dev/null +++ b/test/t/test_dsniff.py @@ -0,0 +1,7 @@ +import pytest + + +class TestDsniff: + @pytest.mark.complete("dsniff -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_du.py b/test/t/test_du.py new file mode 100644 index 0000000..3d73e99 --- /dev/null +++ b/test/t/test_du.py @@ -0,0 +1,11 @@ +import pytest + + +class TestDu: + @pytest.mark.complete("du ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("du -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_dumpdb.py b/test/t/test_dumpdb.py new file mode 100644 index 0000000..5077682 --- /dev/null +++ b/test/t/test_dumpdb.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("PATH=/usr/lib/mailman/bin:$PATH",)) +class TestDumpdb: + @pytest.mark.complete("dumpdb ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_dumpe2fs.py b/test/t/test_dumpe2fs.py new file mode 100644 index 0000000..eacb1fe --- /dev/null +++ b/test/t/test_dumpe2fs.py @@ -0,0 +1,11 @@ +import pytest + + +class TestDumpe2fs: + @pytest.mark.complete("dumpe2fs ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("dumpe2fs -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_e2freefrag.py b/test/t/test_e2freefrag.py new file mode 100644 index 0000000..10eb41d --- /dev/null +++ b/test/t/test_e2freefrag.py @@ -0,0 +1,11 @@ +import pytest + + +class TestE2freefrag: + @pytest.mark.complete("e2freefrag ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("e2freefrag -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_e2label.py b/test/t/test_e2label.py new file mode 100644 index 0000000..ca436a6 --- /dev/null +++ b/test/t/test_e2label.py @@ -0,0 +1,7 @@ +import pytest + + +class TestE2label: + @pytest.mark.complete("e2label ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ebtables.py b/test/t/test_ebtables.py new file mode 100644 index 0000000..bcca3cb --- /dev/null +++ b/test/t/test_ebtables.py @@ -0,0 +1,7 @@ +import pytest + + +class TestEbtables: + @pytest.mark.complete("ebtables -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ecryptfs_migrate_home.py b/test/t/test_ecryptfs_migrate_home.py new file mode 100644 index 0000000..f2115d2 --- /dev/null +++ b/test/t/test_ecryptfs_migrate_home.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="ecryptfs-migrate-home") +class TestEcryptfsMigrateHome: + @pytest.mark.complete("ecryptfs-migrate-home ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ecryptfs-migrate-home -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_eject.py b/test/t/test_eject.py new file mode 100644 index 0000000..d4ec1bd --- /dev/null +++ b/test/t/test_eject.py @@ -0,0 +1,7 @@ +import pytest + + +class TestEject: + @pytest.mark.complete("eject -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_enscript.py b/test/t/test_enscript.py new file mode 100644 index 0000000..97120e3 --- /dev/null +++ b/test/t/test_enscript.py @@ -0,0 +1,7 @@ +import pytest + + +class TestEnscript: + @pytest.mark.complete("enscript --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_env.py b/test/t/test_env.py new file mode 100644 index 0000000..3d1a684 --- /dev/null +++ b/test/t/test_env.py @@ -0,0 +1,7 @@ +import pytest + + +class TestEnv: + @pytest.mark.complete("env --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_eog.py b/test/t/test_eog.py new file mode 100644 index 0000000..5ae21d9 --- /dev/null +++ b/test/t/test_eog.py @@ -0,0 +1,11 @@ +import pytest + + +class TestEog: + @pytest.mark.complete("eog ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("eog -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_ether_wake.py b/test/t/test_ether_wake.py new file mode 100644 index 0000000..7afe286 --- /dev/null +++ b/test/t/test_ether_wake.py @@ -0,0 +1,18 @@ +import os + +import pytest + + +@pytest.mark.bashcomp(cmd="ether-wake") +class TestEtherWake: + @pytest.mark.xfail( + os.environ.get("NETWORK") == "none", + reason="MAC addresses may be N/A with no networking configured", + ) + @pytest.mark.complete("ether-wake ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ether-wake -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_etherwake.py b/test/t/test_etherwake.py new file mode 100644 index 0000000..b444b43 --- /dev/null +++ b/test/t/test_etherwake.py @@ -0,0 +1,7 @@ +import pytest + + +class TestEtherwake: + @pytest.mark.complete("etherwake -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_evince.py b/test/t/test_evince.py new file mode 100644 index 0000000..9e9245d --- /dev/null +++ b/test/t/test_evince.py @@ -0,0 +1,22 @@ +import pytest + + +class TestEvince: + @pytest.mark.complete("evince ", cwd="evince") + def test_1(self, completion): + # .txt should not be here + assert completion == sorted( + "foo/ .bmp .BMP .cbr .CBR .cbz .CBZ .djv .DJV .djvu .DJVU .dvi " + ".DVI .dvi.bz2 .dvi.BZ2 .DVI.bz2 .DVI.BZ2 .dvi.gz .dvi.GZ " + ".DVI.gz .DVI.GZ .eps .EPS .eps.bz2 .eps.BZ2 .EPS.bz2 .EPS.BZ2 " + ".eps.gz .eps.GZ .EPS.gz .EPS.GZ .gif .GIF .ico .ICO .jpeg " + ".JPEG .jpg .JPG .miff .MIFF .pbm .PBM .pcx .PCX .pdf .PDF " + ".pdf.bz2 .pdf.BZ2 .PDF.bz2 .PDF.BZ2 .pdf.gz .pdf.GZ .PDF.gz " + ".PDF.GZ .pgm .PGM .png .PNG .pnm .PNM .ppm .PPM .ps .PS " + ".ps.bz2 .ps.BZ2 .PS.bz2 .PS.BZ2 .ps.gz .ps.GZ .PS.gz .PS.GZ " + ".tga .TGA .tif .TIF .tiff .TIFF .xpm .XPM .xwd .XWD".split() + ) + + @pytest.mark.complete("evince -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_expand.py b/test/t/test_expand.py new file mode 100644 index 0000000..11f4bdb --- /dev/null +++ b/test/t/test_expand.py @@ -0,0 +1,7 @@ +import pytest + + +class TestExpand: + @pytest.mark.complete("expand --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_explodepkg.py b/test/t/test_explodepkg.py new file mode 100644 index 0000000..940fec8 --- /dev/null +++ b/test/t/test_explodepkg.py @@ -0,0 +1,23 @@ +import fnmatch +import os + +import pytest + + +class TestExplodepkg: + @pytest.mark.complete("explodepkg ", cwd="slackware/home") + def test_1(self, completion): + expected = sorted( + [ + "%s/" % x + for x in os.listdir("slackware/home") + if os.path.isdir("./slackware/home/%s" % x) + ] + + [ + x + for x in os.listdir("slackware/home") + if os.path.isfile("./slackware/home/%s" % x) + and fnmatch.fnmatch(x, "*.t[bglx]z") + ] + ) + assert completion == expected diff --git a/test/t/test_export.py b/test/t/test_export.py new file mode 100644 index 0000000..8738913 --- /dev/null +++ b/test/t/test_export.py @@ -0,0 +1,36 @@ +import pytest + + +class TestExport: + @pytest.mark.complete("export BASH") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("export -n BASH") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("export -p ") + def test_3(self, completion): + assert not completion + + @pytest.mark.complete("export FOO=", cwd="shared/default") + def test_4(self, completion): + assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"] + + @pytest.mark.complete("export FOO=f", cwd="shared/default") + def test_5(self, completion): + assert completion == ["foo", "foo.d/"] + + @pytest.mark.complete("export -fn _ex") + def test_6(self, completion): + assert "_expand" in completion + assert "_export" in completion + + @pytest.mark.complete(r"export FOO=$BASH") + def test_7(self, completion): + assert completion + + @pytest.mark.complete("export -", require_cmd=True) + def test_8(self, completion): + assert completion diff --git a/test/t/test_faillog.py b/test/t/test_faillog.py new file mode 100644 index 0000000..edf490b --- /dev/null +++ b/test/t/test_faillog.py @@ -0,0 +1,7 @@ +import pytest + + +class TestFaillog: + @pytest.mark.complete("faillog -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_fbgs.py b/test/t/test_fbgs.py new file mode 100644 index 0000000..53ff741 --- /dev/null +++ b/test/t/test_fbgs.py @@ -0,0 +1,7 @@ +import pytest + + +class TestFbgs: + @pytest.mark.complete("fbgs ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_fbi.py b/test/t/test_fbi.py new file mode 100644 index 0000000..e27fef5 --- /dev/null +++ b/test/t/test_fbi.py @@ -0,0 +1,7 @@ +import pytest + + +class TestFbi: + @pytest.mark.complete("fbi ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_feh.py b/test/t/test_feh.py new file mode 100644 index 0000000..f2d5317 --- /dev/null +++ b/test/t/test_feh.py @@ -0,0 +1,31 @@ +import pytest + + +class TestFeh: + @pytest.mark.complete("feh ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "feh --lis", + xfail="feh --help 2>&1 | command grep -qF 'man feh'", + require_cmd=True, + ) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("feh -S pix") + def test_3(self, completion): + assert completion == "els" + + @pytest.mark.complete("feh --zoom ma") + def test_4(self, completion): + assert completion == "x" + + @pytest.mark.complete("feh -g 640") + def test_5(self, completion): + assert completion == "0 1 2 3 4 5 6 7 8 9 x".split() + + @pytest.mark.complete("feh -g 640x48") + def test_6(self, completion): + assert completion == "0 1 2 3 4 5 6 7 8 9".split() diff --git a/test/t/test_file.py b/test/t/test_file.py new file mode 100644 index 0000000..0c19eb4 --- /dev/null +++ b/test/t/test_file.py @@ -0,0 +1,11 @@ +import pytest + + +class TestFile: + @pytest.mark.complete("file ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("file -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_file_roller.py b/test/t/test_file_roller.py new file mode 100644 index 0000000..80a1bbc --- /dev/null +++ b/test/t/test_file_roller.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="file-roller") +class TestFileRoller: + @pytest.mark.complete("file-roller ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_filefrag.py b/test/t/test_filefrag.py new file mode 100644 index 0000000..342e89c --- /dev/null +++ b/test/t/test_filefrag.py @@ -0,0 +1,11 @@ +import pytest + + +class TestFilefrag: + @pytest.mark.complete("filefrag ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("filefrag -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_filesnarf.py b/test/t/test_filesnarf.py new file mode 100644 index 0000000..cee621e --- /dev/null +++ b/test/t/test_filesnarf.py @@ -0,0 +1,7 @@ +import pytest + + +class TestFilesnarf: + @pytest.mark.complete("filesnarf -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_find.py b/test/t/test_find.py new file mode 100644 index 0000000..9968ade --- /dev/null +++ b/test/t/test_find.py @@ -0,0 +1,37 @@ +import pytest + + +class TestFind: + @pytest.mark.complete("find ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("find -fstype ") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("find -") + def test_3(self, completion): + assert completion + + @pytest.mark.complete("find -wholename ", cwd="shared/default") + def test_4(self, completion): + assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"] + + @pytest.mark.complete("find -uid ") + def test_5(self, completion): + assert not [x for x in completion if not x.isdigit()] + + @pytest.mark.complete("find -gid ") + def test_6(self, completion): + assert not [x for x in completion if not x.isdigit()] + + @pytest.mark.complete("find -exec shared/bin/ar") + def test_exec(self, completion): + assert completion == "p" + + # sh +: something that produces completions also when command is not + # available, and the chosen completion is not one of find's + @pytest.mark.complete("find /some/where -exec sh +") + def test_exec_args(self, completion): + assert "+o" in completion diff --git a/test/t/test_find_member.py b/test/t/test_find_member.py new file mode 100644 index 0000000..bfcf588 --- /dev/null +++ b/test/t/test_find_member.py @@ -0,0 +1,7 @@ +import pytest + + +class TestFindMember: + @pytest.mark.complete("find_member -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_finger.py b/test/t/test_finger.py new file mode 100644 index 0000000..d765fdd --- /dev/null +++ b/test/t/test_finger.py @@ -0,0 +1,33 @@ +import pytest + +from conftest import assert_complete, partialize + + +class TestFinger: + @pytest.fixture(scope="class") + def users_at(self, bash, output_sort_uniq): + return output_sort_uniq("compgen -u -S @") + + @pytest.mark.complete("finger ") + def test_1(self, bash, completion, users_at): + assert completion == users_at + + @pytest.mark.complete("finger r") + def test_2(self, bash, completion, users_at): + if not any(x.startswith("r") for x in users_at): + pytest.skip("No users starting with r") + assert completion + idx = 1 if len(completion) == 1 else 0 + assert completion == sorted( + x[idx:] for x in users_at if x.startswith("r") + ) + assert not completion.endswith(" ") + + def test_partial_hostname(self, bash, known_hosts): + first_char, partial_hosts = partialize(bash, known_hosts) + user = "test" + completion = assert_complete(bash, "finger %s@%s" % (user, first_char)) + if len(completion) == 1: + assert completion == partial_hosts[0][1:] + else: + assert completion == ["%s@%s" % (user, x) for x in partial_hosts] diff --git a/test/t/test_fio.py b/test/t/test_fio.py new file mode 100644 index 0000000..0f6eba7 --- /dev/null +++ b/test/t/test_fio.py @@ -0,0 +1,15 @@ +import pytest + + +class TestFio: + @pytest.mark.complete("fio ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("fio --", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("fio --debug=foo,") + def test_3(self, completion): + assert completion diff --git a/test/t/test_firefox.py b/test/t/test_firefox.py new file mode 100644 index 0000000..2e05255 --- /dev/null +++ b/test/t/test_firefox.py @@ -0,0 +1,12 @@ +import pytest + + +class TestFirefox: + @pytest.mark.complete("firefox ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("firefox -", require_cmd=True) + def test_2(self, completion): + assert completion + assert not completion.endswith(" ") diff --git a/test/t/test_flake8.py b/test/t/test_flake8.py new file mode 100644 index 0000000..67649fa --- /dev/null +++ b/test/t/test_flake8.py @@ -0,0 +1,17 @@ +import pytest + + +class TestFlake8: + @pytest.mark.complete("flake8 ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "flake8 -", require_cmd=True, xfail="! flake8 --help &>/dev/null" + ) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("flake8 --doesnt-exist=") + def test_3(self, completion): + assert not completion diff --git a/test/t/test_fmt.py b/test/t/test_fmt.py new file mode 100644 index 0000000..12706da --- /dev/null +++ b/test/t/test_fmt.py @@ -0,0 +1,9 @@ +import pytest + + +class TestFmt: + @pytest.mark.complete( + "fmt -", require_cmd=True, xfail="! fmt --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_fold.py b/test/t/test_fold.py new file mode 100644 index 0000000..1cbaef9 --- /dev/null +++ b/test/t/test_fold.py @@ -0,0 +1,7 @@ +import pytest + + +class TestFold: + @pytest.mark.complete("fold --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_freebsd_update.py b/test/t/test_freebsd_update.py new file mode 100644 index 0000000..911a49a --- /dev/null +++ b/test/t/test_freebsd_update.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="freebsd-update") +class TestFreebsdUpdate: + @pytest.mark.complete("freebsd-update ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_freeciv.py b/test/t/test_freeciv.py new file mode 100644 index 0000000..a195eb8 --- /dev/null +++ b/test/t/test_freeciv.py @@ -0,0 +1,7 @@ +import pytest + + +class TestFreeciv: + @pytest.mark.complete("freeciv -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_freeciv_server.py b/test/t/test_freeciv_server.py new file mode 100644 index 0000000..8543a21 --- /dev/null +++ b/test/t/test_freeciv_server.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="freeciv-server") +class TestFreecivServer: + @pytest.mark.complete("freeciv-server -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_function.py b/test/t/test_function.py new file mode 100644 index 0000000..4401f02 --- /dev/null +++ b/test/t/test_function.py @@ -0,0 +1,7 @@ +import pytest + + +class TestFunction: + @pytest.mark.complete("function _parse_") + def test_1(self, completion): + assert completion diff --git a/test/t/test_fusermount.py b/test/t/test_fusermount.py new file mode 100644 index 0000000..dbb2bd9 --- /dev/null +++ b/test/t/test_fusermount.py @@ -0,0 +1,11 @@ +import pytest + + +class TestFusermount: + @pytest.mark.complete("fusermount ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("fusermount -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_g4.py b/test/t/test_g4.py new file mode 100644 index 0000000..739c77d --- /dev/null +++ b/test/t/test_g4.py @@ -0,0 +1,7 @@ +import pytest + + +class TestG4: + @pytest.mark.complete("g4 ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_g77.py b/test/t/test_g77.py new file mode 100644 index 0000000..45da624 --- /dev/null +++ b/test/t/test_g77.py @@ -0,0 +1,7 @@ +import pytest + + +class TestG77: + @pytest.mark.complete("g77 ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_gcc.py b/test/t/test_gcc.py new file mode 100644 index 0000000..50906db --- /dev/null +++ b/test/t/test_gcc.py @@ -0,0 +1,64 @@ +import pytest + +from conftest import assert_bash_exec + + +class TestGcc: + @pytest.fixture(scope="class") + def gcc_with_completion(self, bash): + got = assert_bash_exec( + bash, "gcc --help=common || :", want_output=True + ) + if "--completion" not in got: + pytest.skip("GCC does not support --completion") + + @pytest.fixture(scope="class") + def gcc_x86(self, bash): + got = assert_bash_exec(bash, "gcc -v || :", want_output=True) + if "Target: x86" not in got: + pytest.skip("Not a x86 GCC") + + @pytest.mark.complete("gcc ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("gcc -fsanitize=add") + def test_enum_value(self, completion, gcc_with_completion): + assert completion == "ress" + + @pytest.mark.complete("gcc -fsanitize=") + def test_enum_value_with_eq(self, completion, gcc_with_completion): + assert "address" in completion + + @pytest.mark.complete("gcc -fno-ipa-ic") + def test_negative_option(self, completion, gcc_with_completion): + assert "-fno-ipa-icf" in completion + + @pytest.mark.complete("gcc -fxyz-abc") + def test_no_completion(self, completion): + assert not completion + + @pytest.mark.complete("gcc --param ") + def test_param_with_space(self, completion, gcc_with_completion): + assert len(completion) > 50 + # starting with GCC 10.1 param end with = + assert ( + "lto-partitions" in completion or "lto-partitions=" in completion + ) + + @pytest.mark.complete("gcc --param=lto-max-p") + def test_param_with_eq(self, completion, gcc_with_completion): + # starting with GCC 10.1 param ends with = + assert completion in ("artition", "artition=") + + @pytest.mark.complete("gcc -march=amd") + def test_march(self, completion, gcc_with_completion, gcc_x86): + assert completion == "fam10" + + @pytest.mark.complete("gcc -march=") + def test_march_native(self, completion, gcc_with_completion): + assert "native" in completion + + @pytest.mark.complete("gcc -mtune=") + def test_mtune_generic(self, completion, gcc_with_completion): + assert "generic" in completion diff --git a/test/t/test_gcj.py b/test/t/test_gcj.py new file mode 100644 index 0000000..17e2f44 --- /dev/null +++ b/test/t/test_gcj.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGcj: + @pytest.mark.complete("gcj ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_gcl.py b/test/t/test_gcl.py new file mode 100644 index 0000000..f1e7a5f --- /dev/null +++ b/test/t/test_gcl.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGcl: + @pytest.mark.complete("gcl ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_gdb.py b/test/t/test_gdb.py new file mode 100644 index 0000000..2ad12c4 --- /dev/null +++ b/test/t/test_gdb.py @@ -0,0 +1,14 @@ +import pytest + + +class TestGdb: + @pytest.mark.complete("gdb - ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("gdb foo ", cwd="gdb") + def test_2(self, completion): + assert completion == sorted( + "core core.12345 " + "core.weston.1000.deadbeef.5308.1555362132000000".split() + ) diff --git a/test/t/test_genaliases.py b/test/t/test_genaliases.py new file mode 100644 index 0000000..e2f24d6 --- /dev/null +++ b/test/t/test_genaliases.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("PATH=/usr/lib/mailman/bin:$PATH",)) +class TestGenaliases: + @pytest.mark.complete("genaliases -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_gendiff.py b/test/t/test_gendiff.py new file mode 100644 index 0000000..0e2ab4c --- /dev/null +++ b/test/t/test_gendiff.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGendiff: + @pytest.mark.complete("gendiff ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_genisoimage.py b/test/t/test_genisoimage.py new file mode 100644 index 0000000..bfcef3b --- /dev/null +++ b/test/t/test_genisoimage.py @@ -0,0 +1,11 @@ +import pytest + + +class TestGenisoimage: + @pytest.mark.complete("genisoimage ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("genisoimage -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_geoiplookup.py b/test/t/test_geoiplookup.py new file mode 100644 index 0000000..9a1422b --- /dev/null +++ b/test/t/test_geoiplookup.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGeoiplookup: + @pytest.mark.complete("geoiplookup -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_getconf.py b/test/t/test_getconf.py new file mode 100644 index 0000000..c80c803 --- /dev/null +++ b/test/t/test_getconf.py @@ -0,0 +1,25 @@ +import pytest + + +class TestGetconf: + @pytest.mark.complete("getconf P") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("getconf -") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("getconf -a ") + def test_3(self, completion): + assert completion + + @pytest.mark.complete( + "getconf -v ", xfail="! getconf -a 2>&1 | command grep -q ^POSIX_V" + ) + def test_4(self, completion): + assert completion + + @pytest.mark.complete("getconf PATH_MAX ") + def test_5(self, completion): + assert completion diff --git a/test/t/test_getent.py b/test/t/test_getent.py new file mode 100644 index 0000000..a1e9fcb --- /dev/null +++ b/test/t/test_getent.py @@ -0,0 +1,18 @@ +import pytest + + +class TestGetent: + @pytest.mark.complete("getent ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "getent -", + require_cmd=True, + xfail=( + "! (getent --help 2>&1 || :) | " + "command grep -q -- '[[:space:]]-'" + ), + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_gkrellm.py b/test/t/test_gkrellm.py new file mode 100644 index 0000000..fdc2e16 --- /dev/null +++ b/test/t/test_gkrellm.py @@ -0,0 +1,10 @@ +import os + +import pytest + + +@pytest.mark.xfail(not os.environ.get("DISPLAY"), reason="X display required") +class TestGkrellm: + @pytest.mark.complete("gkrellm -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_gm.py b/test/t/test_gm.py new file mode 100644 index 0000000..9cdd73c --- /dev/null +++ b/test/t/test_gm.py @@ -0,0 +1,19 @@ +import pytest + + +class TestGm: + @pytest.mark.complete("gm ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("gm help ", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("gm time ", require_cmd=True) + def test_3(self, completion): + assert completion + + @pytest.mark.complete("gm version ") + def test_4(self, completion): + assert not completion diff --git a/test/t/test_gmplayer.py b/test/t/test_gmplayer.py new file mode 100644 index 0000000..211ef51 --- /dev/null +++ b/test/t/test_gmplayer.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGmplayer: + @pytest.mark.complete("gmplayer ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_gnatmake.py b/test/t/test_gnatmake.py new file mode 100644 index 0000000..c9f5609 --- /dev/null +++ b/test/t/test_gnatmake.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGnatmake: + @pytest.mark.complete("gnatmake ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_gnokii.py b/test/t/test_gnokii.py new file mode 100644 index 0000000..66af6e9 --- /dev/null +++ b/test/t/test_gnokii.py @@ -0,0 +1,11 @@ +import pytest + + +class TestGnokii: + @pytest.mark.complete("gnokii ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("gnokii -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_gnome_mplayer.py b/test/t/test_gnome_mplayer.py new file mode 100644 index 0000000..379c56c --- /dev/null +++ b/test/t/test_gnome_mplayer.py @@ -0,0 +1,17 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="gnome-mplayer", ignore_env=r"^[+-]XDG_DATA_DIRS=") +class TestGnomeMplayer: + @pytest.mark.complete("gnome-mplayer ") + def test_1(self, completion): + assert completion + + # XDG_DATA_DIRS set to a dir with no schemas results in + # "GLib-GIO-ERROR **: No GSettings schemas are installed on the system" + # and a core dump on --help on Ubuntu 14. + @pytest.mark.complete( + "gnome-mplayer -", require_cmd=True, pre_cmds=("unset XDG_DATA_DIRS",) + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_gnome_screenshot.py b/test/t/test_gnome_screenshot.py new file mode 100644 index 0000000..977e03f --- /dev/null +++ b/test/t/test_gnome_screenshot.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="gnome-screenshot") +class TestGnomeScreenshot: + @pytest.mark.complete("gnome-screenshot --help", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_gpasswd.py b/test/t/test_gpasswd.py new file mode 100644 index 0000000..4f0221b --- /dev/null +++ b/test/t/test_gpasswd.py @@ -0,0 +1,11 @@ +import pytest + + +class TestGpasswd: + @pytest.mark.complete("gpasswd ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("gpasswd -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_gpc.py b/test/t/test_gpc.py new file mode 100644 index 0000000..9903ef4 --- /dev/null +++ b/test/t/test_gpc.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGpc: + @pytest.mark.complete("gpc ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_gperf.py b/test/t/test_gperf.py new file mode 100644 index 0000000..54f75b1 --- /dev/null +++ b/test/t/test_gperf.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGperf: + @pytest.mark.complete("gperf --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_gpg.py b/test/t/test_gpg.py new file mode 100644 index 0000000..8ead5e9 --- /dev/null +++ b/test/t/test_gpg.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGpg: + @pytest.mark.complete("gpg ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_gpg2.py b/test/t/test_gpg2.py new file mode 100644 index 0000000..27a39fa --- /dev/null +++ b/test/t/test_gpg2.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGpg2: + @pytest.mark.complete("gpg2 --h", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_gpgv.py b/test/t/test_gpgv.py new file mode 100644 index 0000000..d600c74 --- /dev/null +++ b/test/t/test_gpgv.py @@ -0,0 +1,15 @@ +import pytest + + +class TestGpgv: + @pytest.mark.complete("gpgv ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("gpgv -", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("gpgv foo.sig foo ") + def test_3(self, completion): + assert not completion diff --git a/test/t/test_gphoto2.py b/test/t/test_gphoto2.py new file mode 100644 index 0000000..bb987f7 --- /dev/null +++ b/test/t/test_gphoto2.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGphoto2: + @pytest.mark.complete("gphoto2 --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_gplusplus.py b/test/t/test_gplusplus.py new file mode 100644 index 0000000..eeeb1bf --- /dev/null +++ b/test/t/test_gplusplus.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="g++") +class TestGPlusPlus: + @pytest.mark.complete("g++ ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_gprof.py b/test/t/test_gprof.py new file mode 100644 index 0000000..a30cc1e --- /dev/null +++ b/test/t/test_gprof.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGprof: + @pytest.mark.complete("gprof --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_grep.py b/test/t/test_grep.py new file mode 100644 index 0000000..a249122 --- /dev/null +++ b/test/t/test_grep.py @@ -0,0 +1,16 @@ +import pytest + + +class TestGrep: + @pytest.mark.complete("grep --", require_longopt=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("grep --no-complete-dir f", cwd="shared/default") + def test_2(self, completion): + """ + Test --no-*dir isn't restricted to dirs only. + + Not really a grep option, but tests _longopt. + """ + assert completion == "foo foo.d/".split() diff --git a/test/t/test_groupadd.py b/test/t/test_groupadd.py new file mode 100644 index 0000000..f882d1e --- /dev/null +++ b/test/t/test_groupadd.py @@ -0,0 +1,11 @@ +import pytest + + +class TestGroupadd: + @pytest.mark.complete("groupadd ") + def test_1(self, completion): + assert not completion + + @pytest.mark.complete("groupadd -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_groupdel.py b/test/t/test_groupdel.py new file mode 100644 index 0000000..6e55839 --- /dev/null +++ b/test/t/test_groupdel.py @@ -0,0 +1,11 @@ +import pytest + + +class TestGroupdel: + @pytest.mark.complete("groupdel ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("groupdel -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_groupmems.py b/test/t/test_groupmems.py new file mode 100644 index 0000000..c7b9920 --- /dev/null +++ b/test/t/test_groupmems.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGroupmems: + @pytest.mark.complete("groupmems -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_groupmod.py b/test/t/test_groupmod.py new file mode 100644 index 0000000..7097118 --- /dev/null +++ b/test/t/test_groupmod.py @@ -0,0 +1,11 @@ +import pytest + + +class TestGroupmod: + @pytest.mark.complete("groupmod ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("groupmod -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_growisofs.py b/test/t/test_growisofs.py new file mode 100644 index 0000000..7ce19f6 --- /dev/null +++ b/test/t/test_growisofs.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGrowisofs: + @pytest.mark.complete("growisofs ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_grpck.py b/test/t/test_grpck.py new file mode 100644 index 0000000..dcd1485 --- /dev/null +++ b/test/t/test_grpck.py @@ -0,0 +1,11 @@ +import pytest + + +class TestGrpck: + @pytest.mark.complete("grpck ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("grpck -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_grub.py b/test/t/test_grub.py new file mode 100644 index 0000000..4a6929f --- /dev/null +++ b/test/t/test_grub.py @@ -0,0 +1,7 @@ +import pytest + + +class TestGrub: + @pytest.mark.complete("grub --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_gssdp_discover.py b/test/t/test_gssdp_discover.py new file mode 100644 index 0000000..b545149 --- /dev/null +++ b/test/t/test_gssdp_discover.py @@ -0,0 +1,22 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="gssdp-discover") +class TestGssdpDiscover: + @pytest.mark.complete("gssdp-discover ") + def test_no_args(self, completion): + assert not completion + + @pytest.mark.complete("gssdp-discover --", require_cmd=True) + def test_options(self, completion): + assert completion + + @pytest.mark.complete( + "gssdp-discover --message-type=", + skipif=( + "! gssdp-discover --help 2>&1 " + "| command grep -qF -- --message-type" + ), + ) + def test_message_type(self, completion): + assert completion diff --git a/test/t/test_gzip.py b/test/t/test_gzip.py new file mode 100644 index 0000000..2173cad --- /dev/null +++ b/test/t/test_gzip.py @@ -0,0 +1,15 @@ +import pytest + + +class TestGzip: + @pytest.mark.complete("gzip ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("gzip ~") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("gzip -", require_cmd=True) + def test_3(self, completion): + assert completion diff --git a/test/t/test_hciattach.py b/test/t/test_hciattach.py new file mode 100644 index 0000000..2dc1095 --- /dev/null +++ b/test/t/test_hciattach.py @@ -0,0 +1,7 @@ +import pytest + + +class TestHciattach: + @pytest.mark.complete("hciattach ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_hciconfig.py b/test/t/test_hciconfig.py new file mode 100644 index 0000000..2a3f1fd --- /dev/null +++ b/test/t/test_hciconfig.py @@ -0,0 +1,7 @@ +import pytest + + +class TestHciconfig: + @pytest.mark.complete("hciconfig ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_hcitool.py b/test/t/test_hcitool.py new file mode 100644 index 0000000..0885385 --- /dev/null +++ b/test/t/test_hcitool.py @@ -0,0 +1,11 @@ +import pytest + + +class TestHcitool: + @pytest.mark.complete("hcitool ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("hcitool -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_hddtemp.py b/test/t/test_hddtemp.py new file mode 100644 index 0000000..e80a46c --- /dev/null +++ b/test/t/test_hddtemp.py @@ -0,0 +1,7 @@ +import pytest + + +class TestHddtemp: + @pytest.mark.complete("hddtemp -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_head.py b/test/t/test_head.py new file mode 100644 index 0000000..815b938 --- /dev/null +++ b/test/t/test_head.py @@ -0,0 +1,7 @@ +import pytest + + +class TestHead: + @pytest.mark.complete("head --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_hexdump.py b/test/t/test_hexdump.py new file mode 100644 index 0000000..03a7b1f --- /dev/null +++ b/test/t/test_hexdump.py @@ -0,0 +1,7 @@ +import pytest + + +class TestHexdump: + @pytest.mark.complete("hexdump -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_hid2hci.py b/test/t/test_hid2hci.py new file mode 100644 index 0000000..66766fb --- /dev/null +++ b/test/t/test_hid2hci.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("PATH=/lib/udev:$PATH",)) +class TestHid2hci: + @pytest.mark.complete("hid2hci -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_host.py b/test/t/test_host.py new file mode 100644 index 0000000..2ef1790 --- /dev/null +++ b/test/t/test_host.py @@ -0,0 +1,7 @@ +import pytest + + +class TestHost: + @pytest.mark.complete("host -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_hostname.py b/test/t/test_hostname.py new file mode 100644 index 0000000..f644c1e --- /dev/null +++ b/test/t/test_hostname.py @@ -0,0 +1,7 @@ +import pytest + + +class TestHostname: + @pytest.mark.complete("hostname -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_hping2.py b/test/t/test_hping2.py new file mode 100644 index 0000000..19665ba --- /dev/null +++ b/test/t/test_hping2.py @@ -0,0 +1,11 @@ +import pytest + + +class TestHping2: + @pytest.mark.complete("hping2 ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("hping2 -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_hping3.py b/test/t/test_hping3.py new file mode 100644 index 0000000..a979cfa --- /dev/null +++ b/test/t/test_hping3.py @@ -0,0 +1,7 @@ +import pytest + + +class TestHping3: + @pytest.mark.complete("hping3 ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_htop.py b/test/t/test_htop.py new file mode 100644 index 0000000..e837c5a --- /dev/null +++ b/test/t/test_htop.py @@ -0,0 +1,7 @@ +import pytest + + +class TestHtop: + @pytest.mark.complete("htop -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_htpasswd.py b/test/t/test_htpasswd.py new file mode 100644 index 0000000..92989fa --- /dev/null +++ b/test/t/test_htpasswd.py @@ -0,0 +1,23 @@ +import pytest + + +class TestHtpasswd: + @pytest.mark.complete("htpasswd ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("htpasswd -n htpasswd/ht") + def test_2(self, completion): + assert not completion + + @pytest.mark.complete("htpasswd ", cwd="htpasswd") + def test_3(self, completion): + assert completion == "htpasswd" + + @pytest.mark.complete("htpasswd -D htpasswd ", cwd="htpasswd") + def test_4(self, completion): + assert completion == "foo quux".split() + + @pytest.mark.complete("htpasswd -", require_cmd=True) + def test_5(self, completion): + assert completion diff --git a/test/t/test_hunspell.py b/test/t/test_hunspell.py new file mode 100644 index 0000000..0f27185 --- /dev/null +++ b/test/t/test_hunspell.py @@ -0,0 +1,11 @@ +import pytest + + +class TestHunspell: + @pytest.mark.complete("hunspell ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("hunspell -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_hwclock.py b/test/t/test_hwclock.py new file mode 100644 index 0000000..4717210 --- /dev/null +++ b/test/t/test_hwclock.py @@ -0,0 +1,7 @@ +import pytest + + +class TestHwclock: + @pytest.mark.complete("hwclock -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_iconv.py b/test/t/test_iconv.py new file mode 100644 index 0000000..f42a87f --- /dev/null +++ b/test/t/test_iconv.py @@ -0,0 +1,21 @@ +import pytest + + +class TestIconv: + @pytest.mark.complete( + "iconv -", require_cmd=True, xfail="! iconv --help &>/dev/null" + ) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("iconv -f UTF", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("iconv ") + def test_3(self, completion): + assert completion + + @pytest.mark.complete("iconv -f ") + def test_4(self, completion): + assert "..." not in completion diff --git a/test/t/test_id.py b/test/t/test_id.py new file mode 100644 index 0000000..41f2868 --- /dev/null +++ b/test/t/test_id.py @@ -0,0 +1,7 @@ +import pytest + + +class TestId: + @pytest.mark.complete("id -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_identify.py b/test/t/test_identify.py new file mode 100644 index 0000000..34ae285 --- /dev/null +++ b/test/t/test_identify.py @@ -0,0 +1,7 @@ +import pytest + + +class TestIdentify: + @pytest.mark.complete("identify -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_idn.py b/test/t/test_idn.py new file mode 100644 index 0000000..78172c0 --- /dev/null +++ b/test/t/test_idn.py @@ -0,0 +1,7 @@ +import pytest + + +class TestIdn: + @pytest.mark.complete("idn -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_ifdown.py b/test/t/test_ifdown.py new file mode 100644 index 0000000..e91e4ba --- /dev/null +++ b/test/t/test_ifdown.py @@ -0,0 +1,14 @@ +import pytest + +from conftest import in_container + + +class TestIfdown: + @pytest.mark.xfail(in_container(), reason="Probably fails in a container") + @pytest.mark.complete("ifdown ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ifdown bash-completion ") + def test_2(self, completion): + assert not completion diff --git a/test/t/test_ifstat.py b/test/t/test_ifstat.py new file mode 100644 index 0000000..89b5a0e --- /dev/null +++ b/test/t/test_ifstat.py @@ -0,0 +1,21 @@ +import pytest + + +class TestIfstat: + @pytest.mark.complete("ifstat -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "ifstat -i ", xfail="ifstat -v | command grep -qF iproute2" + ) + def test_2(self, completion): + assert completion + + @pytest.mark.complete( + "ifstat -d ", + require_cmd=True, + xfail="ifstat -v | command grep -qF iproute2", + ) + def test_3(self, completion): + assert completion diff --git a/test/t/test_iftop.py b/test/t/test_iftop.py new file mode 100644 index 0000000..4497310 --- /dev/null +++ b/test/t/test_iftop.py @@ -0,0 +1,11 @@ +import pytest + + +class TestIftop: + @pytest.mark.complete("iftop ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("iftop -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_ifup.py b/test/t/test_ifup.py new file mode 100644 index 0000000..843190e --- /dev/null +++ b/test/t/test_ifup.py @@ -0,0 +1,20 @@ +import pytest + +from conftest import in_container + + +class TestIfup: + @pytest.mark.xfail(in_container(), reason="Probably fails in a container") + @pytest.mark.complete("ifup ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "ifup -", require_cmd=True, skipif="! ifup --help &>/dev/null" + ) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("ifup bash-completion ") + def test_3(self, completion): + assert not completion diff --git a/test/t/test_import.py b/test/t/test_import.py new file mode 100644 index 0000000..2e86065 --- /dev/null +++ b/test/t/test_import.py @@ -0,0 +1,7 @@ +import pytest + + +class TestImport: + @pytest.mark.complete("import ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_influx.py b/test/t/test_influx.py new file mode 100644 index 0000000..53a15bf --- /dev/null +++ b/test/t/test_influx.py @@ -0,0 +1,15 @@ +import pytest + + +class TestInflux: + @pytest.mark.complete("influx ") + def test_nothing(self, completion): + assert not completion + + @pytest.mark.complete("influx -", require_cmd=True) + def test_options(self, completion): + assert completion + + @pytest.mark.complete("influx -format ", require_cmd=True) + def test_format(self, completion): + assert completion diff --git a/test/t/test_info.py b/test/t/test_info.py new file mode 100644 index 0000000..e12d900 --- /dev/null +++ b/test/t/test_info.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("INFOPATH+=:$PWD/info:",)) +class TestInfo: + @pytest.mark.complete("info bash") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("info -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_inject.py b/test/t/test_inject.py new file mode 100644 index 0000000..37680dc --- /dev/null +++ b/test/t/test_inject.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("PATH=/usr/lib/mailman/bin:$PATH",)) +class TestInject: + @pytest.mark.complete("inject ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_inotifywait.py b/test/t/test_inotifywait.py new file mode 100644 index 0000000..19fa4d5 --- /dev/null +++ b/test/t/test_inotifywait.py @@ -0,0 +1,15 @@ +import pytest + + +class TestInotifywait: + @pytest.mark.complete("inotifywait ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("inotifywait --", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("inotifywait -e ", require_cmd=True) + def test_3(self, completion): + assert completion diff --git a/test/t/test_inotifywatch.py b/test/t/test_inotifywatch.py new file mode 100644 index 0000000..281fec4 --- /dev/null +++ b/test/t/test_inotifywatch.py @@ -0,0 +1,15 @@ +import pytest + + +class TestInotifywatch: + @pytest.mark.complete("inotifywatch ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("inotifywatch --", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("inotifywatch -e ", require_cmd=True) + def test_3(self, completion): + assert len(completion) > 1 diff --git a/test/t/test_insmod.py b/test/t/test_insmod.py new file mode 100644 index 0000000..9636185 --- /dev/null +++ b/test/t/test_insmod.py @@ -0,0 +1,7 @@ +import pytest + + +class TestInsmod: + @pytest.mark.complete("insmod ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_installpkg.py b/test/t/test_installpkg.py new file mode 100644 index 0000000..e665f52 --- /dev/null +++ b/test/t/test_installpkg.py @@ -0,0 +1,39 @@ +import fnmatch +import os + +import pytest + + +class TestInstallpkg: + @pytest.mark.complete("installpkg -") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("installpkg --") + def test_2(self, completion): + assert ( + completion == "--ask --infobox --md5sum --menu " + "--priority --root --tagfile --terse --warn".split() + ) + + @pytest.mark.complete("installpkg --root ") + def test_3(self, completion): + dirs = sorted(x for x in os.listdir(".") if os.path.isdir("./%s" % x)) + assert completion == ["%s/" % x for x in dirs] + + @pytest.mark.complete("installpkg ", cwd="slackware/home") + def test_4(self, completion): + expected = sorted( + [ + "%s/" % x + for x in os.listdir("slackware/home") + if os.path.isdir("./slackware/home/%s" % x) + ] + + [ + x + for x in os.listdir("slackware/home") + if os.path.isfile("./slackware/home/%s" % x) + and fnmatch.fnmatch(x, "*.t[bglx]z") + ] + ) + assert completion == expected diff --git a/test/t/test_interdiff.py b/test/t/test_interdiff.py new file mode 100644 index 0000000..83be115 --- /dev/null +++ b/test/t/test_interdiff.py @@ -0,0 +1,11 @@ +import pytest + + +class TestInterdiff: + @pytest.mark.complete("interdiff ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("interdiff -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_invoke_rc_d.py b/test/t/test_invoke_rc_d.py new file mode 100644 index 0000000..61e2987 --- /dev/null +++ b/test/t/test_invoke_rc_d.py @@ -0,0 +1,14 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="invoke-rc.d") +class TestInvokeRcD: + @pytest.mark.complete("invoke-rc.d ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("invoke-rc.d --no-fallback --") + def test_2(self, completion): + """Test already specified option is not offered.""" + assert completion + assert "--no-fallback" not in completion diff --git a/test/t/test_ionice.py b/test/t/test_ionice.py new file mode 100644 index 0000000..b097ebe --- /dev/null +++ b/test/t/test_ionice.py @@ -0,0 +1,7 @@ +import pytest + + +class TestIonice: + @pytest.mark.complete("ionice -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_ip.py b/test/t/test_ip.py new file mode 100644 index 0000000..320647f --- /dev/null +++ b/test/t/test_ip.py @@ -0,0 +1,15 @@ +import pytest + + +class TestIp: + @pytest.mark.complete("ip ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ip a ") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("ip route replace ") + def test_r_r(self, completion): + assert completion diff --git a/test/t/test_ipcalc.py b/test/t/test_ipcalc.py new file mode 100644 index 0000000..5611674 --- /dev/null +++ b/test/t/test_ipcalc.py @@ -0,0 +1,23 @@ +import pytest + + +class TestIpcalc: + @pytest.mark.complete("ipcalc -", require_cmd=True) + def test_options(self, completion): + assert any(x in completion for x in "--help -h".split()) + + @pytest.mark.complete("ipcalc --split -") + def test_split_3args_1(self, completion): + assert not completion + + @pytest.mark.complete("ipcalc --split 1 -") + def test_split_3args_2(self, completion): + assert not completion + + @pytest.mark.complete("ipcalc --split 1 2 -") + def test_split_3args_3(self, completion): + assert not completion + + @pytest.mark.complete("ipcalc --split 1 2 3 -", require_cmd=True) + def test_split_3args_4(self, completion): + assert any(x in completion for x in "--help -h".split()) diff --git a/test/t/test_iperf.py b/test/t/test_iperf.py new file mode 100644 index 0000000..c38e954 --- /dev/null +++ b/test/t/test_iperf.py @@ -0,0 +1,24 @@ +import pytest + + +class TestIperf: + @pytest.mark.complete("iperf ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("iperf --bind ") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("iperf --client foo --", require_cmd=True) + def test_3(self, completion): + assert completion + assert "--daemon" not in completion + + @pytest.mark.complete("iperf --server --", require_cmd=True) + def test_4(self, completion): + assert "--daemon" in completion + + @pytest.mark.complete("iperf -", require_cmd=True) + def test_5(self, completion): + assert completion diff --git a/test/t/test_iperf3.py b/test/t/test_iperf3.py new file mode 100644 index 0000000..15f3a03 --- /dev/null +++ b/test/t/test_iperf3.py @@ -0,0 +1,20 @@ +import pytest + + +class TestIperf3: + @pytest.mark.complete("iperf3 ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("iperf3 --bind ") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("iperf3 --client foo --", require_cmd=True) + def test_3(self, completion): + assert completion + assert "--daemon" not in completion + + @pytest.mark.complete("iperf3 --server --", require_cmd=True) + def test_4(self, completion): + assert "--daemon" in completion diff --git a/test/t/test_ipmitool.py b/test/t/test_ipmitool.py new file mode 100644 index 0000000..f779f91 --- /dev/null +++ b/test/t/test_ipmitool.py @@ -0,0 +1,11 @@ +import pytest + + +class TestIpmitool: + @pytest.mark.complete("ipmitool ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ipmitool -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_ipsec.py b/test/t/test_ipsec.py new file mode 100644 index 0000000..5ff29c7 --- /dev/null +++ b/test/t/test_ipsec.py @@ -0,0 +1,7 @@ +import pytest + + +class TestIpsec: + @pytest.mark.complete("ipsec ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_iptables.py b/test/t/test_iptables.py new file mode 100644 index 0000000..a5c82e5 --- /dev/null +++ b/test/t/test_iptables.py @@ -0,0 +1,7 @@ +import pytest + + +class TestIptables: + @pytest.mark.complete("iptables -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_ipv6calc.py b/test/t/test_ipv6calc.py new file mode 100644 index 0000000..872d8a3 --- /dev/null +++ b/test/t/test_ipv6calc.py @@ -0,0 +1,11 @@ +import pytest + + +class TestIpv6calc: + @pytest.mark.complete("ipv6calc -", require_cmd=True) + def test_1(self, completion): + assert "--action" in completion + + @pytest.mark.complete("ipv6calc --in ", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_irb.py b/test/t/test_irb.py new file mode 100644 index 0000000..801d373 --- /dev/null +++ b/test/t/test_irb.py @@ -0,0 +1,11 @@ +import pytest + + +class TestIrb: + @pytest.mark.complete("irb ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("irb -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_iscsiadm.py b/test/t/test_iscsiadm.py new file mode 100644 index 0000000..885ca0a --- /dev/null +++ b/test/t/test_iscsiadm.py @@ -0,0 +1,7 @@ +import pytest + + +class TestIscsiadm: + @pytest.mark.complete("iscsiadm --mod") + def test_1(self, completion): + assert completion == "e" or "--mode" in completion diff --git a/test/t/test_isort.py b/test/t/test_isort.py new file mode 100644 index 0000000..b142d1c --- /dev/null +++ b/test/t/test_isort.py @@ -0,0 +1,11 @@ +import pytest + + +class TestIsort: + @pytest.mark.complete("isort ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("isort -", require_cmd=True, require_longopt=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_isql.py b/test/t/test_isql.py new file mode 100644 index 0000000..7ff0bdb --- /dev/null +++ b/test/t/test_isql.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("ODBCINI=isql/odbc.ini",)) +class TestIsql: + @pytest.mark.complete("isql ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_iwconfig.py b/test/t/test_iwconfig.py new file mode 100644 index 0000000..3ac4b31 --- /dev/null +++ b/test/t/test_iwconfig.py @@ -0,0 +1,7 @@ +import pytest + + +class TestIwconfig: + @pytest.mark.complete("iwconfig --") + def test_1(self, completion): + assert completion diff --git a/test/t/test_iwlist.py b/test/t/test_iwlist.py new file mode 100644 index 0000000..77ffb99 --- /dev/null +++ b/test/t/test_iwlist.py @@ -0,0 +1,7 @@ +import pytest + + +class TestIwlist: + @pytest.mark.complete("iwlist --") + def test_1(self, completion): + assert completion diff --git a/test/t/test_iwpriv.py b/test/t/test_iwpriv.py new file mode 100644 index 0000000..dac214a --- /dev/null +++ b/test/t/test_iwpriv.py @@ -0,0 +1,7 @@ +import pytest + + +class TestIwpriv: + @pytest.mark.complete("iwpriv --") + def test_1(self, completion): + assert completion diff --git a/test/t/test_iwspy.py b/test/t/test_iwspy.py new file mode 100644 index 0000000..398df37 --- /dev/null +++ b/test/t/test_iwspy.py @@ -0,0 +1,7 @@ +import pytest + + +class TestIwspy: + @pytest.mark.complete("iwspy --") + def test_1(self, completion): + assert completion diff --git a/test/t/test_jar.py b/test/t/test_jar.py new file mode 100644 index 0000000..5d4ed8a --- /dev/null +++ b/test/t/test_jar.py @@ -0,0 +1,7 @@ +import pytest + + +class TestJar: + @pytest.mark.complete("jar ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_jarsigner.py b/test/t/test_jarsigner.py new file mode 100644 index 0000000..a6efa6a --- /dev/null +++ b/test/t/test_jarsigner.py @@ -0,0 +1,7 @@ +import pytest + + +class TestJarsigner: + @pytest.mark.complete("jarsigner ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_java.py b/test/t/test_java.py new file mode 100644 index 0000000..ce0f773 --- /dev/null +++ b/test/t/test_java.py @@ -0,0 +1,49 @@ +import pytest + +from conftest import is_bash_type + + +@pytest.mark.bashcomp( + pre_cmds=("CLASSPATH=$PWD/java/a:$PWD/java/bashcomp.jar",) +) +class TestJava: + @pytest.fixture(scope="class") + def can_list_jar(self, bash): + return ( + is_bash_type(bash, "zipinfo") + or is_bash_type(bash, "unzip") + or is_bash_type(bash, "jar") + ) + + @pytest.mark.complete("java -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("java ") + def test_2(self, completion, can_list_jar): + if can_list_jar: + assert completion == "b bashcomp.jarred c. toplevel".split() + else: + assert completion == "b c.".split() + + @pytest.mark.complete("java -classpath java/bashcomp.jar ") + def test_3(self, completion, can_list_jar): + if can_list_jar: + assert completion == "bashcomp.jarred toplevel".split() + else: + assert not completion + + @pytest.mark.complete("java -cp java/bashcomp.jar:java/a/c ") + def test_4(self, completion, can_list_jar): + if can_list_jar: + assert completion == "bashcomp.jarred d toplevel".split() + else: + assert completion == ["d"] + + @pytest.mark.complete("java -cp '' ") + def test_5(self, completion): + assert not completion + + @pytest.mark.complete("java -jar java/") + def test_6(self, completion): + assert completion == "a/ bashcomp.jar bashcomp.war".split() diff --git a/test/t/test_javac.py b/test/t/test_javac.py new file mode 100644 index 0000000..197004e --- /dev/null +++ b/test/t/test_javac.py @@ -0,0 +1,11 @@ +import pytest + + +class TestJavac: + @pytest.mark.complete("javac ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("javac -cp java/") + def test_2(self, completion): + assert completion == "a/ bashcomp.jar".split() diff --git a/test/t/test_javadoc.py b/test/t/test_javadoc.py new file mode 100644 index 0000000..395d196 --- /dev/null +++ b/test/t/test_javadoc.py @@ -0,0 +1,17 @@ +import pytest + + +class TestJavadoc: + @pytest.mark.complete("javadoc ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("javadoc -linkoffline shared/default/") + def test_2(self, completion): + assert completion == ["bar bar.d/", "foo.d/"] + + @pytest.mark.complete( + "javadoc -nodeprecated -linkoffline foo shared/default/" + ) + def test_3(self, completion): + assert completion == ["bar bar.d/", "foo.d/"] diff --git a/test/t/test_javaws.py b/test/t/test_javaws.py new file mode 100644 index 0000000..596c735 --- /dev/null +++ b/test/t/test_javaws.py @@ -0,0 +1,11 @@ +import pytest + + +class TestJavaws: + @pytest.mark.complete("javaws ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("javaws -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_jpegoptim.py b/test/t/test_jpegoptim.py new file mode 100644 index 0000000..fb52591 --- /dev/null +++ b/test/t/test_jpegoptim.py @@ -0,0 +1,11 @@ +import pytest + + +class TestJpegoptim: + @pytest.mark.complete("jpegoptim ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("jpegoptim -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_jps.py b/test/t/test_jps.py new file mode 100644 index 0000000..add9ef9 --- /dev/null +++ b/test/t/test_jps.py @@ -0,0 +1,7 @@ +import pytest + + +class TestJps: + @pytest.mark.complete("jps -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_jq.py b/test/t/test_jq.py new file mode 100644 index 0000000..4701414 --- /dev/null +++ b/test/t/test_jq.py @@ -0,0 +1,30 @@ +import pytest + + +class TestJq: + @pytest.mark.complete("jq ") + def test_1(self, completion): + assert not completion + + @pytest.mark.complete("jq . ") + def test_2(self, completion): + assert completion + + @pytest.mark.complete( + "jq -", + xfail="! (jq --help 2>&1 || :) | command grep -qF 'options include'", + ) + def test_3(self, completion): + assert completion + + @pytest.mark.complete("jq --arg ") + def test_4(self, completion): + assert not completion + + @pytest.mark.complete("jq --slurpfile ") + def test_5(self, completion): + assert not completion + + @pytest.mark.complete("jq --slurpfile foo ") + def test_6(self, completion): + assert completion diff --git a/test/t/test_jshint.py b/test/t/test_jshint.py new file mode 100644 index 0000000..58049d1 --- /dev/null +++ b/test/t/test_jshint.py @@ -0,0 +1,11 @@ +import pytest + + +class TestJshint: + @pytest.mark.complete("jshint ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("jshint -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_json_xs.py b/test/t/test_json_xs.py new file mode 100644 index 0000000..f6174b1 --- /dev/null +++ b/test/t/test_json_xs.py @@ -0,0 +1,11 @@ +import pytest + + +class TestJsonXs: + @pytest.mark.complete("json_xs ") + def test_1(self, completion): + assert not completion + + @pytest.mark.complete("json_xs -") + def test_2(self, completion): + assert completion diff --git a/test/t/test_jsonschema.py b/test/t/test_jsonschema.py new file mode 100644 index 0000000..6027f5d --- /dev/null +++ b/test/t/test_jsonschema.py @@ -0,0 +1,13 @@ +import pytest + + +class TestJsonschema: + @pytest.mark.complete("jsonschema ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "jsonschema -", require_cmd=True, require_longopt=True + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_k3b.py b/test/t/test_k3b.py new file mode 100644 index 0000000..61b6a4d --- /dev/null +++ b/test/t/test_k3b.py @@ -0,0 +1,11 @@ +import pytest + + +class TestK3b: + @pytest.mark.complete("k3b ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("k3b -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_kcov.py b/test/t/test_kcov.py new file mode 100644 index 0000000..3e377eb --- /dev/null +++ b/test/t/test_kcov.py @@ -0,0 +1,16 @@ +import pytest + + +class TestKcov: + @pytest.mark.complete("kcov ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("kcov --exclude-patter", require_cmd=True) + def test_2(self, completion): + assert completion == "n=" + assert completion.endswith("=") + + @pytest.mark.complete("kcov -l 42,") + def test_3(self, completion): + assert completion diff --git a/test/t/test_kdvi.py b/test/t/test_kdvi.py new file mode 100644 index 0000000..c2ab011 --- /dev/null +++ b/test/t/test_kdvi.py @@ -0,0 +1,10 @@ +import pytest + + +class TestKdvi: + @pytest.mark.complete("kdvi ", cwd="kdvi") + def test_1(self, completion): + assert completion == sorted( + "foo/ .dvi .DVI .dvi.bz2 .DVI.bz2 .dvi.gz " + ".DVI.gz .dvi.Z .DVI.Z".split() + ) diff --git a/test/t/test_kill.py b/test/t/test_kill.py new file mode 100644 index 0000000..9699435 --- /dev/null +++ b/test/t/test_kill.py @@ -0,0 +1,15 @@ +import pytest + + +class TestKill: + @pytest.mark.complete("kill 1", xfail="! type ps &>/dev/null") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("kill -s ") + def test_2(self, completion): + assert all(x in completion for x in "HUP QUIT".split()) + + @pytest.mark.complete("kill -") + def test_3(self, completion): + assert all("-%s" % x in completion for x in "l s ABRT USR1".split()) diff --git a/test/t/test_killall.py b/test/t/test_killall.py new file mode 100644 index 0000000..4b67d96 --- /dev/null +++ b/test/t/test_killall.py @@ -0,0 +1,21 @@ +import pytest + + +class TestKillall: + + # "p": Assume our process name completion runs ps and at least it is shown + @pytest.mark.complete("killall p") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("killall --signal ") + def test_2(self, completion): + assert all(x in completion for x in "INT KILL TERM".split()) + + @pytest.mark.complete("killall ") + def test_3(self, completion): + assert "command=" not in completion + + @pytest.mark.complete("killall -", require_cmd=True) + def test_4(self, completion): + assert completion diff --git a/test/t/test_kldload.py b/test/t/test_kldload.py new file mode 100644 index 0000000..2965e44 --- /dev/null +++ b/test/t/test_kldload.py @@ -0,0 +1,7 @@ +import pytest + + +class TestKldload: + @pytest.mark.complete("kldload ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_kldunload.py b/test/t/test_kldunload.py new file mode 100644 index 0000000..a52c99e --- /dev/null +++ b/test/t/test_kldunload.py @@ -0,0 +1,16 @@ +import subprocess + +import pytest + + +class TestKldunload: + @pytest.mark.complete("kldunload ") + def test_1(self, completion): + try: + subprocess.check_call( + r"kldstat 2>/dev/null | command grep -q '\.ko$'", shell=True + ) + except BaseException: + assert not completion + else: + assert completion diff --git a/test/t/test_koji.py b/test/t/test_koji.py new file mode 100644 index 0000000..73d3e4c --- /dev/null +++ b/test/t/test_koji.py @@ -0,0 +1,11 @@ +import pytest + + +class TestKoji: + @pytest.mark.complete("koji ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("koji -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_kpdf.py b/test/t/test_kpdf.py new file mode 100644 index 0000000..68b36fe --- /dev/null +++ b/test/t/test_kpdf.py @@ -0,0 +1,7 @@ +import pytest + + +class TestKpdf: + @pytest.mark.complete("kpdf ", cwd="kpdf") + def test_1(self, completion): + assert completion == sorted("foo/ .eps .ps .EPS .PS .pdf .PDF".split()) diff --git a/test/t/test_kplayer.py b/test/t/test_kplayer.py new file mode 100644 index 0000000..ef8a08e --- /dev/null +++ b/test/t/test_kplayer.py @@ -0,0 +1,7 @@ +import pytest + + +class TestKplayer: + @pytest.mark.complete("kplayer ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ktutil.py b/test/t/test_ktutil.py new file mode 100644 index 0000000..7c90b80 --- /dev/null +++ b/test/t/test_ktutil.py @@ -0,0 +1,11 @@ +import pytest + + +class TestKtutil: + @pytest.mark.complete("ktutil ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ktutil -") + def test_2(self, completion): + assert completion diff --git a/test/t/test_l2ping.py b/test/t/test_l2ping.py new file mode 100644 index 0000000..c50651b --- /dev/null +++ b/test/t/test_l2ping.py @@ -0,0 +1,7 @@ +import pytest + + +class TestL2ping: + @pytest.mark.complete("l2ping -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_larch.py b/test/t/test_larch.py new file mode 100644 index 0000000..e68183c --- /dev/null +++ b/test/t/test_larch.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLarch: + @pytest.mark.complete("larch library-") + def test_1(self, completion): + assert completion diff --git a/test/t/test_lastlog.py b/test/t/test_lastlog.py new file mode 100644 index 0000000..31a855f --- /dev/null +++ b/test/t/test_lastlog.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLastlog: + @pytest.mark.complete("lastlog -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_ld.py b/test/t/test_ld.py new file mode 100644 index 0000000..f6a16bb --- /dev/null +++ b/test/t/test_ld.py @@ -0,0 +1,11 @@ +import pytest + + +class TestLd: + @pytest.mark.complete("ld ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ld -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_ldapadd.py b/test/t/test_ldapadd.py new file mode 100644 index 0000000..24aa5e3 --- /dev/null +++ b/test/t/test_ldapadd.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLdapadd: + @pytest.mark.complete("ldapadd -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ldapcompare.py b/test/t/test_ldapcompare.py new file mode 100644 index 0000000..6a3afe9 --- /dev/null +++ b/test/t/test_ldapcompare.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLdapcompare: + @pytest.mark.complete("ldapcompare -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ldapdelete.py b/test/t/test_ldapdelete.py new file mode 100644 index 0000000..2065d9b --- /dev/null +++ b/test/t/test_ldapdelete.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLdapdelete: + @pytest.mark.complete("ldapdelete -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ldapmodrdn.py b/test/t/test_ldapmodrdn.py new file mode 100644 index 0000000..da8bdbd --- /dev/null +++ b/test/t/test_ldapmodrdn.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLdapmodrdn: + @pytest.mark.complete("ldapmodrdn -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ldappasswd.py b/test/t/test_ldappasswd.py new file mode 100644 index 0000000..e559f23 --- /dev/null +++ b/test/t/test_ldappasswd.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLdappasswd: + @pytest.mark.complete("ldappasswd -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ldapsearch.py b/test/t/test_ldapsearch.py new file mode 100644 index 0000000..43797f4 --- /dev/null +++ b/test/t/test_ldapsearch.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLdapsearch: + @pytest.mark.complete("ldapsearch -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ldapvi.py b/test/t/test_ldapvi.py new file mode 100644 index 0000000..5e65fc4 --- /dev/null +++ b/test/t/test_ldapvi.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLdapvi: + @pytest.mark.complete("ldapvi -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_ldapwhoami.py b/test/t/test_ldapwhoami.py new file mode 100644 index 0000000..9dcfb5f --- /dev/null +++ b/test/t/test_ldapwhoami.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLdapwhoami: + @pytest.mark.complete("ldapwhoami -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ldd.py b/test/t/test_ldd.py new file mode 100644 index 0000000..7f7201b --- /dev/null +++ b/test/t/test_ldd.py @@ -0,0 +1,13 @@ +import pytest + + +class TestLdd: + @pytest.mark.complete("ldd ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "ldd -", require_cmd=True, xfail="! ldd --help &>/dev/null" + ) + def test_options(self, completion): + assert completion diff --git a/test/t/test_less.py b/test/t/test_less.py new file mode 100644 index 0000000..70833c3 --- /dev/null +++ b/test/t/test_less.py @@ -0,0 +1,11 @@ +import pytest + + +class TestLess: + @pytest.mark.complete("less --", require_longopt=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("less --", require_longopt=True) + def test_no_dashdashdash(self, completion): + assert all(not x.startswith("---") for x in completion) diff --git a/test/t/test_lftp.py b/test/t/test_lftp.py new file mode 100644 index 0000000..f775a4c --- /dev/null +++ b/test/t/test_lftp.py @@ -0,0 +1,16 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("HOME=$PWD/lftp",)) +class TestLftp: + @pytest.mark.complete("lftp ", require_cmd=True) + def test_1(self, bash, completion, output_sort_uniq): + hosts = output_sort_uniq("compgen -A hostname") + assert all(x in completion for x in hosts) + # defined in lftp/.lftp/bookmarks + assert all(x in completion for x in "lftptest spacetest".split()) + assert "badbookmark" not in completion + + @pytest.mark.complete("lftp -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_lftpget.py b/test/t/test_lftpget.py new file mode 100644 index 0000000..c1f453e --- /dev/null +++ b/test/t/test_lftpget.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLftpget: + @pytest.mark.complete("lftpget -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_lilo.py b/test/t/test_lilo.py new file mode 100644 index 0000000..2c69821 --- /dev/null +++ b/test/t/test_lilo.py @@ -0,0 +1,16 @@ +import pytest + + +class TestLilo: + @pytest.mark.complete("lilo -") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("lilo -C lilo/lilo.conf -D ") + def test_labels(self, completion): + # Note that 2.4.33 should not be here, it's commented out + assert completion == sorted("try tamu PCDOS WinXP oldDOS".split()) + + @pytest.mark.complete("lilo -C -D ") + def test_labels_incorrect_command(self, completion): + assert not completion diff --git a/test/t/test_links.py b/test/t/test_links.py new file mode 100644 index 0000000..0806813 --- /dev/null +++ b/test/t/test_links.py @@ -0,0 +1,11 @@ +import pytest + + +class TestLinks: + @pytest.mark.complete("links ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("links -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_lintian.py b/test/t/test_lintian.py new file mode 100644 index 0000000..c652642 --- /dev/null +++ b/test/t/test_lintian.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLintian: + @pytest.mark.complete("lintian --") + def test_1(self, completion): + assert completion diff --git a/test/t/test_lintian_info.py b/test/t/test_lintian_info.py new file mode 100644 index 0000000..bf9afc5 --- /dev/null +++ b/test/t/test_lintian_info.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="lintian-info") +class TestLintianInfo: + @pytest.mark.complete("lintian-info ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("lintian-info --", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_lisp.py b/test/t/test_lisp.py new file mode 100644 index 0000000..8477061 --- /dev/null +++ b/test/t/test_lisp.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLisp: + @pytest.mark.complete("lisp ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_list_admins.py b/test/t/test_list_admins.py new file mode 100644 index 0000000..b65387e --- /dev/null +++ b/test/t/test_list_admins.py @@ -0,0 +1,7 @@ +import pytest + + +class TestListAdmins: + @pytest.mark.complete("list_admins -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_list_lists.py b/test/t/test_list_lists.py new file mode 100644 index 0000000..966ca25 --- /dev/null +++ b/test/t/test_list_lists.py @@ -0,0 +1,7 @@ +import pytest + + +class TestListLists: + @pytest.mark.complete("list_lists -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_list_members.py b/test/t/test_list_members.py new file mode 100644 index 0000000..96ea2ef --- /dev/null +++ b/test/t/test_list_members.py @@ -0,0 +1,7 @@ +import pytest + + +class TestListMembers: + @pytest.mark.complete("list_members -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_list_owners.py b/test/t/test_list_owners.py new file mode 100644 index 0000000..2a6bcab --- /dev/null +++ b/test/t/test_list_owners.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("PATH=/usr/lib/mailman/bin:$PATH",)) +class TestListOwners: + @pytest.mark.complete("list_owners -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_ln.py b/test/t/test_ln.py new file mode 100644 index 0000000..6bf809c --- /dev/null +++ b/test/t/test_ln.py @@ -0,0 +1,11 @@ +import pytest + + +class TestLn: + @pytest.mark.complete("ln ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ln -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_locale_gen.py b/test/t/test_locale_gen.py new file mode 100644 index 0000000..caffb06 --- /dev/null +++ b/test/t/test_locale_gen.py @@ -0,0 +1,13 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="locale-gen") +class TestLocaleGen: + # require_cmd is not strictly true here, but... + @pytest.mark.complete("locale-gen ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("locale-gen --", require_longopt=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_look.py b/test/t/test_look.py new file mode 100644 index 0000000..fd6800e --- /dev/null +++ b/test/t/test_look.py @@ -0,0 +1,16 @@ +import subprocess + +import pytest + + +class TestLook: + @pytest.mark.complete("look foo") + def test_1(self, completion): + try: + subprocess.check_call( + "look foo 2>/dev/null | command grep -q ^foo", shell=True + ) + except BaseException: + assert not completion + else: + assert completion diff --git a/test/t/test_lpq.py b/test/t/test_lpq.py new file mode 100644 index 0000000..0d69270 --- /dev/null +++ b/test/t/test_lpq.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLpq: + @pytest.mark.complete("lpq ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_lpr.py b/test/t/test_lpr.py new file mode 100644 index 0000000..30c710b --- /dev/null +++ b/test/t/test_lpr.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLpr: + @pytest.mark.complete("lpr ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_lrzip.py b/test/t/test_lrzip.py new file mode 100644 index 0000000..d61ee9d --- /dev/null +++ b/test/t/test_lrzip.py @@ -0,0 +1,15 @@ +import pytest + + +class TestLrzip: + @pytest.mark.complete("lrzip ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("lrzip ~") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("lrzip -", require_cmd=True) + def test_3(self, completion): + assert completion diff --git a/test/t/test_ls.py b/test/t/test_ls.py new file mode 100644 index 0000000..8abcb59 --- /dev/null +++ b/test/t/test_ls.py @@ -0,0 +1,40 @@ +import pytest + +from conftest import ( + assert_bash_exec, + assert_complete, + find_unique_completion_pair, +) + + +class TestLs: + @pytest.mark.complete( + "ls --", require_cmd=True, xfail="! ls --help &>/dev/null" + ) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ls ~") + def test_2(self, completion): + assert completion + + def test_3(self, bash): + """~part should complete to ~full<SPACE> if home dir does not exist.""" + res = ( + assert_bash_exec( + bash, + "for u in $(compgen -u); do " + "eval test -d ~$u || echo $u; unset u; done", + want_output=True, + ) + .strip() + .split() + ) + part_full = find_unique_completion_pair(res) + if not part_full: + pytest.skip("No suitable test user found") + return + part, full = part_full + completion = assert_complete(bash, "ls ~%s" % part) + assert completion == full[len(part) :] + assert completion.endswith(" ") diff --git a/test/t/test_lsof.py b/test/t/test_lsof.py new file mode 100644 index 0000000..170d269 --- /dev/null +++ b/test/t/test_lsof.py @@ -0,0 +1,11 @@ +import pytest + + +class TestLsof: + @pytest.mark.complete("lsof ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("lsof -") + def test_2(self, completion): + assert completion diff --git a/test/t/test_lspci.py b/test/t/test_lspci.py new file mode 100644 index 0000000..aba7b5a --- /dev/null +++ b/test/t/test_lspci.py @@ -0,0 +1,13 @@ +import pytest + + +class TestLspci: + @pytest.mark.complete("lspci -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "lspci -A ", require_cmd=True, skipif="! lspci -A help &>/dev/null" + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_lsscsi.py b/test/t/test_lsscsi.py new file mode 100644 index 0000000..fe01ac1 --- /dev/null +++ b/test/t/test_lsscsi.py @@ -0,0 +1,11 @@ +import pytest + + +class TestLsscsi: + @pytest.mark.complete("lsscsi ") + def test_1(self, completion): + assert not completion + + @pytest.mark.complete("lsscsi -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_lsusb.py b/test/t/test_lsusb.py new file mode 100644 index 0000000..c68d046 --- /dev/null +++ b/test/t/test_lsusb.py @@ -0,0 +1,10 @@ +import pytest + + +class TestLsusb: + @pytest.mark.complete( + "lsusb -", + xfail="! (lsusb --help 2>&1 || :) | command grep -qF -- --help", + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_lua.py b/test/t/test_lua.py new file mode 100644 index 0000000..54c2432 --- /dev/null +++ b/test/t/test_lua.py @@ -0,0 +1,11 @@ +import pytest + + +class TestLua: + @pytest.mark.complete("lua ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("lua -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_luac.py b/test/t/test_luac.py new file mode 100644 index 0000000..28dc0e8 --- /dev/null +++ b/test/t/test_luac.py @@ -0,0 +1,11 @@ +import pytest + + +class TestLuac: + @pytest.mark.complete("luac ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("luac -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_luseradd.py b/test/t/test_luseradd.py new file mode 100644 index 0000000..4f1bec9 --- /dev/null +++ b/test/t/test_luseradd.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLuseradd: + @pytest.mark.complete("luseradd -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_luserdel.py b/test/t/test_luserdel.py new file mode 100644 index 0000000..ad88557 --- /dev/null +++ b/test/t/test_luserdel.py @@ -0,0 +1,11 @@ +import pytest + + +class TestLuserdel: + @pytest.mark.complete("luserdel ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("luserdel -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_lusermod.py b/test/t/test_lusermod.py new file mode 100644 index 0000000..69ef07c --- /dev/null +++ b/test/t/test_lusermod.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLusermod: + @pytest.mark.complete("lusermod ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_lvchange.py b/test/t/test_lvchange.py new file mode 100644 index 0000000..3e4feda --- /dev/null +++ b/test/t/test_lvchange.py @@ -0,0 +1,9 @@ +import pytest + + +class TestLvchange: + @pytest.mark.complete( + "lvchange --", require_cmd=True, xfail="! lvchange --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_lvcreate.py b/test/t/test_lvcreate.py new file mode 100644 index 0000000..636f625 --- /dev/null +++ b/test/t/test_lvcreate.py @@ -0,0 +1,9 @@ +import pytest + + +class TestLvcreate: + @pytest.mark.complete( + "lvcreate --", require_cmd=True, xfail="! lvcreate --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_lvdisplay.py b/test/t/test_lvdisplay.py new file mode 100644 index 0000000..5210662 --- /dev/null +++ b/test/t/test_lvdisplay.py @@ -0,0 +1,11 @@ +import pytest + + +class TestLvdisplay: + @pytest.mark.complete( + "lvdisplay --", + require_cmd=True, + xfail="! lvdisplay --help &>/dev/null", + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_lvextend.py b/test/t/test_lvextend.py new file mode 100644 index 0000000..4daa888 --- /dev/null +++ b/test/t/test_lvextend.py @@ -0,0 +1,9 @@ +import pytest + + +class TestLvextend: + @pytest.mark.complete( + "lvextend --", require_cmd=True, xfail="! lvextend --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_lvm.py b/test/t/test_lvm.py new file mode 100644 index 0000000..ea25b97 --- /dev/null +++ b/test/t/test_lvm.py @@ -0,0 +1,7 @@ +import pytest + + +class TestLvm: + @pytest.mark.complete("lvm pv") + def test_1(self, completion): + assert completion diff --git a/test/t/test_lvmdiskscan.py b/test/t/test_lvmdiskscan.py new file mode 100644 index 0000000..1b334b8 --- /dev/null +++ b/test/t/test_lvmdiskscan.py @@ -0,0 +1,11 @@ +import pytest + + +class TestLvmdiskscan: + @pytest.mark.complete( + "lvmdiskscan --", + require_cmd=True, + xfail="! lvmdiskscan --help &>/dev/null", + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_lvreduce.py b/test/t/test_lvreduce.py new file mode 100644 index 0000000..3b614cb --- /dev/null +++ b/test/t/test_lvreduce.py @@ -0,0 +1,9 @@ +import pytest + + +class TestLvreduce: + @pytest.mark.complete( + "lvreduce --", require_cmd=True, xfail="! lvreduce --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_lvremove.py b/test/t/test_lvremove.py new file mode 100644 index 0000000..17486aa --- /dev/null +++ b/test/t/test_lvremove.py @@ -0,0 +1,9 @@ +import pytest + + +class TestLvremove: + @pytest.mark.complete( + "lvremove --", require_cmd=True, xfail="! lvremove --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_lvrename.py b/test/t/test_lvrename.py new file mode 100644 index 0000000..802b72e --- /dev/null +++ b/test/t/test_lvrename.py @@ -0,0 +1,9 @@ +import pytest + + +class TestLvrename: + @pytest.mark.complete( + "lvrename --", require_cmd=True, xfail="! lvrename --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_lvresize.py b/test/t/test_lvresize.py new file mode 100644 index 0000000..bb71feb --- /dev/null +++ b/test/t/test_lvresize.py @@ -0,0 +1,9 @@ +import pytest + + +class TestLvresize: + @pytest.mark.complete( + "lvresize --", require_cmd=True, xfail="! lvresize --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_lvs.py b/test/t/test_lvs.py new file mode 100644 index 0000000..eadc8df --- /dev/null +++ b/test/t/test_lvs.py @@ -0,0 +1,9 @@ +import pytest + + +class TestLvs: + @pytest.mark.complete( + "lvs --", require_cmd=True, xfail="! lvs --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_lvscan.py b/test/t/test_lvscan.py new file mode 100644 index 0000000..a2867b0 --- /dev/null +++ b/test/t/test_lvscan.py @@ -0,0 +1,9 @@ +import pytest + + +class TestLvscan: + @pytest.mark.complete( + "lvscan --", require_cmd=True, xfail="! lvscan --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_lz4.py b/test/t/test_lz4.py new file mode 100644 index 0000000..0e1208c --- /dev/null +++ b/test/t/test_lz4.py @@ -0,0 +1,15 @@ +import pytest + + +class TestLz4: + @pytest.mark.complete("lz4 ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("lz4 ~") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("lz4 -", require_cmd=True) + def test_3(self, completion): + assert completion diff --git a/test/t/test_lzip.py b/test/t/test_lzip.py new file mode 100644 index 0000000..b0313be --- /dev/null +++ b/test/t/test_lzip.py @@ -0,0 +1,11 @@ +import pytest + + +class TestLzip: + @pytest.mark.complete("lzip ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("lzip -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_lzma.py b/test/t/test_lzma.py new file mode 100644 index 0000000..f9d8992 --- /dev/null +++ b/test/t/test_lzma.py @@ -0,0 +1,19 @@ +import pytest + + +class TestLzma: + @pytest.mark.complete("lzma ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("lzma -") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("lzma -d xz/") + def test_3(self, completion): + assert completion == "a/ bashcomp.lzma bashcomp.tlz".split() + + @pytest.mark.complete("lzma ~") + def test_4(self, completion): + assert completion diff --git a/test/t/test_lzop.py b/test/t/test_lzop.py new file mode 100644 index 0000000..bd010fd --- /dev/null +++ b/test/t/test_lzop.py @@ -0,0 +1,11 @@ +import pytest + + +class TestLzop: + @pytest.mark.complete("lzop ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("lzop ~") + def test_2(self, completion): + assert completion diff --git a/test/t/test_m4.py b/test/t/test_m4.py new file mode 100644 index 0000000..7ecd774 --- /dev/null +++ b/test/t/test_m4.py @@ -0,0 +1,9 @@ +import pytest + + +class TestM4: + @pytest.mark.complete( + "m4 --", require_cmd=True, xfail="! m4 --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_macof.py b/test/t/test_macof.py new file mode 100644 index 0000000..17f0eae --- /dev/null +++ b/test/t/test_macof.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMacof: + @pytest.mark.complete("macof -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_mailmanctl.py b/test/t/test_mailmanctl.py new file mode 100644 index 0000000..2baa050 --- /dev/null +++ b/test/t/test_mailmanctl.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("PATH=/usr/lib/mailman/bin:$PATH",)) +class TestMailmanctl: + @pytest.mark.complete("mailmanctl ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_mailsnarf.py b/test/t/test_mailsnarf.py new file mode 100644 index 0000000..0dc3e04 --- /dev/null +++ b/test/t/test_mailsnarf.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMailsnarf: + @pytest.mark.complete("mailsnarf -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_make.py b/test/t/test_make.py new file mode 100644 index 0000000..19861b0 --- /dev/null +++ b/test/t/test_make.py @@ -0,0 +1,47 @@ +import os + +import pytest + + +class TestMake: + @pytest.mark.complete("make -f Ma", cwd="make") + def test_1(self, completion): + assert completion == "kefile" + + @pytest.mark.complete("make .", cwd="make", require_cmd=True) + def test_2(self, bash, completion): + """Hidden targets.""" + assert completion == ".cache/ .test_passes".split() + os.remove("%s/make/%s" % (bash.cwd, "extra_makefile")) + + @pytest.mark.complete("make .cache/", cwd="make", require_cmd=True) + def test_3(self, bash, completion): + assert completion == "1 2".split() + os.remove("%s/make/%s" % (bash.cwd, "extra_makefile")) + + @pytest.mark.complete("make ", cwd="shared/empty_dir") + def test_4(self, completion): + assert not completion + + @pytest.mark.complete("make -j ") + def test_5(self, completion): + assert completion + + @pytest.mark.complete("make ", cwd="make", require_cmd=True) + def test_6(self, bash, completion): + assert completion == "all clean extra_makefile install sample".split() + os.remove("%s/make/%s" % (bash.cwd, "extra_makefile")) + + @pytest.mark.complete("make .cache/.", cwd="make", require_cmd=True) + def test_7(self, bash, completion): + assert completion == ".1 .2".split() + os.remove("%s/make/%s" % (bash.cwd, "extra_makefile")) + + @pytest.mark.complete("make -C make ", require_cmd=True) + def test_8(self, bash, completion): + assert completion == "all clean extra_makefile install sample".split() + os.remove("%s/make/%s" % (bash.cwd, "extra_makefile")) + + @pytest.mark.complete("make -", require_cmd=True) + def test_9(self, completion): + assert completion diff --git a/test/t/test_makepkg.py b/test/t/test_makepkg.py new file mode 100644 index 0000000..f643a29 --- /dev/null +++ b/test/t/test_makepkg.py @@ -0,0 +1,17 @@ +import pytest + + +@pytest.mark.bashcomp( + ignore_env=r"^-declare -f _makepkg_bootstrap$", + xfail="! makepkg --help 2>&1 | command grep -qiF slackware", +) +class TestMakepkg: + @pytest.mark.complete("makepkg ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("makepkg --", require_cmd=True) + def test_2(self, completion): + assert all( + x in completion for x in "--chown --linkadd --prepend".split() + ) diff --git a/test/t/test_man.py b/test/t/test_man.py new file mode 100644 index 0000000..1ff9f84 --- /dev/null +++ b/test/t/test_man.py @@ -0,0 +1,115 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp( + ignore_env=r"^[+-]((BASHOPTS|MANPATH)=|shopt -. failglob)" +) +class TestMan: + + manpath = "$PWD/man" + assumed_present = "man" + + @pytest.fixture + def colonpath(self, request, bash): + try: + assert_bash_exec(bash, "uname -s 2>&1 | grep -qiF cygwin") + except AssertionError: + pass + else: + pytest.skip("Cygwin doesn't like paths with colons") + return + assert_bash_exec(bash, "mkdir -p $TESTDIR/../tmp/man/man3") + assert_bash_exec( + bash, "touch $TESTDIR/../tmp/man/man3/Bash::Completion.3pm.gz" + ) + request.addfinalizer( + lambda: assert_bash_exec(bash, "rm -r $TESTDIR/../tmp/man") + ) + + @pytest.mark.complete( + "man bash-completion-testcas", + env=dict(MANPATH=manpath), + require_cmd=True, + ) + def test_1(self, completion): + assert completion == "e" + + @pytest.mark.complete("man man1/f", cwd="man", env=dict(MANPATH=manpath)) + def test_2(self, completion): + assert completion == "oo.1" + + @pytest.mark.complete("man man/", cwd="man", env=dict(MANPATH=manpath)) + def test_3(self, completion): + assert completion == "quux.8" + + @pytest.mark.complete( + "man %s" % assumed_present, + cwd="shared/empty_dir", + env=dict(MANPATH=manpath), + ) + def test_4(self, completion): + """ + Assumed present should not be completed complete when there's no + leading/trailing colon in $MANPATH. + """ + assert not completion + + @pytest.mark.complete( + "man %s" % assumed_present, + require_cmd=True, + cwd="shared/empty_dir", + env=dict(MANPATH="%s:" % manpath), + ) + def test_5(self, completion): + """Trailing colon appends system man path.""" + assert completion + + @pytest.mark.complete( + "man bash-completion-testcas", + require_cmd=True, + env=dict(MANPATH="%s:" % manpath), + ) + def test_6(self, completion): + assert completion == "e" + + @pytest.mark.complete( + "man %s" % assumed_present, + require_cmd=True, + cwd="shared/empty_dir", + env=dict(MANPATH=":%s" % manpath), + ) + def test_7(self, completion): + """Leading colon prepends system man path.""" + assert completion + + @pytest.mark.complete( + "man bash-completion-testcas", + require_cmd=True, + env=dict(MANPATH=":%s" % manpath), + ) + def test_8(self, completion): + assert completion == "e" + + @pytest.mark.complete( + "man %s" % assumed_present, + require_cmd=True, + cwd="shared/empty_dir", + pre_cmds=("shopt -s failglob",), + ) + def test_9(self, bash, completion): + assert self.assumed_present in completion + assert_bash_exec(bash, "shopt -u failglob") + + @pytest.mark.complete( + "man Bash::C", + require_cmd=True, + env=dict(MANPATH="%s:../tmp/man" % manpath), + ) + def test_10(self, bash, colonpath, completion): + assert completion == "ompletion" + + @pytest.mark.complete("man -", require_cmd=True) + def test_11(self, completion): + assert completion diff --git a/test/t/test_mc.py b/test/t/test_mc.py new file mode 100644 index 0000000..31f88b7 --- /dev/null +++ b/test/t/test_mc.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMc: + @pytest.mark.complete("mc -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_mcrypt.py b/test/t/test_mcrypt.py new file mode 100644 index 0000000..d11f446 --- /dev/null +++ b/test/t/test_mcrypt.py @@ -0,0 +1,19 @@ +import pytest + + +class TestMcrypt: + @pytest.mark.complete("mcrypt ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mcrypt -a ", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("mcrypt -m ", require_cmd=True) + def test_3(self, completion): + assert completion + + @pytest.mark.complete("mcrypt -", require_cmd=True) + def test_4(self, completion): + assert completion diff --git a/test/t/test_md5sum.py b/test/t/test_md5sum.py new file mode 100644 index 0000000..0a3286a --- /dev/null +++ b/test/t/test_md5sum.py @@ -0,0 +1,11 @@ +import pytest + + +class TestMd5sum: + @pytest.mark.complete("md5sum ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("md5sum -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_mdadm.py b/test/t/test_mdadm.py new file mode 100644 index 0000000..143007b --- /dev/null +++ b/test/t/test_mdadm.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMdadm: + @pytest.mark.complete("mdadm ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_mdecrypt.py b/test/t/test_mdecrypt.py new file mode 100644 index 0000000..f6f4c8e --- /dev/null +++ b/test/t/test_mdecrypt.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMdecrypt: + @pytest.mark.complete("mdecrypt ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_mdtool.py b/test/t/test_mdtool.py new file mode 100644 index 0000000..356e907 --- /dev/null +++ b/test/t/test_mdtool.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMdtool: + @pytest.mark.complete("mdtool ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_medusa.py b/test/t/test_medusa.py new file mode 100644 index 0000000..87fb91b --- /dev/null +++ b/test/t/test_medusa.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMedusa: + @pytest.mark.complete("medusa -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_mencoder.py b/test/t/test_mencoder.py new file mode 100644 index 0000000..a17fb96 --- /dev/null +++ b/test/t/test_mencoder.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("HOME=$PWD/mplayer",)) +class TestMencoder: + @pytest.mark.complete("mencoder ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mencoder -v", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_mii_diag.py b/test/t/test_mii_diag.py new file mode 100644 index 0000000..6ed96aa --- /dev/null +++ b/test/t/test_mii_diag.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="mii-diag") +class TestMiiDiag: + @pytest.mark.complete("mii-diag ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mii-diag -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_mii_tool.py b/test/t/test_mii_tool.py new file mode 100644 index 0000000..f028787 --- /dev/null +++ b/test/t/test_mii_tool.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="mii-tool") +class TestMiiTool: + @pytest.mark.complete("mii-tool ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mii-tool -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_minicom.py b/test/t/test_minicom.py new file mode 100644 index 0000000..6fac457 --- /dev/null +++ b/test/t/test_minicom.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMinicom: + @pytest.mark.complete("minicom -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_mkdir.py b/test/t/test_mkdir.py new file mode 100644 index 0000000..afc3fd0 --- /dev/null +++ b/test/t/test_mkdir.py @@ -0,0 +1,21 @@ +import pytest + + +class TestMkdir: + @pytest.mark.complete("mkdir ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mkdir ", cwd="shared/default") + def test_2(self, completion): + assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"] + + @pytest.mark.xfail # TODO: why path in completion, basename in .output? + @pytest.mark.complete("mkdir shared/default/foo.d/") + def test_3(self, completion): + assert completion.output == "foo" + assert completion == [completion.output] + + @pytest.mark.complete("mkdir -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_mkfifo.py b/test/t/test_mkfifo.py new file mode 100644 index 0000000..92e82de --- /dev/null +++ b/test/t/test_mkfifo.py @@ -0,0 +1,11 @@ +import pytest + + +class TestMkfifo: + @pytest.mark.complete("mkfifo ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mkfifo -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_mkinitrd.py b/test/t/test_mkinitrd.py new file mode 100644 index 0000000..7305925 --- /dev/null +++ b/test/t/test_mkinitrd.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMkinitrd: + @pytest.mark.complete("mkinitrd ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_mkisofs.py b/test/t/test_mkisofs.py new file mode 100644 index 0000000..541c6e7 --- /dev/null +++ b/test/t/test_mkisofs.py @@ -0,0 +1,15 @@ +import pytest + + +class TestMkisofs: + @pytest.mark.complete("mkisofs ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mkisofs -uid ") + def test_2(self, completion): + assert not [x for x in completion if not x.isdigit()] + + @pytest.mark.complete("mkisofs -gid ") + def test_3(self, completion): + assert not [x for x in completion if not x.isdigit()] diff --git a/test/t/test_mknod.py b/test/t/test_mknod.py new file mode 100644 index 0000000..03f21e8 --- /dev/null +++ b/test/t/test_mknod.py @@ -0,0 +1,11 @@ +import pytest + + +class TestMknod: + @pytest.mark.complete("mknod ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mknod -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_mktemp.py b/test/t/test_mktemp.py new file mode 100644 index 0000000..9f61be1 --- /dev/null +++ b/test/t/test_mktemp.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMktemp: + @pytest.mark.complete("mktemp -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_mmsitepass.py b/test/t/test_mmsitepass.py new file mode 100644 index 0000000..4dcd9fb --- /dev/null +++ b/test/t/test_mmsitepass.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMmsitepass: + @pytest.mark.complete("mmsitepass -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_mock.py b/test/t/test_mock.py new file mode 100644 index 0000000..5f9eb3e --- /dev/null +++ b/test/t/test_mock.py @@ -0,0 +1,13 @@ +import pytest + + +class TestMock: + @pytest.mark.complete("mock ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "mock -", require_cmd=True, xfail="! mock --help &>/dev/null" + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_modinfo.py b/test/t/test_modinfo.py new file mode 100644 index 0000000..a4f5c50 --- /dev/null +++ b/test/t/test_modinfo.py @@ -0,0 +1,32 @@ +import subprocess + +import pytest + + +class TestModinfo: + @pytest.mark.complete("modinfo -", require_cmd=True) + def test_1(self, completion): + assert completion + + # "in": intel*, ... + @pytest.mark.complete( + "modinfo in", + xfail="! ls /lib/modules/%s &>/dev/null" + % subprocess.check_output( + "uname -r 2>/dev/null || " "echo non-existent-kernel", shell=True + ) + .decode() + .strip(), + ) + def test_2(self, completion): + assert completion + + # "in": intel*, ... + @pytest.mark.complete("modinfo -k non-existent-kernel in") + def test_3(self, completion): + assert not completion + + @pytest.mark.complete("modinfo /tm") + def test_4(self, completion): + assert completion + assert not completion.endswith(" ") diff --git a/test/t/test_modprobe.py b/test/t/test_modprobe.py new file mode 100644 index 0000000..9201119 --- /dev/null +++ b/test/t/test_modprobe.py @@ -0,0 +1,36 @@ +import subprocess + +import pytest + + +class TestModprobe: + @pytest.mark.complete("modprobe --al") + def test_1(self, completion): + assert completion == "l" + + # "in": intel*, ... + @pytest.mark.complete( + "modprobe in", + xfail="! ls /lib/modules/%s &>/dev/null" + % subprocess.check_output( + "uname -r 2>/dev/null || " "echo non-existent-kernel", shell=True + ) + .decode() + .strip(), + ) + def test_2(self, completion): + assert completion + + # "in": intel*, ... + @pytest.mark.complete("modprobe -S non-existent-kernel in") + def test_3(self, completion): + assert not completion + + @pytest.mark.complete("modprobe non-existent-module ") + def test_4(self, completion): + assert not completion + + @pytest.mark.complete("modprobe /tm") + def test_5(self, completion): + assert completion + assert not completion.endswith(" ") diff --git a/test/t/test_module.py b/test/t/test_module.py new file mode 100644 index 0000000..a66dea7 --- /dev/null +++ b/test/t/test_module.py @@ -0,0 +1,7 @@ +import pytest + + +class TestModule: + @pytest.mark.complete("module ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_mogrify.py b/test/t/test_mogrify.py new file mode 100644 index 0000000..22d84a8 --- /dev/null +++ b/test/t/test_mogrify.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMogrify: + @pytest.mark.complete("mogrify ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_monodevelop.py b/test/t/test_monodevelop.py new file mode 100644 index 0000000..59435a1 --- /dev/null +++ b/test/t/test_monodevelop.py @@ -0,0 +1,11 @@ +import pytest + + +class TestMonodevelop: + @pytest.mark.complete("monodevelop ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("monodevelop -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_montage.py b/test/t/test_montage.py new file mode 100644 index 0000000..1237c7d --- /dev/null +++ b/test/t/test_montage.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMontage: + @pytest.mark.complete("montage ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_mount.py b/test/t/test_mount.py new file mode 100644 index 0000000..8254fd4 --- /dev/null +++ b/test/t/test_mount.py @@ -0,0 +1,22 @@ +import pytest + + +class TestMount: + @pytest.mark.complete("mount ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mount -t ") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("mount /dev/sda1 def", cwd="shared") + def test_3(self, completion): + assert completion == "ault/" + assert not completion.endswith(" ") + + @pytest.mark.complete( + "mount mocksrv:/", env=dict(PATH="$PWD/mount/bin:$PATH") + ) + def test_4(self, completion): + assert completion == "/second/path /test/path /test/path2".split() diff --git a/test/t/test_mplayer.py b/test/t/test_mplayer.py new file mode 100644 index 0000000..a06991b --- /dev/null +++ b/test/t/test_mplayer.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("HOME=$PWD/mplayer",)) +class TestMplayer: + @pytest.mark.complete("mplayer ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mplayer -h", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_mr.py b/test/t/test_mr.py new file mode 100644 index 0000000..bfad643 --- /dev/null +++ b/test/t/test_mr.py @@ -0,0 +1,58 @@ +import pytest + + +class TestMr: + @pytest.mark.complete("mr ") + def test_1(self, completion): + assert completion + + # man -h tests below: Some mr versions require man to be around in order + # to provide useful output. + + @pytest.mark.complete( + "mr --", require_cmd=True, xfail="! man -h &>/dev/null" + ) + def test_2(self, completion): + assert completion + + @pytest.mark.complete( + "mr -c shared/default/foo.d/", xfail="! man -h &>/dev/null" + ) + def test_3(self, completion): + assert completion == "foo" + + @pytest.mark.complete( + "mr bootstrap shared/default/", + require_cmd=True, + xfail="! man -h &>/dev/null", + ) + def test_4(self, completion): + assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"] + + @pytest.mark.complete( + "mr clean -", + require_cmd=True, + xfail="! man -h &>/dev/null", + # "clean" does not exist before mr 1.20141023 + skipif="! mr help 2>&1 | command grep -qwF clean", + ) + def test_5(self, completion): + assert completion == "f" + + @pytest.mark.complete( + "mr commit -", require_cmd=True, xfail="! man -h &>/dev/null" + ) + def test_6(self, completion): + assert completion == "m" + + @pytest.mark.complete( + "mr status ", require_cmd=True, xfail="! man -h &>/dev/null" + ) + def test_7(self, completion): + assert not completion + + @pytest.mark.complete( + "mr run ", require_cmd=True, xfail="! man -h &>/dev/null" + ) + def test_8(self, completion): + assert completion diff --git a/test/t/test_msgsnarf.py b/test/t/test_msgsnarf.py new file mode 100644 index 0000000..7484456 --- /dev/null +++ b/test/t/test_msgsnarf.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMsgsnarf: + @pytest.mark.complete("msgsnarf -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_msynctool.py b/test/t/test_msynctool.py new file mode 100644 index 0000000..530d751 --- /dev/null +++ b/test/t/test_msynctool.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMsynctool: + @pytest.mark.complete("msynctool ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_mtx.py b/test/t/test_mtx.py new file mode 100644 index 0000000..6b6f59b --- /dev/null +++ b/test/t/test_mtx.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMtx: + @pytest.mark.complete("mtx ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_munin_node_configure.py b/test/t/test_munin_node_configure.py new file mode 100644 index 0000000..e7570d8 --- /dev/null +++ b/test/t/test_munin_node_configure.py @@ -0,0 +1,19 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="munin-node-configure") +class TestMuninNodeConfigure: + @pytest.mark.complete("munin-node-configure --libdir ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "munin-node-configure -", + require_cmd=True, + xfail=( + "! (munin-node-configure --help 2>&1 || :) " + "| command grep -q -- '[[:space:]]-'" + ), + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_munin_run.py b/test/t/test_munin_run.py new file mode 100644 index 0000000..a031449 --- /dev/null +++ b/test/t/test_munin_run.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="munin-run") +class TestMuninRun: + @pytest.mark.complete("munin-run -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_munindoc.py b/test/t/test_munindoc.py new file mode 100644 index 0000000..eea13ca --- /dev/null +++ b/test/t/test_munindoc.py @@ -0,0 +1,10 @@ +import pytest + + +class TestMunindoc: + + # Assume at least munin* available + # require_cmd is not strictly correct here, but... + @pytest.mark.complete("munindoc m", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_mussh.py b/test/t/test_mussh.py new file mode 100644 index 0000000..357c2b5 --- /dev/null +++ b/test/t/test_mussh.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMussh: + @pytest.mark.complete("mussh -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_mutt.py b/test/t/test_mutt.py new file mode 100644 index 0000000..0c4074f --- /dev/null +++ b/test/t/test_mutt.py @@ -0,0 +1,33 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(pre_cmds=("HOME=$PWD/mutt",)) +class TestMutt: + @pytest.mark.complete("mutt -") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mutt -F muttrc -f =", require_cmd=True, cwd="mutt") + def test_2(self, completion): + assert completion == "bar/ foo/ muttrc".split() + + @pytest.mark.complete("mutt -F muttrc -A ", cwd="mutt") + def test_3(self, completion): + assert completion == "a1 a2".split() + + def test_4(self, bash): + got = ( + assert_bash_exec( + bash, + '_muttconffiles "$HOME/muttrc" "$HOME/muttrc"', + want_output=True, + ) + .strip() + .split() + ) + assert got == [ + "%s/mutt/%s" % (bash.cwd, x) + for x in ("muttrc", "bar/muttrc_b", "foo/muttrc_f") + ] diff --git a/test/t/test_muttng.py b/test/t/test_muttng.py new file mode 100644 index 0000000..3ce19ac --- /dev/null +++ b/test/t/test_muttng.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMuttng: + @pytest.mark.complete("muttng -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_mv.py b/test/t/test_mv.py new file mode 100644 index 0000000..4a354db --- /dev/null +++ b/test/t/test_mv.py @@ -0,0 +1,11 @@ +import pytest + + +class TestMv: + @pytest.mark.complete("mv ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mv -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_mypy.py b/test/t/test_mypy.py new file mode 100644 index 0000000..11628c1 --- /dev/null +++ b/test/t/test_mypy.py @@ -0,0 +1,15 @@ +import pytest + + +class TestMypy: + @pytest.mark.complete("mypy ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mypy --", require_cmd=True, require_longopt=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("mypy --non-existent-option=--") + def test_3(self, completion): + assert not completion diff --git a/test/t/test_mysql.py b/test/t/test_mysql.py new file mode 100644 index 0000000..6a44b7e --- /dev/null +++ b/test/t/test_mysql.py @@ -0,0 +1,15 @@ +import pytest + + +class TestMysql: + @pytest.mark.complete("mysql --") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("mysql --default-character-set=") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("mysql --non-existent-option=--") + def test_3(self, completion): + assert not completion diff --git a/test/t/test_mysqladmin.py b/test/t/test_mysqladmin.py new file mode 100644 index 0000000..85046fe --- /dev/null +++ b/test/t/test_mysqladmin.py @@ -0,0 +1,7 @@ +import pytest + + +class TestMysqladmin: + @pytest.mark.complete("mysqladmin -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_nc.py b/test/t/test_nc.py new file mode 100644 index 0000000..38db5ac --- /dev/null +++ b/test/t/test_nc.py @@ -0,0 +1,7 @@ +import pytest + + +class TestNc: + @pytest.mark.complete("nc -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_ncftp.py b/test/t/test_ncftp.py new file mode 100644 index 0000000..b37f48f --- /dev/null +++ b/test/t/test_ncftp.py @@ -0,0 +1,11 @@ +import pytest + + +class TestNcftp: + @pytest.mark.complete("ncftp ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ncftp -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_nethogs.py b/test/t/test_nethogs.py new file mode 100644 index 0000000..c57185f --- /dev/null +++ b/test/t/test_nethogs.py @@ -0,0 +1,11 @@ +import pytest + + +class TestNethogs: + @pytest.mark.complete("nethogs ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("nethogs -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_netstat.py b/test/t/test_netstat.py new file mode 100644 index 0000000..57ef26c --- /dev/null +++ b/test/t/test_netstat.py @@ -0,0 +1,11 @@ +import pytest + + +class TestNetstat: + @pytest.mark.complete("netstat ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("netstat -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_newgrp.py b/test/t/test_newgrp.py new file mode 100644 index 0000000..7d65a16 --- /dev/null +++ b/test/t/test_newgrp.py @@ -0,0 +1,7 @@ +import pytest + + +class TestNewgrp: + @pytest.mark.complete("newgrp ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_newlist.py b/test/t/test_newlist.py new file mode 100644 index 0000000..1d6b439 --- /dev/null +++ b/test/t/test_newlist.py @@ -0,0 +1,7 @@ +import pytest + + +class TestNewlist: + @pytest.mark.complete("newlist -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_newusers.py b/test/t/test_newusers.py new file mode 100644 index 0000000..51d746a --- /dev/null +++ b/test/t/test_newusers.py @@ -0,0 +1,11 @@ +import pytest + + +class TestNewusers: + @pytest.mark.complete("newusers ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("newusers -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_ngrep.py b/test/t/test_ngrep.py new file mode 100644 index 0000000..53fa60d --- /dev/null +++ b/test/t/test_ngrep.py @@ -0,0 +1,11 @@ +import pytest + + +class TestNgrep: + @pytest.mark.complete("ngrep -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ngrep -d ") + def test_2(self, completion): + assert completion diff --git a/test/t/test_nl.py b/test/t/test_nl.py new file mode 100644 index 0000000..ca910a5 --- /dev/null +++ b/test/t/test_nl.py @@ -0,0 +1,11 @@ +import pytest + + +class TestNl: + @pytest.mark.complete("nl ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("nl -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_nm.py b/test/t/test_nm.py new file mode 100644 index 0000000..328fa50 --- /dev/null +++ b/test/t/test_nm.py @@ -0,0 +1,11 @@ +import pytest + + +class TestNm: + @pytest.mark.complete("nm ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("nm -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_nmap.py b/test/t/test_nmap.py new file mode 100644 index 0000000..9aff8b2 --- /dev/null +++ b/test/t/test_nmap.py @@ -0,0 +1,47 @@ +import pytest + +from conftest import assert_bash_exec + + +class TestNmap: + @pytest.fixture(scope="class") + def functions(self, request, bash): + assert_bash_exec(bash, "_mock_nmap() { cat nmap/nmap-h.txt; }") + assert_bash_exec(bash, "complete -F _nmap _mock_nmap") + + @pytest.mark.complete("nmap --v", require_cmd=True) + def test_live_options(self, completion): + assert completion + + @pytest.mark.complete("nmap ") + def test_hosts(self, completion): + assert completion + + @pytest.mark.complete("_mock_nmap -") + def test_mock_options(self, completion, functions): + assert completion == sorted( + "-iL -iR --exclude --excludefile -sL -sn -Pn -PS -PA -PU -PY -PE " + "-PP -PM -PO -n -R --dns-servers --system-dns --traceroute -sS " + "-sT -sA -sW -sM -sU -sN -sF -sX --scanflags -sI -sY -sZ -sO -b " + "-p --exclude-ports -F -r --top-ports --port-ratio -sV " + "--version-intensity --version-light --version-all " + "--version-trace -sC --script= --script-args= --script-args-file= " + "--script-trace --script-updatedb --script-help= -O " + "--osscan-limit --osscan-guess " + # TODO: -T known mishandled; should expand -T<0-5> to -T0 ... -T5 + "-T --min-hostgroup --max-hostgroup --min-parallelism " + "--max-parallelism --min-rtt-timeout --max-rtt-timeout " + "--initial-rtt-timeout --max-retries --host-timeout --scan-delay " + "--max-scan-delay --min-rate --max-rate -f --mtu -D -S -e -g " + "--source-port --proxies --data --data-string --data-length " + "--ip-options --ttl --spoof-mac --badsum -oN -oX -oS -oG -oA -v " + "-d --reason --open --packet-trace --iflist --append-output " + "--resume --stylesheet --webxml --no-stylesheet -6 -A --datadir " + "--send-eth --send-ip --privileged --unprivileged -V -h" + "".strip().split() + ) + + @pytest.mark.complete("_mock_nmap --script-args-f") + def test_mock_nospace(self, completion, functions): + assert completion == "ile=" + assert completion.endswith("=") # no space appended diff --git a/test/t/test_nmcli.py b/test/t/test_nmcli.py new file mode 100644 index 0000000..f2b7950 --- /dev/null +++ b/test/t/test_nmcli.py @@ -0,0 +1,7 @@ +import pytest + + +class TestNmcli: + @pytest.mark.complete("nmcli ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_nproc.py b/test/t/test_nproc.py new file mode 100644 index 0000000..66a49ac --- /dev/null +++ b/test/t/test_nproc.py @@ -0,0 +1,17 @@ +import pytest + + +class TestNproc: + @pytest.mark.complete("nproc ") + def test_1(self, completion): + assert not completion + + @pytest.mark.complete( + "nproc --", + xfail=( + "! nproc --help &>/dev/null || " + "! nproc --help 2>&1 | command grep -qF -- --help" + ), + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_nslookup.py b/test/t/test_nslookup.py new file mode 100644 index 0000000..0286509 --- /dev/null +++ b/test/t/test_nslookup.py @@ -0,0 +1,7 @@ +import pytest + + +class TestNslookup: + @pytest.mark.complete("nslookup -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_nsupdate.py b/test/t/test_nsupdate.py new file mode 100644 index 0000000..b8a133c --- /dev/null +++ b/test/t/test_nsupdate.py @@ -0,0 +1,11 @@ +import pytest + + +class TestNsupdate: + @pytest.mark.complete("nsupdate ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("nsupdate -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_ntpdate.py b/test/t/test_ntpdate.py new file mode 100644 index 0000000..c8d65cf --- /dev/null +++ b/test/t/test_ntpdate.py @@ -0,0 +1,7 @@ +import pytest + + +class TestNtpdate: + @pytest.mark.complete("ntpdate -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_objcopy.py b/test/t/test_objcopy.py new file mode 100644 index 0000000..e3130fa --- /dev/null +++ b/test/t/test_objcopy.py @@ -0,0 +1,11 @@ +import pytest + + +class TestObjcopy: + @pytest.mark.complete("objcopy ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("objcopy -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_objdump.py b/test/t/test_objdump.py new file mode 100644 index 0000000..6b8bc74 --- /dev/null +++ b/test/t/test_objdump.py @@ -0,0 +1,7 @@ +import pytest + + +class TestObjdump: + @pytest.mark.complete("objdump ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_od.py b/test/t/test_od.py new file mode 100644 index 0000000..e2f5de2 --- /dev/null +++ b/test/t/test_od.py @@ -0,0 +1,11 @@ +import pytest + + +class TestOd: + @pytest.mark.complete("od ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("od -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_oggdec.py b/test/t/test_oggdec.py new file mode 100644 index 0000000..395bb86 --- /dev/null +++ b/test/t/test_oggdec.py @@ -0,0 +1,11 @@ +import pytest + + +class TestOggdec: + @pytest.mark.complete("oggdec ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("oggdec --", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_op.py b/test/t/test_op.py new file mode 100644 index 0000000..662cde5 --- /dev/null +++ b/test/t/test_op.py @@ -0,0 +1,11 @@ +import pytest + + +class TestOp: + @pytest.mark.complete("op ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("op --", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_openssl.py b/test/t/test_openssl.py new file mode 100644 index 0000000..3eaf6d4 --- /dev/null +++ b/test/t/test_openssl.py @@ -0,0 +1,16 @@ +import pytest + + +class TestOpenssl: + @pytest.mark.complete("openssl ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("openssl pkey -cipher ", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("openssl dgst -s", require_cmd=True) + def test_3(self, completion): + assert completion + assert any(x.startswith("-sha") for x in completion) diff --git a/test/t/test_opera.py b/test/t/test_opera.py new file mode 100644 index 0000000..f0c657e --- /dev/null +++ b/test/t/test_opera.py @@ -0,0 +1,11 @@ +import pytest + + +class TestOpera: + @pytest.mark.complete("opera ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("opera -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_optipng.py b/test/t/test_optipng.py new file mode 100644 index 0000000..615d71f --- /dev/null +++ b/test/t/test_optipng.py @@ -0,0 +1,11 @@ +import pytest + + +class TestOptipng: + @pytest.mark.complete("optipng ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("optipng -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_p4.py b/test/t/test_p4.py new file mode 100644 index 0000000..876d261 --- /dev/null +++ b/test/t/test_p4.py @@ -0,0 +1,7 @@ +import pytest + + +class TestP4: + @pytest.mark.complete("p4 ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_pack200.py b/test/t/test_pack200.py new file mode 100644 index 0000000..0960133 --- /dev/null +++ b/test/t/test_pack200.py @@ -0,0 +1,7 @@ +import pytest + + +class TestPack200: + @pytest.mark.complete("pack200 ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_passwd.py b/test/t/test_passwd.py new file mode 100644 index 0000000..f253701 --- /dev/null +++ b/test/t/test_passwd.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPasswd: + @pytest.mark.complete("passwd ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("passwd -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_paste.py b/test/t/test_paste.py new file mode 100644 index 0000000..ecf030b --- /dev/null +++ b/test/t/test_paste.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPaste: + @pytest.mark.complete("paste ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("paste -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_patch.py b/test/t/test_patch.py new file mode 100644 index 0000000..c68a4b6 --- /dev/null +++ b/test/t/test_patch.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPatch: + @pytest.mark.complete("patch ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("patch -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_pdftotext.py b/test/t/test_pdftotext.py new file mode 100644 index 0000000..90d001f --- /dev/null +++ b/test/t/test_pdftotext.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPdftotext: + @pytest.mark.complete("pdftotext ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pdftotext -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_perl.py b/test/t/test_perl.py new file mode 100644 index 0000000..049c91e --- /dev/null +++ b/test/t/test_perl.py @@ -0,0 +1,91 @@ +import pytest + + +@pytest.mark.bashcomp(ignore_env=r"^\+PERL5LIB=") +class TestPerl: + @pytest.mark.complete("perl ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("perl -e ") + def test_2(self, completion): + assert not completion + + @pytest.mark.complete("perl -V:install", require_cmd=True) + def test_3(self, completion): + assert completion + + @pytest.mark.complete("perl -V::install", require_cmd=True) + def test_4(self, completion): + assert completion + + # Assume File::Spec and friends are always installed + + @pytest.mark.complete("perl -MFile", require_cmd=True) + def test_5(self, completion): + assert completion + + @pytest.mark.complete("perl -MFile::Sp", require_cmd=True) + def test_6(self, completion): + assert completion + + @pytest.mark.complete("perl -MFile::Spec::Func", require_cmd=True) + def test_7(self, completion): + assert completion + + @pytest.mark.complete("perl -M-File", require_cmd=True) + def test_8(self, completion): + assert completion + + @pytest.mark.complete("perl -m-File::", require_cmd=True) + def test_9(self, completion): + assert completion + + @pytest.mark.complete("perl -") + def test_10(self, completion): + assert completion + + @pytest.mark.complete("perl foo shared/default/f") + def test_11(self, completion): + """Second arg should complete files+dirs.""" + assert completion == "foo foo.d/".split() + + @pytest.mark.complete("perl -Ishared/default/") + def test_12(self, completion): + """-I without space should complete dirs.""" + assert completion == ["bar bar.d/", "foo.d/"] + + @pytest.mark.complete("perl -I shared/default/") + def test_13(self, completion): + """-I with space should complete dirs.""" + assert completion == ["bar bar.d/", "foo.d/"] + + @pytest.mark.complete("perl -xshared/default/b") + def test_14(self, completion): + """-x without space should complete dirs.""" + assert completion == r"ar\ bar.d/" + + @pytest.mark.complete("perl -x shared/default/b") + def test_15(self, completion): + """-x with space should complete files+dirs.""" + assert completion == ["bar", "bar bar.d/"] + + @pytest.mark.complete( + "perl -d:", env=dict(PERL5LIB="$PWD/perl"), require_cmd=True + ) + def test_16(self, completion): + assert "BashCompletion" in completion + + @pytest.mark.complete( + "perl -dt:", env=dict(PERL5LIB="$PWD/perl"), require_cmd=True + ) + def test_17(self, completion): + assert "BashCompletion" in completion + + @pytest.mark.complete("perl -E ") + def test_dash_capital_e(self, completion): + assert not completion + + @pytest.mark.complete("perl -e") + def test_dash_e(self, completion): + assert not completion diff --git a/test/t/test_perlcritic.py b/test/t/test_perlcritic.py new file mode 100644 index 0000000..51ba201 --- /dev/null +++ b/test/t/test_perlcritic.py @@ -0,0 +1,15 @@ +import pytest + + +class TestPerlcritic: + @pytest.mark.complete("perlcritic ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("perlcritic --", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("perlcritic --theme ", require_cmd=True) + def test_3(self, completion): + assert completion diff --git a/test/t/test_perldoc.py b/test/t/test_perldoc.py new file mode 100644 index 0000000..282f824 --- /dev/null +++ b/test/t/test_perldoc.py @@ -0,0 +1,18 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("export PERL5LIB=$PWD/perldoc",)) +class TestPerldoc: + @pytest.mark.complete("perldoc File::") + def test_1(self, completion): + assert "Path" in completion # Assume File::Path always installed + assert "fixtures/" not in completion # Our fixtures/ dir + assert not [x for x in completion if "File::File::" in x] + + @pytest.mark.complete("perldoc -", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("perldoc BashCompletion") + def test_3(self, completion): + assert completion == "BashCompletionDoc BashCompletionModule".split() diff --git a/test/t/test_perltidy.py b/test/t/test_perltidy.py new file mode 100644 index 0000000..578923a --- /dev/null +++ b/test/t/test_perltidy.py @@ -0,0 +1,19 @@ +import pytest + + +class TestPerltidy: + @pytest.mark.complete("perltidy ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("perltidy -h", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("perltidy -ole=", require_cmd=True) + def test_3(self, completion): + assert completion + + @pytest.mark.complete("perltidy -doesntexist=", require_cmd=True) + def test_4(self, completion): + assert not completion diff --git a/test/t/test_pgrep.py b/test/t/test_pgrep.py new file mode 100644 index 0000000..9a998ed --- /dev/null +++ b/test/t/test_pgrep.py @@ -0,0 +1,35 @@ +import pytest + + +class TestPgrep: + + # "p": Assume that our process name completion runs ps + @pytest.mark.complete("pgrep p") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pgrep -", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete( + "pgrep --nslist ", + require_cmd=True, + skipif=( + "! pgrep --help 2>&1 | command grep -qF 'Available namespaces'" + ), + ) + def test_nslist(self, completion): + assert completion + assert not any("," in x for x in completion) + + @pytest.mark.complete( + "pgrep --nslist foo,", + require_cmd=True, + skipif=( + "! pgrep --help 2>&1 | command grep -qF 'Available namespaces'" + ), + ) + def test_nslist_after_comma(self, completion): + assert completion + assert not any("," in x for x in completion) diff --git a/test/t/test_phing.py b/test/t/test_phing.py new file mode 100644 index 0000000..973a957 --- /dev/null +++ b/test/t/test_phing.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPhing: + @pytest.mark.complete("phing -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("phing -l ", require_cmd=True) + def test_2(self, completion): + assert not completion diff --git a/test/t/test_pidof.py b/test/t/test_pidof.py new file mode 100644 index 0000000..c33a4d3 --- /dev/null +++ b/test/t/test_pidof.py @@ -0,0 +1,15 @@ +import pytest + + +class TestPidof: + + # "p": Assume that our process name completion runs ps + @pytest.mark.complete("pidof p") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "pidof -", require_cmd=True, xfail="! pidof --help &>/dev/null" + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_pine.py b/test/t/test_pine.py new file mode 100644 index 0000000..0c95973 --- /dev/null +++ b/test/t/test_pine.py @@ -0,0 +1,7 @@ +import pytest + + +class TestPine: + @pytest.mark.complete("pine -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_pinfo.py b/test/t/test_pinfo.py new file mode 100644 index 0000000..a22128e --- /dev/null +++ b/test/t/test_pinfo.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("INFOPATH+=:$PWD/info:",)) +class TestPinfo: + @pytest.mark.complete("pinfo -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pinfo bash") + def test_2(self, completion): + assert completion diff --git a/test/t/test_ping.py b/test/t/test_ping.py new file mode 100644 index 0000000..f70582a --- /dev/null +++ b/test/t/test_ping.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPing: + @pytest.mark.complete("ping ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ping -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_pkg_config.py b/test/t/test_pkg_config.py new file mode 100644 index 0000000..81e02ca --- /dev/null +++ b/test/t/test_pkg_config.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="pkg-config") +class TestPkgConfig: + @pytest.mark.complete("pkg-config ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pkg-config -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_pkg_deinstall.py b/test/t/test_pkg_deinstall.py new file mode 100644 index 0000000..5ce6d13 --- /dev/null +++ b/test/t/test_pkg_deinstall.py @@ -0,0 +1,15 @@ +import os + +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("PKG_DBDIR=$PWD/pkgtools/db",)) +class TestPkgDeinstall: + @pytest.mark.complete("pkg_deinstall ") + def test_1(self, completion): + dirs = sorted( + x + for x in os.listdir("pkgtools/db") + if os.path.isdir("pkgtools/db/%s" % x) + ) + assert completion == dirs diff --git a/test/t/test_pkg_delete.py b/test/t/test_pkg_delete.py new file mode 100644 index 0000000..a4b0d85 --- /dev/null +++ b/test/t/test_pkg_delete.py @@ -0,0 +1,7 @@ +import pytest + + +class TestPkgDelete: + @pytest.mark.complete("pkg_delete ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_pkg_get.py b/test/t/test_pkg_get.py new file mode 100644 index 0000000..cb2d283 --- /dev/null +++ b/test/t/test_pkg_get.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="pkg-get") +class TestPkgGet: + @pytest.mark.complete("pkg-get ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_pkg_info.py b/test/t/test_pkg_info.py new file mode 100644 index 0000000..6011f81 --- /dev/null +++ b/test/t/test_pkg_info.py @@ -0,0 +1,7 @@ +import pytest + + +class TestPkgInfo: + @pytest.mark.complete("pkg_info ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_pkgadd.py b/test/t/test_pkgadd.py new file mode 100644 index 0000000..69d08dc --- /dev/null +++ b/test/t/test_pkgadd.py @@ -0,0 +1,8 @@ +import pytest + + +class TestPkgadd: + # require_cmd is not strictly true here, but... + @pytest.mark.complete("pkgadd ", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_pkgrm.py b/test/t/test_pkgrm.py new file mode 100644 index 0000000..2af81ef --- /dev/null +++ b/test/t/test_pkgrm.py @@ -0,0 +1,8 @@ +import pytest + + +class TestPkgrm: + # require_cmd is not strictly true here, but... + @pytest.mark.complete("pkgrm ", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_pkgtool.py b/test/t/test_pkgtool.py new file mode 100644 index 0000000..7d35637 --- /dev/null +++ b/test/t/test_pkgtool.py @@ -0,0 +1,7 @@ +import pytest + + +class TestPkgtool: + @pytest.mark.complete("pkgtool -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_pkgutil.py b/test/t/test_pkgutil.py new file mode 100644 index 0000000..9664728 --- /dev/null +++ b/test/t/test_pkgutil.py @@ -0,0 +1,7 @@ +import pytest + + +class TestPkgutil: + @pytest.mark.complete("pkgutil ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_pkill.py b/test/t/test_pkill.py new file mode 100644 index 0000000..a779958 --- /dev/null +++ b/test/t/test_pkill.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPkill: + @pytest.mark.complete("pkill ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pkill -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_plague_client.py b/test/t/test_plague_client.py new file mode 100644 index 0000000..39eac93 --- /dev/null +++ b/test/t/test_plague_client.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="plague-client") +class TestPlagueClient: + @pytest.mark.complete("plague-client ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_pm_hibernate.py b/test/t/test_pm_hibernate.py new file mode 100644 index 0000000..31b4625 --- /dev/null +++ b/test/t/test_pm_hibernate.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="pm-hibernate") +class TestPmHibernate: + @pytest.mark.complete("pm-hibernate -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_pm_is_supported.py b/test/t/test_pm_is_supported.py new file mode 100644 index 0000000..47f064a --- /dev/null +++ b/test/t/test_pm_is_supported.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="pm-is-supported") +class TestPmIsSupported: + @pytest.mark.complete("pm-is-supported -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_pm_powersave.py b/test/t/test_pm_powersave.py new file mode 100644 index 0000000..7630a41 --- /dev/null +++ b/test/t/test_pm_powersave.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="pm-powersave") +class TestPmPowersave: + @pytest.mark.complete("pm-powersave ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_pngfix.py b/test/t/test_pngfix.py new file mode 100644 index 0000000..9b35a39 --- /dev/null +++ b/test/t/test_pngfix.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPngfix: + @pytest.mark.complete("pngfix ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pngfix -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_portinstall.py b/test/t/test_portinstall.py new file mode 100644 index 0000000..eb2118e --- /dev/null +++ b/test/t/test_portinstall.py @@ -0,0 +1,27 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(ignore_env=r"^[+-]PORTSDIR=") +class TestPortinstall: + @pytest.fixture(scope="class") + def portsdir(self, request, bash): + assert_bash_exec(bash, "PORTSDIR=$PWD/../tmp") + assert_bash_exec( + bash, + "command sed -e s,PORTSDIR,$PORTSDIR,g " + "pkgtools/ports/INDEX.dist >$PORTSDIR/INDEX", + ) + assert_bash_exec(bash, "cp $PORTSDIR/INDEX $PORTSDIR/INDEX-5") + request.addfinalizer( + lambda: assert_bash_exec(bash, "rm $PORTSDIR/INDEX{,-5}") + ) + + @pytest.mark.complete("portinstall ", env=dict(PORTSDIR="$PWD/../tmp")) + def test_1(self, completion, portsdir): + assert ( + completion + == "bash-2.05b.007_6 bash-3.1.17 bash-completion-20060301_2 " + "shells/bash shells/bash-completion shells/bash2".split() + ) diff --git a/test/t/test_portsnap.py b/test/t/test_portsnap.py new file mode 100644 index 0000000..4f5878e --- /dev/null +++ b/test/t/test_portsnap.py @@ -0,0 +1,7 @@ +import pytest + + +class TestPortsnap: + @pytest.mark.complete("portsnap ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_portupgrade.py b/test/t/test_portupgrade.py new file mode 100644 index 0000000..0b46bbf --- /dev/null +++ b/test/t/test_portupgrade.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("PKG_DBDIR=$PWD/pkgtools/db",)) +class TestPortupgrade: + @pytest.mark.complete("portupgrade ") + def test_1(self, completion): + assert completion == "a b-c-d".split() diff --git a/test/t/test_postcat.py b/test/t/test_postcat.py new file mode 100644 index 0000000..73922e2 --- /dev/null +++ b/test/t/test_postcat.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPostcat: + @pytest.mark.complete("postcat ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("postcat -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_postconf.py b/test/t/test_postconf.py new file mode 100644 index 0000000..e034956 --- /dev/null +++ b/test/t/test_postconf.py @@ -0,0 +1,20 @@ +import pytest + + +class TestPostconf: + @pytest.mark.complete("postconf -", require_cmd=True) + def test_1(self, completion): + assert len(completion) > 1 + + # Broken configs may abort output of postconf halfway through, so use + # something from early output to not trigger false positives because of + # this. For example, inet_protocols=all but no IPv6 configured: + # postconf: fatal: parameter inet_interfaces: no local interface found + # for ::1 + # ...and output can be cut off somewhere near lmtp_tls_secur*. + # ...or be completely missing, so all we can do is to skip. + @pytest.mark.complete( + "postconf al", require_cmd=True, xfail="! postconf &>/dev/null" + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_postfix.py b/test/t/test_postfix.py new file mode 100644 index 0000000..10020b0 --- /dev/null +++ b/test/t/test_postfix.py @@ -0,0 +1,22 @@ +import getpass + +import pytest + + +class TestPostfix: + @pytest.mark.complete("postfix ") + def test_1(self, completion): + assert completion + + @pytest.mark.xfail( + getpass.getuser() != "root", + reason="Likely outputs usage only for root", + ) + @pytest.mark.complete( + "postfix -", + require_cmd=True, + xfail="! type unbuffer &>/dev/null", + sleep_after_tab=2, # postfix is slow to output usage + ) + def test_options(self, completion): + assert completion diff --git a/test/t/test_postmap.py b/test/t/test_postmap.py new file mode 100644 index 0000000..ee3eee7 --- /dev/null +++ b/test/t/test_postmap.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPostmap: + @pytest.mark.complete("postmap ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("postmap -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_postsuper.py b/test/t/test_postsuper.py new file mode 100644 index 0000000..b74de8e --- /dev/null +++ b/test/t/test_postsuper.py @@ -0,0 +1,7 @@ +import pytest + + +class TestPostsuper: + @pytest.mark.complete("postsuper ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_povray.py b/test/t/test_povray.py new file mode 100644 index 0000000..99d08ea --- /dev/null +++ b/test/t/test_povray.py @@ -0,0 +1,7 @@ +import pytest + + +class TestPovray: + @pytest.mark.complete("povray ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_pr.py b/test/t/test_pr.py new file mode 100644 index 0000000..c790a86 --- /dev/null +++ b/test/t/test_pr.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPr: + @pytest.mark.complete("pr ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pr -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_prelink.py b/test/t/test_prelink.py new file mode 100644 index 0000000..e75b969 --- /dev/null +++ b/test/t/test_prelink.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPrelink: + @pytest.mark.complete("prelink ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("prelink -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_printenv.py b/test/t/test_printenv.py new file mode 100644 index 0000000..540c4f6 --- /dev/null +++ b/test/t/test_printenv.py @@ -0,0 +1,19 @@ +import pytest + + +class TestPrintenv: + @pytest.mark.complete("printenv ") + def test_empty(self, completion): + assert completion + + @pytest.mark.complete("printenv PAT") + def test_path(self, completion): + assert completion == "H" or "PATH" in completion + + @pytest.mark.complete( + "printenv -", + require_cmd=True, + xfail="! printenv --help 2>&1 | command grep -qF -- ' -'", + ) + def test_options(self, completion): + assert completion diff --git a/test/t/test_protoc.py b/test/t/test_protoc.py new file mode 100644 index 0000000..744b99f --- /dev/null +++ b/test/t/test_protoc.py @@ -0,0 +1,20 @@ +import pytest + + +class TestProtoc: + @pytest.mark.complete("protoc ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("protoc -", require_cmd=True) + def test_2(self, completion): + assert completion + assert any( + x.endswith("_out") or x.endswith("_out=") for x in completion + ) + + @pytest.mark.complete( + "protoc --non_existent_plugin_out ", cwd="shared/default" + ) + def test_all_out(self, completion): + assert completion == ["bar bar.d/", "foo.d/"] diff --git a/test/t/test_psql.py b/test/t/test_psql.py new file mode 100644 index 0000000..ffd6c05 --- /dev/null +++ b/test/t/test_psql.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPsql: + + # --help can fail due to missing package dependencies, e.g. on Ubuntu 14 + @pytest.mark.complete( + "psql -", require_cmd=True, xfail="! psql --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_ptx.py b/test/t/test_ptx.py new file mode 100644 index 0000000..9ddc91c --- /dev/null +++ b/test/t/test_ptx.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPtx: + @pytest.mark.complete("ptx ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ptx -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_puppet.py b/test/t/test_puppet.py new file mode 100644 index 0000000..470f33a --- /dev/null +++ b/test/t/test_puppet.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPuppet: + @pytest.mark.complete("puppet ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("puppet agent --") + def test_2(self, completion): + assert completion diff --git a/test/t/test_pushd.py b/test/t/test_pushd.py new file mode 100644 index 0000000..290e1d1 --- /dev/null +++ b/test/t/test_pushd.py @@ -0,0 +1,7 @@ +import pytest + + +class TestPushd: + @pytest.mark.complete("pushd ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_pv.py b/test/t/test_pv.py new file mode 100644 index 0000000..ad04c47 --- /dev/null +++ b/test/t/test_pv.py @@ -0,0 +1,15 @@ +import pytest + + +class TestPv: + @pytest.mark.complete("pv ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pv -", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("pv --pidfile ") + def test_3(self, completion): + assert completion diff --git a/test/t/test_pvchange.py b/test/t/test_pvchange.py new file mode 100644 index 0000000..4b0a94c --- /dev/null +++ b/test/t/test_pvchange.py @@ -0,0 +1,9 @@ +import pytest + + +class TestPvchange: + @pytest.mark.complete( + "pvchange --", require_cmd=True, xfail="! pvchange --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_pvcreate.py b/test/t/test_pvcreate.py new file mode 100644 index 0000000..2847c47 --- /dev/null +++ b/test/t/test_pvcreate.py @@ -0,0 +1,9 @@ +import pytest + + +class TestPvcreate: + @pytest.mark.complete( + "pvcreate --", require_cmd=True, xfail="! pvcreate --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_pvdisplay.py b/test/t/test_pvdisplay.py new file mode 100644 index 0000000..9d1ea83 --- /dev/null +++ b/test/t/test_pvdisplay.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPvdisplay: + @pytest.mark.complete( + "pvdisplay --", + require_cmd=True, + xfail="! pvdisplay --help &>/dev/null", + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_pvmove.py b/test/t/test_pvmove.py new file mode 100644 index 0000000..e0e2ee8 --- /dev/null +++ b/test/t/test_pvmove.py @@ -0,0 +1,9 @@ +import pytest + + +class TestPvmove: + @pytest.mark.complete( + "pvmove --", require_cmd=True, xfail="! pvmove --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_pvremove.py b/test/t/test_pvremove.py new file mode 100644 index 0000000..c9c031a --- /dev/null +++ b/test/t/test_pvremove.py @@ -0,0 +1,9 @@ +import pytest + + +class TestPvremove: + @pytest.mark.complete( + "pvremove --", require_cmd=True, xfail="! pvremove --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_pvs.py b/test/t/test_pvs.py new file mode 100644 index 0000000..ac173a7 --- /dev/null +++ b/test/t/test_pvs.py @@ -0,0 +1,9 @@ +import pytest + + +class TestPvs: + @pytest.mark.complete( + "pvs --", require_cmd=True, xfail="! pvs --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_pvscan.py b/test/t/test_pvscan.py new file mode 100644 index 0000000..e278956 --- /dev/null +++ b/test/t/test_pvscan.py @@ -0,0 +1,9 @@ +import pytest + + +class TestPvscan: + @pytest.mark.complete( + "pvscan --", require_cmd=True, xfail="! pvscan --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_pwck.py b/test/t/test_pwck.py new file mode 100644 index 0000000..1e36f87 --- /dev/null +++ b/test/t/test_pwck.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPwck: + @pytest.mark.complete("pwck ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pwck -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_pwd.py b/test/t/test_pwd.py new file mode 100644 index 0000000..fe7dd08 --- /dev/null +++ b/test/t/test_pwd.py @@ -0,0 +1,7 @@ +import pytest + + +class TestPwd: + @pytest.mark.complete("pwd -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_pwdx.py b/test/t/test_pwdx.py new file mode 100644 index 0000000..552c82c --- /dev/null +++ b/test/t/test_pwdx.py @@ -0,0 +1,19 @@ +import pytest + + +class TestPwdx: + @pytest.mark.complete("pwdx ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "pwdx -", + require_cmd=True, + xfail=( + "! (pwdx --help 2>&1 || :) | " + "command grep -vF 'invalid process id: --help' | " + "command grep -q -- '[[:space:]]-'" + ), + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_pwgen.py b/test/t/test_pwgen.py new file mode 100644 index 0000000..20ecd73 --- /dev/null +++ b/test/t/test_pwgen.py @@ -0,0 +1,7 @@ +import pytest + + +class TestPwgen: + @pytest.mark.complete("pwgen -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_pycodestyle.py b/test/t/test_pycodestyle.py new file mode 100644 index 0000000..4b4f3a4 --- /dev/null +++ b/test/t/test_pycodestyle.py @@ -0,0 +1,15 @@ +import pytest + + +class TestPycodestyle: + @pytest.mark.complete("pycodestyle ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pycodestyle -", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("pycodestyle --doesnt-exist=") + def test_3(self, completion): + assert not completion diff --git a/test/t/test_pydoc.py b/test/t/test_pydoc.py new file mode 100644 index 0000000..7cf7eb5 --- /dev/null +++ b/test/t/test_pydoc.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPydoc: + @pytest.mark.complete("pydoc r", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pydoc -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_pydocstyle.py b/test/t/test_pydocstyle.py new file mode 100644 index 0000000..1f44320 --- /dev/null +++ b/test/t/test_pydocstyle.py @@ -0,0 +1,13 @@ +import pytest + + +class TestPydocstyle: + @pytest.mark.complete("pydocstyle ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "pydocstyle -", require_cmd=True, require_longopt=True + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_pyflakes.py b/test/t/test_pyflakes.py new file mode 100644 index 0000000..9670321 --- /dev/null +++ b/test/t/test_pyflakes.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPyflakes: + @pytest.mark.complete("pyflakes ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pyflakes -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_pylint.py b/test/t/test_pylint.py new file mode 100644 index 0000000..43a4c43 --- /dev/null +++ b/test/t/test_pylint.py @@ -0,0 +1,11 @@ +import pytest + + +class TestPylint: + @pytest.mark.complete("pylint --v", require_cmd=True, require_longopt=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pylint --confidence=HIGH,") + def test_2(self, completion): + assert completion diff --git a/test/t/test_pylint_3.py b/test/t/test_pylint_3.py new file mode 100644 index 0000000..ee498c3 --- /dev/null +++ b/test/t/test_pylint_3.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="pylint-3") +class TestPylint3: + @pytest.mark.complete("pylint-3 --v", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pylint-3 http.clien") + def test_2(self, completion): + assert completion diff --git a/test/t/test_pytest.py b/test/t/test_pytest.py new file mode 100644 index 0000000..e70c7a5 --- /dev/null +++ b/test/t/test_pytest.py @@ -0,0 +1,50 @@ +import inspect + +import pytest + + +class TestPytest: + @pytest.mark.complete("pytest ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("pytest -") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("pytest ../t/test_pytest.py:") + def test_classes_and_functions(self, completion): + assert completion == ":TestPytest :test_function_canary".split() + + @pytest.mark.complete("pytest ../t/test_pytest.py::TestPytest::") + def test_class_methods(self, completion): + methods = [ + x[0] + for x in inspect.getmembers(self, predicate=inspect.ismethod) + if x[0].startswith("test_") + ] + assert completion == methods + + @pytest.mark.complete("pytest pytest/test_async.py:") + def test_classes_and_async_functions(self, completion): + assert completion == ":Testing :test_positive".split() + + @pytest.mark.complete("pytest pytest/test_async.py::Testing::") + def test_async_class_methods(self, completion): + assert completion == "test_positive" + + def non_test_cananary_method(self): + pass + + +def test_function_canary(): + pass + + +def non_test_canary(): + pass + + +class NonTestCanaryClass: + def test_is_this_function_not(self): + pass diff --git a/test/t/test_python.py b/test/t/test_python.py new file mode 100644 index 0000000..5308dcb --- /dev/null +++ b/test/t/test_python.py @@ -0,0 +1,39 @@ +import pytest + + +class TestPython: + @pytest.mark.complete("python ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("python -", require_cmd=True) + def test_2(self, completion): + assert len(completion) > 1 + + @pytest.mark.complete("python -c ") + def test_3(self, completion): + assert not completion + + @pytest.mark.complete("python shared/default/") + def test_4(self, completion): + assert completion == ["bar bar.d/", "foo.d/"] + + @pytest.mark.complete("python -c foo shared/default/") + def test_5(self, completion): + assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"] + + @pytest.mark.complete("python -c foo -") + def test_6(self, completion): + assert not completion + + @pytest.mark.complete("python -m foo -") + def test_7(self, completion): + assert not completion + + @pytest.mark.complete("python -m sy", require_cmd=True) + def test_8(self, completion): + assert completion + + @pytest.mark.complete("python -m json.", require_cmd=True) + def test_9(self, completion): + assert "json.tool" in completion diff --git a/test/t/test_python3.py b/test/t/test_python3.py new file mode 100644 index 0000000..a4f6d96 --- /dev/null +++ b/test/t/test_python3.py @@ -0,0 +1,39 @@ +import pytest + + +class TestPython3: + @pytest.mark.complete("python3 ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("python3 -", require_cmd=True) + def test_2(self, completion): + assert len(completion) > 1 + + @pytest.mark.complete("python3 -c ") + def test_3(self, completion): + assert not completion + + @pytest.mark.complete("python3 shared/default/") + def test_4(self, completion): + assert completion == ["bar bar.d/", "foo.d/"] + + @pytest.mark.complete("python3 -c foo shared/default/") + def test_5(self, completion): + assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"] + + @pytest.mark.complete("python3 -c foo -") + def test_6(self, completion): + assert not completion + + @pytest.mark.complete("python3 -m foo -") + def test_7(self, completion): + assert not completion + + @pytest.mark.complete("python3 -m sy", require_cmd=True) + def test_8(self, completion): + assert completion + + @pytest.mark.complete("python3 -m json.", require_cmd=True) + def test_9(self, completion): + assert "json.tool" in completion diff --git a/test/t/test_pyvenv.py b/test/t/test_pyvenv.py new file mode 100644 index 0000000..5e9152a --- /dev/null +++ b/test/t/test_pyvenv.py @@ -0,0 +1,7 @@ +import pytest + + +class TestPyvenv: + @pytest.mark.complete("pyvenv ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_qemu.py b/test/t/test_qemu.py new file mode 100644 index 0000000..129c0b4 --- /dev/null +++ b/test/t/test_qemu.py @@ -0,0 +1,11 @@ +import pytest + + +class TestQemu: + @pytest.mark.complete("qemu ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("qemu -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_qrunner.py b/test/t/test_qrunner.py new file mode 100644 index 0000000..4e4cdd8 --- /dev/null +++ b/test/t/test_qrunner.py @@ -0,0 +1,7 @@ +import pytest + + +class TestQrunner: + @pytest.mark.complete("qrunner -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_querybts.py b/test/t/test_querybts.py new file mode 100644 index 0000000..9c81d13 --- /dev/null +++ b/test/t/test_querybts.py @@ -0,0 +1,7 @@ +import pytest + + +class TestQuerybts: + @pytest.mark.complete("querybts --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_quota.py b/test/t/test_quota.py new file mode 100644 index 0000000..c744535 --- /dev/null +++ b/test/t/test_quota.py @@ -0,0 +1,11 @@ +import pytest + + +class TestQuota: + @pytest.mark.complete("quota ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("quota -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_quotacheck.py b/test/t/test_quotacheck.py new file mode 100644 index 0000000..8140604 --- /dev/null +++ b/test/t/test_quotacheck.py @@ -0,0 +1,7 @@ +import pytest + + +class TestQuotacheck: + @pytest.mark.complete("quotacheck -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_quotaon.py b/test/t/test_quotaon.py new file mode 100644 index 0000000..c4386c6 --- /dev/null +++ b/test/t/test_quotaon.py @@ -0,0 +1,7 @@ +import pytest + + +class TestQuotaon: + @pytest.mark.complete("quotaon -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_radvdump.py b/test/t/test_radvdump.py new file mode 100644 index 0000000..a8a16d9 --- /dev/null +++ b/test/t/test_radvdump.py @@ -0,0 +1,11 @@ +import pytest + + +class TestRadvdump: + @pytest.mark.complete("radvdump ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("radvdump -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_rcs.py b/test/t/test_rcs.py new file mode 100644 index 0000000..985bb44 --- /dev/null +++ b/test/t/test_rcs.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRcs: + @pytest.mark.complete("rcs ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_rcsdiff.py b/test/t/test_rcsdiff.py new file mode 100644 index 0000000..d54934c --- /dev/null +++ b/test/t/test_rcsdiff.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRcsdiff: + @pytest.mark.complete("rcsdiff ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_rdesktop.py b/test/t/test_rdesktop.py new file mode 100644 index 0000000..f20ca51 --- /dev/null +++ b/test/t/test_rdesktop.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRdesktop: + @pytest.mark.complete("rdesktop -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_rdict.py b/test/t/test_rdict.py new file mode 100644 index 0000000..da6fb1b --- /dev/null +++ b/test/t/test_rdict.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRdict: + @pytest.mark.complete("rdict --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_readelf.py b/test/t/test_readelf.py new file mode 100644 index 0000000..07ce347 --- /dev/null +++ b/test/t/test_readelf.py @@ -0,0 +1,7 @@ +import pytest + + +class TestReadelf: + @pytest.mark.complete("readelf --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_readonly.py b/test/t/test_readonly.py new file mode 100644 index 0000000..0ac310c --- /dev/null +++ b/test/t/test_readonly.py @@ -0,0 +1,7 @@ +import pytest + + +class TestReadonly: + @pytest.mark.complete("readonly BASH_ARG") + def test_1(self, completion): + assert completion diff --git a/test/t/test_remove_members.py b/test/t/test_remove_members.py new file mode 100644 index 0000000..a3b0afd --- /dev/null +++ b/test/t/test_remove_members.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRemoveMembers: + @pytest.mark.complete("remove_members --") + def test_1(self, completion): + assert completion diff --git a/test/t/test_removepkg.py b/test/t/test_removepkg.py new file mode 100644 index 0000000..9fd7a9d --- /dev/null +++ b/test/t/test_removepkg.py @@ -0,0 +1,15 @@ +import os + +import pytest + + +@pytest.mark.bashcomp(ignore_env=r"^\+ROOT=") +class TestRemovepkg: + @pytest.mark.complete("removepkg -") + def test_1(self, completion): + assert completion == "-copy -keep -preserve -warn".split() + + @pytest.mark.complete("removepkg ", env=dict(ROOT="./slackware")) + def test_2(self, completion): + files = sorted(x for x in os.listdir("slackware/var/log/packages")) + assert completion == files diff --git a/test/t/test_renice.py b/test/t/test_renice.py new file mode 100644 index 0000000..20d59a3 --- /dev/null +++ b/test/t/test_renice.py @@ -0,0 +1,11 @@ +import pytest + + +class TestRenice: + @pytest.mark.complete("renice 1") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("renice -g ") + def test_2(self, completion): + assert completion diff --git a/test/t/test_repomanage.py b/test/t/test_repomanage.py new file mode 100644 index 0000000..bdaba15 --- /dev/null +++ b/test/t/test_repomanage.py @@ -0,0 +1,11 @@ +import pytest + + +class TestRepomanage: + @pytest.mark.complete("repomanage ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("repomanage -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_reportbug.py b/test/t/test_reportbug.py new file mode 100644 index 0000000..2c57b56 --- /dev/null +++ b/test/t/test_reportbug.py @@ -0,0 +1,7 @@ +import pytest + + +class TestReportbug: + @pytest.mark.complete("reportbug --m", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_reptyr.py b/test/t/test_reptyr.py new file mode 100644 index 0000000..7c27cb5 --- /dev/null +++ b/test/t/test_reptyr.py @@ -0,0 +1,11 @@ +import pytest + + +class TestReptyr: + @pytest.mark.complete("reptyr ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("reptyr -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_resolvconf.py b/test/t/test_resolvconf.py new file mode 100644 index 0000000..fdcf584 --- /dev/null +++ b/test/t/test_resolvconf.py @@ -0,0 +1,7 @@ +import pytest + + +class TestResolvconf: + @pytest.mark.complete("resolvconf -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_rfcomm.py b/test/t/test_rfcomm.py new file mode 100644 index 0000000..c30d23b --- /dev/null +++ b/test/t/test_rfcomm.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRfcomm: + @pytest.mark.complete("rfcomm ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_rfkill.py b/test/t/test_rfkill.py new file mode 100644 index 0000000..f8248ff --- /dev/null +++ b/test/t/test_rfkill.py @@ -0,0 +1,11 @@ +import pytest + + +class TestRfkill: + @pytest.mark.complete("rfkill ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("rfkill -") + def test_2(self, completion): + assert completion diff --git a/test/t/test_ri.py b/test/t/test_ri.py new file mode 100644 index 0000000..420b6cb --- /dev/null +++ b/test/t/test_ri.py @@ -0,0 +1,16 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("export RI='-d ri'",)) +class TestRi: + @pytest.mark.complete("ri -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ri --dump=ri/") + def test_2(self, completion): + assert completion == "BashCompletion/ cache.ri".split() + + @pytest.mark.complete("ri BashCompletio", require_cmd=True) + def test_3(self, completion): + assert completion == "n" diff --git a/test/t/test_rlog.py b/test/t/test_rlog.py new file mode 100644 index 0000000..87a4da1 --- /dev/null +++ b/test/t/test_rlog.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRlog: + @pytest.mark.complete("rlog ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_rm.py b/test/t/test_rm.py new file mode 100644 index 0000000..6fda5a1 --- /dev/null +++ b/test/t/test_rm.py @@ -0,0 +1,11 @@ +import pytest + + +class TestRm: + @pytest.mark.complete("rm ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("rm -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_rmdir.py b/test/t/test_rmdir.py new file mode 100644 index 0000000..b981677 --- /dev/null +++ b/test/t/test_rmdir.py @@ -0,0 +1,16 @@ +import pytest + + +class TestRmdir: + @pytest.mark.complete("rmdir ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("/bin/rmdir shared/default/") + def test_2(self, completion): + """Should complete dirs only, also when invoked using full path.""" + assert completion == ["bar bar.d/", "foo.d/"] + + @pytest.mark.complete("rmdir -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_rmlist.py b/test/t/test_rmlist.py new file mode 100644 index 0000000..3a6c6ec --- /dev/null +++ b/test/t/test_rmlist.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRmlist: + @pytest.mark.complete("rmlist -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_rmmod.py b/test/t/test_rmmod.py new file mode 100644 index 0000000..5528705 --- /dev/null +++ b/test/t/test_rmmod.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRmmod: + @pytest.mark.complete("rmmod -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_route.py b/test/t/test_route.py new file mode 100644 index 0000000..741ef58 --- /dev/null +++ b/test/t/test_route.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRoute: + @pytest.mark.complete("route ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_rpcdebug.py b/test/t/test_rpcdebug.py new file mode 100644 index 0000000..e92bdee --- /dev/null +++ b/test/t/test_rpcdebug.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRpcdebug: + @pytest.mark.complete("rpcdebug -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_rpm.py b/test/t/test_rpm.py new file mode 100644 index 0000000..e6f7198 --- /dev/null +++ b/test/t/test_rpm.py @@ -0,0 +1,15 @@ +import pytest + + +class TestRpm: + @pytest.mark.complete("rpm ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("rpm -q ", skipif='test -z "$(rpm -qa 2>/dev/null)"') + def test_2(self, completion): + assert completion + + @pytest.mark.complete("rpm -", require_cmd=True) + def test_3(self, completion): + assert completion diff --git a/test/t/test_rpm2tgz.py b/test/t/test_rpm2tgz.py new file mode 100644 index 0000000..ad6e8bc --- /dev/null +++ b/test/t/test_rpm2tgz.py @@ -0,0 +1,26 @@ +import os + +import pytest + + +class TestRpm2tgz: + @pytest.mark.complete("rpm2tgz -") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("rpm2tgz ", cwd="slackware/home") + def test_2(self, completion): + expected = sorted( + [ + "%s/" % x + for x in os.listdir("slackware/home") + if os.path.isdir("slackware/home/%s" % x) + ] + + [ + x + for x in os.listdir("slackware/home") + if os.path.isfile("slackware/home/%s" % x) + and x.endswith(".rpm") + ] + ) + assert completion == expected diff --git a/test/t/test_rpmbuild.py b/test/t/test_rpmbuild.py new file mode 100644 index 0000000..06c8087 --- /dev/null +++ b/test/t/test_rpmbuild.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRpmbuild: + @pytest.mark.complete("rpmbuild -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_rrdtool.py b/test/t/test_rrdtool.py new file mode 100644 index 0000000..9da8310 --- /dev/null +++ b/test/t/test_rrdtool.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRrdtool: + @pytest.mark.complete("rrdtool ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_rsync.py b/test/t/test_rsync.py new file mode 100644 index 0000000..d54ce6f --- /dev/null +++ b/test/t/test_rsync.py @@ -0,0 +1,16 @@ +import pytest + + +@pytest.mark.bashcomp(ignore_env=r"^[+-]_scp_path_esc=") +class TestRsync: + @pytest.mark.complete("rsync ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("rsync --rsh ") + def test_2(self, completion): + assert completion == "rsh ssh".split() + + @pytest.mark.complete("rsync --rsh=") + def test_3(self, completion): + assert completion == "rsh ssh".split() diff --git a/test/t/test_rtcwake.py b/test/t/test_rtcwake.py new file mode 100644 index 0000000..19d1dfe --- /dev/null +++ b/test/t/test_rtcwake.py @@ -0,0 +1,11 @@ +import pytest + + +class TestRtcwake: + @pytest.mark.complete("rtcwake ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("rtcwake -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_runuser.py b/test/t/test_runuser.py new file mode 100644 index 0000000..01a6d88 --- /dev/null +++ b/test/t/test_runuser.py @@ -0,0 +1,7 @@ +import pytest + + +class TestRunuser: + @pytest.mark.complete("runuser ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_sbcl.py b/test/t/test_sbcl.py new file mode 100644 index 0000000..f05741a --- /dev/null +++ b/test/t/test_sbcl.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSbcl: + @pytest.mark.complete("sbcl shared/default/") + def test_1(self, completion): + assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"] diff --git a/test/t/test_sbcl_mt.py b/test/t/test_sbcl_mt.py new file mode 100644 index 0000000..c396539 --- /dev/null +++ b/test/t/test_sbcl_mt.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="sbcl-mt") +class TestSbclMt: + @pytest.mark.complete("sbcl-mt shared/default/") + def test_1(self, completion): + assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"] diff --git a/test/t/test_sbopkg.py b/test/t/test_sbopkg.py new file mode 100644 index 0000000..44f1521 --- /dev/null +++ b/test/t/test_sbopkg.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSbopkg: + @pytest.mark.complete("sbopkg -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_scp.py b/test/t/test_scp.py new file mode 100644 index 0000000..66b8da2 --- /dev/null +++ b/test/t/test_scp.py @@ -0,0 +1,79 @@ +from itertools import chain + +import pytest + +from conftest import assert_bash_exec + +LIVE_HOST = "bash_completion" + + +class TestScp: + @pytest.mark.complete("scp -F config ", cwd="scp") + def test_basic(self, hosts, completion): + expected = sorted( + chain( + ( + "%s:" % x + for x in chain( + hosts, + # From fixtures/scp/config + "gee hut".split(), + # From fixtures/scp/known_hosts + "blah doo ike".split(), + ) + ), + # Local filenames + ["config", "known_hosts", r"spaced\ \ conf"], + ) + ) + assert completion == expected + + @pytest.mark.complete("scp -F 'spaced conf' ", cwd="scp") + def test_basic_spaced_conf(self, hosts, completion): + expected = sorted( + chain( + ( + "%s:" % x + for x in chain( + hosts, + # From "fixtures/scp/spaced conf" + "gee jar".split(), + # From fixtures/scp/known_hosts + "blah doo ike".split(), + ) + ), + # Local filenames + ["config", "known_hosts", r"spaced\ \ conf"], + ) + ) + assert completion == expected + + @pytest.mark.complete("scp -F") + def test_capital_f_without_space(self, completion): + assert completion + assert not any( + "option requires an argument -- F" in x for x in completion + ) + + @pytest.fixture(scope="class") + def live_pwd(self, bash): + try: + return assert_bash_exec( + bash, + "ssh -o 'Batchmode yes' -o 'ConnectTimeout 1' " + "%s pwd 2>/dev/null" % LIVE_HOST, + want_output=True, + ).strip() + except AssertionError: + pytest.skip("Live host %s not available" % LIVE_HOST) + + @pytest.mark.complete("scp %s:" % LIVE_HOST, sleep_after_tab=2) + def test_live(self, live_pwd, completion): + """ + To support this test, configure a HostName entry for LIVE_HOST + in ssh's configs, e.g. ~/.ssh/config or /etc/ssh/ssh_config. + + Connection to it must open sufficiently quickly for the + ConnectTimeout and sleep_after_tab settings. + """ + assert completion == "%s:%s/" % (LIVE_HOST, live_pwd) diff --git a/test/t/test_screen.py b/test/t/test_screen.py new file mode 100644 index 0000000..3e98837 --- /dev/null +++ b/test/t/test_screen.py @@ -0,0 +1,48 @@ +import pytest + + +class TestScreen: + @pytest.mark.complete("screen -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("screen -c shared/default/") + def test_2(self, completion): + assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"] + + @pytest.mark.complete("screen cat ") + def test_3(self, completion): + assert completion + + # Assume at least vt100 and friends are there + @pytest.mark.complete("screen -T vt") + def test_4(self, completion): + assert completion + + @pytest.mark.complete("screen -T foo ca") + def test_5(self, completion): + assert completion == "t" or "cat" in completion + + @pytest.mark.complete("screen //") + def test_telnet(self, completion): + assert completion == "telnet" + + @pytest.mark.complete("screen cat //") + def test_not_telnet(self, completion): + assert completion != "telnet" + + @pytest.mark.complete("screen //telnet ", env=dict(HOME="$PWD/shared")) + def test_telnet_first_arg(self, completion): + assert "bash-completion-canary-host.local" in completion + + @pytest.mark.complete("screen //telnet foo ", env=dict(HOME="$PWD/shared")) + def test_telnet_other_args(self, completion): + assert not completion + + @pytest.mark.complete("screen /dev/ttyUSB0 ") + def test_serial_2nd_arg(self, completion): + assert "19200" in completion + + @pytest.mark.complete("screen /dev/ttyUSB0 9600 ") + def test_serial_3rdplus_arg(self, completion): + assert not completion diff --git a/test/t/test_scrub.py b/test/t/test_scrub.py new file mode 100644 index 0000000..5853ad2 --- /dev/null +++ b/test/t/test_scrub.py @@ -0,0 +1,19 @@ +import pytest + + +class TestScrub: + @pytest.mark.complete("scrub ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("scrub -", require_cmd=True) + def test_2(self, completion): + assert completion + + # Not all scrub versions list available patterns in --help output + @pytest.mark.complete( + "scrub -p ", + xfail="! (scrub --help 2>&1 || :) | command grep -q ^Available", + ) + def test_3(self, completion): + assert completion diff --git a/test/t/test_sdptool.py b/test/t/test_sdptool.py new file mode 100644 index 0000000..095d90e --- /dev/null +++ b/test/t/test_sdptool.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSdptool: + @pytest.mark.complete("sdptool ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_secret_tool.py b/test/t/test_secret_tool.py new file mode 100644 index 0000000..cbfc0cb --- /dev/null +++ b/test/t/test_secret_tool.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="secret-tool",) +class TestSecretTool: + @pytest.mark.complete("secret-tool ", require_cmd=True) + def test_modes(self, completion): + assert "store" in completion + + @pytest.mark.complete("secret-tool search ") + def test_no_complete(self, completion): + assert not completion diff --git a/test/t/test_sed.py b/test/t/test_sed.py new file mode 100644 index 0000000..53079c9 --- /dev/null +++ b/test/t/test_sed.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSed: + @pytest.mark.complete("sed --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_seq.py b/test/t/test_seq.py new file mode 100644 index 0000000..b672238 --- /dev/null +++ b/test/t/test_seq.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSeq: + @pytest.mark.complete("seq --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_service.py b/test/t/test_service.py new file mode 100644 index 0000000..7ce4312 --- /dev/null +++ b/test/t/test_service.py @@ -0,0 +1,7 @@ +import pytest + + +class TestService: + @pytest.mark.complete("service ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_set.py b/test/t/test_set.py new file mode 100644 index 0000000..08c1671 --- /dev/null +++ b/test/t/test_set.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSet: + @pytest.mark.complete("set no") + def test_1(self, completion): + assert completion diff --git a/test/t/test_setquota.py b/test/t/test_setquota.py new file mode 100644 index 0000000..76fd7b9 --- /dev/null +++ b/test/t/test_setquota.py @@ -0,0 +1,11 @@ +import pytest + + +class TestSetquota: + @pytest.mark.complete("setquota ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("setquota -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_sftp.py b/test/t/test_sftp.py new file mode 100644 index 0000000..a421a44 --- /dev/null +++ b/test/t/test_sftp.py @@ -0,0 +1,46 @@ +from itertools import chain + +import pytest + + +class TestSftp: + @pytest.mark.complete("sftp -Fsp", cwd="sftp") + def test_1(self, completion): + assert completion == r"aced\ \ conf" + + @pytest.mark.complete("sftp -", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("sftp -F config ", cwd="sftp") + def test_hosts(self, hosts, completion): + expected = sorted( + chain( + hosts, + # From fixtures/sftp/config + "gee hut".split(), + # From fixtures/sftp/known_hosts + "10.10.10.10 doo ike".split(), + ) + ) + assert completion == expected + + @pytest.mark.complete(r"sftp -F spaced\ \ conf ", cwd="sftp") + def test_hosts_spaced_conf(self, hosts, completion): + expected = sorted( + chain( + hosts, + # From "fixtures/sftp/spaced conf" + "gee jar".split(), + # From fixtures/sftp/known_hosts + "10.10.10.10 doo ike".split(), + ) + ) + assert completion == expected + + @pytest.mark.complete("sftp -F") + def test_capital_f_without_space(self, completion): + assert completion + assert not any( + "option requires an argument -- F" in x for x in completion + ) diff --git a/test/t/test_sh.py b/test/t/test_sh.py new file mode 100644 index 0000000..f49a168 --- /dev/null +++ b/test/t/test_sh.py @@ -0,0 +1,19 @@ +import pytest + + +class TestSh: + @pytest.mark.complete("sh -") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("sh +") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("sh -o ") + def test_3(self, completion): + assert completion + + @pytest.mark.complete("sh -c ") + def test_4(self, completion): + assert not completion diff --git a/test/t/test_sha1sum.py b/test/t/test_sha1sum.py new file mode 100644 index 0000000..e4296d4 --- /dev/null +++ b/test/t/test_sha1sum.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSha1sum: + @pytest.mark.complete("sha1sum --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_shar.py b/test/t/test_shar.py new file mode 100644 index 0000000..5c23004 --- /dev/null +++ b/test/t/test_shar.py @@ -0,0 +1,7 @@ +import pytest + + +class TestShar: + @pytest.mark.complete("shar --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_shellcheck.py b/test/t/test_shellcheck.py new file mode 100644 index 0000000..703128f --- /dev/null +++ b/test/t/test_shellcheck.py @@ -0,0 +1,19 @@ +import pytest + + +class TestShellcheck: + @pytest.mark.complete("shellcheck ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("shellcheck -", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("shellcheck --format=", require_cmd=True) + def test_3(self, completion): + assert completion + + @pytest.mark.complete("shellcheck -s ", require_cmd=True) + def test_4(self, completion): + assert "bash" in completion diff --git a/test/t/test_sitecopy.py b/test/t/test_sitecopy.py new file mode 100644 index 0000000..afdeeaa --- /dev/null +++ b/test/t/test_sitecopy.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSitecopy: + @pytest.mark.complete("sitecopy --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_slackpkg.py b/test/t/test_slackpkg.py new file mode 100644 index 0000000..3997bb0 --- /dev/null +++ b/test/t/test_slackpkg.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSlackpkg: + @pytest.mark.complete("slackpkg -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_slapt_get.py b/test/t/test_slapt_get.py new file mode 100644 index 0000000..9244971 --- /dev/null +++ b/test/t/test_slapt_get.py @@ -0,0 +1,44 @@ +import os.path +from tempfile import mkstemp + +import pytest + +from conftest import assert_complete, is_bash_type + + +@pytest.mark.bashcomp(cmd="slapt-get") +class TestSlaptGet: + @pytest.fixture(scope="class") + def slapt_getrc(self, request, bash): + fd, fname = mkstemp(prefix="slapt-getrc.", text=True) + request.addfinalizer(lambda: os.remove(fname)) + with os.fdopen(fd, "w") as f: + print( + "WORKINGDIR=%s/" + % os.path.join(bash.cwd, *"slackware var slapt-get".split()), + file=f, + ) + print("SOURCE=file:///home/", file=f) + return fname + + @pytest.mark.complete("slapt-get -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("slapt-get --up", require_cmd=True) + def test_2(self, completion): + assert completion == "--update --upgrade".split() + + @pytest.mark.complete("slapt-get -c non-existent-file --install ") + def test_3(self, completion): + assert not completion + + def test_install(self, bash, slapt_getrc): + if not is_bash_type(bash, "slapt-get"): + pytest.skip("slapt-get not found") + completion = assert_complete( + bash, "slapt-get -c %s --install " % slapt_getrc + ) + assert completion == sorted( + "abc-4-i686-1 ran-1.2-noarch-1 qwe-2.1-i486-1".split() + ) diff --git a/test/t/test_slapt_src.py b/test/t/test_slapt_src.py new file mode 100644 index 0000000..b55b722 --- /dev/null +++ b/test/t/test_slapt_src.py @@ -0,0 +1,43 @@ +import os +from tempfile import mkstemp + +import pytest + +from conftest import assert_complete, is_bash_type + + +@pytest.mark.bashcomp(cmd="slapt-src") +class TestSlaptSrc: + @pytest.fixture(scope="class") + def slapt_srcrc(self, request, bash): + fd, fname = mkstemp(prefix="slapt-srcrc.", text=True) + request.addfinalizer(lambda: os.remove(fname)) + with os.fdopen(fd, "w") as f: + print( + "BUILDDIR=%s/" + % os.path.join( + bash.cwd, *"slackware usr src slapt-src".split() + ), + file=f, + ) + return fname + + @pytest.mark.complete("slapt-src -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("slapt-src --bu", require_cmd=True) + def test_2(self, completion): + assert completion == "ild" or "--build" in completion + + @pytest.mark.complete("slapt-src --ins", require_cmd=True) + def test_3(self, completion): + assert completion == "tall" or "--install" in completion + + def test_install(self, bash, slapt_srcrc): + if not is_bash_type(bash, "slapt-src"): + pytest.skip("slapt-src not found") + completion = assert_complete( + bash, "slapt-src --config %s --install " % slapt_srcrc + ) + assert completion == "abc:4 qwe:2.1".split() diff --git a/test/t/test_smartctl.py b/test/t/test_smartctl.py new file mode 100644 index 0000000..26d0147 --- /dev/null +++ b/test/t/test_smartctl.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSmartctl: + @pytest.mark.complete("smartctl --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_smbcacls.py b/test/t/test_smbcacls.py new file mode 100644 index 0000000..0fe84e3 --- /dev/null +++ b/test/t/test_smbcacls.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSmbcacls: + @pytest.mark.complete("smbcacls -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_smbclient.py b/test/t/test_smbclient.py new file mode 100644 index 0000000..250ab87 --- /dev/null +++ b/test/t/test_smbclient.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSmbclient: + @pytest.mark.complete("smbclient -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_smbcquotas.py b/test/t/test_smbcquotas.py new file mode 100644 index 0000000..16157ed --- /dev/null +++ b/test/t/test_smbcquotas.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSmbcquotas: + @pytest.mark.complete("smbcquotas -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_smbget.py b/test/t/test_smbget.py new file mode 100644 index 0000000..a6df717 --- /dev/null +++ b/test/t/test_smbget.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSmbget: + @pytest.mark.complete("smbget -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_smbpasswd.py b/test/t/test_smbpasswd.py new file mode 100644 index 0000000..9fae8f2 --- /dev/null +++ b/test/t/test_smbpasswd.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSmbpasswd: + @pytest.mark.complete("smbpasswd -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_smbtar.py b/test/t/test_smbtar.py new file mode 100644 index 0000000..2a0e01e --- /dev/null +++ b/test/t/test_smbtar.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSmbtar: + @pytest.mark.complete("smbtar -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_smbtree.py b/test/t/test_smbtree.py new file mode 100644 index 0000000..2cb6767 --- /dev/null +++ b/test/t/test_smbtree.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSmbtree: + @pytest.mark.complete("smbtree -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_snownews.py b/test/t/test_snownews.py new file mode 100644 index 0000000..a05df98 --- /dev/null +++ b/test/t/test_snownews.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSnownews: + @pytest.mark.complete("snownews --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_sort.py b/test/t/test_sort.py new file mode 100644 index 0000000..d1a4e36 --- /dev/null +++ b/test/t/test_sort.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSort: + @pytest.mark.complete("sort --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_split.py b/test/t/test_split.py new file mode 100644 index 0000000..8c3f1f4 --- /dev/null +++ b/test/t/test_split.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSplit: + @pytest.mark.complete("split --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_spovray.py b/test/t/test_spovray.py new file mode 100644 index 0000000..9033f83 --- /dev/null +++ b/test/t/test_spovray.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSpovray: + @pytest.mark.complete("spovray ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_sqlite3.py b/test/t/test_sqlite3.py new file mode 100644 index 0000000..69a1316 --- /dev/null +++ b/test/t/test_sqlite3.py @@ -0,0 +1,15 @@ +import pytest + + +class TestSqlite3: + @pytest.mark.complete("sqlite3 ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("sqlite3 -", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("sqlite3 -scratch foo ", require_cmd=True) + def test_3(self, completion): + assert not completion diff --git a/test/t/test_ss.py b/test/t/test_ss.py new file mode 100644 index 0000000..716c0fd --- /dev/null +++ b/test/t/test_ss.py @@ -0,0 +1,15 @@ +import pytest + + +class TestSs: + @pytest.mark.complete("ss -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ss -A ", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("ss -A foo,", require_cmd=True) + def test_3(self, completion): + assert completion diff --git a/test/t/test_ssh.py b/test/t/test_ssh.py new file mode 100644 index 0000000..8e95819 --- /dev/null +++ b/test/t/test_ssh.py @@ -0,0 +1,60 @@ +import pytest + +from conftest import assert_complete, partialize + + +class TestSsh: + @pytest.mark.complete("ssh -Fsp", cwd="ssh") + def test_1(self, completion): + assert completion == r"aced\ \ conf" + + @pytest.mark.complete("ssh -F config ls", cwd="ssh") + def test_2(self, completion): + """Should complete both commands and hostname.""" + assert all(x in completion for x in "ls ls_known_host".split()) + + @pytest.mark.complete("ssh bash", cwd="ssh") + def test_3(self, completion): + """ + First arg should not complete with commands. + + Assumes there's no "bash" known host. + """ + assert "bash" not in completion + + @pytest.mark.complete("ssh -vo AddressFamily=") + def test_4(self, completion): + assert completion + + @pytest.mark.xfail # TODO our test facilities don't support case change? + @pytest.mark.complete("ssh -vo userknownhostsf") + def test_5(self, completion): + assert "UserKnownHostsFile=" in completion + + @pytest.mark.complete("ssh -", require_cmd=True) + def test_6(self, completion): + assert completion + + @pytest.mark.complete("ssh -F") + def test_capital_f_without_space(self, completion): + assert completion + assert not any( + "option requires an argument -- F" in x for x in completion + ) + + @pytest.mark.complete("ssh -F nonexistent ") + def test_capital_f_nonexistent(self, completion): + assert completion + + def test_partial_hostname(self, bash, known_hosts): + first_char, partial_hosts = partialize(bash, known_hosts) + completion = assert_complete(bash, "ssh %s" % first_char) + if len(completion) == 1: + assert completion == partial_hosts[0][1:] + else: + assert completion == sorted(x for x in partial_hosts) + + @pytest.mark.parametrize("protocol", "4 6 9".split()) + def test_protocol_option_bundling(self, bash, protocol): + completion = assert_complete(bash, "ssh -%sF ssh/" % protocol) + assert "config" in completion diff --git a/test/t/test_ssh_add.py b/test/t/test_ssh_add.py new file mode 100644 index 0000000..7e49372 --- /dev/null +++ b/test/t/test_ssh_add.py @@ -0,0 +1,17 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="ssh-add") +class TestSshAdd: + @pytest.mark.complete("ssh-add ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "ssh-add -", + require_cmd=True, + xfail="ssh-add --help 2>&1 | " + "command grep -qiF 'Could not open a connection'", + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_ssh_copy_id.py b/test/t/test_ssh_copy_id.py new file mode 100644 index 0000000..e38e901 --- /dev/null +++ b/test/t/test_ssh_copy_id.py @@ -0,0 +1,16 @@ +import pytest + + +@pytest.mark.bashcomp( + cmd="ssh-copy-id", + pre_cmds=( + # Some old versions of ssh-copy-id won't output even usage if no + # identities are found. Try to make sure there is at least one. + "HOME=$PWD/ssh-copy-id", + ), + ignore_env=r"^[+-]_scp_path_esc=", +) +class TestSshCopyId: + @pytest.mark.complete("ssh-copy-id -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_ssh_keygen.py b/test/t/test_ssh_keygen.py new file mode 100644 index 0000000..b773ab4 --- /dev/null +++ b/test/t/test_ssh_keygen.py @@ -0,0 +1,59 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="ssh-keygen") +class TestSshKeygen: + @pytest.mark.complete("ssh-keygen -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ssh-keygen -s foo_key ssh-copy-id/.ssh/") + def test_filedir_pub_at_end_of_s(self, completion): + assert completion + assert all(x.endswith(".pub") for x in completion) + + @pytest.mark.complete("ssh-keygen -s foo_key -n foo,") + def test_usernames_for_n(self, completion): + assert completion + assert not any("," in x for x in completion) + # TODO check that these are usernames + + @pytest.mark.complete("ssh-keygen -s foo_key -h -n foo,") + def test_host_for_h_n(self, completion): + assert completion + assert not any("," in x for x in completion) + # TODO check that these are hostnames + + @pytest.mark.complete("ssh-keygen -Y foo -n ") + def test_n_with_Y(self, completion): + assert not completion + + @pytest.mark.complete("ssh-keygen -r ") + def test_r_without_Y(self, completion): + assert not completion + + @pytest.mark.complete("ssh-keygen -Y foo -r ") + def test_r_with_Y(self, completion): + assert "ssh/" in completion + + @pytest.mark.complete("ssh-keygen -t ecdsa -b ") + def test_ecdsa_b(self, completion): + assert completion + + @pytest.mark.complete("ssh-keygen -t ecdsa-sk -b ") + def test_ecdsa_sk_b(self, completion): + assert not completion + + @pytest.mark.complete("ssh-keygen -O ") + def test_O(self, completion): + assert completion + assert any(x.endswith("=") for x in completion) + + @pytest.mark.complete("ssh-keygen -O force-command=bas") + def test_O_force_command(self, completion): + assert completion + assert not completion.startswith("force-command=") + + @pytest.mark.complete("ssh-keygen -O unknown=") + def test_O_unknown(self, completion): + assert not completion diff --git a/test/t/test_sshfs.py b/test/t/test_sshfs.py new file mode 100644 index 0000000..44daed3 --- /dev/null +++ b/test/t/test_sshfs.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(ignore_env=r"^[+-]_scp_path_esc=") +class TestSshfs: + @pytest.mark.complete("sshfs ./") + def test_1(self, completion): + assert completion diff --git a/test/t/test_sshmitm.py b/test/t/test_sshmitm.py new file mode 100644 index 0000000..671fcf5 --- /dev/null +++ b/test/t/test_sshmitm.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSshmitm: + @pytest.mark.complete("sshmitm -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_sshow.py b/test/t/test_sshow.py new file mode 100644 index 0000000..563bc6b --- /dev/null +++ b/test/t/test_sshow.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSshow: + @pytest.mark.complete("sshow -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_strace.py b/test/t/test_strace.py new file mode 100644 index 0000000..e0d6aed --- /dev/null +++ b/test/t/test_strace.py @@ -0,0 +1,7 @@ +import pytest + + +class TestStrace: + @pytest.mark.complete("strace -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_stream.py b/test/t/test_stream.py new file mode 100644 index 0000000..a46e901 --- /dev/null +++ b/test/t/test_stream.py @@ -0,0 +1,7 @@ +import pytest + + +class TestStream: + @pytest.mark.complete("stream ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_strings.py b/test/t/test_strings.py new file mode 100644 index 0000000..6b5d012 --- /dev/null +++ b/test/t/test_strings.py @@ -0,0 +1,11 @@ +import pytest + + +class TestStrings: + @pytest.mark.complete("strings ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("strings -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_strip.py b/test/t/test_strip.py new file mode 100644 index 0000000..105012f --- /dev/null +++ b/test/t/test_strip.py @@ -0,0 +1,7 @@ +import pytest + + +class TestStrip: + @pytest.mark.complete("strip --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_su.py b/test/t/test_su.py new file mode 100644 index 0000000..9aa064d --- /dev/null +++ b/test/t/test_su.py @@ -0,0 +1,11 @@ +import pytest + + +class TestSu: + @pytest.mark.complete("su ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("su -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_sudo.py b/test/t/test_sudo.py new file mode 100644 index 0000000..a349466 --- /dev/null +++ b/test/t/test_sudo.py @@ -0,0 +1,83 @@ +import pytest + +from conftest import assert_complete + + +class TestSudo: + @pytest.mark.complete("sudo -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("sudo cd fo", cwd="shared/default") + def test_2(self, completion): + assert completion == "o.d/" + assert not completion.endswith(" ") + + @pytest.mark.complete("sudo sh share") + def test_3(self, completion): + assert completion == "d/" + assert not completion.endswith(" ") + + @pytest.mark.complete("sudo mount /dev/sda1 def", cwd="shared") + def test_4(self, completion): + assert completion == "ault/" + assert not completion.endswith(" ") + + @pytest.mark.complete("sudo -e -u root bar foo", cwd="shared/default") + def test_5(self, completion): + assert completion == "foo foo.d/".split() + + def test_6(self, bash, part_full_user): + part, full = part_full_user + completion = assert_complete(bash, "sudo chown %s" % part) + assert completion == full[len(part) :] + assert completion.endswith(" ") + + def test_7(self, bash, part_full_user, part_full_group): + _, user = part_full_user + partgroup, fullgroup = part_full_group + completion = assert_complete( + bash, "sudo chown %s:%s" % (user, partgroup) + ) + assert completion == fullgroup[len(partgroup) :] + assert completion.endswith(" ") + + def test_8(self, bash, part_full_group): + part, full = part_full_group + completion = assert_complete(bash, "sudo chown dot.user:%s" % part) + assert completion == full[len(part) :] + assert completion.endswith(" ") + + @pytest.mark.parametrize( + "prefix", + [ + r"funky\ user:", + "funky.user:", + r"funky\.user:", + r"fu\ nky.user:", + r"f\ o\ o\.\bar:", + r"foo\_b\ a\.r\ :", + ], + ) + def test_9(self, bash, part_full_group, prefix): + """Test preserving special chars in $prefix$partgroup<TAB>.""" + part, full = part_full_group + completion = assert_complete(bash, "sudo chown %s%s" % (prefix, part)) + assert completion == full[len(part) :] + assert completion.endswith(" ") + + def test_10(self, bash, part_full_user, part_full_group): + """Test giving up on degenerate cases instead of spewing junk.""" + _, user = part_full_user + partgroup, _ = part_full_group + for x in range(2, 5): + completion = assert_complete( + bash, "sudo chown %s%s:%s" % (user, x * "\\", partgroup) + ) + assert not completion + + def test_11(self, bash, part_full_group): + """Test graceful fail on colon in user/group name.""" + part, _ = part_full_group + completion = assert_complete(bash, "sudo chown foo:bar:%s" % part) + assert not completion diff --git a/test/t/test_sum.py b/test/t/test_sum.py new file mode 100644 index 0000000..bfb2cf4 --- /dev/null +++ b/test/t/test_sum.py @@ -0,0 +1,11 @@ +import pytest + + +class TestSum: + @pytest.mark.complete("sum ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("sum -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_svcadm.py b/test/t/test_svcadm.py new file mode 100644 index 0000000..76d86a4 --- /dev/null +++ b/test/t/test_svcadm.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSvcadm: + @pytest.mark.complete("svcadm ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_svk.py b/test/t/test_svk.py new file mode 100644 index 0000000..8014bb0 --- /dev/null +++ b/test/t/test_svk.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSvk: + @pytest.mark.complete("svk ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_svn.py b/test/t/test_svn.py new file mode 100644 index 0000000..d8bbee7 --- /dev/null +++ b/test/t/test_svn.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSvn: + @pytest.mark.complete("svn ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_svnadmin.py b/test/t/test_svnadmin.py new file mode 100644 index 0000000..2dc7c6c --- /dev/null +++ b/test/t/test_svnadmin.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSvnadmin: + @pytest.mark.complete("svnadmin ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_svnlook.py b/test/t/test_svnlook.py new file mode 100644 index 0000000..26761b0 --- /dev/null +++ b/test/t/test_svnlook.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSvnlook: + @pytest.mark.complete("svnlook ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_sync_members.py b/test/t/test_sync_members.py new file mode 100644 index 0000000..f0d2dcf --- /dev/null +++ b/test/t/test_sync_members.py @@ -0,0 +1,7 @@ +import pytest + + +class TestSyncMembers: + @pytest.mark.complete("sync_members --") + def test_1(self, completion): + assert completion diff --git a/test/t/test_synclient.py b/test/t/test_synclient.py new file mode 100644 index 0000000..8a31a65 --- /dev/null +++ b/test/t/test_synclient.py @@ -0,0 +1,16 @@ +import pytest + + +class TestSynclient: + + # synclient -l may error out with e.g. + # "Couldn't find synaptics properties. No synaptics driver loaded?" + @pytest.mark.complete( + "synclient ", require_cmd=True, xfail="! synclient -l &>/dev/null" + ) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("synclient -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_sysbench.py b/test/t/test_sysbench.py new file mode 100644 index 0000000..4992d8a --- /dev/null +++ b/test/t/test_sysbench.py @@ -0,0 +1,11 @@ +import pytest + + +class TestSysbench: + @pytest.mark.complete("sysbench ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("sysbench -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_sysctl.py b/test/t/test_sysctl.py new file mode 100644 index 0000000..f8db50b --- /dev/null +++ b/test/t/test_sysctl.py @@ -0,0 +1,15 @@ +import pytest + + +class TestSysctl: + @pytest.mark.complete("sysctl -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "sysctl kern", + require_cmd=True, + xfail="! sysctl -N -a 2>/dev/null | command grep -q ^kern", + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_tac.py b/test/t/test_tac.py new file mode 100644 index 0000000..db433cc --- /dev/null +++ b/test/t/test_tac.py @@ -0,0 +1,7 @@ +import pytest + + +class TestTac: + @pytest.mark.complete("tac --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_tail.py b/test/t/test_tail.py new file mode 100644 index 0000000..6f2b3c6 --- /dev/null +++ b/test/t/test_tail.py @@ -0,0 +1,7 @@ +import pytest + + +class TestTail: + @pytest.mark.complete("tail --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_tar.py b/test/t/test_tar.py new file mode 100644 index 0000000..4518d0b --- /dev/null +++ b/test/t/test_tar.py @@ -0,0 +1,120 @@ +import re + +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(ignore_env=r"^-declare -f _tar$") +class TestTar: + @pytest.fixture(scope="class") + def gnu_tar(self, bash): + got = assert_bash_exec(bash, "tar --version || :", want_output=True) + if not re.search(r"\bGNU ", got): + pytest.skip("Not GNU tar") + + @pytest.mark.complete("tar ") + def test_1(self, completion): + assert completion + + # Test "f" when mode is not as first option + @pytest.mark.complete("tar zfc ", cwd="tar") + def test_2(self, completion): + assert completion == "dir/ dir2/".split() + + @pytest.mark.complete("tar cf ", cwd="tar") + def test_3(self, completion): + assert completion == "dir/ dir2/".split() + + @pytest.mark.complete("tar tf archive.tar.xz dir/file", cwd="tar") + def test_4(self, completion): + assert completion == "dir/fileA dir/fileB dir/fileC".split() + + @pytest.mark.complete("tar cTfvv NOT_EXISTS DONT_CREATE.tar ", cwd="tar") + def test_5(self, completion): + assert completion == "archive.tar.xz dir/ dir2/ escape.tar".split() + + @pytest.mark.complete("tar xvf ", cwd="tar") + def test_6(self, completion): + assert completion == "archive.tar.xz dir/ dir2/ escape.tar".split() + + @pytest.mark.complete("tar -c") + def test_7(self, completion, gnu_tar): + """Test short options.""" + assert completion + + @pytest.mark.complete("tar -zcf ", cwd="tar") + def test_8(self, completion, gnu_tar): + """Test mode not as first option.""" + assert completion == "dir/ dir2/".split() + + @pytest.mark.complete("tar -cf ", cwd="tar") + def test_9(self, completion, gnu_tar): + """Test that we don't suggest rewriting existing archive.""" + assert completion == "dir/ dir2/".split() + + @pytest.mark.complete("tar -c --file ", cwd="tar") + def test_10(self, completion, gnu_tar): + assert completion == "dir/ dir2/".split() + + @pytest.mark.complete("tar -cvv --file ", cwd="tar") + def test_11(self, completion, gnu_tar): + assert completion == "dir/ dir2/".split() + + @pytest.mark.complete("tar -tf archive.tar.xz dir/file", cwd="tar") + def test_12(self, completion, gnu_tar): + """Test archive listing.""" + assert completion == "dir/fileA dir/fileB dir/fileC".split() + + @pytest.mark.complete("tar -t --file archive.tar.xz dir/file", cwd="tar") + def test_13(self, completion, gnu_tar): + """Test archive listing with --file.""" + assert completion == "dir/fileA dir/fileB dir/fileC".split() + + @pytest.mark.complete("tar --block") + def test_14(self, completion, gnu_tar): + assert completion == "--block-number --blocking-factor=".split() + + @pytest.mark.complete("tar --add-fil") + def test_15(self, completion, gnu_tar): + assert completion == "e=" + assert not completion.endswith(" ") + + @pytest.mark.complete("tar -cf /dev/null --posi") + def test_16(self, completion, gnu_tar): + assert completion == "x" + assert completion.endswith(" ") + + @pytest.mark.complete("tar --owner=") + def test_17(self, bash, completion, gnu_tar, output_sort_uniq): + users = output_sort_uniq("compgen -u") + assert completion == users + + @pytest.mark.complete("tar --group=") + def test_18(self, bash, completion, gnu_tar, output_sort_uniq): + groups = output_sort_uniq("compgen -g") + assert completion == groups + + # Use -b for this as -b is still not handled by tar's completion + @pytest.mark.complete("tar -cvvfb ") + def test_19(self, bash, completion, gnu_tar): + """Test short option -XXXb <TAB> (arg required).""" + assert not completion + + # Use bsdtar here as it completes to only 'zc zt zx' + # -- 'tar' can be GNU tar and have more options + @pytest.mark.complete("bsdtar z") + def test_20(self, bash, completion): + assert completion == "zc zt zx".split() + + @pytest.mark.complete("bsdtar cbfvv NON_EXISTENT ", cwd="tar") + def test_21(self, bash, completion): + """Test _second_ option in "old" argument.""" + assert completion == "dir/ dir2/".split() + + @pytest.mark.complete(r"tar tf escape.tar a/b\'", cwd="tar") + def test_22(self, bash, completion): + """Test listing escaped chars in old option.""" + assert completion == "c/" + + # TODO: "tar tf escape.tar a/b" diff --git a/test/t/test_tcpdump.py b/test/t/test_tcpdump.py new file mode 100644 index 0000000..a557364 --- /dev/null +++ b/test/t/test_tcpdump.py @@ -0,0 +1,7 @@ +import pytest + + +class TestTcpdump: + @pytest.mark.complete("tcpdump -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_tcpkill.py b/test/t/test_tcpkill.py new file mode 100644 index 0000000..4581a34 --- /dev/null +++ b/test/t/test_tcpkill.py @@ -0,0 +1,7 @@ +import pytest + + +class TestTcpkill: + @pytest.mark.complete("tcpkill -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_tcpnice.py b/test/t/test_tcpnice.py new file mode 100644 index 0000000..fbe9592 --- /dev/null +++ b/test/t/test_tcpnice.py @@ -0,0 +1,7 @@ +import pytest + + +class TestTcpnice: + @pytest.mark.complete("tcpnice -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_tee.py b/test/t/test_tee.py new file mode 100644 index 0000000..3d8bcd7 --- /dev/null +++ b/test/t/test_tee.py @@ -0,0 +1,11 @@ +import pytest + + +class TestTee: + @pytest.mark.complete("tee ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("tee -", require_longopt=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_texindex.py b/test/t/test_texindex.py new file mode 100644 index 0000000..c3f6a0b --- /dev/null +++ b/test/t/test_texindex.py @@ -0,0 +1,7 @@ +import pytest + + +class TestTexindex: + @pytest.mark.complete("texindex --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_tightvncviewer.py b/test/t/test_tightvncviewer.py new file mode 100644 index 0000000..04ebece --- /dev/null +++ b/test/t/test_tightvncviewer.py @@ -0,0 +1,7 @@ +import pytest + + +class TestTightvncviewer: + @pytest.mark.complete("tightvncviewer ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_time.py b/test/t/test_time.py new file mode 100644 index 0000000..231f14e --- /dev/null +++ b/test/t/test_time.py @@ -0,0 +1,23 @@ +import os + +import pytest + + +class TestTime: + @pytest.mark.complete("time set") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("time -p find -typ") + def test_2(self, completion): + assert completion # find's options + + @pytest.mark.complete("time shared/bin/") + def test_3(self, completion): + execs = sorted( + x + for x in os.listdir("shared/bin") + if os.path.isfile("shared/bin/%s" % x) + and os.access("shared/bin/%s" % x, os.X_OK) + ) + assert completion == execs diff --git a/test/t/test_timeout.py b/test/t/test_timeout.py new file mode 100644 index 0000000..46fe2e0 --- /dev/null +++ b/test/t/test_timeout.py @@ -0,0 +1,11 @@ +import pytest + + +class TestTimeout: + @pytest.mark.complete("timeout ") + def test_1(self, completion): + assert not completion + + @pytest.mark.complete("timeout -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_tipc.py b/test/t/test_tipc.py new file mode 100644 index 0000000..17b2bfd --- /dev/null +++ b/test/t/test_tipc.py @@ -0,0 +1,7 @@ +import pytest + + +class TestTipc: + @pytest.mark.complete("tipc ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_totem.py b/test/t/test_totem.py new file mode 100644 index 0000000..f6fb26f --- /dev/null +++ b/test/t/test_totem.py @@ -0,0 +1,7 @@ +import pytest + + +class TestTotem: + @pytest.mark.complete("totem ") + def test_basic(self, completion): + assert completion diff --git a/test/t/test_touch.py b/test/t/test_touch.py new file mode 100644 index 0000000..8a49e50 --- /dev/null +++ b/test/t/test_touch.py @@ -0,0 +1,7 @@ +import pytest + + +class TestTouch: + @pytest.mark.complete("touch --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_tox.py b/test/t/test_tox.py new file mode 100644 index 0000000..f012a03 --- /dev/null +++ b/test/t/test_tox.py @@ -0,0 +1,19 @@ +import pytest + + +class TestTox: + @pytest.mark.complete("tox -") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("tox -e ", cwd="tox") + def test_2(self, completion): + assert all(x in completion for x in "py37 ALL".split()) + + @pytest.mark.complete("tox -e foo,", cwd="tox") + def test_3(self, completion): + assert all(x in completion for x in "py37 ALL".split()) + + @pytest.mark.complete("tox -e foo -- ", cwd="tox") + def test_default_after_dashdash(self, completion): + assert "tox.ini" in completion diff --git a/test/t/test_tr.py b/test/t/test_tr.py new file mode 100644 index 0000000..0a51e9e --- /dev/null +++ b/test/t/test_tr.py @@ -0,0 +1,7 @@ +import pytest + + +class TestTr: + @pytest.mark.complete("tr --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_tracepath.py b/test/t/test_tracepath.py new file mode 100644 index 0000000..e4cac65 --- /dev/null +++ b/test/t/test_tracepath.py @@ -0,0 +1,11 @@ +import pytest + + +class TestTracepath: + @pytest.mark.complete("tracepath ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("tracepath -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_tshark.py b/test/t/test_tshark.py new file mode 100644 index 0000000..f49533e --- /dev/null +++ b/test/t/test_tshark.py @@ -0,0 +1,34 @@ +import pytest + + +@pytest.mark.bashcomp(ignore_env=r"^\+_tshark_pr(ef|otocol)s=") +class TestTshark: + @pytest.mark.complete("tshark -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("tshark -G ", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("tshark -O foo,htt", require_cmd=True) + def test_3(self, completion): + # p: one completion only; http: e.g. http and http2 + assert completion == "p" or "http" in completion + + @pytest.mark.complete("tshark -o tcp", require_cmd=True) + def test_4(self, completion): + assert "tcp.desegment_tcp_streams:" in completion + + @pytest.mark.complete("tshark -otcp", require_cmd=True) + def test_5(self, completion): + assert "-otcp.desegment_tcp_streams:" in completion + + @pytest.mark.complete("tshark -O http") + def test_6(self, completion): + """Test there are no URLs in completions.""" + assert not any("://" in x for x in completion) + + @pytest.mark.complete("tshark -r ") + def test_input_files(self, completion): + assert completion diff --git a/test/t/test_tsig_keygen.py b/test/t/test_tsig_keygen.py new file mode 100644 index 0000000..8c8a64a --- /dev/null +++ b/test/t/test_tsig_keygen.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="tsig-keygen") +class TestTsigKeygen: + @pytest.mark.complete("tsig-keygen ") + def test_basic(self, completion): + assert not completion + + @pytest.mark.complete("tsig-keygen -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_tune2fs.py b/test/t/test_tune2fs.py new file mode 100644 index 0000000..5cc0e41 --- /dev/null +++ b/test/t/test_tune2fs.py @@ -0,0 +1,11 @@ +import pytest + + +class TestTune2fs: + @pytest.mark.complete("tune2fs ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("tune2fs -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_udevadm.py b/test/t/test_udevadm.py new file mode 100644 index 0000000..6191c77 --- /dev/null +++ b/test/t/test_udevadm.py @@ -0,0 +1,11 @@ +import pytest + + +class TestUdevadm: + @pytest.mark.complete("udevadm ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("udevadm -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_ulimit.py b/test/t/test_ulimit.py new file mode 100644 index 0000000..3ab974c --- /dev/null +++ b/test/t/test_ulimit.py @@ -0,0 +1,35 @@ +import pytest + + +class TestUlimit: + @pytest.mark.complete("ulimit ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("ulimit -", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("ulimit -S -") + def test_3(self, completion): + """Test modes are completed after -S (-S not treated as mode).""" + assert completion + + @pytest.mark.complete("ulimit -u -") + def test_4(self, completion): + """Test modes are NOT completed if one is specified.""" + assert not completion + + @pytest.mark.complete("ulimit -c ") + def test_5(self, completion): + assert completion + assert not any(x.startswith("-") for x in completion) + + @pytest.mark.complete("ulimit -a ") + def test_6(self, completion): + assert completion == sorted("-S -H".split()) + + @pytest.mark.complete("ulimit -a -H -") + def test_7(self, completion): + """Test modes are NOT completed with -a given somewhere.""" + assert not completion diff --git a/test/t/test_umount.py b/test/t/test_umount.py new file mode 100644 index 0000000..2baf0da --- /dev/null +++ b/test/t/test_umount.py @@ -0,0 +1,85 @@ +import pytest + +from conftest import assert_bash_exec + + +class TestUmount: + @pytest.fixture(scope="class") + def dummy_mnt(self, request, bash): + """ + umount completion from fstab can't be tested directly because it + (correctly) uses absolute paths. So we create a custom completion which + reads from a file in our text fixture instead. + """ + assert_bash_exec(bash, "unset COMPREPLY cur; unset -f _mnt_completion") + assert_bash_exec( + bash, + "_mnt_completion() { " + "local cur=$(_get_cword); " + "_linux_fstab $(_get_pword) < mount/test-fstab; " + "} && complete -F _mnt_completion _mnt", + ) + request.addfinalizer( + lambda: assert_bash_exec( + bash, "complete -r _mnt; unset -f _mnt_completion" + ) + ) + + @pytest.mark.complete("umount ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("_mnt /mnt/nice-test-p") + def test_mnt_basic(self, completion, dummy_mnt): + assert completion == "ath" + + # Note in tests below that return only one result, that the result + # is shell unescaped due to how assert_complete handles the + # "one result on same line case". + + @pytest.mark.complete(r"_mnt /mnt/nice\ test-p") + def test_mnt_space(self, completion, dummy_mnt): + assert completion == r"ath" + + @pytest.mark.complete(r"_mnt /mnt/nice\$test-p") + def test_mnt_dollar(self, completion, dummy_mnt): + assert completion == "ath" + + @pytest.mark.complete(r"_mnt /mnt/nice\ test\\p") + def test_mnt_backslash(self, completion, dummy_mnt): + assert completion == "ath" + + @pytest.mark.complete(r"_mnt /mnt/nice\ ") + def test_mnt_after_space(self, completion, dummy_mnt): + assert completion == sorted( + (r"/mnt/nice\ test\\path", r"/mnt/nice\ test-path") + ) + + @pytest.mark.complete(r"_mnt /mnt/nice\$") + def test_mnt_at_dollar(self, completion, dummy_mnt): + assert completion == "test-path" + + @pytest.mark.complete(r"_mnt /mnt/nice\'") + def test_mnt_at_quote(self, completion, dummy_mnt): + assert completion == "test-path" + + @pytest.mark.complete("_mnt /mnt/other") + def test_mnt_other(self, completion, dummy_mnt): + assert completion == r"\'test\ path" + + @pytest.mark.complete("_mnt -L Ubu") + def test_mnt_label_space(self, completion, dummy_mnt): + assert completion == r"ntu\ Karmic" + + @pytest.mark.complete("_mnt -L Deb") + def test_mnt_label_quote(self, completion, dummy_mnt): + assert completion == r"ian-it\'s\ awesome" + + def test_linux_fstab_unescape(self, bash): + assert_bash_exec(bash, r"var=one\'two\\040three\\") + assert_bash_exec(bash, "__linux_fstab_unescape var") + output = assert_bash_exec( + bash, r'printf "%s\n" "$var"', want_output=True + ) + assert output.strip() == "one'two three\\" + assert_bash_exec(bash, "unset var") diff --git a/test/t/test_unace.py b/test/t/test_unace.py new file mode 100644 index 0000000..e4d5acb --- /dev/null +++ b/test/t/test_unace.py @@ -0,0 +1,7 @@ +import pytest + + +class TestUnace: + @pytest.mark.complete("unace -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_uname.py b/test/t/test_uname.py new file mode 100644 index 0000000..e71a433 --- /dev/null +++ b/test/t/test_uname.py @@ -0,0 +1,7 @@ +import pytest + + +class TestUname: + @pytest.mark.complete("uname --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_unexpand.py b/test/t/test_unexpand.py new file mode 100644 index 0000000..2f1359b --- /dev/null +++ b/test/t/test_unexpand.py @@ -0,0 +1,7 @@ +import pytest + + +class TestUnexpand: + @pytest.mark.complete("unexpand --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_uniq.py b/test/t/test_uniq.py new file mode 100644 index 0000000..73691fd --- /dev/null +++ b/test/t/test_uniq.py @@ -0,0 +1,7 @@ +import pytest + + +class TestUniq: + @pytest.mark.complete("uniq --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_units.py b/test/t/test_units.py new file mode 100644 index 0000000..824e2ce --- /dev/null +++ b/test/t/test_units.py @@ -0,0 +1,9 @@ +import pytest + + +class TestUnits: + @pytest.mark.complete( + "units --", require_cmd=True, xfail="! units --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_unpack200.py b/test/t/test_unpack200.py new file mode 100644 index 0000000..16c0402 --- /dev/null +++ b/test/t/test_unpack200.py @@ -0,0 +1,7 @@ +import pytest + + +class TestUnpack200: + @pytest.mark.complete("unpack200 ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_unrar.py b/test/t/test_unrar.py new file mode 100644 index 0000000..45e336e --- /dev/null +++ b/test/t/test_unrar.py @@ -0,0 +1,7 @@ +import pytest + + +class TestUnrar: + @pytest.mark.complete("unrar -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_unset.py b/test/t/test_unset.py new file mode 100644 index 0000000..9f3eade --- /dev/null +++ b/test/t/test_unset.py @@ -0,0 +1,7 @@ +import pytest + + +class TestUnset: + @pytest.mark.complete("unset BASH_ARG") + def test_1(self, completion): + assert completion diff --git a/test/t/test_unshunt.py b/test/t/test_unshunt.py new file mode 100644 index 0000000..a354239 --- /dev/null +++ b/test/t/test_unshunt.py @@ -0,0 +1,7 @@ +import pytest + + +class TestUnshunt: + @pytest.mark.complete("unshunt --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_update_alternatives.py b/test/t/test_update_alternatives.py new file mode 100644 index 0000000..7c77730 --- /dev/null +++ b/test/t/test_update_alternatives.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="update-alternatives") +class TestUpdateAlternatives: + @pytest.mark.complete("update-alternatives --", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_update_rc_d.py b/test/t/test_update_rc_d.py new file mode 100644 index 0000000..6f57416 --- /dev/null +++ b/test/t/test_update_rc_d.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="update-rc.d") +class TestUpdateRcD: + @pytest.mark.complete("update-rc.d -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_upgradepkg.py b/test/t/test_upgradepkg.py new file mode 100644 index 0000000..87fe8e4 --- /dev/null +++ b/test/t/test_upgradepkg.py @@ -0,0 +1,51 @@ +import fnmatch +import os + +import pytest + + +class TestUpgradepkg: + @pytest.mark.complete("upgradepkg -") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("upgradepkg --") + def test_2(self, completion): + assert ( + completion == "--dry-run --install-new --reinstall " + "--verbose".split() + ) + + @pytest.mark.complete("upgradepkg ", cwd="slackware/home") + def test_4(self, completion): + expected = sorted( + [ + "%s/" % x + for x in os.listdir("slackware/home") + if os.path.isdir("./slackware/home/%s" % x) + ] + + [ + x + for x in os.listdir("slackware/home") + if os.path.isfile("./slackware/home/%s" % x) + and fnmatch.fnmatch(x, "*.t[bglx]z") + ] + ) + assert completion == expected + + @pytest.mark.complete("upgradepkg foo%", cwd="slackware/home") + def test_after_percent(self, completion): + expected = sorted( + [ + "%s/" % x + for x in os.listdir("slackware/home") + if os.path.isdir("./slackware/home/%s" % x) + ] + + [ + x + for x in os.listdir("slackware/home") + if os.path.isfile("./slackware/home/%s" % x) + and fnmatch.fnmatch(x, "*.t[bglx]z") + ] + ) + assert completion == ["foo%%%s" % x for x in expected] diff --git a/test/t/test_urlsnarf.py b/test/t/test_urlsnarf.py new file mode 100644 index 0000000..8551c60 --- /dev/null +++ b/test/t/test_urlsnarf.py @@ -0,0 +1,7 @@ +import pytest + + +class TestUrlsnarf: + @pytest.mark.complete("urlsnarf -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_uscan.py b/test/t/test_uscan.py new file mode 100644 index 0000000..142c325 --- /dev/null +++ b/test/t/test_uscan.py @@ -0,0 +1,7 @@ +import pytest + + +class TestUscan: + @pytest.mark.complete("uscan -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_useradd.py b/test/t/test_useradd.py new file mode 100644 index 0000000..5cbf6ce --- /dev/null +++ b/test/t/test_useradd.py @@ -0,0 +1,11 @@ +import pytest + + +class TestUseradd: + @pytest.mark.complete("useradd ") + def test_1(self, completion): + assert not completion + + @pytest.mark.complete("useradd -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_userdel.py b/test/t/test_userdel.py new file mode 100644 index 0000000..3405e12 --- /dev/null +++ b/test/t/test_userdel.py @@ -0,0 +1,11 @@ +import pytest + + +class TestUserdel: + @pytest.mark.complete("userdel -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("userdel roo") + def test_2(self, completion): + assert completion == "t" or "root" in completion diff --git a/test/t/test_usermod.py b/test/t/test_usermod.py new file mode 100644 index 0000000..ef3dd5a --- /dev/null +++ b/test/t/test_usermod.py @@ -0,0 +1,11 @@ +import pytest + + +class TestUsermod: + @pytest.mark.complete("usermod ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("usermod -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_valgrind.py b/test/t/test_valgrind.py new file mode 100644 index 0000000..0553b55 --- /dev/null +++ b/test/t/test_valgrind.py @@ -0,0 +1,42 @@ +import os + +import pytest + + +class TestValgrind: + + # b: Assume we have at least bash that starts with b in PATH + @pytest.mark.complete("valgrind b") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("valgrind -", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("valgrind --tool=memche", require_cmd=True) + def test_3(self, completion): + assert completion == "ck" or "--tool=memcheck" in completion + + @pytest.mark.complete( + "valgrind --tool=helgrind --history-l", require_cmd=True + ) + def test_4(self, completion): + assert completion == "evel=" or "--history-level=" in completion + assert not completion.endswith(" ") + + @pytest.mark.complete(r"valgrind --log-file=v\ 0.log ./bin/", cwd="shared") + def test_5(self, completion): + expected = sorted( + [ + "%s/" + for x in os.listdir("shared/bin") + if os.path.isdir("shared/bin/%s" % x) + ] + + [ + x + for x in os.listdir("shared/bin") + if os.path.isfile("shared/bin/%s" % x) + ] + ) + assert completion == expected diff --git a/test/t/test_vdir.py b/test/t/test_vdir.py new file mode 100644 index 0000000..e186989 --- /dev/null +++ b/test/t/test_vdir.py @@ -0,0 +1,11 @@ +import pytest + + +class TestVdir: + @pytest.mark.complete("vdir ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("vdir -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_vgcfgbackup.py b/test/t/test_vgcfgbackup.py new file mode 100644 index 0000000..2e6c6f1 --- /dev/null +++ b/test/t/test_vgcfgbackup.py @@ -0,0 +1,11 @@ +import pytest + + +class TestVgcfgbackup: + @pytest.mark.complete( + "vgcfgbackup -", + require_cmd=True, + xfail="! vgcfgbackup --help &>/dev/null", + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgcfgrestore.py b/test/t/test_vgcfgrestore.py new file mode 100644 index 0000000..acb1a38 --- /dev/null +++ b/test/t/test_vgcfgrestore.py @@ -0,0 +1,11 @@ +import pytest + + +class TestVgcfgrestore: + @pytest.mark.complete( + "vgcfgrestore -", + require_cmd=True, + xfail="! vgcfgrestore --help &>/dev/null", + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgchange.py b/test/t/test_vgchange.py new file mode 100644 index 0000000..ed14f2a --- /dev/null +++ b/test/t/test_vgchange.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgchange: + @pytest.mark.complete( + "vgchange -", require_cmd=True, xfail="! vgchange --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgck.py b/test/t/test_vgck.py new file mode 100644 index 0000000..52ddf88 --- /dev/null +++ b/test/t/test_vgck.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgck: + @pytest.mark.complete( + "vgck -", require_cmd=True, xfail="! vgck --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgconvert.py b/test/t/test_vgconvert.py new file mode 100644 index 0000000..029fe48 --- /dev/null +++ b/test/t/test_vgconvert.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgconvert: + @pytest.mark.complete( + "vgconvert -", require_cmd=True, xfail="! vgconvert --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgcreate.py b/test/t/test_vgcreate.py new file mode 100644 index 0000000..40c1773 --- /dev/null +++ b/test/t/test_vgcreate.py @@ -0,0 +1,13 @@ +import pytest + + +class TestVgcreate: + @pytest.mark.complete( + "vgcreate -", require_cmd=True, xfail="! vgcreate --help &>/dev/null" + ) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("vgcreate __does_not_exist__", require_cmd=True) + def test_2(self, completion): + assert not completion diff --git a/test/t/test_vgdisplay.py b/test/t/test_vgdisplay.py new file mode 100644 index 0000000..6066729 --- /dev/null +++ b/test/t/test_vgdisplay.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgdisplay: + @pytest.mark.complete( + "vgdisplay -", require_cmd=True, xfail="! vgdisplay --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgexport.py b/test/t/test_vgexport.py new file mode 100644 index 0000000..96ecc3c --- /dev/null +++ b/test/t/test_vgexport.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgexport: + @pytest.mark.complete( + "vgexport -", require_cmd=True, xfail="! vgexport --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgextend.py b/test/t/test_vgextend.py new file mode 100644 index 0000000..8c41ab6 --- /dev/null +++ b/test/t/test_vgextend.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgextend: + @pytest.mark.complete( + "vgextend -", require_cmd=True, xfail="! vgextend --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgimport.py b/test/t/test_vgimport.py new file mode 100644 index 0000000..24017d2 --- /dev/null +++ b/test/t/test_vgimport.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgimport: + @pytest.mark.complete( + "vgimport -", require_cmd=True, xfail="! vgimport --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgmerge.py b/test/t/test_vgmerge.py new file mode 100644 index 0000000..7d88932 --- /dev/null +++ b/test/t/test_vgmerge.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgmerge: + @pytest.mark.complete( + "vgmerge -", require_cmd=True, xfail="! vgmerge --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgmknodes.py b/test/t/test_vgmknodes.py new file mode 100644 index 0000000..7e046f0 --- /dev/null +++ b/test/t/test_vgmknodes.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgmknodes: + @pytest.mark.complete( + "vgmknodes -", require_cmd=True, xfail="! vgmknodes --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgreduce.py b/test/t/test_vgreduce.py new file mode 100644 index 0000000..26174b9 --- /dev/null +++ b/test/t/test_vgreduce.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgreduce: + @pytest.mark.complete( + "vgreduce -", require_cmd=True, xfail="! vgreduce --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgremove.py b/test/t/test_vgremove.py new file mode 100644 index 0000000..637d5c3 --- /dev/null +++ b/test/t/test_vgremove.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgremove: + @pytest.mark.complete( + "vgremove -", require_cmd=True, xfail="! vgremove --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgrename.py b/test/t/test_vgrename.py new file mode 100644 index 0000000..87a6a72 --- /dev/null +++ b/test/t/test_vgrename.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgrename: + @pytest.mark.complete( + "vgrename -", require_cmd=True, xfail="! vgrename --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgs.py b/test/t/test_vgs.py new file mode 100644 index 0000000..e0d8a03 --- /dev/null +++ b/test/t/test_vgs.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgs: + @pytest.mark.complete( + "vgs -", require_cmd=True, xfail="! vgs --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgscan.py b/test/t/test_vgscan.py new file mode 100644 index 0000000..95a4026 --- /dev/null +++ b/test/t/test_vgscan.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgscan: + @pytest.mark.complete( + "vgscan -", require_cmd=True, xfail="! vgscan --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vgsplit.py b/test/t/test_vgsplit.py new file mode 100644 index 0000000..1c3dfa8 --- /dev/null +++ b/test/t/test_vgsplit.py @@ -0,0 +1,9 @@ +import pytest + + +class TestVgsplit: + @pytest.mark.complete( + "vgsplit -", require_cmd=True, xfail="! vgsplit --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vi.py b/test/t/test_vi.py new file mode 100644 index 0000000..4f7f4c2 --- /dev/null +++ b/test/t/test_vi.py @@ -0,0 +1,11 @@ +import pytest + + +class TestVi: + @pytest.mark.complete("vi ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("vi shared/ld.so.conf.d/") + def test_2(self, completion): + assert completion == "foo.txt libfoo.conf".split() diff --git a/test/t/test_vipw.py b/test/t/test_vipw.py new file mode 100644 index 0000000..07b454b --- /dev/null +++ b/test/t/test_vipw.py @@ -0,0 +1,7 @@ +import pytest + + +class TestVipw: + @pytest.mark.complete("vipw -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vmstat.py b/test/t/test_vmstat.py new file mode 100644 index 0000000..b7145ff --- /dev/null +++ b/test/t/test_vmstat.py @@ -0,0 +1,7 @@ +import pytest + + +class TestVmstat: + @pytest.mark.complete("vmstat -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_vncviewer.py b/test/t/test_vncviewer.py new file mode 100644 index 0000000..9e2f148 --- /dev/null +++ b/test/t/test_vncviewer.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(ignore_env=r"^-declare -f _vncviewer_bootstrap$") +class TestVncviewer: + @pytest.mark.complete("vncviewer ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_vpnc.py b/test/t/test_vpnc.py new file mode 100644 index 0000000..dac5b15 --- /dev/null +++ b/test/t/test_vpnc.py @@ -0,0 +1,13 @@ +import pytest + + +@pytest.mark.bashcomp( + # On CentOS and Fedora, there's something fishy with consolehelper and + # /usr/bin/vpnc going on at least when invoked as root; try to invoke the + # one in /usr/sbin instead. + pre_cmds=("PATH=/usr/sbin:$PATH",) +) +class TestVpnc: + @pytest.mark.complete("vpnc -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_watch.py b/test/t/test_watch.py new file mode 100644 index 0000000..b1de7f5 --- /dev/null +++ b/test/t/test_watch.py @@ -0,0 +1,7 @@ +import pytest + + +class TestWatch: + @pytest.mark.complete("watch -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_wc.py b/test/t/test_wc.py new file mode 100644 index 0000000..1f83ea7 --- /dev/null +++ b/test/t/test_wc.py @@ -0,0 +1,7 @@ +import pytest + + +class TestWc: + @pytest.mark.complete("wc --", require_longopt=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_webmitm.py b/test/t/test_webmitm.py new file mode 100644 index 0000000..d631dcf --- /dev/null +++ b/test/t/test_webmitm.py @@ -0,0 +1,7 @@ +import pytest + + +class TestWebmitm: + @pytest.mark.complete("webmitm -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_wget.py b/test/t/test_wget.py new file mode 100644 index 0000000..de752c2 --- /dev/null +++ b/test/t/test_wget.py @@ -0,0 +1,11 @@ +import pytest + + +class TestWget: + @pytest.mark.complete("wget ") + def test_1(self, completion): + assert not completion + + @pytest.mark.complete("wget --s", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_who.py b/test/t/test_who.py new file mode 100644 index 0000000..9131ac7 --- /dev/null +++ b/test/t/test_who.py @@ -0,0 +1,9 @@ +import pytest + + +class TestWho: + @pytest.mark.complete( + "who --", require_cmd=True, xfail="! who --help &>/dev/null" + ) + def test_1(self, completion): + assert completion diff --git a/test/t/test_wine.py b/test/t/test_wine.py new file mode 100644 index 0000000..d0e5698 --- /dev/null +++ b/test/t/test_wine.py @@ -0,0 +1,11 @@ +import pytest + + +class TestWine: + @pytest.mark.complete("wine ", cwd="shared/default") + def test_1(self, completion): + assert completion == ["bar bar.d/", "foo.d/"] + + @pytest.mark.complete("wine notepad ", cwd="shared/default") + def test_2(self, completion): + assert completion == ["bar", "bar bar.d/", "foo", "foo.d/"] diff --git a/test/t/test_withlist.py b/test/t/test_withlist.py new file mode 100644 index 0000000..752c394 --- /dev/null +++ b/test/t/test_withlist.py @@ -0,0 +1,7 @@ +import pytest + + +class TestWithlist: + @pytest.mark.complete("withlist --") + def test_1(self, completion): + assert completion diff --git a/test/t/test_wodim.py b/test/t/test_wodim.py new file mode 100644 index 0000000..4b785b6 --- /dev/null +++ b/test/t/test_wodim.py @@ -0,0 +1,7 @@ +import pytest + + +class TestWodim: + @pytest.mark.complete("wodim ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_wol.py b/test/t/test_wol.py new file mode 100644 index 0000000..bf04f76 --- /dev/null +++ b/test/t/test_wol.py @@ -0,0 +1,20 @@ +import pytest + + +@pytest.mark.bashcomp(pre_cmds=("PATH=$PWD/shared/bin:$PATH",)) +class TestWol: + @pytest.mark.complete("wol ") + def test_1(self, completion): + assert all( + x in completion + for x in "00:00:00:00:00:00 11:11:11:11:11:11 " + "22:22:22:22:22:22 33:33:33:33:33:33".split() + ) + + @pytest.mark.complete("wol 00:") + def test_2(self, completion): + assert any(x.endswith("00:00:00:00:00") for x in completion) + + @pytest.mark.complete("wol -", require_cmd=True) + def test_3(self, completion): + assert completion diff --git a/test/t/test_write.py b/test/t/test_write.py new file mode 100644 index 0000000..fc4bfa0 --- /dev/null +++ b/test/t/test_write.py @@ -0,0 +1,7 @@ +import pytest + + +class TestWrite: + @pytest.mark.complete("write roo") + def test_1(self, completion): + assert completion == "t" or "root" in completion diff --git a/test/t/test_wsimport.py b/test/t/test_wsimport.py new file mode 100644 index 0000000..8c27f4b --- /dev/null +++ b/test/t/test_wsimport.py @@ -0,0 +1,18 @@ +import pytest + + +class TestWsimport: + @pytest.mark.complete("wsimport ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete( + "wsimport -", + require_cmd=True, + xfail=( + "! (wsimport -help 2>&1 || :) | " + "command grep -q -- '[[:space:]]-'" + ), + ) + def test_2(self, completion): + assert completion diff --git a/test/t/test_wtf.py b/test/t/test_wtf.py new file mode 100644 index 0000000..45dfcfd --- /dev/null +++ b/test/t/test_wtf.py @@ -0,0 +1,8 @@ +import pytest + + +class TestWtf: + # TODO: actually requires an acronym db, not the cmd + @pytest.mark.complete("wtf A", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_wvdial.py b/test/t/test_wvdial.py new file mode 100644 index 0000000..bbc520d --- /dev/null +++ b/test/t/test_wvdial.py @@ -0,0 +1,7 @@ +import pytest + + +class TestWvdial: + @pytest.mark.complete("wvdial -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_xdg_mime.py b/test/t/test_xdg_mime.py new file mode 100644 index 0000000..432be06 --- /dev/null +++ b/test/t/test_xdg_mime.py @@ -0,0 +1,28 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="xdg-mime") +class TestXdgMime: + @pytest.mark.complete("xdg-mime ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xdg-mime -") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("xdg-mime query ") + def test_3(self, completion): + assert completion + + @pytest.mark.complete("xdg-mime query filetype ") + def test_4(self, completion): + assert completion + + @pytest.mark.complete("xdg-mime default foo.desktop ") + def test_5(self, completion): + assert completion + + @pytest.mark.complete("xdg-mime install --mode ") + def test_6(self, completion): + assert completion diff --git a/test/t/test_xdg_settings.py b/test/t/test_xdg_settings.py new file mode 100644 index 0000000..1a19459 --- /dev/null +++ b/test/t/test_xdg_settings.py @@ -0,0 +1,16 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="xdg-settings") +class TestXdgSettings: + @pytest.mark.complete("xdg-settings ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xdg-settings --", require_cmd=True) + def test_2(self, completion): + assert completion + + @pytest.mark.complete("xdg-settings get ", require_cmd=True) + def test_3(self, completion): + assert completion diff --git a/test/t/test_xfreerdp.py b/test/t/test_xfreerdp.py new file mode 100644 index 0000000..5616271 --- /dev/null +++ b/test/t/test_xfreerdp.py @@ -0,0 +1,60 @@ +import pytest + +from conftest import assert_bash_exec + + +class TestXfreerdp: + def _help(self, bash): + return assert_bash_exec( + bash, "xfreerdp --help 2>&1 || :", want_output=True + ) + + @pytest.fixture(scope="class") + def help_success(self, bash): + output = self._help(bash) + # Example from our CentOS 7 container + # [04:51:31:663] [238:238] [ERROR][com.freerdp.client.x11] - Failed to get pixmap info + if not output or "ERROR" in output.strip().splitlines()[0]: + pytest.skip("--help errored") + + @pytest.fixture(scope="class") + def slash_syntax(self, bash, help_success): + if "/help" not in self._help(bash): + pytest.skip("Not slash syntax") + + @pytest.fixture(scope="class") + def dash_syntax(self, bash): + if "/help" in self._help(bash): + pytest.skip("Not dash syntax") + + @pytest.mark.complete("xfreerdp /", require_cmd=True) + def test_1(self, bash, completion, help_success, slash_syntax): + assert completion + + @pytest.mark.complete("xfreerdp -", require_cmd=True) + def test_2(self, completion, help_success): + assert completion + + @pytest.mark.complete("xfreerdp +", require_cmd=True) + def test_3(self, bash, completion, help_success, slash_syntax): + assert completion + + @pytest.mark.complete( + "xfreerdp /kbd:", + require_cmd=True, + skipif='test -z "$(xfreerdp /kbd-list 2>/dev/null)"', + ) + def test_4(self, bash, completion, help_success, slash_syntax): + assert completion + + @pytest.mark.complete("xfreerdp /help ", require_cmd=True) + def test_5(self, completion, help_success): + assert not completion + + @pytest.mark.complete("xfreerdp -k ", require_cmd=True) + def test_6(self, bash, completion, help_success, dash_syntax): + assert completion + + @pytest.mark.complete("xfreerdp --help ", require_cmd=True) + def test_7(self, completion): + assert not completion diff --git a/test/t/test_xgamma.py b/test/t/test_xgamma.py new file mode 100644 index 0000000..151e2d3 --- /dev/null +++ b/test/t/test_xgamma.py @@ -0,0 +1,12 @@ +import pytest + + +class TestXgamma: + @pytest.mark.complete("xgamma -", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xgamma -gam", require_cmd=True) + def test_2(self, completion): + assert completion == "ma" + assert completion.endswith(" ") diff --git a/test/t/test_xhost.py b/test/t/test_xhost.py new file mode 100644 index 0000000..bb2df82 --- /dev/null +++ b/test/t/test_xhost.py @@ -0,0 +1,22 @@ +import pytest + +from conftest import assert_complete, partialize + + +@pytest.mark.bashcomp(pre_cmds=("HOME=$PWD",)) +class TestXhost: + @pytest.mark.parametrize("prefix", ["+", "-", ""]) + def test_hosts(self, bash, hosts, prefix): + completion = assert_complete(bash, "xhost %s" % prefix) + assert completion == ["%s%s" % (prefix, x) for x in hosts] + + @pytest.mark.parametrize("prefix", ["+", "-", ""]) + def test_partial_hosts(self, bash, hosts, prefix): + first_char, partial_hosts = partialize(bash, hosts) + completion = assert_complete(bash, "xhost %s%s" % (prefix, first_char)) + if len(completion) == 1: + assert completion == partial_hosts[0][1:] + else: + assert completion == sorted( + "%s%s" % (prefix, x) for x in partial_hosts + ) diff --git a/test/t/test_xm.py b/test/t/test_xm.py new file mode 100644 index 0000000..42c4c53 --- /dev/null +++ b/test/t/test_xm.py @@ -0,0 +1,7 @@ +import pytest + + +class TestXm: + @pytest.mark.complete("xm ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_xmllint.py b/test/t/test_xmllint.py new file mode 100644 index 0000000..21c52c7 --- /dev/null +++ b/test/t/test_xmllint.py @@ -0,0 +1,11 @@ +import pytest + + +class TestXmllint: + @pytest.mark.complete("xmllint ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xmllint -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_xmlwf.py b/test/t/test_xmlwf.py new file mode 100644 index 0000000..901f78a --- /dev/null +++ b/test/t/test_xmlwf.py @@ -0,0 +1,11 @@ +import pytest + + +class TestXmlwf: + @pytest.mark.complete("xmlwf ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xmlwf -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_xmms.py b/test/t/test_xmms.py new file mode 100644 index 0000000..a880b16 --- /dev/null +++ b/test/t/test_xmms.py @@ -0,0 +1,11 @@ +import pytest + + +class TestXmms: + @pytest.mark.complete("xmms --", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xmms --non-existent-option=--") + def test_2(self, completion): + assert not completion diff --git a/test/t/test_xmodmap.py b/test/t/test_xmodmap.py new file mode 100644 index 0000000..cc33d73 --- /dev/null +++ b/test/t/test_xmodmap.py @@ -0,0 +1,11 @@ +import pytest + + +class TestXmodmap: + @pytest.mark.complete("xmodmap ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xmodmap -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_xpovray.py b/test/t/test_xpovray.py new file mode 100644 index 0000000..4f603a7 --- /dev/null +++ b/test/t/test_xpovray.py @@ -0,0 +1,7 @@ +import pytest + + +class TestXpovray: + @pytest.mark.complete("xpovray ") + def test_1(self, completion): + assert completion diff --git a/test/t/test_xrandr.py b/test/t/test_xrandr.py new file mode 100644 index 0000000..e766922 --- /dev/null +++ b/test/t/test_xrandr.py @@ -0,0 +1,15 @@ +import pytest + + +class TestXrandr: + @pytest.mark.complete("xrandr ", require_cmd=True) + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xrandr --mode ") + def test_2(self, completion): + assert not completion + + @pytest.mark.complete("xrandr -", require_cmd=True) + def test_3(self, completion): + assert completion diff --git a/test/t/test_xrdb.py b/test/t/test_xrdb.py new file mode 100644 index 0000000..3ffce2c --- /dev/null +++ b/test/t/test_xrdb.py @@ -0,0 +1,11 @@ +import pytest + + +class TestXrdb: + @pytest.mark.complete("xrdb ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xrdb -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_xsltproc.py b/test/t/test_xsltproc.py new file mode 100644 index 0000000..259f9eb --- /dev/null +++ b/test/t/test_xsltproc.py @@ -0,0 +1,11 @@ +import pytest + + +class TestXsltproc: + @pytest.mark.complete("xsltproc ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xsltproc -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_xvfb_run.py b/test/t/test_xvfb_run.py new file mode 100644 index 0000000..89eb830 --- /dev/null +++ b/test/t/test_xvfb_run.py @@ -0,0 +1,12 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="xvfb-run") +class TestXvfbRun: + @pytest.mark.complete("xvfb-run ") + def test_no_args(self, completion): + assert any(x in completion for x in ("bash", "xvfb-run")) + + @pytest.mark.complete("xvfb-run -", require_cmd=True) + def test_options(self, completion): + assert completion diff --git a/test/t/test_xvnc4viewer.py b/test/t/test_xvnc4viewer.py new file mode 100644 index 0000000..72fe3f9 --- /dev/null +++ b/test/t/test_xvnc4viewer.py @@ -0,0 +1,15 @@ +import pytest + + +class TestXvnc4viewer: + @pytest.mark.complete("xvnc4viewer -") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xvnc4viewer -PreferredEncoding ") + def test_2(self, completion): + assert completion == "hextile raw zrle".split() + + @pytest.mark.complete("xvnc4viewer --preferredencoding ") + def test_3(self, completion): + assert completion == "hextile raw zrle".split() diff --git a/test/t/test_xxd.py b/test/t/test_xxd.py new file mode 100644 index 0000000..9e84bb7 --- /dev/null +++ b/test/t/test_xxd.py @@ -0,0 +1,11 @@ +import pytest + + +class TestXxd: + @pytest.mark.complete("xxd ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xxd -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_xz.py b/test/t/test_xz.py new file mode 100644 index 0000000..f226d02 --- /dev/null +++ b/test/t/test_xz.py @@ -0,0 +1,26 @@ +import pytest + + +class TestXz: + @pytest.mark.complete("xz ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xz -d xz/") + def test_2(self, completion): + assert ( + completion == "a/ bashcomp.lzma bashcomp.tar.xz " + "bashcomp.tlz bashcomp.xz".split() + ) + + @pytest.mark.complete("xz xz/") + def test_3(self, completion): + assert completion == "a/ bashcomp.tar".split() + + @pytest.mark.complete("xz ~") + def test_4(self, completion): + assert completion + + @pytest.mark.complete("xz -", require_cmd=True) + def test_5(self, completion): + assert completion diff --git a/test/t/test_xzdec.py b/test/t/test_xzdec.py new file mode 100644 index 0000000..a1e9a3b --- /dev/null +++ b/test/t/test_xzdec.py @@ -0,0 +1,11 @@ +import pytest + + +class TestXzdec: + @pytest.mark.complete("xzdec ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("xzdec -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/test_ypcat.py b/test/t/test_ypcat.py new file mode 100644 index 0000000..0fc4b45 --- /dev/null +++ b/test/t/test_ypcat.py @@ -0,0 +1,7 @@ +import pytest + + +class TestYpcat: + @pytest.mark.complete("ypcat ", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_ypmatch.py b/test/t/test_ypmatch.py new file mode 100644 index 0000000..18331aa --- /dev/null +++ b/test/t/test_ypmatch.py @@ -0,0 +1,8 @@ +import pytest + + +class TestYpmatch: + # Actually requires ypcat + @pytest.mark.complete("ypmatch foo ", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_yum.py b/test/t/test_yum.py new file mode 100644 index 0000000..5dd1eba --- /dev/null +++ b/test/t/test_yum.py @@ -0,0 +1,7 @@ +import pytest + + +class TestYum: + @pytest.mark.complete("yum -", require_cmd=True) + def test_1(self, completion): + assert completion diff --git a/test/t/test_yum_arch.py b/test/t/test_yum_arch.py new file mode 100644 index 0000000..9bbc38f --- /dev/null +++ b/test/t/test_yum_arch.py @@ -0,0 +1,8 @@ +import pytest + + +@pytest.mark.bashcomp(cmd="yum-arch") +class TestYumArch: + @pytest.mark.complete("yum-arch -") + def test_1(self, completion): + assert completion diff --git a/test/t/test_zopfli.py b/test/t/test_zopfli.py new file mode 100644 index 0000000..e5a71b3 --- /dev/null +++ b/test/t/test_zopfli.py @@ -0,0 +1,15 @@ +import pytest + + +class TestZopfli: + @pytest.mark.complete("zopfli ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("zopfli ~") + def test_2(self, completion): + assert completion + + @pytest.mark.complete("zopfli -", require_cmd=True) + def test_3(self, completion): + assert completion diff --git a/test/t/test_zopflipng.py b/test/t/test_zopflipng.py new file mode 100644 index 0000000..3ff120f --- /dev/null +++ b/test/t/test_zopflipng.py @@ -0,0 +1,11 @@ +import pytest + + +class TestZopflipng: + @pytest.mark.complete("zopflipng ") + def test_1(self, completion): + assert completion + + @pytest.mark.complete("zopflipng -", require_cmd=True) + def test_2(self, completion): + assert completion diff --git a/test/t/unit/Makefile.am b/test/t/unit/Makefile.am new file mode 100644 index 0000000..3eb652a --- /dev/null +++ b/test/t/unit/Makefile.am @@ -0,0 +1,24 @@ +EXTRA_DIST = \ + test_unit_count_args.py \ + test_unit_expand.py \ + test_unit_expand_tilde_by_ref.py \ + test_unit_filedir.py \ + test_unit_find_unique_completion_pair.py \ + test_unit_get_comp_words_by_ref.py \ + test_unit_get_cword.py \ + test_unit_init_completion.py \ + test_unit_ip_addresses.py \ + test_unit_known_hosts_real.py \ + test_unit_longopt.py \ + test_unit_parse_help.py \ + test_unit_parse_usage.py \ + test_unit_quote.py \ + test_unit_quote_readline.py \ + test_unit_tilde.py \ + test_unit_variables.py \ + test_unit_xinetd_services.py + +all: + +clean-local: + $(RM) -R __pycache__ diff --git a/test/t/unit/test_unit_count_args.py b/test/t/unit/test_unit_count_args.py new file mode 100644 index 0000000..56bce2c --- /dev/null +++ b/test/t/unit/test_unit_count_args.py @@ -0,0 +1,66 @@ +import pytest + +from conftest import TestUnitBase, assert_bash_exec + + +@pytest.mark.bashcomp( + cmd=None, ignore_env=r"^[+-](args|COMP_(WORDS|CWORD|LINE|POINT))=" +) +class TestUnitCountArgs(TestUnitBase): + def _test(self, *args, **kwargs): + return self._test_unit("_count_args %s; echo $args", *args, **kwargs) + + def test_1(self, bash): + assert_bash_exec(bash, "COMP_CWORD= _count_args >/dev/null") + + def test_2(self, bash): + """a b| should set args to 1""" + output = self._test(bash, "(a b)", 1, "a b", 3) + assert output == "1" + + def test_3(self, bash): + """a b|c should set args to 1""" + output = self._test(bash, "(a bc)", 1, "a bc", 3) + assert output == "1" + + def test_4(self, bash): + """a b c| should set args to 2""" + output = self._test(bash, "(a b c)", 2, "a b c", 4) + assert output == "2" + + def test_5(self, bash): + """a b| c should set args to 1""" + output = self._test(bash, "(a b c)", 1, "a b c", 3) + assert output == "1" + + def test_6(self, bash): + """a b -c| d should set args to 2""" + output = self._test(bash, "(a b -c d)", 2, "a b -c d", 6) + assert output == "2" + + def test_7(self, bash): + """a b -c d e| with -c arg excluded should set args to 2""" + output = self._test( + bash, "(a b -c d e)", 4, "a b -c d e", 10, arg='"" "@(-c|--foo)"' + ) + assert output == "2" + + def test_8(self, bash): + """a -b -c d e| with -c arg excluded + and -b included should set args to 1""" + output = self._test( + bash, + "(a -b -c d e)", + 4, + "a -b -c d e", + 11, + arg='"" "@(-c|--foo)" "-[b]"', + ) + assert output == "2" + + def test_9(self, bash): + """a -b -c d e| with -b included should set args to 3""" + output = self._test( + bash, "(a -b -c d e)", 4, "a -b -c d e", 11, arg='"" "" "-b"' + ) + assert output == "3" diff --git a/test/t/unit/test_unit_expand.py b/test/t/unit/test_unit_expand.py new file mode 100644 index 0000000..d2a3ebc --- /dev/null +++ b/test/t/unit/test_unit_expand.py @@ -0,0 +1,31 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^[+-](cur|COMPREPLY)=") +class TestUnitExpand: + def test_1(self, bash): + assert_bash_exec(bash, "_expand >/dev/null") + + def test_2(self, bash): + """Test environment non-pollution, detected at teardown.""" + assert_bash_exec(bash, "foo() { _expand; }; foo; unset foo") + + def test_user_home_compreply(self, bash, user_home): + user, home = user_home + output = assert_bash_exec( + bash, + r'cur="~%s"; _expand; printf "%%s\n" "$COMPREPLY"' % user, + want_output=True, + ) + assert output.strip() == home + + def test_user_home_cur(self, bash, user_home): + user, home = user_home + output = assert_bash_exec( + bash, + r'cur="~%s/a"; _expand; printf "%%s\n" "$cur"' % user, + want_output=True, + ) + assert output.strip() == "%s/a" % home diff --git a/test/t/unit/test_unit_expand_tilde_by_ref.py b/test/t/unit/test_unit_expand_tilde_by_ref.py new file mode 100644 index 0000000..17bdedf --- /dev/null +++ b/test/t/unit/test_unit_expand_tilde_by_ref.py @@ -0,0 +1,46 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^[+-]var=") +class TestUnitExpandTildeByRef: + def test_1(self, bash): + assert_bash_exec(bash, "__expand_tilde_by_ref >/dev/null") + + def test_2(self, bash): + """Test environment non-pollution, detected at teardown.""" + assert_bash_exec( + bash, + '_x() { local aa="~"; __expand_tilde_by_ref aa; }; _x; unset _x', + ) + + @pytest.mark.parametrize("plain_tilde", (True, False)) + @pytest.mark.parametrize( + "suffix_expanded", + ( + ("", True), + ("/foo", True), + (r"/\$HOME", True), + ("/a b", True), + ("/*", True), + (";echo hello", False), + ("/a;echo hello", True), + ), + ) + def test_expand(self, bash, user_home, plain_tilde, suffix_expanded): + user, home = user_home + suffix, expanded = suffix_expanded + if plain_tilde: + user = "" + if not suffix or not expanded: + home = "~" + elif not expanded: + home = "~%s" % user + output = assert_bash_exec( + bash, + r'var="~%s%s"; __expand_tilde_by_ref var; printf "%%s\n" "$var"' + % (user, suffix), + want_output=True, + ) + assert output.strip() == "%s%s" % (home, suffix.replace(r"\$", "$"),) diff --git a/test/t/unit/test_unit_filedir.py b/test/t/unit/test_unit_filedir.py new file mode 100644 index 0000000..b847efc --- /dev/null +++ b/test/t/unit/test_unit_filedir.py @@ -0,0 +1,235 @@ +import os +import shutil +import sys +import tempfile +from pathlib import Path + +import pytest + +from conftest import assert_bash_exec, assert_complete + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^\+COMPREPLY=") +class TestUnitFiledir: + @pytest.fixture(scope="class") + def functions(self, request, bash): + assert_bash_exec( + bash, + "_f() { local cur=$(_get_cword); unset COMPREPLY; _filedir; }; " + "complete -F _f f; " + "complete -F _f -o filenames f2", + ) + assert_bash_exec( + bash, + "_g() { local cur=$(_get_cword); unset COMPREPLY; _filedir e1; }; " + "complete -F _g g", + ) + assert_bash_exec( + bash, + "_fd() { local cur=$(_get_cword); unset COMPREPLY; _filedir -d; };" + "complete -F _fd fd", + ) + + @pytest.fixture(scope="class") + def non_windows_testdir(self, request, bash): + if sys.platform.startswith("win"): + pytest.skip("Filenames not allowed on Windows") + tempdir = Path(tempfile.mkdtemp(prefix="bash-completion_filedir")) + request.addfinalizer(lambda: shutil.rmtree(str(tempdir))) + subdir = tempdir / 'a"b' + subdir.mkdir() + (subdir / "d").touch() + subdir = tempdir / "a*b" + subdir.mkdir() + (subdir / "j").touch() + subdir = tempdir / r"a\b" + subdir.mkdir() + (subdir / "g").touch() + return tempdir + + @pytest.fixture(scope="class") + def utf8_ctype(self, bash): + # TODO: this likely is not the right thing to do. Instead we should + # grab the setting from the running shell, possibly eval $(locale) + # in a subshell and grab LC_CTYPE from there. That doesn't seem to work + # either everywhere though. + lc_ctype = os.environ.get("LC_CTYPE", "") + if "UTF-8" not in lc_ctype: + pytest.skip("Applicable only in LC_CTYPE=UTF-8 setups") + return lc_ctype + + def test_1(self, bash): + assert_bash_exec(bash, "_filedir >/dev/null") + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_2(self, bash, functions, funcname): + completion = assert_complete(bash, "%s ab/" % funcname, cwd="_filedir") + assert completion == "e" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_3(self, bash, functions, funcname): + completion = assert_complete( + bash, r"%s a\ b/" % funcname, cwd="_filedir" + ) + assert completion == "i" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_4(self, bash, functions, funcname): + completion = assert_complete( + bash, r"%s a\'b/" % funcname, cwd="_filedir" + ) + assert completion == "c" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_5(self, bash, functions, funcname): + completion = assert_complete( + bash, r"%s a\&b/" % funcname, cwd="_filedir" + ) + assert completion == "f" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_6(self, bash, functions, funcname): + completion = assert_complete( + bash, r"%s a\$" % funcname, cwd="_filedir" + ) + assert completion == "b/" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_7(self, bash, functions, funcname): + completion = assert_complete( + bash, r"%s 'ab/" % funcname, cwd="_filedir" + ) + assert completion == "e'" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_8(self, bash, functions, funcname): + completion = assert_complete( + bash, r"%s 'a b/" % funcname, cwd="_filedir" + ) + assert completion == "i'" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_9(self, bash, functions, funcname): + completion = assert_complete( + bash, r"%s 'a$b/" % funcname, cwd="_filedir" + ) + assert completion == "h'" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_10(self, bash, functions, funcname): + completion = assert_complete( + bash, r"%s 'a&b/" % funcname, cwd="_filedir" + ) + assert completion == "f'" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_11(self, bash, functions, funcname): + completion = assert_complete( + bash, r'%s "ab/' % funcname, cwd="_filedir" + ) + assert completion == 'e"' + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_12(self, bash, functions, funcname): + completion = assert_complete( + bash, r'%s "a b/' % funcname, cwd="_filedir" + ) + assert completion == 'i"' + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_13(self, bash, functions, funcname): + completion = assert_complete( + bash, "%s \"a'b/" % funcname, cwd="_filedir" + ) + assert completion == 'c"' + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_14(self, bash, functions, funcname): + completion = assert_complete( + bash, '%s "a&b/' % funcname, cwd="_filedir" + ) + assert completion == 'f"' + + @pytest.mark.complete(r"fd a\ ", cwd="_filedir") + def test_15(self, functions, completion): + assert completion == "b/" + + @pytest.mark.complete("g ", cwd="_filedir/ext") + def test_16(self, functions, completion): + assert completion == sorted("ee.e1 foo/ gg.e1 ii.E1".split()) + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_17(self, bash, functions, funcname): + completion = assert_complete( + bash, r"%s a\$b/" % funcname, cwd="_filedir" + ) + assert completion == "h" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_18(self, bash, functions, funcname): + completion = assert_complete( + bash, r"%s \[x" % funcname, cwd="_filedir/brackets" + ) + assert completion == r"\]" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_19(self, bash, functions, funcname, non_windows_testdir): + completion = assert_complete( + bash, '%s a\\"b/' % funcname, cwd=non_windows_testdir + ) + assert completion == "d" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_20(self, bash, functions, funcname, non_windows_testdir): + completion = assert_complete( + bash, r"%s a\\b/" % funcname, cwd=non_windows_testdir + ) + assert completion == "g" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_21(self, bash, functions, funcname, non_windows_testdir): + completion = assert_complete( + bash, "%s 'a\"b/" % funcname, cwd=non_windows_testdir + ) + assert completion == "d'" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_22(self, bash, functions, funcname, non_windows_testdir): + completion = assert_complete( + bash, r"%s '%s/a\b/" % (funcname, non_windows_testdir) + ) + assert completion == "g'" + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_23(self, bash, functions, funcname, non_windows_testdir): + completion = assert_complete( + bash, r'%s "a\"b/' % funcname, cwd=non_windows_testdir + ) + assert completion == 'd"' + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_24(self, bash, functions, funcname, non_windows_testdir): + completion = assert_complete( + bash, r'%s "a\\b/' % funcname, cwd=non_windows_testdir + ) + assert completion == 'g"' + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_25(self, bash, functions, funcname): + completion = assert_complete( + bash, r'%s "a\b/' % funcname, cwd="_filedir" + ) + assert completion == '\b\b\bb/e"' + + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_26(self, bash, functions, funcname): + completion = assert_complete( + bash, r'%s "a\$b/' % funcname, cwd="_filedir" + ) + assert completion == 'h"' + + @pytest.mark.xfail(reason="TODO: non-ASCII issues with test suite?") + @pytest.mark.parametrize("funcname", "f f2".split()) + def test_27(self, bash, functions, funcname, utf8_ctype): + completion = assert_complete(bash, "%s aé/" % funcname, cwd="_filedir") + assert completion == "g" diff --git a/test/t/unit/test_unit_find_unique_completion_pair.py b/test/t/unit/test_unit_find_unique_completion_pair.py new file mode 100644 index 0000000..25cf9d3 --- /dev/null +++ b/test/t/unit/test_unit_find_unique_completion_pair.py @@ -0,0 +1,55 @@ +import pytest + +from conftest import find_unique_completion_pair + + +@pytest.mark.bashcomp(cmd=None) +class TestUnitFindUniqueCompletionPair: + def _test(self, inp: str, exp: str) -> None: + res = find_unique_completion_pair(inp.split()) + if exp: + part, cont = exp.split() + assert res == (part, part + cont) + else: + assert not exp + + def test_1(self): + self._test("a", "") + + def test_2(self): + self._test("ab", "a b") + + def test_3(self): + self._test("ab ab ab", "a b") + + def test_4(self): + self._test("a ab abcd abc", "") + + def test_5(self): + self._test("user1 user2", "") + + def test_6(self): + self._test("root username1 username2", "ro ot") + + def test_7(self): + self._test("root username21 username2", "ro ot") + + def test_8(self): + self._test( + "long_user_name lang_user_name long_usor_name", "lang_us er_name" + ) + + def test_9(self): + self._test( + "lang_user_name1 long_user_name lang_user_name long_usor_name", + "long_use r_name", + ) + + def test_10(self): + self._test("root username", "user name") + + def test_11(self): + self._test("a aladin", "ala din") + + def test_12(self): + self._test("ala aladin", "alad in") diff --git a/test/t/unit/test_unit_get_comp_words_by_ref.py b/test/t/unit/test_unit_get_comp_words_by_ref.py new file mode 100644 index 0000000..b6498fa --- /dev/null +++ b/test/t/unit/test_unit_get_comp_words_by_ref.py @@ -0,0 +1,260 @@ +import pytest + +from conftest import TestUnitBase, assert_bash_exec + + +@pytest.mark.bashcomp( + cmd=None, + ignore_env=r"^(\+(words|cword|cur|prev)|[+-]COMP_(WORDS|CWORD|LINE|POINT))=", +) +class TestUnitGetCompWordsByRef(TestUnitBase): + def _test(self, bash, *args, **kwargs): + assert_bash_exec(bash, "unset cur prev") + output = self._test_unit( + "_get_comp_words_by_ref %s cur prev; echo $cur,${prev-}", + bash, + *args, + **kwargs + ) + return output.strip() + + def test_1(self, bash): + assert_bash_exec( + bash, + "COMP_WORDS=() COMP_CWORD= COMP_POINT= COMP_LINE= " + "_get_comp_words_by_ref cur >/dev/null", + ) + + def test_2(self, bash): + """a b|""" + output = self._test(bash, "(a b)", 1, "a b", 3) + assert output == "b,a" + + def test_3(self, bash): + """a |""" + output = self._test(bash, "(a)", 1, "a ", 2) + assert output == ",a" + + def test_4(self, bash): + """|a""" + output = self._test(bash, "(a)", 0, "a", 0) + assert output == "," + + def test_5(self, bash): + """|a """ + output = self._test(bash, "(a)", 0, "a ", 0) + assert output == "," + + def test_6(self, bash): + """ | a """ + output = self._test(bash, "(a)", 0, " a ", 1) + assert output.strip() == "," + + def test_7(self, bash): + """a b |""" + output = self._test(bash, "(a b '')", 2, "a b ", 4) + assert output == ",b" + + def test_8(self, bash): + """a b | with WORDBREAKS -= :""" + output = self._test(bash, "(a b '')", 2, "a b ", 4, arg="-n :") + assert output == ",b" + + def test_9(self, bash): + """a b|c""" + output = self._test(bash, "(a bc)", 1, "a bc", 3) + assert output == "b,a" + + def test_10(self, bash): + """a | b""" + output = self._test(bash, "(a b)", 1, "a b", 2) + assert output == ",a" + + def test_11(self, bash): + r"""a b\ c|""" + output = self._test(bash, r"(a 'b\ c')", 1, r"a b\ c", 6) + assert output == r"b\ c,a" + + def test_12(self, bash): + r"""a\ b a\ b|""" + output = self._test(bash, r"('a\ b' 'a\ b')", 1, r"a\ b a\ b", 9) + assert output == r"a\ b,a\ b" + + def test_13(self, bash): + r"""a b\| c""" + output = self._test(bash, r"(a 'b\ c')", 1, r"a b\ c", 4) + assert output == r"b\,a" + + def test_14(self, bash): + r"""a "b\|""" + output = self._test(bash, "(a '\"b')", 1, 'a "b\\', 5) + assert output == r'"b\,a' + + def test_15(self, bash): + """a 'b c|""" + output = self._test(bash, '(a "\'b c")', 1, "a 'b c", 6) + assert output == "'b c,a" + + def test_16(self, bash): + """a "b c|""" + output = self._test(bash, r'(a "\"b c")', 1, 'a "b c', 6) + assert output == '"b c,a' + + def test_17(self, bash): + """a b:c| with WORDBREAKS += :""" + assert_bash_exec(bash, "add_comp_wordbreak_char :") + output = self._test(bash, "(a b : c)", 3, "a b:c", 5) + assert output == "c,:" + + def test_18(self, bash): + """a b:c| with WORDBREAKS -= :""" + output = self._test(bash, "(a b : c)", 3, "a b:c", 5, arg="-n :") + assert output == "b:c,a" + + def test_19(self, bash): + """a b c:| with WORDBREAKS -= :""" + output = self._test(bash, "(a b c :)", 3, "a b c:", 6, arg="-n :") + assert output == "c:,b" + + def test_20(self, bash): + r"""a b:c | with WORDBREAKS -= :""" + output = self._test(bash, "(a b : c '')", 4, "a b:c ", 6, arg="-n :") + assert output == ",b:c" + + def test_21(self, bash): + """a :| with WORDBREAKS -= :""" + output = self._test(bash, "(a :)", 1, "a :", 3, arg="-n :") + assert output == ":,a" + + def test_22(self, bash): + """a b::| with WORDBREAKS -= :""" + output = self._test(bash, "(a b ::)", 2, "a b::", 5, arg="-n :") + assert output == "b::,a" + + def test_23(self, bash): + """a -n| + + This test makes sure `_get_cword' doesn't use `echo' to return its + value, because -n might be interpreted by `echo' and thus woud not + be returned. + """ + output = self._test(bash, "(a -n)", 1, "a -n", 4) + assert output == "-n,a" + + def test_24(self, bash): + """a b>c|""" + output = self._test(bash, r"(a b \> c)", 3, "a b>c", 5) + assert output.startswith("c,") + + def test_25(self, bash): + """a b=c|""" + output = self._test(bash, "(a b = c)", 3, "a b=c", 5) + assert output.startswith("c,") + + def test_26(self, bash): + """a *|""" + output = self._test(bash, r"(a \*)", 1, "a *", 4) + assert output == "*,a" + + def test_27(self, bash): + """a $(b c|""" + output = self._test(bash, "(a '$(b c')", 1, "a $(b c", 7) + assert output == "$(b c,a" + + def test_28(self, bash): + r"""a $(b c\ d|""" + output = self._test(bash, r"(a '$(b c\ d')", 1, r"a $(b c\ d", 10) + assert output == r"$(b c\ d,a" + + def test_29(self, bash): + """a 'b&c|""" + output = self._test(bash, '(a "\'b&c")', 1, "a 'b&c", 6) + assert output == "'b&c,a" + + def test_30(self, bash): + """a b| to all vars""" + assert_bash_exec(bash, "unset words cword cur prev") + output = self._test_unit( + "_get_comp_words_by_ref words cword cur prev%s; " + 'echo "${words[@]}",$cword,$cur,$prev', + bash, + "(a b)", + 1, + "a b", + 3, + ) + assert output == "a b,1,b,a" + + def test_31(self, bash): + """a b| to alternate vars""" + assert_bash_exec(bash, "unset words2 cword2 cur2 prev2") + output = self._test_unit( + "_get_comp_words_by_ref -w words2 -i cword2 -c cur2 -p prev2%s; " + 'echo $cur2,$prev2,"${words2[@]}",$cword2', + bash, + "(a b)", + 1, + "a b", + 3, + ) + assert output == "b,a,a b,1" + assert_bash_exec(bash, "unset words2 cword2 cur2 prev2") + + def test_32(self, bash): + """a b : c| with wordbreaks -= :""" + assert_bash_exec(bash, "unset words") + output = self._test_unit( + '_get_comp_words_by_ref -n : words%s; echo "${words[@]}"', + bash, + "(a b : c)", + 3, + "a b : c", + 7, + ) + assert output == "a b : c" + + def test_33(self, bash): + """a b: c| with wordbreaks -= :""" + assert_bash_exec(bash, "unset words") + output = self._test_unit( + '_get_comp_words_by_ref -n : words%s; echo "${words[@]}"', + bash, + "(a b : c)", + 3, + "a b: c", + 6, + ) + assert output == "a b: c" + + def test_34(self, bash): + """a b :c| with wordbreaks -= :""" + assert_bash_exec(bash, "unset words") + output = self._test_unit( + '_get_comp_words_by_ref -n : words%s; echo "${words[@]}"', + bash, + "(a b : c)", + 3, + "a b :c", + 6, + ) + assert output == "a b :c" + + def test_35(self, bash): + r"""a b\ :c| with wordbreaks -= :""" + assert_bash_exec(bash, "unset words") + output = self._test_unit( + '_get_comp_words_by_ref -n : words%s; echo "${words[@]}"', + bash, + "(a 'b ' : c)", + 3, + r"a b\ :c", + 7, + ) + assert output == "a b :c" + + def test_unknown_arg_error(self, bash): + with pytest.raises(AssertionError) as ex: + _ = assert_bash_exec( + bash, "_get_comp_words_by_ref dummy", want_output=True + ) + ex.match("dummy.* unknown argument") diff --git a/test/t/unit/test_unit_get_cword.py b/test/t/unit/test_unit_get_cword.py new file mode 100644 index 0000000..0b56d16 --- /dev/null +++ b/test/t/unit/test_unit_get_cword.py @@ -0,0 +1,154 @@ +import pexpect +import pytest + +from conftest import PS1, TestUnitBase, assert_bash_exec + + +@pytest.mark.bashcomp( + cmd=None, ignore_env=r"^[+-](COMP_(WORDS|CWORD|LINE|POINT)|_scp_path_esc)=" +) +class TestUnitGetCword(TestUnitBase): + def _test(self, *args, **kwargs): + return self._test_unit("_get_cword %s; echo", *args, **kwargs) + + def test_1(self, bash): + assert_bash_exec( + bash, + "COMP_WORDS=() COMP_CWORD= COMP_LINE= COMP_POINT= " + "_get_cword >/dev/null", + ) + + def test_2(self, bash): + """a b| should return b""" + output = self._test(bash, "(a b)", 1, "a b", 3) + assert output == "b" + + def test_3(self, bash): + """a | should return nothing""" + output = self._test(bash, "(a)", 1, "a ", 2) + assert not output + + def test_4(self, bash): + """a b | should return nothing""" + output = self._test(bash, "(a b '')", 2, "a b ", 4) + assert not output + + def test_5(self, bash): + """a b | with WORDBREAKS -= : should return nothing""" + output = self._test(bash, "(a b '')", 2, "a b ", 4, arg=":") + assert not output + + def test_6(self, bash): + """a b|c should return b""" + output = self._test(bash, "(a bc)", 1, "a bc", 3) + assert output == "b" + + def test_7(self, bash): + r"""a b\ c| should return b\ c""" + output = self._test(bash, r"(a 'b\ c')", 1, r"a b\ c", 6) + assert output == r"b\ c" + + def test_8(self, bash): + r"""a b\| c should return b\ """ + output = self._test(bash, r"(a 'b\ c')", 1, r"a b\ c", 4) + assert output == "b\\" + + def test_9(self, bash): + r"""a "b\| should return "b\ """ + output = self._test(bash, "(a '\"b\\')", 1, r"a \"b\\", 5) + assert output == '"b\\' + + def test_10(self, bash): + r"""a 'b c| should return 'b c""" + output = self._test(bash, '(a "\'b c")', 1, "a 'b c", 6) + assert output == "'b c" + + def test_11(self, bash): + r"""a "b c| should return "b c""" + output = self._test(bash, "(a '\"b c')", 1, 'a "b c', 6) + assert output == '"b c' + + def test_12(self, bash): + """a b:c| with WORDBREAKS += : should return c""" + assert_bash_exec(bash, "add_comp_wordbreak_char :") + output = self._test(bash, "(a b : c)", 3, "a b:c", 5) + assert output == "c" + + def test_13(self, bash): + """a b:c| with WORDBREAKS -= : should return b:c""" + assert_bash_exec(bash, "add_comp_wordbreak_char :") + output = self._test(bash, "(a b : c)", 3, "a b:c", 5, arg=":") + assert output == "b:c" + + def test_14(self, bash): + """a b c:| with WORDBREAKS -= : should return c:""" + assert_bash_exec(bash, "add_comp_wordbreak_char :") + output = self._test(bash, "(a b c :)", 3, "a b c:", 6, arg=":") + assert output == "c:" + + def test_15(self, bash): + """a :| with WORDBREAKS -= : should return :""" + assert_bash_exec(bash, "add_comp_wordbreak_char :") + output = self._test(bash, "(a :)", 1, "a :", 3, arg=":") + assert output == ":" + + def test_16(self, bash): + """a b::| with WORDBREAKS -= : should return b::""" + assert_bash_exec(bash, "add_comp_wordbreak_char :") + output = self._test(bash, "(a b::)", 1, "a b::", 5, arg=":") + assert output == "b::" + + def test_17(self, bash): + """ + a -n| should return -n + + This test makes sure `_get_cword' doesn't use `echo' to return its + value, because -n might be interpreted by `echo' and thus woud not + be returned. + """ + output = self._test(bash, "(a -n)", 1, "a -n", 4) + assert output == "-n" + + def test_18(self, bash): + """a b>c| should return c""" + output = self._test(bash, r"(a b \> c)", 3, "a b>c", 5) + assert output == "c" + + def test_19(self, bash): + """a b=c| should return c""" + output = self._test(bash, "(a b = c)", 3, "a b=c", 5) + assert output == "c" + + def test_20(self, bash): + """a *| should return *""" + output = self._test(bash, r"(a \*)", 1, "a *", 4) + assert output == "*" + + def test_21(self, bash): + """a $(b c| should return $(b c""" + output = self._test(bash, r"(a '$(b c')", 1, "a $(b c", 7) + assert output == "$(b c" + + def test_22(self, bash): + r"""a $(b c\ d| should return $(b c\ d""" + output = self._test(bash, r"(a '$(b c\ d')", 1, r"a $(b c\ d", 10) + assert output == r"$(b c\ d" + + def test_23(self, bash): + """a 'b&c| should return 'b&c""" + output = self._test(bash, '(a "\'b&c")', 1, "a 'b&c", 6) + assert output == "'b&c" + + @pytest.mark.xfail(reason="TODO: non-ASCII issues with test suite?") + def test_24(self, bash): + """Index shouldn't drop below 0""" + bash.send("scp ääää§ se\t\r\n") + got = bash.expect_exact( + [ + "index: substring expression < 0", + PS1, + pexpect.EOF, + pexpect.TIMEOUT, + ] + ) + assert got == 1 diff --git a/test/t/unit/test_unit_init_completion.py b/test/t/unit/test_unit_init_completion.py new file mode 100644 index 0000000..64a5a79 --- /dev/null +++ b/test/t/unit/test_unit_init_completion.py @@ -0,0 +1,34 @@ +import pytest + +from conftest import TestUnitBase, assert_bash_exec, assert_complete + + +@pytest.mark.bashcomp( + cmd=None, + ignore_env=r"^[+-](COMP(_(WORDS|CWORD|LINE|POINT)|REPLY)|" + r"cur|cword|words)=", +) +class TestUnitInitCompletion(TestUnitBase): + def test_1(self, bash): + """Test environment non-pollution, detected at teardown.""" + assert_bash_exec( + bash, + "foo() { " + "local cur prev words cword " + "COMP_WORDS=() COMP_CWORD=0 COMP_LINE= COMP_POINT=0; " + "_init_completion; }; " + "foo; unset foo", + ) + + def test_2(self, bash): + output = self._test_unit( + "_init_completion %s; echo $cur,${prev-}", bash, "(a)", 0, "a", 0 + ) + assert output == "," + + @pytest.mark.parametrize("redirect", "> >> 2> < &>".split()) + def test_redirect(self, bash, redirect): + completion = assert_complete( + bash, "%s " % redirect, cwd="shared/default" + ) + assert all(x in completion for x in "foo bar".split()) diff --git a/test/t/unit/test_unit_ip_addresses.py b/test/t/unit/test_unit_ip_addresses.py new file mode 100644 index 0000000..8120c88 --- /dev/null +++ b/test/t/unit/test_unit_ip_addresses.py @@ -0,0 +1,49 @@ +import pytest + +from conftest import assert_bash_exec, in_container + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^\+COMPREPLY=") +class TestUnitIpAddresses: + @pytest.fixture(scope="class") + def functions(self, request, bash): + assert_bash_exec( + bash, + "_ia() { local cur=$(_get_cword);unset COMPREPLY;" + "_ip_addresses; }", + ) + assert_bash_exec(bash, "complete -F _ia ia") + assert_bash_exec( + bash, + "_iaa() { local cur=$(_get_cword);unset COMPREPLY;" + "_ip_addresses -a; }", + ) + assert_bash_exec(bash, "complete -F _iaa iaa") + assert_bash_exec( + bash, + " _ia6() { local cur=$(_get_cword);unset COMPREPLY;" + "_ip_addresses -6; }", + ) + assert_bash_exec(bash, "complete -F _ia6 ia6") + + def test_1(self, bash): + assert_bash_exec(bash, "_ip_addresses") + + @pytest.mark.complete("iaa ") + def test_2(self, functions, completion): + """_ip_addresses -a should complete ip addresses.""" + assert completion + assert all("." in x or ":" in x for x in completion) + + @pytest.mark.complete("ia ") + def test_3(self, functions, completion): + """_ip_addresses should complete ipv4 addresses.""" + assert completion + assert all("." in x for x in completion) + + @pytest.mark.xfail(in_container(), reason="Probably fails in a container") + @pytest.mark.complete("ia6 ") + def test_4(self, functions, completion): + """_ip_addresses -6 should complete ipv6 addresses.""" + assert completion + assert all(":" in x for x in completion) diff --git a/test/t/unit/test_unit_known_hosts_real.py b/test/t/unit/test_unit_known_hosts_real.py new file mode 100644 index 0000000..ac5205e --- /dev/null +++ b/test/t/unit/test_unit_known_hosts_real.py @@ -0,0 +1,158 @@ +from itertools import chain + +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp( + cmd=None, + ignore_env="^[+-](COMP(REPLY|_KNOWN_HOSTS_WITH_HOSTFILE)|OLDHOME)=", +) +class TestUnitKnownHostsReal: + @pytest.mark.parametrize( + "prefix,colon_flag,hostfile", + [("", "", True), ("", "", False), ("user@", "c", True)], + ) + def test_basic( + self, bash, hosts, avahi_hosts, prefix, colon_flag, hostfile + ): + expected = ( + "%s%s%s" % (prefix, x, ":" if colon_flag else "") + for x in chain( + hosts if hostfile else avahi_hosts, + # fixtures/_known_hosts_real/config + "gee hus jar #not-a-comment".split(), + # fixtures/_known_hosts_real/known_hosts + ( + "doo", + "ike", + "jub", + "10.0.0.1", + "kyl", + "100.0.0.2", + "10.10.0.3", + "blah", + "fd00:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:5555", + "fe80::123:0xff:dead:beef%eth0", + "1111:2222:3333:4444:5555:6666:xxxx:abab", + "11xx:2222:3333:4444:5555:6666:xxxx:abab", + "::42", + ), + ) + ) + assert_bash_exec( + bash, + "unset -v COMP_KNOWN_HOSTS_WITH_HOSTFILE" + if hostfile + else "COMP_KNOWN_HOSTS_WITH_HOSTFILE=", + ) + output = assert_bash_exec( + bash, + "_known_hosts_real -a%sF _known_hosts_real/config '%s'; " + r'printf "%%s\n" "${COMPREPLY[@]}"; unset COMPREPLY' + % (colon_flag, prefix), + want_output=True, + ) + assert sorted(set(output.split())) == sorted(expected) + + @pytest.mark.parametrize( + "family,result", + ( + ("4", "127.0.0.1 localhost"), + ("6", "::1 localhost"), + ("46", "localhost"), + ), + ) + def test_ip_filtering(self, bash, family, result): + assert_bash_exec( + bash, "unset -v COMPREPLY COMP_KNOWN_HOSTS_WITH_HOSTFILE" + ) + output = assert_bash_exec( + bash, + "COMP_KNOWN_HOSTS_WITH_HOSTFILE= " + "_known_hosts_real -%sF _known_hosts_real/localhost_config ''; " + r'printf "%%s\n" "${COMPREPLY[@]}"' % family, + want_output=True, + ) + assert sorted(set(output.strip().split())) == sorted(result.split()) + + def test_consecutive_spaces(self, bash, hosts): + expected = hosts.copy() + # fixtures/_known_hosts_real/spaced conf + expected.extend("gee hus #not-a-comment".split()) + # fixtures/_known_hosts_real/known_hosts2 + expected.extend("two two2 two3 two4".split()) + # fixtures/_known_hosts_/spaced known_hosts + expected.extend("doo ike".split()) + + output = assert_bash_exec( + bash, + "unset -v COMPREPLY COMP_KNOWN_HOSTS_WITH_HOSTFILE; " + "_known_hosts_real -aF '_known_hosts_real/spaced conf' ''; " + r'printf "%s\n" "${COMPREPLY[@]}"', + want_output=True, + ) + assert sorted(set(output.strip().split())) == sorted(expected) + + def test_files_starting_with_tilde(self, bash, hosts): + expected = hosts.copy() + # fixtures/_known_hosts_real/known_hosts2 + expected.extend("two two2 two3 two4".split()) + # fixtures/_known_hosts_real/known_hosts3 + expected.append("three") + # fixtures/_known_hosts_real/known_hosts4 + expected.append("four") + + assert_bash_exec(bash, 'OLDHOME="$HOME"; HOME="%s"' % bash.cwd) + output = assert_bash_exec( + bash, + "unset -v COMPREPLY COMP_KNOWN_HOSTS_WITH_HOSTFILE; " + "_known_hosts_real -aF _known_hosts_real/config_tilde ''; " + r'printf "%s\n" "${COMPREPLY[@]}"', + want_output=True, + ) + assert_bash_exec(bash, 'HOME="$OLDHOME"') + assert sorted(set(output.strip().split())) == sorted(expected) + + def test_included_configs(self, bash, hosts): + expected = hosts.copy() + # fixtures/_known_hosts_real/config_include_recursion + expected.append("recursion") + # fixtures/_known_hosts_real/.ssh/config_relative_path + expected.append("relative_path") + # fixtures/_known_hosts_real/.ssh/config_asterisk_* + expected.extend("asterisk_1 asterisk_2".split()) + # fixtures/_known_hosts_real/.ssh/config_question_mark + expected.append("question_mark") + + assert_bash_exec( + bash, 'OLDHOME="$HOME"; HOME="%s/_known_hosts_real"' % bash.cwd + ) + output = assert_bash_exec( + bash, + "unset -v COMPREPLY COMP_KNOWN_HOSTS_WITH_HOSTFILE; " + "_known_hosts_real -aF _known_hosts_real/config_include ''; " + r'printf "%s\n" "${COMPREPLY[@]}"', + want_output=True, + ) + assert_bash_exec(bash, 'HOME="$OLDHOME"') + assert sorted(set(output.strip().split())) == sorted(expected) + + def test_no_globbing(self, bash): + assert_bash_exec( + bash, 'OLDHOME="$HOME"; HOME="%s/_known_hosts_real"' % bash.cwd + ) + output = assert_bash_exec( + bash, + "cd _known_hosts_real; " + "unset -v COMPREPLY COMP_KNOWN_HOSTS_WITH_HOSTFILE; " + "_known_hosts_real -aF config ''; " + r'printf "%s\n" "${COMPREPLY[@]}"; ' + "cd - &>/dev/null", + want_output=True, + ) + assert_bash_exec(bash, 'HOME="$OLDHOME"') + completion = sorted(set(output.strip().split())) + assert "gee" in completion + assert "gee-filename-canary" not in completion diff --git a/test/t/unit/test_unit_longopt.py b/test/t/unit/test_unit_longopt.py new file mode 100644 index 0000000..c5488e3 --- /dev/null +++ b/test/t/unit/test_unit_longopt.py @@ -0,0 +1,52 @@ +# Based on work by Stephen Gildea, October 2010. + +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^\+COMPREPLY=") +class TestUnitLongopt: + @pytest.fixture(scope="class") + def functions(self, request, bash): + assert_bash_exec(bash, "_grephelp() { cat _longopt/grep--help.txt; }") + assert_bash_exec(bash, "complete -F _longopt _grephelp") + assert_bash_exec(bash, "_various() { cat _longopt/various.txt; }") + assert_bash_exec(bash, "complete -F _longopt _various") + + @pytest.mark.complete("_grephelp --") + def test_1(self, functions, completion): + """First long option should be included""" + assert completion + assert all( + x in completion for x in "--quiet --recursive --text".split() + ) + + @pytest.mark.complete("_grephelp -") + def test_2(self, functions, completion): + """Only long options should be included""" + assert completion + assert all(x.startswith("--") for x in completion) + + @pytest.mark.complete("_grephelp --") + def test_3(self, functions, completion): + """Should have both ones ending with a = and ones not""" + assert completion + assert any(x.endswith("=") for x in completion) + assert any(not x.endswith("=") for x in completion) + + @pytest.mark.complete("_various --") + def test_no_dashdashdash(self, functions, completion): + assert all(not x.startswith("---") for x in completion) + + @pytest.mark.complete("_various --") + def test_no_trailingdash(self, functions, completion): + assert all(not x.endswith("-") for x in completion) + + @pytest.mark.complete("_various --") + def test_underscore(self, functions, completion): + assert "--foo_bar" in completion + + @pytest.mark.complete("_various --") + def test_equals(self, functions, completion): + assert "--foo=" in completion diff --git a/test/t/unit/test_unit_parse_help.py b/test/t/unit/test_unit_parse_help.py new file mode 100644 index 0000000..4a02155 --- /dev/null +++ b/test/t/unit/test_unit_parse_help.py @@ -0,0 +1,183 @@ +# Based on work by Stephen Gildea, October 2010. + +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^\+declare -f fn$") +class TestUnitParseHelp: + def test_1(self, bash): + assert_bash_exec(bash, "fn() { echo; }") + output = assert_bash_exec(bash, "_parse_help fn") + assert not output + + def test_2(self, bash): + assert_bash_exec(bash, "fn() { echo 'no dashes here'; }") + output = assert_bash_exec(bash, "_parse_help fn") + assert not output + + def test_3(self, bash): + assert_bash_exec(bash, "fn() { echo 'internal-dash'; }") + output = assert_bash_exec(bash, "_parse_help fn") + assert not output + + def test_4(self, bash): + assert_bash_exec(bash, "fn() { echo 'no -leading-dashes'; }") + output = assert_bash_exec(bash, "_parse_help fn") + assert not output + + def test_5(self, bash): + assert_bash_exec(bash, "fn() { echo '-one dash'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "-one".split() + + def test_6(self, bash): + assert_bash_exec(bash, "fn() { echo ' -space dash'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "-space".split() + + def test_7(self, bash): + assert_bash_exec(bash, "fn() { echo '-one -two dashes'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "-one".split() + + def test_8(self, bash): + assert_bash_exec(bash, "fn() { echo '-one,-t dashes'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "-one".split() + + def test_9(self, bash): + assert_bash_exec(bash, "fn() { echo '-one dash-inside'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "-one".split() + + def test_10(self, bash): + """Test value not included in completion.""" + assert_bash_exec(bash, "fn() { echo '--long-arg=value'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--long-arg=".split() + + def test_11(self, bash): + """Test -value not seen as option.""" + assert_bash_exec(bash, "fn() { echo '--long-arg=-value'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--long-arg=".split() + + def test_12(self, bash): + assert_bash_exec(bash, "fn() { echo '--long-arg=-value,--opt2=val'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--long-arg=".split() + + def test_13(self, bash): + assert_bash_exec(bash, "fn() { echo '-m,--mirror'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--mirror".split() + + def test_14(self, bash): + assert_bash_exec(bash, "fn() { echo '-T/--upload-file'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--upload-file".split() + + def test_15(self, bash): + assert_bash_exec(bash, "fn() { echo '-T|--upload-file'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--upload-file".split() + + def test_16(self, bash): + assert_bash_exec(bash, "fn() { echo '-f, -F, --foo'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo".split() + + def test_17(self, bash): + assert_bash_exec(bash, "fn() { echo '--foo[=bar]'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo".split() + + def test_18(self, bash): + assert_bash_exec(bash, "fn() { echo '--foo=<bar>'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo=".split() + + def test_19(self, bash): + assert_bash_exec(bash, "fn() { echo '--foo={bar,quux}'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo=".split() + + def test_20(self, bash): + assert_bash_exec(bash, "fn() { echo '--[no]foo'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo --nofoo".split() + + def test_21(self, bash): + assert_bash_exec(bash, "fn() { echo '--[no-]bar[=quux]'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--bar --no-bar".split() + + def test_22(self, bash): + assert_bash_exec(bash, "fn() { echo '--[no-]bar=quux'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--bar= --no-bar=".split() + + def test_23(self, bash): + assert_bash_exec(bash, "fn() { echo '--[dont-]foo'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo --dont-foo".split() + + def test_24(self, bash): + assert_bash_exec(bash, "fn() { echo '-[dont]x --[dont]yy'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--yy --dontyy".split() + + def test_25(self, bash): + assert_bash_exec(bash, "fn() { echo '-f FOO, --foo=FOO'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo=".split() + + def test_26(self, bash): + assert_bash_exec(bash, "fn() { echo '-f [FOO], --foo[=FOO]'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo".split() + + def test_27(self, bash): + assert_bash_exec(bash, "fn() { echo '--foo.'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo".split() + + def test_28(self, bash): + assert_bash_exec(bash, "fn() { echo '-f or --foo'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo".split() + + def test_29(self, bash): + """Test parsing from stdin.""" + output = assert_bash_exec( + bash, "echo '-f or --foo' | _parse_help -", want_output=True + ) + assert output.split() == "--foo".split() + + def test_30(self, bash): + """More than two dashes should not be treated as options.""" + assert_bash_exec( + bash, r"fn() { printf '%s\n' $'----\n---foo\n----- bar'; }" + ) + output = assert_bash_exec(bash, "_parse_help fn") + assert not output + + def test_31(self, bash): + assert_bash_exec( + bash, + r"fn() { printf '%s\n' " + r"'-F ERROR_FORMAT, --error-format ERROR_FORMAT'; }", + ) + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--error-format".split() + + def test_32(self, bash): + assert_bash_exec( + bash, + r"fn() { printf '%s\n' " + r"'-e CODE1,CODE2.. --exclude=CODE1,CODE2..'; }", + ) + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--exclude=".split() diff --git a/test/t/unit/test_unit_parse_usage.py b/test/t/unit/test_unit_parse_usage.py new file mode 100644 index 0000000..f0cb711 --- /dev/null +++ b/test/t/unit/test_unit_parse_usage.py @@ -0,0 +1,69 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^\+declare -f fn$") +class TestUnitParseUsage: + def test_1(self, bash): + assert_bash_exec(bash, "fn() { echo; }") + output = assert_bash_exec(bash, "_parse_usage fn") + assert not output + + def test_2(self, bash): + assert_bash_exec(bash, "fn() { echo 'no dashes here'; }") + output = assert_bash_exec(bash, "_parse_usage fn") + assert not output + + def test_3(self, bash): + assert_bash_exec(bash, "fn() { echo 'foo [-f]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "-f".split() + + def test_4(self, bash): + assert_bash_exec(bash, "fn() { echo 'bar [-aBcD] [-e X]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "-a -B -c -D -e".split() + + def test_5(self, bash): + assert_bash_exec(bash, "fn() { echo '[-[XyZ]] [--long=arg]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "-X -y -Z --long=".split() + + def test_6(self, bash): + assert_bash_exec(bash, "fn() { echo '[-s|--long]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "--long".split() + + def test_7(self, bash): + assert_bash_exec(bash, "fn() { echo '[-s, --long=arg]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "--long=".split() + + def test_8(self, bash): + assert_bash_exec(bash, "fn() { echo '[--long/-s] [-S/--longer]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "--long --longer".split() + + def test_9(self, bash): + assert_bash_exec(bash, "fn() { echo '[ -a ] [ -b foo ]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "-a -b".split() + + def test_10(self, bash): + assert_bash_exec(bash, "fn() { echo '[ -a | --aa ]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "--aa".split() + + def test_11(self, bash): + assert_bash_exec( + bash, "fn() { echo ----; echo ---foo; echo '----- bar'; }" + ) + output = assert_bash_exec(bash, "_parse_usage fn") + assert not output + + def test_12(self, bash): + output = assert_bash_exec( + bash, "echo '[-duh]' | _parse_usage -", want_output=True + ) + assert output.split() == "-d -u -h".split() diff --git a/test/t/unit/test_unit_quote.py b/test/t/unit/test_unit_quote.py new file mode 100644 index 0000000..b280bd6 --- /dev/null +++ b/test/t/unit/test_unit_quote.py @@ -0,0 +1,36 @@ +import pytest + +from conftest import TestUnitBase, assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None) +class TestUnitQuote(TestUnitBase): + def test_1(self, bash): + output = assert_bash_exec( + bash, 'quote "a b"', want_output=True, want_newline=False + ) + assert output.strip() == "'a b'" + + def test_2(self, bash): + output = assert_bash_exec( + bash, 'quote "a b"', want_output=True, want_newline=False + ) + assert output.strip() == "'a b'" + + def test_3(self, bash): + output = assert_bash_exec( + bash, 'quote " a "', want_output=True, want_newline=False + ) + assert output.strip() == "' a '" + + def test_4(self, bash): + output = assert_bash_exec( + bash, "quote \"a'b'c\"", want_output=True, want_newline=False + ) + assert output.strip() == r"'a'\''b'\''c'" + + def test_5(self, bash): + output = assert_bash_exec( + bash, 'quote "a\'"', want_output=True, want_newline=False + ) + assert output.strip() == r"'a'\'''" diff --git a/test/t/unit/test_unit_quote_readline.py b/test/t/unit/test_unit_quote_readline.py new file mode 100644 index 0000000..e2b437e --- /dev/null +++ b/test/t/unit/test_unit_quote_readline.py @@ -0,0 +1,15 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None) +class TestUnitQuoteReadline: + def test_exec(self, bash): + assert_bash_exec(bash, "quote_readline '' >/dev/null") + + def test_env_non_pollution(self, bash): + """Test environment non-pollution, detected at teardown.""" + assert_bash_exec( + bash, "foo() { quote_readline meh >/dev/null; }; foo; unset foo" + ) diff --git a/test/t/unit/test_unit_tilde.py b/test/t/unit/test_unit_tilde.py new file mode 100644 index 0000000..35a4e4c --- /dev/null +++ b/test/t/unit/test_unit_tilde.py @@ -0,0 +1,42 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^\+COMPREPLY=") +class TestUnitTilde: + def test_1(self, bash): + assert_bash_exec(bash, "_tilde >/dev/null") + + def test_2(self, bash): + """Test environment non-pollution, detected at teardown.""" + assert_bash_exec( + bash, 'foo() { local aa="~"; _tilde "$aa"; }; foo; unset foo' + ) + + def test_3(self, bash): + """Test for https://bugs.debian.org/766163""" + assert_bash_exec(bash, "_tilde ~-o") + + def _test_part_full(self, bash, part, full): + res = ( + assert_bash_exec( + bash, + '_tilde "~%s"; echo "${COMPREPLY[@]}"' % part, + want_output=True, + ) + .strip() + .split() + ) + assert res + assert res[0] == "~%s" % full + + def test_4(self, bash, part_full_user): + """~full should complete to ~full unmodified.""" + _, full = part_full_user + self._test_part_full(bash, full, full) + + def test_5(self, bash, part_full_user): + """~part should complete to ~full.""" + part, full = part_full_user + self._test_part_full(bash, part, full) diff --git a/test/t/unit/test_unit_variables.py b/test/t/unit/test_unit_variables.py new file mode 100644 index 0000000..d62bc4a --- /dev/null +++ b/test/t/unit/test_unit_variables.py @@ -0,0 +1,41 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^[+-](___var|assoc[12])=") +class TestUnitVariables: + @pytest.fixture(scope="class") + def functions(self, request, bash): + assert_bash_exec(bash, "unset assoc1 && declare -A assoc1=([idx]=1)") + assert_bash_exec( + bash, "unset assoc2 && declare -A assoc2=([idx1]=1 [idx2]=2)" + ) + assert_bash_exec(bash, "unset ${!___v*} && declare ___var=''") + request.addfinalizer( + lambda: assert_bash_exec(bash, "unset ___var assoc1 assoc2") + ) + + @pytest.mark.complete(": $___v") + def test_simple_variable_name(self, functions, completion): + assert completion == "ar" + + @pytest.mark.complete(": ${assoc1[") + def test_single_array_index(self, functions, completion): + assert completion == "idx]}" + + @pytest.mark.complete(": ${assoc2[") + def test_multiple_array_indexes(self, functions, completion): + assert completion == "${assoc2[idx1]} ${assoc2[idx2]}".split() + + @pytest.mark.complete(": ${assoc1[bogus]") + def test_closing_curly_after_square(self, functions, completion): + assert completion == "}" + + @pytest.mark.complete(": ${assoc1[@") + def test_closing_brackets_after_at(self, functions, completion): + assert completion == "]}" + + @pytest.mark.complete(": ${#___v") + def test_hash_prefix(self, functions, completion): + assert completion == "ar}" diff --git a/test/t/unit/test_unit_xinetd_services.py b/test/t/unit/test_unit_xinetd_services.py new file mode 100644 index 0000000..7a90cb7 --- /dev/null +++ b/test/t/unit/test_unit_xinetd_services.py @@ -0,0 +1,22 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^\+COMPREPLY=") +class TestUnitXinetdServices: + def test_direct(self, bash): + assert_bash_exec(bash, "_xinetd_services >/dev/null") + + def test_env_non_pollution(self, bash): + """Test environment non-pollution, detected at teardown.""" + assert_bash_exec(bash, "foo() { _xinetd_services; }; foo; unset foo") + + def test_basic(self, bash): + output = assert_bash_exec( + bash, + "foo() { local BASHCOMP_XINETDDIR=$PWD/shared/bin;unset COMPREPLY; " + '_xinetd_services; printf "%s\\n" "${COMPREPLY[@]}"; }; foo; unset foo', + want_output=True, + ) + assert sorted(output.split()) == ["arp", "ifconfig"] diff --git a/test/test-cmd-list.txt b/test/test-cmd-list.txt new file mode 100644 index 0000000..eb8398e --- /dev/null +++ b/test/test-cmd-list.txt @@ -0,0 +1,687 @@ +2to3 +7z +a2ps +a2x +abook +aclocal +acpi +acroread +adb +add_members +alias +alpine +animate +ant +apache2ctl +appdata-validate +apt-build +apt-cache +apt-get +aptitude +arch +arp +arping +arpspoof +asciidoc +aspell +autoconf +autoheader +automake +autoreconf +autorpm +autoscan +autossh +autoupdate +avctrl +awk +badblocks +base64 +bash +bc +/bin/chroot +bind +/bin/rmdir +bison +bk +bmake +brctl +bsdtar +btdownloadcurses.py +btdownloadgui.py +btdownloadheadless.py +bts +bzip2 +c++ +cal +cancel +cardctl +carton +cat +cc +ccache +ccze +cd +cdrecord +cfagent +cfrun +chage +change_pw +check_db +check_perms +checksec +chfn +chgrp +chkconfig +chmod +chown +chpasswd +chromium-browser +chronyc +chroot +chrpath +chsh +ci +ciptool +civclient +civserver +cksfv +cleanarch +clisp +clone_member +co +colordiff +compare +compgen +complete +composite +config_list +configure +conjure +convert +cowsay +cp +cpan2dist +cpio +cppcheck +createdb +createuser +crontab +cryptsetup +csplit +curl +cut +cvs +cvsps +date +dcop +dd +declare +deja-dup +desktop-file-validate +df +dfutool +dhclient +dict +diff +dir +display +dmesg +dmypy +dnssec-keygen +dnsspoof +dot +dpkg +dpkg-deb +dpkg-query +dpkg-reconfigure +dpkg-source +dropdb +dropuser +dselect +dsniff +du +dumpdb +dumpe2fs +e2freefrag +e2label +ebtables +ecryptfs-migrate-home +eject +enscript +env +eog +etherwake +ether-wake +evince +expand +explodepkg +export +faillog +fbgs +fbi +feh +file +filefrag +file-roller +filesnarf +find +find_member +finger +fio +firefox +flake8 +fmt +fold +freebsd-update +freeciv +freeciv-server +function +fusermount +g++ +g4 +g77 +gcc +gcj +gcl +gdb +genaliases +gendiff +genisoimage +geoiplookup +getconf +getent +gkrellm +gm +gmplayer +gnatmake +gnokii +gnome-mplayer +gnome-screenshot +gpasswd +gpc +gperf +gpg +gpg2 +gpgv +gphoto2 +gprof +grep +groupadd +groupdel +groupmems +groupmod +growisofs +grpck +grub +gssdp-discover +gzip +hciattach +hciconfig +hcitool +hddtemp +head +hexdump +hid2hci +host +hostname +hping2 +hping3 +htop +htpasswd +hunspell +hwclock +iconv +id +identify +idn +ifdown +ifstat +iftop +ifup +import +influx +info +inject +inotifywait +inotifywatch +insmod +installpkg +interdiff +invoke-rc.d +ionice +ip +ipcalc +iperf +iperf3 +ipmitool +ipsec +iptables +ipv6calc +irb +iscsiadm +isort +isql +iwconfig +iwlist +iwpriv +iwspy +jar +jarsigner +java +javac +javadoc +javaws +jpegoptim +jps +jq +jshint +jsonschema +json_xs +k3b +kcov +kdvi +kill +killall +kldload +kldunload +koji +kpdf +kplayer +ktutil +l2ping +larch +lastlog +ld +ldapadd +ldapcompare +ldapdelete +ldapmodrdn +ldappasswd +ldapsearch +ldapvi +ldapwhoami +ldd +less +lftp +lftpget +lilo +links +lintian +lintian-info +lisp +list_admins +list_lists +list_members +list_owners +ln +locale-gen +look +lpq +lpr +lrzip +ls +lsof +lspci +lsscsi +lsusb +lua +luac +luseradd +luserdel +lusermod +lvchange +lvcreate +lvdisplay +lvextend +lvm +lvmdiskscan +lvreduce +lvremove +lvrename +lvresize +lvs +lvscan +lz4 +lzip +lzma +lzop +m4 +macof +mailmanctl +mailsnarf +make +makepkg +man +mc +mcrypt +md5sum +mdadm +mdecrypt +mdtool +medusa +mencoder +mii-diag +mii-tool +minicom +mkdir +mkfifo +mkinitrd +mkisofs +mknod +mktemp +mmsitepass +mock +modinfo +modprobe +module +mogrify +monodevelop +montage +mount +mplayer +mr +msgsnarf +msynctool +mtx +munindoc +munin-node-configure +munin-run +mussh +mutt +muttng +mv +mypy +mysql +mysqladmin +nc +ncftp +nethogs +netstat +newgrp +newlist +newusers +ngrep +nl +nm +nmap +nmcli +nproc +nslookup +nsupdate +ntpdate +objcopy +objdump +od +oggdec +op +openssl +opera +optipng +p4 +pack200 +passwd +paste +patch +pdftotext +perl +perlcritic +perldoc +perltidy +pgrep +phing +pidof +pine +pinfo +ping +pkgadd +pkg-config +pkg_deinstall +pkg_delete +pkg-get +pkg_info +pkgrm +pkgtool +pkgutil +pkill +plague-client +pm-hibernate +pm-is-supported +pm-powersave +pngfix +portinstall +portsnap +portupgrade +postcat +postconf +postfix +postmap +postsuper +povray +pr +prelink +printenv +protoc +psql +ptx +puppet +pushd +pv +pvchange +pvcreate +pvdisplay +pvmove +pvremove +pvs +pvscan +pwck +pwd +pwdx +pwgen +pycodestyle +pydoc +pydocstyle +pyflakes +pylint +pylint-3 +pytest +python +python3 +pyvenv +qemu +qrunner +querybts +quota +quotacheck +quotaon +radvdump +rcs +rcsdiff +rdesktop +rdict +readelf +readonly +remove_members +removepkg +renice +repomanage +reportbug +reptyr +resolvconf +rfcomm +rfkill +ri +rlog +rm +rmdir +rmlist +rmmod +route +rpcdebug +rpm +rpm2tgz +rpmbuild +rrdtool +rsync +rtcwake +runuser +sbcl +sbcl-mt +sbopkg +scp +screen +scrub +sdptool +secret-tool +sed +seq +service +set +setquota +sftp +sh +sha1sum +shar +shellcheck +sitecopy +slackpkg +slapt-get +slapt-src +smartctl +smbcacls +smbclient +smbcquotas +smbget +smbpasswd +smbtar +smbtree +snownews +sort +split +spovray +sqlite3 +ss +ssh +ssh-add +ssh-copy-id +sshfs +ssh-keygen +sshmitm +sshow +strace +stream +strings +strip +su +sudo +sum +svcadm +svk +svn +svnadmin +svnlook +synclient +sync_members +sysbench +sysctl +tac +tail +tar +tcpdump +tcpkill +tcpnice +tee +texindex +tightvncviewer +time +timeout +tipc +totem +touch +tox +tr +tracepath +tshark +tsig-keygen +tune2fs +udevadm +ulimit +umount +unace +uname +unexpand +uniq +units +unpack200 +unrar +unset +unshunt +update-alternatives +update-rc.d +upgradepkg +urlsnarf +uscan +useradd +userdel +usermod +valgrind +vdir +vgcfgbackup +vgcfgrestore +vgchange +vgck +vgconvert +vgcreate +vgdisplay +vgexport +vgextend +vgimport +vgmerge +vgmknodes +vgreduce +vgremove +vgrename +vgs +vgscan +vgsplit +vi +vipw +vmstat +vncviewer +vpnc +watch +wc +webmitm +wget +who +wine +withlist +wodim +wol +write +wsimport +wtf +wvdial +xdg-mime +xdg-settings +xfreerdp +xgamma +xm +xmllint +xmlwf +xmms +xmodmap +xpovray +xrandr +xrdb +xsltproc +xvfb-run +xvnc4viewer +xxd +xz +xzdec +ypcat +ypmatch +yum +yum-arch +zopfli +zopflipng diff --git a/test/update-test-cmd-list b/test/update-test-cmd-list new file mode 100755 index 0000000..115ae16 --- /dev/null +++ b/test/update-test-cmd-list @@ -0,0 +1,13 @@ +#!/bin/bash -eu + +mydir=$( + cd "$(dirname "$0")" + pwd +) + +cat "$mydir"/t/test_*.py | + tr -d '\n' | + grep -Eo '@pytest.mark.complete(\([^)]*\))' | + sed -ne 's/^[^"]*"\\\?\([^_][^[:space:]"]*\)[[:space:]"].*/\1/p' | + sort -u \ + >"$mydir"/test-cmd-list.txt |