@@ -501,13 +501,17 @@ pub fn parse_file_at_path(
501501 . unwrap_or ( 1 ) ;
502502 let mut indent_level = 1 ;
503503 let mut did_visit_children = false ;
504+ let mut in_error = false ;
504505 loop {
505506 if did_visit_children {
506507 if cursor. goto_next_sibling ( ) {
507508 did_visit_children = false ;
508509 } else if cursor. goto_parent ( ) {
509510 did_visit_children = true ;
510511 indent_level -= 1 ;
512+ if !cursor. node ( ) . has_error ( ) {
513+ in_error = false ;
514+ }
511515 } else {
512516 break ;
513517 }
@@ -519,10 +523,14 @@ pub fn parse_file_at_path(
519523 & mut stdout,
520524 total_width,
521525 indent_level,
526+ in_error,
522527 ) ?;
523528 if cursor. goto_first_child ( ) {
524529 did_visit_children = false ;
525530 indent_level += 1 ;
531+ if cursor. node ( ) . has_error ( ) {
532+ in_error = true ;
533+ }
526534 } else {
527535 did_visit_children = true ;
528536 }
@@ -771,6 +779,7 @@ fn write_node_text(
771779 paint( quote_color, & String :: from( quote) ) ,
772780 ) ?;
773781 } else {
782+ let multiline = source. contains ( '\n' ) ;
774783 for ( i, line) in source. split_inclusive ( '\n' ) . enumerate ( ) {
775784 if line. is_empty ( ) {
776785 break ;
@@ -790,9 +799,18 @@ fn write_node_text(
790799 if !opts. no_ranges {
791800 write ! (
792801 stdout,
793- "\n {}{}{}{}{}" ,
794- render_node_range( opts, cursor, is_named, true , total_width, node_range) ,
795- " " . repeat( indent_level + 1 ) ,
802+ "{}{}{}{}{}{}" ,
803+ if multiline { "\n " } else { "" } ,
804+ if multiline {
805+ render_node_range( opts, cursor, is_named, true , total_width, node_range)
806+ } else {
807+ String :: new( )
808+ } ,
809+ if multiline {
810+ " " . repeat( indent_level + 1 )
811+ } else {
812+ String :: new( )
813+ } ,
796814 paint( quote_color, & String :: from( quote) ) ,
797815 & paint( color, & render_node_text( & formatted_line) ) ,
798816 paint( quote_color, & String :: from( quote) ) ,
@@ -865,6 +883,7 @@ fn cst_render_node(
865883 stdout : & mut StdoutLock < ' static > ,
866884 total_width : usize ,
867885 indent_level : usize ,
886+ in_error : bool ,
868887) -> Result < ( ) > {
869888 let node = cursor. node ( ) ;
870889 let is_named = node. is_named ( ) ;
@@ -875,7 +894,16 @@ fn cst_render_node(
875894 render_node_range( opts, cursor, is_named, false , total_width, node. range( ) )
876895 ) ?;
877896 }
878- write ! ( stdout, "{}" , " " . repeat( indent_level) ) ?;
897+ write ! (
898+ stdout,
899+ "{}{}" ,
900+ " " . repeat( indent_level) ,
901+ if in_error && !node. has_error( ) {
902+ " "
903+ } else {
904+ ""
905+ }
906+ ) ?;
879907 if is_named {
880908 if let Some ( field_name) = cursor. field_name ( ) {
881909 write ! (
@@ -885,10 +913,13 @@ fn cst_render_node(
885913 ) ?;
886914 }
887915
888- let kind_color = if node. has_error ( ) {
916+ if node. has_error ( ) || node . is_error ( ) {
889917 write ! ( stdout, "{}" , paint( opts. parse_theme. error, "•" ) ) ?;
918+ }
919+
920+ let kind_color = if node. is_error ( ) {
890921 opts. parse_theme . error
891- } else if node. is_extra ( ) || node. parent ( ) . is_some_and ( |p| p. is_extra ( ) ) {
922+ } else if node. is_extra ( ) || node. parent ( ) . is_some_and ( |p| p. is_extra ( ) && !p . is_error ( ) ) {
892923 opts. parse_theme . extra
893924 } else {
894925 opts. parse_theme . node_kind
0 commit comments