Improve quick prompt appearance

This commit is contained in:
Anthony Sottile
2020-03-19 20:37:39 -07:00
parent efa6561200
commit b2ebfa7b48
4 changed files with 54 additions and 29 deletions

View File

@@ -453,9 +453,7 @@ class File:
if res != 'a': # make `a` replace the rest of them if res != 'a': # make `a` replace the rest of them
with self._replace_hl.region(self.y, self.x, match.end()): with self._replace_hl.region(self.y, self.x, match.end()):
screen.draw() screen.draw()
res = screen.quick_prompt( res = screen.quick_prompt('replace', ('yes', 'no', 'all'))
'replace [y(es), n(o), a(ll)]?', 'yna',
)
if res in {'y', 'a'}: if res in {'y', 'a'}:
count += 1 count += 1
with self.edit_action_context('replace', final=True): with self.edit_action_context('replace', final=True):

View File

@@ -224,13 +224,40 @@ class Screen:
self.file.scroll_screen_if_needed(self.margin) self.file.scroll_screen_if_needed(self.margin)
self.draw() self.draw()
def quick_prompt(self, prompt: str, opts: str) -> Union[str, PromptResult]: def quick_prompt(
self,
prompt: str,
opt_strs: Tuple[str, ...],
) -> Union[str, PromptResult]:
opts = [opt[0] for opt in opt_strs]
while True: while True:
s = prompt.ljust(curses.COLS) x = 0
if len(s) > curses.COLS:
s = f'{s[:curses.COLS - 1]}' def _write(s: str, *, attr: int = curses.A_REVERSE) -> None:
self.stdscr.insstr(curses.LINES - 1, 0, s, curses.A_REVERSE) nonlocal x
x = min(curses.COLS - 1, len(prompt) + 1)
if x >= curses.COLS:
return
self.stdscr.insstr(curses.LINES - 1, x, s, attr)
x += len(s)
_write(prompt)
_write(' [')
for i, opt_str in enumerate(opt_strs):
_write(opt_str[0], attr=curses.A_REVERSE | curses.A_BOLD)
_write(opt_str[1:])
if i != len(opt_strs) - 1:
_write(', ')
_write(']?')
if x < curses.COLS - 1:
s = ' ' * (curses.COLS - x)
self.stdscr.insstr(curses.LINES - 1, x, s, curses.A_REVERSE)
x += 1
else:
x = curses.COLS - 1
self.stdscr.insstr(curses.LINES - 1, x, '', curses.A_REVERSE)
self.stdscr.move(curses.LINES - 1, x) self.stdscr.move(curses.LINES - 1, x)
key = self.get_char() key = self.get_char()
@@ -427,7 +454,7 @@ class Screen:
def quit_save_modified(self) -> Optional[EditResult]: def quit_save_modified(self) -> Optional[EditResult]:
if self.file.modified: if self.file.modified:
response = self.quick_prompt( response = self.quick_prompt(
'file is modified - save [y(es), n(o)]?', 'yn', 'file is modified - save', ('yes', 'no'),
) )
if response == 'y': if response == 'y':
if self.save_filename() is not PromptResult.CANCELLED: if self.save_filename() is not PromptResult.CANCELLED:

View File

@@ -37,7 +37,7 @@ def test_replace_actual_contents(run, ten_lines):
h.press_and_enter('line_0') h.press_and_enter('line_0')
h.await_text('replace with:') h.await_text('replace with:')
h.press_and_enter('ohai') h.press_and_enter('ohai')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
h.press('y') h.press('y')
h.await_text_missing('line_0') h.await_text_missing('line_0')
h.await_text('ohai') h.await_text('ohai')
@@ -59,7 +59,7 @@ match me!
h.press_and_enter('me!') h.press_and_enter('me!')
h.await_text('replace with:') h.await_text('replace with:')
h.press_and_enter('youuuu') h.press_and_enter('youuuu')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
h.press('y') h.press('y')
h.await_cursor_position(x=6, y=3) h.await_cursor_position(x=6, y=3)
h.press('Up') h.press('Up')
@@ -74,7 +74,7 @@ def test_replace_cancel_at_individual_replace(run, ten_lines):
h.press_and_enter(r'line_\d') h.press_and_enter(r'line_\d')
h.await_text('replace with:') h.await_text('replace with:')
h.press_and_enter('ohai') h.press_and_enter('ohai')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
h.press('^C') h.press('^C')
h.await_text('cancelled') h.await_text('cancelled')
@@ -86,7 +86,7 @@ def test_replace_unknown_characters_at_individual_replace(run, ten_lines):
h.press_and_enter(r'line_\d') h.press_and_enter(r'line_\d')
h.await_text('replace with:') h.await_text('replace with:')
h.press_and_enter('ohai') h.press_and_enter('ohai')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
h.press('?') h.press('?')
h.press('^C') h.press('^C')
h.await_text('cancelled') h.await_text('cancelled')
@@ -99,7 +99,7 @@ def test_replace_say_no_to_individual_replace(run, ten_lines):
h.press_and_enter('line_[135]') h.press_and_enter('line_[135]')
h.await_text('replace with:') h.await_text('replace with:')
h.press_and_enter('ohai') h.press_and_enter('ohai')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
h.press('y') h.press('y')
h.await_text_missing('line_1') h.await_text_missing('line_1')
h.press('n') h.press('n')
@@ -116,7 +116,7 @@ def test_replace_all(run, ten_lines):
h.press_and_enter(r'line_(\d)') h.press_and_enter(r'line_(\d)')
h.await_text('replace with:') h.await_text('replace with:')
h.press_and_enter(r'ohai+\1') h.press_and_enter(r'ohai+\1')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
h.press('a') h.press('a')
h.await_text_missing('line') h.await_text_missing('line')
h.await_text('ohai+1') h.await_text('ohai+1')
@@ -130,7 +130,7 @@ def test_replace_with_empty_string(run, ten_lines):
h.press_and_enter('line_1') h.press_and_enter('line_1')
h.await_text('replace with:') h.await_text('replace with:')
h.press('Enter') h.press('Enter')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
h.press('y') h.press('y')
h.await_text_missing('line_1') h.await_text_missing('line_1')
@@ -153,7 +153,7 @@ def test_replace_small_window_size(run, ten_lines):
h.press_and_enter('line') h.press_and_enter('line')
h.await_text('replace with:') h.await_text('replace with:')
h.press_and_enter('wat') h.press_and_enter('wat')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
with h.resize(width=8, height=24): with h.resize(width=8, height=24):
h.await_text('replace…') h.await_text('replace…')
@@ -170,7 +170,7 @@ def test_replace_height_1_highlight(run, tmpdir):
h.press_and_enter('^x+$') h.press_and_enter('^x+$')
h.await_text('replace with:') h.await_text('replace with:')
h.press('Enter') h.press('Enter')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
with h.resize(width=80, height=1): with h.resize(width=80, height=1):
h.await_text_missing('xxxxx') h.await_text_missing('xxxxx')
@@ -189,7 +189,7 @@ def test_replace_line_goes_off_screen(run):
h.press_and_enter('b+') h.press_and_enter('b+')
h.await_text('replace with:') h.await_text('replace with:')
h.press_and_enter('wat') h.press_and_enter('wat')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
h.await_text(f'{"a" * 20}{"b" * 59}»') h.await_text(f'{"a" * 20}{"b" * 59}»')
h.press('y') h.press('y')
h.await_text(f'{"a" * 20}wat') h.await_text(f'{"a" * 20}wat')
@@ -221,7 +221,7 @@ def test_replace_multiple_occurrences_in_line(run):
h.press_and_enter('a+') h.press_and_enter('a+')
h.await_text('replace with:') h.await_text('replace with:')
h.press_and_enter('q') h.press_and_enter('q')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
h.press('a') h.press('a')
h.await_text('bqbq') h.await_text('bqbq')
@@ -234,7 +234,7 @@ def test_replace_after_wrapping(run, ten_lines):
h.press_and_enter('line_[02]') h.press_and_enter('line_[02]')
h.await_text('replace with:') h.await_text('replace with:')
h.press_and_enter('ohai') h.press_and_enter('ohai')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
h.press('y') h.press('y')
h.await_text_missing('line_2') h.await_text_missing('line_2')
h.press('y') h.press('y')
@@ -251,7 +251,7 @@ def test_replace_after_cursor_after_wrapping(run):
h.press_and_enter('b') h.press_and_enter('b')
h.await_text('replace with:') h.await_text('replace with:')
h.press_and_enter('q') h.press_and_enter('q')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
h.press('n') h.press('n')
h.press('y') h.press('y')
h.await_text('replaced 1 occurrence') h.await_text('replaced 1 occurrence')
@@ -267,7 +267,7 @@ def test_replace_separate_line_after_wrapping(run, ten_lines):
h.press_and_enter('line_[01]') h.press_and_enter('line_[01]')
h.await_text('replace with:') h.await_text('replace with:')
h.press_and_enter('_') h.press_and_enter('_')
h.await_text('replace [y(es), n(o), a(ll)]?') h.await_text('replace [yes, no, all]?')
h.press('y') h.press('y')
h.await_text_missing('line_0') h.await_text_missing('line_0')
h.press('y') h.press('y')

View File

@@ -148,7 +148,7 @@ def test_save_on_exit_cancel_yn(run):
h.press('hello') h.press('hello')
h.await_text('hello') h.await_text('hello')
h.press('^X') h.press('^X')
h.await_text('file is modified - save [y(es), n(o)]?') h.await_text('file is modified - save [yes, no]?')
h.press('^C') h.press('^C')
h.await_text('cancelled') h.await_text('cancelled')
@@ -158,7 +158,7 @@ def test_save_on_exit_cancel_filename(run):
h.press('hello') h.press('hello')
h.await_text('hello') h.await_text('hello')
h.press('^X') h.press('^X')
h.await_text('file is modified - save [y(es), n(o)]?') h.await_text('file is modified - save [yes, no]?')
h.press('y') h.press('y')
h.await_text('enter filename:') h.await_text('enter filename:')
h.press('^C') h.press('^C')
@@ -171,7 +171,7 @@ def test_save_on_exit(run, tmpdir):
h.press('hello') h.press('hello')
h.await_text('hello') h.await_text('hello')
h.press('^X') h.press('^X')
h.await_text('file is modified - save [y(es), n(o)]?') h.await_text('file is modified - save [yes, no]?')
h.press('y') h.press('y')
h.await_text(f'enter filename: {f}') h.await_text(f'enter filename: {f}')
h.press('Enter') h.press('Enter')
@@ -183,9 +183,9 @@ def test_save_on_exit_resize(run, tmpdir):
h.press('hello') h.press('hello')
h.await_text('hello') h.await_text('hello')
h.press('^X') h.press('^X')
h.await_text('file is modified - save [y(es), n(o)]?') h.await_text('file is modified - save [yes, no]?')
with h.resize(width=10, height=24): with h.resize(width=10, height=24):
h.await_text('file is m…') h.await_text('file is m…')
h.await_text('file is modified - save [y(es), n(o)]?') h.await_text('file is modified - save [yes, no]?')
h.press('^C') h.press('^C')
h.await_text('cancelled') h.await_text('cancelled')