Skip to content

Commit bb61e5c

Browse files
committed
Add support for custom history providers
Adds `HISTORY_SUBSTRING_SEARCH_MATCH_FUNCTION` option to allow specification of a custom function for sourcing matching commands.
1 parent 87ce96b commit bb61e5c

File tree

2 files changed

+54
-22
lines changed

2 files changed

+54
-22
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,27 @@ default values.
215215
* `HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_TIMEOUT` is a global variable that
216216
defines a timeout in seconds for clearing the search highlight.
217217

218+
* `HISTORY_SUBSTRING_SEARCH_MATCH_FUNCTION` is a global variable that defines
219+
the name of a function for getting matches from custom history providers.
220+
221+
For example, to integrate with [`histdb`](https://github.com/larkery/zsh-histdb)
222+
the following function could be used:
223+
224+
```bash
225+
function _history-substring-get-raw-matches-histdb {
226+
local SEP=$(printf $'\1') # column separator
227+
local results=$(
228+
histdb --sep ${SEP} ${_history_substring_search_query_parts[@]} |
229+
tail -n +2 | # kill header
230+
sed 's/\(.\+\)[^\x01]\x01/&\x00/' | # add \0 to separate records
231+
cut -d ${SEP} -f 4 # get the command column
232+
)
233+
_history_substring_search_raw_matches=(${(ps:\0:)results})
234+
_history_substring_search_raw_matches=(${_history_substring_search_raw_matches[@]%$'\n'})
235+
}
236+
237+
HISTORY_SUBSTRING_SEARCH_MATCH_FUNCTION="_history-substring-get-raw-matches-histdb"
238+
```
218239

219240
History
220241
------------------------------------------------------------------------------

zsh-history-substring-search.zsh

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
: ${HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE=''}
5050
: ${HISTORY_SUBSTRING_SEARCH_FUZZY=''}
5151
: ${HISTORY_SUBSTRING_SEARCH_PREFIXED=''}
52+
: ${HISTORY_SUBSTRING_SEARCH_MATCH_FUNCTION=''}
5253

5354
#-----------------------------------------------------------------------------
5455
# declare internal global variables
@@ -245,6 +246,30 @@ if [[ $+functions[_zsh_highlight] -eq 0 ]]; then
245246
unfunction _history-substring-search-function-callable
246247
fi
247248

249+
_history-substring-get-raw-matches() {
250+
#
251+
# Escape and join query parts with wildcard character '*' as separator
252+
# `(j:CHAR:)` join array to string with CHAR as separator
253+
#
254+
local search_pattern="${(j:*:)_history_substring_search_query_parts[@]//(#m)[\][()|\\*?#<>~^]/\\$MATCH}*"
255+
256+
#
257+
# Support anchoring history search to the beginning of the command
258+
#
259+
if [[ -z $HISTORY_SUBSTRING_SEARCH_PREFIXED ]]; then
260+
search_pattern="*${search_pattern}"
261+
fi
262+
263+
#
264+
# Find all occurrences of the search pattern in the history file.
265+
#
266+
# (k) returns the "keys" (history index numbers) instead of the values
267+
# (R) returns values in reverse older, so the index of the youngest
268+
# matching history entry is at the head of the list.
269+
#
270+
_history_substring_search_raw_matches=(${(k)history[(R)(#$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)${search_pattern}]})
271+
}
272+
248273
_history-substring-search-begin() {
249274
setopt localoptions extendedglob
250275

@@ -294,27 +319,7 @@ _history-substring-search-begin() {
294319
_history_substring_search_query_parts=(${==_history_substring_search_query})
295320
fi
296321

297-
#
298-
# Escape and join query parts with wildcard character '*' as seperator
299-
# `(j:CHAR:)` join array to string with CHAR as seperator
300-
#
301-
local search_pattern="${(j:*:)_history_substring_search_query_parts[@]//(#m)[\][()|\\*?#<>~^]/\\$MATCH}*"
302-
303-
#
304-
# Support anchoring history search to the beginning of the command
305-
#
306-
if [[ -z $HISTORY_SUBSTRING_SEARCH_PREFIXED ]]; then
307-
search_pattern="*${search_pattern}"
308-
fi
309-
310-
#
311-
# Find all occurrences of the search pattern in the history file.
312-
#
313-
# (k) returns the "keys" (history index numbers) instead of the values
314-
# (R) returns values in reverse older, so the index of the youngest
315-
# matching history entry is at the head of the list.
316-
#
317-
_history_substring_search_raw_matches=(${(k)history[(R)(#$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)${search_pattern}]})
322+
${HISTORY_SUBSTRING_SEARCH_MATCH_FUNCTION:-_history-substring-get-raw-matches}
318323
fi
319324

320325
#
@@ -655,7 +660,13 @@ _history-substring-search-found() {
655660
# 2. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND
656661
# to highlight the current buffer.
657662
#
658-
BUFFER=$history[$_history_substring_search_matches[$_history_substring_search_match_index]]
663+
if [[ -n $HISTORY_SUBSTRING_SEARCH_MATCH_FUNCTION ]]; then
664+
# Custom provider functions provide entries directly
665+
BUFFER=$_history_substring_search_matches[$_history_substring_search_match_index]
666+
else
667+
# Builtin search provides the index to matching history entries
668+
BUFFER=$history[$_history_substring_search_matches[$_history_substring_search_match_index]]
669+
fi
659670
_history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND
660671
}
661672

0 commit comments

Comments
 (0)