summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Mallet <anthony.mallet@laas.fr>2011-11-02 10:57:48 +0100
committerAnthony Mallet <anthony.mallet@laas.fr>2011-11-02 10:57:48 +0100
commite078e252287041be13600c563db07e830ff2440d (patch)
tree6ef4ef4781dfe0a6379ee5a07fcb3d708b07d242
parent5e680a041fd4b697cad4cf3575ec0695dea0c429 (diff)
downloadeltclsh-e078e252287041be13600c563db07e830ff2440d.tar.gz
Add history load/save feature
-rw-r--r--CHANGELOG7
-rw-r--r--eltclsh.130
-rw-r--r--src/el.c83
-rw-r--r--src/eltclsh.h2
-rw-r--r--src/init.c14
5 files changed, 113 insertions, 23 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 7fc0a94..29b9bd8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+ 41. Load/save command history at startup/exit, and improve el::history command
+ to configure the file name and history size (~/.eltclhistory and 800 items
+ by default).
+
eltclsh 1.12 released june 16, 2011
40. Change resource file to ~/.eltclshrc instead of .eltclshrc
@@ -25,7 +29,8 @@ eltclsh 1.10 released february 27, 2009
eltclsh 1.9 released august 8, 2008
- 30. Fix libtool usage and install target to allow cross compilation in OpenEmbedded.
+ 30. Fix libtool usage and install target to allow cross compilation in
+ OpenEmbedded.
29. Honor TCL_DBGX to allow compiling against a tcl library with debugging
symbols enabled.
28. Honor CFLAGS from the environment during the build process
diff --git a/eltclsh.1 b/eltclsh.1
index 95e9a29..e14410e 100644
--- a/eltclsh.1
+++ b/eltclsh.1
@@ -1,5 +1,5 @@
.\" $LAAS$ */
-.\" Copyright (c) 2003 LAAS/CNRS -- Mon Jul 7 2003
+.\" Copyright (c) 2003,2011 LAAS/CNRS -- Mon Jul 7 2003
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -44,5 +44,33 @@ completion engine is programmable in a way similar to
.Xr tcsh 1 ,
and comes
with an intelligent completion for the full tcl language by default.
+.Sh SPECIAL TCL COMMANDS
+eltclsh provides a few specific commands to configure interactive editing
+.Bl -ohang
+.It Sy el::history add Ar string
+Add
+.Ar string
+to the history of commands.
+.It Sy el::history file Ar ?filename?
+Load history from
+.Ar filename
+and sets the filename for future saves, or return current filename. Note that
+if
+.Pa ~/.eltclhistory
+exists and is readable it is automatically loaded at startup.
+If
+.Ar filename
+is the empty string, history loading and saving are disabled.
+.It Sy el::history save
+Save history in ~/.eltclhistory by default, or in the
+.Ar filename
+configured by
+.Sy history file .
+History is automatically saved on exit.
+.It Sy el::history size Ar ?length?
+Set history length to
+.Ar length
+or return current length.
+.El
.Sh SEE ALSO
.Xr tclsh 1 .
diff --git a/src/el.c b/src/el.c
index f61d744..029542b 100644
--- a/src/el.c
+++ b/src/el.c
@@ -1,7 +1,7 @@
/* $LAAS$ */
/*
- * Copyright (c) 2001,2010 LAAS/CNRS -- Sun Oct 14 2001
+ * Copyright (c) 2001,2010-2011 LAAS/CNRS -- Sun Oct 14 2001
* All rights reserved. Anthony Mallet
*
* Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
__RCSID("$LAAS$");
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
@@ -124,28 +125,70 @@ int
elTclHistory(ClientData data, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[])
{
- ElTclInterpInfo *iinfo = data;
- char *string;
- HistEvent ev;
+ enum hidx {
+ hidx_add, hidx_file, hidx_save, hidx_size
+ };
+ static const char *args[] = {
+ [hidx_add] = "add", [hidx_file] = "file", [hidx_save] = "save",
+ [hidx_size] = "size", NULL
+ };
+
+ ElTclInterpInfo *iinfo = data;
+ char *string;
+ HistEvent ev;
+ int s;
+ int i = -1;
+
+ if (objc > 1) {
+ s = Tcl_GetIndexFromObj(interp, objv[1], args, "subcommand", 0, &i);
+ if (s != TCL_OK) return s;
+ }
+ switch(i) {
+ case hidx_add:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "string");
+ return TCL_ERROR;
+ }
+ string = Tcl_GetStringFromObj(objv[2], NULL);
+ if (string == NULL) {
+ Tcl_WrongNumArgs(interp, 2, objv, "string");
+ return TCL_ERROR;
+ }
+ history(iinfo->history, &ev, H_ENTER, string);
+ break;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "add string");
- return TCL_ERROR;
- }
+ case hidx_file:
+ if (objc < 3) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(iinfo->histFile, -1));
+ break;
+ }
+ if (iinfo->histFile) free(iinfo->histFile);
+ Tcl_IncrRefCount(objv[2]);
+ iinfo->histFile = Tcl_FSGetNativePath(objv[2]);
+ if (iinfo->histFile) iinfo->histFile = strdup(iinfo->histFile);
+ if (iinfo->histFile && iinfo->histFile[0])
+ history(iinfo->history, &ev, H_LOAD, iinfo->histFile);
+ Tcl_DecrRefCount(objv[2]);
+ break;
+
+ case hidx_save:
+ if (iinfo->histFile && iinfo->histFile[0])
+ history(iinfo->history, &ev, H_SAVE, iinfo->histFile);
+ break;
+
+ case hidx_size:
+ if (objc < 3) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(iinfo->histSize));
+ break;
+ }
+ if (Tcl_GetIntFromObj(interp, objv[2], &iinfo->histSize) != TCL_OK)
+ return TCL_ERROR;
- if (strcmp(Tcl_GetStringFromObj(objv[1], NULL), "add")) {
- Tcl_WrongNumArgs(interp, 1, objv, "add string");
- return TCL_ERROR;
- }
-
- string = Tcl_GetStringFromObj(objv[2], NULL);
- if (string == NULL) {
- Tcl_WrongNumArgs(interp, 1, objv, "add string");
- return TCL_ERROR;
- }
+ history(iinfo->history, &ev, H_SETSIZE, iinfo->histSize);
+ break;
+ }
- history(iinfo->history, &ev, H_ENTER, string);
- return TCL_OK;
+ return TCL_OK;
}
diff --git a/src/eltclsh.h b/src/eltclsh.h
index ffa2f1f..4465122 100644
--- a/src/eltclsh.h
+++ b/src/eltclsh.h
@@ -69,6 +69,8 @@ typedef struct ElTclInterpInfo {
int gotPartial; /* true if current command is incomplete */
int isTk; /* true if this is a Tk interpreter */
int maxCols; /* limit columns in completion output */
+ int histSize; /* history length (800) */
+ char *histFile; /* history filename (~/.eltclhistory) */
} ElTclInterpInfo;
typedef int (*ElTclAppInitProc)(Tcl_Interp *);
diff --git a/src/init.c b/src/init.c
index 029d8a3..13b9820 100644
--- a/src/init.c
+++ b/src/init.c
@@ -101,6 +101,12 @@ Eltclsh_Init(Tcl_Interp *interp)
iinfo->command = NULL;
iinfo->maxCols = 0; /* if >0, limit number of columns in completion output */
+ iinfo->histSize = 800;
+ obj = Tcl_NewStringObj("~/.eltclhistory", -1);
+ Tcl_IncrRefCount(obj);
+ iinfo->histFile = strdup(Tcl_FSGetNativePath(obj));
+ Tcl_DecrRefCount(obj);
+
if (elTclHandlersInit(iinfo) != TCL_OK) {
fputs("warning: signal facility not created\n", stdout);
}
@@ -145,7 +151,9 @@ Eltclsh_Init(Tcl_Interp *interp)
}
iinfo->history = history_init();
- history(iinfo->history, &ev, H_SETSIZE, 800);
+ history(iinfo->history, &ev, H_SETSIZE, iinfo->histSize);
+ if (iinfo->histFile && iinfo->histFile[0])
+ history(iinfo->history, &ev, H_LOAD, iinfo->histFile);
iinfo->askaHistory = history_init();
history(iinfo->askaHistory, &ev, H_SETSIZE, 100);
@@ -413,6 +421,7 @@ elTclExit(ClientData data,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
ElTclInterpInfo *iinfo = data;
+ HistEvent ev;
int value;
if ((objc != 1) && (objc != 2)) {
@@ -427,6 +436,9 @@ elTclExit(ClientData data,
}
el_end(iinfo->el);
+
+ if (iinfo->histFile && iinfo->histFile[0])
+ history(iinfo->history, &ev, H_SAVE, iinfo->histFile);
history_end(iinfo->history);
history_end(iinfo->askaHistory);