[cura-tools] master: introduce history with tab-completion in lmi-shell.py (78f9596)
by phatina@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/cura-tools.git
On branch : master
>---------------------------------------------------------------
commit 78f9596114c1555445721e9e459905d982fa655e
Author: Peter Hatina <phatina(a)redhat.com>
Date: Tue Oct 30 23:38:07 2012 +0100
introduce history with tab-completion in lmi-shell.py
>---------------------------------------------------------------
cli-tools/lmi-shell.py | 90 +++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 86 insertions(+), 4 deletions(-)
diff --git a/cli-tools/lmi-shell.py b/cli-tools/lmi-shell.py
index 9ee8d51..6a6d1bd 100755
--- a/cli-tools/lmi-shell.py
+++ b/cli-tools/lmi-shell.py
@@ -17,7 +17,75 @@
import os
import sys
import code
+import atexit
+import readline
+import rlcompleter
from lmi.lmi_client_shell import LmiConnection
+from lmi.lmi_client_shell import _LmiNamespace
+from lmi.lmi_client_shell import _LmiClass
+from lmi.lmi_client_shell import _LmiInstance
+
+class _LmiCompleter(rlcompleter.Completer):
+ def __init__(self, namespace = None):
+ rlcompleter.Completer.__init__(self, namespace)
+
+ def __fetchClasses(self, client, expr):
+ namespace = expr.name.split("/")[-1]
+ if self.m_cache[client][namespace].classes:
+ return
+ result = {}
+ classes = expr.classes()
+ for c in classes:
+ result[c] = _LmiCompleterClassCache()
+ self.m_cache[client][namespace].classes = result
+
+ def __completeObjectMethods(self, obj, text):
+ result = filter(lambda m: not m.startswith("_") \
+ and callable(getattr(obj, m)) \
+ and m.lower().startswith(text.lower()), dir(obj))
+ return result
+
+ def _callable_postfix(self, val, word):
+ if hasattr(val, '__call__'):
+ word = word + "("
+ return word
+
+ def complete(self, text, state):
+ if not text:
+ return ("\t", None)[state]
+
+ matches = []
+ members = text.split(".")
+ if members[0] in self.namespace:
+ cmd = ".".join(members[0:-1])
+ to_complete = members[-1]
+ expr = eval(cmd, self.namespace)
+ if isinstance(expr, LmiConnection):
+ namespaces = expr.namespaces()
+ for n in namespaces:
+ if n.lower().startswith(to_complete.lower()):
+ matches.append(cmd + "." + n)
+ return matches[state]
+ elif isinstance(expr, _LmiNamespace):
+ for c in expr.classes():
+ if c.lower().startswith(to_complete.lower()):
+ matches.append(cmd + "." + c)
+ return matches[state]
+ elif isinstance(expr, _LmiClass):
+ methods = self.__completeObjectMethods(expr, to_complete)
+ matches = [cmd + "." + m + "(" for m in methods]
+ return matches[state]
+ elif isinstance(expr, _LmiInstance):
+ for m in expr.methods():
+ if m.lower().startswith(to_complete.lower()):
+ matches.append(cmd + "." + m + "(")
+ for p in expr.properties():
+ if p.lower().startswith(to_complete.lower()):
+ matches.append(cmd + "." + p)
+ methods = self.__completeObjectMethods(expr, to_complete)
+ matches.extend(cmd + "." + m for m in methods)
+ return matches[state]
+ return rlcompleter.Completer.complete(self, text, state)
class LmiInteractiveShell(code.InteractiveConsole):
def __init__(self, prompt, more_prompt, locals = None):
@@ -27,9 +95,15 @@ class LmiInteractiveShell(code.InteractiveConsole):
locals = {}
locals["LmiConnection"] = LmiConnection
locals["connect"] = _connect
+ locals["clear_history"] = self.clearHistory
code.InteractiveConsole.__init__(self, locals)
+ self.m_completer = _LmiCompleter(self.locals)
+ self.m_history_path = os.path.expanduser("~/.lmi_shell_history")
+ readline.set_completer(self.m_completer.complete)
+ readline.parse_and_bind('tab: complete')
def interact(self):
+ self.loadHistory()
try:
sys.ps1
except AttributeError:
@@ -60,13 +134,21 @@ class LmiInteractiveShell(code.InteractiveConsole):
self.write("\n")
self.resetbuffer()
more = 0
+ self.saveHistory()
+
+ def loadHistory(self):
+ if not os.path.exists(self.m_history_path):
+ return
+ readline.read_history_file(self.m_history_path)
+
+ def saveHistory(self):
+ readline.write_history_file(self.m_history_path)
+
+ def clearHistory(self):
+ readline.clear_history()
def _lmi_interact(prompt = "> ", more_prompt = "... "):
console = LmiInteractiveShell(prompt, more_prompt)
- try:
- import readline
- except ImportError:
- pass
console.interact()
def _connect(hostname, username = "", password = ""):