Add a uniquefier for the history function.

This commit is contained in:
christos 2003-01-21 18:40:23 +00:00
parent 46ca961c02
commit f24857bf36
6 changed files with 124 additions and 33 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: editline.3,v 1.29 2002/10/01 19:06:45 wiz Exp $
.\" $NetBSD: editline.3,v 1.30 2003/01/21 18:40:23 christos Exp $
.\"
.\" Copyright (c) 1997-1999 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -562,6 +562,17 @@ Add
.Fa str
as a new element to the history, and, if necessary,
removing the oldest entry to keep the list to the created size.
If
.Dv H_SETUNIQUE
was has been called with a non-zero arguments, the element
will not be entered into the history if its contents match
the ones of the current history element.
If the element is entered
.Fn history
returns 1, if it is ignored as a duplicate returns 0.
Finally
.Fn history
returns -1 if an error occurred.
.It Dv H_PREV_STR , Fa "const char *str"
Return the closest previous event that starts with
.Fa str .
@ -580,10 +591,16 @@ Load the history list stored in
.It Dv H_SAVE , Fa "const char *file"
Save the history list to
.Fa file .
.It Dv H_SETUNIQUE , Fa "int unique"
Set if the adjacent identical event strigns should not be entered into
the history.
.It Dv H_GETUNIQUE
Retrieve the current setting if if adjacent elementes should be entered into
the history.
.El
.Pp
.Fn history
returns 0 if the operation
returns >= 0 if the operation succeeds
.Fa op
succeeds.
Otherwise, -1 is returned and

View File

@ -1,4 +1,4 @@
/* $NetBSD: hist.c,v 1.11 2002/11/15 14:32:33 christos Exp $ */
/* $NetBSD: hist.c,v 1.12 2003/01/21 18:40:23 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -41,7 +41,7 @@
#if 0
static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: hist.c,v 1.11 2002/11/15 14:32:33 christos Exp $");
__RCSID("$NetBSD: hist.c,v 1.12 2003/01/21 18:40:23 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -153,21 +153,41 @@ hist_get(EditLine *el)
}
/* hist_list()
* List history entries
/* hist_command()
* process a history command
*/
protected int
/*ARGSUSED*/
hist_list(EditLine *el, int argc, const char **argv)
hist_command(EditLine *el, int argc, const char **argv)
{
const char *str;
int num;
HistEvent ev;
if (el->el_history.ref == NULL)
return (-1);
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
(void) fprintf(el->el_outfile, "%d %s",
el->el_history.ev.num, str);
return (0);
if (argc == 0 || strcmp(argv[0], "list") == 1) {
/* List history entries */
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
(void) fprintf(el->el_outfile, "%d %s",
el->el_history.ev.num, str);
return (0);
}
if (argc != 2)
return (-1);
num = (int)strtol(argv[1], NULL, 0);
if (strcmp(argv[0], "size") == 0)
return history(el->el_history.ref, &ev, H_SETSIZE, num);
if (strcmp(argv[0], "unique") == 0)
return history(el->el_history.ref, &ev, H_SETUNIQUE, num);
return -1;
}
/* hist_enlargebuf()

View File

@ -1,4 +1,4 @@
/* $NetBSD: hist.h,v 1.8 2002/11/15 14:32:33 christos Exp $ */
/* $NetBSD: hist.h,v 1.9 2003/01/21 18:40:23 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -74,7 +74,7 @@ protected int hist_init(EditLine *);
protected void hist_end(EditLine *);
protected el_action_t hist_get(EditLine *);
protected int hist_set(EditLine *, hist_fun_t, ptr_t);
protected int hist_list(EditLine *, int, const char **);
protected int hist_command(EditLine *, int, const char **);
protected int hist_enlargebuf(EditLine *, size_t, size_t);
#endif /* _h_el_hist */

View File

@ -1,4 +1,4 @@
/* $NetBSD: histedit.h,v 1.20 2002/11/15 14:32:33 christos Exp $ */
/* $NetBSD: histedit.h,v 1.21 2003/01/21 18:40:24 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -193,5 +193,7 @@ int history(History *, HistEvent *, int, ...);
#define H_LOAD 17 /* , const char *); */
#define H_SAVE 18 /* , const char *); */
#define H_CLEAR 19 /* , void); */
#define H_SETUNIQUE 20 /* , int); */
#define H_GETUNIQUE 21 /* , void); */
#endif /* _HISTEDIT_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: history.c,v 1.21 2002/10/27 20:24:28 christos Exp $ */
/* $NetBSD: history.c,v 1.22 2003/01/21 18:40:24 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -41,7 +41,7 @@
#if 0
static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: history.c,v 1.21 2002/10/27 20:24:28 christos Exp $");
__RCSID("$NetBSD: history.c,v 1.22 2003/01/21 18:40:24 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -80,6 +80,7 @@ struct history {
history_efun_t h_enter; /* Add an element */
history_efun_t h_add; /* Append to an element */
};
#define HNEXT(h, ev) (*(h)->h_next)((h)->h_ref, ev)
#define HFIRST(h, ev) (*(h)->h_first)((h)->h_ref, ev)
#define HPREV(h, ev) (*(h)->h_prev)((h)->h_ref, ev)
@ -103,6 +104,8 @@ typedef struct {
private int history_setsize(History *, HistEvent *, int);
private int history_getsize(History *, HistEvent *);
private int history_setunique(History *, HistEvent *, int);
private int history_getunique(History *, HistEvent *);
private int history_set_fun(History *, History *);
private int history_load(History *, const char *);
private int history_save(History *, const char *);
@ -121,15 +124,17 @@ typedef struct hentry_t {
HistEvent ev; /* What we return */
struct hentry_t *next; /* Next entry */
struct hentry_t *prev; /* Previous entry */
} hentry_t;
} hentry_t;
typedef struct history_t {
hentry_t list; /* Fake list header element */
hentry_t *cursor; /* Current element in the list */
int max; /* Maximum number of events */
int cur; /* Current number of events */
hentry_t list; /* Fake list header element */
hentry_t *cursor; /* Current element in the list */
int max; /* Maximum number of events */
int cur; /* Current number of events */
int eventid; /* For generation of unique event id */
} history_t;
int flags; /* History flags */
#define H_UNIQUE 1 /* Store only unique elements */
} history_t;
private int history_def_first(ptr_t, HistEvent *);
private int history_def_last(ptr_t, HistEvent *);
@ -144,8 +149,14 @@ private void history_def_clear(ptr_t, HistEvent *);
private int history_def_insert(history_t *, HistEvent *, const char *);
private void history_def_delete(history_t *, HistEvent *, hentry_t *);
#define history_def_setsize(p, num)(void) (((history_t *) p)->max = (num))
#define history_def_getsize(p) (((history_t *) p)->cur)
#define history_def_setsize(p, num)(void) (((history_t *)p)->max = (num))
#define history_def_getsize(p) (((history_t *)p)->cur)
#define history_def_getunique(p) (((((history_t *)p)->flags) & H_UNIQUE) != 0)
#define history_def_setunique(p, uni) \
if (uni) \
(((history_t *)p)->flags) |= H_UNIQUE; \
else \
(((history_t *)p)->flags) &= ~H_UNIQUE
#define he_strerror(code) he_errlist[code]
#define he_seterrev(evp, code) {\
@ -413,6 +424,10 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str)
{
history_t *h = (history_t *) p;
if ((h->flags & H_UNIQUE) != 0 && h->list.next != &h->list &&
strcmp(h->list.next->ev.str, str) == 0)
return (0);
if (history_def_insert(h, ev, str) == -1)
return (-1); /* error, keep error message */
@ -423,7 +438,7 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str)
while (h->cur > h->max && h->cur > 0)
history_def_delete(h, ev, h->list.prev);
return (0);
return (1);
}
@ -447,6 +462,7 @@ history_def_init(ptr_t *p, HistEvent *ev, int n)
h->list.ev.str = NULL;
h->list.ev.num = 0;
h->cursor = &h->list;
h->flags = 0;
*p = (ptr_t) h;
return 0;
}
@ -541,18 +557,46 @@ history_setsize(History *h, HistEvent *ev, int num)
private int
history_getsize(History *h, HistEvent *ev)
{
int retval = 0;
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1);
}
ev->num = history_def_getsize(h->h_ref);
if (ev->num < -1) {
he_seterrev(ev, _HE_SIZE_NEGATIVE);
return (-1);
}
return (0);
}
/* history_setunique():
* Set if adjacent equal events should not be entered in history.
*/
private int
history_setunique(History *h, HistEvent *ev, int uni)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1);
}
retval = history_def_getsize(h->h_ref);
if (retval < -1) {
he_seterrev(ev, _HE_SIZE_NEGATIVE);
history_def_setunique(h->h_ref, uni);
return (0);
}
/* history_getunique():
* Get if adjacent equal events should not be entered in history.
*/
private int
history_getunique(History *h, HistEvent *ev)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1);
}
ev->num = retval;
ev->num = history_def_getunique(h->h_ref);
return (0);
}
@ -799,6 +843,14 @@ history(History *h, HistEvent *ev, int fun, ...)
retval = history_setsize(h, ev, va_arg(va, int));
break;
case H_GETUNIQUE:
retval = history_getunique(h, ev);
break;
case H_SETUNIQUE:
retval = history_setunique(h, ev, va_arg(va, int));
break;
case H_ADD:
str = va_arg(va, const char *);
retval = HADD(h, ev, str);

View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.15 2002/03/18 16:00:56 christos Exp $ */
/* $NetBSD: parse.c,v 1.16 2003/01/21 18:40:24 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -41,7 +41,7 @@
#if 0
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: parse.c,v 1.15 2002/03/18 16:00:56 christos Exp $");
__RCSID("$NetBSD: parse.c,v 1.16 2003/01/21 18:40:24 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -69,7 +69,7 @@ private const struct {
{ "bind", map_bind },
{ "echotc", term_echotc },
{ "edit", el_editmode },
{ "history", hist_list },
{ "history", hist_command },
{ "telltc", term_telltc },
{ "settc", term_settc },
{ "setty", tty_stty },