summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Minar <miminar@redhat.com>2014-03-21 11:50:01 +0100
committerMichal Minar <miminar@redhat.com>2014-03-21 11:50:48 +0100
commitce3000607483a2a93939f8cc17ce6c1ff661f243 (patch)
treee4b45bef38c5553015f8ca4bc6469fbf1565383f
parent58dcb655301a74112f2bce7bae93dc89b55921f5 (diff)
downloadopenlmi-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.conf3
-rw-r--r--lmi/scripts/_metacommand/interactive.py43
-rw-r--r--lmi/scripts/_metacommand/toplevel.py8
-rw-r--r--lmi/scripts/common/configuration.py13
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