示例#1
0
void
window_copy_cursor_jump_back(struct window_pane *wp)
{
	struct window_copy_mode_data	*data = wp->modedata;
	struct screen			*back_s = data->backing;
	const struct grid_cell		*gc;
	uint				 px, py;

	px = data->cx;
	py = screen_hsize(back_s) + data->cy - data->oy;

	if (px > 0)
		px--;

	for (;;) {
		gc = grid_peek_cell(back_s->grid, px, py);
		if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0
		    && gc->data == data->jumpchar) {

			window_copy_update_cursor(wp, px, data->cy);
			if (window_copy_update_selection(wp))
				window_copy_redraw_lines(wp, data->cy, 1);
			return;
		}
		if (px == 0)
			break;
		px--;
	}
}
示例#2
0
u_int
window_copy_find_length(struct window_pane *wp, u_int py)
{
	const struct grid_cell	*gc;
	u_int			 px;

	/*
	 * If the pane has been resized, its grid can contain old overlong
	 * lines. grid_peek_cell does not allow accessing cells beyond the
	 * width of the grid, and screen_write_copy treats them as spaces, so
	 * ignore them here too.
	 */
	px = wp->base.grid->linedata[py].cellsize;
	if (px > screen_size_x(&wp->base))
		px = screen_size_x(&wp->base);
	while (px > 0) {
		gc = grid_peek_cell(wp->base.grid, px - 1, py);
		if (gc->flags & GRID_FLAG_UTF8)
			break;
		if (gc->data != ' ')
			break;
		px--;
	}
	return (px);
}
示例#3
0
void
window_copy_cursor_jump(struct window_pane *wp)
{
	struct window_copy_mode_data	*data = wp->modedata;
	struct screen			*back_s = data->backing;
	const struct grid_cell		*gc;
	uint				 px, py, xx;

	px = data->cx + 1;
	py = screen_hsize(back_s) + data->cy - data->oy;
	xx = window_copy_find_length(wp, py);

	while (px < xx) {
		gc = grid_peek_cell(back_s->grid, px, py);
		if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0
		    && gc->data == data->jumpchar) {

			window_copy_update_cursor(wp, px, data->cy);
			if (window_copy_update_selection(wp))
				window_copy_redraw_lines(wp, data->cy, 1);
			return;
		}
		px++;
	}
}
示例#4
0
文件: grid.c 项目: sakushin/tmux
/* Convert cells into a string. */
char *
grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
{
	const struct grid_cell	*gc;
	struct utf8_data	 ud;
	char			*buf;
	size_t			 len, off;
	u_int			 xx;

	GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);

	len = 128;
	buf = xmalloc(len);
	off = 0;

	for (xx = px; xx < px + nx; xx++) {
		gc = grid_peek_cell(gd, xx, py);
		if (gc->flags & GRID_FLAG_PADDING)
			continue;
		grid_cell_get(gc, &ud);

		while (len < off + ud.size + 1) {
			buf = xrealloc(buf, 2, len);
			len *= 2;
		}

		memcpy(buf + off, ud.data, ud.size);
		off += ud.size;
	}

	while (off > 0 && buf[off - 1] == ' ')
		off--;
	buf[off] = '\0';
	return (buf);
}
示例#5
0
void
window_copy_copy_line(struct window_pane *wp,
    char **buf, size_t *off, u_int sy, u_int sx, u_int ex)
{
	struct window_copy_mode_data	*data = wp->modedata;
	struct grid			*gd = data->backing->grid;
	const struct grid_cell		*gc;
	const struct grid_utf8		*gu;
	struct grid_line		*gl;
	u_int				 i, xx, wrapped = 0;
	size_t				 size;

	if (sx > ex)
		return;

	/*
	 * Work out if the line was wrapped at the screen edge and all of it is
	 * on screen.
	 */
	gl = &gd->linedata[sy];
	if (gl->flags & GRID_LINE_WRAPPED && gl->cellsize <= gd->sx)
		wrapped = 1;

	/* If the line was wrapped, don't strip spaces (use the full length). */
	if (wrapped)
		xx = gl->cellsize;
	else
		xx = window_copy_find_length(wp, sy);
	if (ex > xx)
		ex = xx;
	if (sx > xx)
		sx = xx;

	if (sx < ex) {
		for (i = sx; i < ex; i++) {
			gc = grid_peek_cell(gd, i, sy);
			if (gc->flags & GRID_FLAG_PADDING)
				continue;
			if (!(gc->flags & GRID_FLAG_UTF8)) {
				*buf = xrealloc(*buf, 1, (*off) + 1);
				(*buf)[(*off)++] = gc->data;
			} else {
				gu = grid_peek_utf8(gd, i, sy);
				size = grid_utf8_size(gu);
				*buf = xrealloc(*buf, 1, (*off) + size);
				*off += grid_utf8_copy(gu, *buf + *off, size);
			}
		}
	}

	/* Only add a newline if the line wasn't wrapped. */
	if (!wrapped || ex != xx) {
		*buf = xrealloc(*buf, 1, (*off) + 1);
		(*buf)[(*off)++] = '\n';
	}
}
示例#6
0
int
window_copy_in_set(struct window_pane *wp, u_int px, u_int py, const char *set)
{
	const struct grid_cell	*gc;

	gc = grid_peek_cell(wp->base.grid, px, py);
	if (gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8))
		return (0);
	if (gc->data == 0x00 || gc->data == 0x7f)
		return (0);
	return (strchr(set, gc->data) != NULL);
}
示例#7
0
int
window_copy_search_compare(
    struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx)
{
	const struct grid_cell	*gc, *sgc;
	const struct grid_utf8	*gu, *sgu;

	gc = grid_peek_cell(gd, px, py);
	sgc = grid_peek_cell(sgd, spx, 0);

	if ((gc->flags & GRID_FLAG_UTF8) != (sgc->flags & GRID_FLAG_UTF8))
		return (0);

	if (gc->flags & GRID_FLAG_UTF8) {
		gu = grid_peek_utf8(gd, px, py);
		sgu = grid_peek_utf8(sgd, spx, 0);
		if (grid_utf8_compare(gu, sgu))
			return (1);
	} else {
		if (gc->data == sgc->data)
			return (1);
	}
	return (0);
}
示例#8
0
/* Convert cells into a string. */
char *
grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
{
	const struct grid_cell	*gc;
	const struct grid_utf8	*gu;
	char			*buf;
	size_t			 len, off, size;
	u_int			 xx;

	GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);

	len = 128;
	buf = xmalloc(len);
	off = 0;

	for (xx = px; xx < px + nx; xx++) {
		gc = grid_peek_cell(gd, xx, py);
		if (gc->flags & GRID_FLAG_PADDING)
			continue;

		if (gc->flags & GRID_FLAG_UTF8) {
			gu = grid_peek_utf8(gd, xx, py);

			size = grid_utf8_size(gu);
			while (len < off + size + 1) {
				buf = xrealloc(buf, 2, len);
				len *= 2;
			}

			off += grid_utf8_copy(gu, buf + off, len - off);
		} else {
			while (len < off + 2) {
				buf = xrealloc(buf, 2, len);
				len *= 2;
			}

			buf[off++] = gc->data;
		}
	}

	while (off > 0 && buf[off - 1] == ' ')
		off--;
	buf[off] = '\0';
	return (buf);
}
示例#9
0
void
window_copy_cursor_back_to_indentation(struct window_pane *wp)
{
	struct window_copy_mode_data	*data = wp->modedata;
	u_int				 px, py, xx;
	const struct grid_cell		*gc;

	px = 0;
	py = screen_hsize(&wp->base) + data->cy - data->oy;
	xx = window_copy_find_length(wp, py);

	while (px < xx) {
		gc = grid_peek_cell(wp->base.grid, px, py);
		if (gc->flags & GRID_FLAG_UTF8)
			break;
		if (gc->data != ' ')
			break;
		px++;
	}

	window_copy_update_cursor(wp, px, data->cy);
	if (window_copy_update_selection(wp))
		window_copy_redraw_lines(wp, data->cy, 1);
}
示例#10
0
/* Get cell for reading. */
const struct grid_cell *
grid_view_peek_cell(struct grid *gd, u_int px, u_int py)
{
	return (grid_peek_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py)));
}
示例#11
0
文件: grid.c 项目: Axylos/dots
/* Convert cells into a string. */
char *
grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
    struct grid_cell **lastgc, int with_codes, int escape_c0, int trim)
{
	const struct grid_cell	*gc;
	static struct grid_cell	 lastgc1;
	struct utf8_data	 ud;
	const char*		 data;
	char			*buf, code[128];
	size_t			 len, off, size, codelen;
	u_int			 xx;

	GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);

	if (lastgc != NULL && *lastgc == NULL) {
		memcpy(&lastgc1, &grid_default_cell, sizeof lastgc1);
		*lastgc = &lastgc1;
	}

	len = 128;
	buf = xmalloc(len);
	off = 0;

	for (xx = px; xx < px + nx; xx++) {
		gc = grid_peek_cell(gd, xx, py);
		if (gc->flags & GRID_FLAG_PADDING)
			continue;
		grid_cell_get(gc, &ud);

		if (with_codes) {
			grid_string_cells_code(*lastgc, gc, code, sizeof code,
			    escape_c0);
			codelen = strlen(code);
			memcpy(*lastgc, gc, sizeof *gc);
		} else
			codelen = 0;

		data = ud.data;
		size = ud.size;
		if (escape_c0 && size == 1 && *data == '\\') {
			data = "\\\\";
			size = 2;
		}

		while (len < off + size + codelen + 1) {
			buf = xrealloc(buf, 2, len);
			len *= 2;
		}

		if (codelen != 0) {
			memcpy(buf + off, code, codelen);
			off += codelen;
		}
		memcpy(buf + off, data, size);
		off += size;
	}

        if (trim) {
		while (off > 0 && buf[off - 1] == ' ')
			off--;
        }
	buf[off] = '\0';

	return (buf);
}