@@ -330,28 +330,43 @@ impl Formatter {
330330 let mut matches = cursor. matches ( & query, root, self . content . as_bytes ( ) ) ;
331331 while let Some ( m) = matches. next ( ) {
332332 let first_node = m. captures [ 0 ] . node ;
333- if m. captures . len ( ) == 3 {
334- let comment_node = m. captures [ 1 ] . node ;
335- let second_node = m. captures [ 2 ] . node ;
336- // If the @comment is on the same line as the first node,
337- // we'll add a blank line before the @second node
338- if comment_node. start_position ( ) . row == first_node. start_position ( ) . row {
339- // Find where to insert the new line (before any indentation)
340- let mut byte_idx = second_node. start_byte ( ) ;
341- let mut position = second_node. start_position ( ) ;
342- position. column = 0 ;
343- while self . content . as_bytes ( ) [ byte_idx] != b'\n' {
344- byte_idx -= 1 ;
333+ let last_node = m. captures . last ( ) . unwrap ( ) . node ;
334+
335+ let mut insert_before = last_node;
336+
337+ let capture_has_comments = m. captures . len ( ) >= 3 ;
338+
339+ if capture_has_comments {
340+ let last_comment_node = m. captures [ m. captures . len ( ) - 2 ] . node ;
341+
342+ let last_comment_is_inline_comment = last_comment_node. start_position ( ) . row
343+ == first_node. start_position ( ) . row ;
344+ let last_comment_is_doc_comment = !last_comment_is_inline_comment
345+ && last_comment_node. start_position ( ) . row
346+ == last_node. start_position ( ) . row - 1 ;
347+
348+ // if last comment node is a doc comment find first doc comment node and insert new lines before that
349+ if last_comment_is_doc_comment {
350+ let mut comment_node_index = m. captures . len ( ) - 2 ;
351+
352+ // find first documentation comment node
353+ while comment_node_index > 2
354+ && m. captures [ comment_node_index - 1 ] . node . start_position ( ) . row
355+ == m. captures [ comment_node_index] . node . start_position ( ) . row - 1
356+ {
357+ comment_node_index -= 1 ;
345358 }
346- new_lines_at. push ( ( byte_idx, position) ) ;
347- } else {
348- // Otherwise, add a blank line after the first node
349- new_lines_at. push ( ( first_node. end_byte ( ) , first_node. end_position ( ) ) ) ;
359+ insert_before = m. captures [ comment_node_index] . node ;
350360 }
351- } else {
352- // If there's no comment between the nodes, add a blank line after the first node
353- new_lines_at. push ( ( first_node. end_byte ( ) , first_node. end_position ( ) ) ) ;
354361 }
362+
363+ let mut byte_idx = insert_before. start_byte ( ) ;
364+ let mut position = insert_before. start_position ( ) ;
365+ position. column = 0 ;
366+ while byte_idx > 0 && self . content . as_bytes ( ) [ byte_idx] != b'\n' {
367+ byte_idx -= 1 ;
368+ }
369+ new_lines_at. push ( ( byte_idx, position) ) ;
355370 }
356371 } ;
357372
@@ -372,7 +387,9 @@ impl Formatter {
372387 let mut new_end_position = position;
373388 let mut new_end_byte_idx = byte_idx;
374389 // Only add a second blank line if there isn't already one
375- if self . content . as_bytes ( ) [ byte_idx + 1 ] != b'\n' {
390+ if !( self . content . as_bytes ( ) [ byte_idx] == b'\n'
391+ && self . content . as_bytes ( ) [ byte_idx - 1 ] == b'\n' )
392+ {
376393 new_end_position. row += 1 ;
377394 new_end_byte_idx += 1 ;
378395 self . content . insert ( byte_idx, '\n' ) ;
0 commit comments