From d567653db0e8cedc28fa84816be27623b0f72793 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Mon, 5 Feb 2007 16:03:44 +0000 Subject: [PATCH] Shell: added command line editing with history (#232374); exit on EOF (#230211, #235709). --- doc/zypper.8 | 5 ++++- package/zypper.changes | 6 ++++++ src/Makefile.am | 2 +- src/zypper.cc | 53 +++++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/doc/zypper.8 b/doc/zypper.8 index 3d9a4d7..a369118 100644 --- a/doc/zypper.8 +++ b/doc/zypper.8 @@ -20,7 +20,7 @@ zypper provides a number of \fBcommands\fR. Each command accepts the option flag .TP .B shell (sh) Starts a shell for entering multiple commands in one session. -(NEW, beware of bugs!) +End it by "exit", "quit", or Ctrl-D. .LP .B Package Management Commands @@ -253,6 +253,9 @@ Operates on a different root directory. .TP .B /var/lib/zypp/cache Directory for storing metadata contained in installation sources. +.TP +.B ~/.zypper_history +Command history for the shell. .SH "EXIT CODES" .LP diff --git a/package/zypper.changes b/package/zypper.changes index f1c3c71..7edf828 100644 --- a/package/zypper.changes +++ b/package/zypper.changes @@ -1,4 +1,10 @@ ------------------------------------------------------------------- +Mon Feb 5 17:00:25 CET 2007 - mvidner@suse.cz + +- Shell: added command line editing with history (#232374); + exit on EOF (#230211, #235709). + +------------------------------------------------------------------- Fri Feb 2 13:29:27 CET 2007 - jkupec@suse.cz - Non-interactive mode turns on --skip-interactive as well diff --git a/src/Makefile.am b/src/Makefile.am index 2c6858d..e371876 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -61,7 +61,7 @@ zypper_SOURCES = zypper.cc zmart-sources.cc zmart-misc.cc \ zypper-getopt.h \ zypper-getopt.cc \ zmart.h -zypper_LDADD = $(ZYPP_LIBS) -lboost_regex +zypper_LDADD = $(ZYPP_LIBS) -lboost_regex -lreadline if BUILD_CHECKPATCHES zypp_checkpatches_SOURCES = zypp-checkpatches.cc zmart-sources.cc \ diff --git a/src/zypper.cc b/src/zypper.cc index ff72a26..9c1f930 100644 --- a/src/zypper.cc +++ b/src/zypper.cc @@ -15,6 +15,8 @@ #include #include +#include +#include #include "zmart.h" #include "zmart-sources.h" @@ -466,7 +468,8 @@ int one_command(const string& command, int argc, char **argv) ); } else if (!command.empty()) { // empty command is treated earlier - cerr << _("Unknown command") << " '" << command << "'." << endl << endl; + if (command != "help") // #235709 + cerr << _("Unknown command") << " '" << command << "'." << endl << endl; cerr << help_commands; return ZYPPER_EXIT_ERR_SYNTAX; } @@ -952,13 +955,51 @@ int safe_one_command(const string& command, int argc, char **argv) return ret; } +// Read a string. "\004" (^D) on EOF. +string readline_getline () +{ + // A static variable for holding the line. + static char *line_read = NULL; + + /* If the buffer has already been allocated, + return the memory to the free pool. */ + if (line_read) { + free (line_read); + line_read = NULL; + } + + /* Get a line from the user. */ + line_read = readline ("zypper> "); + + /* If the line has any text in it, + save it on the history. */ + if (line_read && *line_read) + add_history (line_read); + + if (line_read) + return line_read; + else + return "\004"; +} + void command_shell () { + string histfile; + try { + Pathname p (getenv ("HOME")); + p /= ".zypper_history"; + histfile = p.asString (); + } catch (...) { + // no history + } + using_history (); + if (!histfile.empty ()) + read_history (histfile.c_str ()); + bool loop = true; while (loop) { // read a line - cerr << "zypper> " << flush; - string line = zypp::str::getline (cin); + string line = readline_getline (); cerr_vv << "Got: " << line << endl; // reset optind etc optind = 0; @@ -968,13 +1009,15 @@ void command_shell () char **sh_argv = args.argv (); string command = sh_argv[0]? sh_argv[0]: ""; - // TODO check empty command - if (command == "exit") + if (command == "exit" || command == "quit" || command == "\004") loop = false; else safe_one_command (command, sh_argc, sh_argv); } + + if (!histfile.empty ()) + write_history (histfile.c_str ()); } int main(int argc, char **argv) -- 2.7.4