diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -1850,6 +1850,8 @@ if (InsertInclude && InsertInclude->Insertion) LSP.additionalTextEdits.push_back(*InsertInclude->Insertion); + LSP.score = Score.ExcludingName; + return LSP; } diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h --- a/clang-tools-extra/clangd/Protocol.h +++ b/clang-tools-extra/clangd/Protocol.h @@ -1094,6 +1094,12 @@ /// Indicates if this item is deprecated. bool deprecated = false; + /// The score that Clangd calculates to rank completion items. This score can + /// be used to adjust the ranking on the client side. + /// NOTE: This excludes fuzzy matching score which is typically calculated on + /// the client side. + float score = 0.f; + // TODO(krasimir): The following optional fields defined by the language // server protocol are unsupported: // diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -869,6 +869,7 @@ Result["additionalTextEdits"] = llvm::json::Array(CI.additionalTextEdits); if (CI.deprecated) Result["deprecated"] = CI.deprecated; + Result["score"] = CI.score; return std::move(Result); } diff --git a/clang-tools-extra/clangd/test/completion-auto-trigger.test b/clang-tools-extra/clangd/test/completion-auto-trigger.test --- a/clang-tools-extra/clangd/test/completion-auto-trigger.test +++ b/clang-tools-extra/clangd/test/completion-auto-trigger.test @@ -24,6 +24,7 @@ # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 5, # CHECK-NEXT: "label": " size", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}size", # CHECK-NEXT: "textEdit": { # CHECK-NEXT: "newText": "size", @@ -46,6 +47,7 @@ # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 10, # CHECK-NEXT: "label": " default_capacity", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}default_capacity", # CHECK-NEXT: "textEdit": { # CHECK-NEXT: "newText": "default_capacity", @@ -86,6 +88,7 @@ # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 6, # CHECK-NEXT: "label": " ns_member", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}ns_member", # CHECK-NEXT: "textEdit": { # CHECK-NEXT: "newText": "ns_member", diff --git a/clang-tools-extra/clangd/test/completion-snippets.test b/clang-tools-extra/clangd/test/completion-snippets.test --- a/clang-tools-extra/clangd/test/completion-snippets.test +++ b/clang-tools-extra/clangd/test/completion-snippets.test @@ -33,6 +33,7 @@ # CHECK-NEXT: "insertTextFormat": 2, # CHECK-NEXT: "kind": 3, # CHECK-NEXT: "label": " func_with_args(int a, int b)", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}func_with_args" # CHECK-NEXT: "textEdit": { # CHECK-NEXT: "newText": "func_with_args(${1:int a}, ${2:int b})", diff --git a/clang-tools-extra/clangd/test/completion.test b/clang-tools-extra/clangd/test/completion.test --- a/clang-tools-extra/clangd/test/completion.test +++ b/clang-tools-extra/clangd/test/completion.test @@ -17,6 +17,7 @@ # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 5, # CHECK-NEXT: "label": " a", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}a" # CHECK-NEXT: "textEdit": { # CHECK-NEXT: "newText": "a", @@ -50,6 +51,7 @@ # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 5, # CHECK-NEXT: "label": " b", +# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}}, # CHECK-NEXT: "sortText": "{{.*}}b" # CHECK-NEXT: "textEdit": { # CHECK-NEXT: "newText": "b", diff --git a/clang-tools-extra/clangd/test/protocol.test b/clang-tools-extra/clangd/test/protocol.test --- a/clang-tools-extra/clangd/test/protocol.test +++ b/clang-tools-extra/clangd/test/protocol.test @@ -39,6 +39,7 @@ # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 5, # CHECK-NEXT: "label": " a", +# CHECK-NEXT: "score": 13.200000762939453, # CHECK-NEXT: "sortText": "{{.*}}" # CHECK: ] # CHECK-NEXT: } @@ -68,6 +69,7 @@ # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 5, # CHECK-NEXT: "label": " a", +# CHECK-NEXT: "score": 13.200000762939453, # CHECK-NEXT: "sortText": "{{.*}}" # CHECK: ] # CHECK-NEXT: } @@ -97,6 +99,7 @@ # CHECK-NEXT: "insertTextFormat": 1, # CHECK-NEXT: "kind": 5, # CHECK-NEXT: "label": " a", +# CHECK-NEXT: "score": 13.200000762939453, # CHECK-NEXT: "sortText": "{{.*}}" # CHECK: ] # CHECK-NEXT: } diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -1627,6 +1627,7 @@ Include.Header = "\"foo.h\""; C.Kind = CompletionItemKind::Method; C.Score.Total = 1.0; + C.Score.ExcludingName = .5; C.Origin = SymbolOrigin::AST | SymbolOrigin::Static; CodeCompleteOptions Opts; @@ -1644,6 +1645,7 @@ EXPECT_THAT(R.additionalTextEdits, IsEmpty()); EXPECT_EQ(R.sortText, sortText(1.0, "x")); EXPECT_FALSE(R.deprecated); + EXPECT_EQ(R.score, .5f); Opts.EnableSnippets = true; R = C.render(Opts);