FelixRosencrantz: Some thoughts on incremental Search… What is Incremental Search?
The shell performs an incremental search by searching for a specified string in the shell's history. As the user types each character of the search string the shell gives immediate feedback changing the current command line to the history line and cursor position that matches the search string. The shell will only jump to a new spot if the search string no longer matches at the current spot. The shell provides a mini-buffer (separate from the command line) that shows the current search string. The search starts from the current point in history and searches in one direction either the start or end of history. The shell starts at the current cursor position and searches towards one end of the history.
The mini-buffer has a prompt string that reports status of the search directory and if the search string is not found. The search is case-insensitive, and can start with a “^” to say the search string should match the beginning of a history line. The zle widgets can take an argument which is used as the initial input for the search string.
From the manual: “A restricted set of editing functions is available in the mini-buffer. An interrupt signal, as defined by the stty setting, will stop the search and go back to the original line. An undefined key will have the same effect. The supported functions are: backward-delete-char, vi-backward-delete-char, clear-screen, redisplay, quoted-insert, vi-quoted-insert, accept-and-hold, accept-and-infer-next-history, accept-line and accept-line-and-down-history.
magic-space just inserts a space. vi-cmd-mode toggles between the 'main' and 'vicmd' keymaps; the 'main' keymap (insert mode) will be selected initially. history-incremental-search-backward will get the next occurrence of the contents of the mini-buffer. history-incremental-search-forward inverts the sense of the search. vi-repeat-search and vi-rev-repeat-search are similarly supported. The direction of the search is indicated in the mini-buffer.
Any multi-character string that is not bound to one of the above functions will beep and interrupt the search, leaving the last found line in the buffer. Any single character that is not bound to one of the above functions, or self-insert or self-insert-unmeta, will have the same effect but the function will be executed.”
Incremental search is performed by the following zle widgets:
history-incremental-search-backward
history-incremental-search-forward
Other vi mode widgets (?)
Incremental search is (probably) inspired/copied from Emacs's isearch functionality. Only some of that functionality has been copied into the Z-shell (or other shells for that matter.) So some of the functionality requested here can be directly related to what Emacs has but has been duplicated. Other functionality is different, since the context is different. In Emacs the user is moving around within a file, while within the shell the user is looking at discrete history lines.
Aspects of Incremental Search:
mini-buffer
the search
ZLE
What Could be Improved. Bart points out that the ultimate thing to do here would be to rip out the incremental search builtins entirely and write the whole thing in shell code around the read-from-minibuffer widget. This would allow for greater customization as outlined below. The current mechanism is somewhat limited to it's current functionality, and could provide more ways to add widgets. For example, now only certain widgets can be used in incremental-search mode, and there is no way to add a new widget to be used in this mode.
mini-buffer These items are about how the mini-buffer could be improved and changed.
prompt These items are about how the prompt could be improved.
editing These items relate to how to how text in the mini-buffer is modified.
history Currently the incsrch mini-buffer doesn't have a history of previous search. These items are about what information incsrch might record from previous searches.
strings searched for Previous strings searched for. There is a zle parameter LASTSEARCH that reports the last string, it might be nice if the cursor editing keys (like up&down) could be used to use the history of previous search strings. Like emacs isearch's alt-P and alt-N.
lines that were found and then accepted as is Record what history lines were actually found and then accepted as is. These lines can then refound quickly from within incremental search via some special keystroke, a separate widget, or used via a “smart list” filter. It is assumed if you searched for this line once before, it will probably be interesting to you again later.
lines that were accepted after being found and then modified These lines can then be refound quickly like the case above. Also, for these lines, the shell has information about what part of the line had been previously modified, and make it easier to remodify that part of the line on a future retrieval.
the search
search string syntax
In
zsh-users/8477, Vincent mentions the desire to search for a literal ^ as the first character of search string.
the jump to a new matching spot Currently the jump occurs when the search string no longer matches current spot or user explicitly asks for jump. This explicit jump is such that each character typed corresponds, for purposes of backing up to a previously matched position, to one backspace character.
An option that causes the jump to occur as each character is typed (useful in the situations when typing is a slow process, and if the current spot matches the user would stop). A variation would be to allow the user to specify the number of characters (n-character jump) before an automatic jump would occur.
Don't jump to the same line.
what is considered at match
Provide additional filtering capabilities. For example, an isearch-mode widget that when pressed changes the current search's criteria so that it will only match on lines longer than the current line match. This would be useful if you are looking for a particularly long history line. Likewise a widget could be added to change the criteria to look for a line with a shorter length.
Ability to specify matching specs like for completion.
Maybe allow the search to match separate lines. The first line matched might be starting point for the next line that is matched.
history The search goes through history from the starting point towards one end of history. What if the traversal of history was different?
what is displayed currently the currently matching history line is shown, with the cursor at the matching point.
Maybe show multiple matching lines, instead of having to see only one line at at time.
Maybe use terminal colors to highlight the whole matching string and other places it matches on the displayed line.
During the search the regular ZLE buffer is not being modified, so something like Bart's solution here
http://www.zsh.org/mla/users/2003/msg00153.html or another suggestion from Bart would be to put the entire history line into the prompt and only copy it to the BUFFER when it's accepted. Though ZLE generally is not able to insert extra characters such as terminal escapes into the display of $BUFFER and isn't likely to become able to do so. Also, there is the fish shell (
http://freshmeat.net/projects/thefishshell/) that can handle command line coloring with editting.
What if there was a secondary display, something that looked like a completion menu, that shows just the matching words (or some sort of snippet) from history. This display if easy to navigate, would allow the user to jump to the actual line they want with less typing.
Would it only “complete” words that start with the search string
Would it display words that match in the middle and have case-sensitive issues (e.g. search string “dif” might show 'diff', 'xmldiff', and 'DIFF'.
Help text
acceptance what happens when acceptance occurs, are there different types of acceptance.
widget arguments
ZLE
Links:
Already Added:
Ability to use a zsh parameter to examine the previous search string/set the search string. – FelixRosencrantz?