9front - general discussion about 9front
 help / color / mirror / Atom feed
* [9front] delete in page(1)
@ 2021-12-30 23:15 qwx
  2021-12-31  0:48 ` umbraticus
  0 siblings, 1 reply; 9+ messages in thread
From: qwx @ 2021-12-30 23:15 UTC (permalink / raw)
  To: 9front

Hi,

I wrote a patch allowing one to remove(2) the current file
directly from page(1) with the `d' key.  I've needed this
for instance for pruning image albums, especially with
shuffled lists, etc.  I've tried other strategies instead
of adding this, but they all sucked.

I don't know if anyone wants this merged since it doesn't
seem like something people do much, but in any case here
it is.  Thoughts and comments appreciated as always.

Prost,
qwx


diff 855cf4326f5a07d7142c2d8918f5fa856d912b85 uncommitted
--- a//sys/src/cmd/page.c
+++ b//sys/src/cmd/page.c
@@ -74,6 +74,7 @@
 	Czerox,
 	Cwrite,
 	Cext,
+	Cdel,
 	Cdummy2,
 	Cquit,
 };
@@ -98,6 +99,7 @@
 	[Czerox]	"zerox",	'z', 0, 0,
 	[Cwrite]	"write",	'w', 0, 0,
 	[Cext]		"ext",		'x', 0, 0,
+	[Cdel]		"del",		'd', 0, 0,
 	[Cdummy2]	"",		0, 0, 0,
 	[Cquit]		"quit",		'q', Kdel, Keof,
 };
@@ -134,6 +136,7 @@
 void showpage(Page *);
 void drawpage(Page *);
 Point pagesize(Page *);
+void drawlock(int);
 
 Page*
 addpage(Page *up, char *name, int (*popen)(Page *), void *pdata, int fd)
@@ -986,6 +989,54 @@
 	}
 }
 
+/* page entries are never freed, there's no point
+ * and would break everything */
+Page*
+delpage(Page *p)
+{
+	Page *t, *q;
+
+	if(p == nil)
+		return nil;
+	/* to remove(2) subpages in documents makes no sense, and just
+	 * removing a subentry doesn't seem like a feature worth the bother */
+	if(p->up != root)
+		return p;
+	if(p->fd >= 0)
+		close(p->fd);
+	p->fd = -1;
+	if(remove(p->name) < 0){
+		fprint(2, "remove %s: %r", p->name);
+		return p;
+	}
+	qlock(&pagelock);
+	for(t = p->down; t != nil && t->up != root; t = q){
+		qlock(t);
+		drawlock(0);
+		unloadpage(t);
+		drawlock(1);
+		free(t->name);
+		free(t->data);
+		t->name = t->data = nil;
+		q = nextpage(t);
+		qunlock(t);
+	}
+	drawlock(0);
+	unloadpage(p);
+	drawlock(1);
+	free(p->name);
+	free(p->data);
+	p->name = p->data = nil;
+	if(root->down != p){
+		t = prevpage(p);
+		t->next = p->next;
+	}else
+		root->down = p->next;
+	qunlock(&pagelock);
+	qunlock(p);
+	return p->next != nil ? p->next : t;
+}
+
 /*
  * A draw operation that touches only the area contained in bot but not in top.
  * mp and sp get aligned with bot.min.
@@ -1461,6 +1512,7 @@
 	char buf[NPATH], *s;
 	Point o;
 	int fd;
+	Page *p;
 
 	switch(i){
 	case Corigsize:
@@ -1545,6 +1597,17 @@
 		break;
 	case Csnarf:
 		writeaddr(current, "/dev/snarf");
+		break;
+	case Cdel:
+		if(current == nil || !canqlock(current))
+			break;
+		if((p = delpage(current)) == current)
+			break;
+		current = p;
+		if(current == nil)
+			break;
+		forward = 1;
+		showpage(current);
 		break;
 	case Cnext:
 		forward = 1;

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [9front] delete in page(1)
  2021-12-30 23:15 [9front] delete in page(1) qwx
@ 2021-12-31  0:48 ` umbraticus
  2021-12-31  1:09   ` qwx
  2021-12-31  1:22   ` qwx
  0 siblings, 2 replies; 9+ messages in thread
From: umbraticus @ 2021-12-31  0:48 UTC (permalink / raw)
  To: 9front

Well, that was a good lesson in reading first!
Dump to the rescue...
So the feature I assumed this added was just
removing images from the list, which could
be handy since I usually have a persistent
page catching everything plumbed its way.
I may help myself to just that part of the patch...

Anyway, can confirm it does what it says :)
Removing the last item in the list did seem
to break the b3 menu tho...

umbraticus

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [9front] delete in page(1)
  2021-12-31  0:48 ` umbraticus
@ 2021-12-31  1:09   ` qwx
  2021-12-31  1:22   ` qwx
  1 sibling, 0 replies; 9+ messages in thread
From: qwx @ 2021-12-31  1:09 UTC (permalink / raw)
  To: 9front

On Fri Dec 31 02:59:46 +0200 2021, umbraticus@prosimetrum.com wrote:
> Well, that was a good lesson in reading first!
> Dump to the rescue...
> So the feature I assumed this added was just
> removing images from the list, which could
> be handy since I usually have a persistent
> page catching everything plumbed its way.
> I may help myself to just that part of the patch...

Ouch, might not have explained it clearly enough!  That's
easy to do, you could have both since the only part that
changes is basically the remove(2) call.


> Anyway, can confirm it does what it says :)
> Removing the last item in the list did seem
> to break the b3 menu tho...

Ah, that works fine for me.  I'll have to test it some
more then.  Thanks!

qwx

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [9front] delete in page(1)
  2021-12-31  0:48 ` umbraticus
  2021-12-31  1:09   ` qwx
@ 2021-12-31  1:22   ` qwx
  2021-12-31  2:05     ` umbraticus
  1 sibling, 1 reply; 9+ messages in thread
From: qwx @ 2021-12-31  1:22 UTC (permalink / raw)
  To: 9front

diff 855cf4326f5a07d7142c2d8918f5fa856d912b85 uncommitted
--- a//sys/src/cmd/page.c
+++ b//sys/src/cmd/page.c
@@ -74,6 +74,7 @@
 	Czerox,
 	Cwrite,
 	Cext,
+	Cdel,
 	Cdummy2,
 	Cquit,
 };
@@ -98,6 +99,7 @@
 	[Czerox]	"zerox",	'z', 0, 0,
 	[Cwrite]	"write",	'w', 0, 0,
 	[Cext]		"ext",		'x', 0, 0,
+	[Cdel]		"del",		'd', 0, 0,
 	[Cdummy2]	"",		0, 0, 0,
 	[Cquit]		"quit",		'q', Kdel, Keof,
 };
@@ -134,6 +136,7 @@
 void showpage(Page *);
 void drawpage(Page *);
 Point pagesize(Page *);
+void drawlock(int);
 
 Page*
 addpage(Page *up, char *name, int (*popen)(Page *), void *pdata, int fd)
@@ -986,6 +989,54 @@
 	}
 }
 
+/* page entries are never freed, there's no point
+ * and would break everything */
+Page*
+delpage(Page *p)
+{
+	Page *t, *q;
+
+	if(p == nil)
+		return nil;
+	/* to remove(2) subpages in documents makes no sense, and just
+	 * removing a subentry doesn't seem like a feature worth the bother */
+	if(p->up != root)
+		return p;
+	if(p->fd >= 0)
+		close(p->fd);
+	p->fd = -1;
+	if(remove(p->name) < 0){
+		fprint(2, "remove %s: %r", p->name);
+		return p;
+	}
+	qlock(&pagelock);
+	for(t = p->down; t != nil && t->up != root; t = q){
+		qlock(t);
+		drawlock(0);
+		unloadpage(t);
+		drawlock(1);
+		free(t->name);
+		free(t->data);
+		t->name = t->data = nil;
+		q = nextpage(t);
+		qunlock(t);
+	}
+	drawlock(0);
+	unloadpage(p);
+	drawlock(1);
+	free(p->name);
+	free(p->data);
+	p->name = p->data = nil;
+	if(root->down != p){
+		t = prevpage(p);
+		t->next = p->next;
+	}else
+		root->down = p->next;
+	qunlock(&pagelock);
+	qunlock(p);
+	return p->next != nil ? p->next : t;
+}
+
 /*
  * A draw operation that touches only the area contained in bot but not in top.
  * mp and sp get aligned with bot.min.
@@ -1461,6 +1512,7 @@
 	char buf[NPATH], *s;
 	Point o;
 	int fd;
+	Page *p;
 
 	switch(i){
 	case Corigsize:
@@ -1545,6 +1597,19 @@
 		break;
 	case Csnarf:
 		writeaddr(current, "/dev/snarf");
+		break;
+	case Cdel:
+		if(current == nil || !canqlock(current))
+			break;
+		if((p = delpage(current)) == current){
+			qunlock(current);
+			break;
+		}
+		current = p;
+		if(current == nil)
+			break;
+		forward = 1;
+		showpage(current);
 		break;
 	case Cnext:
 		forward = 1;

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [9front] delete in page(1)
  2021-12-31  1:22   ` qwx
@ 2021-12-31  2:05     ` umbraticus
  2021-12-31 19:10       ` qwx
  0 siblings, 1 reply; 9+ messages in thread
From: umbraticus @ 2021-12-31  2:05 UTC (permalink / raw)
  To: 9front

hmm, still messes up. what I am doing:
1. plumb 1.jpg, opens in new page
2. press d
3. plumb 2.jpg → shows image

can continue to plumb new images but b3menu doesn't open
and prev/next doesn't work.

Also, maybe at least have the key be D instead of d to prevent mistakes...

umbraticus

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [9front] delete in page(1)
  2021-12-31  2:05     ` umbraticus
@ 2021-12-31 19:10       ` qwx
  2022-01-01 10:42         ` umbraticus
  0 siblings, 1 reply; 9+ messages in thread
From: qwx @ 2021-12-31 19:10 UTC (permalink / raw)
  To: 9front

On Fri Dec 31 04:16:49 +0200 2021, umbraticus@prosimetrum.com wrote:
> hmm, still messes up. what I am doing:
> 1. plumb 1.jpg, opens in new page
> 2. press d
> 3. plumb 2.jpg → shows image
> 
> can continue to plumb new images but b3menu doesn't open
> and prev/next doesn't work.
> 
> Also, maybe at least have the key be D instead of d to prevent mistakes...
> 
> umbraticus

Here's a patched patch fixing this and another issue;  it
also has the delete command on the `D' key as suggested and
has a separate `pop' command on the `p' key to only remove
an entry from the list, without deleting the file.  Thoughts?

Thanks,
qwx


diff 855cf4326f5a07d7142c2d8918f5fa856d912b85 uncommitted
--- a/sys/src/cmd/page.c
+++ b/sys/src/cmd/page.c
@@ -74,7 +74,10 @@
 	Czerox,
 	Cwrite,
 	Cext,
+	Cpop,
 	Cdummy2,
+	Cdelete,
+	Cdummy3,
 	Cquit,
 };
 
@@ -98,7 +101,10 @@
 	[Czerox]	"zerox",	'z', 0, 0,
 	[Cwrite]	"write",	'w', 0, 0,
 	[Cext]		"ext",		'x', 0, 0,
+	[Cpop]		"pop",		'p', 0, 0,
 	[Cdummy2]	"",		0, 0, 0,
+	[Cdelete]	"delete",	'D', 0, 0,
+	[Cdummy3]	"",		0, 0, 0,
 	[Cquit]		"quit",		'q', Kdel, Keof,
 };
 
@@ -134,6 +140,7 @@
 void showpage(Page *);
 void drawpage(Page *);
 Point pagesize(Page *);
+void drawlock(int);
 
 Page*
 addpage(Page *up, char *name, int (*popen)(Page *), void *pdata, int fd)
@@ -986,6 +993,71 @@
 	}
 }
 
+/* page entries are never freed, there's no point
+ * and would break everything */
+Page*
+poppage(Page *p)
+{
+	Page *t, *q;
+
+	if(p == nil)
+		return nil;
+	if(p->up != root)
+		return p;
+	qlock(&pagelock);
+	for(t = p->down; t != nil && t->up != root; t = q){
+		qlock(t);
+		drawlock(0);
+		unloadpage(t);
+		drawlock(1);
+		free(t->name);
+		free(t->data);
+		t->name = t->data = nil;
+		q = nextpage(t);
+		qunlock(t);
+	}
+	drawlock(0);
+	unloadpage(p);
+	drawlock(1);
+	free(p->name);
+	free(p->data);
+	p->name = p->data = nil;
+	t = prevpage(p);
+	if(root->tail == p)
+		root->tail = t;
+	if(root->down == p || t == nil)
+		root->down = p->next;
+	else
+		t->next = p->next;
+	qunlock(&pagelock);
+	qunlock(p);
+	if(p->next != nil){
+		forward = 1;
+		return p->next;
+	}
+	forward = -1;
+	return t;
+}
+
+Page*
+delpage(Page *p)
+{
+	if(p == nil)
+		return nil;
+	/* to remove(2) subpages in documents makes no sense, and just
+	 * removing a subentry doesn't seem like a feature worth the bother */
+	if(p->up != root)
+		return p;
+	if(p->fd >= 0)
+		close(p->fd);
+	p->fd = -1;
+	if(remove(p->name) < 0){
+		fprint(2, "remove %s: %r", p->name);
+		return p;
+	}
+	return poppage(p);
+}
+
 /*
  * A draw operation that touches only the area contained in bot but not in top.
  * mp and sp get aligned with bot.min.
@@ -1461,6 +1533,7 @@
 	char buf[NPATH], *s;
 	Point o;
 	int fd;
+	Page *p;
 
 	switch(i){
 	case Corigsize:
@@ -1546,6 +1619,28 @@
 	case Csnarf:
 		writeaddr(current, "/dev/snarf");
 		break;
+	case Cpop:
+		if(current == nil || !canqlock(current))
+			break;
+		if((p = poppage(current)) == current)
+			break;
+	Reset:
+		current = p;
+		if(current == nil){
+			drawlock(0);
+			draw(screen, screen->r, paper, nil, ZP);
+			drawframe(screen->r);
+			drawlock(1);
+			break;
+		}
+		showpage(current);
+		break;
+	case Cdelete:
+		if(current == nil || !canqlock(current))
+			break;
+		if((p = delpage(current)) == current)
+			break;
+		goto Reset;
 	case Cnext:
 		forward = 1;
 		showpage(nextpage(current));

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [9front] delete in page(1)
  2021-12-31 19:10       ` qwx
@ 2022-01-01 10:42         ` umbraticus
  2022-01-02  0:20           ` qwx
  0 siblings, 1 reply; 9+ messages in thread
From: umbraticus @ 2022-01-01 10:42 UTC (permalink / raw)
  To: 9front

Nice work, thanks! I like the isolation in the menu too.

I found another nit :)

Popping a doc eg. /sys/doc/troff.ps works fine
if you are at the root window of the document
(the grey one with name of the file in a box)
and popping from within the doc doesn't work,
which is fine if that's how you want it to behave
but if I open the doc, try to pop from eg. page 3,
then go back to the root and try to pop from
there things hang...

umbraticus

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [9front] delete in page(1)
  2022-01-01 10:42         ` umbraticus
@ 2022-01-02  0:20           ` qwx
  2022-01-02  1:19             ` umbraticus
  0 siblings, 1 reply; 9+ messages in thread
From: qwx @ 2022-01-02  0:20 UTC (permalink / raw)
  To: 9front

On Sat Jan  1 12:50:01 +0200 2022, umbraticus@prosimetrum.com wrote:
> Nice work, thanks! I like the isolation in the menu too.
> 
> I found another nit :)
> 
> Popping a doc eg. /sys/doc/troff.ps works fine
> if you are at the root window of the document
> (the grey one with name of the file in a box)
> and popping from within the doc doesn't work,
> which is fine if that's how you want it to behave
> but if I open the doc, try to pop from eg. page 3,
> then go back to the root and try to pop from
> there things hang...
> 
> umbraticus

Thanks for testing!  Just another locking fuckup,
a bit of a nightmare.

qwx


diff c4e30bede2f79c42dacb8c91713abf4a4d91c45c uncommitted
--- a//sys/src/cmd/page.c
+++ b//sys/src/cmd/page.c
@@ -74,7 +74,10 @@
 	Czerox,
 	Cwrite,
 	Cext,
+	Cpop,
 	Cdummy2,
+	Cdelete,
+	Cdummy3,
 	Cquit,
 };
 
@@ -98,7 +101,10 @@
 	[Czerox]	"zerox",	'z', 0, 0,
 	[Cwrite]	"write",	'w', 0, 0,
 	[Cext]		"ext",		'x', 0, 0,
+	[Cpop]		"pop",		'p', 0, 0,
 	[Cdummy2]	"",		0, 0, 0,
+	[Cdelete]	"delete",	'D', 0, 0,
+	[Cdummy3]	"",		0, 0, 0,
 	[Cquit]		"quit",		'q', Kdel, Keof,
 };
 
@@ -134,6 +140,7 @@
 void showpage(Page *);
 void drawpage(Page *);
 Point pagesize(Page *);
+void drawlock(int);
 
 Page*
 addpage(Page *up, char *name, int (*popen)(Page *), void *pdata, int fd)
@@ -986,6 +993,71 @@
 	}
 }
 
+/* page entries are never freed, there's no point
+ * and would break everything */
+Page*
+poppage(Page *p)
+{
+	Page *t, *q;
+
+	if(p == nil)
+		return nil;
+	if(p->up != root)
+		return p;
+	qlock(&pagelock);
+	for(t = p->down; t != nil && t->up != root; t = q){
+		qlock(t);
+		drawlock(0);
+		unloadpage(t);
+		drawlock(1);
+		free(t->name);
+		free(t->data);
+		t->name = t->data = nil;
+		q = nextpage(t);
+		qunlock(t);
+	}
+	drawlock(0);
+	unloadpage(p);
+	drawlock(1);
+	free(p->name);
+	free(p->data);
+	p->name = p->data = nil;
+	t = prevpage(p);
+	if(root->tail == p)
+		root->tail = t;
+	if(root->down == p || t == nil)
+		root->down = p->next;
+	else
+		t->next = p->next;
+	qunlock(&pagelock);
+	qunlock(p);
+	if(p->next != nil){
+		forward = 1;
+		return p->next;
+	}
+	forward = -1;
+	return t;
+}
+
+Page*
+delpage(Page *p)
+{
+	if(p == nil)
+		return nil;
+	/* to remove(2) subpages in documents makes no sense, and just
+	 * removing a subentry doesn't seem like a feature worth the bother */
+	if(p->up != root)
+		return p;
+	if(p->fd >= 0)
+		close(p->fd);
+	p->fd = -1;
+	if(remove(p->name) < 0){
+		fprint(2, "remove %s: %r", p->name);
+		return p;
+	}
+	return poppage(p);
+}
+
 /*
  * A draw operation that touches only the area contained in bot but not in top.
  * mp and sp get aligned with bot.min.
@@ -1461,6 +1533,7 @@
 	char buf[NPATH], *s;
 	Point o;
 	int fd;
+	Page *p;
 
 	switch(i){
 	case Corigsize:
@@ -1546,6 +1619,32 @@
 	case Csnarf:
 		writeaddr(current, "/dev/snarf");
 		break;
+	case Cpop:
+		if(current == nil || !canqlock(current))
+			break;
+		if((p = poppage(current)) == current){
+			qunlock(current);
+			break;
+		}
+	Reset:
+		current = p;
+		if(current == nil){
+			drawlock(0);
+			draw(screen, screen->r, paper, nil, ZP);
+			drawframe(screen->r);
+			drawlock(1);
+			break;
+		}
+		showpage(current);
+		break;
+	case Cdelete:
+		if(current == nil || !canqlock(current))
+			break;
+		if((p = delpage(current)) == current){
+			qunlock(current);
+			break;
+		}
+		goto Reset;
 	case Cnext:
 		forward = 1;
 		showpage(nextpage(current));

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [9front] delete in page(1)
  2022-01-02  0:20           ` qwx
@ 2022-01-02  1:19             ` umbraticus
  0 siblings, 0 replies; 9+ messages in thread
From: umbraticus @ 2022-01-02  1:19 UTC (permalink / raw)
  To: 9front

works great now; pretty sure I'm done kicking the tyres.
thanks!

umbraticus

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-01-02  1:29 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-30 23:15 [9front] delete in page(1) qwx
2021-12-31  0:48 ` umbraticus
2021-12-31  1:09   ` qwx
2021-12-31  1:22   ` qwx
2021-12-31  2:05     ` umbraticus
2021-12-31 19:10       ` qwx
2022-01-01 10:42         ` umbraticus
2022-01-02  0:20           ` qwx
2022-01-02  1:19             ` umbraticus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).