diff options
author | Anthony Mallet <anthony.mallet@laas.fr> | 2011-11-02 10:57:48 +0100 |
---|---|---|
committer | Anthony Mallet <anthony.mallet@laas.fr> | 2011-11-02 10:57:48 +0100 |
commit | e078e252287041be13600c563db07e830ff2440d (patch) | |
tree | 6ef4ef4781dfe0a6379ee5a07fcb3d708b07d242 | |
parent | 5e680a041fd4b697cad4cf3575ec0695dea0c429 (diff) | |
download | eltclsh-e078e252287041be13600c563db07e830ff2440d.tar.gz |
Add history load/save feature
-rw-r--r-- | CHANGELOG | 7 | ||||
-rw-r--r-- | eltclsh.1 | 30 | ||||
-rw-r--r-- | src/el.c | 83 | ||||
-rw-r--r-- | src/eltclsh.h | 2 | ||||
-rw-r--r-- | src/init.c | 14 |
5 files changed, 113 insertions, 23 deletions
@@ -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 @@ -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 . @@ -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 *); @@ -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); |