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 <lh_mouse@126.com>

Original-idea-by: Brand Huntsman <alpha@qzx.com>
master
Benno Schulenberg 2017-12-18 20:08:06 +01:00
parent 31fe0753e3
commit dc3618a127
3 changed files with 20 additions and 11 deletions

View File

@ -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);

View File

@ -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

View File

@ -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,6 +1028,12 @@ void do_redo(void)
openfile->placewewant = xplustabs();
openfile->totsize = u->newsize;
/* 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. */