From 5a5535aa5b864662cc6f0cc915f929c6fa7176ca Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 5 Oct 2023 14:12:25 -0700 Subject: [PATCH] iocsh: keep history file --- .gitignore | 1 + modules/libcom/src/iocsh/iocsh.cpp | 37 ++++++++++++++++++++++++++++++ src/template/base/top/.gitignore | 3 +++ src/template/ext/top/.gitignore | 3 +++ 4 files changed, 44 insertions(+) diff --git a/.gitignore b/.gitignore index b7a25673a..46b32dc1a 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ O.*/ *.log .*.swp .DS_Store +.iocsh_history diff --git a/modules/libcom/src/iocsh/iocsh.cpp b/modules/libcom/src/iocsh/iocsh.cpp index 29c104ef6..53ffa1bb8 100644 --- a/modules/libcom/src/iocsh/iocsh.cpp +++ b/modules/libcom/src/iocsh/iocsh.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,7 @@ #if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_READLINE # include +# include # define USE_READLINE /* libedit also provides readline.h, but isn't fully compatible with * GNU readline. It also doesn't specifically identify itself. @@ -637,6 +639,15 @@ struct ReadlineContext { rl_completer_quote_characters = (char*)"\""; rl_attempted_completion_function = &iocsh_attempt_completion; rl_bind_key('\t', rl_complete); + compute_hist_file(); + if(!hist_file.empty()) { + if(int err = read_history(hist_file.c_str())) { + if(err!=ENOENT) + fprintf(stderr, "Error %s (%d) loading '%s'\n", + strerror(err), err, hist_file.c_str()); + } + stifle_history(1024); // some limit... + } } #endif return context; @@ -645,6 +656,12 @@ struct ReadlineContext { ~ReadlineContext() { if(context) { #ifdef USE_READLINE + if(!hist_file.empty()) { + if(int err = write_history(hist_file.c_str())) { + fprintf(stderr, "Error %s (%d) writing '%s'\n", + strerror(err), err, hist_file.c_str()); + } + } rl_readline_name = prev_rl_readline_name; rl_basic_word_break_characters = prev_rl_basic_word_break_characters; rl_completer_word_break_characters = prev_rl_completer_word_break_characters; @@ -657,6 +674,26 @@ struct ReadlineContext { epicsReadlineEnd(context); } } + +#ifdef USE_READLINE + std::string hist_file; + + void compute_hist_file() { + std::string scratch; + if(const char *env = getenv("EPICS_IOCSH_HISTFILE")) { + scratch = env; + } else { + scratch = ".iocsh_history"; + } + const char *home = getenv("HOME"); + if(home && scratch.size()>=2 && scratch[0]=='~' && scratch[1]=='/') { + std::ostringstream strm; + strm<