Skip to content

Commit 199c9f7

Browse files
committed
fix: buffer-close ensuring writes
Make sure buffer-close waits for the document to finish its writes.
1 parent 84f605c commit 199c9f7

File tree

5 files changed

+63
-12
lines changed

5 files changed

+63
-12
lines changed

helix-term/src/application.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,8 @@ impl Application {
291291
self.editor.reset_idle_timer();
292292
}
293293
event = self.editor.wait_event() => {
294+
log::debug!("received editor event: {:?}", event);
295+
294296
match event {
295297
EditorEvent::DocumentSave(event) => {
296298
self.handle_document_write(event);

helix-term/src/commands/typed.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ fn buffer_close(
111111
_event: PromptEvent,
112112
) -> anyhow::Result<()> {
113113
let document_ids = buffer_gather_paths_impl(cx.editor, args);
114+
log::debug!("closing buffers: {:?}", document_ids);
114115
buffer_close_by_ids_impl(cx.editor, &document_ids, false)
115116
}
116117

helix-term/tests/test/commands.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ async fn test_write_quit_fail() -> anyhow::Result<()> {
3131
}
3232

3333
#[tokio::test]
34-
#[ignore]
3534
async fn test_buffer_close_concurrent() -> anyhow::Result<()> {
3635
test_key_sequences(
3736
&mut Application::new(Args::default(), Config::default())?,

helix-view/src/document.rs

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,10 @@ impl Document {
550550
}
551551

552552
pub async fn await_save(&mut self) -> Option<DocumentSaveEventResult> {
553+
self.await_save_impl(true).await
554+
}
555+
556+
async fn await_save_impl(&mut self, block: bool) -> Option<DocumentSaveEventResult> {
553557
let mut current_save = self.current_save.lock().await;
554558
if let Some(ref mut save) = *current_save {
555559
let result = save.await;
@@ -561,7 +565,15 @@ impl Document {
561565
// return early if the receiver is closed
562566
self.save_receiver.as_ref()?;
563567

564-
let save = match self.save_receiver.as_mut().unwrap().recv().await {
568+
let rx = self.save_receiver.as_mut().unwrap();
569+
570+
let save_req = if block {
571+
rx.recv().await
572+
} else {
573+
rx.try_recv().ok()
574+
};
575+
576+
let save = match save_req {
565577
Some(save) => save,
566578
None => {
567579
self.save_receiver = None;
@@ -582,19 +594,24 @@ impl Document {
582594
Some(result)
583595
}
584596

585-
/// Prepares the Document for being closed by stopping any new writes
586-
/// and flushing through the queue of pending writes. If any fail,
587-
/// it stops early before emptying the rest of the queue. Callers
588-
/// should keep calling until it returns None.
589-
pub async fn close(&mut self) -> Option<DocumentSaveEventResult> {
590-
if self.save_sender.is_some() {
591-
self.save_sender = None;
592-
}
597+
/// Flushes the queue of pending writes. If any fail,
598+
/// it stops early before emptying the rest of the queue.
599+
pub async fn try_flush_saves(&mut self) -> Option<DocumentSaveEventResult> {
600+
self.flush_saves_impl(false).await
601+
}
593602

603+
async fn flush_saves_impl(&mut self, block: bool) -> Option<DocumentSaveEventResult> {
594604
let mut final_result = None;
595605

596-
while let Some(save_event) = self.await_save().await {
597-
let is_err = save_event.is_err();
606+
while let Some(save_event) = self.await_save_impl(block).await {
607+
let is_err = match &save_event {
608+
Ok(event) => {
609+
self.set_last_saved_revision(event.revision);
610+
false
611+
}
612+
Err(_) => true,
613+
};
614+
598615
final_result = Some(save_event);
599616

600617
if is_err {
@@ -605,6 +622,17 @@ impl Document {
605622
final_result
606623
}
607624

625+
/// Prepares the Document for being closed by stopping any new writes
626+
/// and flushing through the queue of pending writes. If any fail,
627+
/// it stops early before emptying the rest of the queue.
628+
pub async fn close(&mut self) -> Option<DocumentSaveEventResult> {
629+
if self.save_sender.is_some() {
630+
self.save_sender = None;
631+
}
632+
633+
self.flush_saves_impl(true).await
634+
}
635+
608636
/// Detect the programming language based on the file type.
609637
pub fn detect_language(&mut self, config_loader: Arc<syntax::Loader>) {
610638
if let Some(path) = &self.path {
@@ -955,6 +983,11 @@ impl Document {
955983
let history = self.history.take();
956984
let current_revision = history.current_revision();
957985
self.history.set(history);
986+
log::debug!(
987+
"modified - last saved: {}, current: {}",
988+
self.last_saved_revision,
989+
current_revision
990+
);
958991
current_revision != self.last_saved_revision || !self.changes.is_empty()
959992
}
960993

@@ -968,9 +1001,20 @@ impl Document {
9681001

9691002
/// Set the document's latest saved revision to the given one.
9701003
pub fn set_last_saved_revision(&mut self, rev: usize) {
1004+
log::debug!(
1005+
"doc {} revision updated {} -> {}",
1006+
self.id,
1007+
self.last_saved_revision,
1008+
rev
1009+
);
9711010
self.last_saved_revision = rev;
9721011
}
9731012

1013+
/// Get the document's latest saved revision.
1014+
pub fn get_last_saved_revision(&mut self) -> usize {
1015+
self.last_saved_revision
1016+
}
1017+
9741018
/// Get the current revision number
9751019
pub fn get_current_revision(&mut self) -> usize {
9761020
let history = self.history.take();

helix-view/src/editor.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,11 @@ impl Editor {
798798
None => bail!("document does not exist"),
799799
};
800800

801+
// flush out any pending writes first to clear the modified status
802+
if let Some(save_result) = doc.try_flush_saves().await {
803+
save_result?;
804+
}
805+
801806
if !force && doc.is_modified() {
802807
bail!(
803808
"buffer {:?} is modified",

0 commit comments

Comments
 (0)