9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

moveto.c (2712B)


      1 #include "sam.h"
      2 
      3 void
      4 moveto(File *f, Range r)
      5 {
      6 	Posn p1 = r.p1, p2 = r.p2;
      7 
      8 	f->dot.r.p1 = p1;
      9 	f->dot.r.p2 = p2;
     10 	if(f->rasp){
     11 		telldot(f);
     12 		outTsl(Hmoveto, f->tag, f->dot.r.p1);
     13 	}
     14 }
     15 
     16 void
     17 telldot(File *f)
     18 {
     19 	if(f->rasp == 0)
     20 		panic("telldot");
     21 	if(f->dot.r.p1==f->tdot.p1 && f->dot.r.p2==f->tdot.p2)
     22 		return;
     23 	outTsll(Hsetdot, f->tag, f->dot.r.p1, f->dot.r.p2);
     24 	f->tdot = f->dot.r;
     25 }
     26 
     27 void
     28 tellpat(void)
     29 {
     30 	outTS(Hsetpat, &lastpat);
     31 	patset = FALSE;
     32 }
     33 
     34 #define	CHARSHIFT	128
     35 
     36 void
     37 lookorigin(File *f, Posn p0, Posn ls)
     38 {
     39 	int nl, nc, c;
     40 	Posn p, oldp0;
     41 
     42 	if(p0 > f->b.nc)
     43 		p0 = f->b.nc;
     44 	oldp0 = p0;
     45 	p = p0;
     46 	for(nl=nc=c=0; c!=-1 && nl<ls && nc<ls*CHARSHIFT; nc++)
     47 		if((c=filereadc(f, --p)) == '\n'){
     48 			nl++;
     49 			oldp0 = p0-nc;
     50 		}
     51 	if(c == -1)
     52 		p0 = 0;
     53 	else if(nl==0){
     54 		if(p0>=CHARSHIFT/2)
     55 			p0-=CHARSHIFT/2;
     56 		else
     57 			p0 = 0;
     58 	}else
     59 		p0 = oldp0;
     60 	outTsl(Horigin, f->tag, p0);
     61 }
     62 
     63 int
     64 alnum(int c)
     65 {
     66 	/*
     67 	 * Hard to get absolutely right.  Use what we know about ASCII
     68 	 * and assume anything above the Latin control characters is
     69 	 * potentially an alphanumeric.
     70 	 */
     71 	if(c<=' ')
     72 		return 0;
     73 	if(0x7F<=c && c<=0xA0)
     74 		return 0;
     75 	if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))
     76 		return 0;
     77 	return 1;
     78 }
     79 
     80 int
     81 clickmatch(File *f, int cl, int cr, int dir, Posn *p)
     82 {
     83 	int c;
     84 	int nest = 1;
     85 
     86 	for(;;){
     87 		if(dir > 0){
     88 			if(*p >= f->b.nc)
     89 				break;
     90 			c = filereadc(f, (*p)++);
     91 		}else{
     92 			if(*p == 0)
     93 				break;
     94 			c = filereadc(f, --(*p));
     95 		}
     96 		if(c == cr){
     97 			if(--nest==0)
     98 				return 1;
     99 		}else if(c == cl)
    100 			nest++;
    101 	}
    102 	return cl=='\n' && nest==1;
    103 }
    104 
    105 Rune*
    106 strrune(Rune *s, Rune c)
    107 {
    108 	Rune c1;
    109 
    110 	if(c == 0) {
    111 		while(*s++)
    112 			;
    113 		return s-1;
    114 	}
    115 
    116 	while(c1 = *s++)
    117 		if(c1 == c)
    118 			return s-1;
    119 	return 0;
    120 }
    121 
    122 void
    123 doubleclick(File *f, Posn p1)
    124 {
    125 	int c, i;
    126 	Rune *r, *l;
    127 	Posn p;
    128 
    129 	if(p1 > f->b.nc)
    130 		return;
    131 	f->dot.r.p1 = f->dot.r.p2 = p1;
    132 	for(i=0; left[i]; i++){
    133 		l = left[i];
    134 		r = right[i];
    135 		/* try left match */
    136 		p = p1;
    137 		if(p1 == 0)
    138 			c = '\n';
    139 		else
    140 			c = filereadc(f, p - 1);
    141 		if(strrune(l, c)){
    142 			if(clickmatch(f, c, r[strrune(l, c)-l], 1, &p)){
    143 				f->dot.r.p1 = p1;
    144 				f->dot.r.p2 = p-(c!='\n');
    145 			}
    146 			return;
    147 		}
    148 		/* try right match */
    149 		p = p1;
    150 		if(p1 == f->b.nc)
    151 			c = '\n';
    152 		else
    153 			c = filereadc(f, p);
    154 		if(strrune(r, c)){
    155 			if(clickmatch(f, c, l[strrune(r, c)-r], -1, &p)){
    156 				f->dot.r.p1 = p;
    157 				if(c!='\n' || p!=0 || filereadc(f, 0)=='\n')
    158 					f->dot.r.p1++;
    159 				f->dot.r.p2 = p1+(p1<f->b.nc && c=='\n');
    160 			}
    161 			return;
    162 		}
    163 	}
    164 	/* try filling out word to right */
    165 	p = p1;
    166 	while(p < f->b.nc && alnum(filereadc(f, p++)))
    167 		f->dot.r.p2++;
    168 	/* try filling out word to left */
    169 	p = p1;
    170 	while(--p >= 0 && alnum(filereadc(f, p)))
    171 		f->dot.r.p1--;
    172 }
    173