diff options
author | Steve Bennett <steveb@workware.net.au> | 2011-12-06 08:56:35 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2011-12-09 12:10:33 +1000 |
commit | 8e90299b82be4dc6c8c86dbd206db9e0efdbffc6 (patch) | |
tree | bf75cde4346bec5000f5566cc4421703e912d53a | |
parent | a2fe8bd6794e017117986dfa11619fbf00b62239 (diff) | |
download | jimtcl-8e90299b82be4dc6c8c86dbd206db9e0efdbffc6.zip jimtcl-8e90299b82be4dc6c8c86dbd206db9e0efdbffc6.tar.gz jimtcl-8e90299b82be4dc6c8c86dbd206db9e0efdbffc6.tar.bz2 |
Add the history command
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | auto.def | 2 | ||||
-rw-r--r-- | examples/jtclsh.tcl | 36 | ||||
-rw-r--r-- | jim-history.c | 117 |
3 files changed, 155 insertions, 0 deletions
@@ -26,6 +26,7 @@ options { exec - Tcl-compatible exec command file - Tcl-compatible file command glob - Tcl-compatible glob command + history - Tcl access to interactive history readdir - Required for glob package - Package management with the package command load - Load binary extensions at runtime with load or package @@ -195,6 +196,7 @@ dict set extdb attrs { exec { static } file {} glob { tcl } + history {} load { static } mk { cpp optional } oo { tcl optional full } diff --git a/examples/jtclsh.tcl b/examples/jtclsh.tcl new file mode 100644 index 0000000..dc92bca --- /dev/null +++ b/examples/jtclsh.tcl @@ -0,0 +1,36 @@ +# Simple example of how the history extension +# can be used to provide line editing and history + +# Build jimsh with the history extension and enable line editing (the default) +# ./configure --with-ext=history + +package require history + +set histfile [env HOME]/.jtclsh +history load $histfile +while 1 { + if {[history getline "jim> " cmd] < 0} { + break + } + if {$cmd eq "h"} { + history show + continue + } + # Don't bother adding single char commands to the history + if {[string length $cmd] > 1} { + history add $cmd + history save $histfile + } + # jimsh also does: + # - check for a complete command: [info complete] + # - handle other non-error return codes and changes the prompt: [info returncodes] + # - displays the complete error message: [errorInfo] + try { + set result [eval $cmd] + if {$result ne {}} { + puts $result + } + } on error msg { + puts $msg + } +} diff --git a/jim-history.c b/jim-history.c new file mode 100644 index 0000000..d46ed7f --- /dev/null +++ b/jim-history.c @@ -0,0 +1,117 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include "jim.h" +#include "jimautoconf.h" +#include "jim-subcmd.h" + +static int history_cmd_getline(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_Obj *objPtr; + char *line = Jim_HistoryGetline(Jim_String(argv[0])); + + /* On EOF returns -1 if varName was specified, or the empty string. */ + if (line == NULL) { + if (argc == 2) { + Jim_SetResultInt(interp, -1); + } + return JIM_OK; + } + + objPtr = Jim_NewStringObjNoAlloc(interp, line, -1); + + /* Returns the length of the string if varName was specified */ + if (argc == 2) { + if (Jim_SetVariable(interp, argv[1], objPtr) != JIM_OK) { + Jim_FreeNewObj(interp, objPtr); + return JIM_ERR; + } + Jim_SetResultInt(interp, Jim_Length(objPtr)); + } + else { + Jim_SetResult(interp, objPtr); + } + return JIM_OK; +} + +static int history_cmd_load(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_HistoryLoad(Jim_String(argv[0])); + return JIM_OK; +} + +static int history_cmd_save(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_HistorySave(Jim_String(argv[0])); + return JIM_OK; +} + +static int history_cmd_add(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_HistoryAdd(Jim_String(argv[0])); + return JIM_OK; +} + +static int history_cmd_show(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_HistoryShow(); + return JIM_OK; +} + +static const jim_subcmd_type history_command_table[] = { + { "getline", + "prompt ?varname?", + history_cmd_getline, + 1, + 2, + /* Description: Reads one line from the user. Similar to gets. */ + }, + { "load", + "filename", + history_cmd_load, + 1, + 1, + /* Description: Loads history from the given file, if possible */ + }, + { "save", + "filename", + history_cmd_save, + 1, + 1, + /* Description: Saves history to the given file */ + }, + { "add", + "line", + history_cmd_add, + 1, + 1, + /* Description: Adds the line to the history ands saves */ + }, + { "show", + NULL, + history_cmd_show, + 0, + 0, + /* Description: Displays the history */ + }, + { NULL } +}; + +static int JimHistorySubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp, history_command_table, argc, argv), argc, argv); +} + +int Jim_historyInit(Jim_Interp *interp) +{ + void **history; + if (Jim_PackageProvide(interp, "history", "1.0", JIM_ERRMSG)) + return JIM_ERR; + + history = Jim_Alloc(sizeof(*history)); + *history = NULL; + + Jim_CreateCommand(interp, "history", JimHistorySubCmdProc, history, NULL); + return JIM_OK; +} |