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  }