FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

First stage of Interaction abstraction. All frontends now implement r… · bpython/bpython@9aff5bc · GitHub

Commit 9aff5bc

Browse files
committed
First stage of Interaction abstraction. All frontends now implement repl.Interaction to show messages and generally interact with the user (prompts, notices, save prompts)
1 parent 48b6fc1 commit 9aff5bc

4 files changed

Lines changed: 93 additions & 44 deletions

File tree

‎bpython/cli.py‎

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@
5858
# This for keys
5959
from bpython.keys import key_dispatch
6060

61+
from bpython import repl
6162
from bpython.pager import page
62-
from bpython.repl import Interpreter, Repl
6363
import bpython.args
6464

6565

@@ -233,10 +233,25 @@ def make_colors(config):
233233
return c
234234

235235

236-
class CLIRepl(Repl):
236+
class CLIInteraction(repl.Interaction):
237+
def __init__(self, config, statusbar=None):
238+
repl.Interaction.__init__(self, config, statusbar)
239+
240+
def confirm(self, q):
241+
"""Ask for yes or no and return boolean"""
242+
return self.statusbar.prompt(q).lower().startswith('y')
243+
244+
def notify(self, s, n=10):
245+
return self.statusbar.message(s, n)
246+
247+
def file_prompt(self, s):
248+
return self.statusbar.prompt(s)
249+
250+
251+
class CLIRepl(repl.Repl):
237252

238253
def __init__(self, scr, interp, statusbar, config, idle=None):
239-
Repl.__init__(self, interp, config)
254+
repl.Repl.__init__(self, interp, config)
240255
interp.writetb = self.writetb
241256
self.scr = scr
242257
self.stdout_hist = ''
@@ -251,6 +266,7 @@ def __init__(self, scr, interp, statusbar, config, idle=None):
251266
self.s = ''
252267
self.statusbar = statusbar
253268
self.formatter = BPythonFormatter(config.color_scheme)
269+
self.interact = CLIInteraction(self.config, statusbar=self.statusbar)
254270

255271
def addstr(self, s):
256272
"""Add a string to the current input line and figure out
@@ -334,7 +350,7 @@ def clear_current_line(self):
334350
"""Called when a SyntaxError occured in the interpreter. It is
335351
used to prevent autoindentation from occuring after a
336352
traceback."""
337-
Repl.clear_current_line(self)
353+
repl.Repl.clear_current_line(self)
338354
self.s = ''
339355

340356
def clear_wrapped_lines(self):
@@ -359,7 +375,7 @@ def complete(self, tab=False):
359375
return
360376

361377
if self.config.auto_display_list or tab:
362-
self.list_win_visible = Repl.complete(self, tab)
378+
self.list_win_visible = repl.Repl.complete(self, tab)
363379
if self.list_win_visible:
364380
try:
365381
self.show_list(self.matches, self.argspec)
@@ -900,7 +916,7 @@ def push(self, s, insert_into_history=True):
900916
# curses.raw(True) prevents C-c from causing a SIGINT
901917
curses.raw(False)
902918
try:
903-
return Repl.push(self, s, insert_into_history)
919+
return repl.Repl.push(self, s, insert_into_history)
904920
except SystemExit:
905921
# Avoid a traceback on e.g. quit()
906922
self.do_exit = True
@@ -998,10 +1014,7 @@ def resize(self):
9981014
self.statusbar.resize(refresh=False)
9991015
self.redraw()
10001016

1001-
def ask_confirmation(self, q):
1002-
"""Ask for yes or no and return boolean"""
1003-
return self.statusbar.prompt(q).lower().startswith('y')
1004-
1017+
10051018
def getstdout(self):
10061019
"""This method returns the 'spoofed' stdout buffer, for writing to a
10071020
file or sending to a pastebin or whatever."""
@@ -1293,7 +1306,7 @@ def tab(self, back=False):
12931306
return True
12941307

12951308
def undo(self, n=1):
1296-
Repl.undo(self, n)
1309+
repl.Repl.undo(self, n)
12971310

12981311
# This will unhighlight highlighted parens
12991312
self.print_line(self.s)
@@ -1613,6 +1626,7 @@ def main_curses(scr, args, config, interactive=True, locals_=None,
16131626
global stdscr
16141627
global DO_RESIZE
16151628
global colors
1629+
global repl
16161630
DO_RESIZE = False
16171631

16181632
old_sigwinch_handler = signal.signal(signal.SIGWINCH,
@@ -1639,10 +1653,10 @@ def main_curses(scr, args, config, interactive=True, locals_=None,
16391653
if locals_ is None:
16401654
sys.modules['__main__'] = ModuleType('__main__')
16411655
locals_ = sys.modules['__main__'].__dict__
1642-
interpreter = Interpreter(locals_, getpreferredencoding())
1656+
interpreter = repl.Interpreter(locals_, getpreferredencoding())
16431657

1644-
repl = CLIRepl(main_win, interpreter, statusbar, config, idle)
1645-
repl._C = cols
1658+
clirepl = CLIRepl(main_win, interpreter, statusbar, config, idle)
1659+
clirepl._C = cols
16461660

16471661
sys.stdin = FakeStdin(repl)
16481662
sys.stdout = repl
@@ -1652,18 +1666,18 @@ def main_curses(scr, args, config, interactive=True, locals_=None,
16521666
bpython.args.exec_code(interpreter, args)
16531667
if not interactive:
16541668
curses.raw(False)
1655-
return repl.getstdout()
1669+
return clirepl.getstdout()
16561670
else:
16571671
sys.path.insert(0, '')
1658-
repl.startup()
1672+
clirepl.startup()
16591673

16601674
if banner is not None:
1661-
repl.write(banner)
1662-
repl.write('\n')
1663-
repl.repl()
1675+
clirepl.write(banner)
1676+
clirepl.write('\n')
1677+
clirepl.repl()
16641678
if config.hist_length:
16651679
histfilename = os.path.expanduser(config.hist_file)
1666-
repl.rl_history.save(histfilename, getpreferredencoding())
1680+
clirepl.rl_history.save(histfilename, getpreferredencoding())
16671681

16681682
main_win.erase()
16691683
main_win.refresh()

‎bpython/gtk_.py‎

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,11 @@ class Statusbar(gtk.Statusbar):
140140
def __init__(self):
141141
gtk.Statusbar.__init__(self)
142142

143-
self.context_id = self.get_context_id('StatusBar')
143+
self.context_id = self.get_context_id('Statusbar')
144144

145145
def message(self, s, n=3):
146146
self.push(self.context_id, s)
147147

148-
def prompt(self, s):
149-
pass
150-
151148

152149
class SuggestionWindow(gtk.Window):
153150
"""
@@ -267,6 +264,20 @@ def update_matches(self, matches):
267264
self.view.set_property('visible', bool(matches))
268265

269266

267+
class GTKInteraction(repl.Interaction):
268+
def __init__(self, config, statusbar):
269+
repl.Interaction.__init__(self, config, statusbar)
270+
271+
def confirm(self, q):
272+
dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_YES_NO, q)
273+
response = True if dialog.run() == gtk.RESPONSE_YES else False
274+
dialog.destroy()
275+
return response
276+
277+
def notify(self, s, n=10):
278+
self.statusbar.message(s)
279+
280+
270281
class ReplWidget(gtk.TextView, repl.Repl):
271282
__gsignals__ = dict(button_press_event=None,
272283
focus_in_event=None,
@@ -290,7 +301,7 @@ def __init__(self, interpreter, config):
290301
self.modify_base('normal', gtk.gdk.color_parse(_COLORS[self.config.color_gtk_scheme['background']]))
291302

292303
self.text_buffer = self.get_buffer()
293-
self.statusbar = Statusbar()
304+
self.interact = GTKInteraction(self.config, Statusbar())
294305
tags = dict()
295306
for (name, value) in self.config.color_gtk_scheme.iteritems():
296307
tag = tags[name] = self.text_buffer.create_tag(name)
@@ -574,12 +585,6 @@ def on_suggestion_selection_changed(self, selection, word):
574585
self.text_buffer.insert_at_cursor(word)
575586

576587

577-
def ask_confirmation(self, q):
578-
dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_YES_NO, q)
579-
response = True if dialog.run() == gtk.RESPONSE_YES else False
580-
dialog.destroy()
581-
return response
582-
583588
def do_paste(self, widget):
584589
self.pastebin()
585590

@@ -772,7 +777,7 @@ def main(args=None):
772777
sw.add(repl_widget)
773778
container.add(sw)
774779

775-
sb = repl_widget.statusbar
780+
sb = repl_widget.interact.statusbar
776781
container.pack_end(sb, expand=False)
777782

778783
parent.show_all()
@@ -788,7 +793,6 @@ def main(args=None):
788793
repl_widget.rl_history.save(histfilename, getpreferredencoding())
789794
return 0
790795

791-
792796
if __name__ == '__main__':
793797
from bpython.gtk_ import main
794798
main()

‎bpython/repl.py‎

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,23 @@ def update(self, current_word='', matches=[]):
236236
self.index = -1
237237

238238

239+
class Interaction(object):
240+
def __init__(self, config, statusbar=None):
241+
self.config = config
242+
243+
if statusbar:
244+
self.statusbar = statusbar
245+
246+
def confirm(self, s):
247+
raise NotImplementedError
248+
249+
def notify(self, s, n=10):
250+
raise NotImplementedError
251+
252+
def file_prompt(self, s):
253+
raise NotImplementedError
254+
255+
239256
class Repl(object):
240257
"""Implements the necessary guff for a Python-repl-alike interface
241258
@@ -302,6 +319,7 @@ def __init__(self, interp, config):
302319
self.list_win_visible = False
303320
self._C = {}
304321
self.prev_block_finished = 0
322+
self.interact = Interaction(self.config)
305323
# previous pastebin content to prevent duplicate pastes, filled on call
306324
# to repl.pastebin
307325
self.prev_pastebin_content = ''
@@ -615,9 +633,9 @@ def write2file(self):
615633
buffer to disk."""
616634

617635
try:
618-
fn = self.statusbar.prompt('Save to file (Esc to cancel): ')
636+
fn = self.interact.file_prompt('Save to file (Esc to cancel): ')
619637
except ValueError:
620-
self.statusbar.message("Save cancelled.")
638+
self.interact.notify("Save cancelled.")
621639
return
622640

623641
if fn.startswith('~'):
@@ -630,9 +648,9 @@ def write2file(self):
630648
f.write(s)
631649
f.close()
632650
except IOError:
633-
self.statusbar.message("Disk write error for file '%s'." % (fn, ))
651+
self.interact.notify("Disk write error for file '%s'." % (fn, ))
634652
else:
635-
self.statusbar.message('Saved to %s' % (fn, ))
653+
self.interact.notify('Saved to %s' % (fn, ))
636654

637655
def pastebin(self, s=None):
638656
"""Upload to a pastebin and display the URL in the status bar."""
@@ -641,31 +659,31 @@ def pastebin(self, s=None):
641659
s = self.getstdout()
642660

643661
if (self.config.pastebin_confirm and
644-
not self.ask_confirmation("Pastebin buffer? (y/N) ")):
645-
self.statusbar.message("Pastebin aborted")
662+
not self.interact.confirm("Pastebin buffer? (y/N) ")):
663+
self.interact.notify("Pastebin aborted")
646664
return
647665

648666
pasteservice = ServerProxy(self.config.pastebin_url)
649667

650668
if s == self.prev_pastebin_content:
651-
self.statusbar.message('Duplicate pastebin. Previous URL: ' +
652-
self.prev_pastebin_url)
669+
self.interact.notify('Duplicate pastebin. Previous URL: ' +
670+
self.prev_pastebin_url)
653671
return
654672

655673
self.prev_pastebin_content = s
656674

657-
self.statusbar.message('Posting data to pastebin...')
675+
self.interact.notify('Posting data to pastebin...')
658676
try:
659677
paste_id = pasteservice.pastes.newPaste('pycon', s)
660678
except XMLRPCError, e:
661-
self.statusbar.message('Upload failed: %s' % (str(e), ) )
679+
self.interact.notify('Upload failed: %s' % (str(e), ) )
662680
return
663681

664682
paste_url_template = Template(self.config.pastebin_show_url)
665683
paste_id = urlquote(paste_id)
666684
paste_url = paste_url_template.safe_substitute(paste_id=paste_id)
667685
self.prev_pastebin_url = paste_url
668-
self.statusbar.message('Pastebin URL: %s' % (paste_url, ), 10)
686+
self.interact.notify('Pastebin URL: %s' % (paste_url, ), 10)
669687

670688
def push(self, s, insert_into_history=True):
671689
"""Push a line of code onto the buffer so it can process it all

‎bpython/urwid.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,17 @@ def render(self, size, focus=False):
384384
canvas.cursor = cursor
385385
return canvas
386386

387+
class URWIDInteraction(repl.Interaction):
388+
def __init__(self, config, statusbar=None):
389+
repl.Interaction.__init__(self, config, statusbar)
390+
391+
def confirm(self, q):
392+
"""Ask for yes or no and return boolean"""
393+
return self.statusbar.prompt(q).lower().startswith('y')
394+
395+
def notify(self, s, n=10):
396+
return self.statusbar.message(s, n)
397+
387398

388399
class URWIDRepl(repl.Repl):
389400

@@ -400,6 +411,8 @@ def __init__(self, event_loop, palette, interpreter, config):
400411
config.pastebin_key, config.last_output_key,
401412
config.show_source_key))
402413

414+
self.interact = URWIDInteraction(self.config, self.statusbar)
415+
403416
self.tooltip = urwid.ListBox(urwid.SimpleListWalker([]))
404417
self.tooltip.grid = None
405418
self.overlay = Tooltip(self.listbox, self.tooltip)

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL