Merge pull request #2445 from zed-industries/construct-text-buffer-in-background
Construct text buffer in background
This commit is contained in:
@@ -3222,14 +3222,18 @@ async fn test_canceling_buffer_opening(
|
||||
.unwrap();
|
||||
|
||||
// Open a buffer as client B but cancel after a random amount of time.
|
||||
let buffer_b = project_b.update(cx_b, |p, cx| p.open_buffer_by_id(buffer_a.id() as u64, cx));
|
||||
let buffer_b = project_b.update(cx_b, |p, cx| {
|
||||
p.open_buffer_by_id(buffer_a.read_with(cx_a, |a, _| a.remote_id()), cx)
|
||||
});
|
||||
deterministic.simulate_random_delay().await;
|
||||
drop(buffer_b);
|
||||
|
||||
// Try opening the same buffer again as client B, and ensure we can
|
||||
// still do it despite the cancellation above.
|
||||
let buffer_b = project_b
|
||||
.update(cx_b, |p, cx| p.open_buffer_by_id(buffer_a.id() as u64, cx))
|
||||
.update(cx_b, |p, cx| {
|
||||
p.open_buffer_by_id(buffer_a.read_with(cx_a, |a, _| a.remote_id()), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
buffer_b.read_with(cx_b, |buf, _| assert_eq!(buf.text(), "abc"));
|
||||
|
||||
@@ -126,7 +126,7 @@ impl CopilotServer {
|
||||
struct RunningCopilotServer {
|
||||
lsp: Arc<LanguageServer>,
|
||||
sign_in_status: SignInStatus,
|
||||
registered_buffers: HashMap<usize, RegisteredBuffer>,
|
||||
registered_buffers: HashMap<u64, RegisteredBuffer>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -162,7 +162,7 @@ impl Status {
|
||||
}
|
||||
|
||||
struct RegisteredBuffer {
|
||||
id: usize,
|
||||
id: u64,
|
||||
uri: lsp::Url,
|
||||
language_id: String,
|
||||
snapshot: BufferSnapshot,
|
||||
@@ -267,7 +267,7 @@ pub struct Copilot {
|
||||
http: Arc<dyn HttpClient>,
|
||||
node_runtime: Arc<NodeRuntime>,
|
||||
server: CopilotServer,
|
||||
buffers: HashMap<usize, WeakModelHandle<Buffer>>,
|
||||
buffers: HashMap<u64, WeakModelHandle<Buffer>>,
|
||||
}
|
||||
|
||||
impl Entity for Copilot {
|
||||
@@ -582,7 +582,7 @@ impl Copilot {
|
||||
}
|
||||
|
||||
pub fn register_buffer(&mut self, buffer: &ModelHandle<Buffer>, cx: &mut ModelContext<Self>) {
|
||||
let buffer_id = buffer.id();
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
self.buffers.insert(buffer_id, buffer.downgrade());
|
||||
|
||||
if let CopilotServer::Running(RunningCopilotServer {
|
||||
@@ -596,7 +596,8 @@ impl Copilot {
|
||||
return;
|
||||
}
|
||||
|
||||
registered_buffers.entry(buffer.id()).or_insert_with(|| {
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
registered_buffers.entry(buffer_id).or_insert_with(|| {
|
||||
let uri: lsp::Url = uri_for_buffer(buffer, cx);
|
||||
let language_id = id_for_language(buffer.read(cx).language());
|
||||
let snapshot = buffer.read(cx).snapshot();
|
||||
@@ -641,7 +642,8 @@ impl Copilot {
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Result<()> {
|
||||
if let Ok(server) = self.server.as_running() {
|
||||
if let Some(registered_buffer) = server.registered_buffers.get_mut(&buffer.id()) {
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
if let Some(registered_buffer) = server.registered_buffers.get_mut(&buffer_id) {
|
||||
match event {
|
||||
language::Event::Edited => {
|
||||
let _ = registered_buffer.report_changes(&buffer, cx);
|
||||
@@ -695,7 +697,7 @@ impl Copilot {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unregister_buffer(&mut self, buffer_id: usize) {
|
||||
fn unregister_buffer(&mut self, buffer_id: u64) {
|
||||
if let Ok(server) = self.server.as_running() {
|
||||
if let Some(buffer) = server.registered_buffers.remove(&buffer_id) {
|
||||
server
|
||||
@@ -800,7 +802,8 @@ impl Copilot {
|
||||
Err(error) => return Task::ready(Err(error)),
|
||||
};
|
||||
let lsp = server.lsp.clone();
|
||||
let registered_buffer = server.registered_buffers.get_mut(&buffer.id()).unwrap();
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
let registered_buffer = server.registered_buffers.get_mut(&buffer_id).unwrap();
|
||||
let snapshot = registered_buffer.report_changes(buffer, cx);
|
||||
let buffer = buffer.read(cx);
|
||||
let uri = registered_buffer.uri.clone();
|
||||
@@ -919,7 +922,9 @@ fn uri_for_buffer(buffer: &ModelHandle<Buffer>, cx: &AppContext) -> lsp::Url {
|
||||
if let Some(file) = buffer.read(cx).file().and_then(|file| file.as_local()) {
|
||||
lsp::Url::from_file_path(file.abs_path(cx)).unwrap()
|
||||
} else {
|
||||
format!("buffer://{}", buffer.id()).parse().unwrap()
|
||||
format!("buffer://{}", buffer.read(cx).remote_id())
|
||||
.parse()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2594,7 +2594,7 @@ impl Editor {
|
||||
let old_text = buffer.text_for_range(old_range.clone()).collect::<String>();
|
||||
|
||||
let newest_selection = self.selections.newest_anchor();
|
||||
if newest_selection.start.buffer_id != Some(buffer_handle.id()) {
|
||||
if newest_selection.start.buffer_id != Some(buffer_handle.read(cx).remote_id()) {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -2802,7 +2802,7 @@ impl Editor {
|
||||
),
|
||||
);
|
||||
}
|
||||
multibuffer.push_transaction(entries.iter().map(|(b, t)| (b, t)));
|
||||
multibuffer.push_transaction(entries.iter().map(|(b, t)| (b, t)), cx);
|
||||
multibuffer
|
||||
});
|
||||
|
||||
@@ -5764,7 +5764,7 @@ impl Editor {
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) {
|
||||
// If there are multiple definitions, open them in a multibuffer
|
||||
locations.sort_by_key(|location| location.buffer.id());
|
||||
locations.sort_by_key(|location| location.buffer.read(cx).remote_id());
|
||||
let mut locations = locations.into_iter().peekable();
|
||||
let mut ranges_to_highlight = Vec::new();
|
||||
|
||||
@@ -6059,7 +6059,7 @@ impl Editor {
|
||||
buffer.update(&mut cx, |buffer, cx| {
|
||||
if let Some(transaction) = transaction {
|
||||
if !buffer.is_singleton() {
|
||||
buffer.push_transaction(&transaction.0);
|
||||
buffer.push_transaction(&transaction.0, cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -704,10 +704,10 @@ impl Item for Editor {
|
||||
this.update(&mut cx, |editor, cx| {
|
||||
editor.request_autoscroll(Autoscroll::fit(), cx)
|
||||
})?;
|
||||
buffer.update(&mut cx, |buffer, _| {
|
||||
buffer.update(&mut cx, |buffer, cx| {
|
||||
if let Some(transaction) = transaction {
|
||||
if !buffer.is_singleton() {
|
||||
buffer.push_transaction(&transaction.0);
|
||||
buffer.push_transaction(&transaction.0, cx);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -43,7 +43,7 @@ pub struct ExcerptId(usize);
|
||||
|
||||
pub struct MultiBuffer {
|
||||
snapshot: RefCell<MultiBufferSnapshot>,
|
||||
buffers: RefCell<HashMap<usize, BufferState>>,
|
||||
buffers: RefCell<HashMap<u64, BufferState>>,
|
||||
next_excerpt_id: usize,
|
||||
subscriptions: Topic,
|
||||
singleton: bool,
|
||||
@@ -85,7 +85,7 @@ struct History {
|
||||
#[derive(Clone)]
|
||||
struct Transaction {
|
||||
id: TransactionId,
|
||||
buffer_transactions: HashMap<usize, text::TransactionId>,
|
||||
buffer_transactions: HashMap<u64, text::TransactionId>,
|
||||
first_edit_at: Instant,
|
||||
last_edit_at: Instant,
|
||||
suppress_grouping: bool,
|
||||
@@ -145,7 +145,7 @@ pub struct ExcerptBoundary {
|
||||
struct Excerpt {
|
||||
id: ExcerptId,
|
||||
locator: Locator,
|
||||
buffer_id: usize,
|
||||
buffer_id: u64,
|
||||
buffer: BufferSnapshot,
|
||||
range: ExcerptRange<text::Anchor>,
|
||||
max_buffer_row: u32,
|
||||
@@ -337,7 +337,7 @@ impl MultiBuffer {
|
||||
offset: T,
|
||||
theme: Option<&SyntaxTheme>,
|
||||
cx: &AppContext,
|
||||
) -> Option<(usize, Vec<OutlineItem<Anchor>>)> {
|
||||
) -> Option<(u64, Vec<OutlineItem<Anchor>>)> {
|
||||
self.read(cx).symbols_containing(offset, theme)
|
||||
}
|
||||
|
||||
@@ -394,7 +394,7 @@ impl MultiBuffer {
|
||||
is_insertion: bool,
|
||||
original_indent_column: u32,
|
||||
}
|
||||
let mut buffer_edits: HashMap<usize, Vec<BufferEdit>> = Default::default();
|
||||
let mut buffer_edits: HashMap<u64, Vec<BufferEdit>> = Default::default();
|
||||
let mut cursor = snapshot.excerpts.cursor::<usize>();
|
||||
for (ix, (range, new_text)) in edits.enumerate() {
|
||||
let new_text: Arc<str> = new_text.into();
|
||||
@@ -593,7 +593,7 @@ impl MultiBuffer {
|
||||
if let Some(transaction_id) =
|
||||
buffer.update(cx, |buffer, cx| buffer.end_transaction_at(now, cx))
|
||||
{
|
||||
buffer_transactions.insert(buffer.id(), transaction_id);
|
||||
buffer_transactions.insert(buffer.read(cx).remote_id(), transaction_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -614,12 +614,12 @@ impl MultiBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_transaction<'a, T>(&mut self, buffer_transactions: T)
|
||||
pub fn push_transaction<'a, T>(&mut self, buffer_transactions: T, cx: &mut ModelContext<Self>)
|
||||
where
|
||||
T: IntoIterator<Item = (&'a ModelHandle<Buffer>, &'a language::Transaction)>,
|
||||
{
|
||||
self.history
|
||||
.push_transaction(buffer_transactions, Instant::now());
|
||||
.push_transaction(buffer_transactions, Instant::now(), cx);
|
||||
self.history.finalize_last_transaction();
|
||||
}
|
||||
|
||||
@@ -644,7 +644,7 @@ impl MultiBuffer {
|
||||
cursor_shape: CursorShape,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
let mut selections_by_buffer: HashMap<usize, Vec<Selection<text::Anchor>>> =
|
||||
let mut selections_by_buffer: HashMap<u64, Vec<Selection<text::Anchor>>> =
|
||||
Default::default();
|
||||
let snapshot = self.read(cx);
|
||||
let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>();
|
||||
@@ -785,8 +785,8 @@ impl MultiBuffer {
|
||||
let (mut tx, rx) = mpsc::channel(256);
|
||||
let task = cx.spawn(|this, mut cx| async move {
|
||||
for (buffer, ranges) in excerpts {
|
||||
let buffer_id = buffer.id();
|
||||
let buffer_snapshot = buffer.read_with(&cx, |buffer, _| buffer.snapshot());
|
||||
let (buffer_id, buffer_snapshot) =
|
||||
buffer.read_with(&cx, |buffer, _| (buffer.remote_id(), buffer.snapshot()));
|
||||
|
||||
let mut excerpt_ranges = Vec::new();
|
||||
let mut range_counts = Vec::new();
|
||||
@@ -855,7 +855,7 @@ impl MultiBuffer {
|
||||
where
|
||||
O: text::ToPoint + text::ToOffset,
|
||||
{
|
||||
let buffer_id = buffer.id();
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
let buffer_snapshot = buffer.read(cx).snapshot();
|
||||
let (excerpt_ranges, range_counts) =
|
||||
build_excerpt_ranges(&buffer_snapshot, &ranges, context_line_count);
|
||||
@@ -924,7 +924,7 @@ impl MultiBuffer {
|
||||
|
||||
self.sync(cx);
|
||||
|
||||
let buffer_id = buffer.id();
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
let buffer_snapshot = buffer.read(cx).snapshot();
|
||||
|
||||
let mut buffers = self.buffers.borrow_mut();
|
||||
@@ -1051,7 +1051,7 @@ impl MultiBuffer {
|
||||
let buffers = self.buffers.borrow();
|
||||
let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>();
|
||||
for locator in buffers
|
||||
.get(&buffer.id())
|
||||
.get(&buffer.read(cx).remote_id())
|
||||
.map(|state| &state.excerpts)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
@@ -1321,7 +1321,7 @@ impl MultiBuffer {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn buffer(&self, buffer_id: usize) -> Option<ModelHandle<Buffer>> {
|
||||
pub fn buffer(&self, buffer_id: u64) -> Option<ModelHandle<Buffer>> {
|
||||
self.buffers
|
||||
.borrow()
|
||||
.get(&buffer_id)
|
||||
@@ -1478,8 +1478,8 @@ impl MultiBuffer {
|
||||
for (locator, buffer, buffer_edited) in excerpts_to_edit {
|
||||
new_excerpts.push_tree(cursor.slice(&Some(locator), Bias::Left, &()), &());
|
||||
let old_excerpt = cursor.item().unwrap();
|
||||
let buffer_id = buffer.id();
|
||||
let buffer = buffer.read(cx);
|
||||
let buffer_id = buffer.remote_id();
|
||||
|
||||
let mut new_excerpt;
|
||||
if buffer_edited {
|
||||
@@ -1605,11 +1605,11 @@ impl MultiBuffer {
|
||||
let buffer_handle = if rng.gen() || self.buffers.borrow().is_empty() {
|
||||
let text = RandomCharIter::new(&mut *rng).take(10).collect::<String>();
|
||||
buffers.push(cx.add_model(|cx| Buffer::new(0, text, cx)));
|
||||
let buffer = buffers.last().unwrap();
|
||||
let buffer = buffers.last().unwrap().read(cx);
|
||||
log::info!(
|
||||
"Creating new buffer {} with text: {:?}",
|
||||
buffer.id(),
|
||||
buffer.read(cx).text()
|
||||
buffer.remote_id(),
|
||||
buffer.text()
|
||||
);
|
||||
buffers.last().unwrap().clone()
|
||||
} else {
|
||||
@@ -1637,7 +1637,7 @@ impl MultiBuffer {
|
||||
.collect::<Vec<_>>();
|
||||
log::info!(
|
||||
"Inserting excerpts from buffer {} and ranges {:?}: {:?}",
|
||||
buffer_handle.id(),
|
||||
buffer_handle.read(cx).remote_id(),
|
||||
ranges.iter().map(|r| &r.context).collect::<Vec<_>>(),
|
||||
ranges
|
||||
.iter()
|
||||
@@ -1830,7 +1830,7 @@ impl MultiBufferSnapshot {
|
||||
(start..end, word_kind)
|
||||
}
|
||||
|
||||
pub fn as_singleton(&self) -> Option<(&ExcerptId, usize, &BufferSnapshot)> {
|
||||
pub fn as_singleton(&self) -> Option<(&ExcerptId, u64, &BufferSnapshot)> {
|
||||
if self.singleton {
|
||||
self.excerpts
|
||||
.iter()
|
||||
@@ -2938,7 +2938,7 @@ impl MultiBufferSnapshot {
|
||||
&self,
|
||||
offset: T,
|
||||
theme: Option<&SyntaxTheme>,
|
||||
) -> Option<(usize, Vec<OutlineItem<Anchor>>)> {
|
||||
) -> Option<(u64, Vec<OutlineItem<Anchor>>)> {
|
||||
let anchor = self.anchor_before(offset);
|
||||
let excerpt_id = anchor.excerpt_id();
|
||||
let excerpt = self.excerpt(excerpt_id)?;
|
||||
@@ -2978,7 +2978,7 @@ impl MultiBufferSnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buffer_id_for_excerpt(&self, excerpt_id: ExcerptId) -> Option<usize> {
|
||||
pub fn buffer_id_for_excerpt(&self, excerpt_id: ExcerptId) -> Option<u64> {
|
||||
Some(self.excerpt(excerpt_id)?.buffer_id)
|
||||
}
|
||||
|
||||
@@ -3116,7 +3116,7 @@ impl History {
|
||||
fn end_transaction(
|
||||
&mut self,
|
||||
now: Instant,
|
||||
buffer_transactions: HashMap<usize, TransactionId>,
|
||||
buffer_transactions: HashMap<u64, TransactionId>,
|
||||
) -> bool {
|
||||
assert_ne!(self.transaction_depth, 0);
|
||||
self.transaction_depth -= 1;
|
||||
@@ -3141,8 +3141,12 @@ impl History {
|
||||
}
|
||||
}
|
||||
|
||||
fn push_transaction<'a, T>(&mut self, buffer_transactions: T, now: Instant)
|
||||
where
|
||||
fn push_transaction<'a, T>(
|
||||
&mut self,
|
||||
buffer_transactions: T,
|
||||
now: Instant,
|
||||
cx: &mut ModelContext<MultiBuffer>,
|
||||
) where
|
||||
T: IntoIterator<Item = (&'a ModelHandle<Buffer>, &'a language::Transaction)>,
|
||||
{
|
||||
assert_eq!(self.transaction_depth, 0);
|
||||
@@ -3150,7 +3154,7 @@ impl History {
|
||||
id: self.next_transaction_id.tick(),
|
||||
buffer_transactions: buffer_transactions
|
||||
.into_iter()
|
||||
.map(|(buffer, transaction)| (buffer.id(), transaction.id))
|
||||
.map(|(buffer, transaction)| (buffer.read(cx).remote_id(), transaction.id))
|
||||
.collect(),
|
||||
first_edit_at: now,
|
||||
last_edit_at: now,
|
||||
@@ -3247,7 +3251,7 @@ impl Excerpt {
|
||||
fn new(
|
||||
id: ExcerptId,
|
||||
locator: Locator,
|
||||
buffer_id: usize,
|
||||
buffer_id: u64,
|
||||
buffer: BufferSnapshot,
|
||||
range: ExcerptRange<text::Anchor>,
|
||||
has_trailing_newline: bool,
|
||||
@@ -4715,7 +4719,7 @@ mod tests {
|
||||
"Inserting excerpt at {} of {} for buffer {}: {:?}[{:?}] = {:?}",
|
||||
excerpt_ix,
|
||||
expected_excerpts.len(),
|
||||
buffer_handle.id(),
|
||||
buffer_handle.read(cx).remote_id(),
|
||||
buffer.text(),
|
||||
start_ix..end_ix,
|
||||
&buffer.text()[start_ix..end_ix]
|
||||
@@ -4801,8 +4805,8 @@ mod tests {
|
||||
|
||||
let mut excerpt_starts = excerpt_starts.into_iter();
|
||||
for (buffer, range) in &expected_excerpts {
|
||||
let buffer_id = buffer.id();
|
||||
let buffer = buffer.read(cx);
|
||||
let buffer_id = buffer.remote_id();
|
||||
let buffer_range = range.to_offset(buffer);
|
||||
let buffer_start_point = buffer.offset_to_point(buffer_range.start);
|
||||
let buffer_start_point_utf16 =
|
||||
|
||||
@@ -8,7 +8,7 @@ use sum_tree::Bias;
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)]
|
||||
pub struct Anchor {
|
||||
pub(crate) buffer_id: Option<usize>,
|
||||
pub(crate) buffer_id: Option<u64>,
|
||||
pub(crate) excerpt_id: ExcerptId,
|
||||
pub(crate) text_anchor: text::Anchor,
|
||||
}
|
||||
|
||||
@@ -357,20 +357,6 @@ impl Buffer {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn from_file<T: Into<String>>(
|
||||
replica_id: ReplicaId,
|
||||
base_text: T,
|
||||
diff_base: Option<T>,
|
||||
file: Arc<dyn File>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Self {
|
||||
Self::build(
|
||||
TextBuffer::new(replica_id, cx.model_id() as u64, base_text.into()),
|
||||
diff_base.map(|h| h.into().into_boxed_str().into()),
|
||||
Some(file),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn from_proto(
|
||||
replica_id: ReplicaId,
|
||||
message: proto::BufferState,
|
||||
@@ -460,7 +446,11 @@ impl Buffer {
|
||||
self
|
||||
}
|
||||
|
||||
fn build(buffer: TextBuffer, diff_base: Option<String>, file: Option<Arc<dyn File>>) -> Self {
|
||||
pub fn build(
|
||||
buffer: TextBuffer,
|
||||
diff_base: Option<String>,
|
||||
file: Option<Arc<dyn File>>,
|
||||
) -> Self {
|
||||
let saved_mtime = if let Some(file) = file.as_ref() {
|
||||
file.mtime()
|
||||
} else {
|
||||
|
||||
@@ -109,6 +109,7 @@ pub struct Project {
|
||||
collaborators: HashMap<proto::PeerId, Collaborator>,
|
||||
client_subscriptions: Vec<client::Subscription>,
|
||||
_subscriptions: Vec<gpui::Subscription>,
|
||||
next_buffer_id: u64,
|
||||
opened_buffer: (watch::Sender<()>, watch::Receiver<()>),
|
||||
shared_buffers: HashMap<proto::PeerId, HashSet<u64>>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
@@ -124,7 +125,7 @@ pub struct Project {
|
||||
/// Used for re-issuing buffer requests when peers temporarily disconnect
|
||||
incomplete_remote_buffers: HashMap<u64, Option<ModelHandle<Buffer>>>,
|
||||
buffer_snapshots: HashMap<u64, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
|
||||
buffers_being_formatted: HashSet<usize>,
|
||||
buffers_being_formatted: HashSet<u64>,
|
||||
nonce: u128,
|
||||
_maintain_buffer_languages: Task<()>,
|
||||
_maintain_workspace_config: Task<()>,
|
||||
@@ -441,6 +442,7 @@ impl Project {
|
||||
worktrees: Default::default(),
|
||||
buffer_ordered_messages_tx: tx,
|
||||
collaborators: Default::default(),
|
||||
next_buffer_id: 0,
|
||||
opened_buffers: Default::default(),
|
||||
shared_buffers: Default::default(),
|
||||
incomplete_remote_buffers: Default::default(),
|
||||
@@ -509,6 +511,7 @@ impl Project {
|
||||
worktrees: Vec::new(),
|
||||
buffer_ordered_messages_tx: tx,
|
||||
loading_buffers_by_path: Default::default(),
|
||||
next_buffer_id: 0,
|
||||
opened_buffer: watch::channel(),
|
||||
shared_buffers: Default::default(),
|
||||
incomplete_remote_buffers: Default::default(),
|
||||
@@ -1401,9 +1404,10 @@ impl Project {
|
||||
worktree: &ModelHandle<Worktree>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<ModelHandle<Buffer>>> {
|
||||
let buffer_id = post_inc(&mut self.next_buffer_id);
|
||||
let load_buffer = worktree.update(cx, |worktree, cx| {
|
||||
let worktree = worktree.as_local_mut().unwrap();
|
||||
worktree.load_buffer(path, cx)
|
||||
worktree.load_buffer(buffer_id, path, cx)
|
||||
});
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let buffer = load_buffer.await?;
|
||||
@@ -3200,9 +3204,11 @@ impl Project {
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
// Do not allow multiple concurrent formatting requests for the
|
||||
// same buffer.
|
||||
this.update(&mut cx, |this, _| {
|
||||
buffers_with_paths_and_servers
|
||||
.retain(|(buffer, _, _)| this.buffers_being_formatted.insert(buffer.id()));
|
||||
this.update(&mut cx, |this, cx| {
|
||||
buffers_with_paths_and_servers.retain(|(buffer, _, _)| {
|
||||
this.buffers_being_formatted
|
||||
.insert(buffer.read(cx).remote_id())
|
||||
});
|
||||
});
|
||||
|
||||
let _cleanup = defer({
|
||||
@@ -3210,9 +3216,10 @@ impl Project {
|
||||
let mut cx = cx.clone();
|
||||
let buffers = &buffers_with_paths_and_servers;
|
||||
move || {
|
||||
this.update(&mut cx, |this, _| {
|
||||
this.update(&mut cx, |this, cx| {
|
||||
for (buffer, _, _) in buffers {
|
||||
this.buffers_being_formatted.remove(&buffer.id());
|
||||
this.buffers_being_formatted
|
||||
.remove(&buffer.read(cx).remote_id());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -506,6 +506,7 @@ impl LocalWorktree {
|
||||
|
||||
pub(crate) fn load_buffer(
|
||||
&mut self,
|
||||
id: u64,
|
||||
path: &Path,
|
||||
cx: &mut ModelContext<Worktree>,
|
||||
) -> Task<Result<ModelHandle<Buffer>>> {
|
||||
@@ -514,8 +515,12 @@ impl LocalWorktree {
|
||||
let (file, contents, diff_base) = this
|
||||
.update(&mut cx, |t, cx| t.as_local().unwrap().load(&path, cx))
|
||||
.await?;
|
||||
let text_buffer = cx
|
||||
.background()
|
||||
.spawn(async move { text::Buffer::new(0, id, contents) })
|
||||
.await;
|
||||
Ok(cx.add_model(|cx| {
|
||||
let mut buffer = Buffer::from_file(0, contents, diff_base, Arc::new(file), cx);
|
||||
let mut buffer = Buffer::build(text_buffer, diff_base, Some(Arc::new(file)));
|
||||
buffer.git_diff_recalc(cx);
|
||||
buffer
|
||||
}))
|
||||
|
||||
@@ -90,8 +90,7 @@ impl HistoryEntry {
|
||||
}
|
||||
|
||||
struct History {
|
||||
// TODO: Turn this into a String or Rope, maybe.
|
||||
base_text: Arc<str>,
|
||||
base_text: Rope,
|
||||
operations: TreeMap<clock::Local, Operation>,
|
||||
insertion_slices: HashMap<clock::Local, Vec<InsertionSlice>>,
|
||||
undo_stack: Vec<HistoryEntry>,
|
||||
@@ -107,7 +106,7 @@ struct InsertionSlice {
|
||||
}
|
||||
|
||||
impl History {
|
||||
pub fn new(base_text: Arc<str>) -> Self {
|
||||
pub fn new(base_text: Rope) -> Self {
|
||||
Self {
|
||||
base_text,
|
||||
operations: Default::default(),
|
||||
@@ -470,7 +469,7 @@ impl Buffer {
|
||||
let line_ending = LineEnding::detect(&base_text);
|
||||
LineEnding::normalize(&mut base_text);
|
||||
|
||||
let history = History::new(base_text.into());
|
||||
let history = History::new(Rope::from(base_text.as_ref()));
|
||||
let mut fragments = SumTree::new();
|
||||
let mut insertions = SumTree::new();
|
||||
|
||||
@@ -478,7 +477,7 @@ impl Buffer {
|
||||
let mut lamport_clock = clock::Lamport::new(replica_id);
|
||||
let mut version = clock::Global::new();
|
||||
|
||||
let visible_text = Rope::from(history.base_text.as_ref());
|
||||
let visible_text = history.base_text.clone();
|
||||
if !visible_text.is_empty() {
|
||||
let insertion_timestamp = InsertionTimestamp {
|
||||
replica_id: 0,
|
||||
@@ -1165,7 +1164,7 @@ impl Buffer {
|
||||
self.history.group_until(transaction_id);
|
||||
}
|
||||
|
||||
pub fn base_text(&self) -> &Arc<str> {
|
||||
pub fn base_text(&self) -> &Rope {
|
||||
&self.history.base_text
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ pub trait Item: View {
|
||||
style: &theme::Tab,
|
||||
cx: &AppContext,
|
||||
) -> AnyElement<V>;
|
||||
fn for_each_project_item(&self, _: &AppContext, _: &mut dyn FnMut(usize, &dyn project::Item)) {}
|
||||
fn for_each_project_item(&self, _: &AppContext, _: &mut dyn FnMut(usize, &dyn project::Item)) {} // (model id, Item)
|
||||
fn is_singleton(&self, _cx: &AppContext) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user