[clang-tools-extra] 7c13fe8 - [clangd] Introduce codeblocks
Kadir Cetinkaya via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 13 00:59:05 PST 2019
Author: Kadir Cetinkaya
Date: 2019-12-13T09:58:55+01:00
New Revision: 7c13fe8a6a643497d49036e6ea368e1adb06f57e
URL: https://github.com/llvm/llvm-project/commit/7c13fe8a6a643497d49036e6ea368e1adb06f57e
DIFF: https://github.com/llvm/llvm-project/commit/7c13fe8a6a643497d49036e6ea368e1adb06f57e.diff
LOG: [clangd] Introduce codeblocks
Summary: Follow-up to the patch D71248
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71414
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
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/FormattedString.cpp b/clang-tools-extra/clangd/FormattedString.cpp
index 8bb17f38012b..69d33a45ada1 100644
--- a/clang-tools-extra/clangd/FormattedString.cpp
+++ b/clang-tools-extra/clangd/FormattedString.cpp
@@ -72,10 +72,10 @@ std::string renderInlineBlock(llvm::StringRef Input) {
return "`" + std::move(R) + "`";
}
-/// Render \p Input as markdown code block with a specified \p Language. The
-/// result is surrounded by >= 3 backticks. Although markdown also allows to use
-/// '~' for code blocks, they are never used.
-std::string renderCodeBlock(llvm::StringRef Input, llvm::StringRef Language) {
+/// Get marker required for \p Input to represent a markdown codeblock. It
+/// consists of at least 3 backticks(`). Although markdown also allows to use
+/// tilde(~) for code blocks, they are never used.
+std::string getMarkerForCodeBlock(llvm::StringRef Input) {
// Count the maximum number of consecutive backticks in \p Input. We need to
// start and end the code block with more.
unsigned MaxBackticks = 0;
@@ -90,8 +90,7 @@ std::string renderCodeBlock(llvm::StringRef Input, llvm::StringRef Language) {
}
MaxBackticks = std::max(Backticks, MaxBackticks);
// Use the corresponding number of backticks to start and end a code block.
- std::string BlockMarker(/*Repeat=*/std::max(3u, MaxBackticks + 1), '`');
- return BlockMarker + Language.str() + "\n" + Input.str() + "\n" + BlockMarker;
+ return std::string(/*Repeat=*/std::max(3u, MaxBackticks + 1), '`');
}
// Trims the input and concatanates whitespace blocks into a single ` `.
@@ -131,6 +130,26 @@ class Spacer : public Block {
void renderPlainText(llvm::raw_ostream &OS) const override { OS << '\n'; }
};
+class CodeBlock : public Block {
+public:
+ void renderMarkdown(llvm::raw_ostream &OS) const override {
+ std::string Marker = getMarkerForCodeBlock(Contents);
+ // No need to pad from previous blocks, as they should end with a new line.
+ OS << Marker << Language << '\n' << Contents << '\n' << Marker << '\n';
+ }
+
+ void renderPlainText(llvm::raw_ostream &OS) const override {
+ // In plaintext we want one empty line before and after codeblocks.
+ OS << '\n' << Contents << "\n\n";
+ }
+
+ CodeBlock(std::string Contents, std::string Language)
+ : Contents(std::move(Contents)), Language(std::move(Language)) {}
+
+private:
+ std::string Contents;
+ std::string Language;
+};
} // namespace
std::string Block::asMarkdown() const {
@@ -204,6 +223,11 @@ Paragraph &Document::addParagraph() {
void Document::addSpacer() { Children.push_back(std::make_unique<Spacer>()); }
+void Document::addCodeBlock(std::string Code, std::string Language) {
+ Children.emplace_back(
+ std::make_unique<CodeBlock>(std::move(Code), std::move(Language)));
+}
+
std::string Document::asMarkdown() const {
return renderBlocks(Children, &Block::renderMarkdown);
}
diff --git a/clang-tools-extra/clangd/FormattedString.h b/clang-tools-extra/clangd/FormattedString.h
index 02753950f0cf..4ded2fdee315 100644
--- a/clang-tools-extra/clangd/FormattedString.h
+++ b/clang-tools-extra/clangd/FormattedString.h
@@ -70,6 +70,9 @@ class Document {
Paragraph &addParagraph();
/// Inserts a vertical space into the document.
void addSpacer();
+ /// Adds a block of code. This translates to a ``` block in markdown. In plain
+ /// text representation, the code block will be surrounded by newlines.
+ void addCodeBlock(std::string Code, std::string Language = "cpp");
std::string asMarkdown() const;
std::string asPlainText() const;
diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index d6b270c826d9..f55a9c3d1f67 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -95,7 +95,7 @@ std::string printDefinition(const Decl *D) {
}
void printParams(llvm::raw_ostream &OS,
- const std::vector<HoverInfo::Param> &Params) {
+ const std::vector<HoverInfo::Param> &Params) {
for (size_t I = 0, E = Params.size(); I != E; ++I) {
if (I)
OS << ", ";
@@ -456,12 +456,11 @@ markup::Document HoverInfo::present() const {
P.appendCode(llvm::StringRef(*NamespaceScope).drop_back(2));
}
- Output.addSpacer();
if (!Definition.empty()) {
- Output.addParagraph().appendCode(Definition);
+ Output.addCodeBlock(Definition);
} else {
// Builtin types
- Output.addParagraph().appendCode(Name);
+ Output.addCodeBlock(Name);
}
if (!Documentation.empty())
diff --git a/clang-tools-extra/clangd/unittests/FormattedStringTests.cpp b/clang-tools-extra/clangd/unittests/FormattedStringTests.cpp
index 39f5c64a3817..7d57be61f0b2 100644
--- a/clang-tools-extra/clangd/unittests/FormattedStringTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FormattedStringTests.cpp
@@ -54,6 +54,28 @@ TEST(Render, Escaping) {
P = Paragraph();
P.appendCode("`foo`");
EXPECT_EQ(P.asMarkdown(), "` ``foo`` `");
+
+ // Code blocks might need more than 3 backticks.
+ Document D;
+ D.addCodeBlock("foobarbaz `\nqux");
+ EXPECT_EQ(D.asMarkdown(), "```cpp\n"
+ "foobarbaz `\nqux\n"
+ "```");
+ D = Document();
+ D.addCodeBlock("foobarbaz ``\nqux");
+ EXPECT_THAT(D.asMarkdown(), "```cpp\n"
+ "foobarbaz ``\nqux\n"
+ "```");
+ D = Document();
+ D.addCodeBlock("foobarbaz ```\nqux");
+ EXPECT_EQ(D.asMarkdown(), "````cpp\n"
+ "foobarbaz ```\nqux\n"
+ "````");
+ D = Document();
+ D.addCodeBlock("foobarbaz ` `` ``` ```` `\nqux");
+ EXPECT_EQ(D.asMarkdown(), "`````cpp\n"
+ "foobarbaz ` `` ``` ```` `\nqux\n"
+ "`````");
}
TEST(Paragraph, SeparationOfChunks) {
@@ -96,9 +118,18 @@ TEST(Paragraph, NewLines) {
TEST(Document, Separators) {
Document D;
D.addParagraph().appendText("foo");
+ D.addCodeBlock("test");
D.addParagraph().appendText("bar");
- EXPECT_EQ(D.asMarkdown(), "foo\nbar");
- EXPECT_EQ(D.asPlainText(), "foo\nbar");
+ EXPECT_EQ(D.asMarkdown(), R"md(foo
+```cpp
+test
+```
+bar)md");
+ EXPECT_EQ(D.asPlainText(), R"pt(foo
+
+test
+
+bar)pt");
}
TEST(Document, Spacer) {
@@ -110,6 +141,38 @@ TEST(Document, Spacer) {
EXPECT_EQ(D.asPlainText(), "foo\n\nbar");
}
+TEST(CodeBlock, Render) {
+ Document D;
+ // Code blocks preserves any extra spaces.
+ D.addCodeBlock("foo\n bar\n baz");
+ EXPECT_EQ(D.asMarkdown(), R"md(```cpp
+foo
+ bar
+ baz
+```)md");
+ EXPECT_EQ(D.asPlainText(), R"pt(foo
+ bar
+ baz)pt");
+ D.addCodeBlock("foo");
+ EXPECT_EQ(D.asMarkdown(), R"md(```cpp
+foo
+ bar
+ baz
+```
+```cpp
+foo
+```)md");
+ // FIXME: we shouldn't have 2 empty lines in between. A solution might be
+ // having a `verticalMargin` method for blocks, and let container insert new
+ // lines according to that before/after blocks.
+ EXPECT_EQ(D.asPlainText(), R"pt(foo
+ bar
+ baz
+
+
+foo)pt");
+}
+
} // namespace
} // namespace markup
} // namespace clangd
More information about the cfe-commits
mailing list