aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r--crates/ra_syntax/src/ast.rs49
1 files changed, 40 insertions, 9 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 00c60ebf3..74a45f52f 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -115,19 +115,30 @@ pub trait DocCommentsOwner: AstNode {
115 } 115 }
116 116
117 /// Returns the textual content of a doc comment block as a single string. 117 /// Returns the textual content of a doc comment block as a single string.
118 /// That is, strips leading `///` and joins lines 118 /// That is, strips leading `///` (+ optional 1 character of whitespace)
119 /// and joins lines.
119 fn doc_comment_text(&self) -> std::string::String { 120 fn doc_comment_text(&self) -> std::string::String {
120 self.doc_comments() 121 self.doc_comments()
121 .filter(|comment| comment.is_doc_comment()) 122 .filter(|comment| comment.is_doc_comment())
122 .map(|comment| { 123 .map(|comment| {
123 let prefix = comment.prefix(); 124 let prefix_len = comment.prefix().len();
124 let trimmed = comment 125
125 .text() 126 // Strip leading and trailing whitespace
126 .as_str() 127 let line = comment.text().as_str().trim();
127 .trim() 128
128 .trim_start_matches(prefix) 129 // Determine if the prefix or prefix + 1 char is stripped
129 .trim_start(); 130 let pos = if line
130 trimmed.to_owned() 131 .chars()
132 .nth(prefix_len)
133 .map(|c| c.is_whitespace())
134 .unwrap_or(false)
135 {
136 prefix_len + 1
137 } else {
138 prefix_len
139 };
140
141 line[pos..].to_owned()
131 }) 142 })
132 .join("\n") 143 .join("\n")
133 } 144 }
@@ -701,3 +712,23 @@ fn test_doc_comment_of_items() {
701 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 712 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
702 assert_eq!("doc", module.doc_comment_text()); 713 assert_eq!("doc", module.doc_comment_text());
703} 714}
715
716#[test]
717fn test_doc_comment_preserves_indents() {
718 let file = SourceFile::parse(
719 r#"
720 /// doc1
721 /// ```
722 /// fn foo() {
723 /// // ...
724 /// }
725 /// ```
726 mod foo {}
727 "#,
728 );
729 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
730 assert_eq!(
731 "doc1\n```\nfn foo() {\n // ...\n}\n```",
732 module.doc_comment_text()
733 );
734}