aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/cmake/project.lua328
1 files changed, 164 insertions, 164 deletions
diff --git a/lua/cmake/project.lua b/lua/cmake/project.lua
index 0edbb02..4922b49 100644
--- a/lua/cmake/project.lua
+++ b/lua/cmake/project.lua
@@ -38,51 +38,51 @@ local fileapis = {}
--- Set internal variables to default
local reset_internals = function()
- configs = {}
- current_config = nil
- fileapis = {}
- initialised = true
+ configs = {}
+ current_config = nil
+ fileapis = {}
+ initialised = true
end
--- Set `after_success` function to each command which may be executed.
--- These functions do minimal to plugin works
local append_after_success_actions = function()
- local read_reply = function(v, not_presented)
- if (not_presented and not fileapis[v.directory]) or not not_presented then
- utils.symlink(v.directory .. "/compile_commands.json", uv.cwd())
- fileapis[v.directory] = { targets = {} }
- FileApi.read_reply(v.directory, function(target)
- table.insert(fileapis[v.directory].targets, target)
- end)
- end
- end
- for _, v in ipairs(configs) do
- v.generate_command.after_success = function()
- read_reply(v, false)
- end
- for _, bv in ipairs(v.build_options) do
- bv.command.after_success = function()
- read_reply(v, true)
- end
- end
- end
+ local read_reply = function(v, not_presented)
+ if (not_presented and not fileapis[v.directory]) or not not_presented then
+ utils.symlink(v.directory .. "/compile_commands.json", uv.cwd())
+ fileapis[v.directory] = { targets = {} }
+ FileApi.read_reply(v.directory, function(target)
+ table.insert(fileapis[v.directory].targets, target)
+ end)
+ end
+ end
+ for _, v in ipairs(configs) do
+ v.generate_command.after_success = function()
+ read_reply(v, false)
+ end
+ for _, bv in ipairs(v.build_options) do
+ bv.command.after_success = function()
+ read_reply(v, true)
+ end
+ end
+ end
end
--- Clear existing fileapis and read from available build directories
local init_fileapis = function()
- fileapis = {}
- for _, v in ipairs(configs) do
- if not fileapis[v.directory] then
- fileapis[v.directory] = { targets = {} }
- FileApi.exists(v.directory, function(fileapi_exists)
- if fileapi_exists then
- FileApi.read_reply(v.directory, function(target)
- table.insert(fileapis[v.directory].targets, target)
- end)
- end
- end)
- end
- end
+ fileapis = {}
+ for _, v in ipairs(configs) do
+ if not fileapis[v.directory] then
+ fileapis[v.directory] = { targets = {} }
+ FileApi.exists(v.directory, function(fileapi_exists)
+ if fileapi_exists then
+ FileApi.read_reply(v.directory, function(target)
+ table.insert(fileapis[v.directory].targets, target)
+ end)
+ end
+ end)
+ end
+ end
end
-- TODO: validate yaml and fallback to config's variants if not valid
@@ -91,160 +91,160 @@ end
---Initialise project from variants
---@param variants table
function Project.from_variants(variants)
- local variants_copy = vim.deepcopy(variants)
- local list_variants = {}
- for k, v in pairs(variants_copy) do
- table.insert(list_variants, v)
- list_variants[#list_variants]._name = k
- end
- table.sort(list_variants, function(a, b)
- return a._name < b._name
- end)
- for var, is_default in VariantConfig.cartesian_product(list_variants) do
- var.current_build = 1
- table.insert(configs, var)
- current_config = not current_config and is_default and #configs or current_config
- end
- if not current_config and #configs ~= 0 then
- current_config = 1
- end
- append_after_success_actions()
- init_fileapis()
+ local variants_copy = vim.deepcopy(variants)
+ local list_variants = {}
+ for k, v in pairs(variants_copy) do
+ table.insert(list_variants, v)
+ list_variants[#list_variants]._name = k
+ end
+ table.sort(list_variants, function(a, b)
+ return a._name < b._name
+ end)
+ for var, is_default in VariantConfig.cartesian_product(list_variants) do
+ var.current_build = 1
+ table.insert(configs, var)
+ current_config = not current_config and is_default and #configs or current_config
+ end
+ if not current_config and #configs ~= 0 then
+ current_config = 1
+ end
+ append_after_success_actions()
+ init_fileapis()
end
--- Delete `CMakeCache.txt` and `CMakeFiles` from current build directory
function Project.clear_cache()
- local cd = Project.current_directory()
- local Path = require("plenary.path")
- Path:new(vim.fs.joinpath(cd, "CMakeCache.txt")):rm()
- Path:new(vim.fs.joinpath(cd, "CMakeFiles")):rm({ recursive = true })
- -- uv.fs_unlink(vim.fs.joinpath(Project.current_directory(), "CMakeCache.txt"), function(f_err, _)
- -- assert(f_err, f_err)
- -- uv.fs_unlink(vim.fs.joinpath(Project.current_directory(), "CMakeFiles"), function(d_err)
- -- assert(d_err, d_err)
- -- callback()
- -- end)
- -- end)
+ local cd = Project.current_directory()
+ local Path = require("plenary.path")
+ Path:new(vim.fs.joinpath(cd, "CMakeCache.txt")):rm()
+ Path:new(vim.fs.joinpath(cd, "CMakeFiles")):rm({ recursive = true })
+ -- uv.fs_unlink(vim.fs.joinpath(Project.current_directory(), "CMakeCache.txt"), function(f_err, _)
+ -- assert(f_err, f_err)
+ -- uv.fs_unlink(vim.fs.joinpath(Project.current_directory(), "CMakeFiles"), function(d_err)
+ -- assert(d_err, d_err)
+ -- callback()
+ -- end)
+ -- end)
end
--- Get all project's generate configs
--- @return CMakeGenerateOption[]
function Project.generate_options()
- return configs
+ return configs
end
--- Get current generate option
---@return unknown
function Project.current_generate_option()
- assert(current_config, "No current project config")
- return configs[current_config]
+ assert(current_config, "No current project config")
+ return configs[current_config]
end
---Get current generate option's index
---@return number|nil
function Project.current_generate_option_idx()
- return current_config
+ return current_config
end
--- Set current generate option by index
--- @param idx number
function Project.set_current_generate_option(idx)
- assert(
- not (idx < 1 or idx > #configs),
- "Index is out of range. Index is " .. idx .. " for " .. #configs .. " config(s)"
- )
- current_config = idx
+ assert(
+ not (idx < 1 or idx > #configs),
+ "Index is out of range. Index is " .. idx .. " for " .. #configs .. " config(s)"
+ )
+ current_config = idx
end
--- Current build option's index
---@return number
function Project.current_build_option_idx()
- return configs[current_config].current_build
+ return configs[current_config].current_build
end
---Current build option
---@return CMakeBuildOption|nil
function Project.current_build_option()
- if not Project.current_build_option_idx() then
- return nil
- end
- return configs[current_config].build_options[Project.current_build_option_idx()]
+ if not Project.current_build_option_idx() then
+ return nil
+ end
+ return configs[current_config].build_options[Project.current_build_option_idx()]
end
--- Set current build option by index
--- @param idx number
function Project.set_current_build_option(idx)
- local _size = #configs[current_config].build_options
- assert(not (idx < 1 or idx > _size), "Index is out of range. Index is " .. idx .. " for " .. _size .. "config(s)")
- configs[current_config].current_build = idx
+ local _size = #configs[current_config].build_options
+ assert(not (idx < 1 or idx > _size), "Index is out of range. Index is " .. idx .. " for " .. _size .. "config(s)")
+ configs[current_config].current_build = idx
end
---Current build directory (usually `build-<...>`)
---@return string|nil
function Project.current_directory()
- return current_config and configs[current_config].directory or nil
+ return current_config and configs[current_config].directory or nil
end
---Current fileapi
---@return CMakeFileApi|nil
local current_fileapi = function()
- if not Project.current_directory() or not fileapis[Project.current_directory()] then
- return nil
- end
- return fileapis[Project.current_directory()]
+ if not Project.current_directory() or not fileapis[Project.current_directory()] then
+ return nil
+ end
+ return fileapis[Project.current_directory()]
end
---Set current executable target by it's index
---@param idx number
function Project.set_current_executable_target(idx)
- assert(not current_fileapi())
- assert(
- not (idx < 1 or idx > #current_fileapi().targets),
- "Index is out of range. Index is " .. idx .. " for " .. #current_fileapi().targets(" target(s)")
- )
- assert(current_fileapi().targets[idx].type == "EXECUTABLE", "target is not executable")
- current_fileapi().current_executable_target = idx
+ assert(current_fileapi(), "current fileapi in nil")
+ assert(
+ not (idx < 1 or idx > #current_fileapi().targets),
+ "Index is out of range. Index is " .. idx .. " for " .. #current_fileapi().targets .. " target(s)"
+ )
+ assert(current_fileapi().targets[idx].type == "EXECUTABLE", "target is not executable")
+ current_fileapi().current_executable_target = idx
end
---Current executable target's index
---@return number|nil
function Project.current_executable_target_idx()
- local _curr_fileapi = current_fileapi()
- if not _curr_fileapi then
- return nil
- end
- return _curr_fileapi.current_executable_target
+ local _curr_fileapi = current_fileapi()
+ if not _curr_fileapi then
+ return nil
+ end
+ return _curr_fileapi.current_executable_target
end
---Current executable target
---@return CMakeFileApiTarget|nil
function Project.current_executable_target()
- local _curr_fileapi = current_fileapi()
- if not _curr_fileapi then
- return nil
- end
- local _curr_exe_target_idx = Project.current_executable_target_idx()
- if not _curr_exe_target_idx then
- return nil
- end
- return _curr_fileapi.targets[_curr_exe_target_idx]
+ local _curr_fileapi = current_fileapi()
+ if not _curr_fileapi then
+ return nil
+ end
+ local _curr_exe_target_idx = Project.current_executable_target_idx()
+ if not _curr_exe_target_idx then
+ return nil
+ end
+ return _curr_fileapi.targets[_curr_exe_target_idx]
end
---Targets for current generate option (configuration)
---@param opts {type: string|nil}|nil Filter parameters
---@return CMakeFileApiTarget[]|nil
function Project.current_targets(opts)
- opts = opts or {}
- local _curr_fileapi = current_fileapi()
- if not _curr_fileapi then
- return nil
- end
- if opts.type then
- return vim.tbl_filter(function(t)
- return t.type == opts.type
- end, _curr_fileapi.targets)
- end
- return _curr_fileapi.targets
+ opts = opts or {}
+ local _curr_fileapi = current_fileapi()
+ if not _curr_fileapi then
+ return nil
+ end
+ if opts.type then
+ return vim.tbl_filter(function(t)
+ return t.type == opts.type
+ end, _curr_fileapi.targets)
+ end
+ return _curr_fileapi.targets
end
--TODO: opts -> config identifier (which can be number, string or configuration table)
@@ -253,60 +253,60 @@ end
---@param opts {idx:number, path:string, config:CMakeGenerateOption}|nil Specity configuration to generate query
---@param callback function Callback. Will be executed after query created or if it already exists
function Project.create_fileapi_query(opts, callback)
- opts = opts or {}
- local path
+ opts = opts or {}
+ local path
- if type(opts.idx) == "number" then
- path = configs[opts.idx].directory
- elseif type(opts.path) == "string" then
- path = opts.path
- --TODO: compare getmetatable(opts.config) with VariantConfig (and PresetsConfig in future)
- elseif type(opts.config) == "table" then
- path = opts.config.directory
- else
- path = configs[current_config].directory
- end
- FileApi.query_exists(path, function(query_exists)
- if not query_exists then
- FileApi.create(path, function()
- callback()
- end)
- else
- callback()
- end
- end)
+ if type(opts.idx) == "number" then
+ path = configs[opts.idx].directory
+ elseif type(opts.path) == "string" then
+ path = opts.path
+ --TODO: compare getmetatable(opts.config) with VariantConfig (and PresetsConfig in future)
+ elseif type(opts.config) == "table" then
+ path = opts.config.directory
+ else
+ path = configs[current_config].directory
+ end
+ FileApi.query_exists(path, function(query_exists)
+ if not query_exists then
+ FileApi.create(path, function()
+ callback()
+ end)
+ else
+ callback()
+ end
+ end)
end
local do_setup = function(opts)
- reset_internals()
- local variants_path = vim.fs.joinpath(uv.cwd(), constants.variants_yaml_filename)
- utils.file_exists(variants_path, function(variants_exists)
- if variants_exists then
- utils.read_file(variants_path, function(variants_data)
- local yaml = require("cmake.lyaml").eval(variants_data)
- Project.from_variants(yaml)
- end)
- else
- Project.from_variants(config.variants)
- end
- end)
+ reset_internals()
+ local variants_path = vim.fs.joinpath(uv.cwd(), constants.variants_yaml_filename)
+ utils.file_exists(variants_path, function(variants_exists)
+ if variants_exists then
+ utils.read_file(variants_path, function(variants_data)
+ local yaml = require("cmake.lyaml").eval(variants_data)
+ Project.from_variants(yaml)
+ end)
+ else
+ Project.from_variants(config.variants)
+ end
+ end)
end
---Setup project, which means get capabilities, create configurations from presets or variants
---and read fileapis
---@param opts {first_time_only: boolean}|nil
function Project.setup(opts)
- opts = opts or {}
- if opts.first_time_only and initialised then
- return
- end
- if not initialised then
- require("cmake.capabilities").setup(function()
- do_setup(opts)
- end)
- else
- do_setup(opts)
- end
+ opts = opts or {}
+ if opts.first_time_only and initialised then
+ return
+ end
+ if not initialised then
+ require("cmake.capabilities").setup(function()
+ do_setup(opts)
+ end)
+ else
+ do_setup(opts)
+ end
end
return Project