mirror of
https://github.com/MaskRay/ccls.git
synced 2025-04-02 15:02:19 +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,
|
bool CompareLsCompletionItem(const lsCompletionItem& lhs,
|
||||||
const lsCompletionItem& rhs) {
|
const lsCompletionItem& rhs) {
|
||||||
return std::make_tuple(!lhs.found_, lhs.skip_, lhs.priority_,
|
if (lhs.found_ != rhs.found_)
|
||||||
lhs.filterText.length(), std::cref(lhs.filterText),
|
return !lhs.found_ < !rhs.found_;
|
||||||
lhs.label.length(), std::cref(lhs.label)) <
|
if (lhs.skip_ != rhs.skip_)
|
||||||
std::make_tuple(!rhs.found_, rhs.skip_, rhs.priority_,
|
return lhs.skip_ < rhs.skip_;
|
||||||
rhs.filterText.length(), std::cref(rhs.filterText),
|
if (lhs.priority_ != rhs.priority_)
|
||||||
rhs.label.length(), std::cref(rhs.label));
|
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>
|
template <typename T>
|
||||||
@ -144,24 +147,43 @@ void FilterAndSortCompletionResponse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fuzzy match.
|
// Fuzzy match.
|
||||||
for (auto& item : items)
|
bool found = false;
|
||||||
|
for (auto& item : items) {
|
||||||
std::tie(item.found_, item.skip_) =
|
std::tie(item.found_, item.skip_) =
|
||||||
SubsequenceCountSkip(complete_text, item.filterText);
|
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|.
|
// Order all items and set |sortText|.
|
||||||
|
const size_t kMaxSortSize = 200u;
|
||||||
|
if (found) {
|
||||||
|
if (items.size() <= kMaxSortSize)
|
||||||
std::sort(items.begin(), items.end(), CompareLsCompletionItem);
|
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];
|
char buf[16];
|
||||||
for (size_t i = 0; i < items.size(); ++i)
|
for (size_t i = 0; i < items.size(); ++i)
|
||||||
items[i].sortText = tofixedbase64(i, buf);
|
items[i].sortText = tofixedbase64(i, buf);
|
||||||
|
|
||||||
// If there are too many results...
|
// If there are too many results...
|
||||||
const size_t kMaxResultSize = 100u;
|
const size_t kMaxResultSize = 100u;
|
||||||
if (items.size() > kMaxResultSize) {
|
if (items.size() > kMaxResultSize)
|
||||||
if (complete_text.empty()) {
|
|
||||||
items.resize(kMaxResultSize);
|
items.resize(kMaxResultSize);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TextDocumentCompletionHandler : MessageHandler {
|
struct TextDocumentCompletionHandler : MessageHandler {
|
||||||
IpcId GetId() const override { return IpcId::TextDocumentCompletion; }
|
IpcId GetId() const override { return IpcId::TextDocumentCompletion; }
|
||||||
@ -202,7 +224,7 @@ struct TextDocumentCompletionHandler : MessageHandler {
|
|||||||
std::string character = *request->params.context->triggerCharacter;
|
std::string character = *request->params.context->triggerCharacter;
|
||||||
char preceding_index = request->params.position.character - 2;
|
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 == "<") {
|
if (character == "\"" || character == "<") {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (i < buffer_line.size() && isspace(buffer_line[i]))
|
while (i < buffer_line.size() && isspace(buffer_line[i]))
|
||||||
|
Loading…
Reference in New Issue
Block a user