ref: b2aa6ca19cc28e5e0f9811b3692cd556159b8c6e
parent: bb8274cffd9f0754e871812118df2e94bedc1ce3
author: qwx <qwx@sciops.net>
date: Thu Nov 17 07:21:43 EST 2022
fully functional cut/copy/paste, minus graphics glitch
--- a/cmd.c
+++ b/cmd.c
@@ -157,40 +157,46 @@
return 0;
}
-/* does not modify dot range; merges range then splits
- * at left and right offset */
static void
-split(void)
+splitright(Chunk *c, usize off)
{
- usize n, p, Δ;
- Chunk *c, *from, *to, *tc;
+ usize Δ;
+ Chunk *nc;
- from = p2c(dot.pos, &p);
- to = p2c(dot.to.pos, nil);
- if(from != to){
- for(p=dot.pos; p<dot.to.pos; p+=n){
- tc = from->right;
- assert(tc != &norris);
- n = tc->bufsz;
- from = merge(from, tc);
- }
- }
- if(p < dot.from.pos){
- Δ = dot.from.pos - p;
- c = newchunk(Δ);
- memcpy(c->buf, from->buf, Δ);
- linkchunk(from->left, c);
- }
- tc = p2c(dot.to.pos, &p);
- p += tc->bufsz;
- if(dot.to.pos < p){
- Δ = p - dot.to.pos;
- c = newchunk(Δ);
- memcpy(c->buf, tc->buf + dot.to.pos, Δ);
- linkchunk(from, c);
- }
+ Δ = c->bufsz - off;
+ nc = newchunk(Δ);
+ memcpy(nc->buf, c->buf+off, Δ);
+ linkchunk(c, nc);
+ c->buf = erealloc(c->buf, off, c->bufsz);
+ c->bufsz = off;
}
+static Chunk *
+mergedot(usize *off)
+{
+ usize p;
+ Chunk *c;
+
+ c = p2c(dot.from.pos, &p);
+ *off = p;
+ p = dot.from.pos - p;
+ while(p + c->bufsz < dot.to.pos)
+ merge(c, c->right);
+ return c;
+}
+
+/* before one may split oneself, one must first merge oneself */
+static void
+splitdot(void)
+{
+ usize p;
+ Chunk *c;
+
+ c = mergedot(&p);
+ splitright(c, p + dot.to.pos - dot.from.pos);
+ splitright(c, p);
+}
+
uchar *
getbuf(Dot d, usize n, uchar *scratch, usize *boff)
{
@@ -288,7 +294,7 @@
static int
copy(char *)
{
- split();
+ splitdot();
holdchunk(0);
return 0;
}
@@ -296,12 +302,21 @@
static int
cut(char *)
{
- split();
+ splitdot();
totalsz -= p2c(dot.pos, nil)->bufsz;
holdchunk(1);
return 0;
}
+static int
+forcemerge(char *)
+{
+ usize p;
+
+ mergedot(&p);
+ return 0;
+}
+
static Chunk *
readintochunks(int fd)
{
@@ -410,11 +425,11 @@
s += chartorune(&r, s);
for(;;){
n = chartorune(&r´, s);
- if(r´ == Runeerror || r´ == 0){
- werrstr("truncated or malformed input");
+ if(r´ == Runeerror){
+ werrstr("malformed input");
return -1;
}
- if(r´ != ' ' && r´ != '\t')
+ if(r´ == 0 || r´ != ' ' && r´ != '\t')
break;
s += n;
}
@@ -422,8 +437,9 @@
// case '<': return pipefrom(s);
// case '^': return exchange(s);
case '|': return pipeto(s);
-// case 'c': return copy(s);
-// case 'd': return cut(s);
+ case 'c': return copy(s);
+ case 'd': return cut(s);
+ case 'm': return forcemerge(s);
// case 'p': return paste(s);
// case 'r': return readfrom(s);
case 'w': return writeto(s);