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.
This commit is contained in:
parent
ebb3e31118
commit
2d1dac07f7
1 changed files with 37 additions and 46 deletions
|
@ -170,7 +170,7 @@ int alnum(int);
|
||||||
void escapedump(int,uchar *,int);
|
void escapedump(int,uchar *,int);
|
||||||
void paste(void);
|
void paste(void);
|
||||||
void snarfsel(void);
|
void snarfsel(void);
|
||||||
void plumbsel(Point);
|
void plumbsel(void);
|
||||||
|
|
||||||
static Channel *pidchan;
|
static Channel *pidchan;
|
||||||
|
|
||||||
|
@ -982,47 +982,14 @@ snarfsel(void)
|
||||||
free(s);
|
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
|
void
|
||||||
plumbsel(Point p)
|
plumbsel(void)
|
||||||
{
|
{
|
||||||
char *s, wdir[1024];
|
char *s, wdir[1024];
|
||||||
int plumb;
|
int plumb;
|
||||||
|
|
||||||
s = selection();
|
s = selection();
|
||||||
if(s == nil || *s == 0)
|
if(s == nil || *s == 0)
|
||||||
s = surrounding(p);
|
|
||||||
if(s == nil)
|
|
||||||
return;
|
return;
|
||||||
if(getwd(wdir, sizeof wdir) == nil){
|
if(getwd(wdir, sizeof wdir) == nil){
|
||||||
free(s);
|
free(s);
|
||||||
|
@ -1061,6 +1028,13 @@ isalnum(Rune c)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
isspace(Rune c)
|
||||||
|
{
|
||||||
|
return c == 0 || c == ' ' || c == '\t' ||
|
||||||
|
c == '\n' || c == '\r' || c == '\v';
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
unselect(void)
|
unselect(void)
|
||||||
{
|
{
|
||||||
|
@ -1071,11 +1045,23 @@ unselect(void)
|
||||||
selrect = ZR;
|
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
|
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)){
|
if(onscreenr(p.x, p.y) > onscreenr(q.x, q.y)){
|
||||||
select(q, p, line);
|
select(q, p, mode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unselect();
|
unselect();
|
||||||
|
@ -1089,17 +1075,17 @@ select(Point p, Point q, int line)
|
||||||
q.y = ymax;
|
q.y = ymax;
|
||||||
if(!blocksel) q.x = xmax+1;
|
if(!blocksel) q.x = xmax+1;
|
||||||
}
|
}
|
||||||
if(line && eqpt(p, q)){
|
if(mode != 0 && eqpt(p, q)){
|
||||||
while(p.x > 0 && isalnum(*onscreenr(p.x-1, p.y)))
|
while(p.x > 0 && inmode(*onscreenr(p.x-1, p.y), mode))
|
||||||
p.x--;
|
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++;
|
q.x++;
|
||||||
if(p.x != q.x)
|
if(p.x != q.x)
|
||||||
line = 0;
|
mode = 0;
|
||||||
}
|
}
|
||||||
if(p.x < 0 || line)
|
if(p.x < 0 || mode)
|
||||||
p.x = 0;
|
p.x = 0;
|
||||||
if(q.x > xmax+1 || line)
|
if(q.x > xmax+1 || mode)
|
||||||
q.x = xmax+1;
|
q.x = xmax+1;
|
||||||
selrect = Rpt(p, q);
|
selrect = Rpt(p, q);
|
||||||
for(; p.y <= q.y; p.y++)
|
for(; p.y <= q.y; p.y++)
|
||||||
|
@ -1110,13 +1096,18 @@ void
|
||||||
selecting(void)
|
selecting(void)
|
||||||
{
|
{
|
||||||
Point p, q;
|
Point p, q;
|
||||||
static ulong t;
|
static ulong t, mode;
|
||||||
|
|
||||||
p = pos(mc->xy);
|
p = pos(mc->xy);
|
||||||
t += mc->msec;
|
t += mc->msec;
|
||||||
|
mode++;
|
||||||
do{
|
do{
|
||||||
q = pos(mc->xy);
|
q = pos(mc->xy);
|
||||||
select(p, q, t < 200);
|
if(t > 200)
|
||||||
|
mode = 0;
|
||||||
|
if(mode > 2)
|
||||||
|
mode = 2;
|
||||||
|
select(p, q, mode);
|
||||||
drawscreen();
|
drawscreen();
|
||||||
readmouse(mc);
|
readmouse(mc);
|
||||||
} while(button1());
|
} while(button1());
|
||||||
|
@ -1210,7 +1201,7 @@ readmenu(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case Mplumb:
|
case Mplumb:
|
||||||
plumbsel(p);
|
plumbsel();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case Mpage: /* pause and clear at end of screen */
|
case Mpage: /* pause and clear at end of screen */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue