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

     1  package rwedit
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	"unicode"
     7  
     8  	"github.com/jmigpin/editor/util/iout/iorw"
     9  )
    10  
    11  func AutoIndent(ctx *Ctx) error {
    12  	ci := ctx.C.Index()
    13  
    14  	rd1 := iorw.NewLimitedReaderAt(ctx.RW, ci-2000, ci)
    15  	i, err := iorw.LineStartIndex(rd1, ci)
    16  	if err != nil {
    17  		return err
    18  	}
    19  
    20  	rd := iorw.NewLimitedReaderAt(ctx.RW, i, ci)
    21  	j, _, err := iorw.RuneIndexFn(rd, i, false, unicode.IsSpace)
    22  	if err != nil {
    23  		if errors.Is(err, io.EOF) {
    24  			j = ci // all spaces up to ci
    25  		} else {
    26  			return err
    27  		}
    28  	}
    29  
    30  	// string to insert
    31  	s, err := ctx.RW.ReadFastAt(i, j-i)
    32  	if err != nil {
    33  		return err
    34  	}
    35  	s2 := append([]byte{'\n'}, s...)
    36  
    37  	// selection to overwrite
    38  	n := 0
    39  	if a, b, ok := ctx.C.SelectionIndexes(); ok {
    40  		n = b - a
    41  		ci = a
    42  		ctx.C.SetSelectionOff()
    43  	}
    44  
    45  	if err := ctx.RW.OverwriteAt(ci, n, s2); err != nil {
    46  		return err
    47  	}
    48  	ctx.C.SetIndex(ci + len(s2))
    49  	return nil
    50  }