My build of the simple terminal from suckless.org.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

352 lignes
8.7 KiB

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