mirror of
https://github.com/ThePrimeagen/harpoon.git
synced 2025-07-14 01:50:27 +00:00
feat: key for indexing
This commit is contained in:
parent
e08020477a
commit
eafaec8a2e
86
HARPOON2.md
86
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
|
||||
|
@ -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())
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
|
||||
]
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user