Skip to content

Commit 9d4308d

Browse files
committed
More compiled regular expressions and less lists
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
1 parent be5b8fb commit 9d4308d

File tree

1 file changed

+34
-14
lines changed

1 file changed

+34
-14
lines changed

bpython/curtsiesfrontend/manual_readline.py

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
and the cursor location
55
based on http://www.bigsmoke.us/readline/shortcuts"""
66

7-
import re
7+
from bpython.lazyre import LazyReCompile
88
import inspect
99

1010
INDENT = 4
@@ -73,6 +73,7 @@ def __delitem__(self, key):
7373
elif key in self.cut_buffer_edits: del self.cut_buffer_edits[key]
7474
else: raise KeyError("key %r not mapped" % (key,))
7575

76+
7677
class UnconfiguredEdits(AbstractEdits):
7778
"""Maps key to edit functions, and bins them by what parameters they take.
7879
@@ -114,6 +115,7 @@ def add_to_config(func):
114115
return func
115116
return add_to_config
116117

118+
117119
class ConfiguredEdits(AbstractEdits):
118120
def __init__(self, simple_edits, cut_buffer_edits, awaiting_config, config, key_dispatch):
119121
self.simple_edits = dict(simple_edits)
@@ -128,6 +130,7 @@ def add_config_attr(self, config_attr, func):
128130
def add(self, key, func):
129131
raise NotImplementedError("Config already set on this mapping")
130132

133+
131134
edit_keys = UnconfiguredEdits()
132135

133136
# Because the edits.on decorator runs the functions, functions which depend
@@ -161,19 +164,21 @@ def beginning_of_line(cursor_offset, line):
161164
def end_of_line(cursor_offset, line):
162165
return len(line), line
163166

167+
168+
forward_word_re = LazyReCompile(r"\S\s")
169+
170+
164171
@edit_keys.on('<Esc+f>')
165172
@edit_keys.on('<Ctrl-RIGHT>')
166173
@edit_keys.on('<Esc+RIGHT>')
167174
def forward_word(cursor_offset, line):
168-
patt = r"\S\s"
169-
match = re.search(patt, line[cursor_offset:]+' ')
175+
match = forward_word_re.search(line[cursor_offset:]+' ')
170176
delta = match.end() - 1 if match else 0
171177
return (cursor_offset + delta, line)
172178

173179
def last_word_pos(string):
174180
"""returns the start index of the last word of given string"""
175-
patt = r'\S\s'
176-
match = re.search(patt, string[::-1])
181+
match = forward_word_re.search(string[::-1])
177182
index = match and len(string) - match.end() + 1
178183
return index or 0
179184

@@ -204,20 +209,29 @@ def backspace(cursor_offset, line):
204209
def delete_from_cursor_back(cursor_offset, line):
205210
return 0, line[cursor_offset:]
206211

212+
213+
delete_rest_of_word_re = LazyReCompile(r'\w\b')
214+
215+
207216
@edit_keys.on('<Esc+d>') # option-d
208217
@kills_ahead
209218
def delete_rest_of_word(cursor_offset, line):
210-
m = re.search(r'\w\b', line[cursor_offset:])
219+
m = delete_rest_of_word_re.search(line[cursor_offset:])
211220
if not m:
212221
return cursor_offset, line, ''
213222
return (cursor_offset, line[:cursor_offset] + line[m.start()+cursor_offset+1:],
214223
line[cursor_offset:m.start()+cursor_offset+1])
215224

225+
226+
delete_word_to_cursor_re = LazyReCompile(r'\s\S')
227+
228+
216229
@edit_keys.on(config='clear_word_key')
217230
@kills_behind
218231
def delete_word_to_cursor(cursor_offset, line):
219-
matches = list(re.finditer(r'\s\S', line[:cursor_offset]))
220-
start = matches[-1].start()+1 if matches else 0
232+
start = 0
233+
for match in delete_word_to_cursor_re.finditer(line[:cursor_offset]):
234+
start = match.start() + 1
221235
return start, line[:start] + line[cursor_offset:], line[start:cursor_offset]
222236

223237
@edit_keys.on('<Esc+y>')
@@ -259,16 +273,22 @@ def delete_from_cursor_forward(cursor_offset, line):
259273
def titlecase_next_word(cursor_offset, line):
260274
return cursor_offset, line #TODO Not implemented
261275

276+
277+
delete_word_from_cursor_back_re = LazyReCompile(r'\b\w')
278+
279+
262280
@edit_keys.on('<Esc+BACKSPACE>')
263281
@edit_keys.on('<Meta-BACKSPACE>')
264282
@kills_behind
265283
def delete_word_from_cursor_back(cursor_offset, line):
266284
"""Whatever my option-delete does in bash on my mac"""
267285
if not line:
268286
return cursor_offset, line, ''
269-
starts = [m.start() for m in list(re.finditer(r'\b\w', line)) if m.start() < cursor_offset]
270-
if starts:
271-
return starts[-1], line[:starts[-1]] + line[cursor_offset:], line[starts[-1]:cursor_offset]
272-
return cursor_offset, line, ''
273-
274-
287+
start = None
288+
for match in delete_word_from_cursor_back_re.finditer(line):
289+
if match.start() < cursor_offset:
290+
start = match.start()
291+
if start is not None:
292+
return start, line[:start] + line[cursor_offset:], line[start:cursor_offset]
293+
else:
294+
return cursor_offset, line, ''

0 commit comments

Comments
 (0)