Exemple #1
0
/* re_addc():
 *	Draw c, expanding tabs, control chars etc.
 */
static void
re_addc(EditLine *el, wint_t c)
{
	switch (ct_chr_class(c)) {
	case CHTYPE_TAB:        /* expand the tab */
		for (;;) {
			re_putc(el, ' ', 1);
			if ((el->el_refresh.r_cursor.h & 07) == 0)
				break;			/* go until tab stop */
		}
		break;
	case CHTYPE_NL: {
		int oldv = el->el_refresh.r_cursor.v;
		re_putc(el, '\0', 0);			/* assure end of line */
		if (oldv == el->el_refresh.r_cursor.v)	/* XXX */
			re_nextline(el);
		break;
	}
	case CHTYPE_PRINT:
		re_putc(el, c, 1);
		break;
	default: {
		wchar_t visbuf[VISUAL_WIDTH_MAX];
		ssize_t i, n =
		    ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c);
		for (i = 0; n-- > 0; ++i)
		    re_putc(el, visbuf[i], 1);
		break;
	}
	}
}
libedit_private ssize_t
ct_visual_char(wchar_t *dst, size_t len, wchar_t c)
{
	int t = ct_chr_class(c);
	switch (t) {
	case CHTYPE_TAB:
	case CHTYPE_NL:
	case CHTYPE_ASCIICTL:
		if (len < 2)
			return -1;   /* insufficient space */
		*dst++ = '^';
		if (c == '\177')
			*dst = '?'; /* DEL -> ^? */
		else
			*dst = c | 0100;    /* uncontrolify it */
		return 2;
	case CHTYPE_PRINT:
		if (len < 1)
			return -1;  /* insufficient space */
		*dst = c;
		return 1;
	case CHTYPE_NONPRINT:
		/* we only use single-width glyphs for display,
		 * so this is right */
		if ((ssize_t)len < ct_visual_width(c))
			return -1;   /* insufficient space */
		*dst++ = '\\';
		*dst++ = 'U';
		*dst++ = '+';
#define tohexdigit(v) "0123456789ABCDEF"[v]
		if (c > 0xffff) /* prefer standard 4-byte display over 5-byte */
			*dst++ = tohexdigit(((unsigned int) c >> 16) & 0xf);
		*dst++ = tohexdigit(((unsigned int) c >> 12) & 0xf);
		*dst++ = tohexdigit(((unsigned int) c >>  8) & 0xf);
		*dst++ = tohexdigit(((unsigned int) c >>  4) & 0xf);
		*dst   = tohexdigit(((unsigned int) c      ) & 0xf);
		return c > 0xffff ? 8 : 7;
		/*FALLTHROUGH*/
	/* these two should be handled outside this function */
	default:            /* we should never hit the default */
		return 0;
	}
}
libedit_private int
ct_visual_width(wchar_t c)
{
	int t = ct_chr_class(c);
	switch (t) {
	case CHTYPE_ASCIICTL:
		return 2; /* ^@ ^? etc. */
	case CHTYPE_TAB:
		return 1; /* Hmm, this really need to be handled outside! */
	case CHTYPE_NL:
		return 0; /* Should this be 1 instead? */
	case CHTYPE_PRINT:
		return wcwidth(c);
	case CHTYPE_NONPRINT:
		if (c > 0xffff) /* prefer standard 4-byte display over 5-byte */
			return 8; /* \U+12345 */
		else
			return 7; /* \U+1234 */
	default:
		return 0; /* should not happen */
	}
}