File: readline.py

package info (click to toggle)
jython 2.5.3-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 43,304 kB
  • sloc: python: 351,314; java: 216,338; xml: 1,547; sh: 330; perl: 124; ansic: 102; makefile: 101
file content (181 lines) | stat: -rw-r--r-- 5,885 bytes parent folder | download | duplicates (4)
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`~!@#$%^&*()-=+[{]}\\|;:\'",<>/?')