mirror of
https://github.com/ThePrimeagen/harpoon.git
synced 2025-07-14 01:50:27 +00:00
149 lines
2.9 KiB
Lua
149 lines
2.9 KiB
Lua
local Path = require("plenary.path")
|
|
|
|
local data_path = vim.fn.stdpath("data")
|
|
|
|
---@param config HarpoonConfig
|
|
local filename = function(config)
|
|
return config.settings.key()
|
|
end
|
|
|
|
local function hash(path)
|
|
return vim.fn.sha256(path)
|
|
end
|
|
|
|
---@param config HarpoonConfig
|
|
local function fullpath(config)
|
|
local h = hash(filename(config))
|
|
return string.format("%s/%s.json", data_path, h)
|
|
end
|
|
|
|
---@param data any
|
|
---@param config HarpoonConfig
|
|
local function write_data(data, config)
|
|
Path:new(fullpath(config)):write(vim.json.encode(data), "w")
|
|
end
|
|
|
|
local M = {}
|
|
|
|
---@param config HarpoonConfig
|
|
function M.__dangerously_clear_data(config)
|
|
write_data({}, config)
|
|
end
|
|
|
|
function M.info()
|
|
return {
|
|
data_path = data_path,
|
|
}
|
|
end
|
|
|
|
--- @alias HarpoonRawData {[string]: {[string]: string[]}}
|
|
|
|
--- @class HarpoonData
|
|
--- @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
|
|
|
|
---@param config HarpoonConfig
|
|
---@param provided_path string?
|
|
---@return HarpoonRawData
|
|
local function read_data(config, provided_path)
|
|
provided_path = provided_path or fullpath(config)
|
|
local path = Path:new(provided_path)
|
|
local exists = path:exists()
|
|
|
|
if not exists then
|
|
write_data({}, config)
|
|
end
|
|
|
|
local out_data = path:read()
|
|
|
|
if not out_data or out_data == "" then
|
|
write_data({}, config)
|
|
out_data = "{}"
|
|
end
|
|
|
|
local data = vim.json.decode(out_data)
|
|
return data
|
|
end
|
|
|
|
---@param config HarpoonConfig
|
|
---@return HarpoonData
|
|
function Data:new(config)
|
|
local ok, data = pcall(read_data, config)
|
|
|
|
return setmetatable({
|
|
_data = data,
|
|
has_error = not ok,
|
|
}, 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
|
|
|
|
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
|
|
|
|
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
|
|
|
|
pcall(write_data, data)
|
|
end
|
|
|
|
M.Data = Data
|
|
M.test = {
|
|
set_fullpath = function(fp)
|
|
fullpath = fp
|
|
end,
|
|
|
|
read_data = read_data,
|
|
}
|
|
|
|
return M
|