Skip to content

Commit fc25477

Browse files
authored
Setup autocompletion with nvim-cmp (#22)
* Add nvim cmp * Disable cmp for git commits and commandline * Disable cmp for markdown * Update readme
1 parent 3c980de commit fc25477

File tree

6 files changed

+263
-1
lines changed

6 files changed

+263
-1
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Using [lualine](https://github.com/nvim-lualine/lualine.nvim), I built a status
5252

5353
### 📋 List of Plugins
5454

55+
- [cmp](https://github.com/hrsh7th/nvim-cmp)
5556
- [conform](https://github.com/stevearc/conform.nvim)
5657
- [gitsigns](https://github.com/lewis6991/gitsigns.nvim)
5758
- [lualine](https://github.com/nvim-lualine/lualine.nvim)

lua/config-plugins/cmp.lua

+220
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
vim.api.nvim_create_autocmd("FileType", {
2+
callback = function()
3+
local filetypes = { "gitcommit", "markdown" }
4+
for _, f in ipairs(filetypes) do
5+
if vim.bo.filetype == f then
6+
require("cmp").setup.filetype(f, {
7+
enabled = false,
8+
})
9+
end
10+
end
11+
end,
12+
})
13+
14+
vim.api.nvim_create_autocmd("CmdlineEnter", {
15+
callback = function()
16+
require("cmp").setup { enabled = false }
17+
end,
18+
})
19+
20+
vim.api.nvim_create_autocmd("CmdlineLeave", {
21+
callback = function()
22+
require("cmp").setup { enabled = true }
23+
end,
24+
})
25+
26+
return {
27+
"hrsh7th/nvim-cmp",
28+
event = { "BufEnter", "BufReadPre", "BufNewFile" },
29+
dependencies = {
30+
"hrsh7th/cmp-buffer",
31+
"hrsh7th/cmp-nvim-lsp",
32+
"hrsh7th/cmp-nvim-lua",
33+
"hrsh7th/cmp-cmdline",
34+
"hrsh7th/cmp-path",
35+
"f3fora/cmp-spell",
36+
"hrsh7th/cmp-nvim-lsp-signature-help",
37+
"saadparwaiz1/cmp_luasnip",
38+
"lukas-reineke/cmp-under-comparator",
39+
},
40+
config = function()
41+
local kind_icons = {
42+
Text = "󰉿",
43+
Method = "󰆧",
44+
Function = "󰊕",
45+
Constructor = "",
46+
Field = "󰜢",
47+
Variable = "󰀫",
48+
Class = "󰠱",
49+
Interface = "",
50+
Module = "",
51+
Property = "󰜢",
52+
Unit = "󰑭",
53+
Value = "󰎠",
54+
Enum = "",
55+
Keyword = "󰌋",
56+
Snippet = "",
57+
Color = "󰏘",
58+
File = "󰈙",
59+
Reference = "󰈇",
60+
Folder = "󰉋",
61+
EnumMember = "",
62+
Constant = "󰏿",
63+
Struct = "󰙅",
64+
Event = "",
65+
Operator = "󰆕",
66+
TypeParameter = "",
67+
}
68+
69+
local cmp = require("cmp")
70+
local cmplsp = require("cmp_nvim_lsp")
71+
local compare = require("cmp.config.compare")
72+
local luasnip = require("luasnip")
73+
local types = require("cmp.types")
74+
75+
cmplsp.setup()
76+
77+
local modified_priority = {
78+
[types.lsp.CompletionItemKind.Variable] = types.lsp.CompletionItemKind.Method,
79+
[types.lsp.CompletionItemKind.Snippet] = 0, -- top
80+
[types.lsp.CompletionItemKind.Keyword] = 0, -- top
81+
[types.lsp.CompletionItemKind.Text] = 100, -- bottom
82+
}
83+
84+
local function modified_kind(kind)
85+
return modified_priority[kind] or kind
86+
end
87+
88+
local buffers = {
89+
name = "buffer",
90+
option = {
91+
keyword_length = 3,
92+
get_bufnrs = function() -- from all buffers (less than 1MB)
93+
local bufs = {}
94+
for _, bufn in ipairs(vim.api.nvim_list_bufs()) do
95+
local buf_size = vim.api.nvim_buf_get_offset(bufn, vim.api.nvim_buf_line_count(bufn))
96+
if buf_size < 1024 * 1024 then
97+
table.insert(bufs, bufn)
98+
end
99+
end
100+
return bufs
101+
end,
102+
},
103+
}
104+
105+
local spelling = {
106+
name = "spell",
107+
max_item_count = 5,
108+
keyword_length = 3,
109+
option = {
110+
keep_all_entries = false,
111+
enable_in_context = function()
112+
return true
113+
end,
114+
},
115+
}
116+
117+
cmp.setup {
118+
preselect = false,
119+
completion = {
120+
completeopt = "menu,menuone,preview,noselect",
121+
},
122+
snippet = {
123+
expand = function(args)
124+
luasnip.lsp_expand(args.body)
125+
end,
126+
},
127+
formatting = {
128+
fields = { "abbr", "kind", "menu" },
129+
format = function(entry, vim_item)
130+
local kind = vim_item.kind
131+
vim_item.kind = " " .. (kind_icons[kind] or "?") .. ""
132+
local source = entry.source.name
133+
vim_item.menu = "[" .. source .. "]"
134+
135+
return vim_item
136+
end,
137+
},
138+
sorting = {
139+
priority_weight = 1.0,
140+
comparators = {
141+
compare.offset,
142+
compare.exact,
143+
function(entry1, entry2) -- sort by length ignoring "=~"
144+
local len1 = string.len(string.gsub(entry1.completion_item.label, "[=~()_]", ""))
145+
local len2 = string.len(string.gsub(entry2.completion_item.label, "[=~()_]", ""))
146+
if len1 ~= len2 then
147+
return len1 - len2 < 0
148+
end
149+
end,
150+
compare.recently_used,
151+
function(entry1, entry2) -- sort by compare kind (Variable, Function etc)
152+
local kind1 = modified_kind(entry1:get_kind())
153+
local kind2 = modified_kind(entry2:get_kind())
154+
if kind1 ~= kind2 then
155+
return kind1 - kind2 < 0
156+
end
157+
end,
158+
compare.score,
159+
require("cmp-under-comparator").under,
160+
compare.kind,
161+
},
162+
},
163+
matching = {
164+
disallow_fuzzy_matching = true,
165+
disallow_fullfuzzy_matching = true,
166+
disallow_partial_fuzzy_matching = true,
167+
disallow_partial_matching = false,
168+
disallow_prefix_unmatching = true,
169+
},
170+
min_length = 0, -- allow for `from package import _` in Python
171+
mapping = cmp.mapping.preset.insert {
172+
["<CR>"] = cmp.mapping.confirm { select = false }, -- no not select first item
173+
["<C-e>"] = cmp.mapping.abort(),
174+
["<Tab>"] = cmp.mapping(function(fallback)
175+
if cmp.visible() then
176+
cmp.select_next_item()
177+
elseif luasnip.expand_or_jumpable() then
178+
luasnip.expand_or_jump()
179+
else
180+
fallback()
181+
end
182+
end, { "i", "s" }),
183+
["<S-Tab>"] = cmp.mapping(function(fallback)
184+
if cmp.visible() then
185+
cmp.select_prev_item()
186+
elseif luasnip.jumpable(-1) then
187+
luasnip.jump(-1)
188+
else
189+
fallback()
190+
end
191+
end, { "i", "s" }),
192+
},
193+
sources = cmp.config.sources({
194+
{ name = "nvim_lsp", max_item_count = 5 },
195+
{ name = "luasnip", max_item_count = 3 },
196+
{ name = "luasnip", max_item_count = 3 },
197+
{ name = "nvim_lua", max_item_count = 5 },
198+
{ name = "nvim_lsp_signature_help", max_item_count = 5 },
199+
}, {
200+
buffers,
201+
spelling,
202+
}),
203+
performance = {
204+
max_view_entries = 20,
205+
},
206+
window = { documentation = cmp.config.window.bordered(), completion = cmp.config.window.bordered() },
207+
}
208+
209+
-- `:` cmdline setup.
210+
cmp.setup.cmdline(":", {
211+
mapping = cmp.mapping.preset.cmdline(),
212+
sources = cmp.config.sources({
213+
{ name = "path" },
214+
}, {
215+
{ name = "cmdline" },
216+
}),
217+
matching = { disallow_symbol_nonprefix_matching = false },
218+
})
219+
end,
220+
}
File renamed without changes.

lua/config-plugins/conform.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ return {
66
formatters_by_ft = {
77
lua = { "stylua" },
88
-- Conform will run multiple formatters sequentially
9-
python = { "ruff", "isort" },
109
sh = { "shellcheck" },
10+
python = { "isort", "ruff_format" },
1111
terraform = { "terraform_fmt" },
1212
},
1313
format_on_save = {
File renamed without changes.

lua/config-plugins/luasnip.lua

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
return {
2+
"L3MON4D3/LuaSnip", -- snippet completions
3+
event = { "BufReadPre", "BufNewFile" },
4+
dependencies = { "rafamadriz/friendly-snippets" },
5+
build = "make install_jsregexp",
6+
config = function()
7+
local ls = require("luasnip")
8+
9+
local lsloader = require("luasnip.loaders.from_lua")
10+
11+
require("luasnip.loaders.from_vscode").lazy_load()
12+
lsloader.load { paths = "~/.config/nvim/snippets" }
13+
14+
local types = require("luasnip.util.types")
15+
16+
ls.config.set_config {
17+
-- Keep last snippet to jump around
18+
history = true,
19+
20+
-- Enable dynamic snippets
21+
updateevents = "TextChanged,TextChangedI",
22+
-- For cleaning up snippets whose text was deleted
23+
delete_check_events = "TextChanged",
24+
25+
enable_autosnippets = true,
26+
27+
ext_opts = {
28+
[types.choiceNode] = { active = { virt_text = { { "", "Operator" } } } },
29+
},
30+
}
31+
32+
-- Extend changelog with debchangelog
33+
ls.filetype_extend("changelog", { "debchangelog" })
34+
35+
vim.keymap.set("i", "<c-l>", function()
36+
if ls.choice_active() then
37+
ls.change_choice(1)
38+
end
39+
end)
40+
end,
41+
}

0 commit comments

Comments
 (0)