history: prevent overwriting of positions between multiple instances

Whenever a buffer is closed, check whether the positions file on disk
was modified, and if so, reload it.  Then update the position for the
closed buffer and write out the positions file to disk.

Signed-off-by: Brand Huntsman <alpha@qzx.com>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
This commit is contained in:
Brand Huntsman 2017-10-20 21:26:20 -06:00 committed by Benno Schulenberg
parent f0d3685591
commit bfc53f308c
3 changed files with 44 additions and 2 deletions

View File

@ -40,6 +40,8 @@
static bool history_changed = FALSE;
/* Whether any of the history lists has changed. */
static struct stat stat_of_positions_file;
/* The last-obtained stat information of the positions file. */
/* Initialize the lists of historical search and replace strings
* and the list of historical executed commands. */
@ -386,6 +388,15 @@ void save_history(void)
free(histname);
}
/* Update the modification time of the position history file. */
void update_posfile_timestamp(void)
{
char *poshist = concatenate(statedir, POSITION_HISTORY);
stat(poshist, &stat_of_positions_file);
free(poshist);
}
/* Load the recorded cursor positions for files that were edited. */
void load_poshistory(void)
{
@ -448,6 +459,8 @@ void load_poshistory(void)
}
fclose(hisfile);
free(line);
update_posfile_timestamp();
}
free(poshist);
}
@ -487,10 +500,35 @@ void save_poshistory(void)
free(path_and_place);
}
fclose(hisfile);
update_posfile_timestamp();
}
free(poshist);
}
/* Reload the position history file if it has been modified since last load. */
void reload_positions_if_needed(void)
{
char *poshist = concatenate(statedir, POSITION_HISTORY);
struct stat newstat;
stat(poshist, &newstat);
free(poshist);
if (newstat.st_mtime != stat_of_positions_file.st_mtime) {
poshiststruct *ptr, *nextone;
for (ptr = position_history; ptr != NULL; ptr = nextone) {
nextone = ptr->next;
free(ptr->filename);
free(ptr);
}
position_history = NULL;
load_poshistory();
}
}
/* Update the recorded last file positions, given a filename, a line
* and a column. If no entry is found, add a new one at the end. */
void update_poshistory(char *filename, ssize_t lineno, ssize_t xpos)
@ -503,6 +541,8 @@ void update_poshistory(char *filename, ssize_t lineno, ssize_t xpos)
return;
}
reload_positions_if_needed();
/* Look for a matching filename in the list. */
for (posptr = position_history; posptr != NULL; posptr = posptr->next) {
if (!strcmp(posptr->filename, fullpath))
@ -551,6 +591,8 @@ void update_poshistory(char *filename, ssize_t lineno, ssize_t xpos)
theone->next = NULL;
free(fullpath);
save_poshistory();
}
/* Check whether the given file matches an existing entry in the recorded
@ -564,6 +606,8 @@ bool has_old_position(const char *file, ssize_t *line, ssize_t *column)
if (fullpath == NULL)
return FALSE;
reload_positions_if_needed();
while (posptr != NULL && strcmp(posptr->filename, fullpath) != 0)
posptr = posptr->next;

View File

@ -570,7 +570,6 @@ void finish(void)
save_history();
if (ISSET(POS_HISTORY)) {
update_poshistory(openfile->filename, openfile->current->lineno, xplustabs() + 1);
save_poshistory();
}
#endif

View File

@ -370,7 +370,6 @@ bool have_statedir(void);
void load_history(void);
void save_history(void);
void load_poshistory(void);
void save_poshistory(void);
void update_poshistory(char *filename, ssize_t lineno, ssize_t xpos);
bool has_old_position(const char *file, ssize_t *line, ssize_t *column);
#endif