ref: 57fb3f340445e45af9e1e59323b1ee2e2fd30f1e
parent: 5a42de478eb1573244d39ac9a4d0542c7975d39c
author: qwx <qwx@sciops.net>
date: Sun Nov 20 09:22:41 EST 2022
experimental crop command
--- a/cmd.c
+++ b/cmd.c
@@ -14,6 +14,18 @@
static int cutheld;
static int epfd[2];
+static void
+printchunks(void)
+{
+ Chunk *c;
+
+ fprint(2, "chunklist dot %zux %zux %zux: ",
+ dot.from.pos, dot.pos, dot.to.pos);
+ for(c=norris.right; c!=&norris; c=c->right)
+ fprint(2, "%#p:%zux ", c, c->bufsz);
+ fprint(2, "\n");
+}
+
static Chunk *
newchunk(usize n)
{
@@ -186,7 +198,7 @@
}
/* before one may split oneself, one must first merge oneself */
-static void
+static Chunk *
splitdot(void)
{
usize p;
@@ -195,6 +207,7 @@
c = mergedot(&p);
splitright(c, p + dot.to.pos - dot.from.pos);
splitright(c, p);
+ return c;
}
uchar *
@@ -302,13 +315,62 @@
static int
cut(char *)
{
- splitdot();
- totalsz -= p2c(dot.pos, nil)->bufsz;
+ Chunk *c;
+
+ c = splitdot();
+ totalsz -= c->bufsz;
holdchunk(1);
return 1;
}
static int
+crop(char *)
+{
+ usize Δ;
+ Chunk *c, *d;
+
+ Δ = 0;
+ printchunks();
+ for(c=norris.right; c!=&norris; c=d){
+ if(Δ + c->bufsz >= dot.from.pos)
+ break;
+ d = c->right;
+ Δ += c->bufsz;
+ unlinkchunk(c);
+ freechunk(c);
+ }
+ dot.from.pos -= Δ;
+ dot.to.pos -= Δ;
+ totalsz -= Δ;
+ if(dot.from.pos > 0){
+ Δ = c->bufsz - dot.from.pos;
+ memmove(c->buf, c->buf + dot.from.pos, Δ);
+ erealloc(c->buf, Δ, c->bufsz);
+ c->bufsz = Δ;
+ dot.to.pos -= dot.from.pos;
+ totalsz -= dot.from.pos;
+ dot.from.pos = 0;
+ }
+ for(Δ=0; c!=&norris; Δ+=c->bufsz, c=c->right)
+ if(Δ + c->bufsz >= dot.to.pos)
+ break;
+ if(dot.to.pos > 0){
+ totalsz -= c->bufsz - dot.to.pos;
+ erealloc(c->buf, dot.to.pos, c->bufsz);
+ c->bufsz = dot.to.pos;
+ }
+ for(c=c->right; c!=&norris; c=d){
+ d = c->right;
+ totalsz -= c->bufsz;
+ unlinkchunk(c);
+ freechunk(c);
+ }
+ dot.pos = 0;
+ dot.to.pos = totalsz;
+ return 1;
+}
+
+static int
forcemerge(char *)
{
usize p;
@@ -443,7 +505,7 @@
case 'p': return paste(s);
// case 'r': return readfrom(s);
case 'w': return writeto(s);
-// case 'x': return crop(s);
+ case 'x': return crop(s);
default: werrstr("unknown command %C", r); break;
}
return -1;