Esempio n. 1
0
/* 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;
	}
}
Esempio n. 2
0
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;
}