From 761d4d44a27cc8a36697ec509303360567d04b60 Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Wed, 28 Feb 2024 19:13:34 -0800 Subject: [PATCH] list: save and restore cursor positions Harpoon was not remembering the cursor position after quitting nvim. Ensure that the cursor information is always saved and applied so that we get back to exactly where we last were in the harpooned file. Closes: #441 --- lua/harpoon/config.lua | 64 ++++++++++++++++++++++-------------------- lua/harpoon/init.lua | 1 + lua/harpoon/list.lua | 21 ++++++++++++++ 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/lua/harpoon/config.lua b/lua/harpoon/config.lua index d6ffc24b..a90c1701 100644 --- a/lua/harpoon/config.lua +++ b/lua/harpoon/config.lua @@ -1,5 +1,6 @@ local Extensions = require("harpoon.extensions") local Logger = require("harpoon.logger") +local List = require("harpoon.list") local Utils = require("harpoon.utils") local function to_exact_name(value) @@ -102,13 +103,11 @@ function M.get_default_config() return end + list:sync_cursor() options = options or {} local bufnr = vim.fn.bufnr(to_exact_name(list_item.value)) - local set_position = false if bufnr == -1 then -- must create a buffer! - set_position = true - -- bufnr = vim.fn.bufnr(list_item.value, true) bufnr = vim.fn.bufadd(list_item.value) end if not vim.api.nvim_buf_is_loaded(bufnr) then @@ -128,39 +127,42 @@ function M.get_default_config() vim.api.nvim_set_current_buf(bufnr) - if set_position then - local lines = vim.api.nvim_buf_line_count(bufnr) + 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 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] + 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 + if list_item.context.col > col then + list_item.context.col = col + edited = true + end - vim.api.nvim_win_set_cursor(0, { - list_item.context.row or 1, - list_item.context.col or 0, - }) + vim.api.nvim_win_set_cursor(0, { + list_item.context.row or 1, + list_item.context.col or 0, + }) - if edited then - Extensions.extensions:emit( - Extensions.event_names.POSITION_UPDATED, - { - list_item = list_item, - } - ) - end + if edited then + Extensions.extensions:emit( + Extensions.event_names.POSITION_UPDATED, + { + list_item = list_item, + } + ) end + -- The stored cursor position could be outside of the file bounds. + pcall(vim.api.nvim_win_set_cursor, 0, { + list_item.context.row or 1, + list_item.context.col or 0, + }) Extensions.extensions:emit(Extensions.event_names.NAVIGATE, { buffer = bufnr, @@ -224,7 +226,7 @@ function M.get_default_config() local item = list:get_by_value(bufname) if item then - local pos = vim.api.nvim_win_get_cursor(0) + local pos = List._sync_cursor(item) Logger:log( "config_default#BufLeave updating position", diff --git a/lua/harpoon/init.lua b/lua/harpoon/init.lua index e34a7971..bc6648fd 100644 --- a/lua/harpoon/init.lua +++ b/lua/harpoon/init.lua @@ -104,6 +104,7 @@ function Harpoon:sync() return end + list:sync_cursor() local encoded = list:encode() self.data:update(key, list_name, encoded) end) diff --git a/lua/harpoon/list.lua b/lua/harpoon/list.lua index 897122fa..1155b2a6 100644 --- a/lua/harpoon/list.lua +++ b/lua/harpoon/list.lua @@ -1,6 +1,7 @@ local Logger = require("harpoon.logger") local utils = require("harpoon.utils") local Extensions = require("harpoon.extensions") +local Utils = require("harpoon.utils") local function guess_length(arr) local last_known = #arr @@ -285,6 +286,17 @@ function HarpoonList:resolve_displayed(displayed, length) end end +function HarpoonList:sync_cursor() + local current_display = Utils.normalize_path( + vim.api.nvim_buf_get_name(vim.api.nvim_get_current_buf()), + self.config.get_root_dir() + ) + local item = self:get_by_display(current_display) + if item then + HarpoonList._sync_cursor(item) + end +end + function HarpoonList:select(index, options) local item = self.items[index] if item or self.config.select_with_nil then @@ -365,4 +377,13 @@ function HarpoonList.decode(list_config, name, items) return HarpoonList:new(list_config, name, list_items) end +--- @return integer[] +--- @param item HarpoonItem +function HarpoonList._sync_cursor(item) + local pos = vim.api.nvim_win_get_cursor(0) + item.context.row = pos[1] + item.context.col = pos[2] + return pos +end + return HarpoonList