X Tutup
Skip to content

Commit 4f689ba

Browse files
committed
Merged in thomasballinger/bpython (pull request #28)
fix issue #161 - edit current current line in editor
2 parents 7b78234 + 231dc91 commit 4f689ba

File tree

3 files changed

+106
-15
lines changed

3 files changed

+106
-15
lines changed

bpython/cli.py

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,9 @@ def p_key(self, key):
995995
self.do_exit = True
996996
return None
997997

998+
elif key == '\x18':
999+
return self.send_current_line_to_editor()
1000+
9981001
elif key[0:3] == 'PAD' and not key in ('PAD0', 'PADSTOP'):
9991002
pad_keys = {
10001003
'PADMINUS': '-',
@@ -1108,10 +1111,10 @@ def repl(self):
11081111
self.push('from bpython._internal import _help as help\n', False)
11091112

11101113
self.iy, self.ix = self.scr.getyx()
1111-
more = False
1114+
self.more = False
11121115
while not self.do_exit:
11131116
self.f_string = ''
1114-
self.prompt(more)
1117+
self.prompt(self.more)
11151118
try:
11161119
inp = self.get_line()
11171120
except KeyboardInterrupt:
@@ -1132,8 +1135,8 @@ def repl(self):
11321135
else:
11331136
self.stdout_hist += inp.encode(getpreferredencoding()) + '\n'
11341137
stdout_position = len(self.stdout_hist)
1135-
more = self.push(inp)
1136-
if not more:
1138+
self.more = self.push(inp)
1139+
if not self.more:
11371140
self.prev_block_finished = stdout_position
11381141
self.s = ''
11391142
return self.exit_value
@@ -1203,8 +1206,8 @@ def reevaluate(self):
12031206
# I decided it was easier to just do this manually
12041207
# than to make the print_line and history stuff more flexible.
12051208
self.scr.addstr('\n')
1206-
more = self.push(line)
1207-
self.prompt(more)
1209+
self.more = self.push(line)
1210+
self.prompt(self.more)
12081211
self.iy, self.ix = self.scr.getyx()
12091212

12101213
self.cpos = 0
@@ -1505,6 +1508,46 @@ def yank_from_buffer(self):
15051508
self.addstr(self.cut_buffer)
15061509
self.print_line(self.s, clr=True)
15071510

1511+
def send_current_line_to_editor(self):
1512+
lines = repl.send_to_external_editor(self.s).split('\n')
1513+
self.s = ''
1514+
self.print_line(self.s)
1515+
while lines and not lines[-1]:
1516+
lines.pop()
1517+
if not lines:
1518+
return ''
1519+
1520+
self.f_string = ''
1521+
self.cpos = -1 # Set cursor position to -1 to prevent paren matching
1522+
1523+
self.iy, self.ix = self.scr.getyx()
1524+
self.evaluating = True
1525+
for line in lines:
1526+
if py3:
1527+
self.stdout_hist += line + '\n'
1528+
else:
1529+
self.stdout_hist += line.encode(getpreferredencoding()) + '\n'
1530+
self.history.append(line)
1531+
self.print_line(line)
1532+
self.s_hist[-1] += self.f_string
1533+
self.scr.addstr('\n')
1534+
self.more = self.push(line)
1535+
self.prompt(self.more)
1536+
self.iy, self.ix = self.scr.getyx()
1537+
self.evaluating = False
1538+
1539+
self.cpos = 0
1540+
indent = repl.next_indentation(self.s, self.config.tab_length)
1541+
self.s = ''
1542+
self.scr.refresh()
1543+
1544+
if self.buffer:
1545+
for _ in xrange(indent):
1546+
self.tab()
1547+
1548+
self.print_line(self.s)
1549+
self.scr.redrawwin()
1550+
return ''
15081551

15091552
class Statusbar(object):
15101553
"""This class provides the status bar at the bottom of the screen.

bpython/curtsiesfrontend/repl.py

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -279,15 +279,7 @@ def process_event(self, e):
279279
elif isinstance(e, events.PasteEvent):
280280
self.paste_mode = True
281281
for ee in e.events:
282-
if ee in ("\n", "\r", "PAD_ENTER"):
283-
self.on_enter()
284-
while self.fake_refresh_request:
285-
self.fake_refresh_request = False
286-
self.process_event(events.RefreshRequestEvent())
287-
elif isinstance(ee, events.Event):
288-
pass # ignore events in a paste
289-
else:
290-
self.add_normal_character(ee if len(ee) == 1 else ee[-1]) #strip control seq
282+
self.process_simple_event(ee)
291283
self.paste_mode = False
292284
self.update_completion()
293285

@@ -348,6 +340,8 @@ def process_event(self, e):
348340
elif e in key_dispatch[self.config.external_editor_key]:
349341
self.send_to_external_editor()
350342
#TODO add PAD keys hack as in bpython.cli
343+
elif e in ["\x18"]:
344+
self.send_current_block_to_external_editor()
351345
else:
352346
self.add_normal_character(e if len(e) == 1 else e[-1]) #strip control seq
353347
self.update_completion()
@@ -884,6 +878,50 @@ def send_to_external_editor(self, filename=None):
884878
self._current_line = lines[-1][4:]
885879
self.cursor_offset_in_line = len(self._current_line)
886880

881+
def get_current_block(self):
882+
return '\n'.join(self.buffer + [self._current_line])
883+
884+
def clear_current_block(self):
885+
self.display_buffer = []
886+
[self.history.pop() for _ in self.buffer]
887+
self.buffer = []
888+
self.cursor_offset_in_line = 0
889+
self.saved_indent = 0
890+
self._current_line = ''
891+
self.cursor_offset_in_line = len(self._current_line)
892+
self.done = True
893+
894+
def send_current_block_to_external_editor(self, filename=None):
895+
editor = os.environ.get('VISUAL', os.environ.get('EDITOR', 'vim'))
896+
editor_args = editor.split()
897+
text = self.get_current_block()
898+
self.clear_current_block()
899+
with tempfile.NamedTemporaryFile(suffix='.py') as temp:
900+
temp.write(text.encode('utf8'))
901+
temp.flush()
902+
subprocess.call(editor_args + [temp.name])
903+
lines = [line for line in open(temp.name).read().split('\n')]
904+
while not lines[-1].split():
905+
lines.pop()
906+
events = '\n'.join(lines + ([''] if len(lines) == 1 else ['', '']))
907+
self.paste_mode = True
908+
for e in events:
909+
self.process_simple_event(e)
910+
self.paste_mode = False
911+
self._current_line = ''
912+
self.cursor_offset_in_line = len(self._current_line)
913+
914+
def process_simple_event(self, e):
915+
if e in ("\n", "\r", "PAD_ENTER"):
916+
self.on_enter()
917+
while self.fake_refresh_request:
918+
self.fake_refresh_request = False
919+
self.process_event(events.RefreshRequestEvent())
920+
elif isinstance(e, events.Event):
921+
pass # ignore events
922+
else:
923+
self.add_normal_character(e if len(e) == 1 else e[-1]) #strip control seq
924+
887925
def simple_repl():
888926
refreshes = []
889927
def request_refresh():

bpython/repl.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import pydoc
3131
import subprocess
3232
import sys
33+
import tempfile
3334
import textwrap
3435
import traceback
3536
import unicodedata
@@ -1064,3 +1065,12 @@ def extract_exit_value(args):
10641065
return args[0]
10651066
else:
10661067
return args
1068+
1069+
def send_to_external_editor(text, filename=None):
1070+
editor = os.environ.get('VISUAL', os.environ.get('EDITOR', 'vim'))
1071+
editor_args = editor.split()
1072+
with tempfile.NamedTemporaryFile(suffix='.py') as temp:
1073+
temp.write(text)
1074+
temp.flush()
1075+
subprocess.call(editor_args + [temp.name])
1076+
return open(temp.name).read()

0 commit comments

Comments
 (0)
X Tutup