github.com/oweisse/u-root@v0.0.0-20181109060735-d005ad25fef1/cmds/elvish/edit/highlight/styling.go (about) 1 package highlight 2 3 import ( 4 "bytes" 5 "sort" 6 7 "github.com/u-root/u-root/cmds/elvish/edit/ui" 8 ) 9 10 // Preparing and applying styling. 11 12 type Styling struct { 13 begins []stylingEvent 14 ends []stylingEvent 15 } 16 17 func (s *Styling) Add(begin, end int, style string) { 18 if style == "" { 19 return 20 } 21 s.begins = append(s.begins, stylingEvent{begin, style}) 22 s.ends = append(s.ends, stylingEvent{end, style}) 23 } 24 25 func (s *Styling) Apply() *StylingApplier { 26 sort.Sort(stylingEvents(s.begins)) 27 sort.Sort(stylingEvents(s.ends)) 28 return &StylingApplier{s, make(map[string]int), 0, 0, ""} 29 } 30 31 type StylingApplier struct { 32 *Styling 33 occurrence map[string]int 34 ibegin int 35 iend int 36 result string 37 } 38 39 func (a *StylingApplier) At(i int) { 40 changed := false 41 for a.iend < len(a.ends) && a.ends[a.iend].pos == i { 42 a.occurrence[a.ends[a.iend].style]-- 43 a.iend++ 44 changed = true 45 } 46 for a.ibegin < len(a.begins) && a.begins[a.ibegin].pos == i { 47 a.occurrence[a.begins[a.ibegin].style]++ 48 a.ibegin++ 49 changed = true 50 } 51 52 if changed { 53 b := new(bytes.Buffer) 54 for style, occ := range a.occurrence { 55 if occ == 0 { 56 continue 57 } 58 if b.Len() > 0 { 59 b.WriteString(";") 60 } 61 b.WriteString(ui.TranslateStyle(style)) 62 } 63 a.result = b.String() 64 } 65 } 66 67 func (a *StylingApplier) Get() string { 68 return a.result 69 } 70 71 type stylingEvent struct { 72 pos int 73 style string 74 } 75 76 type stylingEvents []stylingEvent 77 78 func (s stylingEvents) Len() int { return len(s) } 79 func (s stylingEvents) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 80 func (s stylingEvents) Less(i, j int) bool { return s[i].pos < s[j].pos }