mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-29 02:51:57 +00:00
Speedup sorting and limit number of completion results.
This commit is contained in:
parent
e76a336f19
commit
2e6d596a5a
@ -70,12 +70,15 @@ MAKE_REFLECT_STRUCT(Out_TextDocumentComplete, jsonrpc, id, result);
|
||||
|
||||
bool CompareLsCompletionItem(const lsCompletionItem& lhs,
|
||||
const lsCompletionItem& rhs) {
|
||||
return std::make_tuple(!lhs.found_, lhs.skip_, lhs.priority_,
|
||||
lhs.filterText.length(), std::cref(lhs.filterText),
|
||||
lhs.label.length(), std::cref(lhs.label)) <
|
||||
std::make_tuple(!rhs.found_, rhs.skip_, rhs.priority_,
|
||||
rhs.filterText.length(), std::cref(rhs.filterText),
|
||||
rhs.label.length(), std::cref(rhs.label));
|
||||
if (lhs.found_ != rhs.found_)
|
||||
return !lhs.found_ < !rhs.found_;
|
||||
if (lhs.skip_ != rhs.skip_)
|
||||
return lhs.skip_ < rhs.skip_;
|
||||
if (lhs.priority_ != rhs.priority_)
|
||||
return lhs.priority_ < rhs.priority_;
|
||||
if (lhs.filterText.length() != rhs.filterText.length())
|
||||
return lhs.filterText.length() < rhs.filterText.length();
|
||||
return lhs.filterText < rhs.filterText;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -144,24 +147,43 @@ void FilterAndSortCompletionResponse(
|
||||
}
|
||||
|
||||
// Fuzzy match.
|
||||
for (auto& item : items)
|
||||
bool found = false;
|
||||
for (auto& item : items) {
|
||||
std::tie(item.found_, item.skip_) =
|
||||
SubsequenceCountSkip(complete_text, item.filterText);
|
||||
found = found || item.found_;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
auto filter = [](const lsCompletionItem& item) { return !item.found_; };
|
||||
items.erase(std::remove_if(items.begin(), items.end(), filter),
|
||||
items.end());
|
||||
}
|
||||
|
||||
// Order all items and set |sortText|.
|
||||
const size_t kMaxSortSize = 200u;
|
||||
if (found) {
|
||||
if (items.size() <= kMaxSortSize)
|
||||
std::sort(items.begin(), items.end(), CompareLsCompletionItem);
|
||||
else {
|
||||
// Just place items that found the text before those not.
|
||||
std::vector<lsCompletionItem> items_found, items_notfound;
|
||||
for (auto& item : items)
|
||||
(item.found_ ? items_found : items_notfound).push_back(item);
|
||||
items = items_found;
|
||||
items.insert(items.end(), items_notfound.begin(), items_notfound.end());
|
||||
}
|
||||
}
|
||||
|
||||
char buf[16];
|
||||
for (size_t i = 0; i < items.size(); ++i)
|
||||
items[i].sortText = tofixedbase64(i, buf);
|
||||
|
||||
// If there are too many results...
|
||||
const size_t kMaxResultSize = 100u;
|
||||
if (items.size() > kMaxResultSize) {
|
||||
if (complete_text.empty()) {
|
||||
if (items.size() > kMaxResultSize)
|
||||
items.resize(kMaxResultSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TextDocumentCompletionHandler : MessageHandler {
|
||||
IpcId GetId() const override { return IpcId::TextDocumentCompletion; }
|
||||
@ -202,7 +224,7 @@ struct TextDocumentCompletionHandler : MessageHandler {
|
||||
std::string character = *request->params.context->triggerCharacter;
|
||||
char preceding_index = request->params.position.character - 2;
|
||||
|
||||
// If the character is '"' or '<', make sure the line is start with '#'.
|
||||
// If the character is '"' or '<', make sure that the line starts with '#'.
|
||||
if (character == "\"" || character == "<") {
|
||||
size_t i = 0;
|
||||
while (i < buffer_line.size() && isspace(buffer_line[i]))
|
||||
|
Loading…
Reference in New Issue
Block a user