@@ -33,23 +33,23 @@ H.scroller = {
33
33
self .window_only = (self .options .mode ~= " cursor" )
34
34
self .step_delay = math.max (math.floor (self .options .delay ), 1 )
35
35
36
- local original_view = vim .fn .winsaveview ()
37
- local original_position = H .get_position ()
38
- local original_buffer_id = vim .api .nvim_get_current_buf ()
39
36
local original_window_id = vim .api .nvim_get_current_win ()
37
+ local original_buffer_id = vim .api .nvim_get_current_buf ()
38
+ local original_view = vim .fn .winsaveview ()
39
+ self .original_position = H .get_position ()
40
40
41
41
H .execute_command (command )
42
42
43
+ self .window_id = vim .api .nvim_get_current_win ()
44
+ self .buffer_id = vim .api .nvim_get_current_buf ()
43
45
self .target_view = vim .fn .winsaveview ()
44
46
self .target_position = H .get_position ()
45
- self .buffer_id = vim .api .nvim_get_current_buf ()
46
- self .window_id = vim .api .nvim_get_current_win ()
47
47
48
48
self .error = {
49
- line = H .get_line_error (original_position , self .target_position ),
50
- col = self .target_position .col - original_position .col ,
51
- winline = self .target_position .winline - original_position .winline ,
52
- wincol = self .target_position .wincol - original_position .wincol ,
49
+ line = H .get_line_error (self . original_position , self .target_position ),
50
+ col = self .target_position .col - self . original_position .col ,
51
+ winline = self .target_position .winline - self . original_position .winline ,
52
+ wincol = self .target_position .wincol - self . original_position .wincol ,
53
53
}
54
54
55
55
local step_count = math.max (
@@ -104,6 +104,7 @@ H.scroller = {
104
104
self .saved_scrolloff = vim .wo .scrolloff
105
105
vim .wo .scrolloff = 0 -- Don't scroll the view when the cursor is near the edge
106
106
107
+ self .current_position = self .original_position
107
108
self .initial_changedtick = vim .b .changedtick
108
109
self .interrupted = false
109
110
self .previous_step_position = nil
@@ -169,8 +170,8 @@ H.scroller = {
169
170
local winline_before = vim .fn .winline ()
170
171
local wincol_before = vim .fn .wincol ()
171
172
172
- local line_step = H . move_step (" line" , self .step_queue .line )
173
- local col_step = H . move_step (" col" , self .step_queue .col )
173
+ local line_step = self : move_cursor (" line" , self .step_queue .line )
174
+ local col_step = self : move_cursor (" col" , self .step_queue .col )
174
175
175
176
local winline_step = vim .fn .winline () - winline_before
176
177
local wincol_step = vim .fn .wincol () - wincol_before
@@ -187,9 +188,9 @@ H.scroller = {
187
188
188
189
-- When wrap is enabled, the winline change is not equal to the step size
189
190
winline_before = vim .fn .winline ()
190
- H . move_step (" winline" , self .step_queue .winline )
191
+ self : move_window (" winline" , self .step_queue .winline )
191
192
winline_step = vim .fn .winline () - winline_before
192
- wincol_step = H . move_step (" wincol" , self .step_queue .wincol )
193
+ wincol_step = self : move_window (" wincol" , self .step_queue .wincol )
193
194
194
195
self .step_queue .winline = self .step_queue .winline - winline_step
195
196
self .step_queue .wincol = self .step_queue .wincol - wincol_step
@@ -212,23 +213,65 @@ H.scroller = {
212
213
end
213
214
end ,
214
215
216
+ --- @param component " line" | " col"
217
+ --- @param distance number
218
+ move_cursor = function (self , component , distance )
219
+ if distance > 0 then
220
+ distance = math.floor (distance )
221
+ else
222
+ distance = math.ceil (distance )
223
+ end
224
+
225
+ if distance == 0 then
226
+ return 0
227
+ end
228
+
229
+ self .current_position [component ] = self .current_position [component ] + distance
230
+ vim .api .nvim_win_set_cursor (0 , { self .current_position .line , self .current_position .col })
231
+
232
+ return distance
233
+ end ,
234
+
235
+ --- @param component " winline" | " wincol"
236
+ --- @param distance number
237
+ --- @return number
238
+ move_window = function (self , component , distance )
239
+ if distance > 0 then
240
+ distance = math.floor (distance )
241
+ else
242
+ distance = math.ceil (distance )
243
+ end
244
+ local count = math.abs (distance )
245
+
246
+ if count == 0 then
247
+ return 0
248
+ end
249
+
250
+ local command = " normal! "
251
+ if count > 1 then
252
+ command = command .. count
253
+ end
254
+
255
+ if component == " winline" then
256
+ command = command .. (distance > 0 and " \25 " or " \5 " )
257
+ else
258
+ command = command .. (distance > 0 and " zh" or " zl" )
259
+ end
260
+
261
+ vim .cmd (command )
262
+
263
+ return distance
264
+ end ,
265
+
215
266
move_to_target = function (self )
216
267
if self .target_view == nil then
217
268
error (" Target view has not been set" )
218
269
end
219
270
220
- -- The 'curswant' value has to be set with cursor() for the '$' movement.
221
- -- Setting it with winrestview() causes issues when within 'scrolloff'.
222
271
vim .api .nvim_win_call (self .window_id , function ()
223
- vim .fn .cursor ({
224
- self .target_view .lnum ,
225
- self .target_view .col + 1 ,
226
- self .target_view .coladd ,
227
- self .target_view .curswant + 1 ,
228
- })
272
+ vim .fn .winrestview (self .target_view )
229
273
end )
230
274
231
- -- Cursor isn't redrawn if the window was exited
232
275
vim .cmd .redraw ()
233
276
end ,
234
277
@@ -293,43 +336,12 @@ H.execute_command = function(command)
293
336
vim .api .nvim_exec_autocmds (" User" , { pattern = " CinnamonCmdPost" })
294
337
end
295
338
296
- --- @param component " line" | " col" | " winline" | " wincol"
297
- --- @param distance number
298
- --- @return number
299
- H .move_step = function (component , distance )
300
- local command = " normal! "
301
- local movement = " "
302
- distance = (distance > 0 ) and math.floor (distance ) or math.ceil (distance )
303
- local count = math.abs (distance )
304
-
305
- if count == 0 then
306
- return 0
307
- elseif count > 1 then
308
- command = command .. count
309
- end
310
-
311
- if component == " line" then
312
- movement = distance > 0 and " j" or " k"
313
- elseif component == " col" then
314
- movement = distance > 0 and " l" or " h"
315
- elseif component == " winline" then
316
- movement = distance > 0 and " \25 " or " \5 "
317
- elseif component == " wincol" then
318
- movement = distance > 0 and " zh" or " zl"
319
- else
320
- error (" Invalid component: " .. component )
321
- end
322
-
323
- vim .cmd (command .. movement )
324
-
325
- return distance
326
- end
327
-
328
339
--- @return Position
329
340
H .get_position = function ()
341
+ local cursor = vim .api .nvim_win_get_cursor (0 )
330
342
return {
331
- line = vim . fn . line ( " . " ) ,
332
- col = vim . fn . virtcol ( " . " ) ,
343
+ line = cursor [ 1 ] ,
344
+ col = cursor [ 2 ] ,
333
345
winline = vim .fn .winline (),
334
346
wincol = vim .fn .wincol (),
335
347
}
0 commit comments