@@ -332,28 +332,43 @@ impl Formatter {
332332 let mut matches = cursor. matches ( & query, root, self . content . as_bytes ( ) ) ;
333333 while let Some ( m) = matches. next ( ) {
334334 let first_node = m. captures [ 0 ] . node ;
335- if m. captures . len ( ) == 3 {
336- let comment_node = m. captures [ 1 ] . node ;
337- let second_node = m. captures [ 2 ] . node ;
338- // If the @comment is on the same line as the first node,
339- // we'll add a blank line before the @second node
340- if comment_node. start_position ( ) . row == first_node. start_position ( ) . row {
341- // Find where to insert the new line (before any indentation)
342- let mut byte_idx = second_node. start_byte ( ) ;
343- let mut position = second_node. start_position ( ) ;
344- position. column = 0 ;
345- while self . content . as_bytes ( ) [ byte_idx] != b'\n' {
346- byte_idx -= 1 ;
335+ let last_node = m. captures . last ( ) . unwrap ( ) . node ;
336+
337+ let mut insert_before = last_node;
338+
339+ let capture_has_comments = m. captures . len ( ) >= 3 ;
340+
341+ if capture_has_comments {
342+ let last_comment_node = m. captures [ m. captures . len ( ) - 2 ] . node ;
343+
344+ let last_comment_is_inline_comment = last_comment_node. start_position ( ) . row
345+ == first_node. start_position ( ) . row ;
346+ let last_comment_is_doc_comment = !last_comment_is_inline_comment
347+ && last_comment_node. start_position ( ) . row
348+ == last_node. start_position ( ) . row - 1 ;
349+
350+ // if last comment node is a doc comment find first doc comment node and insert new lines before that
351+ if last_comment_is_doc_comment {
352+ let mut comment_node_index = m. captures . len ( ) - 2 ;
353+
354+ // find first documentation comment node
355+ while comment_node_index > 2
356+ && m. captures [ comment_node_index - 1 ] . node . start_position ( ) . row
357+ == m. captures [ comment_node_index] . node . start_position ( ) . row - 1
358+ {
359+ comment_node_index -= 1 ;
347360 }
348- new_lines_at. push ( ( byte_idx, position) ) ;
349- } else {
350- // Otherwise, add a blank line after the first node
351- new_lines_at. push ( ( first_node. end_byte ( ) , first_node. end_position ( ) ) ) ;
361+ insert_before = m. captures [ comment_node_index] . node ;
352362 }
353- } else {
354- // If there's no comment between the nodes, add a blank line after the first node
355- new_lines_at. push ( ( first_node. end_byte ( ) , first_node. end_position ( ) ) ) ;
356363 }
364+
365+ let mut byte_idx = insert_before. start_byte ( ) ;
366+ let mut position = insert_before. start_position ( ) ;
367+ position. column = 0 ;
368+ while byte_idx > 0 && self . content . as_bytes ( ) [ byte_idx] != b'\n' {
369+ byte_idx -= 1 ;
370+ }
371+ new_lines_at. push ( ( byte_idx, position) ) ;
357372 }
358373 } ;
359374
@@ -374,7 +389,9 @@ impl Formatter {
374389 let mut new_end_position = position;
375390 let mut new_end_byte_idx = byte_idx;
376391 // Only add a second blank line if there isn't already one
377- if self . content . as_bytes ( ) [ byte_idx + 1 ] != b'\n' {
392+ if !( self . content . as_bytes ( ) [ byte_idx] == b'\n'
393+ && self . content . as_bytes ( ) [ byte_idx - 1 ] == b'\n' )
394+ {
378395 new_end_position. row += 1 ;
379396 new_end_byte_idx += 1 ;
380397 self . content . insert ( byte_idx, '\n' ) ;
0 commit comments