From dde3dfdbf6a334331735d9ea2de9dd9f62f0b5c5 Mon Sep 17 00:00:00 2001 From: Julia Date: Thu, 13 Oct 2022 16:34:34 -0400 Subject: [PATCH] Quick cut of using display point conversion to layout hunks Co-Authored-By: Max Brunsfeld --- crates/editor/src/element.rs | 211 ++++++++++++++++------------------- 1 file changed, 98 insertions(+), 113 deletions(-) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 054c34515d..e6f876028a 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -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, 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, - start_row: u32, - buffer_rows: &mut std::iter::Peekable)>>, - ) -> (Option, 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, snapshot: &EditorSnapshot, ) -> Vec { - 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(), - }; + let start_row = DisplayPoint::new(rows.start, 0).to_point(snapshot).row; + let end_row = DisplayPoint::new(rows.end, 0).to_point(snapshot).row; - //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 + let mut layouts = Vec::new(); + for hunk in snapshot .buffer_snapshot - .git_diff_hunks_in_range(start_actual_row..u32::MAX) - .peekable(); + .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()); + + if let Some(hunk) = layouts.last_mut() { + // + } + + layouts.push(DiffHunkLayout { + visual_range: start.row()..end.row(), + status: hunk.status(), + is_folded, + }); + } + + 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 buffer_rows = buffer_rows + // .take((rows.end - rows.start) as usize) + // .enumerate() + // .peekable(); - let mut layouts = Vec::new(); - let mut previous_buffer_row = None; + // 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, - }; + // 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); + // 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_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; - } + // 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); + // //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); - } + // if let Some(layout) = layout { + // layouts.push(layout); + // } - diff_hunks.next(); - } - } - } + // diff_hunks.next(); + // } + // } + // } - layouts + // layouts } fn layout_line_numbers(