mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-12-11 19:31:21 +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:
parent
76ec200cc4
commit
e8eca2ee4b
1 changed files with 135 additions and 16 deletions
151
Src/hist.c
151
Src/hist.c
|
|
@ -1791,13 +1791,26 @@ resizehistents(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember the last line in the history file so we can find it again. */
|
/* Remember the last line in the history file so we can find it again. */
|
||||||
static struct {
|
static struct histfile_stats {
|
||||||
char *text;
|
char *text;
|
||||||
time_t stim, mtim;
|
time_t stim, mtim;
|
||||||
off_t fpos, fsiz;
|
off_t fpos, fsiz;
|
||||||
int next_write_ev;
|
int next_write_ev;
|
||||||
} lasthist;
|
} 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 histfile_linect;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -2078,31 +2091,20 @@ savehistfile(char *fn, int err, int writeflags)
|
||||||
fclose(out);
|
fclose(out);
|
||||||
|
|
||||||
if ((writeflags & (HFILE_SKIPOLD | HFILE_FAST)) == HFILE_SKIPOLD) {
|
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;
|
int remember_histactive = histactive;
|
||||||
|
|
||||||
hist_ring = NULL;
|
/* Zeroing histactive avoids unnecessary munging of curline. */
|
||||||
curhist = histlinect = 0;
|
|
||||||
histsiz = savehistsiz;
|
|
||||||
histactive = 0;
|
histactive = 0;
|
||||||
createhisttable(); /* sets histtab */
|
/* The NULL leaves HISTFILE alone, preserving fn's value. */
|
||||||
|
pushhiststack(NULL, savehistsiz, savehistsiz);
|
||||||
|
|
||||||
hist_ignore_all_dups |= isset(HISTSAVENODUPS);
|
hist_ignore_all_dups |= isset(HISTSAVENODUPS);
|
||||||
readhistfile(fn, err, 0);
|
readhistfile(fn, err, 0);
|
||||||
hist_ignore_all_dups = isset(HISTIGNOREALLDUPS);
|
hist_ignore_all_dups = isset(HISTIGNOREALLDUPS);
|
||||||
if (histlinect)
|
if (histlinect)
|
||||||
savehistfile(fn, err, 0);
|
savehistfile(fn, err, 0);
|
||||||
deletehashtable(histtab);
|
|
||||||
|
|
||||||
curhist = remember_curhist;
|
pophiststack();
|
||||||
histlinect = remember_histlinect;
|
|
||||||
hist_ring = remember_hist_ring;
|
|
||||||
histtab = remember_histtab;
|
|
||||||
histsiz = remember_histsiz;
|
|
||||||
histactive = remember_histactive;
|
histactive = remember_histactive;
|
||||||
}
|
}
|
||||||
} else if (err)
|
} else if (err)
|
||||||
|
|
@ -2331,3 +2333,120 @@ bufferwords(LinkList list, char *buf, int *index)
|
||||||
|
|
||||||
return list;
|
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;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue