vt: fix selection past baseline (thanks BurnZeZ)
This commit is contained in:
parent
217e8a0619
commit
2e9835e771
1 changed files with 53 additions and 60 deletions
|
@ -162,7 +162,7 @@ void waitio(void);
|
|||
int rcvchar(void);
|
||||
void bigscroll(void);
|
||||
void readmenu(void);
|
||||
void selection(void);
|
||||
void selecting(void);
|
||||
int selected(int, int);
|
||||
void resized(void);
|
||||
void drawcursor(void);
|
||||
|
@ -810,7 +810,7 @@ Next:
|
|||
switch(alt(a)){
|
||||
case AMOUSE:
|
||||
if(button1())
|
||||
selection();
|
||||
selecting();
|
||||
else if(button2() || button3())
|
||||
readmenu();
|
||||
else if(resize_flag == 0)
|
||||
|
@ -912,8 +912,8 @@ resized(void)
|
|||
werrstr(""); /* clear spurious error messages */
|
||||
}
|
||||
|
||||
Rune *
|
||||
selrange(Rune *r, int x0, int y0, int x1, int y1)
|
||||
char*
|
||||
selrange(char *d, int x0, int y0, int x1, int y1)
|
||||
{
|
||||
Rune *s, *e;
|
||||
int z, p;
|
||||
|
@ -925,72 +925,63 @@ selrange(Rune *r, int x0, int y0, int x1, int y1)
|
|||
if(*s == '\n')
|
||||
z = p = 0;
|
||||
else if(p++ == 0){
|
||||
while(z-- > 0) *r++ = ' ';
|
||||
while(z-- > 0) *d++ = ' ';
|
||||
}
|
||||
*r++ = *s;
|
||||
d += runetochar(d, s);
|
||||
} else {
|
||||
z++;
|
||||
}
|
||||
}
|
||||
*r = 0;
|
||||
return r;
|
||||
return d;
|
||||
}
|
||||
|
||||
Rune*
|
||||
selrunes(void)
|
||||
char*
|
||||
selection(void)
|
||||
{
|
||||
Rune *r, *p;
|
||||
int sz;
|
||||
char *s, *p;
|
||||
int y;
|
||||
|
||||
/* generous, but we can spare a few bytes for a few microseconds */
|
||||
sz = xmax*(selrect.max.y - selrect.min.y + 2) + 1;
|
||||
r = p = malloc(sizeof(Rune)*sz + 1);
|
||||
if(!r)
|
||||
s = p = malloc(UTFmax*(xmax+1)*(Dy(selrect)+1)+1);
|
||||
if(s == nil)
|
||||
return nil;
|
||||
if(blocksel){
|
||||
for(y = selrect.min.y; y <= selrect.max.y; y++){
|
||||
p = selrange(p, selrect.min.x, y, selrect.max.x, y);
|
||||
*p++ = '\n';
|
||||
}
|
||||
*p = 0;
|
||||
} else {
|
||||
p = selrange(p, selrect.min.x, selrect.min.y, selrect.max.x, selrect.max.y);
|
||||
}
|
||||
else
|
||||
selrange(r, selrect.min.x, selrect.min.y, selrect.max.x, selrect.max.y);
|
||||
return r;
|
||||
*p = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
snarfsel(void)
|
||||
{
|
||||
Biobuf *b;
|
||||
Rune *r;
|
||||
char *s;
|
||||
|
||||
if((r = selrunes()) == nil)
|
||||
if((s = selection()) == nil)
|
||||
return;
|
||||
if((b = Bopen("/dev/snarf", OWRITE|OTRUNC)) == nil){
|
||||
free(r);
|
||||
free(s);
|
||||
return;
|
||||
}
|
||||
Bprint(b, "%S", r);
|
||||
Bprint(b, "%s", s);
|
||||
Bterm(b);
|
||||
free(r);
|
||||
free(s);
|
||||
}
|
||||
|
||||
void
|
||||
plumbsel(void)
|
||||
{
|
||||
char *s, wdir[1024];
|
||||
Rune *r;
|
||||
int plumb;
|
||||
|
||||
if((r = selrunes()) == nil)
|
||||
if((s = selection()) == nil)
|
||||
return;
|
||||
if((s = smprint("%S", r)) == nil){
|
||||
free(r);
|
||||
return;
|
||||
}
|
||||
free(r);
|
||||
if(getwd(wdir, sizeof wdir) == nil){
|
||||
free(s);
|
||||
return;
|
||||
|
@ -1022,29 +1013,42 @@ unselect(void)
|
|||
}
|
||||
|
||||
void
|
||||
selection(void)
|
||||
select(Point p, Point q)
|
||||
{
|
||||
Point p, q;
|
||||
int y;
|
||||
if(onscreenr(p.x, p.y) > onscreenr(q.x, q.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);
|
||||
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();
|
||||
readmouse(mc);
|
||||
select(p, pos(mc->xy));
|
||||
} while(button1());
|
||||
switch(mc->buttons & 0x7){
|
||||
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 */
|
||||
selrect.min.y -= d;
|
||||
selrect.max.y -= d;
|
||||
if(selrect.max.y < 0 || selrect.min.y > ymax)
|
||||
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;
|
||||
}
|
||||
}
|
||||
select(selrect.min, selrect.max);
|
||||
|
||||
clear(0, cy, xmax+1, cy+1);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue