aboutsummaryrefslogtreecommitdiff
path: root/lua/tasks/utils.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/tasks/utils.lua')
-rw-r--r--lua/tasks/utils.lua100
1 files changed, 100 insertions, 0 deletions
diff --git a/lua/tasks/utils.lua b/lua/tasks/utils.lua
new file mode 100644
index 0000000..983bde7
--- /dev/null
+++ b/lua/tasks/utils.lua
@@ -0,0 +1,100 @@
1local scandir = require('plenary.scandir')
2local Path = require('plenary.path')
3local utils = {}
4
5local args_regex = vim.regex([[\s\%(\%([^'"]*\(['"]\)[^'"]*\1\)*[^'"]*$\)\@=]])
6
7--- A small wrapper around `vim.notify` that adds plugin title.
8---@param msg string
9---@param log_level number
10function utils.notify(msg, log_level) vim.notify(msg, log_level, { title = 'Tasks' }) end
11
12--- Splits command line arguments respecting quotes.
13---@param args string?
14---@return table
15function utils.split_args(args)
16 if not args then
17 return {}
18 end
19
20 -- Split on spaces unless in quotes.
21 local splitted_args = {}
22 local match_beg
23 while true do
24 match_beg = args_regex:match_str(args)
25 if match_beg then
26 table.insert(splitted_args, args:sub(1, match_beg))
27 args = args:sub(match_beg + 2)
28 else
29 -- Insert last arg left.
30 table.insert(splitted_args, args)
31 break
32 end
33 end
34
35 -- Remove quotes
36 for i, arg in ipairs(splitted_args) do
37 splitted_args[i] = arg:gsub('"', ''):gsub("'", '')
38 end
39 return splitted_args
40end
41
42--- Joins command line arguments respecting spaces by putting double quotes around them.
43---@param args table?
44---@return string
45function utils.join_args(args)
46 if not args then
47 return ''
48 end
49
50 -- Add quotes if argument contain spaces
51 for index, arg in ipairs(args) do
52 if arg:find(' ') then
53 args[index] = '"' .. arg .. '"'
54 end
55 end
56
57 return table.concat(args, ' ')
58end
59
60---@return table
61function utils.get_module_names()
62 local module_dir = Path:new(debug.getinfo(1).source:sub(2)):parent() / 'module'
63
64 local modules = {}
65 for _, entry in ipairs(scandir.scan_dir(module_dir.filename, { depth = 1 })) do
66 -- Strip full path and extension
67 local extension_len = 4
68 local parent_offset = 2
69 table.insert(modules, entry:sub(#Path:new(entry):parent().filename + parent_offset, #entry - extension_len))
70 end
71
72 return modules
73end
74
75--- Find a module by name
76---@param module_type string name of a module or `auto` string to pick a first module that match a condition.
77---@return table?, string?: module and its name.
78function utils.get_module(module_type)
79 if module_type == 'auto' then
80 for _, name in ipairs(utils.get_module_names()) do
81 local module = require('tasks.module.' .. name)
82 if module.condition() then
83 return module, name
84 end
85 end
86
87 utils.notify('Unable to autodetect module for this working directory', vim.log.levels.ERROR)
88 return nil, nil
89 end
90
91 local module = require('tasks.module.' .. module_type)
92 if not module then
93 utils.notify('Unable to find a module named ' .. module_type, vim.log.levels.ERROR)
94 return nil, nil
95 end
96
97 return module, module_type
98end
99
100return utils