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

2020-03-06 Thread Sam McCall via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc86f794bd555: [clangd][VSCode] Force VSCode to use the 
ranking provided by clangd. (authored by sammccall).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75623/new/

https://reviews.llvm.org/D75623

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


Index: clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
===
--- clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
+++ clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
@@ -98,7 +98,33 @@
 },
 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',


Index: clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
===
--- clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
+++ clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
@@ -98,7 +98,33 @@
 },
 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',
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2020-03-05 Thread Sam McCall via Phabricator via cfe-commits
sammccall updated this revision to Diff 248497.
sammccall marked 2 inline comments as done.
sammccall added a comment.

address review comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75623/new/

https://reviews.llvm.org/D75623

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


Index: clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
===
--- clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
+++ clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
@@ -98,7 +98,33 @@
 },
 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',


Index: clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
===
--- clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
+++ clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
@@ -98,7 +98,33 @@
 },
 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',
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2020-03-05 Thread Haojian Wu via Phabricator via cfe-commits
hokein added a comment.

thanks for fixing that! Played around it locally, it seems work, found an issue 
where the global code completion is not triggered, see my comment.




Comment at: clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts:116
+// Get the incomplete identifier before the cursor.
+let word = document.getWordRangeAtPosition(position);
+let prefix = document.getText(new vscode.Range(word.start, 
position));

the word is `undefined` if we trigger the global code completion, e.g. `^`, 
`std::^`.





Comment at: clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts:124
+})
+return new vscode.CompletionList(items, true);
+  }

nit: /*isInComplete=*/true


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75623/new/

https://reviews.llvm.org/D75623



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2020-03-04 Thread Sam McCall via Phabricator via cfe-commits
sammccall added a comment.

I tested this with an example like:

  int a_b_c;
  char *abc;
  int x = ab^ // prefer a_b_c due to type match.

before this patch, we see [abc, a_b_c]. After this patch, [a_b_c, abc].


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75623/new/

https://reviews.llvm.org/D75623



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2020-03-04 Thread Sam McCall via Phabricator via cfe-commits
sammccall created this revision.
sammccall added a reviewer: hokein.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous, 
MaskRay, ilya-biryukov.
Herald added a project: clang.
sammccall added a comment.

I tested this with an example like:

  int a_b_c;
  char *abc;
  int x = ab^ // prefer a_b_c due to type match.

before this patch, we see [abc, a_b_c]. After this patch, [a_b_c, abc].


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.

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75623

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


Index: clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
===
--- clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
+++ clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
@@ -98,7 +98,32 @@
 },
 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 = 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 => {
+  item.filterText = prefix + "_" + item.filterText;
+  return item;
+})
+return new vscode.CompletionList(items, true);
+  }
+},
 };
 
   const clangdClient = new ClangdLanguageClient('Clang Language Server',


Index: clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
===
--- clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
+++ clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
@@ -98,7 +98,32 @@
 },
 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 = document.getText(new vscode.Range(word.start, position));
+
+let list = await next(document, position, context, token);
+