diff --git a/crates/acp_thread/src/acp_thread.rs b/crates/acp_thread/src/acp_thread.rs index 56e33fda47f095eef1873f7a0724b021e88a0bdc..a42eaa491f7f98e9965cd3aba801690ed996a39a 100644 --- a/crates/acp_thread/src/acp_thread.rs +++ b/crates/acp_thread/src/acp_thread.rs @@ -347,13 +347,13 @@ impl ToolCall { let buffer = buffer.await.log_err()?; let position = buffer .update(cx, |buffer, _| { + let snapshot = buffer.snapshot(); if let Some(row) = location.line { - let snapshot = buffer.snapshot(); let column = snapshot.indent_size_for_line(row).len; let point = snapshot.clip_point(Point::new(row, column), Bias::Left); snapshot.anchor_before(point) } else { - Anchor::MIN + Anchor::min_for_buffer(snapshot.remote_id()) } }) .ok()?; @@ -2120,7 +2120,7 @@ impl AcpThread { position: edits .last() .map(|(range, _)| range.end) - .unwrap_or(Anchor::MIN), + .unwrap_or(Anchor::min_for_buffer(buffer.read(cx).remote_id())), }), cx, ); diff --git a/crates/acp_thread/src/diff.rs b/crates/acp_thread/src/diff.rs index 055b2f7fb86ffe9d7f12459b6b16405ce77815a0..f17e9d0fce404483ae99efc95bf666586c1f644b 100644 --- a/crates/acp_thread/src/diff.rs +++ b/crates/acp_thread/src/diff.rs @@ -50,9 +50,14 @@ impl Diff { let hunk_ranges = { let buffer = buffer.read(cx); let diff = diff.read(cx); - diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, buffer, cx) - .map(|diff_hunk| diff_hunk.buffer_range.to_point(buffer)) - .collect::>() + diff.hunks_intersecting_range( + Anchor::min_for_buffer(buffer.remote_id()) + ..Anchor::max_for_buffer(buffer.remote_id()), + buffer, + cx, + ) + .map(|diff_hunk| diff_hunk.buffer_range.to_point(buffer)) + .collect::>() }; multibuffer.set_excerpts_for_path( @@ -316,7 +321,12 @@ impl PendingDiff { let buffer = self.new_buffer.read(cx); let diff = self.diff.read(cx); let mut ranges = diff - .hunks_intersecting_range(Anchor::MIN..Anchor::MAX, buffer, cx) + .hunks_intersecting_range( + Anchor::min_for_buffer(buffer.remote_id()) + ..Anchor::max_for_buffer(buffer.remote_id()), + buffer, + cx, + ) .map(|diff_hunk| diff_hunk.buffer_range.to_point(buffer)) .collect::>(); ranges.extend( diff --git a/crates/action_log/src/action_log.rs b/crates/action_log/src/action_log.rs index 78265007a5abe3e724166610013ade776d82dbeb..80c9438bc9f8051cb58357e56a82b5307fd20b75 100644 --- a/crates/action_log/src/action_log.rs +++ b/crates/action_log/src/action_log.rs @@ -409,9 +409,11 @@ impl ActionLog { let new_diff_base = new_diff_base.clone(); async move { let mut unreviewed_edits = Patch::default(); - for hunk in diff_snapshot - .hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &buffer_snapshot) - { + for hunk in diff_snapshot.hunks_intersecting_range( + Anchor::min_for_buffer(buffer_snapshot.remote_id()) + ..Anchor::max_for_buffer(buffer_snapshot.remote_id()), + &buffer_snapshot, + ) { let old_range = new_diff_base .offset_to_point(hunk.diff_base_byte_range.start) ..new_diff_base.offset_to_point(hunk.diff_base_byte_range.end); @@ -732,12 +734,10 @@ impl ActionLog { cx: &mut Context, ) -> Task<()> { let futures = self.changed_buffers(cx).into_keys().map(|buffer| { - let reject = self.reject_edits_in_ranges( - buffer, - vec![Anchor::MIN..Anchor::MAX], - telemetry.clone(), - cx, - ); + let buffer_ranges = vec![Anchor::min_max_range_for_buffer( + buffer.read(cx).remote_id(), + )]; + let reject = self.reject_edits_in_ranges(buffer, buffer_ranges, telemetry.clone(), cx); async move { reject.await.log_err(); @@ -2010,7 +2010,8 @@ mod tests { // User accepts the single hunk action_log.update(cx, |log, cx| { - log.keep_edits_in_range(buffer.clone(), Anchor::MIN..Anchor::MAX, None, cx) + let buffer_range = Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()); + log.keep_edits_in_range(buffer.clone(), buffer_range, None, cx) }); cx.run_until_parked(); assert_eq!(unreviewed_hunks(&action_log, cx), vec![]); @@ -2031,7 +2032,14 @@ mod tests { // User rejects the hunk action_log .update(cx, |log, cx| { - log.reject_edits_in_ranges(buffer.clone(), vec![Anchor::MIN..Anchor::MAX], None, cx) + log.reject_edits_in_ranges( + buffer.clone(), + vec![Anchor::min_max_range_for_buffer( + buffer.read(cx).remote_id(), + )], + None, + cx, + ) }) .await .unwrap(); diff --git a/crates/agent/src/edit_agent.rs b/crates/agent/src/edit_agent.rs index e5b1d1e3871ecb0070f60f5f382196482e24963a..5ea04729a49afae944c5e7ca88ad67791e18b6f3 100644 --- a/crates/agent/src/edit_agent.rs +++ b/crates/agent/src/edit_agent.rs @@ -172,14 +172,14 @@ impl EditAgent { project.set_agent_location( Some(AgentLocation { buffer: buffer.downgrade(), - position: language::Anchor::MAX, + position: language::Anchor::max_for_buffer(buffer.read(cx).remote_id()), }), cx, ) }); output_events_tx .unbounded_send(EditAgentOutputEvent::Edited( - language::Anchor::MIN..language::Anchor::MAX, + Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()), )) .ok(); })?; @@ -187,7 +187,7 @@ impl EditAgent { while let Some(event) = parse_rx.next().await { match event? { CreateFileParserEvent::NewTextChunk { chunk } => { - cx.update(|cx| { + let buffer_id = cx.update(|cx| { buffer.update(cx, |buffer, cx| buffer.append(chunk, cx)); self.action_log .update(cx, |log, cx| log.buffer_edited(buffer.clone(), cx)); @@ -195,15 +195,18 @@ impl EditAgent { project.set_agent_location( Some(AgentLocation { buffer: buffer.downgrade(), - position: language::Anchor::MAX, + position: language::Anchor::max_for_buffer( + buffer.read(cx).remote_id(), + ), }), cx, ) }); + buffer.read(cx).remote_id() })?; output_events_tx .unbounded_send(EditAgentOutputEvent::Edited( - language::Anchor::MIN..language::Anchor::MAX, + Anchor::min_max_range_for_buffer(buffer_id), )) .ok(); } @@ -1200,7 +1203,9 @@ mod tests { project.read_with(cx, |project, _| project.agent_location()), Some(AgentLocation { buffer: buffer.downgrade(), - position: language::Anchor::MAX + position: language::Anchor::max_for_buffer( + cx.update(|cx| buffer.read(cx).remote_id()) + ), }) ); @@ -1218,7 +1223,9 @@ mod tests { project.read_with(cx, |project, _| project.agent_location()), Some(AgentLocation { buffer: buffer.downgrade(), - position: language::Anchor::MAX + position: language::Anchor::max_for_buffer( + cx.update(|cx| buffer.read(cx).remote_id()) + ), }) ); @@ -1236,7 +1243,9 @@ mod tests { project.read_with(cx, |project, _| project.agent_location()), Some(AgentLocation { buffer: buffer.downgrade(), - position: language::Anchor::MAX + position: language::Anchor::max_for_buffer( + cx.update(|cx| buffer.read(cx).remote_id()) + ), }) ); @@ -1254,7 +1263,9 @@ mod tests { project.read_with(cx, |project, _| project.agent_location()), Some(AgentLocation { buffer: buffer.downgrade(), - position: language::Anchor::MAX + position: language::Anchor::max_for_buffer( + cx.update(|cx| buffer.read(cx).remote_id()) + ), }) ); @@ -1269,7 +1280,9 @@ mod tests { project.read_with(cx, |project, _| project.agent_location()), Some(AgentLocation { buffer: buffer.downgrade(), - position: language::Anchor::MAX + position: language::Anchor::max_for_buffer( + cx.update(|cx| buffer.read(cx).remote_id()) + ), }) ); } diff --git a/crates/agent/src/tools/read_file_tool.rs b/crates/agent/src/tools/read_file_tool.rs index eccb40737c744d57792655cadb925e18a68d2835..77852c5fda674c55b324af8bae90d7d6a57bcff0 100644 --- a/crates/agent/src/tools/read_file_tool.rs +++ b/crates/agent/src/tools/read_file_tool.rs @@ -275,7 +275,9 @@ impl AgentTool for ReadFileTool { project.set_agent_location( Some(AgentLocation { buffer: buffer.downgrade(), - position: anchor.unwrap_or(text::Anchor::MIN), + position: anchor.unwrap_or_else(|| { + text::Anchor::min_for_buffer(buffer.read(cx).remote_id()) + }), }), cx, ); diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index fd0b1eedbdf80d1893760e6182cd2e57d96ef010..1c9e3f83e383658051f7799a7e3096f532addbe1 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -4103,7 +4103,9 @@ impl AcpThreadView { action_log .reject_edits_in_ranges( buffer.clone(), - vec![Anchor::MIN..Anchor::MAX], + vec![Anchor::min_max_range_for_buffer( + buffer.read(cx).remote_id(), + )], Some(telemetry.clone()), cx, ) @@ -4124,7 +4126,9 @@ impl AcpThreadView { action_log.update(cx, |action_log, cx| { action_log.keep_edits_in_range( buffer.clone(), - Anchor::MIN..Anchor::MAX, + Anchor::min_max_range_for_buffer( + buffer.read(cx).remote_id(), + ), Some(telemetry.clone()), cx, ); @@ -4743,11 +4747,8 @@ impl AcpThreadView { let buffer = multibuffer.as_singleton(); if agent_location.buffer.upgrade() == buffer { let excerpt_id = multibuffer.excerpt_ids().first().cloned(); - let anchor = editor::Anchor::in_buffer( - excerpt_id.unwrap(), - buffer.unwrap().read(cx).remote_id(), - agent_location.position, - ); + let anchor = + editor::Anchor::in_buffer(excerpt_id.unwrap(), agent_location.position); editor.change_selections(Default::default(), window, cx, |selections| { selections.select_anchor_ranges([anchor..anchor]); }) diff --git a/crates/agent_ui/src/agent_diff.rs b/crates/agent_ui/src/agent_diff.rs index 53e7a2f46d37e4cd2f0688d5af2a7d4a01174801..8aece1984ad597e629cd966c0e61d6a5681d7020 100644 --- a/crates/agent_ui/src/agent_diff.rs +++ b/crates/agent_ui/src/agent_diff.rs @@ -145,7 +145,7 @@ impl AgentDiffPane { let diff_hunk_ranges = diff .hunks_intersecting_range( - language::Anchor::MIN..language::Anchor::MAX, + language::Anchor::min_max_range_for_buffer(snapshot.remote_id()), &snapshot, cx, ) diff --git a/crates/agent_ui/src/inline_assistant.rs b/crates/agent_ui/src/inline_assistant.rs index 81242135757561a6c829cc9cabf8893294d9e875..0f617044546f186bddb2be5de3983edf9dad2e0c 100644 --- a/crates/agent_ui/src/inline_assistant.rs +++ b/crates/agent_ui/src/inline_assistant.rs @@ -440,7 +440,6 @@ impl InlineAssistant { { let anchor_range = Anchor::range_in_buffer( excerpt_id, - buffer.remote_id(), buffer.anchor_before(buffer_range.start)..buffer.anchor_after(buffer_range.end), ); diff --git a/crates/assistant_text_thread/src/text_thread.rs b/crates/assistant_text_thread/src/text_thread.rs index 2bc4ceec4c243a654abf04b19b4e2ba93a1fef4f..613c9b862e8a0b055465a73fe34c541ecb18d4a1 100644 --- a/crates/assistant_text_thread/src/text_thread.rs +++ b/crates/assistant_text_thread/src/text_thread.rs @@ -797,7 +797,7 @@ impl TextThread { }); let message = MessageAnchor { id: first_message_id, - start: language::Anchor::MIN, + start: language::Anchor::min_for_buffer(this.buffer.read(cx).remote_id()), }; this.messages_metadata.insert( first_message_id, @@ -1147,12 +1147,10 @@ impl TextThread { cx: &App, ) -> bool { let version = &self.buffer.read(cx).version; - let observed_start = range.start == language::Anchor::MIN - || range.start == language::Anchor::MAX - || version.observed(range.start.timestamp); - let observed_end = range.end == language::Anchor::MIN - || range.end == language::Anchor::MAX - || version.observed(range.end.timestamp); + let observed_start = + range.start.is_min() || range.start.is_max() || version.observed(range.start.timestamp); + let observed_end = + range.end.is_min() || range.end.is_max() || version.observed(range.end.timestamp); observed_start && observed_end } @@ -2858,7 +2856,8 @@ impl TextThread { messages.next(); } } - let message_end_anchor = message_end.unwrap_or(language::Anchor::MAX); + let message_end_anchor = + message_end.unwrap_or(language::Anchor::max_for_buffer(buffer.remote_id())); let message_end = message_end_anchor.to_offset(buffer); return Some(Message { diff --git a/crates/buffer_diff/src/buffer_diff.rs b/crates/buffer_diff/src/buffer_diff.rs index 52c6463b9bcccd242ef18e5f3dcb518bd335686d..38b9b8e4baa1d0789bf64ae53f28bc28bfe6bd98 100644 --- a/crates/buffer_diff/src/buffer_diff.rs +++ b/crates/buffer_diff/src/buffer_diff.rs @@ -153,6 +153,10 @@ impl std::fmt::Debug for BufferDiffInner { } impl BufferDiffSnapshot { + pub fn buffer_diff_id(&self) -> BufferId { + self.inner.base_text.remote_id() + } + fn empty(buffer: &text::BufferSnapshot, cx: &mut App) -> BufferDiffSnapshot { BufferDiffSnapshot { inner: BufferDiffInner { @@ -340,7 +344,7 @@ impl BufferDiffInner { }; let hunk = PendingHunk { - buffer_range: Anchor::MIN..Anchor::MAX, + buffer_range: Anchor::min_max_range_for_buffer(buffer.remote_id()), diff_base_byte_range: 0..index_text.map_or(0, |rope| rope.len()), buffer_version: buffer.version().clone(), new_status, @@ -780,7 +784,7 @@ fn compute_hunks( } else { tree.push( InternalDiffHunk { - buffer_range: Anchor::MIN..Anchor::MAX, + buffer_range: Anchor::min_max_range_for_buffer(buffer.remote_id()), diff_base_byte_range: 0..0, }, &buffer, @@ -941,10 +945,10 @@ impl BufferDiff { pub fn clear_pending_hunks(&mut self, cx: &mut Context) { if self.secondary_diff.is_some() { self.inner.pending_hunks = SumTree::from_summary(DiffHunkSummary { - buffer_range: Anchor::MIN..Anchor::MIN, + buffer_range: Anchor::min_min_range_for_buffer(self.buffer_id), }); cx.emit(BufferDiffEvent::DiffChanged { - changed_range: Some(Anchor::MIN..Anchor::MAX), + changed_range: Some(Anchor::min_max_range_for_buffer(self.buffer_id)), }); } } @@ -1065,7 +1069,10 @@ impl BufferDiff { { (false, new_state.compare(state, buffer)) } - _ => (true, Some(text::Anchor::MIN..text::Anchor::MAX)), + _ => ( + true, + Some(text::Anchor::min_max_range_for_buffer(self.buffer_id)), + ), }; if let Some(secondary_changed_range) = secondary_diff_change @@ -1126,7 +1133,11 @@ impl BufferDiff { buffer_snapshot: &'a text::BufferSnapshot, cx: &'a App, ) -> impl 'a + Iterator { - self.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, buffer_snapshot, cx) + self.hunks_intersecting_range( + Anchor::min_max_range_for_buffer(buffer_snapshot.remote_id()), + buffer_snapshot, + cx, + ) } pub fn hunks_intersecting_range<'a>( @@ -1222,7 +1233,9 @@ impl BufferDiff { impl DiffHunk { pub fn is_created_file(&self) -> bool { - self.diff_base_byte_range == (0..0) && self.buffer_range == (Anchor::MIN..Anchor::MAX) + self.diff_base_byte_range == (0..0) + && self.buffer_range.start.is_min() + && self.buffer_range.end.is_min() } pub fn status(&self) -> DiffHunkStatus { @@ -1389,7 +1402,10 @@ mod tests { let mut buffer = Buffer::new(ReplicaId::LOCAL, BufferId::new(1).unwrap(), buffer_text); let mut diff = BufferDiffSnapshot::new_sync(buffer.clone(), diff_base.clone(), cx); assert_hunks( - diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &buffer), + diff.hunks_intersecting_range( + Anchor::min_max_range_for_buffer(buffer.remote_id()), + &buffer, + ), &buffer, &diff_base, &[(1..2, "two\n", "HELLO\n", DiffHunkStatus::modified_none())], @@ -1398,7 +1414,10 @@ mod tests { buffer.edit([(0..0, "point five\n")]); diff = BufferDiffSnapshot::new_sync(buffer.clone(), diff_base.clone(), cx); assert_hunks( - diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &buffer), + diff.hunks_intersecting_range( + Anchor::min_max_range_for_buffer(buffer.remote_id()), + &buffer, + ), &buffer, &diff_base, &[ @@ -1409,7 +1428,10 @@ mod tests { diff = cx.update(|cx| BufferDiffSnapshot::empty(&buffer, cx)); assert_hunks::<&str, _>( - diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &buffer), + diff.hunks_intersecting_range( + Anchor::min_max_range_for_buffer(buffer.remote_id()), + &buffer, + ), &buffer, &diff_base, &[], @@ -1483,7 +1505,10 @@ mod tests { ]; assert_hunks( - uncommitted_diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &buffer), + uncommitted_diff.hunks_intersecting_range( + Anchor::min_max_range_for_buffer(buffer.remote_id()), + &buffer, + ), &buffer, &head_text, &expected_hunks, @@ -1542,8 +1567,11 @@ mod tests { }) .await; assert_eq!( - diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &buffer) - .count(), + diff.hunks_intersecting_range( + Anchor::min_max_range_for_buffer(buffer.remote_id()), + &buffer + ) + .count(), 8 ); @@ -2155,8 +2183,12 @@ mod tests { let mut diff = uncommitted_diff(&working_copy, &index_text, head_text.clone(), cx); let mut hunks = diff.update(cx, |diff, cx| { - diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &working_copy, cx) - .collect::>() + diff.hunks_intersecting_range( + Anchor::min_max_range_for_buffer(diff.buffer_id), + &working_copy, + cx, + ) + .collect::>() }); if hunks.is_empty() { return; @@ -2185,8 +2217,12 @@ mod tests { diff = uncommitted_diff(&working_copy, &index_text, head_text.clone(), cx); let found_hunks = diff.update(cx, |diff, cx| { - diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &working_copy, cx) - .collect::>() + diff.hunks_intersecting_range( + Anchor::min_max_range_for_buffer(diff.buffer_id), + &working_copy, + cx, + ) + .collect::>() }); assert_eq!(hunks.len(), found_hunks.len()); diff --git a/crates/collab/src/tests/editor_tests.rs b/crates/collab/src/tests/editor_tests.rs index fe20ab935c9fb2ffd2c18962953f9d62ca06fb16..e5d3661aaf1aa0c74a4204e0989018121f5eb64a 100644 --- a/crates/collab/src/tests/editor_tests.rs +++ b/crates/collab/src/tests/editor_tests.rs @@ -1581,7 +1581,10 @@ async fn test_share_project( buffer_a.read_with(cx_a, |buffer, _| { buffer .snapshot() - .selections_in_range(text::Anchor::MIN..text::Anchor::MAX, false) + .selections_in_range( + text::Anchor::min_max_range_for_buffer(buffer.remote_id()), + false, + ) .count() == 1 }); @@ -1622,7 +1625,10 @@ async fn test_share_project( buffer_a.read_with(cx_a, |buffer, _| { buffer .snapshot() - .selections_in_range(text::Anchor::MIN..text::Anchor::MAX, false) + .selections_in_range( + text::Anchor::min_max_range_for_buffer(buffer.remote_id()), + false, + ) .count() == 0 }); diff --git a/crates/diagnostics/src/diagnostic_renderer.rs b/crates/diagnostics/src/diagnostic_renderer.rs index 2636b1aadc9708ff6832a5baa212277672dd305f..72ad7b591413832183bb85d58d188e692d46ffad 100644 --- a/crates/diagnostics/src/diagnostic_renderer.rs +++ b/crates/diagnostics/src/diagnostic_renderer.rs @@ -284,7 +284,7 @@ impl DiagnosticBlock { if range.context.overlaps(&diagnostic.range, &snapshot) { Self::jump_to( editor, - Anchor::range_in_buffer(excerpt_id, buffer_id, diagnostic.range), + Anchor::range_in_buffer(excerpt_id, diagnostic.range), window, cx, ); diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index b24a63b830b93cdbe14e2329abe524f6523cbbd6..413b73d1b6f679fa464d378760e37c773e1583e7 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -308,7 +308,7 @@ impl ProjectDiagnosticsEditor { .selections .all_anchors(&snapshot) .iter() - .filter_map(|anchor| anchor.start.buffer_id) + .filter_map(|anchor| anchor.start.text_anchor.buffer_id) .collect::>() }); for buffer_id in buffer_ids { diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index b55c5330dd398428c549ae1932c1f0a25c8e1436..58dea4010caaec98cdc14c9dc0e2b02af8ef1712 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -2976,7 +2976,7 @@ mod tests { ); } - #[gpui::test(iterations = 100)] + #[gpui::test(iterations = 60)] fn test_random_blocks(cx: &mut gpui::TestAppContext, mut rng: StdRng) { cx.update(init_test); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 08627f1bd64be6e62581014628c57306df43623e..cd7a872f8c129c3b67b544ed2ba78d7fde104b48 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1780,7 +1780,7 @@ impl Editor { let start_row = (multi_buffer_visible_start.row).min(max_row); let end_row = (multi_buffer_visible_start.row + 10).min(max_row); - if let Some((excerpt_id, buffer_id, buffer)) = multi_buffer.read(cx).as_singleton() { + if let Some((excerpt_id, _, buffer)) = multi_buffer.read(cx).as_singleton() { let outline_items = buffer .outline_items_containing( Point::new(start_row, 0)..Point::new(end_row, 0), @@ -1790,10 +1790,9 @@ impl Editor { .into_iter() .map(|outline_item| OutlineItem { depth: outline_item.depth, - range: Anchor::range_in_buffer(*excerpt_id, buffer_id, outline_item.range), + range: Anchor::range_in_buffer(*excerpt_id, outline_item.range), source_range_for_text: Anchor::range_in_buffer( *excerpt_id, - buffer_id, outline_item.source_range_for_text, ), text: outline_item.text, @@ -1801,10 +1800,10 @@ impl Editor { name_ranges: outline_item.name_ranges, body_range: outline_item .body_range - .map(|range| Anchor::range_in_buffer(*excerpt_id, buffer_id, range)), + .map(|range| Anchor::range_in_buffer(*excerpt_id, range)), annotation_range: outline_item .annotation_range - .map(|range| Anchor::range_in_buffer(*excerpt_id, buffer_id, range)), + .map(|range| Anchor::range_in_buffer(*excerpt_id, range)), }); return Some(outline_items.collect()); } @@ -3259,7 +3258,7 @@ impl Editor { } if local { - if let Some(buffer_id) = new_cursor_position.buffer_id { + if let Some(buffer_id) = new_cursor_position.text_anchor.buffer_id { self.register_buffer(buffer_id, cx); } @@ -4198,8 +4197,8 @@ impl Editor { continue; } if self.selections.disjoint_anchor_ranges().any(|s| { - if s.start.buffer_id != selection.start.buffer_id - || s.end.buffer_id != selection.end.buffer_id + if s.start.text_anchor.buffer_id != selection.start.buffer_id + || s.end.text_anchor.buffer_id != selection.end.buffer_id { return false; } @@ -5484,6 +5483,7 @@ impl Editor { } let buffer_position = multibuffer_snapshot.anchor_before(position); let Some(buffer) = buffer_position + .text_anchor .buffer_id .and_then(|buffer_id| self.buffer.read(cx).buffer(buffer_id)) else { @@ -6923,8 +6923,7 @@ impl Editor { continue; } - let range = - Anchor::range_in_buffer(excerpt_id, buffer_id, *start..*end); + let range = Anchor::range_in_buffer(excerpt_id, *start..*end); if highlight.kind == lsp::DocumentHighlightKind::WRITE { write_ranges.push(range); } else { @@ -7033,11 +7032,8 @@ impl Editor { .anchor_after(search_range.start + match_range.start); let match_end = buffer_snapshot .anchor_before(search_range.start + match_range.end); - let match_anchor_range = Anchor::range_in_buffer( - excerpt_id, - buffer_snapshot.remote_id(), - match_start..match_end, - ); + let match_anchor_range = + Anchor::range_in_buffer(excerpt_id, match_start..match_end); (match_anchor_range != query_range).then_some(match_anchor_range) }), ); @@ -8212,8 +8208,7 @@ impl Editor { cx, ); for (breakpoint, state) in breakpoints { - let multi_buffer_anchor = - Anchor::in_buffer(excerpt_id, buffer_snapshot.remote_id(), breakpoint.position); + let multi_buffer_anchor = Anchor::in_buffer(excerpt_id, breakpoint.position); let position = multi_buffer_anchor .to_point(&multi_buffer_snapshot) .to_display_point(&snapshot); @@ -20804,8 +20799,7 @@ impl Editor { let start = highlight.range.start.to_display_point(&snapshot); let end = highlight.range.end.to_display_point(&snapshot); let start_row = start.row().0; - let end_row = if highlight.range.end.text_anchor != text::Anchor::MAX - && end.column() == 0 + let end_row = if !highlight.range.end.text_anchor.is_max() && end.column() == 0 { end.row().0.saturating_sub(1) } else { @@ -21361,7 +21355,7 @@ impl Editor { .for_each(|hint| { let inlay = Inlay::debugger( post_inc(&mut editor.next_inlay_id), - Anchor::in_buffer(excerpt_id, buffer_id, hint.position), + Anchor::in_buffer(excerpt_id, hint.position), hint.text(), ); if !inlay.text().chars().contains(&'\n') { @@ -24105,7 +24099,6 @@ impl EditorSnapshot { display_row_range: hunk_display_start.row()..end_row, multi_buffer_range: Anchor::range_in_buffer( hunk.excerpt_id, - hunk.buffer_id, hunk.buffer_range, ), is_created_file, diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 119c7058e061406b4a75017b6c5c8717f9f250c0..f68b15b6b258a5ab730a13af9d7ecc62763321ea 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -21550,10 +21550,9 @@ async fn test_adjacent_diff_hunks(executor: BackgroundExecutor, cx: &mut TestApp .diff_hunks_in_ranges(&[Anchor::min()..Anchor::max()], &snapshot.buffer_snapshot()) .collect::>(); let excerpt_id = editor.buffer.read(cx).excerpt_ids()[0]; - let buffer_id = hunks[0].buffer_id; hunks .into_iter() - .map(|hunk| Anchor::range_in_buffer(excerpt_id, buffer_id, hunk.buffer_range)) + .map(|hunk| Anchor::range_in_buffer(excerpt_id, hunk.buffer_range)) .collect::>() }); assert_eq!(hunk_ranges.len(), 2); @@ -21641,10 +21640,9 @@ async fn test_adjacent_diff_hunks(executor: BackgroundExecutor, cx: &mut TestApp .diff_hunks_in_ranges(&[Anchor::min()..Anchor::max()], &snapshot.buffer_snapshot()) .collect::>(); let excerpt_id = editor.buffer.read(cx).excerpt_ids()[0]; - let buffer_id = hunks[0].buffer_id; hunks .into_iter() - .map(|hunk| Anchor::range_in_buffer(excerpt_id, buffer_id, hunk.buffer_range)) + .map(|hunk| Anchor::range_in_buffer(excerpt_id, hunk.buffer_range)) .collect::>() }); assert_eq!(hunk_ranges.len(), 2); @@ -21707,10 +21705,9 @@ async fn test_toggle_deletion_hunk_at_start_of_file( .diff_hunks_in_ranges(&[Anchor::min()..Anchor::max()], &snapshot.buffer_snapshot()) .collect::>(); let excerpt_id = editor.buffer.read(cx).excerpt_ids()[0]; - let buffer_id = hunks[0].buffer_id; hunks .into_iter() - .map(|hunk| Anchor::range_in_buffer(excerpt_id, buffer_id, hunk.buffer_range)) + .map(|hunk| Anchor::range_in_buffer(excerpt_id, hunk.buffer_range)) .collect::>() }); assert_eq!(hunk_ranges.len(), 1); diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 71c76c0cb3eba0e70da140191ab5eb8daa5735bc..4ea12f0a21295d97cdcff565c484750e14334223 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -9283,7 +9283,7 @@ impl Element for EditorElement { HashMap::default(); for selection in all_anchor_selections.iter() { let head = selection.head(); - if let Some(buffer_id) = head.buffer_id { + if let Some(buffer_id) = head.text_anchor.buffer_id { anchors_by_buffer .entry(buffer_id) .and_modify(|(latest_id, latest_anchor)| { diff --git a/crates/editor/src/inlays/inlay_hints.rs b/crates/editor/src/inlays/inlay_hints.rs index cd9456be7a109ce5c2535339bc153bb5434ab94f..4379276707ceacd07935d660d54ac3b52216a720 100644 --- a/crates/editor/src/inlays/inlay_hints.rs +++ b/crates/editor/src/inlays/inlay_hints.rs @@ -584,8 +584,11 @@ impl Editor { }) .max_by_key(|hint| hint.id) { - if let Some(ResolvedHint::Resolved(cached_hint)) = - hovered_hint.position.buffer_id.and_then(|buffer_id| { + if let Some(ResolvedHint::Resolved(cached_hint)) = hovered_hint + .position + .text_anchor + .buffer_id + .and_then(|buffer_id| { lsp_store.update(cx, |lsp_store, cx| { lsp_store.resolved_hint(buffer_id, hovered_hint.id, cx) }) @@ -757,7 +760,7 @@ impl Editor { let visible_inlay_hint_ids = self .visible_inlay_hints(cx) .iter() - .filter(|inlay| inlay.position.buffer_id == Some(buffer_id)) + .filter(|inlay| inlay.position.text_anchor.buffer_id == Some(buffer_id)) .map(|inlay| inlay.id) .collect::>(); let Some(inlay_hints) = &mut self.inlay_hints else { @@ -858,9 +861,13 @@ impl Editor { self.visible_inlay_hints(cx) .iter() .filter(|inlay| { - inlay.position.buffer_id.is_none_or(|buffer_id| { - invalidate_hints_for_buffers.contains(&buffer_id) - }) + inlay + .position + .text_anchor + .buffer_id + .is_none_or(|buffer_id| { + invalidate_hints_for_buffers.contains(&buffer_id) + }) }) .map(|inlay| inlay.id), ); diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 157ad84d053b9125dfd59243098deb680be7b264..7e82336b4403cc8142983ef3802a9cdb9ca9cf2b 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -455,21 +455,13 @@ async fn update_editor_from_message( })??; // Deserialize the editor state. - let (selections, pending_selection, scroll_top_anchor) = this.update(cx, |editor, cx| { - let buffer = editor.buffer.read(cx).read(cx); - let selections = message - .selections - .into_iter() - .filter_map(|selection| deserialize_selection(&buffer, selection)) - .collect::>(); - let pending_selection = message - .pending_selection - .and_then(|selection| deserialize_selection(&buffer, selection)); - let scroll_top_anchor = message - .scroll_top_anchor - .and_then(|anchor| deserialize_anchor(&buffer, anchor)); - anyhow::Ok((selections, pending_selection, scroll_top_anchor)) - })??; + let selections = message + .selections + .into_iter() + .filter_map(deserialize_selection) + .collect::>(); + let pending_selection = message.pending_selection.and_then(deserialize_selection); + let scroll_top_anchor = message.scroll_top_anchor.and_then(deserialize_anchor); // Wait until the buffer has received all of the operations referenced by // the editor's new state. @@ -563,24 +555,20 @@ fn deserialize_excerpt_range( )) } -fn deserialize_selection( - buffer: &MultiBufferSnapshot, - selection: proto::Selection, -) -> Option> { +fn deserialize_selection(selection: proto::Selection) -> Option> { Some(Selection { id: selection.id as usize, - start: deserialize_anchor(buffer, selection.start?)?, - end: deserialize_anchor(buffer, selection.end?)?, + start: deserialize_anchor(selection.start?)?, + end: deserialize_anchor(selection.end?)?, reversed: selection.reversed, goal: SelectionGoal::None, }) } -fn deserialize_anchor(buffer: &MultiBufferSnapshot, anchor: proto::EditorAnchor) -> Option { +fn deserialize_anchor(anchor: proto::EditorAnchor) -> Option { let excerpt_id = ExcerptId::from_proto(anchor.excerpt_id); Some(Anchor::in_buffer( excerpt_id, - buffer.buffer_id_for_excerpt(excerpt_id)?, language::proto::deserialize_anchor(anchor.anchor?)?, )) } @@ -1374,7 +1362,7 @@ impl ProjectItem for Editor { cx: &mut Context, ) -> Self { let mut editor = Self::for_buffer(buffer.clone(), Some(project), window, cx); - if let Some((excerpt_id, buffer_id, snapshot)) = + if let Some((excerpt_id, _, snapshot)) = editor.buffer().read(cx).snapshot(cx).as_singleton() && WorkspaceSettings::get(None, cx).restore_on_file_reopen && let Some(restoration_data) = Self::project_item_kind() @@ -1397,11 +1385,8 @@ impl ProjectItem for Editor { }); } let (top_row, offset) = restoration_data.scroll_position; - let anchor = Anchor::in_buffer( - *excerpt_id, - buffer_id, - snapshot.anchor_before(Point::new(top_row, 0)), - ); + let anchor = + Anchor::in_buffer(*excerpt_id, snapshot.anchor_before(Point::new(top_row, 0))); editor.set_scroll_anchor(ScrollAnchor { anchor, offset }, window, cx); } @@ -1783,11 +1768,7 @@ impl SearchableItem for Editor { .anchor_after(search_range.start + match_range.start); let end = search_buffer .anchor_before(search_range.start + match_range.end); - Anchor::range_in_buffer( - excerpt_id, - search_buffer.remote_id(), - start..end, - ) + Anchor::range_in_buffer(excerpt_id, start..end) } }), ); diff --git a/crates/editor/src/linked_editing_ranges.rs b/crates/editor/src/linked_editing_ranges.rs index 33635a2ae2009031220ab0a58e99f8b07957de94..ff3096961d646a2a98458319d927a4e2723d0602 100644 --- a/crates/editor/src/linked_editing_ranges.rs +++ b/crates/editor/src/linked_editing_ranges.rs @@ -70,8 +70,8 @@ pub(super) fn refresh_linked_ranges( let cursor_position = selection.head(); let start_position = snapshot.anchor_before(cursor_position); let end_position = snapshot.anchor_after(selection.tail()); - if start_position.buffer_id != end_position.buffer_id - || end_position.buffer_id.is_none() + if start_position.text_anchor.buffer_id != end_position.text_anchor.buffer_id + || end_position.text_anchor.buffer_id.is_none() { // Throw away selections spanning multiple buffers. continue; diff --git a/crates/editor/src/lsp_ext.rs b/crates/editor/src/lsp_ext.rs index 36353e8d42527cd59043ab3cf2b6105c534412d9..37cc734ab1ef0a0b677b3e405ff70b461d349a1c 100644 --- a/crates/editor/src/lsp_ext.rs +++ b/crates/editor/src/lsp_ext.rs @@ -37,7 +37,7 @@ where .selections .disjoint_anchors_arc() .iter() - .filter_map(|selection| Some((selection.head(), selection.head().buffer_id?))) + .filter_map(|selection| Some((selection.head(), selection.head().text_anchor.buffer_id?))) .unique_by(|(_, buffer_id)| *buffer_id) .find_map(|(trigger_anchor, buffer_id)| { let buffer = editor.buffer().read(cx).buffer(buffer_id)?; diff --git a/crates/editor/src/rust_analyzer_ext.rs b/crates/editor/src/rust_analyzer_ext.rs index ffa0c017c0eb157df776cc49e0dba51e617e3379..f548db75ad5d8cfe32a59a798b6d23931c34f215 100644 --- a/crates/editor/src/rust_analyzer_ext.rs +++ b/crates/editor/src/rust_analyzer_ext.rs @@ -322,7 +322,11 @@ fn cancel_flycheck_action( .disjoint_anchors_arc() .iter() .find_map(|selection| { - let buffer_id = selection.start.buffer_id.or(selection.end.buffer_id)?; + let buffer_id = selection + .start + .text_anchor + .buffer_id + .or(selection.end.text_anchor.buffer_id)?; let project = project.read(cx); let entry_id = project .buffer_for_id(buffer_id, cx)? @@ -347,7 +351,11 @@ fn run_flycheck_action( .disjoint_anchors_arc() .iter() .find_map(|selection| { - let buffer_id = selection.start.buffer_id.or(selection.end.buffer_id)?; + let buffer_id = selection + .start + .text_anchor + .buffer_id + .or(selection.end.text_anchor.buffer_id)?; let project = project.read(cx); let entry_id = project .buffer_for_id(buffer_id, cx)? @@ -372,7 +380,11 @@ fn clear_flycheck_action( .disjoint_anchors_arc() .iter() .find_map(|selection| { - let buffer_id = selection.start.buffer_id.or(selection.end.buffer_id)?; + let buffer_id = selection + .start + .text_anchor + .buffer_id + .or(selection.end.text_anchor.buffer_id)?; let project = project.read(cx); let entry_id = project .buffer_for_id(buffer_id, cx)? diff --git a/crates/editor/src/test/editor_test_context.rs b/crates/editor/src/test/editor_test_context.rs index 5793bcf576c7ed0e1604c30aada0fb362f65bb9f..cd45a6ec47ad7631404189194a6a0291a6240647 100644 --- a/crates/editor/src/test/editor_test_context.rs +++ b/crates/editor/src/test/editor_test_context.rs @@ -490,11 +490,7 @@ impl EditorTestContext { ); assert_eq!( multibuffer_snapshot - .text_for_range(Anchor::range_in_buffer( - excerpt_id, - snapshot.remote_id(), - range.context.clone() - )) + .text_for_range(Anchor::range_in_buffer(excerpt_id, range.context.clone())) .collect::(), expected_text, "{}", @@ -675,11 +671,7 @@ impl std::fmt::Display for FormatMultiBufferAsMarkedText { } let mut text = multibuffer_snapshot - .text_for_range(Anchor::range_in_buffer( - *excerpt_id, - snapshot.remote_id(), - range.context.clone(), - )) + .text_for_range(Anchor::range_in_buffer(*excerpt_id, range.context.clone())) .collect::(); let selections = selections diff --git a/crates/git_ui/src/commit_view.rs b/crates/git_ui/src/commit_view.rs index 3251ab43f71292d2d46503ef83f61692f385dc76..41fd99982c97967c016d9a59199f22ea7ba6115c 100644 --- a/crates/git_ui/src/commit_view.rs +++ b/crates/git_ui/src/commit_view.rs @@ -223,7 +223,11 @@ impl CommitView { let snapshot = buffer.read(cx).snapshot(); let diff = buffer_diff.read(cx); let diff_hunk_ranges = diff - .hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &snapshot, cx) + .hunks_intersecting_range( + Anchor::min_max_range_for_buffer(diff.buffer_id), + &snapshot, + cx, + ) .map(|diff_hunk| diff_hunk.buffer_range.to_point(&snapshot)) .collect::>(); let path = snapshot.file().unwrap().path().clone(); diff --git a/crates/git_ui/src/project_diff.rs b/crates/git_ui/src/project_diff.rs index 715b74db333e78081a245f2fb362426591db79d9..a6de68b789c33ff75b8e6f474f31b7f9f6d8399c 100644 --- a/crates/git_ui/src/project_diff.rs +++ b/crates/git_ui/src/project_diff.rs @@ -383,12 +383,8 @@ impl ProjectDiff { .collect::>(); if !ranges.iter().any(|range| range.start != range.end) { selection = false; - if let Some((excerpt_id, buffer, range)) = self.editor.read(cx).active_excerpt(cx) { - ranges = vec![multi_buffer::Anchor::range_in_buffer( - excerpt_id, - buffer.read(cx).remote_id(), - range, - )]; + if let Some((excerpt_id, _, range)) = self.editor.read(cx).active_excerpt(cx) { + ranges = vec![multi_buffer::Anchor::range_in_buffer(excerpt_id, range)]; } else { ranges = Vec::default(); } @@ -488,7 +484,11 @@ impl ProjectDiff { let snapshot = buffer.read(cx).snapshot(); let diff_read = diff.read(cx); let diff_hunk_ranges = diff_read - .hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &snapshot, cx) + .hunks_intersecting_range( + Anchor::min_max_range_for_buffer(diff_read.buffer_id), + &snapshot, + cx, + ) .map(|diff_hunk| diff_hunk.buffer_range); let conflicts = conflict_addon .conflict_set(snapshot.remote_id()) diff --git a/crates/language/src/buffer_tests.rs b/crates/language/src/buffer_tests.rs index 05402abcad478e2eedb17d31853ab0bc2bd3702c..efef0a08127bc66f9c6d8f21fe5a545dbee20fb1 100644 --- a/crates/language/src/buffer_tests.rs +++ b/crates/language/src/buffer_tests.rs @@ -3427,7 +3427,7 @@ fn test_random_collaboration(cx: &mut App, mut rng: StdRng) { for buffer in &buffers { let buffer = buffer.read(cx).snapshot(); let actual_remote_selections = buffer - .selections_in_range(Anchor::MIN..Anchor::MAX, false) + .selections_in_range(Anchor::min_max_range_for_buffer(buffer.remote_id()), false) .map(|(replica_id, _, _, selections)| (replica_id, selections.collect::>())) .collect::>(); let expected_remote_selections = active_selections diff --git a/crates/language/src/syntax_map.rs b/crates/language/src/syntax_map.rs index 33a652b6fdeb32a2adbc1743cf8a70fe453518f5..8574d52ff900563ddfb733c09204caab5eb6ae44 100644 --- a/crates/language/src/syntax_map.rs +++ b/crates/language/src/syntax_map.rs @@ -330,7 +330,7 @@ impl SyntaxSnapshot { let slice = cursor.slice( &SyntaxLayerPosition { depth: depth + 1, - range: Anchor::MIN..Anchor::MAX, + range: Anchor::min_max_range_for_buffer(text.remote_id()), language: None, }, Bias::Left, @@ -493,7 +493,7 @@ impl SyntaxSnapshot { start_point: Point::zero().to_ts_point(), end_point: text.max_point().to_ts_point(), }], - range: Anchor::MIN..Anchor::MAX, + range: Anchor::min_max_range_for_buffer(text.remote_id()), mode: ParseMode::Single, }); @@ -515,7 +515,7 @@ impl SyntaxSnapshot { } else { SyntaxLayerPosition { depth: max_depth + 1, - range: Anchor::MAX..Anchor::MAX, + range: Anchor::min_max_range_for_buffer(text.remote_id()), language: None, } }; diff --git a/crates/multi_buffer/src/anchor.rs b/crates/multi_buffer/src/anchor.rs index b8c1680574a86354d92f39c544c202642293f619..51696ba09e4bdb1c6be065f63d3ee7ff634e6b1a 100644 --- a/crates/multi_buffer/src/anchor.rs +++ b/crates/multi_buffer/src/anchor.rs @@ -7,12 +7,9 @@ use std::{ ops::{AddAssign, Range, Sub}, }; use sum_tree::Bias; -use text::BufferId; #[derive(Clone, Copy, Eq, PartialEq, Hash)] pub struct Anchor { - /// Invariant: If buffer id is `None`, excerpt id must be `ExcerptId::min()` or `ExcerptId::max()`. - pub buffer_id: Option, pub excerpt_id: ExcerptId, pub text_anchor: text::Anchor, pub diff_base_anchor: Option, @@ -20,15 +17,14 @@ pub struct Anchor { impl std::fmt::Debug for Anchor { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if *self == Self::min() { - return f.write_str("Anchor::MIN"); + if self.is_min() { + return write!(f, "Anchor::min({:?})", self.text_anchor.buffer_id); } - if *self == Self::max() { - return f.write_str("Anchor::MAX"); + if self.is_max() { + return write!(f, "Anchor::max({:?})", self.text_anchor.buffer_id); } f.debug_struct("Anchor") - .field("buffer_id", &self.buffer_id) .field("excerpt_id", &self.excerpt_id) .field("text_anchor", &self.text_anchor) .field("diff_base_anchor", &self.diff_base_anchor) @@ -44,35 +40,20 @@ impl Anchor { } } - pub fn in_buffer( - excerpt_id: ExcerptId, - buffer_id: BufferId, - text_anchor: text::Anchor, - ) -> Self { - debug_assert!( - text_anchor.buffer_id.is_none_or(|id| id == buffer_id), - "buffer id does not match the one in the text anchor: {buffer_id:?} {text_anchor:?}", - ); + pub fn in_buffer(excerpt_id: ExcerptId, text_anchor: text::Anchor) -> Self { Self { - buffer_id: Some(buffer_id), excerpt_id, text_anchor, diff_base_anchor: None, } } - pub fn range_in_buffer( - excerpt_id: ExcerptId, - buffer_id: BufferId, - range: Range, - ) -> Range { - Self::in_buffer(excerpt_id, buffer_id, range.start) - ..Self::in_buffer(excerpt_id, buffer_id, range.end) + pub fn range_in_buffer(excerpt_id: ExcerptId, range: Range) -> Range { + Self::in_buffer(excerpt_id, range.start)..Self::in_buffer(excerpt_id, range.end) } pub fn min() -> Self { Self { - buffer_id: None, excerpt_id: ExcerptId::min(), text_anchor: text::Anchor::MIN, diff_base_anchor: None, @@ -81,13 +62,24 @@ impl Anchor { pub fn max() -> Self { Self { - buffer_id: None, excerpt_id: ExcerptId::max(), text_anchor: text::Anchor::MAX, diff_base_anchor: None, } } + pub fn is_min(&self) -> bool { + self.excerpt_id == ExcerptId::min() + && self.text_anchor.is_min() + && self.diff_base_anchor.is_none() + } + + pub fn is_max(&self) -> bool { + self.excerpt_id == ExcerptId::max() + && self.text_anchor.is_max() + && self.diff_base_anchor.is_none() + } + pub fn cmp(&self, other: &Anchor, snapshot: &MultiBufferSnapshot) -> Ordering { if self == other { return Ordering::Equal; @@ -101,8 +93,8 @@ impl Anchor { return excerpt_id_cmp; } if self_excerpt_id == ExcerptId::max() - && self.text_anchor == text::Anchor::MAX - && self.text_anchor == text::Anchor::MAX + && self.text_anchor.is_max() + && self.text_anchor.is_max() && self.diff_base_anchor.is_none() && other.diff_base_anchor.is_none() { @@ -147,7 +139,6 @@ impl Anchor { && let Some(excerpt) = snapshot.excerpt(self.excerpt_id) { return Self { - buffer_id: Some(excerpt.buffer_id), excerpt_id: excerpt.id, text_anchor: self.text_anchor.bias_left(&excerpt.buffer), diff_base_anchor: self.diff_base_anchor.map(|a| { @@ -171,7 +162,6 @@ impl Anchor { && let Some(excerpt) = snapshot.excerpt(self.excerpt_id) { return Self { - buffer_id: Some(excerpt.buffer_id), excerpt_id: excerpt.id, text_anchor: self.text_anchor.bias_right(&excerpt.buffer), diff_base_anchor: self.diff_base_anchor.map(|a| { @@ -202,8 +192,8 @@ impl Anchor { } pub fn is_valid(&self, snapshot: &MultiBufferSnapshot) -> bool { - if *self == Anchor::min() || self.excerpt_id == ExcerptId::max() { - !snapshot.is_empty() + if self.is_min() || self.is_max() { + true } else if let Some(excerpt) = snapshot.excerpt(self.excerpt_id) { (self.text_anchor == excerpt.range.context.start || self.text_anchor == excerpt.range.context.end diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index 7922692d30eb3a79e835f5e4b94313c3ea886a7c..2e59eaa621c79bc8d0d0a149704cb55314e9b70d 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -158,12 +158,13 @@ impl MultiBufferDiffHunk { pub fn is_created_file(&self) -> bool { self.diff_base_byte_range == (BufferOffset(0)..BufferOffset(0)) - && self.buffer_range == (text::Anchor::MIN..text::Anchor::MAX) + && self.buffer_range.start.is_min() + && self.buffer_range.end.is_max() } pub fn multi_buffer_range(&self) -> Range { - let start = Anchor::in_buffer(self.excerpt_id, self.buffer_id, self.buffer_range.start); - let end = Anchor::in_buffer(self.excerpt_id, self.buffer_id, self.buffer_range.end); + let start = Anchor::in_buffer(self.excerpt_id, self.buffer_range.start); + let end = Anchor::in_buffer(self.excerpt_id, self.buffer_range.end); start..end } } @@ -1028,9 +1029,12 @@ impl MultiBuffer { }, ); this.singleton = true; + let buffer_id = buffer.read(cx).remote_id(); this.push_excerpts( buffer, - [ExcerptRange::new(text::Anchor::MIN..text::Anchor::MAX)], + [ExcerptRange::new(text::Anchor::min_max_range_for_buffer( + buffer_id, + ))], cx, ); this @@ -1912,7 +1916,7 @@ impl MultiBuffer { } pub fn buffer_for_anchor(&self, anchor: Anchor, cx: &App) -> Option> { - if let Some(buffer_id) = anchor.buffer_id { + if let Some(buffer_id) = anchor.text_anchor.buffer_id { self.buffer(buffer_id) } else { let (_, buffer, _) = self.excerpt_containing(anchor, cx)?; @@ -1975,7 +1979,7 @@ impl MultiBuffer { found.map(|(point, excerpt_id)| { let text_anchor = snapshot.anchor_after(point); - Anchor::in_buffer(excerpt_id, snapshot.remote_id(), text_anchor) + Anchor::in_buffer(excerpt_id, text_anchor) }) } @@ -1990,7 +1994,7 @@ impl MultiBuffer { if range.context.start.cmp(&anchor, &snapshot).is_le() && range.context.end.cmp(&anchor, &snapshot).is_ge() { - return Some(Anchor::in_buffer(excerpt_id, snapshot.remote_id(), anchor)); + return Some(Anchor::in_buffer(excerpt_id, anchor)); } } @@ -2112,7 +2116,7 @@ impl MultiBuffer { let mut error = None; let mut futures = Vec::new(); for anchor in anchors { - if let Some(buffer_id) = anchor.buffer_id { + if let Some(buffer_id) = anchor.text_anchor.buffer_id { if let Some(buffer) = self.buffers.get(&buffer_id) { buffer.buffer.update(cx, |buffer, _| { futures.push(buffer.wait_for_anchors([anchor.text_anchor])) @@ -2143,7 +2147,11 @@ impl MultiBuffer { ) -> Option<(Entity, language::Anchor)> { let snapshot = self.read(cx); let anchor = snapshot.anchor_before(position); - let buffer = self.buffers.get(&anchor.buffer_id?)?.buffer.clone(); + let buffer = self + .buffers + .get(&anchor.text_anchor.buffer_id?)? + .buffer + .clone(); Some((buffer, anchor.text_anchor)) } @@ -2205,7 +2213,7 @@ impl MultiBuffer { .get(&buffer_id) .is_none_or(|old_diff| !new_diff.base_texts_eq(old_diff)); - snapshot.diffs.insert(buffer_id, new_diff); + snapshot.diffs.insert_or_replace(buffer_id, new_diff); let mut excerpt_edits = Vec::new(); for locator in &buffer_state.excerpts { @@ -2402,7 +2410,11 @@ impl MultiBuffer { pub fn add_diff(&mut self, diff: Entity, cx: &mut Context) { let buffer_id = diff.read(cx).buffer_id; - self.buffer_diff_changed(diff.clone(), text::Anchor::MIN..text::Anchor::MAX, cx); + self.buffer_diff_changed( + diff.clone(), + text::Anchor::min_max_range_for_buffer(buffer_id), + cx, + ); self.diffs.insert(buffer_id, DiffState::new(diff, cx)); } @@ -2500,16 +2512,8 @@ impl MultiBuffer { if last_hunk_row.is_some_and(|row| row >= diff_hunk.row_range.start) { continue; } - let start = Anchor::in_buffer( - diff_hunk.excerpt_id, - diff_hunk.buffer_id, - diff_hunk.buffer_range.start, - ); - let end = Anchor::in_buffer( - diff_hunk.excerpt_id, - diff_hunk.buffer_id, - diff_hunk.buffer_range.end, - ); + let start = Anchor::in_buffer(diff_hunk.excerpt_id, diff_hunk.buffer_range.start); + let end = Anchor::in_buffer(diff_hunk.excerpt_id, diff_hunk.buffer_range.end); let start = snapshot.excerpt_offset_for_anchor(&start); let end = snapshot.excerpt_offset_for_anchor(&end); last_hunk_row = Some(diff_hunk.row_range.start); @@ -3945,9 +3949,7 @@ impl MultiBufferSnapshot { if hunk_end >= current_position { continue; } - let start = - Anchor::in_buffer(excerpt.id, excerpt.buffer_id, hunk.buffer_range.start) - .to_point(self); + let start = Anchor::in_buffer(excerpt.id, hunk.buffer_range.start).to_point(self); return Some(MultiBufferRow(start.row)); } } @@ -3964,8 +3966,7 @@ impl MultiBufferSnapshot { let Some(hunk) = hunks.next() else { continue; }; - let start = Anchor::in_buffer(excerpt.id, excerpt.buffer_id, hunk.buffer_range.start) - .to_point(self); + let start = Anchor::in_buffer(excerpt.id, hunk.buffer_range.start).to_point(self); return Some(MultiBufferRow(start.row)); } } @@ -4955,7 +4956,7 @@ impl MultiBufferSnapshot { { text_anchor = excerpt.range.context.end; } - Anchor::in_buffer(excerpt.id, excerpt.buffer_id, text_anchor) + Anchor::in_buffer(excerpt.id, text_anchor) } else if let Some(excerpt) = prev_excerpt { let mut text_anchor = excerpt .range @@ -4968,7 +4969,7 @@ impl MultiBufferSnapshot { { text_anchor = excerpt.range.context.start; } - Anchor::in_buffer(excerpt.id, excerpt.buffer_id, text_anchor) + Anchor::in_buffer(excerpt.id, text_anchor) } else if anchor.text_anchor.bias == Bias::Left { Anchor::min() } else { @@ -5050,7 +5051,7 @@ impl MultiBufferSnapshot { let buffer_start = excerpt.range.context.start.to_offset(&excerpt.buffer); let text_anchor = excerpt.clip_anchor(excerpt.buffer.anchor_at(buffer_start + overshoot, bias)); - let anchor = Anchor::in_buffer(excerpt.id, excerpt.buffer_id, text_anchor); + let anchor = Anchor::in_buffer(excerpt.id, text_anchor); match diff_base_anchor { Some(diff_base_anchor) => anchor.with_diff_base_anchor(diff_base_anchor), None => anchor, @@ -5066,7 +5067,11 @@ impl MultiBufferSnapshot { /// Wraps the [`text::Anchor`] in a [`multi_buffer::Anchor`] if this multi-buffer is a singleton. pub fn as_singleton_anchor(&self, text_anchor: text::Anchor) -> Option { let (excerpt, buffer, _) = self.as_singleton()?; - Some(Anchor::in_buffer(*excerpt, buffer, text_anchor)) + if text_anchor.buffer_id.is_none_or(|id| id == buffer) { + Some(Anchor::in_buffer(*excerpt, text_anchor)) + } else { + None + } } /// Returns an anchor for the given excerpt and text anchor, @@ -5099,12 +5104,8 @@ impl MultiBufferSnapshot { match text_anchor.buffer_id { Some(buffer_id) if buffer_id == excerpt.buffer_id => (), Some(_) => return None, - None if text_anchor == text::Anchor::MAX || text_anchor == text::Anchor::MIN => { - return Some(Anchor::in_buffer( - excerpt.id, - excerpt.buffer_id, - text_anchor, - )); + None if text_anchor.is_max() || text_anchor.is_min() => { + return Some(Anchor::in_buffer(excerpt.id, text_anchor)); } None => return None, } @@ -5116,11 +5117,7 @@ impl MultiBufferSnapshot { return None; } - Some(Anchor::in_buffer( - excerpt.id, - excerpt.buffer_id, - text_anchor, - )) + Some(Anchor::in_buffer(excerpt.id, text_anchor)) } pub fn context_range_for_excerpt(&self, excerpt_id: ExcerptId) -> Option> { @@ -5128,7 +5125,7 @@ impl MultiBufferSnapshot { } pub fn can_resolve(&self, anchor: &Anchor) -> bool { - if *anchor == Anchor::min() || anchor.excerpt_id == ExcerptId::max() { + if anchor.is_min() || anchor.is_max() { // todo(lw): should be `!self.is_empty()` true } else if let Some(excerpt) = self.excerpt(anchor.excerpt_id) { @@ -5998,7 +5995,7 @@ impl MultiBufferSnapshot { .. } = self.excerpt(anchor.excerpt_id)?; if cfg!(debug_assertions) { - match anchor.buffer_id { + match anchor.text_anchor.buffer_id { // we clearly are hitting this according to sentry, but in what situations can this occur? Some(anchor_buffer_id) => { assert_eq!( @@ -6006,7 +6003,7 @@ impl MultiBufferSnapshot { "anchor {anchor:?} does not match with resolved excerpt {excerpt:?}" ) } - None => assert_eq!(anchor, Anchor::max()), + None => assert!(anchor.is_max()), } }; Some(( @@ -6019,19 +6016,18 @@ impl MultiBufferSnapshot { depth: item.depth, source_range_for_text: Anchor::range_in_buffer( excerpt_id, - buffer_id, item.source_range_for_text, ), - range: Anchor::range_in_buffer(excerpt_id, buffer_id, item.range), + range: Anchor::range_in_buffer(excerpt_id, item.range), text: item.text, highlight_ranges: item.highlight_ranges, name_ranges: item.name_ranges, - body_range: item.body_range.map(|body_range| { - Anchor::range_in_buffer(excerpt_id, buffer_id, body_range) - }), - annotation_range: item.annotation_range.map(|body_range| { - Anchor::range_in_buffer(excerpt_id, buffer_id, body_range) - }), + body_range: item + .body_range + .map(|body_range| Anchor::range_in_buffer(excerpt_id, body_range)), + annotation_range: item + .annotation_range + .map(|body_range| Anchor::range_in_buffer(excerpt_id, body_range)), }) }) .collect(), @@ -6180,7 +6176,7 @@ impl MultiBufferSnapshot { } pub fn buffer_id_for_anchor(&self, anchor: Anchor) -> Option { - if let Some(id) = anchor.buffer_id { + if let Some(id) = anchor.text_anchor.buffer_id { return Some(id); } let excerpt = self.excerpt_containing(anchor..anchor)?; @@ -6212,10 +6208,8 @@ impl MultiBufferSnapshot { .selections_in_range(query_range, include_local) .flat_map(move |(replica_id, line_mode, cursor_shape, selections)| { selections.map(move |selection| { - let mut start = - Anchor::in_buffer(excerpt.id, excerpt.buffer_id, selection.start); - let mut end = - Anchor::in_buffer(excerpt.id, excerpt.buffer_id, selection.end); + let mut start = Anchor::in_buffer(excerpt.id, selection.start); + let mut end = Anchor::in_buffer(excerpt.id, selection.end); if range.start.cmp(&start, self).is_gt() { start = range.start; } @@ -6687,7 +6681,8 @@ impl Excerpt { } fn contains(&self, anchor: &Anchor) -> bool { - (anchor.buffer_id == None || anchor.buffer_id == Some(self.buffer_id)) + (anchor.text_anchor.buffer_id == None + || anchor.text_anchor.buffer_id == Some(self.buffer_id)) && self .range .context @@ -6723,19 +6718,11 @@ impl<'a> MultiBufferExcerpt<'a> { } pub fn start_anchor(&self) -> Anchor { - Anchor::in_buffer( - self.excerpt.id, - self.excerpt.buffer_id, - self.excerpt.range.context.start, - ) + Anchor::in_buffer(self.excerpt.id, self.excerpt.range.context.start) } pub fn end_anchor(&self) -> Anchor { - Anchor::in_buffer( - self.excerpt.id, - self.excerpt.buffer_id, - self.excerpt.range.context.end, - ) + Anchor::in_buffer(self.excerpt.id, self.excerpt.range.context.end) } pub fn buffer(&self) -> &'a BufferSnapshot { diff --git a/crates/multi_buffer/src/multi_buffer_tests.rs b/crates/multi_buffer/src/multi_buffer_tests.rs index 9517f1f76ece2f34aa5c95eb27b408e1ef004b99..e95d222c651999645a6966195be2da31347f1409 100644 --- a/crates/multi_buffer/src/multi_buffer_tests.rs +++ b/crates/multi_buffer/src/multi_buffer_tests.rs @@ -3401,14 +3401,11 @@ fn test_summaries_for_anchors(cx: &mut TestAppContext) { ), ); - let id_1 = buffer_1.read_with(cx, |buffer, _| buffer.remote_id()); - let id_2 = buffer_2.read_with(cx, |buffer, _| buffer.remote_id()); - - let anchor_1 = Anchor::in_buffer(ids[0], id_1, text::Anchor::MIN); + let anchor_1 = Anchor::in_buffer(ids[0], text::Anchor::MIN); let point_1 = snapshot.summaries_for_anchors::([&anchor_1])[0]; assert_eq!(point_1, Point::new(0, 0)); - let anchor_2 = Anchor::in_buffer(ids[1], id_2, text::Anchor::MIN); + let anchor_2 = Anchor::in_buffer(ids[1], text::Anchor::MIN); let point_2 = snapshot.summaries_for_anchors::([&anchor_2])[0]; assert_eq!(point_2, Point::new(3, 0)); } diff --git a/crates/multi_buffer/src/path_key.rs b/crates/multi_buffer/src/path_key.rs index 530bb4aa6435fb9a3aa768d84a2bbcf829eb72c6..5d9b653a2b8c9df8c854ca01c47c57b42c159f1e 100644 --- a/crates/multi_buffer/src/path_key.rs +++ b/crates/multi_buffer/src/path_key.rs @@ -56,11 +56,7 @@ impl MultiBuffer { let excerpt_id = self.excerpts_by_path.get(path)?.first()?; let snapshot = self.read(cx); let excerpt = snapshot.excerpt(*excerpt_id)?; - Some(Anchor::in_buffer( - excerpt.id, - excerpt.buffer_id, - excerpt.range.context.start, - )) + Some(Anchor::in_buffer(excerpt.id, excerpt.range.context.start)) } pub fn excerpt_paths(&self) -> impl Iterator { @@ -263,7 +259,6 @@ impl MultiBuffer { for range in ranges.by_ref().take(range_count) { let range = Anchor::range_in_buffer( excerpt_id, - buffer_snapshot.remote_id(), buffer_snapshot.anchor_before(&range.primary.start) ..buffer_snapshot.anchor_after(&range.primary.end), ); diff --git a/crates/outline_panel/src/outline_panel.rs b/crates/outline_panel/src/outline_panel.rs index 36cd9d076bb428f37c898a142fa7f3d1da887918..cb857a72898bbd6f4161a0f4d218394efeab5c7e 100644 --- a/crates/outline_panel/src/outline_panel.rs +++ b/crates/outline_panel/src/outline_panel.rs @@ -2044,8 +2044,9 @@ impl OutlinePanel { PanelEntry::Fs(FsEntry::ExternalFile(..)) => None, PanelEntry::Search(SearchEntry { match_range, .. }) => match_range .start + .text_anchor .buffer_id - .or(match_range.end.buffer_id) + .or(match_range.end.text_anchor.buffer_id) .map(|buffer_id| { outline_panel.update(cx, |outline_panel, cx| { outline_panel diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index f5d931737dff9a873fc5d63e5445b2b5d49bab56..4f7022a264db18f96150c369fadb957556e33b75 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -2746,7 +2746,7 @@ impl LocalLspStore { let actions = lsp_store .update(cx, move |this, cx| { let request = GetCodeActions { - range: text::Anchor::MIN..text::Anchor::MAX, + range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()), kinds: Some(code_action_kinds), }; let server = LanguageServerToQuery::Other(language_server_id); diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 149d30a5283c13f71477fc6776d5ca7f61f6205d..beebf5a1d133eb75fdd98184ddf7880b9cedc7e0 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -4002,7 +4002,8 @@ impl Project { ) -> Task>> { let snapshot = buffer_handle.read(cx).snapshot(); - let captures = snapshot.debug_variables_query(Anchor::MIN..range.end); + let captures = + snapshot.debug_variables_query(Anchor::min_for_buffer(snapshot.remote_id())..range.end); let row = snapshot .summary_for_anchor::(&range.end) diff --git a/crates/sum_tree/src/tree_map.rs b/crates/sum_tree/src/tree_map.rs index 3e56194dddd9910f819e91c209f6701b55efdd02..e58f7a65dd5d13ca67d4433bd25118ffb55d1169 100644 --- a/crates/sum_tree/src/tree_map.rs +++ b/crates/sum_tree/src/tree_map.rs @@ -72,6 +72,12 @@ impl TreeMap { self.0.insert_or_replace(MapEntry { key, value }, ()); } + pub fn insert_or_replace(&mut self, key: K, value: V) -> Option { + self.0 + .insert_or_replace(MapEntry { key, value }, ()) + .map(|it| it.value) + } + pub fn extend(&mut self, iter: impl IntoIterator) { let edits: Vec<_> = iter .into_iter() diff --git a/crates/text/src/anchor.rs b/crates/text/src/anchor.rs index 63a9ff6f1863041594fba7ebea0b3feaba6b8db7..c6d47a1e233b2fdf58fbc73adb622fc801832335 100644 --- a/crates/text/src/anchor.rs +++ b/crates/text/src/anchor.rs @@ -18,11 +18,11 @@ pub struct Anchor { impl Debug for Anchor { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if *self == Self::MIN { - return f.write_str("Anchor::MIN"); + if self.is_min() { + return write!(f, "Anchor::min({:?})", self.buffer_id); } - if *self == Self::MAX { - return f.write_str("Anchor::MAX"); + if self.is_max() { + return write!(f, "Anchor::max({:?})", self.buffer_id); } f.debug_struct("Anchor") @@ -49,6 +49,36 @@ impl Anchor { buffer_id: None, }; + pub fn min_for_buffer(buffer_id: BufferId) -> Self { + Self { + timestamp: clock::Lamport::MIN, + offset: usize::MIN, + bias: Bias::Left, + buffer_id: Some(buffer_id), + } + } + + pub fn max_for_buffer(buffer_id: BufferId) -> Self { + Self { + timestamp: clock::Lamport::MAX, + offset: usize::MAX, + bias: Bias::Right, + buffer_id: Some(buffer_id), + } + } + + pub fn min_min_range_for_buffer(buffer_id: BufferId) -> std::ops::Range { + let min = Self::min_for_buffer(buffer_id); + min..min + } + pub fn max_max_range_for_buffer(buffer_id: BufferId) -> std::ops::Range { + let max = Self::max_for_buffer(buffer_id); + max..max + } + pub fn min_max_range_for_buffer(buffer_id: BufferId) -> std::ops::Range { + Self::min_for_buffer(buffer_id)..Self::max_for_buffer(buffer_id) + } + pub fn cmp(&self, other: &Anchor, buffer: &BufferSnapshot) -> Ordering { let fragment_id_comparison = if self.timestamp == other.timestamp { Ordering::Equal @@ -109,7 +139,7 @@ impl Anchor { /// Returns true when the [`Anchor`] is located inside a visible fragment. pub fn is_valid(&self, buffer: &BufferSnapshot) -> bool { - if *self == Anchor::MIN || *self == Anchor::MAX { + if self.is_min() || self.is_max() { true } else if self.buffer_id.is_none_or(|id| id != buffer.remote_id) { false @@ -127,6 +157,18 @@ impl Anchor { item.is_some_and(|fragment| fragment.visible) } } + + pub fn is_min(&self) -> bool { + self.timestamp == clock::Lamport::MIN + && self.offset == usize::MIN + && self.bias == Bias::Left + } + + pub fn is_max(&self) -> bool { + self.timestamp == clock::Lamport::MAX + && self.offset == usize::MAX + && self.bias == Bias::Right + } } pub trait OffsetRangeExt { diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index 5f87e5441d2bb97863b0086ac273e4d4d8acfdc9..c16c6a7b27e2b1fc4c945007395dbe26f98adcda 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -1652,10 +1652,7 @@ impl Buffer { ) -> impl 'static + Future> + use { let mut futures = Vec::new(); for anchor in anchors { - if !self.version.observed(anchor.timestamp) - && anchor != Anchor::MAX - && anchor != Anchor::MIN - { + if !self.version.observed(anchor.timestamp) && !anchor.is_max() && !anchor.is_min() { let (tx, rx) = oneshot::channel(); self.edit_id_resolvers .entry(anchor.timestamp) @@ -2258,9 +2255,9 @@ impl BufferSnapshot { let mut position = D::zero(()); anchors.map(move |(anchor, payload)| { - if *anchor == Anchor::MIN { + if anchor.is_min() { return (D::zero(()), payload); - } else if *anchor == Anchor::MAX { + } else if anchor.is_max() { return (D::from_text_summary(&self.visible_text.summary()), payload); } @@ -2318,9 +2315,9 @@ impl BufferSnapshot { } pub fn offset_for_anchor(&self, anchor: &Anchor) -> usize { - if *anchor == Anchor::MIN { + if anchor.is_min() { 0 - } else if *anchor == Anchor::MAX { + } else if anchor.is_max() { self.visible_text.len() } else { debug_assert!(anchor.buffer_id == Some(self.remote_id)); @@ -2393,9 +2390,9 @@ impl BufferSnapshot { } fn try_fragment_id_for_anchor(&self, anchor: &Anchor) -> Option<&Locator> { - if *anchor == Anchor::MIN { + if anchor.is_min() { Some(Locator::min_ref()) - } else if *anchor == Anchor::MAX { + } else if anchor.is_max() { Some(Locator::max_ref()) } else { let anchor_key = InsertionFragmentKey { @@ -2440,9 +2437,9 @@ impl BufferSnapshot { fn anchor_at_offset(&self, offset: usize, bias: Bias) -> Anchor { if bias == Bias::Left && offset == 0 { - Anchor::MIN + Anchor::min_for_buffer(self.remote_id) } else if bias == Bias::Right && offset == self.len() { - Anchor::MAX + Anchor::max_for_buffer(self.remote_id) } else { if cfg!(debug_assertions) { self.visible_text.assert_char_boundary(offset); @@ -2462,8 +2459,8 @@ impl BufferSnapshot { } pub fn can_resolve(&self, anchor: &Anchor) -> bool { - *anchor == Anchor::MIN - || *anchor == Anchor::MAX + anchor.is_min() + || anchor.is_max() || (Some(self.remote_id) == anchor.buffer_id && self.version.observed(anchor.timestamp)) } diff --git a/crates/vim/src/motion.rs b/crates/vim/src/motion.rs index b0faa7bb068135a3feafc507e4f8a6ed97863e8c..dc108b0957d993b2229e8c04fed5923e9de250d4 100644 --- a/crates/vim/src/motion.rs +++ b/crates/vim/src/motion.rs @@ -2268,17 +2268,13 @@ fn go_to_line(map: &DisplaySnapshot, display_point: DisplayPoint, line: usize) - ..language::ToOffset::to_offset(&range.context.end, buffer); if offset >= excerpt_range.start && offset <= excerpt_range.end { let text_anchor = buffer.anchor_after(offset); - let anchor = Anchor::in_buffer(excerpt, buffer.remote_id(), text_anchor); + let anchor = Anchor::in_buffer(excerpt, text_anchor); return anchor.to_display_point(map); } else if offset <= excerpt_range.start { - let anchor = Anchor::in_buffer(excerpt, buffer.remote_id(), range.context.start); + let anchor = Anchor::in_buffer(excerpt, range.context.start); return anchor.to_display_point(map); } else { - last_position = Some(Anchor::in_buffer( - excerpt, - buffer.remote_id(), - range.context.end, - )); + last_position = Some(Anchor::in_buffer(excerpt, range.context.end)); } } diff --git a/crates/vim/src/state.rs b/crates/vim/src/state.rs index eba4476ea878932518dc8a3951e04f4c6ea96d29..e96fd3a329e95311eeb73b87b53acbe76939f0cd 100644 --- a/crates/vim/src/state.rs +++ b/crates/vim/src/state.rs @@ -606,7 +606,7 @@ impl MarksState { let text_anchors = anchors.get(name)?; let anchors = text_anchors .iter() - .map(|anchor| Anchor::in_buffer(excerpt_id, buffer_id, *anchor)) + .map(|anchor| Anchor::in_buffer(excerpt_id, *anchor)) .collect(); return Some(Mark::Local(anchors)); }