package main import ( "errors" "io/fs" "os" "path/filepath" "strings" rt "github.com/arnodel/golua/runtime" ) type luaHistory struct {} func (h *luaHistory) Write(line string) (int, error) { histWrite := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("add")) ln, err := rt.Call1(l.MainThread(), histWrite, rt.StringValue(line)) var num int64 if ln.Type() == rt.IntType { num = ln.AsInt() } return int(num), err } func (h *luaHistory) GetLine(idx int) (string, error) { histGet := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("get")) lcmd, err := rt.Call1(l.MainThread(), histGet, rt.IntValue(int64(idx))) var cmd string if lcmd.Type() == rt.StringType { cmd = lcmd.AsString() } return cmd, err } func (h *luaHistory) Len() int { histSize := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("size")) ln, _ := rt.Call1(l.MainThread(), histSize) var num int64 if ln.Type() == rt.IntType { num = ln.AsInt() } return int(num) } func (h *luaHistory) Dump() interface{} { // hilbish.history interface already has all function, this isnt used in readline return nil } type fileHistory struct { items []string f *os.File } func newFileHistory(path string) *fileHistory { dir := filepath.Dir(path) err := os.MkdirAll(dir, 0755) if err != nil { panic(err) } data, err := os.ReadFile(path) if err != nil { if !errors.Is(err, fs.ErrNotExist) { panic(err) } } lines := strings.Split(string(data), "\n") itms := make([]string, len(lines) - 1) for i, l := range lines { if i == len(lines) - 1 { continue } itms[i] = l } f, err := os.OpenFile(path, os.O_APPEND | os.O_WRONLY | os.O_CREATE, 0755) if err != nil { panic(err) } fh := &fileHistory{ items: itms, f: f, } return fh } func (h *fileHistory) Write(line string) (int, error) { if line == "" { return len(h.items), nil } _, err := h.f.WriteString(line + "\n") if err != nil { return 0, err } h.f.Sync() h.items = append(h.items, line) return len(h.items), nil } func (h *fileHistory) GetLine(idx int) (string, error) { if len(h.items) == 0 { return "", nil } if idx == -1 { // this should be fixed readline side return "", nil } return h.items[idx], nil } func (h *fileHistory) Len() int { return len(h.items) } func (h *fileHistory) Dump() interface{} { return h.items } func (h *fileHistory) clear() { h.items = []string{} h.f.Truncate(0) h.f.Sync() }