◐ Shell
reader mode source ↗
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
File filter
Conversations
Jump to
Diff view
Apply and reload
Show whitespace
Diff view
Apply and reload
43 changes: 27 additions & 16 deletions bpython/curtsiesfrontend/interaction.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import greenlet
import time
from curtsies import events

from ..translations import _
Expand Down Expand Up @@ -43,8 +43,8 @@ def __init__(
self.permanent_stack = []
if permanent_text:
self.permanent_stack.append(permanent_text)
self.main_context = greenlet.getcurrent()
self.request_context = None
self.request_refresh = request_refresh
self.schedule_refresh = schedule_refresh

Expand Down Expand Up @@ -83,13 +83,14 @@ def process_event(self, e):
assert self.in_prompt or self.in_confirm or self.waiting_for_refresh
if isinstance(e, RefreshRequestEvent):
self.waiting_for_refresh = False
self.request_context.switch()
elif isinstance(e, events.PasteEvent):
for ee in e.events:
# strip control seq
self.add_normal_character(ee if len(ee) == 1 else ee[-1])
elif e == "<ESC>" or isinstance(e, events.SigIntEvent):
self.request_context.switch(False)
self.escape()
elif e in edit_keys:
self.cursor_offset_in_line, self._current_line = edit_keys[e](
Expand All @@ -102,12 +103,12 @@ def process_event(self, e):
elif self.in_prompt and e in ("\n", "\r", "<Ctrl-j>", "Ctrl-m>"):
line = self._current_line
self.escape()
self.request_context.switch(line)
elif self.in_confirm:
if e.lower() == _("y"):
self.request_context.switch(True)
else:
self.request_context.switch(False)
self.escape()
else: # add normal character
self.add_normal_character(e)
Expand All @@ -126,6 +127,7 @@ def add_normal_character(self, e):

def escape(self):
"""unfocus from statusbar, clear prompt state, wait for notify call"""
self.in_prompt = False
self.in_confirm = False
self.prompt = ""
Expand All @@ -148,27 +150,36 @@ def current_line(self):
def should_show_message(self):
return bool(self.current_line)

# interaction interface - should be called from other greenlets
def notify(self, msg, n=3, wait_for_keypress=False):
self.request_context = greenlet.getcurrent()
self.message_time = n
self.message(msg, schedule_refresh=wait_for_keypress)
self.waiting_for_refresh = True
self.request_refresh()
self.main_context.switch(msg)

# below really ought to be called from greenlets other than main because
# they block
def confirm(self, q):
"""Expected to return True or False, given question prompt q"""
self.request_context = greenlet.getcurrent()
self.prompt = q
self.in_confirm = True
return self.main_context.switch(q)

def file_prompt(self, s):
"""Expected to return a file name, given"""
self.request_context = greenlet.getcurrent()
self.prompt = s
self.in_prompt = True
return self.main_context.switch(s)
Loading
Toggle all file notes Toggle all file annotations