25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
5.1KB

  1. /* vedit.c - buffer editing for the c64 vim clone: insert, delete, save. */
  2. extern char *bfr;
  3. extern unsigned blen;
  4. extern unsigned lptr[];
  5. extern int nlines, cy, cx, top, leftcol, mode, dirty;
  6. extern char *note;
  7. extern char fname[];
  8. extern char ybuf[];
  9. extern int ylen, yok;
  10. extern int redraw; /* 1 cursor row, 2 whole screen */
  11. /* end offset (exclusive of the $0d) of line ln */
  12. linend(ln)
  13. int ln;
  14. {
  15. if (ln + 1 < nlines) return lptr[ln + 1] - 1;
  16. return blen;
  17. }
  18. /* keep cx inside the current line */
  19. clampx()
  20. {
  21. int len;
  22. len = linend(cy) - lptr[cy];
  23. if (cx > len) cx = len;
  24. if (cx < 0) cx = 0;
  25. return 0;
  26. }
  27. /* ------------------------------------------------------------- editing */
  28. /* insert byte ch at buffer offset pos. 1 on success, 0 if the buffer is full */
  29. bins(pos, ch)
  30. unsigned pos;
  31. int ch;
  32. {
  33. if (blen >= 18999) return 0;
  34. mlmove((unsigned) bfr + pos, (unsigned) bfr + pos + 1, blen - pos);
  35. bfr[pos] = ch;
  36. blen++;
  37. dirty = 1;
  38. return 1;
  39. }
  40. /* remove n bytes at offset pos */
  41. delrange(pos, n)
  42. unsigned pos, n;
  43. {
  44. mlmove((unsigned) bfr + pos + n, (unsigned) bfr + pos, blen - pos - n);
  45. blen = blen - n;
  46. dirty = 1;
  47. return 0;
  48. }
  49. #define MAXCOL 80 /* longest line the editor keeps */
  50. /* type one character at the cursor */
  51. inschar(ch)
  52. int ch;
  53. {
  54. if (linend(cy) - lptr[cy] >= MAXCOL) {
  55. note = "line full (80)";
  56. return 0;
  57. }
  58. if (bins(lptr[cy] + cx, ch) == 0) return 0;
  59. mladj((unsigned) &lptr[cy + 1], nlines - cy - 1, 1);
  60. cx++;
  61. if (redraw < 1) redraw = 1;
  62. return 1;
  63. }
  64. /* split the line at the cursor */
  65. newline()
  66. {
  67. unsigned pos;
  68. if (nlines >= 599) return 0;
  69. pos = lptr[cy] + cx;
  70. if (bins(pos, 13) == 0) return 0;
  71. mlmove((unsigned) &lptr[cy + 1], (unsigned) &lptr[cy + 2],
  72. (nlines - cy - 1) * 2);
  73. lptr[cy + 1] = pos + 1;
  74. nlines++;
  75. mladj((unsigned) &lptr[cy + 2], nlines - cy - 2, 1);
  76. redraw = 2;
  77. cy++;
  78. cx = 0;
  79. return 1;
  80. }
  81. /* delete the character under the cursor */
  82. delchar()
  83. {
  84. if (cx >= linend(cy) - lptr[cy]) return 0;
  85. delrange(lptr[cy] + cx, 1);
  86. mladj((unsigned) &lptr[cy + 1], nlines - cy - 1, 65535);
  87. if (redraw < 1) redraw = 1;
  88. return 1;
  89. }
  90. /* backspace: delete before the cursor, or join onto the previous line */
  91. bkspace()
  92. {
  93. int pl;
  94. if (cx > 0) {
  95. cx--;
  96. delchar();
  97. return 0;
  98. }
  99. if (cy == 0) return 0;
  100. pl = linend(cy - 1) - lptr[cy - 1];
  101. if (pl + linend(cy) - lptr[cy] > MAXCOL) {
  102. note = "joined line would pass 80";
  103. return 0;
  104. }
  105. delrange(lptr[cy] - 1, 1);
  106. mlmove((unsigned) &lptr[cy + 1], (unsigned) &lptr[cy],
  107. (nlines - cy - 1) * 2);
  108. nlines--;
  109. mladj((unsigned) &lptr[cy], nlines - cy, 65535);
  110. redraw = 2;
  111. cy--;
  112. cx = pl;
  113. return 0;
  114. }
  115. /* dd: yank the current line and remove it */
  116. delline()
  117. {
  118. int i;
  119. unsigned s, e, n;
  120. s = lptr[cy];
  121. e = linend(cy);
  122. ylen = e - s;
  123. if (ylen > MAXCOL) ylen = MAXCOL;
  124. for (i = 0; i < ylen; i++) ybuf[i] = bfr[s + i];
  125. yok = 1;
  126. if (nlines == 1) {
  127. blen = 0;
  128. dirty = 1;
  129. } else if (cy + 1 < nlines) {
  130. n = lptr[cy + 1] - s;
  131. delrange(s, n);
  132. mlmove((unsigned) &lptr[cy + 1], (unsigned) &lptr[cy],
  133. (nlines - cy - 1) * 2);
  134. nlines--;
  135. mladj((unsigned) &lptr[cy], nlines - cy, 0 - n);
  136. } else { /* last line: take its leading $0d */
  137. delrange(s - 1, blen - s + 1);
  138. nlines--;
  139. cy--;
  140. }
  141. cx = 0;
  142. redraw = 2;
  143. return 0;
  144. }
  145. /* p: put the yanked line below the cursor line */
  146. paste()
  147. {
  148. int i;
  149. if (yok == 0) return 0;
  150. cx = linend(cy) - lptr[cy];
  151. if (newline() == 0) return 0;
  152. for (i = 0; i < ylen; i++) inschar(ybuf[i]);
  153. cx = 0;
  154. return 0;
  155. }
  156. /* cursor keys, the same in both modes. 1 if k was one of them */
  157. arrow(k)
  158. int k;
  159. {
  160. if (k == 17) {
  161. if (cy + 1 < nlines) {
  162. cy++;
  163. clampx();
  164. }
  165. return 1;
  166. }
  167. if (k == 145) {
  168. if (cy > 0) {
  169. cy--;
  170. clampx();
  171. }
  172. return 1;
  173. }
  174. if (k == 29) {
  175. cx++;
  176. clampx();
  177. return 1;
  178. }
  179. if (k == 157) {
  180. if (cx > 0) cx--;
  181. return 1;
  182. }
  183. return 0;
  184. }
  185. /* write the buffer to fname, replacing any old copy. 1 on success */
  186. savef()
  187. {
  188. char on[32];
  189. int i, f;
  190. unsigned j;
  191. on[0] = 64; /* @ */
  192. on[1] = 48; /* 0 */
  193. on[2] = 58; /* : */
  194. i = 3;
  195. j = 0;
  196. while (fname[j] && j < 20) on[i++] = fname[j++];
  197. on[i++] = 44; /* , */
  198. on[i++] = 83; /* S (petscii, not ascii) */
  199. on[i++] = 44; /* , */
  200. on[i++] = 87; /* W */
  201. on[i] = 0;
  202. f = open(5, 8, 3, on);
  203. if (f == 0) return 0;
  204. for (j = 0; j < blen; j++) putc(bfr[j], 5);
  205. if (blen > 0) {
  206. if (bfr[blen - 1] != 13) putc(13, 5);
  207. }
  208. close(5);
  209. return 1;
  210. }

Powered by TurnKey Linux.