Skip to content

Commit 8ce76c3

Browse files
committed
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
1 parent 238780e commit 8ce76c3

File tree

3 files changed

+55
-31
lines changed

3 files changed

+55
-31
lines changed

lua/harpoon/config.lua

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
local Extensions = require("harpoon.extensions")
22
local Logger = require("harpoon.logger")
3+
local List = require("harpoon.list")
34
local Utils = require("harpoon.utils")
45

56
local function to_exact_name(value)
@@ -102,13 +103,11 @@ function M.get_default_config()
102103
return
103104
end
104105

106+
list:sync_cursor()
105107
options = options or {}
106108

107109
local bufnr = vim.fn.bufnr(to_exact_name(list_item.value))
108-
local set_position = false
109110
if bufnr == -1 then -- must create a buffer!
110-
set_position = true
111-
-- bufnr = vim.fn.bufnr(list_item.value, true)
112111
bufnr = vim.fn.bufadd(list_item.value)
113112
end
114113
if not vim.api.nvim_buf_is_loaded(bufnr) then
@@ -128,39 +127,42 @@ function M.get_default_config()
128127

129128
vim.api.nvim_set_current_buf(bufnr)
130129

131-
if set_position then
132-
local lines = vim.api.nvim_buf_line_count(bufnr)
130+
local lines = vim.api.nvim_buf_line_count(bufnr)
133131

134-
local edited = false
135-
if list_item.context.row > lines then
136-
list_item.context.row = lines
137-
edited = true
138-
end
132+
local edited = false
133+
if list_item.context.row > lines then
134+
list_item.context.row = lines
135+
edited = true
136+
end
139137

140-
local row = list_item.context.row
141-
local row_text =
142-
vim.api.nvim_buf_get_lines(0, row - 1, row, false)
143-
local col = #row_text[1]
138+
local row = list_item.context.row
139+
local row_text =
140+
vim.api.nvim_buf_get_lines(0, row - 1, row, false)
141+
local col = #row_text[1]
144142

145-
if list_item.context.col > col then
146-
list_item.context.col = col
147-
edited = true
148-
end
143+
if list_item.context.col > col then
144+
list_item.context.col = col
145+
edited = true
146+
end
149147

150-
vim.api.nvim_win_set_cursor(0, {
151-
list_item.context.row or 1,
152-
list_item.context.col or 0,
153-
})
148+
vim.api.nvim_win_set_cursor(0, {
149+
list_item.context.row or 1,
150+
list_item.context.col or 0,
151+
})
154152

155-
if edited then
156-
Extensions.extensions:emit(
157-
Extensions.event_names.POSITION_UPDATED,
158-
{
159-
list_item = list_item,
160-
}
161-
)
162-
end
153+
if edited then
154+
Extensions.extensions:emit(
155+
Extensions.event_names.POSITION_UPDATED,
156+
{
157+
list_item = list_item,
158+
}
159+
)
163160
end
161+
-- The stored cursor position could be outside of the file bounds.
162+
pcall(vim.api.nvim_win_set_cursor, 0, {
163+
list_item.context.row or 1,
164+
list_item.context.col or 0,
165+
})
164166

165167
Extensions.extensions:emit(Extensions.event_names.NAVIGATE, {
166168
buffer = bufnr,
@@ -224,7 +226,7 @@ function M.get_default_config()
224226
local item = list:get_by_value(bufname)
225227

226228
if item then
227-
local pos = vim.api.nvim_win_get_cursor(0)
229+
local pos = List._sync_cursor(item)
228230

229231
Logger:log(
230232
"config_default#BufLeave updating position",

lua/harpoon/init.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ function Harpoon:sync()
104104
return
105105
end
106106

107+
list:sync_cursor()
107108
local encoded = list:encode()
108109
self.data:update(key, list_name, encoded)
109110
end)

lua/harpoon/list.lua

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
local Logger = require("harpoon.logger")
22
local Extensions = require("harpoon.extensions")
3+
local Utils = require("harpoon.utils")
34

45
local function guess_length(arr)
56
local last_known = #arr
@@ -284,6 +285,17 @@ function HarpoonList:resolve_displayed(displayed, length)
284285
end
285286
end
286287

288+
function HarpoonList:sync_cursor()
289+
local current_display = Utils.normalize_path(
290+
vim.api.nvim_buf_get_name(vim.api.nvim_get_current_buf()),
291+
self.config.get_root_dir()
292+
)
293+
local item = self:get_by_value(current_display)
294+
if item then
295+
HarpoonList._sync_cursor(item)
296+
end
297+
end
298+
287299
function HarpoonList:select(index, options)
288300
local item = self.items[index]
289301
if item or self.config.select_with_nil then
@@ -364,4 +376,13 @@ function HarpoonList.decode(list_config, name, items)
364376
return HarpoonList:new(list_config, name, list_items)
365377
end
366378

379+
--- @return integer[]
380+
--- @param item HarpoonItem
381+
function HarpoonList._sync_cursor(item)
382+
local pos = vim.api.nvim_win_get_cursor(0)
383+
item.context.row = pos[1]
384+
item.context.col = pos[2]
385+
return pos
386+
end
387+
367388
return HarpoonList

0 commit comments

Comments
 (0)