ref: 2e9835e771c54cb9a0c9cd81012e7b4b75f878f7
parent: 217e8a06198cf6681fb0c38c26f34d96ae4302f6
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Sep 4 16:55:10 EDT 2018
vt: fix selection past baseline (thanks BurnZeZ)
--- a/sys/src/cmd/vt/main.c
+++ b/sys/src/cmd/vt/main.c
@@ -162,7 +162,7 @@
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 @@
switch(alt(a)){
case AMOUSE:
if(button1())
- selection();
+ selecting();
else if(button2() || button3())
readmenu();
else if(resize_flag == 0)
@@ -912,8 +912,8 @@
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,28 +925,25 @@
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++){
@@ -953,11 +950,11 @@
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
@@ -964,17 +961,17 @@
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
@@ -981,16 +978,10 @@
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 @@
}
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 @@
/* 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);
}