mirror of
https://github.com/tmux/tmux.git
synced 2024-12-12 17:38:48 +00:00
Add support for scroll up escape sequence (CSI S) and use it when
possible instead of sending individual line feeds.
This commit is contained in:
parent
13a0b6bb3f
commit
e100d465da
5
input.c
5
input.c
@ -222,6 +222,7 @@ enum input_csi_type {
|
||||
INPUT_CSI_SGR,
|
||||
INPUT_CSI_SM,
|
||||
INPUT_CSI_SM_PRIVATE,
|
||||
INPUT_CSI_SU,
|
||||
INPUT_CSI_TBC,
|
||||
INPUT_CSI_VPA,
|
||||
INPUT_CSI_WINOPS,
|
||||
@ -243,6 +244,7 @@ static const struct input_table_entry input_csi_table[] = {
|
||||
{ 'L', "", INPUT_CSI_IL },
|
||||
{ 'M', "", INPUT_CSI_DL },
|
||||
{ 'P', "", INPUT_CSI_DCH },
|
||||
{ 'S', "", INPUT_CSI_SU },
|
||||
{ 'X', "", INPUT_CSI_ECH },
|
||||
{ 'Z', "", INPUT_CSI_CBT },
|
||||
{ 'c', "", INPUT_CSI_DA },
|
||||
@ -1413,6 +1415,9 @@ input_csi_dispatch(struct input_ctx *ictx)
|
||||
case INPUT_CSI_SM_PRIVATE:
|
||||
input_csi_dispatch_sm_private(ictx);
|
||||
break;
|
||||
case INPUT_CSI_SU:
|
||||
screen_write_scrollup(sctx, input_get(ictx, 0, 1, 1));
|
||||
break;
|
||||
case INPUT_CSI_TBC:
|
||||
switch (input_get(ictx, 0, 0, 0)) {
|
||||
case 0:
|
||||
|
@ -839,6 +839,8 @@ screen_write_scrollregion(struct screen_write_ctx *ctx, u_int rupper,
|
||||
if (rupper >= rlower) /* cannot be one line */
|
||||
return;
|
||||
|
||||
screen_write_collect_flush(ctx);
|
||||
|
||||
/* Cursor moves to top-left. */
|
||||
s->cx = 0;
|
||||
s->cy = 0;
|
||||
@ -854,7 +856,6 @@ screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
|
||||
struct screen *s = ctx->s;
|
||||
struct grid *gd = s->grid;
|
||||
struct grid_line *gl;
|
||||
struct tty_ctx ttyctx;
|
||||
|
||||
gl = &gd->linedata[gd->hsize + s->cy];
|
||||
if (wrapped)
|
||||
@ -864,14 +865,32 @@ screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
|
||||
|
||||
if (s->cy == s->rlower) {
|
||||
grid_view_scroll_region_up(gd, s->rupper, s->rlower);
|
||||
|
||||
screen_write_collect_scroll(ctx);
|
||||
screen_write_initctx(ctx, &ttyctx);
|
||||
tty_write(tty_cmd_linefeed, &ttyctx);
|
||||
ctx->scrolled++;
|
||||
} else if (s->cy < screen_size_y(s) - 1)
|
||||
s->cy++;
|
||||
}
|
||||
|
||||
/* Scroll up. */
|
||||
void
|
||||
screen_write_scrollup(struct screen_write_ctx *ctx, u_int lines)
|
||||
{
|
||||
struct screen *s = ctx->s;
|
||||
struct grid *gd = s->grid;
|
||||
u_int i;
|
||||
|
||||
if (lines == 0)
|
||||
lines = 1;
|
||||
else if (lines > s->rlower - s->rupper + 1)
|
||||
lines = s->rlower - s->rupper + 1;
|
||||
|
||||
for (i = 0; i < lines; i++) {
|
||||
grid_view_scroll_region_up(gd, s->rupper, s->rlower);
|
||||
screen_write_collect_scroll(ctx);
|
||||
}
|
||||
ctx->scrolled += lines;
|
||||
}
|
||||
|
||||
/* Carriage return (cursor to start of line). */
|
||||
void
|
||||
screen_write_carriagereturn(struct screen_write_ctx *ctx)
|
||||
@ -1009,6 +1028,18 @@ screen_write_collect_flush(struct screen_write_ctx *ctx)
|
||||
u_int y, cx, cy;
|
||||
struct tty_ctx ttyctx;
|
||||
|
||||
if (ctx->scrolled != 0) {
|
||||
log_debug("%s: scrolled %u (region %u-%u)", __func__,
|
||||
ctx->scrolled, s->rupper, s->rlower);
|
||||
if (ctx->scrolled > s->rlower - s->rupper + 1)
|
||||
ctx->scrolled = s->rlower - s->rupper + 1;
|
||||
|
||||
screen_write_initctx(ctx, &ttyctx);
|
||||
ttyctx.num = ctx->scrolled;
|
||||
tty_write(tty_cmd_scrollup, &ttyctx);
|
||||
}
|
||||
ctx->scrolled = 0;
|
||||
|
||||
cx = s->cx; cy = s->cy;
|
||||
for (y = 0; y < screen_size_y(s); y++) {
|
||||
TAILQ_FOREACH_SAFE(ci, &ctx->list[y].items, entry, tmp) {
|
||||
|
4
tmux.h
4
tmux.h
@ -241,6 +241,7 @@ enum tty_code_code {
|
||||
TTYC_ICH1, /* insert_character, ic */
|
||||
TTYC_IL, /* parm_insert_line, IL */
|
||||
TTYC_IL1, /* insert_line, il */
|
||||
TTYC_INDN, /* parm_index, indn */
|
||||
TTYC_INVIS, /* enter_secure_mode, mk */
|
||||
TTYC_IS1, /* init_1string, i1 */
|
||||
TTYC_IS2, /* init_2string, i2 */
|
||||
@ -663,6 +664,7 @@ struct screen_write_ctx {
|
||||
|
||||
struct screen_write_collect_item *item;
|
||||
struct screen_write_collect_line *list;
|
||||
u_int scrolled;
|
||||
|
||||
u_int cells;
|
||||
u_int written;
|
||||
@ -1658,6 +1660,7 @@ void tty_cmd_erasecharacter(struct tty *, const struct tty_ctx *);
|
||||
void tty_cmd_insertcharacter(struct tty *, const struct tty_ctx *);
|
||||
void tty_cmd_insertline(struct tty *, const struct tty_ctx *);
|
||||
void tty_cmd_linefeed(struct tty *, const struct tty_ctx *);
|
||||
void tty_cmd_scrollup(struct tty *, const struct tty_ctx *);
|
||||
void tty_cmd_reverseindex(struct tty *, const struct tty_ctx *);
|
||||
void tty_cmd_setselection(struct tty *, const struct tty_ctx *);
|
||||
void tty_cmd_rawstring(struct tty *, const struct tty_ctx *);
|
||||
@ -1984,6 +1987,7 @@ void screen_write_cursormove(struct screen_write_ctx *, u_int, u_int);
|
||||
void screen_write_reverseindex(struct screen_write_ctx *);
|
||||
void screen_write_scrollregion(struct screen_write_ctx *, u_int, u_int);
|
||||
void screen_write_linefeed(struct screen_write_ctx *, int);
|
||||
void screen_write_scrollup(struct screen_write_ctx *, u_int);
|
||||
void screen_write_carriagereturn(struct screen_write_ctx *);
|
||||
void screen_write_clearendofscreen(struct screen_write_ctx *, u_int);
|
||||
void screen_write_clearstartofscreen(struct screen_write_ctx *, u_int);
|
||||
|
@ -95,6 +95,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
|
||||
[TTYC_ICH1] = { TTYCODE_STRING, "ich1" },
|
||||
[TTYC_IL] = { TTYCODE_STRING, "il" },
|
||||
[TTYC_IL1] = { TTYCODE_STRING, "il1" },
|
||||
[TTYC_INDN] = { TTYCODE_STRING, "indn" },
|
||||
[TTYC_INVIS] = { TTYCODE_STRING, "invis" },
|
||||
[TTYC_IS1] = { TTYCODE_STRING, "is1" },
|
||||
[TTYC_IS2] = { TTYCODE_STRING, "is2" },
|
||||
|
26
tty.c
26
tty.c
@ -1021,6 +1021,32 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
|
||||
tty_putc(tty, '\n');
|
||||
}
|
||||
|
||||
void
|
||||
tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx)
|
||||
{
|
||||
struct window_pane *wp = ctx->wp;
|
||||
u_int i;
|
||||
|
||||
if ((!tty_pane_full_width(tty, ctx) && !tty_use_margin(tty)) ||
|
||||
tty_fake_bce(tty, wp, ctx->bg) ||
|
||||
!tty_term_has(tty->term, TTYC_CSR)) {
|
||||
tty_redraw_region(tty, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
tty_attributes(tty, &grid_default_cell, wp);
|
||||
|
||||
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
|
||||
tty_margin_pane(tty, ctx);
|
||||
|
||||
if (ctx->num == 1 || !tty_term_has(tty->term, TTYC_INDN)) {
|
||||
tty_cursor(tty, tty->rright, ctx->yoff + tty->rlower);
|
||||
for (i = 0; i < ctx->num; i++)
|
||||
tty_putc(tty, '\n');
|
||||
} else
|
||||
tty_putcode1(tty, TTYC_INDN, ctx->num);
|
||||
}
|
||||
|
||||
void
|
||||
tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user