diff --git a/prompt_toolkit/buffer.py b/prompt_toolkit/buffer.py index f5df28982..83dc41a63 100644 --- a/prompt_toolkit/buffer.py +++ b/prompt_toolkit/buffer.py @@ -209,11 +209,13 @@ class Buffer(object): :param complete_while_typing: :class:`~prompt_toolkit.filters.SimpleFilter` instance. Decide whether or not to do asynchronous autocompleting while typing. - :param enable_history_search: :class:`~prompt_toolkit.filters.SimpleFilter` - to indicate when up-arrow partial string matching is enabled. It is - adviced to not enable this at the same time as `complete_while_typing`, - because when there is an autocompletion found, the up arrows usually - browse through the completions, rather than through the history. + :param enable_history_search: `bool`, `'endswith'`, `'contains'` or + :class:`~prompt_toolkit.filters.SimpleFilter` instance, + to indicate when up-arrow partial string matching or full string matching + is enabled. It is advised to not enable this at the same time as + `complete_while_typing`, because when there is an autocompletion found, + the up arrows usually browses through the completions, + rather than through the history. :param read_only: :class:`~prompt_toolkit.filters.SimpleFilter`. When True, changes will not be allowed. """ @@ -224,6 +226,19 @@ def __init__(self, completer=None, auto_suggest=None, history=None, accept_action=AcceptAction.IGNORE, read_only=False, on_text_changed=None, on_text_insert=None, on_cursor_position_changed=None): + if enable_history_search == 'contains': + def f(history_line, search_text): + return search_text in history_line + self._history_search_line_fn = f + enable_history_search = True + + else: + def f(history_line, search_text): + return history_line.startswith(search_text) + self._history_search_line_fn = f + if(self.is_history_search_option(enable_history_search)): + enable_history_search = True + # Accept both filters and booleans as input. enable_history_search = to_simple_filter(enable_history_search) is_multiline = to_simple_filter(is_multiline) @@ -859,7 +874,7 @@ def _history_matches(self, i): (when we don't have history search, it's also True.) """ return (self.history_search_text is None or - self._working_lines[i].startswith(self.history_search_text)) + self._history_search_line_fn(self._working_lines[i], self.history_search_text)) def history_forward(self, count=1): """ @@ -1115,6 +1130,15 @@ def validate(self): self.validation_error = None return True + @staticmethod + def history_search_options(): + return ['contains', 'startswith'] + + @staticmethod + def is_history_search_option(enable_history_search): + return any(enable_history_search == x + for x in Buffer.history_search_options()) + def append_to_history(self): """ Append the current input to the history. diff --git a/prompt_toolkit/shortcuts.py b/prompt_toolkit/shortcuts.py index 9893624c6..f8851dcee 100644 --- a/prompt_toolkit/shortcuts.py +++ b/prompt_toolkit/shortcuts.py @@ -412,7 +412,7 @@ def create_prompt_application( :param complete_while_typing: `bool` or :class:`~prompt_toolkit.filters.SimpleFilter`. Enable autocompletion while typing. - :param enable_history_search: `bool` or + :param enable_history_search: `bool`, `'endswith'`, `'contains'` or :class:`~prompt_toolkit.filters.SimpleFilter`. Enable up-arrow parting string matching. :param lexer: :class:`~prompt_toolkit.layout.lexers.Lexer` to be used for @@ -457,6 +457,11 @@ def create_prompt_application( if vi_mode: editing_mode = EditingMode.VI + # History Search + history_search_param = enable_history_search + is_history_search_option = Buffer.is_history_search_option(enable_history_search) + if (is_history_search_option): + enable_history_search = True # Make sure that complete_while_typing is disabled when enable_history_search # is enabled. (First convert to SimpleFilter, to avoid doing bitwise operations # on bool objects.) @@ -465,6 +470,8 @@ def create_prompt_application( multiline = to_simple_filter(multiline) complete_while_typing = complete_while_typing & ~enable_history_search + if (not is_history_search_option): + history_search_param = enable_history_search # Accept Pygments styles as well for backwards compatibility. try: @@ -489,7 +496,7 @@ def create_prompt_application( extra_input_processors=extra_input_processors, wrap_lines=wrap_lines), buffer=Buffer( - enable_history_search=enable_history_search, + enable_history_search=history_search_param, complete_while_typing=complete_while_typing, is_multiline=multiline, history=(history or InMemoryHistory()),