mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-25 12:23:09 +00:00
Break out COMPLETE_NO_CASE and COMPLETE_REPLACES_TOKEN into separate flags, in preparation for upcoming fuzzy completion work
This commit is contained in:
parent
b2012467b3
commit
4d19bb17a9
7 changed files with 131 additions and 73 deletions
|
@ -545,7 +545,7 @@ static int builtin_complete(parser_t &parser, wchar_t **argv)
|
|||
recursion_level++;
|
||||
|
||||
std::vector<completion_t> comp;
|
||||
complete(do_complete_param, comp, COMPLETE_DEFAULT);
|
||||
complete(do_complete_param, comp, COMPLETION_REQUEST_DEFAULT);
|
||||
|
||||
for (size_t i=0; i< comp.size() ; i++)
|
||||
{
|
||||
|
@ -553,7 +553,7 @@ static int builtin_complete(parser_t &parser, wchar_t **argv)
|
|||
|
||||
const wchar_t *prepend;
|
||||
|
||||
if (next.flags & COMPLETE_NO_CASE)
|
||||
if (next.flags & COMPLETE_REPLACES_TOKEN)
|
||||
{
|
||||
prepend = L"";
|
||||
}
|
||||
|
|
98
complete.cpp
98
complete.cpp
|
@ -104,14 +104,25 @@
|
|||
#define C_(string) (string)
|
||||
#endif
|
||||
|
||||
/* Testing apparatus */
|
||||
const wcstring_list_t *s_override_variable_names = NULL;
|
||||
|
||||
/**
|
||||
The maximum amount of time that we're willing to spend doing
|
||||
username tilde completion. This special limit has been coded in
|
||||
because user lookup can be extremely slow in cases of a humongous
|
||||
LDAP database. (Google, I'm looking at you)
|
||||
*/
|
||||
#define MAX_USER_LOOKUP_TIME 0.2
|
||||
void complete_set_variable_names(const wcstring_list_t *names)
|
||||
{
|
||||
s_override_variable_names = names;
|
||||
}
|
||||
|
||||
static inline wcstring_list_t complete_get_variable_names(void)
|
||||
{
|
||||
if (s_override_variable_names != NULL)
|
||||
{
|
||||
return *s_override_variable_names;
|
||||
}
|
||||
else
|
||||
{
|
||||
return env_get_names(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Struct describing a completion option entry.
|
||||
|
@ -326,7 +337,7 @@ void sort_completions(std::vector<completion_t> &completions)
|
|||
/** Class representing an attempt to compute completions */
|
||||
class completer_t
|
||||
{
|
||||
const complete_type_t type;
|
||||
const completion_request_flags_t flags;
|
||||
const wcstring initial_cmd;
|
||||
std::vector<completion_t> completions;
|
||||
wcstring_list_t commands_to_load;
|
||||
|
@ -334,10 +345,32 @@ class completer_t
|
|||
/** Table of completions conditions that have already been tested and the corresponding test results */
|
||||
typedef std::map<wcstring, bool> condition_cache_t;
|
||||
condition_cache_t condition_cache;
|
||||
|
||||
enum complete_type_t
|
||||
{
|
||||
COMPLETE_DEFAULT,
|
||||
COMPLETE_AUTOSUGGEST
|
||||
};
|
||||
|
||||
complete_type_t type() const
|
||||
{
|
||||
return (flags & COMPLETION_REQUEST_AUTOSUGGESTION) ? COMPLETE_AUTOSUGGEST : COMPLETE_DEFAULT;
|
||||
}
|
||||
|
||||
bool wants_descriptions() const
|
||||
{
|
||||
return !! (flags & COMPLETION_REQUEST_DESCRIPTIONS);
|
||||
}
|
||||
|
||||
bool fuzzy() const
|
||||
{
|
||||
return !! (flags & COMPLETION_REQUEST_FUZZY_MATCH);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
completer_t(const wcstring &c, complete_type_t t) :
|
||||
type(t),
|
||||
completer_t(const wcstring &c, completion_request_flags_t f) :
|
||||
flags(f),
|
||||
initial_cmd(c)
|
||||
{
|
||||
}
|
||||
|
@ -389,7 +422,7 @@ public:
|
|||
{
|
||||
/* Never do command substitution in autosuggestions. Sadly, we also can't yet do job expansion because it's not thread safe. */
|
||||
expand_flags_t result = 0;
|
||||
if (type == COMPLETE_AUTOSUGGEST)
|
||||
if (this->type() == COMPLETE_AUTOSUGGEST)
|
||||
result |= EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_JOBS;
|
||||
return result;
|
||||
}
|
||||
|
@ -449,7 +482,7 @@ bool completer_t::condition_test(const wcstring &condition)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (this->type == COMPLETE_AUTOSUGGEST)
|
||||
if (this->type() == COMPLETE_AUTOSUGGEST)
|
||||
{
|
||||
/* Autosuggestion can't support conditions */
|
||||
return 0;
|
||||
|
@ -1096,8 +1129,6 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool
|
|||
if (cdpath.missing_or_empty())
|
||||
cdpath = L".";
|
||||
|
||||
const bool wants_description = (type == COMPLETE_DEFAULT);
|
||||
|
||||
if (str_cmd.find(L'/') != wcstring::npos || str_cmd.at(0) == L'~')
|
||||
{
|
||||
|
||||
|
@ -1106,7 +1137,7 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool
|
|||
|
||||
if (expand_string(str_cmd, this->completions, ACCEPT_INCOMPLETE | EXECUTABLES_ONLY | this->expand_flags()) != EXPAND_ERROR)
|
||||
{
|
||||
if (wants_description)
|
||||
if (this->wants_descriptions())
|
||||
{
|
||||
this->complete_cmd_desc(str_cmd);
|
||||
}
|
||||
|
@ -1144,7 +1175,7 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool
|
|||
for (size_t i=prev_count; i< this->completions.size(); i++)
|
||||
{
|
||||
completion_t &c = this->completions.at(i);
|
||||
if (c.flags & COMPLETE_NO_CASE)
|
||||
if (c.flags & COMPLETE_REPLACES_TOKEN)
|
||||
{
|
||||
|
||||
c.completion.erase(0, base_path.size());
|
||||
|
@ -1152,7 +1183,7 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool
|
|||
}
|
||||
}
|
||||
}
|
||||
if (wants_description)
|
||||
if (this->wants_descriptions())
|
||||
this->complete_cmd_desc(str_cmd);
|
||||
}
|
||||
}
|
||||
|
@ -1205,7 +1236,7 @@ void completer_t::complete_from_args(const wcstring &str,
|
|||
|
||||
std::vector<completion_t> possible_comp;
|
||||
|
||||
bool is_autosuggest = (this->type == COMPLETE_AUTOSUGGEST);
|
||||
bool is_autosuggest = (this->type() == COMPLETE_AUTOSUGGEST);
|
||||
parser_t parser(is_autosuggest ? PARSER_TYPE_COMPLETIONS_ONLY : PARSER_TYPE_GENERAL, false);
|
||||
|
||||
/* If type is COMPLETE_AUTOSUGGEST, it means we're on a background thread, so don't call proc_push_interactive */
|
||||
|
@ -1335,11 +1366,11 @@ bool completer_t::complete_param(const wcstring &scmd_orig, const wcstring &spop
|
|||
wcstring cmd, path;
|
||||
parse_cmd_string(cmd_orig, path, cmd);
|
||||
|
||||
if (this->type == COMPLETE_DEFAULT)
|
||||
if (this->type() == COMPLETE_DEFAULT)
|
||||
{
|
||||
complete_load(cmd, true);
|
||||
}
|
||||
else if (this->type == COMPLETE_AUTOSUGGEST)
|
||||
else if (this->type() == COMPLETE_AUTOSUGGEST)
|
||||
{
|
||||
/* Maybe indicate we should try loading this on the main thread */
|
||||
if (! list_contains_string(this->commands_to_load, cmd) && ! completion_autoloader.has_tried_loading(cmd))
|
||||
|
@ -1514,11 +1545,14 @@ bool completer_t::complete_param(const wcstring &scmd_orig, const wcstring &spop
|
|||
size_t offset = 0;
|
||||
complete_flags_t flags = 0;
|
||||
|
||||
|
||||
if (match)
|
||||
{
|
||||
offset = wcslen(str);
|
||||
}
|
||||
else
|
||||
flags = COMPLETE_NO_CASE;
|
||||
{
|
||||
flags = COMPLETE_REPLACES_TOKEN | COMPLETE_CASE_INSENSITIVE;
|
||||
}
|
||||
|
||||
has_arg = ! o->comp.empty();
|
||||
req_arg = (o->result_mode & NO_COMMON);
|
||||
|
@ -1580,7 +1614,7 @@ void completer_t::complete_param_expand(const wcstring &sstr, bool do_file)
|
|||
flags |= EXPAND_SKIP_WILDCARDS;
|
||||
|
||||
/* Squelch file descriptions per issue 254 */
|
||||
if (type == COMPLETE_AUTOSUGGEST || do_file)
|
||||
if (this->type() == COMPLETE_AUTOSUGGEST || do_file)
|
||||
flags |= EXPAND_NO_DESCRIPTIONS;
|
||||
|
||||
if (expand_string(comp_str,
|
||||
|
@ -1608,9 +1642,8 @@ bool completer_t::complete_variable(const wcstring &str, size_t start_offset)
|
|||
const wchar_t *var = &whole_var[start_offset];
|
||||
size_t varlen = wcslen(var);
|
||||
int res = 0;
|
||||
bool wants_description = (type != COMPLETE_AUTOSUGGEST);
|
||||
|
||||
const wcstring_list_t names = env_get_names(0);
|
||||
const wcstring_list_t names = complete_get_variable_names();
|
||||
for (size_t i=0; i<names.size(); i++)
|
||||
{
|
||||
const wcstring & env_name = names.at(i);
|
||||
|
@ -1640,18 +1673,18 @@ bool completer_t::complete_variable(const wcstring &str, size_t start_offset)
|
|||
{
|
||||
comp.append(whole_var, start_offset);
|
||||
comp.append(env_name);
|
||||
flags = COMPLETE_NO_CASE | COMPLETE_DONT_ESCAPE;
|
||||
flags = COMPLETE_CASE_INSENSITIVE | COMPLETE_REPLACES_TOKEN | COMPLETE_DONT_ESCAPE;
|
||||
}
|
||||
|
||||
wcstring desc;
|
||||
if (wants_description)
|
||||
if (this->wants_descriptions())
|
||||
{
|
||||
env_var_t value_unescaped = env_get_string(env_name);
|
||||
if (value_unescaped.missing())
|
||||
continue;
|
||||
|
||||
wcstring value = expand_escape_variable(value_unescaped);
|
||||
if (type != COMPLETE_AUTOSUGGEST)
|
||||
if (this->type() != COMPLETE_AUTOSUGGEST)
|
||||
desc = format_string(COMPLETE_VAR_DESC_VAL, value.c_str());
|
||||
}
|
||||
|
||||
|
@ -1744,7 +1777,7 @@ bool completer_t::try_complete_user(const wcstring &str)
|
|||
append_completion(this->completions,
|
||||
name,
|
||||
desc,
|
||||
COMPLETE_NO_CASE | COMPLETE_DONT_ESCAPE | COMPLETE_NO_SPACE);
|
||||
COMPLETE_CASE_INSENSITIVE | COMPLETE_REPLACES_TOKEN | COMPLETE_DONT_ESCAPE | COMPLETE_NO_SPACE);
|
||||
res=1;
|
||||
}
|
||||
}
|
||||
|
@ -1756,11 +1789,12 @@ bool completer_t::try_complete_user(const wcstring &str)
|
|||
return res;
|
||||
}
|
||||
|
||||
void complete(const wcstring &cmd, std::vector<completion_t> &comps, complete_type_t type, wcstring_list_t *commands_to_load)
|
||||
void complete(const wcstring &cmd, std::vector<completion_t> &comps, completion_request_flags_t flags, wcstring_list_t *commands_to_load)
|
||||
{
|
||||
/* Make our completer */
|
||||
completer_t completer(cmd, type);
|
||||
completer_t completer(cmd, flags);
|
||||
|
||||
const bool fuzzy = !! (flags & COMPLETION_REQUEST_FUZZY_MATCH);
|
||||
const wchar_t *tok_begin, *tok_end, *cmdsubst_begin, *cmdsubst_end, *prev_begin, *prev_end;
|
||||
wcstring current_token, prev_token;
|
||||
wcstring current_command;
|
||||
|
@ -1969,7 +2003,7 @@ void complete(const wcstring &cmd, std::vector<completion_t> &comps, complete_ty
|
|||
do_file = false;
|
||||
|
||||
/* And if we're autosuggesting, and the token is empty, don't do file suggestions */
|
||||
if (type == COMPLETE_AUTOSUGGEST && current_token_unescape.empty())
|
||||
if ((flags & COMPLETION_REQUEST_AUTOSUGGESTION) && current_token_unescape.empty())
|
||||
do_file = false;
|
||||
|
||||
/*
|
||||
|
|
37
complete.h
37
complete.h
|
@ -75,25 +75,20 @@ enum
|
|||
*/
|
||||
COMPLETE_NO_SPACE = 1 << 0,
|
||||
|
||||
/**
|
||||
This completion is case insensitive.
|
||||
|
||||
Warning: The contents of the completion_t structure is actually
|
||||
different if this flag is set! Specifically, the completion string
|
||||
contains the _entire_ completion token, not merely its suffix.
|
||||
*/
|
||||
COMPLETE_NO_CASE = 1 << 1,
|
||||
/** This completion is case insensitive. */
|
||||
COMPLETE_CASE_INSENSITIVE = 1 << 1,
|
||||
|
||||
/** This is not the suffix of a token, but replaces it entirely */
|
||||
COMPLETE_REPLACES_TOKEN = 1 << 2,
|
||||
|
||||
/**
|
||||
This completion may or may not want a space at the end - guess by
|
||||
checking the last character of the completion.
|
||||
*/
|
||||
COMPLETE_AUTO_SPACE = 1 << 2,
|
||||
COMPLETE_AUTO_SPACE = 1 << 3,
|
||||
|
||||
/**
|
||||
This completion should be inserted as-is, without escaping.
|
||||
*/
|
||||
COMPLETE_DONT_ESCAPE = 1 << 3
|
||||
/** This completion should be inserted as-is, without escaping. */
|
||||
COMPLETE_DONT_ESCAPE = 1 << 4
|
||||
};
|
||||
typedef int complete_flags_t;
|
||||
|
||||
|
@ -130,7 +125,7 @@ public:
|
|||
|
||||
bool is_case_insensitive() const
|
||||
{
|
||||
return !!(flags & COMPLETE_NO_CASE);
|
||||
return !!(flags & COMPLETE_CASE_INSENSITIVE);
|
||||
}
|
||||
|
||||
/* Construction. Note: defining these so that they are not inlined reduces the executable size. */
|
||||
|
@ -144,11 +139,13 @@ public:
|
|||
bool operator != (const completion_t& rhs) const;
|
||||
};
|
||||
|
||||
enum complete_type_t
|
||||
{
|
||||
COMPLETE_DEFAULT,
|
||||
COMPLETE_AUTOSUGGEST
|
||||
enum {
|
||||
COMPLETION_REQUEST_DEFAULT = 0,
|
||||
COMPLETION_REQUEST_AUTOSUGGESTION = 1 << 0, // indicates the completion is for an autosuggestion
|
||||
COMPLETION_REQUEST_DESCRIPTIONS = 1 << 1, // indicates that we want descriptions
|
||||
COMPLETION_REQUEST_FUZZY_MATCH = 1 << 2 // indicates that we don't require a prefix match
|
||||
};
|
||||
typedef uint32_t completion_request_flags_t;
|
||||
|
||||
/** Given a list of completions, returns a list of their completion fields */
|
||||
wcstring_list_t completions_to_wcstring_list(const std::vector<completion_t> &completions);
|
||||
|
@ -233,7 +230,7 @@ void complete_remove(const wchar_t *cmd,
|
|||
*/
|
||||
void complete(const wcstring &cmd,
|
||||
std::vector<completion_t> &comp,
|
||||
complete_type_t type,
|
||||
completion_request_flags_t flags,
|
||||
wcstring_list_t *to_load = NULL);
|
||||
|
||||
/**
|
||||
|
@ -284,5 +281,7 @@ void complete_load(const wcstring &cmd, bool reload);
|
|||
*/
|
||||
void append_completion(std::vector<completion_t> &completions, const wcstring &comp, const wcstring &desc = L"", int flags = 0);
|
||||
|
||||
/* Function used for testing */
|
||||
void complete_set_variable_names(const wcstring_list_t *names);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -959,6 +959,25 @@ static void test_colors()
|
|||
assert(rgb_color_t(L"mooganta").is_none());
|
||||
}
|
||||
|
||||
static void test_complete(void)
|
||||
{
|
||||
say(L"Testing complete");
|
||||
const wchar_t *name_strs[] = {L"Foo1", L"Foo2", L"Foo3", L"Bar1", L"Bar2", L"Bar3"};
|
||||
size_t count = sizeof name_strs / sizeof *name_strs;
|
||||
const wcstring_list_t names(name_strs, name_strs + count);
|
||||
|
||||
complete_set_variable_names(&names);
|
||||
|
||||
std::vector<completion_t> completions;
|
||||
complete(L"$F", completions, COMPLETION_REQUEST_DEFAULT);
|
||||
assert(completions.size() == 3);
|
||||
assert(completions.at(0).completion == L"oo1");
|
||||
assert(completions.at(1).completion == L"oo2");
|
||||
assert(completions.at(2).completion == L"oo3");
|
||||
|
||||
complete_set_variable_names(NULL);
|
||||
}
|
||||
|
||||
static void test_1_completion(wcstring line, const wcstring &completion, complete_flags_t flags, bool append_only, wcstring expected, long source_line)
|
||||
{
|
||||
// str is given with a caret, which we use to represent the cursor position
|
||||
|
@ -981,10 +1000,10 @@ static void test_1_completion(wcstring line, const wcstring &completion, complet
|
|||
assert(cursor_pos == out_cursor_pos);
|
||||
}
|
||||
|
||||
static void test_completions()
|
||||
static void test_completion_insertions()
|
||||
{
|
||||
#define TEST_1_COMPLETION(a, b, c, d, e) test_1_completion(a, b, c, d, e, __LINE__)
|
||||
say(L"Testing completions");
|
||||
say(L"Testing completion insertions");
|
||||
TEST_1_COMPLETION(L"foo^", L"bar", 0, false, L"foobar ^");
|
||||
TEST_1_COMPLETION(L"foo^ baz", L"bar", 0, false, L"foobar ^ baz"); //we really do want to insert two spaces here - otherwise it's hidden by the cursor
|
||||
TEST_1_COMPLETION(L"'foo^", L"bar", 0, false, L"'foobar' ^");
|
||||
|
@ -1006,8 +1025,8 @@ static void test_completions()
|
|||
TEST_1_COMPLETION(L"'foo\\'^", L"bar", COMPLETE_NO_SPACE, false, L"'foo\\'bar^");
|
||||
TEST_1_COMPLETION(L"foo\\'^", L"bar", COMPLETE_NO_SPACE, false, L"foo\\'bar^");
|
||||
|
||||
TEST_1_COMPLETION(L"foo^", L"bar", COMPLETE_NO_CASE, false, L"bar ^");
|
||||
TEST_1_COMPLETION(L"'foo^", L"bar", COMPLETE_NO_CASE, false, L"bar ^");
|
||||
TEST_1_COMPLETION(L"foo^", L"bar", COMPLETE_CASE_INSENSITIVE | COMPLETE_REPLACES_TOKEN, false, L"bar ^");
|
||||
TEST_1_COMPLETION(L"'foo^", L"bar", COMPLETE_CASE_INSENSITIVE | COMPLETE_REPLACES_TOKEN, false, L"bar ^");
|
||||
}
|
||||
|
||||
static void perform_one_autosuggestion_test(const wcstring &command, const wcstring &wd, const wcstring &expected, long line)
|
||||
|
@ -1139,7 +1158,7 @@ void perf_complete()
|
|||
str[0]=c;
|
||||
reader_set_buffer(str, 0);
|
||||
|
||||
complete(str, out, COMPLETE_DEFAULT, NULL);
|
||||
complete(str, out, COMPLETION_REQUEST_DEFAULT, NULL);
|
||||
|
||||
matches += out.size();
|
||||
out.clear();
|
||||
|
@ -1159,7 +1178,7 @@ void perf_complete()
|
|||
|
||||
reader_set_buffer(str, 0);
|
||||
|
||||
complete(str, out, COMPLETE_DEFAULT, NULL);
|
||||
complete(str, out, COMPLETION_REQUEST_DEFAULT, NULL);
|
||||
|
||||
matches += out.size();
|
||||
out.clear();
|
||||
|
@ -1695,7 +1714,7 @@ int main(int argc, char **argv)
|
|||
builtin_init();
|
||||
reader_init();
|
||||
env_init();
|
||||
|
||||
|
||||
test_format();
|
||||
test_escape();
|
||||
test_convert();
|
||||
|
@ -1710,7 +1729,8 @@ int main(int argc, char **argv)
|
|||
test_word_motion();
|
||||
test_is_potential_path();
|
||||
test_colors();
|
||||
test_completions();
|
||||
test_complete();
|
||||
test_completion_insertions();
|
||||
test_autosuggestion_combining();
|
||||
test_autosuggest_suggest_special();
|
||||
history_tests_t::test_history();
|
||||
|
|
21
reader.cpp
21
reader.cpp
|
@ -979,7 +979,7 @@ wcstring completion_apply_to_command_line(const wcstring &val_str, complete_flag
|
|||
{
|
||||
const wchar_t *val = val_str.c_str();
|
||||
bool add_space = !(flags & COMPLETE_NO_SPACE);
|
||||
bool do_replace = !!(flags & COMPLETE_NO_CASE);
|
||||
bool do_replace = !!(flags & COMPLETE_REPLACES_TOKEN);
|
||||
bool do_escape = !(flags & COMPLETE_DONT_ESCAPE);
|
||||
|
||||
const size_t cursor_pos = *inout_cursor_pos;
|
||||
|
@ -1134,7 +1134,6 @@ static void run_pager(const wcstring &prefix, int is_quoted, const std::vector<c
|
|||
return;
|
||||
|
||||
wchar_t *escaped_separator;
|
||||
int has_case_sensitive=0;
|
||||
|
||||
if (prefix.empty())
|
||||
{
|
||||
|
@ -1155,10 +1154,15 @@ static void run_pager(const wcstring &prefix, int is_quoted, const std::vector<c
|
|||
|
||||
escaped_separator = escape(COMPLETE_SEP_STR, 1);
|
||||
|
||||
bool has_case_sensitive = false;
|
||||
for (size_t i=0; i< comp.size(); i++)
|
||||
{
|
||||
const completion_t &el = comp.at(i);
|
||||
has_case_sensitive |= !(el.flags & COMPLETE_NO_CASE);
|
||||
if (! (el.flags & COMPLETE_CASE_INSENSITIVE))
|
||||
{
|
||||
has_case_sensitive = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i=0; i< comp.size(); i++)
|
||||
|
@ -1170,13 +1174,13 @@ static void run_pager(const wcstring &prefix, int is_quoted, const std::vector<c
|
|||
wcstring completion_text;
|
||||
wcstring description_text;
|
||||
|
||||
if (has_case_sensitive && (el.flags & COMPLETE_NO_CASE))
|
||||
if (has_case_sensitive && (el.flags & COMPLETE_CASE_INSENSITIVE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Note that an empty completion is perfectly sensible here, e.g. tab-completing 'foo' with a file called 'foo' and another called 'foobar'
|
||||
if (el.flags & COMPLETE_NO_CASE)
|
||||
if (el.flags & COMPLETE_REPLACES_TOKEN)
|
||||
{
|
||||
if (base_len == -1)
|
||||
{
|
||||
|
@ -1328,7 +1332,7 @@ struct autosuggestion_context_t
|
|||
|
||||
/* Try normal completions */
|
||||
std::vector<completion_t> completions;
|
||||
complete(search_string, completions, COMPLETE_AUTOSUGGEST, &this->commands_to_load);
|
||||
complete(search_string, completions, COMPLETION_REQUEST_AUTOSUGGESTION, &this->commands_to_load);
|
||||
if (! completions.empty())
|
||||
{
|
||||
const completion_t &comp = completions.at(0);
|
||||
|
@ -3057,8 +3061,9 @@ const wchar_t *reader_readline()
|
|||
|
||||
/* Construct a copy of the string from the beginning of the command substitution up to the end of the token we're completing */
|
||||
const wcstring buffcpy = wcstring(cmdsub_begin, token_end);
|
||||
|
||||
data->complete_func(buffcpy, comp, COMPLETE_DEFAULT, NULL);
|
||||
|
||||
//fprintf(stderr, "Complete (%ls)\n", buffcpy.c_str());
|
||||
data->complete_func(buffcpy, comp, COMPLETION_REQUEST_DEFAULT | COMPLETION_REQUEST_DESCRIPTIONS, NULL);
|
||||
|
||||
/* Munge our completions */
|
||||
sort_and_make_unique(comp);
|
||||
|
|
2
reader.h
2
reader.h
|
@ -163,7 +163,7 @@ void reader_pop();
|
|||
- The command to be completed as a null terminated array of wchar_t
|
||||
- An array_list_t in which completions will be inserted.
|
||||
*/
|
||||
typedef void (*complete_function_t)(const wcstring &, std::vector<completion_t> &, complete_type_t, wcstring_list_t * lst);
|
||||
typedef void (*complete_function_t)(const wcstring &, std::vector<completion_t> &, completion_request_flags_t, wcstring_list_t * lst);
|
||||
void reader_set_complete_function(complete_function_t);
|
||||
|
||||
/**
|
||||
|
|
|
@ -225,7 +225,7 @@ static bool wildcard_complete_internal(const wcstring &orig,
|
|||
wcstring out_completion;
|
||||
wcstring out_desc = (desc ? desc : L"");
|
||||
|
||||
if (flags & COMPLETE_NO_CASE)
|
||||
if (flags & COMPLETE_REPLACES_TOKEN)
|
||||
{
|
||||
out_completion = orig;
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ static bool wildcard_complete_internal(const wcstring &orig,
|
|||
}
|
||||
else if (towlower(*wc) == towlower(*str))
|
||||
{
|
||||
return wildcard_complete_internal(orig, str+1, wc+1, 0, desc, desc_func, out, flags | COMPLETE_NO_CASE);
|
||||
return wildcard_complete_internal(orig, str+1, wc+1, 0, desc, desc_func, out, flags | COMPLETE_CASE_INSENSITIVE | COMPLETE_REPLACES_TOKEN);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1095,7 +1095,7 @@ int wildcard_expand(const wchar_t *wc,
|
|||
{
|
||||
completion_t &c = out.at(i);
|
||||
|
||||
if (c.flags & COMPLETE_NO_CASE)
|
||||
if (c.flags & COMPLETE_REPLACES_TOKEN)
|
||||
{
|
||||
c.completion = format_string(L"%ls%ls%ls", base_dir, wc_base.c_str(), c.completion.c_str());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue