Skip to content

Commit b791d08

Browse files
committed
整行高亮
1 parent 67e5e68 commit b791d08

File tree

2 files changed

+79
-103
lines changed

2 files changed

+79
-103
lines changed

asyncgit/src/sync/diff.rs

+4
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ pub struct FileDiff {
130130
pub sizes: (u64, u64),
131131
/// size delta in bytes
132132
pub size_delta: i64,
133+
/// the content of old file
134+
pub old_file_content: Option<String>,
135+
/// the content of new file
136+
pub new_file_content: Option<String>,
133137
}
134138

135139
/// see <https://libgit2.org/libgit2/#HEAD/type/git_diff_options>

src/components/diff.rs

+75-103
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ use ratatui::{
3636
Frame,
3737
};
3838
use std::{borrow::Cow, cell::Cell, cmp, path::Path};
39+
use unicode_segmentation::UnicodeSegmentation;
40+
use unicode_width::UnicodeWidthStr;
3941

4042
#[derive(Default)]
4143
struct Current {
@@ -502,6 +504,18 @@ impl DiffComponent {
502504
])]
503505
}
504506

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+
505519
fn get_line_to_add<'a>(
506520
syntax: Option<&SyntaxText>,
507521
width: u16,
@@ -540,115 +554,73 @@ impl DiffComponent {
540554
};
541555
let content = trim_offset(&content, scrolled_right);
542556

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);
550559

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,
576607
)
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;
647618
}
648619
None => {}
649620
}
650621
}
651-
DiffLineType::Delete => {}
622+
(DiffLineType::Delete, _) => {}
623+
_ => {}
652624
}
653625

654626
Line::from(vec![

0 commit comments

Comments
 (0)