package bookmarks import ( "encoding/json" "os" "path/filepath" ) // dataFile resolves ${XDG_DATA_HOME:-~/.local/share}/lectio/ -- the same // data-dir rule as the sigla store and the bookmarks file. func dataFile(name string) string { base := os.Getenv("XDG_DATA_HOME") if base == "" { home, err := os.UserHomeDir() if err != nil { home = "." } base = filepath.Join(home, ".local", "share") } return filepath.Join(base, "lectio", name) } // Place is the reader's last position, so the TUI reader can reopen where it // left off (book + chapter + the top-visible verse). type Place struct { Book string `json:"book"` // canonical English name (Bible-corpus key) Chapter int `json:"chapter"` Verse int `json:"verse"` } // SavePlace persists the reader's last position (atomic temp+rename). func SavePlace(p Place) error { path := dataFile("reader-place.json") if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { return err } data, err := json.MarshalIndent(p, "", " ") if err != nil { return err } tmp := path + ".tmp" if err := os.WriteFile(tmp, data, 0o644); err != nil { return err } return os.Rename(tmp, path) } // LoadPlace reads the reader's last position; ok is false when none is saved // (or the file names no book). func LoadPlace() (Place, bool, error) { data, err := os.ReadFile(dataFile("reader-place.json")) if err != nil { if os.IsNotExist(err) { return Place{}, false, nil } return Place{}, false, err } var p Place if err := json.Unmarshal(data, &p); err != nil { return Place{}, false, err } if p.Book == "" { return Place{}, false, nil } return p, true, nil }