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.
 
 
 
 
 

324 lignes
7.8 KiB

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