From 5c451ff0f2f8e6aa2c0b47e5439bf2e459ccf37a Mon Sep 17 00:00:00 2001 From: Grzegorz Milka Date: Wed, 15 Mar 2023 19:11:26 +0100 Subject: [PATCH] feat: add max_traversed_entries option At my work, we have a huge monorepo with a directory with over 70k entries. This plugin, being synchronous, was blocking Neovim for tens of seconds. This option should be universally useful to just time-box any search done by this plugin. I don't think it makes sense to leave this search unbounded as people expect interactivity from Neovim. Perhaps, some change of API will make it possible to make search more optimal (e.g., a batch fetch), but even than a limit to how many entries Neovim has to process is relevant. --- README.md | 10 ++++++++++ lua/cmp_path/init.lua | 7 ++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1cfd7a6..a5d33da 100644 --- a/README.md +++ b/README.md @@ -48,3 +48,13 @@ Specify if directory names in the completion menu should include a trailing slas _Default:_ returns the current working directory of the current buffer Specifies the base directory for relative paths. + +### max_traverse_entries (type: number) + +_Default:_ `nil` + +The maximum count of entries in a directory will this source traverse before returning candidates. + +Some directories may have a large number of entries. Users, who prefer to have a time-bounded feedback over completeness, may limit the number of entries this plugin fetches with this option. + +If this option is set to nil, there's no effective limit. diff --git a/lua/cmp_path/init.lua b/lua/cmp_path/init.lua index 4e63d27..86ed495 100644 --- a/lua/cmp_path/init.lua +++ b/lua/cmp_path/init.lua @@ -13,6 +13,7 @@ local constants = { ---@field public trailing_slash boolean ---@field public label_trailing_slash boolean ---@field public get_cwd fun(): string +---@field public max_traversed_entries number ---@type cmp_path.Option local defaults = { @@ -21,6 +22,7 @@ local defaults = { get_cwd = function(params) return vim.fn.expand(('#%d:p:h'):format(params.context.bufnr)) end, + max_traversed_entries = nil, } source.new = function() @@ -168,7 +170,8 @@ source._candidates = function(_, dirname, include_hidden, option, callback) table.insert(items, item) end - while true do + local entry_count = 0 + while option.max_traversed_entries == nil or entry_count < option.max_traversed_entries do local name, fs_type, e = vim.loop.fs_scandir_next(fs) if e then return callback(fs_type, nil) @@ -177,6 +180,7 @@ source._candidates = function(_, dirname, include_hidden, option, callback) break end create_item(name, fs_type) + entry_count = entry_count + 1 end callback(nil, items) @@ -198,6 +202,7 @@ source._validate_option = function(_, params) trailing_slash = { option.trailing_slash, 'boolean' }, label_trailing_slash = { option.label_trailing_slash, 'boolean' }, get_cwd = { option.get_cwd, 'function' }, + max_traversed_entries = { option.max_traversed_entries, { 'number', 'nil' }}, }) return option end