Example #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;
	}
	}
}
Example #2
0
/* re_putc():
 *	Draw the character given
 */
libedit_private void
re_putc(EditLine *el, wint_t c, int shift)
{
	coord_t *cur = &el->el_refresh.r_cursor;
	int i, w = wcwidth(c);
	int sizeh = el->el_terminal.t_size.h;

	ELRE_DEBUG(1, (__F, "printing %5x '%lc'\r\n", c, c));
	if (w == -1)
		w = 0;

	while (shift && (cur->h + w > sizeh))
	    re_putc(el, ' ', 1);

	el->el_vdisplay[cur->v][cur->h] = c;
	/* assumes !shift is only used for single-column chars */
	i = w;
	while (--i > 0)
		el->el_vdisplay[cur->v][cur->h + i] = MB_FILL_CHAR;

	if (!shift)
		return;

	cur->h += w;	/* advance to next place */
	if (cur->h >= sizeh) {
		/* assure end of line */
		el->el_vdisplay[cur->v][sizeh] = '\0';
		re_nextline(el);
	}
}
Example #3
0
/* re_refresh():
 *	draws the new virtual screen image from the current input
 *	line, then goes line-by-line changing the real image to the new
 *	virtual image. The routine to re-draw a line can be replaced
 *	easily in hopes of a smarter one being placed there.
 */
libedit_private void
re_refresh(EditLine *el)
{
	int i, rhdiff;
	wchar_t *cp, *st;
	coord_t cur;
#ifdef notyet
	size_t termsz;
#endif

	ELRE_DEBUG(1, (__F, "el->el_line.buffer = :%ls:\r\n",
	    el->el_line.buffer));

	literal_clear(el);
	/* reset the Drawing cursor */
	el->el_refresh.r_cursor.h = 0;
	el->el_refresh.r_cursor.v = 0;

	terminal_move_to_char(el, 0);

	/* temporarily draw rprompt to calculate its size */
	prompt_print(el, EL_RPROMPT);

	/* reset the Drawing cursor */
	el->el_refresh.r_cursor.h = 0;
	el->el_refresh.r_cursor.v = 0;

	if (el->el_line.cursor >= el->el_line.lastchar) {
		if (el->el_map.current == el->el_map.alt
		    && el->el_line.lastchar != el->el_line.buffer)
			el->el_line.cursor = el->el_line.lastchar - 1;
		else
			el->el_line.cursor = el->el_line.lastchar;
	}

	cur.h = -1;		/* set flag in case I'm not set */
	cur.v = 0;

	prompt_print(el, EL_PROMPT);

	/* draw the current input buffer */
#if notyet
	termsz = el->el_terminal.t_size.h * el->el_terminal.t_size.v;
	if (el->el_line.lastchar - el->el_line.buffer > termsz) {
		/*
		 * If line is longer than terminal, process only part
		 * of line which would influence display.
		 */
		size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz;

		st = el->el_line.lastchar - rem
			- (termsz - (((rem / el->el_terminal.t_size.v) - 1)
					* el->el_terminal.t_size.v));
	} else
#endif
		st = el->el_line.buffer;

	for (cp = st; cp < el->el_line.lastchar; cp++) {
		if (cp == el->el_line.cursor) {
                        int w = wcwidth(*cp);
			/* save for later */
			cur.h = el->el_refresh.r_cursor.h;
			cur.v = el->el_refresh.r_cursor.v;
                        /* handle being at a linebroken doublewidth char */
                        if (w > 1 && el->el_refresh.r_cursor.h + w >
			    el->el_terminal.t_size.h) {
				cur.h = 0;
				cur.v++;
                        }
		}
		re_addc(el, *cp);
	}

	if (cur.h == -1) {	/* if I haven't been set yet, I'm at the end */
		cur.h = el->el_refresh.r_cursor.h;
		cur.v = el->el_refresh.r_cursor.v;
	}
	rhdiff = el->el_terminal.t_size.h - el->el_refresh.r_cursor.h -
	    el->el_rprompt.p_pos.h;
	if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v &&
	    !el->el_refresh.r_cursor.v && rhdiff > 1) {
		/*
		 * have a right-hand side prompt that will fit
		 * on the end of the first line with at least
		 * one character gap to the input buffer.
		 */
		while (--rhdiff > 0)	/* pad out with spaces */
			re_putc(el, ' ', 1);
		prompt_print(el, EL_RPROMPT);
	} else {
		el->el_rprompt.p_pos.h = 0;	/* flag "not using rprompt" */
		el->el_rprompt.p_pos.v = 0;
	}

	re_putc(el, '\0', 0);	/* make line ended with NUL, no cursor shift */

	el->el_refresh.r_newcv = el->el_refresh.r_cursor.v;

	ELRE_DEBUG(1, (__F,
		"term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
		el->el_terminal.t_size.h, el->el_refresh.r_cursor.h,
		el->el_refresh.r_cursor.v, ct_encode_string(el->el_vdisplay[0],
		&el->el_scratch)));

	ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv));
	for (i = 0; i <= el->el_refresh.r_newcv; i++) {
		/* NOTE THAT re_update_line MAY CHANGE el_display[i] */
		re_update_line(el, el->el_display[i], el->el_vdisplay[i], i);

		/*
		 * Copy the new line to be the current one, and pad out with
		 * spaces to the full width of the terminal so that if we try
		 * moving the cursor by writing the character that is at the
		 * end of the screen line, it won't be a NUL or some old
		 * leftover stuff.
		 */
		re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
		    (size_t) el->el_terminal.t_size.h);
	}
	ELRE_DEBUG(1, (__F,
	"\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
	    el->el_refresh.r_cursor.v, el->el_refresh.r_oldcv, i));

	if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
		for (; i <= el->el_refresh.r_oldcv; i++) {
			terminal_move_to_line(el, i);
			terminal_move_to_char(el, 0);
                        /* This wcslen should be safe even with MB_FILL_CHARs */
			terminal_clear_EOL(el, (int) wcslen(el->el_display[i]));
#ifdef DEBUG_REFRESH
			terminal_overwrite(el, L"C\b", 2);
#endif /* DEBUG_REFRESH */
			el->el_display[i][0] = '\0';
		}

	el->el_refresh.r_oldcv = el->el_refresh.r_newcv; /* set for next time */
	ELRE_DEBUG(1, (__F,
	    "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
	    el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
	    cur.h, cur.v));
	terminal_move_to_line(el, cur.v);	/* go to where the cursor is */
	terminal_move_to_char(el, cur.h);
}