feat: add editor tabs

This commit is contained in:
Valdemar Lorenzen
2026-10-12 09:34:54 +02:00
parent b72a3e206f
commit fc382529c5
11 changed files with 1241 additions and 105 deletions
+46 -46
View File
@@ -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
}