-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwidgets.py
130 lines (111 loc) · 4.76 KB
/
widgets.py
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
##############################################################################
# Copyright (c) 2012 Piotr Skamruk.
# All Rights Reserved.
#
# This software is subject to the provisions of the BSD-like license at
# https://github.com/jellonek/urwidext/blob/master/LICENSE. A copy of the
# license should accompany this distribution. THIS SOFTWARE IS PROVIDED
# "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF TITLE,
# MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE
from urwid.widget import Edit, LEFT, SPACE
class ExtendedEdit(Edit):
def __init__(self, prompt=u'', edit_text=u'',
align=LEFT, wrap=SPACE, allow_tab=False,
edit_pos=None):
if not isinstance(prompt, unicode):
prompt = unicode(prompt)
self.__super.__init__(prompt, edit_text, False, align, wrap,
allow_tab, edit_pos, None, None)
def keypress(self, size, key):
if key == 'ctrl w':
p = self.edit_pos
while self.edit_pos and self.edit_text[self.edit_pos - 1] == ' ':
self.edit_pos -= 1
try:
self.edit_pos = self.edit_text[:self.edit_pos].rindex(' ') + 1
self.set_edit_text(
self.edit_text[:self.edit_pos] + self.edit_text[p:])
except ValueError:
self.set_edit_text(self.edit_text[p:])
self.set_edit_pos(0)
elif key == 'ctrl left':
while self.edit_pos and self.edit_text[self.edit_pos - 1] == ' ':
self.edit_pos -= 1
try:
self.edit_pos = self.edit_text[:self.edit_pos].rindex(' ') + 1
except ValueError:
self.set_edit_pos(0)
elif key == 'ctrl right':
try:
while self.edit_pos < len(self.edit_text) and \
self.edit_text[self.edit_pos] == ' ':
self.edit_pos += 1
self.edit_pos = self.edit_text.index(' ', self.edit_pos)
while self.edit_pos < len(self.edit_text) and \
self.edit_text[self.edit_pos] == ' ':
self.edit_pos += 1
self._invalidate()
except ValueError:
self.set_edit_pos(self.edit_text)
elif key == 'ctrl k':
self.set_edit_text(u'')
else:
return self.__super.keypress(size, key)
return True
class CompletingEdit(ExtendedEdit):
def __init__(self, prompt=u'', edit_text=u'',
align=LEFT, wrap=SPACE, allow_tab=False,
edit_pos=None, completing_dict=None):
if not isinstance(completing_dict, dict):
# it has to be dictionary with specified values
raise ValueError()
self.completing_dict = completing_dict
self.in_multiple_completion = False
self.__super.__init__(prompt, edit_text, align, wrap,
allow_tab, edit_pos)
def keypress(self, size, key):
if key == 'tab':
if self.edit_text[:self.edit_pos].find(' ') == -1:
command = self._complete_command()
if command:
t = [command]
if not len(self.edit_text) + 1 > self.edit_pos:
t.append(' ')
t.append(self.edit_text[self.edit_pos:])
self.set_edit_text(''.join(t))
self.set_edit_pos(len(command))
else:
return self._complete_arguments()
return
else:
self.in_multiple_completion = False
return self.__super.keypress(size, key)
return True
def _complete_command(self):
command = self.edit_text[:self.edit_pos]
matches = []
for el in self.completing_dict.keys():
if el.startswith(command):
matches.append(el)
if not matches:
return
if len(matches) == 1:
return matches[0]
else:
newstart = command
while True:
try:
newstart += matches[0][len(command)]
except IndexError:
return command
for el in matches:
if not el.startswith(newstart):
self.in_multiple_completion = True
return command
command = newstart
def _complete_arguments(self):
# TODO: check which parameter is to be completed and call
# completing function for command at the begining of edit_text
# with command, param_nr, text to complete, position in this text
return True