diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 806703a544d681fd690e5777597000558797ba28..c7d97c1ef35464b1d87e67138eb8740fd53920c7 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -5,16 +5,17 @@ use collections::{BTreeMap, HashSet}; use editor::{ diagnostic_block_renderer, display_map::{BlockDisposition, BlockId, BlockProperties, RenderBlock}, - highlight_diagnostic_message, Autoscroll, Editor, ExcerptId, MultiBuffer, ToOffset, + highlight_diagnostic_message, Autoscroll, Editor, ExcerptId, ExcerptRange, MultiBuffer, + ToOffset, }; use gpui::{ - actions, elements::*, fonts::TextStyle, impl_internal_actions, platform::CursorStyle, - serde_json, AnyViewHandle, AppContext, Entity, ModelHandle, MutableAppContext, RenderContext, - Task, View, ViewContext, ViewHandle, WeakViewHandle, + actions, elements::*, fonts::TextStyle, impl_internal_actions, serde_json, AnyViewHandle, + AppContext, Entity, ModelHandle, MutableAppContext, RenderContext, Task, View, ViewContext, + ViewHandle, WeakViewHandle, }; use language::{ Anchor, Bias, Buffer, Diagnostic, DiagnosticEntry, DiagnosticSeverity, Point, Selection, - SelectionGoal, ToPoint, + SelectionGoal, }; use project::{DiagnosticSummary, Project, ProjectPath}; use serde_json::json; @@ -27,7 +28,7 @@ use std::{ path::PathBuf, sync::Arc, }; -use util::{ResultExt, TryFutureExt}; +use util::TryFutureExt; use workspace::{ItemHandle as _, ItemNavHistory, Workspace}; actions!(diagnostics, [Deploy]); @@ -38,7 +39,6 @@ const CONTEXT_LINE_COUNT: u32 = 1; pub fn init(cx: &mut MutableAppContext) { cx.add_action(ProjectDiagnosticsEditor::deploy); - cx.add_action(ProjectDiagnosticsEditor::jump); items::init(cx); } @@ -194,30 +194,6 @@ impl ProjectDiagnosticsEditor { } } - fn jump(workspace: &mut Workspace, action: &Jump, cx: &mut ViewContext) { - let editor = workspace.open_path(action.path.clone(), true, cx); - let position = action.position; - let anchor = action.anchor; - cx.spawn_weak(|_, mut cx| async move { - let editor = editor.await.log_err()?.downcast::()?; - editor.update(&mut cx, |editor, cx| { - let buffer = editor.buffer().read(cx).as_singleton()?; - let buffer = buffer.read(cx); - let cursor = if buffer.can_resolve(&anchor) { - anchor.to_point(buffer) - } else { - buffer.clip_point(position, Bias::Left) - }; - editor.change_selections(Some(Autoscroll::Newest), cx, |s| { - s.select_ranges([cursor..cursor]); - }); - Some(()) - })?; - Some(()) - }) - .detach() - } - fn update_excerpts(&mut self, language_server_id: Option, cx: &mut ViewContext) { let mut paths = Vec::new(); self.paths_to_update.retain(|path, server_id| { @@ -348,7 +324,10 @@ impl ProjectDiagnosticsEditor { .insert_excerpts_after( &prev_excerpt_id, buffer.clone(), - [excerpt_start..excerpt_end], + [ExcerptRange { + context: excerpt_start..excerpt_end, + primary: Some(range.clone()), + }], excerpts_cx, ) .pop() @@ -363,20 +342,13 @@ impl ProjectDiagnosticsEditor { is_first_excerpt_for_group = false; let mut primary = group.entries[group.primary_ix].diagnostic.clone(); - let anchor = group.entries[group.primary_ix].range.start; - let position = anchor.to_point(&snapshot); primary.message = primary.message.split('\n').next().unwrap().to_string(); group_state.block_count += 1; blocks_to_add.push(BlockProperties { position: header_position, height: 2, - render: diagnostic_header_renderer( - primary, - path.clone(), - position, - anchor, - ), + render: diagnostic_header_renderer(primary), disposition: BlockDisposition::Above, }); } @@ -633,18 +605,10 @@ impl workspace::Item for ProjectDiagnosticsEditor { } } -fn diagnostic_header_renderer( - diagnostic: Diagnostic, - path: ProjectPath, - position: Point, - anchor: Anchor, -) -> RenderBlock { - enum JumpIcon {} - +fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock { let (message, highlights) = highlight_diagnostic_message(&diagnostic.message); Arc::new(move |cx| { let settings = cx.global::(); - let tooltip_style = settings.theme.tooltip.clone(); let theme = &settings.theme.editor; let style = theme.diagnostic_header.clone(); let font_size = (style.text_scale_factor * settings.buffer_font_size).round(); @@ -685,43 +649,6 @@ fn diagnostic_header_renderer( .aligned() .boxed() })) - .with_child( - MouseEventHandler::new::(diagnostic.group_id, cx, |state, _| { - let style = style.jump_icon.style_for(state, false); - Svg::new("icons/jump.svg") - .with_color(style.color) - .constrained() - .with_width(style.icon_width) - .aligned() - .contained() - .with_style(style.container) - .constrained() - .with_width(style.button_width) - .with_height(style.button_width) - .boxed() - }) - .with_cursor_style(CursorStyle::PointingHand) - .on_click({ - let path = path.clone(); - move |_, _, cx| { - cx.dispatch_action(Jump { - path: path.clone(), - position, - anchor, - }); - } - }) - .with_tooltip( - diagnostic.group_id, - "Jump to diagnostic".to_string(), - Some(Box::new(editor::OpenExcerpts)), - tooltip_style, - cx, - ) - .aligned() - .flex_float() - .boxed(), - ) .contained() .with_style(style.container) .with_padding_left(x_padding) diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index bdfff4862c41d156cfad9c5bf8376e0e84a6a9e7..36abef60e5a8cb00785569d52fbb592ac579d41b 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -2,7 +2,7 @@ use super::{ wrap_map::{self, WrapEdit, WrapPoint, WrapSnapshot}, TextHighlights, }; -use crate::{Anchor, ToPoint as _}; +use crate::{Anchor, ExcerptRange, ToPoint as _}; use collections::{Bound, HashMap, HashSet}; use gpui::{ElementBox, RenderContext}; use language::{BufferSnapshot, Chunk, Patch}; @@ -97,8 +97,9 @@ struct Transform { pub enum TransformBlock { Custom(Arc), ExcerptHeader { + key: usize, buffer: BufferSnapshot, - range: Range, + range: ExcerptRange, height: u8, starts_new_buffer: bool, }, @@ -126,7 +127,7 @@ impl Debug for TransformBlock { Self::Custom(block) => f.debug_struct("Custom").field("block", block).finish(), Self::ExcerptHeader { buffer, .. } => f .debug_struct("ExcerptHeader") - .field("path", &buffer.path()) + .field("path", &buffer.file().map(|f| f.path())) .finish(), } } @@ -359,6 +360,7 @@ impl BlockMap { .from_point(Point::new(excerpt_boundary.row, 0), Bias::Left) .row(), TransformBlock::ExcerptHeader { + key: excerpt_boundary.key, buffer: excerpt_boundary.buffer, range: excerpt_boundary.range, height: if excerpt_boundary.starts_new_buffer { diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index cce1ebd17c7881560d57f7b17d22684212884038..8cd2e8a96df45138b46a2dcd095cea6020025566 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -36,10 +36,11 @@ use language::{ }; use multi_buffer::MultiBufferChunks; pub use multi_buffer::{ - Anchor, AnchorRangeExt, ExcerptId, MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint, + Anchor, AnchorRangeExt, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, ToOffset, + ToPoint, }; use ordered_float::OrderedFloat; -use project::{HoverBlock, Project, ProjectTransaction}; +use project::{HoverBlock, Project, ProjectPath, ProjectTransaction}; use selections_collection::{resolve_multiple, MutableSelectionsCollection, SelectionsCollection}; use serde::{Deserialize, Serialize}; use settings::Settings; @@ -85,6 +86,13 @@ pub struct HoverAt { point: Option, } +#[derive(Clone, Debug, PartialEq)] +pub struct Jump { + path: ProjectPath, + position: Point, + anchor: language::Anchor, +} + #[derive(Clone, Deserialize, PartialEq)] pub struct Input(pub String); @@ -215,7 +223,7 @@ impl_actions!( ] ); -impl_internal_actions!(editor, [Scroll, Select, HoverAt]); +impl_internal_actions!(editor, [Scroll, Select, HoverAt, Jump]); enum DocumentHighlightRead {} enum DocumentHighlightWrite {} @@ -305,6 +313,7 @@ pub fn init(cx: &mut MutableAppContext) { cx.add_action(Editor::hover); cx.add_action(Editor::hover_at); cx.add_action(Editor::open_excerpts); + cx.add_action(Editor::jump); cx.add_action(Editor::restart_language_server); cx.add_async_action(Editor::confirm_completion); cx.add_async_action(Editor::confirm_code_action); @@ -2833,11 +2842,11 @@ impl Editor { let start = highlight .range .start - .max(&excerpt_range.start, cursor_buffer_snapshot); + .max(&excerpt_range.context.start, cursor_buffer_snapshot); let end = highlight .range .end - .min(&excerpt_range.end, cursor_buffer_snapshot); + .min(&excerpt_range.context.end, cursor_buffer_snapshot); if start.cmp(&end, cursor_buffer_snapshot).is_ge() { continue; } @@ -5825,6 +5834,34 @@ impl Editor { nav_history.borrow_mut().enable(); }); } + + fn jump(workspace: &mut Workspace, action: &Jump, cx: &mut ViewContext) { + let editor = workspace.open_path(action.path.clone(), true, cx); + let position = action.position; + let anchor = action.anchor; + cx.spawn_weak(|_, mut cx| async move { + let editor = editor.await.log_err()?.downcast::()?; + editor.update(&mut cx, |editor, cx| { + let buffer = editor.buffer().read(cx).as_singleton()?; + let buffer = buffer.read(cx); + let cursor = if buffer.can_resolve(&anchor) { + language::ToPoint::to_point(&anchor, buffer) + } else { + buffer.clip_point(position, Bias::Left) + }; + + let nav_history = editor.nav_history.take(); + editor.change_selections(Some(Autoscroll::Newest), cx, |s| { + s.select_ranges([cursor..cursor]); + }); + editor.nav_history = nav_history; + + Some(()) + })?; + Some(()) + }) + .detach() + } } impl EditorSnapshot { @@ -7718,12 +7755,18 @@ mod tests { let mut multibuffer = MultiBuffer::new(0); multibuffer.push_excerpts( toml_buffer.clone(), - [Point::new(0, 0)..Point::new(2, 0)], + [ExcerptRange { + context: Point::new(0, 0)..Point::new(2, 0), + primary: None, + }], cx, ); multibuffer.push_excerpts( rust_buffer.clone(), - [Point::new(0, 0)..Point::new(1, 0)], + [ExcerptRange { + context: Point::new(0, 0)..Point::new(1, 0), + primary: None, + }], cx, ); multibuffer @@ -9595,8 +9638,14 @@ mod tests { multibuffer.push_excerpts( buffer.clone(), [ - Point::new(0, 0)..Point::new(0, 4), - Point::new(1, 0)..Point::new(1, 4), + ExcerptRange { + context: Point::new(0, 0)..Point::new(0, 4), + primary: None, + }, + ExcerptRange { + context: Point::new(1, 0)..Point::new(1, 4), + primary: None, + }, ], cx, ); @@ -9634,6 +9683,10 @@ mod tests { [aaaa (bbbb] cccc)"}); + let excerpt_ranges = excerpt_ranges.into_iter().map(|context| ExcerptRange { + context, + primary: None, + }); let buffer = cx.add_model(|cx| Buffer::new(0, initial_text, cx)); let multibuffer = cx.add_model(|cx| { let mut multibuffer = MultiBuffer::new(0); @@ -9687,8 +9740,14 @@ mod tests { .push_excerpts( buffer.clone(), [ - Point::new(0, 0)..Point::new(1, 4), - Point::new(1, 0)..Point::new(2, 4), + ExcerptRange { + context: Point::new(0, 0)..Point::new(1, 4), + primary: None, + }, + ExcerptRange { + context: Point::new(1, 0)..Point::new(2, 4), + primary: None, + }, ], cx, ) @@ -9771,8 +9830,14 @@ mod tests { .push_excerpts( buffer.clone(), [ - Point::new(0, 0)..Point::new(1, 4), - Point::new(1, 0)..Point::new(2, 4), + ExcerptRange { + context: Point::new(0, 0)..Point::new(1, 4), + primary: None, + }, + ExcerptRange { + context: Point::new(1, 0)..Point::new(2, 4), + primary: None, + }, ], cx, ) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 594c047d5b3e1119c775b43b90309209d2b92ef1..d73569a03f8f0f9e3c35b4e9277ad9dacce088c6 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -27,6 +27,7 @@ use gpui::{ }; use json::json; use language::{Bias, DiagnosticSeverity, Selection}; +use project::ProjectPath; use settings::Settings; use smallvec::SmallVec; use std::{ @@ -795,6 +796,7 @@ impl EditorElement { return Default::default(); }; + let tooltip_style = cx.global::().theme.tooltip.clone(); let scroll_x = snapshot.scroll_position.x(); snapshot .blocks_in_range(rows.clone()) @@ -827,10 +829,60 @@ impl EditorElement { }) } TransformBlock::ExcerptHeader { + key, buffer, + range, starts_new_buffer, .. } => { + let jump_icon = project::File::from_dyn(buffer.file()).map(|file| { + let jump_position = range + .primary + .as_ref() + .map_or(range.context.start, |primary| primary.start); + let jump_action = crate::Jump { + path: ProjectPath { + worktree_id: file.worktree_id(cx), + path: file.path.clone(), + }, + position: language::ToPoint::to_point(&jump_position, buffer), + anchor: jump_position, + }; + + enum JumpIcon {} + cx.render(&editor, |_, cx| { + MouseEventHandler::new::(*key, cx, |state, _| { + let style = style.jump_icon.style_for(state, false); + Svg::new("icons/jump.svg") + .with_color(style.color) + .constrained() + .with_width(style.icon_width) + .aligned() + .contained() + .with_style(style.container) + .constrained() + .with_width(style.button_width) + .with_height(style.button_width) + .boxed() + }) + .with_cursor_style(CursorStyle::PointingHand) + .on_click({ + move |_, _, cx| cx.dispatch_action(jump_action.clone()) + }) + .with_tooltip( + *key, + "Jump to Buffer".to_string(), + Some(Box::new(crate::OpenExcerpts)), + tooltip_style.clone(), + cx, + ) + .aligned() + .flex_float() + .boxed() + }) + }); + + let padding = gutter_padding + scroll_x * em_width; if *starts_new_buffer { let style = &self.style.diagnostic_path_header; let font_size = @@ -838,7 +890,8 @@ impl EditorElement { let mut filename = None; let mut parent_path = None; - if let Some(path) = buffer.path() { + if let Some(file) = buffer.file() { + let path = file.path(); filename = path.file_name().map(|f| f.to_string_lossy().to_string()); parent_path = @@ -853,6 +906,7 @@ impl EditorElement { ) .contained() .with_style(style.filename.container) + .aligned() .boxed(), ) .with_children(parent_path.map(|path| { @@ -862,20 +916,25 @@ impl EditorElement { ) .contained() .with_style(style.path.container) + .aligned() .boxed() })) - .aligned() - .left() + .with_children(jump_icon) .contained() .with_style(style.container) - .with_padding_left(gutter_padding + scroll_x * em_width) + .with_padding_left(padding) + .with_padding_right(padding) .expanded() .named("path header block") } else { let text_style = self.style.text.clone(); - Label::new("…".to_string(), text_style) + Flex::row() + .with_child(Label::new("…".to_string(), text_style).boxed()) + .with_children(jump_icon) .contained() - .with_padding_left(gutter_padding + scroll_x * em_width) + .with_padding_left(padding) + .with_padding_right(padding) + .expanded() .named("collapsed context") } } diff --git a/crates/editor/src/movement.rs b/crates/editor/src/movement.rs index 1f4486739bd41a0764ec5ed02093e181d097d739..1b9a8db2280d2ec5d153feac8651226eabf6d84a 100644 --- a/crates/editor/src/movement.rs +++ b/crates/editor/src/movement.rs @@ -272,7 +272,7 @@ pub fn surrounding_word(map: &DisplaySnapshot, position: DisplayPoint) -> Range< #[cfg(test)] mod tests { use super::*; - use crate::{test::marked_display_snapshot, Buffer, DisplayMap, MultiBuffer}; + use crate::{test::marked_display_snapshot, Buffer, DisplayMap, ExcerptRange, MultiBuffer}; use language::Point; use settings::Settings; @@ -494,8 +494,14 @@ mod tests { multibuffer.push_excerpts( buffer.clone(), [ - Point::new(0, 0)..Point::new(1, 4), - Point::new(2, 0)..Point::new(3, 2), + ExcerptRange { + context: Point::new(0, 0)..Point::new(1, 4), + primary: None, + }, + ExcerptRange { + context: Point::new(2, 0)..Point::new(3, 2), + primary: None, + }, ], cx, ); diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index 32e2021fd2b2fc52d9b87a8e021fe28f95dab1a8..de268d95b9ede3d34a8a2f6837ebb280ad8f687e 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -31,6 +31,7 @@ use text::{ Edit, Point, PointUtf16, TextSummary, }; use theme::SyntaxTheme; +use util::post_inc; const NEWLINES: &'static [u8] = &[b'\n'; u8::MAX as usize]; @@ -40,6 +41,7 @@ pub struct MultiBuffer { snapshot: RefCell, buffers: RefCell>, used_excerpt_ids: SumTree, + next_excerpt_key: usize, subscriptions: Topic, singleton: bool, replica_id: ReplicaId, @@ -102,23 +104,31 @@ pub struct MultiBufferSnapshot { pub struct ExcerptBoundary { pub id: ExcerptId, + pub key: usize, pub row: u32, pub buffer: BufferSnapshot, - pub range: Range, + pub range: ExcerptRange, pub starts_new_buffer: bool, } #[derive(Clone)] struct Excerpt { id: ExcerptId, + key: usize, buffer_id: usize, buffer: BufferSnapshot, - range: Range, + range: ExcerptRange, max_buffer_row: u32, text_summary: TextSummary, has_trailing_newline: bool, } +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ExcerptRange { + pub context: Range, + pub primary: Option>, +} + #[derive(Clone, Debug, Default)] struct ExcerptSummary { excerpt_id: ExcerptId, @@ -161,6 +171,7 @@ impl MultiBuffer { snapshot: Default::default(), buffers: Default::default(), used_excerpt_ids: Default::default(), + next_excerpt_key: Default::default(), subscriptions: Default::default(), singleton: false, replica_id, @@ -198,7 +209,8 @@ impl MultiBuffer { Self { snapshot: RefCell::new(self.snapshot.borrow().clone()), buffers: RefCell::new(buffers), - used_excerpt_ids: Default::default(), + used_excerpt_ids: self.used_excerpt_ids.clone(), + next_excerpt_key: self.next_excerpt_key, subscriptions: Default::default(), singleton: self.singleton, replica_id: self.replica_id, @@ -215,7 +227,14 @@ impl MultiBuffer { pub fn singleton(buffer: ModelHandle, cx: &mut ModelContext) -> Self { let mut this = Self::new(buffer.read(cx).replica_id()); this.singleton = true; - this.push_excerpts(buffer, [text::Anchor::MIN..text::Anchor::MAX], cx); + this.push_excerpts( + buffer, + [ExcerptRange { + context: text::Anchor::MIN..text::Anchor::MAX, + primary: None, + }], + cx, + ); this.snapshot.borrow_mut().singleton = true; this } @@ -343,8 +362,12 @@ impl MultiBuffer { } let start_excerpt = cursor.item().expect("start offset out of bounds"); let start_overshoot = range.start - cursor.start(); - let buffer_start = - start_excerpt.range.start.to_offset(&start_excerpt.buffer) + start_overshoot; + let buffer_start = start_excerpt + .range + .context + .start + .to_offset(&start_excerpt.buffer) + + start_overshoot; cursor.seek(&range.end, Bias::Right, &()); if cursor.item().is_none() && range.end == *cursor.start() { @@ -352,7 +375,12 @@ impl MultiBuffer { } let end_excerpt = cursor.item().expect("end offset out of bounds"); let end_overshoot = range.end - cursor.start(); - let buffer_end = end_excerpt.range.start.to_offset(&end_excerpt.buffer) + end_overshoot; + let buffer_end = end_excerpt + .range + .context + .start + .to_offset(&end_excerpt.buffer) + + end_overshoot; if start_excerpt.id == end_excerpt.id { buffer_edits @@ -360,10 +388,18 @@ impl MultiBuffer { .or_insert(Vec::new()) .push((buffer_start..buffer_end, new_text, true)); } else { - let start_excerpt_range = - buffer_start..start_excerpt.range.end.to_offset(&start_excerpt.buffer); - let end_excerpt_range = - end_excerpt.range.start.to_offset(&end_excerpt.buffer)..buffer_end; + let start_excerpt_range = buffer_start + ..start_excerpt + .range + .context + .end + .to_offset(&start_excerpt.buffer); + let end_excerpt_range = end_excerpt + .range + .context + .start + .to_offset(&end_excerpt.buffer) + ..buffer_end; buffer_edits .entry(start_excerpt.buffer_id) .or_insert(Vec::new()) @@ -383,7 +419,7 @@ impl MultiBuffer { .entry(excerpt.buffer_id) .or_insert(Vec::new()) .push(( - excerpt.range.to_offset(&excerpt.buffer), + excerpt.range.context.to_offset(&excerpt.buffer), new_text.clone(), false, )); @@ -523,8 +559,8 @@ impl MultiBuffer { break; } - let mut start = excerpt.range.start.clone(); - let mut end = excerpt.range.end.clone(); + let mut start = excerpt.range.context.start.clone(); + let mut end = excerpt.range.context.end.clone(); if excerpt.id == selection.start.excerpt_id { start = selection.start.text_anchor.clone(); } @@ -644,7 +680,7 @@ impl MultiBuffer { pub fn push_excerpts( &mut self, buffer: ModelHandle, - ranges: impl IntoIterator>, + ranges: impl IntoIterator>, cx: &mut ModelContext, ) -> Vec where @@ -692,7 +728,10 @@ impl MultiBuffer { } } - excerpt_ranges.push(excerpt_start..excerpt_end); + excerpt_ranges.push(ExcerptRange { + context: excerpt_start..excerpt_end, + primary: Some(range), + }); range_counts.push(ranges_in_excerpt); } @@ -722,7 +761,7 @@ impl MultiBuffer { &mut self, prev_excerpt_id: &ExcerptId, buffer: ModelHandle, - ranges: impl IntoIterator>, + ranges: impl IntoIterator>, cx: &mut ModelContext, ) -> Vec where @@ -786,10 +825,17 @@ impl MultiBuffer { if let Err(ix) = buffer_state.excerpts.binary_search(&id) { buffer_state.excerpts.insert(ix, id.clone()); } - let range = buffer_snapshot.anchor_before(&range.start) - ..buffer_snapshot.anchor_after(&range.end); + let range = ExcerptRange { + context: buffer_snapshot.anchor_before(&range.context.start) + ..buffer_snapshot.anchor_after(&range.context.end), + primary: range.primary.map(|primary| { + buffer_snapshot.anchor_before(&primary.start) + ..buffer_snapshot.anchor_after(&primary.end) + }), + }; let excerpt = Excerpt::new( id.clone(), + post_inc(&mut self.next_excerpt_key), buffer_id, buffer_snapshot.clone(), range, @@ -846,7 +892,7 @@ impl MultiBuffer { &self, buffer: &ModelHandle, cx: &AppContext, - ) -> Vec<(ExcerptId, Range)> { + ) -> Vec<(ExcerptId, ExcerptRange)> { let mut excerpts = Vec::new(); let snapshot = self.read(cx); let buffers = self.buffers.borrow(); @@ -894,7 +940,7 @@ impl MultiBuffer { .unwrap() .buffer .clone(), - excerpt.range.clone(), + excerpt.range.context.clone(), ) }) } @@ -914,7 +960,7 @@ impl MultiBuffer { } cursor.item().map(|excerpt| { - let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer); + let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer); let buffer_point = excerpt_start + offset - *cursor.start(); let buffer = self.buffers.borrow()[&excerpt.buffer_id].buffer.clone(); @@ -943,7 +989,7 @@ impl MultiBuffer { if excerpt.has_trailing_newline { end_before_newline -= 1; } - let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer); + let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer); let start = excerpt_start + (cmp::max(start, *cursor.start()) - *cursor.start()); let end = excerpt_start + (cmp::min(end, end_before_newline) - *cursor.start()); let buffer = self.buffers.borrow()[&excerpt.buffer_id].buffer.clone(); @@ -1234,7 +1280,7 @@ impl MultiBuffer { buffer .edits_since_in_range::( old_excerpt.buffer.version(), - old_excerpt.range.clone(), + old_excerpt.range.context.clone(), ) .map(|mut edit| { let excerpt_old_start = cursor.start().1; @@ -1249,6 +1295,7 @@ impl MultiBuffer { new_excerpt = Excerpt::new( id.clone(), + old_excerpt.key, buffer_id, buffer.snapshot(), old_excerpt.range.clone(), @@ -1384,7 +1431,10 @@ impl MultiBuffer { let end_ix = buffer.clip_offset(rng.gen_range(0..=buffer.len()), Bias::Right); let start_ix = buffer.clip_offset(rng.gen_range(0..=end_ix), Bias::Left); - start_ix..end_ix + ExcerptRange { + context: start_ix..end_ix, + primary: None, + } }) .collect::>(); log::info!( @@ -1393,7 +1443,7 @@ impl MultiBuffer { ranges, ranges .iter() - .map(|range| &buffer_text[range.clone()]) + .map(|range| &buffer_text[range.context.clone()]) .collect::>() ); @@ -1465,7 +1515,7 @@ impl MultiBufferSnapshot { cursor.seek(&offset, Bias::Left, &()); let mut excerpt_chunks = cursor.item().map(|excerpt| { let end_before_footer = cursor.start() + excerpt.text_summary.bytes; - let start = excerpt.range.start.to_offset(&excerpt.buffer); + let start = excerpt.range.context.start.to_offset(&excerpt.buffer); let end = start + (cmp::min(offset, end_before_footer) - cursor.start()); excerpt.buffer.reversed_chunks_in_range(start..end) }); @@ -1476,7 +1526,7 @@ impl MultiBufferSnapshot { excerpt_chunks = Some( excerpt .buffer - .reversed_chunks_in_range(excerpt.range.clone()), + .reversed_chunks_in_range(excerpt.range.context.clone()), ); } @@ -1581,7 +1631,7 @@ impl MultiBufferSnapshot { let mut cursor = self.excerpts.cursor::(); cursor.seek(&offset, Bias::Right, &()); let overshoot = if let Some(excerpt) = cursor.item() { - let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer); + let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer); let buffer_offset = excerpt .buffer .clip_offset(excerpt_start + (offset - cursor.start()), bias); @@ -1600,7 +1650,7 @@ impl MultiBufferSnapshot { let mut cursor = self.excerpts.cursor::(); cursor.seek(&point, Bias::Right, &()); let overshoot = if let Some(excerpt) = cursor.item() { - let excerpt_start = excerpt.range.start.to_point(&excerpt.buffer); + let excerpt_start = excerpt.range.context.start.to_point(&excerpt.buffer); let buffer_point = excerpt .buffer .clip_point(excerpt_start + (point - cursor.start()), bias); @@ -1621,7 +1671,7 @@ impl MultiBufferSnapshot { let overshoot = if let Some(excerpt) = cursor.item() { let excerpt_start = excerpt .buffer - .offset_to_point_utf16(excerpt.range.start.to_offset(&excerpt.buffer)); + .offset_to_point_utf16(excerpt.range.context.start.to_offset(&excerpt.buffer)); let buffer_point = excerpt .buffer .clip_point_utf16(excerpt_start + (point - cursor.start()), bias); @@ -1690,8 +1740,8 @@ impl MultiBufferSnapshot { if let Some(excerpt) = cursor.item() { let (start_offset, start_point) = cursor.start(); let overshoot = offset - start_offset; - let excerpt_start_offset = excerpt.range.start.to_offset(&excerpt.buffer); - let excerpt_start_point = excerpt.range.start.to_point(&excerpt.buffer); + let excerpt_start_offset = excerpt.range.context.start.to_offset(&excerpt.buffer); + let excerpt_start_point = excerpt.range.context.start.to_point(&excerpt.buffer); let buffer_point = excerpt .buffer .offset_to_point(excerpt_start_offset + overshoot); @@ -1711,8 +1761,8 @@ impl MultiBufferSnapshot { if let Some(excerpt) = cursor.item() { let (start_offset, start_point) = cursor.start(); let overshoot = offset - start_offset; - let excerpt_start_offset = excerpt.range.start.to_offset(&excerpt.buffer); - let excerpt_start_point = excerpt.range.start.to_point_utf16(&excerpt.buffer); + let excerpt_start_offset = excerpt.range.context.start.to_offset(&excerpt.buffer); + let excerpt_start_point = excerpt.range.context.start.to_point_utf16(&excerpt.buffer); let buffer_point = excerpt .buffer .offset_to_point_utf16(excerpt_start_offset + overshoot); @@ -1732,8 +1782,9 @@ impl MultiBufferSnapshot { if let Some(excerpt) = cursor.item() { let (start_offset, start_point) = cursor.start(); let overshoot = point - start_offset; - let excerpt_start_point = excerpt.range.start.to_point(&excerpt.buffer); - let excerpt_start_point_utf16 = excerpt.range.start.to_point_utf16(&excerpt.buffer); + let excerpt_start_point = excerpt.range.context.start.to_point(&excerpt.buffer); + let excerpt_start_point_utf16 = + excerpt.range.context.start.to_point_utf16(&excerpt.buffer); let buffer_point = excerpt .buffer .point_to_point_utf16(excerpt_start_point + overshoot); @@ -1753,8 +1804,8 @@ impl MultiBufferSnapshot { if let Some(excerpt) = cursor.item() { let (start_point, start_offset) = cursor.start(); let overshoot = point - start_point; - let excerpt_start_offset = excerpt.range.start.to_offset(&excerpt.buffer); - let excerpt_start_point = excerpt.range.start.to_point(&excerpt.buffer); + let excerpt_start_offset = excerpt.range.context.start.to_offset(&excerpt.buffer); + let excerpt_start_point = excerpt.range.context.start.to_point(&excerpt.buffer); let buffer_offset = excerpt .buffer .point_to_offset(excerpt_start_point + overshoot); @@ -1774,10 +1825,10 @@ impl MultiBufferSnapshot { if let Some(excerpt) = cursor.item() { let (start_point, start_offset) = cursor.start(); let overshoot = point - start_point; - let excerpt_start_offset = excerpt.range.start.to_offset(&excerpt.buffer); + let excerpt_start_offset = excerpt.range.context.start.to_offset(&excerpt.buffer); let excerpt_start_point = excerpt .buffer - .offset_to_point_utf16(excerpt.range.start.to_offset(&excerpt.buffer)); + .offset_to_point_utf16(excerpt.range.context.start.to_offset(&excerpt.buffer)); let buffer_offset = excerpt .buffer .point_utf16_to_offset(excerpt_start_point + overshoot); @@ -1811,8 +1862,8 @@ impl MultiBufferSnapshot { cursor.seek(&Point::new(row, 0), Bias::Right, &()); if let Some(excerpt) = cursor.item() { let overshoot = row - cursor.start().row; - let excerpt_start = excerpt.range.start.to_point(&excerpt.buffer); - let excerpt_end = excerpt.range.end.to_point(&excerpt.buffer); + let excerpt_start = excerpt.range.context.start.to_point(&excerpt.buffer); + let excerpt_end = excerpt.range.context.end.to_point(&excerpt.buffer); let buffer_row = excerpt_start.row + overshoot; let line_start = Point::new(buffer_row, 0); let line_end = Point::new(buffer_row, excerpt.buffer.line_len(buffer_row)); @@ -1847,7 +1898,7 @@ impl MultiBufferSnapshot { end_before_newline -= 1; } - let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer); + let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer); let start_in_excerpt = excerpt_start + (range.start - cursor.start()); let end_in_excerpt = excerpt_start + (cmp::min(end_before_newline, range.end) - cursor.start()); @@ -1881,7 +1932,7 @@ impl MultiBufferSnapshot { if let Some(excerpt) = cursor.item() { range.end = cmp::max(*cursor.start(), range.end); - let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer); + let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer); let end_in_excerpt = excerpt_start + (range.end - cursor.start()); summary.add_assign( &excerpt @@ -1907,8 +1958,9 @@ impl MultiBufferSnapshot { let mut position = D::from_text_summary(&cursor.start().text); if let Some(excerpt) = cursor.item() { if excerpt.id == anchor.excerpt_id { - let excerpt_buffer_start = excerpt.range.start.summary::(&excerpt.buffer); - let excerpt_buffer_end = excerpt.range.end.summary::(&excerpt.buffer); + let excerpt_buffer_start = + excerpt.range.context.start.summary::(&excerpt.buffer); + let excerpt_buffer_end = excerpt.range.context.end.summary::(&excerpt.buffer); let buffer_position = cmp::min( excerpt_buffer_end, anchor.text_anchor.summary::(&excerpt.buffer), @@ -1954,8 +2006,10 @@ impl MultiBufferSnapshot { let position = D::from_text_summary(&cursor.start().text); if let Some(excerpt) = cursor.item() { if excerpt.id == *excerpt_id { - let excerpt_buffer_start = excerpt.range.start.summary::(&excerpt.buffer); - let excerpt_buffer_end = excerpt.range.end.summary::(&excerpt.buffer); + let excerpt_buffer_start = + excerpt.range.context.start.summary::(&excerpt.buffer); + let excerpt_buffer_end = + excerpt.range.context.end.summary::(&excerpt.buffer); summaries.extend( excerpt .buffer @@ -2036,10 +2090,14 @@ impl MultiBufferSnapshot { anchor = if let Some(excerpt) = next_excerpt { let mut text_anchor = excerpt .range + .context .start .bias(anchor.text_anchor.bias, &excerpt.buffer); - if text_anchor.cmp(&excerpt.range.end, &excerpt.buffer).is_gt() { - text_anchor = excerpt.range.end.clone(); + if text_anchor + .cmp(&excerpt.range.context.end, &excerpt.buffer) + .is_gt() + { + text_anchor = excerpt.range.context.end.clone(); } Anchor { buffer_id: Some(excerpt.buffer_id), @@ -2049,13 +2107,14 @@ impl MultiBufferSnapshot { } else if let Some(excerpt) = prev_excerpt { let mut text_anchor = excerpt .range + .context .end .bias(anchor.text_anchor.bias, &excerpt.buffer); if text_anchor - .cmp(&excerpt.range.start, &excerpt.buffer) + .cmp(&excerpt.range.context.start, &excerpt.buffer) .is_lt() { - text_anchor = excerpt.range.start.clone(); + text_anchor = excerpt.range.context.start.clone(); } Anchor { buffer_id: Some(excerpt.buffer_id), @@ -2106,7 +2165,7 @@ impl MultiBufferSnapshot { bias = Bias::Right; } - let buffer_start = excerpt.range.start.to_offset(&excerpt.buffer); + 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)); Anchor { @@ -2196,6 +2255,7 @@ impl MultiBufferSnapshot { let starts_new_buffer = Some(excerpt.buffer_id) != prev_buffer_id; let boundary = ExcerptBoundary { id: excerpt.id.clone(), + key: excerpt.key, row: cursor.start().1.row, buffer: excerpt.buffer.clone(), range: excerpt.range.clone(), @@ -2239,8 +2299,11 @@ impl MultiBufferSnapshot { return None; } - let excerpt_buffer_start = - start_excerpt.range.start.to_offset(&start_excerpt.buffer); + let excerpt_buffer_start = start_excerpt + .range + .context + .start + .to_offset(&start_excerpt.buffer); let excerpt_buffer_end = excerpt_buffer_start + start_excerpt.text_summary.bytes; let start_in_buffer = @@ -2340,8 +2403,11 @@ impl MultiBufferSnapshot { return None; } - let excerpt_buffer_start = - start_excerpt.range.start.to_offset(&start_excerpt.buffer); + let excerpt_buffer_start = start_excerpt + .range + .context + .start + .to_offset(&start_excerpt.buffer); let excerpt_buffer_end = excerpt_buffer_start + start_excerpt.text_summary.bytes; let start_in_buffer = @@ -2427,7 +2493,8 @@ impl MultiBufferSnapshot { cursor .take_while(move |excerpt| excerpt.id <= range.end.excerpt_id) .flat_map(move |excerpt| { - let mut query_range = excerpt.range.start.clone()..excerpt.range.end.clone(); + let mut query_range = + excerpt.range.context.start.clone()..excerpt.range.context.end.clone(); if excerpt.id == range.start.excerpt_id { query_range.start = range.start.text_anchor.clone(); } @@ -2617,15 +2684,18 @@ impl History { impl Excerpt { fn new( id: ExcerptId, + key: usize, buffer_id: usize, buffer: BufferSnapshot, - range: Range, + range: ExcerptRange, has_trailing_newline: bool, ) -> Self { Excerpt { id, - max_buffer_row: range.end.to_point(&buffer).row, - text_summary: buffer.text_summary_for_range::(range.to_offset(&buffer)), + key, + max_buffer_row: range.context.end.to_point(&buffer).row, + text_summary: buffer + .text_summary_for_range::(range.context.to_offset(&buffer)), buffer_id, buffer, range, @@ -2638,7 +2708,7 @@ impl Excerpt { range: Range, language_aware: bool, ) -> ExcerptChunks<'a> { - let content_start = self.range.start.to_offset(&self.buffer); + let content_start = self.range.context.start.to_offset(&self.buffer); let chunks_start = content_start + range.start; let chunks_end = content_start + cmp::min(range.end, self.text_summary.bytes); @@ -2660,7 +2730,7 @@ impl Excerpt { } fn bytes_in_range(&self, range: Range) -> ExcerptBytes { - let content_start = self.range.start.to_offset(&self.buffer); + let content_start = self.range.context.start.to_offset(&self.buffer); let bytes_start = content_start + range.start; let bytes_end = content_start + cmp::min(range.end, self.text_summary.bytes); let footer_height = if self.has_trailing_newline @@ -2680,10 +2750,16 @@ impl Excerpt { } fn clip_anchor(&self, text_anchor: text::Anchor) -> text::Anchor { - if text_anchor.cmp(&self.range.start, &self.buffer).is_lt() { - self.range.start.clone() - } else if text_anchor.cmp(&self.range.end, &self.buffer).is_gt() { - self.range.end.clone() + if text_anchor + .cmp(&self.range.context.start, &self.buffer) + .is_lt() + { + self.range.context.start.clone() + } else if text_anchor + .cmp(&self.range.context.end, &self.buffer) + .is_gt() + { + self.range.context.end.clone() } else { text_anchor } @@ -2693,11 +2769,13 @@ impl Excerpt { Some(self.buffer_id) == anchor.buffer_id && self .range + .context .start .cmp(&anchor.text_anchor, &self.buffer) .is_le() && self .range + .context .end .cmp(&anchor.text_anchor, &self.buffer) .is_ge() @@ -2802,7 +2880,7 @@ impl<'a> MultiBufferRows<'a> { if let Some(excerpt) = self.excerpts.item() { let overshoot = row - self.excerpts.start().row; - let excerpt_start = excerpt.range.start.to_point(&excerpt.buffer).row; + let excerpt_start = excerpt.range.context.start.to_point(&excerpt.buffer).row; self.buffer_row_range.start = excerpt_start + overshoot; self.buffer_row_range.end = excerpt_start + excerpt.text_summary.lines.row + 1; } @@ -2822,7 +2900,7 @@ impl<'a> Iterator for MultiBufferRows<'a> { self.excerpts.item()?; self.excerpts.next(&()); let excerpt = self.excerpts.item()?; - self.buffer_row_range.start = excerpt.range.start.to_point(&excerpt.buffer).row; + self.buffer_row_range.start = excerpt.range.context.start.to_point(&excerpt.buffer).row; self.buffer_row_range.end = self.buffer_row_range.start + excerpt.text_summary.lines.row + 1; } @@ -3079,7 +3157,14 @@ mod tests { let subscription = multibuffer.update(cx, |multibuffer, cx| { let subscription = multibuffer.subscribe(); - multibuffer.push_excerpts(buffer_1.clone(), [Point::new(1, 2)..Point::new(2, 5)], cx); + multibuffer.push_excerpts( + buffer_1.clone(), + [ExcerptRange { + context: Point::new(1, 2)..Point::new(2, 5), + primary: None, + }], + cx, + ); assert_eq!( subscription.consume().into_inner(), [Edit { @@ -3088,8 +3173,22 @@ mod tests { }] ); - multibuffer.push_excerpts(buffer_1.clone(), [Point::new(3, 3)..Point::new(4, 4)], cx); - multibuffer.push_excerpts(buffer_2.clone(), [Point::new(3, 1)..Point::new(3, 3)], cx); + multibuffer.push_excerpts( + buffer_1.clone(), + [ExcerptRange { + context: Point::new(3, 3)..Point::new(4, 4), + primary: None, + }], + cx, + ); + multibuffer.push_excerpts( + buffer_2.clone(), + [ExcerptRange { + context: Point::new(3, 1)..Point::new(3, 3), + primary: None, + }], + cx, + ); assert_eq!( subscription.consume().into_inner(), [Edit { @@ -3253,7 +3352,7 @@ mod tests { boundary.row, boundary .buffer - .text_for_range(boundary.range) + .text_for_range(boundary.range.context) .collect::(), boundary.starts_new_buffer, ) @@ -3334,8 +3433,22 @@ mod tests { let buffer_2 = cx.add_model(|cx| Buffer::new(0, "efghi", cx)); let multibuffer = cx.add_model(|cx| { let mut multibuffer = MultiBuffer::new(0); - multibuffer.push_excerpts(buffer_1.clone(), [0..4], cx); - multibuffer.push_excerpts(buffer_2.clone(), [0..5], cx); + multibuffer.push_excerpts( + buffer_1.clone(), + [ExcerptRange { + context: 0..4, + primary: None, + }], + cx, + ); + multibuffer.push_excerpts( + buffer_2.clone(), + [ExcerptRange { + context: 0..5, + primary: None, + }], + cx, + ); multibuffer }); let old_snapshot = multibuffer.read(cx).snapshot(cx); @@ -3385,7 +3498,14 @@ mod tests { buffer_1.update(cx, |buffer, cx| buffer.edit([(4..4, "123")], cx)); let excerpt_id_1 = multibuffer.update(cx, |multibuffer, cx| { multibuffer - .push_excerpts(buffer_1.clone(), [0..7], cx) + .push_excerpts( + buffer_1.clone(), + [ExcerptRange { + context: 0..7, + primary: None, + }], + cx, + ) .pop() .unwrap() }); @@ -3397,7 +3517,24 @@ mod tests { let (excerpt_id_2, excerpt_id_3) = multibuffer.update(cx, |multibuffer, cx| { multibuffer.remove_excerpts([&excerpt_id_1], cx); let mut ids = multibuffer - .push_excerpts(buffer_2.clone(), [0..4, 6..10, 12..16], cx) + .push_excerpts( + buffer_2.clone(), + [ + ExcerptRange { + context: 0..4, + primary: None, + }, + ExcerptRange { + context: 6..10, + primary: None, + }, + ExcerptRange { + context: 12..16, + primary: None, + }, + ], + cx, + ) .into_iter(); (ids.next().unwrap(), ids.next().unwrap()) }); @@ -3437,7 +3574,15 @@ mod tests { let excerpt_id_5 = multibuffer.update(cx, |multibuffer, cx| { multibuffer.remove_excerpts([&excerpt_id_3], cx); multibuffer - .insert_excerpts_after(&excerpt_id_3, buffer_2.clone(), [5..8], cx) + .insert_excerpts_after( + &excerpt_id_3, + buffer_2.clone(), + [ExcerptRange { + context: 5..8, + primary: None, + }], + cx, + ) .pop() .unwrap() }); @@ -3584,7 +3729,10 @@ mod tests { .insert_excerpts_after( &prev_excerpt_id, buffer_handle.clone(), - [start_ix..end_ix], + [ExcerptRange { + context: start_ix..end_ix, + primary: None, + }], cx, ) .pop() @@ -3893,8 +4041,22 @@ mod tests { let multibuffer = cx.add_model(|_| MultiBuffer::new(0)); let group_interval = multibuffer.read(cx).history.group_interval; multibuffer.update(cx, |multibuffer, cx| { - multibuffer.push_excerpts(buffer_1.clone(), [0..buffer_1.read(cx).len()], cx); - multibuffer.push_excerpts(buffer_2.clone(), [0..buffer_2.read(cx).len()], cx); + multibuffer.push_excerpts( + buffer_1.clone(), + [ExcerptRange { + context: 0..buffer_1.read(cx).len(), + primary: None, + }], + cx, + ); + multibuffer.push_excerpts( + buffer_2.clone(), + [ExcerptRange { + context: 0..buffer_2.read(cx).len(), + primary: None, + }], + cx, + ); }); let mut now = Instant::now(); diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 38dbaa29fde63e8a9b42e0cdc6b0a39e9ce06d2d..425bff2242dd9fa7f4c8494d363d2e98a0a4f13b 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -49,7 +49,7 @@ lazy_static! { pub struct Buffer { text: TextBuffer, - file: Option>, + file: Option>, saved_version: clock::Global, saved_mtime: SystemTime, language: Option>, @@ -72,7 +72,7 @@ pub struct Buffer { pub struct BufferSnapshot { text: text::BufferSnapshot, tree: Option, - path: Option>, + file: Option>, diagnostics: DiagnosticSet, diagnostics_update_count: usize, file_update_count: usize, @@ -152,7 +152,7 @@ pub enum Event { Closed, } -pub trait File { +pub trait File: Send + Sync { fn as_local(&self) -> Option<&dyn LocalFile>; fn is_local(&self) -> bool { @@ -306,7 +306,7 @@ impl Buffer { pub fn from_file>>( replica_id: ReplicaId, base_text: T, - file: Box, + file: Arc, cx: &mut ModelContext, ) -> Self { Self::build( @@ -322,7 +322,7 @@ impl Buffer { pub fn from_proto( replica_id: ReplicaId, message: proto::BufferState, - file: Option>, + file: Option>, cx: &mut ModelContext, ) -> Result { let buffer = TextBuffer::new( @@ -403,7 +403,7 @@ impl Buffer { self } - fn build(buffer: TextBuffer, file: Option>) -> Self { + fn build(buffer: TextBuffer, file: Option>) -> Self { let saved_mtime; if let Some(file) = file.as_ref() { saved_mtime = file.mtime(); @@ -438,7 +438,7 @@ impl Buffer { BufferSnapshot { text: self.text.snapshot(), tree: self.syntax_tree(), - path: self.file.as_ref().map(|f| f.path().clone()), + file: self.file.clone(), remote_selections: self.remote_selections.clone(), diagnostics: self.diagnostics.clone(), diagnostics_update_count: self.diagnostics_update_count, @@ -496,7 +496,7 @@ impl Buffer { &mut self, version: clock::Global, mtime: SystemTime, - new_file: Option>, + new_file: Option>, cx: &mut ModelContext, ) { self.saved_mtime = mtime; @@ -550,7 +550,7 @@ impl Buffer { pub fn file_updated( &mut self, - new_file: Box, + new_file: Arc, cx: &mut ModelContext, ) -> Task<()> { let old_file = if let Some(file) = self.file.as_ref() { @@ -1980,8 +1980,8 @@ impl BufferSnapshot { self.selections_update_count } - pub fn path(&self) -> Option<&Arc> { - self.path.as_ref() + pub fn file(&self) -> Option<&dyn File> { + self.file.as_deref() } pub fn file_update_count(&self) -> usize { @@ -1994,7 +1994,7 @@ impl Clone for BufferSnapshot { Self { text: self.text.clone(), tree: self.tree.clone(), - path: self.path.clone(), + file: self.file.clone(), remote_selections: self.remote_selections.clone(), diagnostics: self.diagnostics.clone(), selections_update_count: self.selections_update_count, diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index c502b1eccc4ea52083b13a05dda7de7d61901343..63a77f2642858d58e05a4dc7bfcefb1591c29a02 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -4013,7 +4013,7 @@ impl Project { }) .log_err(); } - buffer.file_updated(Box::new(new_file), cx).detach(); + buffer.file_updated(Arc::new(new_file), cx).detach(); } }); } else { @@ -4565,7 +4565,7 @@ impl Project { .and_then(|b| b.upgrade(cx)) .ok_or_else(|| anyhow!("no such buffer"))?; buffer.update(cx, |buffer, cx| { - buffer.file_updated(Box::new(file), cx).detach(); + buffer.file_updated(Arc::new(file), cx).detach(); }); Ok(()) }) @@ -5089,8 +5089,8 @@ impl Project { anyhow!("no worktree found for id {}", file.worktree_id) })?; buffer_file = - Some(Box::new(File::from_proto(file, worktree.clone(), cx)?) - as Box); + Some(Arc::new(File::from_proto(file, worktree.clone(), cx)?) + as Arc); buffer_worktree = Some(worktree); Ok::<_, anyhow::Error>(()) })?; diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index 599d6f0a2a5778856c8c267bd70f9522655d7e80..1007b43d75eb988815d64f2ca5e50d3b5ab2ce65 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -519,7 +519,7 @@ impl LocalWorktree { let (file, contents) = this .update(&mut cx, |t, cx| t.as_local().unwrap().load(&path, cx)) .await?; - Ok(cx.add_model(|cx| Buffer::from_file(0, contents, Box::new(file), cx))) + Ok(cx.add_model(|cx| Buffer::from_file(0, contents, Arc::new(file), cx))) }) } @@ -648,7 +648,7 @@ impl LocalWorktree { }; buffer_handle.update(&mut cx, |buffer, cx| { - buffer.did_save(version, file.mtime, Some(Box::new(file)), cx); + buffer.did_save(version, file.mtime, Some(Arc::new(file)), cx); }); Ok(()) diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 26c260c4c3d69fbcbe399233c9cc1710ff844f98..ce36e63ad29aebc01891bc64f690c1026d784e46 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -485,7 +485,7 @@ impl BufferSearchBar { ); } else { for excerpt in buffer.excerpt_boundaries_in_range(0..buffer.len()) { - let excerpt_range = excerpt.range.to_offset(&excerpt.buffer); + let excerpt_range = excerpt.range.context.to_offset(&excerpt.buffer); let rope = excerpt.buffer.as_rope().slice(excerpt_range.clone()); ranges.extend(query.search(&rope).await.into_iter().map(|range| { let start = excerpt diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index 8e282100d4b65d2d8f6ad959fe80299fce377e58..80e9a8619f3b3b251fefb5d2ccfdfea7ae74e124 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -454,6 +454,7 @@ pub struct Editor { pub code_actions_indicator: Color, pub unnecessary_code_fade: f32, pub hover_popover: HoverPopover, + pub jump_icon: Interactive, } #[derive(Clone, Deserialize, Default)] @@ -473,7 +474,6 @@ pub struct DiagnosticHeader { pub code: ContainedText, pub text_scale_factor: f32, pub icon_width_factor: f32, - pub jump_icon: Interactive, } #[derive(Clone, Deserialize, Default)] diff --git a/styles/src/styleTree/editor.ts b/styles/src/styleTree/editor.ts index 14e7f9449fa1b321d88870a34a037cccbaeefbb5..9637e969d188ef6e32f58f7906abd49bb62fc7e4 100644 --- a/styles/src/styleTree/editor.ts +++ b/styles/src/styleTree/editor.ts @@ -101,14 +101,6 @@ export default function editor(theme: Theme) { background: backgroundColor(theme, 300), iconWidthFactor: 1.5, textScaleFactor: 0.857, // NateQ: Will we need dynamic sizing for text? If so let's create tokens for these. - jumpIcon: { - color: iconColor(theme, "primary"), - iconWidth: 10, - buttonWidth: 10, - hover: { - color: iconColor(theme, "active") - } - }, border: border(theme, "secondary", { bottom: true, top: true, @@ -147,6 +139,14 @@ export default function editor(theme: Theme) { invalidInformationDiagnostic: diagnostic(theme, "muted"), invalidWarningDiagnostic: diagnostic(theme, "muted"), hover_popover: hoverPopover(theme), + jumpIcon: { + color: iconColor(theme, "primary"), + iconWidth: 10, + buttonWidth: 10, + hover: { + color: iconColor(theme, "active") + } + }, syntax, }; }