forked from declancm/cinnamon.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscroll.lua
184 lines (156 loc) · 5.07 KB
/
scroll.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
local M = {}
local config = require('cinnamon.config')
local utils = require('cinnamon.utils')
local fn = require('cinnamon.functions')
local motions = require('cinnamon.motions')
local saved_guicursor = vim.opt.guicursor:get()
local warning_given = false
LastScrollTime = 0
SpamMultiplier = 1
M.scroll = function(command, scroll_win, use_count, delay_length, deprecated_arg)
-- Check if plugin is disabled.
if config.disabled then
vim.cmd('norm! ' .. command)
return
end
if deprecated_arg ~= nil and not warning_given then
utils.error_msg('Argument 5 for the Cinnamon Scroll API function is now deprecated.', 'Warning', 'WARN')
warning_given = true
end
-- Convert arguments to boolean:
local int_to_bool = function(val)
if val == 0 then
return false
else
return true
end
end
-- Setting argument defaults:
if not command then
utils.error_msg('The command argument cannot be nil')
return
end
scroll_win = int_to_bool(scroll_win or 0)
use_count = int_to_bool(use_count or 0)
if not delay_length or delay_length == -1 then
delay_length = config.default_delay
end
-- Execute command if only moving one line/char.
if vim.tbl_contains(motions.no_scroll, command) and vim.v.count1 == 1 then
vim.cmd('norm! ' .. command)
return
end
-- Check if command is a mouse wheel scroll.
local scroll_wheel = false
if vim.tbl_contains(motions.scroll_wheel, command) then
scroll_wheel = true
end
-- Check for any errors with the command.
if fn.check_command_errors(command) then
return
end
-- Save and set options.
local saved = {}
saved.lazyredraw = vim.opt.lazyredraw:get()
vim.opt.lazyredraw = true
local restore_options = function()
vim.opt.lazyredraw = saved.lazyredraw
end
-- Get initial position values.
local saved_view = vim.fn.winsaveview()
local prev_filepath = vim.fn.getreg('%')
local _, prev_lnum, prev_column, _, prev_curswant = unpack(vim.fn.getcurpos())
local prev_winline = vim.fn.winline()
local prev_wincol = vim.fn.wincol()
-- Perform the command.
if command == 'definition' or command == 'declaration' then
require('vim.lsp.buf')[command]()
vim.cmd('sleep 100m')
elseif use_count and vim.v.count > 0 then
vim.cmd('norm! ' .. vim.v.count .. command)
else
vim.cmd('norm! ' .. command)
end
-- Get final position values.
local curpos = vim.fn.getcurpos()
local filepath = vim.fn.getreg('%')
local _, lnum, column, _, curswant = unpack(curpos)
local winline = vim.fn.winline()
local wincol = vim.fn.wincol()
local distance = fn.get_visual_distance(prev_lnum, lnum)
-- Check if the file changed or the scroll limit exceeded.
if prev_filepath ~= filepath or (math.abs(distance) > config.scroll_limit and config.scroll_limit ~= -1) then
if scroll_win and config.centered then
vim.cmd('norm! zz')
end
restore_options()
return
end
-- Restore the original view.
vim.fn.winrestview(saved_view)
-- Check if scrolled vertically and/or horizontally.
local scrolled_window_vertically = false
if winline - lnum ~= prev_winline - prev_lnum then
scrolled_window_vertically = true
end
local scrolled_view_horizontally = false
if wincol - column ~= prev_wincol - prev_column then
scrolled_view_horizontally = true
end
-- Check if values have changed.
if curswant == prev_curswant then
column = -1
end
if wincol == prev_wincol then
wincol = -1
end
-- Hide the cursor.
local cursor_hidden = false
if config.hide_cursor and vim.opt.termguicolors:get() then
if vim.opt.guicursor:get() ~= 'a:CinnamonHideCursor' then
saved_guicursor = vim.opt.guicursor:get()
end
vim.opt.guicursor = 'a:CinnamonHideCursor'
cursor_hidden = true
end
-- Calculate the delay length.
local scrollTime = os.time()
local hitDelta = scrollTime - LastScrollTime
local spammed = hitDelta < 0.2
local shouldReset = hitDelta > 0.5
LastScrollTime = scrollTime
if spammed then
SpamMultiplier = SpamMultiplier * 2
end
if shouldReset then
SpamMultiplier = 1
end
if config.max_length ~= -1 then
if math.abs(distance) * delay_length > config.max_length then
delay_length = math.floor((config.max_length / math.abs(distance)) + 0.5)
end
end
delay_length = delay_length / SpamMultiplier
-- Scroll vertically.
if scroll_wheel then
fn.scroll_wheel_vertically(command, distance, curpos, winline, delay_length)
elseif scrolled_window_vertically or config.always_scroll or scroll_win or scroll_wheel then
fn.scroll_vertically(distance, curpos, winline, scroll_win, delay_length)
else
fn.scroll_vertically(distance, curpos, winline, scroll_win, 0)
end
-- Scroll horizontally.
if
(scrolled_view_horizontally and config.horizontal_scroll or config.always_scroll) and vim.fn.foldclosed('.') == -1
then
fn.scroll_horizontally(column, wincol, math.ceil(delay_length / 3))
else
fn.scroll_horizontally(column, wincol, 0)
end
-- Restore the cursor.
if cursor_hidden then
vim.opt.guicursor = saved_guicursor
end
restore_options()
end
return M