mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-27 16:50:58 +01:00
24853: use metafied strings for inner loops over history
This commit is contained in:
parent
a12b1f35aa
commit
b8ec06c870
14 changed files with 651 additions and 354 deletions
10
ChangeLog
10
ChangeLog
|
|
@ -1,5 +1,13 @@
|
||||||
2008-04-20 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
2008-04-20 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||||
|
|
||||||
|
* 24853: Src/utils.c, Src/zsh.h, 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_move.c, Src/Zle/zle_refresh.c,
|
||||||
|
Src/Zle/zle_thingy.c, Src/Zle/zle_utils.c, Src/Zle/zle_vi.c,
|
||||||
|
Src/Zle/zle_word.c: use metafied strings for inner loops
|
||||||
|
involving history, with consequent changes for similar code
|
||||||
|
such as execute-name-command, plus some utility functions.
|
||||||
|
|
||||||
* 24852: Src/zle_main.c (Jun T.), Src/Zle/zle_vi.c: more
|
* 24852: Src/zle_main.c (Jun T.), Src/Zle/zle_vi.c: more
|
||||||
combining chars fallout.
|
combining chars fallout.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2432,7 +2432,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
||||||
}
|
}
|
||||||
first = 0;
|
first = 0;
|
||||||
if (mode == MM_INTER)
|
if (mode == MM_INTER)
|
||||||
statusline = stringaszleline(status, 0, &statusll, NULL, NULL);
|
statusline = status;
|
||||||
else if (mode) {
|
else if (mode) {
|
||||||
int l = sprintf(status, "%s%sisearch%s: ",
|
int l = sprintf(status, "%s%sisearch%s: ",
|
||||||
((msearchstate & MS_FAILED) ? "failed " : ""),
|
((msearchstate & MS_FAILED) ? "failed " : ""),
|
||||||
|
|
@ -2441,17 +2441,12 @@ domenuselect(Hookdef dummy, Chdata dat)
|
||||||
|
|
||||||
strncat(status, msearchstr, MAX_STATUS - l - 1);
|
strncat(status, msearchstr, MAX_STATUS - l - 1);
|
||||||
|
|
||||||
statusline = stringaszleline(status, 0, &statusll, NULL, NULL);
|
statusline = status;
|
||||||
} else {
|
} else {
|
||||||
statusline = NULL;
|
statusline = NULL;
|
||||||
statusll = 0;
|
|
||||||
}
|
}
|
||||||
zrefresh();
|
zrefresh();
|
||||||
if (statusline) {
|
statusline = NULL;
|
||||||
free(statusline);
|
|
||||||
statusline = NULL;
|
|
||||||
statusll = 0;
|
|
||||||
}
|
|
||||||
inselect = 1;
|
inselect = 1;
|
||||||
if (noselect) {
|
if (noselect) {
|
||||||
broken = 1;
|
broken = 1;
|
||||||
|
|
@ -2622,12 +2617,10 @@ domenuselect(Hookdef dummy, Chdata dat)
|
||||||
if (nmatches < 1 || !minfo.cur || !*(minfo.cur)) {
|
if (nmatches < 1 || !minfo.cur || !*(minfo.cur)) {
|
||||||
nolist = 1;
|
nolist = 1;
|
||||||
if (mode == MM_INTER) {
|
if (mode == MM_INTER) {
|
||||||
statusline = stringaszleline(status, 0,
|
statusline = status;
|
||||||
&statusll, NULL, NULL);
|
|
||||||
} else {
|
} else {
|
||||||
/* paranoia */
|
/* paranoia */
|
||||||
statusline = NULL;
|
statusline = NULL;
|
||||||
statusll = 0;
|
|
||||||
}
|
}
|
||||||
if (nmessages) {
|
if (nmessages) {
|
||||||
showinglist = -2;
|
showinglist = -2;
|
||||||
|
|
@ -2645,11 +2638,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
||||||
zrefresh();
|
zrefresh();
|
||||||
showinglist = clearlist = 0;
|
showinglist = clearlist = 0;
|
||||||
}
|
}
|
||||||
if (statusline) {
|
statusline = NULL;
|
||||||
free(statusline);
|
|
||||||
statusline = NULL;
|
|
||||||
statusll = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
goto getk;
|
goto getk;
|
||||||
}
|
}
|
||||||
|
|
@ -2763,19 +2752,13 @@ domenuselect(Hookdef dummy, Chdata dat)
|
||||||
|
|
||||||
if (nolist) {
|
if (nolist) {
|
||||||
if (mode == MM_INTER) {
|
if (mode == MM_INTER) {
|
||||||
statusline = stringaszleline(status, 0,
|
statusline = status;
|
||||||
&statusll, NULL, NULL);
|
|
||||||
} else {
|
} else {
|
||||||
/* paranoia */
|
/* paranoia */
|
||||||
statusline = NULL;
|
statusline = NULL;
|
||||||
statusll = 0;
|
|
||||||
}
|
}
|
||||||
zrefresh();
|
zrefresh();
|
||||||
if (statusline) {
|
statusline = NULL;
|
||||||
free(statusline);
|
|
||||||
statusline = NULL;
|
|
||||||
statusll = 0;
|
|
||||||
}
|
|
||||||
goto getk;
|
goto getk;
|
||||||
}
|
}
|
||||||
if (mode)
|
if (mode)
|
||||||
|
|
|
||||||
|
|
@ -74,9 +74,21 @@ typedef wint_t ZLE_INT_T;
|
||||||
#define LASTFULLCHAR lastchar_wide
|
#define LASTFULLCHAR lastchar_wide
|
||||||
#define LASTFULLCHAR_T ZLE_INT_T
|
#define LASTFULLCHAR_T ZLE_INT_T
|
||||||
|
|
||||||
/* We may need to handle combining character alignment */
|
/*
|
||||||
|
* We may need to handle combining character alignment.
|
||||||
|
* The following fix up the position of the cursor so that it
|
||||||
|
* never ends up over a zero-width punctuation character following
|
||||||
|
* an alphanumeric character. The first is used if we were
|
||||||
|
* moving the cursor left, the second if we were moving right or
|
||||||
|
* if something under the cursor may have changed.
|
||||||
|
*/
|
||||||
#define CCLEFT() alignmultiwordleft(&zlecs, 1)
|
#define CCLEFT() alignmultiwordleft(&zlecs, 1)
|
||||||
#define CCRIGHT() alignmultiwordright(&zlecs, 1)
|
#define CCRIGHT() alignmultiwordright(&zlecs, 1)
|
||||||
|
/*
|
||||||
|
* Same for any other position
|
||||||
|
*/
|
||||||
|
#define CCLEFTPOS(pos) alignmultiwordleft(&pos, 1)
|
||||||
|
#define CCRIGHTPOS(pos) alignmultiwordright(&pos, 1)
|
||||||
/*
|
/*
|
||||||
* Increment or decrement the cursor position, skipping over
|
* Increment or decrement the cursor position, skipping over
|
||||||
* combining characters.
|
* combining characters.
|
||||||
|
|
@ -151,6 +163,8 @@ static inline int ZS_strncmp(ZLE_STRING_T s1, ZLE_STRING_T s2, size_t l)
|
||||||
/* Combining character alignment: none in this mode */
|
/* Combining character alignment: none in this mode */
|
||||||
#define CCLEFT()
|
#define CCLEFT()
|
||||||
#define CCRIGHT()
|
#define CCRIGHT()
|
||||||
|
#define CCLEFTPOS()
|
||||||
|
#define CCRIGHTPOS()
|
||||||
/*
|
/*
|
||||||
* Increment or decrement the cursor position: simple in this case.
|
* Increment or decrement the cursor position: simple in this case.
|
||||||
*/
|
*/
|
||||||
|
|
@ -235,7 +249,13 @@ struct modifier {
|
||||||
|
|
||||||
#define CUT_FRONT (1<<0) /* Text goes in front of cut buffer */
|
#define CUT_FRONT (1<<0) /* Text goes in front of cut buffer */
|
||||||
#define CUT_REPLACE (1<<1) /* Text replaces cut buffer */
|
#define CUT_REPLACE (1<<1) /* Text replaces cut buffer */
|
||||||
#define CUT_RAW (1<<2) /* Raw character counts (not used in cut itself) */
|
#define CUT_RAW (1<<2) /*
|
||||||
|
* Raw character counts (not used in cut itself).
|
||||||
|
* This is used when the values are offsets
|
||||||
|
* into the zleline array rather than numbers
|
||||||
|
* of visible characters directly input by
|
||||||
|
* the user.
|
||||||
|
*/
|
||||||
|
|
||||||
/* undo system */
|
/* undo system */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,9 @@ int previous_search_len = 0;
|
||||||
|
|
||||||
|
|
||||||
struct zle_text {
|
struct zle_text {
|
||||||
ZLE_STRING_T text;
|
/* Metafied, NULL-terminated string */
|
||||||
int len;
|
char *text;
|
||||||
|
/* 1 if we have allocated space for text */
|
||||||
int alloced;
|
int alloced;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -67,30 +68,18 @@ struct zle_text {
|
||||||
* Each use of this must have a matching zletextfree() in order
|
* Each use of this must have a matching zletextfree() in order
|
||||||
* to free up the allocated line, if any. (N.B.: each use *of
|
* to free up the allocated line, if any. (N.B.: each use *of
|
||||||
* the function*, not just each use of a struct zle_text.)
|
* 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
|
static void
|
||||||
zletext(Histent ent, struct zle_text *zt)
|
zletext(Histent ent, struct zle_text *zt)
|
||||||
{
|
{
|
||||||
char *duptext;
|
|
||||||
|
|
||||||
if (ent->zle_text) {
|
if (ent->zle_text) {
|
||||||
zt->text = ent->zle_text;
|
zt->text = ent->zle_text;
|
||||||
zt->len = ent->zle_len;
|
|
||||||
zt->alloced = 0;
|
zt->alloced = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
duptext = ztrdup(ent->node.nam);
|
zt->text = ztrdup(ent->node.nam);
|
||||||
zt->text = stringaszleline(duptext, 0, &zt->len, NULL, NULL);
|
|
||||||
zsfree(duptext);
|
|
||||||
zt->alloced = 1;
|
zt->alloced = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,14 +100,15 @@ remember_edits(void)
|
||||||
{
|
{
|
||||||
Histent ent = quietgethist(histline);
|
Histent ent = quietgethist(histline);
|
||||||
if (ent) {
|
if (ent) {
|
||||||
if (!ent->zle_text || ent->zle_len != zlell ||
|
char *line =
|
||||||
ZS_memcmp(ent->zle_text, zleline, zlell) != 0) {
|
zlemetaline ? zlemetaline :
|
||||||
|
zlelineasstring(zleline, zlell, 0, NULL, NULL, 0);
|
||||||
|
if (!ent->zle_text || strcmp(line, ent->zle_text) != 0) {
|
||||||
if (ent->zle_text)
|
if (ent->zle_text)
|
||||||
free(ent->zle_text);
|
free(ent->zle_text);
|
||||||
ent->zle_text = zalloc(zlell * ZLE_CHAR_SIZE);
|
ent->zle_text = zlemetaline ? ztrdup(line) : line;
|
||||||
ent->zle_len = zlell;
|
} else if (!zlemetaline)
|
||||||
ZS_memcpy(ent->zle_text, zleline, zlell);
|
free(line);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,7 +122,6 @@ forget_edits(void)
|
||||||
if (he->zle_text) {
|
if (he->zle_text) {
|
||||||
free(he->zle_text);
|
free(he->zle_text);
|
||||||
he->zle_text = NULL;
|
he->zle_text = NULL;
|
||||||
he->zle_len = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -150,65 +139,99 @@ forget_edits(void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zlinecmp(ZLE_STRING_T histp, int histl, ZLE_STRING_T inputp, int inputl)
|
zlinecmp(const char *histp, const char *inputp)
|
||||||
{
|
{
|
||||||
int cnt;
|
const char *hptr = histp, *iptr = inputp;
|
||||||
|
#ifdef MULTIBYTE_SUPPORT
|
||||||
|
mbstate_t hstate, istate;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (histl < inputl) {
|
while (*hptr == *iptr) {
|
||||||
/* Not identical, second string is not a prefix. */
|
hptr++;
|
||||||
return 3;
|
iptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ZS_memcmp(histp, inputp, inputl)) {
|
if (!*iptr) {
|
||||||
/* Common prefix is identical */
|
if (!*hptr) {
|
||||||
/* If lines are identical return 0 */
|
/* strings are the same */
|
||||||
if (histl == inputl)
|
|
||||||
return 0;
|
return 0;
|
||||||
/* Second string is a prefix of the first */
|
} else {
|
||||||
return -1;
|
/* inputp is a prefix */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (cnt = inputl; cnt; cnt--) {
|
#ifdef MULTIBYTE_SUPPORT
|
||||||
if ((ZLE_INT_T)*inputp++ != ZC_tolower(*histp++))
|
memset(&hstate, 0, sizeof(hstate));
|
||||||
|
memset(&istate, 0, sizeof(istate));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* look for lower case versions */
|
||||||
|
while (*histp && *inputp) {
|
||||||
|
#ifdef MULTIBYTE_SUPPORT
|
||||||
|
wint_t hwc, iwc;
|
||||||
|
int hlen, ilen;
|
||||||
|
|
||||||
|
hlen = mb_metacharlenconv_r(histp, &hwc, &hstate);
|
||||||
|
ilen = mb_metacharlenconv_r(inputp, &iwc, &istate);
|
||||||
|
|
||||||
|
if (hwc == WEOF || iwc == WEOF) {
|
||||||
|
/* can't convert, compare input characters */
|
||||||
|
if (ilen != hlen || memcmp(histp, inputp, hlen) != 0)
|
||||||
|
return 3;
|
||||||
|
} else if (towlower(hwc) != iwc)
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
|
histp += hlen;
|
||||||
|
inputp += ilen;
|
||||||
|
#else
|
||||||
|
if (tulower(*histp++) != *inputp++)
|
||||||
|
return 3;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* Is second string is lowercase version of first? */
|
if (!*inputp) {
|
||||||
if (histl == inputl)
|
/* one string finished, if it's the input... */
|
||||||
return 1;
|
if (!*histp)
|
||||||
/* Second string is lowercase prefix of first */
|
return 1; /* ...same, else */
|
||||||
return 2;
|
else
|
||||||
|
return 2; /* ...prefix */
|
||||||
|
}
|
||||||
|
/* Different */
|
||||||
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search for needle in haystack. Haystack and needle are ZLE strings
|
* Search for needle in haystack. Haystack and needle are metafied strings.
|
||||||
* of the indicated length. Start the search at position
|
* Start the search at position pos in haystack.
|
||||||
* pos in haystack. Search forward if dir > 0, otherwise search
|
* Search forward if dir > 0, otherwise search backward.
|
||||||
* backward. sens is used to test against the return value of linecmp.
|
* sens is used to test against the return value of linecmp.
|
||||||
|
*
|
||||||
|
* Return the pointer to the location in haystack found, else NULL.
|
||||||
|
*
|
||||||
|
* We assume we'll only find needle at some sensible position in a multibyte
|
||||||
|
* string, so we don't bother calculating multibyte character lengths for
|
||||||
|
* incrementing and decrementing the search position.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static ZLE_STRING_T
|
static char *
|
||||||
zlinefind(ZLE_STRING_T haystack, int haylen, int pos,
|
zlinefind(char *haystack, int pos, char *needle, int dir, int sens)
|
||||||
ZLE_STRING_T needle, int needlen, int dir, int sens)
|
|
||||||
{
|
{
|
||||||
ZLE_STRING_T s = haystack + pos;
|
char *s = haystack + pos;
|
||||||
int slen = haylen - pos;
|
|
||||||
|
|
||||||
if (dir > 0) {
|
if (dir > 0) {
|
||||||
while (slen) {
|
while (*s) {
|
||||||
if (zlinecmp(s, slen, needle, needlen) < sens)
|
if (zlinecmp(s, needle) < sens)
|
||||||
return s;
|
return s;
|
||||||
s++;
|
s++;
|
||||||
slen--;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (zlinecmp(s, slen, needle, needlen) < sens)
|
if (zlinecmp(s, needle) < sens)
|
||||||
return s;
|
return s;
|
||||||
if (s == haystack)
|
if (s == haystack)
|
||||||
break;
|
break;
|
||||||
s--;
|
s--;
|
||||||
slen++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,7 +280,7 @@ upline(void)
|
||||||
if ((zlecs += lastcol) >= x) {
|
if ((zlecs += lastcol) >= x) {
|
||||||
zlecs = x;
|
zlecs = x;
|
||||||
if (zlecs > findbol() && invicmdmode())
|
if (zlecs > findbol() && invicmdmode())
|
||||||
zlecs--;
|
DECCS();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
|
|
@ -341,7 +364,7 @@ downline(void)
|
||||||
if ((zlecs += lastcol) >= x) {
|
if ((zlecs += lastcol) >= x) {
|
||||||
zlecs = x;
|
zlecs = x;
|
||||||
if (zlecs > findbol() && invicmdmode())
|
if (zlecs > findbol() && invicmdmode())
|
||||||
zlecs--;
|
DECCS();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
|
|
@ -421,16 +444,26 @@ downhistory(UNUSED(char **args))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int histpos, srch_hl, srch_cs = -1;
|
/*
|
||||||
static ZLE_STRING_T srch_str;
|
* Values remembered for history searches to enable repetition.
|
||||||
|
* srch_hl remembers the old value of histline, to see if it's changed
|
||||||
|
* since the last search.
|
||||||
|
* srch_cs remembers the old value of zlecs for the same purpose (it is
|
||||||
|
* not use for any other purpose, i.e. does not need to be a valid
|
||||||
|
* index into anything).
|
||||||
|
* srch_str is the metafied search string, as extracted from the start
|
||||||
|
* of zleline.
|
||||||
|
*/
|
||||||
|
static int srch_hl, srch_cs = -1;
|
||||||
|
static char *srch_str;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
historysearchbackward(char **args)
|
historysearchbackward(char **args)
|
||||||
{
|
{
|
||||||
Histent he;
|
Histent he;
|
||||||
int n = zmult, hp;
|
int n = zmult, histpos;
|
||||||
ZLE_STRING_T str;
|
char *str;
|
||||||
struct zle_text zt;
|
struct zle_text zt;
|
||||||
|
|
||||||
if (zmult < 0) {
|
if (zmult < 0) {
|
||||||
|
|
@ -440,46 +473,45 @@ historysearchbackward(char **args)
|
||||||
zmult = n;
|
zmult = n;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (*args)
|
if (*args) {
|
||||||
str = stringaszleline(*args, 0, &hp, NULL, NULL);
|
str = *args;
|
||||||
else {
|
} else {
|
||||||
|
char *line = zlelineasstring(zleline, zlell, 0, NULL, NULL, 0);
|
||||||
if (histline == curhist || histline != srch_hl || zlecs != srch_cs ||
|
if (histline == curhist || histline != srch_hl || zlecs != srch_cs ||
|
||||||
mark != 0 || ZS_memcmp(srch_str, zleline, histpos) != 0) {
|
mark != 0 || strncmp(srch_str, line, histpos) != 0) {
|
||||||
zfree(srch_str, histpos);
|
free(srch_str);
|
||||||
for (histpos = 0; histpos < zlell && !ZC_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 * ZLE_CHAR_SIZE);
|
/* ensure we're not on a combining character */
|
||||||
ZS_memcpy(srch_str, zleline, histpos);
|
CCRIGHTPOS(histpos);
|
||||||
|
/* histpos from now on on is an index into the metafied string */
|
||||||
|
srch_str = zlelineasstring(zleline, histpos, 0, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
|
free(line);
|
||||||
str = srch_str;
|
str = srch_str;
|
||||||
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->node.flags & HIST_DUP)
|
if (isset(HISTFINDNODUPS) && he->node.flags & HIST_DUP)
|
||||||
continue;
|
continue;
|
||||||
zletext(he, &zt);
|
zletext(he, &zt);
|
||||||
if (zlinecmp(zt.text, zt.len, str, hp) < 0 &&
|
if (zlinecmp(zt.text, str) < 0 &&
|
||||||
(*args || zlell != zt.len || ZS_memcmp(zt.text, str, zlell))) {
|
(*args || strcmp(zt.text, str) != 0)) {
|
||||||
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);
|
zletextfree(&zt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
}
|
}
|
||||||
if (*args)
|
|
||||||
free(str);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -488,8 +520,8 @@ int
|
||||||
historysearchforward(char **args)
|
historysearchforward(char **args)
|
||||||
{
|
{
|
||||||
Histent he;
|
Histent he;
|
||||||
int n = zmult, hp;
|
int n = zmult, histpos;
|
||||||
ZLE_STRING_T str;
|
char *str;
|
||||||
struct zle_text zt;
|
struct zle_text zt;
|
||||||
|
|
||||||
if (zmult < 0) {
|
if (zmult < 0) {
|
||||||
|
|
@ -499,46 +531,43 @@ historysearchforward(char **args)
|
||||||
zmult = n;
|
zmult = n;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (*args)
|
if (*args) {
|
||||||
str = stringaszleline(*args, 0, &hp, NULL, NULL);
|
str = *args;
|
||||||
else {
|
} else {
|
||||||
|
char *line = zlelineasstring(zleline, zlell, 0, NULL, NULL, 0);
|
||||||
if (histline == curhist || histline != srch_hl || zlecs != srch_cs ||
|
if (histline == curhist || histline != srch_hl || zlecs != srch_cs ||
|
||||||
mark != 0 || ZS_memcmp(srch_str, zleline, histpos) != 0) {
|
mark != 0 || strncmp(srch_str, line, histpos) != 0) {
|
||||||
zfree(srch_str, histpos * ZLE_CHAR_SIZE);
|
free(srch_str);
|
||||||
for (histpos = 0; histpos < zlell && !ZC_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 * ZLE_CHAR_SIZE);
|
CCRIGHT();
|
||||||
ZS_memcpy(srch_str, zleline, histpos);
|
srch_str = zlelineasstring(zleline, histpos, 0, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
|
free(line);
|
||||||
str = srch_str;
|
str = srch_str;
|
||||||
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->node.flags & HIST_DUP)
|
if (isset(HISTFINDNODUPS) && he->node.flags & HIST_DUP)
|
||||||
continue;
|
continue;
|
||||||
zletext(he, &zt);
|
zletext(he, &zt);
|
||||||
if (zlinecmp(zt.text, zt.len, str, hp) < (he->histnum == curhist) &&
|
if (zlinecmp(zt.text, str) < (he->histnum == curhist) &&
|
||||||
(*args || zlell != zt.len || ZS_memcmp(zt.text, str, zlell))) {
|
(*args || strcmp(zt.text, str) != 0)) {
|
||||||
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);
|
zletextfree(&zt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
}
|
}
|
||||||
if (*args)
|
|
||||||
free(str);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -741,29 +770,21 @@ insertlastword(char **args)
|
||||||
void
|
void
|
||||||
zle_setline(Histent he)
|
zle_setline(Histent he)
|
||||||
{
|
{
|
||||||
|
int remetafy;
|
||||||
|
if (zlemetaline) {
|
||||||
|
unmetafy_line();
|
||||||
|
remetafy = 1;
|
||||||
|
} else
|
||||||
|
remetafy = 0;
|
||||||
remember_edits();
|
remember_edits();
|
||||||
mkundoent();
|
mkundoent();
|
||||||
histline = he->histnum;
|
histline = he->histnum;
|
||||||
|
|
||||||
if (he->zle_text) {
|
setline(he->zle_text ? he->zle_text : he->node.nam, ZSL_COPY|ZSL_TOEND);
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
if ((zlecs = zlell) && invicmdmode())
|
|
||||||
DECCS();
|
|
||||||
} else {
|
|
||||||
setline(he->node.nam, ZSL_COPY|ZSL_TOEND);
|
|
||||||
}
|
|
||||||
/* Move right if we're on a zero-width combining character */
|
|
||||||
CCRIGHT();
|
|
||||||
setlastline();
|
setlastline();
|
||||||
clearlist = 1;
|
clearlist = 1;
|
||||||
|
if (remetafy)
|
||||||
|
metafy_line();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
@ -783,6 +804,8 @@ int
|
||||||
zle_goto_hist(int ev, int n, int skipdups)
|
zle_goto_hist(int ev, int n, int skipdups)
|
||||||
{
|
{
|
||||||
Histent he = quietgethist(ev);
|
Histent he = quietgethist(ev);
|
||||||
|
char *line = zlelineasstring(zleline, zlell, 0, NULL, NULL, 1);
|
||||||
|
|
||||||
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) {
|
||||||
|
|
@ -793,7 +816,7 @@ zle_goto_hist(int ev, int n, int skipdups)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
zletext(he, &zt);
|
zletext(he, &zt);
|
||||||
ret = zlinecmp(zt.text, zt.len, zleline, zlell);
|
ret = zlinecmp(zt.text, line);
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
|
|
@ -961,7 +984,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 ZWS("failing XXX-i-search: ")
|
#define ISEARCH_PROMPT "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)
|
||||||
|
|
||||||
|
|
@ -969,17 +992,18 @@ 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)
|
||||||
{
|
{
|
||||||
ZLE_STRING_T ibuf = zhalloc(80 * ZLE_CHAR_SIZE);
|
char *ibuf = zhalloc(80);
|
||||||
ZLE_STRING_T sbuf = ibuf + FIRST_SEARCH_CHAR;
|
char *sbuf = ibuf + FIRST_SEARCH_CHAR;
|
||||||
ZLE_STRING_T last_line = NULL;
|
char *last_line = NULL;
|
||||||
struct zle_text zt;
|
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, last_len;
|
int hl = histline, savekeys = -1, feep = 0;
|
||||||
Thingy cmd;
|
Thingy cmd;
|
||||||
char *okeymap;
|
char *okeymap;
|
||||||
Histent he;
|
Histent he;
|
||||||
|
ZleIntFunc exitfn = (ZleIntFunc)0;
|
||||||
|
|
||||||
if (!(he = quietgethist(hl)))
|
if (!(he = quietgethist(hl)))
|
||||||
return;
|
return;
|
||||||
|
|
@ -994,18 +1018,21 @@ doisearch(char **args, int dir)
|
||||||
ungetbytes(arg, len);
|
ungetbytes(arg, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZS_strcpy(ibuf, ISEARCH_PROMPT);
|
strcpy(ibuf, ISEARCH_PROMPT);
|
||||||
ZS_memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? ZWS("fwd") : ZWS("bck"), 3);
|
/* careful with fwd/bck: we don't want the NULL copied */
|
||||||
remember_edits();
|
memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? "fwd" : "bck", 3);
|
||||||
okeymap = ztrdup(curkeymapname);
|
okeymap = ztrdup(curkeymapname);
|
||||||
zletext(he, &zt);
|
|
||||||
selectkeymap("main", 1);
|
selectkeymap("main", 1);
|
||||||
pos = zlecs;
|
|
||||||
|
metafy_line();
|
||||||
|
remember_edits();
|
||||||
|
zletext(he, &zt);
|
||||||
|
pos = zlemetacs;
|
||||||
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, zlemetacs, sbptr, dir, nomatch);
|
||||||
if (sbptr == 1 && sbuf[0] == ZWC('^')) {
|
if (sbptr == 1 && sbuf[0] == '^') {
|
||||||
zlecs = 0;
|
zlemetacs = 0;
|
||||||
nomatch = 0;
|
nomatch = 0;
|
||||||
statusline = ibuf + NORM_PROMPT_POS;
|
statusline = ibuf + NORM_PROMPT_POS;
|
||||||
} else if (sbptr > 0) {
|
} else if (sbptr > 0) {
|
||||||
|
|
@ -1016,21 +1043,28 @@ doisearch(char **args, int dir)
|
||||||
*/
|
*/
|
||||||
if (last_line)
|
if (last_line)
|
||||||
free(last_line);
|
free(last_line);
|
||||||
last_line = zalloc(zt.len * ZLE_CHAR_SIZE);
|
last_line = ztrdup(zt.text);
|
||||||
ZS_memcpy(last_line, zt.text, zt.len);
|
|
||||||
last_len = zt.len;
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ZLE_STRING_T t;
|
char *t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If instructed, move past a match position:
|
||||||
|
* backwards if searching backwards (skipping
|
||||||
|
* the line if we're at the start), forwards
|
||||||
|
* if searching forwards (skipping a line if we're
|
||||||
|
* at the end).
|
||||||
|
*/
|
||||||
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 = backwardmetafiedchar(zlemetaline,
|
||||||
} else if (sbuf[0] != ZWC('^')) {
|
zlemetaline + pos,
|
||||||
if (pos >= zt.len - 1)
|
NULL) - zlemetaline;
|
||||||
|
} else if (sbuf[0] != '^') {
|
||||||
|
if (pos >= strlen(zt.text) - 1)
|
||||||
skip_line = 1;
|
skip_line = 1;
|
||||||
else
|
else
|
||||||
pos += 1;
|
pos += 1;
|
||||||
|
|
@ -1038,25 +1072,33 @@ doisearch(char **args, int dir)
|
||||||
skip_line = 1;
|
skip_line = 1;
|
||||||
skip_pos = 0;
|
skip_pos = 0;
|
||||||
}
|
}
|
||||||
if (!skip_line && ((sbuf[0] == ZWC('^')) ?
|
/*
|
||||||
(t = zlinecmp(zt.text, zt.len, sbuf + 1, sbptr - 1) < sens
|
* First search for a(nother) match within the
|
||||||
? zt.text : NULL) :
|
* current line, unless we've been told to skip it.
|
||||||
(t = zlinefind(zt.text, zt.len, pos, sbuf,
|
*/
|
||||||
sbptr, dir, sens)))) {
|
sbuf[sbptr] = '\0';
|
||||||
|
if (!skip_line && ((sbuf[0] == '^') ?
|
||||||
|
(t = (zlinecmp(zt.text, sbuf + 1) < sens
|
||||||
|
? zt.text : NULL)) :
|
||||||
|
(t = zlinefind(zt.text, pos, sbuf, dir, sens)))) {
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
pos = t - zt.text;
|
pos = t - zt.text;
|
||||||
zlecs = pos +
|
zlemetacs = pos +
|
||||||
(dir == 1 ? sbptr - (sbuf[0] == ZWC('^')) : 0);
|
(dir == 1 ? sbptr - (sbuf[0] == '^') : 0);
|
||||||
nomatch = 0;
|
nomatch = 0;
|
||||||
statusline = ibuf + NORM_PROMPT_POS;
|
statusline = ibuf + NORM_PROMPT_POS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* If not found within that line, move through
|
||||||
|
* the history to try again.
|
||||||
|
*/
|
||||||
if (!(zlereadflags & ZLRF_HISTORY)
|
if (!(zlereadflags & ZLRF_HISTORY)
|
||||||
|| !(he = movehistent(he, dir, hist_skip_flags))) {
|
|| !(he = movehistent(he, dir, hist_skip_flags))) {
|
||||||
if (sbptr == (int)isrch_spots[top_spot-1].len
|
if (sbptr == (int)isrch_spots[top_spot-1].len
|
||||||
&& (isrch_spots[top_spot-1].flags & ISS_FAILING))
|
&& (isrch_spots[top_spot-1].flags & ISS_FAILING))
|
||||||
top_spot--;
|
top_spot--;
|
||||||
get_isrch_spot(top_spot, &hl, &pos, &zlecs, &sbptr,
|
get_isrch_spot(top_spot, &hl, &pos, &zlemetacs, &sbptr,
|
||||||
&dir, &nomatch);
|
&dir, &nomatch);
|
||||||
if (!nomatch) {
|
if (!nomatch) {
|
||||||
feep = 1;
|
feep = 1;
|
||||||
|
|
@ -1072,18 +1114,18 @@ doisearch(char **args, int dir)
|
||||||
hl = he->histnum;
|
hl = he->histnum;
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
zletext(he, &zt);
|
zletext(he, &zt);
|
||||||
pos = (dir == 1) ? 0 : zt.len;
|
pos = (dir == 1) ? 0 : strlen(zt.text);
|
||||||
skip_line = isset(HISTFINDNODUPS) ? !!(he->node.flags & HIST_DUP)
|
skip_line = isset(HISTFINDNODUPS)
|
||||||
: (zt.len == last_len &&
|
? !!(he->node.flags & HIST_DUP)
|
||||||
!ZS_memcmp(zt.text, last_line, zt.len));
|
: !strcmp(zt.text, last_line);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
top_spot = 0;
|
top_spot = 0;
|
||||||
nomatch = 0;
|
nomatch = 0;
|
||||||
statusline = ibuf + NORM_PROMPT_POS;
|
statusline = ibuf + NORM_PROMPT_POS;
|
||||||
}
|
}
|
||||||
sbuf[sbptr] = ZWC('_');
|
sbuf[sbptr] = '_';
|
||||||
statusll = sbuf - statusline + sbptr + 1;
|
sbuf[sbptr+1] = '\0';
|
||||||
ref:
|
ref:
|
||||||
zrefresh();
|
zrefresh();
|
||||||
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
||||||
|
|
@ -1093,7 +1135,7 @@ doisearch(char **args, int dir)
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
zletext(he, &zt);
|
zletext(he, &zt);
|
||||||
zlecs = i;
|
zlemetacs = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(cmd == Th(z_clearscreen)) {
|
if(cmd == Th(z_clearscreen)) {
|
||||||
|
|
@ -1109,7 +1151,7 @@ doisearch(char **args, int dir)
|
||||||
} else if(cmd == Th(z_vibackwarddeletechar) ||
|
} else if(cmd == Th(z_vibackwarddeletechar) ||
|
||||||
cmd == Th(z_backwarddeletechar)) {
|
cmd == Th(z_backwarddeletechar)) {
|
||||||
if (top_spot)
|
if (top_spot)
|
||||||
get_isrch_spot(--top_spot, &hl, &pos, &zlecs, &sbptr,
|
get_isrch_spot(--top_spot, &hl, &pos, &zlemetacs, &sbptr,
|
||||||
&dir, &nomatch);
|
&dir, &nomatch);
|
||||||
else
|
else
|
||||||
feep = 1;
|
feep = 1;
|
||||||
|
|
@ -1120,67 +1162,66 @@ doisearch(char **args, int dir)
|
||||||
he = quietgethist(hl);
|
he = quietgethist(hl);
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
zletext(he, &zt);
|
zletext(he, &zt);
|
||||||
if (nomatch || !sbptr || (sbptr == 1 && sbuf[0] == ZWC('^'))) {
|
if (nomatch || !sbptr || (sbptr == 1 && sbuf[0] == '^')) {
|
||||||
int i = zlecs;
|
int i = zlemetacs;
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
zlecs = i;
|
zlemetacs = i;
|
||||||
}
|
}
|
||||||
ZS_memcpy(ibuf + NORM_PROMPT_POS,
|
memcpy(ibuf + NORM_PROMPT_POS,
|
||||||
(dir == 1) ? ZWS("fwd") : ZWS("bck"), 3);
|
(dir == 1) ? "fwd" : "bck", 3);
|
||||||
continue;
|
continue;
|
||||||
} else if(cmd == Th(z_acceptandhold)) {
|
} else if(cmd == Th(z_acceptandhold)) {
|
||||||
acceptandhold(zlenoargs);
|
exitfn = acceptandhold;
|
||||||
break;
|
break;
|
||||||
} else if(cmd == Th(z_acceptandinfernexthistory)) {
|
} else if(cmd == Th(z_acceptandinfernexthistory)) {
|
||||||
acceptandinfernexthistory(zlenoargs);
|
exitfn = acceptandinfernexthistory;
|
||||||
break;
|
break;
|
||||||
} else if(cmd == Th(z_acceptlineanddownhistory)) {
|
} else if(cmd == Th(z_acceptlineanddownhistory)) {
|
||||||
acceptlineanddownhistory(zlenoargs);
|
exitfn = acceptlineanddownhistory;
|
||||||
break;
|
break;
|
||||||
} else if(cmd == Th(z_acceptline)) {
|
} else if(cmd == Th(z_acceptline)) {
|
||||||
acceptline(zlenoargs);
|
exitfn = acceptline;
|
||||||
break;
|
break;
|
||||||
} else if(cmd == Th(z_historyincrementalsearchbackward)) {
|
} else if(cmd == Th(z_historyincrementalsearchbackward)) {
|
||||||
set_isrch_spot(top_spot++, hl, pos, zlecs, sbptr, dir, nomatch);
|
set_isrch_spot(top_spot++, hl, pos, zlemetacs, sbptr, dir, nomatch);
|
||||||
if (dir != -1)
|
if (dir != -1)
|
||||||
dir = -1;
|
dir = -1;
|
||||||
else
|
else
|
||||||
skip_pos = 1;
|
skip_pos = 1;
|
||||||
goto rpt;
|
goto rpt;
|
||||||
} else if(cmd == Th(z_historyincrementalsearchforward)) {
|
} else if(cmd == Th(z_historyincrementalsearchforward)) {
|
||||||
set_isrch_spot(top_spot++, hl, pos, zlecs, sbptr, dir, nomatch);
|
set_isrch_spot(top_spot++, hl, pos, zlemetacs, sbptr, dir, nomatch);
|
||||||
if (dir != 1)
|
if (dir != 1)
|
||||||
dir = 1;
|
dir = 1;
|
||||||
else
|
else
|
||||||
skip_pos = 1;
|
skip_pos = 1;
|
||||||
goto rpt;
|
goto rpt;
|
||||||
} else if(cmd == Th(z_virevrepeatsearch)) {
|
} else if(cmd == Th(z_virevrepeatsearch)) {
|
||||||
set_isrch_spot(top_spot++, hl, pos, zlecs, sbptr, dir, nomatch);
|
set_isrch_spot(top_spot++, hl, pos, zlemetacs, sbptr, dir, nomatch);
|
||||||
dir = -odir;
|
dir = -odir;
|
||||||
skip_pos = 1;
|
skip_pos = 1;
|
||||||
goto rpt;
|
goto rpt;
|
||||||
} else if(cmd == Th(z_virepeatsearch)) {
|
} else if(cmd == Th(z_virepeatsearch)) {
|
||||||
set_isrch_spot(top_spot++, hl, pos, zlecs, sbptr, dir, nomatch);
|
set_isrch_spot(top_spot++, hl, pos, zlemetacs, sbptr, dir, nomatch);
|
||||||
dir = odir;
|
dir = odir;
|
||||||
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) {
|
||||||
ibuf = hrealloc((char *)ibuf, sibuf * ZLE_CHAR_SIZE,
|
ibuf = hrealloc((char *)ibuf, sibuf,
|
||||||
(sibuf + previous_search_len)
|
(sibuf + previous_search_len));
|
||||||
* ZLE_CHAR_SIZE);
|
|
||||||
sbuf = ibuf + FIRST_SEARCH_CHAR;
|
sbuf = ibuf + FIRST_SEARCH_CHAR;
|
||||||
sibuf += previous_search_len;
|
sibuf += previous_search_len;
|
||||||
}
|
}
|
||||||
ZS_memcpy(sbuf, previous_search, sbptr = previous_search_len);
|
memcpy(sbuf, previous_search, sbptr = previous_search_len);
|
||||||
}
|
}
|
||||||
ZS_memcpy(ibuf + NORM_PROMPT_POS,
|
memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? "fwd" : "bck", 3);
|
||||||
(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] = ZWC('^');
|
sbuf[sbptr] = '^';
|
||||||
|
sbuf[sbptr+1] = '\0';
|
||||||
zrefresh();
|
zrefresh();
|
||||||
}
|
}
|
||||||
if (getfullchar(0) == ZLEEOF)
|
if (getfullchar(0) == ZLEEOF)
|
||||||
|
|
@ -1213,10 +1254,13 @@ doisearch(char **args, int dir)
|
||||||
feep = 1;
|
feep = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
set_isrch_spot(top_spot++, hl, pos, zlecs, sbptr, dir, nomatch);
|
set_isrch_spot(top_spot++, hl, pos, zlemetacs, sbptr, dir, nomatch);
|
||||||
if (sbptr >= sibuf - FIRST_SEARCH_CHAR - 2) {
|
if (sbptr >= sibuf - FIRST_SEARCH_CHAR - 2
|
||||||
ibuf = hrealloc((char *)ibuf, sibuf * ZLE_CHAR_SIZE,
|
#ifdef MULTIBYTE_SUPPORT
|
||||||
sibuf * 2 * ZLE_CHAR_SIZE);
|
- 2 * MB_CUR_MAX
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
ibuf = hrealloc(ibuf, sibuf, sibuf * 2);
|
||||||
sbuf = ibuf + FIRST_SEARCH_CHAR;
|
sbuf = ibuf + FIRST_SEARCH_CHAR;
|
||||||
sibuf *= 2;
|
sibuf *= 2;
|
||||||
}
|
}
|
||||||
|
|
@ -1224,7 +1268,7 @@ doisearch(char **args, int dir)
|
||||||
* 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;
|
sbptr += zlecharasstring(LASTFULLCHAR, sbuf + sbptr);
|
||||||
}
|
}
|
||||||
if (feep)
|
if (feep)
|
||||||
handlefeep(zlenoargs);
|
handlefeep(zlenoargs);
|
||||||
|
|
@ -1232,10 +1276,13 @@ 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 * ZLE_CHAR_SIZE);
|
previous_search = zalloc(sbptr);
|
||||||
ZS_memcpy(previous_search, sbuf, previous_search_len = sbptr);
|
memcpy(previous_search, sbuf, previous_search_len = sbptr);
|
||||||
}
|
}
|
||||||
statusline = NULL;
|
statusline = NULL;
|
||||||
|
unmetafy_line();
|
||||||
|
if (exitfn)
|
||||||
|
exitfn(zlenoargs);
|
||||||
selectkeymap(okeymap, 1);
|
selectkeymap(okeymap, 1);
|
||||||
zsfree(okeymap);
|
zsfree(okeymap);
|
||||||
/*
|
/*
|
||||||
|
|
@ -1252,17 +1299,20 @@ doisearch(char **args, int dir)
|
||||||
static Histent
|
static Histent
|
||||||
infernexthist(Histent he, UNUSED(char **args))
|
infernexthist(Histent he, UNUSED(char **args))
|
||||||
{
|
{
|
||||||
|
metafy_line();
|
||||||
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)) {
|
||||||
struct zle_text zt;
|
struct zle_text zt;
|
||||||
zletext(he, &zt);
|
zletext(he, &zt);
|
||||||
|
|
||||||
if (!zlinecmp(zt.text, zt.len, zleline, zlell)) {
|
if (!zlinecmp(zt.text, zlemetaline)) {
|
||||||
|
unmetafy_line();
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
return movehistent(he, 1, HIST_FOREIGN);
|
return movehistent(he, 1, HIST_FOREIGN);
|
||||||
}
|
}
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
}
|
}
|
||||||
|
unmetafy_line();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1321,7 +1371,7 @@ static int visrchsense;
|
||||||
static int
|
static int
|
||||||
getvisrchstr(void)
|
getvisrchstr(void)
|
||||||
{
|
{
|
||||||
ZLE_STRING_T sbuf = zhalloc(80 * ZLE_CHAR_SIZE);
|
char *sbuf = zhalloc(80);
|
||||||
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);
|
||||||
|
|
@ -1337,11 +1387,11 @@ getvisrchstr(void)
|
||||||
}
|
}
|
||||||
clearlist = 1;
|
clearlist = 1;
|
||||||
statusline = sbuf;
|
statusline = sbuf;
|
||||||
sbuf[0] = (visrchsense == -1) ? ZWC('?') : ZWC('/');
|
sbuf[0] = (visrchsense == -1) ? '?' : '/';
|
||||||
selectkeymap("main", 1);
|
selectkeymap("main", 1);
|
||||||
while (sptr) {
|
while (sptr) {
|
||||||
sbuf[sptr] = ZWC('_');
|
sbuf[sptr] = '_';
|
||||||
statusll = sptr + 1;
|
sbuf[sptr] = '\0';
|
||||||
zrefresh();
|
zrefresh();
|
||||||
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
@ -1357,32 +1407,52 @@ 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)) {
|
||||||
int newlen;
|
if (sptr) {
|
||||||
sbuf[sptr] = ZWC('\0');
|
sbuf[sptr] = ZWC('\0');
|
||||||
visrchstr = zlelineasstring(sbuf+1, sptr-1, 0, &newlen, NULL, 0);
|
visrchstr = ztrdup(sbuf+1);
|
||||||
if (!newlen) {
|
} else {
|
||||||
zsfree(visrchstr);
|
|
||||||
visrchstr = ztrdup(vipenultsrchstr);
|
visrchstr = ztrdup(vipenultsrchstr);
|
||||||
}
|
}
|
||||||
ret = 1;
|
ret = 1;
|
||||||
sptr = 0;
|
sptr = 0;
|
||||||
} else if(cmd == Th(z_backwarddeletechar) ||
|
} else if(cmd == Th(z_backwarddeletechar) ||
|
||||||
cmd == Th(z_vibackwarddeletechar)) {
|
cmd == Th(z_vibackwarddeletechar)) {
|
||||||
sptr--;
|
sptr = backwardmetafiedchar(sbuf+1, sbuf+sptr, NULL) - sbuf;
|
||||||
} else if(cmd == Th(z_backwardkillword) ||
|
} else if(cmd == Th(z_backwardkillword) ||
|
||||||
cmd == Th(z_vibackwardkillword)) {
|
cmd == Th(z_vibackwardkillword)) {
|
||||||
while(sptr != 1 && ZC_iblank(sbuf[sptr - 1]))
|
convchar_t cc;
|
||||||
sptr--;
|
char *newpos;
|
||||||
if(ZC_iident(sbuf[sptr - 1]))
|
while (sptr != 1) {
|
||||||
while(sptr != 1 && ZC_iident(sbuf[sptr - 1]))
|
newpos = backwardmetafiedchar(sbuf+1, sbuf+sptr, &cc);
|
||||||
sptr--;
|
if (!ZC_iblank(cc))
|
||||||
else
|
break;
|
||||||
while(sptr != 1 && !ZC_iident(sbuf[sptr - 1]) &&
|
sptr = newpos - sbuf;
|
||||||
!ZC_iblank(sbuf[sptr - 1]))
|
}
|
||||||
sptr--;
|
if (sptr > 1) {
|
||||||
|
newpos = backwardmetafiedchar(sbuf+1, sbuf+sptr, &cc);
|
||||||
|
if (ZC_iident(cc)) {
|
||||||
|
for (;;) {
|
||||||
|
sptr = newpos - sbuf;
|
||||||
|
if (sptr == 1)
|
||||||
|
break;
|
||||||
|
newpos = backwardmetafiedchar(sbuf+1, sbuf+sptr, &cc);
|
||||||
|
if (!ZC_iident(cc))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (;;) {
|
||||||
|
sptr = newpos - sbuf;
|
||||||
|
if (sptr == 1)
|
||||||
|
break;
|
||||||
|
newpos = backwardmetafiedchar(sbuf+1, sbuf+sptr, &cc);
|
||||||
|
if (ZC_iident(cc) || ZC_iblank(cc))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} 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] = ZWC('^');
|
sbuf[sptr] = '^';
|
||||||
zrefresh();
|
zrefresh();
|
||||||
}
|
}
|
||||||
if (getfullchar(0) == ZLEEOF)
|
if (getfullchar(0) == ZLEEOF)
|
||||||
|
|
@ -1405,12 +1475,11 @@ getvisrchstr(void)
|
||||||
}
|
}
|
||||||
ins:
|
ins:
|
||||||
if (sptr == ssbuf - 1) {
|
if (sptr == ssbuf - 1) {
|
||||||
ZLE_STRING_T newbuf =
|
char *newbuf = (char *)zhalloc((ssbuf *= 2));
|
||||||
(ZLE_STRING_T) zhalloc((ssbuf *= 2) * ZLE_CHAR_SIZE);
|
strcpy(newbuf, sbuf);
|
||||||
ZS_strcpy(newbuf, sbuf);
|
|
||||||
statusline = sbuf = newbuf;
|
statusline = sbuf = newbuf;
|
||||||
}
|
}
|
||||||
sbuf[sptr++] = LASTFULLCHAR;
|
sptr += zlecharasstring(LASTFULLCHAR, sbuf + sptr);
|
||||||
} else {
|
} else {
|
||||||
feep = 1;
|
feep = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -1471,8 +1540,6 @@ int
|
||||||
virepeatsearch(UNUSED(char **args))
|
virepeatsearch(UNUSED(char **args))
|
||||||
{
|
{
|
||||||
Histent he;
|
Histent he;
|
||||||
ZLE_STRING_T srcstr;
|
|
||||||
int srclen;
|
|
||||||
int n = zmult;
|
int n = zmult;
|
||||||
struct zle_text zt;
|
struct zle_text zt;
|
||||||
|
|
||||||
|
|
@ -1482,28 +1549,26 @@ virepeatsearch(UNUSED(char **args))
|
||||||
n = -n;
|
n = -n;
|
||||||
visrchsense = -visrchsense;
|
visrchsense = -visrchsense;
|
||||||
}
|
}
|
||||||
srcstr = stringaszleline(visrchstr, 0, &srclen, NULL, NULL);
|
|
||||||
if (!(he = quietgethist(histline)))
|
if (!(he = quietgethist(histline)))
|
||||||
return 1;
|
return 1;
|
||||||
|
metafy_line();
|
||||||
while ((he = movehistent(he, visrchsense, hist_skip_flags))) {
|
while ((he = movehistent(he, visrchsense, hist_skip_flags))) {
|
||||||
if (isset(HISTFINDNODUPS) && he->node.flags & HIST_DUP)
|
if (isset(HISTFINDNODUPS) && he->node.flags & HIST_DUP)
|
||||||
continue;
|
continue;
|
||||||
zletext(he, &zt);
|
zletext(he, &zt);
|
||||||
if (zlinecmp(zt.text, zt.len, zleline, zlell) &&
|
if (zlinecmp(zt.text, zlemetaline) &&
|
||||||
(*visrchstr == '^'?
|
(*visrchstr == '^' ? strpfx(zt.text, visrchstr + 1) :
|
||||||
(zt.len == srclen - 1 &&
|
zlinefind(zt.text, 0, visrchstr, 1, 1) != 0)) {
|
||||||
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) {
|
||||||
|
unmetafy_line();
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
free(srcstr);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
}
|
}
|
||||||
free(srcstr);
|
unmetafy_line();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1540,13 +1605,20 @@ historybeginningsearchbackward(char **args)
|
||||||
}
|
}
|
||||||
if (!(he = quietgethist(histline)))
|
if (!(he = quietgethist(histline)))
|
||||||
return 1;
|
return 1;
|
||||||
|
metafy_line();
|
||||||
while ((he = movehistent(he, -1, hist_skip_flags))) {
|
while ((he = movehistent(he, -1, hist_skip_flags))) {
|
||||||
|
int tst;
|
||||||
|
char sav;
|
||||||
if (isset(HISTFINDNODUPS) && he->node.flags & HIST_DUP)
|
if (isset(HISTFINDNODUPS) && he->node.flags & HIST_DUP)
|
||||||
continue;
|
continue;
|
||||||
zletext(he, &zt);
|
zletext(he, &zt);
|
||||||
if (zlinecmp(zt.text, zt.len, zleline, zlecs) < 0 &&
|
sav = zlemetaline[zlemetacs];
|
||||||
zlinecmp(zt.text, zt.len, zleline, zlell)) {
|
zlemetaline[zlemetacs] = '\0';
|
||||||
|
tst = zlinecmp(zt.text, zlemetaline);
|
||||||
|
zlemetaline[zlemetacs] = sav;
|
||||||
|
if (tst < 0 && zlinecmp(zt.text, zlemetaline)) {
|
||||||
if (--n <= 0) {
|
if (--n <= 0) {
|
||||||
|
unmetafy_line();
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
zlecs = cpos;
|
zlecs = cpos;
|
||||||
|
|
@ -1556,6 +1628,7 @@ historybeginningsearchbackward(char **args)
|
||||||
}
|
}
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
}
|
}
|
||||||
|
unmetafy_line();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1580,14 +1653,20 @@ historybeginningsearchforward(char **args)
|
||||||
}
|
}
|
||||||
if (!(he = quietgethist(histline)))
|
if (!(he = quietgethist(histline)))
|
||||||
return 1;
|
return 1;
|
||||||
|
metafy_line();
|
||||||
while ((he = movehistent(he, 1, hist_skip_flags))) {
|
while ((he = movehistent(he, 1, hist_skip_flags))) {
|
||||||
|
char sav;
|
||||||
|
int tst;
|
||||||
if (isset(HISTFINDNODUPS) && he->node.flags & HIST_DUP)
|
if (isset(HISTFINDNODUPS) && he->node.flags & HIST_DUP)
|
||||||
continue;
|
continue;
|
||||||
zletext(he, &zt);
|
zletext(he, &zt);
|
||||||
if (zlinecmp(zt.text, zt.len, zleline, zlecs) <
|
sav = zlemetaline[zlemetacs];
|
||||||
(he->histnum == curhist) &&
|
zlemetaline[zlemetacs] = '\0';
|
||||||
zlinecmp(zt.text, zt.len, zleline, zlell)) {
|
tst = zlinecmp(zt.text, zlemetaline) < (he->histnum == curhist);
|
||||||
|
zlemetaline[zlemetacs] = sav;
|
||||||
|
if (tst && zlinecmp(zt.text, zlemetaline)) {
|
||||||
if (--n <= 0) {
|
if (--n <= 0) {
|
||||||
|
unmetafy_line();
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
zle_setline(he);
|
zle_setline(he);
|
||||||
zlecs = cpos;
|
zlecs = cpos;
|
||||||
|
|
@ -1597,5 +1676,6 @@ historybeginningsearchforward(char **args)
|
||||||
}
|
}
|
||||||
zletextfree(&zt);
|
zletextfree(&zt);
|
||||||
}
|
}
|
||||||
|
unmetafy_line();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,12 +143,10 @@ mod_export int lastcmd;
|
||||||
/**/
|
/**/
|
||||||
mod_export Widget compwidget;
|
mod_export Widget compwidget;
|
||||||
|
|
||||||
/* the status line, and its length */
|
/* the status line, a null-terminated metafied string */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
mod_export ZLE_STRING_T statusline;
|
mod_export char *statusline;
|
||||||
/**/
|
|
||||||
mod_export int statusll;
|
|
||||||
|
|
||||||
/* The current history line and cursor position for the top line *
|
/* The current history line and cursor position for the top line *
|
||||||
* on the buffer stack. */
|
* on the buffer stack. */
|
||||||
|
|
@ -1240,12 +1238,16 @@ zleread(char **lp, char **rp, int flags, int context)
|
||||||
int
|
int
|
||||||
execzlefunc(Thingy func, char **args, int set_bindk)
|
execzlefunc(Thingy func, char **args, int set_bindk)
|
||||||
{
|
{
|
||||||
int r = 0, ret = 0;
|
int r = 0, ret = 0, remetafy = 0;
|
||||||
Widget w;
|
Widget w;
|
||||||
Thingy save_bindk = bindk;
|
Thingy save_bindk = bindk;
|
||||||
|
|
||||||
if (set_bindk)
|
if (set_bindk)
|
||||||
bindk = func;
|
bindk = func;
|
||||||
|
if (zlemetaline) {
|
||||||
|
unmetafy_line();
|
||||||
|
remetafy = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(func->flags & DISABLED) {
|
if(func->flags & DISABLED) {
|
||||||
/* this thingy is not the name of a widget */
|
/* this thingy is not the name of a widget */
|
||||||
|
|
@ -1350,6 +1352,8 @@ execzlefunc(Thingy func, char **args, int set_bindk)
|
||||||
* directly.
|
* directly.
|
||||||
*/
|
*/
|
||||||
CCRIGHT();
|
CCRIGHT();
|
||||||
|
if (remetafy)
|
||||||
|
metafy_line();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1632,8 +1636,7 @@ describekeybriefly(UNUSED(char **args))
|
||||||
if (statusline)
|
if (statusline)
|
||||||
return 1;
|
return 1;
|
||||||
clearlist = 1;
|
clearlist = 1;
|
||||||
statusline = ZWS("Describe key briefly: _");
|
statusline = "Describe key briefly: _";
|
||||||
statusll = ZS_strlen(statusline);
|
|
||||||
zrefresh();
|
zrefresh();
|
||||||
seq = getkeymapcmd(curkeymap, &func, &str);
|
seq = getkeymapcmd(curkeymap, &func, &str);
|
||||||
statusline = NULL;
|
statusline = NULL;
|
||||||
|
|
|
||||||
|
|
@ -914,24 +914,27 @@ executenamedcommand(char *prmt)
|
||||||
Thingy cmd;
|
Thingy cmd;
|
||||||
int l, len, feep = 0, listed = 0, curlist = 0;
|
int l, len, feep = 0, listed = 0, curlist = 0;
|
||||||
int ols = (listshown && validlist), olll = lastlistlen;
|
int ols = (listshown && validlist), olll = lastlistlen;
|
||||||
ZLE_STRING_T cmdbuf, ptr, zprmt;
|
char *cmdbuf, *ptr;
|
||||||
char *okeymap = ztrdup(curkeymapname);
|
char *okeymap = ztrdup(curkeymapname);
|
||||||
|
|
||||||
clearlist = 1;
|
clearlist = 1;
|
||||||
/* prmt may be constant */
|
/* prmt may be constant */
|
||||||
prmt = ztrdup(prmt);
|
prmt = ztrdup(prmt);
|
||||||
zprmt = stringaszleline(prmt, 0, &l, NULL, NULL);
|
l = strlen(prmt);
|
||||||
cmdbuf = zhalloc((l + NAMLEN + 2) * ZLE_CHAR_SIZE);
|
cmdbuf = (char *)zhalloc(l + NAMLEN + 2 +
|
||||||
ZS_memcpy(cmdbuf, zprmt, l);
|
#ifdef MULTIBYTE_SUPPORT
|
||||||
free(zprmt);
|
2 * MB_CUR_MAX
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
strcpy(cmdbuf, prmt);
|
||||||
zsfree(prmt);
|
zsfree(prmt);
|
||||||
statusline = cmdbuf;
|
statusline = cmdbuf;
|
||||||
selectkeymap("main", 1);
|
selectkeymap("main", 1);
|
||||||
ptr = cmdbuf += l;
|
ptr = cmdbuf += l;
|
||||||
len = 0;
|
len = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
*ptr = ZWC('_');
|
*ptr = '_';
|
||||||
statusll = l + len + 1;
|
ptr[1] = '\0';
|
||||||
zrefresh();
|
zrefresh();
|
||||||
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
||||||
statusline = NULL;
|
statusline = NULL;
|
||||||
|
|
@ -966,31 +969,45 @@ executenamedcommand(char *prmt)
|
||||||
zmult = zmultsav;
|
zmult = zmultsav;
|
||||||
}
|
}
|
||||||
} else if(cmd == Th(z_viquotedinsert)) {
|
} else if(cmd == Th(z_viquotedinsert)) {
|
||||||
*ptr = ZWC('^');
|
*ptr = '^';
|
||||||
zrefresh();
|
zrefresh();
|
||||||
getfullchar(0);
|
getfullchar(0);
|
||||||
if(LASTFULLCHAR == ZLEEOF || !LASTFULLCHAR || len == NAMLEN)
|
if(LASTFULLCHAR == ZLEEOF || !LASTFULLCHAR || len >= NAMLEN)
|
||||||
feep = 1;
|
feep = 1;
|
||||||
else {
|
else {
|
||||||
*ptr++ = LASTFULLCHAR, len++, curlist = 0;
|
int ret = zlecharasstring(LASTFULLCHAR, ptr);
|
||||||
|
len += ret;
|
||||||
|
ptr += ret;
|
||||||
|
curlist = 0;
|
||||||
}
|
}
|
||||||
} else if(cmd == Th(z_quotedinsert)) {
|
} else if(cmd == Th(z_quotedinsert)) {
|
||||||
if(getfullchar(0) == ZLEEOF ||
|
if(getfullchar(0) == ZLEEOF ||
|
||||||
!LASTFULLCHAR || len == NAMLEN)
|
!LASTFULLCHAR || len == NAMLEN)
|
||||||
feep = 1;
|
feep = 1;
|
||||||
else {
|
else {
|
||||||
*ptr++ = LASTFULLCHAR, len++, curlist = 0;
|
int ret = zlecharasstring(LASTFULLCHAR, ptr);
|
||||||
|
len += ret;
|
||||||
|
ptr += ret;
|
||||||
|
curlist = 0;
|
||||||
}
|
}
|
||||||
} else if(cmd == Th(z_backwarddeletechar) ||
|
} else if(cmd == Th(z_backwarddeletechar) ||
|
||||||
cmd == Th(z_vibackwarddeletechar)) {
|
cmd == Th(z_vibackwarddeletechar)) {
|
||||||
if (len) {
|
if (len) {
|
||||||
len--, ptr--, curlist = 0;
|
ptr = backwardmetafiedchar(cmdbuf, ptr, NULL);
|
||||||
|
len = ptr - cmdbuf;
|
||||||
|
curlist = 0;
|
||||||
}
|
}
|
||||||
} else if(cmd == Th(z_killregion) || cmd == Th(z_backwardkillword) ||
|
} else if(cmd == Th(z_killregion) || cmd == Th(z_backwardkillword) ||
|
||||||
cmd == Th(z_vibackwardkillword)) {
|
cmd == Th(z_vibackwardkillword)) {
|
||||||
if (len)
|
if (len)
|
||||||
curlist = 0;
|
curlist = 0;
|
||||||
while (len && (len--, *--ptr != ZWC('-')));
|
while (len) {
|
||||||
|
convchar_t cc;
|
||||||
|
ptr = backwardmetafiedchar(cmdbuf, ptr, &cc);
|
||||||
|
len = ptr - cmdbuf;
|
||||||
|
if (cc == ZWC('-'))
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else if(cmd == Th(z_killwholeline) || cmd == Th(z_vikillline) ||
|
} else if(cmd == Th(z_killwholeline) || cmd == Th(z_vikillline) ||
|
||||||
cmd == Th(z_backwardkillline)) {
|
cmd == Th(z_backwardkillline)) {
|
||||||
len = 0;
|
len = 0;
|
||||||
|
|
@ -1003,10 +1020,7 @@ executenamedcommand(char *prmt)
|
||||||
Thingy r;
|
Thingy r;
|
||||||
unambiguous:
|
unambiguous:
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
namedcmdstr = zlelineasstring(cmdbuf, len, 0, NULL, NULL, 0);
|
r = rthingy(cmdbuf);
|
||||||
r = rthingy(namedcmdstr);
|
|
||||||
free(namedcmdstr);
|
|
||||||
namedcmdstr = NULL;
|
|
||||||
if (!(r->flags & DISABLED)) {
|
if (!(r->flags & DISABLED)) {
|
||||||
unrefthingy(r);
|
unrefthingy(r);
|
||||||
statusline = NULL;
|
statusline = NULL;
|
||||||
|
|
@ -1033,9 +1047,9 @@ executenamedcommand(char *prmt)
|
||||||
|
|
||||||
namedcmdll = newlinklist();
|
namedcmdll = newlinklist();
|
||||||
|
|
||||||
namedcmdstr = zlelineasstring(cmdbuf, len, 0, NULL, NULL, 0);
|
*ptr = '\0';
|
||||||
|
namedcmdstr = cmdbuf;
|
||||||
scanhashtable(thingytab, 1, 0, DISABLED, scancompcmd, 0);
|
scanhashtable(thingytab, 1, 0, DISABLED, scancompcmd, 0);
|
||||||
free(namedcmdstr);
|
|
||||||
namedcmdstr = NULL;
|
namedcmdstr = NULL;
|
||||||
|
|
||||||
if (empty(namedcmdll)) {
|
if (empty(namedcmdll)) {
|
||||||
|
|
@ -1046,39 +1060,29 @@ executenamedcommand(char *prmt)
|
||||||
} else if (cmd == Th(z_listchoices) ||
|
} else if (cmd == Th(z_listchoices) ||
|
||||||
cmd == Th(z_deletecharorlist)) {
|
cmd == Th(z_deletecharorlist)) {
|
||||||
int zmultsav = zmult;
|
int zmultsav = zmult;
|
||||||
*ptr = ZWC('_');
|
*ptr = '_';
|
||||||
statusll = l + len + 1;
|
ptr[1] = '\0';
|
||||||
zmult = 1;
|
zmult = 1;
|
||||||
listlist(namedcmdll);
|
listlist(namedcmdll);
|
||||||
listed = curlist = 1;
|
listed = curlist = 1;
|
||||||
showinglist = 0;
|
showinglist = 0;
|
||||||
zmult = zmultsav;
|
zmult = zmultsav;
|
||||||
} else if (!nextnode(firstnode(namedcmdll))) {
|
} else if (!nextnode(firstnode(namedcmdll))) {
|
||||||
char *peekstr = ztrdup(peekfirst(namedcmdll));
|
strcpy(ptr = cmdbuf, peekfirst(namedcmdll));
|
||||||
ZLE_STRING_T ztmp = stringaszleline(peekstr, 0, &len,
|
len = strlen(ptr);
|
||||||
NULL, NULL);
|
|
||||||
zsfree(peekstr);
|
|
||||||
ZS_memcpy(ptr = cmdbuf, ztmp, len);
|
|
||||||
ptr += len;
|
ptr += len;
|
||||||
free(ztmp);
|
if (cmd == Th(z_acceptline) || cmd == Th(z_vicmdmode))
|
||||||
if(cmd == Th(z_acceptline) || cmd == Th(z_vicmdmode))
|
|
||||||
goto unambiguous;
|
goto unambiguous;
|
||||||
} else {
|
} else {
|
||||||
int ltmp;
|
strcpy(cmdbuf, peekfirst(namedcmdll));
|
||||||
char *peekstr = ztrdup(peekfirst(namedcmdll));
|
|
||||||
ZLE_STRING_T ztmp = stringaszleline(peekstr, 0, <mp,
|
|
||||||
NULL, NULL);
|
|
||||||
zsfree(peekstr);
|
|
||||||
ZS_memcpy(cmdbuf, ztmp, ltmp);
|
|
||||||
free(ztmp);
|
|
||||||
ptr = cmdbuf + namedcmdambig;
|
ptr = cmdbuf + namedcmdambig;
|
||||||
*ptr = ZWC('_');
|
*ptr = '_';
|
||||||
|
ptr[1] = '\0';
|
||||||
if (isset(AUTOLIST) &&
|
if (isset(AUTOLIST) &&
|
||||||
!(isset(LISTAMBIGUOUS) && namedcmdambig > len)) {
|
!(isset(LISTAMBIGUOUS) && namedcmdambig > len)) {
|
||||||
int zmultsav = zmult;
|
int zmultsav = zmult;
|
||||||
if (isset(LISTBEEP))
|
if (isset(LISTBEEP))
|
||||||
feep = 1;
|
feep = 1;
|
||||||
statusll = l + namedcmdambig + 1;
|
|
||||||
zmult = 1;
|
zmult = 1;
|
||||||
listlist(namedcmdll);
|
listlist(namedcmdll);
|
||||||
listed = curlist = 1;
|
listed = curlist = 1;
|
||||||
|
|
@ -1100,8 +1104,16 @@ executenamedcommand(char *prmt)
|
||||||
#endif
|
#endif
|
||||||
if (ZC_icntrl(LASTFULLCHAR))
|
if (ZC_icntrl(LASTFULLCHAR))
|
||||||
feep = 1;
|
feep = 1;
|
||||||
else
|
else {
|
||||||
*ptr++ = LASTFULLCHAR, len++, curlist = 0;
|
int ret = zlecharasstring(LASTFULLCHAR, ptr);
|
||||||
|
len += ret;
|
||||||
|
ptr += ret;
|
||||||
|
if (listed) {
|
||||||
|
clearlist = listshown = 1;
|
||||||
|
listed = 0;
|
||||||
|
} else
|
||||||
|
curlist = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,144 @@ decpos(int *pos)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Size of buffer in the following function */
|
||||||
|
#define BMC_BUFSIZE MB_CUR_MAX
|
||||||
|
/*
|
||||||
|
* For a metafied string that starts at "start" and where the
|
||||||
|
* current position is "ptr", go back one full character,
|
||||||
|
* taking account of combining characters if necessary.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**/
|
||||||
|
char *
|
||||||
|
backwardmetafiedchar(char *start, char *ptr, convchar_t *retchr)
|
||||||
|
{
|
||||||
|
#ifdef MULTIBYTE_SUPPORT
|
||||||
|
int charlen = 0;
|
||||||
|
char *last = NULL, *bufptr, *endptr = ptr;
|
||||||
|
convchar_t lastc;
|
||||||
|
mbstate_t mbs;
|
||||||
|
size_t ret;
|
||||||
|
wchar_t wc;
|
||||||
|
VARARR(char, buf, BMC_BUFSIZE);
|
||||||
|
|
||||||
|
bufptr = buf + BMC_BUFSIZE;
|
||||||
|
while (ptr > start) {
|
||||||
|
ptr--;
|
||||||
|
/*
|
||||||
|
* Scanning backwards we're not guaranteed ever to find a
|
||||||
|
* valid character. If we've looked as far as we should
|
||||||
|
* need to, give up.
|
||||||
|
*/
|
||||||
|
if (bufptr-- == buf)
|
||||||
|
break;
|
||||||
|
charlen++;
|
||||||
|
if (ptr > start && ptr[-1] == Meta)
|
||||||
|
*bufptr = *ptr-- ^ 32;
|
||||||
|
else
|
||||||
|
*bufptr = *ptr;
|
||||||
|
|
||||||
|
/* we always need to restart the character from scratch */
|
||||||
|
memset(&mbs, 0, sizeof(mbs));
|
||||||
|
ret = mbrtowc(&wc, bufptr, charlen, &mbs);
|
||||||
|
if (ret == 0) {
|
||||||
|
/* NULL: unlikely, but handle anyway. */
|
||||||
|
if (last) {
|
||||||
|
if (retchr)
|
||||||
|
*retchr = lastc;
|
||||||
|
return last;
|
||||||
|
} else {
|
||||||
|
if (retchr)
|
||||||
|
*retchr = wc;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret >= 0) {
|
||||||
|
if (ret < charlen) {
|
||||||
|
/* The last character didn't convert, so use it raw. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!isset(COMBININGCHARS)) {
|
||||||
|
if (retchr)
|
||||||
|
*retchr = wc;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
/* HERE: test for combining char, fix when test changes */
|
||||||
|
if (!iswpunct(wc) || wcwidth(wc) != 0) {
|
||||||
|
/* not a combining character... */
|
||||||
|
if (last) {
|
||||||
|
/*
|
||||||
|
* ... but we were looking for a suitable base character,
|
||||||
|
* test it.
|
||||||
|
*/
|
||||||
|
/* HERE this test will change too */
|
||||||
|
if (iwsalnum(wc) && wcwidth(wc) > 0) {
|
||||||
|
/*
|
||||||
|
* Yes, this will do.
|
||||||
|
*/
|
||||||
|
if (retchr)
|
||||||
|
*retchr = wc;
|
||||||
|
return ptr;
|
||||||
|
} else {
|
||||||
|
/* No, just return the first character we found */
|
||||||
|
if (retchr)
|
||||||
|
*retchr = lastc;
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* This is the first character, so just return it. */
|
||||||
|
if (retchr)
|
||||||
|
*retchr = wc;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
if (!last) {
|
||||||
|
/* still looking for the character immediately before ptr */
|
||||||
|
last = ptr;
|
||||||
|
}
|
||||||
|
/* searching for base character of combining character */
|
||||||
|
charlen = 0;
|
||||||
|
bufptr = buf + BMC_BUFSIZE;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Else keep scanning this character even if MB_INVALID: we can't
|
||||||
|
* expect MB_INCOMPLETE to work when moving backwards.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Found something we didn't like, was there a good character
|
||||||
|
* immediately before ptr?
|
||||||
|
*/
|
||||||
|
if (last) {
|
||||||
|
if (retchr)
|
||||||
|
*retchr = lastc;
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* No, we couldn't find any good character, so just treat
|
||||||
|
* the last unmetafied byte we found as a character.
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
if (endptr > start) {
|
||||||
|
if (endptr > start - 1 && endptr[-2] == Meta)
|
||||||
|
{
|
||||||
|
if (retchr)
|
||||||
|
*retchr = (convchar_t)(endptr[-1] ^ 32);
|
||||||
|
return endptr - 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (retchr)
|
||||||
|
*retchr = (convchar_t)endptr[-1];
|
||||||
|
return endptr - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (retchr)
|
||||||
|
*retchr = (convchar_t)0;
|
||||||
|
return endptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
beginningofline(char **args)
|
beginningofline(char **args)
|
||||||
|
|
|
||||||
|
|
@ -1387,11 +1387,15 @@ zrefresh(void)
|
||||||
more_end = 1;
|
more_end = 1;
|
||||||
|
|
||||||
if (statusline) {
|
if (statusline) {
|
||||||
|
int outll, outsz;
|
||||||
|
ZLE_STRING_T outputline =
|
||||||
|
stringaszleline(statusline, 0, &outll, &outsz, NULL);
|
||||||
|
|
||||||
rpms.tosln = rpms.ln + 1;
|
rpms.tosln = rpms.ln + 1;
|
||||||
nbuf[rpms.ln][winw + 1] = zr_zr; /* text not wrapped */
|
nbuf[rpms.ln][winw + 1] = zr_zr; /* text not wrapped */
|
||||||
snextline(&rpms);
|
snextline(&rpms);
|
||||||
u = statusline;
|
u = outputline;
|
||||||
for (; u < statusline + statusll; u++) {
|
for (; u < outputline + outll; u++) {
|
||||||
#ifdef MULTIBYTE_SUPPORT
|
#ifdef MULTIBYTE_SUPPORT
|
||||||
if (iswprint(*u)) {
|
if (iswprint(*u)) {
|
||||||
int width = wcwidth(*u);
|
int width = wcwidth(*u);
|
||||||
|
|
@ -1449,6 +1453,7 @@ zrefresh(void)
|
||||||
*/
|
*/
|
||||||
snextline(&rpms);
|
snextline(&rpms);
|
||||||
}
|
}
|
||||||
|
zfree(outputline, outsz);
|
||||||
}
|
}
|
||||||
*rpms.s = zr_zr;
|
*rpms.s = zr_zr;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -406,16 +406,15 @@ bin_zle_list(UNUSED(char *name), char **args, Options ops, UNUSED(char func))
|
||||||
static int
|
static int
|
||||||
bin_zle_refresh(UNUSED(char *name), char **args, Options ops, UNUSED(char func))
|
bin_zle_refresh(UNUSED(char *name), char **args, Options ops, UNUSED(char func))
|
||||||
{
|
{
|
||||||
ZLE_STRING_T s = statusline;
|
char *s = statusline;
|
||||||
int sl = statusll, ocl = clearlist;
|
int ocl = clearlist;
|
||||||
|
|
||||||
if (!zleactive)
|
if (!zleactive)
|
||||||
return 1;
|
return 1;
|
||||||
statusline = NULL;
|
statusline = NULL;
|
||||||
statusll = 0;
|
|
||||||
if (*args) {
|
if (*args) {
|
||||||
if (**args)
|
if (**args)
|
||||||
statusline = stringaszleline(*args, 0, &statusll, NULL, NULL);
|
statusline = *args;
|
||||||
if (*++args) {
|
if (*++args) {
|
||||||
LinkList l = newlinklist();
|
LinkList l = newlinklist();
|
||||||
int zmultsav = zmult;
|
int zmultsav = zmult;
|
||||||
|
|
@ -439,12 +438,8 @@ bin_zle_refresh(UNUSED(char *name), char **args, Options ops, UNUSED(char func))
|
||||||
}
|
}
|
||||||
zrefresh();
|
zrefresh();
|
||||||
|
|
||||||
if (statusline)
|
|
||||||
free(statusline);
|
|
||||||
|
|
||||||
clearlist = ocl;
|
clearlist = ocl;
|
||||||
statusline = s;
|
statusline = s;
|
||||||
statusll = sl;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,54 @@ zleaddtoline(int chr)
|
||||||
zlemetaline[zlemetacs++] = chr;
|
zlemetaline[zlemetacs++] = chr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a line editor character to a possibly multibyte character
|
||||||
|
* in a metafied string. To be safe buf should have space for at least
|
||||||
|
* 2 * MB_CUR_MAX chars for multibyte mode and 2 otherwise. Returns the
|
||||||
|
* length of the string added.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**/
|
||||||
|
int
|
||||||
|
zlecharasstring(ZLE_CHAR_T inchar, char *buf)
|
||||||
|
{
|
||||||
|
#ifdef MULTIBYTE_SUPPORT
|
||||||
|
size_t ret;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
ret = wctomb(buf, inchar);
|
||||||
|
if (ret <= 0) {
|
||||||
|
/* Ick. */
|
||||||
|
buf[0] = '?';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ptr = buf + ret - 1;
|
||||||
|
for (;;) {
|
||||||
|
if (imeta(*ptr)) {
|
||||||
|
char *ptr2 = buf + ret - 1;
|
||||||
|
for (;;) {
|
||||||
|
ptr2[1] = ptr2[0];
|
||||||
|
if (ptr2 == ptr)
|
||||||
|
break;
|
||||||
|
ptr2--;
|
||||||
|
}
|
||||||
|
*ptr = Meta;
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr == buf)
|
||||||
|
return ret;
|
||||||
|
ptr--;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (imeta(inchar)) {
|
||||||
|
buf[0] = Meta;
|
||||||
|
buf[1] = inchar ^ 32;
|
||||||
|
} else
|
||||||
|
buf[0] = inchar;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Input a line in internal zle format, possibly using wide characters,
|
* Input a line in internal zle format, possibly using wide characters,
|
||||||
* possibly not, together with its length and the cursor position.
|
* possibly not, together with its length and the cursor position.
|
||||||
|
|
@ -621,7 +669,7 @@ void
|
||||||
setline(char *s, int flags)
|
setline(char *s, int flags)
|
||||||
{
|
{
|
||||||
char *scp;
|
char *scp;
|
||||||
|
|
||||||
if (flags & ZSL_COPY)
|
if (flags & ZSL_COPY)
|
||||||
scp = ztrdup(s);
|
scp = ztrdup(s);
|
||||||
else
|
else
|
||||||
|
|
@ -639,7 +687,6 @@ setline(char *s, int flags)
|
||||||
else if (zlecs > zlell)
|
else if (zlecs > zlell)
|
||||||
zlecs = zlell;
|
zlecs = zlell;
|
||||||
CCRIGHT();
|
CCRIGHT();
|
||||||
|
|
||||||
if (flags & ZSL_COPY)
|
if (flags & ZSL_COPY)
|
||||||
free(scp);
|
free(scp);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -853,8 +853,7 @@ vicapslockpanic(UNUSED(char **args))
|
||||||
{
|
{
|
||||||
clearlist = 1;
|
clearlist = 1;
|
||||||
zbeep();
|
zbeep();
|
||||||
statusline = ZWS("press a lowercase key to continue");
|
statusline = "press a lowercase key to continue";
|
||||||
statusll = ZS_strlen(statusline);
|
|
||||||
zrefresh();
|
zrefresh();
|
||||||
while (!ZC_ilower(getfullchar(0)));
|
while (!ZC_ilower(getfullchar(0)));
|
||||||
statusline = NULL;
|
statusline = NULL;
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,6 @@ viforwardwordend(char **args)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
while (n--) {
|
while (n--) {
|
||||||
/* HERE: the zlecs + 1 here is suspect */
|
|
||||||
int pos;
|
int pos;
|
||||||
while (zlecs != zlell) {
|
while (zlecs != zlell) {
|
||||||
pos = zlecs;
|
pos = zlecs;
|
||||||
|
|
|
||||||
81
Src/utils.c
81
Src/utils.c
|
|
@ -3967,6 +3967,50 @@ nicedup(const char *s, int heap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The guts of mb_metacharlenconv(). This version assumes we are
|
||||||
|
* processing a true multibyte character string without tokens, and
|
||||||
|
* takes the shift state as an argument.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**/
|
||||||
|
mod_export int
|
||||||
|
mb_metacharlenconv_r(const char *s, wint_t *wcp, mbstate_t *mbsp)
|
||||||
|
{
|
||||||
|
size_t ret = MB_INVALID;
|
||||||
|
char inchar;
|
||||||
|
const char *ptr;
|
||||||
|
wchar_t wc;
|
||||||
|
|
||||||
|
for (ptr = s; *ptr; ) {
|
||||||
|
if (*ptr == Meta) {
|
||||||
|
inchar = *++ptr ^ 32;
|
||||||
|
DPUTS(!*ptr,
|
||||||
|
"BUG: unexpected end of string in mb_metacharlen()\n");
|
||||||
|
} else
|
||||||
|
inchar = *ptr;
|
||||||
|
ptr++;
|
||||||
|
ret = mbrtowc(&wc, &inchar, 1, mbsp);
|
||||||
|
|
||||||
|
if (ret == MB_INVALID)
|
||||||
|
break;
|
||||||
|
if (ret == MB_INCOMPLETE)
|
||||||
|
continue;
|
||||||
|
if (wcp)
|
||||||
|
*wcp = wc;
|
||||||
|
return ptr - s;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wcp)
|
||||||
|
*wcp = WEOF;
|
||||||
|
/* No valid multibyte sequence */
|
||||||
|
memset(mbsp, 0, sizeof(*mbsp));
|
||||||
|
if (ptr > s) {
|
||||||
|
return 1 + (*s == Meta); /* Treat as single byte character */
|
||||||
|
} else
|
||||||
|
return 0; /* Probably shouldn't happen */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Length of metafied string s which contains the next multibyte
|
* Length of metafied string s which contains the next multibyte
|
||||||
* character; single (possibly metafied) character if string is not null
|
* character; single (possibly metafied) character if string is not null
|
||||||
|
|
@ -3982,11 +4026,6 @@ nicedup(const char *s, int heap)
|
||||||
mod_export int
|
mod_export int
|
||||||
mb_metacharlenconv(const char *s, wint_t *wcp)
|
mb_metacharlenconv(const char *s, wint_t *wcp)
|
||||||
{
|
{
|
||||||
char inchar;
|
|
||||||
const char *ptr;
|
|
||||||
size_t ret;
|
|
||||||
wchar_t wc;
|
|
||||||
|
|
||||||
if (!isset(MULTIBYTE)) {
|
if (!isset(MULTIBYTE)) {
|
||||||
/* treat as single byte, possibly metafied */
|
/* treat as single byte, possibly metafied */
|
||||||
if (wcp)
|
if (wcp)
|
||||||
|
|
@ -4009,37 +4048,7 @@ mb_metacharlenconv(const char *s, wint_t *wcp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = MB_INVALID;
|
return mb_metacharlenconv_r(s, wcp, &mb_shiftstate);
|
||||||
for (ptr = s; *ptr; ) {
|
|
||||||
if (*ptr == Meta) {
|
|
||||||
inchar = *++ptr ^ 32;
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (!*ptr)
|
|
||||||
fprintf(stderr,
|
|
||||||
"BUG: unexpected end of string in mb_metacharlen()\n");
|
|
||||||
#endif
|
|
||||||
} else
|
|
||||||
inchar = *ptr;
|
|
||||||
ptr++;
|
|
||||||
ret = mbrtowc(&wc, &inchar, 1, &mb_shiftstate);
|
|
||||||
|
|
||||||
if (ret == MB_INVALID)
|
|
||||||
break;
|
|
||||||
if (ret == MB_INCOMPLETE)
|
|
||||||
continue;
|
|
||||||
if (wcp)
|
|
||||||
*wcp = wc;
|
|
||||||
return ptr - s;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wcp)
|
|
||||||
*wcp = WEOF;
|
|
||||||
/* No valid multibyte sequence */
|
|
||||||
memset(&mb_shiftstate, 0, sizeof(mb_shiftstate));
|
|
||||||
if (ptr > s) {
|
|
||||||
return 1 + (*s == Meta); /* Treat as single byte character */
|
|
||||||
} else
|
|
||||||
return 0; /* Probably shouldn't happen */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
11
Src/zsh.h
11
Src/zsh.h
|
|
@ -1606,12 +1606,11 @@ 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) */
|
||||||
#ifdef MULTIBYTE_SUPPORT /* (Note: must match ZLE_STRING_T!) */
|
char *zle_text; /* the edited history line,
|
||||||
wchar_t *zle_text; /* the edited history line */
|
* a metafied, NULL-terminated string,
|
||||||
#else
|
* i.e the same format as the original
|
||||||
char *zle_text; /* the edited history line */
|
* entry
|
||||||
#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