--- st.c +++ st.c @@ -1224,92 +1361,118 @@ kscrollup(const Arg* a) { int n = a->i; + if (!term.histf || IS_SET(MODE_ALTSCREEN)) + return; + if (n < 0) - n = term.row + n; + n = MAX(term.row / -n, 1); - if (term.scr <= HISTSIZE-n) { + if (term.scr + n <= term.histf) { term.scr += n; - selscroll(0, n); - tfulldirt(); + } else { + n = term.histf - term.scr; + term.scr = term.histf; } + + if (sel.ob.x != -1 && !sel.alt) + selmove(n); /* negate change in term.scr */ + tfulldirt(); } void -tscrolldown(int orig, int n, int copyhist) +tscrolldown(int top, int n) { - int i; + int i, bot = term.bot; Line temp; - LIMIT(n, 0, term.bot-orig+1); - if (copyhist) { - term.histi = (term.histi - 1 + HISTSIZE) % HISTSIZE; - temp = term.hist[term.histi]; - term.hist[term.histi] = term.line[term.bot]; - term.line[term.bot] = temp; - } - + if (n <= 0) + return; + n = MIN(n, bot-top+1); - tsetdirt(orig, term.bot-n); - tclearregion(0, term.bot-n+1, term.col-1, term.bot); + tsetdirt(top, bot-n); + tclearregion(0, bot-n+1, term.col-1, bot, 1); - for (i = term.bot; i >= orig+n; i--) { + for (i = bot; i >= top+n; i--) { temp = term.line[i]; term.line[i] = term.line[i-n]; term.line[i-n] = temp; } - if (term.scr == 0) - selscroll(orig, n); + if (sel.ob.x != -1 && sel.alt == IS_SET(MODE_ALTSCREEN)) + selscroll(top, bot, n); } void -tscrollup(int orig, int n, int copyhist) +tscrollup(int top, int bot, int n, int mode) { - int i; + int i, j, s; + int alt = IS_SET(MODE_ALTSCREEN); + int savehist = !alt && top == 0 && mode != SCROLL_NOSAVEHIST; Line temp; - LIMIT(n, 0, term.bot-orig+1); - - if (copyhist) { - term.histi = (term.histi + 1) % HISTSIZE; - temp = term.hist[term.histi]; - term.hist[term.histi] = term.line[orig]; - term.line[orig] = temp; + if (n <= 0) + return; + n = MIN(n, bot-top+1); + + if (savehist) { + for (i = 0; i < n; i++) { + term.histi = (term.histi + 1) % HISTSIZE; + temp = term.hist[term.histi]; + for (j = 0; j < term.col; j++) + tclearglyph(&temp[j], 1); + term.hist[term.histi] = term.line[i]; + term.line[i] = temp; + } + term.histf = MIN(term.histf + n, HISTSIZE); + s = n; + if (term.scr) { + j = term.scr; + term.scr = MIN(j + n, HISTSIZE); + s = j + n - term.scr; + } + if (mode != SCROLL_RESIZE) + tfulldirt(); + } else { + tclearregion(0, top, term.col-1, top+n-1, 1); + tsetdirt(top+n, bot); } - if (term.scr > 0 && term.scr < HISTSIZE) - term.scr = MIN(term.scr + n, HISTSIZE-1); - - tclearregion(0, orig, term.col-1, orig+n-1); - tsetdirt(orig+n, term.bot); - - for (i = orig; i <= term.bot-n; i++) { + for (i = top; i <= bot-n; i++) { temp = term.line[i]; term.line[i] = term.line[i+n]; term.line[i+n] = temp; } - if (term.scr == 0) - selscroll(orig, -n); + if (sel.ob.x != -1 && sel.alt == alt) { + if (!savehist) { + selscroll(top, bot, -n); + } else if (s > 0) { + selmove(-s); + if (-term.scr + sel.nb.y < -term.histf) + selremove(); + } + } } void -selscroll(int orig, int n) +selmove(int n) { - if (sel.ob.x == -1) - return; + sel.ob.y += n, sel.nb.y += n; + sel.oe.y += n, sel.ne.y += n; +} + +void +selscroll(int top, int bot, int n) +{ + /* turn absolute coordinates into relative */ + top += term.scr, bot += term.scr; - if (BETWEEN(sel.nb.y, orig, term.bot) != BETWEEN(sel.ne.y, orig, term.bot)) { + if (BETWEEN(sel.nb.y, top, bot) != BETWEEN(sel.ne.y, top, bot)) { selclear(); - } else if (BETWEEN(sel.nb.y, orig, term.bot)) { - sel.ob.y += n; - sel.oe.y += n; - if (sel.ob.y < term.top || sel.ob.y > term.bot || - sel.oe.y < term.top || sel.oe.y > term.bot) { + } else if (BETWEEN(sel.nb.y, top, bot)) { + selmove(n); + if (sel.nb.y < top || sel.ne.y > bot) selclear(); - } else { - selnormalize(); - } } } @@ -1922,24 +2092,24 @@ csihandle(void) case 'K': /* EL -- Clear line */ switch (csiescseq.arg[0]) { case 0: /* right */ - tclearregion(term.c.x, term.c.y, term.col-1, - term.c.y); + tclearregion(term.c.x, term.c.y, term.col-1, term.c.y, 1); break; case 1: /* left */ - tclearregion(0, term.c.y, term.c.x, term.c.y); + tclearregion(0, term.c.y, term.c.x, term.c.y, 1); break; case 2: /* all */ - tclearregion(0, term.c.y, term.col-1, term.c.y); + tclearregion(0, term.c.y, term.col-1, term.c.y, 1); break; } break; case 'S': /* SU -- Scroll line up */ DEFAULT(csiescseq.arg[0], 1); - tscrollup(term.top, csiescseq.arg[0], 0); + /* xterm, urxvt, alacritty save this in history */ + tscrollup(term.top, term.bot, csiescseq.arg[0], SCROLL_SAVEHIST); break; case 'T': /* SD -- Scroll line down */ DEFAULT(csiescseq.arg[0], 1); - tscrolldown(term.top, csiescseq.arg[0], 0); + tscrolldown(term.top, csiescseq.arg[0]); break; case 'L': /* IL -- Insert blank lines */ DEFAULT(csiescseq.arg[0], 1); @@ -1979,9 +2151,9 @@ csihandle(void) break; case 'n': /* DSR – Device Status Report (cursor position) */ if (csiescseq.arg[0] == 6) { - len = snprintf(buf, sizeof(buf), "\033[%i;%iR", + n = snprintf(buf, sizeof(buf), "\033[%i;%iR", term.c.y+1, term.c.x+1); - ttywrite(buf, len, 0); + ttywrite(buf, n, 0); } break; case 'r': /* DECSTBM -- Set Scrolling Region */