mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-12-16 21:10:55 +01:00
20863: fix history (i)searching for Unicode
This commit is contained in:
parent
29b6b82ade
commit
ddd172ebe2
6 changed files with 335 additions and 172 deletions
|
|
@ -12,6 +12,10 @@
|
||||||
|
|
||||||
2005-02-24 Peter Stephenson <pws@csr.com>
|
2005-02-24 Peter Stephenson <pws@csr.com>
|
||||||
|
|
||||||
|
* 20863: Src/utils.c, Src/zsh.h, Src/Zle/zle.h,
|
||||||
|
Src/Zle/zle_hist.c, Src/Zle/zle_utils.c: fix history (i)searching
|
||||||
|
for Unicode.
|
||||||
|
|
||||||
* 20861: Src/Zle/complist.c, Src/Zle/zle.h, Src/Zle/zle_hist.c,
|
* 20861: Src/Zle/complist.c, Src/Zle/zle.h, Src/Zle/zle_hist.c,
|
||||||
Src/Zle/zle_main.c, Src/Zle/zle_misc.c, Src/Zle/zle_refresh.c,
|
Src/Zle/zle_main.c, Src/Zle/zle_misc.c, Src/Zle/zle_refresh.c,
|
||||||
Src/Zle/zle_thingy.c, Src/Zle/zle_vi.c: Fix use of statusline
|
Src/Zle/zle_thingy.c, Src/Zle/zle_vi.c: Fix use of statusline
|
||||||
|
|
|
||||||
|
|
@ -53,12 +53,21 @@ typedef wint_t ZLE_INT_T;
|
||||||
#define ZS_memcpy wmemcpy
|
#define ZS_memcpy wmemcpy
|
||||||
#define ZS_memmove wmemmove
|
#define ZS_memmove wmemmove
|
||||||
#define ZS_memset wmemset
|
#define ZS_memset wmemset
|
||||||
|
#define ZS_memcmp wmemcmp
|
||||||
#define ZS_strlen wcslen
|
#define ZS_strlen wcslen
|
||||||
#define ZS_strcpy wcscpy
|
#define ZS_strcpy wcscpy
|
||||||
#define ZS_strncpy wcsncpy
|
#define ZS_strncpy wcsncpy
|
||||||
#define ZS_strncmp wcsncmp
|
#define ZS_strncmp wcsncmp
|
||||||
|
|
||||||
#define ZC_icntrl iswcntrl
|
#define ZC_icntrl iswcntrl
|
||||||
|
#define ZC_iblank iswspace
|
||||||
|
/*
|
||||||
|
* TODO: doesn't work on arguments with side effects.
|
||||||
|
* Also YUK. Not even sure this is guaranteed to work.
|
||||||
|
*/
|
||||||
|
#define ZC_iident(x) (x < 256 && iident((int)x))
|
||||||
|
|
||||||
|
#define ZC_tolower towlower
|
||||||
|
|
||||||
#define LASTFULLCHAR lastchar_wide
|
#define LASTFULLCHAR lastchar_wide
|
||||||
|
|
||||||
|
|
@ -78,12 +87,17 @@ typedef int ZLE_INT_T;
|
||||||
#define ZS_memcpy memcpy
|
#define ZS_memcpy memcpy
|
||||||
#define ZS_memmove memmove
|
#define ZS_memmove memmove
|
||||||
#define ZS_memset memset
|
#define ZS_memset memset
|
||||||
|
#define ZS_memcmp memcmp
|
||||||
#define ZS_strlen strlen
|
#define ZS_strlen strlen
|
||||||
#define ZS_strcpy strcpy
|
#define ZS_strcpy strcpy
|
||||||
#define ZS_strncpy strncpy
|
#define ZS_strncpy strncpy
|
||||||
#define ZS_strncmp strncmp
|
#define ZS_strncmp strncmp
|
||||||
|
|
||||||
#define ZC_icntrl icntrl
|
#define ZC_icntrl icntrl
|
||||||
|
#define ZC_iblank iblank
|
||||||
|
#define ZC_iident iident
|
||||||
|
|
||||||
|
#define ZC_tolower tulower
|
||||||
|
|
||||||
#define LASTFULLCHAR lastchar
|
#define LASTFULLCHAR lastchar
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,21 +44,71 @@ int histline;
|
||||||
/* Previous search string use in an incremental search */
|
/* Previous search string use in an incremental search */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
char *previous_search = NULL;
|
ZLE_STRING_T previous_search = NULL;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int previous_search_len = 0;
|
int previous_search_len = 0;
|
||||||
|
|
||||||
#define ZLETEXT(X) ((X)->zle_text ? (X)->zle_text : (X)->text)
|
struct zle_text {
|
||||||
|
ZLE_STRING_T text;
|
||||||
|
int len;
|
||||||
|
int alloced;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fetch the text of a history line in internal ZLE format.
|
||||||
|
* If the line has been edited, returns that, else allocates
|
||||||
|
* a converted line.
|
||||||
|
*
|
||||||
|
* Each use of this must have a matching zletextfree() in order
|
||||||
|
* to free up the allocated line, if any. (N.B.: each use *of
|
||||||
|
* the function*, not just each use of a struct zle_text.)
|
||||||
|
*
|
||||||
|
* TODO: This is quite inefficient. We could convert zlinecmp and
|
||||||
|
* zlinefind to take a metafied string as input and acquire a (wide)
|
||||||
|
* character from it whenever needed, which would also require storing
|
||||||
|
* zle_text as a metafied string in remember_edits(). However, the
|
||||||
|
* following is good enough for now (although searching a really huge
|
||||||
|
* history might not be so much fun).
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
zletext(Histent ent, struct zle_text *zt)
|
||||||
|
{
|
||||||
|
if (ent->zle_text) {
|
||||||
|
zt->text = ent->zle_text;
|
||||||
|
zt->len = ent->zle_len;
|
||||||
|
zt->alloced = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zt->text = stringaszleline(ent->text, &zt->len, NULL);
|
||||||
|
zt->alloced = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See above. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
zletextfree(struct zle_text *zt)
|
||||||
|
{
|
||||||
|
if (zt->alloced) {
|
||||||
|
free(zt->text);
|
||||||
|
zt->alloced = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
remember_edits(void)
|
remember_edits(void)
|
||||||
{
|
{
|
||||||
Histent ent = quietgethist(histline);
|
Histent ent = quietgethist(histline);
|
||||||
if (ent && metadiffer(ZLETEXT(ent), (char *) zleline, zlell)) {
|
if (ent) {
|
||||||
zsfree(ent->zle_text);
|
if (!ent->zle_text || ent->zle_len != zlell ||
|
||||||
ent->zle_text = metafy((char *) zleline, zlell, META_DUP);
|
ZS_memcmp(ent->zle_text, zleline, zlell) != 0) {
|
||||||
|
if (ent->zle_text)
|
||||||
|
free(ent->zle_text);
|
||||||
|
ent->zle_text = stringaszleline(ent->text, &ent->zle_len, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,8 +119,11 @@ forget_edits(void)
|
||||||
Histent he;
|
Histent he;
|
||||||
|
|
||||||
for (he = hist_ring; he; he = up_histent(he)) {
|
for (he = hist_ring; he; he = up_histent(he)) {
|
||||||
zsfree(he->zle_text);
|
if (he->zle_text) {
|
||||||
he->zle_text = NULL;
|
free(he->zle_text);
|
||||||
|
he->zle_text = NULL;
|
||||||
|
he->zle_len = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,7 +330,7 @@ downhistory(UNUSED(char **args))
|
||||||
}
|
}
|
||||||
|
|
||||||
static int histpos, srch_hl, srch_cs = -1;
|
static int histpos, srch_hl, srch_cs = -1;
|
||||||
static char *srch_str;
|
static ZLE_STRING_T srch_str;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
|
|
@ -285,7 +338,8 @@ historysearchbackward(char **args)
|
||||||
{
|
{
|
||||||
Histent he;
|
Histent he;
|
||||||
int n = zmult, hp;
|
int n = zmult, hp;
|
||||||
char *s, *str;
|
ZLE_STRING_T str;
|
||||||
|
struct zle_text zt;
|
||||||
|
|
||||||
if (zmult < 0) {
|
if (zmult < 0) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
@ -294,37 +348,46 @@ historysearchbackward(char **args)
|
||||||
zmult = n;
|
zmult = n;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if ((str = *args))
|
if (*args) {
|
||||||
hp = strlen(str);
|
str = stringaszleline((unsigned char *)*args, &hp, NULL);
|
||||||
else {
|
} else {
|
||||||
if (histline == curhist || histline != srch_hl || zlecs != srch_cs ||
|
if (histline == curhist || histline != srch_hl || zlecs != srch_cs ||
|
||||||
mark != 0 || memcmp(srch_str, zleline, histpos) != 0) {
|
mark != 0 || ZS_memcmp(srch_str, zleline, histpos) != 0) {
|
||||||
zfree(srch_str, histpos);
|
zfree(srch_str, histpos);
|
||||||
for (histpos = 0; histpos < zlell && !iblank(zleline[histpos]); histpos++) ;
|
for (histpos = 0; histpos < zlell && !ZC_iblank(zleline[histpos]); histpos++) ;
|
||||||
if (histpos < zlell)
|
if (histpos < zlell)
|
||||||
histpos++;
|
histpos++;
|
||||||
srch_str = zalloc(histpos);
|
srch_str = zalloc(histpos * ZLE_CHAR_SIZE);
|
||||||
memcpy(srch_str, zleline, histpos);
|
ZS_memcpy(srch_str, zleline, histpos);
|
||||||
}
|
}
|
||||||
str = srch_str;
|
str = srch_str;
|
||||||
hp = histpos;
|
hp = histpos;
|
||||||
}
|
}
|
||||||
if (!(he = quietgethist(histline)))
|
if (!(he = quietgethist(histline))) {
|
||||||
|
if (*args)
|
||||||
|
free(str);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
while ((he = movehistent(he, -1, hist_skip_flags))) {
|
while ((he = movehistent(he, -1, hist_skip_flags))) {
|
||||||
if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
|
if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
|
||||||
continue;
|
continue;
|
||||||
s = ZLETEXT(he);
|
zletext(he, &zt);
|
||||||
if (metadiffer(s, str, hp) < 0 &&
|
if (zlinecmp(zt.text, zt.len, str, hp) < 0 &&
|
||||||
(*args || metadiffer(s, str, zlell))) {
|
(*args || zlell != zt.len || ZS_memcmp(zt.text, str, zlell))) {
|
||||||
if (--n <= 0) {
|
if (--n <= 0) {
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
srch_hl = histline;
|
srch_hl = histline;
|
||||||
srch_cs = zlecs;
|
srch_cs = zlecs;
|
||||||
|
if (*args)
|
||||||
|
free(str);
|
||||||
|
zletextfree(&zt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
zletextfree(&zt);
|
||||||
}
|
}
|
||||||
|
if (*args)
|
||||||
|
free(str);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -334,7 +397,8 @@ historysearchforward(char **args)
|
||||||
{
|
{
|
||||||
Histent he;
|
Histent he;
|
||||||
int n = zmult, hp;
|
int n = zmult, hp;
|
||||||
char *s, *str;
|
ZLE_STRING_T str;
|
||||||
|
struct zle_text zt;
|
||||||
|
|
||||||
if (zmult < 0) {
|
if (zmult < 0) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
@ -343,37 +407,46 @@ historysearchforward(char **args)
|
||||||
zmult = n;
|
zmult = n;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if ((str = *args))
|
if (*args) {
|
||||||
hp = strlen(str);
|
str = stringaszleline((unsigned char *)*args, &hp, NULL);
|
||||||
else {
|
} else {
|
||||||
if (histline == curhist || histline != srch_hl || zlecs != srch_cs ||
|
if (histline == curhist || histline != srch_hl || zlecs != srch_cs ||
|
||||||
mark != 0 || memcmp(srch_str, zleline, histpos) != 0) {
|
mark != 0 || ZS_memcmp(srch_str, zleline, histpos) != 0) {
|
||||||
zfree(srch_str, histpos);
|
zfree(srch_str, histpos * ZLE_CHAR_SIZE);
|
||||||
for (histpos = 0; histpos < zlell && !iblank(zleline[histpos]); histpos++) ;
|
for (histpos = 0; histpos < zlell && !ZC_iblank(zleline[histpos]); histpos++) ;
|
||||||
if (histpos < zlell)
|
if (histpos < zlell)
|
||||||
histpos++;
|
histpos++;
|
||||||
srch_str = zalloc(histpos);
|
srch_str = zalloc(histpos * ZLE_CHAR_SIZE);
|
||||||
memcpy(srch_str, zleline, histpos);
|
ZS_memcpy(srch_str, zleline, histpos);
|
||||||
}
|
}
|
||||||
str = srch_str;
|
str = srch_str;
|
||||||
hp = histpos;
|
hp = histpos;
|
||||||
}
|
}
|
||||||
if (!(he = quietgethist(histline)))
|
if (!(he = quietgethist(histline))) {
|
||||||
|
if (*args)
|
||||||
|
free(str);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
while ((he = movehistent(he, 1, hist_skip_flags))) {
|
while ((he = movehistent(he, 1, hist_skip_flags))) {
|
||||||
if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
|
if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
|
||||||
continue;
|
continue;
|
||||||
s = ZLETEXT(he);
|
zletext(he, &zt);
|
||||||
if (metadiffer(s, str, hp) < (he->histnum == curhist) &&
|
if (zlinecmp(zt.text, zt.len, str, hp) < (he->histnum == curhist) &&
|
||||||
(*args || metadiffer(s, str, zlell))) {
|
(*args || zlell != zt.len || ZS_memcmp(zt.text, str, zlell))) {
|
||||||
if (--n <= 0) {
|
if (--n <= 0) {
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
srch_hl = histline;
|
srch_hl = histline;
|
||||||
srch_cs = zlecs;
|
srch_cs = zlecs;
|
||||||
|
if (*args)
|
||||||
|
free(str);
|
||||||
|
zletextfree(&zt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
zletextfree(&zt);
|
||||||
}
|
}
|
||||||
|
if (*args)
|
||||||
|
free(str);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -420,7 +493,7 @@ endofhistory(UNUSED(char **args))
|
||||||
int
|
int
|
||||||
insertlastword(char **args)
|
insertlastword(char **args)
|
||||||
{
|
{
|
||||||
int n, nwords, histstep = -1, wordpos = 0, deleteword = 0, len, sz;
|
int n, nwords, histstep = -1, wordpos = 0, deleteword = 0, len;
|
||||||
char *s, *t;
|
char *s, *t;
|
||||||
Histent he = NULL;
|
Histent he = NULL;
|
||||||
LinkList l = NULL;
|
LinkList l = NULL;
|
||||||
|
|
@ -556,9 +629,9 @@ insertlastword(char **args)
|
||||||
n = zmult;
|
n = zmult;
|
||||||
zmult = 1;
|
zmult = 1;
|
||||||
|
|
||||||
zs = stringaszleline((unsigned char *)s, &len, &sz);
|
zs = stringaszleline((unsigned char *)s, &len, NULL);
|
||||||
doinsert(zs, len);
|
doinsert(zs, len);
|
||||||
zfree(zs, sz);
|
free(zs);
|
||||||
zmult = n;
|
zmult = n;
|
||||||
*t = save;
|
*t = save;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -571,7 +644,23 @@ zle_setline(Histent he)
|
||||||
remember_edits();
|
remember_edits();
|
||||||
mkundoent();
|
mkundoent();
|
||||||
histline = he->histnum;
|
histline = he->histnum;
|
||||||
setline(ZLETEXT(he), ZSL_COPY|ZSL_TOEND);
|
|
||||||
|
if (he->zle_text) {
|
||||||
|
/*
|
||||||
|
* Optimise out conversion to metafied string and back.
|
||||||
|
* Remember convention of extra 2 characters spare.
|
||||||
|
*/
|
||||||
|
free(zleline);
|
||||||
|
linesz = zlell = he->zle_len;
|
||||||
|
zleline = zalloc((zlell + 2) * ZLE_CHAR_SIZE);
|
||||||
|
ZS_memcpy(zleline, he->zle_text, zlell);
|
||||||
|
|
||||||
|
zlecs = zlell;
|
||||||
|
if (invicmdmode())
|
||||||
|
zlecs--;
|
||||||
|
} else {
|
||||||
|
setline(he->text, ZSL_COPY|ZSL_TOEND);
|
||||||
|
}
|
||||||
setlastline();
|
setlastline();
|
||||||
clearlist = 1;
|
clearlist = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -596,9 +685,19 @@ zle_goto_hist(int ev, int n, int skipdups)
|
||||||
if (!he || !(he = movehistent(he, n, hist_skip_flags)))
|
if (!he || !(he = movehistent(he, n, hist_skip_flags)))
|
||||||
return 1;
|
return 1;
|
||||||
if (skipdups && n) {
|
if (skipdups && n) {
|
||||||
|
struct zle_text zt;
|
||||||
|
|
||||||
n = n < 0? -1 : 1;
|
n = n < 0? -1 : 1;
|
||||||
while (he && !metadiffer(ZLETEXT(he), (char *) zleline, zlell))
|
while (he) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
zletext(he, &zt);
|
||||||
|
ret = zlinecmp(zt.text, zt.len, zleline, zlell);
|
||||||
|
zletextfree(&zt);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
he = movehistent(he, n, hist_skip_flags);
|
he = movehistent(he, n, hist_skip_flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!he)
|
if (!he)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -762,7 +861,7 @@ get_isrch_spot(int num, int *hlp, int *posp, int *csp, int *lenp, int *dirp, int
|
||||||
*nomatch = (isrch_spots[num].flags & ISS_FAILING);
|
*nomatch = (isrch_spots[num].flags & ISS_FAILING);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ISEARCH_PROMPT "failing XXX-i-search: "
|
#define ISEARCH_PROMPT ZWC("failing XXX-i-search: ")
|
||||||
#define NORM_PROMPT_POS 8
|
#define NORM_PROMPT_POS 8
|
||||||
#define FIRST_SEARCH_CHAR (NORM_PROMPT_POS + 14)
|
#define FIRST_SEARCH_CHAR (NORM_PROMPT_POS + 14)
|
||||||
|
|
||||||
|
|
@ -774,11 +873,14 @@ get_isrch_spot(int num, int *hlp, int *posp, int *csp, int *lenp, int *dirp, int
|
||||||
static void
|
static void
|
||||||
doisearch(char **args, int dir)
|
doisearch(char **args, int dir)
|
||||||
{
|
{
|
||||||
char *s, *ibuf = zhalloc(80), *sbuf = ibuf + FIRST_SEARCH_CHAR;
|
ZLE_STRING_T ibuf = zhalloc(80 * ZLE_CHAR_SIZE);
|
||||||
|
ZLE_STRING_T sbuf = ibuf + FIRST_SEARCH_CHAR;
|
||||||
|
ZLE_STRING_T last_line = NULL;
|
||||||
|
struct zle_text zt;
|
||||||
int sbptr = 0, top_spot = 0, pos, sibuf = 80;
|
int sbptr = 0, top_spot = 0, pos, sibuf = 80;
|
||||||
int nomatch = 0, skip_line = 0, skip_pos = 0;
|
int nomatch = 0, skip_line = 0, skip_pos = 0;
|
||||||
int odir = dir, sens = zmult == 1 ? 3 : 1;
|
int odir = dir, sens = zmult == 1 ? 3 : 1;
|
||||||
int hl = histline, savekeys = -1, feep = 0;
|
int hl = histline, savekeys = -1, feep = 0, last_len;
|
||||||
Thingy cmd;
|
Thingy cmd;
|
||||||
char *okeymap;
|
char *okeymap;
|
||||||
Histent he;
|
Histent he;
|
||||||
|
|
@ -796,47 +898,59 @@ doisearch(char **args, int dir)
|
||||||
ungetbytes(arg, len);
|
ungetbytes(arg, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(ibuf, ISEARCH_PROMPT);
|
ZS_strcpy(ibuf, ISEARCH_PROMPT);
|
||||||
memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? "fwd" : "bck", 3);
|
ZS_memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? ZWC("fwd") : ZWC("bck"), 3);
|
||||||
remember_edits();
|
remember_edits();
|
||||||
okeymap = ztrdup(curkeymapname);
|
okeymap = ztrdup(curkeymapname);
|
||||||
s = ZLETEXT(he);
|
zletext(he, &zt);
|
||||||
selectkeymap("main", 1);
|
selectkeymap("main", 1);
|
||||||
pos = metalen(s, zlecs);
|
pos = zlecs;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Remember the current values in case search fails (doesn't push). */
|
/* Remember the current values in case search fails (doesn't push). */
|
||||||
set_isrch_spot(top_spot, hl, pos, zlecs, sbptr, dir, nomatch);
|
set_isrch_spot(top_spot, hl, pos, zlecs, sbptr, dir, nomatch);
|
||||||
if (sbptr == 1 && sbuf[0] == '^') {
|
if (sbptr == 1 && sbuf[0] == ZWC('^')) {
|
||||||
zlecs = 0;
|
zlecs = 0;
|
||||||
nomatch = 0;
|
nomatch = 0;
|
||||||
statusline = ibuf + NORM_PROMPT_POS;
|
statusline = ibuf + NORM_PROMPT_POS;
|
||||||
} else if (sbptr > 0) {
|
} else if (sbptr > 0) {
|
||||||
char *last_line = s;
|
/*
|
||||||
|
* As we may free zt.text as soon as we switch to a new
|
||||||
|
* line, we can't keep the pointer to it. This is a bit
|
||||||
|
* ghastly.
|
||||||
|
*/
|
||||||
|
if (last_line)
|
||||||
|
free(last_line);
|
||||||
|
last_line = zalloc(zt.len * ZLE_CHAR_SIZE);
|
||||||
|
ZS_memcpy(last_line, zt.text, zt.len);
|
||||||
|
last_len = zt.len;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char *t;
|
ZLE_STRING_T t;
|
||||||
|
|
||||||
if (skip_pos) {
|
if (skip_pos) {
|
||||||
if (dir < 0) {
|
if (dir < 0) {
|
||||||
if (pos == 0)
|
if (pos == 0)
|
||||||
skip_line = 1;
|
skip_line = 1;
|
||||||
else
|
else
|
||||||
pos -= 1 + (pos != 1 && s[pos-2] == Meta);
|
pos -= 1;
|
||||||
} else if (sbuf[0] != '^') {
|
} else if (sbuf[0] != ZWC('^')) {
|
||||||
if (pos >= (int)strlen(s+1))
|
if (pos >= zt.len - 1)
|
||||||
skip_line = 1;
|
skip_line = 1;
|
||||||
else
|
else
|
||||||
pos += 1 + (s[pos] == Meta);
|
pos += 1;
|
||||||
} else
|
} else
|
||||||
skip_line = 1;
|
skip_line = 1;
|
||||||
skip_pos = 0;
|
skip_pos = 0;
|
||||||
}
|
}
|
||||||
if (!skip_line && ((sbuf[0] == '^') ?
|
if (!skip_line && ((sbuf[0] == ZWC('^')) ?
|
||||||
(t = metadiffer(s, sbuf + 1, sbptr - 1) < sens ? s : NULL) :
|
(t = zlinecmp(zt.text, zt.len, sbuf + 1, sbptr - 1) < sens
|
||||||
(t = hstrnstr(s, pos, sbuf, sbptr, dir, sens)))) {
|
? zt.text : NULL) :
|
||||||
|
(t = zlinefind(zt.text, zt.len, pos, sbuf,
|
||||||
|
sbptr, dir, sens)))) {
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
pos = t - s;
|
pos = t - zt.text;
|
||||||
zlecs = ztrsub(t, s) + (dir == 1? sbptr - (sbuf[0]=='^') : 0);
|
zlecs = pos +
|
||||||
|
(dir == 1 ? sbptr - (sbuf[0] == ZWC('^')) : 0);
|
||||||
nomatch = 0;
|
nomatch = 0;
|
||||||
statusline = ibuf + NORM_PROMPT_POS;
|
statusline = ibuf + NORM_PROMPT_POS;
|
||||||
break;
|
break;
|
||||||
|
|
@ -853,24 +967,27 @@ doisearch(char **args, int dir)
|
||||||
nomatch = 1;
|
nomatch = 1;
|
||||||
}
|
}
|
||||||
he = quietgethist(hl);
|
he = quietgethist(hl);
|
||||||
s = ZLETEXT(he);
|
zletextfree(&zt);
|
||||||
|
zletext(he, &zt);
|
||||||
skip_line = 0;
|
skip_line = 0;
|
||||||
statusline = ibuf;
|
statusline = ibuf;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
hl = he->histnum;
|
hl = he->histnum;
|
||||||
s = ZLETEXT(he);
|
zletextfree(&zt);
|
||||||
pos = dir == 1? 0 : strlen(s);
|
zletext(he, &zt);
|
||||||
skip_line = isset(HISTFINDNODUPS)? !!(he->flags & HIST_DUP)
|
pos = (dir == 1) ? 0 : zt.len;
|
||||||
: !strcmp(last_line, s);
|
skip_line = isset(HISTFINDNODUPS) ? !!(he->flags & HIST_DUP)
|
||||||
|
: (zt.len == last_len &&
|
||||||
|
!ZS_memcmp(zt.text, last_line, zt.len));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
top_spot = 0;
|
top_spot = 0;
|
||||||
nomatch = 0;
|
nomatch = 0;
|
||||||
statusline = ibuf + NORM_PROMPT_POS;
|
statusline = ibuf + NORM_PROMPT_POS;
|
||||||
}
|
}
|
||||||
sbuf[sbptr] = '_';
|
sbuf[sbptr] = ZWC('_');
|
||||||
statusll = sbuf - (char *)/*TODO*/statusline + sbptr + 1;
|
statusll = sbuf - statusline + sbptr + 1;
|
||||||
ref:
|
ref:
|
||||||
zrefresh();
|
zrefresh();
|
||||||
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
||||||
|
|
@ -878,7 +995,8 @@ doisearch(char **args, int dir)
|
||||||
get_isrch_spot(0, &hl, &pos, &i, &sbptr, &dir, &nomatch);
|
get_isrch_spot(0, &hl, &pos, &i, &sbptr, &dir, &nomatch);
|
||||||
he = quietgethist(hl);
|
he = quietgethist(hl);
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
s = ZLETEXT(he);
|
zletextfree(&zt);
|
||||||
|
zletext(he, &zt);
|
||||||
zlecs = i;
|
zlecs = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -904,13 +1022,15 @@ doisearch(char **args, int dir)
|
||||||
skip_pos = 1;
|
skip_pos = 1;
|
||||||
}
|
}
|
||||||
he = quietgethist(hl);
|
he = quietgethist(hl);
|
||||||
s = ZLETEXT(he);
|
zletextfree(&zt);
|
||||||
if (nomatch || !sbptr || (sbptr == 1 && sbuf[0] == '^')) {
|
zletext(he, &zt);
|
||||||
|
if (nomatch || !sbptr || (sbptr == 1 && sbuf[0] == ZWC('^'))) {
|
||||||
int i = zlecs;
|
int i = zlecs;
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
zlecs = i;
|
zlecs = i;
|
||||||
}
|
}
|
||||||
memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? "fwd" : "bck", 3);
|
ZS_memcpy(ibuf + NORM_PROMPT_POS,
|
||||||
|
(dir == 1) ? ZWS("fwd") : ZWS("bck"), 3);
|
||||||
continue;
|
continue;
|
||||||
} else if(cmd == Th(z_acceptandhold)) {
|
} else if(cmd == Th(z_acceptandhold)) {
|
||||||
acceptandhold(zlenoargs);
|
acceptandhold(zlenoargs);
|
||||||
|
|
@ -949,23 +1069,21 @@ doisearch(char **args, int dir)
|
||||||
skip_pos = 1;
|
skip_pos = 1;
|
||||||
rpt:
|
rpt:
|
||||||
if (!sbptr && previous_search_len) {
|
if (!sbptr && previous_search_len) {
|
||||||
if (previous_search_len > sibuf - FIRST_SEARCH_CHAR - 2
|
if (previous_search_len > sibuf - FIRST_SEARCH_CHAR - 2) {
|
||||||
#ifdef ZLE_UNICODE_SUPPORT
|
ibuf = hrealloc(ibuf, sibuf, (sibuf + previous_search_len)
|
||||||
- MB_CUR_MAX
|
* ZLE_CHAR_SIZE);
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
ibuf = hrealloc(ibuf, sibuf, sibuf + previous_search_len);
|
|
||||||
sbuf = ibuf + FIRST_SEARCH_CHAR;
|
sbuf = ibuf + FIRST_SEARCH_CHAR;
|
||||||
sibuf += previous_search_len;
|
sibuf += previous_search_len;
|
||||||
}
|
}
|
||||||
memcpy(sbuf, previous_search, sbptr = previous_search_len);
|
ZS_memcpy(sbuf, previous_search, sbptr = previous_search_len);
|
||||||
}
|
}
|
||||||
memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? "fwd" : "bck", 3);
|
ZS_memcpy(ibuf + NORM_PROMPT_POS,
|
||||||
|
(dir == 1) ? ZWS("fwd") : ZWS("bck"), 3);
|
||||||
continue;
|
continue;
|
||||||
} else if(cmd == Th(z_viquotedinsert) ||
|
} else if(cmd == Th(z_viquotedinsert) ||
|
||||||
cmd == Th(z_quotedinsert)) {
|
cmd == Th(z_quotedinsert)) {
|
||||||
if(cmd == Th(z_viquotedinsert)) {
|
if(cmd == Th(z_viquotedinsert)) {
|
||||||
sbuf[sbptr] = '^';
|
sbuf[sbptr] = ZWC('^');
|
||||||
zrefresh();
|
zrefresh();
|
||||||
}
|
}
|
||||||
if (getfullchar(0) == ZLEEOF)
|
if (getfullchar(0) == ZLEEOF)
|
||||||
|
|
@ -996,28 +1114,16 @@ doisearch(char **args, int dir)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
set_isrch_spot(top_spot++, hl, pos, zlecs, sbptr, dir, nomatch);
|
set_isrch_spot(top_spot++, hl, pos, zlecs, sbptr, dir, nomatch);
|
||||||
if (sbptr >= sibuf - FIRST_SEARCH_CHAR - 2
|
if (sbptr >= sibuf - FIRST_SEARCH_CHAR - 2) {
|
||||||
#ifdef ZLE_UNICODE_SUPPORT
|
ibuf = hrealloc(ibuf, sibuf, sibuf * 2 * ZLE_CHAR_SIZE);
|
||||||
- MB_CUR_MAX
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
ibuf = hrealloc(ibuf, sibuf, sibuf * 2);
|
|
||||||
sbuf = ibuf + FIRST_SEARCH_CHAR;
|
sbuf = ibuf + FIRST_SEARCH_CHAR;
|
||||||
sibuf *= 2;
|
sibuf *= 2;
|
||||||
}
|
}
|
||||||
#ifdef ZLE_UNICODE_SUPPORT
|
|
||||||
/*
|
/*
|
||||||
* We've supposedly arranged above that lastchar_wide is
|
* We've supposedly arranged above that lastchar_wide is
|
||||||
* always valid at this point.
|
* always valid at this point.
|
||||||
*/
|
*/
|
||||||
{
|
sbuf[sbptr++] = LASTFULLCHAR;
|
||||||
int len = wctomb(sbuf + sbptr, lastchar_wide);
|
|
||||||
if (len > 0)
|
|
||||||
sbptr += len;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
sbuf[sbptr++] = lastchar;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (feep)
|
if (feep)
|
||||||
handlefeep(zlenoargs);
|
handlefeep(zlenoargs);
|
||||||
|
|
@ -1025,8 +1131,8 @@ doisearch(char **args, int dir)
|
||||||
}
|
}
|
||||||
if (sbptr) {
|
if (sbptr) {
|
||||||
zfree(previous_search, previous_search_len);
|
zfree(previous_search, previous_search_len);
|
||||||
previous_search = zalloc(sbptr);
|
previous_search = zalloc(sbptr * ZLE_CHAR_SIZE);
|
||||||
memcpy(previous_search, sbuf, previous_search_len = sbptr);
|
ZS_memcpy(previous_search, sbuf, previous_search_len = sbptr);
|
||||||
}
|
}
|
||||||
statusline = NULL;
|
statusline = NULL;
|
||||||
selectkeymap(okeymap, 1);
|
selectkeymap(okeymap, 1);
|
||||||
|
|
@ -1037,6 +1143,9 @@ doisearch(char **args, int dir)
|
||||||
*/
|
*/
|
||||||
if (savekeys >= 0 && kungetct > savekeys)
|
if (savekeys >= 0 && kungetct > savekeys)
|
||||||
kungetct = savekeys;
|
kungetct = savekeys;
|
||||||
|
if (last_line)
|
||||||
|
free(last_line);
|
||||||
|
zletextfree(&zt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Histent
|
static Histent
|
||||||
|
|
@ -1044,8 +1153,14 @@ infernexthist(Histent he, UNUSED(char **args))
|
||||||
{
|
{
|
||||||
for (he = movehistent(he, -2, HIST_FOREIGN);
|
for (he = movehistent(he, -2, HIST_FOREIGN);
|
||||||
he; he = movehistent(he, -1, HIST_FOREIGN)) {
|
he; he = movehistent(he, -1, HIST_FOREIGN)) {
|
||||||
if (!metadiffer(he->text, (char *) zleline, zlell))
|
struct zle_text zt;
|
||||||
|
zletext(he, &zt);
|
||||||
|
|
||||||
|
if (!zlinecmp(zt.text, zt.len, zleline, zlell)) {
|
||||||
|
zletextfree(&zt);
|
||||||
return movehistent(he, 1, HIST_FOREIGN);
|
return movehistent(he, 1, HIST_FOREIGN);
|
||||||
|
}
|
||||||
|
zletextfree(&zt);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -1105,7 +1220,7 @@ static int visrchsense;
|
||||||
static int
|
static int
|
||||||
getvisrchstr(void)
|
getvisrchstr(void)
|
||||||
{
|
{
|
||||||
char *sbuf = zhalloc(80);
|
ZLE_STRING_T sbuf = zhalloc(80 * ZLE_CHAR_SIZE);
|
||||||
int sptr = 1, ret = 0, ssbuf = 80, feep = 0;
|
int sptr = 1, ret = 0, ssbuf = 80, feep = 0;
|
||||||
Thingy cmd;
|
Thingy cmd;
|
||||||
char *okeymap = ztrdup(curkeymapname);
|
char *okeymap = ztrdup(curkeymapname);
|
||||||
|
|
@ -1120,10 +1235,10 @@ getvisrchstr(void)
|
||||||
}
|
}
|
||||||
clearlist = 1;
|
clearlist = 1;
|
||||||
statusline = sbuf;
|
statusline = sbuf;
|
||||||
sbuf[0] = (visrchsense == -1) ? '?' : '/';
|
sbuf[0] = (visrchsense == -1) ? ZWC('?') : ZWC('/');
|
||||||
selectkeymap("main", 1);
|
selectkeymap("main", 1);
|
||||||
while (sptr) {
|
while (sptr) {
|
||||||
sbuf[sptr] = '_';
|
sbuf[sptr] = ZWC('_');
|
||||||
statusll = sptr + 1;
|
statusll = sptr + 1;
|
||||||
zrefresh();
|
zrefresh();
|
||||||
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
||||||
|
|
@ -1140,9 +1255,11 @@ getvisrchstr(void)
|
||||||
clearscreen(zlenoargs);
|
clearscreen(zlenoargs);
|
||||||
} else if(cmd == Th(z_acceptline) ||
|
} else if(cmd == Th(z_acceptline) ||
|
||||||
cmd == Th(z_vicmdmode)) {
|
cmd == Th(z_vicmdmode)) {
|
||||||
sbuf[sptr] = 0;
|
int newlen;
|
||||||
visrchstr = metafy(sbuf + 1, sptr - 1, META_DUP);
|
sbuf[sptr] = ZWC('\0');
|
||||||
if (!strlen(visrchstr)) {
|
visrchstr = zlelineasstring(sbuf + 1, sptr - 1, 0, &newlen,
|
||||||
|
NULL, 0);
|
||||||
|
if (!newlen) {
|
||||||
zsfree(visrchstr);
|
zsfree(visrchstr);
|
||||||
visrchstr = ztrdup(vipenultsrchstr);
|
visrchstr = ztrdup(vipenultsrchstr);
|
||||||
}
|
}
|
||||||
|
|
@ -1153,17 +1270,18 @@ getvisrchstr(void)
|
||||||
sptr--;
|
sptr--;
|
||||||
} else if(cmd == Th(z_backwardkillword) ||
|
} else if(cmd == Th(z_backwardkillword) ||
|
||||||
cmd == Th(z_vibackwardkillword)) {
|
cmd == Th(z_vibackwardkillword)) {
|
||||||
while(sptr != 1 && iblank(sbuf[sptr - 1]))
|
while(sptr != 1 && ZC_iblank(sbuf[sptr - 1]))
|
||||||
sptr--;
|
sptr--;
|
||||||
if(iident(sbuf[sptr - 1]))
|
if(ZC_iident(sbuf[sptr - 1]))
|
||||||
while(sptr != 1 && iident(sbuf[sptr - 1]))
|
while(sptr != 1 && ZC_iident(sbuf[sptr - 1]))
|
||||||
sptr--;
|
sptr--;
|
||||||
else
|
else
|
||||||
while(sptr != 1 && !iident(sbuf[sptr - 1]) && !iblank(sbuf[sptr - 1]))
|
while(sptr != 1 && !ZC_iident(sbuf[sptr - 1]) &&
|
||||||
|
!ZC_iblank(sbuf[sptr - 1]))
|
||||||
sptr--;
|
sptr--;
|
||||||
} else if(cmd == Th(z_viquotedinsert) || cmd == Th(z_quotedinsert)) {
|
} else if(cmd == Th(z_viquotedinsert) || cmd == Th(z_quotedinsert)) {
|
||||||
if(cmd == Th(z_viquotedinsert)) {
|
if(cmd == Th(z_viquotedinsert)) {
|
||||||
sbuf[sptr] = '^';
|
sbuf[sptr] = ZWC('^');
|
||||||
zrefresh();
|
zrefresh();
|
||||||
}
|
}
|
||||||
if (getfullchar(0) == ZLEEOF)
|
if (getfullchar(0) == ZLEEOF)
|
||||||
|
|
@ -1187,15 +1305,7 @@ getvisrchstr(void)
|
||||||
strcpy(newbuf, sbuf);
|
strcpy(newbuf, sbuf);
|
||||||
statusline = sbuf = newbuf;
|
statusline = sbuf = newbuf;
|
||||||
}
|
}
|
||||||
#ifdef ZLE_UNICODE_SUPPORT
|
sbuf[sptr++] = LASTFULLCHAR;
|
||||||
{
|
|
||||||
int len = wctomb(sbuf + sptr, lastchar_wide);
|
|
||||||
if (len > 0)
|
|
||||||
sptr += len;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
sbuf[sptr++] = lastchar;
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
feep = 1;
|
feep = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -1256,9 +1366,10 @@ int
|
||||||
virepeatsearch(UNUSED(char **args))
|
virepeatsearch(UNUSED(char **args))
|
||||||
{
|
{
|
||||||
Histent he;
|
Histent he;
|
||||||
int t0;
|
ZLE_STRING_T srcstr;
|
||||||
|
int srclen;
|
||||||
int n = zmult;
|
int n = zmult;
|
||||||
char *s;
|
struct zle_text zt;
|
||||||
|
|
||||||
if (!visrchstr)
|
if (!visrchstr)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -1266,22 +1377,28 @@ virepeatsearch(UNUSED(char **args))
|
||||||
n = -n;
|
n = -n;
|
||||||
visrchsense = -visrchsense;
|
visrchsense = -visrchsense;
|
||||||
}
|
}
|
||||||
t0 = strlen(visrchstr);
|
srcstr = stringaszleline(visrchstr, &srclen, NULL);
|
||||||
if (!(he = quietgethist(histline)))
|
if (!(he = quietgethist(histline)))
|
||||||
return 1;
|
return 1;
|
||||||
while ((he = movehistent(he, visrchsense, hist_skip_flags))) {
|
while ((he = movehistent(he, visrchsense, hist_skip_flags))) {
|
||||||
if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
|
if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
|
||||||
continue;
|
continue;
|
||||||
s = ZLETEXT(he);
|
zletext(he, &zt);
|
||||||
if (metadiffer(s, (char *) zleline, zlell)
|
if (zlinecmp(zt.text, zt.len, zleline, zlell) &&
|
||||||
&& (*visrchstr == '^'? strncmp(s, visrchstr + 1, t0 - 1) == 0
|
(*visrchstr == '^'?
|
||||||
: hstrnstr(s, 0, visrchstr, t0, 1, 1) != 0)) {
|
(zt.len == srclen - 1 &&
|
||||||
|
ZS_memcmp(zt.text, srcstr + 1, zt.len) == 0) :
|
||||||
|
zlinefind(zt.text, zt.len, 0, srcstr, srclen, 1, 1) != 0)) {
|
||||||
if (--n <= 0) {
|
if (--n <= 0) {
|
||||||
|
zletextfree(&zt);
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
|
free(srcstr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
zletextfree(&zt);
|
||||||
}
|
}
|
||||||
|
free(srcstr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1307,7 +1424,7 @@ historybeginningsearchbackward(char **args)
|
||||||
Histent he;
|
Histent he;
|
||||||
int cpos = zlecs; /* save cursor position */
|
int cpos = zlecs; /* save cursor position */
|
||||||
int n = zmult;
|
int n = zmult;
|
||||||
char *s;
|
struct zle_text zt;
|
||||||
|
|
||||||
if (zmult < 0) {
|
if (zmult < 0) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
@ -1321,15 +1438,17 @@ historybeginningsearchbackward(char **args)
|
||||||
while ((he = movehistent(he, -1, hist_skip_flags))) {
|
while ((he = movehistent(he, -1, hist_skip_flags))) {
|
||||||
if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
|
if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
|
||||||
continue;
|
continue;
|
||||||
s = ZLETEXT(he);
|
zletext(he, &zt);
|
||||||
if (metadiffer(s, (char *)zleline, zlecs) < 0 &&
|
if (zlinecmp(zt.text, zt.len, zleline, zlecs) < 0 &&
|
||||||
metadiffer(s, (char *)zleline, zlell)) {
|
zlinecmp(zt.text, zt.len, zleline, zlell)) {
|
||||||
if (--n <= 0) {
|
if (--n <= 0) {
|
||||||
|
zletextfree(&zt);
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
zlecs = cpos;
|
zlecs = cpos;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
zletextfree(&zt);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -1344,7 +1463,7 @@ historybeginningsearchforward(char **args)
|
||||||
Histent he;
|
Histent he;
|
||||||
int cpos = zlecs; /* save cursor position */
|
int cpos = zlecs; /* save cursor position */
|
||||||
int n = zmult;
|
int n = zmult;
|
||||||
char *s;
|
struct zle_text zt;
|
||||||
|
|
||||||
if (zmult < 0) {
|
if (zmult < 0) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
@ -1358,15 +1477,18 @@ historybeginningsearchforward(char **args)
|
||||||
while ((he = movehistent(he, 1, hist_skip_flags))) {
|
while ((he = movehistent(he, 1, hist_skip_flags))) {
|
||||||
if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
|
if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
|
||||||
continue;
|
continue;
|
||||||
s = ZLETEXT(he);
|
zletext(he, &zt);
|
||||||
if (metadiffer(s, (char *)zleline, zlecs) < (he->histnum == curhist) &&
|
if (zlinecmp(zt.text, zt.len, zleline, zlecs) <
|
||||||
metadiffer(s, (char *)zleline, zlell)) {
|
(he->histnum == curhist) &&
|
||||||
|
zlinecmp(zt.text, zt.len, zleline, zlell)) {
|
||||||
if (--n <= 0) {
|
if (--n <= 0) {
|
||||||
|
zletextfree(&zt);
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
zlecs = cpos;
|
zlecs = cpos;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
zletextfree(&zt);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -466,31 +466,79 @@ findline(int *a, int *b)
|
||||||
*b = findeol();
|
*b = findeol();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search for needle in haystack. Haystack is a metafied string while *
|
/*
|
||||||
* needle is unmetafied and len-long. Start the search at position *
|
* Return zero if the ZLE string histp length histl and the ZLE string
|
||||||
* pos. Search forward if dir > 0 otherwise search backward. */
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
char *
|
int
|
||||||
hstrnstr(char *haystack, int pos, char *needle, int len, int dir, int sens)
|
zlinecmp(ZLE_STRING_T histp, int histl, ZLE_STRING_T inputp, int inputl)
|
||||||
{
|
{
|
||||||
char *s = haystack + pos;
|
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 (*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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**/
|
||||||
|
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) {
|
if (dir > 0) {
|
||||||
while (*s) {
|
while (slen) {
|
||||||
if (metadiffer(s, needle, len) < sens)
|
if (zlinecmp(s, slen, needle, needlen) < sens)
|
||||||
return s;
|
return s;
|
||||||
s += 1 + (*s == Meta);
|
s++;
|
||||||
|
slen--;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (metadiffer(s, needle, len) < sens)
|
if (zlinecmp(s, slen, needle, needlen) < sens)
|
||||||
return s;
|
return s;
|
||||||
if (s == haystack)
|
if (s == haystack)
|
||||||
break;
|
break;
|
||||||
s -= 1 + (s != haystack+1 && s[-2] == Meta);
|
s--;
|
||||||
|
slen++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
30
Src/utils.c
30
Src/utils.c
|
|
@ -2925,36 +2925,6 @@ ztrcmp(unsigned char const *s1, unsigned char const *s2)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return zero if the metafied string s and the non-metafied, *
|
|
||||||
* len-long string r are the same. Return -1 if r is a prefix *
|
|
||||||
* of s. Return 1 if r is the lowercase version of s. Return *
|
|
||||||
* 2 is r is the lowercase prefix of s and return 3 otherwise. */
|
|
||||||
|
|
||||||
/**/
|
|
||||||
mod_export int
|
|
||||||
metadiffer(char const *s, char const *r, int len)
|
|
||||||
{
|
|
||||||
int l = len;
|
|
||||||
|
|
||||||
while (l-- && *s && *r++ == (*s == Meta ? *++s ^ 32 : *s))
|
|
||||||
s++;
|
|
||||||
if (*s && l < 0)
|
|
||||||
return -1;
|
|
||||||
if (l < 0)
|
|
||||||
return 0;
|
|
||||||
if (!*s)
|
|
||||||
return 3;
|
|
||||||
s -= len - l - 1;
|
|
||||||
r -= len - l;
|
|
||||||
while (len-- && *s && *r++ == tulower(*s == Meta ? *++s ^ 32 : *s))
|
|
||||||
s++;
|
|
||||||
if (*s && len < 0)
|
|
||||||
return 2;
|
|
||||||
if (len < 0)
|
|
||||||
return 1;
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the unmetafied length of a metafied string. */
|
/* Return the unmetafied length of a metafied string. */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
|
||||||
|
|
@ -1368,7 +1368,12 @@ struct histent {
|
||||||
|
|
||||||
Histent up; /* previous line (moving upward) */
|
Histent up; /* previous line (moving upward) */
|
||||||
Histent down; /* next line (moving downward) */
|
Histent down; /* next line (moving downward) */
|
||||||
char *zle_text; /* the edited history line */
|
#ifdef ZLE_UNICODE_SUPPORT
|
||||||
|
wchar_t *zle_text; /* the edited history line */
|
||||||
|
#else
|
||||||
|
unsigned char *zle_text; /* the edited history line */
|
||||||
|
#endif
|
||||||
|
int zle_len; /* length of zle_text */
|
||||||
time_t stim; /* command started time (datestamp) */
|
time_t stim; /* command started time (datestamp) */
|
||||||
time_t ftim; /* command finished time */
|
time_t ftim; /* command finished time */
|
||||||
short *words; /* Position of words in history */
|
short *words; /* Position of words in history */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue