From eafaec8a2ebd6620824dca3e712cd6225444eee4 Mon Sep 17 00:00:00 2001 From: mpaulson Date: Thu, 9 Nov 2023 08:46:05 -0700 Subject: [PATCH] feat: key for indexing --- HARPOON2.md | 86 +---------- lua/harpoon2/config.lua | 22 ++- lua/harpoon2/data.lua | 35 ++++- lua/harpoon2/init.lua | 33 +++-- lua/harpoon2/some.json | 228 ----------------------------- lua/harpoon2/test/harpoon_spec.lua | 33 +++-- lua/harpoon2/test/utils.lua | 11 ++ 7 files changed, 104 insertions(+), 344 deletions(-) delete mode 100644 lua/harpoon2/some.json diff --git a/HARPOON2.md b/HARPOON2.md index d282069..ed90f43 100644 --- a/HARPOON2.md +++ b/HARPOON2.md @@ -1,84 +1,8 @@ -### Features -* select how to generate the list key - -#### was -list_key = [cwd [+ git branch]] -* files -* terminals -* tmux - -#### is -list_key = [key] + [list_name] - -nil = default -false = turn off - -listA = { - listLine({ ... }) - { ... } - { ... } - { ... } -} - -harpoon.setup({ - - settings = { - jumpToFileLocation: boolean => defaults true - } - - default = { - // defaults to json.parse - encode = function(obj) => string - decode = function(string) => object - key = function() ... end - display = function(listLine) => string - select = function(listLine) => void - equals = function(list_line_a, list_line_b) => boolean - - # question mark: what does it take to support custom things in here? - # potentially subject to change - add = function() HarpoonListItem - } - - frecency = { - ... a file list that is generated by harpoon ... - ... can be opened via viewer ... - } - - events = { - on_change = function(operation, list, value) - } - - project = { - //key = vim.loop.cwd - key = git origin? - } - - specifics = { - key = vim.loop.cwd + git_branch - } - - list_name = { - key = function() ... end - } - -}) - -### Functionality -select by index -prev/next -addToBack -addToFront -checking for deleted files? -- perhaps this could be part of the default select operation and use error -select -- default file select should come with options so you can open split/tab as - well - -harpoon.current = "default" -harpoon.current = "listName" - -harpoon.set_current(list_name) +### TODO +* encode being false means no writing to disk +* bring over the ui from harpoon 1.0 +* autocmds for leaving buffer and quitteriousing vim +* write some tests around file moving within the display ### LATER FEATUERS frecency = later feature likely, but great idea diff --git a/lua/harpoon2/config.lua b/lua/harpoon2/config.lua index 8fc1659..b8f21a4 100644 --- a/lua/harpoon2/config.lua +++ b/lua/harpoon2/config.lua @@ -6,7 +6,6 @@ local M = {} ---@class HarpoonPartialConfigItem ---@field encode? (fun(list_item: HarpoonListItem): string) ---@field decode? (fun(obj: string): any) ----@field key? (fun(): string) ---@field display? (fun(list_item: HarpoonListItem): string) ---@field select? (fun(list_item: HarpoonListItem, options: any?): nil) ---@field equals? (fun(list_line_a: HarpoonListItem, list_line_b: HarpoonListItem): boolean) @@ -15,6 +14,13 @@ local M = {} ---@class HarpoonSettings ---@field save_on_toggle boolean defaults to true ---@field jump_to_file_location boolean defaults to true +---@field key (fun(): string) + +---@class HarpoonPartialSettings +---@field save_on_toggle? boolean +---@field jump_to_file_location? boolean +---@field key? (fun(): string) + ---@class HarpoonConfig ---@field default HarpoonPartialConfigItem @@ -22,8 +28,8 @@ local M = {} ---@field [string] HarpoonPartialConfigItem ---@class HarpoonPartialConfig ----@field default HarpoonPartialConfigItem? ----@field settings HarpoonSettings? +---@field default? HarpoonPartialConfigItem +---@field settings? HarpoonPartialSettings ---@field [string] HarpoonPartialConfigItem @@ -35,9 +41,13 @@ end ---@return HarpoonConfig function M.get_default_config() return { + settings = { save_on_toggle = true, jump_to_file_location = true, + key = function() + return vim.loop.cwd() + end, }, default = { @@ -53,10 +63,6 @@ function M.get_default_config() return vim.json.decode(str) end, - key = function() - return vim.loop.cwd() - end, - ---@param list_item HarpoonListItem display = function(list_item) return list_item.value @@ -99,7 +105,7 @@ function M.get_default_config() return list_item_a.value == list_item_b.value end, - ---@param value any + ---@param name any ---@return HarpoonListItem add = function(name) name = name or vim.api.nvim_buf_get_name(vim.api.nvim_get_current_buf()) diff --git a/lua/harpoon2/data.lua b/lua/harpoon2/data.lua index 6b4f04d..7050b89 100644 --- a/lua/harpoon2/data.lua +++ b/lua/harpoon2/data.lua @@ -32,10 +32,10 @@ local function has_keys(t) return false end ---- @alias HarpoonRawData {[string]: string[]} +--- @alias HarpoonRawData {[string]: {[string]: string[]}} --- @class HarpoonData ---- @field seen {[string]: boolean} +--- @field seen {[string]: {[string]: boolean}} --- @field _data HarpoonRawData --- @field has_error boolean local Data = {} @@ -51,6 +51,7 @@ Data.__index = Data local function read_data() local path = Path:new(full_data_path) local exists = path:exists() + if not exists then write_data({}) end @@ -68,25 +69,45 @@ function Data:new() has_error = not ok, seen = {} }, self) + end +---@param key string ---@param name string ---@return string[] -function Data:data(name) +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 - self.seen[name] = true - return self._data[name] or {} + + 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(name, values) +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._data[name] = values + self:_get_data(key, name) + self._data[key][name] = values end function Data:sync() diff --git a/lua/harpoon2/init.lua b/lua/harpoon2/init.lua index 83443a0..e700cbe 100644 --- a/lua/harpoon2/init.lua +++ b/lua/harpoon2/init.lua @@ -6,12 +6,14 @@ local List = require("harpoon2.list") -- read from a config file -- +-- TODO: rename lists into something better... + local DEFAULT_LIST = "__harpoon_files" ---@class Harpoon ---@field config HarpoonConfig ---@field data HarpoonData ----@field lists HarpoonList[] +---@field lists {[string]: {[string]: HarpoonList}} local Harpoon = {} Harpoon.__index = Harpoon @@ -39,25 +41,36 @@ end function Harpoon:list(name) name = name or DEFAULT_LIST - local existing_list = self.lists[name] + local key = self.config.settings.key() + local lists = self.lists[key] - if existing_list then - return self.lists[name] + if not lists then + lists = {} + self.lists[key] = lists end - local data = self.data:data(name) + local existing_list = lists[name] + + if existing_list then + return existing_list + end + + local data = self.data:data(key, name) local list_config = Config.get_config(self.config, name) local list = List.decode(list_config, name, data) - self.lists[name] = list + 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) + local key = self.config.settings.key() + local seen = self.data.seen[key] + local lists = self.lists[key] + for list_name, _ in pairs(seen) do + local encoded = lists[list_name]:encode() + self.data:update(key, list_name, encoded) end self.data:sync() end @@ -72,7 +85,7 @@ end function Harpoon:info() return { paths = Data.info(), - default_key = DEFAULT_LIST, + default_list_name = DEFAULT_LIST, } end diff --git a/lua/harpoon2/some.json b/lua/harpoon2/some.json deleted file mode 100644 index e9fa520..0000000 --- a/lua/harpoon2/some.json +++ /dev/null @@ -1,228 +0,0 @@ -{ - "key": [ - - nothuntoehuntoehuntoehuntoehuntoehun - oentuhnoteuhntoehuouenhtuoenhtuonhtuoenhtuoenht 0,nthouenhtouenthoue - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - - 1, - 3, - 5, - 7, - 9, - 11, - 13, - 15, - 17, - 19, - 21, - 23, - - 2, - 5, - 8, - 11, - 14, - 17, - 20, - 23, - 26, - 29, - 32, - 35, - - 3, - 7, - 11, - 15, - 19, - 23, - 27, - 31, - 35, - 39, - 43, - 47, - - 4, - 9, - 14, - 19, - 24, - 29, - 34, - 39, - 44, - 49, - 54, - 59, - - 5, - 11, - 17, - 23, - 29, - 35, - 41, - 47, - 53, - 59, - 65, - 71, - - 6, - 13, - 20, - 27, - 34, - 41, - 48, - 55, - 62, - 69, - 76, - 83, - - 7, - 15, - 23, - 31, - 39, - 47, - 55, - 63, - 71, - 79, - 87, - 95, - - 8, - 17, - 26, - 35, - 44, - 53, - 62, - 71, - 80, - 89, - 98, - 107, - - 9, - 19, - 29, - 39, - 49, - 59, - 69, - 79, - 89, - 99, - 109, - 119, - - 10, - 21, - 32, - 43, - 54, - 65, - 76, - 87, - 98, - 109, - 120, - 131, - - 11, - 23, - 35, - 47, - 59, - 71, - 83, - 95, - 107, - 119, - 131, - 143, - - 12, - 25, - 38, - 51, - 64, - 77, - 90, - 103, - 116, - 129, - 142, - 155, - - 13, - 27, - 41, - 55, - 69, - 83, - 97, - 111, - 125, - 139, - 153, - 167, - - 14, - 29, - 44, - 59, - 74, - 89, - 104, - 119, - 134, - 149, - 164, - 179, - - 15, - 31, - 47, - 63, - 79, - 95, - 111, - 127, - 143, - 159, - 175, - 191, - - 16, - 33, - 50, - 67, - 84, - 101, - 118, - 135, - 152, - 169, - 186, - 203, - - ] -} - diff --git a/lua/harpoon2/test/harpoon_spec.lua b/lua/harpoon2/test/harpoon_spec.lua index 60f1cb9..02670b3 100644 --- a/lua/harpoon2/test/harpoon_spec.lua +++ b/lua/harpoon2/test/harpoon_spec.lua @@ -13,14 +13,24 @@ describe("harpoon", function() Data = require("harpoon2.data") Data.set_data_path("/tmp/harpoon2.json") harpoon = require("harpoon2") + utils.clean_files() + + harpoon:setup({ + settings = { + key = function() + return "testies" + end + } + }) + end) it("full harpoon add sync cycle", function() local file_name = "/tmp/harpoon-test" local row = 3 local col = 1 - local default_key = harpoon:info().default_key - local bufnr = utils.create_file(file_name, { + local default_list_name = harpoon:info().default_list_name + utils.create_file(file_name, { "foo", "bar", "baz", @@ -31,12 +41,14 @@ describe("harpoon", function() harpoon:sync() eq(harpoon:dump(), { - [default_key] = list:encode() + testies = { + [default_list_name] = list:encode() + } }) end) it("prepend/append double add", function() - local default_key = harpoon:info().default_key + local default_list_name = harpoon:info().default_list_name local file_name_1 = "/tmp/harpoon-test" local row_1 = 3 local col_1 = 1 @@ -56,7 +68,9 @@ describe("harpoon", function() harpoon:sync() eq(harpoon:dump(), { - [default_key] = list:encode() + testies = { + [default_list_name] = list:encode() + } }) eq(list.items, { @@ -154,23 +168,22 @@ describe("harpoon", function() list:resolve_displayed(displayed) - eq(list.items, { + eq({ {value = file_names[1], context = {row = 4, col = 2}}, {value = file_names[4], context = {row = 4, col = 2}}, {value = "/tmp/harpoon-test-other-file-1", context = {row = 1, col = 0}}, {value = "/tmp/harpoon-test-other-file-2", context = {row = 1, col = 0}}, - }) + }, list.items) table.remove(displayed, 3) table.insert(displayed, "/tmp/harpoon-test-4") list:resolve_displayed(displayed) - eq(list.items, { + eq({ {value = file_names[1], context = {row = 4, col = 2}}, {value = file_names[4], context = {row = 4, col = 2}}, {value = "/tmp/harpoon-test-other-file-2", context = {row = 1, col = 0}}, - }) + }, list.items) end) end) - diff --git a/lua/harpoon2/test/utils.lua b/lua/harpoon2/test/utils.lua index e40b3bf..ecee9c1 100644 --- a/lua/harpoon2/test/utils.lua +++ b/lua/harpoon2/test/utils.lua @@ -1,6 +1,16 @@ local M = {} +M.created_files = {} + +function M.clean_files() + for _, bufnr in ipairs(M.created_files) do + vim.api.nvim_buf_delete(bufnr, {force = true}) + end + + M.created_files = {} +end + ---@param name string ---@param contents string[] function M.create_file(name, contents, row, col) @@ -11,6 +21,7 @@ function M.create_file(name, contents, row, col) vim.api.nvim_win_set_cursor(0, {row, col}) end + table.insert(M.created_files, bufnr) return bufnr end