From: <zy...@us...> - 2010-10-16 05:12:24
|
Revision: 7150 http://jython.svn.sourceforge.net/jython/?rev=7150&view=rev Author: zyasoft Date: 2010-10-16 05:12:18 +0000 (Sat, 16 Oct 2010) Log Message: ----------- Hardened completion sso it doesn't fail on missing symbols. Modified Paths: -------------- trunk/jython/Lib/readline.py Modified: trunk/jython/Lib/readline.py =================================================================== --- trunk/jython/Lib/readline.py 2010-10-16 03:07:47 UTC (rev 7149) +++ trunk/jython/Lib/readline.py 2010-10-16 05:12:18 UTC (rev 7150) @@ -1,30 +1,17 @@ -""" Emulate module 'readline' from CPython. -We are using the JavaReadline JNI wrapper for GNU readline. - -2004-10-27, mar...@rw... - -""" - from __future__ import with_statement import os.path import sys -# XXX move to _jline_readline.py, just like our _gnu_readline.py (which is orphaned) -# then simply try successive imports to see what is installed - -# XXX what's oru character encoding issues here, if any? - try: reader = sys._jy_interpreter.reader - #from JLine import Completor except AttributeError: raise ImportError("Cannot access JLineConsole") def parse_and_bind(string): - # XXX this should probably reinitialize the reader, if possible + # TODO this should probably reinitialize the reader, if possible # with any desired settings; this will require some more work to implement - # most importantly, need to support + # 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 pass @@ -68,33 +55,39 @@ return reader.history.historyList[index] def remove_history_item(pos): + # TODO possible? raise Exception("not implemented") def redisplay(): - reader.drawLine() # XXX not certain + reader.redrawLine() def set_startup_hook(function=None): + # TODO add pass def set_pre_input_hook(function=None): + # TODO add pass _completion_function = None def set_completer(function=None): - # XXX single method interface, http://jline.sourceforge.net/apidocs/jline/Completor.html - # just need to figure out what's necessary to adapt to Python's convention, - # but it should be fine :) + """set_completer([function]) -> None + Set or remove the completer function. + The function is called as function(text, state), + for state in 0, 1, 2, ..., until it returns a non-string. + It should return the next possible completion starting with 'text'.""" - """The completer method is called as completerclass.completer(text, state), for state in 0, 1, 2, ..., - until it returns a non-string value. It should return the next possible completion starting with text.""" - _completion_function = function def complete_handler(buffer, cursor, candidates): - for state in xrange(100): - completion = function(buffer[:cursor], state) + for state in xrange(100): # TODO arbitrary, what's the number used by gnu readline? + completion = None + try: + completion = function(buffer[:cursor], state) + except: + pass if completion: candidates.add(completion) else: @@ -108,9 +101,11 @@ return _completion_function def get_begidx(): + # TODO add pass def get_endidx(): + # TODO add pass def set_completer_delims(string): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2010-10-17 16:59:42
|
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. |
From: <zy...@us...> - 2010-10-22 03:02:02
|
Revision: 7164 http://jython.svn.sourceforge.net/jython/?rev=7164&view=rev Author: zyasoft Date: 2010-10-22 03:01:56 +0000 (Fri, 22 Oct 2010) Log Message: ----------- More fixes of readline to support ipython Modified Paths: -------------- trunk/jython/Lib/readline.py Modified: trunk/jython/Lib/readline.py =================================================================== --- trunk/jython/Lib/readline.py 2010-10-22 01:40:30 UTC (rev 7163) +++ trunk/jython/Lib/readline.py 2010-10-22 03:01:56 UTC (rev 7164) @@ -21,12 +21,15 @@ _history_list = None -# the need for these warnings should go away once we update JLine +# The need for the following warnings should go away once we update +# JLine. Choosing ImportWarning as the closest warning to what is +# going on here, namely this is functionality not yet available on +# Jython. -class NotImplementedWarning(UserWarning): +class NotImplementedWarning(ImportWarning): """Not yet implemented by Jython""" -class SecurityWarning(UserWarning): +class SecurityWarning(ImportWarning): """Security manager prevents access to private field""" @@ -56,9 +59,9 @@ 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) + warn("Cannot bind tab key to complete. You need to do this in a .jlinebindings.properties file instead", SecurityWarning, stacklevel=2) else: - warn("Cannot bind key %s. You need to do this in a .jlinebindings.properties file instead" % (string,), NotImplementedWarning) + warn("Cannot bind key %s. You need to do this in a .jlinebindings.properties file instead" % (string,), NotImplementedWarning, stacklevel=2) def get_line_buffer(): return str(_reader.cursorBuffer.buffer) @@ -67,11 +70,13 @@ _reader.putString(string) def read_init_file(filename=None): - warn("read_init_file: %s" % (filename,), NotImplementedWarning) + warn("read_init_file: %s" % (filename,), NotImplementedWarning, "module", 2) def read_history_file(filename="~/.history"): + print "Reading history:", filename expanded = os.path.expanduser(filename) new_history = _reader.getHistory().getClass()() + # new_history.clear() with open(expanded) as f: for line in f: new_history.addToHistory(line.rstrip()) @@ -83,6 +88,7 @@ with open(expanded, 'w') as f: for line in _reader.history.historyList: f.write(line) + f.write("\n") def clear_history(): _reader.history.clear() @@ -106,7 +112,7 @@ if _history_list: _history_list.remove(pos) else: - warn("Cannot remove history item at position: %s" % (pos,), SecurityWarning) + warn("Cannot remove history item at position: %s" % (pos,), SecurityWarning, stacklevel=2) def redisplay(): _reader.redrawLine() @@ -115,7 +121,7 @@ sys._jy_interpreter.startupHook = function def set_pre_input_hook(function=None): - warn("set_pre_input_hook %s" % (function,), NotImplementedWarning) + warn("set_pre_input_hook %s" % (function,), NotImplementedWarning, stacklevel=2) _completer_function = None This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-12-24 23:27:30
|
Revision: 7179 http://jython.svn.sourceforge.net/jython/?rev=7179&view=rev Author: pjenvey Date: 2010-12-24 23:27:23 +0000 (Fri, 24 Dec 2010) Log Message: ----------- dos2unix Modified Paths: -------------- trunk/jython/Lib/readline.py Modified: trunk/jython/Lib/readline.py =================================================================== --- trunk/jython/Lib/readline.py 2010-12-24 23:23:05 UTC (rev 7178) +++ trunk/jython/Lib/readline.py 2010-12-24 23:27:23 UTC (rev 7179) @@ -1,181 +1,181 @@ -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 -except AttributeError: - raise ImportError("Cannot access JLineConsole") - -_history_list = None - -# The need for the following warnings should go away once we update -# JLine. Choosing ImportWarning as the closest warning to what is -# going on here, namely this is functionality not yet available on -# Jython. - -class NotImplementedWarning(ImportWarning): - """Not yet implemented by Jython""" - -class SecurityWarning(ImportWarning): - """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 - - history = _reader.history - try: - history_list_field = history.class.getDeclaredField("history") - history_list_field.setAccessible(True) - _history_list = history_list_field.get(history) - except: - pass - -_setup_history() - -def parse_and_bind(string): - 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, stacklevel=2) - else: - warn("Cannot bind key %s. You need to do this in a .jlinebindings.properties file instead" % (string,), NotImplementedWarning, stacklevel=2) - -def get_line_buffer(): - return str(_reader.cursorBuffer.buffer) - -def insert_text(string): - _reader.putString(string) - -def read_init_file(filename=None): - warn("read_init_file: %s" % (filename,), NotImplementedWarning, "module", 2) - -def read_history_file(filename="~/.history"): - print "Reading history:", filename - expanded = os.path.expanduser(filename) - new_history = _reader.getHistory().getClass()() - # new_history.clear() - with open(expanded) as f: - for line in f: - new_history.addToHistory(line.rstrip()) - _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: - f.write(line) - f.write("\n") - -def clear_history(): - _reader.history.clear() - -def add_history(line): - _reader.addToHistory(line) - -def get_history_length(): - return _reader.history.maxSize - -def set_history_length(length): - _reader.history.maxSize = length - -def get_current_history_length(): - return len(_reader.history.historyList) - -def get_history_item(index): - return _reader.history.historyList[index] - -def remove_history_item(pos): - if _history_list: - _history_list.remove(pos) - else: - warn("Cannot remove history item at position: %s" % (pos,), SecurityWarning, stacklevel=2) - -def redisplay(): - _reader.redrawLine() - -def set_startup_hook(function=None): - sys._jy_interpreter.startupHook = function - -def set_pre_input_hook(function=None): - warn("set_pre_input_hook %s" % (function,), NotImplementedWarning, stacklevel=2) - -_completer_function = None - -def set_completer(function=None): - """set_completer([function]) -> None - Set or remove the completer function. - The function is called as function(text, state), - for state in 0, 1, 2, ..., until it returns a non-string. - It should return the next possible completion starting with 'text'.""" - - global _completer_function - _completer_function = function - - def complete_handler(buffer, cursor, candidates): - start = _get_delimited(buffer, cursor)[0] - delimited = buffer[start:cursor] - for state in xrange(100): # TODO arbitrary, what's the number used by gnu readline? - completion = None - try: - completion = function(delimited, state) - except: - pass - if completion: - candidates.add(completion) - else: - break - return start - - _reader.addCompletor(complete_handler) - - -def get_completer(): - return _completer_function - -def _get_delimited(buffer, cursor): - start = cursor - for i in xrange(cursor-1, -1, -1): - if buffer[i] in _completer_delims: - break - start = i - return start, cursor - -def get_begidx(): - 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] - -def set_completer_delims(string): - global _completer_delims, _completer_delims_set - _completer_delims = string - _completer_delims_set = set(string) - -def get_completer_delims(): - return _completer_delims - -set_completer_delims(' \t\n`~!@#$%^&*()-=+[{]}\\|;:\'",<>/?') +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 +except AttributeError: + raise ImportError("Cannot access JLineConsole") + +_history_list = None + +# The need for the following warnings should go away once we update +# JLine. Choosing ImportWarning as the closest warning to what is +# going on here, namely this is functionality not yet available on +# Jython. + +class NotImplementedWarning(ImportWarning): + """Not yet implemented by Jython""" + +class SecurityWarning(ImportWarning): + """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 + + history = _reader.history + try: + history_list_field = history.class.getDeclaredField("history") + history_list_field.setAccessible(True) + _history_list = history_list_field.get(history) + except: + pass + +_setup_history() + +def parse_and_bind(string): + 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, stacklevel=2) + else: + warn("Cannot bind key %s. You need to do this in a .jlinebindings.properties file instead" % (string,), NotImplementedWarning, stacklevel=2) + +def get_line_buffer(): + return str(_reader.cursorBuffer.buffer) + +def insert_text(string): + _reader.putString(string) + +def read_init_file(filename=None): + warn("read_init_file: %s" % (filename,), NotImplementedWarning, "module", 2) + +def read_history_file(filename="~/.history"): + print "Reading history:", filename + expanded = os.path.expanduser(filename) + new_history = _reader.getHistory().getClass()() + # new_history.clear() + with open(expanded) as f: + for line in f: + new_history.addToHistory(line.rstrip()) + _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: + f.write(line) + f.write("\n") + +def clear_history(): + _reader.history.clear() + +def add_history(line): + _reader.addToHistory(line) + +def get_history_length(): + return _reader.history.maxSize + +def set_history_length(length): + _reader.history.maxSize = length + +def get_current_history_length(): + return len(_reader.history.historyList) + +def get_history_item(index): + return _reader.history.historyList[index] + +def remove_history_item(pos): + if _history_list: + _history_list.remove(pos) + else: + warn("Cannot remove history item at position: %s" % (pos,), SecurityWarning, stacklevel=2) + +def redisplay(): + _reader.redrawLine() + +def set_startup_hook(function=None): + sys._jy_interpreter.startupHook = function + +def set_pre_input_hook(function=None): + warn("set_pre_input_hook %s" % (function,), NotImplementedWarning, stacklevel=2) + +_completer_function = None + +def set_completer(function=None): + """set_completer([function]) -> None + Set or remove the completer function. + The function is called as function(text, state), + for state in 0, 1, 2, ..., until it returns a non-string. + It should return the next possible completion starting with 'text'.""" + + global _completer_function + _completer_function = function + + def complete_handler(buffer, cursor, candidates): + start = _get_delimited(buffer, cursor)[0] + delimited = buffer[start:cursor] + for state in xrange(100): # TODO arbitrary, what's the number used by gnu readline? + completion = None + try: + completion = function(delimited, state) + except: + pass + if completion: + candidates.add(completion) + else: + break + return start + + _reader.addCompletor(complete_handler) + + +def get_completer(): + return _completer_function + +def _get_delimited(buffer, cursor): + start = cursor + for i in xrange(cursor-1, -1, -1): + if buffer[i] in _completer_delims: + break + start = i + return start, cursor + +def get_begidx(): + 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] + +def set_completer_delims(string): + global _completer_delims, _completer_delims_set + _completer_delims = string + _completer_delims_set = set(string) + +def get_completer_delims(): + return _completer_delims + +set_completer_delims(' \t\n`~!@#$%^&*()-=+[{]}\\|;:\'",<>/?') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |