99 lines
1.8 KiB
Go
99 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,
|
||
}
|
||
}
|