Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ VPATH = $(srcdir)
HFILES = config.h es.h gc.h input.h prim.h print.h sigmsgs.h \
stdenv.h syntax.h term.h var.h
CFILES = access.c closure.c conv.c dict.c eval.c except.c fd.c gc.c glob.c \
glom.c input.c heredoc.c list.c main.c match.c open.c opt.c \
glom.c input.c heredoc.c history.c list.c main.c match.c open.c opt.c \
prim-ctl.c prim-etc.c prim-io.c prim-sys.c prim.c print.c proc.c \
sigmsgs.c signal.c split.c status.c str.c syntax.c term.c token.c \
tree.c util.c var.c vec.c version.c y.tab.c dump.c
OFILES = access.o closure.o conv.o dict.o eval.o except.o fd.o gc.o glob.o \
glom.o input.o heredoc.o list.o main.o match.o open.o opt.o \
glom.o input.o heredoc.o history.o list.o main.o match.o open.o opt.o \
prim-ctl.o prim-etc.o prim-io.o prim-sys.o prim.o print.o proc.o \
sigmsgs.o signal.o split.o status.o str.o syntax.o term.o token.o \
tree.o util.o var.o vec.o version.o y.tab.o
Expand Down Expand Up @@ -133,6 +133,7 @@ glob.o : glob.c es.h config.h stdenv.h gc.h
glom.o : glom.c es.h config.h stdenv.h gc.h
input.o : input.c es.h config.h stdenv.h input.h
heredoc.o : heredoc.c es.h config.h stdenv.h gc.h input.h syntax.h
history.o : history.c es.h config.h stdenv.h gc.h input.h
list.o : list.c es.h config.h stdenv.h gc.h
main.o : main.c es.h config.h stdenv.h
match.o : match.c es.h config.h stdenv.h
Expand Down
69 changes: 51 additions & 18 deletions doc/es.1
Original file line number Diff line number Diff line change
Expand Up @@ -2559,6 +2559,22 @@ For each named
returns the pathname, primitive, lambda, or code fragment which
would be run if the program appeared as the first word of a command.
.TP
.Cr "%write-history \fIinput\fP"
Called at the end of
.Cr %parse
to write the
.I input
to the file given in
.Cr $history ,
if such a file exists and can be written.
Also appends the
.I input
to the in-memory history log if
.I readline
support is compiled in.
(For more on this, see
.Cr max-history-length .)
.TP
.Cr "%writeto \fIvar output cmd\fP"
Runs
.I cmd
Expand Down Expand Up @@ -2690,8 +2706,8 @@ apids here read
close home run
count newfd seq
dup openfile split
flatten parse var
fsplit pipe whatis
flatten var fsplit
pipe whatis
.ft R
.De
.PP
Expand All @@ -2707,12 +2723,19 @@ batchloop exitonfalse isinteractive
.De
.PP
The
.Cr parse
primitive is used to implement the
.Cr %parse
hook function.
.PP
The
.Cr background
primitive is used to implement the
.Cr %background
hook function, but does not print the process ID of the
background process or set
.Cr $apid .
.PP
The
.Cr backquote
primitive is used to implement the
Expand All @@ -2726,7 +2749,7 @@ The following primitives implement the similarly named settor functions:
.ta 1.75i 3.5i
.Ds
.ft \*(Cf
sethistory setnoexport setsignals
setnoexport setsignals
.ft R
.De
.PP
Expand All @@ -2745,27 +2768,37 @@ writeto %writeto
.ft R
.De
.PP
The primitive
.Cr resetterminal
is if
The following primitives in particular are included if
.I es
is compiled with support for the
.I readline
library.
It is used in the implementation of settor functions of the
.Cr TERM
library:
.ta 2i
.Ds
.ft \*(Cf
resetterminal sethistory
setmaxhistorylength writehistory
.ft R
.De
.PP
.Cr sethistory
and
.Cr TERMCAP
variables to notify the line editing packages that the terminal
configuration has changed.
Similarly,
.Cr setmaxhistorylength
is used as the settor function for the
are used as settor functions for the
.Cr history
and
.Cr max-history-length
variable, which signals to the
.I readline
library how much of the history file should be read into the in-memory
history log.
variables.
.Cr resetterminal
is used in the settor functions for the
.Cr TERM
and
.Cr TERMCAP
variables.
.Cr writehistory
is used as the initial implementation of the
.Cr %write-history
function.
.PP
Several primitives are not directly associated with other function.
They are:
Expand Down
20 changes: 16 additions & 4 deletions es.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,8 @@ extern Boolean streq2(const char *s, const char *t1, const char *t2);
extern char *prompt, *prompt2;
extern Tree *parse(char *esprompt1, char *esprompt2);
extern Tree *parsestring(const char *str);
extern void sethistory(char *file);
extern Boolean isinteractive(void);
#if HAVE_READLINE
extern void setmaxhistorylength(int length);
#endif
extern Boolean isfromfd(void);
extern void initgetenv(void);
extern void initinput(void);
extern void resetparser(void);
Expand All @@ -316,6 +313,21 @@ extern Boolean resetterminal;
#endif


/* history.c */
#if HAVE_READLINE
extern void inithistory(void);

extern void sethistory(char *file);
extern void loghistory(char *cmd);
extern void setmaxhistorylength(int length);
extern void checkreloadhistory(void);
#endif

extern void newhistbuffer(void);
extern void addhistbuffer(char c);
extern char *dumphistbuffer(void);


/* opt.c */

extern void esoptbegin(List *list, const char *caller, const char *usage, Boolean throws);
Expand Down
5 changes: 0 additions & 5 deletions heredoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ extern Tree *snarfheredoc(const char *eof, Boolean quoted) {
return NULL;
}
ignoreeof = TRUE;
disablehistory = TRUE;

for (tree = NULL, tailp = &tree, buf = openbuffer(0);;) {
int c;
Expand All @@ -65,7 +64,6 @@ extern Tree *snarfheredoc(const char *eof, Boolean quoted) {
yyerror("incomplete here document");
freebuffer(buf);
ignoreeof = FALSE;
disablehistory = FALSE;
return NULL;
}
if (c == '$' && !quoted && (c = GETC()) != '$') {
Expand All @@ -81,7 +79,6 @@ extern Tree *snarfheredoc(const char *eof, Boolean quoted) {
if (var == NULL) {
freebuffer(buf);
ignoreeof = FALSE;
disablehistory = FALSE;
return NULL;
}
*tailp = treecons(var, NULL);
Expand All @@ -96,7 +93,6 @@ extern Tree *snarfheredoc(const char *eof, Boolean quoted) {
}

ignoreeof = FALSE;
disablehistory = FALSE;
return tree->CDR == NULL ? tree->CAR : tree;
}

Expand Down Expand Up @@ -146,5 +142,4 @@ extern Boolean queueheredoc(Tree *t) {

extern void emptyherequeue(void) {
hereq = NULL;
disablehistory = FALSE;
}
134 changes: 134 additions & 0 deletions history.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/* history.c -- control the history file ($Revision: 1.1.1.1 $) */

#include "es.h"
#include "gc.h"
#include "input.h"


/*
* constants
*/

#define BUFSIZE ((size_t) 4096) /* buffer size to fill reads into */


/*
* globals
*/

static Buffer *histbuffer = NULL;

#if HAVE_READLINE
#include <readline/history.h>

Boolean reloadhistory = FALSE;
static char *history;

#if 0
/* These split history file entries by timestamp, which allows readline to pick up
* multi-line commands correctly across process boundaries. Disabled by default,
* because it leaves the history file itself kind of ugly. */
static int history_write_timestamps = 1;
static char history_comment_char = '#';
#endif
#endif


/*
* histbuffer -- build the history line during input and dump it as a gc-string
*/


extern void newhistbuffer() {
assert(histbuffer == NULL);
histbuffer = openbuffer(BUFSIZE);
}

extern void addhistbuffer(char c) {
if (histbuffer == NULL)
return;
histbuffer = bufputc(histbuffer, c);
}

extern char *dumphistbuffer() {
char *s;
size_t len;
assert(histbuffer != NULL);

s = sealcountedbuffer(histbuffer);
histbuffer = NULL;

len = strlen(s);
if (len > 0 && s[len - 1] == '\n')
s[len - 1] = '\0';
return s;
}


/*
* history file
*/

#if HAVE_READLINE
extern void setmaxhistorylength(int len) {
static int currenthistlen = -1; /* unlimited */
if (len != currenthistlen) {
switch (len) {
case -1:
unstifle_history();
break;
case 0:
clear_history();
FALLTHROUGH;
default:
stifle_history(len);
}
currenthistlen = len;
}
}

extern void loghistory(char *cmd) {
int err;
if (cmd == NULL)
return;
add_history(cmd);
if (history == NULL)
return;

if ((err = append_history(1, history))) {
eprint("history(%s): %s\n", history, esstrerror(err));
vardef("history", NULL, NULL);
}
}

static void reload_history(void) {
/* Attempt to populate readline history with new history file. */
if (history != NULL)
read_history(history);
using_history();

reloadhistory = FALSE;
}

extern void sethistory(char *file) {
if (reloadhistory)
reload_history();
reloadhistory = TRUE;
history = file;
}

extern void checkreloadhistory(void) {
if (reloadhistory)
reload_history();
}

/*
* initialization
*/

/* inithistory -- called at dawn of time from main() */
extern void inithistory(void) {
/* declare the global roots */
globalroot(&history); /* history file */
}
#endif
Loading