214 lines
5.2 KiB
Plaintext
214 lines
5.2 KiB
Plaintext
--- 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 <n> 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 <n> 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 <n> 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 */
|