1 /* $MirOS: contrib/code/jupp/uisrch.c,v 1.7 2017/01/10 19:16:28 tg Exp $ */
5 * (C) 1992 Joseph H. Allen
7 * This file is part of JOE (Joe's Own Editor)
29 struct isrch *lastisrch = NULL; /* Previous search */
31 unsigned char *lastpat = NULL; /* Previous pattern */
33 extern SRCH *globalsrch; /* Existing SRCH structure */
35 IREC fri = { {&fri, &fri} }; /* Free-list of irecs */
37 static IREC *alirec(void)
38 { /* Allocate an IREC */
39 return alitem(&fri, sizeof(IREC));
42 static void frirec(IREC *i)
44 enquef(IREC, link, &fri, i);
47 static void rmisrch(struct isrch *isrch)
48 { /* Eliminate a struct isrch */
52 frchn(&fri, &isrch->irecs);
57 static int iabrt(BW *bw, struct isrch *isrch)
63 static void iappend(BW *bw, struct isrch *isrch, unsigned char *s, int len)
64 { /* Append text and search */
65 /* Append char and search */
70 i->disp = bw->cursor->byte;
71 isrch->pattern = vsncpy(sv(isrch->pattern), s, len);
72 if (!qempty(IREC, link, &isrch->irecs)) {
73 pgoto(bw->cursor, isrch->irecs.link.prev->start);
75 i->start = bw->cursor->byte;
78 srch = mksrch(NULL,NULL,icase,isrch->dir,-1,0,0);
84 srch->addr = bw->cursor->byte;
86 if (!srch->wrap_p || srch->wrap_p->b!=bw->b) {
88 srch->wrap_p = pdup(bw->cursor);
89 srch->wrap_p->owner = &srch->wrap_p;
93 i->wrap_flag = srch->wrap_flag;
96 srch->pattern = vsncpy(NULL, 0, isrch->pattern, sLen(isrch->pattern));
97 srch->backwards = isrch->dir;
99 if (dopfnext(bw, srch, NULL)) {
103 enqueb(IREC, link, &isrch->irecs, i);
106 /* Main user interface */
107 /* When called with c==-1, it just creates the prompt */
108 static int itype(BW *bw, int c, struct isrch *isrch, int *notify)
116 if (c == 8 || c == 127) { /* Backup */
117 if ((i = isrch->irecs.link.prev) != &isrch->irecs) {
118 pgoto(bw->cursor, i->disp);
120 globalsrch->wrap_flag = i->wrap_flag;
125 isrch->pattern = vstrunc(isrch->pattern, sLEN(isrch->pattern) - i->what);
126 frirec(deque_f(IREC, link, i));
131 } else if (c == 'Q' - '@' || c == '`') {
133 } else if (c == 'S' - '@' || c == '\\' - '@' || c == 'L' - '@' || c == 'R' - '@') {
135 if (c == 'R' - '@') {
140 if (qempty(IREC, link, &isrch->irecs)) {
141 if (lastpat && lastpat[0]) {
142 iappend(bw, isrch, sv(lastpat));
147 i->disp = i->start = bw->cursor->byte;
151 srch = mksrch(NULL,NULL,icase,isrch->dir,-1,0,0);
157 srch->addr = bw->cursor->byte;
159 if (!srch->wrap_p || srch->wrap_p->b!=bw->b) {
161 srch->wrap_p = pdup(bw->cursor);
162 srch->wrap_p->owner = &srch->wrap_p;
166 i->wrap_flag = srch->wrap_flag;
169 srch->pattern = vsncpy(NULL, 0, isrch->pattern, sLen(isrch->pattern));
170 srch->backwards = isrch->dir;
172 if (dopfnext(bw, srch, NULL)) {
177 enqueb(IREC, link, &isrch->irecs, i);
180 } else if (c >= 0 && c < 32) {
181 /* Done when a control character is received */
188 lastpat = vstrunc(lastpat, 0);
189 lastpat = vsncpy(lastpat, 0, lastisrch->pattern, sLen(lastisrch->pattern));
194 } else if (c != -1) {
195 unsigned char buf[16];
201 /* Convert to/from utf-8 */
202 if (locale_map->type && !bw->b->o.charmap->type) {
204 c = from_utf8(bw->b->o.charmap,buf);
205 } else if(!locale_map->type && bw->b->o.charmap->type) {
206 to_utf8(locale_map,buf,c);
207 c = utf8_decode_string(buf);
210 if (bw->b->o.charmap->type) {
211 buf_len = utf8_encode(buf,c);
218 iappend(bw, isrch, buf, buf_len);
222 bw->cursor->xcol = piscol(bw->cursor);
226 isrch->prompt = vstrunc(isrch->prompt, isrch->ofst);
228 if (locale_map->type && !bw->b->o.charmap->type) {
229 /* Translate bytes to utf-8 */
230 unsigned char buf[16];
232 for (x=0; x!=sLEN(isrch->pattern); ++x) {
233 int c_ = to_uni(bw->b->o.charmap, isrch->pattern[x]);
235 isrch->prompt = vsncpy(sv(isrch->prompt),sz(buf));
237 } else if (!locale_map->type && bw->b->o.charmap->type) {
238 /* Translate utf-8 to bytes */
239 unsigned char *p = isrch->pattern;
240 int len = sLEN(isrch->pattern);
242 int c_ = utf8_decode_fwrd(&p, &len);
244 c_ = from_uni(locale_map, c_);
245 isrch->prompt = vsadd(isrch->prompt, c_);
249 /* FIXME: translate when charmaps do not match */
250 isrch->prompt = vsncpy(sv(isrch->prompt),sv(isrch->pattern));
253 if (mkqwnsr(bw->parent, sv(isrch->prompt), itype, iabrt, isrch, notify)) {
261 static int doisrch(BW *bw, int dir)
262 { /* Create a struct isrch */
263 struct isrch *isrch = (struct isrch *) joe_malloc(sizeof(struct isrch));
265 izque(IREC, link, &isrch->irecs);
266 isrch->pattern = vsncpy(NULL, 0, NULL, 0);
269 isrch->prompt = vsncpy(NULL, 0, sc("I-find: "));
270 isrch->ofst = sLen(isrch->prompt);
271 return itype(bw, -1, isrch, NULL);
276 if (smode && lastisrch) {
277 struct isrch *isrch = lastisrch;
280 return itype(bw, 'S' - '@', isrch, NULL);
287 lastpat = vstrunc(lastpat, 0);
288 lastpat = vsncpy(lastpat, 0, lastisrch->pattern, sLen(lastisrch->pattern));
292 return doisrch(bw, 0);
298 if (smode && lastisrch) {
299 struct isrch *isrch = lastisrch;
302 return itype(bw, 'R' - '@', isrch, NULL);
309 lastpat = vstrunc(lastpat, 0);
310 lastpat = vsncpy(lastpat, 0, lastisrch->pattern, sLen(lastisrch->pattern));
314 return doisrch(bw, 1);