Unify completion from container content logic

This commit is contained in:
Maxime Coste 2014-12-23 13:54:09 +00:00
parent 064fb81b8d
commit b6ff15aa75
14 changed files with 75 additions and 73 deletions

View File

@ -3,6 +3,7 @@
#include "assert.hh" #include "assert.hh"
#include "buffer.hh" #include "buffer.hh"
#include "client_manager.hh" #include "client_manager.hh"
#include "containers.hh"
#include "exception.hh" #include "exception.hh"
#include "file.hh" #include "file.hh"
#include "string.hh" #include "string.hh"
@ -117,27 +118,19 @@ void BufferManager::backup_modified_buffers()
CandidateList BufferManager::complete_buffer_name(StringView prefix, CandidateList BufferManager::complete_buffer_name(StringView prefix,
ByteCount cursor_pos) ByteCount cursor_pos)
{ {
auto real_prefix = prefix.substr(0, cursor_pos); const bool include_dirs = contains(prefix.substr(0, cursor_pos), '/');
const bool include_dirs = contains(real_prefix, '/'); auto c = transformed(m_buffers,
CandidateList result; [include_dirs](const safe_ptr<Buffer>& buffer) -> String {
CandidateList subsequence_result;
for (auto& buffer : m_buffers)
{
String name = buffer->display_name(); String name = buffer->display_name();
StringView match_name = name;
if (not include_dirs and buffer->flags() & Buffer::Flags::File) if (not include_dirs and buffer->flags() & Buffer::Flags::File)
{ {
ByteCount pos = name.find_last_of('/'); ByteCount pos = name.find_last_of('/');
if (pos != (int)String::npos) if (pos != (int)String::npos)
match_name = name.substr(pos+1); return name.substr(pos+1);
} }
return name;
if (prefix_match(match_name, real_prefix)) });
result.push_back(name); return complete(prefix, cursor_pos, c, prefix_match, subsequence_match);
if (subsequence_match(name, real_prefix))
subsequence_result.push_back(name);
}
return result.empty() ? subsequence_result : result;
} }
void BufferManager::clear_buffer_trash() void BufferManager::clear_buffer_trash()

View File

@ -2,6 +2,7 @@
#include "buffer_manager.hh" #include "buffer_manager.hh"
#include "command_manager.hh" #include "command_manager.hh"
#include "containers.hh"
#include "event_manager.hh" #include "event_manager.hh"
#include "face_registry.hh" #include "face_registry.hh"
#include "file.hh" #include "file.hh"
@ -172,19 +173,8 @@ void ClientManager::clear_mode_trashes() const
CandidateList ClientManager::complete_client_name(StringView prefix, CandidateList ClientManager::complete_client_name(StringView prefix,
ByteCount cursor_pos) const ByteCount cursor_pos) const
{ {
auto real_prefix = prefix.substr(0, cursor_pos); auto c = transformed(m_clients, [](const std::unique_ptr<Client>& c){ return c->context().name(); });
CandidateList result; return complete(prefix, cursor_pos, c, prefix_match, subsequence_match);
CandidateList subsequence_result;
for (auto& client : m_clients)
{
const String& name = client->context().name();
if (prefix_match(name, real_prefix))
result.push_back(name);
if (subsequence_match(name, real_prefix))
subsequence_result.push_back(name);
}
return result.empty() ? subsequence_result : result;
} }
} }

View File

@ -53,5 +53,43 @@ inline Completions offset_pos(Completions completion, ByteCount offset)
std::move(completion.candidates) }; std::move(completion.candidates) };
} }
namespace detail
{
template<typename Str, typename Func>
void do_matches(Str&& str, StringView prefix,
CandidateList* res, Func match_func)
{
if (match_func(str, prefix))
res->push_back(str);
}
template<typename Str, typename Func, typename... Rest>
void do_matches(Str&& str, StringView prefix,
CandidateList* res, Func match_func, Rest... rest)
{
do_matches(str, prefix, res, match_func);
do_matches(str, prefix, res+1, rest...);
}
}
template<typename Container, typename... MatchFunc>
CandidateList complete(StringView prefix, ByteCount cursor_pos,
const Container& container, MatchFunc... match_func)
{
CandidateList res[sizeof...(match_func)];
auto real_prefix = prefix.substr(0, cursor_pos);
for (const auto& elem : container)
detail::do_matches(elem, real_prefix, res, match_func...);
auto it = find_if(res, [](CandidateList& c) { return not c.empty(); });
return it == end(res) ? CandidateList{} : std::move(*it);
}
template<typename Container>
CandidateList complete(StringView prefix, ByteCount cursor_pos,
const Container& container)
{
return complete(prefix, cursor_pos, container, prefix_match);
}
} }
#endif // completion_hh_INCLUDED #endif // completion_hh_INCLUDED

View File

@ -2,6 +2,7 @@
#include "containers.hh" #include "containers.hh"
#include "exception.hh" #include "exception.hh"
#include "containers.hh"
namespace Kakoune namespace Kakoune
{ {
@ -82,14 +83,10 @@ void FaceRegistry::register_alias(const String& name, const String& facedesc,
CandidateList FaceRegistry::complete_alias_name(StringView prefix, CandidateList FaceRegistry::complete_alias_name(StringView prefix,
ByteCount cursor_pos) const ByteCount cursor_pos) const
{ {
CandidateList res; using ValueType = std::pair<String, FaceOrAlias>;
auto real_prefix = prefix.substr(0, cursor_pos); return complete(prefix, cursor_pos,
for (auto& alias : m_aliases) transformed(m_aliases,
{ [](const ValueType& v){ return v.first; }));
if (prefix_match(alias.first, real_prefix))
res.push_back(alias.first);
}
return res;
} }
FaceRegistry::FaceRegistry() FaceRegistry::FaceRegistry()

View File

@ -5,6 +5,7 @@
#include "id_map.hh" #include "id_map.hh"
#include "string.hh" #include "string.hh"
#include "exception.hh" #include "exception.hh"
#include "containers.hh"
namespace Kakoune namespace Kakoune
{ {
@ -35,7 +36,8 @@ public:
CandidateList complete_name(StringView prefix, ByteCount cursor_pos) CandidateList complete_name(StringView prefix, ByteCount cursor_pos)
{ {
return m_functions.complete_id(prefix, cursor_pos); auto c = transformed(m_functions, id_map<FunctionType>::get_id);
return complete(prefix, cursor_pos, c);
} }
private: private:

View File

@ -48,11 +48,12 @@ Completions HighlighterGroup::complete_child(StringView path, ByteCount cursor_p
return offset_pos(hl.complete_child(path.substr(offset), cursor_pos - offset, group), offset); return offset_pos(hl.complete_child(path.substr(offset), cursor_pos - offset, group), offset);
} }
auto condition = [=](const HighlighterMap::value_type& hl) using ValueType = HighlighterMap::value_type;
{ auto c = transformed(filtered(m_highlighters,
return not group or hl.second->has_children(); [=](const ValueType& hl)
}; { return not group or hl.second->has_children(); }),
return { 0, 0, m_highlighters.complete_id_if(path, cursor_pos, condition) }; HighlighterMap::get_id);
return { 0, 0, complete(path, cursor_pos, c) };
} }
} }

View File

@ -3,6 +3,7 @@
#include "assert.hh" #include "assert.hh"
#include "buffer_utils.hh" #include "buffer_utils.hh"
#include "context.hh" #include "context.hh"
#include "containers.hh"
#include "display_buffer.hh" #include "display_buffer.hh"
#include "face_registry.hh" #include "face_registry.hh"
#include "highlighter_group.hh" #include "highlighter_group.hh"
@ -957,7 +958,8 @@ public:
return offset_pos(hl.complete_child(path.substr(offset), cursor_pos - offset, group), offset); return offset_pos(hl.complete_child(path.substr(offset), cursor_pos - offset, group), offset);
} }
return { 0, 0, m_groups.complete_id(path, cursor_pos) }; auto container = transformed(m_groups, id_map<HighlighterGroup>::get_id);
return { 0, 0, complete(path, cursor_pos, container) };
} }
static HighlighterAndId create(HighlighterParameters params) static HighlighterAndId create(HighlighterParameters params)

View File

@ -1,5 +1,6 @@
#include "hook_manager.hh" #include "hook_manager.hh"
#include "containers.hh"
#include "context.hh" #include "context.hh"
#include "debug.hh" #include "debug.hh"
#include "regex.hh" #include "regex.hh"
@ -26,8 +27,8 @@ CandidateList HookManager::complete_hook_group(StringView prefix, ByteCount pos_
CandidateList res; CandidateList res;
for (auto& list : m_hook) for (auto& list : m_hook)
{ {
auto candidates = list.second.complete_id(prefix, pos_in_token); auto container = transformed(list.second, id_map<HookFunc>::get_id);
for (auto& c : candidates) for (auto& c : complete(prefix, pos_in_token, container))
{ {
if (!contains(res, c)) if (!contains(res, c))
res.push_back(c); res.push_back(c);

View File

@ -2,6 +2,7 @@
#define hook_manager_hh_INCLUDED #define hook_manager_hh_INCLUDED
#include "id_map.hh" #include "id_map.hh"
#include "completion.hh"
#include "unordered_map.hh" #include "unordered_map.hh"
namespace Kakoune namespace Kakoune

View File

@ -2,7 +2,6 @@
#define id_map_hh_INCLUDED #define id_map_hh_INCLUDED
#include "containers.hh" #include "containers.hh"
#include "completion.hh"
#include "string.hh" #include "string.hh"
#include <vector> #include <vector>
@ -63,30 +62,7 @@ public:
m_content.erase(it, end()); m_content.erase(it, end());
} }
template<typename Condition> static const String& get_id(const value_type& v) { return v.first; }
CandidateList complete_id_if(StringView prefix,
ByteCount cursor_pos,
Condition condition) const
{
auto real_prefix = prefix.substr(0, cursor_pos);
CandidateList result;
for (auto& value : m_content)
{
if (not condition(value))
continue;
if (prefix_match(value.first, real_prefix))
result.push_back(value.first);
}
return result;
}
CandidateList complete_id(StringView prefix,
ByteCount cursor_pos) const
{
return complete_id_if(
prefix, cursor_pos, [](const value_type&) { return true; });
}
bool empty() const { return m_content.empty(); } bool empty() const { return m_content.empty(); }

View File

@ -1,5 +1,6 @@
#include "ncurses_ui.hh" #include "ncurses_ui.hh"
#include "containers.hh"
#include "display_buffer.hh" #include "display_buffer.hh"
#include "event_manager.hh" #include "event_manager.hh"
#include "keys.hh" #include "keys.hh"

View File

@ -6,7 +6,6 @@
#include "exception.hh" #include "exception.hh"
#include "flags.hh" #include "flags.hh"
#include "option_types.hh" #include "option_types.hh"
#include "utils.hh"
#include "regex.hh" #include "regex.hh"
namespace Kakoune namespace Kakoune

View File

@ -1,8 +1,8 @@
#include "register_manager.hh" #include "register_manager.hh"
#include "assert.hh" #include "assert.hh"
#include "id_map.hh"
#include "exception.hh" #include "exception.hh"
#include "id_map.hh"
namespace Kakoune namespace Kakoune
{ {

View File

@ -5,6 +5,7 @@
#include "hook_manager.hh" #include "hook_manager.hh"
#include "keymap_manager.hh" #include "keymap_manager.hh"
#include "option_manager.hh" #include "option_manager.hh"
#include "utils.hh"
namespace Kakoune namespace Kakoune
{ {