diff options
Diffstat (limited to 'Src/Zle/zle_hist.c')
-rw-r--r-- | Src/Zle/zle_hist.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c index 38f32b97c..2fdda1696 100644 --- a/Src/Zle/zle_hist.c +++ b/Src/Zle/zle_hist.c @@ -49,6 +49,10 @@ ZLE_STRING_T previous_search = NULL; /**/ int previous_search_len = 0; + +/*** History text manipulation utilities ***/ + + struct zle_text { ZLE_STRING_T text; int len; @@ -133,6 +137,88 @@ forget_edits(void) } } + +/*** Search utilities ***/ + + +/* + * Return zero if the ZLE string histp length histl and the ZLE string + * inputp length inputl are the same. Return -1 if inputp is a prefix + * of histp. Return 1 if inputp is the lowercase version of histp. + * Return 2 if inputp is the lowercase prefix of histp and return 3 + * otherwise. + */ + +static int +zlinecmp(ZLE_STRING_T histp, int histl, ZLE_STRING_T inputp, int inputl) +{ + int cnt; + + if (histl < inputl) { + /* Not identical, second string is not a prefix. */ + return 3; + } + + if (!ZS_memcmp(histp, inputp, inputl)) { + /* Common prefix is identical */ + /* If lines are identical return 0 */ + if (histl == inputl) + return 0; + /* Second string is a prefix of the first */ + return -1; + } + + for (cnt = inputl; cnt; cnt--) { + if ((ZLE_INT_T)*inputp++ != ZC_tolower(*histp++)) + return 3; + } + /* Is second string is lowercase version of first? */ + if (histl == inputl) + return 1; + /* Second string is lowercase prefix of first */ + return 2; +} + + +/* + * Search for needle in haystack. Haystack and needle are ZLE strings + * of the indicated length. Start the search at position + * pos in haystack. Search forward if dir > 0, otherwise search + * backward. sens is used to test against the return value of linecmp. + */ + +static ZLE_STRING_T +zlinefind(ZLE_STRING_T haystack, int haylen, int pos, + ZLE_STRING_T needle, int needlen, int dir, int sens) +{ + ZLE_STRING_T s = haystack + pos; + int slen = haylen - pos; + + if (dir > 0) { + while (slen) { + if (zlinecmp(s, slen, needle, needlen) < sens) + return s; + s++; + slen--; + } + } else { + for (;;) { + if (zlinecmp(s, slen, needle, needlen) < sens) + return s; + if (s == haystack) + break; + s--; + slen++; + } + } + + return NULL; +} + + +/*** Widgets ***/ + + /**/ int uphistory(UNUSED(char **args)) |