aboutsummaryrefslogtreecommitdiff
path: root/lua/cmake/actions.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/cmake/actions.lua')
-rw-r--r--lua/cmake/actions.lua198
1 files changed, 155 insertions, 43 deletions
diff --git a/lua/cmake/actions.lua b/lua/cmake/actions.lua
index 8c5a300..972e07e 100644
--- a/lua/cmake/actions.lua
+++ b/lua/cmake/actions.lua
@@ -5,13 +5,13 @@ local utils = require("cmake.utils")
local constants = require("cmake.constants")
local Path = require("plenary.path")
-local uv = vim.uv or vim.loop
+local uv = vim.uv
local M = {}
local default_generate_exe_opts = {
notify = {
- ok_message = "CMake build finished",
+ ok_message = "CMake generate finished",
err_message = function(code)
return "CMake generate failed with code " .. tostring(code)
end,
@@ -27,57 +27,161 @@ local default_build_exe_opts = {
},
}
-M.reset_project = function(opts)
- require("cmake.project").setup(opts)
+local _explain = function(command)
+ vim.notify(
+ table.concat({
+ table.concat(
+ vim.iter(command.env or {})
+ :map(function(k, v)
+ if v:find(" ") then
+ return k .. '="' .. v .. '"'
+ end
+ return k .. "=" .. v
+ end)
+ :totable(),
+ " "
+ ),
+ command.cmd,
+ command.args,
+ }, " "),
+ vim.log.levels.INFO
+ )
end
-M.generate = function(opts)
+--- Extends generate command by given options
+---@param command table
+---@param opts GenerateOpts
+---@return table
+local _extend_generate_command = function(command, opts)
+ opts = opts or {}
+ local new = vim.tbl_deep_extend("keep", command, {})
+ return new
+end
+
+--- Extends build command by given options
+---@param command table
+---@param opts BuildOpts
+---@return table
+local _extend_build_command = function(command, opts)
+ local new = vim.tbl_deep_extend("keep", command, {})
+ if opts.j then
+ new.args = new.args .. " -j " .. tostring(opts.j)
+ end
+ if opts.clean then
+ new.args = new.args .. " --clean-first"
+ end
+ return new
+end
+
+local _generate = function(option, opts)
+ opts = opts or {}
+ local main_path = function()
+ pr.create_fileapi_query({}, function()
+ vim.schedule(function()
+ t.cmake_execute(_extend_generate_command(option.generate_command, opts), default_generate_exe_opts)
+ end)
+ end)
+ end
+ if opts.fresh then
+ pr.clear_cache(main_path)
+ else
+ main_path()
+ end
+end
+
+local _for_current_generate_option = function(func)
local idx = pr.current_generate_option_idx()
if not idx then
- vim.notify("CMake: no project to generate")
- return
+ vim.notify("CMake: no configuration to generate", vim.log.levels.WARN)
+ else
+ func(pr.current_generate_option())
end
- pr.create_fileapi_query({ idx = idx }, function()
- vim.schedule(function()
- t.cmake_execute(pr.current_generate_option().generate_command, default_generate_exe_opts)
- end)
+end
+
+---@class GenerateOpts
+---@field fresh boolean|nil
+
+--- Generate project with current generate option
+--- @param opts GenerateOpts
+M.generate = function(opts)
+ opts = opts or {}
+ _for_current_generate_option(function(option)
+ _generate(option, opts)
+ end)
+end
+
+--- Generate project with current generate option
+--- @param opts GenerateOpts
+M.generate_explain = function(opts)
+ opts = opts or {}
+ _for_current_generate_option(function(option)
+ _explain(_extend_generate_command(option.generate_command, opts))
end)
end
+--- Generate project with current generate option
+--- @param opts table|nil
M.generate_select = function(opts)
+ opts = opts or {}
local items = pr.generate_options(opts)
vim.ui.select(items, {
prompt = "Select configuration to generate:",
format_item = function(item)
return table.concat(item.name, config.variants_display.short.sep)
end,
- }, function(choice, idx)
+ }, function(_, idx)
if not idx then
return
end
pr.set_current_generate_option(idx)
- pr.create_fileapi_query({ idx = idx }, function()
- vim.schedule(function()
- t.cmake_execute(choice.generate_command, default_generate_exe_opts)
- end)
- end)
end)
end
-M.build = function(opts)
- if not pr.current_build_option_idx() then
- M.build_select(opts)
+local _for_current_build_option = function(func)
+ local idx = pr.current_build_option()
+ if not idx then
+ vim.notify("CMake: no build configuration to generate", vim.log.levels.WARN)
else
- pr.create_fileapi_query({ idx = pr.current_build_option_idx() }, function()
- vim.schedule(function()
- t.cmake_execute(pr.current_build_option().command, default_build_exe_opts)
- end)
- end)
+ func(pr.current_build_option())
end
end
+local _build = function(option, opts)
+ opts = opts or {}
+ pr.create_fileapi_query({}, function()
+ vim.schedule(function()
+ t.cmake_execute(_extend_build_command(option.command, opts), default_build_exe_opts)
+ end)
+ end)
+end
+
+---@class BuildOpts
+---@field clean boolean|nil
+---@field j number|nil
+---@field target number|nil
+
+--- Build project with current build option
+--- @param opts BuildOpts
+M.build = function(opts)
+ opts = opts or {}
+ _for_current_build_option(function(option)
+ _build(option, opts)
+ end)
+end
+
+--- Build project with current build option
+--- @param opts BuildOpts
+M.build_explain = function(opts)
+ opts = opts or {}
+ _for_current_build_option(function(option)
+ _explain(_extend_build_command(option.command, opts))
+ end)
+end
+
+---Change current build option
+---@param opts any|nil
M.build_select = function(opts)
- local items = pr.current_generate_option(opts).build_options
+ local items = pr.current_generate_option().build_options
vim.ui.select(items, {
prompt = "Select build option to generate:",
format_item = function(item)
@@ -88,28 +192,34 @@ M.build_select = function(opts)
return
end
pr.set_current_build_option(idx)
- pr.create_fileapi_query({ idx = idx }, function()
- vim.schedule(function()
- t.cmake_execute(choice.command, default_build_exe_opts)
- end)
- end)
end)
end
-M.run_tagret = function(opts)
+local _run_target = function(opts)
+ local command = {
+ cmd = opts.path,
+ cwd = pr.current_directory(),
+ }
+ t.target_execute(command)
+end
+
+---@class RunTargetOpts
+---@field explain boolean|nil
+
+--- Run target
+--- @param opts RunTargetOpts
+M.run_target = function(opts)
opts = opts or {}
local _curr_exe_cmd = pr.current_executable_target()
if not _curr_exe_cmd then
- M.run_tagret_select(opts)
+ M.run_target_select(opts)
else
- local command = {
- cmd = Path:new(pr.current_directory(), _curr_exe_cmd.path):make_relative(uv.cwd()),
- }
- t.target_execute(command)
+ _run_target({ path = _curr_exe_cmd.path })
end
end
-M.run_tagret_select = function(opts)
+--- Select target to run
+M.run_target_select = function(opts)
opts = opts or {}
opts.type = "EXECUTABLE"
local items = pr.current_targets(opts)
@@ -118,22 +228,20 @@ M.run_tagret_select = function(opts)
format_item = function(item)
return item.name
end,
- }, function(choice, idx)
+ }, function(_, idx)
if not idx then
return
end
pr.set_current_executable_target(idx)
- local command = {
- cmd = Path:new(pr.current_directory(), choice.path):make_relative(uv.cwd()),
- }
- t.target_execute(command)
end)
end
+---Toggle CMake terminal window
M.toggle = function()
t.cmake_toggle()
end
+---Edit `.cmake-variants.yaml` file
M.edit_variants = function()
utils.file_exists(constants.variants_yaml_filename, function(variants_exists)
if variants_exists then
@@ -151,4 +259,8 @@ M.edit_variants = function()
end)
end
+M.reset_project = function(opts)
+ require("cmake.project").setup(opts)
+end
+
return M