[PATCH] D67224: [clangd] Enable completions with fixes in VSCode
Ilya Biryukov via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 5 07:00:13 PDT 2019
ilya-biryukov created this revision.
Herald added subscribers: cfe-commits, kadircet, arphaman, mgrang, jkorous, MaskRay.
Herald added a project: clang.
Currently, the completions are not shown to the user as VSCode tries to match
'filterText' against the text in the edit range. Since the text contains '.'
or '->', we end up trying to match 'field' against '->field' and fail.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D67224
Files:
clang-tools-extra/clangd/CodeComplete.cpp
clang-tools-extra/clangd/CodeComplete.h
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
@@ -65,6 +65,14 @@
}
}
+class EnableEditsNearCursorFeature implements vscodelc.StaticFeature {
+ fillClientCapabilities(capabilities: vscodelc.ClientCapabilities): void {
+ const extendedCompletionCapabilities: any = capabilities.textDocument.completion;
+ extendedCompletionCapabilities.editsNearCursor = true;
+ }
+ initialize(capabilities: vscodelc.ServerCapabilities, documentSelector: (string | { language: string; scheme?: string; pattern?: string; } | { language?: string; scheme: string; pattern?: string; } | { language?: string; scheme?: string; pattern: string; })[]): void {
+ }
+}
/**
* this method is called when your extension is activate
* your extension is activated the very first time the command is executed
@@ -114,6 +122,7 @@
context.subscriptions.push(
vscode.Disposable.from(semanticHighlightingFeature));
clangdClient.registerFeature(semanticHighlightingFeature);
+ clangdClient.registerFeature(new EnableEditsNearCursorFeature);
console.log('Clang Language Server is now active!');
context.subscriptions.push(clangdClient.start());
context.subscriptions.push(vscode.commands.registerCommand(
Index: clang-tools-extra/clangd/CodeComplete.h
===================================================================
--- clang-tools-extra/clangd/CodeComplete.h
+++ clang-tools-extra/clangd/CodeComplete.h
@@ -175,9 +175,13 @@
// thse includes may not be accurate for all of them.
llvm::SmallVector<IncludeCandidate, 1> Includes;
+ struct FixIt {
+ std::string Before;
+ TextEdit Edit;
+ };
/// Holds information about small corrections that needs to be done. Like
/// converting '->' to '.' on member access.
- std::vector<TextEdit> FixIts;
+ std::vector<FixIt> FixIts;
/// Holds the range of the token we are going to replace with this completion.
Range CompletionTokenRange;
Index: clang-tools-extra/clangd/CodeComplete.cpp
===================================================================
--- clang-tools-extra/clangd/CodeComplete.cpp
+++ clang-tools-extra/clangd/CodeComplete.cpp
@@ -277,12 +277,25 @@
Completion.Name.back() == '/')
Completion.Kind = CompletionItemKind::Folder;
for (const auto &FixIt : C.SemaResult->FixIts) {
- Completion.FixIts.push_back(toTextEdit(
- FixIt, ASTCtx->getSourceManager(), ASTCtx->getLangOpts()));
+ // FIXME: this should live in SourceCode.h
+ auto &SM = ASTCtx->getSourceManager();
+ CharSourceRange Range = Lexer::makeFileCharRange(FixIt.RemoveRange, SM,
+ ASTCtx->getLangOpts());
+ FileID FID;
+ unsigned StartOffset;
+ std::tie(FID, StartOffset) = SM.getDecomposedLoc(Range.getBegin());
+
+ std::string Code = SM.getBufferData(FID).substr(
+ StartOffset, SM.getFileOffset(Range.getEnd()) - StartOffset);
+
+ Completion.FixIts.push_back(CodeCompletion::FixIt{
+ std::move(Code), toTextEdit(FixIt, ASTCtx->getSourceManager(),
+ ASTCtx->getLangOpts())});
}
- llvm::sort(Completion.FixIts, [](const TextEdit &X, const TextEdit &Y) {
- return std::tie(X.range.start.line, X.range.start.character) <
- std::tie(Y.range.start.line, Y.range.start.character);
+ llvm::sort(Completion.FixIts, [](const CodeCompletion::FixIt &X,
+ const CodeCompletion::FixIt &Y) {
+ return std::tie(X.Edit.range.start.line, X.Edit.range.start.character) <
+ std::tie(Y.Edit.range.start.line, Y.Edit.range.start.character);
});
Completion.Deprecated |=
(C.SemaResult->Availability == CXAvailability_Deprecated);
@@ -1817,11 +1830,12 @@
// is mainly to help LSP clients again, so that changes do not effect each
// other.
for (const auto &FixIt : FixIts) {
- if (isRangeConsecutive(FixIt.range, LSP.textEdit->range)) {
- LSP.textEdit->newText = FixIt.newText + LSP.textEdit->newText;
- LSP.textEdit->range.start = FixIt.range.start;
+ if (isRangeConsecutive(FixIt.Edit.range, LSP.textEdit->range)) {
+ LSP.textEdit->newText = FixIt.Edit.newText + LSP.textEdit->newText;
+ LSP.textEdit->range.start = FixIt.Edit.range.start;
+ LSP.filterText = FixIt.Before + LSP.filterText;
} else {
- LSP.additionalTextEdits.push_back(FixIt);
+ LSP.additionalTextEdits.push_back(FixIt.Edit);
}
}
if (Opts.EnableSnippets)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D67224.218910.patch
Type: text/x-patch
Size: 4796 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190905/980119d2/attachment-0001.bin>
More information about the cfe-commits
mailing list