Introduction
Introduction Statistics Contact Development Disclaimer Help
st-scrollback-20201205-4ef0cbd.diff - sites - public wiki contents of suckless.…
git clone git://git.suckless.org/sites
Log
Files
Refs
---
st-scrollback-20201205-4ef0cbd.diff (8904B)
---
1 diff --git a/config.def.h b/config.def.h
2 index 6f05dce..93cbcc0 100644
3 --- a/config.def.h
4 +++ b/config.def.h
5 @@ -199,6 +199,8 @@ static Shortcut shortcuts[] = {
6 { TERMMOD, XK_Y, selpaste, {.i = …
7 { ShiftMask, XK_Insert, selpaste, {.i = …
8 { TERMMOD, XK_Num_Lock, numlock, {.i = …
9 + { ShiftMask, XK_Page_Up, kscrollup, {.i = -…
10 + { ShiftMask, XK_Page_Down, kscrolldown, {.i = -…
11 };
12
13 /*
14 diff --git a/st.c b/st.c
15 index abbbe4b..e2dd722 100644
16 --- a/st.c
17 +++ b/st.c
18 @@ -35,6 +35,7 @@
19 #define ESC_ARG_SIZ 16
20 #define STR_BUF_SIZ ESC_BUF_SIZ
21 #define STR_ARG_SIZ ESC_ARG_SIZ
22 +#define HISTSIZE 2000
23
24 /* macros */
25 #define IS_SET(flag) ((term.mode & (flag)) != 0)
26 @@ -42,6 +43,9 @@
27 #define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
28 #define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
29 #define ISDELIM(u) (u && wcschr(worddelimiters, u))
30 +#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term…
31 + term.scr + HISTSIZE + 1) % HISTSIZE] : \
32 + term.line[(y) - term.scr])
33
34 enum term_mode {
35 MODE_WRAP = 1 << 0,
36 @@ -115,6 +119,9 @@ typedef struct {
37 int col; /* nb col */
38 Line *line; /* screen */
39 Line *alt; /* alternate screen */
40 + Line hist[HISTSIZE]; /* history buffer */
41 + int histi; /* history index */
42 + int scr; /* scroll back */
43 int *dirty; /* dirtyness of lines */
44 TCursor c; /* cursor */
45 int ocx; /* old cursor col */
46 @@ -184,8 +191,8 @@ static void tnewline(int);
47 static void tputtab(int);
48 static void tputc(Rune);
49 static void treset(void);
50 -static void tscrollup(int, int);
51 -static void tscrolldown(int, int);
52 +static void tscrollup(int, int, int);
53 +static void tscrolldown(int, int, int);
54 static void tsetattr(int *, int);
55 static void tsetchar(Rune, Glyph *, int, int);
56 static void tsetdirt(int, int);
57 @@ -414,10 +421,10 @@ tlinelen(int y)
58 {
59 int i = term.col;
60
61 - if (term.line[y][i - 1].mode & ATTR_WRAP)
62 + if (TLINE(y)[i - 1].mode & ATTR_WRAP)
63 return i;
64
65 - while (i > 0 && term.line[y][i - 1].u == ' ')
66 + while (i > 0 && TLINE(y)[i - 1].u == ' ')
67 --i;
68
69 return i;
70 @@ -526,7 +533,7 @@ selsnap(int *x, int *y, int direction)
71 * Snap around if the word wraps around at the end or
72 * beginning of a line.
73 */
74 - prevgp = &term.line[*y][*x];
75 + prevgp = &TLINE(*y)[*x];
76 prevdelim = ISDELIM(prevgp->u);
77 for (;;) {
78 newx = *x + direction;
79 @@ -541,14 +548,14 @@ selsnap(int *x, int *y, int direction)
80 yt = *y, xt = *x;
81 else
82 yt = newy, xt = newx;
83 - if (!(term.line[yt][xt].mode & ATTR_WRA…
84 + if (!(TLINE(yt)[xt].mode & ATTR_WRAP))
85 break;
86 }
87
88 if (newx >= tlinelen(newy))
89 break;
90
91 - gp = &term.line[newy][newx];
92 + gp = &TLINE(newy)[newx];
93 delim = ISDELIM(gp->u);
94 if (!(gp->mode & ATTR_WDUMMY) && (delim != prev…
95 || (delim && gp->u != prevgp->u…
96 @@ -569,14 +576,14 @@ selsnap(int *x, int *y, int direction)
97 *x = (direction < 0) ? 0 : term.col - 1;
98 if (direction < 0) {
99 for (; *y > 0; *y += direction) {
100 - if (!(term.line[*y-1][term.col-1].mode
101 + if (!(TLINE(*y-1)[term.col-1].mode
102 & ATTR_WRAP)) {
103 break;
104 }
105 }
106 } else if (direction > 0) {
107 for (; *y < term.row-1; *y += direction) {
108 - if (!(term.line[*y][term.col-1].mode
109 + if (!(TLINE(*y)[term.col-1].mode
110 & ATTR_WRAP)) {
111 break;
112 }
113 @@ -607,13 +614,13 @@ getsel(void)
114 }
115
116 if (sel.type == SEL_RECTANGULAR) {
117 - gp = &term.line[y][sel.nb.x];
118 + gp = &TLINE(y)[sel.nb.x];
119 lastx = sel.ne.x;
120 } else {
121 - gp = &term.line[y][sel.nb.y == y ? sel.nb.x : 0…
122 + gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0];
123 lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1;
124 }
125 - last = &term.line[y][MIN(lastx, linelen-1)];
126 + last = &TLINE(y)[MIN(lastx, linelen-1)];
127 while (last >= gp && last->u == ' ')
128 --last;
129
130 @@ -848,6 +855,9 @@ void
131 ttywrite(const char *s, size_t n, int may_echo)
132 {
133 const char *next;
134 + Arg arg = (Arg) { .i = term.scr };
135 +
136 + kscrolldown(&arg);
137
138 if (may_echo && IS_SET(MODE_ECHO))
139 twrite(s, n, 1);
140 @@ -1059,13 +1069,53 @@ tswapscreen(void)
141 }
142
143 void
144 -tscrolldown(int orig, int n)
145 +kscrolldown(const Arg* a)
146 +{
147 + int n = a->i;
148 +
149 + if (n < 0)
150 + n = term.row + n;
151 +
152 + if (n > term.scr)
153 + n = term.scr;
154 +
155 + if (term.scr > 0) {
156 + term.scr -= n;
157 + selscroll(0, -n);
158 + tfulldirt();
159 + }
160 +}
161 +
162 +void
163 +kscrollup(const Arg* a)
164 +{
165 + int n = a->i;
166 +
167 + if (n < 0)
168 + n = term.row + n;
169 +
170 + if (term.scr <= HISTSIZE-n) {
171 + term.scr += n;
172 + selscroll(0, n);
173 + tfulldirt();
174 + }
175 +}
176 +
177 +void
178 +tscrolldown(int orig, int n, int copyhist)
179 {
180 int i;
181 Line temp;
182
183 LIMIT(n, 0, term.bot-orig+1);
184
185 + if (copyhist) {
186 + term.histi = (term.histi - 1 + HISTSIZE) % HISTSIZE;
187 + temp = term.hist[term.histi];
188 + term.hist[term.histi] = term.line[term.bot];
189 + term.line[term.bot] = temp;
190 + }
191 +
192 tsetdirt(orig, term.bot-n);
193 tclearregion(0, term.bot-n+1, term.col-1, term.bot);
194
195 @@ -1075,17 +1125,28 @@ tscrolldown(int orig, int n)
196 term.line[i-n] = temp;
197 }
198
199 - selscroll(orig, n);
200 + if (term.scr == 0)
201 + selscroll(orig, n);
202 }
203
204 void
205 -tscrollup(int orig, int n)
206 +tscrollup(int orig, int n, int copyhist)
207 {
208 int i;
209 Line temp;
210
211 LIMIT(n, 0, term.bot-orig+1);
212
213 + if (copyhist) {
214 + term.histi = (term.histi + 1) % HISTSIZE;
215 + temp = term.hist[term.histi];
216 + term.hist[term.histi] = term.line[orig];
217 + term.line[orig] = temp;
218 + }
219 +
220 + if (term.scr > 0 && term.scr < HISTSIZE)
221 + term.scr = MIN(term.scr + n, HISTSIZE-1);
222 +
223 tclearregion(0, orig, term.col-1, orig+n-1);
224 tsetdirt(orig+n, term.bot);
225
226 @@ -1095,7 +1156,8 @@ tscrollup(int orig, int n)
227 term.line[i+n] = temp;
228 }
229
230 - selscroll(orig, -n);
231 + if (term.scr == 0)
232 + selscroll(orig, -n);
233 }
234
235 void
236 @@ -1124,7 +1186,7 @@ tnewline(int first_col)
237 int y = term.c.y;
238
239 if (y == term.bot) {
240 - tscrollup(term.top, 1);
241 + tscrollup(term.top, 1, 1);
242 } else {
243 y++;
244 }
245 @@ -1289,14 +1351,14 @@ void
246 tinsertblankline(int n)
247 {
248 if (BETWEEN(term.c.y, term.top, term.bot))
249 - tscrolldown(term.c.y, n);
250 + tscrolldown(term.c.y, n, 0);
251 }
252
253 void
254 tdeleteline(int n)
255 {
256 if (BETWEEN(term.c.y, term.top, term.bot))
257 - tscrollup(term.c.y, n);
258 + tscrollup(term.c.y, n, 0);
259 }
260
261 int32_t
262 @@ -1733,11 +1795,11 @@ csihandle(void)
263 break;
264 case 'S': /* SU -- Scroll <n> line up */
265 DEFAULT(csiescseq.arg[0], 1);
266 - tscrollup(term.top, csiescseq.arg[0]);
267 + tscrollup(term.top, csiescseq.arg[0], 0);
268 break;
269 case 'T': /* SD -- Scroll <n> line down */
270 DEFAULT(csiescseq.arg[0], 1);
271 - tscrolldown(term.top, csiescseq.arg[0]);
272 + tscrolldown(term.top, csiescseq.arg[0], 0);
273 break;
274 case 'L': /* IL -- Insert <n> blank lines */
275 DEFAULT(csiescseq.arg[0], 1);
276 @@ -2249,7 +2311,7 @@ eschandle(uchar ascii)
277 return 0;
278 case 'D': /* IND -- Linefeed */
279 if (term.c.y == term.bot) {
280 - tscrollup(term.top, 1);
281 + tscrollup(term.top, 1, 1);
282 } else {
283 tmoveto(term.c.x, term.c.y+1);
284 }
285 @@ -2262,7 +2324,7 @@ eschandle(uchar ascii)
286 break;
287 case 'M': /* RI -- Reverse index */
288 if (term.c.y == term.top) {
289 - tscrolldown(term.top, 1);
290 + tscrolldown(term.top, 1, 1);
291 } else {
292 tmoveto(term.c.x, term.c.y-1);
293 }
294 @@ -2472,7 +2534,7 @@ twrite(const char *buf, int buflen, int show_ctrl)
295 void
296 tresize(int col, int row)
297 {
298 - int i;
299 + int i, j;
300 int minrow = MIN(row, term.row);
301 int mincol = MIN(col, term.col);
302 int *bp;
303 @@ -2509,6 +2571,14 @@ tresize(int col, int row)
304 term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty));
305 term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs));
306
307 + for (i = 0; i < HISTSIZE; i++) {
308 + term.hist[i] = xrealloc(term.hist[i], col * sizeof(Glyp…
309 + for (j = mincol; j < col; j++) {
310 + term.hist[i][j] = term.c.attr;
311 + term.hist[i][j].u = ' ';
312 + }
313 + }
314 +
315 /* resize each row to new width, zero-pad if needed */
316 for (i = 0; i < minrow; i++) {
317 term.line[i] = xrealloc(term.line[i], col * sizeof(Glyp…
318 @@ -2567,7 +2637,7 @@ drawregion(int x1, int y1, int x2, int y2)
319 continue;
320
321 term.dirty[y] = 0;
322 - xdrawline(term.line[y], x1, y, x2);
323 + xdrawline(TLINE(y), x1, y, x2);
324 }
325 }
326
327 @@ -2588,8 +2658,9 @@ draw(void)
328 cx--;
329
330 drawregion(0, 0, term.col, term.row);
331 - xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
332 - term.ocx, term.ocy, term.line[term.ocy][term.oc…
333 + if (term.scr == 0)
334 + xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
335 + term.ocx, term.ocy, term.line[term.ocy]…
336 term.ocx = cx;
337 term.ocy = term.c.y;
338 xfinishdraw();
339 diff --git a/st.h b/st.h
340 index 3d351b6..f44e1d3 100644
341 --- a/st.h
342 +++ b/st.h
343 @@ -81,6 +81,8 @@ void die(const char *, ...);
344 void redraw(void);
345 void draw(void);
346
347 +void kscrolldown(const Arg *);
348 +void kscrollup(const Arg *);
349 void printscreen(const Arg *);
350 void printsel(const Arg *);
351 void sendbreak(const Arg *);
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.