From 5b5aea71b1d5f25ebea4d38aaac79a086127c9cb Mon Sep 17 00:00:00 2001 From: Riatre Foo Date: Wed, 10 Oct 2018 02:20:53 +0800 Subject: [PATCH] Fix has_open_paren in FilterCandidates --- src/messages/textDocument_completion.cc | 46 +++++++++---------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index 7d129a87..c1df2971 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -155,10 +155,20 @@ template char *tofixedbase64(T input, char *out) { // when given 1000+ completion items. void FilterCandidates(Out_TextDocumentComplete *complete_response, const std::string &complete_text, lsPosition begin_pos, - lsPosition end_pos, bool has_open_paren, - const std::string &buffer_line) { + lsPosition end_pos, const std::string &buffer_line) { + assert(begin_pos.line == end_pos.line); 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::|". + 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 = [&]() { int max_num = g_config->completion.maxNum; if (items.size() > max_num) { @@ -168,8 +178,8 @@ void FilterCandidates(Out_TextDocumentComplete *complete_response, for (auto &item : items) { item.textEdit.range = lsRange{begin_pos, end_pos}; - if (has_open_paren) - item.textEdit.newText = item.label; + if (has_open_paren && item.filterText) + item.textEdit.newText = item.filterText.value(); // https://github.com/Microsoft/language-server-protocol/issues/543 // Order of textEdit and additionalTextEdits is unspecified. auto &edits = item.additionalTextEdits; @@ -237,27 +247,6 @@ void FilterCandidates(Out_TextDocumentComplete *complete_response, finalize(); } -// Returns true if position is an points to a '(' character in |lines|. Skips -// whitespace. -bool IsOpenParenOrAngle(const std::vector &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) { switch (cursor_kind) { case CXCursor_UnexposedDecl: @@ -570,7 +559,6 @@ struct Handler_TextDocumentCompletion params.position, &completion_text, &end_pos); ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line); - bool has_open_paren = IsOpenParenOrAngle(file->buffer_lines, end_pos); if (preprocess.ok && preprocess.keyword.compare("include") == 0) { Out_TextDocumentComplete out; @@ -588,13 +576,13 @@ struct Handler_TextDocumentCompletion begin_pos.character = 0; end_pos.character = (int)buffer_line.size(); FilterCandidates(&out, preprocess.pattern, begin_pos, end_pos, - has_open_paren, buffer_line); + buffer_line); DecorateIncludePaths(preprocess.match, &out.result.items); pipeline::WriteStdout(kMethodType, out); } else { std::string path = params.textDocument.uri.GetPath(); 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) { if (!OptConsumer) return; @@ -604,7 +592,7 @@ struct Handler_TextDocumentCompletion out.result.items = Consumer->ls_items; FilterCandidates(&out, completion_text, begin_pos, end_pos, - has_open_paren, buffer_line); + buffer_line); pipeline::WriteStdout(kMethodType, out); if (!Consumer->from_cache) { cache.WithLock([&]() {