mirror of
https://github.com/MaskRay/ccls.git
synced 2025-06-14 12:12:20 +00:00
Fix has_open_paren in FilterCandidates
This commit is contained in:
parent
a157393717
commit
5b5aea71b1
@ -155,10 +155,20 @@ template <typename T> char *tofixedbase64(T input, char *out) {
|
|||||||
// when given 1000+ completion items.
|
// when given 1000+ completion items.
|
||||||
void FilterCandidates(Out_TextDocumentComplete *complete_response,
|
void FilterCandidates(Out_TextDocumentComplete *complete_response,
|
||||||
const std::string &complete_text, lsPosition begin_pos,
|
const std::string &complete_text, lsPosition begin_pos,
|
||||||
lsPosition end_pos, bool has_open_paren,
|
lsPosition end_pos, const std::string &buffer_line) {
|
||||||
const std::string &buffer_line) {
|
assert(begin_pos.line == end_pos.line);
|
||||||
auto &items = complete_response->result.items;
|
auto &items = complete_response->result.items;
|
||||||
|
|
||||||
|
// People usually does not want to insert snippets or parenthesis when
|
||||||
|
// changing function or type names, e.g. "str.|()" or "std::|<int>".
|
||||||
|
bool has_open_paren = false;
|
||||||
|
for (int c = end_pos.character; c < buffer_line.size(); ++c) {
|
||||||
|
if (buffer_line[c] == '(' || buffer_line[c] == '<')
|
||||||
|
has_open_paren = true;
|
||||||
|
if (!isspace(buffer_line[c]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
auto finalize = [&]() {
|
auto finalize = [&]() {
|
||||||
int max_num = g_config->completion.maxNum;
|
int max_num = g_config->completion.maxNum;
|
||||||
if (items.size() > max_num) {
|
if (items.size() > max_num) {
|
||||||
@ -168,8 +178,8 @@ void FilterCandidates(Out_TextDocumentComplete *complete_response,
|
|||||||
|
|
||||||
for (auto &item : items) {
|
for (auto &item : items) {
|
||||||
item.textEdit.range = lsRange{begin_pos, end_pos};
|
item.textEdit.range = lsRange{begin_pos, end_pos};
|
||||||
if (has_open_paren)
|
if (has_open_paren && item.filterText)
|
||||||
item.textEdit.newText = item.label;
|
item.textEdit.newText = item.filterText.value();
|
||||||
// https://github.com/Microsoft/language-server-protocol/issues/543
|
// https://github.com/Microsoft/language-server-protocol/issues/543
|
||||||
// Order of textEdit and additionalTextEdits is unspecified.
|
// Order of textEdit and additionalTextEdits is unspecified.
|
||||||
auto &edits = item.additionalTextEdits;
|
auto &edits = item.additionalTextEdits;
|
||||||
@ -237,27 +247,6 @@ void FilterCandidates(Out_TextDocumentComplete *complete_response,
|
|||||||
finalize();
|
finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if position is an points to a '(' character in |lines|. Skips
|
|
||||||
// whitespace.
|
|
||||||
bool IsOpenParenOrAngle(const std::vector<std::string> &lines,
|
|
||||||
const lsPosition &position) {
|
|
||||||
auto [c, l] = position;
|
|
||||||
while (l < lines.size()) {
|
|
||||||
const auto &line = lines[l];
|
|
||||||
if (c >= line.size())
|
|
||||||
return false;
|
|
||||||
if (line[c] == '(' || line[c] == '<')
|
|
||||||
return true;
|
|
||||||
if (!isspace(line[c]))
|
|
||||||
break;
|
|
||||||
if (++c >= line.size()) {
|
|
||||||
c = 0;
|
|
||||||
l++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) {
|
lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) {
|
||||||
switch (cursor_kind) {
|
switch (cursor_kind) {
|
||||||
case CXCursor_UnexposedDecl:
|
case CXCursor_UnexposedDecl:
|
||||||
@ -570,7 +559,6 @@ struct Handler_TextDocumentCompletion
|
|||||||
params.position, &completion_text, &end_pos);
|
params.position, &completion_text, &end_pos);
|
||||||
|
|
||||||
ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line);
|
ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line);
|
||||||
bool has_open_paren = IsOpenParenOrAngle(file->buffer_lines, end_pos);
|
|
||||||
|
|
||||||
if (preprocess.ok && preprocess.keyword.compare("include") == 0) {
|
if (preprocess.ok && preprocess.keyword.compare("include") == 0) {
|
||||||
Out_TextDocumentComplete out;
|
Out_TextDocumentComplete out;
|
||||||
@ -588,13 +576,13 @@ struct Handler_TextDocumentCompletion
|
|||||||
begin_pos.character = 0;
|
begin_pos.character = 0;
|
||||||
end_pos.character = (int)buffer_line.size();
|
end_pos.character = (int)buffer_line.size();
|
||||||
FilterCandidates(&out, preprocess.pattern, begin_pos, end_pos,
|
FilterCandidates(&out, preprocess.pattern, begin_pos, end_pos,
|
||||||
has_open_paren, buffer_line);
|
buffer_line);
|
||||||
DecorateIncludePaths(preprocess.match, &out.result.items);
|
DecorateIncludePaths(preprocess.match, &out.result.items);
|
||||||
pipeline::WriteStdout(kMethodType, out);
|
pipeline::WriteStdout(kMethodType, out);
|
||||||
} else {
|
} else {
|
||||||
std::string path = params.textDocument.uri.GetPath();
|
std::string path = params.textDocument.uri.GetPath();
|
||||||
CompletionManager::OnComplete callback =
|
CompletionManager::OnComplete callback =
|
||||||
[completion_text, path, begin_pos, end_pos, has_open_paren,
|
[completion_text, path, begin_pos, end_pos,
|
||||||
id = request->id, buffer_line](CodeCompleteConsumer *OptConsumer) {
|
id = request->id, buffer_line](CodeCompleteConsumer *OptConsumer) {
|
||||||
if (!OptConsumer)
|
if (!OptConsumer)
|
||||||
return;
|
return;
|
||||||
@ -604,7 +592,7 @@ struct Handler_TextDocumentCompletion
|
|||||||
out.result.items = Consumer->ls_items;
|
out.result.items = Consumer->ls_items;
|
||||||
|
|
||||||
FilterCandidates(&out, completion_text, begin_pos, end_pos,
|
FilterCandidates(&out, completion_text, begin_pos, end_pos,
|
||||||
has_open_paren, buffer_line);
|
buffer_line);
|
||||||
pipeline::WriteStdout(kMethodType, out);
|
pipeline::WriteStdout(kMethodType, out);
|
||||||
if (!Consumer->from_cache) {
|
if (!Consumer->from_cache) {
|
||||||
cache.WithLock([&]() {
|
cache.WithLock([&]() {
|
||||||
|
Loading…
Reference in New Issue
Block a user