github.com/jmigpin/editor@v1.6.0/util/iout/iorw/rwedit/find.go (about)

     1  package rwedit
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"io"
     7  
     8  	"github.com/jmigpin/editor/util/iout/iorw"
     9  )
    10  
    11  func Find(cctx context.Context, ectx *Ctx, str string, reverse bool, opt *iorw.IndexOpt) (bool, error) {
    12  	if str == "" {
    13  		return false, nil
    14  	}
    15  	if reverse {
    16  		i, n, err := find2Rev(cctx, ectx, []byte(str), opt)
    17  		if err != nil || i < 0 {
    18  			return false, err
    19  		}
    20  		ectx.C.SetSelection(i+n, i) // cursor at start to allow searching next
    21  	} else {
    22  		i, n, err := find2(cctx, ectx, []byte(str), opt)
    23  		if err != nil || i < 0 {
    24  			return false, err
    25  		}
    26  		ectx.C.SetSelection(i, i+n) // cursor at end to allow searching next
    27  	}
    28  
    29  	return true, nil
    30  }
    31  func find2(cctx context.Context, ectx *Ctx, b []byte, opt *iorw.IndexOpt) (int, int, error) {
    32  	ci := ectx.C.Index()
    33  	// index to end
    34  	i, n, err := iorw.IndexCtx(cctx, ectx.RW, ci, b, opt)
    35  	if err != nil || i >= 0 {
    36  		return i, n, err
    37  	}
    38  	// start to index
    39  	e := ci + len(b) - 1
    40  	rd := iorw.NewLimitedReaderAt(ectx.RW, 0, e)
    41  	k, n, err := iorw.IndexCtx(cctx, rd, 0, b, opt)
    42  	if err != nil {
    43  		if errors.Is(err, io.EOF) {
    44  			return -1, 0, nil
    45  		}
    46  		return -1, 0, err
    47  	}
    48  	return k, n, nil
    49  }
    50  func find2Rev(cctx context.Context, ectx *Ctx, b []byte, opt *iorw.IndexOpt) (int, int, error) {
    51  	ci := ectx.C.Index()
    52  	// start to index (in reverse)
    53  	i, n, err := iorw.LastIndexCtx(cctx, ectx.RW, ci, b, opt)
    54  	if err != nil || i >= 0 {
    55  		return i, n, err
    56  	}
    57  	// index to end (in reverse)
    58  	s := ci - len(b) + 1
    59  	e := ectx.RW.Max()
    60  	rd2 := iorw.NewLimitedReaderAt(ectx.RW, s, e)
    61  	k, n, err := iorw.LastIndexCtx(cctx, rd2, e, b, opt)
    62  	if err != nil {
    63  		if errors.Is(err, io.EOF) {
    64  			return -1, 0, nil
    65  		}
    66  		return -1, 0, err
    67  	}
    68  	return k, n, nil
    69  }