mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
text: Wrap BufferId into a newtype
This commit is contained in:
parent
941e838be9
commit
5ab715aac9
@ -35,7 +35,7 @@ use gpui::{
|
||||
StatefulInteractiveElement, Styled, Subscription, Task, TextStyle, UniformListScrollHandle,
|
||||
View, ViewContext, VisualContext, WeakModel, WeakView, WhiteSpace, WindowContext,
|
||||
};
|
||||
use language::{language_settings::SoftWrap, Buffer, LanguageRegistry, ToOffset as _};
|
||||
use language::{language_settings::SoftWrap, Buffer, BufferId, LanguageRegistry, ToOffset as _};
|
||||
use project::Project;
|
||||
use search::{buffer_search::DivRegistrar, BufferSearchBar};
|
||||
use semantic_index::{SemanticIndex, SemanticIndexStatus};
|
||||
@ -1414,7 +1414,7 @@ impl Conversation {
|
||||
) -> Self {
|
||||
let markdown = language_registry.language_for_name("Markdown");
|
||||
let buffer = cx.new_model(|cx| {
|
||||
let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), "");
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "");
|
||||
buffer.set_language_registry(language_registry);
|
||||
cx.spawn(|buffer, mut cx| async move {
|
||||
let markdown = markdown.await?;
|
||||
@ -1515,7 +1515,11 @@ impl Conversation {
|
||||
let mut message_anchors = Vec::new();
|
||||
let mut next_message_id = MessageId(0);
|
||||
let buffer = cx.new_model(|cx| {
|
||||
let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), saved_conversation.text);
|
||||
let mut buffer = Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
saved_conversation.text,
|
||||
);
|
||||
for message in saved_conversation.messages {
|
||||
message_anchors.push(MessageAnchor {
|
||||
id: message.id,
|
||||
|
@ -365,7 +365,9 @@ mod tests {
|
||||
use futures::stream::{self};
|
||||
use gpui::{Context, TestAppContext};
|
||||
use indoc::indoc;
|
||||
use language::{language_settings, tree_sitter_rust, Buffer, Language, LanguageConfig, Point};
|
||||
use language::{
|
||||
language_settings, tree_sitter_rust, Buffer, BufferId, Language, LanguageConfig, Point,
|
||||
};
|
||||
use rand::prelude::*;
|
||||
use serde::Serialize;
|
||||
use settings::SettingsStore;
|
||||
@ -394,8 +396,9 @@ mod tests {
|
||||
}
|
||||
}
|
||||
"};
|
||||
let buffer =
|
||||
cx.new_model(|cx| Buffer::new(0, 0, text).with_language(Arc::new(rust_lang()), cx));
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(0, BufferId::new(1).unwrap(), text).with_language(Arc::new(rust_lang()), cx)
|
||||
});
|
||||
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
let range = buffer.read_with(cx, |buffer, cx| {
|
||||
let snapshot = buffer.snapshot(cx);
|
||||
@ -460,8 +463,9 @@ mod tests {
|
||||
le
|
||||
}
|
||||
"};
|
||||
let buffer =
|
||||
cx.new_model(|cx| Buffer::new(0, 0, text).with_language(Arc::new(rust_lang()), cx));
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(0, BufferId::new(1).unwrap(), text).with_language(Arc::new(rust_lang()), cx)
|
||||
});
|
||||
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
let position = buffer.read_with(cx, |buffer, cx| {
|
||||
let snapshot = buffer.snapshot(cx);
|
||||
@ -525,8 +529,9 @@ mod tests {
|
||||
" \n",
|
||||
"}\n" //
|
||||
);
|
||||
let buffer =
|
||||
cx.new_model(|cx| Buffer::new(0, 0, text).with_language(Arc::new(rust_lang()), cx));
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(0, BufferId::new(1).unwrap(), text).with_language(Arc::new(rust_lang()), cx)
|
||||
});
|
||||
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
let position = buffer.read_with(cx, |buffer, cx| {
|
||||
let snapshot = buffer.snapshot(cx);
|
||||
|
@ -178,7 +178,9 @@ pub(crate) mod tests {
|
||||
|
||||
use gpui::{AppContext, Context};
|
||||
use indoc::indoc;
|
||||
use language::{language_settings, tree_sitter_rust, Buffer, Language, LanguageConfig, Point};
|
||||
use language::{
|
||||
language_settings, tree_sitter_rust, Buffer, BufferId, Language, LanguageConfig, Point,
|
||||
};
|
||||
use settings::SettingsStore;
|
||||
|
||||
pub(crate) fn rust_lang() -> Language {
|
||||
@ -253,8 +255,9 @@ pub(crate) mod tests {
|
||||
}
|
||||
}
|
||||
"};
|
||||
let buffer =
|
||||
cx.new_model(|cx| Buffer::new(0, 0, text).with_language(Arc::new(rust_lang()), cx));
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(0, BufferId::new(1).unwrap(), text).with_language(Arc::new(rust_lang()), cx)
|
||||
});
|
||||
let snapshot = buffer.read(cx).snapshot();
|
||||
|
||||
assert_eq!(
|
||||
|
@ -9,6 +9,7 @@ use rpc::{
|
||||
TypedEnvelope,
|
||||
};
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use text::BufferId;
|
||||
use util::ResultExt;
|
||||
|
||||
pub const ACKNOWLEDGE_DEBOUNCE_INTERVAL: Duration = Duration::from_millis(250);
|
||||
@ -53,7 +54,7 @@ impl ChannelBuffer {
|
||||
channel_id: channel.id,
|
||||
})
|
||||
.await?;
|
||||
|
||||
let buffer_id = BufferId::new(response.buffer_id)?;
|
||||
let base_text = response.base_text;
|
||||
let operations = response
|
||||
.operations
|
||||
@ -63,12 +64,7 @@ impl ChannelBuffer {
|
||||
|
||||
let buffer = cx.new_model(|cx| {
|
||||
let capability = channel_store.read(cx).channel_capability(channel.id);
|
||||
language::Buffer::remote(
|
||||
response.buffer_id,
|
||||
response.replica_id as u16,
|
||||
capability,
|
||||
base_text,
|
||||
)
|
||||
language::Buffer::remote(buffer_id, response.replica_id as u16, capability, base_text)
|
||||
})?;
|
||||
buffer.update(&mut cx, |buffer, cx| buffer.apply_ops(operations, cx))??;
|
||||
|
||||
@ -107,7 +103,7 @@ impl ChannelBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remote_id(&self, cx: &AppContext) -> u64 {
|
||||
pub fn remote_id(&self, cx: &AppContext) -> BufferId {
|
||||
self.buffer.read(cx).remote_id()
|
||||
}
|
||||
|
||||
@ -210,7 +206,7 @@ impl ChannelBuffer {
|
||||
pub fn acknowledge_buffer_version(&mut self, cx: &mut ModelContext<'_, ChannelBuffer>) {
|
||||
let buffer = self.buffer.read(cx);
|
||||
let version = buffer.version();
|
||||
let buffer_id = buffer.remote_id();
|
||||
let buffer_id = buffer.remote_id().into();
|
||||
let client = self.client.clone();
|
||||
let epoch = self.epoch();
|
||||
|
||||
|
@ -693,7 +693,7 @@ impl Database {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut text_buffer = text::Buffer::new(0, 0, base_text);
|
||||
let mut text_buffer = text::Buffer::new(0, text::BufferId::new(1).unwrap(), base_text);
|
||||
text_buffer
|
||||
.apply_ops(operations.into_iter().filter_map(operation_from_wire))
|
||||
.unwrap();
|
||||
|
@ -67,7 +67,7 @@ async fn test_channel_buffers(db: &Arc<Database>) {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut buffer_a = Buffer::new(0, 0, "".to_string());
|
||||
let mut buffer_a = Buffer::new(0, text::BufferId::new(0).unwrap(), "".to_string());
|
||||
let mut operations = Vec::new();
|
||||
operations.push(buffer_a.edit([(0..0, "hello world")]));
|
||||
operations.push(buffer_a.edit([(5..5, ", cruel")]));
|
||||
@ -90,7 +90,11 @@ async fn test_channel_buffers(db: &Arc<Database>) {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut buffer_b = Buffer::new(0, 0, buffer_response_b.base_text);
|
||||
let mut buffer_b = Buffer::new(
|
||||
0,
|
||||
text::BufferId::new(0).unwrap(),
|
||||
buffer_response_b.base_text,
|
||||
);
|
||||
buffer_b
|
||||
.apply_ops(buffer_response_b.operations.into_iter().map(|operation| {
|
||||
let operation = proto::deserialize_operation(operation).unwrap();
|
||||
@ -223,7 +227,11 @@ async fn test_channel_buffers_last_operations(db: &Database) {
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
text_buffers.push(Buffer::new(0, 0, "".to_string()));
|
||||
text_buffers.push(Buffer::new(
|
||||
0,
|
||||
text::BufferId::new(1).unwrap(),
|
||||
"".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let operations = db
|
||||
@ -270,7 +278,7 @@ async fn test_channel_buffers_last_operations(db: &Database) {
|
||||
db.join_channel_buffer(buffers[1].channel_id, user_id, connection_id)
|
||||
.await
|
||||
.unwrap();
|
||||
text_buffers[1] = Buffer::new(1, 0, "def".to_string());
|
||||
text_buffers[1] = Buffer::new(1, text::BufferId::new(1).unwrap(), "def".to_string());
|
||||
update_buffer(
|
||||
buffers[1].channel_id,
|
||||
user_id,
|
||||
|
@ -1023,12 +1023,15 @@ async fn get_copilot_lsp(http: Arc<dyn HttpClient>) -> anyhow::Result<PathBuf> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use gpui::TestAppContext;
|
||||
use language::BufferId;
|
||||
|
||||
#[gpui::test(iterations = 10)]
|
||||
async fn test_buffer_management(cx: &mut TestAppContext) {
|
||||
let (copilot, mut lsp) = Copilot::fake(cx);
|
||||
|
||||
let buffer_1 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "Hello"));
|
||||
let buffer_1 = cx.new_model(|cx| {
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "Hello")
|
||||
});
|
||||
let buffer_1_uri: lsp::Url = format!("buffer://{}", buffer_1.entity_id().as_u64())
|
||||
.parse()
|
||||
.unwrap();
|
||||
@ -1046,7 +1049,13 @@ mod tests {
|
||||
}
|
||||
);
|
||||
|
||||
let buffer_2 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "Goodbye"));
|
||||
let buffer_2 = cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
"Goodbye",
|
||||
)
|
||||
});
|
||||
let buffer_2_uri: lsp::Url = format!("buffer://{}", buffer_2.entity_id().as_u64())
|
||||
.parse()
|
||||
.unwrap();
|
||||
@ -1235,7 +1244,7 @@ mod tests {
|
||||
|
||||
fn buffer_reloaded(
|
||||
&self,
|
||||
_: u64,
|
||||
_: BufferId,
|
||||
_: &clock::Global,
|
||||
_: language::RopeFingerprint,
|
||||
_: language::LineEnding,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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,10 +2346,19 @@ 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")
|
||||
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| {
|
||||
@ -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(
|
||||
|
@ -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>,
|
||||
|
@ -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| {
|
||||
let buffers = project
|
||||
.update(cx, |project, cx| {
|
||||
buffer_ids
|
||||
.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<_>>>()
|
||||
})
|
||||
.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
|
||||
|
@ -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(
|
||||
|
@ -314,7 +314,7 @@ mod tests {
|
||||
use std::assert_eq;
|
||||
|
||||
use super::*;
|
||||
use text::Buffer;
|
||||
use text::{Buffer, BufferId};
|
||||
use unindent::Unindent as _;
|
||||
|
||||
#[test]
|
||||
@ -333,7 +333,7 @@ mod tests {
|
||||
"
|
||||
.unindent();
|
||||
|
||||
let mut buffer = Buffer::new(0, 0, buffer_text);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), buffer_text);
|
||||
let mut diff = BufferDiff::new();
|
||||
smol::block_on(diff.update(&diff_base, &buffer));
|
||||
assert_hunks(
|
||||
@ -393,7 +393,7 @@ mod tests {
|
||||
"
|
||||
.unindent();
|
||||
|
||||
let buffer = Buffer::new(0, 0, buffer_text);
|
||||
let buffer = Buffer::new(0, BufferId::new(1).unwrap(), buffer_text);
|
||||
let mut diff = BufferDiff::new();
|
||||
smol::block_on(diff.update(&diff_base, &buffer));
|
||||
assert_eq!(diff.hunks(&buffer).count(), 8);
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
||||
},
|
||||
CodeLabel, LanguageScope, Outline,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
pub use clock::ReplicaId;
|
||||
use futures::channel::oneshot;
|
||||
use gpui::{AppContext, EventEmitter, HighlightStyle, ModelContext, Task, TaskLabel};
|
||||
@ -44,10 +44,10 @@ use sum_tree::TreeMap;
|
||||
use text::operation_queue::OperationQueue;
|
||||
use text::*;
|
||||
pub use text::{
|
||||
Anchor, Bias, Buffer as TextBuffer, BufferSnapshot as TextBufferSnapshot, Edit, OffsetRangeExt,
|
||||
OffsetUtf16, Patch, Point, PointUtf16, Rope, RopeFingerprint, Selection, SelectionGoal,
|
||||
Subscription, TextDimension, TextSummary, ToOffset, ToOffsetUtf16, ToPoint, ToPointUtf16,
|
||||
Transaction, TransactionId, Unclipped,
|
||||
Anchor, Bias, Buffer as TextBuffer, BufferId, BufferSnapshot as TextBufferSnapshot, Edit,
|
||||
OffsetRangeExt, OffsetUtf16, Patch, Point, PointUtf16, Rope, RopeFingerprint, Selection,
|
||||
SelectionGoal, Subscription, TextDimension, TextSummary, ToOffset, ToOffsetUtf16, ToPoint,
|
||||
ToPointUtf16, Transaction, TransactionId, Unclipped,
|
||||
};
|
||||
use theme::SyntaxTheme;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
@ -396,7 +396,7 @@ pub trait LocalFile: File {
|
||||
/// Called when the buffer is reloaded from disk.
|
||||
fn buffer_reloaded(
|
||||
&self,
|
||||
buffer_id: u64,
|
||||
buffer_id: BufferId,
|
||||
version: &clock::Global,
|
||||
fingerprint: RopeFingerprint,
|
||||
line_ending: LineEnding,
|
||||
@ -517,7 +517,7 @@ pub enum CharKind {
|
||||
|
||||
impl Buffer {
|
||||
/// Create a new buffer with the given base text.
|
||||
pub fn new<T: Into<String>>(replica_id: ReplicaId, id: u64, base_text: T) -> Self {
|
||||
pub fn new<T: Into<String>>(replica_id: ReplicaId, id: BufferId, base_text: T) -> Self {
|
||||
Self::build(
|
||||
TextBuffer::new(replica_id, id, base_text.into()),
|
||||
None,
|
||||
@ -528,7 +528,7 @@ impl Buffer {
|
||||
|
||||
/// Create a new buffer that is a replica of a remote buffer.
|
||||
pub fn remote(
|
||||
remote_id: u64,
|
||||
remote_id: BufferId,
|
||||
replica_id: ReplicaId,
|
||||
capability: Capability,
|
||||
base_text: String,
|
||||
@ -549,7 +549,9 @@ impl Buffer {
|
||||
message: proto::BufferState,
|
||||
file: Option<Arc<dyn File>>,
|
||||
) -> Result<Self> {
|
||||
let buffer = TextBuffer::new(replica_id, message.id, message.base_text);
|
||||
let buffer_id = BufferId::new(message.id)
|
||||
.with_context(|| anyhow!("Could not deserialize buffer_id"))?;
|
||||
let buffer = TextBuffer::new(replica_id, buffer_id, message.base_text);
|
||||
let mut this = Self::build(
|
||||
buffer,
|
||||
message.diff_base.map(|text| text.into_boxed_str().into()),
|
||||
@ -572,7 +574,7 @@ impl Buffer {
|
||||
/// Serialize the buffer's state to a protobuf message.
|
||||
pub fn to_proto(&self) -> proto::BufferState {
|
||||
proto::BufferState {
|
||||
id: self.remote_id(),
|
||||
id: self.remote_id().into(),
|
||||
file: self.file.as_ref().map(|f| f.to_proto()),
|
||||
base_text: self.base_text().to_string(),
|
||||
diff_base: self.diff_base.as_ref().map(|h| h.to_string()),
|
||||
|
@ -18,7 +18,7 @@ use std::{
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use text::network::Network;
|
||||
use text::LineEnding;
|
||||
use text::{BufferId, LineEnding};
|
||||
use text::{Point, ToPoint};
|
||||
use unindent::Unindent as _;
|
||||
use util::{assert_set_eq, post_inc, test::marked_text_ranges, RandomCharIter};
|
||||
@ -43,7 +43,11 @@ fn test_line_endings(cx: &mut gpui::AppContext) {
|
||||
init_settings(cx, |_| {});
|
||||
|
||||
cx.new_model(|cx| {
|
||||
let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), "one\r\ntwo\rthree")
|
||||
let mut buffer = Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
"one\r\ntwo\rthree",
|
||||
)
|
||||
.with_language(Arc::new(rust_lang()), cx);
|
||||
assert_eq!(buffer.text(), "one\ntwo\nthree");
|
||||
assert_eq!(buffer.line_ending(), LineEnding::Windows);
|
||||
@ -138,8 +142,10 @@ fn test_edit_events(cx: &mut gpui::AppContext) {
|
||||
let buffer_1_events = Arc::new(Mutex::new(Vec::new()));
|
||||
let buffer_2_events = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
let buffer1 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abcdef"));
|
||||
let buffer2 = cx.new_model(|cx| Buffer::new(1, cx.entity_id().as_u64(), "abcdef"));
|
||||
let buffer1 = cx
|
||||
.new_model(|cx| Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "abcdef"));
|
||||
let buffer2 = cx
|
||||
.new_model(|cx| Buffer::new(1, BufferId::new(cx.entity_id().as_u64()).unwrap(), "abcdef"));
|
||||
let buffer1_ops = Arc::new(Mutex::new(Vec::new()));
|
||||
buffer1.update(cx, {
|
||||
let buffer1_ops = buffer1_ops.clone();
|
||||
@ -218,7 +224,8 @@ fn test_edit_events(cx: &mut gpui::AppContext) {
|
||||
#[gpui::test]
|
||||
async fn test_apply_diff(cx: &mut TestAppContext) {
|
||||
let text = "a\nbb\nccc\ndddd\neeeee\nffffff\n";
|
||||
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text));
|
||||
let buffer =
|
||||
cx.new_model(|cx| Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text));
|
||||
let anchor = buffer.update(cx, |buffer, _| buffer.anchor_before(Point::new(3, 3)));
|
||||
|
||||
let text = "a\nccc\ndddd\nffffff\n";
|
||||
@ -250,7 +257,8 @@ async fn test_normalize_whitespace(cx: &mut gpui::TestAppContext) {
|
||||
]
|
||||
.join("\n");
|
||||
|
||||
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text));
|
||||
let buffer =
|
||||
cx.new_model(|cx| Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text));
|
||||
|
||||
// Spawn a task to format the buffer's whitespace.
|
||||
// Pause so that the foratting task starts running.
|
||||
@ -315,7 +323,8 @@ async fn test_normalize_whitespace(cx: &mut gpui::TestAppContext) {
|
||||
async fn test_reparse(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(Arc::new(rust_lang()), cx)
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(Arc::new(rust_lang()), cx)
|
||||
});
|
||||
|
||||
// Wait for the initial text to parse
|
||||
@ -443,8 +452,8 @@ async fn test_reparse(cx: &mut gpui::TestAppContext) {
|
||||
#[gpui::test]
|
||||
async fn test_resetting_language(cx: &mut gpui::TestAppContext) {
|
||||
let buffer = cx.new_model(|cx| {
|
||||
let mut buffer =
|
||||
Buffer::new(0, cx.entity_id().as_u64(), "{}").with_language(Arc::new(rust_lang()), cx);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "{}")
|
||||
.with_language(Arc::new(rust_lang()), cx);
|
||||
buffer.set_sync_parse_timeout(Duration::ZERO);
|
||||
buffer
|
||||
});
|
||||
@ -493,7 +502,8 @@ async fn test_outline(cx: &mut gpui::TestAppContext) {
|
||||
.unindent();
|
||||
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx)
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(Arc::new(rust_lang()), cx)
|
||||
});
|
||||
let outline = buffer
|
||||
.update(cx, |buffer, _| buffer.snapshot().outline(None))
|
||||
@ -579,7 +589,8 @@ async fn test_outline_nodes_with_newlines(cx: &mut gpui::TestAppContext) {
|
||||
.unindent();
|
||||
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx)
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(Arc::new(rust_lang()), cx)
|
||||
});
|
||||
let outline = buffer
|
||||
.update(cx, |buffer, _| buffer.snapshot().outline(None))
|
||||
@ -617,7 +628,8 @@ async fn test_outline_with_extra_context(cx: &mut gpui::TestAppContext) {
|
||||
.unindent();
|
||||
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(language), cx)
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(Arc::new(language), cx)
|
||||
});
|
||||
let snapshot = buffer.update(cx, |buffer, _| buffer.snapshot());
|
||||
|
||||
@ -661,7 +673,8 @@ async fn test_symbols_containing(cx: &mut gpui::TestAppContext) {
|
||||
.unindent();
|
||||
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx)
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(Arc::new(rust_lang()), cx)
|
||||
});
|
||||
let snapshot = buffer.update(cx, |buffer, _| buffer.snapshot());
|
||||
|
||||
@ -883,8 +896,8 @@ fn test_enclosing_bracket_ranges_where_brackets_are_not_outermost_children(cx: &
|
||||
fn test_range_for_syntax_ancestor(cx: &mut AppContext) {
|
||||
cx.new_model(|cx| {
|
||||
let text = "fn a() { b(|c| {}) }";
|
||||
let buffer =
|
||||
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
|
||||
let buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(Arc::new(rust_lang()), cx);
|
||||
let snapshot = buffer.snapshot();
|
||||
|
||||
assert_eq!(
|
||||
@ -924,8 +937,8 @@ fn test_autoindent_with_soft_tabs(cx: &mut AppContext) {
|
||||
|
||||
cx.new_model(|cx| {
|
||||
let text = "fn a() {}";
|
||||
let mut buffer =
|
||||
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(Arc::new(rust_lang()), cx);
|
||||
|
||||
buffer.edit([(8..8, "\n\n")], Some(AutoindentMode::EachLine), cx);
|
||||
assert_eq!(buffer.text(), "fn a() {\n \n}");
|
||||
@ -967,8 +980,8 @@ fn test_autoindent_with_hard_tabs(cx: &mut AppContext) {
|
||||
|
||||
cx.new_model(|cx| {
|
||||
let text = "fn a() {}";
|
||||
let mut buffer =
|
||||
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(Arc::new(rust_lang()), cx);
|
||||
|
||||
buffer.edit([(8..8, "\n\n")], Some(AutoindentMode::EachLine), cx);
|
||||
assert_eq!(buffer.text(), "fn a() {\n\t\n}");
|
||||
@ -1007,10 +1020,9 @@ fn test_autoindent_does_not_adjust_lines_with_unchanged_suggestion(cx: &mut AppC
|
||||
init_settings(cx, |_| {});
|
||||
|
||||
cx.new_model(|cx| {
|
||||
let entity_id = cx.entity_id();
|
||||
let mut buffer = Buffer::new(
|
||||
0,
|
||||
entity_id.as_u64(),
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
"
|
||||
fn a() {
|
||||
c;
|
||||
@ -1085,7 +1097,7 @@ fn test_autoindent_does_not_adjust_lines_with_unchanged_suggestion(cx: &mut AppC
|
||||
|
||||
let mut buffer = Buffer::new(
|
||||
0,
|
||||
cx.entity_id().as_u64(),
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
"
|
||||
fn a() {
|
||||
b();
|
||||
@ -1150,7 +1162,7 @@ fn test_autoindent_does_not_adjust_lines_within_newly_created_errors(cx: &mut Ap
|
||||
cx.new_model(|cx| {
|
||||
let mut buffer = Buffer::new(
|
||||
0,
|
||||
cx.entity_id().as_u64(),
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
"
|
||||
fn a() {
|
||||
i
|
||||
@ -1212,7 +1224,7 @@ fn test_autoindent_adjusts_lines_when_only_text_changes(cx: &mut AppContext) {
|
||||
cx.new_model(|cx| {
|
||||
let mut buffer = Buffer::new(
|
||||
0,
|
||||
cx.entity_id().as_u64(),
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
"
|
||||
fn a() {}
|
||||
"
|
||||
@ -1268,8 +1280,8 @@ fn test_autoindent_with_edit_at_end_of_buffer(cx: &mut AppContext) {
|
||||
|
||||
cx.new_model(|cx| {
|
||||
let text = "a\nb";
|
||||
let mut buffer =
|
||||
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(Arc::new(rust_lang()), cx);
|
||||
buffer.edit(
|
||||
[(0..1, "\n"), (2..3, "\n")],
|
||||
Some(AutoindentMode::EachLine),
|
||||
@ -1295,8 +1307,8 @@ fn test_autoindent_multi_line_insertion(cx: &mut AppContext) {
|
||||
"
|
||||
.unindent();
|
||||
|
||||
let mut buffer =
|
||||
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(Arc::new(rust_lang()), cx);
|
||||
buffer.edit(
|
||||
[(Point::new(3, 0)..Point::new(3, 0), "e(\n f()\n);\n")],
|
||||
Some(AutoindentMode::EachLine),
|
||||
@ -1333,8 +1345,8 @@ fn test_autoindent_block_mode(cx: &mut AppContext) {
|
||||
}
|
||||
"#
|
||||
.unindent();
|
||||
let mut buffer =
|
||||
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(Arc::new(rust_lang()), cx);
|
||||
|
||||
// When this text was copied, both of the quotation marks were at the same
|
||||
// indent level, but the indentation of the first line was not included in
|
||||
@ -1419,8 +1431,8 @@ fn test_autoindent_block_mode_without_original_indent_columns(cx: &mut AppContex
|
||||
}
|
||||
"#
|
||||
.unindent();
|
||||
let mut buffer =
|
||||
Buffer::new(0, cx.entity_id().as_u64(), text).with_language(Arc::new(rust_lang()), cx);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(Arc::new(rust_lang()), cx);
|
||||
|
||||
// The original indent columns are not known, so this text is
|
||||
// auto-indented in a block as if the first line was copied in
|
||||
@ -1499,7 +1511,8 @@ fn test_autoindent_language_without_indents_query(cx: &mut AppContext) {
|
||||
"
|
||||
.unindent();
|
||||
|
||||
let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), text).with_language(
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(
|
||||
Arc::new(Language::new(
|
||||
LanguageConfig {
|
||||
name: "Markdown".into(),
|
||||
@ -1575,7 +1588,7 @@ fn test_autoindent_with_injected_languages(cx: &mut AppContext) {
|
||||
false,
|
||||
);
|
||||
|
||||
let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), text);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text);
|
||||
buffer.set_language_registry(language_registry);
|
||||
buffer.set_language(Some(html_language), cx);
|
||||
buffer.edit(
|
||||
@ -1611,8 +1624,8 @@ fn test_autoindent_query_with_outdent_captures(cx: &mut AppContext) {
|
||||
});
|
||||
|
||||
cx.new_model(|cx| {
|
||||
let mut buffer =
|
||||
Buffer::new(0, cx.entity_id().as_u64(), "").with_language(Arc::new(ruby_lang()), cx);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "")
|
||||
.with_language(Arc::new(ruby_lang()), cx);
|
||||
|
||||
let text = r#"
|
||||
class C
|
||||
@ -1713,8 +1726,8 @@ fn test_language_scope_at_with_javascript(cx: &mut AppContext) {
|
||||
"#
|
||||
.unindent();
|
||||
|
||||
let buffer =
|
||||
Buffer::new(0, cx.entity_id().as_u64(), &text).with_language(Arc::new(language), cx);
|
||||
let buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), &text)
|
||||
.with_language(Arc::new(language), cx);
|
||||
let snapshot = buffer.snapshot();
|
||||
|
||||
let config = snapshot.language_scope_at(0).unwrap();
|
||||
@ -1831,7 +1844,11 @@ fn test_language_scope_at_with_rust(cx: &mut AppContext) {
|
||||
"#
|
||||
.unindent();
|
||||
|
||||
let buffer = Buffer::new(0, cx.entity_id().as_u64(), text.clone())
|
||||
let buffer = Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
text.clone(),
|
||||
)
|
||||
.with_language(Arc::new(language), cx);
|
||||
let snapshot = buffer.snapshot();
|
||||
|
||||
@ -1876,7 +1893,7 @@ fn test_language_scope_at_with_combined_injections(cx: &mut AppContext) {
|
||||
language_registry.add(Arc::new(html_lang()));
|
||||
language_registry.add(Arc::new(erb_lang()));
|
||||
|
||||
let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), text);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text);
|
||||
buffer.set_language_registry(language_registry.clone());
|
||||
buffer.set_language(
|
||||
language_registry
|
||||
@ -1911,7 +1928,7 @@ fn test_serialization(cx: &mut gpui::AppContext) {
|
||||
let mut now = Instant::now();
|
||||
|
||||
let buffer1 = cx.new_model(|cx| {
|
||||
let mut buffer = Buffer::new(0, cx.entity_id().as_u64(), "abc");
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "abc");
|
||||
buffer.edit([(3..3, "D")], None, cx);
|
||||
|
||||
now += Duration::from_secs(1);
|
||||
@ -1966,8 +1983,13 @@ fn test_random_collaboration(cx: &mut AppContext, mut rng: StdRng) {
|
||||
let mut replica_ids = Vec::new();
|
||||
let mut buffers = Vec::new();
|
||||
let network = Arc::new(Mutex::new(Network::new(rng.clone())));
|
||||
let base_buffer =
|
||||
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), base_text.as_str()));
|
||||
let base_buffer = cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
base_text.as_str(),
|
||||
)
|
||||
});
|
||||
|
||||
for i in 0..rng.gen_range(min_peers..=max_peers) {
|
||||
let buffer = cx.new_model(|cx| {
|
||||
@ -2475,7 +2497,11 @@ fn assert_bracket_pairs(
|
||||
) {
|
||||
let (expected_text, selection_ranges) = marked_text_ranges(selection_text, false);
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(0, cx.entity_id().as_u64(), expected_text.clone())
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
expected_text.clone(),
|
||||
)
|
||||
.with_language(Arc::new(language), cx)
|
||||
});
|
||||
let buffer = buffer.update(cx, |buffer, _cx| buffer.snapshot());
|
||||
|
@ -241,7 +241,7 @@ pub fn serialize_anchor(anchor: &Anchor) -> proto::Anchor {
|
||||
Bias::Left => proto::Bias::Left as i32,
|
||||
Bias::Right => proto::Bias::Right as i32,
|
||||
},
|
||||
buffer_id: anchor.buffer_id,
|
||||
buffer_id: anchor.buffer_id.map(Into::into),
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,6 +420,11 @@ pub fn deserialize_diagnostics(
|
||||
|
||||
/// Deserializes an [`Anchor`] from the RPC representation.
|
||||
pub fn deserialize_anchor(anchor: proto::Anchor) -> Option<Anchor> {
|
||||
let buffer_id = if let Some(id) = anchor.buffer_id {
|
||||
Some(BufferId::new(id).ok()?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Some(Anchor {
|
||||
timestamp: clock::Lamport {
|
||||
replica_id: anchor.replica_id as ReplicaId,
|
||||
@ -430,7 +435,7 @@ pub fn deserialize_anchor(anchor: proto::Anchor) -> Option<Anchor> {
|
||||
proto::Bias::Left => Bias::Left,
|
||||
proto::Bias::Right => Bias::Right,
|
||||
},
|
||||
buffer_id: anchor.buffer_id,
|
||||
buffer_id,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ use super::*;
|
||||
use crate::LanguageConfig;
|
||||
use rand::rngs::StdRng;
|
||||
use std::{env, ops::Range, sync::Arc};
|
||||
use text::Buffer;
|
||||
use text::{Buffer, BufferId};
|
||||
use tree_sitter::Node;
|
||||
use unindent::Unindent as _;
|
||||
use util::test::marked_text_ranges;
|
||||
@ -86,7 +86,7 @@ fn test_syntax_map_layers_for_range() {
|
||||
|
||||
let mut buffer = Buffer::new(
|
||||
0,
|
||||
0,
|
||||
BufferId::new(1).unwrap(),
|
||||
r#"
|
||||
fn a() {
|
||||
assert_eq!(
|
||||
@ -185,7 +185,7 @@ fn test_dynamic_language_injection() {
|
||||
|
||||
let mut buffer = Buffer::new(
|
||||
0,
|
||||
0,
|
||||
BufferId::new(1).unwrap(),
|
||||
r#"
|
||||
This is a code block:
|
||||
|
||||
@ -860,7 +860,7 @@ fn test_random_edits(
|
||||
.map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
|
||||
.unwrap_or(10);
|
||||
|
||||
let mut buffer = Buffer::new(0, 0, text);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), text);
|
||||
|
||||
let mut syntax_map = SyntaxMap::new();
|
||||
syntax_map.set_language_registry(registry.clone());
|
||||
@ -1040,7 +1040,7 @@ fn test_edit_sequence(language_name: &str, steps: &[&str]) -> (Buffer, SyntaxMap
|
||||
.now_or_never()
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let mut buffer = Buffer::new(0, 0, Default::default());
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), Default::default());
|
||||
|
||||
let mut mutated_syntax_map = SyntaxMap::new();
|
||||
mutated_syntax_map.set_language_registry(registry.clone());
|
||||
|
@ -5,10 +5,11 @@ use std::{
|
||||
ops::{Range, Sub},
|
||||
};
|
||||
use sum_tree::Bias;
|
||||
use text::BufferId;
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)]
|
||||
pub struct Anchor {
|
||||
pub buffer_id: Option<u64>,
|
||||
pub buffer_id: Option<BufferId>,
|
||||
pub excerpt_id: ExcerptId,
|
||||
pub text_anchor: text::Anchor,
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ use sum_tree::{Bias, Cursor, SumTree};
|
||||
use text::{
|
||||
locator::Locator,
|
||||
subscription::{Subscription, Topic},
|
||||
Edit, TextSummary,
|
||||
BufferId, Edit, TextSummary,
|
||||
};
|
||||
use theme::SyntaxTheme;
|
||||
use util::post_inc;
|
||||
@ -48,7 +48,7 @@ pub struct ExcerptId(usize);
|
||||
|
||||
pub struct MultiBuffer {
|
||||
snapshot: RefCell<MultiBufferSnapshot>,
|
||||
buffers: RefCell<HashMap<u64, BufferState>>,
|
||||
buffers: RefCell<HashMap<BufferId, BufferState>>,
|
||||
next_excerpt_id: usize,
|
||||
subscriptions: Topic,
|
||||
singleton: bool,
|
||||
@ -101,7 +101,7 @@ struct History {
|
||||
#[derive(Clone)]
|
||||
struct Transaction {
|
||||
id: TransactionId,
|
||||
buffer_transactions: HashMap<u64, text::TransactionId>,
|
||||
buffer_transactions: HashMap<BufferId, text::TransactionId>,
|
||||
first_edit_at: Instant,
|
||||
last_edit_at: Instant,
|
||||
suppress_grouping: bool,
|
||||
@ -161,7 +161,7 @@ pub struct ExcerptBoundary {
|
||||
struct Excerpt {
|
||||
id: ExcerptId,
|
||||
locator: Locator,
|
||||
buffer_id: u64,
|
||||
buffer_id: BufferId,
|
||||
buffer: BufferSnapshot,
|
||||
range: ExcerptRange<text::Anchor>,
|
||||
max_buffer_row: u32,
|
||||
@ -366,7 +366,7 @@ impl MultiBuffer {
|
||||
offset: T,
|
||||
theme: Option<&SyntaxTheme>,
|
||||
cx: &AppContext,
|
||||
) -> Option<(u64, Vec<OutlineItem<Anchor>>)> {
|
||||
) -> Option<(BufferId, Vec<OutlineItem<Anchor>>)> {
|
||||
self.read(cx).symbols_containing(offset, theme)
|
||||
}
|
||||
|
||||
@ -412,7 +412,7 @@ impl MultiBuffer {
|
||||
is_insertion: bool,
|
||||
original_indent_column: u32,
|
||||
}
|
||||
let mut buffer_edits: HashMap<u64, Vec<BufferEdit>> = Default::default();
|
||||
let mut buffer_edits: HashMap<BufferId, Vec<BufferEdit>> = Default::default();
|
||||
let mut edited_excerpt_ids = Vec::new();
|
||||
let mut cursor = snapshot.excerpts.cursor::<usize>();
|
||||
for (ix, (range, new_text)) in edits.enumerate() {
|
||||
@ -514,7 +514,7 @@ impl MultiBuffer {
|
||||
// Non-generic part of edit, hoisted out to avoid blowing up LLVM IR.
|
||||
fn tail(
|
||||
this: &mut MultiBuffer,
|
||||
buffer_edits: HashMap<u64, Vec<BufferEdit>>,
|
||||
buffer_edits: HashMap<BufferId, Vec<BufferEdit>>,
|
||||
autoindent_mode: Option<AutoindentMode>,
|
||||
edited_excerpt_ids: Vec<ExcerptId>,
|
||||
cx: &mut ModelContext<MultiBuffer>,
|
||||
@ -720,7 +720,7 @@ impl MultiBuffer {
|
||||
cursor_shape: CursorShape,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
let mut selections_by_buffer: HashMap<u64, Vec<Selection<text::Anchor>>> =
|
||||
let mut selections_by_buffer: HashMap<BufferId, Vec<Selection<text::Anchor>>> =
|
||||
Default::default();
|
||||
let snapshot = self.read(cx);
|
||||
let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>();
|
||||
@ -1440,7 +1440,7 @@ impl MultiBuffer {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn buffer(&self, buffer_id: u64) -> Option<Model<Buffer>> {
|
||||
pub fn buffer(&self, buffer_id: BufferId) -> Option<Model<Buffer>> {
|
||||
self.buffers
|
||||
.borrow()
|
||||
.get(&buffer_id)
|
||||
@ -1661,7 +1661,8 @@ impl MultiBuffer {
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
impl MultiBuffer {
|
||||
pub fn build_simple(text: &str, cx: &mut gpui::AppContext) -> Model<Self> {
|
||||
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text));
|
||||
let buffer = cx
|
||||
.new_model(|cx| Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text));
|
||||
cx.new_model(|cx| Self::singleton(buffer, cx))
|
||||
}
|
||||
|
||||
@ -1671,7 +1672,9 @@ impl MultiBuffer {
|
||||
) -> Model<Self> {
|
||||
let multi = cx.new_model(|_| Self::new(0, Capability::ReadWrite));
|
||||
for (text, ranges) in excerpts {
|
||||
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text));
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
});
|
||||
let excerpt_ranges = ranges.into_iter().map(|range| ExcerptRange {
|
||||
context: range,
|
||||
primary: None,
|
||||
@ -1760,7 +1763,9 @@ impl MultiBuffer {
|
||||
if excerpt_ids.is_empty() || (rng.gen() && excerpt_ids.len() < max_excerpts) {
|
||||
let buffer_handle = if rng.gen() || self.buffers.borrow().is_empty() {
|
||||
let text = RandomCharIter::new(&mut *rng).take(10).collect::<String>();
|
||||
buffers.push(cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), text)));
|
||||
buffers.push(cx.new_model(|cx| {
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
}));
|
||||
let buffer = buffers.last().unwrap().read(cx);
|
||||
log::info!(
|
||||
"Creating new buffer {} with text: {:?}",
|
||||
@ -1987,7 +1992,7 @@ impl MultiBufferSnapshot {
|
||||
(start..end, word_kind)
|
||||
}
|
||||
|
||||
pub fn as_singleton(&self) -> Option<(&ExcerptId, u64, &BufferSnapshot)> {
|
||||
pub fn as_singleton(&self) -> Option<(&ExcerptId, BufferId, &BufferSnapshot)> {
|
||||
if self.singleton {
|
||||
self.excerpts
|
||||
.iter()
|
||||
@ -3209,7 +3214,7 @@ impl MultiBufferSnapshot {
|
||||
&self,
|
||||
offset: T,
|
||||
theme: Option<&SyntaxTheme>,
|
||||
) -> Option<(u64, Vec<OutlineItem<Anchor>>)> {
|
||||
) -> Option<(BufferId, Vec<OutlineItem<Anchor>>)> {
|
||||
let anchor = self.anchor_before(offset);
|
||||
let excerpt_id = anchor.excerpt_id;
|
||||
let excerpt = self.excerpt(excerpt_id)?;
|
||||
@ -3249,7 +3254,7 @@ impl MultiBufferSnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buffer_id_for_excerpt(&self, excerpt_id: ExcerptId) -> Option<u64> {
|
||||
pub fn buffer_id_for_excerpt(&self, excerpt_id: ExcerptId) -> Option<BufferId> {
|
||||
Some(self.excerpt(excerpt_id)?.buffer_id)
|
||||
}
|
||||
|
||||
@ -3387,7 +3392,7 @@ impl History {
|
||||
fn end_transaction(
|
||||
&mut self,
|
||||
now: Instant,
|
||||
buffer_transactions: HashMap<u64, TransactionId>,
|
||||
buffer_transactions: HashMap<BufferId, TransactionId>,
|
||||
) -> bool {
|
||||
assert_ne!(self.transaction_depth, 0);
|
||||
self.transaction_depth -= 1;
|
||||
@ -3561,7 +3566,7 @@ impl Excerpt {
|
||||
fn new(
|
||||
id: ExcerptId,
|
||||
locator: Locator,
|
||||
buffer_id: u64,
|
||||
buffer_id: BufferId,
|
||||
buffer: BufferSnapshot,
|
||||
range: ExcerptRange<text::Anchor>,
|
||||
has_trailing_newline: bool,
|
||||
@ -4154,8 +4159,13 @@ mod tests {
|
||||
|
||||
#[gpui::test]
|
||||
fn test_singleton(cx: &mut AppContext) {
|
||||
let buffer =
|
||||
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(6, 6, 'a')));
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
sample_text(6, 6, 'a'),
|
||||
)
|
||||
});
|
||||
let multibuffer = cx.new_model(|cx| MultiBuffer::singleton(buffer.clone(), cx));
|
||||
|
||||
let snapshot = multibuffer.read(cx).snapshot(cx);
|
||||
@ -4182,7 +4192,8 @@ mod tests {
|
||||
|
||||
#[gpui::test]
|
||||
fn test_remote(cx: &mut AppContext) {
|
||||
let host_buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "a"));
|
||||
let host_buffer =
|
||||
cx.new_model(|cx| Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "a"));
|
||||
let guest_buffer = cx.new_model(|cx| {
|
||||
let state = host_buffer.read(cx).to_proto();
|
||||
let ops = cx
|
||||
@ -4213,10 +4224,20 @@ mod tests {
|
||||
|
||||
#[gpui::test]
|
||||
fn test_excerpt_boundaries_and_clipping(cx: &mut AppContext) {
|
||||
let buffer_1 =
|
||||
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(6, 6, 'a')));
|
||||
let buffer_2 =
|
||||
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(6, 6, 'g')));
|
||||
let buffer_1 = cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
sample_text(6, 6, 'a'),
|
||||
)
|
||||
});
|
||||
let buffer_2 = cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
sample_text(6, 6, 'g'),
|
||||
)
|
||||
});
|
||||
let multibuffer = cx.new_model(|_| MultiBuffer::new(0, Capability::ReadWrite));
|
||||
|
||||
let events = Arc::new(RwLock::new(Vec::<Event>::new()));
|
||||
@ -4449,10 +4470,20 @@ mod tests {
|
||||
|
||||
#[gpui::test]
|
||||
fn test_excerpt_events(cx: &mut AppContext) {
|
||||
let buffer_1 =
|
||||
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(10, 3, 'a')));
|
||||
let buffer_2 =
|
||||
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(10, 3, 'm')));
|
||||
let buffer_1 = cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
sample_text(10, 3, 'a'),
|
||||
)
|
||||
});
|
||||
let buffer_2 = cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
sample_text(10, 3, 'm'),
|
||||
)
|
||||
});
|
||||
|
||||
let leader_multibuffer = cx.new_model(|_| MultiBuffer::new(0, Capability::ReadWrite));
|
||||
let follower_multibuffer = cx.new_model(|_| MultiBuffer::new(0, Capability::ReadWrite));
|
||||
@ -4557,8 +4588,13 @@ mod tests {
|
||||
|
||||
#[gpui::test]
|
||||
fn test_push_excerpts_with_context_lines(cx: &mut AppContext) {
|
||||
let buffer =
|
||||
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(20, 3, 'a')));
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
sample_text(20, 3, 'a'),
|
||||
)
|
||||
});
|
||||
let multibuffer = cx.new_model(|_| MultiBuffer::new(0, Capability::ReadWrite));
|
||||
let anchor_ranges = multibuffer.update(cx, |multibuffer, cx| {
|
||||
multibuffer.push_excerpts_with_context_lines(
|
||||
@ -4594,8 +4630,13 @@ mod tests {
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_stream_excerpts_with_context_lines(cx: &mut TestAppContext) {
|
||||
let buffer =
|
||||
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), sample_text(20, 3, 'a')));
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
sample_text(20, 3, 'a'),
|
||||
)
|
||||
});
|
||||
let multibuffer = cx.new_model(|_| MultiBuffer::new(0, Capability::ReadWrite));
|
||||
let anchor_ranges = multibuffer.update(cx, |multibuffer, cx| {
|
||||
let snapshot = buffer.read(cx);
|
||||
@ -4641,7 +4682,9 @@ mod tests {
|
||||
|
||||
#[gpui::test]
|
||||
fn test_singleton_multibuffer_anchors(cx: &mut AppContext) {
|
||||
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abcd"));
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "abcd")
|
||||
});
|
||||
let multibuffer = cx.new_model(|cx| MultiBuffer::singleton(buffer.clone(), cx));
|
||||
let old_snapshot = multibuffer.read(cx).snapshot(cx);
|
||||
buffer.update(cx, |buffer, cx| {
|
||||
@ -4661,8 +4704,12 @@ mod tests {
|
||||
|
||||
#[gpui::test]
|
||||
fn test_multibuffer_anchors(cx: &mut AppContext) {
|
||||
let buffer_1 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abcd"));
|
||||
let buffer_2 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "efghi"));
|
||||
let buffer_1 = cx.new_model(|cx| {
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "abcd")
|
||||
});
|
||||
let buffer_2 = cx.new_model(|cx| {
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "efghi")
|
||||
});
|
||||
let multibuffer = cx.new_model(|cx| {
|
||||
let mut multibuffer = MultiBuffer::new(0, Capability::ReadWrite);
|
||||
multibuffer.push_excerpts(
|
||||
@ -4719,9 +4766,16 @@ mod tests {
|
||||
|
||||
#[gpui::test]
|
||||
fn test_resolving_anchors_after_replacing_their_excerpts(cx: &mut AppContext) {
|
||||
let buffer_1 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "abcd"));
|
||||
let buffer_2 =
|
||||
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "ABCDEFGHIJKLMNOP"));
|
||||
let buffer_1 = cx.new_model(|cx| {
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "abcd")
|
||||
});
|
||||
let buffer_2 = cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
"ABCDEFGHIJKLMNOP",
|
||||
)
|
||||
});
|
||||
let multibuffer = cx.new_model(|_| MultiBuffer::new(0, Capability::ReadWrite));
|
||||
|
||||
// Create an insertion id in buffer 1 that doesn't exist in buffer 2.
|
||||
@ -4932,9 +4986,13 @@ mod tests {
|
||||
let base_text = util::RandomCharIter::new(&mut rng)
|
||||
.take(10)
|
||||
.collect::<String>();
|
||||
buffers.push(
|
||||
cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), base_text)),
|
||||
);
|
||||
buffers.push(cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
base_text,
|
||||
)
|
||||
}));
|
||||
buffers.last().unwrap()
|
||||
} else {
|
||||
buffers.choose(&mut rng).unwrap()
|
||||
@ -5276,8 +5334,12 @@ mod tests {
|
||||
let test_settings = SettingsStore::test(cx);
|
||||
cx.set_global(test_settings);
|
||||
|
||||
let buffer_1 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "1234"));
|
||||
let buffer_2 = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), "5678"));
|
||||
let buffer_1 = cx.new_model(|cx| {
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "1234")
|
||||
});
|
||||
let buffer_2 = cx.new_model(|cx| {
|
||||
Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "5678")
|
||||
});
|
||||
let multibuffer = cx.new_model(|_| MultiBuffer::new(0, Capability::ReadWrite));
|
||||
let group_interval = multibuffer.read(cx).history.group_interval;
|
||||
multibuffer.update(cx, |multibuffer, cx| {
|
||||
|
@ -21,7 +21,7 @@ use lsp::{
|
||||
OneOf, ServerCapabilities,
|
||||
};
|
||||
use std::{cmp::Reverse, ops::Range, path::Path, sync::Arc};
|
||||
use text::LineEnding;
|
||||
use text::{BufferId, LineEnding};
|
||||
|
||||
pub fn lsp_formatting_options(tab_size: u32) -> lsp::FormattingOptions {
|
||||
lsp::FormattingOptions {
|
||||
@ -84,7 +84,7 @@ pub trait LspCommand: 'static + Sized + Send {
|
||||
cx: AsyncAppContext,
|
||||
) -> Result<Self::Response>;
|
||||
|
||||
fn buffer_id_from_proto(message: &Self::ProtoRequest) -> u64;
|
||||
fn buffer_id_from_proto(message: &Self::ProtoRequest) -> Result<BufferId>;
|
||||
}
|
||||
|
||||
pub(crate) struct PrepareRename {
|
||||
@ -205,7 +205,7 @@ impl LspCommand for PrepareRename {
|
||||
fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::PrepareRename {
|
||||
proto::PrepareRename {
|
||||
project_id,
|
||||
buffer_id: buffer.remote_id(),
|
||||
buffer_id: buffer.remote_id().into(),
|
||||
position: Some(language::proto::serialize_anchor(
|
||||
&buffer.anchor_before(self.position),
|
||||
)),
|
||||
@ -274,8 +274,8 @@ impl LspCommand for PrepareRename {
|
||||
}
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::PrepareRename) -> u64 {
|
||||
message.buffer_id
|
||||
fn buffer_id_from_proto(message: &proto::PrepareRename) -> Result<BufferId> {
|
||||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,7 +332,7 @@ impl LspCommand for PerformRename {
|
||||
fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::PerformRename {
|
||||
proto::PerformRename {
|
||||
project_id,
|
||||
buffer_id: buffer.remote_id(),
|
||||
buffer_id: buffer.remote_id().into(),
|
||||
position: Some(language::proto::serialize_anchor(
|
||||
&buffer.anchor_before(self.position),
|
||||
)),
|
||||
@ -393,8 +393,8 @@ impl LspCommand for PerformRename {
|
||||
.await
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::PerformRename) -> u64 {
|
||||
message.buffer_id
|
||||
fn buffer_id_from_proto(message: &proto::PerformRename) -> Result<BufferId> {
|
||||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,7 +437,7 @@ impl LspCommand for GetDefinition {
|
||||
fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetDefinition {
|
||||
proto::GetDefinition {
|
||||
project_id,
|
||||
buffer_id: buffer.remote_id(),
|
||||
buffer_id: buffer.remote_id().into(),
|
||||
position: Some(language::proto::serialize_anchor(
|
||||
&buffer.anchor_before(self.position),
|
||||
)),
|
||||
@ -486,8 +486,8 @@ impl LspCommand for GetDefinition {
|
||||
location_links_from_proto(message.links, project, cx).await
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::GetDefinition) -> u64 {
|
||||
message.buffer_id
|
||||
fn buffer_id_from_proto(message: &proto::GetDefinition) -> Result<BufferId> {
|
||||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -538,7 +538,7 @@ impl LspCommand for GetTypeDefinition {
|
||||
fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetTypeDefinition {
|
||||
proto::GetTypeDefinition {
|
||||
project_id,
|
||||
buffer_id: buffer.remote_id(),
|
||||
buffer_id: buffer.remote_id().into(),
|
||||
position: Some(language::proto::serialize_anchor(
|
||||
&buffer.anchor_before(self.position),
|
||||
)),
|
||||
@ -587,8 +587,8 @@ impl LspCommand for GetTypeDefinition {
|
||||
location_links_from_proto(message.links, project, cx).await
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::GetTypeDefinition) -> u64 {
|
||||
message.buffer_id
|
||||
fn buffer_id_from_proto(message: &proto::GetTypeDefinition) -> Result<BufferId> {
|
||||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -617,9 +617,10 @@ async fn location_links_from_proto(
|
||||
for link in proto_links {
|
||||
let origin = match link.origin {
|
||||
Some(origin) => {
|
||||
let buffer_id = BufferId::new(origin.buffer_id)?;
|
||||
let buffer = project
|
||||
.update(&mut cx, |this, cx| {
|
||||
this.wait_for_remote_buffer(origin.buffer_id, cx)
|
||||
this.wait_for_remote_buffer(buffer_id, cx)
|
||||
})?
|
||||
.await?;
|
||||
let start = origin
|
||||
@ -642,9 +643,10 @@ async fn location_links_from_proto(
|
||||
};
|
||||
|
||||
let target = link.target.ok_or_else(|| anyhow!("missing target"))?;
|
||||
let buffer_id = BufferId::new(target.buffer_id)?;
|
||||
let buffer = project
|
||||
.update(&mut cx, |this, cx| {
|
||||
this.wait_for_remote_buffer(target.buffer_id, cx)
|
||||
this.wait_for_remote_buffer(buffer_id, cx)
|
||||
})?
|
||||
.await?;
|
||||
let start = target
|
||||
@ -761,7 +763,9 @@ fn location_links_to_proto(
|
||||
.into_iter()
|
||||
.map(|definition| {
|
||||
let origin = definition.origin.map(|origin| {
|
||||
let buffer_id = project.create_buffer_for_peer(&origin.buffer, peer_id, cx);
|
||||
let buffer_id = project
|
||||
.create_buffer_for_peer(&origin.buffer, peer_id, cx)
|
||||
.into();
|
||||
proto::Location {
|
||||
start: Some(serialize_anchor(&origin.range.start)),
|
||||
end: Some(serialize_anchor(&origin.range.end)),
|
||||
@ -769,7 +773,9 @@ fn location_links_to_proto(
|
||||
}
|
||||
});
|
||||
|
||||
let buffer_id = project.create_buffer_for_peer(&definition.target.buffer, peer_id, cx);
|
||||
let buffer_id = project
|
||||
.create_buffer_for_peer(&definition.target.buffer, peer_id, cx)
|
||||
.into();
|
||||
let target = proto::Location {
|
||||
start: Some(serialize_anchor(&definition.target.range.start)),
|
||||
end: Some(serialize_anchor(&definition.target.range.end)),
|
||||
@ -859,7 +865,7 @@ impl LspCommand for GetReferences {
|
||||
fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetReferences {
|
||||
proto::GetReferences {
|
||||
project_id,
|
||||
buffer_id: buffer.remote_id(),
|
||||
buffer_id: buffer.remote_id().into(),
|
||||
position: Some(language::proto::serialize_anchor(
|
||||
&buffer.anchor_before(self.position),
|
||||
)),
|
||||
@ -901,7 +907,7 @@ impl LspCommand for GetReferences {
|
||||
proto::Location {
|
||||
start: Some(serialize_anchor(&definition.range.start)),
|
||||
end: Some(serialize_anchor(&definition.range.end)),
|
||||
buffer_id,
|
||||
buffer_id: buffer_id.into(),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
@ -917,9 +923,10 @@ impl LspCommand for GetReferences {
|
||||
) -> Result<Vec<Location>> {
|
||||
let mut locations = Vec::new();
|
||||
for location in message.locations {
|
||||
let buffer_id = BufferId::new(location.buffer_id)?;
|
||||
let target_buffer = project
|
||||
.update(&mut cx, |this, cx| {
|
||||
this.wait_for_remote_buffer(location.buffer_id, cx)
|
||||
this.wait_for_remote_buffer(buffer_id, cx)
|
||||
})?
|
||||
.await?;
|
||||
let start = location
|
||||
@ -941,8 +948,8 @@ impl LspCommand for GetReferences {
|
||||
Ok(locations)
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::GetReferences) -> u64 {
|
||||
message.buffer_id
|
||||
fn buffer_id_from_proto(message: &proto::GetReferences) -> Result<BufferId> {
|
||||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1007,7 +1014,7 @@ impl LspCommand for GetDocumentHighlights {
|
||||
fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetDocumentHighlights {
|
||||
proto::GetDocumentHighlights {
|
||||
project_id,
|
||||
buffer_id: buffer.remote_id(),
|
||||
buffer_id: buffer.remote_id().into(),
|
||||
position: Some(language::proto::serialize_anchor(
|
||||
&buffer.anchor_before(self.position),
|
||||
)),
|
||||
@ -1092,8 +1099,8 @@ impl LspCommand for GetDocumentHighlights {
|
||||
Ok(highlights)
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::GetDocumentHighlights) -> u64 {
|
||||
message.buffer_id
|
||||
fn buffer_id_from_proto(message: &proto::GetDocumentHighlights) -> Result<BufferId> {
|
||||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1195,7 +1202,7 @@ impl LspCommand for GetHover {
|
||||
fn to_proto(&self, project_id: u64, buffer: &Buffer) -> Self::ProtoRequest {
|
||||
proto::GetHover {
|
||||
project_id,
|
||||
buffer_id: buffer.remote_id(),
|
||||
buffer_id: buffer.remote_id().into(),
|
||||
position: Some(language::proto::serialize_anchor(
|
||||
&buffer.anchor_before(self.position),
|
||||
)),
|
||||
@ -1308,8 +1315,8 @@ impl LspCommand for GetHover {
|
||||
}))
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &Self::ProtoRequest) -> u64 {
|
||||
message.buffer_id
|
||||
fn buffer_id_from_proto(message: &Self::ProtoRequest) -> Result<BufferId> {
|
||||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1492,7 +1499,7 @@ impl LspCommand for GetCompletions {
|
||||
let anchor = buffer.anchor_after(self.position);
|
||||
proto::GetCompletions {
|
||||
project_id,
|
||||
buffer_id: buffer.remote_id(),
|
||||
buffer_id: buffer.remote_id().into(),
|
||||
position: Some(language::proto::serialize_anchor(&anchor)),
|
||||
version: serialize_version(&buffer.version()),
|
||||
}
|
||||
@ -1556,8 +1563,8 @@ impl LspCommand for GetCompletions {
|
||||
future::try_join_all(completions).await
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::GetCompletions) -> u64 {
|
||||
message.buffer_id
|
||||
fn buffer_id_from_proto(message: &proto::GetCompletions) -> Result<BufferId> {
|
||||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1630,7 +1637,7 @@ impl LspCommand for GetCodeActions {
|
||||
fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::GetCodeActions {
|
||||
proto::GetCodeActions {
|
||||
project_id,
|
||||
buffer_id: buffer.remote_id(),
|
||||
buffer_id: buffer.remote_id().into(),
|
||||
start: Some(language::proto::serialize_anchor(&self.range.start)),
|
||||
end: Some(language::proto::serialize_anchor(&self.range.end)),
|
||||
version: serialize_version(&buffer.version()),
|
||||
@ -1695,8 +1702,8 @@ impl LspCommand for GetCodeActions {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::GetCodeActions) -> u64 {
|
||||
message.buffer_id
|
||||
fn buffer_id_from_proto(message: &proto::GetCodeActions) -> Result<BufferId> {
|
||||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1768,7 +1775,7 @@ impl LspCommand for OnTypeFormatting {
|
||||
fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::OnTypeFormatting {
|
||||
proto::OnTypeFormatting {
|
||||
project_id,
|
||||
buffer_id: buffer.remote_id(),
|
||||
buffer_id: buffer.remote_id().into(),
|
||||
position: Some(language::proto::serialize_anchor(
|
||||
&buffer.anchor_before(self.position),
|
||||
)),
|
||||
@ -1831,8 +1838,8 @@ impl LspCommand for OnTypeFormatting {
|
||||
Ok(Some(language::proto::deserialize_transaction(transaction)?))
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::OnTypeFormatting) -> u64 {
|
||||
message.buffer_id
|
||||
fn buffer_id_from_proto(message: &proto::OnTypeFormatting) -> Result<BufferId> {
|
||||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2291,7 +2298,7 @@ impl LspCommand for InlayHints {
|
||||
fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::InlayHints {
|
||||
proto::InlayHints {
|
||||
project_id,
|
||||
buffer_id: buffer.remote_id(),
|
||||
buffer_id: buffer.remote_id().into(),
|
||||
start: Some(language::proto::serialize_anchor(&self.range.start)),
|
||||
end: Some(language::proto::serialize_anchor(&self.range.end)),
|
||||
version: serialize_version(&buffer.version()),
|
||||
@ -2358,7 +2365,7 @@ impl LspCommand for InlayHints {
|
||||
Ok(hints)
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::InlayHints) -> u64 {
|
||||
message.buffer_id
|
||||
fn buffer_id_from_proto(message: &proto::InlayHints) -> Result<BufferId> {
|
||||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
use std::{path::Path, sync::Arc};
|
||||
|
||||
use anyhow::Context;
|
||||
use anyhow::{Context, Result};
|
||||
use async_trait::async_trait;
|
||||
use gpui::{AppContext, AsyncAppContext, Model};
|
||||
use language::{point_to_lsp, proto::deserialize_anchor, Buffer};
|
||||
use lsp::{LanguageServer, LanguageServerId};
|
||||
use rpc::proto::{self, PeerId};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use text::{PointUtf16, ToPointUtf16};
|
||||
use text::{BufferId, PointUtf16, ToPointUtf16};
|
||||
|
||||
use crate::{lsp_command::LspCommand, Project};
|
||||
|
||||
@ -83,7 +83,7 @@ impl LspCommand for ExpandMacro {
|
||||
fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::LspExtExpandMacro {
|
||||
proto::LspExtExpandMacro {
|
||||
project_id,
|
||||
buffer_id: buffer.remote_id(),
|
||||
buffer_id: buffer.remote_id().into(),
|
||||
position: Some(language::proto::serialize_anchor(
|
||||
&buffer.anchor_before(self.position),
|
||||
)),
|
||||
@ -131,7 +131,7 @@ impl LspCommand for ExpandMacro {
|
||||
})
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::LspExtExpandMacro) -> u64 {
|
||||
message.buffer_id
|
||||
fn buffer_id_from_proto(message: &proto::LspExtExpandMacro) -> Result<BufferId> {
|
||||
BufferId::new(message.buffer_id)
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ mod project_tests;
|
||||
#[cfg(test)]
|
||||
mod worktree_tests;
|
||||
|
||||
use anyhow::{anyhow, Context as _, Result};
|
||||
use anyhow::{anyhow, bail, Context as _, Result};
|
||||
use client::{proto, Client, Collaborator, TypedEnvelope, UserStore};
|
||||
use clock::ReplicaId;
|
||||
use collections::{hash_map, BTreeMap, HashMap, HashSet, VecDeque};
|
||||
@ -81,7 +81,7 @@ use std::{
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use terminals::Terminals;
|
||||
use text::Anchor;
|
||||
use text::{Anchor, BufferId};
|
||||
use util::{
|
||||
debug_panic, defer, http::HttpClient, merge_json_value_into,
|
||||
paths::LOCAL_SETTINGS_RELATIVE_PATH, post_inc, ResultExt, TryFutureExt as _,
|
||||
@ -120,9 +120,9 @@ pub struct Project {
|
||||
collaborators: HashMap<proto::PeerId, Collaborator>,
|
||||
client_subscriptions: Vec<client::Subscription>,
|
||||
_subscriptions: Vec<gpui::Subscription>,
|
||||
next_buffer_id: u64,
|
||||
next_buffer_id: BufferId,
|
||||
opened_buffer: (watch::Sender<()>, watch::Receiver<()>),
|
||||
shared_buffers: HashMap<proto::PeerId, HashSet<u64>>,
|
||||
shared_buffers: HashMap<proto::PeerId, HashSet<BufferId>>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
loading_buffers_by_path: HashMap<
|
||||
ProjectPath,
|
||||
@ -131,14 +131,14 @@ pub struct Project {
|
||||
#[allow(clippy::type_complexity)]
|
||||
loading_local_worktrees:
|
||||
HashMap<Arc<Path>, Shared<Task<Result<Model<Worktree>, Arc<anyhow::Error>>>>>,
|
||||
opened_buffers: HashMap<u64, OpenBuffer>,
|
||||
local_buffer_ids_by_path: HashMap<ProjectPath, u64>,
|
||||
local_buffer_ids_by_entry_id: HashMap<ProjectEntryId, u64>,
|
||||
opened_buffers: HashMap<BufferId, OpenBuffer>,
|
||||
local_buffer_ids_by_path: HashMap<ProjectPath, BufferId>,
|
||||
local_buffer_ids_by_entry_id: HashMap<ProjectEntryId, BufferId>,
|
||||
/// A mapping from a buffer ID to None means that we've started waiting for an ID but haven't finished loading it.
|
||||
/// Used for re-issuing buffer requests when peers temporarily disconnect
|
||||
incomplete_remote_buffers: HashMap<u64, Option<Model<Buffer>>>,
|
||||
buffer_snapshots: HashMap<u64, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
|
||||
buffers_being_formatted: HashSet<u64>,
|
||||
incomplete_remote_buffers: HashMap<BufferId, Option<Model<Buffer>>>,
|
||||
buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
|
||||
buffers_being_formatted: HashSet<BufferId>,
|
||||
buffers_needing_diff: HashSet<WeakModel<Buffer>>,
|
||||
git_diff_debouncer: DelayedDebounced,
|
||||
nonce: u128,
|
||||
@ -210,7 +210,7 @@ struct LspBufferSnapshot {
|
||||
/// Message ordered with respect to buffer operations
|
||||
enum BufferOrderedMessage {
|
||||
Operation {
|
||||
buffer_id: u64,
|
||||
buffer_id: BufferId,
|
||||
operation: proto::Operation,
|
||||
},
|
||||
LanguageServerUpdate {
|
||||
@ -224,7 +224,7 @@ enum LocalProjectUpdate {
|
||||
WorktreesChanged,
|
||||
CreateBufferForPeer {
|
||||
peer_id: proto::PeerId,
|
||||
buffer_id: u64,
|
||||
buffer_id: BufferId,
|
||||
},
|
||||
}
|
||||
|
||||
@ -636,7 +636,7 @@ impl Project {
|
||||
worktrees: Vec::new(),
|
||||
buffer_ordered_messages_tx: tx,
|
||||
collaborators: Default::default(),
|
||||
next_buffer_id: 0,
|
||||
next_buffer_id: BufferId::new(1).unwrap(),
|
||||
opened_buffers: Default::default(),
|
||||
shared_buffers: Default::default(),
|
||||
incomplete_remote_buffers: Default::default(),
|
||||
@ -722,7 +722,7 @@ impl Project {
|
||||
worktrees: Vec::new(),
|
||||
buffer_ordered_messages_tx: tx,
|
||||
loading_buffers_by_path: Default::default(),
|
||||
next_buffer_id: 0,
|
||||
next_buffer_id: BufferId::default(),
|
||||
opened_buffer: watch::channel(),
|
||||
shared_buffers: Default::default(),
|
||||
incomplete_remote_buffers: Default::default(),
|
||||
@ -997,7 +997,7 @@ impl Project {
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn buffer_for_id(&self, remote_id: u64) -> Option<Model<Buffer>> {
|
||||
pub fn buffer_for_id(&self, remote_id: BufferId) -> Option<Model<Buffer>> {
|
||||
self.opened_buffers
|
||||
.get(&remote_id)
|
||||
.and_then(|buffer| buffer.upgrade())
|
||||
@ -1479,7 +1479,7 @@ impl Project {
|
||||
variant: Some(
|
||||
proto::create_buffer_for_peer::Variant::Chunk(
|
||||
proto::BufferChunk {
|
||||
buffer_id,
|
||||
buffer_id: buffer_id.into(),
|
||||
operations: chunk,
|
||||
is_last,
|
||||
},
|
||||
@ -1713,7 +1713,7 @@ impl Project {
|
||||
if self.is_remote() {
|
||||
return Err(anyhow!("creating buffers as a guest is not supported yet"));
|
||||
}
|
||||
let id = post_inc(&mut self.next_buffer_id);
|
||||
let id = self.next_buffer_id.next();
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(self.replica_id(), id, text)
|
||||
.with_language(language.unwrap_or_else(|| language::PLAIN_TEXT.clone()), cx)
|
||||
@ -1814,7 +1814,7 @@ impl Project {
|
||||
worktree: &Model<Worktree>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Model<Buffer>>> {
|
||||
let buffer_id = post_inc(&mut self.next_buffer_id);
|
||||
let buffer_id = self.next_buffer_id.next();
|
||||
let load_buffer = worktree.update(cx, |worktree, cx| {
|
||||
let worktree = worktree.as_local_mut().unwrap();
|
||||
worktree.load_buffer(buffer_id, path, cx)
|
||||
@ -1845,8 +1845,9 @@ impl Project {
|
||||
path: path_string,
|
||||
})
|
||||
.await?;
|
||||
let buffer_id = BufferId::new(response.buffer_id)?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.wait_for_remote_buffer(response.buffer_id, cx)
|
||||
this.wait_for_remote_buffer(buffer_id, cx)
|
||||
})?
|
||||
.await
|
||||
})
|
||||
@ -1895,7 +1896,7 @@ impl Project {
|
||||
|
||||
pub fn open_buffer_by_id(
|
||||
&mut self,
|
||||
id: u64,
|
||||
id: BufferId,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Model<Buffer>>> {
|
||||
if let Some(buffer) = self.buffer_for_id(id) {
|
||||
@ -1903,11 +1904,12 @@ impl Project {
|
||||
} else if self.is_local() {
|
||||
Task::ready(Err(anyhow!("buffer {} does not exist", id)))
|
||||
} else if let Some(project_id) = self.remote_id() {
|
||||
let request = self
|
||||
.client
|
||||
.request(proto::OpenBufferById { project_id, id });
|
||||
let request = self.client.request(proto::OpenBufferById {
|
||||
project_id,
|
||||
id: id.into(),
|
||||
});
|
||||
cx.spawn(move |this, mut cx| async move {
|
||||
let buffer_id = request.await?.buffer_id;
|
||||
let buffer_id = BufferId::new(request.await?.buffer_id)?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.wait_for_remote_buffer(buffer_id, cx)
|
||||
})?
|
||||
@ -2223,7 +2225,7 @@ impl Project {
|
||||
let mut operations_by_buffer_id = HashMap::default();
|
||||
async fn flush_operations(
|
||||
this: &WeakModel<Project>,
|
||||
operations_by_buffer_id: &mut HashMap<u64, Vec<proto::Operation>>,
|
||||
operations_by_buffer_id: &mut HashMap<BufferId, Vec<proto::Operation>>,
|
||||
needs_resync_with_host: &mut bool,
|
||||
is_local: bool,
|
||||
cx: &mut AsyncAppContext,
|
||||
@ -2232,7 +2234,7 @@ impl Project {
|
||||
let request = this.update(cx, |this, _| {
|
||||
let project_id = this.remote_id()?;
|
||||
Some(this.client.request(proto::UpdateBuffer {
|
||||
buffer_id,
|
||||
buffer_id: buffer_id.into(),
|
||||
project_id,
|
||||
operations,
|
||||
}))
|
||||
@ -4078,7 +4080,9 @@ impl Project {
|
||||
buffer_ids: remote_buffers
|
||||
.iter()
|
||||
.filter_map(|buffer| {
|
||||
buffer.update(&mut cx, |buffer, _| buffer.remote_id()).ok()
|
||||
buffer
|
||||
.update(&mut cx, |buffer, _| buffer.remote_id().into())
|
||||
.ok()
|
||||
})
|
||||
.collect(),
|
||||
})
|
||||
@ -4324,7 +4328,7 @@ impl Project {
|
||||
buffer_ids: buffers
|
||||
.iter()
|
||||
.map(|buffer| {
|
||||
buffer.update(&mut cx, |buffer, _| buffer.remote_id())
|
||||
buffer.update(&mut cx, |buffer, _| buffer.remote_id().into())
|
||||
})
|
||||
.collect::<Result<_>>()?,
|
||||
})
|
||||
@ -4720,8 +4724,9 @@ impl Project {
|
||||
});
|
||||
cx.spawn(move |this, mut cx| async move {
|
||||
let response = request.await?;
|
||||
let buffer_id = BufferId::new(response.buffer_id)?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.wait_for_remote_buffer(response.buffer_id, cx)
|
||||
this.wait_for_remote_buffer(buffer_id, cx)
|
||||
})?
|
||||
.await
|
||||
})
|
||||
@ -5047,7 +5052,7 @@ impl Project {
|
||||
let response = client
|
||||
.request(proto::ApplyCompletionAdditionalEdits {
|
||||
project_id,
|
||||
buffer_id,
|
||||
buffer_id: buffer_id.into(),
|
||||
completion: Some(language::proto::serialize_completion(&completion)),
|
||||
})
|
||||
.await?;
|
||||
@ -5179,7 +5184,7 @@ impl Project {
|
||||
let client = self.client.clone();
|
||||
let request = proto::ApplyCodeAction {
|
||||
project_id,
|
||||
buffer_id: buffer_handle.read(cx).remote_id(),
|
||||
buffer_id: buffer_handle.read(cx).remote_id().into(),
|
||||
action: Some(language::proto::serialize_code_action(&action)),
|
||||
};
|
||||
cx.spawn(move |this, mut cx| async move {
|
||||
@ -5242,7 +5247,7 @@ impl Project {
|
||||
let client = self.client.clone();
|
||||
let request = proto::OnTypeFormatting {
|
||||
project_id,
|
||||
buffer_id: buffer.read(cx).remote_id(),
|
||||
buffer_id: buffer.read(cx).remote_id().into(),
|
||||
position: Some(serialize_anchor(&position)),
|
||||
trigger,
|
||||
version: serialize_version(&buffer.read(cx).version()),
|
||||
@ -5531,7 +5536,7 @@ impl Project {
|
||||
let range = buffer.anchor_before(range.start)..buffer.anchor_before(range.end);
|
||||
let range_start = range.start;
|
||||
let range_end = range.end;
|
||||
let buffer_id = buffer.remote_id();
|
||||
let buffer_id = buffer.remote_id().into();
|
||||
let buffer_version = buffer.version().clone();
|
||||
let lsp_request = InlayHints { range };
|
||||
|
||||
@ -5624,7 +5629,7 @@ impl Project {
|
||||
let client = self.client.clone();
|
||||
let request = proto::ResolveInlayHint {
|
||||
project_id,
|
||||
buffer_id: buffer_handle.read(cx).remote_id(),
|
||||
buffer_id: buffer_handle.read(cx).remote_id().into(),
|
||||
language_server_id: server_id.0 as u64,
|
||||
hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
|
||||
};
|
||||
@ -5659,9 +5664,10 @@ impl Project {
|
||||
let response = request.await?;
|
||||
let mut result = HashMap::default();
|
||||
for location in response.locations {
|
||||
let buffer_id = BufferId::new(location.buffer_id)?;
|
||||
let target_buffer = this
|
||||
.update(&mut cx, |this, cx| {
|
||||
this.wait_for_remote_buffer(location.buffer_id, cx)
|
||||
this.wait_for_remote_buffer(buffer_id, cx)
|
||||
})?
|
||||
.await?;
|
||||
let start = location
|
||||
@ -6555,7 +6561,7 @@ impl Project {
|
||||
self.client
|
||||
.send(proto::UpdateBufferFile {
|
||||
project_id,
|
||||
buffer_id: buffer_id as u64,
|
||||
buffer_id: buffer_id.into(),
|
||||
file: Some(new_file.to_proto()),
|
||||
})
|
||||
.log_err();
|
||||
@ -6721,7 +6727,7 @@ impl Project {
|
||||
for (buffer, diff_base) in diff_bases_by_buffer {
|
||||
let buffer_id = buffer.update(&mut cx, |buffer, cx| {
|
||||
buffer.set_diff_base(diff_base.clone(), cx);
|
||||
buffer.remote_id()
|
||||
buffer.remote_id().into()
|
||||
})?;
|
||||
if let Some(project_id) = remote_id {
|
||||
client
|
||||
@ -7353,7 +7359,7 @@ impl Project {
|
||||
) -> Result<proto::Ack> {
|
||||
this.update(&mut cx, |this, cx| {
|
||||
let payload = envelope.payload.clone();
|
||||
let buffer_id = payload.buffer_id;
|
||||
let buffer_id = BufferId::new(payload.buffer_id)?;
|
||||
let ops = payload
|
||||
.operations
|
||||
.into_iter()
|
||||
@ -7404,7 +7410,7 @@ impl Project {
|
||||
as Arc<dyn language::File>);
|
||||
}
|
||||
|
||||
let buffer_id = state.id;
|
||||
let buffer_id = BufferId::new(state.id)?;
|
||||
let buffer = cx.new_model(|_| {
|
||||
Buffer::from_proto(this.replica_id(), this.capability(), state, buffer_file)
|
||||
.unwrap()
|
||||
@ -7413,9 +7419,10 @@ impl Project {
|
||||
.insert(buffer_id, Some(buffer));
|
||||
}
|
||||
proto::create_buffer_for_peer::Variant::Chunk(chunk) => {
|
||||
let buffer_id = BufferId::new(chunk.buffer_id)?;
|
||||
let buffer = this
|
||||
.incomplete_remote_buffers
|
||||
.get(&chunk.buffer_id)
|
||||
.get(&buffer_id)
|
||||
.cloned()
|
||||
.flatten()
|
||||
.ok_or_else(|| {
|
||||
@ -7432,7 +7439,7 @@ impl Project {
|
||||
buffer.update(cx, |buffer, cx| buffer.apply_ops(operations, cx))?;
|
||||
|
||||
if chunk.is_last {
|
||||
this.incomplete_remote_buffers.remove(&chunk.buffer_id);
|
||||
this.incomplete_remote_buffers.remove(&buffer_id);
|
||||
this.register_buffer(&buffer, cx)?;
|
||||
}
|
||||
}
|
||||
@ -7450,6 +7457,7 @@ impl Project {
|
||||
) -> Result<()> {
|
||||
this.update(&mut cx, |this, cx| {
|
||||
let buffer_id = envelope.payload.buffer_id;
|
||||
let buffer_id = BufferId::new(buffer_id)?;
|
||||
let diff_base = envelope.payload.diff_base;
|
||||
if let Some(buffer) = this
|
||||
.opened_buffers
|
||||
@ -7475,6 +7483,7 @@ impl Project {
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<()> {
|
||||
let buffer_id = envelope.payload.buffer_id;
|
||||
let buffer_id = BufferId::new(buffer_id)?;
|
||||
|
||||
this.update(&mut cx, |this, cx| {
|
||||
let payload = envelope.payload.clone();
|
||||
@ -7509,7 +7518,7 @@ impl Project {
|
||||
_: Arc<Client>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<proto::BufferSaved> {
|
||||
let buffer_id = envelope.payload.buffer_id;
|
||||
let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
|
||||
let (project_id, buffer) = this.update(&mut cx, |this, _cx| {
|
||||
let project_id = this.remote_id().ok_or_else(|| anyhow!("not connected"))?;
|
||||
let buffer = this
|
||||
@ -7530,7 +7539,7 @@ impl Project {
|
||||
.await?;
|
||||
Ok(buffer.update(&mut cx, |buffer, _| proto::BufferSaved {
|
||||
project_id,
|
||||
buffer_id,
|
||||
buffer_id: buffer_id.into(),
|
||||
version: serialize_version(buffer.saved_version()),
|
||||
mtime: Some(buffer.saved_mtime().into()),
|
||||
fingerprint: language::proto::serialize_fingerprint(buffer.saved_version_fingerprint()),
|
||||
@ -7547,9 +7556,10 @@ impl Project {
|
||||
let reload = this.update(&mut cx, |this, cx| {
|
||||
let mut buffers = HashSet::default();
|
||||
for buffer_id in &envelope.payload.buffer_ids {
|
||||
let buffer_id = BufferId::new(*buffer_id)?;
|
||||
buffers.insert(
|
||||
this.opened_buffers
|
||||
.get(buffer_id)
|
||||
.get(&buffer_id)
|
||||
.and_then(|buffer| buffer.upgrade())
|
||||
.ok_or_else(|| anyhow!("unknown buffer id {}", buffer_id))?,
|
||||
);
|
||||
@ -7580,12 +7590,12 @@ impl Project {
|
||||
this.update(&mut cx, |this, cx| {
|
||||
let Some(guest_id) = envelope.original_sender_id else {
|
||||
error!("missing original_sender_id on SynchronizeBuffers request");
|
||||
return;
|
||||
bail!("missing original_sender_id on SynchronizeBuffers request");
|
||||
};
|
||||
|
||||
this.shared_buffers.entry(guest_id).or_default().clear();
|
||||
for buffer in envelope.payload.buffers {
|
||||
let buffer_id = buffer.id;
|
||||
let buffer_id = BufferId::new(buffer.id)?;
|
||||
let remote_version = language::proto::deserialize_version(&buffer.version);
|
||||
if let Some(buffer) = this.buffer_for_id(buffer_id) {
|
||||
this.shared_buffers
|
||||
@ -7595,7 +7605,7 @@ impl Project {
|
||||
|
||||
let buffer = buffer.read(cx);
|
||||
response.buffers.push(proto::BufferVersion {
|
||||
id: buffer_id,
|
||||
id: buffer_id.into(),
|
||||
version: language::proto::serialize_version(&buffer.version),
|
||||
});
|
||||
|
||||
@ -7605,7 +7615,7 @@ impl Project {
|
||||
client
|
||||
.send(proto::UpdateBufferFile {
|
||||
project_id,
|
||||
buffer_id: buffer_id as u64,
|
||||
buffer_id: buffer_id.into(),
|
||||
file: Some(file.to_proto()),
|
||||
})
|
||||
.log_err();
|
||||
@ -7614,7 +7624,7 @@ impl Project {
|
||||
client
|
||||
.send(proto::UpdateDiffBase {
|
||||
project_id,
|
||||
buffer_id: buffer_id as u64,
|
||||
buffer_id: buffer_id.into(),
|
||||
diff_base: buffer.diff_base().map(Into::into),
|
||||
})
|
||||
.log_err();
|
||||
@ -7622,7 +7632,7 @@ impl Project {
|
||||
client
|
||||
.send(proto::BufferReloaded {
|
||||
project_id,
|
||||
buffer_id,
|
||||
buffer_id: buffer_id.into(),
|
||||
version: language::proto::serialize_version(buffer.saved_version()),
|
||||
mtime: Some(buffer.saved_mtime().into()),
|
||||
fingerprint: language::proto::serialize_fingerprint(
|
||||
@ -7642,7 +7652,7 @@ impl Project {
|
||||
client
|
||||
.request(proto::UpdateBuffer {
|
||||
project_id,
|
||||
buffer_id,
|
||||
buffer_id: buffer_id.into(),
|
||||
operations: chunk,
|
||||
})
|
||||
.await?;
|
||||
@ -7654,7 +7664,8 @@ impl Project {
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
})?;
|
||||
Ok(())
|
||||
})??;
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
@ -7669,9 +7680,10 @@ impl Project {
|
||||
let format = this.update(&mut cx, |this, cx| {
|
||||
let mut buffers = HashSet::default();
|
||||
for buffer_id in &envelope.payload.buffer_ids {
|
||||
let buffer_id = BufferId::new(*buffer_id)?;
|
||||
buffers.insert(
|
||||
this.opened_buffers
|
||||
.get(buffer_id)
|
||||
.get(&buffer_id)
|
||||
.and_then(|buffer| buffer.upgrade())
|
||||
.ok_or_else(|| anyhow!("unknown buffer id {}", buffer_id))?,
|
||||
);
|
||||
@ -7696,11 +7708,12 @@ impl Project {
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
|
||||
let (buffer, completion) = this.update(&mut cx, |this, cx| {
|
||||
let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
|
||||
let buffer = this
|
||||
.opened_buffers
|
||||
.get(&envelope.payload.buffer_id)
|
||||
.get(&buffer_id)
|
||||
.and_then(|buffer| buffer.upgrade())
|
||||
.ok_or_else(|| anyhow!("unknown buffer id {}", envelope.payload.buffer_id))?;
|
||||
.ok_or_else(|| anyhow!("unknown buffer id {}", buffer_id))?;
|
||||
let language = buffer.read(cx).language();
|
||||
let completion = language::proto::deserialize_completion(
|
||||
envelope
|
||||
@ -7774,9 +7787,10 @@ impl Project {
|
||||
.ok_or_else(|| anyhow!("invalid action"))?,
|
||||
)?;
|
||||
let apply_code_action = this.update(&mut cx, |this, cx| {
|
||||
let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
|
||||
let buffer = this
|
||||
.opened_buffers
|
||||
.get(&envelope.payload.buffer_id)
|
||||
.get(&buffer_id)
|
||||
.and_then(|buffer| buffer.upgrade())
|
||||
.ok_or_else(|| anyhow!("unknown buffer id {}", envelope.payload.buffer_id))?;
|
||||
Ok::<_, anyhow::Error>(this.apply_code_action(buffer, action, false, cx))
|
||||
@ -7798,11 +7812,12 @@ impl Project {
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<proto::OnTypeFormattingResponse> {
|
||||
let on_type_formatting = this.update(&mut cx, |this, cx| {
|
||||
let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
|
||||
let buffer = this
|
||||
.opened_buffers
|
||||
.get(&envelope.payload.buffer_id)
|
||||
.get(&buffer_id)
|
||||
.and_then(|buffer| buffer.upgrade())
|
||||
.ok_or_else(|| anyhow!("unknown buffer id {}", envelope.payload.buffer_id))?;
|
||||
.ok_or_else(|| anyhow!("unknown buffer id {}", buffer_id))?;
|
||||
let position = envelope
|
||||
.payload
|
||||
.position
|
||||
@ -7830,9 +7845,10 @@ impl Project {
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<proto::InlayHintsResponse> {
|
||||
let sender_id = envelope.original_sender_id()?;
|
||||
let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
|
||||
let buffer = this.update(&mut cx, |this, _| {
|
||||
this.opened_buffers
|
||||
.get(&envelope.payload.buffer_id)
|
||||
.get(&buffer_id)
|
||||
.and_then(|buffer| buffer.upgrade())
|
||||
.ok_or_else(|| anyhow!("unknown buffer id {}", envelope.payload.buffer_id))
|
||||
})??;
|
||||
@ -7886,10 +7902,11 @@ impl Project {
|
||||
let hint = InlayHints::proto_to_project_hint(proto_hint)
|
||||
.context("resolved proto inlay hint conversion")?;
|
||||
let buffer = this.update(&mut cx, |this, _cx| {
|
||||
let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
|
||||
this.opened_buffers
|
||||
.get(&envelope.payload.buffer_id)
|
||||
.get(&buffer_id)
|
||||
.and_then(|buffer| buffer.upgrade())
|
||||
.ok_or_else(|| anyhow!("unknown buffer id {}", envelope.payload.buffer_id))
|
||||
.ok_or_else(|| anyhow!("unknown buffer id {}", buffer_id))
|
||||
})??;
|
||||
let response_hint = this
|
||||
.update(&mut cx, |project, cx| {
|
||||
@ -7930,7 +7947,7 @@ impl Project {
|
||||
<T::LspRequest as lsp::request::Request>::Result: Send,
|
||||
{
|
||||
let sender_id = envelope.original_sender_id()?;
|
||||
let buffer_id = T::buffer_id_from_proto(&envelope.payload);
|
||||
let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
|
||||
let buffer_handle = this.update(&mut cx, |this, _cx| {
|
||||
this.opened_buffers
|
||||
.get(&buffer_id)
|
||||
@ -7995,7 +8012,7 @@ impl Project {
|
||||
let start = serialize_anchor(&range.start);
|
||||
let end = serialize_anchor(&range.end);
|
||||
let buffer_id = this.update(&mut cx, |this, cx| {
|
||||
this.create_buffer_for_peer(&buffer, peer_id, cx)
|
||||
this.create_buffer_for_peer(&buffer, peer_id, cx).into()
|
||||
})?;
|
||||
locations.push(proto::Location {
|
||||
buffer_id,
|
||||
@ -8037,7 +8054,7 @@ impl Project {
|
||||
|
||||
Ok(proto::OpenBufferForSymbolResponse {
|
||||
buffer_id: this.update(&mut cx, |this, cx| {
|
||||
this.create_buffer_for_peer(&buffer, peer_id, cx)
|
||||
this.create_buffer_for_peer(&buffer, peer_id, cx).into()
|
||||
})?,
|
||||
})
|
||||
}
|
||||
@ -8057,14 +8074,13 @@ impl Project {
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<proto::OpenBufferResponse> {
|
||||
let peer_id = envelope.original_sender_id()?;
|
||||
let buffer_id = BufferId::new(envelope.payload.id)?;
|
||||
let buffer = this
|
||||
.update(&mut cx, |this, cx| {
|
||||
this.open_buffer_by_id(envelope.payload.id, cx)
|
||||
})?
|
||||
.update(&mut cx, |this, cx| this.open_buffer_by_id(buffer_id, cx))?
|
||||
.await?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
Ok(proto::OpenBufferResponse {
|
||||
buffer_id: this.create_buffer_for_peer(&buffer, peer_id, cx),
|
||||
buffer_id: this.create_buffer_for_peer(&buffer, peer_id, cx).into(),
|
||||
})
|
||||
})?
|
||||
}
|
||||
@ -8090,7 +8106,7 @@ impl Project {
|
||||
let buffer = open_buffer.await?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
Ok(proto::OpenBufferResponse {
|
||||
buffer_id: this.create_buffer_for_peer(&buffer, peer_id, cx),
|
||||
buffer_id: this.create_buffer_for_peer(&buffer, peer_id, cx).into(),
|
||||
})
|
||||
})?
|
||||
}
|
||||
@ -8108,7 +8124,7 @@ impl Project {
|
||||
for (buffer, transaction) in project_transaction.0 {
|
||||
serialized_transaction
|
||||
.buffer_ids
|
||||
.push(self.create_buffer_for_peer(&buffer, peer_id, cx));
|
||||
.push(self.create_buffer_for_peer(&buffer, peer_id, cx).into());
|
||||
serialized_transaction
|
||||
.transactions
|
||||
.push(language::proto::serialize_transaction(&transaction));
|
||||
@ -8126,6 +8142,7 @@ impl Project {
|
||||
let mut project_transaction = ProjectTransaction::default();
|
||||
for (buffer_id, transaction) in message.buffer_ids.into_iter().zip(message.transactions)
|
||||
{
|
||||
let buffer_id = BufferId::new(buffer_id)?;
|
||||
let buffer = this
|
||||
.update(&mut cx, |this, cx| {
|
||||
this.wait_for_remote_buffer(buffer_id, cx)
|
||||
@ -8158,7 +8175,7 @@ impl Project {
|
||||
buffer: &Model<Buffer>,
|
||||
peer_id: proto::PeerId,
|
||||
cx: &mut AppContext,
|
||||
) -> u64 {
|
||||
) -> BufferId {
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
if let ProjectClientState::Shared { updates_tx, .. } = &self.client_state {
|
||||
updates_tx
|
||||
@ -8170,7 +8187,7 @@ impl Project {
|
||||
|
||||
fn wait_for_remote_buffer(
|
||||
&mut self,
|
||||
id: u64,
|
||||
id: BufferId,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Model<Buffer>>> {
|
||||
let mut opened_buffer_rx = self.opened_buffer.1.clone();
|
||||
@ -8239,7 +8256,7 @@ impl Project {
|
||||
.filter_map(|(id, buffer)| {
|
||||
let buffer = buffer.upgrade()?;
|
||||
Some(proto::BufferVersion {
|
||||
id: *id,
|
||||
id: (*id).into(),
|
||||
version: language::proto::serialize_version(&buffer.read(cx).version),
|
||||
})
|
||||
})
|
||||
@ -8265,7 +8282,12 @@ impl Project {
|
||||
.into_iter()
|
||||
.map(|buffer| {
|
||||
let client = client.clone();
|
||||
let buffer_id = buffer.id;
|
||||
let buffer_id = match BufferId::new(buffer.id) {
|
||||
Ok(id) => id,
|
||||
Err(e) => {
|
||||
return Task::ready(Err(e));
|
||||
}
|
||||
};
|
||||
let remote_version = language::proto::deserialize_version(&buffer.version);
|
||||
if let Some(buffer) = this.buffer_for_id(buffer_id) {
|
||||
let operations =
|
||||
@ -8276,7 +8298,7 @@ impl Project {
|
||||
client
|
||||
.request(proto::UpdateBuffer {
|
||||
project_id,
|
||||
buffer_id,
|
||||
buffer_id: buffer_id.into(),
|
||||
operations: chunk,
|
||||
})
|
||||
.await?;
|
||||
@ -8294,7 +8316,10 @@ impl Project {
|
||||
// creates these buffers for us again to unblock any waiting futures.
|
||||
for id in incomplete_buffer_ids {
|
||||
cx.background_executor()
|
||||
.spawn(client.request(proto::OpenBufferById { project_id, id }))
|
||||
.spawn(client.request(proto::OpenBufferById {
|
||||
project_id,
|
||||
id: id.into(),
|
||||
}))
|
||||
.detach();
|
||||
}
|
||||
|
||||
@ -8436,6 +8461,7 @@ impl Project {
|
||||
) -> Result<()> {
|
||||
let fingerprint = deserialize_fingerprint(&envelope.payload.fingerprint)?;
|
||||
let version = deserialize_version(&envelope.payload.version);
|
||||
let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
|
||||
let mtime = envelope
|
||||
.payload
|
||||
.mtime
|
||||
@ -8445,11 +8471,11 @@ impl Project {
|
||||
this.update(&mut cx, |this, cx| {
|
||||
let buffer = this
|
||||
.opened_buffers
|
||||
.get(&envelope.payload.buffer_id)
|
||||
.get(&buffer_id)
|
||||
.and_then(|buffer| buffer.upgrade())
|
||||
.or_else(|| {
|
||||
this.incomplete_remote_buffers
|
||||
.get(&envelope.payload.buffer_id)
|
||||
.get(&buffer_id)
|
||||
.and_then(|b| b.clone())
|
||||
});
|
||||
if let Some(buffer) = buffer {
|
||||
@ -8478,14 +8504,15 @@ impl Project {
|
||||
.mtime
|
||||
.ok_or_else(|| anyhow!("missing mtime"))?
|
||||
.into();
|
||||
let buffer_id = BufferId::new(payload.buffer_id)?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
let buffer = this
|
||||
.opened_buffers
|
||||
.get(&payload.buffer_id)
|
||||
.get(&buffer_id)
|
||||
.and_then(|buffer| buffer.upgrade())
|
||||
.or_else(|| {
|
||||
this.incomplete_remote_buffers
|
||||
.get(&payload.buffer_id)
|
||||
.get(&buffer_id)
|
||||
.cloned()
|
||||
.flatten()
|
||||
});
|
||||
|
@ -62,6 +62,7 @@ use std::{
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
use sum_tree::{Bias, Edit, SeekTarget, SumTree, TreeMap, TreeSet};
|
||||
use text::BufferId;
|
||||
use util::{
|
||||
paths::{PathMatcher, HOME},
|
||||
ResultExt,
|
||||
@ -672,7 +673,7 @@ impl LocalWorktree {
|
||||
|
||||
pub(crate) fn load_buffer(
|
||||
&mut self,
|
||||
id: u64,
|
||||
id: BufferId,
|
||||
path: &Path,
|
||||
cx: &mut ModelContext<Worktree>,
|
||||
) -> Task<Result<Model<Buffer>>> {
|
||||
@ -1043,7 +1044,7 @@ impl LocalWorktree {
|
||||
let buffer = buffer_handle.read(cx);
|
||||
|
||||
let rpc = self.client.clone();
|
||||
let buffer_id = buffer.remote_id();
|
||||
let buffer_id: u64 = buffer.remote_id().into();
|
||||
let project_id = self.share.as_ref().map(|share| share.project_id);
|
||||
|
||||
let text = buffer.as_rope().clone();
|
||||
@ -1481,7 +1482,7 @@ impl RemoteWorktree {
|
||||
cx: &mut ModelContext<Worktree>,
|
||||
) -> Task<Result<()>> {
|
||||
let buffer = buffer_handle.read(cx);
|
||||
let buffer_id = buffer.remote_id();
|
||||
let buffer_id = buffer.remote_id().into();
|
||||
let version = buffer.version();
|
||||
let rpc = self.client.clone();
|
||||
let project_id = self.project_id;
|
||||
@ -2840,7 +2841,7 @@ impl language::LocalFile for File {
|
||||
|
||||
fn buffer_reloaded(
|
||||
&self,
|
||||
buffer_id: u64,
|
||||
buffer_id: BufferId,
|
||||
version: &clock::Global,
|
||||
fingerprint: RopeFingerprint,
|
||||
line_ending: LineEnding,
|
||||
@ -2853,7 +2854,7 @@ impl language::LocalFile for File {
|
||||
.client
|
||||
.send(proto::BufferReloaded {
|
||||
project_id,
|
||||
buffer_id,
|
||||
buffer_id: buffer_id.into(),
|
||||
version: serialize_version(version),
|
||||
mtime: Some(mtime.into()),
|
||||
fingerprint: serialize_fingerprint(fingerprint),
|
||||
|
@ -21,6 +21,7 @@ use std::{
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use text::BufferId;
|
||||
use util::{http::FakeHttpClient, test::temp_tree, ResultExt};
|
||||
|
||||
#[gpui::test]
|
||||
@ -511,9 +512,11 @@ async fn test_open_gitignored_files(cx: &mut TestAppContext) {
|
||||
let prev_read_dir_count = fs.read_dir_call_count();
|
||||
let buffer = tree
|
||||
.update(cx, |tree, cx| {
|
||||
tree.as_local_mut()
|
||||
.unwrap()
|
||||
.load_buffer(0, "one/node_modules/b/b1.js".as_ref(), cx)
|
||||
tree.as_local_mut().unwrap().load_buffer(
|
||||
BufferId::new(1).unwrap(),
|
||||
"one/node_modules/b/b1.js".as_ref(),
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
@ -553,9 +556,11 @@ async fn test_open_gitignored_files(cx: &mut TestAppContext) {
|
||||
let prev_read_dir_count = fs.read_dir_call_count();
|
||||
let buffer = tree
|
||||
.update(cx, |tree, cx| {
|
||||
tree.as_local_mut()
|
||||
.unwrap()
|
||||
.load_buffer(0, "one/node_modules/a/a2.js".as_ref(), cx)
|
||||
tree.as_local_mut().unwrap().load_buffer(
|
||||
BufferId::new(1).unwrap(),
|
||||
"one/node_modules/a/a2.js".as_ref(),
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
@ -1007,7 +1007,7 @@ mod tests {
|
||||
use super::*;
|
||||
use editor::{DisplayPoint, Editor};
|
||||
use gpui::{Context, Hsla, TestAppContext, VisualTestContext};
|
||||
use language::Buffer;
|
||||
use language::{Buffer, BufferId};
|
||||
use smol::stream::StreamExt as _;
|
||||
use unindent::Unindent as _;
|
||||
|
||||
@ -1029,7 +1029,7 @@ mod tests {
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
cx.entity_id().as_u64(),
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
r#"
|
||||
A regular expression (shortened as regex or regexp;[1] also referred to as
|
||||
rational expression[2][3]) is a sequence of characters that specifies a search
|
||||
@ -1385,7 +1385,13 @@ mod tests {
|
||||
expected_query_matches_count > 1,
|
||||
"Should pick a query with multiple results"
|
||||
);
|
||||
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), buffer_text));
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
buffer_text,
|
||||
)
|
||||
});
|
||||
let window = cx.add_window(|_| ());
|
||||
|
||||
let editor = window.build_view(cx, |cx| Editor::for_buffer(buffer.clone(), None, cx));
|
||||
@ -1581,7 +1587,13 @@ mod tests {
|
||||
for "find" or "find and replace" operations on strings, or for input validation.
|
||||
"#
|
||||
.unindent();
|
||||
let buffer = cx.new_model(|cx| Buffer::new(0, cx.entity_id().as_u64(), buffer_text));
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(
|
||||
0,
|
||||
BufferId::new(cx.entity_id().as_u64()).unwrap(),
|
||||
buffer_text,
|
||||
)
|
||||
});
|
||||
let cx = cx.add_empty_window();
|
||||
|
||||
let editor = cx.new_view(|cx| Editor::for_buffer(buffer.clone(), None, cx));
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
locator::Locator, BufferSnapshot, Point, PointUtf16, TextDimension, ToOffset, ToPoint,
|
||||
ToPointUtf16,
|
||||
locator::Locator, BufferId, BufferSnapshot, Point, PointUtf16, TextDimension, ToOffset,
|
||||
ToPoint, ToPointUtf16,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use std::{cmp::Ordering, fmt::Debug, ops::Range};
|
||||
@ -11,7 +11,7 @@ pub struct Anchor {
|
||||
pub timestamp: clock::Lamport,
|
||||
pub offset: usize,
|
||||
pub bias: Bias,
|
||||
pub buffer_id: Option<u64>,
|
||||
pub buffer_id: Option<BufferId>,
|
||||
}
|
||||
|
||||
impl Anchor {
|
||||
|
@ -18,7 +18,7 @@ fn init_logger() {
|
||||
|
||||
#[test]
|
||||
fn test_edit() {
|
||||
let mut buffer = Buffer::new(0, 0, "abc".into());
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), "abc".into());
|
||||
assert_eq!(buffer.text(), "abc");
|
||||
buffer.edit([(3..3, "def")]);
|
||||
assert_eq!(buffer.text(), "abcdef");
|
||||
@ -42,7 +42,7 @@ fn test_random_edits(mut rng: StdRng) {
|
||||
let mut reference_string = RandomCharIter::new(&mut rng)
|
||||
.take(reference_string_len)
|
||||
.collect::<String>();
|
||||
let mut buffer = Buffer::new(0, 0, reference_string.clone());
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), reference_string.clone());
|
||||
LineEnding::normalize(&mut reference_string);
|
||||
|
||||
buffer.set_group_interval(Duration::from_millis(rng.gen_range(0..=200)));
|
||||
@ -164,7 +164,7 @@ fn test_line_endings() {
|
||||
LineEnding::Windows
|
||||
);
|
||||
|
||||
let mut buffer = Buffer::new(0, 0, "one\r\ntwo\rthree".into());
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), "one\r\ntwo\rthree".into());
|
||||
assert_eq!(buffer.text(), "one\ntwo\nthree");
|
||||
assert_eq!(buffer.line_ending(), LineEnding::Windows);
|
||||
buffer.check_invariants();
|
||||
@ -178,7 +178,7 @@ fn test_line_endings() {
|
||||
|
||||
#[test]
|
||||
fn test_line_len() {
|
||||
let mut buffer = Buffer::new(0, 0, "".into());
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), "".into());
|
||||
buffer.edit([(0..0, "abcd\nefg\nhij")]);
|
||||
buffer.edit([(12..12, "kl\nmno")]);
|
||||
buffer.edit([(18..18, "\npqrs\n")]);
|
||||
@ -195,7 +195,7 @@ fn test_line_len() {
|
||||
#[test]
|
||||
fn test_common_prefix_at_position() {
|
||||
let text = "a = str; b = δα";
|
||||
let buffer = Buffer::new(0, 0, text.into());
|
||||
let buffer = Buffer::new(0, BufferId::new(1).unwrap(), text.into());
|
||||
|
||||
let offset1 = offset_after(text, "str");
|
||||
let offset2 = offset_after(text, "δα");
|
||||
@ -243,7 +243,11 @@ fn test_common_prefix_at_position() {
|
||||
|
||||
#[test]
|
||||
fn test_text_summary_for_range() {
|
||||
let buffer = Buffer::new(0, 0, "ab\nefg\nhklm\nnopqrs\ntuvwxyz".into());
|
||||
let buffer = Buffer::new(
|
||||
0,
|
||||
BufferId::new(1).unwrap(),
|
||||
"ab\nefg\nhklm\nnopqrs\ntuvwxyz".into(),
|
||||
);
|
||||
assert_eq!(
|
||||
buffer.text_summary_for_range::<TextSummary, _>(1..3),
|
||||
TextSummary {
|
||||
@ -313,7 +317,7 @@ fn test_text_summary_for_range() {
|
||||
|
||||
#[test]
|
||||
fn test_chars_at() {
|
||||
let mut buffer = Buffer::new(0, 0, "".into());
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), "".into());
|
||||
buffer.edit([(0..0, "abcd\nefgh\nij")]);
|
||||
buffer.edit([(12..12, "kl\nmno")]);
|
||||
buffer.edit([(18..18, "\npqrs")]);
|
||||
@ -335,7 +339,7 @@ fn test_chars_at() {
|
||||
assert_eq!(chars.collect::<String>(), "PQrs");
|
||||
|
||||
// Regression test:
|
||||
let mut buffer = Buffer::new(0, 0, "".into());
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), "".into());
|
||||
buffer.edit([(0..0, "[workspace]\nmembers = [\n \"xray_core\",\n \"xray_server\",\n \"xray_cli\",\n \"xray_wasm\",\n]\n")]);
|
||||
buffer.edit([(60..60, "\n")]);
|
||||
|
||||
@ -345,7 +349,7 @@ fn test_chars_at() {
|
||||
|
||||
#[test]
|
||||
fn test_anchors() {
|
||||
let mut buffer = Buffer::new(0, 0, "".into());
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), "".into());
|
||||
buffer.edit([(0..0, "abc")]);
|
||||
let left_anchor = buffer.anchor_before(2);
|
||||
let right_anchor = buffer.anchor_after(2);
|
||||
@ -463,7 +467,7 @@ fn test_anchors() {
|
||||
|
||||
#[test]
|
||||
fn test_anchors_at_start_and_end() {
|
||||
let mut buffer = Buffer::new(0, 0, "".into());
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), "".into());
|
||||
let before_start_anchor = buffer.anchor_before(0);
|
||||
let after_end_anchor = buffer.anchor_after(0);
|
||||
|
||||
@ -486,7 +490,7 @@ fn test_anchors_at_start_and_end() {
|
||||
|
||||
#[test]
|
||||
fn test_undo_redo() {
|
||||
let mut buffer = Buffer::new(0, 0, "1234".into());
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), "1234".into());
|
||||
// Set group interval to zero so as to not group edits in the undo stack.
|
||||
buffer.set_group_interval(Duration::from_secs(0));
|
||||
|
||||
@ -523,7 +527,7 @@ fn test_undo_redo() {
|
||||
#[test]
|
||||
fn test_history() {
|
||||
let mut now = Instant::now();
|
||||
let mut buffer = Buffer::new(0, 0, "123456".into());
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), "123456".into());
|
||||
buffer.set_group_interval(Duration::from_millis(300));
|
||||
|
||||
let transaction_1 = buffer.start_transaction_at(now).unwrap();
|
||||
@ -590,7 +594,7 @@ fn test_history() {
|
||||
#[test]
|
||||
fn test_finalize_last_transaction() {
|
||||
let now = Instant::now();
|
||||
let mut buffer = Buffer::new(0, 0, "123456".into());
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), "123456".into());
|
||||
|
||||
buffer.start_transaction_at(now);
|
||||
buffer.edit([(2..4, "cd")]);
|
||||
@ -625,7 +629,7 @@ fn test_finalize_last_transaction() {
|
||||
#[test]
|
||||
fn test_edited_ranges_for_transaction() {
|
||||
let now = Instant::now();
|
||||
let mut buffer = Buffer::new(0, 0, "1234567".into());
|
||||
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), "1234567".into());
|
||||
|
||||
buffer.start_transaction_at(now);
|
||||
buffer.edit([(2..4, "cd")]);
|
||||
@ -664,9 +668,9 @@ fn test_edited_ranges_for_transaction() {
|
||||
fn test_concurrent_edits() {
|
||||
let text = "abcdef";
|
||||
|
||||
let mut buffer1 = Buffer::new(1, 0, text.into());
|
||||
let mut buffer2 = Buffer::new(2, 0, text.into());
|
||||
let mut buffer3 = Buffer::new(3, 0, text.into());
|
||||
let mut buffer1 = Buffer::new(1, BufferId::new(1).unwrap(), text.into());
|
||||
let mut buffer2 = Buffer::new(2, BufferId::new(1).unwrap(), text.into());
|
||||
let mut buffer3 = Buffer::new(3, BufferId::new(1).unwrap(), text.into());
|
||||
|
||||
let buf1_op = buffer1.edit([(1..2, "12")]);
|
||||
assert_eq!(buffer1.text(), "a12cdef");
|
||||
@ -705,7 +709,7 @@ fn test_random_concurrent_edits(mut rng: StdRng) {
|
||||
let mut network = Network::new(rng.clone());
|
||||
|
||||
for i in 0..peers {
|
||||
let mut buffer = Buffer::new(i as ReplicaId, 0, base_text.clone());
|
||||
let mut buffer = Buffer::new(i as ReplicaId, BufferId::new(1).unwrap(), base_text.clone());
|
||||
buffer.history.group_interval = Duration::from_millis(rng.gen_range(0..=200));
|
||||
buffers.push(buffer);
|
||||
replica_ids.push(i as u16);
|
||||
|
@ -26,6 +26,7 @@ pub use selection::*;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
cmp::{self, Ordering, Reverse},
|
||||
fmt::Display,
|
||||
future::Future,
|
||||
iter::Iterator,
|
||||
ops::{self, Deref, Range, Sub},
|
||||
@ -59,10 +60,39 @@ pub struct Buffer {
|
||||
wait_for_version_txs: Vec<(clock::Global, oneshot::Sender<()>)>,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, PartialOrd, Ord, Eq)]
|
||||
pub struct BufferId(u64);
|
||||
|
||||
impl Display for BufferId {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl BufferId {
|
||||
/// Returns Err if `id` is outside of BufferId domain.
|
||||
pub fn new(id: u64) -> anyhow::Result<Self> {
|
||||
Ok(Self(id))
|
||||
}
|
||||
/// Increments this buffer id, returning the old value.
|
||||
/// So that's a post-increment operator in disguise.
|
||||
pub fn next(&mut self) -> Self {
|
||||
let old = *self;
|
||||
self.0 += 1;
|
||||
old
|
||||
}
|
||||
}
|
||||
impl From<BufferId> for u64 {
|
||||
fn from(id: BufferId) -> Self {
|
||||
id.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BufferSnapshot {
|
||||
replica_id: ReplicaId,
|
||||
remote_id: u64,
|
||||
remote_id: BufferId,
|
||||
visible_text: Rope,
|
||||
deleted_text: Rope,
|
||||
line_ending: LineEnding,
|
||||
@ -369,7 +399,7 @@ struct Edits<'a, D: TextDimension, F: FnMut(&FragmentSummary) -> bool> {
|
||||
old_end: D,
|
||||
new_end: D,
|
||||
range: Range<(&'a Locator, usize)>,
|
||||
buffer_id: u64,
|
||||
buffer_id: BufferId,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
@ -478,7 +508,7 @@ pub struct UndoOperation {
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
pub fn new(replica_id: u16, remote_id: u64, mut base_text: String) -> Buffer {
|
||||
pub fn new(replica_id: u16, remote_id: BufferId, mut base_text: String) -> Buffer {
|
||||
let line_ending = LineEnding::detect(&base_text);
|
||||
LineEnding::normalize(&mut base_text);
|
||||
|
||||
@ -545,7 +575,7 @@ impl Buffer {
|
||||
self.lamport_clock.replica_id
|
||||
}
|
||||
|
||||
pub fn remote_id(&self) -> u64 {
|
||||
pub fn remote_id(&self) -> BufferId {
|
||||
self.remote_id
|
||||
}
|
||||
|
||||
@ -1590,7 +1620,7 @@ impl BufferSnapshot {
|
||||
&self.visible_text
|
||||
}
|
||||
|
||||
pub fn remote_id(&self) -> u64 {
|
||||
pub fn remote_id(&self) -> BufferId {
|
||||
self.remote_id
|
||||
}
|
||||
|
||||
|
@ -69,14 +69,14 @@ mod test {
|
||||
use crate::{test::VimTestContext, Vim};
|
||||
use editor::Editor;
|
||||
use gpui::{Context, Entity, VisualTestContext};
|
||||
use language::Buffer;
|
||||
use language::{Buffer, BufferId};
|
||||
|
||||
// regression test for blur called with a different active editor
|
||||
#[gpui::test]
|
||||
async fn test_blur_focus(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
|
||||
let buffer = cx.new_model(|_| Buffer::new(0, 0, "a = 1\nb = 2\n"));
|
||||
let buffer = cx.new_model(|_| Buffer::new(0, BufferId::new(1).unwrap(), "a = 1\nb = 2\n"));
|
||||
let window2 = cx.add_window(|cx| Editor::for_buffer(buffer, None, cx));
|
||||
let editor2 = cx
|
||||
.update(|cx| {
|
||||
@ -111,7 +111,7 @@ mod test {
|
||||
let mut cx1 = VisualTestContext::from_window(cx.window, &cx);
|
||||
let editor1 = cx.editor.clone();
|
||||
|
||||
let buffer = cx.new_model(|_| Buffer::new(0, 0, "a = 1\nb = 2\n"));
|
||||
let buffer = cx.new_model(|_| Buffer::new(0, BufferId::new(1).unwrap(), "a = 1\nb = 2\n"));
|
||||
let (editor2, cx2) = cx.add_window_view(|cx| Editor::for_buffer(buffer, None, cx));
|
||||
|
||||
editor2.update(cx2, |_, cx| {
|
||||
|
@ -278,6 +278,7 @@ mod tests {
|
||||
use language::{language_settings::AllLanguageSettings, AutoindentMode, Buffer};
|
||||
use settings::SettingsStore;
|
||||
use std::num::NonZeroU32;
|
||||
use text::BufferId;
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_c_autoindent(cx: &mut TestAppContext) {
|
||||
@ -295,8 +296,8 @@ mod tests {
|
||||
let language = crate::languages::language("c", tree_sitter_c::language(), None).await;
|
||||
|
||||
cx.new_model(|cx| {
|
||||
let mut buffer =
|
||||
Buffer::new(0, cx.entity_id().as_u64(), "").with_language(language, cx);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "")
|
||||
.with_language(language, cx);
|
||||
|
||||
// empty function
|
||||
buffer.edit([(0..0, "int main() {}")], None, cx);
|
||||
|
@ -181,6 +181,7 @@ mod tests {
|
||||
use language::{language_settings::AllLanguageSettings, AutoindentMode, Buffer};
|
||||
use settings::SettingsStore;
|
||||
use std::num::NonZeroU32;
|
||||
use text::BufferId;
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_python_autoindent(cx: &mut TestAppContext) {
|
||||
@ -199,8 +200,8 @@ mod tests {
|
||||
});
|
||||
|
||||
cx.new_model(|cx| {
|
||||
let mut buffer =
|
||||
Buffer::new(0, cx.entity_id().as_u64(), "").with_language(language, cx);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "")
|
||||
.with_language(language, cx);
|
||||
let append = |buffer: &mut Buffer, text: &str, cx: &mut ModelContext<Buffer>| {
|
||||
let ix = buffer.len();
|
||||
buffer.edit([(ix..ix, text)], Some(AutoindentMode::EachLine), cx);
|
||||
|
@ -297,6 +297,7 @@ mod tests {
|
||||
use gpui::{Context, Hsla, TestAppContext};
|
||||
use language::language_settings::AllLanguageSettings;
|
||||
use settings::SettingsStore;
|
||||
use text::BufferId;
|
||||
use theme::SyntaxTheme;
|
||||
|
||||
#[gpui::test]
|
||||
@ -509,8 +510,8 @@ mod tests {
|
||||
let language = crate::languages::language("rust", tree_sitter_rust::language(), None).await;
|
||||
|
||||
cx.new_model(|cx| {
|
||||
let mut buffer =
|
||||
Buffer::new(0, cx.entity_id().as_u64(), "").with_language(language, cx);
|
||||
let mut buffer = Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), "")
|
||||
.with_language(language, cx);
|
||||
|
||||
// indent between braces
|
||||
buffer.set_text("fn a() {}", cx);
|
||||
|
@ -349,6 +349,7 @@ async fn get_cached_eslint_server_binary(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use gpui::{Context, TestAppContext};
|
||||
use text::BufferId;
|
||||
use unindent::Unindent;
|
||||
|
||||
#[gpui::test]
|
||||
@ -376,7 +377,8 @@ mod tests {
|
||||
.unindent();
|
||||
|
||||
let buffer = cx.new_model(|cx| {
|
||||
language::Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
|
||||
language::Buffer::new(0, BufferId::new(cx.entity_id().as_u64()).unwrap(), text)
|
||||
.with_language(language, cx)
|
||||
});
|
||||
let outline = buffer.update(cx, |buffer, _| buffer.snapshot().outline(None).unwrap());
|
||||
assert_eq!(
|
||||
|
Loading…
Reference in New Issue
Block a user