From 67d43ddd598b2d2a07812004ce99e3dc0c29c3ee Mon Sep 17 00:00:00 2001 From: hrsh7th Date: Mon, 11 Oct 2021 00:26:21 +0900 Subject: [PATCH] Fix incorrect highlight --- lua/cmp/entry.lua | 17 +++++++++++++++++ lua/cmp/source.lua | 45 ++++++++++++++++++--------------------------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/lua/cmp/entry.lua b/lua/cmp/entry.lua index 70911b3..133bfca 100644 --- a/lua/cmp/entry.lua +++ b/lua/cmp/entry.lua @@ -4,10 +4,12 @@ local misc = require('cmp.utils.misc') local str = require('cmp.utils.str') local config = require('cmp.config') local types = require('cmp.types') +local matcher = require('cmp.matcher') ---@class cmp.Entry ---@field public id number ---@field public cache cmp.Cache +---@field public match_cache cmp.Cache ---@field public score number ---@field public exact boolean ---@field public matches table @@ -32,6 +34,7 @@ entry.new = function(ctx, source, completion_item) local self = setmetatable({}, { __index = entry }) self.id = misc.id('entry') self.cache = cache.new() + self.match_cache = cache.new() self.score = 0 self.exact = false self.matches = {} @@ -337,6 +340,20 @@ entry.get_replace_range = function(self) end) end +---Match line. +---@param input string +---@return { score: number, matches: table[] } +entry.match = function(self, input) + return self.match_cache:ensure(input, function() + local score, matches + score, matches = matcher.match(input, self:get_filter_text(), { self:get_word() }) + if self:get_filter_text() ~= self:get_completion_item().label then + _, matches = matcher.match(input, self:get_completion_item().label) + end + return { score = score, matches = matches } + end) +end + ---Get resolved completion item if possible. ---@return lsp.CompletionItem entry.get_completion_item = function(self) diff --git a/lua/cmp/source.lua b/lua/cmp/source.lua index 274b255..80510a4 100644 --- a/lua/cmp/source.lua +++ b/lua/cmp/source.lua @@ -82,7 +82,7 @@ source.get_entries = function(self, ctx) return {} end - local prev_entries = (function() + local target_entries = (function() local key = { 'get_entries', self.revision } for i = ctx.cursor.col, self.offset, -1 do key[3] = string.sub(ctx.cursor_before_line, 1, i) @@ -91,36 +91,27 @@ source.get_entries = function(self, ctx) return prev_entries end end - return nil + return self.entries end)() - local entries = self.cache:ensure({ 'get_entries', self.revision, ctx.cursor_before_line }, function() - debug.log(self:get_debug_name(), 'filter', #(prev_entries or self.entries)) - - local inputs = {} - local entries = {} - for _, e in ipairs(prev_entries or self.entries) do - local o = e:get_offset() - if not inputs[o] then - inputs[o] = string.sub(ctx.cursor_before_line, o) - end - local score, matches = matcher.match(inputs[o], e:get_filter_text(), { e:get_word() }) - e.score = score - e.exact = false - if e.score >= 1 then - if e:get_filter_text() ~= e.completion_item.label then - local _, matches_for_highlights = matcher.match(inputs[o], e.completion_item.label, {}) - e.matches = matches_for_highlights - else - e.matches = matches - end - e.exact = e:get_filter_text() == inputs[o] or e:get_word() == inputs[o] - table.insert(entries, e) - end + local inputs = {} + local entries = {} + for _, e in ipairs(target_entries) do + local o = e:get_offset() + if not inputs[o] then + inputs[o] = string.sub(ctx.cursor_before_line, o) end - return entries - end) + local match = e:match(inputs[o]) + e.score = match.score + e.exact = false + if e.score >= 1 then + e.matches = match.matches + e.exact = e:get_filter_text() == inputs[o] or e:get_word() == inputs[o] + table.insert(entries, e) + end + end + self.cache:set({ 'get_entries', self.revision, ctx.cursor_before_line }, entries) local max_item_count = self:get_config().max_item_count or 200 local limited_entries = {}