diff options
author | Kevin Ballard <kevin@sb.org> | 2014-09-20 00:26:10 -0700 |
---|---|---|
committer | Kevin Ballard <kevin@sb.org> | 2014-09-20 00:31:33 -0700 |
commit | 8a3cf144f25dd0cb1e20928b2c2f2c53b34c40c3 (patch) | |
tree | 362fd43b490ecea73a023f249106bf9e35455ff7 | |
parent | a381ac2691b7c1d52ec7436a7c97ba91b3d496aa (diff) |
Don't include child directories of $PATH in completions
Directories are completed like commands, because of implicit cd.
However, directories found inside $PATH entries should not be completed,
as implicit cd doesn't work there. Similarly, directories should not be
completed after the `command` builtin.
Fixes #1695.
-rw-r--r-- | complete.cpp | 15 | ||||
-rwxr-xr-x | tests/test6.in | 29 | ||||
-rw-r--r-- | tests/test6.out | 3 | ||||
-rw-r--r-- | wildcard.cpp | 10 |
4 files changed, 54 insertions, 3 deletions
diff --git a/complete.cpp b/complete.cpp index 311e4141..9f9a27b8 100644 --- a/complete.cpp +++ b/complete.cpp @@ -412,7 +412,8 @@ public: void complete_cmd(const wcstring &str, bool use_function, bool use_builtin, - bool use_command); + bool use_command, + bool use_implicit_cd); void complete_from_args(const wcstring &str, const wcstring &args, @@ -1133,7 +1134,7 @@ static wcstring complete_function_desc(const wcstring &fn) \param comp the list to add all completions to */ -void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool use_builtin, bool use_command) +void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool use_builtin, bool use_command, bool use_implicit_cd) { /* Paranoia */ if (str_cmd.empty()) @@ -1156,6 +1157,10 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool } } } + if (use_implicit_cd) + { + (void)expand_string(str_cmd, this->completions, ACCEPT_INCOMPLETE | DIRECTORIES_ONLY | this->expand_flags(), NULL); + } if (str_cmd.find(L'/') == wcstring::npos && str_cmd.at(0) != L'~') { if (use_command) @@ -1861,6 +1866,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> &comps bool use_command = 1; bool use_function = 1; bool use_builtin = 1; + bool use_implicit_cd = 1; //debug( 1, L"Complete '%ls'", cmd.c_str() ); @@ -1942,6 +1948,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> &comps use_command = true; use_function = true; use_builtin = true; + use_implicit_cd = true; break; case parse_statement_decoration_command: @@ -1949,19 +1956,21 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> &comps use_command = true; use_function = false; use_builtin = false; + use_implicit_cd = false; break; case parse_statement_decoration_builtin: use_command = false; use_function = false; use_builtin = true; + use_implicit_cd = false; break; } if (cmd_node && cmd_node->location_in_or_at_end_of_source_range(pos)) { /* Complete command filename */ - completer.complete_cmd(current_token, use_function, use_builtin, use_command); + completer.complete_cmd(current_token, use_function, use_builtin, use_command, use_implicit_cd); } else { diff --git a/tests/test6.in b/tests/test6.in index 93be594a..9a441b65 100755 --- a/tests/test6.in +++ b/tests/test6.in @@ -1,3 +1,4 @@ +# vim: set filetype=fish: # Test that conditions that add or remove completions don't deadlock, etc. # We actually encountered some case that was effectively like this (Issue 2 in github) @@ -43,3 +44,31 @@ complete -C'CCCC -' | sort complete -c CCCC -e echo "CCCC:" complete -C'CCCC -' | sort + +# Test that directory completions work correctly +if begin; rm -rf test6.tmp.dir; and mkdir test6.tmp.dir; end + pushd test6.tmp.dir + set -l dir (mktemp -d XXXXXXXX) + if complete -C$dir | grep "^$dir/.*Directory" >/dev/null + echo "implicit cd complete works" + else + echo "no implicit cd complete" + end + if complete -C"command $dir" | grep "^$dir/.*Directory" >/dev/null + echo "implicit cd complete incorrect after 'command'" + else + echo "no implicit cd complete after 'command'" + end + popd + if begin + set -l PATH $PWD/test6.tmp.dir $PATH + complete -C$dir | grep "^$dir/.*Directory" >/dev/null + end + echo "incorrect implicit cd from PATH" + else + echo "PATH does not cause incorrect implicit cd" + end + rm -rf test6.tmp.dir +else + echo "error: could not create temp environment" >&2 +end diff --git a/tests/test6.out b/tests/test6.out index d61d3c5f..268b05ea 100644 --- a/tests/test6.out +++ b/tests/test6.out @@ -30,3 +30,6 @@ CCCC: -b -bar CCCC: +implicit cd complete works +no implicit cd complete after 'command' +PATH does not cause incorrect implicit cd diff --git a/wildcard.cpp b/wildcard.cpp index fde6ddc6..7814a53f 100644 --- a/wildcard.cpp +++ b/wildcard.cpp @@ -732,6 +732,16 @@ static bool test_flags(const wchar_t *filename, expand_flags_t flags) { if (waccess(filename, X_OK) != 0) return false; + struct stat buf; + if (wstat(filename, &buf) == -1) + { + return false; + } + + if (!S_ISREG(buf.st_mode)) + { + return false; + } } return true; |