mirror of
https://github.com/zed-industries/zed.git
synced 2026-07-09 16:00:35 +00:00
multi_buffer: Don't eagerly clone BufferSnapshot in range_to_buffer_ranges (#59190)
Both cloning and dropping of these has quite a bit of overhead (despite them being snapshots), so avoid where possible, especially in display map syncing Release Notes: - N/A or Added/Fixed/Improved ...
This commit is contained in:
parent
992f395c3d
commit
b6c7496aea
30 changed files with 78 additions and 85 deletions
|
|
@ -1245,7 +1245,7 @@ impl<T: PromptCompletionProviderDelegate> PromptCompletionProvider<T> {
|
|||
let path_prefix = if include_root_name {
|
||||
worktree.read(cx).root_name().into()
|
||||
} else {
|
||||
RelPath::empty().into()
|
||||
RelPath::empty_arc()
|
||||
};
|
||||
Match::File(FileMatch {
|
||||
mat: fuzzy::PathMatch {
|
||||
|
|
@ -2143,9 +2143,9 @@ pub(crate) fn search_files(
|
|||
project
|
||||
.worktree_for_id(project_path.worktree_id, cx)
|
||||
.map(|wt| wt.read(cx).root_name().into())
|
||||
.unwrap_or_else(|| RelPath::empty().into())
|
||||
.unwrap_or_else(|| RelPath::empty_arc())
|
||||
} else {
|
||||
RelPath::empty().into()
|
||||
RelPath::empty_arc()
|
||||
};
|
||||
|
||||
FileMatch {
|
||||
|
|
@ -2167,7 +2167,7 @@ pub(crate) fn search_files(
|
|||
let path_prefix: Arc<RelPath> = if include_root_name {
|
||||
worktree.root_name().into()
|
||||
} else {
|
||||
RelPath::empty().into()
|
||||
RelPath::empty_arc()
|
||||
};
|
||||
worktree.entries(false, 0).map(move |entry| FileMatch {
|
||||
mat: PathMatch {
|
||||
|
|
|
|||
|
|
@ -184,6 +184,9 @@ impl Editor {
|
|||
.range_to_buffer_ranges(visible_range)
|
||||
.into_iter()
|
||||
.filter(|(_, excerpt_visible_range, _)| !excerpt_visible_range.is_empty())
|
||||
.map(|(buffer_snapshot, buffer_offset_range, excerpt_range)| {
|
||||
(buffer_snapshot.clone(), buffer_offset_range, excerpt_range)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -773,6 +773,8 @@ impl BlockMap {
|
|||
|
||||
edits = self.deferred_edits.take().compose(edits);
|
||||
|
||||
let max_point = wrap_snapshot.max_point();
|
||||
|
||||
// Handle changing the last excerpt if it is empty.
|
||||
if buffer.trailing_excerpt_update_count()
|
||||
!= self
|
||||
|
|
@ -781,7 +783,6 @@ impl BlockMap {
|
|||
.buffer_snapshot()
|
||||
.trailing_excerpt_update_count()
|
||||
{
|
||||
let max_point = wrap_snapshot.max_point();
|
||||
let edit_start = wrap_snapshot.prev_row_boundary(max_point);
|
||||
let edit_end = max_point.row() + WrapRow(1); // this is end of file
|
||||
edits = edits.compose([WrapEdit {
|
||||
|
|
@ -829,7 +830,7 @@ impl BlockMap {
|
|||
let mut my_start = wrap_snapshot.make_wrap_point(my_start, Bias::Left);
|
||||
let mut my_end = wrap_snapshot.make_wrap_point(my_end, Bias::Left);
|
||||
// TODO(split-diff) should use trailing_excerpt_update_count for the second case
|
||||
if my_end.column() > 0 || my_end == wrap_snapshot.max_point() {
|
||||
if my_end.column() > 0 || my_end == max_point {
|
||||
*my_end.row_mut() += 1;
|
||||
*my_end.column_mut() = 0;
|
||||
}
|
||||
|
|
@ -837,7 +838,7 @@ impl BlockMap {
|
|||
// Empty edits won't survive Patch::compose, but we still need to make sure
|
||||
// we recompute spacers when we get them.
|
||||
if my_start.row() == my_end.row() {
|
||||
if my_end.row() <= wrap_snapshot.max_point().row() {
|
||||
if my_end.row() <= max_point.row() {
|
||||
*my_end.row_mut() += 1;
|
||||
*my_end.column_mut() = 0;
|
||||
} else if my_start.row() > WrapRow(0) {
|
||||
|
|
@ -1006,7 +1007,7 @@ impl BlockMap {
|
|||
};
|
||||
|
||||
let end_bound;
|
||||
let end_block_ix = if new_end > wrap_snapshot.max_point().row() {
|
||||
let end_block_ix = if new_end > max_point.row() {
|
||||
end_bound = Bound::Unbounded;
|
||||
self.custom_blocks.len()
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -72,6 +72,9 @@ impl TabMap {
|
|||
old_snapshot.tab_size = tab_size;
|
||||
return (old_snapshot.clone(), vec![]);
|
||||
}
|
||||
|
||||
let old_fold_max_point = old_snapshot.fold_snapshot.max_point();
|
||||
|
||||
// Expand each edit to include the next tab on the same line as the edit,
|
||||
// and any subsequent tabs on that line that moved across the tab expansion
|
||||
// boundary.
|
||||
|
|
@ -89,11 +92,9 @@ impl TabMap {
|
|||
// expansion boundary (transitioning between expanded and non-expanded).
|
||||
for fold_edit in &mut fold_edits {
|
||||
let old_end = fold_edit.old.end.to_point(&old_snapshot.fold_snapshot);
|
||||
let old_end_row_successor_offset = cmp::min(
|
||||
FoldPoint::new(old_end.row() + 1, 0),
|
||||
old_snapshot.fold_snapshot.max_point(),
|
||||
)
|
||||
.to_offset(&old_snapshot.fold_snapshot);
|
||||
let old_end_row_successor_offset =
|
||||
cmp::min(FoldPoint::new(old_end.row() + 1, 0), old_fold_max_point)
|
||||
.to_offset(&old_snapshot.fold_snapshot);
|
||||
let new_end = fold_edit.new.end.to_point(&fold_snapshot);
|
||||
|
||||
let mut offset_from_edit = 0;
|
||||
|
|
@ -211,7 +212,7 @@ impl std::ops::Deref for TabSnapshot {
|
|||
}
|
||||
|
||||
impl TabSnapshot {
|
||||
#[ztracing::instrument(skip_all)]
|
||||
#[inline]
|
||||
pub fn buffer_snapshot(&self) -> &MultiBufferSnapshot {
|
||||
&self.fold_snapshot.inlay_snapshot.buffer
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use super::{
|
|||
use futures_lite::future::yield_now;
|
||||
use gpui::{App, AppContext as _, Context, Entity, Font, LineWrapper, Pixels, Task};
|
||||
use language::{LanguageAwareStyling, Point};
|
||||
use multi_buffer::{MultiBufferSnapshot, RowInfo};
|
||||
use multi_buffer::RowInfo;
|
||||
use std::{cmp, collections::VecDeque, mem, ops::Range, sync::LazyLock, time::Duration};
|
||||
use sum_tree::{Bias, Cursor, Dimensions, SumTree};
|
||||
use text::Patch;
|
||||
|
|
@ -381,11 +381,6 @@ impl WrapSnapshot {
|
|||
}
|
||||
}
|
||||
|
||||
#[ztracing::instrument(skip_all)]
|
||||
pub fn buffer_snapshot(&self) -> &MultiBufferSnapshot {
|
||||
self.tab_snapshot.buffer_snapshot()
|
||||
}
|
||||
|
||||
#[ztracing::instrument(skip_all)]
|
||||
fn interpolate(&mut self, new_tab_snapshot: TabSnapshot, tab_edits: &[TabEdit]) -> WrapPatch {
|
||||
let mut new_transforms;
|
||||
|
|
|
|||
|
|
@ -534,13 +534,15 @@ pub struct EditorStyle {
|
|||
|
||||
impl Default for EditorStyle {
|
||||
fn default() -> Self {
|
||||
static NONE_SYNTAX: std::sync::LazyLock<Arc<SyntaxTheme>> =
|
||||
std::sync::LazyLock::new(|| Arc::new(SyntaxTheme::default()));
|
||||
Self {
|
||||
background: Hsla::default(),
|
||||
border: Hsla::default(),
|
||||
local_player: PlayerColor::default(),
|
||||
text: TextStyle::default(),
|
||||
scrollbar_width: Pixels::default(),
|
||||
syntax: Default::default(),
|
||||
syntax: NONE_SYNTAX.clone(),
|
||||
// HACK: Status colors don't have a real default.
|
||||
// We should look into removing the status colors from the editor
|
||||
// style and retrieve them directly from the theme.
|
||||
|
|
|
|||
|
|
@ -2376,7 +2376,7 @@ impl NewlineConfig {
|
|||
.range_to_buffer_ranges(range.start..range.end)
|
||||
.as_slice()
|
||||
{
|
||||
[(buffer_snapshot, range, _)] => (buffer_snapshot.clone(), range.clone()),
|
||||
[(buffer_snapshot, range, _)] => (*buffer_snapshot, range.clone()),
|
||||
_ => return false,
|
||||
};
|
||||
let pair = {
|
||||
|
|
|
|||
|
|
@ -2255,7 +2255,7 @@ mod tests {
|
|||
#[gpui::test]
|
||||
fn test_path_for_file(cx: &mut App) {
|
||||
let file: Arc<dyn language::File> = Arc::new(TestFile {
|
||||
path: RelPath::empty().into(),
|
||||
path: RelPath::empty_arc(),
|
||||
root_name: String::new(),
|
||||
local_root: None,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -187,15 +187,15 @@ fn patches_for_range<F>(
|
|||
where
|
||||
F: Fn(&BufferDiffSnapshot, RangeInclusive<Point>, &text::BufferSnapshot) -> Patch<Point>,
|
||||
{
|
||||
struct PendingExcerpt {
|
||||
source_buffer_snapshot: language::BufferSnapshot,
|
||||
struct PendingExcerpt<'a> {
|
||||
source_buffer_snapshot: &'a language::BufferSnapshot,
|
||||
source_excerpt_range: ExcerptRange<text::Anchor>,
|
||||
buffer_point_range: Range<Point>,
|
||||
}
|
||||
|
||||
let mut result = Vec::new();
|
||||
let mut current_buffer_id: Option<BufferId> = None;
|
||||
let mut pending_excerpts: Vec<PendingExcerpt> = Vec::new();
|
||||
let mut pending_excerpts: Vec<PendingExcerpt<'_>> = Vec::new();
|
||||
let mut union_context_start: Option<Point> = None;
|
||||
let mut union_context_end: Option<Point> = None;
|
||||
|
||||
|
|
|
|||
|
|
@ -764,7 +764,7 @@ fn matching_history_items<'a>(
|
|||
candidates_paths.remove_entry(&project_path).or_else(|| {
|
||||
candidates_paths.remove_entry(&ProjectPath {
|
||||
worktree_id,
|
||||
path: RelPath::empty().into_arc(),
|
||||
path: RelPath::empty_arc(),
|
||||
})
|
||||
})?;
|
||||
// Key with path_match.path so the deduplication check in push_new_matches
|
||||
|
|
@ -824,7 +824,7 @@ fn project_path_for_search_match(
|
|||
.worktree_for_id(worktree_id, cx)
|
||||
.is_some_and(|worktree| worktree.read(cx).is_single_file())
|
||||
{
|
||||
RelPath::empty().into_arc()
|
||||
RelPath::empty_arc()
|
||||
} else {
|
||||
path_match.path.clone()
|
||||
};
|
||||
|
|
@ -1457,7 +1457,7 @@ impl FileFinderDelegate {
|
|||
positions: Vec::new(),
|
||||
worktree_id: worktree.read(cx).id().to_usize(),
|
||||
path: relative_path,
|
||||
path_prefix: RelPath::empty().into(),
|
||||
path_prefix: RelPath::empty_arc(),
|
||||
is_dir: false, // File finder doesn't support directories
|
||||
distance_to_relative_ancestor: usize::MAX,
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -2641,7 +2641,7 @@ async fn test_single_file_search_result_split_open(cx: &mut gpui::TestAppContext
|
|||
active_editor.read(cx).active_project_path(cx),
|
||||
Some(ProjectPath {
|
||||
worktree_id,
|
||||
path: RelPath::empty().into_arc(),
|
||||
path: RelPath::empty_arc(),
|
||||
}),
|
||||
"Should split-open the single-file worktree root with an empty relative path"
|
||||
);
|
||||
|
|
|
|||
|
|
@ -605,7 +605,7 @@ mod tests {
|
|||
worktree_id: 0,
|
||||
positions: positions.clone(),
|
||||
path: candidate.path.into(),
|
||||
path_prefix: RelPath::empty().into(),
|
||||
path_prefix: RelPath::empty_arc(),
|
||||
distance_to_relative_ancestor: usize::MAX,
|
||||
is_dir: false,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -116,11 +116,7 @@ pub fn match_fixed_path_set(
|
|||
|
||||
(worktree_root_name, path_prefix_chars, lowercase_pfx)
|
||||
}
|
||||
None => (
|
||||
RelPath::empty().into(),
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
),
|
||||
None => (RelPath::empty_arc(), Default::default(), Default::default()),
|
||||
};
|
||||
|
||||
matcher.match_candidates(
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ fn path_match_helper<'a>(
|
|||
candidate.path.into()
|
||||
},
|
||||
path_prefix: if root_is_file {
|
||||
RelPath::empty().into()
|
||||
RelPath::empty_arc()
|
||||
} else {
|
||||
Arc::clone(path_prefix)
|
||||
},
|
||||
|
|
@ -239,7 +239,7 @@ pub fn match_fixed_path_set(
|
|||
|
||||
let root_is_file = worktree_root_name.is_some() && candidates.iter().all(|c| c.path.is_empty());
|
||||
|
||||
let path_prefix = worktree_root_name.unwrap_or_else(|| RelPath::empty().into());
|
||||
let path_prefix = worktree_root_name.unwrap_or_else(|| RelPath::empty_arc());
|
||||
|
||||
let mut results = Vec::new();
|
||||
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ impl DivInspector {
|
|||
|
||||
let project_path = worktree.read_with(cx, |worktree, _cx| ProjectPath {
|
||||
worktree_id: worktree.id(),
|
||||
path: RelPath::empty().into(),
|
||||
path: RelPath::empty_arc(),
|
||||
});
|
||||
|
||||
let buffer = project
|
||||
|
|
|
|||
|
|
@ -889,7 +889,7 @@ impl ContextProvider for PythonContextProvider {
|
|||
.as_ref()
|
||||
.and_then(|f| f.path().parent())
|
||||
.map(Arc::from)
|
||||
.unwrap_or_else(|| RelPath::empty().into());
|
||||
.unwrap_or_else(|| RelPath::empty_arc());
|
||||
|
||||
toolchains
|
||||
.active_toolchain(worktree_id, file_path, "Python".into(), cx)
|
||||
|
|
|
|||
|
|
@ -3610,7 +3610,7 @@ impl MultiBufferSnapshot {
|
|||
&self,
|
||||
range: Range<T>,
|
||||
) -> Vec<(
|
||||
BufferSnapshot,
|
||||
&BufferSnapshot,
|
||||
Range<BufferOffset>,
|
||||
ExcerptRange<text::Anchor>,
|
||||
)> {
|
||||
|
|
@ -3621,7 +3621,7 @@ impl MultiBufferSnapshot {
|
|||
cursor.seek(&start);
|
||||
|
||||
let mut result: Vec<(
|
||||
BufferSnapshot,
|
||||
&BufferSnapshot,
|
||||
Range<BufferOffset>,
|
||||
ExcerptRange<text::Anchor>,
|
||||
)> = Vec::new();
|
||||
|
|
@ -3653,7 +3653,7 @@ impl MultiBufferSnapshot {
|
|||
{
|
||||
prev.1.end = end;
|
||||
} else {
|
||||
result.push((region.buffer.clone(), start..end, excerpt_range));
|
||||
result.push((region.buffer, start..end, excerpt_range));
|
||||
}
|
||||
}
|
||||
cursor.next();
|
||||
|
|
@ -3676,11 +3676,7 @@ impl MultiBufferSnapshot {
|
|||
|| prev_excerpt.context.start != excerpt_range.context.start
|
||||
})
|
||||
{
|
||||
result.push((
|
||||
buffer_snapshot.clone(),
|
||||
buffer_offset..buffer_offset,
|
||||
excerpt_range,
|
||||
));
|
||||
result.push((buffer_snapshot, buffer_offset..buffer_offset, excerpt_range));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,14 +26,14 @@ impl PathKey {
|
|||
pub fn min() -> Self {
|
||||
Self {
|
||||
sort_prefix: None,
|
||||
path: RelPath::empty().into_arc(),
|
||||
path: RelPath::empty_arc(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sorted(sort_prefix: u64) -> Self {
|
||||
Self {
|
||||
sort_prefix: Some(sort_prefix),
|
||||
path: RelPath::empty().into_arc(),
|
||||
path: RelPath::empty_arc(),
|
||||
}
|
||||
}
|
||||
pub fn with_sort_prefix(sort_prefix: u64, path: Arc<RelPath>) -> Self {
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ impl ManifestTree {
|
|||
.and_then(|manifest_name| self.root_for_path(project_path, manifest_name, delegate, cx))
|
||||
.unwrap_or_else(|| ProjectPath {
|
||||
worktree_id,
|
||||
path: RelPath::empty().into(),
|
||||
path: RelPath::empty_arc(),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -338,7 +338,7 @@ impl LanguageServerTree {
|
|||
.entry(worktree_id)
|
||||
.or_default()
|
||||
.roots
|
||||
.entry(RelPath::empty().into())
|
||||
.entry(RelPath::empty_arc())
|
||||
.or_default()
|
||||
.entry(node.disposition.server_name.clone())
|
||||
.or_insert_with(|| (node, BTreeSet::new()))
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ impl ProjectPath {
|
|||
pub fn root_path(worktree_id: WorktreeId) -> Self {
|
||||
Self {
|
||||
worktree_id,
|
||||
path: RelPath::empty().into(),
|
||||
path: RelPath::empty_arc(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6385,7 +6385,7 @@ impl<'a> fuzzy::PathMatchCandidateSet<'a> for PathMatchCandidateSet {
|
|||
if self.snapshot.root_entry().is_some_and(|e| e.is_file()) || self.include_root_name {
|
||||
self.snapshot.root_name().into()
|
||||
} else {
|
||||
RelPath::empty().into()
|
||||
RelPath::empty_arc()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6460,7 +6460,7 @@ impl<'a> fuzzy_nucleo::PathMatchCandidateSet<'a> for PathMatchCandidateSet {
|
|||
if self.snapshot.root_entry().is_some_and(|e| e.is_file()) || self.include_root_name {
|
||||
self.snapshot.root_name().into()
|
||||
} else {
|
||||
RelPath::empty().into()
|
||||
RelPath::empty_arc()
|
||||
}
|
||||
}
|
||||
fn root_is_file(&self) -> bool {
|
||||
|
|
|
|||
|
|
@ -1202,7 +1202,7 @@ mod tests {
|
|||
let other_worktree = WorktreeId::from_usize(2);
|
||||
let kind = TaskSourceKind::Worktree {
|
||||
id: task_worktree,
|
||||
directory_in_worktree: RelPath::empty().into_arc(),
|
||||
directory_in_worktree: RelPath::empty_arc(),
|
||||
id_base: Cow::Borrowed("worktree"),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ impl ToolchainStore {
|
|||
let path = if let Some(path) = envelope.payload.path {
|
||||
RelPath::from_proto(&path)?
|
||||
} else {
|
||||
RelPath::empty().into()
|
||||
RelPath::empty_arc()
|
||||
};
|
||||
Ok(this.activate_toolchain(ProjectPath { worktree_id, path }, toolchain, cx))
|
||||
})?
|
||||
|
|
|
|||
|
|
@ -433,7 +433,7 @@ impl WorktreeStore {
|
|||
Task::ready(Ok((tree, relative_path)))
|
||||
} else {
|
||||
let worktree = self.create_worktree(abs_path, visible, cx);
|
||||
cx.background_spawn(async move { Ok((worktree.await?, RelPath::empty().into())) })
|
||||
cx.background_spawn(async move { Ok((worktree.await?, RelPath::empty_arc())) })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@ pub fn python_env_kernel_specifications(
|
|||
let toolchains = project.read(cx).available_toolchains(
|
||||
ProjectPath {
|
||||
worktree_id,
|
||||
path: RelPath::empty().into(),
|
||||
path: RelPath::empty_arc(),
|
||||
},
|
||||
python_language,
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ impl ReplStore {
|
|||
let active_toolchain = project.read(cx).active_toolchain(
|
||||
ProjectPath {
|
||||
worktree_id,
|
||||
path: RelPath::empty().into(),
|
||||
path: RelPath::empty_arc(),
|
||||
},
|
||||
LanguageName::new_static("Python"),
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -1169,10 +1169,10 @@ impl SettingsStore {
|
|||
) -> impl '_ + Iterator<Item = (Arc<RelPath>, &ProjectSettingsContent)> {
|
||||
self.local_settings
|
||||
.range(
|
||||
(root_id, RelPath::empty().into())
|
||||
(root_id, RelPath::empty_arc())
|
||||
..(
|
||||
WorktreeId::from_usize(root_id.to_usize() + 1),
|
||||
RelPath::empty().into(),
|
||||
RelPath::empty_arc(),
|
||||
),
|
||||
)
|
||||
.map(|((_, path), content)| (path.clone(), &content.project))
|
||||
|
|
@ -2566,7 +2566,7 @@ mod tests {
|
|||
store
|
||||
.set_user_settings(r#"{"preferred_line_length": 0}"#, cx)
|
||||
.unwrap();
|
||||
let local = (WorktreeId::from_usize(0), RelPath::empty().into_arc());
|
||||
let local = (WorktreeId::from_usize(0), RelPath::empty_arc());
|
||||
store
|
||||
.set_local_settings(
|
||||
local.0,
|
||||
|
|
@ -2626,7 +2626,7 @@ mod tests {
|
|||
store.register_setting::<DefaultLanguageSettings>();
|
||||
store.register_setting::<AutoUpdateSetting>();
|
||||
|
||||
let local_1 = (WorktreeId::from_usize(0), RelPath::empty().into_arc());
|
||||
let local_1 = (WorktreeId::from_usize(0), RelPath::empty_arc());
|
||||
|
||||
let local_1_child = (
|
||||
WorktreeId::from_usize(0),
|
||||
|
|
@ -2638,7 +2638,7 @@ mod tests {
|
|||
.into_arc(),
|
||||
);
|
||||
|
||||
let local_2 = (WorktreeId::from_usize(1), RelPath::empty().into_arc());
|
||||
let local_2 = (WorktreeId::from_usize(1), RelPath::empty_arc());
|
||||
let local_2_child = (
|
||||
WorktreeId::from_usize(1),
|
||||
RelPath::new(
|
||||
|
|
@ -2759,11 +2759,11 @@ mod tests {
|
|||
let mut store = SettingsStore::new(cx, &test_settings());
|
||||
store.register_setting::<DefaultLanguageSettings>();
|
||||
|
||||
let wt0_root = (WorktreeId::from_usize(0), RelPath::empty().into_arc());
|
||||
let wt0_root = (WorktreeId::from_usize(0), RelPath::empty_arc());
|
||||
let wt0_child1 = (WorktreeId::from_usize(0), rel_path("child1").into_arc());
|
||||
let wt0_child2 = (WorktreeId::from_usize(0), rel_path("child2").into_arc());
|
||||
|
||||
let wt1_root = (WorktreeId::from_usize(1), RelPath::empty().into_arc());
|
||||
let wt1_root = (WorktreeId::from_usize(1), RelPath::empty_arc());
|
||||
let wt1_subdir = (WorktreeId::from_usize(1), rel_path("subdir").into_arc());
|
||||
|
||||
fn get(content: &SettingsContent) -> &Option<u32> {
|
||||
|
|
@ -2881,15 +2881,13 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_file_ord() {
|
||||
let wt0_root =
|
||||
SettingsFile::Project((WorktreeId::from_usize(0), RelPath::empty().into_arc()));
|
||||
let wt0_root = SettingsFile::Project((WorktreeId::from_usize(0), RelPath::empty_arc()));
|
||||
let wt0_child1 =
|
||||
SettingsFile::Project((WorktreeId::from_usize(0), rel_path("child1").into_arc()));
|
||||
let wt0_child2 =
|
||||
SettingsFile::Project((WorktreeId::from_usize(0), rel_path("child2").into_arc()));
|
||||
|
||||
let wt1_root =
|
||||
SettingsFile::Project((WorktreeId::from_usize(1), RelPath::empty().into_arc()));
|
||||
let wt1_root = SettingsFile::Project((WorktreeId::from_usize(1), RelPath::empty_arc()));
|
||||
let wt1_subdir =
|
||||
SettingsFile::Project((WorktreeId::from_usize(1), rel_path("subdir").into_arc()));
|
||||
|
||||
|
|
|
|||
|
|
@ -2661,7 +2661,7 @@ mod tests {
|
|||
let entry = cx
|
||||
.update(|cx| {
|
||||
wt.update(cx, |wt, cx| {
|
||||
wt.create_entry(RelPath::empty().into(), is_dir, None, cx)
|
||||
wt.create_entry(RelPath::empty_arc(), is_dir, None, cx)
|
||||
})
|
||||
})
|
||||
.await
|
||||
|
|
|
|||
|
|
@ -36,6 +36,12 @@ impl RelPath {
|
|||
Self::new_unchecked("")
|
||||
}
|
||||
|
||||
/// Creates an empty [`RelPath`].
|
||||
pub fn empty_arc() -> Arc<Self> {
|
||||
static EMPTY: std::sync::OnceLock<Arc<RelPath>> = std::sync::OnceLock::new();
|
||||
EMPTY.get_or_init(|| Arc::from(Self::empty())).clone()
|
||||
}
|
||||
|
||||
/// Converts a path with a given style into a [`RelPath`].
|
||||
///
|
||||
/// Returns an error if the path is absolute, or is not valid unicode.
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ impl WorkDirectory {
|
|||
fn path_key(&self) -> PathKey {
|
||||
match self {
|
||||
WorkDirectory::InProject { relative_path } => PathKey(relative_path.clone()),
|
||||
WorkDirectory::AboveProject { .. } => PathKey(RelPath::empty().into()),
|
||||
WorkDirectory::AboveProject { .. } => PathKey(RelPath::empty_arc()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -440,9 +440,7 @@ impl Worktree {
|
|||
abs_path
|
||||
.file_name()
|
||||
.and_then(|f| f.to_str())
|
||||
.map_or(RelPath::empty().into(), |f| {
|
||||
RelPath::unix(f).unwrap().into()
|
||||
}),
|
||||
.map_or(RelPath::empty_arc(), |f| RelPath::unix(f).unwrap().into()),
|
||||
abs_path.clone(),
|
||||
PathStyle::local(),
|
||||
),
|
||||
|
|
@ -471,7 +469,7 @@ impl Worktree {
|
|||
let share_private_files = false;
|
||||
if let Some(metadata) = metadata {
|
||||
let mut entry = Entry::new(
|
||||
RelPath::empty().into(),
|
||||
RelPath::empty_arc(),
|
||||
&metadata,
|
||||
ProjectEntryId::new(&next_entry_id),
|
||||
snapshot.root_char_bag,
|
||||
|
|
@ -529,8 +527,7 @@ impl Worktree {
|
|||
cx.new(|cx: &mut Context<Self>| {
|
||||
let mut snapshot = Snapshot::new(
|
||||
WorktreeId::from_proto(worktree.id),
|
||||
RelPath::from_proto(&worktree.root_name)
|
||||
.unwrap_or_else(|_| RelPath::empty().into()),
|
||||
RelPath::from_proto(&worktree.root_name).unwrap_or_else(|_| RelPath::empty_arc()),
|
||||
Path::new(&worktree.abs_path).into(),
|
||||
path_style,
|
||||
);
|
||||
|
|
@ -1552,7 +1549,7 @@ impl LocalWorktree {
|
|||
}
|
||||
}
|
||||
|
||||
lowest_ancestor.unwrap_or_else(|| RelPath::empty().into())
|
||||
lowest_ancestor.unwrap_or_else(|| RelPath::empty_arc())
|
||||
}
|
||||
|
||||
pub fn create_entry(
|
||||
|
|
@ -2058,9 +2055,7 @@ impl LocalWorktree {
|
|||
.as_path()
|
||||
.file_name()
|
||||
.and_then(|f| f.to_str())
|
||||
.map_or(RelPath::empty().into(), |f| {
|
||||
RelPath::unix(f).unwrap().into()
|
||||
});
|
||||
.map_or(RelPath::empty_arc(), |f| RelPath::unix(f).unwrap().into());
|
||||
self.snapshot.update_abs_path(new_path, root_name);
|
||||
self.restart_background_scanners(cx);
|
||||
}
|
||||
|
|
@ -3698,7 +3693,7 @@ impl<S: Summary> Summary for PathSummary<S> {
|
|||
|
||||
fn zero(cx: Self::Context<'_>) -> Self {
|
||||
Self {
|
||||
max_path: RelPath::empty().into(),
|
||||
max_path: RelPath::empty_arc(),
|
||||
item_summary: S::zero(cx),
|
||||
}
|
||||
}
|
||||
|
|
@ -3955,7 +3950,7 @@ pub struct PathKey(pub Arc<RelPath>);
|
|||
|
||||
impl Default for PathKey {
|
||||
fn default() -> Self {
|
||||
Self(RelPath::empty().into())
|
||||
Self(RelPath::empty_arc())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue