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 }