feat: add editor tabs
This commit is contained in:
+46
-46
@@ -169,7 +169,7 @@ pub struct EditorSession {
|
||||
pending_hover: bool,
|
||||
pending_completion: bool,
|
||||
hover_owner: Option<String>,
|
||||
diff_worker: Option<DiffWorker>,
|
||||
diff_workers: BTreeMap<usize, DiffWorker>,
|
||||
}
|
||||
|
||||
impl EditorSession {
|
||||
@@ -261,7 +261,7 @@ impl EditorSession {
|
||||
pending_hover: false,
|
||||
pending_completion: false,
|
||||
hover_owner: None,
|
||||
diff_worker: None,
|
||||
diff_workers: BTreeMap::new(),
|
||||
};
|
||||
session.synchronize_documents();
|
||||
Ok(session)
|
||||
@@ -319,27 +319,27 @@ impl EditorSession {
|
||||
}
|
||||
|
||||
fn start_diff_request(&mut self) {
|
||||
if self.editor.workspace_diff().is_none() {
|
||||
self.diff_worker = None;
|
||||
return;
|
||||
}
|
||||
if self
|
||||
.editor
|
||||
.workspace_diff()
|
||||
.is_some_and(|diff| !diff.loading)
|
||||
&& let Some(worker) = &mut self.diff_worker
|
||||
&& let Some(id) = worker.pending.take()
|
||||
{
|
||||
worker.cancelled_request.store(id, Ordering::Release);
|
||||
worker.cancelled.store(true, Ordering::Release);
|
||||
}
|
||||
self.diff_workers.retain(|tab, worker| {
|
||||
let Some(diff) = self.editor.tab_diff(*tab) else {
|
||||
return false;
|
||||
};
|
||||
if !diff.loading
|
||||
&& let Some(id) = worker.pending.take()
|
||||
{
|
||||
worker.cancelled_request.store(id, Ordering::Release);
|
||||
worker.cancelled.store(true, Ordering::Release);
|
||||
}
|
||||
true
|
||||
});
|
||||
let Some((id, operation)) = self.editor.take_diff_request() else {
|
||||
return;
|
||||
};
|
||||
if self.diff_worker.is_none() {
|
||||
let root = self.editor.diff_root();
|
||||
match DiffWorker::start(root) {
|
||||
Ok(worker) => self.diff_worker = Some(worker),
|
||||
let tab = self.editor.tab_id();
|
||||
if let std::collections::btree_map::Entry::Vacant(entry) = self.diff_workers.entry(tab) {
|
||||
match DiffWorker::start(self.editor.diff_root()) {
|
||||
Ok(worker) => {
|
||||
entry.insert(worker);
|
||||
}
|
||||
Err(error) => {
|
||||
self.editor.apply_diff_result(id, Err(error));
|
||||
return;
|
||||
@@ -347,46 +347,46 @@ impl EditorSession {
|
||||
}
|
||||
}
|
||||
if let Err(error) = self
|
||||
.diff_worker
|
||||
.as_mut()
|
||||
.diff_workers
|
||||
.get_mut(&tab)
|
||||
.expect("diff worker started")
|
||||
.request(id, operation)
|
||||
{
|
||||
self.editor.apply_diff_result(id, Err(error));
|
||||
self.diff_worker = None;
|
||||
self.diff_workers.remove(&tab);
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_diff(&mut self) -> bool {
|
||||
self.start_diff_request();
|
||||
let mut changed = false;
|
||||
while let Some(worker) = self.diff_worker.as_ref() {
|
||||
let result = worker
|
||||
.results
|
||||
.as_ref()
|
||||
.expect("live diff worker has results")
|
||||
.try_recv();
|
||||
match result {
|
||||
Ok((id, result)) => {
|
||||
if let Some(worker) = &mut self.diff_worker
|
||||
&& worker.pending == Some(id)
|
||||
{
|
||||
worker.pending = None;
|
||||
self.diff_workers.retain(|_, worker| {
|
||||
loop {
|
||||
let result = worker
|
||||
.results
|
||||
.as_ref()
|
||||
.expect("live diff worker has results")
|
||||
.try_recv();
|
||||
match result {
|
||||
Ok((id, result)) => {
|
||||
if worker.pending == Some(id) {
|
||||
worker.pending = None;
|
||||
}
|
||||
changed |= self.editor.apply_diff_result(id, result);
|
||||
}
|
||||
changed |= self.editor.apply_diff_result(id, result);
|
||||
}
|
||||
Err(mpsc::TryRecvError::Empty) => break,
|
||||
Err(mpsc::TryRecvError::Disconnected) => {
|
||||
if let Some(id) = self.diff_worker.as_ref().and_then(|worker| worker.pending) {
|
||||
changed |= self
|
||||
.editor
|
||||
.apply_diff_result(id, Err("Diff worker stopped unexpectedly".into()));
|
||||
Err(mpsc::TryRecvError::Empty) => return true,
|
||||
Err(mpsc::TryRecvError::Disconnected) => {
|
||||
if let Some(id) = worker.pending.take() {
|
||||
changed |= self.editor.apply_diff_result(
|
||||
id,
|
||||
Err("Diff worker stopped unexpectedly".into()),
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
self.diff_worker = None;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
changed
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user