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`", _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits