/* When called with c==-1, it just creates the prompt */ static int itype(W *w, int c, void *obj, int *notify) { IREC *i; int omid; BW *bw; struct isrch *isrch = (struct isrch *)obj; WIND_BW(bw,w); if (isrch->quote) { goto in; } if (c == 8 || c == 127) { /* Backup */ if ((i = isrch->irecs.link.prev) != &isrch->irecs) { pgoto(bw->cursor, i->disp); if (globalsrch) globalsrch->wrap_flag = i->wrap_flag; omid = opt_mid; opt_mid = 1; dofollows(); opt_mid = omid; isrch->pattern = vstrunc(isrch->pattern, sLEN(isrch->pattern) - i->what); frirec(deque_f(IREC, link, i)); } else { if(joe_beep) ttputc(7); } } else if (c == 'Q' - '@' /* || c == '`' */) { isrch->quote = 1; } else if (c == 'S' - '@' || c == '\\' - '@' || c == 'L' - '@' || c == 'R' - '@') { /* Repeat */ if (c == 'R' - '@') { isrch->dir = 1; } else { isrch->dir = 0; } if (qempty(IREC, link, &isrch->irecs)) { if (lastpat && lastpat[0]) { iappend(bw, isrch, sv(lastpat)); } } else { SRCH *srch; i = alirec(); i->disp = i->start = bw->cursor->byte; i->what = 0; if (!globalsrch) srch = mksrch(NULL,NULL,opt_icase,isrch->dir,-1,0,0,0,0); else { srch = globalsrch; globalsrch = 0; } srch->addr = bw->cursor->byte; if (!srch->wrap_p || srch->wrap_p->b!=bw->b) { prm(srch->wrap_p); srch->wrap_p = pdup(bw->cursor, "itype"); srch->wrap_p->owner = &srch->wrap_p; srch->wrap_flag = 0; } i->wrap_flag = srch->wrap_flag; setpat(srch, vsncpy(NULL, 0, isrch->pattern, sLen(isrch->pattern))); srch->backwards = isrch->dir; if (dopfnext(bw, srch, NULL)) { if(joe_beep) ttputc(7); frirec(i); } else { enqueb(IREC, link, &isrch->irecs, i); } } } else if (c >= 0 && c < 32) { /* Done when a control character is received */ nungetc(c); if (notify) { *notify = 1; } smode = 2; if (lastisrch) { lastpat = vstrunc(lastpat, 0); lastpat = vsncpy(lastpat, 0, lastisrch->pattern, sLen(lastisrch->pattern)); rmisrch(lastisrch); } lastisrch = isrch; return 0; } else if (c != -1) { char buf[16]; ptrdiff_t buf_len; /* Search */ in: if (bw->b->o.charmap->type) { buf_len = utf8_encode(buf, c); } else { buf[0] = TO_CHAR_OK(from_uni(bw->b->o.charmap, c)); buf_len = 1; } isrch->quote = 0; iappend(bw, isrch, buf, buf_len); } omid = opt_mid; opt_mid = 1; bw->cursor->xcol = piscol(bw->cursor); dofollows(); opt_mid = omid; isrch->prompt = vstrunc(isrch->prompt, isrch->ofst); if (locale_map->type && !bw->b->o.charmap->type) { /* Translate bytes to utf-8 */ char buf[16]; int x; for (x=0; x!=sLEN(isrch->pattern); ++x) { int tc = to_uni(bw->b->o.charmap, isrch->pattern[x]); utf8_encode(buf, tc); isrch->prompt = vsncpy(sv(isrch->prompt),sz(buf)); } } else if (!locale_map->type && bw->b->o.charmap->type) { /* Translate utf-8 to bytes */ const char *p = isrch->pattern; ptrdiff_t len = sLEN(isrch->pattern); while (len) { int tc = utf8_decode_fwrd(&p, &len); if (tc >= 0) { tc = from_uni(locale_map, tc); isrch->prompt = vsadd(isrch->prompt, TO_CHAR_OK(tc)); } } } else { /* FIXME: translate when charmaps do not match */ isrch->prompt = vsncpy(sv(isrch->prompt),sv(isrch->pattern)); } if (mkqwnsr(bw->parent, sv(isrch->prompt), itype, iabrt, isrch, notify)) { return 0; } else { rmisrch(isrch); return -1; } }
static KMAP *kbuild(CAP *cap, KMAP *kmap, unsigned char *seq, void *bind, int *err, unsigned char *capseq, int seql) { int v, w; if (!seql && seq[0] == '.' && seq[1]) { int x, c; unsigned char *s; for (x = 0; seq[x] && seq[x] != ' '; ++x) ; c = seq[x]; seq[x] = 0; #ifdef __MSDOS__ if (!zcmp(seq + 1, "ku")) { capseq = "\0H"; seql = 2; } else if (!zcmp(seq + 1, USTR "kd")) { capseq = "\0P"; seql = 2; } else if (!zcmp(seq + 1, USTR "kl")) { capseq = "\0K"; seql = 2; } else if (!zcmp(seq + 1, USTR "kr")) { capseq = "\0M"; seql = 2; } else if (!zcmp(seq + 1, USTR "kI")) { capseq = "\0R"; seql = 2; } else if (!zcmp(seq + 1, USTR "kD")) { capseq = "\0S"; seql = 2; } else if (!zcmp(seq + 1, USTR "kh")) { capseq = "\0G"; seql = 2; } else if (!zcmp(seq + 1, USTR "kH")) { capseq = "\0O"; seql = 2; } else if (!zcmp(seq + 1, USTR "kP")) { capseq = "\0I"; seql = 2; } else if (!zcmp(seq + 1, USTR "kN")) { capseq = "\0Q"; seql = 2; } else if (!zcmp(seq + 1, USTR "k1")) { capseq = "\0;"; seql = 2; } else if (!zcmp(seq + 1, USTR "k2")) { capseq = "\0<"; seql = 2; } else if (!zcmp(seq + 1, USTR "k3")) { capseq = "\0="; seql = 2; } else if (!zcmp(seq + 1, USTR "k4")) { capseq = "\0>"; seql = 2; } else if (!zcmp(seq + 1, USTR "k5")) { capseq = "\0?"; seql = 2; } else if (!zcmp(seq + 1, USTR "k6")) { capseq = "\0@"; seql = 2; } else if (!zcmp(seq + 1, USTR "k7")) { capseq = "\0A"; seql = 2; } else if (!zcmp(seq + 1, USTR "k8")) { capseq = "\0B"; seql = 2; } else if (!zcmp(seq + 1, USTR "k9")) { capseq = "\0C"; seql = 2; } else if (!zcmp(seq + 1, USTR "k0")) { capseq = "\0D"; seql = 2; } seq[x] = c; if (seql) { for (seq += x; *seq == ' '; ++seq) ; } #else s = jgetstr(cap, seq + 1); seq[x] = c; if (s && (s = tcompile(cap, s, 0, 0, 0, 0)) && (sLEN(s) > 1 || (signed char)s[0] < 0)) { capseq = s; seql = sLEN(s); for (seq += x; *seq == ' '; ++seq) ; } #endif else { *err = -2; return kmap; } } if (seql) { v = w = (unsigned char) *capseq++; --seql; } else { seq = range(seq, &v, &w); if (!seq) { *err = -1; return kmap; } } if (!kmap) kmap = mkkmap(); /* Create new keymap if 'kmap' was NULL */ /* Make bindings between v and w */ while (v <= w) { if (*seq || seql) { if (kmap->keys[v].k == 0) kmap->keys[v].value.submap = NULL; kmap->keys[v].k = 1; kmap->keys[v].value.submap = kbuild(cap, kmap->keys[v].value.submap, seq, bind, err, capseq, seql); if (!kmap->keys[v].value.submap) { /* Error during recursion. Prevent crash later. */ kmap->keys[v].k = 0; } } else { if (kmap->keys[v].k == 1) rmkmap(kmap->keys[v].value.submap); kmap->keys[v].k = 0; kmap->keys[v].value.bind = /* This bit of code sticks the key value in the macro */ (v == w ? macstk(bind, v) : dupmacro(macstk(bind, v))); } ++v; } return kmap; }