diff --git a/lua/harpoon/init.lua b/lua/harpoon/init.lua deleted file mode 100644 index dc6e7b7..0000000 --- a/lua/harpoon/init.lua +++ /dev/null @@ -1,41 +0,0 @@ -local Data = require("harpoon.data") -local Config = require("harpoon.config") - --- setup --- read from a config file --- - -local DEFAULT_LIST = "__harpoon_files" - ----@class Harpoon ----@field config HarpoonConfig ----@field data Data -local Harpoon = {} - -Harpoon.__index = Harpoon - ----@return Harpoon -function Harpoon:new() - local config = Config.get_default_config() - - return setmetatable({ - config = config, - data = Data:new() - }, self) -end - ----@param partial_config HarpoonPartialConfig ----@return Harpoon -function Harpoon:setup(partial_config) - self.config = Config.merge_config(partial_config, self.config) - return self -end - ----@param list string? ----@return HarpoonList -function Harpoon:list(name) - name = name or DEFAULT_LIST -end - -return Harpoon:new() - diff --git a/lua/harpoon/config.lua b/lua/harpoon2/config.lua similarity index 100% rename from lua/harpoon/config.lua rename to lua/harpoon2/config.lua diff --git a/lua/harpoon/data.lua b/lua/harpoon2/data.lua similarity index 71% rename from lua/harpoon/data.lua rename to lua/harpoon2/data.lua index 2d07d1e..6b4f04d 100644 --- a/lua/harpoon/data.lua +++ b/lua/harpoon2/data.lua @@ -3,8 +3,24 @@ 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 @@ -16,33 +32,34 @@ local function has_keys(t) return false end ---- @alias RawData {[string]: string[]} +--- @alias HarpoonRawData {[string]: string[]} ---- @class Data +--- @class HarpoonData --- @field seen {[string]: boolean} ---- @field _data RawData +--- @field _data HarpoonRawData --- @field has_error boolean +local Data = {} -- 1. load the data -- 2. keep track of the lists requested -- 3. sync save -local Data = {} - Data.__index = Data ----@param data any -local function write_data(data) - Path:new(full_data_path):write_data(vim.json.encode(data)) -end - ----@return RawData +---@return HarpoonRawData local function read_data() - return vim.json.decode(Path:new(full_data_path):read()) + local path = Path:new(full_data_path) + local exists = path:exists() + if not exists then + write_data({}) + end + + local data = vim.json.decode(path:read()) + return data end ----@return Harpoon +---@return HarpoonData function Data:new() local ok, data = pcall(read_data) @@ -59,6 +76,7 @@ function Data:data(name) if self.has_error then error("Harpoon: there was an error reading the data file, cannot read data") end + self.seen[name] = true return self._data[name] or {} end @@ -68,7 +86,6 @@ function Data:update(name, values) if self.has_error then error("Harpoon: there was an error reading the data file, cannot update") end - self.seen[name] = true self._data[name] = values end @@ -90,11 +107,14 @@ function Data:sync() data[k] = v end - pcall(write_data, data) + ok = pcall(write_data, data) + + if ok then + self.seen = {} + end end M.Data = Data return M - diff --git a/lua/harpoon2/init.lua b/lua/harpoon2/init.lua new file mode 100644 index 0000000..83443a0 --- /dev/null +++ b/lua/harpoon2/init.lua @@ -0,0 +1,86 @@ +local Data = require("harpoon2.data") +local Config = require("harpoon2.config") +local List = require("harpoon2.list") + +-- setup +-- read from a config file +-- + +local DEFAULT_LIST = "__harpoon_files" + +---@class Harpoon +---@field config HarpoonConfig +---@field data HarpoonData +---@field lists HarpoonList[] +local Harpoon = {} + +Harpoon.__index = Harpoon + +---@return Harpoon +function Harpoon:new() + local config = Config.get_default_config() + + return setmetatable({ + config = config, + data = Data.Data:new(), + lists = {}, + }, self) +end + +---@param partial_config HarpoonPartialConfig +---@return Harpoon +function Harpoon:setup(partial_config) + self.config = Config.merge_config(partial_config, self.config) + return self +end + +---@param name string? +---@return HarpoonList +function Harpoon:list(name) + name = name or DEFAULT_LIST + + local existing_list = self.lists[name] + + if existing_list then + return self.lists[name] + end + + local data = self.data:data(name) + local list_config = Config.get_config(self.config, name) + + local list = List.decode(list_config, name, data) + self.lists[name] = list + + return list +end + +function Harpoon:sync() + for k, _ in pairs(self.data.seen) do + local encoded = self.lists[k]:encode() + self.data:update(k, encoded) + end + self.data:sync() +end + +function Harpoon:setup_hooks() + -- setup the autocommands + -- vim exits sync data + -- buf exit setup the cursor location + error("I haven't implemented this yet") +end + +function Harpoon:info() + return { + paths = Data.info(), + default_key = DEFAULT_LIST, + } +end + +--- PLEASE DONT USE THIS OR YOU WILL BE FIRED +function Harpoon:dump() + return self.data._data +end + +return Harpoon:new() + + diff --git a/lua/harpoon/list.lua b/lua/harpoon2/list.lua similarity index 72% rename from lua/harpoon/list.lua rename to lua/harpoon2/list.lua index 7874dd7..3c22198 100644 --- a/lua/harpoon/list.lua +++ b/lua/harpoon2/list.lua @@ -1,5 +1,3 @@ -local get_config = require "harpoon.config".get_config - -- TODO: Define the config object --- @class HarpoonItem @@ -8,7 +6,7 @@ local get_config = require "harpoon.config".get_config --- create a table object to be new'd --- @class HarpoonList ---- @field config any +--- @field config HarpoonPartialConfigItem --- @field name string --- @field items HarpoonItem[] local HarpoonList = {} @@ -22,25 +20,35 @@ function HarpoonList:new(config, name, items) }, self) end +---@return HarpoonList function HarpoonList:push(item) + item = item or self.config.add() table.insert(self.items, item) + return self end +---@return HarpoonList function HarpoonList:addToFront(item) + item = item or self.config.add() table.insert(self.items, 1, item) + return self end +---@return HarpoonList function HarpoonList:remove(item) for i, v in ipairs(self.items) do - if get_config(self.config, self.name)(v, item) then + if self.config.equals(v, item) then table.remove(self.items, i) break end end + return self end +---@return HarpoonList function HarpoonList:removeAt(index) table.remove(self.items, index) + return self end function HarpoonList:get(index) @@ -51,12 +59,11 @@ end ---@param displayed string[] function HarpoonList:resolve_displayed(displayed) local not_found = {} - local config = get_config(self.config, self.name) for _, v in ipairs(displayed) do local found = false for _, in_table in ipairs(self.items) do - if config.display(in_table) == v then + if self.config.display(in_table) == v then found = true break end @@ -75,9 +82,8 @@ end --- @return string[] function HarpoonList:display() local out = {} - local config = get_config(self.config, self.name) for _, v in ipairs(self.items) do - table.insert(out, config.display(v)) + table.insert(out, self.config.display(v)) end return out @@ -86,27 +92,25 @@ end --- @return string[] function HarpoonList:encode() local out = {} - local config = get_config(self.config, self.name) for _, v in ipairs(self.items) do - table.insert(out, config.encode(v)) + table.insert(out, self.config.encode(v)) end return out end --- @return HarpoonList ---- @param config HarpoonConfig +--- @param list_config HarpoonPartialConfigItem --- @param name string --- @param items string[] -function HarpoonList.decode(config, name, items) +function HarpoonList.decode(list_config, name, items) local list_items = {} - local c = get_config(config, name) for _, item in ipairs(items) do - table.insert(list_items, c.decode(item)) + table.insert(list_items, list_config.decode(item)) end - return HarpoonList:new(config, name, list_items) + return HarpoonList:new(list_config, name, list_items) end diff --git a/lua/harpoon/some.json b/lua/harpoon2/some.json similarity index 100% rename from lua/harpoon/some.json rename to lua/harpoon2/some.json diff --git a/lua/harpoon/test/config_spec.lua b/lua/harpoon2/test/config_spec.lua similarity index 89% rename from lua/harpoon/test/config_spec.lua rename to lua/harpoon2/test/config_spec.lua index b0e9e14..c81f99e 100644 --- a/lua/harpoon/test/config_spec.lua +++ b/lua/harpoon2/test/config_spec.lua @@ -1,5 +1,5 @@ -local List = require("harpoon.list") -local Config = require("harpoon.config") +local List = require("harpoon2.list") +local Config = require("harpoon2.config") local eq = assert.are.same describe("config", function() @@ -10,7 +10,6 @@ describe("config", function() local bufnr = vim.fn.bufnr("/tmp/harpoon-test", true) vim.api.nvim_set_current_buf(bufnr) - vim.api.nvim_buf_set_text(0, 0, 0, 0, 0, { "foo", "bar", diff --git a/lua/harpoon2/test/harpoon_spec.lua b/lua/harpoon2/test/harpoon_spec.lua new file mode 100644 index 0000000..e409a25 --- /dev/null +++ b/lua/harpoon2/test/harpoon_spec.lua @@ -0,0 +1,41 @@ +local Data = require("harpoon2.data") +local harpoon = require("harpoon2") + +local eq = assert.are.same + +describe("harpoon", function() + + before_each(function() + Data.set_data_path("/tmp/harpoon2.json") + Data.__dangerously_clear_data() + require("plenary.reload").reload_module("harpoon2") + Data = require("harpoon2.data") + Data.set_data_path("/tmp/harpoon2.json") + harpoon = require("harpoon2") + end) + + it("full harpoon add sync cycle", function() + local file_name = "/tmp/harpoon-test" + local row = 3 + local col = 1 + local bufnr = vim.fn.bufnr(file_name, true) + local default_key = harpoon:info().default_key + vim.api.nvim_set_current_buf(bufnr) + vim.api.nvim_buf_set_text(0, 0, 0, 0, 0, { + "foo", + "bar", + "baz", + "qux" + }) + vim.api.nvim_win_set_cursor(0, {row, col}) + + local list = harpoon:list():push() + harpoon:sync() + + eq(harpoon:dump(), { + [default_key] = list:encode() + }) + end) +end) + + diff --git a/lua/harpoon/test/list_spec.lua b/lua/harpoon2/test/list_spec.lua similarity index 90% rename from lua/harpoon/test/list_spec.lua rename to lua/harpoon2/test/list_spec.lua index ef6ef7b..4ef8627 100644 --- a/lua/harpoon/test/list_spec.lua +++ b/lua/harpoon2/test/list_spec.lua @@ -1,5 +1,5 @@ -local List = require("harpoon.list") -local Config = require("harpoon.config") +local List = require("harpoon2.list") +local Config = require("harpoon2.config") local eq = assert.are.same describe("list", function()