Unify completion from container content logic
This commit is contained in:
parent
064fb81b8d
commit
b6ff15aa75
|
@ -3,6 +3,7 @@
|
|||
#include "assert.hh"
|
||||
#include "buffer.hh"
|
||||
#include "client_manager.hh"
|
||||
#include "containers.hh"
|
||||
#include "exception.hh"
|
||||
#include "file.hh"
|
||||
#include "string.hh"
|
||||
|
@ -117,27 +118,19 @@ void BufferManager::backup_modified_buffers()
|
|||
CandidateList BufferManager::complete_buffer_name(StringView prefix,
|
||||
ByteCount cursor_pos)
|
||||
{
|
||||
auto real_prefix = prefix.substr(0, cursor_pos);
|
||||
const bool include_dirs = contains(real_prefix, '/');
|
||||
CandidateList result;
|
||||
CandidateList subsequence_result;
|
||||
for (auto& buffer : m_buffers)
|
||||
{
|
||||
const bool include_dirs = contains(prefix.substr(0, cursor_pos), '/');
|
||||
auto c = transformed(m_buffers,
|
||||
[include_dirs](const safe_ptr<Buffer>& buffer) -> String {
|
||||
String name = buffer->display_name();
|
||||
StringView match_name = name;
|
||||
if (not include_dirs and buffer->flags() & Buffer::Flags::File)
|
||||
{
|
||||
ByteCount pos = name.find_last_of('/');
|
||||
if (pos != (int)String::npos)
|
||||
match_name = name.substr(pos+1);
|
||||
return name.substr(pos+1);
|
||||
}
|
||||
|
||||
if (prefix_match(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;
|
||||
return name;
|
||||
});
|
||||
return complete(prefix, cursor_pos, c, prefix_match, subsequence_match);
|
||||
}
|
||||
|
||||
void BufferManager::clear_buffer_trash()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "buffer_manager.hh"
|
||||
#include "command_manager.hh"
|
||||
#include "containers.hh"
|
||||
#include "event_manager.hh"
|
||||
#include "face_registry.hh"
|
||||
#include "file.hh"
|
||||
|
@ -172,19 +173,8 @@ void ClientManager::clear_mode_trashes() const
|
|||
CandidateList ClientManager::complete_client_name(StringView prefix,
|
||||
ByteCount cursor_pos) const
|
||||
{
|
||||
auto real_prefix = prefix.substr(0, cursor_pos);
|
||||
CandidateList result;
|
||||
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;
|
||||
auto c = transformed(m_clients, [](const std::unique_ptr<Client>& c){ return c->context().name(); });
|
||||
return complete(prefix, cursor_pos, c, prefix_match, subsequence_match);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,5 +53,43 @@ inline Completions offset_pos(Completions completion, ByteCount offset)
|
|||
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
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "containers.hh"
|
||||
#include "exception.hh"
|
||||
#include "containers.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -80,16 +81,12 @@ void FaceRegistry::register_alias(const String& name, const String& facedesc,
|
|||
}
|
||||
|
||||
CandidateList FaceRegistry::complete_alias_name(StringView prefix,
|
||||
ByteCount cursor_pos) const
|
||||
ByteCount cursor_pos) const
|
||||
{
|
||||
CandidateList res;
|
||||
auto real_prefix = prefix.substr(0, cursor_pos);
|
||||
for (auto& alias : m_aliases)
|
||||
{
|
||||
if (prefix_match(alias.first, real_prefix))
|
||||
res.push_back(alias.first);
|
||||
}
|
||||
return res;
|
||||
using ValueType = std::pair<String, FaceOrAlias>;
|
||||
return complete(prefix, cursor_pos,
|
||||
transformed(m_aliases,
|
||||
[](const ValueType& v){ return v.first; }));
|
||||
}
|
||||
|
||||
FaceRegistry::FaceRegistry()
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "id_map.hh"
|
||||
#include "string.hh"
|
||||
#include "exception.hh"
|
||||
#include "containers.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -35,7 +36,8 @@ public:
|
|||
|
||||
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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
auto condition = [=](const HighlighterMap::value_type& hl)
|
||||
{
|
||||
return not group or hl.second->has_children();
|
||||
};
|
||||
return { 0, 0, m_highlighters.complete_id_if(path, cursor_pos, condition) };
|
||||
using ValueType = HighlighterMap::value_type;
|
||||
auto c = transformed(filtered(m_highlighters,
|
||||
[=](const ValueType& hl)
|
||||
{ return not group or hl.second->has_children(); }),
|
||||
HighlighterMap::get_id);
|
||||
return { 0, 0, complete(path, cursor_pos, c) };
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "assert.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "context.hh"
|
||||
#include "containers.hh"
|
||||
#include "display_buffer.hh"
|
||||
#include "face_registry.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 { 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)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "hook_manager.hh"
|
||||
|
||||
#include "containers.hh"
|
||||
#include "context.hh"
|
||||
#include "debug.hh"
|
||||
#include "regex.hh"
|
||||
|
@ -26,8 +27,8 @@ CandidateList HookManager::complete_hook_group(StringView prefix, ByteCount pos_
|
|||
CandidateList res;
|
||||
for (auto& list : m_hook)
|
||||
{
|
||||
auto candidates = list.second.complete_id(prefix, pos_in_token);
|
||||
for (auto& c : candidates)
|
||||
auto container = transformed(list.second, id_map<HookFunc>::get_id);
|
||||
for (auto& c : complete(prefix, pos_in_token, container))
|
||||
{
|
||||
if (!contains(res, c))
|
||||
res.push_back(c);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define hook_manager_hh_INCLUDED
|
||||
|
||||
#include "id_map.hh"
|
||||
#include "completion.hh"
|
||||
#include "unordered_map.hh"
|
||||
|
||||
namespace Kakoune
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define id_map_hh_INCLUDED
|
||||
|
||||
#include "containers.hh"
|
||||
#include "completion.hh"
|
||||
#include "string.hh"
|
||||
|
||||
#include <vector>
|
||||
|
@ -63,30 +62,7 @@ public:
|
|||
m_content.erase(it, end());
|
||||
}
|
||||
|
||||
template<typename Condition>
|
||||
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; });
|
||||
}
|
||||
static const String& get_id(const value_type& v) { return v.first; }
|
||||
|
||||
bool empty() const { return m_content.empty(); }
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "ncurses_ui.hh"
|
||||
|
||||
#include "containers.hh"
|
||||
#include "display_buffer.hh"
|
||||
#include "event_manager.hh"
|
||||
#include "keys.hh"
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "exception.hh"
|
||||
#include "flags.hh"
|
||||
#include "option_types.hh"
|
||||
#include "utils.hh"
|
||||
#include "regex.hh"
|
||||
|
||||
namespace Kakoune
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "register_manager.hh"
|
||||
|
||||
#include "assert.hh"
|
||||
#include "id_map.hh"
|
||||
#include "exception.hh"
|
||||
#include "id_map.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "hook_manager.hh"
|
||||
#include "keymap_manager.hh"
|
||||
#include "option_manager.hh"
|
||||
#include "utils.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user