@@ -35,7 +35,7 @@ use gpui::{
WeakViewHandle,
};
use json::json;
-use language::{Bias, DiagnosticSeverity, OffsetUtf16, Selection};
+use language::{Bias, DiagnosticSeverity, OffsetUtf16, Point, Selection};
use project::ProjectPath;
use settings::{GitGutter, Settings};
use smallvec::SmallVec;
@@ -52,6 +52,7 @@ use theme::DiffStyle;
struct DiffHunkLayout {
visual_range: Range<u32>,
status: DiffHunkStatus,
+ is_folded: bool,
}
struct SelectionLayout {
@@ -544,12 +545,12 @@ impl EditorElement {
gutter_layout: &GutterLayout,
diff_style: &DiffStyle,
) -> Quad {
- let color = match hunk.status {
- DiffHunkStatus::Added => diff_style.inserted,
- DiffHunkStatus::Modified => diff_style.modified,
+ let color = match (hunk.status, hunk.is_folded) {
+ (DiffHunkStatus::Added, false) => diff_style.inserted,
+ (DiffHunkStatus::Modified, false) => diff_style.modified,
//TODO: This rendering is entirely a horrible hack
- DiffHunkStatus::Removed => {
+ (DiffHunkStatus::Removed, false) => {
let row = hunk.visual_range.start;
let offset = gutter_layout.line_height / 2.;
@@ -569,6 +570,24 @@ impl EditorElement {
corner_radius: 1. * gutter_layout.line_height,
};
}
+
+ (_, true) => {
+ let row = hunk.visual_range.start;
+ let start_y = row as f32 * gutter_layout.line_height - gutter_layout.scroll_top;
+ let end_y = start_y + gutter_layout.line_height;
+
+ let width = diff_style.removed_width_em * gutter_layout.line_height;
+ let highlight_origin = gutter_layout.bounds.origin() + vec2f(-width, start_y);
+ let highlight_size = vec2f(width * 2., end_y - start_y);
+ let highlight_bounds = RectF::new(highlight_origin, highlight_size);
+
+ return Quad {
+ bounds: highlight_bounds,
+ background: Some(diff_style.modified),
+ border: Border::new(0., Color::transparent_black()),
+ corner_radius: 1. * gutter_layout.line_height,
+ };
+ }
};
let start_row = hunk.visual_range.start;
@@ -986,47 +1005,6 @@ impl EditorElement {
.width()
}
- //-> (layout, buffer row advancement)
- fn layout_diff_hunk(
- hunk: &DiffHunk<u32>,
- start_row: u32,
- buffer_rows: &mut std::iter::Peekable<impl Iterator<Item = (usize, Option<u32>)>>,
- ) -> (Option<DiffHunkLayout>, u32) {
- //`buffer_rows` should start with a row which is contained in the hunk's buffer range
- let first_buffer_rows = match buffer_rows.peek() {
- Some(first_buffer_rows) => first_buffer_rows,
- None => return (None, 0),
- };
-
- //The `usize` field is 1-index so we have to sub to move it into 0-offset to match actual rows
- let visual_start = start_row + first_buffer_rows.0 as u32 - 1;
-
- let mut visual_count = 0;
- let mut buffer_row_advancement = 0;
- while let Some(&buffer_row) = buffer_rows.peek() {
- if let (_, Some(buffer_row)) = buffer_row {
- buffer_row_advancement += 1;
- if buffer_row == hunk.buffer_range.end {
- visual_count += 1;
- break;
- } else if buffer_row > hunk.buffer_range.end {
- break;
- }
- visual_count += 1;
- } else {
- visual_count += 1;
- }
-
- buffer_rows.next();
- }
-
- let layout = DiffHunkLayout {
- visual_range: visual_start..visual_start + visual_count,
- status: hunk.status(),
- };
- (Some(layout), buffer_row_advancement)
- }
-
//Folds contained in a hunk are ignored apart from shrinking visual size
//If a fold contains any hunks then that fold line is marked as modified
fn layout_git_gutters(
@@ -1034,87 +1012,94 @@ impl EditorElement {
rows: Range<u32>,
snapshot: &EditorSnapshot,
) -> Vec<DiffHunkLayout> {
- let buffer_rows = snapshot.buffer_rows(rows.start);
- let start_actual_row = match buffer_rows
- .clone()
- .take((rows.end - rows.start) as usize)
- .find_map(|b| b)
- {
- Some(start_actual_row) => start_actual_row,
- None => return Vec::new(),
- };
-
- //Get all hunks after our starting actual buffer row
- //The loop is in terms of visual buffer rows so we simply
- //return before touching any hunks past the end of the view
- let mut diff_hunks = snapshot
- .buffer_snapshot
- .git_diff_hunks_in_range(start_actual_row..u32::MAX)
- .peekable();
-
- //Some number followed by Nones for wrapped lines
- //Jump in number for folded lines
- let mut buffer_rows = buffer_rows
- .take((rows.end - rows.start) as usize)
- .enumerate()
- .peekable();
+ let start_row = DisplayPoint::new(rows.start, 0).to_point(snapshot).row;
+ let end_row = DisplayPoint::new(rows.end, 0).to_point(snapshot).row;
let mut layouts = Vec::new();
- let mut previous_buffer_row = None;
-
- while let Some((idx, buffer_row)) = buffer_rows.next() {
- let buffer_row = match buffer_row {
- Some(buffer_row) => buffer_row,
- None => continue,
- };
-
- let is_start_of_fold = previous_buffer_row
- .map(|prev| buffer_row > prev + 1)
- .unwrap_or(false);
- previous_buffer_row = Some(buffer_row);
-
- if is_start_of_fold {
- //Consume all hunks within fold
- let mut consumed_hunks = false;
- while let Some(hunk) = diff_hunks.peek() {
- let is_past = hunk.buffer_range.start > buffer_row;
- let is_removal = hunk.status() == DiffHunkStatus::Removed;
- let is_on_next_line = hunk.buffer_range.start == buffer_row + 1;
- let is_removal_inside = is_removal && is_on_next_line;
-
- if is_past && !is_removal_inside {
- break;
- }
- diff_hunks.next();
- consumed_hunks = true;
- }
-
- //And mark fold as modified if there were any
- if consumed_hunks {
- let current_visual_row = rows.start + idx as u32 - 1;
- layouts.push(DiffHunkLayout {
- visual_range: current_visual_row..current_visual_row + 1,
- status: DiffHunkStatus::Modified,
- });
- }
- } else if let Some(hunk) = diff_hunks.peek() {
- let row_inside_hunk = hunk.buffer_range.contains(&buffer_row);
- let starts_on_row = hunk.buffer_range.start == buffer_row;
- if row_inside_hunk || starts_on_row {
- let (layout, buffer_row_advancement) =
- Self::layout_diff_hunk(hunk, rows.start, &mut buffer_rows);
- previous_buffer_row = Some(buffer_row + buffer_row_advancement);
-
- if let Some(layout) = layout {
- layouts.push(layout);
- }
+ for hunk in snapshot
+ .buffer_snapshot
+ .git_diff_hunks_in_range(start_row..end_row)
+ {
+ let start = Point::new(hunk.buffer_range.start, 0).to_display_point(snapshot);
+ let end = Point::new(hunk.buffer_range.end, 0).to_display_point(snapshot);
+ let is_folded = start == end && snapshot.is_line_folded(start.row());
- diff_hunks.next();
- }
+ if let Some(hunk) = layouts.last_mut() {
+ //
}
+
+ layouts.push(DiffHunkLayout {
+ visual_range: start.row()..end.row(),
+ status: hunk.status(),
+ is_folded,
+ });
}
- layouts
+ return layouts;
+
+ //Some number followed by Nones for wrapped lines
+ //Jump in number for folded lines
+ // let mut buffer_rows = buffer_rows
+ // .take((rows.end - rows.start) as usize)
+ // .enumerate()
+ // .peekable();
+
+ // let mut layouts = Vec::new();
+ // let mut previous_buffer_row = None;
+
+ // while let Some((idx, buffer_row)) = buffer_rows.next() {
+ // let buffer_row = match buffer_row {
+ // Some(buffer_row) => buffer_row,
+ // None => continue,
+ // };
+
+ // let is_start_of_fold = previous_buffer_row
+ // .map(|prev| buffer_row > prev + 1)
+ // .unwrap_or(false);
+ // previous_buffer_row = Some(buffer_row);
+
+ // if is_start_of_fold {
+ // //Consume all hunks within fold
+ // let mut consumed_hunks = false;
+ // while let Some(hunk) = diff_hunks.peek() {
+ // let is_past = hunk.buffer_range.start > buffer_row;
+ // let is_removal = hunk.status() == DiffHunkStatus::Removed;
+ // let is_on_next_line = hunk.buffer_range.start == buffer_row + 1;
+ // let is_removal_inside = is_removal && is_on_next_line;
+
+ // if is_past && !is_removal_inside {
+ // break;
+ // }
+ // diff_hunks.next();
+ // consumed_hunks = true;
+ // }
+
+ // //And mark fold as modified if there were any
+ // if consumed_hunks {
+ // let current_visual_row = rows.start + idx as u32 - 1;
+ // layouts.push(DiffHunkLayout {
+ // visual_range: current_visual_row..current_visual_row + 1,
+ // status: DiffHunkStatus::Modified,
+ // });
+ // }
+ // } else if let Some(hunk) = diff_hunks.peek() {
+ // let row_inside_hunk = hunk.buffer_range.contains(&buffer_row);
+ // let starts_on_row = hunk.buffer_range.start == buffer_row;
+ // if row_inside_hunk || starts_on_row {
+ // let (layout, buffer_row_advancement) =
+ // Self::layout_diff_hunk(hunk, rows.start, &mut buffer_rows);
+ // previous_buffer_row = Some(buffer_row + buffer_row_advancement);
+
+ // if let Some(layout) = layout {
+ // layouts.push(layout);
+ // }
+
+ // diff_hunks.next();
+ // }
+ // }
+ // }
+
+ // layouts
}
fn layout_line_numbers(