/* 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; /* 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; { unsigned i; if (blen >= 18999) return 0; for (i = blen; i > pos; i--) bfr[i] = bfr[i - 1]; bfr[pos] = ch; blen++; dirty = 1; return 1; } /* remove n bytes at offset pos */ delrange(pos, n) unsigned pos, n; { unsigned i; for (i = pos; i + n < blen; i++) bfr[i] = bfr[i + n]; blen = blen - n; dirty = 1; return 0; } /* type one character at the cursor */ inschar(ch) int ch; { int l; if (bins(lptr[cy] + cx, ch) == 0) return 0; for (l = cy + 1; l < nlines; l++) lptr[l]++; cx++; return 1; } /* split the line at the cursor */ newline() { int l; unsigned pos; if (nlines >= 599) return 0; pos = lptr[cy] + cx; if (bins(pos, 13) == 0) return 0; for (l = nlines; l > cy + 1; l--) lptr[l] = lptr[l - 1]; lptr[cy + 1] = pos + 1; nlines++; for (l = cy + 2; l < nlines; l++) lptr[l]++; cy++; cx = 0; return 1; } /* delete the character under the cursor */ delchar() { int l; if (cx >= linend(cy) - lptr[cy]) return 0; delrange(lptr[cy] + cx, 1); for (l = cy + 1; l < nlines; l++) lptr[l]--; return 1; } /* backspace: delete before the cursor, or join onto the previous line */ bkspace() { int l, pl; if (cx > 0) { cx--; delchar(); return 0; } if (cy == 0) return 0; pl = linend(cy - 1) - lptr[cy - 1]; delrange(lptr[cy] - 1, 1); for (l = cy; l < nlines - 1; l++) lptr[l] = lptr[l + 1]; nlines--; for (l = cy; l < nlines; l++) lptr[l]--; cy--; cx = pl; return 0; } /* dd: yank the current line and remove it */ delline() { int l, i; unsigned s, e, n; s = lptr[cy]; e = linend(cy); ylen = e - s; if (ylen > 159) ylen = 159; 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); for (l = cy; l < nlines - 1; l++) lptr[l] = lptr[l + 1]; nlines--; for (l = cy; l < nlines; l++) lptr[l] -= n; } else { /* last line: take its leading $0d */ delrange(s - 1, blen - s + 1); nlines--; cy--; } cx = 0; 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; }