Skip to content

Commit d4d3180

Browse files
authored
Merge pull request #1 from bpython/master
Redo (#812)
2 parents d6bd2e5 + be1160a commit d4d3180

File tree

5 files changed

+31
-10
lines changed

5 files changed

+31
-10
lines changed

bpython/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ def loadini(struct, configfile):
108108
"last_output": "F9",
109109
"left": "C-b",
110110
"pastebin": "F8",
111+
"redo": "C-g",
111112
"reimport": "F6",
112113
"reverse_incremental_search": "M-r",
113114
"right": "C-f",
@@ -193,6 +194,7 @@ def get_key_no_doublebind(command):
193194
struct.suspend_key = get_key_no_doublebind("suspend")
194195
struct.toggle_file_watch_key = get_key_no_doublebind("toggle_file_watch")
195196
struct.undo_key = get_key_no_doublebind("undo")
197+
struct.redo_key = get_key_no_doublebind("redo")
196198
struct.reimport_key = get_key_no_doublebind("reimport")
197199
struct.reverse_incremental_search_key = get_key_no_doublebind(
198200
"reverse_incremental_search"

bpython/curtsiesfrontend/repl.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,8 @@ def process_key_event(self, e):
775775
self.on_tab(back=True)
776776
elif e in key_dispatch[self.config.undo_key]: # ctrl-r for undo
777777
self.prompt_undo()
778+
elif e in key_dispatch[self.config.redo_key]: # ctrl-g for redo
779+
self.redo()
778780
elif e in key_dispatch[self.config.save_key]: # ctrl-s for save
779781
greenlet.greenlet(self.write2file).switch()
780782
elif e in key_dispatch[self.config.pastebin_key]: # F8 for pastebin
@@ -858,14 +860,17 @@ def readline_kill(self, e):
858860
else:
859861
self.cut_buffer = cut
860862

861-
def on_enter(self, insert_into_history=True, reset_rl_history=True):
863+
def on_enter(self, new_code=True, reset_rl_history=True):
862864
# so the cursor isn't touching a paren TODO: necessary?
865+
if new_code:
866+
self.redo_stack = []
867+
863868
self._set_cursor_offset(-1, update_completion=False)
864869
if reset_rl_history:
865870
self.rl_history.reset()
866871

867872
self.history.append(self.current_line)
868-
self.push(self.current_line, insert_into_history=insert_into_history)
873+
self.push(self.current_line, insert_into_history=new_code)
869874

870875
def on_tab(self, back=False):
871876
"""Do something on tab key
@@ -1019,7 +1024,7 @@ def send_session_to_external_editor(self, filename=None):
10191024
source = preprocess("\n".join(from_editor), self.interp.compile)
10201025
lines = source.split("\n")
10211026
self.history = lines
1022-
self.reevaluate(insert_into_history=True)
1027+
self.reevaluate(new_code=True)
10231028
self.current_line = current_line
10241029
self.cursor_offset = len(self.current_line)
10251030
self.status_bar.message(_("Session edited and reevaluated"))
@@ -1030,7 +1035,7 @@ def clear_modules_and_reevaluate(self):
10301035
cursor, line = self.cursor_offset, self.current_line
10311036
for modname in set(sys.modules.keys()) - self.original_modules:
10321037
del sys.modules[modname]
1033-
self.reevaluate(insert_into_history=True)
1038+
self.reevaluate(new_code=True)
10341039
self.cursor_offset, self.current_line = cursor, line
10351040
self.status_bar.message(
10361041
_("Reloaded at %s by user.") % (time.strftime("%X"),)
@@ -1811,7 +1816,15 @@ def prompt_for_undo():
18111816

18121817
greenlet.greenlet(prompt_for_undo).switch()
18131818

1814-
def reevaluate(self, insert_into_history=False):
1819+
def redo(self):
1820+
if (self.redo_stack):
1821+
temp = self.redo_stack.pop()
1822+
self.push(temp)
1823+
self.history.append(temp)
1824+
else:
1825+
self.status_bar.message("Nothing to redo.")
1826+
1827+
def reevaluate(self, new_code=False):
18151828
"""bpython.Repl.undo calls this"""
18161829
if self.watcher:
18171830
self.watcher.reset()
@@ -1835,7 +1848,7 @@ def reevaluate(self, insert_into_history=False):
18351848
sys.stdin = ReevaluateFakeStdin(self.stdin, self)
18361849
for line in old_logical_lines:
18371850
self._current_line = line
1838-
self.on_enter(insert_into_history=insert_into_history)
1851+
self.on_enter(new_code=new_code)
18391852
while self.fake_refresh_requested:
18401853
self.fake_refresh_requested = False
18411854
self.process_event(bpythonevents.RefreshRequestEvent())

bpython/repl.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,8 @@ def __init__(self, interp, config):
439439
duplicates=config.hist_duplicates, hist_size=config.hist_length
440440
)
441441
self.s_hist = []
442-
self.history = []
442+
self.history = [] # commands executed since beginning of session
443+
self.redo_stack = []
443444
self.evaluating = False
444445
self.matches_iter = MatchesIterator()
445446
self.funcprops = None
@@ -1009,6 +1010,10 @@ def undo(self, n=1):
10091010

10101011
entries = list(self.rl_history.entries)
10111012

1013+
#Most recently undone command
1014+
last_entries = self.history[-n:]
1015+
last_entries.reverse()
1016+
self.redo_stack += last_entries
10121017
self.history = self.history[:-n]
10131018
self.reevaluate()
10141019

bpython/sample-config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
# toggle_file_watch = F5
6868
# save = C-s
6969
# undo = C-r
70+
# redo = C-g
7071
# up_one_line = C-p
7172
# down_one_line = C-n
7273
# cut_to_buffer = C-k

bpython/test/test_curtsies_painting.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def test_run_line(self):
102102
orig_stdout = sys.stdout
103103
sys.stdout = self.repl.stdout
104104
[self.repl.add_normal_character(c) for c in "1 + 1"]
105-
self.repl.on_enter(insert_into_history=False)
105+
self.repl.on_enter(new_code=False)
106106
screen = fsarray([">>> 1 + 1", "2", "Welcome to"])
107107
self.assert_paint_ignoring_formatting(screen, (1, 1))
108108
finally:
@@ -248,7 +248,7 @@ def enter(self, line=None):
248248
self.repl._set_cursor_offset(len(line), update_completion=False)
249249
self.repl.current_line = line
250250
with output_to_repl(self.repl):
251-
self.repl.on_enter(insert_into_history=False)
251+
self.repl.on_enter(new_code=False)
252252
self.assertEqual(self.repl.rl_history.entries, [""])
253253
self.send_refreshes()
254254

@@ -592,7 +592,7 @@ def test_cursor_stays_at_bottom_of_screen(self):
592592
self.repl.width = 50
593593
self.repl.current_line = "__import__('random').__name__"
594594
with output_to_repl(self.repl):
595-
self.repl.on_enter(insert_into_history=False)
595+
self.repl.on_enter(new_code=False)
596596
screen = [">>> __import__('random').__name__", "'random'"]
597597
self.assert_paint_ignoring_formatting(screen)
598598

0 commit comments

Comments
 (0)