URI: 
       tmoveto.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tmoveto.c (2711B)
       ---
            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 }