diff --git a/README.md b/README.md index 6faffed..07e01ba 100644 --- a/README.md +++ b/README.md @@ -23,16 +23,27 @@ or to configure `codesettings.nvim` itself with local files. - lazy.nvim (recommended) + + ```lua return { 'mrjones2014/codesettings.nvim', -- these are the default settings just set `opts = {}` to use defaults opts = { ---Look for these config files - config_file_paths = { '.vscode/settings.json', 'codesettings.json', 'lspsettings.json' }, + config_file_paths = { ".vscode/settings.json", "codesettings.json", "lspsettings.json" }, + ---Set filetype to jsonc when opening a file specified by `config_file_paths`, + ---make sure you have the json tree-sitter parser installed for highlighting + jsonc_filetype = true, ---Integrate with jsonls to provide LSP completion for LSP settings based on schemas jsonls_integration = true, - ---Set up library paths for lua_ls automatically to pick up the generated type + ---Enable live reloading of settings when config files change; for servers that support it, + ---this is done via the `workspace/didChangeConfiguration` notification, otherwise the + ---server is restarted + live_reload = false, + ---List of loader extensions to use when loading settings; `string` values will be `require`d + loader_extensions = {}, + ---Set up library paths for `lua_ls` automatically to pick up the generated type ---annotations provided by codesettings.nvim; to enable for only your nvim config, ---you can also do something like: ---lua_ls_integration = function() @@ -40,19 +51,12 @@ return { ---end, ---This integration also works for emmylua_ls lua_ls_integration = true, - ---Set filetype to jsonc when opening a file specified by `config_file_paths`, - ---make sure you have the json tree-sitter parser installed for highlighting - jsonc_filetype = true, - ---Enable live reloading of settings when config files change; for servers that support it, - ---this is done via the `workspace/didChangeConfiguration` notification, otherwise the - ---server is restarted - live_reload = false, + ---How to merge lists; 'append' (default), 'prepend' or 'replace' + merge_lists = "append", ---Provide your own root dir; can be a string or function returning a string. ---It should be/return the full absolute path to the root directory. ---If not set, defaults to `require('codesettings.util').get_root()` root_dir = nil, - --- How to merge lists; 'append' (default), 'prepend' or 'replace' - merge_lists = 'append', }, -- I recommend loading on these filetype so that the -- jsonls integration, lua_ls integration, and jsonc filetype setup works @@ -60,6 +64,8 @@ return { } ``` + + `codesettings.nvim` can also be specified in the local JSON configuration files by using a top-level `codesettings` object key, and these _override the global plugin configuration._ For example: @@ -369,7 +375,7 @@ This project would not exist without the hard work of some other open source pro ## Supported LSP Servers - + - [x] [als](https://github.com/AdaCore/ada_language_server/tree/master/integration/vscode/ada/package.json) - [x] [angularls](https://github.com/angular/vscode-ng-language-service/refs/heads/tree/main/package.json) @@ -444,3 +450,4 @@ This project would not exist without the hard work of some other open source pro - [x] [zeta_note](https://github.com/artempyanykh/zeta-note-vscode/tree/main/package.json) - [x] [zls](https://github.com/zigtools/zls-vscode/tree/master/package.json) + diff --git a/lua/codesettings/build/doc.lua b/lua/codesettings/build/doc.lua index ac122c8..f72e976 100644 --- a/lua/codesettings/build/doc.lua +++ b/lua/codesettings/build/doc.lua @@ -1,13 +1,17 @@ +local ConfigSchema = require('codesettings.config.schema') local Schemas = require('codesettings.build.schemas') local Util = require('codesettings.util') local M = {} -function M.build() - if #arg == 0 then - error('This function is part of a build tool and should not be called directly!') - end - print('Generating list of supported LSP servers in README.md...') +---@class DocSection +---@field start_marker string The start marker to find in the README (without ) +---@field end_marker string The end marker to find in the README (without ) +---@field generator fun(): string Function that generates the content for this section + +---Generate the LSP servers list section +---@return string +local function generate_lsp_servers() local lines = {} local schemas = Schemas.get_schemas() local lsp_names = vim.tbl_keys(schemas) @@ -24,10 +28,112 @@ function M.build() end table.insert(lines, ('- [x] [%s](%s)'):format(name, url)) end - local generated_doc = '\n\n' .. table.concat(lines, '\n') .. '\n' + return table.concat(lines, '\n') +end + +---Format a value for Lua code +---@param value any +---@return string +local function format_value(value) + if value == nil or value == vim.NIL then + return 'nil' + elseif type(value) == 'string' then + return vim.inspect(value) + elseif type(value) == 'table' and vim.tbl_isempty(value) then + return '{}' + else + return vim.inspect(value) + end +end + +---Generate the default config section +---@return string +local function generate_default_config() + local lines = {} + table.insert(lines, '```lua') + table.insert(lines, 'return {') + table.insert(lines, " 'mrjones2014/codesettings.nvim',") + table.insert(lines, ' -- these are the default settings just set `opts = {}` to use defaults') + table.insert(lines, ' opts = {') + + -- Get sorted property names + local props = vim.tbl_keys(ConfigSchema.properties) + table.sort(props) + + for _, name in ipairs(props) do + local prop = ConfigSchema.properties[name] + + -- Add description as comment + if prop.description then + -- Handle multi-line descriptions + for line in prop.description:gmatch('[^\n]+') do + table.insert(lines, ' ---' .. line) + end + end + + -- Add the field with default value + local default_val = prop.default + if default_val == vim.NIL then + default_val = nil + end + + local formatted_value = format_value(default_val) + table.insert(lines, ' ' .. name .. ' = ' .. formatted_value .. ',') + end + + table.insert(lines, ' },') + table.insert(lines, ' -- I recommend loading on these filetype so that the') + table.insert(lines, ' -- jsonls integration, lua_ls integration, and jsonc filetype setup works') + table.insert(lines, " ft = { 'json', 'jsonc', 'lua' },") + table.insert(lines, '}') + table.insert(lines, '```') + + return table.concat(lines, '\n') +end + +---@type DocSection[] +local sections = { + { + start_marker = 'GENERATED:CONFIG:START', + end_marker = 'GENERATED:CONFIG:END', + generator = generate_default_config, + }, + { + start_marker = 'GENERATED:SERVERS:START', + end_marker = 'GENERATED:SERVERS:END', + generator = generate_lsp_servers, + }, +} + +function M.build() + if #arg == 0 then + error('This function is part of a build tool and should not be called directly!') + end + + print('Generating documentation sections in README.md...') local readme = Util.read_file('README.md') - readme = readme:gsub('.*', generated_doc) .. '\n' + + -- Process each section + for _, section in ipairs(sections) do + local content = section.generator() + local start_pattern = '' + local end_pattern = '' + + -- Replace content between start and end markers + local pattern = '(' .. start_pattern .. ').-(' .. end_pattern .. ')' + local replacement = '%1\n\n' .. content .. '\n\n%2' + + local new_readme, count = readme:gsub(pattern, replacement) + if count > 0 then + readme = new_readme + print(' Generated section: ' .. section.start_marker:gsub(':START', '')) + else + print(' Warning: Markers not found: ' .. section.start_marker .. ' / ' .. section.end_marker) + end + end + Util.write_file('README.md', readme) + print('Documentation generation complete!') end return M diff --git a/lua/codesettings/config/schema.lua b/lua/codesettings/config/schema.lua index ae80452..2b6b4f7 100644 --- a/lua/codesettings/config/schema.lua +++ b/lua/codesettings/config/schema.lua @@ -33,20 +33,22 @@ M.properties = { config_file_paths = { type = 'array', items = { type = 'string', description = 'List of relative config file paths to look for' }, - description = 'List of config file paths to look for', + description = 'Look for these config files', default = { '.vscode/settings.json', 'codesettings.json', 'lspsettings.json' }, overridable = true, }, merge_lists = { type = 'CodesettingsMergeListsBehavior', - description = 'How to merge list fields when combining settings from multiple sources', + description = [[How to merge lists; 'append' (default), 'prepend' or 'replace']], enum = { 'replace', 'append', 'prepend' }, default = 'append', overridable = true, }, root_dir = { type = { 'string', { args = {}, ret = 'string' }, 'null' }, - description = "Function or string to determine the project root directory; defaults to `require('codesettings.util').get_root()`", + description = [[Provide your own root dir; can be a string or function returning a string. +It should be/return the full absolute path to the root directory. +If not set, defaults to `require('codesettings.util').get_root()`]], default = vim.NIL, overridable = true, }, @@ -62,22 +64,31 @@ M.properties = { }, jsonls_integration = { type = 'boolean', - description = 'Integrate with jsonls for LSP settings completion', + description = 'Integrate with jsonls to provide LSP completion for LSP settings based on schemas', default = true, }, lua_ls_integration = { type = { 'boolean', { args = {}, ret = 'boolean' } }, - description = 'Integrate with lua_ls for LSP settings completion; can be a function so that, for example, you can enable it only if editing your nvim config', + description = [[Set up library paths for `lua_ls` automatically to pick up the generated type +annotations provided by codesettings.nvim; to enable for only your nvim config, +you can also do something like: +lua_ls_integration = function() + return vim.uv.cwd() == ('%%s/.config/nvim'):format(vim.env.HOME) +end, +This integration also works for emmylua_ls]], default = true, }, jsonc_filetype = { type = 'boolean', - description = 'Set filetype to jsonc for config files', + description = [[Set filetype to jsonc when opening a file specified by `config_file_paths`, +make sure you have the json tree-sitter parser installed for highlighting]], default = true, }, live_reload = { type = 'boolean', - description = 'Enable live reloading of settings when config files change; for servers that support it, this is done via the `workspace/didChangeConfiguration` notification, otherwise the server is restarted', + description = [[Enable live reloading of settings when config files change; for servers that support it, +this is done via the `workspace/didChangeConfiguration` notification, otherwise the +server is restarted]], default = false, }, } diff --git a/lua/codesettings/generated/codesettings-config-schema.lua b/lua/codesettings/generated/codesettings-config-schema.lua index d28b2b2..12c53b2 100644 --- a/lua/codesettings/generated/codesettings-config-schema.lua +++ b/lua/codesettings/generated/codesettings-config-schema.lua @@ -8,7 +8,7 @@ ---Options which can be passed on a per-load basis (i.e. can override global config) ---@class CodesettingsOverridableConfig ----List of config file paths to look for +---Look for these config files --- ---```lua ---default = { ".vscode/settings.json", "codesettings.json", "lspsettings.json" } @@ -20,13 +20,15 @@ ---default = {} ---``` ---@field loader_extensions (string|CodesettingsLoaderExtension)[]? ----How to merge list fields when combining settings from multiple sources +---How to merge lists; 'append' (default), 'prepend' or 'replace' --- ---```lua ---default = "append" ---``` ---@field merge_lists CodesettingsMergeListsBehavior? ----Function or string to determine the project root directory; defaults to `require('codesettings.util').get_root()` +---Provide your own root dir; can be a string or function returning a string. +---It should be/return the full absolute path to the root directory. +---If not set, defaults to `require('codesettings.util').get_root()` --- ---```lua ---default = nil @@ -35,21 +37,30 @@ ---Main configuration class ---@class CodesettingsConfig: CodesettingsOverridableConfig ----Set filetype to jsonc for config files +---Set filetype to jsonc when opening a file specified by `config_file_paths`, +---make sure you have the json tree-sitter parser installed for highlighting --- ---```lua ---default = true ---``` ---@field jsonc_filetype boolean ----Integrate with jsonls for LSP settings completion +---Integrate with jsonls to provide LSP completion for LSP settings based on schemas --- ---```lua ---default = true ---``` ---@field jsonls_integration boolean ----Enable live reloading of settings when config files change; for servers that support it, this is done via the `workspace/didChangeConfiguration` notification, otherwise the server is restarted +---Enable live reloading of settings when config files change; for servers that support it, +---this is done via the `workspace/didChangeConfiguration` notification, otherwise the +---server is restarted ---@field live_reload boolean ----Integrate with lua_ls for LSP settings completion; can be a function so that, for example, you can enable it only if editing your nvim config +---Set up library paths for `lua_ls` automatically to pick up the generated type +---annotations provided by codesettings.nvim; to enable for only your nvim config, +---you can also do something like: +---lua_ls_integration = function() +--- return vim.uv.cwd() == ('%%s/.config/nvim'):format(vim.env.HOME) +---end, +---This integration also works for emmylua_ls --- ---```lua ---default = true @@ -62,7 +73,7 @@ ---Each overridable config property gets a corresponding setter method. ---@class CodesettingsConfigBuilder ---@field private _config CodesettingsOverridableConfig ----List of config file paths to look for +---Look for these config files --- ---```lua ---default = { ".vscode/settings.json", "codesettings.json", "lspsettings.json" } @@ -74,13 +85,15 @@ ---default = {} ---``` ---@field loader_extensions fun(self: CodesettingsConfigBuilder, value: (string|CodesettingsLoaderExtension)[]): CodesettingsConfigBuilder ----How to merge list fields when combining settings from multiple sources +---How to merge lists; 'append' (default), 'prepend' or 'replace' --- ---```lua ---default = "append" ---``` ---@field merge_lists fun(self: CodesettingsConfigBuilder, value: CodesettingsMergeListsBehavior): CodesettingsConfigBuilder ----Function or string to determine the project root directory; defaults to `require('codesettings.util').get_root()` +---Provide your own root dir; can be a string or function returning a string. +---It should be/return the full absolute path to the root directory. +---If not set, defaults to `require('codesettings.util').get_root()` --- ---```lua ---default = nil