From 153dd2fe0bf5be124b7bd70e45186691920c3e94 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 23 Nov 2021 18:02:41 +0100 Subject: [PATCH] ClangCodeModel: Fix overly simplistic check ... when doing function call completion with clangd. We did not take default arguments into account. E.g. the following declaration: void func(int i, int j = int()); was mis-detected as taking no arguments, causing to the cursor to be at the wrong location afterwards. Change-Id: I522921721b0cb347ed593c43ed285ca6d02ccfee Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdclient.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index 7ca82cf1a8d..68a94b1fea9 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -2938,10 +2938,12 @@ void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator, if (!edit) return; + const int labelOpenParenOffset = item.label().indexOf('('); + const int labelClosingParenOffset = item.label().indexOf(')'); const auto kind = static_cast( item.kind().value_or(CompletionItemKind::Text)); - const bool isMacroCall = kind == CompletionItemKind::Text && item.label().contains('(') - && item.label().contains(')'); // Heuristic + const bool isMacroCall = kind == CompletionItemKind::Text && labelOpenParenOffset != -1 + && labelClosingParenOffset > labelOpenParenOffset; // Heuristic const bool isFunctionLike = kind == CompletionItemKind::Function || kind == CompletionItemKind::Method || kind == CompletionItemKind::Constructor || isMacroCall; @@ -2951,10 +2953,12 @@ void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator, // Some preparation for our magic involving (non-)insertion of parentheses and // cursor placement. if (isFunctionLike && !rawInsertText.contains('(')) { - if (item.label().contains("()")) // function takes no arguments - rawInsertText += "()"; - else if (item.label().contains('(')) // function takes arguments - rawInsertText += "( )"; + if (labelOpenParenOffset != -1) { + if (labelClosingParenOffset == labelOpenParenOffset + 1) // function takes no arguments + rawInsertText += "()"; + else // function takes arguments + rawInsertText += "( )"; + } } const int firstParenOffset = rawInsertText.indexOf('(');