aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/nvim/.config/nvim/lua/tobyvin/utils.lua
blob: c107d174b46d5d265a607765782482bffcbcab1a (plain)
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