github.com/jmigpin/editor@v1.6.0/util/drawutil/drawer4/linestart.go (about)

     1  package drawer4
     2  
     3  import (
     4  	"github.com/jmigpin/editor/util/iout/iorw"
     5  )
     6  
     7  type LineStart struct {
     8  	d *Drawer
     9  }
    10  
    11  func (ls *LineStart) Init() {
    12  	st := &ls.d.st.lineStart
    13  	// content line start
    14  	ls.d.st.lineStart.q = nil
    15  	ls.d.st.lineStart.uppedLines = 0
    16  	ls.d.st.runeR.ri = ls.lineStartIndex(st.offset, st.nLinesUp)
    17  }
    18  
    19  func (ls *LineStart) Iter() {
    20  	st := &ls.d.st.lineStart
    21  	if ls.d.st.line.lineStart || ls.d.st.lineWrap.postLineWrap {
    22  		st.q = append(st.q, ls.d.st.runeR.ri)
    23  	}
    24  	if ls.d.st.runeR.ri >= st.offset {
    25  		// don't stop before postLineWrap
    26  		if !ls.d.st.lineWrap.preLineWrap {
    27  			ls.d.iterStop()
    28  			return
    29  		}
    30  	}
    31  	if !ls.d.iterNext() {
    32  		return
    33  	}
    34  }
    35  
    36  func (ls *LineStart) End() {
    37  	st := &ls.d.st.lineStart
    38  	// count lines back
    39  	if len(st.q) == 0 {
    40  		// worst case ri (start ri)
    41  		st.ri = ls.d.st.runeR.startRi
    42  	} else {
    43  		k := st.nLinesUp
    44  		if k >= len(st.q) {
    45  			k = len(st.q) - 1
    46  		}
    47  		st.ri = st.q[len(st.q)-1-k]
    48  		st.uppedLines = k
    49  	}
    50  }
    51  
    52  //----------
    53  
    54  func (ls *LineStart) lineStartIndex(offset, nLinesUp int) int {
    55  	w := ls.linesStartIndexes(offset, nLinesUp)
    56  
    57  	// read error case
    58  	if len(w) == 0 {
    59  		return offset
    60  	}
    61  
    62  	if nLinesUp >= len(w) {
    63  		nLinesUp = len(w) - 1
    64  	}
    65  	return w[nLinesUp]
    66  }
    67  
    68  func (ls *LineStart) linesStartIndexes(offset, nLinesUp int) []int {
    69  	// reader
    70  	rd := ls.d.st.lineStart.reader
    71  	if rd == nil {
    72  		rd = ls.d.limitedReaderPad(offset)
    73  	}
    74  
    75  	// ensure offset is within max bound
    76  	if offset > rd.Max() {
    77  		offset = rd.Max()
    78  	}
    79  
    80  	w := []int{}
    81  	for i := 0; i <= nLinesUp; i++ {
    82  		k, err := iorw.LineStartIndex(rd, offset)
    83  		if err != nil {
    84  			break
    85  		}
    86  		w = append(w, k)
    87  		offset = k - 1
    88  		if offset < 0 {
    89  			break
    90  		}
    91  	}
    92  	return w
    93  }