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
|
local M = {}
--- vim.notify title
M.appid = "Nvim Config"
--- loop through files in directory
---@param path string absolute path of directory to be looped through
---@param body function function to use on every recursion of the loop
---@param ext string? desired file extension of files to be returned from directory
function M.loopf(path, body, ext)
ext = ext and [[v:val =~ '\.]]..ext..[[$']] or nil
for _, file in ipairs(vim.fn.readdir(path, ext)) do
body(file)
end
end
--- extend vim.kemap.set
---@param mode string|table mode for the keymap
---@param bind string|table keymap
---@param cmd function|string command to run
---@param opts vim.keymap.set.Opts? keymap options
function M.map(mode, bind, cmd, opts)
opts = opts or {}
opts["noremap"] = true
opts["silent"] = true
-- attempt to autogenerate a basic description
if not opts["desc"] then
if type(cmd) == "string" then
opts["desc"] = cmd:gsub("<%a+>", "")
elseif type(cmd) == "function" then
-- TODO: find a way to generate a better name
local file_name = vim.fn.fnamemodify(debug.getinfo(cmd, "S").short_src, ":t")
opts["desc"] = "origin@"..file_name
end
end
-- define the keybinds
if type(bind) == "table" then
for i in pairs(bind) do
vim.keymap.set(mode, bind[i], cmd, opts)
end
elseif type(bind) == "string" then
vim.keymap.set(mode, bind, cmd, opts)
end
end
--- a small map wrapper to easily create local buffer mappings
---@param mode string|table mode for the keymap
---@param bind string|table keymap
---@param cmd function|string command to run
---@param opts table? keymap options
function M.map_local(mode, bind, cmd, opts)
opts = opts or {}
opts["buffer"] = 0
M.map(mode, bind, cmd, opts)
end
--- extend vim.api.nvim_create_autocmd
---@param event string|table event or events
---@param opts vim.api.keyset.create_autocmd options
function M.auto(event, opts)
vim.api.nvim_create_autocmd(event, opts)
end
--- extend auto group
---@param name string name of the autogroup
---@param opts table? table of options
function M.augroup(name, opts)
opts = opts or {}
vim.api.nvim_create_augroup(name, opts)
end
--- extend vim.api.nvim_set_hl
---@param group string|table highlight group
---@param opts table highlight options
---@param namespace? number highlight space
function M.highlight(group, opts, namespace)
namespace = namespace or 0
if type(group) == "table" then
for i in pairs(group) do
vim.api.nvim_set_hl(namespace, group[i], opts)
end
elseif type(group) == "string" then
vim.api.nvim_set_hl(namespace, group, opts)
end
end
--- highlight something with some highlight group for a certain amount of time
--- example:
--- ```lua
--- {
--- -- highlight group to use
--- hl = "IncSearch",
---
--- -- # of ms to stay highlighted for
--- timeout = 250,
---
--- -- line to highlight
--- line = vim.api.nvim_win_get_cursor(0)[1],
---
--- -- range to highlight if this is used line will be ignored
--- range = {
--- { 0, 0 },
--- { 0, 0 }
--- }
--- }
--- ```
--- opts is optional and if empty will simply highlight the current line for
--- 250ms using IncSearch as the highlight group
---@param opts table? options
function M.timeout_highlight(opts)
opts = opts or {}
opts.hl = opts.hl or "IncSearch"
opts.timeout = opts.timeout or 250
if type(opts.range) ~= "table" or type(opts.range[1]) ~= "table" or
type(opts.range[2]) ~= "table" then
local curline = opts.line or vim.api.nvim_win_get_cursor(0)[1]
opts.range = {
{ curline - 1, 0 },
{ curline, 0 }
}
end
local namespaceid = vim.api.nvim_create_namespace("timeout_highlight")
-- timer code was happily stolen from neovim/runtime/lua/vim/highlight.lua :)
local timer, timer_cancel
if not vim.fn.has("nvim-0.11") then
if timer then
timer:close()
assert(timer_cancel)
timer_cancel()
end
end
-- set the highlight
vim.highlight.range(0, namespaceid, opts.hl, opts.range[1], opts.range[2], {
opts.timeout,
})
if not vim.fn.has("nvim-0.11") then
timer_cancel = function()
timer = nil
timer_cancel = nil
pcall(vim.api.nvim_buf_clear_namespace, 0, namespaceid, 0, -1)
pcall(vim.api.nvim_win_remove_ns, 0, namespaceid)
end
timer = vim.defer_fn(timer_cancel, opts.timeout)
end
end
return M
|