From 0c6a89af9a62ecc18f7cf89393b077af1063cd6c Mon Sep 17 00:00:00 2001 From: hrsh7th <629908+hrsh7th@users.noreply.github.com> Date: Sat, 18 Feb 2023 16:46:02 +0900 Subject: [PATCH] Improve perf --- lua/cmp/config/compare.lua | 2 +- lua/cmp/core.lua | 8 ++-- lua/cmp/entry.lua | 66 ++++++++++++++++---------------- lua/cmp/source.lua | 2 +- lua/cmp/utils/misc.lua | 15 +------- lua/cmp/view/ghost_text_view.lua | 4 ++ 6 files changed, 45 insertions(+), 52 deletions(-) diff --git a/lua/cmp/config/compare.lua b/lua/cmp/config/compare.lua index b240ca4..318e527 100644 --- a/lua/cmp/config/compare.lua +++ b/lua/cmp/config/compare.lua @@ -71,7 +71,7 @@ end -- sortText compare.sort_text = function(entry1, entry2) - if misc.safe(entry1.completion_item.sortText) and misc.safe(entry2.completion_item.sortText) then + if entry1.completion_item.sortText and entry2.completion_item.sortText then local diff = vim.stricmp(entry1.completion_item.sortText, entry2.completion_item.sortText) if diff < 0 then return true diff --git a/lua/cmp/core.lua b/lua/cmp/core.lua index efc85ba..2393cc9 100644 --- a/lua/cmp/core.lua +++ b/lua/cmp/core.lua @@ -389,10 +389,10 @@ core.confirm = function(self, e, option, callback) feedkeys.call('', 'n', function() -- Apply additionalTextEdits. local ctx = context.new() - if #(misc.safe(e:get_completion_item().additionalTextEdits) or {}) == 0 then + if #(e:get_completion_item().additionalTextEdits or {}) == 0 then e:resolve(function() local new = context.new() - local text_edits = misc.safe(e:get_completion_item().additionalTextEdits) or {} + local text_edits = e:get_completion_item().additionalTextEdits or {} if #text_edits == 0 then return end @@ -423,9 +423,9 @@ core.confirm = function(self, e, option, callback) feedkeys.call('', 'n', function() local ctx = context.new() local completion_item = misc.copy(e:get_completion_item()) - if not misc.safe(completion_item.textEdit) then + if not completion_item.textEdit then completion_item.textEdit = {} - completion_item.textEdit.newText = misc.safe(completion_item.insertText) or completion_item.word or completion_item.label + completion_item.textEdit.newText = completion_item.insertText or completion_item.word or completion_item.label end local behavior = option.behavior or config.get().confirmation.default_behavior if behavior == types.cmp.ConfirmBehavior.Replace then diff --git a/lua/cmp/entry.lua b/lua/cmp/entry.lua index 45b3618..c808c14 100644 --- a/lua/cmp/entry.lua +++ b/lua/cmp/entry.lua @@ -57,10 +57,10 @@ end entry.get_offset = function(self) return self.cache:ensure('get_offset', function() local offset = self.source_offset - if misc.safe(self:get_completion_item().textEdit) then + if self:get_completion_item().textEdit then local range = self:get_insert_range() if range then - offset = self.context.cache:ensure({ 'entry', 'get_offset', tostring(range.start.character) }, function() + offset = self.context.cache:ensure('entry:' .. 'get_offset:'.. tostring(range.start.character), function() for idx = range.start.character + 1, self.source_offset do if not char.is_white(string.byte(self.context.cursor_line, idx)) then return idx @@ -105,12 +105,12 @@ end entry.get_word = function(self) return self.cache:ensure('get_word', function() --NOTE: This is nvim-cmp specific implementation. - if misc.safe(self:get_completion_item().word) then + if self:get_completion_item().word then return self:get_completion_item().word end local word - if misc.safe(self:get_completion_item().textEdit) and not misc.empty(self:get_completion_item().textEdit.newText) then + if self:get_completion_item().textEdit and not misc.empty(self:get_completion_item().textEdit.newText) then word = str.trim(self:get_completion_item().textEdit.newText) if self:get_completion_item().insertTextFormat == types.lsp.InsertTextFormat.Snippet then word = vim.lsp.util.parse_snippet(word) @@ -135,10 +135,10 @@ end ---@return integer[] entry.get_overwrite = function(self) return self.cache:ensure('get_overwrite', function() - if misc.safe(self:get_completion_item().textEdit) then + if self:get_completion_item().textEdit then local range = self:get_insert_range() if range then - return self.context.cache:ensure({ 'entry', 'get_overwrite', tostring(range.start.character), tostring(range['end'].character) }, function() + return self.context.cache:ensure('entry:' .. 'get_overwrite:' .. tostring(range.start.character) .. ':' .. tostring(range['end'].character), function() local vim_start = range.start.character + 1 local vim_end = range['end'].character + 1 local before = self.context.cursor.col - vim_start @@ -156,7 +156,7 @@ end entry.get_filter_text = function(self) return self.cache:ensure('get_filter_text', function() local word - if misc.safe(self:get_completion_item().filterText) then + if self:get_completion_item().filterText then word = self:get_completion_item().filterText else word = str.trim(self:get_completion_item().label) @@ -170,12 +170,12 @@ end entry.get_insert_text = function(self) return self.cache:ensure('get_insert_text', function() local word - if misc.safe(self:get_completion_item().textEdit) then + if self:get_completion_item().textEdit then word = str.trim(self:get_completion_item().textEdit.newText) if self:get_completion_item().insertTextFormat == types.lsp.InsertTextFormat.Snippet then word = str.remove_suffix(str.remove_suffix(word, '$0'), '${0}') end - elseif misc.safe(self:get_completion_item().insertText) then + elseif self:get_completion_item().insertText then word = str.trim(self:get_completion_item().insertText) if self:get_completion_item().insertTextFormat == types.lsp.InsertTextFormat.Snippet then word = str.remove_suffix(str.remove_suffix(word, '$0'), '${0}') @@ -199,7 +199,7 @@ end ---@return { abbr: { text: string, bytes: integer, width: integer, hl_group: string }, kind: { text: string, bytes: integer, width: integer, hl_group: string }, menu: { text: string, bytes: integer, width: integer, hl_group: string } } entry.get_view = function(self, suggest_offset, entries_buf) local item = self:get_vim_item(suggest_offset) - return self.cache:ensure({ 'get_view', tostring(entries_buf) }, function() + return self.cache:ensure('get_view:' .. tostring(entries_buf), function() local view = {} -- The result of vim.fn.strdisplaywidth depends on which buffer it was -- called in because it reads the values of the option 'tabstop' when @@ -230,7 +230,7 @@ end ---@param suggest_offset integer ---@return vim.CompletedItem entry.get_vim_item = function(self, suggest_offset) - return self.cache:ensure({ 'get_vim_item', tostring(suggest_offset) }, function() + return self.cache:ensure('get_vim_item:' .. tostring(suggest_offset), function() local completion_item = self:get_completion_item() local word = self:get_word() local abbr = str.oneline(completion_item.label) @@ -238,7 +238,7 @@ entry.get_vim_item = function(self, suggest_offset) -- ~ indicator local is_expandable = false local expandable_indicator = config.get().formatting.expandable_indicator - if #(misc.safe(completion_item.additionalTextEdits) or {}) > 0 then + if #(completion_item.additionalTextEdits or {}) > 0 then is_expandable = true elseif completion_item.insertTextFormat == types.lsp.InsertTextFormat.Snippet then is_expandable = self:get_insert_text() ~= word @@ -256,12 +256,12 @@ entry.get_vim_item = function(self, suggest_offset) -- labelDetails. local menu = nil - if misc.safe(completion_item.labelDetails) then + if completion_item.labelDetails then menu = '' - if misc.safe(completion_item.labelDetails.detail) then + if completion_item.labelDetails.detail then menu = menu .. completion_item.labelDetails.detail end - if misc.safe(completion_item.labelDetails.description) then + if completion_item.labelDetails.description then menu = menu .. completion_item.labelDetails.description end end @@ -303,15 +303,15 @@ end ---Get commit characters ---@return string[] entry.get_commit_characters = function(self) - return misc.safe(self:get_completion_item().commitCharacters) or {} + return self:get_completion_item().commitCharacters or {} end ---Return insert range ---@return lsp.Range|nil entry.get_insert_range = function(self) local insert_range - if misc.safe(self:get_completion_item().textEdit) then - if misc.safe(self:get_completion_item().textEdit.insert) then + if self:get_completion_item().textEdit then + if self:get_completion_item().textEdit.insert then insert_range = self:get_completion_item().textEdit.insert else insert_range = self:get_completion_item().textEdit.range --[[@as lsp.Range]] @@ -334,8 +334,8 @@ end entry.get_replace_range = function(self) return self.cache:ensure('get_replace_range', function() local replace_range - if misc.safe(self:get_completion_item().textEdit) then - if misc.safe(self:get_completion_item().textEdit.replace) then + if self:get_completion_item().textEdit then + if self:get_completion_item().textEdit.replace then replace_range = self:get_completion_item().textEdit.replace else replace_range = self:get_completion_item().textEdit.range --[[@as lsp.Range]] @@ -361,14 +361,14 @@ end ---@param matching_config cmp.MatchingConfig ---@return { score: integer, matches: table[] } entry.match = function(self, input, matching_config) - return self.match_cache:ensure({ - input, - self.resolved_completion_item and '1' or '0', - matching_config.disallow_fuzzy_matching and '1' or '0', - matching_config.disallow_partial_fuzzy_matching and '1' or '0', - matching_config.disallow_partial_matching and '1' or '0', - matching_config.disallow_prefix_unmatching and '1' or '0', - }, function() + return self.match_cache:ensure( + input .. ':' .. + (self.resolved_completion_item and '1' or '0' .. ':') .. + (matching_config.disallow_fuzzy_matching and '1' or '0') .. ':' .. + (matching_config.disallow_partial_fuzzy_matching and '1' or '0') .. ':' .. + (matching_config.disallow_partial_matching and '1' or '0') .. ':' .. + (matching_config.disallow_prefix_unmatching and '1' or '0') + , function() local option = { disallow_fuzzy_matching = matching_config.disallow_fuzzy_matching, disallow_partial_fuzzy_matching = matching_config.disallow_partial_fuzzy_matching, @@ -386,7 +386,7 @@ entry.match = function(self, input, matching_config) -- Support the language server that doesn't respect VSCode's behaviors. if score == 0 then - if misc.safe(self:get_completion_item().textEdit) and not misc.empty(self:get_completion_item().textEdit.newText) then + if self:get_completion_item().textEdit and not misc.empty(self:get_completion_item().textEdit.newText) then local diff = self.source_offset - self:get_offset() if diff > 0 then local prefix = string.sub(self.context.cursor_line, self:get_offset(), self:get_offset() + diff) @@ -434,7 +434,7 @@ entry.get_documentation = function(self) local documents = {} -- detail - if misc.safe(item.detail) and item.detail ~= '' then + if item.detail and item.detail ~= '' then local ft = self.context.filetype local dot_index = string.find(ft, '%.') if dot_index ~= nil then @@ -471,7 +471,7 @@ end ---Get completion item kind ---@return lsp.CompletionItemKind entry.get_kind = function(self) - return misc.safe(self:get_completion_item().kind) or types.lsp.CompletionItemKind.Text + return self:get_completion_item().kind or types.lsp.CompletionItemKind.Text end ---Execute completion item's command. @@ -495,7 +495,7 @@ entry.resolve = function(self, callback) if not completion_item then return end - self.resolved_completion_item = misc.safe(completion_item) or self.completion_item + self.resolved_completion_item = completion_item or self.completion_item self.cache:clear() for _, c in ipairs(self.resolved_callbacks) do c() @@ -549,7 +549,7 @@ end ---Convert the oneline range encoding. entry.convert_range_encoding = function(self, range) local from_encoding = self.source:get_position_encoding_kind() - return self.context.cache:ensure('entry.convert_range_encoding.' .. range.start.character .. '.' .. range['end'].character .. '.' .. from_encoding, function() + return self.context.cache:ensure('entry.convert_range_encoding:' .. range.start.character .. ':' .. range['end'].character .. ':' .. from_encoding, function() return { start = types.lsp.Position.to_utf8(self.context.cursor_line, range.start, from_encoding), ['end'] = types.lsp.Position.to_utf8(self.context.cursor_line, range['end'], from_encoding), diff --git a/lua/cmp/source.lua b/lua/cmp/source.lua index 25c3cb3..ba16b77 100644 --- a/lua/cmp/source.lua +++ b/lua/cmp/source.lua @@ -342,7 +342,7 @@ source.complete = function(self, ctx, callback) self.status = source.SourceStatus.COMPLETED self.entries = {} for i, item in ipairs(response.items or response) do - if (misc.safe(item) or {}).label then + if (item or {}).label then local e = entry.new(ctx, self, item, response.itemDefaults) self.entries[i] = e self.offset = math.min(self.offset, e:get_offset()) diff --git a/lua/cmp/utils/misc.lua b/lua/cmp/utils/misc.lua index 6211406..9f8a40d 100644 --- a/lua/cmp/utils/misc.lua +++ b/lua/cmp/utils/misc.lua @@ -123,23 +123,12 @@ misc.id = setmetatable({ end, }) ----Check the value is nil or not. ----@generic T|nil|vim.NIL ----@param v T ----@return T|nil -misc.safe = function(v) - if v == nil or v == vim.NIL then - return nil - end - return v -end - ---Treat 1/0 as bool value ---@param v boolean|1|0 ---@param def boolean ---@return boolean misc.bool = function(v, def) - if misc.safe(v) == nil then + if v == nil then return def end return v == true or v == 1 @@ -153,7 +142,7 @@ misc.set = function(t, keys, v) local c = t for i = 1, #keys - 1 do local key = keys[i] - c[key] = misc.safe(c[key]) or {} + c[key] = c[key] or {} c = c[key] end c[keys[#keys]] = v diff --git a/lua/cmp/view/ghost_text_view.lua b/lua/cmp/view/ghost_text_view.lua index b798ebb..91a1fe4 100644 --- a/lua/cmp/view/ghost_text_view.lua +++ b/lua/cmp/view/ghost_text_view.lua @@ -78,6 +78,10 @@ ghost_text_view.show = function(self, e) if not api.is_insert_mode() then return end + local c = config.get().experimental.ghost_text + if not c then + return + end local changed = e ~= self.entry self.win = vim.api.nvim_get_current_win() self.entry = e