Index: clang-tools-extra/trunk/clangd/FormattedString.cpp =================================================================== --- clang-tools-extra/trunk/clangd/FormattedString.cpp +++ clang-tools-extra/trunk/clangd/FormattedString.cpp @@ -112,15 +112,20 @@ std::string FormattedString::renderAsMarkdown() const { std::string R; + auto EnsureWhitespace = [&R]() { + // Adds a space for nicer rendering. + if (!R.empty() && !isWhitespace(R.back())) + R += " "; + }; for (const auto &C : Chunks) { switch (C.Kind) { case ChunkKind::PlainText: + if (!C.Contents.empty() && !isWhitespace(C.Contents.front())) + EnsureWhitespace(); R += renderText(C.Contents); continue; case ChunkKind::InlineCodeBlock: - // Make sure we don't glue two backticks together. - if (llvm::StringRef(R).endswith("`")) - R += " "; + EnsureWhitespace(); R += renderInlineBlock(C.Contents); continue; case ChunkKind::CodeBlock: Index: clang-tools-extra/trunk/clangd/unittests/FormattedStringTests.cpp =================================================================== --- clang-tools-extra/trunk/clangd/unittests/FormattedStringTests.cpp +++ clang-tools-extra/trunk/clangd/unittests/FormattedStringTests.cpp @@ -72,7 +72,7 @@ S.appendText("baz"); EXPECT_EQ(S.renderAsPlainText(), "foo bar baz"); - EXPECT_EQ(S.renderAsMarkdown(), "foo`bar`baz"); + EXPECT_EQ(S.renderAsMarkdown(), "foo `bar` baz"); } TEST(FormattedString, Escaping) { @@ -158,6 +158,42 @@ "`````\n"); } +TEST(FormattedString, MarkdownWhitespace) { + // Whitespace should be added as separators between blocks. + FormattedString S; + S.appendText("foo"); + S.appendText("bar"); + EXPECT_EQ(S.renderAsMarkdown(), "foo bar"); + + S = FormattedString(); + S.appendInlineCode("foo"); + S.appendInlineCode("bar"); + EXPECT_EQ(S.renderAsMarkdown(), "`foo` `bar`"); + + // However, we don't want to add any extra whitespace. + S = FormattedString(); + S.appendText("foo "); + S.appendInlineCode("bar"); + EXPECT_EQ(S.renderAsMarkdown(), "foo `bar`"); + + S = FormattedString(); + S.appendText("foo\n"); + S.appendInlineCode("bar"); + EXPECT_EQ(S.renderAsMarkdown(), "foo\n`bar`"); + + S = FormattedString(); + S.appendInlineCode("foo"); + S.appendText(" bar"); + EXPECT_EQ(S.renderAsMarkdown(), "`foo` bar"); + + S = FormattedString(); + S.appendText("foo"); + S.appendCodeBlock("bar"); + S.appendText("baz"); + EXPECT_EQ(S.renderAsMarkdown(), "foo\n```cpp\nbar\n```\nbaz"); +} + + } // namespace } // namespace clangd } // namespace clang