SF.net SVN: jython:[7154] trunk/jython/Lib/readline.py

[email protected] Sun, 17 Oct 2010 16:59:07 +0000
Newsgroups gmane.comp.lang.jython.cvs
Message-ID <[email protected]>
Revision: 7154
          http://jython.svn.sourceforge.net/jython/?rev=7154&view=rev
Author:   zyasoft
Date:     2010-10-17 16:59:06 +0000 (Sun, 17 Oct 2010)

Log Message:
-----------
Added support for readline.parse_and_bind('tab: complete') through
reflection, to avoid user setup issues with alternative key binding
files. This completes work on #1133. We should revisit by pushing the
features implemented by reflection on JLine into JLine itself,
however.

Modified Paths:
--------------
    trunk/jython/Lib/readline.py

Modified: trunk/jython/Lib/readline.py
===================================================================
--- trunk/jython/Lib/readline.py	2010-10-17 04:51:15 UTC (rev 7153)
+++ trunk/jython/Lib/readline.py	2010-10-17 16:59:06 UTC (rev 7154)
@@ -1,98 +1,121 @@
 from __future__ import with_statement
 import os.path
 import sys
+from warnings import warn
 
+import java.lang.reflect.Array
+
+__all__ = ['add_history', 'clear_history', 'get_begidx', 'get_completer',
+           'get_completer_delims', 'get_current_history_length',
+           'get_endidx', 'get_history_item', 'get_history_length',
+           'get_line_buffer', 'insert_text', 'parse_and_bind',
+           'read_history_file', 'read_init_file', 'redisplay',
+           'remove_history_item', 'set_completer', 'set_completer_delims',
+           'set_history_length', 'set_pre_input_hook', 'set_startup_hook',
+           'write_history_file']
+
 try:    
-    reader = sys._jy_interpreter.reader
+    _reader = sys._jy_interpreter.reader
 except AttributeError:
     raise ImportError("Cannot access JLineConsole")
 
-history_list = None
+_history_list = None
 
+# the need for these warnings should go away once we update JLine
+
+class NotImplementedWarning(UserWarning):
+    """Not yet implemented by Jython"""
+
+class SecurityWarning(UserWarning):
+    """Security manager prevents access to private field"""
+
+
 def _setup_history():
     # This is obviously not desirable, but avoids O(n) workarounds to
     # modify the history (ipython uses the function
     # remove_history_item to mutate the history relatively frequently)
-    global history_list
+    global _history_list
     
-    history = reader.history
+    history = _reader.history
     try:
         history_list_field = history.class.getDeclaredField("history")
         history_list_field.setAccessible(True)
-        history_list = history_list_field.get(history)
+        _history_list = history_list_field.get(history)
     except:
         pass
 
 _setup_history()
 
 def parse_and_bind(string):
-    # TODO this should probably reinitialize the reader, if possible
-    # with any desired settings; this will require some more work to implement
+    if string == "tab: complete":
+        try:
+            keybindings_field = _reader.class.getDeclaredField("keybindings")
+            keybindings_field.setAccessible(True)
+            keybindings = keybindings_field.get(_reader)
+            COMPLETE = _reader.KEYMAP_NAMES.get('COMPLETE')
+            if java.lang.reflect.Array.getShort(keybindings, 9) != COMPLETE:
+                java.lang.reflect.Array.setShort(keybindings, 9, COMPLETE)
+        except:
+            warn("Cannot bind tab key to complete. You need to do this in a .jlinebindings.properties file instead", SecurityWarning)
+    else:
+        warn("Cannot bind key %s. You need to do this in a .jlinebindings.properties file instead" % (string,), NotImplementedWarning)
 
-    # most importantly, need to support at least
-    # readline.parse_and_bind("tab: complete")
-    # but it's possible we can readily support other aspects of a readline file
-
-    # XXX first time through, print a warning message about the required setup
-    # with jline properties (or potentially test...)
-    pass
-
 def get_line_buffer():
-    return str(reader.cursorBuffer.buffer)
+    return str(_reader.cursorBuffer.buffer)
 
 def insert_text(string):
-    reader.putString(string)
+    _reader.putString(string)
     
 def read_init_file(filename=None):
-    print "Not implemented: read_init_file", filename
+    warn("read_init_file: %s" % (filename,), NotImplementedWarning)
 
 def read_history_file(filename="~/.history"):
     expanded = os.path.expanduser(filename)
-    new_history = reader.getHistory().getClass()()
+    new_history = _reader.getHistory().getClass()()
     with open(expanded) as f:
         for line in f:
             new_history.addToHistory(line.rstrip())
-    reader.history = new_history
+    _reader.history = new_history
     _setup_history()
 
 def write_history_file(filename="~/.history"):
     expanded = os.path.expanduser(filename)
     with open(expanded, 'w') as f:
-        for line in reader.history.historyList:
+        for line in _reader.history.historyList:
             f.write(line)
 
 def clear_history():
-    reader.history.clear()
+    _reader.history.clear()
 
 def add_history(line):
-    reader.addToHistory(line)
+    _reader.addToHistory(line)
 
 def get_history_length():
-    return reader.history.maxSize
+    return _reader.history.maxSize
 
 def set_history_length(length):
-    reader.history.maxSize = length
+    _reader.history.maxSize = length
 
 def get_current_history_length():
-    return len(reader.history.historyList)
+    return len(_reader.history.historyList)
 
 def get_history_item(index):
-    return reader.history.historyList[index]
+    return _reader.history.historyList[index]
 
 def remove_history_item(pos):
-    if history_list:
-        history_list.remove(pos)
+    if _history_list:
+        _history_list.remove(pos)
     else:
-        print "Cannot remove history item at position:", pos
+        warn("Cannot remove history item at position: %s" % (pos,), SecurityWarning)
 
 def redisplay():
-    reader.redrawLine()
+    _reader.redrawLine()
 
 def set_startup_hook(function=None):
     sys._jy_interpreter.startupHook = function
     
 def set_pre_input_hook(function=None):
-    print "Not implemented: set_pre_input_hook", function
+    warn("set_pre_input_hook %s" % (function,), NotImplementedWarning)
 
 _completer_function = None
 
@@ -121,7 +144,7 @@
                 break
         return start
 
-    reader.addCompletor(complete_handler)
+    _reader.addCompletor(complete_handler)
     
 
 def get_completer():
@@ -136,10 +159,10 @@
     return start, cursor
 
 def get_begidx():
-    return _get_delimited(str(reader.cursorBuffer.buffer), reader.cursorBuffer.cursor)[0]
+    return _get_delimited(str(_reader.cursorBuffer.buffer), _reader.cursorBuffer.cursor)[0]
 
 def get_endidx():
-    return _get_delimited(str(reader.cursorBuffer.buffer), reader.cursorBuffer.cursor)[1]
+    return _get_delimited(str(_reader.cursorBuffer.buffer), _reader.cursorBuffer.cursor)[1]
 
 def set_completer_delims(string):
     global _completer_delims, _completer_delims_set


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.

------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly 
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev