kadircet created this revision.
kadircet added reviewers: ioeric, ilya-biryukov, hokein.
Herald added subscribers: cfe-commits, arphaman, jkorous, MaskRay.

Currently we only add parantheses to the functions if snippets are
enabled, which also inserts snippets for parameters into parantheses. Adding a
new option to put only parantheses. Also it moves the cursor within parantheses
or at the end of them by looking at whether completion item has any parameters
or not. Still requires snippets support on the client side.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D50835

Files:
  clangd/CodeComplete.cpp
  clangd/CodeComplete.h
  unittests/clangd/CodeCompleteTests.cpp


Index: unittests/clangd/CodeCompleteTests.cpp
===================================================================
--- unittests/clangd/CodeCompleteTests.cpp
+++ unittests/clangd/CodeCompleteTests.cpp
@@ -1590,6 +1590,44 @@
               ElementsAre(Sig("foo(T, U) -> void", {"T", "U"})));
 }
 
+TEST(CompletionTest, RenderWithCursorRelocation) {
+  CodeCompleteOptions Opts;
+  Opts.EnableCursorRelocation = true;
+
+  {
+    CodeCompletion C;
+    C.RequiredQualifier = "Foo::";
+    C.Name = "x";
+    C.SnippetSuffix = "";
+
+    auto R = C.render(Opts);
+    EXPECT_EQ(R.textEdit->newText, "Foo::x");
+    EXPECT_EQ(R.insertTextFormat, InsertTextFormat::Snippet);
+  }
+
+  {
+    CodeCompletion C;
+    C.RequiredQualifier = "Foo::";
+    C.Name = "x";
+    C.SnippetSuffix = "()";
+
+    auto R = C.render(Opts);
+    EXPECT_EQ(R.textEdit->newText, "Foo::x()");
+    EXPECT_EQ(R.insertTextFormat, InsertTextFormat::Snippet);
+  }
+
+  {
+    CodeCompletion C;
+    C.RequiredQualifier = "Foo::";
+    C.Name = "x";
+    C.SnippetSuffix = "(${0:bool})";
+
+    auto R = C.render(Opts);
+    EXPECT_EQ(R.textEdit->newText, "Foo::x(${0})");
+    EXPECT_EQ(R.insertTextFormat, InsertTextFormat::Snippet);
+  }
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clangd/CodeComplete.h
===================================================================
--- clangd/CodeComplete.h
+++ clangd/CodeComplete.h
@@ -81,6 +81,12 @@
   /// Include completions that require small corrections, e.g. change '.' to
   /// '->' on member access etc.
   bool IncludeFixIts = false;
+
+  /// Enables cursor to be moved around according to completions needs even 
when
+  /// snippets are disabled. For example selecting a function with parameters 
as
+  /// completion item moves the cursor within the parameters, whereas without
+  /// parameters moves to after closing parantheses.
+  bool EnableCursorRelocation = false;
 };
 
 // Semi-structured representation of a code-complete suggestion for our C++ 
API.
Index: clangd/CodeComplete.cpp
===================================================================
--- clangd/CodeComplete.cpp
+++ clangd/CodeComplete.cpp
@@ -1373,11 +1373,21 @@
   }
   if (Opts.EnableSnippets)
     LSP.textEdit->newText += SnippetSuffix;
+  // Check if we have cursor relocation enabled and completing a function.
+  else if (SnippetSuffix.size() && Opts.EnableCursorRelocation) {
+    // Check whether function has any parameters or not.
+    if (SnippetSuffix.size() > 2)
+      LSP.textEdit->newText += "(${0})";
+    else
+      LSP.textEdit->newText += "()";
+  }
+
   // FIXME(kadircet): Do not even fill insertText after making sure textEdit is
   // compatible with most of the editors.
   LSP.insertText = LSP.textEdit->newText;
-  LSP.insertTextFormat = Opts.EnableSnippets ? InsertTextFormat::Snippet
-                                             : InsertTextFormat::PlainText;
+  LSP.insertTextFormat = Opts.EnableSnippets || Opts.EnableCursorRelocation
+                             ? InsertTextFormat::Snippet
+                             : InsertTextFormat::PlainText;
   if (HeaderInsertion)
     LSP.additionalTextEdits.push_back(*HeaderInsertion);
   return LSP;


Index: unittests/clangd/CodeCompleteTests.cpp
===================================================================
--- unittests/clangd/CodeCompleteTests.cpp
+++ unittests/clangd/CodeCompleteTests.cpp
@@ -1590,6 +1590,44 @@
               ElementsAre(Sig("foo(T, U) -> void", {"T", "U"})));
 }
 
+TEST(CompletionTest, RenderWithCursorRelocation) {
+  CodeCompleteOptions Opts;
+  Opts.EnableCursorRelocation = true;
+
+  {
+    CodeCompletion C;
+    C.RequiredQualifier = "Foo::";
+    C.Name = "x";
+    C.SnippetSuffix = "";
+
+    auto R = C.render(Opts);
+    EXPECT_EQ(R.textEdit->newText, "Foo::x");
+    EXPECT_EQ(R.insertTextFormat, InsertTextFormat::Snippet);
+  }
+
+  {
+    CodeCompletion C;
+    C.RequiredQualifier = "Foo::";
+    C.Name = "x";
+    C.SnippetSuffix = "()";
+
+    auto R = C.render(Opts);
+    EXPECT_EQ(R.textEdit->newText, "Foo::x()");
+    EXPECT_EQ(R.insertTextFormat, InsertTextFormat::Snippet);
+  }
+
+  {
+    CodeCompletion C;
+    C.RequiredQualifier = "Foo::";
+    C.Name = "x";
+    C.SnippetSuffix = "(${0:bool})";
+
+    auto R = C.render(Opts);
+    EXPECT_EQ(R.textEdit->newText, "Foo::x(${0})");
+    EXPECT_EQ(R.insertTextFormat, InsertTextFormat::Snippet);
+  }
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clangd/CodeComplete.h
===================================================================
--- clangd/CodeComplete.h
+++ clangd/CodeComplete.h
@@ -81,6 +81,12 @@
   /// Include completions that require small corrections, e.g. change '.' to
   /// '->' on member access etc.
   bool IncludeFixIts = false;
+
+  /// Enables cursor to be moved around according to completions needs even when
+  /// snippets are disabled. For example selecting a function with parameters as
+  /// completion item moves the cursor within the parameters, whereas without
+  /// parameters moves to after closing parantheses.
+  bool EnableCursorRelocation = false;
 };
 
 // Semi-structured representation of a code-complete suggestion for our C++ API.
Index: clangd/CodeComplete.cpp
===================================================================
--- clangd/CodeComplete.cpp
+++ clangd/CodeComplete.cpp
@@ -1373,11 +1373,21 @@
   }
   if (Opts.EnableSnippets)
     LSP.textEdit->newText += SnippetSuffix;
+  // Check if we have cursor relocation enabled and completing a function.
+  else if (SnippetSuffix.size() && Opts.EnableCursorRelocation) {
+    // Check whether function has any parameters or not.
+    if (SnippetSuffix.size() > 2)
+      LSP.textEdit->newText += "(${0})";
+    else
+      LSP.textEdit->newText += "()";
+  }
+
   // FIXME(kadircet): Do not even fill insertText after making sure textEdit is
   // compatible with most of the editors.
   LSP.insertText = LSP.textEdit->newText;
-  LSP.insertTextFormat = Opts.EnableSnippets ? InsertTextFormat::Snippet
-                                             : InsertTextFormat::PlainText;
+  LSP.insertTextFormat = Opts.EnableSnippets || Opts.EnableCursorRelocation
+                             ? InsertTextFormat::Snippet
+                             : InsertTextFormat::PlainText;
   if (HeaderInsertion)
     LSP.additionalTextEdits.push_back(*HeaderInsertion);
   return LSP;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to