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