ref: 2d1dac07f7770e096d76ecbddea364ed538f0e70
parent: ebb3e31118724ff3a655815abc333992ac7287ed
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Apr 11 10:19:46 EDT 2020
triple-click to select non-whitespace segment The previous patch to plumb non-whitespace segments was confusing due to lack of visual feedback. This removes the empty selecton plumb behavior, and instead makes triple clicking work to get a plumbable selection.
--- a/sys/src/cmd/vt/main.c
+++ b/sys/src/cmd/vt/main.c
@@ -170,7 +170,7 @@
void escapedump(int,uchar *,int);
void paste(void);
void snarfsel(void);
-void plumbsel(Point);
+void plumbsel(void);
static Channel *pidchan;
@@ -982,39 +982,8 @@
free(s);
}
-/*
- * Grabs the non-whitespace text around a character
- * cell, matching the behavior in rio for plumbing.
- * Does not modify the selection.
- */
-char*
-surrounding(Point p)
-{
- int c, x0, x1;
- char *s, *e;
-
- for(x0 = p.x; x0 > 0; x0--){
- c = *onscreenr(x0 - 1, p.y);
- if(c == 0 || c == ' ' || c == '\t' || c == '\n')
- break;
- }
- for(x1 = p.x; x1 <= xmax; x1++){
- c = *onscreenr(x1, p.y);
- if(c == 0 || c == ' ' || c == '\t' || c == '\n')
- break;
- }
- if(x0 == x1)
- return nil;
- s = malloc((x1 - x0 + 1)*UTFmax);
- if(s == nil)
- return nil;
- e = selrange(s, x0, p.y, x1, p.y);
- *e = 0;
- return s;
-}
-
void
-plumbsel(Point p)
+plumbsel(void)
{
char *s, wdir[1024];
int plumb;
@@ -1021,8 +990,6 @@
s = selection();
if(s == nil || *s == 0)
- s = surrounding(p);
- if(s == nil)
return;
if(getwd(wdir, sizeof wdir) == nil){
free(s);
@@ -1061,6 +1028,13 @@
return 1;
}
+int
+isspace(Rune c)
+{
+ return c == 0 || c == ' ' || c == '\t' ||
+ c == '\n' || c == '\r' || c == '\v';
+}
+
void
unselect(void)
{
@@ -1071,11 +1045,23 @@
selrect = ZR;
}
+int
+inmode(Rune r, int mode)
+{
+ return (mode == 1) ? isalnum(r) : r && !isspace(r);
+}
+
+/*
+ * Selects different things based on mode.
+ * 0: selects swept-over text.
+ * 1: selects alphanumeric segment
+ * 2: selects non-whitespace segment.
+ */
void
-select(Point p, Point q, int line)
+select(Point p, Point q, int mode)
{
if(onscreenr(p.x, p.y) > onscreenr(q.x, q.y)){
- select(q, p, line);
+ select(q, p, mode);
return;
}
unselect();
@@ -1089,17 +1075,17 @@
q.y = ymax;
if(!blocksel) q.x = xmax+1;
}
- if(line && eqpt(p, q)){
- while(p.x > 0 && isalnum(*onscreenr(p.x-1, p.y)))
+ if(mode != 0 && eqpt(p, q)){
+ while(p.x > 0 && inmode(*onscreenr(p.x-1, p.y), mode))
p.x--;
- while(q.x <= xmax && isalnum(*onscreenr(q.x, q.y)))
+ while(q.x <= xmax && inmode(*onscreenr(q.x, q.y), mode))
q.x++;
if(p.x != q.x)
- line = 0;
+ mode = 0;
}
- if(p.x < 0 || line)
+ if(p.x < 0 || mode)
p.x = 0;
- if(q.x > xmax+1 || line)
+ if(q.x > xmax+1 || mode)
q.x = xmax+1;
selrect = Rpt(p, q);
for(; p.y <= q.y; p.y++)
@@ -1110,13 +1096,18 @@
selecting(void)
{
Point p, q;
- static ulong t;
+ static ulong t, mode;
p = pos(mc->xy);
t += mc->msec;
+ mode++;
do{
q = pos(mc->xy);
- select(p, q, t < 200);
+ if(t > 200)
+ mode = 0;
+ if(mode > 2)
+ mode = 2;
+ select(p, q, mode);
drawscreen();
readmouse(mc);
} while(button1());
@@ -1210,7 +1201,7 @@
return;
case Mplumb:
- plumbsel(p);
+ plumbsel();
return;
case Mpage: /* pause and clear at end of screen */