diff --git a/crates/git_ui/src/conflict_view.rs b/crates/git_ui/src/conflict_view.rs index c869e57f7d..b09bf10189 100644 --- a/crates/git_ui/src/conflict_view.rs +++ b/crates/git_ui/src/conflict_view.rs @@ -14,6 +14,7 @@ use ui::{ ActiveTheme, AnyElement, Element as _, StatefulInteractiveElement, Styled, StyledTypography as _, div, h_flex, rems, }; +use util::{debug_panic, maybe}; pub(crate) struct ConflictAddon { buffers: HashMap, @@ -89,12 +90,22 @@ fn excerpt_for_buffer_updated( cx: &mut Context, ) { let conflicts_len = conflict_set.read(cx).snapshot().conflicts.len(); + let buffer_id = conflict_set.read(cx).snapshot().buffer_id; + let Some(buffer_conflicts) = editor + .addon_mut::() + .unwrap() + .buffers + .get(&buffer_id) + else { + return; + }; + let addon_conflicts_len = buffer_conflicts.block_ids.len(); conflicts_updated( editor, conflict_set, &ConflictSetUpdate { buffer_range: None, - old_range: 0..conflicts_len, + old_range: 0..addon_conflicts_len, new_range: 0..conflicts_len, }, cx, @@ -174,10 +185,37 @@ fn conflicts_updated( return; }; + let old_range = maybe!({ + let conflict_addon = editor.addon_mut::().unwrap(); + let buffer_conflicts = conflict_addon.buffers.get(&buffer_id)?; + match buffer_conflicts.block_ids.get(event.old_range.clone()) { + Some(_) => Some(event.old_range.clone()), + None => { + debug_panic!( + "conflicts updated event old range is invalid for buffer conflicts view (block_ids len is {:?}, old_range is {:?})", + buffer_conflicts.block_ids.len(), + event.old_range, + ); + if event.old_range.start <= event.old_range.end { + Some( + event.old_range.start.min(buffer_conflicts.block_ids.len()) + ..event.old_range.end.min(buffer_conflicts.block_ids.len()), + ) + } else { + None + } + } + } + }); + // Remove obsolete highlights and blocks let conflict_addon = editor.addon_mut::().unwrap(); - if let Some(buffer_conflicts) = conflict_addon.buffers.get_mut(&buffer_id) { - let old_conflicts = buffer_conflicts.block_ids[event.old_range.clone()].to_owned(); + if let Some((buffer_conflicts, old_range)) = conflict_addon + .buffers + .get_mut(&buffer_id) + .zip(old_range.clone()) + { + let old_conflicts = buffer_conflicts.block_ids[old_range].to_owned(); let mut removed_highlighted_ranges = Vec::new(); let mut removed_block_ids = HashSet::default(); for (conflict_range, block_id) in old_conflicts { @@ -263,9 +301,11 @@ fn conflicts_updated( let new_block_ids = editor.insert_blocks(blocks, None, cx); let conflict_addon = editor.addon_mut::().unwrap(); - if let Some(buffer_conflicts) = conflict_addon.buffers.get_mut(&buffer_id) { + if let Some((buffer_conflicts, old_range)) = + conflict_addon.buffers.get_mut(&buffer_id).zip(old_range) + { buffer_conflicts.block_ids.splice( - event.old_range.clone(), + old_range, new_conflicts .iter() .map(|conflict| conflict.range.clone())