mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-02-21 09:12:11 +08:00
Don't complete variables when single quoted. Fixes #1023
This commit is contained in:
parent
414530c9c2
commit
5ea7f52df2
74
complete.cpp
74
complete.cpp
@ -1712,29 +1712,67 @@ bool completer_t::complete_variable(const wcstring &str, size_t start_offset)
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
Search the specified string for the \$ sign. If found, try to
|
||||
complete as an environment variable.
|
||||
|
||||
\return 0 if unable to complete, 1 otherwise
|
||||
*/
|
||||
bool completer_t::try_complete_variable(const wcstring &str)
|
||||
{
|
||||
size_t i = str.size();
|
||||
while (i--)
|
||||
enum {e_unquoted, e_single_quoted, e_double_quoted} mode = e_unquoted;
|
||||
const size_t len = str.size();
|
||||
|
||||
/* Get the position of the dollar heading a run of valid variable characters. -1 means none. */
|
||||
size_t variable_start = -1;
|
||||
|
||||
for (size_t in_pos=0; in_pos<len; in_pos++)
|
||||
{
|
||||
wchar_t c = str.at(i);
|
||||
if (c == L'$')
|
||||
wchar_t c = str.at(in_pos);
|
||||
if (! wcsvarchr(c))
|
||||
{
|
||||
/* wprintf( L"Var prefix \'%ls\'\n", &cmd[i+1] );*/
|
||||
return this->complete_variable(str, i+1);
|
||||
/* This character cannot be in a variable, reset the dollar */
|
||||
variable_start = -1;
|
||||
}
|
||||
if (!isalnum(c) && c != L'_')
|
||||
|
||||
switch (c)
|
||||
{
|
||||
return false;
|
||||
case L'\\':
|
||||
in_pos++;
|
||||
break;
|
||||
|
||||
case L'$':
|
||||
if (mode == e_unquoted || mode == e_double_quoted)
|
||||
{
|
||||
variable_start = in_pos;
|
||||
}
|
||||
break;
|
||||
|
||||
case L'\'':
|
||||
if (mode == e_single_quoted)
|
||||
{
|
||||
mode = e_unquoted;
|
||||
}
|
||||
else if (mode == e_unquoted)
|
||||
{
|
||||
mode = e_single_quoted;
|
||||
}
|
||||
break;
|
||||
|
||||
case L'"':
|
||||
if (mode == e_double_quoted)
|
||||
{
|
||||
mode = e_unquoted;
|
||||
}
|
||||
else if (mode == e_unquoted)
|
||||
{
|
||||
mode = e_double_quoted;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
/* Now complete if we have a variable start that's also not the last character */
|
||||
bool result = false;
|
||||
if (variable_start != static_cast<size_t>(-1) && variable_start + 1 < len)
|
||||
{
|
||||
result = this->complete_variable(str, variable_start + 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1822,7 +1860,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> &comps
|
||||
bool use_function = 1;
|
||||
bool use_builtin = 1;
|
||||
|
||||
// debug( 1, L"Complete '%ls'", cmd );
|
||||
//debug( 1, L"Complete '%ls'", cmd.c_str() );
|
||||
|
||||
const wchar_t *cmd_cstr = cmd.c_str();
|
||||
const wchar_t *tok_begin = NULL, *prev_begin = NULL, *prev_end = NULL;
|
||||
@ -1832,9 +1870,11 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> &comps
|
||||
If we are completing a variable name or a tilde expansion user
|
||||
name, we do that and return. No need for any other completions.
|
||||
*/
|
||||
|
||||
const wcstring current_token = tok_begin;
|
||||
|
||||
/* Get the quote type of the current token */
|
||||
|
||||
|
||||
if (!done)
|
||||
{
|
||||
done = completer.try_complete_variable(current_token) || completer.try_complete_user(current_token);
|
||||
|
@ -1535,7 +1535,14 @@ static void test_complete(void)
|
||||
complete(L"foobarbaz ", completions, COMPLETION_REQUEST_DEFAULT);
|
||||
do_test(completions.size() == 1);
|
||||
do_test(completions.at(0).completion == L"qux");
|
||||
|
||||
|
||||
/* Don't complete variable names in single quotes (#1023) */
|
||||
completions.clear();
|
||||
complete(L"echo '$Foo", completions, COMPLETION_REQUEST_DEFAULT);
|
||||
do_test(completions.empty());
|
||||
completions.clear();
|
||||
complete(L"echo \\$Foo", completions, COMPLETION_REQUEST_DEFAULT);
|
||||
do_test(completions.empty());
|
||||
|
||||
complete_set_variable_names(NULL);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user