diff --git a/.gitmodules b/.gitmodules index 7674c96..26bffd9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "completions"] path = completions url = https://github.com/zsh-users/zsh-completions.git +[submodule "plugins/history-substring-search/external"] + path = plugins/history-substring-search/external + url = https://github.com/zsh-users/zsh-history-substring-search.git diff --git a/plugins/history-substring-search/external b/plugins/history-substring-search/external new file mode 160000 index 0000000..04c2eca --- /dev/null +++ b/plugins/history-substring-search/external @@ -0,0 +1 @@ +Subproject commit 04c2eca00c09f3351e72409923719c426f424160 diff --git a/plugins/history-substring-search/history-substring-search.zsh b/plugins/history-substring-search/history-substring-search.zsh deleted file mode 100644 index 14bffb8..0000000 --- a/plugins/history-substring-search/history-substring-search.zsh +++ /dev/null @@ -1,544 +0,0 @@ -#!/usr/bin/env zsh -############################################################################## -# -# Copyright (c) 2009 Peter Stephenson -# Copyright (c) 2011 Guido van Steen -# Copyright (c) 2011 Suraj N. Kurapati -# Copyright (c) 2011 Sorin Ionescu -# Copyright (c) 2011 Vincent Guerci -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# -# * Neither the name of the FIZSH nor the names of its contributors -# may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################## - -#----------------------------------------------------------------------------- -# configuration variables -#----------------------------------------------------------------------------- - -HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND='bg=magenta,fg=white,bold' -HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=white,bold' -HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i' - -#----------------------------------------------------------------------------- -# the main ZLE widgets -#----------------------------------------------------------------------------- - -function history-substring-search-up { - _history-substring-search-begin - - _history-substring-search-up-history || - _history-substring-search-up-buffer || - _history-substring-search-up-search - - _history-substring-search-end -} - -function history-substring-search-down { - _history-substring-search-begin - - _history-substring-search-down-history || - _history-substring-search-down-buffer || - _history-substring-search-down-search - - _history-substring-search-end -} - -zle -N history-substring-search-up -zle -N history-substring-search-down - -bindkey '\e[A' history-substring-search-up -bindkey '\e[B' history-substring-search-down - -#----------------------------------------------------------------------------- -# implementation details -#----------------------------------------------------------------------------- - -zmodload -F zsh/parameter - -# -# We have to "override" some keys and widgets if the -# zsh-syntax-highlighting plugin has not been loaded: -# -# https://github.com/nicoulaj/zsh-syntax-highlighting -# -if [[ $+functions[_zsh_highlight] -eq 0 ]]; then - # - # Dummy implementation of _zsh_highlight() that - # simply removes any existing highlights when the - # user inserts printable characters into $BUFFER. - # - function _zsh_highlight { - if [[ $KEYS == [[:print:]] ]]; then - region_highlight=() - fi - } - - # - # The following snippet was taken from the zsh-syntax-highlighting project: - # - # https://github.com/zsh-users/zsh-syntax-highlighting/blob/56b134f5d62ae3d4e66c7f52bd0cc2595f9b305b/zsh-syntax-highlighting.zsh#L126-161 - # - # Copyright (c) 2010-2011 zsh-syntax-highlighting contributors - # All rights reserved. - # - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions are - # met: - # - # * Redistributions of source code must retain the above copyright - # notice, this list of conditions and the following disclaimer. - # - # * Redistributions in binary form must reproduce the above copyright - # notice, this list of conditions and the following disclaimer in the - # documentation and/or other materials provided with the distribution. - # - # * Neither the name of the zsh-syntax-highlighting contributors nor the - # names of its contributors may be used to endorse or promote products - # derived from this software without specific prior written permission. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - # - #--------------8<-------------------8<-------------------8<----------------- - # Rebind all ZLE widgets to make them invoke _zsh_highlights. - function _zsh_highlight_bind_widgets { - # Load Zsh module zsh/zleparameter, needed to override user defined widgets. - zmodload zsh/zleparameter 2>/dev/null || { - print 'history-substring-search: failed loading: zsh/zleparameter' >&2 - return 1 - } - - # Override ZLE widgets to make them invoke _zsh_highlight. - local cur_widget - for cur_widget in ${${(f)"$(builtin zle -la)"}:#(.*|_*|orig-*|run-help|which-command|beep)}; do - case $widgets[$cur_widget] in - - # Already rebound event: do nothing. - user:$cur_widget|user:_zsh_highlight_widget_*);; - - # User defined widget: override and rebind old one with prefix "orig-". - user:*) eval "zle -N orig-$cur_widget ${widgets[$cur_widget]#*:}; \ - _zsh_highlight_widget_$cur_widget() { builtin zle orig-$cur_widget -- \"\$@\" && _zsh_highlight }; \ - zle -N $cur_widget _zsh_highlight_widget_$cur_widget";; - - # Completion widget: override and rebind old one with prefix "orig-". - completion:*) eval "zle -C orig-$cur_widget ${${widgets[$cur_widget]#*:}/:/ }; \ - _zsh_highlight_widget_$cur_widget() { builtin zle orig-$cur_widget -- \"\$@\" && _zsh_highlight }; \ - zle -N $cur_widget _zsh_highlight_widget_$cur_widget";; - - # Builtin widget: override and make it call the builtin ".widget". - builtin) eval "function _zsh_highlight_widget_$cur_widget { builtin zle .$cur_widget -- \"\$@\" && _zsh_highlight }; \ - zle -N $cur_widget _zsh_highlight_widget_$cur_widget";; - - # Default: unhandled case. - *) print "history-substring-search: unhandled ZLE widget: $cur_widget" >&2 ;; - esac - done - } - #-------------->8------------------->8------------------->8----------------- - - _zsh_highlight_bind_widgets -fi - -function _history-substring-search-begin { - setopt LOCAL_OPTIONS EXTENDED_GLOB - - _history_substring_search_move_cursor_eol=false - _history_substring_search_query_highlight= - - # - # Continue using the previous $_history_substring_search_result by default, - # unless the current query was cleared or a new/different query was entered. - # - if [[ -z $BUFFER || $BUFFER != $_history_substring_search_result ]]; then - # - # For the purpose of highlighting we will also keep - # a version without doubly-escaped meta characters. - # - _history_substring_search_query=$BUFFER - - # - # $BUFFER contains the text that is in the command-line currently. - # we put an extra "\\" before meta characters such as "\(" and "\)", - # so that they become "\\\(" and "\\\)". - # - _history_substring_search_query_escaped=${BUFFER//(#m)[\][()|\\*?#<>~^]/\\$MATCH} - - # - # Find all occurrences of the search query in the history file. - # - # (k) turns it an array of line numbers. - # - # (on) seems to remove duplicates, which are default - # options. They can be turned off by (ON). - # - _history_substring_search_matches=(${(kon)history[(R)(#$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)*${_history_substring_search_query_escaped}*]}) - - # - # Define the range of values that $_history_substring_search_match_index - # can take: [0, $_history_substring_search_matches_count_plus]. - # - _history_substring_search_matches_count=$#_history_substring_search_matches - _history_substring_search_matches_count_plus=$(( _history_substring_search_matches_count + 1 )) - _history_substring_search_matches_count_sans=$(( _history_substring_search_matches_count - 1 )) - - # - # If $_history_substring_search_match_index is equal to - # $_history_substring_search_matches_count_plus, this indicates that we - # are beyond the beginning of $_history_substring_search_matches. - # - # If $_history_substring_search_match_index is equal to 0, this indicates - # that we are beyond the end of $_history_substring_search_matches. - # - # If we have initially pressed "up" we have to initialize - # $_history_substring_search_match_index to - # $_history_substring_search_matches_count_plus so that it will be - # decreased to $_history_substring_search_matches_count. - # - # If we have initially pressed "down" we have to initialize - # $_history_substring_search_match_index to - # $_history_substring_search_matches_count so that it will be increased to - # $_history_substring_search_matches_count_plus. - # - if [[ $WIDGET == history-substring-search-down ]]; then - _history_substring_search_match_index=$_history_substring_search_matches_count - else - _history_substring_search_match_index=$_history_substring_search_matches_count_plus - fi - fi -} - -function _history-substring-search-end { - setopt LOCAL_OPTIONS EXTENDED_GLOB - - _history_substring_search_result=$BUFFER - - # move the cursor to the end of the command line - if [[ $_history_substring_search_move_cursor_eol == true ]]; then - CURSOR=${#BUFFER} - fi - - # highlight command line using zsh-syntax-highlighting - _zsh_highlight - - # highlight the search query inside the command line - if [[ -n $_history_substring_search_query_highlight && -n $_history_substring_search_query ]]; then - # - # The following expression yields a variable $MBEGIN, which - # indicates the begin position + 1 of the first occurrence - # of _history_substring_search_query_escaped in $BUFFER. - # - : ${(S)BUFFER##(#m$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)($_history_substring_search_query##)} - local begin=$(( MBEGIN - 1 )) - local end=$(( begin + $#_history_substring_search_query )) - region_highlight+=("$begin $end $_history_substring_search_query_highlight") - fi - - # For debugging purposes: - # zle -R "mn: "$_history_substring_search_match_index" m#: "${#_history_substring_search_matches} - # read -k -t 200 && zle -U $REPLY - - # Exit successfully from the history-substring-search-* widgets. - true -} - -function _history-substring-search-up-buffer { - # - # Check if the UP arrow was pressed to move the cursor within a multi-line - # buffer. This amounts to three tests: - # - # 1. $#buflines -gt 1. - # - # 2. $CURSOR -ne $#BUFFER. - # - # 3. Check if we are on the first line of the current multi-line buffer. - # If so, pressing UP would amount to leaving the multi-line buffer. - # - # We check this by adding an extra "x" to $LBUFFER, which makes - # sure that xlbuflines is always equal to the number of lines - # until $CURSOR (including the line with the cursor on it). - # - local buflines XLBUFFER xlbuflines - buflines=(${(f)BUFFER}) - XLBUFFER=$LBUFFER"x" - xlbuflines=(${(f)XLBUFFER}) - - if [[ $#buflines -gt 1 && $CURSOR -ne $#BUFFER && $#xlbuflines -ne 1 ]]; then - zle up-line-or-history - return true - fi - - false -} - -function _history-substring-search-down-buffer { - # - # Check if the DOWN arrow was pressed to move the cursor within a multi-line - # buffer. This amounts to three tests: - # - # 1. $#buflines -gt 1. - # - # 2. $CURSOR -ne $#BUFFER. - # - # 3. Check if we are on the last line of the current multi-line buffer. - # If so, pressing DOWN would amount to leaving the multi-line buffer. - # - # We check this by adding an extra "x" to $RBUFFER, which makes - # sure that xrbuflines is always equal to the number of lines - # from $CURSOR (including the line with the cursor on it). - # - local buflines XRBUFFER xrbuflines - buflines=(${(f)BUFFER}) - XRBUFFER="x"$RBUFFER - xrbuflines=(${(f)XRBUFFER}) - - if [[ $#buflines -gt 1 && $CURSOR -ne $#BUFFER && $#xrbuflines -ne 1 ]]; then - zle down-line-or-history - return true - fi - - false -} - -function _history-substring-search-up-history { - # - # Behave like up in Zsh, except clear the $BUFFER - # when beginning of history is reached like in Fish. - # - if [[ -z $_history_substring_search_query ]]; then - - # we have reached the absolute top of history - if [[ $HISTNO -eq 1 ]]; then - BUFFER= - - # going up from somewhere below the top of history - else - zle up-line-or-history - fi - - return true - fi - - false -} - -function _history-substring-search-down-history { - # - # Behave like down-history in Zsh, except clear the - # $BUFFER when end of history is reached like in Fish. - # - if [[ -z $_history_substring_search_query ]]; then - - # going down from the absolute top of history - if [[ $HISTNO -eq 1 && -z $BUFFER ]]; then - BUFFER=${history[1]} - _history_substring_search_move_cursor_eol=true - - # going down from somewhere above the bottom of history - else - zle down-line-or-history - fi - - return true - fi - - false -} - -function _history-substring-search-up-search { - _history_substring_search_move_cursor_eol=true - - # - # Highlight matches during history-substring-up-search: - # - # The following constants have been initialized in - # _history-substring-search-up/down-search(): - # - # $_history_substring_search_matches is the current list of matches - # $_history_substring_search_matches_count is the current number of matches - # $_history_substring_search_matches_count_plus is the current number of matches + 1 - # $_history_substring_search_matches_count_sans is the current number of matches - 1 - # $_history_substring_search_match_index is the index of the current match - # - # The range of values that $_history_substring_search_match_index can take - # is: [0, $_history_substring_search_matches_count_plus]. A value of 0 - # indicates that we are beyond the end of - # $_history_substring_search_matches. A value of - # $_history_substring_search_matches_count_plus indicates that we are beyond - # the beginning of $_history_substring_search_matches. - # - # In _history-substring-search-up-search() the initial value of - # $_history_substring_search_match_index is - # $_history_substring_search_matches_count_plus. This value is set in - # _history-substring-search-begin(). _history-substring-search-up-search() - # will initially decrease it to $_history_substring_search_matches_count. - # - if [[ $_history_substring_search_match_index -ge 2 ]]; then - # - # Highlight the next match: - # - # 1. Decrease the value of $_history_substring_search_match_index. - # - # 2. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND - # to highlight the current buffer. - # - (( _history_substring_search_match_index-- )) - BUFFER=$history[$_history_substring_search_matches[$_history_substring_search_match_index]] - _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND - - elif [[ $_history_substring_search_match_index -eq 1 ]]; then - # - # We will move beyond the end of $_history_substring_search_matches: - # - # 1. Decrease the value of $_history_substring_search_match_index. - # - # 2. Save the current buffer in $_history_substring_search_old_buffer, - # so that it can be retrieved by - # _history-substring-search-down-search() later. - # - # 3. Make $BUFFER equal to $_history_substring_search_query. - # - # 4. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND - # to highlight the current buffer. - # - (( _history_substring_search_match_index-- )) - _history_substring_search_old_buffer=$BUFFER - BUFFER=$_history_substring_search_query - _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND - - elif [[ $_history_substring_search_match_index -eq $_history_substring_search_matches_count_plus ]]; then - # - # We were beyond the beginning of $_history_substring_search_matches but - # UP makes us move back to $_history_substring_search_matches: - # - # 1. Decrease the value of $_history_substring_search_match_index. - # - # 2. Restore $BUFFER from $_history_substring_search_old_buffer. - # - # 3. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND - # to highlight the current buffer. - # - (( _history_substring_search_match_index-- )) - BUFFER=$_history_substring_search_old_buffer - _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND - fi -} - -function _history-substring-search-down-search { - _history_substring_search_move_cursor_eol=true - - # - # Highlight matches during history-substring-up-search: - # - # The following constants have been initialized in - # _history-substring-search-up/down-search(): - # - # $_history_substring_search_matches is the current list of matches - # $_history_substring_search_matches_count is the current number of matches - # $_history_substring_search_matches_count_plus is the current number of matches + 1 - # $_history_substring_search_matches_count_sans is the current number of matches - 1 - # $_history_substring_search_match_index is the index of the current match - # - # The range of values that $_history_substring_search_match_index can take - # is: [0, $_history_substring_search_matches_count_plus]. A value of 0 - # indicates that we are beyond the end of - # $_history_substring_search_matches. A value of - # $_history_substring_search_matches_count_plus indicates that we are beyond - # the beginning of $_history_substring_search_matches. - # - # In _history-substring-search-down-search() the initial value of - # $_history_substring_search_match_index is - # $_history_substring_search_matches_count. This value is set in - # _history-substring-search-begin(). - # _history-substring-search-down-search() will initially increase it to - # $_history_substring_search_matches_count_plus. - # - if [[ $_history_substring_search_match_index -le $_history_substring_search_matches_count_sans ]]; then - # - # Highlight the next match: - # - # 1. Increase $_history_substring_search_match_index by 1. - # - # 2. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND - # to highlight the current buffer. - # - (( _history_substring_search_match_index++ )) - BUFFER=$history[$_history_substring_search_matches[$_history_substring_search_match_index]] - _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND - - elif [[ $_history_substring_search_match_index -eq $_history_substring_search_matches_count ]]; then - # - # We will move beyond the beginning of $_history_substring_search_matches: - # - # 1. Increase $_history_substring_search_match_index by 1. - # - # 2. Save the current buffer in $_history_substring_search_old_buffer, so - # that it can be retrieved by _history-substring-search-up-search() - # later. - # - # 3. Make $BUFFER equal to $_history_substring_search_query. - # - # 4. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND - # to highlight the current buffer. - # - (( _history_substring_search_match_index++ )) - _history_substring_search_old_buffer=$BUFFER - BUFFER=$_history_substring_search_query - _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND - - elif [[ $_history_substring_search_match_index -eq 0 ]]; then - # - # We were beyond the end of $_history_substring_search_matches but DOWN - # makes us move back to the $_history_substring_search_matches: - # - # 1. Increase $_history_substring_search_match_index by 1. - # - # 2. Restore $BUFFER from $_history_substring_search_old_buffer. - # - # 3. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND - # to highlight the current buffer. - # - (( _history_substring_search_match_index++ )) - BUFFER=$_history_substring_search_old_buffer - _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND - fi -} - -# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- -# vim: ft=zsh sw=2 ts=2 et - diff --git a/plugins/history-substring-search/init.zsh b/plugins/history-substring-search/init.zsh index 8d3403f..66ffaec 100644 --- a/plugins/history-substring-search/init.zsh +++ b/plugins/history-substring-search/init.zsh @@ -6,7 +6,7 @@ # Sorin Ionescu # -source "${0:h}/history-substring-search.zsh" +source "${0:h}/external/zsh-history-substring-search.zsh" if zstyle -t ':omz:plugin:history-substring-search' case-sensitive; then unset HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS