mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Instead of having a complicated check to see if the cursor is in the last
position to avoid an explicit wrap, actually move it there. Some UTF-8 fixes to come.
This commit is contained in:
		| @@ -22,7 +22,7 @@ | |||||||
|  |  | ||||||
| #include "tmux.h" | #include "tmux.h" | ||||||
|  |  | ||||||
| void	screen_write_initctx(struct screen_write_ctx *, struct tty_ctx *); | void	screen_write_initctx(struct screen_write_ctx *, struct tty_ctx *, int); | ||||||
| void	screen_write_overwrite(struct screen_write_ctx *); | void	screen_write_overwrite(struct screen_write_ctx *); | ||||||
|  |  | ||||||
| /* Initialise writing with a window. */ | /* Initialise writing with a window. */ | ||||||
| @@ -418,9 +418,14 @@ screen_write_copy(struct screen_write_ctx *ctx, | |||||||
|  |  | ||||||
| /* Set up context for TTY command. */ | /* Set up context for TTY command. */ | ||||||
| void | void | ||||||
| screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx) | screen_write_initctx( | ||||||
|  |     struct screen_write_ctx *ctx, struct tty_ctx *ttyctx, int save_last) | ||||||
| { | { | ||||||
| 	struct screen		*s = ctx->s; | 	struct screen		*s = ctx->s; | ||||||
|  | 	struct grid		*gd = s->grid; | ||||||
|  | 	const struct grid_cell	*gc; | ||||||
|  | 	const struct grid_utf8	*gu; | ||||||
|  | 	u_int			 xx; | ||||||
|  |  | ||||||
| 	ttyctx->wp = ctx->wp; | 	ttyctx->wp = ctx->wp; | ||||||
|  |  | ||||||
| @@ -429,6 +434,23 @@ screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx) | |||||||
|  |  | ||||||
| 	ttyctx->orlower = s->rlower; | 	ttyctx->orlower = s->rlower; | ||||||
| 	ttyctx->orupper = s->rupper; | 	ttyctx->orupper = s->rupper; | ||||||
|  |  | ||||||
|  | 	if (!save_last) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	/* Save the last cell on the screen. */ | ||||||
|  | 	gc = NULL; | ||||||
|  | 	for (xx = 1; xx < screen_size_x(s); xx++) { | ||||||
|  | 		gc = grid_view_peek_cell(gd, screen_size_x(s) - xx, s->cy); | ||||||
|  | 		if (!(gc->flags & GRID_FLAG_PADDING)) | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 	ttyctx->last_width = xx; | ||||||
|  | 	memcpy(&ttyctx->last_cell, gc, sizeof ttyctx->last_cell); | ||||||
|  | 	if (gc->flags & GRID_FLAG_UTF8) { | ||||||
|  | 		gu = grid_view_peek_utf8(gd, screen_size_x(s) - xx, s->cy); | ||||||
|  | 		memcpy(&ttyctx->last_utf8, gu, sizeof ttyctx->last_utf8); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Cursor up by ny. */ | /* Cursor up by ny. */ | ||||||
| @@ -541,7 +563,7 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx) | |||||||
| 	struct grid_cell       	 gc; | 	struct grid_cell       	 gc; | ||||||
| 	u_int			 xx, yy; | 	u_int			 xx, yy; | ||||||
|  |  | ||||||
| 	screen_write_initctx(ctx, &ttyctx); | 	screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 	memcpy(&gc, &grid_default_cell, sizeof gc); | 	memcpy(&gc, &grid_default_cell, sizeof gc); | ||||||
| 	gc.data = 'E'; | 	gc.data = 'E'; | ||||||
| @@ -576,7 +598,7 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx) | |||||||
| 	if (nx == 0) | 	if (nx == 0) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	screen_write_initctx(ctx, &ttyctx); | 	screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 	if (s->cx <= screen_size_x(s) - 1) | 	if (s->cx <= screen_size_x(s) - 1) | ||||||
| 		grid_view_insert_cells(s->grid, s->cx, s->cy, nx); | 		grid_view_insert_cells(s->grid, s->cx, s->cy, nx); | ||||||
| @@ -600,7 +622,7 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx) | |||||||
| 	if (nx == 0) | 	if (nx == 0) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	screen_write_initctx(ctx, &ttyctx); | 	screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 	if (s->cx <= screen_size_x(s) - 1) | 	if (s->cx <= screen_size_x(s) - 1) | ||||||
| 		grid_view_delete_cells(s->grid, s->cx, s->cy, nx); | 		grid_view_delete_cells(s->grid, s->cx, s->cy, nx); | ||||||
| @@ -625,7 +647,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny) | |||||||
| 		if (ny == 0) | 		if (ny == 0) | ||||||
| 			return; | 			return; | ||||||
|  |  | ||||||
| 		screen_write_initctx(ctx, &ttyctx); | 		screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 		grid_view_insert_lines(s->grid, s->cy, ny); | 		grid_view_insert_lines(s->grid, s->cy, ny); | ||||||
|  |  | ||||||
| @@ -639,7 +661,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny) | |||||||
| 	if (ny == 0) | 	if (ny == 0) | ||||||
| 		return; | 		return; | ||||||
| 	 | 	 | ||||||
| 	screen_write_initctx(ctx, &ttyctx); | 	screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 	if (s->cy < s->rupper || s->cy > s->rlower) | 	if (s->cy < s->rupper || s->cy > s->rlower) | ||||||
| 		grid_view_insert_lines(s->grid, s->cy, ny); | 		grid_view_insert_lines(s->grid, s->cy, ny); | ||||||
| @@ -666,7 +688,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny) | |||||||
| 		if (ny == 0) | 		if (ny == 0) | ||||||
| 			return; | 			return; | ||||||
|  |  | ||||||
| 		screen_write_initctx(ctx, &ttyctx); | 		screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 		grid_view_delete_lines(s->grid, s->cy, ny); | 		grid_view_delete_lines(s->grid, s->cy, ny); | ||||||
|  |  | ||||||
| @@ -680,7 +702,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny) | |||||||
| 	if (ny == 0) | 	if (ny == 0) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	screen_write_initctx(ctx, &ttyctx); | 	screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 	if (s->cy < s->rupper || s->cy > s->rlower) | 	if (s->cy < s->rupper || s->cy > s->rlower) | ||||||
| 		grid_view_delete_lines(s->grid, s->cy, ny); | 		grid_view_delete_lines(s->grid, s->cy, ny); | ||||||
| @@ -698,7 +720,7 @@ screen_write_clearline(struct screen_write_ctx *ctx) | |||||||
| 	struct screen	*s = ctx->s; | 	struct screen	*s = ctx->s; | ||||||
| 	struct tty_ctx	 ttyctx; | 	struct tty_ctx	 ttyctx; | ||||||
|  |  | ||||||
| 	screen_write_initctx(ctx, &ttyctx); | 	screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 	grid_view_clear(s->grid, 0, s->cy, screen_size_x(s), 1); | 	grid_view_clear(s->grid, 0, s->cy, screen_size_x(s), 1); | ||||||
|  |  | ||||||
| @@ -713,7 +735,7 @@ screen_write_clearendofline(struct screen_write_ctx *ctx) | |||||||
| 	struct tty_ctx	 ttyctx; | 	struct tty_ctx	 ttyctx; | ||||||
| 	u_int		 sx; | 	u_int		 sx; | ||||||
|  |  | ||||||
| 	screen_write_initctx(ctx, &ttyctx); | 	screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 	sx = screen_size_x(s); | 	sx = screen_size_x(s); | ||||||
|  |  | ||||||
| @@ -731,7 +753,7 @@ screen_write_clearstartofline(struct screen_write_ctx *ctx) | |||||||
| 	struct tty_ctx	 ttyctx; | 	struct tty_ctx	 ttyctx; | ||||||
| 	u_int		 sx; | 	u_int		 sx; | ||||||
|  |  | ||||||
| 	screen_write_initctx(ctx, &ttyctx); | 	screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 	sx = screen_size_x(s); | 	sx = screen_size_x(s); | ||||||
|  |  | ||||||
| @@ -777,7 +799,7 @@ screen_write_reverseindex(struct screen_write_ctx *ctx) | |||||||
| 	struct screen	*s = ctx->s; | 	struct screen	*s = ctx->s; | ||||||
| 	struct tty_ctx	 ttyctx; | 	struct tty_ctx	 ttyctx; | ||||||
|  |  | ||||||
| 	screen_write_initctx(ctx, &ttyctx); | 	screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 	if (s->cy == s->rupper) | 	if (s->cy == s->rupper) | ||||||
| 		grid_view_scroll_region_down(s->grid, s->rupper, s->rlower); | 		grid_view_scroll_region_down(s->grid, s->rupper, s->rlower); | ||||||
| @@ -861,7 +883,7 @@ screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped) | |||||||
| { | { | ||||||
| 	struct tty_ctx	 ttyctx; | 	struct tty_ctx	 ttyctx; | ||||||
|  |  | ||||||
| 	screen_write_initctx(ctx, &ttyctx); | 	screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 	screen_write_linefeedscreen(ctx, wrapped); | 	screen_write_linefeedscreen(ctx, wrapped); | ||||||
|  |  | ||||||
| @@ -909,7 +931,7 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx) | |||||||
| 	struct tty_ctx	 ttyctx; | 	struct tty_ctx	 ttyctx; | ||||||
| 	u_int		 sx, sy; | 	u_int		 sx, sy; | ||||||
|  |  | ||||||
| 	screen_write_initctx(ctx, &ttyctx); | 	screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 	sx = screen_size_x(s); | 	sx = screen_size_x(s); | ||||||
| 	sy = screen_size_y(s); | 	sy = screen_size_y(s); | ||||||
| @@ -929,7 +951,7 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx) | |||||||
| 	struct tty_ctx	 ttyctx; | 	struct tty_ctx	 ttyctx; | ||||||
| 	u_int		 sx; | 	u_int		 sx; | ||||||
|  |  | ||||||
| 	screen_write_initctx(ctx, &ttyctx); | 	screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 	sx = screen_size_x(s); | 	sx = screen_size_x(s); | ||||||
|  |  | ||||||
| @@ -950,7 +972,7 @@ screen_write_clearscreen(struct screen_write_ctx *ctx) | |||||||
| 	struct screen	*s = ctx->s; | 	struct screen	*s = ctx->s; | ||||||
| 	struct tty_ctx	 ttyctx; | 	struct tty_ctx	 ttyctx; | ||||||
|  |  | ||||||
| 	screen_write_initctx(ctx, &ttyctx); | 	screen_write_initctx(ctx, &ttyctx, 0); | ||||||
|  |  | ||||||
| 	grid_view_clear(s->grid, 0, 0, screen_size_x(s), screen_size_y(s)); | 	grid_view_clear(s->grid, 0, 0, screen_size_x(s), screen_size_y(s)); | ||||||
|  |  | ||||||
| @@ -1004,8 +1026,12 @@ screen_write_cell( | |||||||
| 		} | 		} | ||||||
| 		memcpy(tmp_gu->data + i, udata, UTF8_SIZE - i); | 		memcpy(tmp_gu->data + i, udata, UTF8_SIZE - i); | ||||||
|  |  | ||||||
| 		/* Assume the previous character has just been input. */ | 		/* | ||||||
| 		screen_write_initctx(ctx, &ttyctx); | 		 * Assume the previous character has just been input.  | ||||||
|  | 		 * XXX There is no guarantee this is true, need to redraw | ||||||
|  | 		 * entire line. | ||||||
|  | 		 */ | ||||||
|  | 		screen_write_initctx(ctx, &ttyctx, 0); | ||||||
| 		ttyctx.ptr = udata; | 		ttyctx.ptr = udata; | ||||||
| 		tty_write(tty_cmd_utf8character, &ttyctx); | 		tty_write(tty_cmd_utf8character, &ttyctx); | ||||||
| 		return; | 		return; | ||||||
| @@ -1019,6 +1045,9 @@ screen_write_cell( | |||||||
| 		gc = &tmp_gc; | 		gc = &tmp_gc; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/* Initialise the redraw context, saving the last cell. */ | ||||||
|  | 	screen_write_initctx(ctx, &ttyctx, 1); | ||||||
|  |  | ||||||
| 	/* If in insert mode, make space for the cells. */ | 	/* If in insert mode, make space for the cells. */ | ||||||
| 	if (s->mode & MODE_INSERT && s->cx <= screen_size_x(s) - width) { | 	if (s->mode & MODE_INSERT && s->cx <= screen_size_x(s) - width) { | ||||||
| 		xx = screen_size_x(s) - s->cx - width; | 		xx = screen_size_x(s) - s->cx - width; | ||||||
| @@ -1063,7 +1092,6 @@ screen_write_cell( | |||||||
| 		grid_view_set_utf8(gd, s->cx, s->cy, &gu); | 		grid_view_set_utf8(gd, s->cx, s->cy, &gu); | ||||||
|  |  | ||||||
| 	/* Move the cursor. */ | 	/* Move the cursor. */ | ||||||
| 	screen_write_initctx(ctx, &ttyctx); |  | ||||||
| 	s->cx += width; | 	s->cx += width; | ||||||
|  |  | ||||||
| 	/* Draw to the screen if necessary. */ | 	/* Draw to the screen if necessary. */ | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -970,6 +970,11 @@ struct tty_ctx { | |||||||
|  |  | ||||||
| 	u_int		 orupper; | 	u_int		 orupper; | ||||||
| 	u_int		 orlower; | 	u_int		 orlower; | ||||||
|  |  | ||||||
|  | 	/* Saved last cell on line. */ | ||||||
|  | 	struct grid_cell last_cell; | ||||||
|  | 	struct grid_utf8 last_utf8; | ||||||
|  | 	u_int		 last_width; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* Mouse input. */ | /* Mouse input. */ | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								tty.c
									
									
									
									
									
								
							| @@ -456,7 +456,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) | |||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 * Don't move the cursor to the start permission if it will wrap there | 	 * Don't move the cursor to the start permission if it will wrap there | ||||||
| 	 * itself; much the same as the conditions in tty_cmd_cell. | 	 * itself. | ||||||
| 	 */ | 	 */ | ||||||
| 	gl = NULL; | 	gl = NULL; | ||||||
| 	if (py != 0) | 	if (py != 0) | ||||||
| @@ -842,33 +842,21 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) | |||||||
| { | { | ||||||
| 	struct window_pane	*wp = ctx->wp; | 	struct window_pane	*wp = ctx->wp; | ||||||
| 	struct screen		*s = wp->screen; | 	struct screen		*s = wp->screen; | ||||||
| 	struct grid_line	*gl; | 	u_int			 cx; | ||||||
| 	u_int			 wx, wy; |  | ||||||
|  |  | ||||||
| 	tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); | 	tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); | ||||||
|  |  | ||||||
| 	wx = ctx->ocx + wp->xoff; |  | ||||||
| 	wy = ctx->ocy + wp->yoff; |  | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 * If: | 	 * Should the cursor be in the last cursor position ready for a natural | ||||||
| 	 *  | 	 * wrap? If so - and it isn't - move to and rewrite the last cell. | ||||||
| 	 * - the line was wrapped: |  | ||||||
| 	 * - the cursor is beyond the edge of the screen, |  | ||||||
| 	 * - the desired position is at the left, |  | ||||||
| 	 * - and either a) the desired next line is the one below the current |  | ||||||
| 	 *   or b) the current line is the bottom of the scroll region, |  | ||||||
| 	 * |  | ||||||
| 	 * Then just printing the next character will be enough to scroll into |  | ||||||
| 	 * place, so don't do an explicit cursor move. |  | ||||||
| 	 */ | 	 */ | ||||||
| 	gl = NULL; | 	if (ctx->ocx + wp->xoff > tty->sx - ctx->last_width) { | ||||||
| 	if (ctx->ocy != 0) | 		if (tty->cx < tty->sx) { | ||||||
| 		gl = &s->grid->linedata[s->grid->hsize + ctx->ocy - 1]; | 			cx = screen_size_x(s) - ctx->last_width; | ||||||
| 	if (wy == 0 || (gl != NULL && !(gl->flags & GRID_LINE_WRAPPED)) || | 			tty_cursor_pane(tty, ctx, cx, ctx->ocy); | ||||||
| 	    tty->cx < tty->sx ||	/* not at edge of screen */ | 			tty_cell(tty, &ctx->last_cell, &ctx->last_utf8); | ||||||
| 	    wx != 0 ||			/* don't want 0 next */ | 		} | ||||||
| 	    (wy != tty->cy + 1 && tty->cy != ctx->orlower + wp->yoff)) | 	} else | ||||||
| 		tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); | 		tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); | ||||||
|  |  | ||||||
| 	tty_cell(tty, ctx->cell, ctx->utf8); | 	tty_cell(tty, ctx->cell, ctx->utf8); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Nicholas Marriott
					Nicholas Marriott