vt: fix selection past baseline (thanks BurnZeZ)

This commit is contained in:
cinap_lenrek 2018-09-04 20:55:10 +02:00
parent 217e8a0619
commit 2e9835e771

View file

@ -162,7 +162,7 @@ void waitio(void);
int rcvchar(void); int rcvchar(void);
void bigscroll(void); void bigscroll(void);
void readmenu(void); void readmenu(void);
void selection(void); void selecting(void);
int selected(int, int); int selected(int, int);
void resized(void); void resized(void);
void drawcursor(void); void drawcursor(void);
@ -810,7 +810,7 @@ Next:
switch(alt(a)){ switch(alt(a)){
case AMOUSE: case AMOUSE:
if(button1()) if(button1())
selection(); selecting();
else if(button2() || button3()) else if(button2() || button3())
readmenu(); readmenu();
else if(resize_flag == 0) else if(resize_flag == 0)
@ -912,8 +912,8 @@ resized(void)
werrstr(""); /* clear spurious error messages */ werrstr(""); /* clear spurious error messages */
} }
Rune * char*
selrange(Rune *r, int x0, int y0, int x1, int y1) selrange(char *d, int x0, int y0, int x1, int y1)
{ {
Rune *s, *e; Rune *s, *e;
int z, p; int z, p;
@ -925,72 +925,63 @@ selrange(Rune *r, int x0, int y0, int x1, int y1)
if(*s == '\n') if(*s == '\n')
z = p = 0; z = p = 0;
else if(p++ == 0){ else if(p++ == 0){
while(z-- > 0) *r++ = ' '; while(z-- > 0) *d++ = ' ';
} }
*r++ = *s; d += runetochar(d, s);
} else { } else {
z++; z++;
} }
} }
*r = 0; return d;
return r;
} }
Rune* char*
selrunes(void) selection(void)
{ {
Rune *r, *p; char *s, *p;
int sz;
int y; int y;
/* generous, but we can spare a few bytes for a few microseconds */ /* generous, but we can spare a few bytes for a few microseconds */
sz = xmax*(selrect.max.y - selrect.min.y + 2) + 1; s = p = malloc(UTFmax*(xmax+1)*(Dy(selrect)+1)+1);
r = p = malloc(sizeof(Rune)*sz + 1); if(s == nil)
if(!r)
return nil; return nil;
if(blocksel){ if(blocksel){
for(y = selrect.min.y; y <= selrect.max.y; y++){ for(y = selrect.min.y; y <= selrect.max.y; y++){
p = selrange(p, selrect.min.x, y, selrect.max.x, y); p = selrange(p, selrect.min.x, y, selrect.max.x, y);
*p++ = '\n'; *p++ = '\n';
} }
*p = 0; } else {
p = selrange(p, selrect.min.x, selrect.min.y, selrect.max.x, selrect.max.y);
} }
else *p = 0;
selrange(r, selrect.min.x, selrect.min.y, selrect.max.x, selrect.max.y); return s;
return r;
} }
void void
snarfsel(void) snarfsel(void)
{ {
Biobuf *b; Biobuf *b;
Rune *r; char *s;
if((r = selrunes()) == nil) if((s = selection()) == nil)
return; return;
if((b = Bopen("/dev/snarf", OWRITE|OTRUNC)) == nil){ if((b = Bopen("/dev/snarf", OWRITE|OTRUNC)) == nil){
free(r); free(s);
return; return;
} }
Bprint(b, "%S", r); Bprint(b, "%s", s);
Bterm(b); Bterm(b);
free(r); free(s);
} }
void void
plumbsel(void) plumbsel(void)
{ {
char *s, wdir[1024]; char *s, wdir[1024];
Rune *r;
int plumb; int plumb;
if((r = selrunes()) == nil) if((s = selection()) == nil)
return; return;
if((s = smprint("%S", r)) == nil){
free(r);
return;
}
free(r);
if(getwd(wdir, sizeof wdir) == nil){ if(getwd(wdir, sizeof wdir) == nil){
free(s); free(s);
return; return;
@ -1022,29 +1013,42 @@ unselect(void)
} }
void void
selection(void) select(Point p, Point q)
{ {
Point p, q; if(onscreenr(p.x, p.y) > onscreenr(q.x, q.y)){
int y; select(q, p);
return;
}
unselect();
if(p.y < 0 || p.y > ymax)
return;
if(p.y < 0){
p.y = 0;
if(!blocksel) p.x = 0;
}
if(q.y > ymax){
q.y = ymax;
if(!blocksel) q.x = xmax+1;
}
if(p.x < 0)
p.x = 0;
if(q.x > xmax+1)
q.x = xmax+1;
selrect = Rpt(p, q);
for(; p.y <= q.y; p.y++)
screenchange(p.y) = 1;
}
void
selecting(void)
{
Point p;
p = pos(mc->xy); p = pos(mc->xy);
do{ do{
/* Clear the old selection rectangle. */
unselect();
q = pos(mc->xy);
if(onscreenr(p.x, p.y) > onscreenr(q.x, q.y)){
selrect.min = q;
selrect.max = p;
} else {
selrect.min = p;
selrect.max = q;
}
/* And mark the new one as changed. */
for(y = selrect.min.y; y <= selrect.max.y; y++)
screenchange(y) = 1;
readmouse(mc);
drawscreen(); drawscreen();
readmouse(mc);
select(p, pos(mc->xy));
} while(button1()); } while(button1());
switch(mc->buttons & 0x7){ switch(mc->buttons & 0x7){
case 3: snarfsel(); break; case 3: snarfsel(); break;
@ -1255,18 +1259,7 @@ scroll(int sy, int ly, int dy, int cy) /* source, limit, dest, which line to cle
/* move selection */ /* move selection */
selrect.min.y -= d; selrect.min.y -= d;
selrect.max.y -= d; selrect.max.y -= d;
if(selrect.max.y < 0 || selrect.min.y > ymax) select(selrect.min, selrect.max);
selrect = ZR;
else {
if(selrect.min.y < 0){
selrect.min.y = 0;
if(!blocksel) selrect.min.x = 0;
}
if(selrect.max.y > ymax){
selrect.max.y = ymax;
if(!blocksel) selrect.max.x = xmax+1;
}
}
clear(0, cy, xmax+1, cy+1); clear(0, cy, xmax+1, cy+1);
} }