From 26a9184c888d6c6a5d9782f5b15e02ddd3e8a663 Mon Sep 17 00:00:00 2001 From: hrsh7th Date: Fri, 11 Feb 2022 15:20:24 +0900 Subject: [PATCH] Add filetype config Use view.entries == 'native' instead of experimental.native_menu --- README.md | 9 ++++ doc/cmp.txt | 47 ++++++++++------- lua/cmp/config.lua | 83 ++++++++++++++++++++++++++---- lua/cmp/config/default.lua | 100 ++++++++++++++++++------------------- lua/cmp/init.lua | 5 +- lua/cmp/types/cmp.lua | 19 ++++--- plugin/cmp.lua | 2 +- 7 files changed, 179 insertions(+), 86 deletions(-) diff --git a/README.md b/README.md index 501f2df..410140b 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,15 @@ lua < call plug#begin(s:plug_dir) @@ -148,6 +148,9 @@ NOTE: You can call these functions in mapping via `lua require('cmp').compl *cmp.setup* (config: cmp.ConfigSchema) Setup global configuration. See configuration option. +*cmp.setup.filetype* (filetype: string, config: cmp.ConfigSchema) + Setup filetype configuration to the specific filetype. + *cmp.setup.buffer* (config: cmp.ConfigSchema) Setup buffer configuration to the current buffer. @@ -380,18 +383,25 @@ completion.autocomplete~ nvim-cmp does not completion automatically but you can still use the manual completion though. - *cmp-config.formatting.format* -formatting.format~ - `fun(entry: cmp.Entry, vim_item: vim.CompletedItem): vim.CompletedItem` - The function to customize the completion menu appearance. See |complete-items|. - NOTE: The `vim.CompletedItem` can have special properties `abbr_hl_group`, - `kind_hl_group` and `menu_hl_group`. + *cmp-config.completion.completeopt* +completion.completeopt~ + `string` + The vim's completeopt like setting. See 'completeopt'. + Besically, You don't need to modify this. *cmp-config.formatting.fields* formatting.fields~ `cmp.ItemField[]` The array of completion menu field to specify the order of them. + *cmp-config.formatting.format* +formatting.format~ + `fun(entry: cmp.Entry, vim_item: vim.CompletedItem): vim.CompletedItem` + The function to customize the completion menu appearance. See |complete-items|. + This value also can be used to modify `dup` property. + NOTE: The `vim.CompletedItem` can have special properties `abbr_hl_group`, + `kind_hl_group` and `menu_hl_group`. + *cmp-config.sorting.priority_weight* sorting.priority_weight~ `number` @@ -473,16 +483,17 @@ sources[n].group_index~ }) } < + *cmp-config.view* +view~ + `{ entries: cmp.EntriesConfig|string }` + Specify the view class to customize appearance. + Currently, the possible configurations are: + *cmp-config.experimental.ghost_text* experimental.ghost_text~ `boolean | { hl_group = string }` The boolean value to enable or disable the ghost_text feature. - *cmp-config.experimental.native_menu* -experimental.native_menu~ - `boolean` - The boolean value to enable or disable the native completion menu. - ============================================================================== @@ -592,12 +603,12 @@ How to setup on the specific buffer?~ You can setup buffer specific configuration like this. > - autocmd FileType markdown lua require('cmp').setup.buffer { - \ sources = { - \ { name = 'path' }, - \ { name = 'buffer' }, - \ } - \ } + cmp.setup.filetype('markdown', { + sources = { + { name = 'path' }, + { name = 'buffer' }, + } + }) < How to customize menu appearance?~ diff --git a/lua/cmp/config.lua b/lua/cmp/config.lua index 7984b57..7fc53e8 100644 --- a/lua/cmp/config.lua +++ b/lua/cmp/config.lua @@ -17,6 +17,9 @@ config.global = require('cmp.config.default')() ---@type table config.buffers = {} +---@type table +config.filetypes = {} + ---@type table config.cmdline = {} @@ -40,6 +43,15 @@ config.set_buffer = function(c, bufnr) config.buffers[bufnr].revision = revision + 1 end +---Set configuration for filetype +---@param c cmp.ConfigSchema +---@param filetype string +config.set_filetype = function(c, filetype) + local revision = (config.filetypes[filetype] or {}).revision or 1 + config.filetypes[filetype] = c or {} + config.filetypes[filetype].revision = revision + 1 +end + ---Set configuration for cmdline ---@param c cmp.ConfigSchema ---@param cmdtype string @@ -59,23 +71,48 @@ end ---@return cmp.ConfigSchema config.get = function() - local global = config.global + local global_config = config.global if config.onetime.sources then - local onetime = config.onetime - return config.cache:ensure({ 'get_onetime', global.revision or 0, onetime.revision or 0 }, function() - return misc.merge(config.normalize(onetime), config.normalize(global)) + local onetime_config = config.onetime + return config.cache:ensure({ + 'get', + 'onetime', + global_config.revision or 0, + onetime_config.revision or 0 + }, function() + return misc.merge(config.normalize(onetime_config), config.normalize(global_config)) end) elseif api.is_cmdline_mode() then local cmdtype = vim.fn.getcmdtype() - local cmdline = config.cmdline[cmdtype] or { revision = 1, sources = {} } - return config.cache:ensure({ 'get_cmdline', cmdtype, global.revision or 0, cmdline.revision or 0 }, function() - return misc.merge(config.normalize(cmdline), config.normalize(global)) + local cmdline_config = config.cmdline[cmdtype] or { revision = 1, sources = {} } + return config.cache:ensure({ + 'get', + 'cmdline', + global_config.revision or 0, + cmdtype, + cmdline_config.revision or 0 + }, function() + return misc.merge(config.normalize(cmdline_config), config.normalize(global_config)) end) else local bufnr = vim.api.nvim_get_current_buf() - local buffer = config.buffers[bufnr] or { revision = 1 } - return config.cache:ensure({ 'get_buffer', bufnr, global.revision or 0, buffer.revision or 0 }, function() - return misc.merge(config.normalize(buffer), config.normalize(global)) + local filetype = vim.api.nvim_buf_get_option(bufnr, 'filetype') + local buffer_config = config.buffers[bufnr] or { revision = 1 } + local filetype_config = config.filetypes[filetype] or { revision = 1 } + return config.cache:ensure({ + 'get', + 'default', + global_config.revision or 0, + filetype, + filetype_config.revision or 0, + bufnr, + buffer_config.revision or 0, + }, function() + local c = {} + c = misc.merge(c, config.normalize(buffer_config)) + c = misc.merge(c, config.normalize(filetype_config)) + c = misc.merge(c, config.normalize(global_config)) + return c end) end end @@ -102,6 +139,18 @@ config.get_source_config = function(name) return nil end +---Return the current menu is native or not. +config.is_native_menu = function() + local c = config.get() + if c.experimental and c.experimental.native_menu then + return true + end + if c.view and c.view.entries then + return c.view.entries == 'native' or c.view.entries.name == 'native' + end + return false +end + ---Normalize mapping key ---@param c cmp.ConfigSchema ---@return cmp.ConfigSchema @@ -114,6 +163,20 @@ config.normalize = function(c) c.mapping = normalized end + if c.experimental and c.experimental.native_menu then + vim.api.nvim_echo({ + { '[nvim-cmp] ', 'Normal' }, + { 'experimental.native_menu', 'WarningMsg' }, + { ' is deprecated.\n', 'Normal' }, + { '[nvim-cmp] Please use ', 'Normal' }, + { 'view.entries = "native"', 'WarningMsg' }, + { ' instead.', 'Normal' }, + }, true, {}) + + c.view = c.view or {} + c.view.entries = c.view.entries or 'native' + end + if c.sources then for _, s in ipairs(c.sources) do if s.opts and not s.option then diff --git a/lua/cmp/config/default.lua b/lua/cmp/config/default.lua index eda83a7..63dae2b 100644 --- a/lua/cmp/config/default.lua +++ b/lua/cmp/config/default.lua @@ -10,53 +10,9 @@ return function() enabled = function() return vim.api.nvim_buf_get_option(0, 'buftype') ~= 'prompt' end, - completion = { - autocomplete = { - types.cmp.TriggerEvent.TextChanged, - }, - completeopt = 'menu,menuone,noselect', - keyword_pattern = [[\%(-\?\d\+\%(\.\d\+\)\?\|\h\w*\%(-\w*\)*\)]], - keyword_length = 1, - }, - - snippet = { - expand = function() - error('snippet engine is not configured.') - end, - }, preselect = types.cmp.PreselectMode.Item, - documentation = { - border = { '', '', '', ' ', '', '', '', ' ' }, - winhighlight = 'NormalFloat:NormalFloat,FloatBorder:NormalFloat', - maxwidth = math.floor((WIDE_HEIGHT * 2) * (vim.o.columns / (WIDE_HEIGHT * 2 * 16 / 9))), - maxheight = math.floor(WIDE_HEIGHT * (WIDE_HEIGHT / vim.o.lines)), - }, - - confirmation = { - default_behavior = types.cmp.ConfirmBehavior.Insert, - get_commit_characters = function(commit_characters) - return commit_characters - end, - }, - - sorting = { - priority_weight = 2, - comparators = { - compare.offset, - compare.exact, - compare.score, - compare.recently_used, - compare.kind, - compare.sort_text, - compare.length, - compare.order, - }, - }, - - event = {}, - mapping = { [''] = mapping({ i = mapping.select_next_item({ behavior = types.cmp.SelectBehavior.Select }), @@ -79,7 +35,7 @@ return function() [''] = mapping({ c = function(fallback) local cmp = require('cmp') - if #cmp.core:get_sources() > 0 and not cmp.get_config().experimental.native_menu then + if #cmp.core:get_sources() > 0 and not require('cmp.config').is_native_menu() then if cmp.visible() then cmp.select_next_item() else @@ -93,7 +49,7 @@ return function() [''] = mapping({ c = function(fallback) local cmp = require('cmp') - if #cmp.core:get_sources() > 0 and not cmp.get_config().experimental.native_menu then + if #cmp.core:get_sources() > 0 and not require('cmp.config').is_native_menu() then if cmp.visible() then cmp.select_prev_item() else @@ -110,6 +66,21 @@ return function() [''] = mapping.abort(), }, + snippet = { + expand = function() + error('snippet engine is not configured.') + end, + }, + + completion = { + keyword_length = 1, + keyword_pattern = [[\%(-\?\d\+\%(\.\d\+\)\?\|\h\w*\%(-\w*\)*\)]], + autocomplete = { + types.cmp.TriggerEvent.TextChanged, + }, + completeopt = 'menu,menuone,noselect', + }, + formatting = { fields = { 'abbr', 'kind', 'menu' }, format = function(_, vim_item) @@ -117,15 +88,44 @@ return function() end, }, - experimental = { - native_menu = false, - ghost_text = false, + sorting = { + priority_weight = 2, + comparators = { + compare.offset, + compare.exact, + compare.score, + compare.recently_used, + compare.kind, + compare.sort_text, + compare.length, + compare.order, + }, }, sources = {}, + documentation = { + border = { '', '', '', ' ', '', '', '', ' ' }, + winhighlight = 'NormalFloat:NormalFloat,FloatBorder:NormalFloat', + maxwidth = math.floor((WIDE_HEIGHT * 2) * (vim.o.columns / (WIDE_HEIGHT * 2 * 16 / 9))), + maxheight = math.floor(WIDE_HEIGHT * (WIDE_HEIGHT / vim.o.lines)), + }, + + confirmation = { + default_behavior = types.cmp.ConfirmBehavior.Insert, + get_commit_characters = function(commit_characters) + return commit_characters + end, + }, + + event = {}, + + experimental = { + ghost_text = false, + }, + view = { - entries = { name = 'custom' }, + entries = 'custom', }, } end diff --git a/lua/cmp/init.lua b/lua/cmp/init.lua index 99432bd..11e359a 100644 --- a/lua/cmp/init.lua +++ b/lua/cmp/init.lua @@ -236,7 +236,7 @@ cmp.status = function() for _, name in ipairs(kinds.available) do vim.api.nvim_echo({ { ('- %s\n'):format(name), 'Normal' } }, false, {}) end - end + end if #kinds.unavailable > 0 then vim.api.nvim_echo({ { '\n', 'Normal' } }, false, {}) @@ -268,6 +268,9 @@ cmp.setup = setmetatable({ global = function(c) config.set_global(c) end, + filetype = function(filetype, c) + config.set_filetype(c, filetype) + end, buffer = function(c) config.set_buffer(c, vim.api.nvim_get_current_buf()) end, diff --git a/lua/cmp/types/cmp.lua b/lua/cmp/types/cmp.lua index df45d5e..c54037c 100644 --- a/lua/cmp/types/cmp.lua +++ b/lua/cmp/types/cmp.lua @@ -131,12 +131,19 @@ cmp.ItemField.Menu = 'menu' ---@field public max_item_count number|nil ---@field public group_index number|nil ----@class cmp.EntriesConfig ----@field name string +---@class cmp.ViewConfig +---@field public entries cmp.EntriesConfig + +---@alias cmp.EntriesConfig cmp.CustomEntriesConfig|cmp.NativeEntriesConfig|cmp.WildmenuEntriesConfig|string + +---@class cmp.CustomEntriesConfig +---@field name "'custom'" + +---@class cmp.NativeEntriesConfig +---@field name "'native'" + +---@class cmp.WildmenuEntriesConfig +---@field name "'wildmenu'" ---@field separator string|nil ----@class cmp.ViewConfig ----@field public entries string|cmp.EntriesConfig ----@field public separator string - return cmp diff --git a/plugin/cmp.lua b/plugin/cmp.lua index eda9db3..a977a78 100644 --- a/plugin/cmp.lua +++ b/plugin/cmp.lua @@ -26,7 +26,7 @@ vim.cmd [[ ]] misc.set(_G, { 'cmp', 'plugin', 'cmdline', 'enter' }, function() - if config.get().experimental.native_menu then + if config.is_native_menu() then return end if vim.fn.expand('')~= '=' then