Merge pull request #247 from rkta/hist
Do not override history file if it was changed
This commit is contained in:
73
history.c
73
history.c
@@ -2,6 +2,19 @@
|
||||
#include "fm.h"
|
||||
|
||||
#ifdef USE_HISTORY
|
||||
/* Merge entries from their history into ours */
|
||||
static int
|
||||
mergeHistory(Hist *ours, Hist *theirs)
|
||||
{
|
||||
HistItem *item;
|
||||
|
||||
for (item = theirs->list->first; item; item = item->next)
|
||||
if (!getHashHist(ours, item->ptr))
|
||||
pushHist(ours, (char *)item->ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Buffer *
|
||||
historyBuffer(Hist *hist)
|
||||
{
|
||||
@@ -31,16 +44,23 @@ historyBuffer(Hist *hist)
|
||||
return loadHTMLString(src);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
loadHistory(Hist *hist)
|
||||
{
|
||||
FILE *f;
|
||||
Str line;
|
||||
struct stat st;
|
||||
|
||||
if (hist == NULL)
|
||||
return;
|
||||
return 1;
|
||||
if ((f = fopen(rcFile(HISTORY_FILE), "rt")) == NULL)
|
||||
return;
|
||||
return 1;
|
||||
|
||||
if (fstat(fileno(f), &st) == -1) {
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
hist->mtime = (long long)st.st_mtim.tv_sec;
|
||||
|
||||
while (!feof(f)) {
|
||||
line = Strfgets(f);
|
||||
@@ -52,42 +72,61 @@ loadHistory(Hist *hist)
|
||||
pushHist(hist, url_quote(line->ptr));
|
||||
}
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
saveHistory(Hist *hist, size_t size)
|
||||
{
|
||||
FILE *f;
|
||||
Hist *fhist;
|
||||
HistItem *item;
|
||||
char *histf;
|
||||
char *tmpf;
|
||||
int rename_ret;
|
||||
struct stat st;
|
||||
|
||||
if (hist == NULL || hist->list == NULL)
|
||||
return;
|
||||
tmpf = tmpfname(TMPF_HIST, NULL)->ptr;
|
||||
if ((f = fopen(tmpf, "w")) == NULL) {
|
||||
/* FIXME: gettextize? */
|
||||
disp_err_message("Can't open history", FALSE);
|
||||
return;
|
||||
|
||||
histf = rcFile(HISTORY_FILE);
|
||||
if (stat(histf, &st) == -1)
|
||||
goto fail;
|
||||
if (hist->mtime != (long long)st.st_mtim.tv_sec) {
|
||||
fhist = newHist();
|
||||
if (loadHistory(fhist) || mergeHistory(fhist, hist))
|
||||
disp_err_message("Can't merge history", FALSE);
|
||||
else
|
||||
hist = fhist;
|
||||
}
|
||||
|
||||
tmpf = tmpfname(TMPF_HIST, NULL)->ptr;
|
||||
if ((f = fopen(tmpf, "w")) == NULL)
|
||||
goto fail;
|
||||
for (item = hist->list->first; item && hist->list->nitem > size;
|
||||
item = item->next)
|
||||
size++;
|
||||
for (; item; item = item->next)
|
||||
fprintf(f, "%s\n", (char *)item->ptr);
|
||||
if (fclose(f) == EOF) {
|
||||
/* FIXME: gettextize? */
|
||||
disp_err_message("Can't save history", FALSE);
|
||||
return;
|
||||
}
|
||||
if (fclose(f) == EOF)
|
||||
goto fail;
|
||||
rename_ret = rename(tmpf, rcFile(HISTORY_FILE));
|
||||
if (rename_ret != 0) {
|
||||
disp_err_message("Can't save history", FALSE);
|
||||
return;
|
||||
}
|
||||
if (rename_ret != 0)
|
||||
goto fail;
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
disp_err_message("Can't open history", FALSE);
|
||||
return;
|
||||
}
|
||||
#endif /* USE_HISTORY */
|
||||
|
||||
/*
|
||||
* The following functions are used for internal stuff, we need them regardless
|
||||
* if history is used or not.
|
||||
*/
|
||||
|
||||
Hist *
|
||||
newHist(void)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef struct {
|
||||
HistList *list;
|
||||
HistItem *current;
|
||||
Hash_sv *hash;
|
||||
long long mtime;
|
||||
} Hist;
|
||||
|
||||
extern Hist *newHist(void);
|
||||
@@ -28,4 +29,12 @@ extern char *lastHist(Hist *hist);
|
||||
extern char *nextHist(Hist *hist);
|
||||
extern char *prevHist(Hist *hist);
|
||||
|
||||
#ifdef USE_HISTORY
|
||||
extern int loadHistory(Hist *hist);
|
||||
extern void saveHistory(Hist *hist, size_t size);
|
||||
extern void ldHist(void);
|
||||
#else /* not USE_HISTORY */
|
||||
#define ldHist nulcmd
|
||||
#endif /* not USE_HISTORY */
|
||||
|
||||
#endif /* HISTORY_H */
|
||||
|
||||
5
proto.h
5
proto.h
@@ -391,11 +391,6 @@ extern char *inputLineHistSearch(char *prompt, char *def_str, int flag,
|
||||
extern Str unescape_spaces(Str s);
|
||||
#ifdef USE_HISTORY
|
||||
extern Buffer *historyBuffer(Hist *hist);
|
||||
extern void loadHistory(Hist *hist);
|
||||
extern void saveHistory(Hist *hist, size_t size);
|
||||
extern void ldHist(void);
|
||||
#else /* not USE_HISTORY */
|
||||
#define ldHist nulcmd
|
||||
#endif /* not USE_HISTORY */
|
||||
extern double log_like(int x);
|
||||
extern struct table *newTable(void);
|
||||
|
||||
Reference in New Issue
Block a user