mirror of
https://github.com/ThePrimeagen/harpoon.git
synced 2025-07-14 10:00:29 +00:00
147 lines
2.7 KiB
Lua
147 lines
2.7 KiB
Lua
local Path = require("plenary.path")
|
|
|
|
local data_path = vim.fn.stdpath("data")
|
|
local full_data_path = string.format("%s/harpoon2.json", data_path)
|
|
|
|
---@param data any
|
|
local function write_data(data)
|
|
Path:new(full_data_path):write(vim.json.encode(data), "w")
|
|
end
|
|
|
|
local M = {}
|
|
|
|
function M.__dangerously_clear_data()
|
|
write_data({})
|
|
end
|
|
|
|
function M.info()
|
|
return {
|
|
data_path = data_path,
|
|
full_data_path = full_data_path,
|
|
}
|
|
end
|
|
|
|
function M.set_data_path(path)
|
|
full_data_path = path
|
|
end
|
|
|
|
local function has_keys(t)
|
|
|
|
-- luacheck: ignore 512
|
|
for _ in pairs(t) do
|
|
return true
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
--- @alias HarpoonRawData {[string]: {[string]: string[]}}
|
|
|
|
--- @class HarpoonData
|
|
--- @field seen {[string]: {[string]: boolean}}
|
|
--- @field _data HarpoonRawData
|
|
--- @field has_error boolean
|
|
local Data = {}
|
|
|
|
-- 1. load the data
|
|
-- 2. keep track of the lists requested
|
|
-- 3. sync save
|
|
|
|
Data.__index = Data
|
|
|
|
---@return HarpoonRawData
|
|
local function read_data()
|
|
local path = Path:new(full_data_path)
|
|
local exists = path:exists()
|
|
|
|
if not exists then
|
|
write_data({})
|
|
end
|
|
|
|
local out_data = path:read()
|
|
local data = vim.json.decode(out_data)
|
|
return data
|
|
end
|
|
|
|
---@return HarpoonData
|
|
function Data:new()
|
|
local ok, data = pcall(read_data)
|
|
|
|
return setmetatable({
|
|
_data = data,
|
|
has_error = not ok,
|
|
seen = {},
|
|
}, self)
|
|
end
|
|
|
|
---@param key string
|
|
---@param name string
|
|
---@return string[]
|
|
function Data:_get_data(key, name)
|
|
if not self._data[key] then
|
|
self._data[key] = {}
|
|
end
|
|
|
|
return self._data[key][name] or {}
|
|
end
|
|
|
|
---@param key string
|
|
---@param name string
|
|
---@return string[]
|
|
function Data:data(key, name)
|
|
if self.has_error then
|
|
error(
|
|
"Harpoon: there was an error reading the data file, cannot read data"
|
|
)
|
|
end
|
|
|
|
if not self.seen[key] then
|
|
self.seen[key] = {}
|
|
end
|
|
|
|
self.seen[key][name] = true
|
|
|
|
return self:_get_data(key, name)
|
|
end
|
|
|
|
---@param name string
|
|
---@param values string[]
|
|
function Data:update(key, name, values)
|
|
if self.has_error then
|
|
error(
|
|
"Harpoon: there was an error reading the data file, cannot update"
|
|
)
|
|
end
|
|
self:_get_data(key, name)
|
|
self._data[key][name] = values
|
|
end
|
|
|
|
function Data:sync()
|
|
if self.has_error then
|
|
return
|
|
end
|
|
|
|
if not has_keys(self.seen) then
|
|
return
|
|
end
|
|
|
|
local ok, data = pcall(read_data)
|
|
if not ok then
|
|
error("Harpoon: unable to sync data, error reading data file")
|
|
end
|
|
|
|
for k, v in pairs(self._data) do
|
|
data[k] = v
|
|
end
|
|
|
|
ok = pcall(write_data, data)
|
|
|
|
if ok then
|
|
self.seen = {}
|
|
end
|
|
end
|
|
|
|
M.Data = Data
|
|
|
|
return M
|