[clang-tools-extra] c86f794 - [clangd][VSCode] Force VSCode to use the ranking provided by clangd.

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 6 04:35:23 PST 2020


Author: Sam McCall
Date: 2020-03-06T13:34:25+01:00
New Revision: c86f794bd555a272f0f74a0b0a48f158e84b26b4

URL: https://github.com/llvm/llvm-project/commit/c86f794bd555a272f0f74a0b0a48f158e84b26b4
DIFF: https://github.com/llvm/llvm-project/commit/c86f794bd555a272f0f74a0b0a48f158e84b26b4.diff

LOG: [clangd][VSCode] Force VSCode to use the ranking provided by clangd.

Summary:
Clangd's approach is to provide lots of completions, and let ranking sort them
out. This relies on various important signals (Quality.h), without which the
large completion lists are extremely spammy.

Even with a completion result exactly at the cursor, vscode looks backwards and
tries to match the presumed partial-identifier against filterText, and uses
the result to rank, with sortText only used as a tiebreak.
By prepending the partial-identifier to the filterText, we can force the match
to be perfect and so give sortText full control of the ranking.

Full sad story: https://github.com/microsoft/language-server-protocol/issues/898

It's possible to do this on the server side too of course, and switch it on
with an initialization option. But it's a little easier in the extension, it
will get the fix to users of old clangd versions, and other editors

Reviewers: hokein

Reviewed By: hokein

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D75623

Added: 
    

Modified: 
    clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts b/clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
index 4d2e04bce26a..3d8ed2d65564 100644
--- a/clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
+++ b/clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
@@ -98,7 +98,33 @@ export function activate(context: vscode.ExtensionContext) {
         },
         initializationOptions: { clangdFileStatus: true },
         // Do not switch to output window when clangd returns output
-        revealOutputChannelOn: vscodelc.RevealOutputChannelOn.Never
+        revealOutputChannelOn: vscodelc.RevealOutputChannelOn.Never,
+
+        // We hack up the completion items a bit to prevent VSCode from re-ranking them
+        // and throwing away all our delicious signals like type information.
+        //
+        // VSCode sorts by (fuzzymatch(prefix, item.filterText), item.sortText)
+        // By adding the prefix to the beginning of the filterText, we get a perfect
+        // fuzzymatch score for every item.
+        // The sortText (which reflects clangd ranking) breaks the tie.
+        //
+        // We also have to mark the list as incomplete to force retrieving new rankings.
+        // See https://github.com/microsoft/language-server-protocol/issues/898
+        middleware: {
+          provideCompletionItem: async (document, position, context, token, next) => {
+            // Get the incomplete identifier before the cursor.
+            let word = document.getWordRangeAtPosition(position);
+            let prefix = word && document.getText(new vscode.Range(word.start, position));
+            
+            let list = await next(document, position, context, token);
+            let items = (Array.isArray(list) ? list : list.items).map(item => {
+              if (prefix)
+                item.filterText = prefix + "_" + item.filterText;
+              return item;
+            })
+            return new vscode.CompletionList(items, /*isIncomplete=*/true);
+          }
+        },
     };
 
   const clangdClient = new ClangdLanguageClient('Clang Language Server',


        


More information about the cfe-commits mailing list