[clang-tools-extra] 2cf93ef - [clangd] Render doc-comment code spans with `backticks` in plaintext mode

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 30 11:17:13 PDT 2020


Author: Sam McCall
Date: 2020-04-30T20:16:51+02:00
New Revision: 2cf93ef9fe1df61b2aac97dc3320a12386a7dab5

URL: https://github.com/llvm/llvm-project/commit/2cf93ef9fe1df61b2aac97dc3320a12386a7dab5
DIFF: https://github.com/llvm/llvm-project/commit/2cf93ef9fe1df61b2aac97dc3320a12386a7dab5.diff

LOG: [clangd] Render doc-comment code spans with `backticks` in plaintext mode

Reviewers: kadircet

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits

Tags: #clang

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

Added: 
    

Modified: 
    clang-tools-extra/clangd/FormattedString.cpp
    clang-tools-extra/clangd/FormattedString.h
    clang-tools-extra/clangd/Hover.cpp
    clang-tools-extra/clangd/unittests/FormattedStringTests.cpp
    clang-tools-extra/clangd/unittests/HoverTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/FormattedString.cpp b/clang-tools-extra/clangd/FormattedString.cpp
index d24103f0dd61..309cb69a2bfc 100644
--- a/clang-tools-extra/clangd/FormattedString.cpp
+++ b/clang-tools-extra/clangd/FormattedString.cpp
@@ -369,10 +369,24 @@ std::unique_ptr<Block> Paragraph::clone() const {
   return std::make_unique<Paragraph>(*this);
 }
 
+/// Choose a marker to delimit `Text` from a prioritized list of options.
+/// This is more readable than escaping for plain-text.
+llvm::StringRef chooseMarker(llvm::ArrayRef<llvm::StringRef> Options,
+                             llvm::StringRef Text) {
+  // Prefer a delimiter whose characters don't appear in the text.
+  for (llvm::StringRef S : Options)
+    if (Text.find_first_of(S) == llvm::StringRef::npos)
+      return S;
+  return Options.front();
+}
+
 void Paragraph::renderPlainText(llvm::raw_ostream &OS) const {
   llvm::StringRef Sep = "";
   for (auto &C : Chunks) {
-    OS << Sep << C.Contents;
+    llvm::StringRef Marker = "";
+    if (C.Preserve && C.Kind == Chunk::InlineCode)
+      Marker = chooseMarker({"`", "'", "\""}, C.Contents);
+    OS << Sep << Marker << C.Contents << Marker;
     Sep = " ";
   }
   OS << '\n';
@@ -407,7 +421,7 @@ Paragraph &Paragraph::appendText(llvm::StringRef Text) {
   return *this;
 }
 
-Paragraph &Paragraph::appendCode(llvm::StringRef Code) {
+Paragraph &Paragraph::appendCode(llvm::StringRef Code, bool Preserve) {
   std::string Norm = canonicalizeSpaces(std::move(Code));
   if (Norm.empty())
     return *this;
@@ -415,6 +429,7 @@ Paragraph &Paragraph::appendCode(llvm::StringRef Code) {
   Chunk &C = Chunks.back();
   C.Contents = std::move(Norm);
   C.Kind = Chunk::InlineCode;
+  C.Preserve = Preserve;
   return *this;
 }
 

diff  --git a/clang-tools-extra/clangd/FormattedString.h b/clang-tools-extra/clangd/FormattedString.h
index 4cdaf2002ed4..295b22db8dab 100644
--- a/clang-tools-extra/clangd/FormattedString.h
+++ b/clang-tools-extra/clangd/FormattedString.h
@@ -51,7 +51,8 @@ class Paragraph : public Block {
   Paragraph &appendText(llvm::StringRef Text);
 
   /// Append inline code, this translates to the ` block in markdown.
-  Paragraph &appendCode(llvm::StringRef Code);
+  /// \p Preserve indicates the code span must be apparent even in plaintext.
+  Paragraph &appendCode(llvm::StringRef Code, bool Preserve = false);
 
 private:
   struct Chunk {
@@ -59,6 +60,8 @@ class Paragraph : public Block {
       PlainText,
       InlineCode,
     } Kind = PlainText;
+    // Preserve chunk markers in plaintext.
+    bool Preserve = false;
     std::string Contents;
   };
   std::vector<Chunk> Chunks;

diff  --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index ebacca823afb..b563273733be 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -877,7 +877,7 @@ void parseDocumentationLine(llvm::StringRef Line, markup::Paragraph &Out) {
       case '`':
         if (auto Range = getBacktickQuoteRange(Line, I)) {
           Out.appendText(Line.substr(0, I));
-          Out.appendCode(Range->trim("`"));
+          Out.appendCode(Range->trim("`"), /*Preserve=*/true);
           return parseDocumentationLine(Line.substr(I+Range->size()), Out);
         }
         break;

diff  --git a/clang-tools-extra/clangd/unittests/FormattedStringTests.cpp b/clang-tools-extra/clangd/unittests/FormattedStringTests.cpp
index 6202f930b504..63cbf3dac9d7 100644
--- a/clang-tools-extra/clangd/unittests/FormattedStringTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FormattedStringTests.cpp
@@ -112,8 +112,10 @@ TEST(Render, Escaping) {
 
   // But we have to escape the backticks.
   P = Paragraph();
-  P.appendCode("foo`bar`baz");
+  P.appendCode("foo`bar`baz", /*Preserve=*/true);
   EXPECT_EQ(P.asMarkdown(), "`foo``bar``baz`");
+  // In plain-text, we fall back to 
diff erent quotes.
+  EXPECT_EQ(P.asPlainText(), "'foo`bar`baz'");
 
   // Inline code blocks starting or ending with backticks should add spaces.
   P = Paragraph();
@@ -149,6 +151,17 @@ TEST(Render, Escaping) {
                             "`````");
 }
 
+TEST(Paragraph, Chunks) {
+  Paragraph P = Paragraph();
+  P.appendText("One ");
+  P.appendCode("fish");
+  P.appendText(", two");
+  P.appendCode("fish", /*Preserve=*/true);
+
+  EXPECT_EQ(P.asMarkdown(), "One `fish` , two `fish`");
+  EXPECT_EQ(P.asPlainText(), "One fish , two `fish`");
+}
+
 TEST(Paragraph, SeparationOfChunks) {
   // This test keeps appending contents to a single Paragraph and checks
   // expected accumulated contents after each one.

diff  --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 45c027102590..c8689b7b9183 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -2022,12 +2022,12 @@ TEST(Hover, ParseDocumentation) {
                    // FIXME: we insert spaces between code and text chunk.
                    "Tests primality of `p`.",
                    "Tests primality of `p` .",
-                   "Tests primality of p .",
+                   "Tests primality of `p` .",
                },
                {
                    "'`' should not occur in `Code`",
                    "'\\`' should not occur in `Code`",
-                   "'`' should not occur in Code",
+                   "'`' should not occur in `Code`",
                },
                {
                    "`not\nparsed`",


        


More information about the cfe-commits mailing list