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
|
local M = {
fs = require("tobyvin.utils.fs"),
buf = require("tobyvin.utils.buf"),
dashboard = require("tobyvin.utils.dashboard"),
session = require("tobyvin.utils.session"),
dap = require("tobyvin.utils.dap"),
}
function M.inspect(v)
print(vim.inspect(v))
return v
end
function M.select(items, opts, on_choice)
if #items == 1 then
on_choice(items[1])
elseif #items > 1 then
vim.ui.select(items, opts, function(item, idx)
return item ~= nil and on_choice(item, idx) or nil
end)
else
vim.print("No results found")
end
end
function M.lazy_require(modname)
return setmetatable({}, {
__index = function(_, k)
return function(...)
return require(modname)[k](...)
end
end,
})
end
---@param ms integer
---@param fn function
function M.debounce(ms, fn)
local timer = vim.loop.new_timer()
return function(...)
local argv = { ... }
timer:start(ms, 0, function()
timer:stop()
vim.schedule_wrap(fn)(unpack(argv))
end)
end
end
function M.system(...)
local s = vim.system(...)
--- @param obj vim.SystemObj
--- @param cmd string[]
--- @param opts SystemOpts|nil)
--- @param on_exit function|nil
---@diagnostic disable-next-line: inject-field
s.pipe = function(obj, cmd, opts, on_exit)
opts = vim.tbl_extend("keep", opts or {}, { stdin = obj:wait().stdout })
return M.system(cmd, opts, on_exit)
end
--- @param obj vim.SystemObj
--- @param cmd string[]
--- @param opts SystemOpts|nil)
--- @param on_exit function|nil
---@diagnostic disable-next-line: inject-field
s.try_pipe = function(obj, cmd, opts, on_exit)
if vim.fn.executable(cmd[1]) ~= 1 then
cmd = { "cat" }
end
---@diagnostic disable-next-line: undefined-field
return obj:pipe(cmd, opts, on_exit)
end
return s
end
---Register callback to run when a lsp server matching a filter attaches to a buffer
---@param on_attach fun(client: lsp.Client, buffer: integer): boolean|nil
---@param filter vim.lsp.get_clients.filter|nil
function M.on_attach(on_attach, filter)
vim.api.nvim_create_autocmd("LspAttach", {
desc = "on client attach",
callback = function(args)
local bufnr = args.buf ---@type number
local client = vim.lsp.get_client_by_id(args.data.client_id)
filter = filter or {}
if
client
and (filter.id == nil or client.id == filter.id)
and (filter.name == nil or client.name == filter.name)
and (filter.bufnr == nil or bufnr == filter.bufnr)
and (filter.method == nil or client.supports_method(filter.method, { bufnr = bufnr }))
then
on_attach(client, bufnr)
end
end,
})
end
---Merges two or more highlights groups into a new highlight group.
---
---**Note**: This will overwrite any existing group named <name>. If you would like to both merge
---*and* overwrite a group, specify it both as <name>, as well as in the list of groups to merge.
---
---E.g. extend_hl(ns, "Normal", "Normal", "Special", { fg = "#333333" }, { other_ns, "Specific" })
---@param ns integer Namespace
---@param name string name of new hightlight group. ---If you want to groups into an existing group, add <name> to the list of groups to merge.*
---@param ... string|table|{ [1]: integer, [2]: string|table } Two or more highlight group names, anonymous highlight definitions, or tuples in the form of { namespace, name|definition }
function M.extend_hl(ns, name, ...)
local hl = {}
for _, arg in pairs({ ... }) do
local hl_name_or_val, hl_ns, hl_val
if
vim.tbl_islist(arg --[[@as table]])
then
hl_ns, hl_name_or_val = arg[1], arg[2]
else
hl_ns, hl_name_or_val = ns, arg --[[@as string|table]]
end
if type(hl_name_or_val) == "string" then
hl_val = vim.api.nvim_get_hl(hl_ns, { name = hl_name_or_val, link = false })
else
hl_val = hl_name_or_val
end
hl = vim.tbl_extend("keep", hl, hl_val)
end
vim.api.nvim_set_hl(ns, name, hl)
end
return M
|