Skip to content

Commit 5c75fa3

Browse files
scopakinomyoga
andcommitted
feat(env): complete commands and variable assignments
Refs #1111 Co-authored-by: Koichi Murase <[email protected]>
1 parent a3e8a5e commit 5c75fa3

File tree

4 files changed

+75
-1
lines changed

4 files changed

+75
-1
lines changed

bash_completion

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2991,7 +2991,7 @@ _comp_complete_longopt()
29912991
# makeinfo and texi2dvi are defined elsewhere.
29922992
complete -F _comp_complete_longopt \
29932993
a2ps awk base64 bash bc bison cat chroot colordiff cp \
2994-
csplit cut date df diff dir du enscript env expand fmt fold gperf \
2994+
csplit cut date df diff dir du enscript expand fmt fold gperf \
29952995
grep grub head irb ld ldd less ln ls m4 mkdir mkfifo mknod \
29962996
mv netstat nl nm objcopy objdump od paste pr ptx readelf rm rmdir \
29972997
sed seq shar sort split strip sum tac tail tee \

completions/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ bashcomp_DATA = 2to3 \
100100
ebtables \
101101
ecryptfs-migrate-home \
102102
_eject \
103+
env \
103104
eog \
104105
ether-wake \
105106
evince \

completions/env

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# bash completion for env(1) -*- shell-script -*-
2+
3+
_comp_cmd_env()
4+
{
5+
local cur prev words cword was_split comp_args
6+
_comp_initialize -s -- "$@" || return
7+
8+
local i noargopts='!(-*|*[uCS]*)'
9+
for ((i = 1; i <= cword; i++)); do
10+
if [[ ${words[i]} != -* && ${words[i]} != *=* ]]; then
11+
_comp_command_offset $i
12+
return
13+
fi
14+
# shellcheck disable=SC2254
15+
[[ ${words[i]} == @(--@(unset|chdir|split-string)|-${noargopts}[uCS]) ]] &&
16+
((i++))
17+
done
18+
19+
# shellcheck disable=SC2254
20+
case "$prev" in
21+
--unset | -${noargopts}u)
22+
_comp_compgen -- -A variable
23+
return
24+
;;
25+
--chdir | -${noargopts}C)
26+
_comp_compgen_filedir -d
27+
return
28+
;;
29+
--split-string | -${noargopts}S)
30+
return
31+
;;
32+
--block-signal | --default-signal | --ignore-signal)
33+
# TODO signals, but only if completing with a =SIG
34+
;;
35+
esac
36+
37+
[[ $was_split ]] && return
38+
39+
_comp_variable_assignments "$cur" && return
40+
41+
if [[ $cur == -* ]]; then
42+
_comp_compgen_help || _comp_compgen_usage
43+
[[ ${COMPREPLY-} == *= ]] && compopt -o nospace
44+
return
45+
fi
46+
} &&
47+
complete -F _comp_cmd_env env
48+
49+
# ex: filetype=sh

test/t/test_env.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,31 @@
11
import pytest
22

3+
from conftest import assert_complete
4+
35

46
class TestEnv:
57
@pytest.mark.complete("env --", require_longopt=True)
68
def test_1(self, completion):
79
assert completion
10+
11+
@pytest.mark.complete("env __unknown_variable__=")
12+
def test_unknown_variable_falls_back_to_filedir(self, completion):
13+
assert "shared/" in completion
14+
15+
@pytest.mark.complete("env LANG=", xfail="! locale -a &>/dev/null")
16+
def test_lang_envvar(self, completion):
17+
assert any(x == "C" or x.startswith("C.") for x in completion)
18+
19+
@pytest.mark.parametrize(
20+
"opts",
21+
[
22+
"",
23+
"foo=bar",
24+
"--debug",
25+
"foo=bar --debug",
26+
"--debug foo=bar",
27+
],
28+
)
29+
def test_command(self, bash, opts):
30+
completion = assert_complete(bash, "env %s s" % opts)
31+
assert completion == "h" or "sh" in completion

0 commit comments

Comments
 (0)