github.com/jmigpin/editor@v1.6.0/core/internalcmds/find.go (about)

     1  package internalcmds
     2  
     3  import (
     4  	"bytes"
     5  	"flag"
     6  	"fmt"
     7  	"io"
     8  	"strings"
     9  
    10  	"github.com/jmigpin/editor/core"
    11  	"github.com/jmigpin/editor/util/iout/iorw"
    12  	"github.com/jmigpin/editor/util/iout/iorw/rwedit"
    13  	"github.com/jmigpin/editor/util/parseutil"
    14  )
    15  
    16  func Find(args0 *core.InternalCmdArgs) error {
    17  	// setup flagset
    18  	fs := flag.NewFlagSet("Find", flag.ContinueOnError)
    19  	fs.SetOutput(io.Discard) // don't output to stderr
    20  	reverseFlag := fs.Bool("rev", false, "reverse find")
    21  	iopt := &iorw.IndexOpt{}
    22  	fs.BoolVar(&iopt.IgnoreCase, "icase", true, "ignore case: 'a' will also match 'A'")
    23  	fs.BoolVar(&iopt.IgnoreCaseDiacritics, "icasediac", false, "ignore case diacritics: 'á' will also match 'Á'. Because ignore case is usually on by default, this is a separate option to explicitly lower the case of diacritics due to being more expensive (~8x slower)'")
    24  	fs.BoolVar(&iopt.IgnoreDiacritics, "idiac", false, "ignore diacritics: 'a' will also match 'á'")
    25  
    26  	// parse flags
    27  	part := args0.Part
    28  	args := part.ArgsStrings()[1:]
    29  	err := fs.Parse(args)
    30  	if err != nil {
    31  		if err == flag.ErrHelp {
    32  			buf := &bytes.Buffer{}
    33  			fs.SetOutput(buf)
    34  			fs.Usage()
    35  			args0.Ed.Message(buf.String())
    36  			return nil
    37  		}
    38  		return err
    39  	}
    40  
    41  	// this cmd is allowed to get here without a row in order to run the help cmd from the toolbar easily
    42  	erow := args0.ERow
    43  	if erow == nil {
    44  		return fmt.Errorf("%s: no active row", part)
    45  	}
    46  
    47  	args2 := fs.Args()
    48  
    49  	// unquote args
    50  	w := []string{}
    51  	for _, arg := range args2 {
    52  		if u, err := parseutil.UnquoteStringBs(arg); err == nil {
    53  			arg = u
    54  		}
    55  		w = append(w, arg)
    56  	}
    57  
    58  	str := strings.Join(w, " ")
    59  
    60  	found, err := rwedit.Find(args0.Ctx, erow.Row.TextArea.EditCtx(), str, *reverseFlag, iopt)
    61  	if err != nil {
    62  		return err
    63  	}
    64  	if !found {
    65  		return fmt.Errorf("string not found: %q", str)
    66  	}
    67  
    68  	// flash
    69  	ta := erow.Row.TextArea
    70  	if a, b, ok := ta.Cursor().SelectionIndexes(); ok {
    71  		erow.MakeRangeVisibleAndFlash(a, b-a)
    72  	}
    73  
    74  	return nil
    75  }