aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorRobin Haberkorn <rhaberkorn@fmsbw.de>2025-12-29 00:31:20 +0100
committerRobin Haberkorn <rhaberkorn@fmsbw.de>2025-12-29 00:42:41 +0100
commit713462dfdf3c46a998b43525cbbf5ae0ec8ea84b (patch)
tree0d54c9634677ef326892277d06d758bd2c718830 /src
parent0b593eb7d0e6907b19cdbb605caf1becae351004 (diff)
avoid unnecessary cleanups of recovery files
* After the last commit 0b593eb7d0e6907b19cdbb605caf1becae351004 we tried to clean up (unlink) recovery files for all dirty buffers. This resulted in superfluous file deletions before any recovery file was dumped; after disabling file recovery and even in batch mode. It's not tolerable that SciTECO scripts try to unlink files as a side effect e.g. of EW. Also, sometimes you may have to clean up recovery dumps even in batch mode, e.g. in Quit hooks. * Also, it was broken for dirty unnamed buffers, which would cause glib errors. * That's why we had to add another buffer state for dirty files with outdated recovery dumps (TECO_BUFFER_DIRTY_OUTDATED_DUMP). Once a dump was written, a buffer never directly transitions into the TECO_BUFFER_DIRTY_NO_DUMP state again. We can now reliably unlink() only where we'd expect a recovery file to exist in the first place.
Diffstat (limited to 'src')
-rw-r--r--src/ring.c33
-rw-r--r--src/ring.h10
2 files changed, 25 insertions, 18 deletions
diff --git a/src/ring.c b/src/ring.c
index 1fd39e9..fca32cc 100644
--- a/src/ring.c
+++ b/src/ring.c
@@ -118,11 +118,11 @@ teco_buffer_save(teco_buffer_t *ctx, const gchar *filename, GError **error)
*/
if (ctx == teco_ring_current && !teco_qreg_current)
undo__teco_interface_info_update_buffer(ctx);
- if (ctx->state >= TECO_BUFFER_DIRTY) {
+ if (ctx->state > TECO_BUFFER_DIRTY_NO_DUMP) {
g_autofree gchar *filename_recovery = teco_buffer_get_recovery(ctx);
g_unlink(filename_recovery);
/* on rubout, we do not restore the recovery file */
- ctx->state = TECO_BUFFER_DIRTY;
+ ctx->state = TECO_BUFFER_DIRTY_NO_DUMP;
}
teco_undo_guint(ctx->state) = TECO_BUFFER_CLEAN;
@@ -143,7 +143,7 @@ teco_buffer_save(teco_buffer_t *ctx, const gchar *filename, GError **error)
static inline void
teco_buffer_free(teco_buffer_t *ctx)
{
- if (ctx->state >= TECO_BUFFER_DIRTY) {
+ if (ctx->state > TECO_BUFFER_DIRTY_NO_DUMP) {
g_autofree gchar *filename_recovery = teco_buffer_get_recovery(ctx);
g_unlink(filename_recovery);
}
@@ -244,7 +244,7 @@ teco_ring_find_by_id(teco_int_t id)
static void
teco_ring_undirtify(void)
{
- if (teco_ring_current->state >= TECO_BUFFER_DIRTY) {
+ if (teco_ring_current->state > TECO_BUFFER_DIRTY_NO_DUMP) {
g_autofree gchar *filename_recovery = teco_buffer_get_recovery(teco_ring_current);
g_unlink(filename_recovery);
}
@@ -261,17 +261,18 @@ teco_ring_dirtify(void)
if (teco_qreg_current)
return;
- teco_buffer_state_t old_state = teco_ring_current->state;
- teco_ring_current->state = TECO_BUFFER_DIRTY;
- switch (old_state) {
+ switch ((teco_buffer_state_t)teco_ring_current->state) {
case TECO_BUFFER_CLEAN:
+ teco_ring_current->state = TECO_BUFFER_DIRTY_NO_DUMP;
teco_interface_info_update(teco_ring_current);
undo__teco_ring_undirtify();
break;
- case TECO_BUFFER_DIRTY:
+ case TECO_BUFFER_DIRTY_NO_DUMP:
+ case TECO_BUFFER_DIRTY_OUTDATED_DUMP:
break;
- case TECO_BUFFER_DIRTY_DUMPED:
- /* set to TECO_BUFFER_DIRTY on rubout */
+ case TECO_BUFFER_DIRTY_RECENT_DUMP:
+ teco_ring_current->state = TECO_BUFFER_DIRTY_OUTDATED_DUMP;
+ /* set to TECO_BUFFER_DIRTY_OUTDATED_DUMP on rubout */
teco_undo_guint(teco_ring_current->state);
break;
}
@@ -327,12 +328,16 @@ teco_ring_dump_recovery(void)
for (teco_tailq_entry_t *cur = teco_ring_head.first; cur != NULL; cur = cur->next) {
teco_buffer_t *buffer = (teco_buffer_t *)cur;
+ /* already dumped buffers don't have to be written again */
+ if (buffer->state != TECO_BUFFER_DIRTY_NO_DUMP &&
+ buffer->state != TECO_BUFFER_DIRTY_OUTDATED_DUMP)
+ continue;
+
/*
* Dirty unnamed buffers cannot be backed up.
- * Already backed-up buffers don't have to be written again.
- * FIXME: Perhaps they should be under ~/UNNAMED~?
+ * FIXME: Perhaps they should be dumped under ~/#UNNAMED#?
*/
- if (buffer->state != TECO_BUFFER_DIRTY || !buffer->filename)
+ if (!buffer->filename)
continue;
g_autofree gchar *filename_recovery = teco_buffer_get_recovery(buffer);
@@ -357,7 +362,7 @@ teco_ring_dump_recovery(void)
if (!teco_view_save_to_channel(buffer->view, channel, NULL))
continue;
- buffer->state = TECO_BUFFER_DIRTY_DUMPED;
+ buffer->state = TECO_BUFFER_DIRTY_RECENT_DUMP;
}
}
diff --git a/src/ring.h b/src/ring.h
index 4624983..d81c3db 100644
--- a/src/ring.h
+++ b/src/ring.h
@@ -28,10 +28,12 @@
typedef enum {
/** buffer is freshly opened or saved */
TECO_BUFFER_CLEAN = 0,
- /** buffer modified - if a recovery file already exists, it is outdated */
- TECO_BUFFER_DIRTY,
- /** buffer modified and recovery file already written */
- TECO_BUFFER_DIRTY_DUMPED
+ /** buffer modified, but a recovery file does not yet exist */
+ TECO_BUFFER_DIRTY_NO_DUMP,
+ /** buffer modified, recovery file outdated */
+ TECO_BUFFER_DIRTY_OUTDATED_DUMP,
+ /** buffer modified and recovery file is up to date */
+ TECO_BUFFER_DIRTY_RECENT_DUMP
} teco_buffer_state_t;
typedef struct teco_buffer_t {