-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathinit.lua
294 lines (233 loc) · 10 KB
/
init.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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
require('nvim-treesitter')
local utils = require("nvim-biscuits.utils")
local config = require("nvim-biscuits.config")
local languages = require("nvim-biscuits.languages")
local parse = require("vendor.parse")
local final_config = config.default_config()
local function is_file_too_big()
local file_size = vim.fn.wordcount().bytes
local max_file_size = final_config.max_file_size
if final_config.max_file_size == nil then
max_file_size = 0
end
local original_max_file_size = max_file_size
if type(max_file_size) == "string" then
max_file_size = parse.file_size(max_file_size)
else
return nil
end
if max_file_size == nil then
vim.notify("nvim-biscuits: max_file_size is invalid. Valid case-insensitive values include: b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib")
max_file_size = 0
end
return max_file_size > 0 and file_size > max_file_size
end
local has_ts, _ = pcall(require, 'nvim-treesitter')
if not has_ts then error("nvim-treesitter must be installed") end
local ts_parsers = require('nvim-treesitter.parsers')
local ts_utils = require('nvim-treesitter.ts_utils')
local nvim_biscuits = {should_render_biscuits = true}
local make_biscuit_hl_group_name =
function(lang)
return 'BiscuitColor' .. lang
end
nvim_biscuits.decorate_nodes = function(bufnr, lang)
if config.get_language_config(final_config, lang, "disabled") then return end
local parser = ts_parsers.get_parser(bufnr, lang)
if parser == nil then
utils.console_log('no parser for ' .. lang)
return
end
local biscuit_highlight_group_name = make_biscuit_hl_group_name(lang)
local biscuit_highlight_group = vim.api.nvim_create_namespace(
biscuit_highlight_group_name)
if not nvim_biscuits.should_render_biscuits then
vim.api.nvim_buf_clear_namespace(bufnr, biscuit_highlight_group, 0, -1)
return
end
local root = parser:parse()[1]:root()
local nodes = ts_utils.get_named_children(root)
local children = {}
local has_nodes = true
vim.api.nvim_buf_clear_namespace(bufnr, biscuit_highlight_group,
0, -1)
while has_nodes do
for index, node in ipairs(nodes) do
children = utils.merge_arrays(children,
ts_utils.get_named_children(node))
local start_line, start_col, end_line, end_col =
vim.treesitter.get_node_range(node)
local lines = vim.api.nvim_buf_get_lines(bufnr, start_line,
start_line + 1, false)
local text = lines[1]
text = utils.trim(text)
local should_decorate = true
-- bail out of empty text
if text == '' then should_decorate = false end
-- bail out of short text
if string.len(text) <= 1 then should_decorate = false end
-- bail out if start line and end line are the same
if start_line == end_line then should_decorate = false end
-- bail out distance is less than minimum distance
if end_line - start_line < final_config.min_distance then
should_decorate = false
end
-- bail out if this node should not be decorated based on language specific filters
if languages.should_decorate(lang, node, text, bufnr) == false then
should_decorate = false
end
-- bail out if the user has cursor line only on and we are not on their cursor line
local cursor = vim.api.nvim_win_get_cursor(0)
local should_clear = false
if final_config.cursor_line_only and end_line + 1 ~= cursor[1] then
should_decorate = false
should_clear = true
end
if should_decorate == true then
local trim_by_words = config.get_language_config(final_config,
lang,
"trim_by_words")
local max_length = config.get_language_config(final_config,
lang, "max_length")
if trim_by_words == true then
local words = {}
for word in string.gmatch(text, "%w+") do
words[#words + 1] = word
if #words >= max_length then
break
end
end
text = table.concat(words, " ")
else
if string.len(text) >= max_length then
text = string.sub(text, 1, max_length)
text = text .. '...'
end
end
text = text:gsub("\n", ' ')
local prefix_string = config.get_language_config(final_config,
lang,
"prefix_string")
-- language specific text filter
text = languages.transform_text(lang, node, text, bufnr)
if utils.trim(text) ~= '' then
text = prefix_string .. text
vim.api.nvim_buf_clear_namespace(bufnr,
biscuit_highlight_group,
end_line, end_line + 1)
vim.api.nvim_buf_set_extmark(bufnr, biscuit_highlight_group,
end_line, 0, {
virt_text_pos = "eol",
virt_text = {{text, biscuit_highlight_group_name}},
hl_mode = "combine"
})
end
end
if should_decorate == false and should_clear == true then
vim.api.nvim_buf_clear_namespace(bufnr, biscuit_highlight_group,
end_line, end_line + 1)
end
end
nodes = children
children = {}
if table.getn(nodes) == 0 then has_nodes = false end
end
end
local attached_buffers = {}
nvim_biscuits.BufferAttach = function(bufnr, lang)
if bufnr == nil then
bufnr = vim.api.nvim_get_current_buf()
end
if lang == nil then
lang = ts_parsers.get_buf_lang(bufnr):gsub("-", "")
end
if attached_buffers[bufnr] then return end
attached_buffers[bufnr] = true
local toggle_keybind = config.get_language_config(final_config, lang,
"toggle_keybind")
if toggle_keybind ~= nil then
vim.api.nvim_set_keymap("n", toggle_keybind,
"<Cmd>lua require('nvim-biscuits').toggle_biscuits()<CR>",
{ noremap = false, desc = "toggle biscuits" })
end
if is_file_too_big() then
vim.notify_once("nvim-biscuits: File is larger than configured max_file_size")
return
end
local on_lines = function() nvim_biscuits.decorate_nodes(bufnr, lang) end
if lang then
vim.cmd("highlight default link " .. make_biscuit_hl_group_name(lang) ..
" BiscuitColor")
end
-- we need to fire once at the very start if config allows
if (not toggle_keybind) or config.get_language_config(final_config, lang, "show_on_start") then
if bufnr then
nvim_biscuits.decorate_nodes(bufnr, lang)
end
else
nvim_biscuits.should_render_biscuits = false
end
local on_events = table.concat(final_config.on_events, ',')
if on_events ~= "" then
vim.api.nvim_exec(string.format([[
augroup Biscuits
au!
au %s <buffer=%s> :lua require("nvim-biscuits").decorate_nodes(%s, "%s")
augroup END
]], on_events, bufnr, bufnr, lang), false)
elseif final_config.cursor_line_only == true then
vim.api.nvim_exec(string.format([[
augroup Biscuits
au!
au %s <buffer=%s> :lua require("nvim-biscuits").decorate_nodes(%s, "%s")
augroup END
]], "CursorMoved,CursorMovedI", bufnr, bufnr, lang), false)
else
vim.api.nvim_buf_attach(bufnr, false,
{
on_lines = on_lines,
on_detach = function() attached_buffers[bufnr] = nil end
})
end
end
nvim_biscuits.setup = function(user_config)
if user_config == nil then
user_config = {}
end
final_config = utils.merge_tables(final_config, user_config)
if user_config.default_config then
final_config = utils.merge_tables(final_config,
user_config.default_config)
end
-- This uses the official nvim-treesitter api to attach/detach to buffers
-- see: https://github.com/nvim-treesitter/nvim-treesitter#adding-modules
-- the attach/detach functions will not run if the is_supported function
-- returns false.
require'nvim-treesitter'.define_modules {
nvim_biscuits = {
enable = true,
attach = function(bufnr, lang)
nvim_biscuits.BufferAttach(bufnr, lang)
end,
detach = function(bufnr)
attached_buffers[bufnr] = nil
end,
is_supported = function(lang)
return not config.get_language_config(final_config, lang, "disabled")
end
}
}
utils.clear_log()
end
nvim_biscuits.toggle_biscuits = function()
if is_file_too_big() then
vim.notify("nvim-biscuits: File is larger than configured max_file_size")
return
end
nvim_biscuits.should_render_biscuits =
not nvim_biscuits.should_render_biscuits
local bufnr = vim.api.nvim_get_current_buf()
local lang = ts_parsers.get_buf_lang(bufnr):gsub("-", "")
nvim_biscuits.decorate_nodes(bufnr, lang)
end
return nvim_biscuits