mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-25 20:33:08 +00:00
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.
This commit is contained in:
parent
a381ac2691
commit
8a3cf144f2
4 changed files with 54 additions and 3 deletions
15
complete.cpp
15
complete.cpp
|
@ -412,7 +412,8 @@ public:
|
||||||
void complete_cmd(const wcstring &str,
|
void complete_cmd(const wcstring &str,
|
||||||
bool use_function,
|
bool use_function,
|
||||||
bool use_builtin,
|
bool use_builtin,
|
||||||
bool use_command);
|
bool use_command,
|
||||||
|
bool use_implicit_cd);
|
||||||
|
|
||||||
void complete_from_args(const wcstring &str,
|
void complete_from_args(const wcstring &str,
|
||||||
const wcstring &args,
|
const wcstring &args,
|
||||||
|
@ -1133,7 +1134,7 @@ static wcstring complete_function_desc(const wcstring &fn)
|
||||||
|
|
||||||
\param comp the list to add all completions to
|
\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 */
|
/* Paranoia */
|
||||||
if (str_cmd.empty())
|
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 (str_cmd.find(L'/') == wcstring::npos && str_cmd.at(0) != L'~')
|
||||||
{
|
{
|
||||||
if (use_command)
|
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_command = 1;
|
||||||
bool use_function = 1;
|
bool use_function = 1;
|
||||||
bool use_builtin = 1;
|
bool use_builtin = 1;
|
||||||
|
bool use_implicit_cd = 1;
|
||||||
|
|
||||||
//debug( 1, L"Complete '%ls'", cmd.c_str() );
|
//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_command = true;
|
||||||
use_function = true;
|
use_function = true;
|
||||||
use_builtin = true;
|
use_builtin = true;
|
||||||
|
use_implicit_cd = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case parse_statement_decoration_command:
|
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_command = true;
|
||||||
use_function = false;
|
use_function = false;
|
||||||
use_builtin = false;
|
use_builtin = false;
|
||||||
|
use_implicit_cd = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case parse_statement_decoration_builtin:
|
case parse_statement_decoration_builtin:
|
||||||
use_command = false;
|
use_command = false;
|
||||||
use_function = false;
|
use_function = false;
|
||||||
use_builtin = true;
|
use_builtin = true;
|
||||||
|
use_implicit_cd = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd_node && cmd_node->location_in_or_at_end_of_source_range(pos))
|
if (cmd_node && cmd_node->location_in_or_at_end_of_source_range(pos))
|
||||||
{
|
{
|
||||||
/* Complete command filename */
|
/* 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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# vim: set filetype=fish:
|
||||||
|
|
||||||
# Test that conditions that add or remove completions don't deadlock, etc.
|
# 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)
|
# 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
|
complete -c CCCC -e
|
||||||
echo "CCCC:"
|
echo "CCCC:"
|
||||||
complete -C'CCCC -' | sort
|
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
|
||||||
|
|
|
@ -30,3 +30,6 @@ CCCC:
|
||||||
-b
|
-b
|
||||||
-bar
|
-bar
|
||||||
CCCC:
|
CCCC:
|
||||||
|
implicit cd complete works
|
||||||
|
no implicit cd complete after 'command'
|
||||||
|
PATH does not cause incorrect implicit cd
|
||||||
|
|
10
wildcard.cpp
10
wildcard.cpp
|
@ -732,6 +732,16 @@ static bool test_flags(const wchar_t *filename, expand_flags_t flags)
|
||||||
{
|
{
|
||||||
if (waccess(filename, X_OK) != 0)
|
if (waccess(filename, X_OK) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
struct stat buf;
|
||||||
|
if (wstat(filename, &buf) == -1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!S_ISREG(buf.st_mode))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in a new issue