search.c (screen-4.8.0) | : | search.c (screen-4.9.0) | ||
---|---|---|---|---|
skipping to change at line 49 | skipping to change at line 49 | |||
extern struct win *fore; | extern struct win *fore; | |||
#ifdef COPY_PASTE | #ifdef COPY_PASTE | |||
int search_ic; | int search_ic; | |||
/******************************************************************** | /******************************************************************** | |||
* VI style Search | * VI style Search | |||
*/ | */ | |||
static int matchword __P((char *, int, int, int)); | static int matchword __P((char*, int, int, int)); | |||
static void searchend __P((char *, int, char *)); | static void searchend __P((char*, int, char *)); | |||
static void backsearchend __P((char *, int, char *)); | static void backsearchend __P((char*, int, char *)); | |||
void | void | |||
Search(dir) | Search(int dir) | |||
int dir; | ||||
{ | { | |||
struct markdata *markdata; | struct markdata *markdata; | |||
if (dir == 0) | if (dir == 0) { | |||
{ | markdata = (struct markdata *)flayer->l_data; | |||
markdata = (struct markdata *)flayer->l_data; | if (markdata->isdir > 0) | |||
if (markdata->isdir > 0) | searchend(0, 0, NULL); | |||
searchend(0, 0, NULL); | else if (markdata->isdir < 0) | |||
else if (markdata->isdir < 0) | backsearchend(0, 0, NULL); | |||
backsearchend(0, 0, NULL); | else | |||
else | LMsg(0, "No previous pattern"); | |||
LMsg(0, "No previous pattern"); | } else | |||
} | Input((dir > 0 ? "/" : "?"), sizeof(markdata->isstr) - 1, | |||
else | INP_COOKED, (dir > 0 ? searchend : backsearchend), NULL, 0); | |||
Input((dir > 0 ? "/" : "?"), sizeof(markdata->isstr)-1, INP_COOKED, | ||||
(dir > 0 ? searchend : backsearchend), NULL, 0); | ||||
} | } | |||
static void | static void | |||
searchend(buf, len, data) | searchend(char *buf, int len, char *data) | |||
char *buf; | ||||
int len; | ||||
char *data; /* dummy */ | ||||
{ | { | |||
int x = 0, sx, ex, y; | int x = 0, sx, ex, y; | |||
struct markdata *markdata; | struct markdata *markdata; | |||
struct win *p; | struct win *p; | |||
markdata = (struct markdata *)flayer->l_data; | markdata = (struct markdata *)flayer->l_data; | |||
p = markdata->md_window; | p = markdata->md_window; | |||
markdata->isdir = 1; | markdata->isdir = 1; | |||
if (len) | if (len) | |||
strcpy(markdata->isstr, buf); | strcpy(markdata->isstr, buf); | |||
sx = markdata->cx + 1; | sx = markdata->cx + 1; | |||
ex = flayer->l_width - 1; | ex = flayer->l_width - 1; | |||
for (y = markdata->cy; y < p->w_histheight + flayer->l_height; y++, sx = 0) | for (y = markdata->cy; y < p->w_histheight + flayer->l_height; | |||
{ | y++, sx = 0) { | |||
if ((x = matchword(markdata->isstr, y, sx, ex)) >= 0) | if ((x = matchword(markdata->isstr, y, sx, ex)) >= 0) | |||
break; | break; | |||
} | } | |||
if (y >= p->w_histheight + flayer->l_height) | if (y >= p->w_histheight + flayer->l_height) { | |||
{ | LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); | |||
LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); | LMsg(0, "Pattern not found"); | |||
LMsg(0, "Pattern not found"); | } else | |||
} | revto(x, y); | |||
else | ||||
revto(x, y); | ||||
} | } | |||
static void | static void | |||
backsearchend(buf, len, data) | backsearchend(char *buf, int len, char *data) | |||
char *buf; | ||||
int len; | ||||
char *data; /* dummy */ | ||||
{ | { | |||
int sx, ex, x = -1, y; | int sx, ex, x = -1, y; | |||
struct markdata *markdata; | struct markdata *markdata; | |||
markdata = (struct markdata *)flayer->l_data; | ||||
markdata->isdir = -1; | ||||
if (len) | ||||
strcpy(markdata->isstr, buf); | ||||
ex = markdata->cx - 1; | ||||
for (y = markdata->cy; y >= 0; y--, ex = flayer->l_width - 1) { | ||||
sx = 0; | ||||
while ((sx = matchword(markdata->isstr, y, sx, ex)) >= 0) | ||||
x = sx++; | ||||
if (x >= 0) | ||||
break; | ||||
} | ||||
markdata = (struct markdata *)flayer->l_data; | if (y < 0) { | |||
markdata->isdir = -1; | LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); | |||
if (len) | LMsg(0, "Pattern not found"); | |||
strcpy(markdata->isstr, buf); | } else | |||
ex = markdata->cx - 1; | revto(x, y); | |||
for (y = markdata->cy; y >= 0; y--, ex = flayer->l_width - 1) | ||||
{ | ||||
sx = 0; | ||||
while ((sx = matchword(markdata->isstr, y, sx, ex)) >= 0) | ||||
x = sx++; | ||||
if (x >= 0) | ||||
break; | ||||
} | ||||
if (y < 0) | ||||
{ | ||||
LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); | ||||
LMsg(0, "Pattern not found"); | ||||
} | ||||
else | ||||
revto(x, y); | ||||
} | } | |||
/* | /* | |||
* Search for a string that matches pattern. The first character of the | * Search for a string that matches pattern. The first character of the | |||
* match must be on line y, between columns sx and ex (inclusive), but | * match must be on line y, between columns sx and ex (inclusive), but | |||
* the rest of the match can extend beyond column ex and even onto the | * the rest of the match can extend beyond column ex and even onto the | |||
* following line. Returns the starting column of the first match found, | * following line. Returns the starting column of the first match found, | |||
* or -1 if there's no match. | * or -1 if there's no match. | |||
*/ | */ | |||
static int | static int | |||
matchword(pattern, y, sx, ex) | matchword(char *pattern, int y, int sx, int ex) | |||
char *pattern; | ||||
int y, sx, ex; | ||||
{ | { | |||
unsigned char *ip, *cp, *pp, *cpe; | unsigned char *cp, *pp, *cpe; | |||
int cy; | int cy; | |||
fore = ((struct markdata *)flayer->l_data)->md_window; | fore = ((struct markdata *)flayer->l_data)->md_window; | |||
for (;sx <= ex; sx++) | for (; sx <= ex; sx++) { | |||
{ | cy = y; | |||
cy = y; | cp = WIN(cy)->image + sx; | |||
cp = WIN(cy)->image + sx; | cpe = WIN(cy)->image + flayer->l_width; | |||
cpe = WIN(cy)->image + flayer->l_width; | pp = (unsigned char *)pattern; | |||
pp = (unsigned char *)pattern; | for (;;) { | |||
for (;;) | if (*cp != *pp) | |||
{ | if (!search_ic || ((*cp ^ *pp) & 0xdf) || | |||
if (*cp != *pp) | (*cp | 0x20) < 'a' || (*cp | 0x20) > 'z') | |||
if (!search_ic || ((*cp ^ *pp) & 0xdf) || (*cp | 0x20) < 'a' || (*cp | break; | |||
| 0x20) > 'z') | cp++; | |||
break; | pp++; | |||
cp++; | if (*pp == 0) | |||
pp++; | return sx; | |||
if (*pp == 0) | if (cp == cpe) { | |||
return sx; | ||||
if (cp == cpe) { | ||||
/* | /* | |||
* We have a partial match, but we've hit | * We have a partial match, but we've hit | |||
* the end of this line. Does it wrap onto | * the end of this line. Does it wrap onto | |||
* the following line? If not, we're done. | * the following line? If not, we're done. | |||
*/ | */ | |||
if (*cp == ' ' || cy >= fore->w_histheight + flayer->l_height - 1 | if (*cp == ' ' || | |||
) | cy >= | |||
break; | fore->w_histheight + flayer->l_height - 1) | |||
break; | ||||
/* | /* | |||
* This line does wrap, so look on the next | * This line does wrap, so look on the next | |||
* line for the rest of our match. | * line for the rest of our match. | |||
*/ | */ | |||
cy++; | cy++; | |||
cp = WIN(cy)->image; | cp = WIN(cy)->image; | |||
cpe = WIN(cy)->image + flayer->l_width; | cpe = WIN(cy)->image + flayer->l_width; | |||
} | ||||
} | } | |||
} | } | |||
} | return -1; | |||
return -1; | ||||
} | } | |||
/******************************************************************** | /******************************************************************** | |||
* Emacs style ISearch | * Emacs style ISearch | |||
*/ | */ | |||
static char *isprompts[] = { | static char *isprompts[] = { | |||
"I-search backward: ", "failing I-search backward: ", | "I-search backward: ", "failing I-search backward: ", | |||
"I-search: ", "failing I-search: " | "I-search: ", "failing I-search: " | |||
}; | }; | |||
static int is_redo __P((struct markdata *)); | static int is_redo __P((struct markdata*)); | |||
static void is_process __P((char *, int, char *)); | static void is_process __P((char*, int, char *)); | |||
static int is_bm __P((char *, int, int, int, int)); | static int is_bm __P((char*, int, int, int, int)); | |||
static int | static int | |||
is_bm(str, l, p, end, dir) | is_bm(char *str, int l, int p, int end, int dir) | |||
char *str; | ||||
int l, p, end, dir; | ||||
{ | { | |||
int tab[256]; | int tab[256]; | |||
int i, q; | int i, q; | |||
unsigned char *s, c; | unsigned char *s, c; | |||
int w = flayer->l_width; | int w = flayer->l_width; | |||
/* *sigh* to make WIN work */ | /* *sigh* to make WIN work */ | |||
fore = ((struct markdata *)flayer->l_next->l_data)->md_window; | fore = ((struct markdata *)flayer->l_next->l_data)->md_window; | |||
debug2("is_bm: searching for %s len %d\n", str, l); | debug2("is_bm: searching for %s len %d\n", str, l); | |||
debug3("start at %d end %d dir %d\n", p, end, dir); | debug3("start at %d end %d dir %d\n", p, end, dir); | |||
if (p < 0 || p + l > end) | ||||
return -1; | if (p < 0 || p + l > end) | |||
if (l == 0) | return -1; | |||
return p; | if (l == 0) | |||
if (dir < 0) | return p; | |||
str += l - 1; | if (dir < 0) | |||
for (i = 0; i < 256; i++) | str += l - 1; | |||
tab[i] = l * dir; | for (i = 0; i < 256; i++) | |||
for (i = 0; i < l - 1; i++, str += dir) | tab[i] = l * dir; | |||
{ | ||||
q = *(unsigned char *)str; | for (i = 0; i < l - 1; i++, str += dir) { | |||
tab[q] = (l - 1 - i) * dir; | q = *(unsigned char *)str; | |||
if (search_ic && (q | 0x20) >= 'a' && ((q | 0x20) <= 'z')) | tab[q] = (l - 1 - i) * dir; | |||
tab[q ^ 0x20] = (l - 1 - i) * dir; | if (search_ic && (q | 0x20) >= 'a' && ((q | 0x20) <= 'z')) | |||
} | tab[q ^ 0x20] = (l - 1 - i) * dir; | |||
if (dir > 0) | ||||
p += l - 1; | ||||
debug1("first char to match: %c\n", *str); | ||||
while (p >= 0 && p < end) | ||||
{ | ||||
q = p; | ||||
s = (unsigned char *)str; | ||||
for (i = 0;;) | ||||
{ | ||||
c = (WIN(q / w))->image[q % w]; | ||||
if (i == 0) | ||||
p += tab[(int)(unsigned char) c]; | ||||
if (c != *s) | ||||
if (!search_ic || ((c ^ *s) & 0xdf) || (c | 0x20) < 'a' || (c | 0x20) | ||||
> 'z') | ||||
break; | ||||
q -= dir; | ||||
s -= dir; | ||||
if (++i == l) | ||||
return q + (dir > 0 ? 1 : -l); | ||||
} | } | |||
} | ||||
return -1; | if (dir > 0) | |||
p += l - 1; | ||||
debug1("first char to match: %c\n", *str); | ||||
while (p >= 0 && p < end) { | ||||
q = p; | ||||
s = (unsigned char *)str; | ||||
for (i = 0;;) { | ||||
c = (WIN(q / w))->image[q % w]; | ||||
if (i == 0) | ||||
p += tab[(int)(unsigned char)c]; | ||||
if (c != *s) | ||||
if (!search_ic || ((c ^ *s) & 0xdf) || | ||||
(c | 0x20) < 'a' || (c | 0x20) > 'z') | ||||
break; | ||||
q -= dir; | ||||
s -= dir; | ||||
if (++i == l) | ||||
return q + (dir > 0 ? 1 : -l); | ||||
} | ||||
} | ||||
return -1; | ||||
} | } | |||
/*ARGSUSED*/ | /*ARGSUSED*/ | |||
static void | static void | |||
is_process(p, n, data) /* i-search */ | is_process(char *p, int n, char *data) /* i-search */ | |||
char *p; | ||||
int n; | ||||
char *data; /* dummy */ | ||||
{ | { | |||
int pos, x, y, dir; | int pos, x, y, dir; | |||
struct markdata *markdata; | struct markdata *markdata; | |||
if (n == 0) | if (n == 0) | |||
return; | return; | |||
ASSERT(p); | ASSERT(p); | |||
markdata = (struct markdata *)flayer->l_next->l_data; | markdata = (struct markdata *)flayer->l_next->l_data; | |||
pos = markdata->cx + markdata->cy * flayer->l_width; | pos = markdata->cx + markdata->cy * flayer->l_width; | |||
LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); | LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); | |||
switch (*p) | switch (*p) { | |||
{ | case '\007': /* CTRL-G */ | |||
case '\007': /* CTRL-G */ | pos = markdata->isstartpos; | |||
pos = markdata->isstartpos; | ||||
/*FALLTHROUGH*/ | /*FALLTHROUGH*/ | |||
case '\033': /* ESC */ | case '\033': /* ESC */ | |||
*p = 0; | *p = 0; | |||
break; | break; | |||
case '\013': /* CTRL-K */ | case '\013': /* CTRL-K */ | |||
case '\027': /* CTRL-W */ | case '\027': /* CTRL-W */ | |||
markdata->isistrl = 1; | markdata->isistrl = 1; | |||
/*FALLTHROUGH*/ | /*FALLTHROUGH*/ | |||
case '\b': | case '\b': | |||
case '\177': | case '\177': | |||
if (markdata->isistrl == 0) | if (markdata->isistrl == 0) | |||
return; | return; | |||
markdata->isistrl--; | markdata->isistrl--; | |||
pos = is_redo(markdata); | pos = is_redo(markdata); | |||
*p = '\b'; | *p = '\b'; | |||
break; | break; | |||
case '\023': /* CTRL-S */ | case '\023': /* CTRL-S */ | |||
case '\022': /* CTRL-R */ | case '\022': /* CTRL-R */ | |||
if (markdata->isistrl >= (int)sizeof(markdata->isistr)) | if (markdata->isistrl >= (int)sizeof(markdata->isistr)) | |||
return; | return; | |||
dir = (*p == '\023') ? 1 : -1; | dir = (*p == '\023') ? 1 : -1; | |||
pos += dir; | pos += dir; | |||
if (markdata->isdir == dir && markdata->isistrl == 0) | if (markdata->isdir == dir && markdata->isistrl == 0) { | |||
{ | strcpy(markdata->isistr, markdata->isstr); | |||
strcpy(markdata->isistr, markdata->isstr); | markdata->isistrl = markdata->isstrl = strlen(markdata->i | |||
markdata->isistrl = markdata->isstrl = strlen(markdata->isstr); | sstr); | |||
break; | break; | |||
} | ||||
markdata->isdir = dir; | ||||
markdata->isistr[markdata->isistrl++] = *p; | ||||
break; | ||||
default: | ||||
if (*p < ' ' || | ||||
markdata->isistrl >= | ||||
(int)sizeof(markdata->isistr) || | ||||
markdata->isstrl >= (int)sizeof(markdata->isstr) - 1) | ||||
return; | ||||
markdata->isstr[markdata->isstrl++] = *p; | ||||
markdata->isistr[markdata->isistrl++] = *p; | ||||
markdata->isstr[markdata->isstrl] = 0; | ||||
debug2("New char: %c - left %d\n", *p, | ||||
(int)sizeof(markdata->isistr) - markdata->isistrl); | ||||
} | ||||
if (*p && *p != '\b') | ||||
pos = is_bm(markdata->isstr, markdata->isstrl, pos, | ||||
flayer->l_width * | ||||
(markdata->md_window->w_histheight + flayer->l_height), | ||||
markdata->isdir); | ||||
if (pos >= 0) { | ||||
x = pos % flayer->l_width; | ||||
y = pos / flayer->l_width; | ||||
LAY_CALL_UP(LayRedisplayLine(INPUTLINE, 0, flayer -> l_width - 1, | ||||
0) ; revto(x, y) ; if(W2D(markdata -> cy) == INPUTLINE) revto_lin | ||||
e(markdata | ||||
-> cx, markdata -> cy, INPUTLINE > 0 ? INPUTLINE - 1 : 1) ;); | ||||
} | } | |||
markdata->isdir = dir; | if (*p) | |||
markdata->isistr[markdata->isistrl++] = *p; | inp_setprompt(isprompts[markdata->isdir + (pos < 0) + 1], | |||
break; | markdata->isstrl ? markdata->isstr : ""); | |||
default: | flayer->l_x = markdata->cx; | |||
if (*p < ' ' || markdata->isistrl >= (int)sizeof(markdata->isistr) | flayer->l_y = W2D(markdata->cy); | |||
|| markdata->isstrl >= (int)sizeof(markdata->isstr) - 1) | LGotoPos(flayer, flayer->l_x, flayer->l_y); | |||
return; | if (!*p) { | |||
markdata->isstr[markdata->isstrl++] = *p; | ||||
markdata->isistr[markdata->isistrl++] = *p; | ||||
markdata->isstr[markdata->isstrl] = 0; | ||||
debug2("New char: %c - left %d\n", *p, (int)sizeof(markdata->isistr) - mar | ||||
kdata->isistrl); | ||||
} | ||||
if (*p && *p != '\b') | ||||
pos = is_bm(markdata->isstr, markdata->isstrl, pos, flayer->l_width * (markd | ||||
ata->md_window->w_histheight + flayer->l_height), markdata->isdir); | ||||
if (pos >= 0) | ||||
{ | ||||
x = pos % flayer->l_width; | ||||
y = pos / flayer->l_width; | ||||
LAY_CALL_UP | ||||
( | ||||
LayRedisplayLine(INPUTLINE, 0, flayer->l_width - 1, 0); | ||||
revto(x, y); | ||||
if (W2D(markdata->cy) == INPUTLINE) | ||||
revto_line(markdata->cx, markdata->cy, INPUTLINE > 0 ? INPUTLINE - 1 | ||||
: 1); | ||||
); | ||||
} | ||||
if (*p) | ||||
inp_setprompt(isprompts[markdata->isdir + (pos < 0) + 1], markdata->isstrl ? | ||||
markdata->isstr : ""); | ||||
flayer->l_x = markdata->cx; | ||||
flayer->l_y = W2D(markdata->cy); | ||||
LGotoPos(flayer, flayer->l_x, flayer->l_y); | ||||
if (!*p) | ||||
{ | ||||
/* we are about to finish, keep cursor position */ | /* we are about to finish, keep cursor position */ | |||
flayer->l_next->l_x = markdata->cx; | flayer->l_next->l_x = markdata->cx; | |||
flayer->l_next->l_y = W2D(markdata->cy); | flayer->l_next->l_y = W2D(markdata->cy); | |||
} | } | |||
} | } | |||
static int | static int | |||
is_redo(markdata) | is_redo(struct markdata *markdata) | |||
struct markdata *markdata; | ||||
{ | { | |||
int i, pos, npos, dir; | int i, pos, npos, dir; | |||
char c; | char c; | |||
npos = pos = markdata->isstartpos; | npos = pos = markdata->isstartpos; | |||
dir = markdata->isstartdir; | dir = markdata->isstartdir; | |||
markdata->isstrl = 0; | markdata->isstrl = 0; | |||
for (i = 0; i < markdata->isistrl; i++) | ||||
{ | for (i = 0; i < markdata->isistrl; i++) { | |||
c = markdata->isistr[i]; | c = markdata->isistr[i]; | |||
if (c == '\022') /* ^R */ | if (c == '\022') /* ^R */ | |||
pos += (dir = -1); | pos += (dir = -1); | |||
else if (c == '\023') /* ^S */ | else if (c == '\023') /* ^S */ | |||
pos += (dir = 1); | pos += (dir = 1); | |||
else | else | |||
markdata->isstr[markdata->isstrl++] = c; | markdata->isstr[markdata->isstrl++] = c; | |||
if (pos >= 0) | if (pos >= 0) { | |||
{ | npos = is_bm(markdata->isstr, markdata->isstrl, pos, | |||
npos = is_bm(markdata->isstr, markdata->isstrl, pos, flayer->l_width * | flayer->l_width * | |||
(markdata->md_window->w_histheight + flayer->l_height), dir); | (markdata->md_window->w_histheight + | |||
if (npos >= 0) | flayer->l_height), dir); | |||
pos = npos; | if (npos >= 0) | |||
pos = npos; | ||||
} | ||||
} | } | |||
} | markdata->isstr[markdata->isstrl] = 0; | |||
markdata->isstr[markdata->isstrl] = 0; | markdata->isdir = dir; | |||
markdata->isdir = dir; | return npos; | |||
return npos; | ||||
} | } | |||
void | void | |||
ISearch(dir) | ISearch(int dir) | |||
int dir; | ||||
{ | { | |||
struct markdata *markdata; | struct markdata *markdata; | |||
markdata = (struct markdata *)flayer->l_data; | markdata = (struct markdata *)flayer->l_data; | |||
markdata->isdir = markdata->isstartdir = dir; | markdata->isdir = markdata->isstartdir = dir; | |||
markdata->isstartpos = markdata->cx + markdata->cy * flayer->l_width; | markdata->isstartpos = markdata->cx + markdata->cy * flayer->l_width; | |||
markdata->isistrl = markdata->isstrl = 0; | markdata->isistrl = markdata->isstrl = 0; | |||
if (W2D(markdata->cy) == INPUTLINE) | ||||
revto_line(markdata->cx, markdata->cy, INPUTLINE > 0 ? INPUTLINE - 1 : 1); | if (W2D(markdata->cy) == INPUTLINE) | |||
Input(isprompts[dir + 1], sizeof(markdata->isstr) - 1, INP_RAW, | revto_line(markdata->cx, markdata->cy, | |||
is_process, NULL, 0); | INPUTLINE > 0 ? INPUTLINE - 1 : 1); | |||
LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); | ||||
flayer->l_x = markdata->cx; | Input(isprompts[dir + 1], sizeof(markdata->isstr) - 1, INP_RAW, | |||
flayer->l_y = W2D(markdata->cy); | is_process, NULL, 0); | |||
LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); | ||||
flayer->l_x = markdata->cx; | ||||
flayer->l_y = W2D(markdata->cy); | ||||
} | } | |||
#endif /* COPY_PASTE */ | #endif /* COPY_PASTE */ | |||
End of changes. 35 change blocks. | ||||
278 lines changed or deleted | 261 lines changed or added |