Default to previous search entry
This commit is contained in:
34
babi.py
34
babi.py
@@ -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:
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user