feat: closes #542 : out of bounds navigation. this was a pain in the ass

This commit is contained in:
theprimeagen 2024-04-04 10:58:56 -06:00
parent 77d52b2a88
commit 5b344710b7
7 changed files with 113 additions and 17 deletions

View File

@ -16,6 +16,7 @@ local function get_harpoon_menu_name()
end end
function M.run_select_command() function M.run_select_command()
---@type Harpoon
local harpoon = require("harpoon") local harpoon = require("harpoon")
harpoon.logger:log("select by keymap '<CR>'") harpoon.logger:log("select by keymap '<CR>'")
harpoon.ui:select_menu_item() harpoon.ui:select_menu_item()

View File

@ -100,11 +100,12 @@ function M.get_default_config()
list.name, list.name,
options options
) )
options = options or {}
if list_item == nil then if list_item == nil then
return return
end end
options = options or {}
local bufnr = vim.fn.bufnr(to_exact_name(list_item.value)) local bufnr = vim.fn.bufnr(to_exact_name(list_item.value))
local set_position = false local set_position = false
if bufnr == -1 then -- must create a buffer! if bufnr == -1 then -- must create a buffer!
@ -130,10 +131,33 @@ function M.get_default_config()
vim.api.nvim_set_current_buf(bufnr) vim.api.nvim_set_current_buf(bufnr)
if set_position then if set_position then
local lines = vim.api.nvim_buf_line_count(bufnr)
local edited = false
if list_item.context.row > lines then
list_item.context.row = lines
edited = true
end
local row = list_item.context.row
local row_text = vim.api.nvim_buf_get_lines(0, row - 1, row, false)
local col = #row_text[1]
if list_item.context.col > col then
list_item.context.col = col
edited = true
end
vim.api.nvim_win_set_cursor(0, { vim.api.nvim_win_set_cursor(0, {
list_item.context.row or 1, list_item.context.row or 1,
list_item.context.col or 0, list_item.context.col or 0,
}) })
if edited then
Extensions.extensions:emit(Extensions.event_names.POSITION_UPDATED, {
list_item = list_item
})
end
end end
Extensions.extensions:emit(Extensions.event_names.NAVIGATE, { Extensions.extensions:emit(Extensions.event_names.NAVIGATE, {
@ -192,6 +216,8 @@ function M.get_default_config()
} }
end, end,
---@param arg {buf: number}
---@param list HarpoonList
BufLeave = function(arg, list) BufLeave = function(arg, list)
local bufnr = arg.buf local bufnr = arg.buf
local bufname = vim.api.nvim_buf_get_name(bufnr) local bufname = vim.api.nvim_buf_get_name(bufnr)

View File

@ -135,7 +135,7 @@ end
local the_harpoon = Harpoon:new() local the_harpoon = Harpoon:new()
---@param self Harpoon ---@param self Harpoon
---@param partial_config HarpoonPartialConfig ---@param partial_config HarpoonPartialConfig?
---@return Harpoon ---@return Harpoon
function Harpoon.setup(self, partial_config) function Harpoon.setup(self, partial_config)
if self ~= the_harpoon then if self ~= the_harpoon then

View File

@ -226,7 +226,7 @@ end
function HarpoonList:get_by_display(name) function HarpoonList:get_by_display(name)
local displayed = self:display() local displayed = self:display()
local index = index_of(displayed, #displayed, name, self.config) local index = index_of(displayed, #displayed, name)
if index == -1 then if index == -1 then
return nil return nil
end end

View File

@ -1,5 +1,9 @@
local utils = require("harpoon.test.utils") local utils = require("harpoon.test.utils")
local logger = require("harpoon.logger")
---@type Harpoon
local harpoon = require("harpoon") local harpoon = require("harpoon")
local Extensions = require("harpoon.extensions") local Extensions = require("harpoon.extensions")
local Config = require("harpoon.config") local Config = require("harpoon.config")
local Data = require("harpoon.data") local Data = require("harpoon.data")
@ -19,9 +23,43 @@ local function expect_data(data)
end end
end end
---@param out {row: number, col: number}
---@param expected {row: number, col: number}
local function out_of_bounds_test(out, expected)
local file_name = "/tmp/harpoon-test"
local list = harpoon:list()
local to_unload = utils.create_file(file_name, {
"foo",
"bar",
"baz",
"qux",
})
list:add()
utils.create_file(file_name .. "2", {
"foo",
"bar",
"baz",
"qux",
})
vim.api.nvim_buf_delete(to_unload, {force = true})
-- i have to force it to be out of bounds
list.items[1].context = out
harpoon:list():select(1)
eq({
{ value = file_name, context = expected}
}, harpoon:list().items)
end
describe("harpoon", function() describe("harpoon", function()
before_each(function() before_each(function()
be() be()
logger:clear()
harpoon = require("harpoon") harpoon = require("harpoon")
end) end)
@ -85,6 +123,36 @@ describe("harpoon", function()
}) })
end) end)
it("out of bounds test: row over", function()
out_of_bounds_test({
row = 5,
col = 3
}, {
row = 4,
col = 3
})
end)
it("out of bounds test: col over", function()
out_of_bounds_test({
row = 4,
col = 4
}, {
row = 4,
col = 3
})
end)
it("out of bounds test: both over", function()
out_of_bounds_test({
row = 5,
col = 4
}, {
row = 4,
col = 3
})
end)
it("prepend/add double add", function() it("prepend/add double add", function()
local file_name_1 = "/tmp/harpoon-test" local file_name_1 = "/tmp/harpoon-test"
local row_1 = 3 local row_1 = 3

View File

@ -5,15 +5,6 @@ local harpoon = require("harpoon")
local eq = assert.are.same local eq = assert.are.same
local be = utils.before_each(os.tmpname()) local be = utils.before_each(os.tmpname())
---@param k string
local function key(k)
vim.api.nvim_feedkeys(
vim.api.nvim_replace_termcodes(k, true, false, true),
"x",
true
)
end
describe("harpoon", function() describe("harpoon", function()
before_each(function() before_each(function()
be() be()
@ -100,7 +91,7 @@ describe("harpoon", function()
harpoon.ui:toggle_quick_menu(harpoon:list()) harpoon.ui:toggle_quick_menu(harpoon:list())
key("<CR>") utils.key("<CR>")
eq(3, harpoon:list():length()) eq(3, harpoon:list():length())
eq({ eq({
@ -155,7 +146,7 @@ describe("harpoon", function()
eq(vim.api.nvim_win_is_valid(win_id), true) eq(vim.api.nvim_win_is_valid(win_id), true)
eq(vim.api.nvim_get_current_buf(), bufnr) eq(vim.api.nvim_get_current_buf(), bufnr)
key("<C-w><C-w>") utils.key("<C-w><C-w>")
eq(vim.api.nvim_buf_is_valid(bufnr), false) eq(vim.api.nvim_buf_is_valid(bufnr), false)
eq(vim.api.nvim_win_is_valid(win_id), false) eq(vim.api.nvim_win_is_valid(win_id), false)
@ -173,7 +164,7 @@ describe("harpoon", function()
eq(vim.api.nvim_win_is_valid(win_id), true) eq(vim.api.nvim_win_is_valid(win_id), true)
eq(vim.api.nvim_get_current_buf(), bufnr) eq(vim.api.nvim_get_current_buf(), bufnr)
key("q") utils.key("q")
eq(vim.api.nvim_buf_is_valid(bufnr), false) eq(vim.api.nvim_buf_is_valid(bufnr), false)
eq(vim.api.nvim_win_is_valid(win_id), false) eq(vim.api.nvim_win_is_valid(win_id), false)
@ -191,7 +182,7 @@ describe("harpoon", function()
eq(vim.api.nvim_win_is_valid(win_id), true) eq(vim.api.nvim_win_is_valid(win_id), true)
eq(vim.api.nvim_get_current_buf(), bufnr) eq(vim.api.nvim_get_current_buf(), bufnr)
key("<Esc>") utils.key("<Esc>")
eq(vim.api.nvim_buf_is_valid(bufnr), false) eq(vim.api.nvim_buf_is_valid(bufnr), false)
eq(vim.api.nvim_win_is_valid(win_id), false) eq(vim.api.nvim_win_is_valid(win_id), false)

View File

@ -1,4 +1,5 @@
local Data = require("harpoon.data") local Data = require("harpoon.data")
local Path = require("plenary.path")
local Config = require("harpoon.config") local Config = require("harpoon.config")
local M = {} local M = {}
@ -21,6 +22,15 @@ function M.return_to_checkpoint()
M.clean_files() M.clean_files()
end end
---@param k string
function M.key(k)
vim.api.nvim_feedkeys(
vim.api.nvim_replace_termcodes(k, true, false, true),
"x",
true
)
end
local function fullpath(name) local function fullpath(name)
return function() return function()
return name return name
@ -64,12 +74,12 @@ end
---@param name string ---@param name string
---@param contents string[] ---@param contents string[]
function M.create_file(name, contents, row, col) function M.create_file(name, contents, row, col)
Path:new(name):write(table.concat(contents, "\n"), "w")
local bufnr = vim.fn.bufnr(name, true) local bufnr = vim.fn.bufnr(name, true)
vim.api.nvim_set_option_value("bufhidden", "hide", { vim.api.nvim_set_option_value("bufhidden", "hide", {
buf = bufnr, buf = bufnr,
}) })
vim.api.nvim_set_current_buf(bufnr) vim.api.nvim_set_current_buf(bufnr)
vim.api.nvim_buf_set_text(0, 0, 0, 0, 0, contents)
if row then if row then
vim.api.nvim_win_set_cursor(0, { row or 1, col or 0 }) vim.api.nvim_win_set_cursor(0, { row or 1, col or 0 })
end end