Keep history based on paths instead of positions

This commit is contained in:
lostd 2014-10-22 21:05:59 +03:00
parent 8d018e620f
commit aa555a3b35

69
noice.c
View file

@ -51,7 +51,7 @@ struct entry {
}; };
struct history { struct history {
int pos; char *path;
SLIST_ENTRY(history) entry; SLIST_ENTRY(history) entry;
}; };
@ -483,33 +483,71 @@ dentfree(struct entry *dents, int n)
free(dents); free(dents);
} }
char *
makepath(char *dir, char *name)
{
char *path;
/* Handle root case */
if (strcmp(dir, "/") == 0)
asprintf(&path, "/%s", name);
else
asprintf(&path, "%s/%s", dir, name);
return path;
}
/* Return the position of the matching entry or 0 otherwise */
int
dentfind(struct entry *dents, int n, char *cwd, char *path)
{
int i;
char *tmp;
if (path == NULL)
return 0;
for (i = 0; i < n; i++) {
tmp = makepath(cwd, dents[i].name);
DPRINTF_S(path);
DPRINTF_S(tmp);
if (strcmp(tmp, path) == 0) {
free(tmp);
return i;
}
free(tmp);
}
return 0;
}
void void
pushhist(int pos) pushhist(char *path)
{ {
struct history *hist; struct history *hist;
hist = xmalloc(sizeof(*hist)); hist = xmalloc(sizeof(*hist));
hist->pos = pos; hist->path = xstrdup(path);
SLIST_INSERT_HEAD(&histhead, hist, entry); SLIST_INSERT_HEAD(&histhead, hist, entry);
} }
int char *
pophist(void) pophist(void)
{ {
struct history *hist; struct history *hist;
int pos; char *path;
/* Recall history */ /* Recall history */
hist = SLIST_FIRST(&histhead); hist = SLIST_FIRST(&histhead);
if (hist != NULL) { if (hist != NULL) {
pos = hist->pos; path = hist->path;
SLIST_REMOVE_HEAD(&histhead, entry); SLIST_REMOVE_HEAD(&histhead, entry);
free(hist); free(hist);
} else { } else {
pos = 0; path = NULL;
} }
return pos; return path;
} }
void void
@ -520,6 +558,7 @@ forgethist(void)
while (SLIST_EMPTY(&histhead) == 0) { while (SLIST_EMPTY(&histhead) == 0) {
hist = SLIST_FIRST(&histhead); hist = SLIST_FIRST(&histhead);
SLIST_REMOVE_HEAD(&histhead, entry); SLIST_REMOVE_HEAD(&histhead, entry);
free(hist->path);
free(hist); free(hist);
} }
} }
@ -536,8 +575,10 @@ browse(const char *ipath, const char *ifilter)
regex_t filter_re; regex_t filter_re;
char *cwd; char *cwd;
struct stat sb; struct stat sb;
char *hpath;
cur = 0; cur = 0;
hpath = NULL;
begin: begin:
/* Path and filter should be malloc(3)-ed strings at all times */ /* Path and filter should be malloc(3)-ed strings at all times */
n = 0; n = 0;
@ -559,11 +600,13 @@ begin:
n = dentfill(dirp, &dents, visible, &filter_re); n = dentfill(dirp, &dents, visible, &filter_re);
/* Make sure cur is in range */
cur = MIN(cur, n - 1);
qsort(dents, n, sizeof(*dents), entrycmp); qsort(dents, n, sizeof(*dents), entrycmp);
/* Find cur from history */
cur = dentfind(dents, n, path, hpath);
free(hpath);
hpath = NULL;
for (;;) { for (;;) {
int nlines; int nlines;
int odd; int odd;
@ -627,7 +670,7 @@ nochange:
free(filter); free(filter);
filter = xstrdup(ifilter); filter = xstrdup(ifilter);
/* Recall history */ /* Recall history */
cur = pophist(); hpath = pophist();
goto out; goto out;
case SEL_GOIN: case SEL_GOIN:
/* Cannot descend in empty directories */ /* Cannot descend in empty directories */
@ -657,7 +700,7 @@ nochange:
free(filter); free(filter);
filter = xstrdup(ifilter); filter = xstrdup(ifilter);
/* Remember history */ /* Remember history */
pushhist(cur); pushhist(path);
cur = 0; cur = 0;
goto out; goto out;
case S_IFREG: case S_IFREG: