From dc3618a1273007a4113c9ef382faf1d0dfd0c365 Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Mon, 18 Dec 2017 20:08:06 +0100 Subject: [PATCH] text: set and reset the Modified state correctly when undoing/redoing Unset the "Modified" marker only at the point where the file was last saved -- if there is such a point, because it can be missing when the undo stack was discarded. This fixes https://savannah.gnu.org/bugs/?52689. Reported-by: Liu Hao Original-idea-by: Brand Huntsman --- src/files.c | 6 +++++- src/nano.h | 5 ++--- src/text.c | 20 +++++++++++++------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/files.c b/src/files.c index 071bab21..1f18ea94 100644 --- a/src/files.c +++ b/src/files.c @@ -99,8 +99,8 @@ void make_new_buffer(void) openfile->undotop = NULL; openfile->current_undo = NULL; + openfile->last_saved = NULL; openfile->last_action = OTHER; - openfile->pristine = TRUE; openfile->current_stat = NULL; openfile->lock_filename = NULL; @@ -1953,6 +1953,10 @@ bool write_file(const char *name, FILE *f_open, bool tmp, #ifndef NANO_TINY /* Get or update the stat info to reflect the current state. */ stat_with_alloc(realname, &openfile->current_stat); + + /* Record at which point in the undo stack the file was saved. */ + openfile->last_saved = openfile->current_undo; + openfile->last_action = OTHER; #endif openfile->modified = FALSE; titlebar(NULL); diff --git a/src/nano.h b/src/nano.h index 7e6d8f81..62867b26 100644 --- a/src/nano.h +++ b/src/nano.h @@ -394,11 +394,10 @@ typedef struct openfilestruct { /* The top of the undo list. */ undo *current_undo; /* The current (i.e. next) level of undo. */ + undo *last_saved; + /* The undo item at which the file was last saved. */ undo_type last_action; /* The type of the last action the user performed. */ - bool pristine; - /* Whether the undo stack still contains the first edit -- it won't - * when a justification or spell check discarded the undo stack. */ char *lock_filename; /* The path of the lockfile, if we created one. */ #endif diff --git a/src/text.c b/src/text.c index a01bcc86..84e432e0 100644 --- a/src/text.c +++ b/src/text.c @@ -868,8 +868,8 @@ void do_undo(void) openfile->totsize = u->wassize; - /* If *everything* was undone, then unset the "Modified" marker. */ - if (openfile->current_undo == NULL && openfile->pristine) { + /* When at the point where the file was last saved, unset "Modified". */ + if (openfile->current_undo == openfile->last_saved) { openfile->modified = FALSE; titlebar(NULL); } else @@ -1028,7 +1028,13 @@ void do_redo(void) openfile->placewewant = xplustabs(); openfile->totsize = u->newsize; - set_modified(); + + /* When at the point where the file was last saved, unset "Modified". */ + if (openfile->current_undo == openfile->last_saved) { + openfile->modified = FALSE; + titlebar(NULL); + } else + set_modified(); } #endif /* !NANO_TINY */ @@ -1191,7 +1197,7 @@ bool execute_command(const char *command) } /* Discard undo items that are newer than the given one, or all if NULL. - * When keep is TRUE, do not touch the pristine flag. */ + * When keep is TRUE, do not touch the last_saved pointer. */ void discard_until(const undo *thisitem, openfilestruct *thefile, bool keep) { undo *dropit = thefile->undotop; @@ -1209,7 +1215,6 @@ void discard_until(const undo *thisitem, openfilestruct *thefile, bool keep) free(group); group = next; } - free(dropit); dropit = thefile->undotop; } @@ -1219,9 +1224,10 @@ void discard_until(const undo *thisitem, openfilestruct *thefile, bool keep) /* Prevent a chain of editing actions from continuing. */ thefile->last_action = OTHER; - /* When requested, record that the undo stack was chopped. */ + /* When requested, record that the undo stack was chopped, and + * that thus there is no point at which the file was last saved. */ if (!keep) - thefile->pristine = FALSE; + thefile->last_saved = (undo *)0xbeeb; } /* Add a new undo struct to the top of the current pile. */