gob/shell/console/atom/history.go

118 lines
2.3 KiB
Go
Raw Normal View History

2023-10-07 19:13:39 +00:00
package atom
import (
"bufio"
"fmt"
"io"
"unicode/utf8"
"gitea.zaclys.com/bvaudour/gob/option"
)
// History stocke lhistorique des saisies.
type History struct {
Cycler
}
// Append ajoute une entrée dans lhistorique.
func (h *History) Append(data string) {
h.Cycler.Append(data)
h.cursor = h.Len()
}
// Clear efface lhistorique.
func (h *History) Clear() {
h.Cycler.Clear()
h.cursor = 0
}
// SetCursor positionne le pointeur de lhistorique.
func (h *History) SetCursor(n int) (ok bool) {
l := h.Len()
if ok = n >= -1 && n <= l; ok {
h.cursor = n
}
return
}
// Next incrémente le pointeur de lhistorique
// et retourne vrai si le pointeur pointe vers un élément.
func (h *History) Next() (ok bool) {
if ok = h.SetCursor(h.cursor + 1); ok {
ok = isCursorValid(h.cursor, h.Len())
} else if h.cycled {
ok = h.SetCursor(0)
}
return
}
// Prev décrémente le pointeur de lhistorique
// et retourne vrai si le pointeur pointe vers un élément.
func (h *History) Prev() (ok bool) {
if ok = h.SetCursor(h.cursor - 1); ok {
ok = isCursorValid(h.cursor, h.Len())
} else if l := h.Len(); h.cycled && l > 0 {
ok = h.SetCursor(l - 1)
}
return
}
// Read charge lhistorique à partir dun fichier
// et retourne le nombre dentrées ajoutées.
func (h *History) Read(r io.Reader) option.Result[int] {
var n int
buf := bufio.NewReader(r)
for {
line, part, err := buf.ReadLine()
if err == nil {
if part {
err = fmt.Errorf("line %d is too long", n+1)
} else if !utf8.Valid(line) {
err = fmt.Errorf("invalid string at line %d", n+1)
} else {
h.Append(string(line))
n++
}
}
if err != nil {
if err == io.EOF {
break
}
return option.Err[int](err)
}
}
return option.Ok(n)
}
// Write persiste lhistorique dans un fichier
// et retourne le nombre dentrées ajoutées.
func (h *History) Write(w io.Writer) option.Result[int] {
var n int
for _, item := range h.data {
_, err := fmt.Fprintln(w, item)
if err != nil {
return option.Err[int](err)
}
n++
}
return option.Ok(n)
}
// NewHistory retourne un nouvel historique.
// Si cycled est faux lhistorique ne peut être parcouru en boucle.
func NewHistory(cycled bool) *History {
var h History
h.cycled = cycled
return &h
}