mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
Move completions from linked list to std::set
This commit is contained in:
parent
8585e0e9b8
commit
e2c3ca9950
2 changed files with 36 additions and 29 deletions
59
complete.cpp
59
complete.cpp
|
@ -192,9 +192,20 @@ class completion_entry_t
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Linked list of all completion entries */
|
/** Set of all completion entries */
|
||||||
typedef std::list<completion_entry_t *> completion_entry_list_t;
|
struct completion_entry_set_comparer {
|
||||||
static completion_entry_list_t completion_entries;
|
/** Comparison for std::set */
|
||||||
|
bool operator()(completion_entry_t *p1, completion_entry_t *p2) const {
|
||||||
|
/* Paths always come last for no particular reason */
|
||||||
|
if (p1->cmd_is_path != p2->cmd_is_path) {
|
||||||
|
return p1->cmd_is_path < p2->cmd_is_path;
|
||||||
|
} else {
|
||||||
|
return p1->cmd < p2->cmd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
typedef std::set<completion_entry_t *, completion_entry_set_comparer> completion_entry_set_t;
|
||||||
|
static completion_entry_set_t completion_set;
|
||||||
|
|
||||||
/** The lock that guards the list of completion entries */
|
/** The lock that guards the list of completion entries */
|
||||||
static pthread_mutex_t completion_lock = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t completion_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
@ -355,13 +366,13 @@ bool completer_t::condition_test( const wcstring &condition )
|
||||||
static completion_entry_t *complete_find_exact_entry( const wchar_t *cmd, const bool cmd_is_path )
|
static completion_entry_t *complete_find_exact_entry( const wchar_t *cmd, const bool cmd_is_path )
|
||||||
{
|
{
|
||||||
ASSERT_IS_LOCKED(completion_lock);
|
ASSERT_IS_LOCKED(completion_lock);
|
||||||
for (completion_entry_list_t::iterator iter = completion_entries.begin(); iter != completion_entries.end(); ++iter)
|
completion_entry_t *result = NULL;
|
||||||
{
|
completion_entry_t tmp_entry(cmd, cmd_is_path, L"", false);
|
||||||
completion_entry_t *entry = *iter;
|
completion_entry_set_t::iterator iter = completion_set.find(&tmp_entry);
|
||||||
if (entry->cmd == cmd && cmd_is_path == entry->cmd_is_path)
|
if (iter != completion_set.end()) {
|
||||||
return entry;
|
result = *iter;
|
||||||
}
|
}
|
||||||
return NULL;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Locate the specified entry. Create it if it doesn't exist. Must be called while locked. */
|
/** Locate the specified entry. Create it if it doesn't exist. Must be called while locked. */
|
||||||
|
@ -375,7 +386,7 @@ static completion_entry_t *complete_get_exact_entry( const wchar_t *cmd, bool cm
|
||||||
if( c == NULL )
|
if( c == NULL )
|
||||||
{
|
{
|
||||||
c = new completion_entry_t(cmd, cmd_is_path, L"", true);
|
c = new completion_entry_t(cmd, cmd_is_path, L"", true);
|
||||||
completion_entries.push_front(c);
|
completion_set.insert(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
|
@ -504,22 +515,18 @@ void complete_remove( const wchar_t *cmd,
|
||||||
{
|
{
|
||||||
CHECK( cmd, );
|
CHECK( cmd, );
|
||||||
scoped_lock lock(completion_lock);
|
scoped_lock lock(completion_lock);
|
||||||
for (completion_entry_list_t::iterator iter = completion_entries.begin(); iter != completion_entries.end(); ) {
|
|
||||||
completion_entry_t *e = *iter;
|
|
||||||
bool delete_it = false;
|
|
||||||
if(cmd_is_path == e->cmd_is_path && cmd == e->cmd) {
|
|
||||||
delete_it = complete_remove_entry( e, short_opt, long_opt );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
completion_entry_t tmp_entry(cmd, cmd_is_path, L"", false);
|
||||||
|
completion_entry_set_t::iterator iter = completion_set.find(&tmp_entry);
|
||||||
|
if (iter != completion_set.end()) {
|
||||||
|
completion_entry_t *entry = *iter;
|
||||||
|
bool delete_it = complete_remove_entry(entry, short_opt, long_opt);
|
||||||
if (delete_it) {
|
if (delete_it) {
|
||||||
/* Delete this entry */
|
/* Delete this entry */
|
||||||
iter = completion_entries.erase(iter);
|
completion_set.erase(iter);
|
||||||
delete e;
|
delete entry;
|
||||||
} else {
|
|
||||||
/* Don't delete it */
|
|
||||||
++iter;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Formats an error string by prepending the prefix and then appending the str in single quotes */
|
/* Formats an error string by prepending the prefix and then appending the str in single quotes */
|
||||||
|
@ -628,7 +635,7 @@ int complete_is_valid_option( const wchar_t *str,
|
||||||
|
|
||||||
scoped_lock lock(completion_lock);
|
scoped_lock lock(completion_lock);
|
||||||
scoped_lock lock2(completion_entry_lock);
|
scoped_lock lock2(completion_entry_lock);
|
||||||
for (completion_entry_list_t::iterator iter = completion_entries.begin(); iter != completion_entries.end(); ++iter)
|
for (completion_entry_set_t::const_iterator iter = completion_set.begin(); iter != completion_set.end(); ++iter)
|
||||||
{
|
{
|
||||||
const completion_entry_t *i = *iter;
|
const completion_entry_t *i = *iter;
|
||||||
const wcstring &match = i->cmd_is_path ? path : cmd;
|
const wcstring &match = i->cmd_is_path ? path : cmd;
|
||||||
|
@ -1278,7 +1285,7 @@ bool completer_t::complete_param( const wcstring &scmd_orig, const wcstring &spo
|
||||||
|
|
||||||
scoped_lock lock(completion_lock);
|
scoped_lock lock(completion_lock);
|
||||||
scoped_lock lock2(completion_entry_lock);
|
scoped_lock lock2(completion_entry_lock);
|
||||||
for (completion_entry_list_t::iterator iter = completion_entries.begin(); iter != completion_entries.end(); ++iter)
|
for (completion_entry_set_t::const_iterator iter = completion_set.begin(); iter != completion_set.end(); ++iter)
|
||||||
{
|
{
|
||||||
const completion_entry_t *i = *iter;
|
const completion_entry_t *i = *iter;
|
||||||
const wcstring &match = i->cmd_is_path ? path : cmd;
|
const wcstring &match = i->cmd_is_path ? path : cmd;
|
||||||
|
@ -1927,7 +1934,7 @@ void complete_print( wcstring &out )
|
||||||
{
|
{
|
||||||
scoped_lock locker(completion_lock);
|
scoped_lock locker(completion_lock);
|
||||||
scoped_lock locker2(completion_entry_lock);
|
scoped_lock locker2(completion_entry_lock);
|
||||||
for (completion_entry_list_t::const_iterator iter = completion_entries.begin(); iter != completion_entries.end(); ++iter)
|
for (completion_entry_set_t::const_iterator iter = completion_set.begin(); iter != completion_set.end(); ++iter)
|
||||||
{
|
{
|
||||||
const completion_entry_t *e = *iter;
|
const completion_entry_t *e = *iter;
|
||||||
const option_list_t options = e->get_options();
|
const option_list_t options = e->get_options();
|
||||||
|
|
|
@ -2332,8 +2332,8 @@ void parser_t::eval_job( tokenizer *tok )
|
||||||
if(!skip )
|
if(!skip )
|
||||||
{
|
{
|
||||||
int was_builtin = 0;
|
int was_builtin = 0;
|
||||||
// if( j->first_process->type==INTERNAL_BUILTIN && !j->first_process->next)
|
if( j->first_process->type==INTERNAL_BUILTIN && !j->first_process->next)
|
||||||
// was_builtin = 1;
|
was_builtin = 1;
|
||||||
prev_tokenizer_pos = current_tokenizer_pos;
|
prev_tokenizer_pos = current_tokenizer_pos;
|
||||||
current_tokenizer_pos = job_begin_pos;
|
current_tokenizer_pos = job_begin_pos;
|
||||||
exec( *this, j );
|
exec( *this, j );
|
||||||
|
|
Loading…
Reference in a new issue