@@ -55,16 +55,26 @@ describe("marksman.nvim", function()
5555 describe (" mark operations" , function ()
5656 local marksman = require (" marksman" )
5757 local test_file
58+ local test_file2
5859
5960 before_each (function ()
6061 clear_marks ()
6162 local test_dir = vim .env .MARKSMAN_TEST_DIR or vim .fn .tempname ()
6263 test_file = test_dir .. " /test.lua"
63- vim . fn . mkdir ( vim . fn . fnamemodify ( test_file , " :h " ), " p " )
64+ test_file2 = test_dir .. " /test2.lua "
6465
6566 setup_buffer_with_file (test_file , {
6667 " local function test()" ,
67- " return true" ,
68+ " local value = false" ,
69+ " if value then" ,
70+ " return true" ,
71+ " end" ,
72+ " return false" ,
73+ })
74+
75+ setup_buffer_with_file (test_file2 , {
76+ " local function test2()" ,
77+ " return false" ,
6878 " end" ,
6979 })
7080 end )
@@ -125,6 +135,150 @@ describe("marksman.nvim", function()
125135 assert .equals (3 , vim .fn .col (" ." ))
126136 end )
127137
138+ it (" jumps to next mark with wrap-around" , function ()
139+ -- open the test file and place marks on lines 1, 2, and 3
140+ vim .cmd (" edit " .. test_file )
141+
142+ vim .fn .cursor (1 , 1 )
143+ marksman .add_mark (" m1" )
144+
145+ vim .fn .cursor (2 , 1 )
146+ marksman .add_mark (" m2" )
147+
148+ vim .fn .cursor (3 , 1 )
149+ marksman .add_mark (" m3" )
150+
151+ -- start at m1
152+ vim .fn .cursor (1 , 1 )
153+ local result = marksman .goto_next ()
154+ assert .is_true (result .success )
155+ assert .equals (2 , vim .fn .line (" ." ), " Should jump from m1 to m2" )
156+
157+ -- now at m2 -> next should be m3
158+ result = marksman .goto_next ()
159+ assert .is_true (result .success )
160+ assert .equals (3 , vim .fn .line (" ." ), " Should jump from m2 to m3" )
161+
162+ -- now at m3 -> next should wrap back to m1
163+ result = marksman .goto_next ()
164+ assert .is_true (result .success )
165+ assert .equals (1 , vim .fn .line (" ." ), " Should wrap from m3 to m1" )
166+ end )
167+
168+ it (" jumps to next mark when cursor is between marks" , function ()
169+ vim .cmd (" edit " .. test_file )
170+
171+ vim .fn .cursor (1 , 1 )
172+ marksman .add_mark (" m1" )
173+
174+ vim .fn .cursor (4 , 1 )
175+ marksman .add_mark (" m2" )
176+
177+ vim .fn .cursor (5 , 1 )
178+ marksman .add_mark (" m3" )
179+
180+ -- cursor on line 3 → distance to m1 = 2, m2 = 1 → choose m2 as current index
181+ vim .fn .cursor (3 , 1 )
182+
183+ local result = marksman .goto_next ()
184+ assert .is_true (result .success )
185+ assert .equals (5 , vim .fn .line (" ." ), " Should jump from m2 to m3" )
186+ end )
187+
188+ it (" jumps to next in another file" , function ()
189+ -- file A
190+ vim .cmd (" edit " .. test_file )
191+ vim .fn .cursor (1 , 1 )
192+ marksman .add_mark (" a1" )
193+
194+ -- file B
195+ vim .cmd (" edit " .. test_file2 )
196+ vim .fn .cursor (1 , 1 )
197+ marksman .add_mark (" b1" )
198+ vim .fn .cursor (3 , 1 )
199+ marksman .add_mark (" b2" )
200+
201+ vim .cmd (" edit " .. test_file )
202+ vim .fn .cursor (1 , 1 ) -- at a1
203+ local result = marksman .goto_next ()
204+
205+ assert .is_true (result .success )
206+ assert .equals (test_file2 , vim .fn .expand (" %:p" ), " Should move to next mark in file2" )
207+ assert .equals (1 , vim .fn .line (" ." ), " Should move to b1" )
208+ end )
209+
210+ it (" jumps to second mark when current file has no marks" , function ()
211+ -- file A with marks
212+ vim .cmd (" edit " .. test_file )
213+ vim .fn .cursor (1 , 1 )
214+ marksman .add_mark (" m1" )
215+ vim .fn .cursor (2 , 1 )
216+ marksman .add_mark (" m2" )
217+
218+ -- file B with zero marks
219+ vim .cmd (" edit " .. test_file2 )
220+ vim .fn .cursor (1 , 1 )
221+
222+ local result = marksman .goto_next ()
223+ assert .is_true (result .success )
224+
225+ -- Should jump to second mark because fallback picks first index
226+ assert .equals (test_file , vim .fn .expand (" %:p" ))
227+ assert .equals (2 , vim .fn .line (" ." ), " Should move to m2" )
228+ end )
229+
230+ it (" jumps to first mark when only 1 mark exists" , function ()
231+ -- file A with marks
232+ vim .cmd (" edit " .. test_file )
233+ vim .fn .cursor (1 , 1 )
234+ marksman .add_mark (" m1" )
235+
236+ -- file B with zero marks
237+ vim .cmd (" edit " .. test_file2 )
238+ vim .fn .cursor (1 , 1 )
239+
240+ local result = marksman .goto_next ()
241+ assert .is_true (result .success )
242+
243+ assert .equals (test_file , vim .fn .expand (" %:p" ))
244+ assert .equals (1 , vim .fn .line (" ." ), " Should move to m1" )
245+ end )
246+
247+ it (" returns error when no marks exist" , function ()
248+ local result = marksman .goto_next ()
249+ assert .is_false (result .success )
250+ assert .is_string (result .message )
251+ end )
252+
253+ it (" jumps to previous mark with wrap-around" , function ()
254+ vim .cmd (" edit " .. test_file )
255+
256+ vim .fn .cursor (1 , 1 )
257+ marksman .add_mark (" m1" )
258+
259+ vim .fn .cursor (2 , 1 )
260+ marksman .add_mark (" m2" )
261+
262+ vim .fn .cursor (3 , 1 )
263+ marksman .add_mark (" m3" )
264+
265+ -- start at m1 -> previous should wrap to m3
266+ vim .fn .cursor (1 , 1 )
267+ local result = marksman .goto_previous ()
268+ assert .is_true (result .success )
269+ assert .equals (3 , vim .fn .line (" ." ), " Should wrap from m1 to m3" )
270+
271+ -- now at m3 -> previous should be m2
272+ result = marksman .goto_previous ()
273+ assert .is_true (result .success )
274+ assert .equals (2 , vim .fn .line (" ." ), " Should jump from m3 to m2" )
275+
276+ -- now at m2 -> previous should be m1
277+ result = marksman .goto_previous ()
278+ assert .is_true (result .success )
279+ assert .equals (1 , vim .fn .line (" ." ), " Should jump from m2 to m1" )
280+ end )
281+
128282 it (" deletes marks" , function ()
129283 vim .cmd (" edit " .. test_file )
130284 marksman .add_mark (" delete_me" )
0 commit comments