Merge pull request #1692 from zed-industries/avoid-duplicate-autoformat-edits

Avoid duplicate autoformat edits
This commit is contained in:
Max Brunsfeld 2022-10-07 09:35:10 -07:00 committed by GitHub
commit ec76146a23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 738 additions and 659 deletions

File diff suppressed because it is too large Load diff

View file

@ -325,7 +325,12 @@ impl Deterministic {
let mut state = self.state.lock(); let mut state = self.state.lock();
let wakeup_at = state.now + duration; let wakeup_at = state.now + duration;
let id = util::post_inc(&mut state.next_timer_id); let id = util::post_inc(&mut state.next_timer_id);
state.pending_timers.push((id, wakeup_at, tx)); match state
.pending_timers
.binary_search_by_key(&wakeup_at, |e| e.1)
{
Ok(ix) | Err(ix) => state.pending_timers.insert(ix, (id, wakeup_at, tx)),
}
let state = self.state.clone(); let state = self.state.clone();
Timer::Deterministic(DeterministicTimer { rx, id, state }) Timer::Deterministic(DeterministicTimer { rx, id, state })
} }

View file

@ -8,10 +8,7 @@ pub mod worktree;
mod project_tests; mod project_tests;
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use client::{ use client::{proto, Client, PeerId, TypedEnvelope, User, UserStore};
proto::{self},
Client, PeerId, TypedEnvelope, User, UserStore,
};
use clock::ReplicaId; use clock::ReplicaId;
use collections::{hash_map, BTreeMap, HashMap, HashSet}; use collections::{hash_map, BTreeMap, HashMap, HashSet};
use futures::{future::Shared, AsyncWriteExt, Future, FutureExt, StreamExt, TryFutureExt}; use futures::{future::Shared, AsyncWriteExt, Future, FutureExt, StreamExt, TryFutureExt};
@ -66,7 +63,7 @@ use std::{
time::Instant, time::Instant,
}; };
use thiserror::Error; use thiserror::Error;
use util::{post_inc, ResultExt, TryFutureExt as _}; use util::{defer, post_inc, ResultExt, TryFutureExt as _};
pub use db::Db; pub use db::Db;
pub use fs::*; pub use fs::*;
@ -128,6 +125,7 @@ pub struct Project {
opened_buffers: HashMap<u64, OpenBuffer>, opened_buffers: HashMap<u64, OpenBuffer>,
incomplete_buffers: HashMap<u64, ModelHandle<Buffer>>, incomplete_buffers: HashMap<u64, ModelHandle<Buffer>>,
buffer_snapshots: HashMap<u64, Vec<(i32, TextBufferSnapshot)>>, buffer_snapshots: HashMap<u64, Vec<(i32, TextBufferSnapshot)>>,
buffers_being_formatted: HashSet<usize>,
nonce: u128, nonce: u128,
initialized_persistent_state: bool, initialized_persistent_state: bool,
_maintain_buffer_languages: Task<()>, _maintain_buffer_languages: Task<()>,
@ -512,6 +510,7 @@ impl Project {
language_server_statuses: Default::default(), language_server_statuses: Default::default(),
last_workspace_edits_by_language_server: Default::default(), last_workspace_edits_by_language_server: Default::default(),
language_server_settings: Default::default(), language_server_settings: Default::default(),
buffers_being_formatted: Default::default(),
next_language_server_id: 0, next_language_server_id: 0,
nonce: StdRng::from_entropy().gen(), nonce: StdRng::from_entropy().gen(),
initialized_persistent_state: false, initialized_persistent_state: false,
@ -627,6 +626,7 @@ impl Project {
last_workspace_edits_by_language_server: Default::default(), last_workspace_edits_by_language_server: Default::default(),
next_language_server_id: 0, next_language_server_id: 0,
opened_buffers: Default::default(), opened_buffers: Default::default(),
buffers_being_formatted: Default::default(),
buffer_snapshots: Default::default(), buffer_snapshots: Default::default(),
nonce: StdRng::from_entropy().gen(), nonce: StdRng::from_entropy().gen(),
initialized_persistent_state: false, initialized_persistent_state: false,
@ -3113,7 +3113,26 @@ impl Project {
.await?; .await?;
} }
for (buffer, buffer_abs_path, language_server) in local_buffers { // Do not allow multiple concurrent formatting requests for the
// same buffer.
this.update(&mut cx, |this, _| {
local_buffers
.retain(|(buffer, _, _)| this.buffers_being_formatted.insert(buffer.id()));
});
let _cleanup = defer({
let this = this.clone();
let mut cx = cx.clone();
let local_buffers = &local_buffers;
move || {
this.update(&mut cx, |this, _| {
for (buffer, _, _) in local_buffers {
this.buffers_being_formatted.remove(&buffer.id());
}
});
}
});
for (buffer, buffer_abs_path, language_server) in &local_buffers {
let (format_on_save, formatter, tab_size) = buffer.read_with(&cx, |buffer, cx| { let (format_on_save, formatter, tab_size) = buffer.read_with(&cx, |buffer, cx| {
let settings = cx.global::<Settings>(); let settings = cx.global::<Settings>();
let language_name = buffer.language().map(|language| language.name()); let language_name = buffer.language().map(|language| language.name());
@ -3165,7 +3184,7 @@ impl Project {
buffer.forget_transaction(transaction.id) buffer.forget_transaction(transaction.id)
}); });
} }
project_transaction.0.insert(buffer, transaction); project_transaction.0.insert(buffer.clone(), transaction);
} }
} }