aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--complete.cpp15
-rwxr-xr-xtests/test6.in29
-rw-r--r--tests/test6.out3
-rw-r--r--wildcard.cpp10
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;