Preserve indentation in doc comments

This commit is contained in:
Jeremy Kolb 2019-01-25 21:31:31 -05:00
parent 5af7b2f4af
commit 8c08b6825e

View file

@ -115,19 +115,30 @@ pub trait DocCommentsOwner: AstNode {
} }
/// Returns the textual content of a doc comment block as a single string. /// Returns the textual content of a doc comment block as a single string.
/// That is, strips leading `///` and joins lines /// That is, strips leading `///` (+ optional 1 character of whitespace)
/// and joins lines.
fn doc_comment_text(&self) -> std::string::String { fn doc_comment_text(&self) -> std::string::String {
self.doc_comments() self.doc_comments()
.filter(|comment| comment.is_doc_comment()) .filter(|comment| comment.is_doc_comment())
.map(|comment| { .map(|comment| {
let prefix = comment.prefix(); let prefix_len = comment.prefix().len();
let trimmed = comment
.text() // Strip leading and trailing whitespace
.as_str() let line = comment.text().as_str().trim();
.trim()
.trim_start_matches(prefix) // Determine if the prefix or prefix + 1 char is stripped
.trim_start(); let pos = if line
trimmed.to_owned() .chars()
.nth(prefix_len)
.map(|c| c.is_whitespace())
.unwrap_or(false)
{
prefix_len + 1
} else {
prefix_len
};
line[pos..].to_owned()
}) })
.join("\n") .join("\n")
} }
@ -701,3 +712,23 @@ fn test_doc_comment_of_items() {
let module = file.syntax().descendants().find_map(Module::cast).unwrap(); let module = file.syntax().descendants().find_map(Module::cast).unwrap();
assert_eq!("doc", module.doc_comment_text()); assert_eq!("doc", module.doc_comment_text());
} }
#[test]
fn test_doc_comment_preserves_indents() {
let file = SourceFile::parse(
r#"
/// doc1
/// ```
/// fn foo() {
/// // ...
/// }
/// ```
mod foo {}
"#,
);
let module = file.syntax().descendants().find_map(Module::cast).unwrap();
assert_eq!(
"doc1\n```\nfn foo() {\n // ...\n}\n```",
module.doc_comment_text()
);
}