ollama

Форк
0
/
history.go 
155 строк · 2.3 Кб
1
package readline
2

3
import (
4
	"bufio"
5
	"errors"
6
	"io"
7
	"os"
8
	"path/filepath"
9
	"strings"
10

11
	"github.com/emirpasic/gods/lists/arraylist"
12
)
13

14
type History struct {
15
	Buf      *arraylist.List
16
	Autosave bool
17
	Pos      int
18
	Limit    int
19
	Filename string
20
	Enabled  bool
21
}
22

23
func NewHistory() (*History, error) {
24
	h := &History{
25
		Buf:      arraylist.New(),
26
		Limit:    100, // resizeme
27
		Autosave: true,
28
		Enabled:  true,
29
	}
30

31
	err := h.Init()
32
	if err != nil {
33
		return nil, err
34
	}
35

36
	return h, nil
37
}
38

39
func (h *History) Init() error {
40
	home, err := os.UserHomeDir()
41
	if err != nil {
42
		return err
43
	}
44

45
	path := filepath.Join(home, ".ollama", "history")
46
	if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
47
		return err
48
	}
49

50
	h.Filename = path
51

52
	f, err := os.OpenFile(path, os.O_CREATE|os.O_RDONLY, 0o600)
53
	if err != nil {
54
		if errors.Is(err, os.ErrNotExist) {
55
			return nil
56
		}
57
		return err
58
	}
59
	defer f.Close()
60

61
	r := bufio.NewReader(f)
62
	for {
63
		line, err := r.ReadString('\n')
64
		if err != nil {
65
			if err == io.EOF {
66
				break
67
			}
68
			return err
69
		}
70

71
		line = strings.TrimSpace(line)
72
		if len(line) == 0 {
73
			continue
74
		}
75

76
		h.Add([]rune(line))
77
	}
78

79
	return nil
80
}
81

82
func (h *History) Add(l []rune) {
83
	h.Buf.Add(l)
84
	h.Compact()
85
	h.Pos = h.Size()
86
	if h.Autosave {
87
		_ = h.Save()
88
	}
89
}
90

91
func (h *History) Compact() {
92
	s := h.Buf.Size()
93
	if s > h.Limit {
94
		for cnt := 0; cnt < s-h.Limit; cnt++ {
95
			h.Buf.Remove(0)
96
		}
97
	}
98
}
99

100
func (h *History) Clear() {
101
	h.Buf.Clear()
102
}
103

104
func (h *History) Prev() []rune {
105
	var line []rune
106
	if h.Pos > 0 {
107
		h.Pos -= 1
108
	}
109
	v, _ := h.Buf.Get(h.Pos)
110
	line, _ = v.([]rune)
111
	return line
112
}
113

114
func (h *History) Next() []rune {
115
	var line []rune
116
	if h.Pos < h.Buf.Size() {
117
		h.Pos += 1
118
		v, _ := h.Buf.Get(h.Pos)
119
		line, _ = v.([]rune)
120
	}
121
	return line
122
}
123

124
func (h *History) Size() int {
125
	return h.Buf.Size()
126
}
127

128
func (h *History) Save() error {
129
	if !h.Enabled {
130
		return nil
131
	}
132

133
	tmpFile := h.Filename + ".tmp"
134

135
	f, err := os.OpenFile(tmpFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC|os.O_APPEND, 0o600)
136
	if err != nil {
137
		return err
138
	}
139
	defer f.Close()
140

141
	buf := bufio.NewWriter(f)
142
	for cnt := 0; cnt < h.Size(); cnt++ {
143
		v, _ := h.Buf.Get(cnt)
144
		line, _ := v.([]rune)
145
		buf.WriteString(string(line) + "\n")
146
	}
147
	buf.Flush()
148
	f.Close()
149

150
	if err = os.Rename(tmpFile, h.Filename); err != nil {
151
		return err
152
	}
153

154
	return nil
155
}
156

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.