diff options
author | Daniil Rozanov <daniilrozzanov@gmail.com> | 2024-05-03 01:24:29 +0300 |
---|---|---|
committer | Daniil Rozanov <daniilrozzanov@gmail.com> | 2024-05-03 01:24:29 +0300 |
commit | 1caad46f40e1965e4bf0cc68d98f341bc4310d8c (patch) | |
tree | 622cab831bb5354cbb7be72ab213617652199818 | |
parent | bbe3a27633002d9eb37c98603e34a00e9ea9d962 (diff) |
docs: lua documentation for most used tables and functions
-rw-r--r-- | lua/cmake/actions.lua | 9 | ||||
-rw-r--r-- | lua/cmake/commandline.lua | 7 | ||||
-rw-r--r-- | lua/cmake/config.lua | 54 | ||||
-rw-r--r-- | lua/cmake/fileapi.lua | 12 | ||||
-rw-r--r-- | lua/cmake/init.lua | 1 | ||||
-rw-r--r-- | lua/cmake/project.lua | 86 | ||||
-rw-r--r-- | lua/cmake/variants.lua | 3 |
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 }) |