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 }