diff options
Diffstat (limited to 'lua/tasks/utils.lua')
-rw-r--r-- | lua/tasks/utils.lua | 100 |
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 @@ | |||
1 | local scandir = require('plenary.scandir') | ||
2 | local Path = require('plenary.path') | ||
3 | local utils = {} | ||
4 | |||
5 | local 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 | ||
10 | function 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 | ||
15 | function 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 | ||
40 | end | ||
41 | |||
42 | --- Joins command line arguments respecting spaces by putting double quotes around them. | ||
43 | ---@param args table? | ||
44 | ---@return string | ||
45 | function 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, ' ') | ||
58 | end | ||
59 | |||
60 | ---@return table | ||
61 | function 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 | ||
73 | end | ||
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. | ||
78 | function 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 | ||
98 | end | ||
99 | |||
100 | return utils | ||