feat: show current-line git blame by default
This commit is contained in:
+163
@@ -1834,6 +1834,36 @@ fn draw_document(
|
||||
document_caret = Some(position);
|
||||
}
|
||||
}
|
||||
if focused
|
||||
&& document_caret.is_some()
|
||||
&& let Some(label) = editor.line_blame()
|
||||
&& let Some((screen_row, &(_, continuation, segment))) = document
|
||||
.visible
|
||||
.iter()
|
||||
.enumerate()
|
||||
.rev()
|
||||
.find(|(_, (row, _, _))| *row == cursor.row)
|
||||
{
|
||||
let line = &editor.lines()[cursor.row];
|
||||
let end = display_column(line, usize::MAX);
|
||||
let start = end.saturating_sub(segment.start).saturating_add(2);
|
||||
let label_width = UnicodeWidthStr::width(label);
|
||||
if end >= segment.start
|
||||
&& end <= segment.end
|
||||
&& (!wrapped || continuation + 1 == document.wrap.segments(cursor.row, line).len())
|
||||
&& start.saturating_add(label_width) <= width
|
||||
{
|
||||
frame.render_widget(
|
||||
Paragraph::new(label).style(Style::default().fg(Color::DarkGray)),
|
||||
Rect::new(
|
||||
viewport.x + start as u16,
|
||||
viewport.y + screen_row as u16,
|
||||
label_width as u16,
|
||||
1,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
if !focused {
|
||||
return;
|
||||
}
|
||||
@@ -7394,6 +7424,139 @@ end
|
||||
assert!(titles.contains("2 [No Name]"), "{titles}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_blame_sanitizes_metadata_preserves_text_and_hides_stale_labels() {
|
||||
let directory = Directory::new();
|
||||
let mut editor = Editor::open(
|
||||
Some(directory.file("source.txt", "界 e\u{301}\nsecond")),
|
||||
vec![],
|
||||
)
|
||||
.unwrap();
|
||||
let source = editor.blame_source().unwrap();
|
||||
assert!(editor.set_line_blame(
|
||||
source,
|
||||
crate::blame::LineBlame {
|
||||
commit: "0123456789abcdef".into(),
|
||||
author: "A\tuthor".into(),
|
||||
summary: "Summary\n\u{1b}done".into(),
|
||||
uncommitted: false,
|
||||
}
|
||||
));
|
||||
let mut terminal = Terminal::new(ratatui::backend::TestBackend::new(80, 8)).unwrap();
|
||||
let mut views = BufferViewports::default();
|
||||
terminal
|
||||
.draw(|frame| views.draw(frame, &mut editor))
|
||||
.unwrap();
|
||||
let screen = screen_text(&terminal);
|
||||
assert!(
|
||||
screen.contains("界") && screen.contains("e\u{301}"),
|
||||
"{screen}"
|
||||
);
|
||||
assert!(
|
||||
screen.contains("A�uthor · Summary��done (01234567)"),
|
||||
"{screen}"
|
||||
);
|
||||
let caret = terminal.get_cursor_position().unwrap();
|
||||
let cell = terminal.backend().buffer()[(caret.x, caret.y)].clone();
|
||||
editor.handle(Input::Down);
|
||||
assert!(editor.line_blame().is_none());
|
||||
terminal
|
||||
.draw(|frame| views.draw(frame, &mut editor))
|
||||
.unwrap();
|
||||
assert!(!screen_text(&terminal).contains("Summary"));
|
||||
editor.handle(Input::Up);
|
||||
assert_eq!(
|
||||
editor.line_blame(),
|
||||
Some("A�uthor · Summary��done (01234567)")
|
||||
);
|
||||
terminal
|
||||
.draw(|frame| views.draw(frame, &mut editor))
|
||||
.unwrap();
|
||||
assert!(screen_text(&terminal).contains("A�uthor · Summary��done (01234567)"));
|
||||
assert_eq!(terminal.get_cursor_position().unwrap(), caret);
|
||||
assert_eq!(terminal.backend().buffer()[(caret.x, caret.y)], cell);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_blame_uses_last_wrap_continuation_and_never_overflows_narrow_panes() {
|
||||
let directory = Directory::new();
|
||||
let mut editor =
|
||||
Editor::open(Some(directory.file("source.txt", &"x".repeat(60))), vec![]).unwrap();
|
||||
editor.execute("word_wrap.toggle");
|
||||
let source = editor.blame_source().unwrap();
|
||||
editor.set_line_blame(
|
||||
source,
|
||||
crate::blame::LineBlame {
|
||||
commit: String::new(),
|
||||
author: String::new(),
|
||||
summary: String::new(),
|
||||
uncommitted: true,
|
||||
},
|
||||
);
|
||||
let mut views = BufferViewports::default();
|
||||
let mut terminal = Terminal::new(ratatui::backend::TestBackend::new(50, 8)).unwrap();
|
||||
terminal
|
||||
.draw(|frame| views.draw(frame, &mut editor))
|
||||
.unwrap();
|
||||
let caret = terminal.get_cursor_position().unwrap();
|
||||
assert!(!pane_screen(&terminal, Rect::new(0, caret.y, 50, 1)).contains("Uncommitted"));
|
||||
assert!(pane_screen(&terminal, Rect::new(0, caret.y + 1, 50, 1)).contains("Uncommitted"));
|
||||
let cell = terminal.backend().buffer()[(16, caret.y + 1)].clone();
|
||||
assert_eq!(cell.symbol(), "U");
|
||||
assert_eq!(cell.fg, Color::DarkGray);
|
||||
let mut narrow = Terminal::new(ratatui::backend::TestBackend::new(12, 8)).unwrap();
|
||||
narrow.draw(|frame| views.draw(frame, &mut editor)).unwrap();
|
||||
assert!(!screen_text(&narrow).contains("Uncommitted"));
|
||||
assert!(screen_text(&narrow).contains("xxx"));
|
||||
editor.execute("git_blame.toggle");
|
||||
terminal
|
||||
.draw(|frame| views.draw(frame, &mut editor))
|
||||
.unwrap();
|
||||
assert!(!screen_text(&terminal).contains("Uncommitted"));
|
||||
let mut historical = readonly_diff_editor(deletion_file());
|
||||
assert!(historical.blame_source().is_none());
|
||||
historical.execute("tab.new");
|
||||
assert!(historical.diff().is_none());
|
||||
assert!(historical.blame_source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_blame_disappears_when_wheel_scroll_hides_the_primary_caret() {
|
||||
let directory = Directory::new();
|
||||
let text = (0..40)
|
||||
.map(|row| format!("row {row}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
let mut session =
|
||||
EditorSession::open(Some(directory.file("source.txt", &text)), vec![], None).unwrap();
|
||||
let source = session.editor().blame_source().unwrap();
|
||||
session.editor_mut().set_line_blame(
|
||||
source,
|
||||
crate::blame::LineBlame {
|
||||
commit: String::new(),
|
||||
author: String::new(),
|
||||
summary: String::new(),
|
||||
uncommitted: true,
|
||||
},
|
||||
);
|
||||
let mut terminal = Terminal::new(ratatui::backend::TestBackend::new(80, 8)).unwrap();
|
||||
let mut views = BufferViewports::default();
|
||||
terminal
|
||||
.draw(|frame| views.draw_session(frame, &mut session))
|
||||
.unwrap();
|
||||
assert!(screen_text(&terminal).contains("Uncommitted"));
|
||||
let area = views.document.geometry.unwrap().1;
|
||||
assert!(views.scroll(
|
||||
&mut session,
|
||||
document_wheel(MouseEventKind::ScrollDown, area.x + 2, area.y + 2)
|
||||
));
|
||||
terminal
|
||||
.draw(|frame| views.draw_session(frame, &mut session))
|
||||
.unwrap();
|
||||
assert!(!screen_text(&terminal).contains("Uncommitted"));
|
||||
assert_eq!(session.editor().cursor().row, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_native_battery_and_custom_override_redraw_through_clear() {
|
||||
let directory = Directory::new();
|
||||
|
||||
Reference in New Issue
Block a user