diff --git a/lua/cmp/config.lua b/lua/cmp/config.lua index 2a95cf4..84ddbd5 100644 --- a/lua/cmp/config.lua +++ b/lua/cmp/config.lua @@ -157,7 +157,6 @@ end ---@param c cmp.ConfigSchema ---@return cmp.ConfigSchema config.normalize = function(c) - -- make sure c is not 'nil' local c = c == nil and {} or c diff --git a/lua/cmp/config/compare.lua b/lua/cmp/config/compare.lua index d5657cb..d4d3f3f 100644 --- a/lua/cmp/config/compare.lua +++ b/lua/cmp/config/compare.lua @@ -100,4 +100,68 @@ compare.order = function(entry1, entry2) end end +-- locals +compare.locals = setmetatable({ + locals_map = {}, + update = function(self) + local config = require('cmp').get_config() + if not vim.tbl_contains(config.sorting.comparators, compare.locals) then + return + end + + local ok, locals = pcall(require, 'nvim-treesitter.locals') + if ok then + local win, buf = vim.api.nvim_get_current_win(), vim.api.nvim_get_current_buf() + local cursor_row = vim.api.nvim_win_get_cursor(win)[1] - 1 + local ts_utils = require('nvim-treesitter.ts_utils') + + -- Cursor scope. + local cursor_scope = nil + for _, scope in ipairs(locals.get_scopes(buf)) do + if not cursor_scope then + cursor_scope = scope + else + if scope:start() <= cursor_row and cursor_row <= scope:end_() then + if math.abs(scope:end_() - scope:start()) < math.abs(cursor_scope:end_() - cursor_scope:start()) then + cursor_scope = scope + end + end + end + end + + -- Definitions. + local definitions = locals.get_definitions_lookup_table(buf) + + -- Narrow definitions. + local depth = 0 + for scope in locals.iter_scope_tree(cursor_scope, buf) do + -- Check scope's direct child. + for _, definition in pairs(definitions) do + if scope:id() == locals.containing_scope(definition.node, buf):id() then + local text = ts_utils.get_node_text(definition.node)[1] + if not self.locals_map[text] then + self.locals_map[text] = depth + end + end + end + depth = depth + 1 + end + end + end, +}, { + __call = function(self, entry1, entry2) + local local1 = self.locals_map[entry1:get_completion_item().label] + local local2 = self.locals_map[entry2:get_completion_item().label] + if local1 ~= local2 then + if local1 == nil then + return false + end + if local2 == nil then + return true + end + return local1 < local2 + end + end, +}) + return compare diff --git a/lua/cmp/config/default.lua b/lua/cmp/config/default.lua index ff0311b..f17048a 100644 --- a/lua/cmp/config/default.lua +++ b/lua/cmp/config/default.lua @@ -101,6 +101,7 @@ return function() compare.exact, compare.score, compare.recently_used, + -- compare.locals, compare.kind, compare.sort_text, compare.length, diff --git a/lua/cmp/entry.lua b/lua/cmp/entry.lua index 5d82d19..83c53a2 100644 --- a/lua/cmp/entry.lua +++ b/lua/cmp/entry.lua @@ -412,9 +412,9 @@ entry.get_documentation = function(self) -- detail if misc.safe(item.detail) and item.detail ~= '' then local ft = self.context.filetype - local dot_index = string.find(ft, "%.") + local dot_index = string.find(ft, '%.') if dot_index ~= nil then - ft = string.sub(ft, 0, dot_index-1) + ft = string.sub(ft, 0, dot_index - 1) end table.insert(documents, { kind = types.lsp.MarkupKind.Markdown, diff --git a/lua/cmp/init.lua b/lua/cmp/init.lua index 6a4c617..282d5fd 100644 --- a/lua/cmp/init.lua +++ b/lua/cmp/init.lua @@ -338,10 +338,15 @@ autocmd.subscribe('CursorMoved', function() end end) +autocmd.subscribe('InsertEnter', function() + cmp.config.compare.locals:update() +end) + cmp.event:on('complete_done', function(evt) if evt.entry then cmp.config.compare.recently_used:add_entry(evt.entry) end + cmp.config.compare.locals:update() end) cmp.event:on('confirm_done', function(evt) diff --git a/lua/cmp/utils/misc.lua b/lua/cmp/utils/misc.lua index b68bf2e..8dd3529 100644 --- a/lua/cmp/utils/misc.lua +++ b/lua/cmp/utils/misc.lua @@ -206,7 +206,7 @@ end misc.redraw = setmetatable({ doing = false, force = false, - termcode = vim.api.nvim_replace_termcodes('', true, true, true) + termcode = vim.api.nvim_replace_termcodes('', true, true, true), }, { __call = function(self, force) if vim.tbl_contains({ '/', '?' }, vim.fn.getcmdtype()) then