@@ -36,6 +36,8 @@ use ratatui::{
36
36
Frame ,
37
37
} ;
38
38
use std:: { borrow:: Cow , cell:: Cell , cmp, path:: Path } ;
39
+ use unicode_segmentation:: UnicodeSegmentation ;
40
+ use unicode_width:: UnicodeWidthStr ;
39
41
40
42
#[ derive( Default ) ]
41
43
struct Current {
@@ -502,6 +504,18 @@ impl DiffComponent {
502
504
] ) ]
503
505
}
504
506
507
+ // fn get_syntax_highlight_line<'a>(
508
+ // syntax: Option<&SyntaxText>,
509
+ // width: u16,
510
+ // line: &'a DiffLine,
511
+ // selected: bool,
512
+ // selected_hunk: bool,
513
+ // end_of_hunk: bool,
514
+ // theme: &SharedTheme,
515
+ // scrolled_right: usize,
516
+ // ) -> Line<'a> {
517
+ // }
518
+
505
519
fn get_line_to_add < ' a > (
506
520
syntax : Option < & SyntaxText > ,
507
521
width : u16 ,
@@ -540,115 +554,73 @@ impl DiffComponent {
540
554
} ;
541
555
let content = trim_offset ( & content, scrolled_right) ;
542
556
543
- let filled = if selected {
544
- // selected line
545
- format ! ( "{content:w$}\n " , w = width as usize )
546
- } else {
547
- // weird eof missing eol line
548
- format ! ( "{content}\n " )
549
- } ;
557
+ // weird eof missing eol line
558
+ let filled = format ! ( "{content:w$}\n " , w = width as usize ) ;
550
559
551
- match line. line_type {
552
- DiffLineType :: None => { }
553
- DiffLineType :: Header => { }
554
- DiffLineType :: Add => {
555
- match syntax {
556
- Some ( syntax) => {
557
- match syntax
558
- . lines
559
- . iter ( )
560
- . skip (
561
- line. position
562
- . new_lineno
563
- . unwrap_or_default ( )
564
- . saturating_sub ( 1 ) as _ ,
565
- )
566
- . next ( )
567
- {
568
- Some ( syntax_line) => {
569
- info ! (
570
- "line content: {}" ,
571
- line. content
572
- ) ;
573
- let mut line_span: Line =
574
- Vec :: with_capacity (
575
- syntax_line. items . len ( ) + 1 ,
560
+ // 语法高亮,当然 add,remove 和 common 都要有。
561
+
562
+ match ( line. line_type , line. position . new_lineno ) {
563
+ ( DiffLineType :: Header , _) => { }
564
+ (
565
+ DiffLineType :: None | DiffLineType :: Add ,
566
+ Some ( lineno) ,
567
+ ) => {
568
+ let line_index = lineno. saturating_sub ( 1 ) ;
569
+ match syntax
570
+ . and_then ( |s| s. lines . get ( line_index as usize ) )
571
+ {
572
+ Some ( syntax_line) => {
573
+ info ! ( "line content: {}" , line. content) ;
574
+ // format
575
+ let mut line_span: Line = Vec :: with_capacity (
576
+ syntax_line. items . len ( ) + 1 ,
577
+ )
578
+ . into ( ) ;
579
+ line_span. spans . push ( left_side_of_line) ;
580
+ let line_content =
581
+ tabs_to_spaces ( line. content . to_string ( ) ) ;
582
+ let mut char_count = 0 ;
583
+ for ( style, _, range) in & syntax_line. items {
584
+ info ! ( "range: {:?}" , range) ;
585
+
586
+ let item_content =
587
+ & line_content[ range. clone ( ) ] ;
588
+ // char_count += item_content.len();
589
+
590
+ char_count +=
591
+ UnicodeSegmentation :: graphemes (
592
+ item_content,
593
+ true ,
594
+ )
595
+ . map ( |c| c. width ( ) )
596
+ . sum :: < usize > ( ) ;
597
+
598
+ let item_style =
599
+ syntact_style_to_tui ( & style) ;
600
+
601
+ line_span. spans . push ( Span :: styled (
602
+ item_content. to_string ( ) ,
603
+ theme
604
+ . diff_line (
605
+ line. line_type ,
606
+ selected,
576
607
)
577
- . into ( ) ;
578
- line_span
579
- . spans
580
- . push ( left_side_of_line) ;
581
- let line_content = tabs_to_spaces (
582
- line. content . to_string ( ) ,
583
- ) ;
584
- for ( style, _, range) in
585
- & syntax_line. items
586
- {
587
- info ! ( "range: {:?}" , range) ;
588
-
589
- let item_content =
590
- & line_content[ range. clone ( ) ] ;
591
- let item_style =
592
- syntact_style_to_tui ( & style) ;
593
-
594
- // theme.diff_line(
595
- // line.line_type,
596
- // selected,
597
- // );
598
- line_span. spans . push (
599
- Span :: styled (
600
- item_content. to_string ( ) ,
601
- theme
602
- . diff_line (
603
- line. line_type ,
604
- selected,
605
- )
606
- . patch ( item_style) ,
607
- ) ,
608
- ) ;
609
- }
610
- return line_span;
611
- }
612
- None => { }
613
- } ;
614
- // return Line::from(vec![
615
- // left_side_of_line,
616
- // Span::styled(
617
- // Cow::from(filled),
618
- // theme.diff_line(
619
- // line.line_type,
620
- // selected,
621
- // ),
622
- // ),
623
- // ]);
624
-
625
- // let mut result_lines: Vec<Line> =
626
- // Vec::with_capacity(v.lines.len());
627
-
628
- // for (syntax_line, line_content) in
629
- // v.lines.iter().zip(v.text.lines())
630
- // {
631
- // let mut line_span: Line =
632
- // Vec::with_capacity(syntax_line.items.len()).into();
633
-
634
- // for (style, _, range) in &syntax_line.items {
635
- // let item_content = &line_content[range.clone()];
636
- // let item_style = syntact_style_to_tui(style);
637
-
638
- // line_span
639
- // .spans
640
- // .push(Span::styled(item_content, item_style));
641
- // }
642
-
643
- // result_lines.push(line_span);
644
- // }
645
-
646
- // result_lines.into()
608
+ . patch ( item_style) ,
609
+ ) ) ;
610
+ }
611
+ let spaces =
612
+ width. saturating_sub ( char_count as _ ) ;
613
+ line_span. spans . push ( Span :: styled (
614
+ " " . repeat ( spaces as _ ) ,
615
+ theme. diff_line ( line. line_type , selected) ,
616
+ ) ) ;
617
+ return line_span;
647
618
}
648
619
None => { }
649
620
}
650
621
}
651
- DiffLineType :: Delete => { }
622
+ ( DiffLineType :: Delete , _) => { }
623
+ _ => { }
652
624
}
653
625
654
626
Line :: from ( vec ! [
0 commit comments