feat: key for indexing

This commit is contained in:
mpaulson 2023-11-09 08:46:05 -07:00
parent e08020477a
commit eafaec8a2e
7 changed files with 104 additions and 344 deletions

View File

@ -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

View File

@ -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())

View File

@ -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()

View File

@ -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

View File

@ -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,
]
}

View File

@ -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)

View File

@ -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