git: plan9front

Download patch

ref: dd43db468a79e285d5763b7efd156f33fd27fa80
parent: 3f98f75d92d7dc5a68c22ffb3a291ca3798c1cbf
author: Aidan K. Wiggins <akw@oneiri.one>
date: Fri Sep 12 00:12:55 EDT 2025

samterm: add scroll-select

--- a/sys/src/cmd/samterm/flayer.c
+++ b/sys/src/cmd/samterm/flayer.c
@@ -23,6 +23,8 @@
 Image	*maincols[NCOL];
 Image	*cmdcols[NCOL];
 
+int	sel;
+
 void
 flstart(Rectangle r)
 {
@@ -78,6 +80,7 @@
 	l->visible = All;
 	l->origin = l->p0 = l->p1 = 0;
 	frinit(&l->f, insetrect(flrect(l, r), FLMARGIN), ft, screen, cols);
+	l->f.scroll = frscroll;
 	l->f.maxtab = maxtab*stringwidth(ft, "0");
 	newvisibilities(1);
 	draw(screen, l->entire, l->f.cols[BACK], nil, ZP);
@@ -261,7 +264,7 @@
 	dt = mousep->msec - l->click;
 	dx = abs(mousep->xy.x - clickpt.x);
 	dy = abs(mousep->xy.y - clickpt.y);
-	*p = frcharofpt(&l->f, mousep->xy) + l->origin;
+	*p = sel = frcharofpt(&l->f, mousep->xy) + l->origin;
 
 	l->click = mousep->msec;
 	clickpt = mousep->xy;
@@ -271,8 +274,8 @@
 	clickcount = 0;
 
 	frselect(&l->f, mousectl);
-	l->p0 = l->f.p0+l->origin;
-	l->p1 = l->f.p1+l->origin;
+	l->p0 = sel < l->origin? sel: l->origin + l->f.p0;
+	l->p1 = sel > l->origin+l->f.nchars? sel: l->origin + l->f.p1;
 	return 0;
 }
 
--- a/sys/src/cmd/samterm/flayer.h
+++ b/sys/src/cmd/samterm/flayer.h
@@ -48,3 +48,5 @@
 
 extern	Image	*maincols[NCOL];
 extern	Image	*cmdcols[NCOL];
+
+extern	int	sel;
--- a/sys/src/cmd/samterm/io.c
+++ b/sys/src/cmd/samterm/io.c
@@ -177,6 +177,52 @@
 	return (char*)hostp;
 }
 
+void
+frscroll(Frame *f, int n)
+{
+	Flayer *l = which;
+	Text *t = l->user1;
+	long p;
+
+	if(nbrecv(mousectl->c, &mousectl->Mouse) < 0)
+		panic("mouse");
+
+	if(n < 0){
+		if(sel > l->origin+f->p0){
+			l->p0 = l->origin+f->p0;
+			l->p1 = sel;
+		}else{
+			l->p0 = sel;
+			l->p1 = l->origin+f->p0;
+		}
+		scrorigin(l, 1, -n+1);
+	}else if(n == 0){
+		sleep(25);
+		return;
+	}else{
+		if(sel >= l->origin+f->p1){
+			l->p0 = l->origin+f->p1;
+			l->p1 = sel;
+		}else{
+			l->p0 = sel;
+			l->p1 = l->origin+f->p1;
+		}
+		p = l->origin;
+		if(l->origin+f->nchars != t->rasp.nrunes)
+			p += frcharofpt(f, Pt(l->scroll.max.x, l->scroll.min.y + n * f->font->height));
+		scrorigin(l, 2, p);
+	}
+
+	/*
+	 * we must pull io from host while we are in frame(2)
+	 */
+	do{
+		block = ~(1 << RHost);
+		waitforio();
+		rcv();
+	}while(t->lock);
+}
+
 int
 getch(void)
 {
--- a/sys/src/cmd/samterm/main.c
+++ b/sys/src/cmd/samterm/main.c
@@ -106,8 +106,8 @@
 					scroll(which, (mousep->buttons&8) ? 4 : 1);
 				else if(nwhich && nwhich!=which)
 					current(nwhich);
-				else{
-					t=(Text *)which->user1;
+				else if(ptinrect(mousep->xy, which->f.r)){
+					t = which->user1;
 					nclick = flselect(which, &p);
 					if(nclick > 0){
 						if(nclick > 1)
--- a/sys/src/cmd/samterm/mesg.c
+++ b/sys/src/cmd/samterm/mesg.c
@@ -620,6 +620,7 @@
 			t->lock++;	/* for the Trequest */
 			t->lock++;	/* for the Tcheck */
 			reqd++;
+			continue;
 		}
 	    Checksel:
 		flsetselect(l, l->p0, l->p1);
--- a/sys/src/cmd/samterm/samterm.h
+++ b/sys/src/cmd/samterm/samterm.h
@@ -109,6 +109,7 @@
 int	load(char*, int);
 int	waitforio(void);
 int	rcvchar(void);
+void	frscroll(Frame*, int);
 int	getch(void);
 int	kbdchar(void);
 int	qpeekc(void);
--