aboutsummaryrefslogtreecommitdiff
path: root/lua/tasks/init.lua
blob: 4b6c893cc3473bacba5d770ce3ce900434277304 (plain) (blame)
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
local config = require('tasks.config')
local runner = require('tasks.runner')
local constants = require('tasks.constants')
local utils = require('tasks.utils')
local ProjectConfig = require('tasks.project_config')
local tasks = {}

--- Apply user settings.
---@param values table
function tasks.setup(values) setmetatable(config, { __index = vim.tbl_deep_extend('force', config.defaults, values) }) end

--- Execute a task from a module.
---@param module_type string: Name of a module or `auto` string to pick a first module that match a condition.
---@param task_name string
---@vararg string additional arguments that will be passed to the last task.
function tasks.start(module_type, task_name, ...)
  local current_job_name = runner.get_current_job_name()
  if current_job_name then
    utils.notify(string.format('Another job is currently running: "%s"', current_job_name), vim.log.levels.ERROR)
    return
  end

  local module, module_name = utils.get_module(module_type)
  if not module then
    return
  end

  local commands = module.tasks[task_name]
  if not commands then
    utils.notify(string.format('Unable to find a task named "%s" in module "%s"', task_name, module_name), vim.log.levels.ERROR)
    return
  end

  if config.save_before_run then
    vim.api.nvim_command('silent! wall')
  end

  local project_config = ProjectConfig.new()
  local module_config = project_config[module_name]
  if not vim.tbl_islist(commands) then
    commands = { commands }
  end
  runner.chain_commands(task_name, commands, module_config, { ... })
end

--- Set a module-specific parameter. Settings will be stored on disk.
---@param module_type string: Name of a module or `auto` string to pick a first module that match a condition.
---@param param_name string
function tasks.set_module_param(module_type, param_name)
  local module, module_name = utils.get_module(module_type)
  if not module then
    return
  end

  if not module then
    return
  end

  local project_config = ProjectConfig.new()
  local current_value = vim.tbl_get(project_config, module_name, param_name)

  local param = module.params[param_name]
  if not param then
    if vim.tbl_contains(module.params, param_name) then
      -- Contains a string without a value, request for input
      vim.ui.input({ prompt = string.format('Set "%s" for module "%s"', param_name, module_name), default = current_value }, function(input)
        project_config[module_name][param_name] = input
        project_config:write()
      end)
    else
      utils.notify(string.format('No such parameter "%s" for module "%s"', param_name, module_name), vim.log.levels.ERROR)
    end
    return
  end

  if vim.is_callable(param) then
    param = param()
    if not param then
      return
    end
  end

  -- Put current value first
  if current_value then
    for index, value in ipairs(param) do
      if value == current_value then
        table.remove(param, index)
        break
      end
    end
    table.insert(param, 1, current_value)
  end

  vim.ui.select(param, { prompt = string.format('Select "%s"', param_name) }, function(choice, idx)
    if not idx then
      return
    end
    if not project_config[module_name] then
      project_config[module_name] = {}
    end
    project_config[module_name][param_name] = choice
    project_config:write()
  end)
end

--- Set a parameter for a module task. Settings will be stored on disk.
---@param module_type string: Name of a module or `auto` string to pick a first module that match a condition.
---@param task_name string
---@param param_name string
function tasks.set_task_param(module_type, task_name, param_name)
  local module, module_name = utils.get_module(module_type)
  if not module then
    return
  end
  if not vim.tbl_contains(constants.task_params, param_name) then
    utils.notify(string.format('Unknown task parameter "%s"\nAvailable task parameters: %s', param_name, table.concat(constants.task_params, ', ')), vim.log.levels.ERROR)
    return
  end

  local project_config = ProjectConfig.new()
  local current_value = vim.tbl_get(project_config, module_name, param_name, task_name)
  current_value = current_value and utils.join_args(current_value) or ''
  vim.ui.input({ prompt = string.format('Set "%s" for task "%s" from module "%s": ', param_name, task_name, module_name), default = current_value, completion = 'file' }, function(input)
    if not project_config[module_name] then
      project_config[module_name] = {}
    end
    if not project_config[module_name][param_name] then
      project_config[module_name][param_name] = {}
    end
    project_config[module_name][param_name][task_name] = utils.split_args(input)
    project_config:write()
  end)
end

--- Cancel last current task.
function tasks.cancel()
  if not runner.cancel_job() then
    utils.notify('No running process')
  end
end

return tasks