[clangd] Return empty results on spurious completion triggers
authorIlya Biryukov <ibiryukov@google.com>
Fri, 7 Jun 2019 16:24:38 +0000 (16:24 +0000)
committerIlya Biryukov <ibiryukov@google.com>
Fri, 7 Jun 2019 16:24:38 +0000 (16:24 +0000)
Summary:
We currently return an error, this causes `coc.nvim` and VSCode to
show an error message in the logs.

Returning empty list of completions allows to avod the error message
without altering other user-visible behavior.

Reviewers: sammccall

Reviewed By: sammccall

Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

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

llvm-svn: 362811

clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/test/completion-auto-trigger.test

index 0c09eaaeabf9f8bcb07a879eddfccb0c2fe587f1..0b8f762cb693354f72c8e45c65f285bf956845e0 100644 (file)
 namespace clang {
 namespace clangd {
 namespace {
-class IgnoreCompletionError : public llvm::ErrorInfo<CancelledError> {
-public:
-  void log(llvm::raw_ostream &OS) const override {
-    OS << "ignored auto-triggered completion, preceding char did not match";
-  }
-  std::error_code convertToErrorCode() const override {
-    return std::make_error_code(std::errc::operation_canceled);
-  }
-};
-
 /// Transforms a tweak into a code action that would apply it if executed.
 /// EXPECTS: T.prepare() was called and returned true.
 CodeAction toCodeAction(const ClangdServer::TweakRef &T, const URIForFile &File,
@@ -738,8 +728,12 @@ void ClangdLSPServer::onCodeAction(const CodeActionParams &Params,
 
 void ClangdLSPServer::onCompletion(const CompletionParams &Params,
                                    Callback<CompletionList> Reply) {
-  if (!shouldRunCompletion(Params))
-    return Reply(llvm::make_error<IgnoreCompletionError>());
+  if (!shouldRunCompletion(Params)) {
+    // Clients sometimes auto-trigger completions in undesired places (e.g.
+    // 'a >^ '), we return empty results in those cases.
+    vlog("ignored auto-triggered completion, preceding char did not match");
+    return Reply(CompletionList());
+  }
   Server->codeComplete(Params.textDocument.uri.file(), Params.position, CCOpts,
                        Bind(
                            [this](decltype(Reply) Reply,
index 96830285f04525e74c6b2f4605317fd335f06471..46871b9d3e34cddf202ec410df9d73ae91234e96 100644 (file)
@@ -4,11 +4,12 @@
 {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"namespace ns { int ns_member; } struct vector { int size; static int default_capacity; };\nvoid test(vector *a, vector *b) {\n  if (a > b) {} \n  a->size = 10;\n\n  a ? a : b;\n  ns::ns_member = 10;\n}"}}}
 ---
 {"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":9},"context":{"triggerKind":2,"triggerCharacter":">"}}}
-#      CHECK:  "error": {
-# CHECK-NEXT:    "code": -32001,
-# CHECK-NEXT:    "message": "ignored auto-triggered completion, preceding char did not match"
-# CHECK-NEXT:  },
-# CHECK-NEXT:  "id": 1,
+#      CHECK:  "id": 1,
+# CHECK-NEXT:  "jsonrpc": "2.0"
+# CHECK-NEXT:  "result": {
+# CHECK-NEXT:    "isIncomplete": false,
+# CHECK-NEXT:    "items": []
+# CHECK-NEXT:  }
 ---
 {"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":3,"character":5},"context":{"triggerKind":2,"triggerCharacter":">"}}}
 #      CHECK:  "id": 2,
 # CHECK-NEXT:   }
 ---
 {"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":5,"character":9},"context":{"triggerKind":2,"triggerCharacter":":"}}}
-#      CHECK:  "error": {
-# CHECK-NEXT:    "code": -32001,
-# CHECK-NEXT:    "message": "ignored auto-triggered completion, preceding char did not match"
-# CHECK-NEXT:  },
-# CHECK-NEXT:  "id": 3,
+#      CHECK:  "id": 3,
+# CHECK-NEXT:  "jsonrpc": "2.0",
+# CHECK-NEXT:  "result": {
+# CHECK-NEXT:    "isIncomplete": false,
+# CHECK-NEXT:    "items": []
+# CHECK-NEXT:  }
 ---
 {"jsonrpc":"2.0","id":4,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":6,"character":6},"context":{"triggerKind":2,"triggerCharacter":":"}}}
 ---