/* vedit.c - buffer editing for the c64 vim clone: insert, delete, save. */ extern char *bfr; extern unsigned blen; extern unsigned lptr[]; extern int nlines, cy, cx, top, leftcol, mode, dirty; extern char *note; extern char fname[]; extern char ybuf[]; extern int ylen, yok; extern int redraw; /* 1 cursor row, 2 whole screen */ /* end offset (exclusive of the $0d) of line ln */ linend(ln) int ln; { if (ln + 1 < nlines) return lptr[ln + 1] - 1; return blen; } /* keep cx inside the current line */ clampx() { int len; len = linend(cy) - lptr[cy]; if (cx > len) cx = len; if (cx < 0) cx = 0; return 0; } /* ------------------------------------------------------------- editing */ /* insert byte ch at buffer offset pos. 1 on success, 0 if the buffer is full */ bins(pos, ch) unsigned pos; int ch; { if (blen >= 18999) return 0; mlmove((unsigned) bfr + pos, (unsigned) bfr + pos + 1, blen - pos); bfr[pos] = ch; blen++; dirty = 1; return 1; } /* remove n bytes at offset pos */ delrange(pos, n) unsigned pos, n; { mlmove((unsigned) bfr + pos + n, (unsigned) bfr + pos, blen - pos - n); blen = blen - n; dirty = 1; return 0; } #define MAXCOL 80 /* longest line the editor keeps */ /* type one character at the cursor */ inschar(ch) int ch; { if (linend(cy) - lptr[cy] >= MAXCOL) { note = "line full (80)"; return 0; } if (bins(lptr[cy] + cx, ch) == 0) return 0; mladj((unsigned) &lptr[cy + 1], nlines - cy - 1, 1); cx++; if (redraw < 1) redraw = 1; return 1; } /* split the line at the cursor */ newline() { unsigned pos; if (nlines >= 599) return 0; pos = lptr[cy] + cx; if (bins(pos, 13) == 0) return 0; mlmove((unsigned) &lptr[cy + 1], (unsigned) &lptr[cy + 2], (nlines - cy - 1) * 2); lptr[cy + 1] = pos + 1; nlines++; mladj((unsigned) &lptr[cy + 2], nlines - cy - 2, 1); redraw = 2; cy++; cx = 0; return 1; } /* delete the character under the cursor */ delchar() { if (cx >= linend(cy) - lptr[cy]) return 0; delrange(lptr[cy] + cx, 1); mladj((unsigned) &lptr[cy + 1], nlines - cy - 1, 65535); if (redraw < 1) redraw = 1; return 1; } /* backspace: delete before the cursor, or join onto the previous line */ bkspace() { int pl; if (cx > 0) { cx--; delchar(); return 0; } if (cy == 0) return 0; pl = linend(cy - 1) - lptr[cy - 1]; if (pl + linend(cy) - lptr[cy] > MAXCOL) { note = "joined line would pass 80"; return 0; } delrange(lptr[cy] - 1, 1); mlmove((unsigned) &lptr[cy + 1], (unsigned) &lptr[cy], (nlines - cy - 1) * 2); nlines--; mladj((unsigned) &lptr[cy], nlines - cy, 65535); redraw = 2; cy--; cx = pl; return 0; } /* dd: yank the current line and remove it */ delline() { int i; unsigned s, e, n; s = lptr[cy]; e = linend(cy); ylen = e - s; if (ylen > MAXCOL) ylen = MAXCOL; for (i = 0; i < ylen; i++) ybuf[i] = bfr[s + i]; yok = 1; if (nlines == 1) { blen = 0; dirty = 1; } else if (cy + 1 < nlines) { n = lptr[cy + 1] - s; delrange(s, n); mlmove((unsigned) &lptr[cy + 1], (unsigned) &lptr[cy], (nlines - cy - 1) * 2); nlines--; mladj((unsigned) &lptr[cy], nlines - cy, 0 - n); } else { /* last line: take its leading $0d */ delrange(s - 1, blen - s + 1); nlines--; cy--; } cx = 0; redraw = 2; return 0; } /* p: put the yanked line below the cursor line */ paste() { int i; if (yok == 0) return 0; cx = linend(cy) - lptr[cy]; if (newline() == 0) return 0; for (i = 0; i < ylen; i++) inschar(ybuf[i]); cx = 0; return 0; } /* cursor keys, the same in both modes. 1 if k was one of them */ arrow(k) int k; { if (k == 17) { if (cy + 1 < nlines) { cy++; clampx(); } return 1; } if (k == 145) { if (cy > 0) { cy--; clampx(); } return 1; } if (k == 29) { cx++; clampx(); return 1; } if (k == 157) { if (cx > 0) cx--; return 1; } return 0; } /* write the buffer to fname, replacing any old copy. 1 on success */ savef() { char on[32]; int i, f; unsigned j; on[0] = 64; /* @ */ on[1] = 48; /* 0 */ on[2] = 58; /* : */ i = 3; j = 0; while (fname[j] && j < 20) on[i++] = fname[j++]; on[i++] = 44; /* , */ on[i++] = 83; /* S (petscii, not ascii) */ on[i++] = 44; /* , */ on[i++] = 87; /* W */ on[i] = 0; f = open(5, 8, 3, on); if (f == 0) return 0; for (j = 0; j < blen; j++) putc(bfr[j], 5); if (blen > 0) { if (bfr[blen - 1] != 13) putc(13, 5); } close(5); return 1; }