[clang-tools-extra] r325242 - [clangd] Enable snippet completion based on client capabilities.

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 15 06:32:57 PST 2018


Author: ibiryukov
Date: Thu Feb 15 06:32:57 2018
New Revision: 325242

URL: http://llvm.org/viewvc/llvm-project?rev=325242&view=rev
Log:
[clangd] Enable snippet completion based on client capabilities.

Summary: And remove -enable-snippets flag.

Reviewers: hokein, ioeric, sammccall

Reviewed By: ioeric

Subscribers: klimek, jkorous-apple, cfe-commits

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

Added:
    clang-tools-extra/trunk/test/clangd/completion-snippets.test
Modified:
    clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
    clang-tools-extra/trunk/clangd/Protocol.cpp
    clang-tools-extra/trunk/clangd/Protocol.h
    clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp

Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=325242&r1=325241&r2=325242&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Thu Feb 15 06:32:57 2018
@@ -87,6 +87,14 @@ std::vector<TextEdit> replacementsToEdit
 } // namespace
 
 void ClangdLSPServer::onInitialize(InitializeParams &Params) {
+  if (Params.rootUri && !Params.rootUri->file.empty())
+    Server.setRootPath(Params.rootUri->file);
+  else if (Params.rootPath && !Params.rootPath->empty())
+    Server.setRootPath(*Params.rootPath);
+
+  CCOpts.EnableSnippets =
+      Params.capabilities.textDocument.completion.completionItem.snippetSupport;
+
   reply(json::obj{
       {{"capabilities",
         json::obj{
@@ -116,10 +124,6 @@ void ClangdLSPServer::onInitialize(Initi
                  {"commands", {ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND}},
              }},
         }}}});
-  if (Params.rootUri && !Params.rootUri->file.empty())
-    Server.setRootPath(Params.rootUri->file);
-  else if (Params.rootPath && !Params.rootPath->empty())
-    Server.setRootPath(*Params.rootPath);
 }
 
 void ClangdLSPServer::onShutdown(ShutdownParams &Params) {

Modified: clang-tools-extra/trunk/clangd/Protocol.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.cpp?rev=325242&r1=325241&r2=325242&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.cpp (original)
+++ clang-tools-extra/trunk/clangd/Protocol.cpp Thu Feb 15 06:32:57 2018
@@ -150,6 +150,41 @@ bool fromJSON(const json::Expr &E, Trace
   return false;
 }
 
+bool fromJSON(const json::Expr &Params, CompletionItemClientCapabilities &R) {
+  json::ObjectMapper O(Params);
+  if (!O)
+    return false;
+  O.map("snippetSupport", R.snippetSupport);
+  O.map("commitCharacterSupport", R.commitCharacterSupport);
+  return true;
+}
+
+bool fromJSON(const json::Expr &Params, CompletionClientCapabilities &R) {
+  json::ObjectMapper O(Params);
+  if (!O)
+    return false;
+  O.map("dynamicRegistration", R.dynamicRegistration);
+  O.map("completionItem", R.completionItem);
+  O.map("contextSupport", R.contextSupport);
+  return true;
+}
+
+bool fromJSON(const json::Expr &Params, TextDocumentClientCapabilities &R) {
+  json::ObjectMapper O(Params);
+  if (!O)
+    return false;
+  O.map("completion", R.completion);
+  return true;
+}
+
+bool fromJSON(const json::Expr &Params, ClientCapabilities &R) {
+  json::ObjectMapper O(Params);
+  if (!O)
+    return false;
+  O.map("textDocument", R.textDocument);
+  return true;
+}
+
 bool fromJSON(const json::Expr &Params, InitializeParams &R) {
   json::ObjectMapper O(Params);
   if (!O)
@@ -159,6 +194,7 @@ bool fromJSON(const json::Expr &Params,
   O.map("processId", R.processId);
   O.map("rootUri", R.rootUri);
   O.map("rootPath", R.rootPath);
+  O.map("capabilities", R.capabilities);
   O.map("trace", R.trace);
   // initializationOptions, capabilities unused
   return true;

Modified: clang-tools-extra/trunk/clangd/Protocol.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.h?rev=325242&r1=325241&r2=325242&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.h (original)
+++ clang-tools-extra/trunk/clangd/Protocol.h Thu Feb 15 06:32:57 2018
@@ -179,6 +179,51 @@ inline bool fromJSON(const json::Expr &,
 using ShutdownParams = NoParams;
 using ExitParams = NoParams;
 
+struct CompletionItemClientCapabilities {
+  /// Client supports snippets as insert text.
+  bool snippetSupport = false;
+  /// Client supports commit characters on a completion item.
+  bool commitCharacterSupport = false;
+  // Client supports the follow content formats for the documentation property.
+  // The order describes the preferred format of the client.
+  // NOTE: not used by clangd at the moment.
+  // std::vector<MarkupKind> documentationFormat;
+};
+bool fromJSON(const json::Expr &, CompletionItemClientCapabilities &);
+
+struct CompletionClientCapabilities {
+  /// Whether completion supports dynamic registration.
+  bool dynamicRegistration = false;
+  /// The client supports the following `CompletionItem` specific capabilities.
+  CompletionItemClientCapabilities completionItem;
+  // NOTE: not used by clangd at the moment.
+  // llvm::Optional<CompletionItemKindCapabilities> completionItemKind;
+
+  /// The client supports to send additional context information for a
+  /// `textDocument/completion` request.
+  bool contextSupport = false;
+};
+bool fromJSON(const json::Expr &, CompletionClientCapabilities &);
+
+// FIXME: most of the capabilities are missing from this struct. Only the ones
+// used by clangd are currently there.
+struct TextDocumentClientCapabilities {
+  /// Capabilities specific to the `textDocument/completion`
+  CompletionClientCapabilities completion;
+};
+bool fromJSON(const json::Expr &, TextDocumentClientCapabilities &);
+
+struct ClientCapabilities {
+  // Workspace specific client capabilities.
+  // NOTE: not used by clangd at the moment.
+  // WorkspaceClientCapabilities workspace;
+
+  // Text document specific client capabilities.
+  TextDocumentClientCapabilities textDocument;
+};
+
+bool fromJSON(const json::Expr &, ClientCapabilities &);
+
 struct InitializeParams {
   /// The process Id of the parent process that started
   /// the server. Is null if the process has not been started by another
@@ -201,8 +246,7 @@ struct InitializeParams {
   // initializationOptions?: any;
 
   /// The capabilities provided by the client (editor or tool)
-  /// Note: Not currently used by clangd
-  // ClientCapabilities capabilities;
+  ClientCapabilities capabilities;
 
   /// The initial trace setting. If omitted trace is disabled ('off').
   llvm::Optional<TraceLevel> trace;

Modified: clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp?rev=325242&r1=325241&r2=325242&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp (original)
+++ clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp Thu Feb 15 06:32:57 2018
@@ -58,13 +58,6 @@ static llvm::cl::opt<unsigned>
                        llvm::cl::desc("Number of async workers used by clangd"),
                        llvm::cl::init(getDefaultAsyncThreadsCount()));
 
-static llvm::cl::opt<bool> EnableSnippets(
-    "enable-snippets",
-    llvm::cl::desc(
-        "Present snippet completions instead of plaintext completions. "
-        "This also enables code pattern results." /* FIXME: should it? */),
-    llvm::cl::init(clangd::CodeCompleteOptions().EnableSnippets));
-
 // FIXME: Flags are the wrong mechanism for user preferences.
 // We should probably read a dotfile or similar.
 static llvm::cl::opt<bool> IncludeIneligibleResults(
@@ -237,7 +230,6 @@ int main(int argc, char *argv[]) {
   if (EnableIndexBasedCompletion && !YamlSymbolFile.empty())
     StaticIdx = BuildStaticIndex(YamlSymbolFile);
   clangd::CodeCompleteOptions CCOpts;
-  CCOpts.EnableSnippets = EnableSnippets;
   CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;
   CCOpts.Limit = LimitCompletionResult;
   // Initialize and run ClangdLSPServer.

Added: clang-tools-extra/trunk/test/clangd/completion-snippets.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/completion-snippets.test?rev=325242&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clangd/completion-snippets.test (added)
+++ clang-tools-extra/trunk/test/clangd/completion-snippets.test Thu Feb 15 06:32:57 2018
@@ -0,0 +1,43 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+# RUN: clangd -lit-test -pch-storage=memory < %s | FileCheck -strict-whitespace %s
+{
+  "jsonrpc": "2.0",
+  "id": 0,
+  "method": "initialize",
+  "params": {
+    "processId": 123,
+    "rootPath": "clangd",
+    "capabilities": {
+      "textDocument": {
+        "completion": {
+          "completionItem": {
+            "snippetSupport": true
+          }
+        }
+      }
+    },
+    "trace": "off"
+  }
+}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"int func_with_args(int a, int b);\nint main() {\nfunc_with\n}"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":7}}}
+#      CHECK:  "id": 1
+# CHECK-NEXT:  "jsonrpc": "2.0",
+# CHECK-NEXT:  "result": {
+# CHECK-NEXT:    "isIncomplete": {{.*}}
+# CHECK-NEXT:    "items": [
+# CHECK-NEXT:    {
+# CHECK-NEXT:      "detail": "int",
+# CHECK-NEXT:      "filterText": "func_with_args",
+# CHECK-NEXT:      "insertText": "func_with_args(${1:int a}, ${2:int b})",
+# CHECK-NEXT:      "insertTextFormat": 2,
+# CHECK-NEXT:      "kind": 3,
+# CHECK-NEXT:      "label": "func_with_args(int a, int b)",
+# CHECK-NEXT:      "sortText": "{{.*}}func_with_args"
+# CHECK-NEXT:    }
+# CHECK-NEXT:    ]
+# CHECK-NEXT:  }
+---
+{"jsonrpc":"2.0","id":4,"method":"shutdown"}




More information about the cfe-commits mailing list