Default to previous search entry

This commit is contained in:
Anthony Sottile
2019-11-30 17:09:19 -08:00
parent c5c3a4a2d9
commit 78934d13be
2 changed files with 48 additions and 18 deletions

34
babi.py
View File

@@ -207,6 +207,7 @@ class Status:
self._action_counter = -1
self._history: Dict[str, List[str]] = collections.defaultdict(list)
self._history_orig_len: Dict[str, int] = collections.defaultdict(int)
self._history_prev: Dict[str, str] = {}
@contextlib.contextmanager
def save_history(self) -> Generator[None, None, None]:
@@ -260,11 +261,14 @@ class Status:
prompt: str,
*,
history: Optional[str] = None,
default_prev: bool = False,
) -> str:
self.clear()
if history is not None:
lst = [*self._history[history], '']
lst_pos = len(lst) - 1
if history in self._history_prev:
prompt = f'{prompt} [{self._history_prev[history]}]'
else:
lst = ['']
lst_pos = 0
@@ -276,11 +280,25 @@ class Status:
def set_buf(s: str) -> None:
lst[lst_pos] = s
def _save_history_entry() -> None:
def _save_history_and_get_retv() -> str:
if history is not None:
prev = self._history_prev.get(history)
entry = buf()
if entry: # only put non-empty things in history
history_lst = self._history[history]
if not history_lst or history_lst[-1] != lst[lst_pos]:
history_lst.append(lst[lst_pos])
if not history_lst or history_lst[-1] != entry:
history_lst.append(entry)
self._history_prev[history] = entry
if (
default_prev and
prev is not None and
lst_pos == len(lst) - 1 and
not lst[lst_pos]
):
return prev
return buf()
def _render_prompt(*, base: str = prompt) -> None:
if not base or curses.COLS < 7:
@@ -358,8 +376,7 @@ class Status:
elif key.keyname == b'^C':
return ''
elif key.key == ord('\r'):
_save_history_entry()
return lst[lst_pos]
return _save_history_and_get_retv()
else:
# python3.8+ optimizes this out
# https://github.com/nedbat/coveragepy/issues/772
@@ -368,8 +385,7 @@ class Status:
elif key.keyname == b'^C':
return ''
elif key.key == ord('\r'):
_save_history_entry()
return lst[lst_pos]
return _save_history_and_get_retv()
def _restore_lines_eof_invariant(lines: MutableSequenceNoSlice) -> None:
@@ -1053,7 +1069,9 @@ def _edit(screen: Screen) -> EditResult:
else:
screen.file.go_to_line(lineno, screen.margin)
elif key.keyname == b'^W':
response = screen.status.prompt(screen, 'search', history='search')
response = screen.status.prompt(
screen, 'search', history='search', default_prev=True,
)
if response == '':
screen.status.update('cancelled')
else:

View File

@@ -707,6 +707,20 @@ def test_search_cancel(ten_lines, key):
h.await_text('cancelled')
def test_search_repeated_search(ten_lines):
with run(str(ten_lines)) as h, and_exit(h):
h.press('^W')
h.press('line')
h.await_text('search: line')
h.press('Enter')
h.await_cursor_position(x=0, y=2)
h.press('^W')
h.await_text('search [line]:')
h.press('Enter')
h.await_cursor_position(x=0, y=3)
def test_search_history_recorded():
with run() as h, and_exit(h):
h.press('^W')
@@ -716,10 +730,10 @@ def test_search_history_recorded():
h.press('^W')
h.press('Up')
h.await_text('search: asdf')
h.await_text('search [asdf]: asdf')
h.press('BSpace')
h.press('test')
h.await_text('search: asdtest')
h.await_text('search [asdf]: asdtest')
h.press('Down')
h.await_text_missing('asdtest')
h.press('Down') # can't go past the end
@@ -732,9 +746,9 @@ def test_search_history_recorded():
h.press('^W')
h.press('Up')
h.await_text('search: asdtest')
h.await_text('search [asdtest]: asdtest')
h.press('Up')
h.await_text('search: asdf')
h.await_text('search [asdtest]: asdf')
h.press('^C')
@@ -746,14 +760,12 @@ def test_search_history_duplicates_dont_repeat():
h.await_text('no matches')
h.press('^W')
h.press('search2')
h.await_text('search:')
h.await_text('search [search1]:')
h.press_and_enter('search2')
h.await_text('no matches')
h.press('^W')
h.press('search2')
h.await_text('search:')
h.await_text('search [search2]:')
h.press_and_enter('search2')
h.await_text('no matches')
@@ -856,7 +868,7 @@ def test_search_reverse_search_enter_saves_entry(xdg_data_home, ten_lines):
h.press('Enter')
h.press('^W')
h.press('Up')
h.await_text('search: line_1')
h.await_text('search [line_1]: line_1')
h.press('^C')