1
0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-11-19 21:44:11 +01:00

- Added functions to push and pop the current history list, allowing

functions to more easily switch to their own private history.
- Changed the existing history push/pop code in savehistfile() (which
  uses a separate history buf to allow it to rewrite the on-disk
  version of the history file without disturbing the in-memory list).
This commit is contained in:
Wayne Davison 2004-05-20 22:23:02 +00:00
parent 76ec200cc4
commit e8eca2ee4b

@ -1791,13 +1791,26 @@ resizehistents(void)
}
/* Remember the last line in the history file so we can find it again. */
static struct {
static struct histfile_stats {
char *text;
time_t stim, mtim;
off_t fpos, fsiz;
int next_write_ev;
} lasthist;
static struct histsave {
struct histfile_stats lasthist;
char *histfile;
HashTable histtab;
Histent hist_ring;
int curhist;
int histlinect;
int histsiz;
int savehistsiz;
} *histsave_stack;
static int histsave_stack_size = 0;
static int histsave_stack_pos = 0;
static int histfile_linect;
static int
@ -2078,31 +2091,20 @@ savehistfile(char *fn, int err, int writeflags)
fclose(out);
if ((writeflags & (HFILE_SKIPOLD | HFILE_FAST)) == HFILE_SKIPOLD) {
HashTable remember_histtab = histtab;
Histent remember_hist_ring = hist_ring;
int remember_histlinect = histlinect;
int remember_curhist = curhist;
int remember_histsiz = histsiz;
int remember_histactive = histactive;
hist_ring = NULL;
curhist = histlinect = 0;
histsiz = savehistsiz;
/* Zeroing histactive avoids unnecessary munging of curline. */
histactive = 0;
createhisttable(); /* sets histtab */
/* The NULL leaves HISTFILE alone, preserving fn's value. */
pushhiststack(NULL, savehistsiz, savehistsiz);
hist_ignore_all_dups |= isset(HISTSAVENODUPS);
readhistfile(fn, err, 0);
hist_ignore_all_dups = isset(HISTIGNOREALLDUPS);
if (histlinect)
savehistfile(fn, err, 0);
deletehashtable(histtab);
curhist = remember_curhist;
histlinect = remember_histlinect;
hist_ring = remember_hist_ring;
histtab = remember_histtab;
histsiz = remember_histsiz;
pophiststack();
histactive = remember_histactive;
}
} else if (err)
@ -2331,3 +2333,120 @@ bufferwords(LinkList list, char *buf, int *index)
return list;
}
/* Move the current history list out of the way and prepare a fresh history
* list using hf for HISTFILE, hs for HISTSIZE, and shs for SAVEHIST. If
* the hf value is an empty string, HISTFILE will be unset from the new
* environment; if it is NULL, HISTFILE will not be changed, not even by the
* pop function (this functionality is used internally to rewrite the current
* history file without affecting pointers into the environment).
*/
/**/
int
pushhiststack(char *hf, int hs, int shs)
{
struct histsave *h;
int curline_in_ring = (histactive & HA_ACTIVE) && hist_ring == &curline;
if (histsave_stack_pos == histsave_stack_size) {
histsave_stack_size += 5;
histsave_stack = zrealloc(histsave_stack,
histsave_stack_size * sizeof (struct histsave));
}
if (curline_in_ring)
unlinkcurline();
h = &histsave_stack[histsave_stack_pos++];
h->lasthist = lasthist;
if (hf) {
if ((h->histfile = getsparam("HISTFILE")) != NULL && *h->histfile)
h->histfile = ztrdup(h->histfile);
else
h->histfile = "";
} else
h->histfile = NULL;
h->histtab = histtab;
h->hist_ring = hist_ring;
h->curhist = curhist;
h->histlinect = histlinect;
h->histsiz = histsiz;
h->savehistsiz = savehistsiz;
memset(&lasthist, 0, sizeof lasthist);
if (hf) {
if (*hf)
setsparam("HISTFILE", ztrdup(hf));
else
unsetparam("HISTFILE");
}
hist_ring = NULL;
curhist = histlinect = 0;
histsiz = hs;
savehistsiz = shs;
inithist(); /* sets histtab */
if (curline_in_ring)
linkcurline();
return histsave_stack_pos;
}
/**/
int
pophiststack(void)
{
struct histsave *h;
int curline_in_ring = (histactive & HA_ACTIVE) && hist_ring == &curline;
if (histsave_stack_pos == 0)
return 0;
if (curline_in_ring)
unlinkcurline();
deletehashtable(histtab);
zsfree(lasthist.text);
h = &histsave_stack[--histsave_stack_pos];
lasthist = h->lasthist;
if (h->histfile) {
if (*h->histfile)
setsparam("HISTFILE", h->histfile);
else
unsetparam("HISTFILE");
}
histtab = h->histtab;
hist_ring = h->hist_ring;
curhist = h->curhist;
histlinect = h->histlinect;
histsiz = h->histsiz;
savehistsiz = h->savehistsiz;
if (curline_in_ring)
linkcurline();
return histsave_stack_pos + 1;
}
/**/
int
saveandpophiststack(int down_through)
{
if (down_through < 0)
down_through += histsave_stack_pos + 1;
if (down_through <= 0)
down_through = 1;
if (histsave_stack_pos < down_through)
return 0;
do {
if (!nohistsave)
savehistfile(NULL, 1, HFILE_USE_OPTIONS);
pophiststack();
} while (histsave_stack_pos >= down_through);
return 1;
}