diff options
author | Michal Minar <miminar@redhat.com> | 2014-03-21 11:50:01 +0100 |
---|---|---|
committer | Michal Minar <miminar@redhat.com> | 2014-03-21 11:50:48 +0100 |
commit | ce3000607483a2a93939f8cc17ce6c1ff661f243 (patch) | |
tree | e4b45bef38c5553015f8ca4bc6469fbf1565383f | |
parent | 58dcb655301a74112f2bce7bae93dc89b55921f5 (diff) | |
download | openlmi-scripts-ce3000607483a2a93939f8cc17ce6c1ff661f243.tar.gz openlmi-scripts-ce3000607483a2a93939f8cc17ce6c1ff661f243.tar.xz openlmi-scripts-ce3000607483a2a93939f8cc17ce6c1ff661f243.zip |
use history file
History file is now written on lmi's exit and read on its startup.
Applies just to interactive mode.
-rw-r--r-- | config/lmi.conf | 3 | ||||
-rw-r--r-- | lmi/scripts/_metacommand/interactive.py | 43 | ||||
-rw-r--r-- | lmi/scripts/_metacommand/toplevel.py | 8 | ||||
-rw-r--r-- | lmi/scripts/common/configuration.py | 13 |
4 files changed, 65 insertions, 2 deletions
diff --git a/config/lmi.conf b/config/lmi.conf index 1144e5a..6b35fc8 100644 --- a/config/lmi.conf +++ b/config/lmi.conf @@ -16,6 +16,9 @@ # stdout. #Verbosity = 0 +# Maximum number of lines stored in history file. +#HistoryMaxLength = 4000 + [CIM] # To override default CIM namespace, uncomment the line below. #namespace = root/cimv2 diff --git a/lmi/scripts/_metacommand/interactive.py b/lmi/scripts/_metacommand/interactive.py index f2b327c..349d622 100644 --- a/lmi/scripts/_metacommand/interactive.py +++ b/lmi/scripts/_metacommand/interactive.py @@ -35,6 +35,7 @@ import cmd import docopt import itertools import os +import readline import shlex from lmi.scripts.common import errors @@ -90,6 +91,7 @@ class Interactive(cmd.Cmd): self._last_exit_code = exit.EXIT_CODE_SUCCESS self.doc_header = 'Static commands' self.app.active_command = top_level_cmd + self.load_history() # ************************************************************************* # Properties @@ -253,6 +255,10 @@ class Interactive(cmd.Cmd): if not text or n.startswith(text)) return completions + def clear_history(self): + """ Clear readline history. """ + readline.clear_history() + def default(self, line): """ This is run, when line contains unknown command to ``cmd.Cmd``. It @@ -392,6 +398,26 @@ class Interactive(cmd.Cmd): finally: self.app.active_command = cur_node + def load_history(self): + """ + Load a readline history file. + """ + if ( self.app.config.history_max_length == 0 + or not os.path.exists(self.app.config.history_file)): + return + LOG().debug('Reading history file "%s"', self.app.config.history_file) + try: + readline.read_history_file(self.app.config.history_file) + if ( self.app.config.history_max_length > 0 + and readline.get_current_history_length() + > self.app.config.history_max_length): + readline.set_history_length(self.app.config.history_max_length) + readline.write_history_file(self.app.config.history_file) + readline.read_history_file(self.app.config.history_file) + except (IOError, OSError) as err: + LOG().warn('Failed to read history file "%s".', + self.app.config.history_file, exc_info=err) + def postcmd(self, stop, _line): """ This is called after the ``do_*`` command to postprocess its result and @@ -430,3 +456,20 @@ class Interactive(cmd.Cmd): raise cmd_inst = cmd_factory(self.app, args[0], parent) return cmd_inst.run(args[1:]) + + def save_history(self): + """ + Saves current history of commands into the history file. If the length + of history exceeds a maximum history file length, the history will be + truncated. + """ + if self.app.config.history_max_length != 0: + LOG().debug('Writing history file "%s"', + self.app.config.history_file) + if self.app.config.history_max_length > 0: + readline.set_history_length(self.app.config.history_max_length) + try: + readline.write_history_file(self.app.config.history_file) + except (IOError, OSError), err: + LOG().warn('Failed to write history file "%s".', + self.app.config.history_file, exc_info=err) diff --git a/lmi/scripts/_metacommand/toplevel.py b/lmi/scripts/_metacommand/toplevel.py index 29d257b..1e654a3 100644 --- a/lmi/scripts/_metacommand/toplevel.py +++ b/lmi/scripts/_metacommand/toplevel.py @@ -131,12 +131,16 @@ class TopLevelCommand(base.LmiBaseCommand): iapp = Interactive(self) while True: try: - return iapp.cmdloop() + ret = iapp.cmdloop() + break except errors.LmiTerminate as err: - return err.args[0] + ret = err.args[0] + break except KeyboardInterrupt as err: LOG().debug('%s: %s', err.__class__.__name__, str(err)) self.app.stdout.write('\n') + iapp.save_history() + return ret def run(self, args): """ diff --git a/lmi/scripts/common/configuration.py b/lmi/scripts/common/configuration.py index d2efb5e..97ebebe 100644 --- a/lmi/scripts/common/configuration.py +++ b/lmi/scripts/common/configuration.py @@ -58,6 +58,7 @@ class Configuration(BaseConfiguration): """ USER_CONFIG_FILE_PATH = "~/.lmirc" + HISTORY_FILE = "~/.lmi_history" OUTPUT_SILENT = -1 OUTPUT_WARNING = 0 @@ -79,6 +80,7 @@ class Configuration(BaseConfiguration): self._lister_format = None self._no_headings = None self._log_file = None + self._history_max_length = None @classmethod def provider_prefix(cls): @@ -95,6 +97,7 @@ class Configuration(BaseConfiguration): defaults["CommandNamespace"] = 'lmi.scripts.cmd' defaults["Trace"] = "False" defaults["Verbosity"] = "0" + defaults["HistoryMaxLength"] = "4000" # [Log] options defaults['ConsoleFormat'] = DEFAULT_FORMAT_STRING defaults['ConsoleInfoFormat'] = '%(message)s' @@ -141,6 +144,16 @@ class Configuration(BaseConfiguration): # [Main] options # ************************************************************************* @property + def history_file(self): + """ Path to a file with history of interactive mode. """ + return os.path.expanduser(self.HISTORY_FILE) + + @property + def history_max_length(self): + """ Maximum number of lines kept in history file. """ + return self.get_safe('Main', 'HistoryMaxLength', int) + + @property def silent(self): """ Whether to suppress all output messages except for errors. """ return self.verbosity <= self.OUTPUT_SILENT |