1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 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`~!@#$%^&*()-=+[{]}\\|;:\'",<>/?')
|