98 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package atom
 | ||
| 
 | ||
| import (
 | ||
| 	"gitea.zaclys.com/bvaudour/gob/option"
 | ||
| )
 | ||
| 
 | ||
| // Cycler stocke les données possibles de l’autocomplétion
 | ||
| type Cycler struct {
 | ||
| 	data   []string
 | ||
| 	cursor int
 | ||
| 	cycled bool
 | ||
| }
 | ||
| 
 | ||
| func isCursorValid(c, l int) bool {
 | ||
| 	return c >= 0 && c < l
 | ||
| }
 | ||
| 
 | ||
| // Len retourne le nombre de propositions du cycler.
 | ||
| func (c *Cycler) Len() int {
 | ||
| 	return len(c.data)
 | ||
| }
 | ||
| 
 | ||
| // Cursor retourne la position de l’élément pointé.
 | ||
| func (c *Cycler) Cursor() int {
 | ||
| 	return c.cursor
 | ||
| }
 | ||
| 
 | ||
| // Index retourne l’élément selon son index.
 | ||
| func (c *Cycler) Index(i int) (value option.Option[string]) {
 | ||
| 	l := c.Len()
 | ||
| 	if i < 0 {
 | ||
| 		i += l
 | ||
| 	}
 | ||
| 
 | ||
| 	if isCursorValid(i, l) {
 | ||
| 		value = option.Some(c.data[i])
 | ||
| 	}
 | ||
| 
 | ||
| 	return
 | ||
| }
 | ||
| 
 | ||
| // SetCursor positionne le pointeur à l’index donné.
 | ||
| func (c *Cycler) SetCursor(n int) (ok bool) {
 | ||
| 	l := c.Len()
 | ||
| 	if n < 0 {
 | ||
| 		n += l
 | ||
| 	}
 | ||
| 
 | ||
| 	if ok = isCursorValid(n, l); ok {
 | ||
| 		c.cursor = n
 | ||
| 	}
 | ||
| 
 | ||
| 	return
 | ||
| }
 | ||
| 
 | ||
| // Append ajoute une proposition au cycler.
 | ||
| func (c *Cycler) Append(data string) {
 | ||
| 	c.data = append(c.data, data)
 | ||
| }
 | ||
| 
 | ||
| // Clear efface le cycler.
 | ||
| func (c *Cycler) Clear() {
 | ||
| 	c.data = c.data[:0]
 | ||
| 	c.cursor = -1
 | ||
| }
 | ||
| 
 | ||
| // Next incrémente le pointeur et retourne vrai
 | ||
| // si le pointeur pointe sur un élément.
 | ||
| func (c *Cycler) Next() (ok bool) {
 | ||
| 	n := c.cursor + 1
 | ||
| 	if ok = c.SetCursor(n); !ok && c.cycled {
 | ||
| 		ok = c.SetCursor(0)
 | ||
| 	}
 | ||
| 
 | ||
| 	return
 | ||
| }
 | ||
| 
 | ||
| // Prev décrémente le pointeur et retourne vrai
 | ||
| // si le pointeur pointe sur un élément.
 | ||
| func (c *Cycler) Prev() (ok bool) {
 | ||
| 	n := c.cursor - 1
 | ||
| 	if ok = n >= 0 && c.SetCursor(n); !ok && c.cycled {
 | ||
| 		ok = c.SetCursor(-1)
 | ||
| 	}
 | ||
| 
 | ||
| 	return
 | ||
| }
 | ||
| 
 | ||
| // NewCycler crée un nouveau cycler avec les données fournies.
 | ||
| // Si cycled est vrai, le cycler revient au début s’il a atteint la
 | ||
| // fin et inversement.
 | ||
| func NewCycler(cycled bool, data ...string) *Cycler {
 | ||
| 	return &Cycler{
 | ||
| 		data:   data,
 | ||
| 		cycled: cycled,
 | ||
| 		cursor: -1,
 | ||
| 	}
 | ||
| }
 | 
