diff options
| author | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2025-12-17 01:17:11 +0100 |
|---|---|---|
| committer | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2025-12-17 01:17:11 +0100 |
| commit | deed71ac895451041359d7b18e58eca0a0972bc3 (patch) | |
| tree | 2cce2c266b2f92fca45335c95f0a4b8f4945d31e /src/interface-curses/interface.c | |
| parent | ad0780c7163c9673f89dc584d2a6096f317bec2b (diff) | |
implemented backup file mechanism
* The backup mechanism is supposed to guard against crashes of SciTECO and
unexpected program terminations (e.g. power cycling, etc.)
* In a given interval (no matter whether busy or idlying on the prompt)
SciTECO saves all modified buffers with the filename~ (like most other editors).
As an optimization files are not backed up if they have been backed up
previously to avoid pointless and possibly slow file system writes.
* While the backup mechanism exists outside of the usual undo-paradigm -
backup file creating is not bound to character input and it makes no sense
to restore the exact state of backup files - there are some interesting
interactions:
* When a buffer is dirtyfied or saved that was previously backed up, it must always
be reset to the DIRTY state on rubout, so backups are eventually recreated.
* When a buffer is dirtyfied first (was clean), the backup file must be
removed on rubout as well - we don't expect backup files for clean buffers.
* There is currently no automatic way to restore backup files.
This could potentially be done by opener.tes and session.tes in the future,
although you couldn't currently always get meaningful user feedback
(whether he wants to restore the file).
Perhaps we should at least log a message when detecting backup files that
are newer than the file that is being opened.
Diffstat (limited to 'src/interface-curses/interface.c')
| -rw-r--r-- | src/interface-curses/interface.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c index 8f41f2a..e03ba72 100644 --- a/src/interface-curses/interface.c +++ b/src/interface-curses/interface.c @@ -205,6 +205,9 @@ static struct { teco_string_t info_current; gboolean info_dirty; + /** timer to track the backup interval */ + GTimer *backup_timer; + WINDOW *msg_window; /** @@ -1217,7 +1220,7 @@ teco_interface_info_update_buffer(const teco_buffer_t *buffer) teco_string_clear(&teco_interface.info_current); teco_string_init(&teco_interface.info_current, filename, strlen(filename)); - teco_interface.info_dirty = buffer->dirty; + teco_interface.info_dirty = buffer->state > TECO_BUFFER_CLEAN; teco_interface.info_type = TECO_INFO_TYPE_BUFFER; /* NOTE: drawn in teco_interface_event_loop_iter() */ } @@ -2014,6 +2017,18 @@ teco_interface_blocking_getch(void) /* no special <CTRL/C> handling */ raw(); nodelay(teco_interface.input_pad, FALSE); + + /* + * Make sure we return when it's time to create backups. + */ + if (teco_ring_backup_interval != 0) { + if (G_UNLIKELY(!teco_interface.backup_timer)) + teco_interface.backup_timer = g_timer_new(); + gdouble elapsed = g_timer_elapsed(teco_interface.backup_timer, NULL); + wtimeout(teco_interface.input_pad, + MAX((gdouble)teco_ring_backup_interval - elapsed, 0)*1000); + } + /* * Memory limiting is stopped temporarily, since it might otherwise * constantly place 100% load on the CPU. @@ -2029,6 +2044,12 @@ teco_interface_blocking_getch(void) cbreak(); #endif + if (key == ERR && teco_ring_backup_interval != 0 && + g_timer_elapsed(teco_interface.backup_timer, NULL) >= teco_ring_backup_interval) { + teco_ring_backup(); + g_timer_start(teco_interface.backup_timer); + } + return key; } @@ -2290,4 +2311,7 @@ teco_interface_cleanup(void) if (teco_interface.pair_table) g_hash_table_destroy(teco_interface.pair_table); + + if (teco_interface.backup_timer) + g_timer_destroy(teco_interface.backup_timer); } |
