@@ -289,15 +289,17 @@ function M.goto_mark(name_or_index)
289289 end
290290end
291291
292+ -- Finds the mark index closest to the current cursor position, using 1 as fallback.
293+ -- Returns:
294+ -- index (number | nil): the resolved mark index, or nil if no marks exist
295+ -- total (number | nil): total number of marks when successful, nil on failure
296+ -- error (string | nil): error message when no marks are available
292297local function get_current_mark_index (storage_module )
293298 local mark_names = storage_module .get_mark_names ()
294299 local count = # mark_names
295300
296301 if count == 0 then
297- return nil , " No marks available"
298- end
299- if count == 1 then
300- return nil , " Not enough marks to move"
302+ return nil , nil , " No marks available"
301303 end
302304
303305 local marks = storage_module .get_marks ()
@@ -311,7 +313,7 @@ local function get_current_mark_index(storage_module)
311313 local mark = marks [mark_name ]
312314 if mark .file == current_file then
313315 if mark .line == current_line then
314- return index , nil
316+ return index , count , nil
315317 end
316318 local distance = math.abs (mark .line - current_line )
317319 if not best_distance or distance < best_distance then
@@ -321,42 +323,50 @@ local function get_current_mark_index(storage_module)
321323 end
322324 end
323325
324- return best_index or 1 , nil
326+ return best_index or 1 , count , nil
325327end
326328
327- --- Jump to next mark
328- --- @return table result Result with success and message
329+ --- Jump to the next mark.
330+ --- Navigation is context-aware:
331+ --- • If the cursor is on a mark, jump relative to it.
332+ --- • If the cursor is not on a mark, select the nearest mark in the same file before jumping.
333+ --- • If the current file has no marks, fall back to first index before jumping.
334+ --- Wraps when reaching the last mark.
335+ --- @return table result Result with success and optional message
329336function M .goto_next ()
330337 local storage_module = get_storage ()
331338 if not storage_module then
332339 return { success = false , message = " Failed to load storage module" }
333340 end
334341
335- local current_index , err = get_current_mark_index (storage_module )
342+ local current_index , count , err = get_current_mark_index (storage_module )
336343 if not current_index then
337344 return { success = false , message = err }
338345 end
339346
340- local mark_names = storage_module .get_mark_names ()
341- local next_index = (current_index % # mark_names ) + 1
347+ local next_index = (current_index % count ) + 1
342348 return M .goto_mark (next_index )
343349end
344350
345- --- Jump to previous mark
346- --- @return table result Result with success and message
351+ --- Jump to the previous mark.
352+ --- Navigation is context-aware:
353+ --- • If the cursor is on a mark, jump relative to it.
354+ --- • If the cursor is not on a mark, select the nearest mark in the same file before jumping.
355+ --- • If the current file has no marks, fall back to first index before jumping.
356+ --- Wraps when reaching the last mark.
357+ --- @return table result Result with success and optional message
347358function M .goto_previous ()
348359 local storage_module = get_storage ()
349360 if not storage_module then
350361 return { success = false , message = " Failed to load storage module" }
351362 end
352363
353- local current_index , err = get_current_mark_index (storage_module )
364+ local current_index , count , err = get_current_mark_index (storage_module )
354365 if not current_index then
355366 return { success = false , message = err }
356367 end
357368
358- local mark_names = storage_module .get_mark_names ()
359- local previous_index = ((current_index - 2 ) % # mark_names ) + 1
369+ local previous_index = ((current_index - 2 ) % count ) + 1
360370 return M .goto_mark (previous_index )
361371end
362372
0 commit comments