diff --git a/bash_completion b/bash_completion index 89a9584be12..cf16b672924 100644 --- a/bash_completion +++ b/bash_completion @@ -2856,7 +2856,7 @@ _comp_command_offset() _comp_compgen_commands else _comp_dequote "${COMP_WORDS[0]}" || REPLY=${COMP_WORDS[0]} - local cmd=$REPLY compcmd=$REPLY + local cmd=${REPLY-} compcmd=${REPLY-} local cspec=$(complete -p -- "$cmd" 2>/dev/null) # If we have no completion for $cmd yet, see if we have for basename diff --git a/completions/ssh b/completions/ssh index b8e84b38f88..55753333684 100644 --- a/completions/ssh +++ b/completions/ssh @@ -459,7 +459,6 @@ _comp_cmd_sftp() shopt -u hostcomplete && complete -F _comp_cmd_sftp sftp # things we want to backslash escape in scp paths -# shellcheck disable=SC2089 _comp_cmd_scp__path_esc='[][(){}<>"'"'"',:;^&!$=?`\\|[:space:]]' # Complete remote files with ssh. Returns paths escaped with three backslashes @@ -493,7 +492,6 @@ _comp_xfunc_scp_compgen_remote_files() local _path=${cur#*:} # unescape (3 backslashes to 1 for chars we escaped) - # shellcheck disable=SC2090 _path=$(command sed -e 's/\\\\\\\('"$_comp_cmd_scp__path_esc"'\)/\\\1/g' <<<"$_path") # default to home dir of specified user on remote host @@ -509,18 +507,17 @@ _comp_xfunc_scp_compgen_remote_files() local _files if [[ $_dirs_only ]]; 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/'"$_comp_cmd_scp__path_esc"'/'"$_escape_replacement"'/g' -e '/[^\/]$/d') + command sed -e 's/'"$_comp_cmd_scp__path_esc"'/'"$_escape_replacement"'/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/'"$_comp_cmd_scp__path_esc"'/'"$_escape_replacement"'/g' -e 's/[*@|=]$//g' \ - -e 's/[^\/]$/& /g') + command sed -e 's/[*@|=]$//g' \ + -e 's/'"$_comp_cmd_scp__path_esc"'/'"$_escape_replacement"'/g' \ + -e 's/[^/]$/& /g') fi _comp_compgen -R split -l -- "$_files" } @@ -538,25 +535,26 @@ _scp_remote_files() # @since 2.12 _comp_xfunc_scp_compgen_local_files() { - local _dirsonly="" + local _dirs_only="" if [[ ${1-} == -d ]]; then - _dirsonly=set + _dirs_only=set shift fi local files _comp_expand_glob files '"$cur"*' || return 0 - if [[ $_dirsonly ]]; then - _comp_compgen -U files split -l -- "$( + if [[ $_dirs_only ]]; then + _comp_compgen -RU files split -l ${1:+-P "$1"} -- "$( command ls -aF1dL "${files[@]}" 2>/dev/null | command sed -e "s/$_comp_cmd_scp__path_esc/\\\\&/g" \ - -e '/[^\/]$/d' -e "s/^/${1-}/" + -e '/[^/]$/d' )" else - _comp_compgen -U files split -l -- "$( + _comp_compgen -RU files split -l ${1:+-P "$1"} -- "$( command ls -aF1dL "${files[@]}" 2>/dev/null | - command sed -e "s/$_comp_cmd_scp__path_esc/\\\\&/g" \ - -e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' -e "s/^/${1-}/" + command sed -e 's/[*@|=]$//g' \ + -e "s/$_comp_cmd_scp__path_esc/\\\\&/g" \ + -e 's/[^/]$/& /g' )" fi } diff --git a/test/fixtures/sshfs/local_path-dir/dummy.txt b/test/fixtures/sshfs/local_path-dir/dummy.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git "a/test/fixtures/sshfs/local_path-file\\" "b/test/fixtures/sshfs/local_path-file\\" new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/t/test_cancel.py b/test/t/test_cancel.py index 4aeafd2c5fa..9384908c630 100644 --- a/test/t/test_cancel.py +++ b/test/t/test_cancel.py @@ -16,7 +16,7 @@ def added_job(self, request, bash): ) 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]) diff --git a/test/t/test_ls.py b/test/t/test_ls.py index f91ee6b2e2e..56f0ee71e90 100644 --- a/test/t/test_ls.py +++ b/test/t/test_ls.py @@ -33,7 +33,7 @@ def test_3(self, bash): 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) :] diff --git a/test/t/test_man.py b/test/t/test_man.py index 081b8fcc1e7..bec41de9613 100644 --- a/test/t/test_man.py +++ b/test/t/test_man.py @@ -23,7 +23,7 @@ def colonpath(self, request, bash): pass else: pytest.skip("Cygwin doesn't like paths with colons") - return + tmpdir, _, _ = prepare_fixture_dir( request, files=["man/man3/Bash::Completion.3pm.gz"], diff --git a/test/t/test_scp.py b/test/t/test_scp.py index b91e5476827..e630bbdc9f9 100644 --- a/test/t/test_scp.py +++ b/test/t/test_scp.py @@ -2,7 +2,12 @@ import pytest -from conftest import assert_bash_exec, assert_complete, bash_env_saved +from conftest import ( + assert_bash_exec, + assert_complete, + bash_env_saved, + prepare_fixture_dir, +) LIVE_HOST = "bash_completion" @@ -55,6 +60,14 @@ def test_capital_f_without_space(self, completion): "option requires an argument -- F" in x for x in completion ) + @pytest.mark.complete("scp -Fconf", cwd="scp") + def test_capital_f_without_space_2(self, completion): + assert completion == "ig" + + @pytest.mark.complete("scp -Fbi", cwd="scp") + def test_capital_f_without_space_3(self, completion): + assert completion == "n/" + @pytest.fixture(scope="class") def live_pwd(self, bash): try: @@ -141,3 +154,22 @@ def test_xfunc_remote_files(self, bash): "shared/default/foo ", "shared/default/foo.d/", ] + + @pytest.fixture + def tmpdir_mkfifo(self, request, bash): + tmpdir, _, _ = prepare_fixture_dir(request, files=[], dirs=[]) + + try: + assert_bash_exec(bash, "mkfifo '%s/local_path_1-pipe'" % tmpdir) + except Exception: + pytest.skip( + "The present system does not allow creating a named pipe." + ) + + return tmpdir + + def test_local_path_mark_1(self, bash, tmpdir_mkfifo): + completion = assert_complete( + bash, "scp local_path_1-", cwd=tmpdir_mkfifo + ) + assert completion == "pipe" diff --git a/test/t/test_sshfs.py b/test/t/test_sshfs.py index cb4189bf5e1..71977adf367 100644 --- a/test/t/test_sshfs.py +++ b/test/t/test_sshfs.py @@ -6,3 +6,7 @@ class TestSshfs: @pytest.mark.complete("sshfs ./") def test_1(self, completion): assert completion + + @pytest.mark.complete("sshfs local_path", cwd="sshfs") + def test_local_path_suffix_1(self, completion): + assert completion == "-dir/"