text: Wrap BufferId into a newtype

This commit is contained in:
Piotr Osiewicz
2024-01-29 20:00:47 +01:00
parent 941e838be9
commit 5ab715aac9
34 changed files with 687 additions and 383 deletions
+7 -3
View File
@@ -1007,6 +1007,7 @@ pub mod tests {
use settings::SettingsStore;
use smol::stream::StreamExt;
use std::{env, sync::Arc};
use text::BufferId;
use theme::{LoadThemes, SyntaxTheme};
use util::test::{marked_text_ranges, sample_text};
use Bias::*;
@@ -1467,7 +1468,8 @@ pub mod tests {
cx.update(|cx| init_test(cx, |s| s.defaults.tab_size = Some(2.try_into().unwrap())));
let buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
.with_language(language, cx)
});
cx.condition(&buffer, |buf, _| !buf.is_parsing()).await;
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
@@ -1553,7 +1555,8 @@ pub mod tests {
cx.update(|cx| init_test(cx, |_| {}));
let buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
.with_language(language, cx)
});
cx.condition(&buffer, |buf, _| !buf.is_parsing()).await;
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
@@ -1620,7 +1623,8 @@ pub mod tests {
let (text, highlighted_ranges) = marked_text_ranges(r#"constˇ «a»: B = "c «d»""#, false);
let buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
.with_language(language, cx)
});
cx.condition(&buffer, |buf, _| !buf.is_parsing()).await;
+22 -4
View File
@@ -109,7 +109,7 @@ use std::{
};
pub use sum_tree::Bias;
use sum_tree::TreeMap;
use text::{OffsetUtf16, Rope};
use text::{BufferId, OffsetUtf16, Rope};
use theme::{
observe_buffer_font_size_adjustment, ActiveTheme, PlayerColor, StatusColors, SyntaxTheme,
ThemeColors, ThemeSettings,
@@ -1289,19 +1289,37 @@ impl InlayHintRefreshReason {
impl Editor {
pub fn single_line(cx: &mut ViewContext<Self>) -> Self {
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), String::new()));
let buffer = cx.new_model(|cx| {
Buffer::new(
0,
BufferId::new(cx.entity_id().as_u64()).unwrap(),
String::new(),
)
});
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
Self::new(EditorMode::SingleLine, buffer, None, cx)
}
pub fn multi_line(cx: &mut ViewContext<Self>) -> Self {
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), String::new()));
let buffer = cx.new_model(|cx| {
Buffer::new(
0,
BufferId::new(cx.entity_id().as_u64()).unwrap(),
String::new(),
)
});
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
Self::new(EditorMode::Full, buffer, None, cx)
}
pub fn auto_height(max_lines: usize, cx: &mut ViewContext<Self>) -> Self {
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), String::new()));
let buffer = cx.new_model(|cx| {
Buffer::new(
0,
BufferId::new(cx.entity_id().as_u64()).unwrap(),
String::new(),
)
});
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
Self::new(EditorMode::AutoHeight { max_lines }, buffer, None, cx)
}
+82 -23
View File
@@ -39,7 +39,8 @@ fn test_edit_events(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let buffer = cx.new_model(|cx| {
let mut buffer = language::Buffer::new(0, cx.entity_id().as_u64(), "123456");
let mut buffer =
language::Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "123456");
buffer.set_group_interval(Duration::from_secs(1));
buffer
});
@@ -154,7 +155,9 @@ fn test_undo_redo_with_selection_restoration(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let mut now = Instant::now();
let buffer = cx.new_model(|cx| language::Buffer::new(0, cx.entity_id().as_u64(), "123456"));
let buffer = cx.new_model(|cx| {
language::Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "123456")
});
let group_interval = buffer.update(cx, |buffer, _| buffer.transaction_group_interval());
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let editor = cx.add_window(|cx| build_editor(buffer.clone(), cx));
@@ -225,7 +228,8 @@ fn test_ime_composition(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let buffer = cx.new_model(|cx| {
let mut buffer = language::Buffer::new(0, cx.entity_id().as_u64(), "abcde");
let mut buffer =
language::Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "abcde");
// Ensure automatic grouping doesn't occur.
buffer.set_group_interval(Duration::ZERO);
buffer
@@ -629,7 +633,7 @@ async fn test_navigation_history(cx: &mut TestAppContext) {
// Ensure we don't panic when navigation data contains invalid anchors *and* points.
let mut invalid_anchor = editor.scroll_manager.anchor().anchor;
invalid_anchor.text_anchor.buffer_id = Some(999);
invalid_anchor.text_anchor.buffer_id = BufferId::new(999).ok();
let invalid_point = Point::new(9999, 0);
editor.navigate(
Box::new(NavigationData {
@@ -2342,11 +2346,20 @@ fn test_indent_outdent_with_excerpts(cx: &mut TestAppContext) {
));
let toml_buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), "a = 1\nb = 2\n").with_language(toml_language, cx)
Buffer::new(
0,
BufferId::new(cx.entity_id().as_u64()).unwrap(),
"a = 1\nb = 2\n",
)
.with_language(toml_language, cx)
});
let rust_buffer = cx.new_model(|cx| {
Buffer::new(0, cx.entity_id().as_u64(), "const c: usize = 3;\n")
.with_language(rust_language, cx)
Buffer::new(
0,
BufferId::new(cx.entity_id().as_u64()).unwrap(),
"const c: usize = 3;\n",
)
.with_language(rust_language, cx)
});
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0, ReadWrite);
@@ -3984,8 +3997,10 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut gpui::TestAppContext) {
"#
.unindent();
let buffer = cx
.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx));
let buffer = cx.new_model(|cx| {
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
.with_language(language, cx)
});
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (view, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
@@ -4149,8 +4164,10 @@ async fn test_autoindent_selections(cx: &mut gpui::TestAppContext) {
let text = "fn a() {}";
let buffer = cx
.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx));
let buffer = cx.new_model(|cx| {
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
.with_language(language, cx)
});
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
editor
@@ -4713,8 +4730,10 @@ async fn test_surround_with_pair(cx: &mut gpui::TestAppContext) {
"#
.unindent();
let buffer = cx
.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx));
let buffer = cx.new_model(|cx| {
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
.with_language(language, cx)
});
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (view, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
view.condition::<crate::EditorEvent>(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
@@ -4862,8 +4881,10 @@ async fn test_delete_autoclose_pair(cx: &mut gpui::TestAppContext) {
"#
.unindent();
let buffer = cx
.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx));
let buffer = cx.new_model(|cx| {
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
.with_language(language, cx)
});
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (editor, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
editor
@@ -6095,7 +6116,13 @@ async fn test_toggle_block_comment(cx: &mut gpui::TestAppContext) {
fn test_editing_disjoint_excerpts(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(3, 4, 'a')));
let buffer = cx.new_model(|cx| {
Buffer::new(
0,
BufferId::new(cx.entity_id().as_u64()).unwrap(),
sample_text(3, 4, 'a'),
)
});
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0, ReadWrite);
multibuffer.push_excerpts(
@@ -6179,7 +6206,13 @@ fn test_editing_overlapping_excerpts(cx: &mut TestAppContext) {
primary: None,
}
});
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), initial_text));
let buffer = cx.new_model(|cx| {
Buffer::new(
0,
BufferId::new(cx.entity_id().as_u64()).unwrap(),
initial_text,
)
});
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0, ReadWrite);
multibuffer.push_excerpts(buffer, excerpt_ranges, cx);
@@ -6237,7 +6270,13 @@ fn test_editing_overlapping_excerpts(cx: &mut TestAppContext) {
fn test_refresh_selections(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(3, 4, 'a')));
let buffer = cx.new_model(|cx| {
Buffer::new(
0,
BufferId::new(cx.entity_id().as_u64()).unwrap(),
sample_text(3, 4, 'a'),
)
});
let mut excerpt1_id = None;
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0, ReadWrite);
@@ -6322,7 +6361,13 @@ fn test_refresh_selections(cx: &mut TestAppContext) {
fn test_refresh_selections_while_selecting_with_mouse(cx: &mut TestAppContext) {
init_test(cx, |_| {});
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(3, 4, 'a')));
let buffer = cx.new_model(|cx| {
Buffer::new(
0,
BufferId::new(cx.entity_id().as_u64()).unwrap(),
sample_text(3, 4, 'a'),
)
});
let mut excerpt1_id = None;
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0, ReadWrite);
@@ -6417,8 +6462,10 @@ async fn test_extra_newline_insertion(cx: &mut gpui::TestAppContext) {
"{{} }\n", //
);
let buffer = cx
.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx));
let buffer = cx.new_model(|cx| {
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
.with_language(language, cx)
});
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let (view, cx) = cx.add_window_view(|cx| build_editor(buffer, cx));
view.condition::<crate::EditorEvent>(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx))
@@ -7498,8 +7545,20 @@ async fn test_copilot_multibuffer(executor: BackgroundExecutor, cx: &mut gpui::T
let (copilot, copilot_lsp) = Copilot::fake(cx);
_ = cx.update(|cx| cx.set_global(copilot));
let buffer_1 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "a = 1\nb = 2\n"));
let buffer_2 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "c = 3\nd = 4\n"));
let buffer_1 = cx.new_model(|cx| {
Buffer::new(
0,
BufferId::new(cx.entity_id().as_u64()).unwrap(),
"a = 1\nb = 2\n",
)
});
let buffer_2 = cx.new_model(|cx| {
Buffer::new(
0,
BufferId::new(cx.entity_id().as_u64()).unwrap(),
"c = 3\nd = 4\n",
)
});
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0, ReadWrite);
multibuffer.push_excerpts(
+4 -4
View File
@@ -28,7 +28,7 @@ use collections::{hash_map, HashMap, HashSet};
use language::language_settings::InlayHintSettings;
use smol::lock::Semaphore;
use sum_tree::Bias;
use text::{ToOffset, ToPoint};
use text::{BufferId, ToOffset, ToPoint};
use util::post_inc;
pub struct InlayHintCache {
@@ -50,7 +50,7 @@ struct TasksForRanges {
struct CachedExcerptHints {
version: usize,
buffer_version: Global,
buffer_id: u64,
buffer_id: BufferId,
ordered_hints: Vec<InlayId>,
hints_by_id: HashMap<InlayId, InlayHint>,
}
@@ -93,7 +93,7 @@ struct ExcerptHintsUpdate {
#[derive(Debug, Clone, Copy)]
struct ExcerptQuery {
buffer_id: u64,
buffer_id: BufferId,
excerpt_id: ExcerptId,
cache_version: usize,
invalidate: InvalidationStrategy,
@@ -553,7 +553,7 @@ impl InlayHintCache {
/// Queries a certain hint from the cache for extra data via the LSP <a href="https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#inlayHint_resolve">resolve</a> request.
pub(super) fn spawn_hint_resolve(
&self,
buffer_id: u64,
buffer_id: BufferId,
excerpt_id: ExcerptId,
id: InlayId,
cx: &mut ViewContext<'_, Editor>,
+24 -19
View File
@@ -30,7 +30,7 @@ use std::{
path::{Path, PathBuf},
sync::Arc,
};
use text::Selection;
use text::{BufferId, Selection};
use theme::Theme;
use ui::{h_flex, prelude::*, Label};
use util::{paths::PathExt, paths::FILE_ROW_COLUMN_DELIMITER, ResultExt, TryFutureExt};
@@ -73,12 +73,14 @@ impl FollowableItem for Editor {
.iter()
.map(|excerpt| excerpt.buffer_id)
.collect::<HashSet<_>>();
let buffers = project.update(cx, |project, cx| {
buffer_ids
.iter()
.map(|id| project.open_buffer_by_id(*id, cx))
.collect::<Vec<_>>()
});
let buffers = project
.update(cx, |project, cx| {
buffer_ids
.iter()
.map(|id| BufferId::new(*id).map(|id| project.open_buffer_by_id(id, cx)))
.collect::<Result<Vec<_>>>()
})
.ok()?;
let pane = pane.downgrade();
Some(cx.spawn(|mut cx| async move {
@@ -109,10 +111,12 @@ impl FollowableItem for Editor {
MultiBuffer::new(replica_id, project.read(cx).capability());
let mut excerpts = state.excerpts.into_iter().peekable();
while let Some(excerpt) = excerpts.peek() {
let buffer_id = excerpt.buffer_id;
let Ok(buffer_id) = BufferId::new(excerpt.buffer_id) else {
continue;
};
let buffer_excerpts = iter::from_fn(|| {
let excerpt = excerpts.peek()?;
(excerpt.buffer_id == buffer_id)
(excerpt.buffer_id == u64::from(buffer_id))
.then(|| excerpts.next().unwrap())
});
let buffer =
@@ -189,7 +193,7 @@ impl FollowableItem for Editor {
.excerpts()
.map(|(id, buffer, range)| proto::Excerpt {
id: id.to_proto(),
buffer_id: buffer.remote_id(),
buffer_id: buffer.remote_id().into(),
context_start: Some(serialize_text_anchor(&range.context.start)),
context_end: Some(serialize_text_anchor(&range.context.end)),
primary_start: range
@@ -336,9 +340,9 @@ async fn update_editor_from_message(
let inserted_excerpt_buffers = project.update(cx, |project, cx| {
inserted_excerpt_buffer_ids
.into_iter()
.map(|id| project.open_buffer_by_id(id, cx))
.collect::<Vec<_>>()
})?;
.map(|id| BufferId::new(id).map(|id| project.open_buffer_by_id(id, cx)))
.collect::<Result<Vec<_>>>()
})??;
let _inserted_excerpt_buffers = try_join_all(inserted_excerpt_buffers).await?;
// Update the editor's excerpts.
@@ -362,7 +366,7 @@ async fn update_editor_from_message(
let Some(previous_excerpt_id) = insertion.previous_excerpt_id else {
continue;
};
let buffer_id = excerpt.buffer_id;
let buffer_id = BufferId::new(excerpt.buffer_id)?;
let Some(buffer) = project.read(cx).buffer_for_id(buffer_id) else {
continue;
};
@@ -370,7 +374,7 @@ async fn update_editor_from_message(
let adjacent_excerpts = iter::from_fn(|| {
let insertion = insertions.peek()?;
if insertion.previous_excerpt_id.is_none()
&& insertion.excerpt.as_ref()?.buffer_id == buffer_id
&& insertion.excerpt.as_ref()?.buffer_id == u64::from(buffer_id)
{
insertions.next()?.excerpt
} else {
@@ -395,8 +399,9 @@ async fn update_editor_from_message(
}
multibuffer.remove_excerpts(removed_excerpt_ids, cx);
});
})?;
Result::<(), anyhow::Error>::Ok(())
})
})??;
// Deserialize the editor state.
let (selections, pending_selection, scroll_top_anchor) = this.update(cx, |editor, cx| {
@@ -450,13 +455,13 @@ async fn update_editor_from_message(
}
fn serialize_excerpt(
buffer_id: u64,
buffer_id: BufferId,
id: &ExcerptId,
range: &ExcerptRange<language::Anchor>,
) -> Option<proto::Excerpt> {
Some(proto::Excerpt {
id: id.to_proto(),
buffer_id,
buffer_id: buffer_id.into(),
context_start: Some(serialize_text_anchor(&range.context.start)),
context_end: Some(serialize_text_anchor(&range.context.end)),
primary_start: range
+8 -2
View File
@@ -522,6 +522,7 @@ mod tests {
use language::Capability;
use project::Project;
use settings::SettingsStore;
use text::BufferId;
use util::post_inc;
#[gpui::test]
@@ -822,8 +823,13 @@ mod tests {
let font = font("Helvetica");
let buffer =
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abc\ndefg\nhijkl\nmn"));
let buffer = cx.new_model(|cx| {
Buffer::new(
0,
BufferId::new(cx.entity_id().as_u64()).unwrap(),
"abc\ndefg\nhijkl\nmn",
)
});
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(0, Capability::ReadWrite);
multibuffer.push_excerpts(