return r;
}
+static int
+spacesindentbswidth(Text *t)
+{
+ uint q, col;
+ Rune r;
+
+ col = textbswidth(t, 0x15);
+ q = t->q0;
+ while(q > 0){
+ r = textreadc(t, q-1);
+ if(r != ' ')
+ break;
+ q--;
+ if(--col % t->tabstop == 0)
+ break;
+ }
+ if(t->q0 == q)
+ return 1;
+ return t->q0-q;
+}
+
int
textbswidth(Text *t, Rune c)
{
int skipping;
/* there is known to be at least one character to erase */
- if(c == 0x08) /* ^H: erase character */
+ if(c == 0x08){ /* ^H: erase character */
+ if(t->what == Body && t->w->indent[SPACESINDENT])
+ return spacesindentbswidth(t);
return 1;
+ }
q = t->q0;
skipping = TRUE;
while(q > 0){
for(i=0; i<t->file->ntext; i++)
textfill(t->file->text[i]);
return;
+ case '\t':
+ if(t->what == Body && t->w->indent[SPACESINDENT]){
+ nnb = textbswidth(t, 0x15);
+ if(nnb == 1 && textreadc(t, t->q0-1) == '\n')
+ nnb = 0;
+ nnb = t->tabstop - nnb % t->tabstop;
+ rp = runemalloc(nnb);
+ for(nr = 0; nr < nnb; nr++)
+ rp[nr] = ' ';
+ }
+ break;
case '\n':
- if(t->what == Body && t->w->autoindent){
+ if(t->what == Body && t->w->indent[AUTOINDENT]){
/* find beginning of previous line using backspace code */
nnb = textbswidth(t, 0x15); /* ^U case */
rp = runemalloc(nnb + 1);
static Text *clicktext;
static uint clickmsec;
+static int clickcount;
+static Point clickpt;
static Text *selecttext;
static uint selectq;
textsetselect(t, selectq, t->org+t->p1);
}
textsetorigin(t, q0, TRUE);
+ flushimage(display, 1);
}
textselect(Text *t)
{
uint q0, q1;
- int b, x, y;
+ int b, x, y, dx, dy;
int state;
selecttext = t;
b = mouse->buttons;
q0 = t->q0;
q1 = t->q1;
+ dx = abs(clickpt.x - mouse->xy.x);
+ dy = abs(clickpt.y - mouse->xy.y);
+ clickpt = mouse->xy;
selectq = t->org+frcharofpt(t, mouse->xy);
- if(clicktext==t && mouse->msec-clickmsec<500)
- if(q0==q1 && selectq==q0){
- textdoubleclick(t, &q0, &q1);
+ clickcount++;
+ if(mouse->msec-clickmsec >= 500 || selecttext != t || clickcount > 3 || dx > 3 || dy > 3)
+ clickcount = 0;
+ if(clickcount >= 1 && selecttext==t && mouse->msec-clickmsec < 500){
+ textstretchsel(t, selectq, &q0, &q1, clickcount);
textsetselect(t, q0, q1);
flushimage(display, 1);
x = mouse->xy.x;
y = mouse->xy.y;
/* stay here until something interesting happens */
- do
+ while(1){
readmouse(mousectl);
- while(mouse->buttons==b && abs(mouse->xy.x-x)<3 && abs(mouse->xy.y-y)<3);
+ dx = abs(mouse->xy.x - x);
+ dy = abs(mouse->xy.y - y);
+ if(mouse->buttons != b || dx >= 3 || dy >= 3)
+ break;
+ clickcount++;
+ clickmsec = mouse->msec;
+ }
mouse->xy.x = x; /* in case we're calling frselect */
mouse->xy.y = y;
q0 = t->q0; /* may have changed */
q1 = t->q1;
- selectq = q0;
+ selectq = t->org+frcharofpt(t, mouse->xy);;
}
- if(mouse->buttons == b){
+ if(mouse->buttons == b && clickcount == 0){
t->Frame.scroll = framescroll;
frselect(t, mousectl);
/* horrible botch: while asleep, may have lost selection altogether */
q1 = t->org+t->p1;
}
if(q0 == q1){
- if(q0==t->q0 && clicktext==t && mouse->msec-clickmsec<500){
- textdoubleclick(t, &q0, &q1);
- clicktext = nil;
- }else{
+ if(q0==t->q0 && mouse->msec-clickmsec<500)
+ textstretchsel(t, selectq, &q0, &q1, clickcount);
+ else
clicktext = t;
- clickmsec = mouse->msec;
- }
+ clickmsec = mouse->msec;
}else
clicktext = nil;
textsetselect(t, q0, q1);
flushimage(display, 1);
while(mouse->buttons == b)
readmouse(mousectl);
- clicktext = nil;
+ if(mouse->msec-clickmsec >= 500)
+ clicktext = nil;
}
}
nil
};
+int
+inmode(Rune r, int mode)
+{
+ return (mode == 1) ? isalnum(r) : r && !isspace(r);
+}
+
void
-textdoubleclick(Text *t, uint *q0, uint *q1)
+textstretchsel(Text *t, uint mp, uint *q0, uint *q1, int mode)
{
int c, i;
Rune *r, *l, *p;
uint q;
+ *q0 = mp;
+ *q1 = mp;
for(i=0; left[i]!=nil; i++){
q = *q0;
l = left[i];
}
}
/* try filling out word to right */
- while(*q1<t->file->nc && isalnum(textreadc(t, *q1)))
+ while(*q1<t->file->nc && inmode(textreadc(t, *q1), mode))
(*q1)++;
/* try filling out word to left */
- while(*q0>0 && isalnum(textreadc(t, *q0-1)))
+ while(*q0>0 && inmode(textreadc(t, *q0-1), mode))
(*q0)--;
}
Rune *r;
uint n;
- if(org>0 && !exact){
+ if(org>0 && !exact && textreadc(t, org-1) != '\n'){
/* org is an estimate of the char posn; find a newline */
/* don't try harder than 256 chars */
for(i=0; i<256 && org<t->file->nc; i++){