aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniil Rozanov <daniilrozzanov@gmail.com>2024-05-03 01:24:29 +0300
committerDaniil Rozanov <daniilrozzanov@gmail.com>2024-05-03 01:24:29 +0300
commit1caad46f40e1965e4bf0cc68d98f341bc4310d8c (patch)
tree622cab831bb5354cbb7be72ab213617652199818
parentbbe3a27633002d9eb37c98603e34a00e9ea9d962 (diff)
docs: lua documentation for most used tables and functions
-rw-r--r--lua/cmake/actions.lua9
-rw-r--r--lua/cmake/commandline.lua7
-rw-r--r--lua/cmake/config.lua54
-rw-r--r--lua/cmake/fileapi.lua12
-rw-r--r--lua/cmake/init.lua1
-rw-r--r--lua/cmake/project.lua86
-rw-r--r--lua/cmake/variants.lua3
7 files changed, 160 insertions, 12 deletions
diff --git a/lua/cmake/actions.lua b/lua/cmake/actions.lua
index 9f16bf5..0eff4ed 100644
--- a/lua/cmake/actions.lua
+++ b/lua/cmake/actions.lua
@@ -54,7 +54,7 @@ end
---@return table
local _extend_generate_command = function(command, opts)
opts = opts or {}
- local new = vim.tbl_deep_extend("keep", command, {})
+ local new = vim.deepcopy(command)
return new
end
@@ -63,13 +63,16 @@ end
---@param opts BuildOpts
---@return table
local _extend_build_command = function(command, opts)
- local new = vim.tbl_deep_extend("keep", command, {})
+ local new = vim.deepcopy(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
+ if opts.target and #opts.target ~= 0 then
+ new.args = new.args .. " --target " .. table.concat(opts.target, " ")
+ end
return new
end
@@ -157,7 +160,7 @@ end
---@class BuildOpts
---@field clean boolean|nil
---@field j number|nil
----@field target number|nil
+---@field target string[]|nil
--- Build project with current build option
--- @param opts BuildOpts
diff --git a/lua/cmake/commandline.lua b/lua/cmake/commandline.lua
index 55c671c..c3d0ef1 100644
--- a/lua/cmake/commandline.lua
+++ b/lua/cmake/commandline.lua
@@ -67,7 +67,10 @@ end
local build_options = {
clean = true,
- targets = complete_value(project.current_targets, {}, "name"),
+ j = function()
+ return {}
+ end,
+ target = complete_value(project.current_targets, {}, "name"),
}
local install_options = {
@@ -128,7 +131,7 @@ function M.parse(args)
if not value then
result[key] = true
else
- if key == "targets" then
+ if key == "target" then
result[key] = vim.split(value, ",")
else
result[key] = value
diff --git a/lua/cmake/config.lua b/lua/cmake/config.lua
index 0cc95ca..0392319 100644
--- a/lua/cmake/config.lua
+++ b/lua/cmake/config.lua
@@ -1,3 +1,52 @@
+---@class CMakeConfig
+---@field cmake CMakeConfigCMake Configuration for `cmake` command itself
+---@field save_before_build boolean Save all unsaved files before running `cmake`
+---@field generate_after_save boolean Generate after saving `CMakeLists.txt` file
+---@field cmake_terminal CMakeConfigCMakeTerminal Settings for terminal where cmake will be executed
+---@field target_terminal CMakeConfigTargetTerminal Settings for terminal where executable targets will be executed
+---@field disabled_commands string[] List of commands that will not be initialized
+
+---@class CMakeConfigCMake
+---@field cmake_path string Path to `cmake` executable
+---@field ctest_path string Path to `ctest` executable
+---@field cpack_path string Path to `cpack` executable
+---@field build_args string[] An array of additional arguments to pass to `cmake --build`
+---@field build_tool_args string[] An array of additional arguments to pass to the underlying build tool
+---@field generator? string Set to a string to override CMake Tools’ preferred generator logic. If this is set, CMake will unconditionally use it as the -G CMake generator command line argument
+---@field parallel_jobs? number By specifying a number, you can define how many jobs are run in parallel during the build
+---@field variants {[string]:CMakeVariant} Default variants. Parameters defined in variants have more priority than defined in `cmake = {...}` ones
+
+---@class CMakeVariant
+---@field default string Default choice
+---@field description string Description for variant option
+---@field choices {[string]:CMakeVariantChoice} Choices for variant option
+
+---@class CMakeVariantChoice
+---@field short string Short description for choice
+---@field long? string Short description for choice
+---@field buildType? string Value for `CMAKE_BUILD_TYPE` variable.
+---@field generator? string Set to a string to override CMake Tools’ preferred generator logic. If this is set, CMake will unconditionally use it as the -G CMake generator command line argument
+---@field buildArgs? string[] An array of additional arguments to pass to `cmake --build`
+---@field buildToolArgs? string[] An array of additional arguments to pass to the underlying build tool
+---@field settings? {[string]:string} Table of parameters which will be passed as `-Dkey=value` to `cmake` command
+---@field env? {[string]:string} Table of parameters which will be passed as environment variables to `cmake`
+---@field linkage? "static"|"shared" Linkage type
+
+---@class CMakeConfigCMakeTerminal
+---@field split "left"|"right"|"below"|"above" Split direction
+---@field size number Terminal's size in lines
+---@field close_on_exit "success"|"failure"|boolean When to close termilal. `"success"` - after success, `"failure"` - after failure, `true` - always, `false` - never
+---@field open_on_start boolean Open terminal when `cmake` starts
+---@field clear_env boolean Do not pass shell environment to cmake process
+---@field enter boolean Focus on opened terminal window
+
+---@class CMakeConfigTargetTerminal
+---@field split "left"|"right"|"below"|"above" Split direction
+---@field size number Terminal's size in lines
+---@field enter boolean Focus on opened terminal window
+---@field immediately boolean Run command immediately. If false, command will just be pasted to terminal so you can modify it
+
+---@type CMakeConfig
local default_config = {
cmake = {
cmake_path = "cmake",
@@ -37,8 +86,8 @@ local default_config = {
target_terminal = {
split = "below",
size = 15,
- clear_env = false,
enter = true,
+ immediately = true,
},
notification = {
after = "success",
@@ -48,10 +97,13 @@ local default_config = {
long = { sep = " ❄ ", show = false },
},
keybinds = {},
+ disable_commands = {},
}
local M = vim.deepcopy(default_config)
+---Setup configs
+---@param opts CMakeConfig
M.setup = function(opts)
local newconf = vim.tbl_deep_extend("force", default_config, opts or {})
diff --git a/lua/cmake/fileapi.lua b/lua/cmake/fileapi.lua
index 213fab3..6beffcb 100644
--- a/lua/cmake/fileapi.lua
+++ b/lua/cmake/fileapi.lua
@@ -8,6 +8,16 @@ local reply_dir_suffix = { ".cmake", "api", "v1", "reply" }
local FileApi = {}
+---@class CMakeFileApi
+---@field targets CMakeFileApiTarget[]
+---@field current_executable_target? number Index for current executable target
+---
+---@class CMakeFileApiTarget
+---@field id string Unique tagret id
+---@field name string Target name
+---@field type "EXECUTABLE"|"STATIC_LIBRARY"|"SHARED_LIBRARY"|"MODULE_LIBRARY"|"OBJECT_LIBRARY"|"INTERFACE_LIBRARY"|"UTILITY" Target type
+---@field path string|nil Path to executable associated with target
+
function FileApi.create(path, callback)
local query = vim.fs.joinpath(path, unpack(query_path_suffix))
utils.file_exists(query, function(exists)
@@ -55,10 +65,12 @@ function FileApi.read_reply(path, callback)
Path:new(reply_dir, target.jsonFile):absolute(),
function(target_data)
local target_json = vim.json.decode(target_data)
+ ---@type CMakeTarget
local _target = {
id = target_json.id,
name = target_json.name,
type = target_json.type,
+ path = nil,
}
if target_json.artifacts then
--NOTE: add_library(<name> OBJECT ...) could contain more than ohe object in artifacts
diff --git a/lua/cmake/init.lua b/lua/cmake/init.lua
index be5308b..6d7843c 100644
--- a/lua/cmake/init.lua
+++ b/lua/cmake/init.lua
@@ -15,6 +15,7 @@ function M.setup(opts)
autocmds.setup()
utils.file_exists(vim.fs.joinpath(uv.cwd(), constants.cmakelists), function(cmake_lists_exists)
if cmake_lists_exists then
+ --TODO: init autocommands needs to be related with project setup
vim.schedule(function()
autocmds.set_on_variants()
commands.register_commands()
diff --git a/lua/cmake/project.lua b/lua/cmake/project.lua
index 36e2645..f5afde2 100644
--- a/lua/cmake/project.lua
+++ b/lua/cmake/project.lua
@@ -9,10 +9,34 @@ local Project = {}
local initialised = false
+---@type CMakeGenerateOption[]
local configs = {}
+---@type number|nil
local current_config = nil
+---@type CMakeFileApi[]
local fileapis = {}
+---@class CMakeGenerateOption Initial configuration, which defines generation stage, it's build stages, it's targets and other artifacts produced by `cmake -S <source_dir> -B <build_dir> ...` command
+---@field generate_command CMakeCommand Command which will be executed on generate stage
+---@field directory string Absolute path to build directory created after generate stage
+---@field build_options CMakeBuildOption[] Build options available for this generate options. Each build option have it's generate option scope
+---@field current_build number Current build option's index
+---@field name string[] Parts of short name to display. Should be concatenated with delimiter
+---@field long_name string[] Parts of long name to display. Should be concatenated with delimiter
+
+---@class CMakeBuildOption Option corresponding to build stage
+---@field command CMakeCommand Command which will be executed on build stage
+---@field name string[] Parts of short name to display. Should be concatenated with delimiter
+---@field long_name string[] Parts of long name to display. Should be concatenated with delimiter
+
+---@class CMakeCommand Command table to pass to any kind of runner or task manager
+---@field cmd string Path to executable command
+---@field args string|nil Command's arguments
+---@field env {[string]:string}[]|nil Environvemt variables
+---@field cwd string Current working directory
+---@field after_success function|nil Function which neends to be invoked after command succesfully executed
+
+--- Set internal variables to default
local reset_internals = function()
configs = {}
current_config = nil
@@ -20,6 +44,8 @@ local reset_internals = function()
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
@@ -42,6 +68,7 @@ local append_after_success_actions = function()
end
end
+--- Clear existing fileapis and read from available build directories
local init_fileapis = function()
fileapis = {}
for _, v in ipairs(configs) do
@@ -60,6 +87,9 @@ end
-- TODO: validate yaml and fallback to config's variants if not valid
-- TODO: make variants order more stable. at least when reading from file
+
+---Initialise project from variants
+---@param variants table
function Project.from_variants(variants)
local variants_copy = vim.deepcopy(variants)
local list_variants = {}
@@ -82,6 +112,7 @@ function Project.from_variants(variants)
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")
@@ -96,31 +127,43 @@ function Project.clear_cache()
-- end)
end
-function Project.generate_options(opts)
- opts = opts or {}
+--- Get all project's generate configs
+--- @return CMakeGenerateOption[]
+function Project.generate_options()
return configs
end
---TODO: remove opts where it is useless
-function Project.current_generate_option(opts)
- opts = opts or {}
+--- Get current generate option
+---@return unknown
+function Project.current_generate_option()
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
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
end
---TODO: check on out of range
+--- Current build option's index
+---@return number
function Project.current_build_option_idx()
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
@@ -128,14 +171,22 @@ function Project.current_build_option()
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 = #Project[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
end
+---Current fileapi
+---@return CMakeFileApi|nil
local current_fileapi = function()
if not Project.current_directory() or not fileapis[Project.current_directory()] then
return nil
@@ -143,10 +194,20 @@ local current_fileapi = function()
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
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
@@ -155,6 +216,8 @@ function Project.current_executable_target_idx()
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
@@ -167,6 +230,9 @@ function Project.current_executable_target()
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()
@@ -181,6 +247,11 @@ function Project.current_targets(opts)
return _curr_fileapi.targets
end
+--TODO: opts -> config identifier (which can be number, string or configuration table)
+
+---Create `query.json` file so `cmake` will produce reply directory
+---@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
@@ -221,6 +292,9 @@ local do_setup = function(opts)
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
diff --git a/lua/cmake/variants.lua b/lua/cmake/variants.lua
index 6a4c859..cb846e8 100644
--- a/lua/cmake/variants.lua
+++ b/lua/cmake/variants.lua
@@ -79,6 +79,9 @@ local _build_command = function(obj, build_args)
return ret
end
+---Create configuration from variant
+---@param source table
+---@return CMakeGenerateOption
function VariantConfig:new(source)
local obj = {}
local subs = vim.tbl_deep_extend("keep", global_variant_subs, { ["${buildType}"] = source.buildType })