func (sel eSel) matches(rexp []rune, neg bool) ([][]sre.Range, error) { re, err := sre.Compile(rexp, sre.Fwd) if err != nil { return nil, err } sels := make([][]sre.Range, 0) for sel.P0 < sel.P1 { rgs := re.Exec(sel.F, sel.P0, sel.P1) dprintf("match sel %s rgs %v\n", sel, rgs) if len(rgs) == 0 { if neg { s := sre.Range{sel.P0, sel.P1} sels = append(sels, []sre.Range{s}) } break } if neg { s := sre.Range{sel.P0, rgs[0].P0} sels = append(sels, []sre.Range{s}) } else { sels = append(sels, rgs) } sel.P0 = rgs[0].P1 if rgs[0].P0 == rgs[0].P1 { sel.P0++ } } return sels, nil }
func (s eSel) matchBck(re []rune) []sre.Range { prg, err := sre.Compile(re, sre.Bck) if err != nil { panic(err) } rg := prg.Exec(s.F, s.P0, s.F.Len()) if len(rg) == 0 && s.P0 == 0 { rg = prg.Exec(s.F, s.F.Len(), s.F.Len()) } return rg }
func (s eSel) matchFwd(re []rune) []sre.Range { prg, err := sre.Compile(re, sre.Fwd) if err != nil { panic(err) } rg := prg.Exec(s.F, s.P1, s.F.Len()) if len(rg) == 0 && s.P1 >= s.F.Len() { rg = prg.Exec(s.F, s.P0, s.F.Len()) } return rg }
func cmdgv(s *Sam, c *Cmd) { re, err := sre.Compile(c.Rexp, sre.Fwd) if err != nil { panic(fmt.Sprintf("g: regexp: %s", err)) } rg := re.Exec(c.dot.F, c.dot.P0, c.dot.P1) if (len(rg) == 0 && c.Ch == 'v') || (len(rg) > 0 && c.Ch == 'g') { for _, child := range c.Child { child.dot = c.dot child.dot.setFileSel() s.runCmd(child) } } }
func (s *Sam) matchFile(re []rune) *file { prg, err := sre.Compile(re, sre.Fwd) if err != nil { panic(fmt.Sprintf("match file regexp: %s", err)) } for _, f := range s.f { nm := f.MenuLine() if rg := prg.ExecStr(nm, 0, len(nm)); len(rg) > 0 { return f } } panic("no file matches") return nil }
func cmdXY(s *Sam, c *Cmd) { if s.inXY { panic("can't next X or Y commands") } s.inXY = true defer func() { s.inXY = false }() var re *sre.ReProg var err error if c.Rexp != nil { if re, err = sre.Compile(c.Rexp, sre.Fwd); err != nil { panic(fmt.Sprintf("%c: regexp: %s", c.Ch, err)) } } else if c.Ch == 'Y' { panic("Y: no regexp given") } nf := make([]*file, len(s.f)) copy(nf, s.f) for _, f := range nf { matches := true if re != nil { nm := f.MenuLine() + "\n" rg := re.ExecStr(nm, 0, len(nm)) matches = len(rg) > 0 } if (c.Ch == 'X' && !matches) || (c.Ch == 'Y' && matches) { continue } c.dot = f.Sel() for _, child := range c.Child { child.dot = c.dot if err := s.runCmd(child); err != nil { s.Out <- fmt.Sprintf("%s\n", err) } } } }