diff --git a/README.md b/README.md index a5ac3fc1..a3d9be13 100644 --- a/README.md +++ b/README.md @@ -243,87 +243,91 @@ You can find these in [`project/config/defaults.lua`](./lua/project/config/defau ```lua { - ---@param target_dir string - ---@param method string - before_attach = function(target_dir, method) end, - ---@param dir string - ---@param method string - on_attach = function(dir, method) end, - use_lsp = true, - manual_mode = false, - patterns = { ---@type string[] - '.git', - '.github', - '_darcs', - '.hg', - '.bzr', - '.svn', - 'Pipfile', - 'pyproject.toml', - '.pre-commit-config.yaml', - '.pre-commit-config.yml', - '.csproj', - '.sln', - '.nvim.lua', - }, - allow_patterns_for_lsp = false, - allow_different_owners = false, - enable_autochdir = false, - show_hidden = false, - ignore_lsp = {}, ---@type string[] - exclude_dirs = {}, ---@type string[] - silent_chdir = true, - scope_chdir = 'global', ---@type 'global'|'tab'|'win' - datapath = vim.fn.stdpath('data'), - historysize = 100, - log = { ---@type Project.Config.Logging - enabled = false, - max_size = 1.1, - logpath = vim.fn.stdpath('state'), - }, - fzf_lua = { enabled = false }, ---@type Project.Config.FzfLua - disable_on = { - ft = { -- `filetype` - '', - 'NvimTree', - 'TelescopePrompt', - 'TelescopeResults', - 'alpha', - 'checkhealth', - 'lazy', - 'log', - 'ministarter', - 'neo-tree', - 'notify', - 'nvim-pack', - 'packer', - 'qf', - }, - bt = { 'help', 'nofile', 'nowrite', 'terminal' }, + ---@param target_dir string + ---@param method string + before_attach = function(target_dir, method) end, + ---@param dir string + ---@param method string + on_attach = function(dir, method) end, + lsp = { ---@type Project.Config.LSP + enabled = true, ---@type boolean + ignore = {}, ---@type string[] + use_pattern_matching = false, ---@type boolean + -- WARNING: USE AT YOUR OWN DISCRETION!!!! + no_fallback = false, ---@type boolean + }, + manual_mode = false, + patterns = { ---@type string[] + '.git', + '.github', + '_darcs', + '.hg', + '.bzr', + '.svn', + 'Pipfile', + 'pyproject.toml', + '.pre-commit-config.yaml', + '.pre-commit-config.yml', + '.csproj', + '.sln', + '.nvim.lua', + }, + allow_different_owners = false, + enable_autochdir = false, + show_hidden = false, + exclude_dirs = {}, ---@type string[] + silent_chdir = true, + scope_chdir = 'global', ---@type 'global'|'tab'|'win' + datapath = vim.fn.stdpath('data'), + historysize = 100, + log = { ---@type Project.Config.Logging + enabled = false, + max_size = 1.1, + logpath = vim.fn.stdpath('state'), + }, + fzf_lua = { enabled = false }, ---@type Project.Config.FzfLua + disable_on = { + ft = { -- `filetype` + '', + 'NvimTree', + 'TelescopePrompt', + 'TelescopeResults', + 'alpha', + 'checkhealth', + 'lazy', + 'log', + 'ministarter', + 'neo-tree', + 'notify', + 'nvim-pack', + 'packer', + 'qf', }, - telescope = { ---@type Project.Config.Telescope - sort = 'newest', ---@type 'oldest'|'newest' - prefer_file_browser = false, - disable_file_picker = false, - mappings = { ---@type table<'n'|'i', table> - n = { - b = 'browse_project_files', - d = 'delete_project', - f = 'find_project_files', - r = 'recent_project_files', - s = 'search_in_project_files', - w = 'change_working_directory', - }, - i = { - [''] = 'browse_project_files', - [''] = 'delete_project', - [''] = 'find_project_files', - [''] = 'recent_project_files', - [''] = 'search_in_project_files', - [''] = 'change_working_directory', - }, - }, + bt = { 'help', 'nofile', 'nowrite', 'terminal' }, + }, + telescope = { ---@type Project.Config.Telescope + sort = 'newest', ---@type 'oldest'|'newest' + prefer_file_browser = false, + disable_file_picker = false, + mappings = { ---@type table<'n'|'i', table> + n = { + b = 'browse_project_files', + d = 'delete_project', + f = 'find_project_files', + r = 'recent_project_files', + s = 'search_in_project_files', + w = 'change_working_directory', + }, + i = { + [''] = 'browse_project_files', + [''] = 'delete_project', + [''] = 'find_project_files', + [''] = 'recent_project_files', + [''] = 'search_in_project_files', + [''] = 'change_working_directory', + }, }, + }, } ``` diff --git a/doc/project-nvim.txt b/doc/project-nvim.txt index efed7ed9..babcf0a7 100644 --- a/doc/project-nvim.txt +++ b/doc/project-nvim.txt @@ -28,9 +28,10 @@ Table of Contents *project-nvim.toc* 2.5 luarocks |project-nvim.install-luarocks| 3. project-nvim.setup |project-nvim.setup| 3.1. `Project.Config.Options` |Project.Config.Options| - 3.2. `Project.Config.Telescope` |Project.Config.Telescope| - 3.3. `Project.Config.FzfLua` |Project.Config.FzfLua| - 3.4. `Project.Config.Logging` |Project.Config.Logging| + 3.2. `Project.Config.LSP` |Project.Config.LSP| + 3.3. `Project.Config.Telescope` |Project.Config.Telescope| + 3.4. `Project.Config.FzfLua` |Project.Config.FzfLua| + 3.5. `Project.Config.Logging` |Project.Config.Logging| 4. Pattern Matching |project-nvim.pattern-matching| 5. Nvim Tree |project-nvim.nvim-tree| 6. Neo Tree |project-nvim.neo-tree| @@ -186,12 +187,6 @@ Table of Contents *project-nvim.toc* 3.1 `Project.Config.Options` *Project.Config.Options* *project-nvim.setup-options* - * {log} (|Project.Options.Logging|) - Options for logging. - - Default: |Project.Options.Logging| ~ - - * {disable_on} (`{ ft: string[], bt: string[] }`) CREDITS TO @Zeioth! ~ @@ -215,16 +210,6 @@ Table of Contents *project-nvim.toc* Default: `false` ~ - * {use_lsp} (boolean) - If `true` then LSP-based method detection - will take precedence over traditional - pattern matching. - See |project-nvim.pattern-matching| - for more info - - Default: `true` ~ - - * {patterns} (`string[]`) All the patterns used to detect the root dir. See |project-nvim.pattern-matching| for more @@ -242,23 +227,6 @@ Table of Contents *project-nvim.toc* keep this empty! - * {allow_patterns_for_lsp} (boolean) - Sets whether to use Pattern Matching rules - to the LSP client. - - If `false` the Pattern Matching will - only apply to normal pattern matching. - If `true` the {patterns} setting will - also filter your LSP's `root_dir`, - assuming there is one and {use_lsp} - is set to `true`. - - See |project-nvim.pattern-matching| for more - info on pattern matching - - Default: `false` ~ - - * {allow_different_owners} (boolean) Determines whether a project will be added if its project root is owned @@ -297,6 +265,14 @@ Table of Contents *project-nvim.toc* Default: `false` ~ + * {lsp} (|Project.Config.LSP|) + Table containing all the + LSP-adjacent options. + + See |Project.Config.LSP| for more + details + + * {telescope} (|Project.Config.Telescope|) Table of options used for the telescope picker. @@ -313,14 +289,11 @@ Table of Contents *project-nvim.toc* details - * {ignore_lsp} (`string[]`) - Table of LSP clients to ignore by name, - e.g. `{ 'efm', ... }` - - If you have `nvim-lspconfig` installed you can - look up |lspconfig-all| for a list of servers + * {log} (|Project.Options.Logging|) + Options for logging. - Default: `{}` ~ + See |Project.Config.Logging| for more + details * {exclude_dirs} (`string[]`) @@ -354,7 +327,7 @@ Table of Contents *project-nvim.toc* Default: `'global'` ~ - * {before_attach} (`fun(target_dir?: string, method?: string)`) + * {before_attach} (`fun(target_dir: string, method: string)`) Hook to run before attaching to a new project. It optionally recieves `target_dir` and the `method` used to change directory @@ -362,7 +335,7 @@ Table of Contents *project-nvim.toc* Default: empty function ~ - * {on_attach} (`fun(dir?: string, method?: string)`) + * {on_attach} (`fun(dir: string, method: string)`) Hook to run after attaching to a new project. It optionally recieves `dir` and the `method` used to change directory. @@ -384,7 +357,59 @@ Table of Contents *project-nvim.toc* ------------------------------------------------------------------------------ -3.2 `Project.Config.Telescope` *Project.Config.Telescope* +3.2 `Project.Config.LSP` *Project.Config.LSP* + *project-nvim.lsp-config* + + + * {enabled} (boolean) + If `true` then LSP-based method detection + will take precedence over traditional + pattern matching. + See |project-nvim.pattern-matching| + for more info + + Default: `true` ~ + + + * {ignore} (`string[]`) + Table of LSP clients to ignore by name, + e.g. `{ 'efm', ... }` + + If you have `nvim-lspconfig` installed you can + look up |lspconfig-all| for a list of servers + + Default: `{}` ~ + + + * {no_fallback} (boolean) + If `true` then LSP-based method detection + will not be compared with + pattern-matching-based detection. + + WARNING: USE AT YOUR OWN DISCRETION! ~ + + Default: `false` ~ + + + * {use_pattern_matching} (boolean) + Sets whether to use Pattern Matching rules + to the LSP client. + + If `false` the Pattern Matching will + only apply to normal pattern matching. + If `true` the {patterns} setting will + also filter your LSP's `root_dir`, + assuming there is one and {lsp.enabled} + is set to `true`. + + See |project-nvim.pattern-matching| for more + info on pattern matching + + Default: `false` ~ + + +------------------------------------------------------------------------------ +3.3 `Project.Config.Telescope` *Project.Config.Telescope* *project-nvim.telescope-config* @@ -425,7 +450,7 @@ Table of Contents *project-nvim.toc* ------------------------------------------------------------------------------ -3.3 `Project.Config.FzfLua` *Project.Config.FzfLua* +3.4 `Project.Config.FzfLua` *Project.Config.FzfLua* *project-nvim.fzf-lua-config* * {enabled} (boolean) @@ -438,7 +463,7 @@ Table of Contents *project-nvim.toc* ------------------------------------------------------------------------------ -3.4 `Project.Config.Logging` *Project.Config.Logging* +3.5 `Project.Config.Logging` *Project.Config.Logging* *project-nvim.logging-config* * {enabled} (boolean) diff --git a/lua/project/api.lua b/lua/project/api.lua index ea893d93..11812e97 100644 --- a/lua/project/api.lua +++ b/lua/project/api.lua @@ -69,7 +69,7 @@ function Api.find_lsp_root(bufnr) return end - local ignore_lsp = Config.options.ignore_lsp + local ignore_lsp = Config.options.lsp.ignore local ft = vim.api.nvim_get_option_value('filetype', { buf = bufnr }) for _, client in ipairs(clients) do ---@type string[] @@ -83,7 +83,7 @@ function Api.find_lsp_root(bufnr) ) if valid then local dir, name = client.config.root_dir, client.name - if Config.options.allow_patterns_for_lsp then + if Config.options.lsp.use_pattern_matching then if Path.root_included(dir) == nil then return end @@ -295,7 +295,7 @@ function Api.get_project_root(bufnr) return false end, } - local roots = {} ---@type { [1]: string, [2]: string, [3]: 'lsp'|'pattern' }[] + local roots = {} ---@type { root: string, method_msg: string, method: 'lsp'|'pattern' }[] local root, lsp_method = nil, nil local ops = vim.tbl_keys(SWITCH) ---@type string[] local success = false @@ -303,7 +303,9 @@ function Api.get_project_root(bufnr) if in_list(ops, method) then success, root, lsp_method = SWITCH[method]() if success then - table.insert(roots, { root, lsp_method, method }) + ---@cast root string + ---@cast lsp_method string + table.insert(roots, { root = root, method_msg = lsp_method, method = method }) end end end @@ -311,16 +313,16 @@ function Api.get_project_root(bufnr) if vim.tbl_isempty(roots) then return end - if #roots == 1 then - return roots[1][1], roots[1][2] + if #roots == 1 or Config.options.lsp.no_fallback then + return roots[1].root, roots[1].method_msg end - if roots[1][1] == roots[2][1] then - return roots[1][1], roots[1][2] + if roots[1].root == roots[2].root then + return roots[1].root, roots[1].method_msg end for _, tbl in ipairs(roots) do - if tbl[3] == 'pattern' then - return tbl[1], tbl[2] + if tbl.method == 'pattern' then + return tbl.root, tbl.method_msg end end end diff --git a/lua/project/config.lua b/lua/project/config.lua index 3230ad5e..ca4c327f 100644 --- a/lua/project/config.lua +++ b/lua/project/config.lua @@ -70,6 +70,7 @@ function Config.get_config() 'verify_datapath', 'verify_histsize', 'verify_logging', + 'verify_lsp', 'verify_methods', 'verify_scope_chdir', } diff --git a/lua/project/config/defaults.lua b/lua/project/config/defaults.lua index c159e5d9..96b9bb91 100644 --- a/lua/project/config/defaults.lua +++ b/lua/project/config/defaults.lua @@ -7,79 +7,6 @@ ---|'recent_project_files' ---|'search_in_project_files' ----@class Project.Telescope.Mappings ----@field i? table ----@field n? table - ----@class Project.Config.DisableOn ----@field ft? string[] ----@field bt? string[] - ----Table of options used for the telescope picker. ---- --- ----@class Project.Config.Telescope ----Determines whether the newest projects come first in the ----telescope picker (`'newest'`), or the oldest (`'oldest'`). ---- --- ----Default: `'newest'` ---- --- ----@field sort? 'newest'|'oldest' ----If you have `telescope-file-browser.nvim` installed, you can enable this ----so that the Telescope picker uses it instead of the `find_files` builtin. ---- ----If `true`, use `telescope-file-browser.nvim` instead of builtins. ----In case it is not available, it'll fall back to `find_files`. ---- --- ----Default: `false` ---- --- ----@field prefer_file_browser? boolean ----Set this to `true` if you don't want the file picker to appear ----after you've selected a project. ---- ----CREDITS: [UNKNOWN](https://github.com/ahmedkhalf/project.nvim/issues/157#issuecomment-2226419783) ---- --- ----Default: `false` ---- --- ----@field disable_file_picker? boolean ----Table of mappings for the Telescope picker. ---- ----Only supports Normal and Insert modes. ---- --- ----Default: check the README ---- --- ----@field mappings? Project.Telescope.Mappings - ----Table of options used for `fzf-lua` integration ---- --- ----@class Project.Config.FzfLua ----Determines whether the `fzf-lua` integration is enabled. ---- ----If `fzf-lua` is not installed, this won't make a difference. ---- --- ----Default: `false` ---- --- ----@field enabled? boolean - ----Options for logging utility. ---- --- ----@class Project.Config.Logging ----If `true`, it enables logging in the same directory in which your ----history file is stored. ---- --- ----Default: `false` ---- --- ----@field enabled? boolean ----The maximum logfile size (in megabytes). ---- --- ----Default: `1.1` ---- --- ----@field max_size? number ----Path in which the log file will be saved. ---- --- ----Default: `vim.fn.stdpath('state')` ---- --- ----@field logpath? string - local MODSTR = 'project.config.defaults' local WARN = vim.log.levels.WARN local in_list = vim.tbl_contains @@ -88,16 +15,49 @@ local Util = require('project.utils.util') ---The options available for in `require('project').setup()`. --- --- ---@class Project.Config.Options ----@field detection_methods? ('lsp'|'pattern')[] local DEFAULTS = { - ---If `true` then LSP-based method detection - ---will take precedence over traditional pattern matching. - --- - ---See |project-nvim.pattern-matching| for more info. - --- --- - ---Default: `true` - --- --- - use_lsp = true, ---@type boolean + ---Table containing all the LSP-adjacent options. + --- --- + ---@class Project.Config.LSP + lsp = { + ---If `true` then LSP-based method detection + ---will take precedence over traditional pattern matching. + --- + ---See |project-nvim.pattern-matching| for more info. + --- --- + ---Default: `true` + --- --- + enabled = true, ---@type boolean + ---Table of lsp clients to ignore by name, + ---e.g. `{ 'efm', ... }`. + --- + ---If you have `nvim-lspconfig` installed **see** `:h lspconfig-all` + ---for a list of servers. + --- --- + ---Default: `{}` + --- --- + ignore = {}, ---@type string[] + ---If `true` then LSP-based method detection + ---will not be compared with pattern-matching-based detection. + --- + ---**WARNING: USE AT YOUR OWN DISCRETION!** + --- --- + ---Default: `false` + --- --- + no_fallback = false, ---@type boolean + ---Sets whether to use Pattern Matching rules to the LSP client. + --- + ---If `false` the Pattern Matching will only apply + ---to normal pattern matching. + --- + ---If `true` the `patterns` setting will also filter + ---your LSP's `root_dir`, assuming there is one + ---and `lsp.enabled` is set to `true`. + --- --- + ---Default: `false` + --- --- + use_pattern_matching = false, ---@type boolean + }, ---If `true` your root directory won't be changed automatically, ---so you have the option to manually do so ---using the `:ProjectRoot` command. @@ -151,18 +111,6 @@ local DEFAULTS = { ---@param dir string ---@param method string on_attach = function(dir, method) end, ---@diagnostic disable-line:unused-local - ---Sets whether to use Pattern Matching rules to the LSP client. - --- - ---If `false` the Pattern Matching will only apply - ---to normal pattern matching. - --- - ---If `true` the `patterns` setting will also filter - ---your LSP's `root_dir`, assuming there is one - ---and `use_lsp` is set to `true`. - --- --- - ---Default: `false` - --- --- - allow_patterns_for_lsp = false, ---@type boolean ---Determines whether a project will be added ---if its project root is owned by a different user. --- @@ -184,15 +132,6 @@ local DEFAULTS = { ---Default: `false` --- --- show_hidden = false, ---@type boolean - ---Table of lsp clients to ignore by name, - ---e.g. `{ 'efm', ... }`. - --- - ---If you have `nvim-lspconfig` installed **see** `:h lspconfig-all` - ---for a list of servers. - --- --- - ---Default: `{}` - --- --- - ignore_lsp = {}, ---@type string[] ---Don't calculate root dir on specific directories, ---e.g. `{ '~/.cargo/*', ... }`. --- @@ -231,7 +170,10 @@ local DEFAULTS = { --- --- ---The default value for this one can be found in the project's `README.md`. --- --- - disable_on = { ---@type Project.Config.DisableOn + ---@class Project.Config.DisableOn + ---@field ft? string[] + ---@field bt? string[] + disable_on = { ft = { '', 'NvimTree', @@ -267,12 +209,79 @@ local DEFAULTS = { ---Default: `100` --- --- historysize = 100, ---@type integer - fzf_lua = { enabled = false }, ---@type Project.Config.FzfLua - log = { enabled = false, max_size = 1.1, logpath = vim.fn.stdpath('state') }, ---@type Project.Config.Logging - telescope = { ---@type Project.Config.Telescope - sort = 'newest', - prefer_file_browser = false, - disable_file_picker = false, + ---Table of options used for `fzf-lua` integration + --- --- + ---@class Project.Config.FzfLua + fzf_lua = { + ---Determines whether the `fzf-lua` integration is enabled. + --- + ---If `fzf-lua` is not installed, this won't make a difference. + --- --- + ---Default: `false` + --- --- + enabled = false, ---@type boolean + }, + ---Options for logging utility. + --- --- + ---@class Project.Config.Logging + log = { + ---If `true`, it enables logging in the same directory in which your + ---history file is stored. + --- --- + ---Default: `false` + --- --- + enabled = false, ---@type boolean + ---The maximum logfile size (in megabytes). + --- --- + ---Default: `1.1` + --- --- + max_size = 1.1, ---@type number + ---Path in which the log file will be saved. + --- --- + ---Default: `vim.fn.stdpath('state')` + --- --- + logpath = vim.fn.stdpath('state'), ---@type string + }, + ---Table of options used for the telescope picker. + --- --- + ---@class Project.Config.Telescope + telescope = { + ---Determines whether the newest projects come first in the + ---telescope picker (`'newest'`), or the oldest (`'oldest'`). + --- --- + ---Default: `'newest'` + --- --- + sort = 'newest', ---@type 'newest'|'oldest' + ---If you have `telescope-file-browser.nvim` installed, you can enable this + ---so that the Telescope picker uses it instead of the `find_files` builtin. + --- + ---If `true`, use `telescope-file-browser.nvim` instead of builtins. + ---In case it is not available, it'll fall back to `find_files`. + --- --- + ---Default: `false` + --- --- + prefer_file_browser = false, ---@type boolean + ---Set this to `true` if you don't want the file picker to appear + ---after you've selected a project. + --- + ---CREDITS: [UNKNOWN](https://github.com/ahmedkhalf/project.nvim/issues/157#issuecomment-2226419783) + --- --- + ---Default: `false` + --- --- + disable_file_picker = false, ---@type boolean + ---Table of mappings for the Telescope picker. + --- + ---Only supports Normal and Insert modes. + --- --- + ---Default: check the README + --- --- + ---@class Project.Telescope.Mappings + ---Normal mode mappings. + --- --- + ---@field i? table + ---Insert mode mappings. + --- --- + ---@field n? table mappings = { n = { b = 'browse_project_files', @@ -341,8 +350,9 @@ end ---@return { [1]: 'pattern' }|{ [1]: 'lsp', [2]: 'pattern' } methods function DEFAULTS:gen_methods() + self:verify_lsp() local methods = { 'pattern' } ---@type { [1]: 'pattern' }|{ [1]: 'lsp', [2]: 'pattern' } - if self.use_lsp then + if self.lsp.enabled then table.insert(methods, 1, 'lsp') end @@ -387,10 +397,33 @@ function DEFAULTS:expand_excluded() end end +function DEFAULTS:verify_lsp() + self.lsp = self.lsp and vim.tbl_deep_extend('keep', self.lsp, DEFAULTS.lsp) or DEFAULTS.lsp + if self.use_lsp ~= nil then + vim.notify('`use_lsp` is deprecated! Use `lsp.enabled` instead.', WARN) + self.lsp.enabled = self.use_lsp + self.use_lsp = nil + end + if self.allow_patterns_for_lsp ~= nil then + vim.notify( + '`allow_patterns_for_lsp` is deprecated! Use `lsp.use_pattern_matching` instead.', + WARN + ) + self.lsp.use_pattern_matching = self.allow_patterns_for_lsp + self.allow_patterns_for_lsp = nil + end + if self.ignore_lsp and type(self.ignore_lsp) == 'table' then + vim.notify('`ignore_lsp` is deprecated! Use `lsp.ignore` instead.', WARN) + self.lsp.ignore = vim.deepcopy(self.ignore_lsp) + self.ignore_lsp = nil + end +end + ---Verify config integrity. --- --- function DEFAULTS:verify() self:verify_datapath() + self:verify_lsp() self:verify_histsize() self:verify_scope_chdir() self:verify_logging() @@ -400,7 +433,7 @@ function DEFAULTS:verify() end vim.schedule(function() vim.notify( - '(project.nvim): `detection_methods` has been deprecated!\nUse `use_lsp` instead.', + '(project.nvim): `detection_methods` has been deprecated!\nUse `lsp.enabled` instead.', WARN ) end)