fix: keep diff explorer below the top bar
This commit is contained in:
+87
-34
@@ -412,6 +412,17 @@ impl BufferViewports {
|
||||
Some(document_layout(area, editor))
|
||||
};
|
||||
let full_workspace = chrome.map_or(area, |areas| areas[0]);
|
||||
let diff_header = editor
|
||||
.diff()
|
||||
.filter(|diff| !multiple && diff.phase == Phase::View)
|
||||
.map(|_| {
|
||||
Rect::new(
|
||||
full_workspace.x,
|
||||
full_workspace.y,
|
||||
full_workspace.width,
|
||||
full_workspace.height.min(1),
|
||||
)
|
||||
});
|
||||
let (workspace, dock) = match editor.file_picker() {
|
||||
Some(picker) if picker.presentation == FilePresentation::Docked => dock_layout(
|
||||
full_workspace,
|
||||
@@ -424,6 +435,13 @@ impl BufferViewports {
|
||||
),
|
||||
_ => (full_workspace, None),
|
||||
};
|
||||
let dock = dock.map(|mut panel| {
|
||||
if let Some(header) = diff_header {
|
||||
panel.y = panel.y.saturating_add(header.height);
|
||||
panel.height = panel.height.saturating_sub(header.height);
|
||||
}
|
||||
panel
|
||||
});
|
||||
editor.set_pane_bounds(pane_rect(workspace));
|
||||
self.rects.clear();
|
||||
editor
|
||||
@@ -491,6 +509,11 @@ impl BufferViewports {
|
||||
}
|
||||
self.activate(focused, editor);
|
||||
self.panels.workspace_managed = false;
|
||||
if let Some(header) = diff_header
|
||||
&& let Some(diff) = editor.diff()
|
||||
{
|
||||
draw_diff_header(frame, diff, Some(editor), header);
|
||||
}
|
||||
if let Some(panel) = dock
|
||||
&& let Some(picker) = editor.file_picker()
|
||||
{
|
||||
@@ -1842,6 +1865,46 @@ fn draw_diff_popups(
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_diff_header(frame: &mut Frame, diff: &DiffState, editor: Option<&Editor>, header: Rect) {
|
||||
if header.width == 0 || header.height == 0 {
|
||||
return;
|
||||
}
|
||||
let (before, after) = diff.comparison.as_ref().map_or(("", ""), |comparison| {
|
||||
(comparison.before.as_str(), comparison.after.as_str())
|
||||
});
|
||||
frame.render_widget(
|
||||
Paragraph::new(format!(
|
||||
"Diff · {} → {} · {:?} focus · {}",
|
||||
display_text(before),
|
||||
display_text(after),
|
||||
diff.focus,
|
||||
editor
|
||||
.filter(|editor| editor.diff_interacting())
|
||||
.map_or_else(
|
||||
|| "read-only".into(),
|
||||
|editor| format!(
|
||||
"{} · {}{} · {}:{}",
|
||||
if editor.diff_editing() {
|
||||
"editable"
|
||||
} else {
|
||||
"read-only"
|
||||
},
|
||||
if editor.visual_linewise() {
|
||||
"VISUAL LINE".into()
|
||||
} else {
|
||||
editor.mode().to_string()
|
||||
},
|
||||
if editor.dirty() { " [+]" } else { "" },
|
||||
editor.cursor().row + 1,
|
||||
editor.cursor().column + 1,
|
||||
),
|
||||
)
|
||||
))
|
||||
.style(Style::default().fg(Color::Black).bg(Color::Cyan)),
|
||||
header,
|
||||
);
|
||||
}
|
||||
|
||||
fn draw_diff(
|
||||
frame: &mut Frame,
|
||||
diff: &DiffState,
|
||||
@@ -2072,40 +2135,9 @@ fn draw_diff(
|
||||
Constraint::Length(u16::from(area.height >= 3)),
|
||||
])
|
||||
.areas(area);
|
||||
let (before, after) = comparison.map_or(("", ""), |comparison| {
|
||||
(comparison.before.as_str(), comparison.after.as_str())
|
||||
});
|
||||
frame.render_widget(
|
||||
Paragraph::new(format!(
|
||||
"Diff · {} → {} · {:?} focus · {}",
|
||||
display_text(before),
|
||||
display_text(after),
|
||||
diff.focus,
|
||||
editor
|
||||
.filter(|editor| editor.diff_interacting())
|
||||
.map_or_else(
|
||||
|| "read-only".into(),
|
||||
|editor| format!(
|
||||
"{} · {}{} · {}:{}",
|
||||
if editor.diff_editing() {
|
||||
"editable"
|
||||
} else {
|
||||
"read-only"
|
||||
},
|
||||
if editor.visual_linewise() {
|
||||
"VISUAL LINE".into()
|
||||
} else {
|
||||
editor.mode().to_string()
|
||||
},
|
||||
if editor.dirty() { " [+]" } else { "" },
|
||||
editor.cursor().row + 1,
|
||||
editor.cursor().column + 1,
|
||||
),
|
||||
)
|
||||
))
|
||||
.style(Style::default().fg(Color::Black).bg(Color::Cyan)),
|
||||
header,
|
||||
);
|
||||
if !panels.workspace_managed || editor.is_none_or(|editor| editor.pane_layout().len() > 1) {
|
||||
draw_diff_header(frame, diff, editor, header);
|
||||
}
|
||||
if let Some(notice) = notice {
|
||||
frame.render_widget(
|
||||
Paragraph::new(display_text(notice)).style(Style::default().fg(
|
||||
@@ -5059,6 +5091,27 @@ mod tests {
|
||||
assert_eq!(dock.height, 28);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn native_diff_dock_stays_below_the_full_width_header() {
|
||||
let mut editor = readonly_diff_editor(deletion_file());
|
||||
let mut views = BufferViewports::default();
|
||||
for (width, height) in [(120, 30), (32, 9)] {
|
||||
let mut terminal =
|
||||
Terminal::new(ratatui::backend::TestBackend::new(width, height)).unwrap();
|
||||
terminal
|
||||
.draw(|frame| views.draw(frame, &mut editor))
|
||||
.unwrap();
|
||||
let dock = views.panels.files.unwrap().0;
|
||||
let before = views.panels.diff.as_ref().unwrap().regions[1].0;
|
||||
assert_eq!(dock.y, before.y);
|
||||
assert_eq!(dock.y, 1);
|
||||
assert_eq!(dock.right(), width);
|
||||
for x in 0..width {
|
||||
assert_eq!(terminal.backend().buffer()[(x, 0)].bg, Color::Cyan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn revision_selector_overlays_and_clears_workspace_pane_borders() {
|
||||
let mut editor = Editor::open(None, vec![]).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user