nano

nano with my custom patches
git clone git://bsandro.tech/nano
Log | Files | Refs | README | LICENSE

commit bfc53f308c5cdb26c5846c5307532a6e4962b928
parent f0d368559178185943c0c1561da8e9b158ad0af1
Author: Brand Huntsman <alpha@qzx.com>
Date:   Fri, 20 Oct 2017 21:26:20 -0600

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>

Diffstat:
Msrc/history.c | 44++++++++++++++++++++++++++++++++++++++++++++
Msrc/nano.c | 1-
Msrc/proto.h | 1-
3 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/src/history.c b/src/history.c @@ -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; diff --git a/src/nano.c b/src/nano.c @@ -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 diff --git a/src/proto.h b/src/proto.h @@ -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