* Widget for multi-word history searching
@ 2016-05-22 7:16 Sebastian Gniazdowski
0 siblings, 0 replies; only message in thread
From: Sebastian Gniazdowski @ 2016-05-22 7:16 UTC (permalink / raw)
To: Zsh Users
[-- Attachment #1: Type: text/plain, Size: 689 bytes --]
Hello,
I've developed a widget that can do AND search of given words:
https://asciinema.org/a/46341
Would anyone like to contribute? To be done:
- approximate matching on e.g. Ctrl-F, like in n-history
- mark of current element (underline?)
- highlight of what's matched from the query
- possible use of mini-buffer instead of recursive edit
To use, copy to site-functions and add:
autoload history-search-multi-word
zle -N history-search-multi-word
zle -N history-search-multi-word-backwards history-search-multi-word
bindkey "^R" history-search-multi-word
to zshrc. Or use as plugin, link:
https://github.com/psprint/history-search-multi-word
Best regards,
Sebastian Gniazdowski
[-- Attachment #2: history-search-multi-word --]
[-- Type: application/octet-stream, Size: 4326 bytes --]
emulate -LR zsh
setopt typesetsilent extendedglob noshortloops
# When an error, then no cursor keys bindings
zmodload zsh/terminfo 2>/dev/null
zmodload zsh/termcap 2>/dev/null
typeset -g __hsmw_hcw_index
typeset -g __hsmw_hcw_widget_name __hsmw_hcw_restart __hsmw_hcw_call_count
typeset -gaU __hsmw_hcw_found
(( __hsmw_hcw_call_count ++ ))
_zhcw_main() {
# First call or restart?
if [[ "$__hsmw_hcw_call_count" -le 1 || "$__hsmw_hcw_restart" = "1" ]]; then
# '0' will get changed into $to_display limit
[[ "$WIDGET" != *-backwards ]] && __hsmw_hcw_index="1" || __hsmw_hcw_index="0"
__hsmw_hcw_widget_name="${WIDGET%-backwards}"
__hsmw_hcw_found=( )
__hsmw_hcw_finished="0"
__hsmw_hcw_restart="0"
else
# Consecutive call
[[ "$WIDGET" != *-backwards ]] && (( __hsmw_hcw_index ++ )) || (( __hsmw_hcw_index -- ))
fi
# Find history entries matching pattern *word1*~^*word2*~^*word3* etc.
if [ "$#__hsmw_hcw_found" -eq "0" ]; then
local search_buffer="${BUFFER%% ##}"
search_buffer="${search_buffer## ##}"
search_buffer="${search_buffer//(#m)[][*?|#~^()><\\]/\\$MATCH}"
local search_pattern=""
search_pattern="${search_buffer// ##/*~^*}"
# The repeat will make the matching work on a fresh heap arena
repeat 1; do
__hsmw_hcw_found=( "${(@M)history:#(#i)*$~search_pattern*}" )
echo "searched for: $search_pattern, found #${#__hsmw_hcw_found}" >> /tmp/reply
done
fi
if [ "$#__hsmw_hcw_found" -le "0" ]; then
zle -M "No matches found"
return 0
fi
#
# Pagination, index value guards
#
integer page_size=$(( LINES / 2 ))
integer max_index="$#__hsmw_hcw_found"
[ "$page_size" -gt "$max_index" ] && page_size="$max_index"
[ "$__hsmw_hcw_index" -le 0 ] && __hsmw_hcw_index="$max_index"
[ "$__hsmw_hcw_index" -gt "$max_index" ] && __hsmw_hcw_index=1
integer page_start_idx=$(( ((__hsmw_hcw_index-1)/page_size)*page_size+1 ))
integer on_page_idx=$(( (__hsmw_hcw_index-1) % page_size + 1 ))
#
# Prepare display
#
typeset -a disp_list
disp_list=( "${(@)__hsmw_hcw_found[page_start_idx,page_start_idx+page_size-1]}" )
# All entries should have multilines replaced
disp_list=( "${(@)disp_list//$'\n'/\\n}" )
disp_list[on_page_idx]="> ${disp_list[on_page_idx]} <"
zle -M -- \
"Searching for '$BUFFER'. "\
"Element #$__hsmw_hcw_index of $max_index"$'\n'"${(F)disp_list}"
}
_zhcw_self_insert() {
LBUFFER+="${KEYS[-1]}"
__hsmw_hcw_restart="1"
_zhcw_main
}
_zhcw_backward_delete_char() {
LBUFFER="${LBUFFER%?}"
__hsmw_hcw_restart="1"
_zhcw_main
}
_zhcw_delete_char() {
RBUFFER="${RBUFFER#?}"
__hsmw_hcw_restart="1"
_zhcw_main
}
_zhcw_main
if [ "$__hsmw_hcw_call_count" -eq "1" ]; then
# Make the zhcw keymap a copy of the current main
bindkey -N zhcw main
local down_widget="${WIDGET%-backwards}"
local up_widget="${down_widget}-backwards"
# Manual, termcap, terminfo
bindkey -M zhcw '^[OA' "$up_widget"
bindkey -M zhcw '^[OB' "$down_widget"
bindkey -M zhcw '^[[A' "$up_widget"
bindkey -M zhcw '^[[B' "$down_widget"
[ -n "$termcap[ku]" ] && bindkey -M zhcw "$termcap[ku]" "$up_widget"
[ -n "$termcap[kd]" ] && bindkey -M zhcw "$termcap[kd]" "$down_widget"
[ -n "$terminfo[kcuu1]" ] && bindkey -M zhcw "$terminfo[kcuu1]" "$up_widget"
[ -n "$terminfo[kcud1]" ] && bindkey -M zhcw "$terminfo[kcud1]" "$down_widget"
# Substitute self-insert, backward-delete-char, delete-char
zle -A self-insert saved-self-insert
zle -A backward-delete-char saved-backward-delete-char
zle -A delete-char saved-delete-char
zle -N self-insert _zhcw_self_insert
zle -N backward-delete-char _zhcw_backward_delete_char
zle -N delete-char _zhcw_delete_char
zle recursive-edit -K zhcw
BUFFER="${__hsmw_hcw_found[__hsmw_hcw_index]}"
zle -M ""
zle -A saved-self-insert self-insert
zle -A saved-backward-delete-char backward-delete-char
zle -A saved-delete-char delete-char
zle -D saved-self-insert saved-backward-delete-char saved-delete-char
# Full reinitialisation at next call
__hsmw_hcw_call_count="0"
fi
# vim:ft=zsh
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2016-05-22 7:16 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-22 7:16 Widget for multi-word history searching Sebastian Gniazdowski
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).