Improve the ergonomics of creating local buffers (#10347)
This PR renames `language::Buffer::new` to `language::Buffer::local` and
simplifies its interface. Instead of taking a replica id (which should
always be 0 for the local case) and a `BufferId`, which was awkward and
verbose to construct, it simply takes text and a `cx`.
It uses the `cx` to derive a `BufferId` from the `EntityId` associated
with the `cx`, which should always be positive based on the following
analysis...
We convert the entity id to a u64 using this method on `EntityId`, which
is defined by macros in the `slotmap` crate:
```rust
pub fn as_ffi(self) -> u64 {
(u64::from(self.version.get()) << 32) | u64::from(self.idx)
}
```
If you look at the type of `version` in `KeyData`, it is non-zero:
```rust
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct KeyData {
idx: u32,
version: NonZeroU32,
}
```
This commit also adds `Context::reserve_model` and
`Context::insert_model` to determine a model's entity ID before it is
created, which we need in order to assign a `BufferId` in the background
when loading a buffer asynchronously.
Release Notes:
- N/A
---------
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
This commit is contained in:
co-authored by
Piotr Osiewicz
parent
664efef76b
commit
7abb63cfda
@@ -178,7 +178,6 @@ pub struct Project {
|
||||
collaborators: HashMap<proto::PeerId, Collaborator>,
|
||||
client_subscriptions: Vec<client::Subscription>,
|
||||
_subscriptions: Vec<gpui::Subscription>,
|
||||
next_buffer_id: BufferId,
|
||||
loading_buffers: HashMap<BufferId, Vec<oneshot::Sender<Result<Model<Buffer>, anyhow::Error>>>>,
|
||||
incomplete_remote_buffers: HashMap<BufferId, Model<Buffer>>,
|
||||
shared_buffers: HashMap<proto::PeerId, HashSet<BufferId>>,
|
||||
@@ -675,7 +674,6 @@ impl Project {
|
||||
flush_language_server_update: None,
|
||||
pending_language_server_update: None,
|
||||
collaborators: Default::default(),
|
||||
next_buffer_id: BufferId::new(1).unwrap(),
|
||||
opened_buffers: Default::default(),
|
||||
shared_buffers: Default::default(),
|
||||
loading_buffers_by_path: Default::default(),
|
||||
@@ -792,7 +790,6 @@ impl Project {
|
||||
pending_language_server_update: None,
|
||||
flush_language_server_update: None,
|
||||
loading_buffers_by_path: Default::default(),
|
||||
next_buffer_id: BufferId::new(1).unwrap(),
|
||||
loading_buffers: Default::default(),
|
||||
shared_buffers: Default::default(),
|
||||
incomplete_remote_buffers: Default::default(),
|
||||
@@ -1849,9 +1846,8 @@ impl Project {
|
||||
if self.is_remote() {
|
||||
return Err(anyhow!("creating buffers as a guest is not supported yet"));
|
||||
}
|
||||
let id = self.next_buffer_id.next();
|
||||
let buffer = cx.new_model(|cx| {
|
||||
Buffer::new(self.replica_id(), id, text)
|
||||
Buffer::local(text, cx)
|
||||
.with_language(language.unwrap_or_else(|| language::PLAIN_TEXT.clone()), cx)
|
||||
});
|
||||
self.register_buffer(&buffer, cx)?;
|
||||
@@ -1950,10 +1946,9 @@ impl Project {
|
||||
worktree: Model<Worktree>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Model<Buffer>>> {
|
||||
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)
|
||||
worktree.load_buffer(&path, cx)
|
||||
});
|
||||
fn is_not_found_error(error: &anyhow::Error) -> bool {
|
||||
error
|
||||
@@ -1967,7 +1962,7 @@ impl Project {
|
||||
Err(error) if is_not_found_error(&error) => {
|
||||
worktree.update(&mut cx, |worktree, cx| {
|
||||
let worktree = worktree.as_local_mut().unwrap();
|
||||
worktree.new_buffer(buffer_id, path, cx)
|
||||
worktree.new_buffer(path, cx)
|
||||
})
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
|
||||
Reference in New Issue
Block a user