summaryrefslogtreecommitdiff
path: root/dot_config/nvim/lua/plugins/nvim-cmp.lua.tmpl
blob: 60c77d3589851af7ffb3569bc7f5b054c9f6cb78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
-- {{/*
-- vim:ft=lua
-- This file supports Go's text/template language.
--
-- My work role allows me to use an enterprise subscription to GitHub
-- Copilot, but I don't pay to use this personally.
--
-- Since copilot.lua is integrated tightly into nvim-cmp, using a
-- Chezmoi template is the easiest way to manage this machine-specific
-- difference.
--
-- Unfortunately, it's tough to get an editor to treat this as both
-- a Go template and as a Lua file. I compromise by calling it a Lua
-- file and wrapping template directives in Lua comments. This has the
-- side effect of adding a few extra random dash characters to the
-- rendered file, but I don't mind.
-- */}}

-- Optional features:
-- * GitHub Copilot: {{ .enable_nvim_copilot }}
--
-- To adjust optional features, see the Chezmoi config at {{ .chezmoi.configFile }}

return {
    "hrsh7th/nvim-cmp",
    version = false, -- last release is way too old
    event = { "InsertEnter", "CmdlineEnter" },
    dependencies = {
        "L3MON4D3/LuaSnip",             -- Snippet engine
        "rafamadriz/friendly-snippets", -- Useful snippets in VSCode snippet format
        "onsails/lspkind.nvim",         -- Pretty formatting in the completion menu

        -- Completion sources
        "hrsh7th/cmp-nvim-lsp",
        "hrsh7th/cmp-nvim-lsp-signature-help",
        "hrsh7th/cmp-buffer",
        "hrsh7th/cmp-path",
        "saadparwaiz1/cmp_luasnip",

        -- {{ if eq .enable_nvim_copilot true -}}
        -- GitHub Copilot
        "zbirenbaum/copilot.lua",
        "zbirenbaum/copilot-cmp",
        -- {{- end }}
    },
    config = function()
        local cmp = require("cmp")
        local luasnip = require("luasnip")

        -- Load any VSCode-style snippets from other installed plugins
        require("luasnip.loaders.from_vscode").lazy_load()

        -- {{ if eq .enable_nvim_copilot true -}}
        -- Init Copilot
        require("copilot").setup({
            suggestion = { enabled = false },
            panel = { enabled = false },
        })
        require("copilot_cmp").setup()
        -- {{ end }}

        cmp.setup({
            completion = {
                -- See :help completeopt
                completeopt = "menu,menuone,noinsert,preview",
            },
            snippet = {
                expand = function(args)
                    luasnip.lsp_expand(args.body)
                end,
            },
            mapping = cmp.mapping.preset.insert({
                ["<C-n>"] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }),
                ["<C-p>"] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }),
                ["<C-b>"] = cmp.mapping.scroll_docs(-4),
                ["<C-f>"] = cmp.mapping.scroll_docs(4),

                -- Ctrl+Space does not currently work in Neovim core on Windows
                -- https://github.com/neovim/neovim/issues/8435
                -- ["<C-Space>"] = cmp.mapping.complete(),
                ["<C-c>"] = cmp.mapping.complete(),

                ["<C-e>"] = cmp.mapping.abort(),
                ["<C-y>"] = cmp.mapping.confirm({
                    -- Accept currently selected item
                    behavior = cmp.ConfirmBehavior.Insert,
                    select = true,
                }),
                ["<C-S-y>"] = cmp.mapping.confirm({
                    -- Accept currently selected item, replacing stuff as needed
                    behavior = cmp.ConfirmBehavior.Replace,
                    select = true,
                }),
                ["<CR>"] = cmp.mapping({
                    -- https://github.com/hrsh7th/nvim-cmp/wiki/Example-mappings#safely-select-entries-with-cr
                    i = function(fallback)
                        -- In insert mode, only use Enter to complete something if cmp
                        -- is active and the user has explicitly selected an item
                        if cmp.visible() and cmp.get_active_entry() then
                            cmp.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = false })
                        else
                            fallback()
                        end
                    end,
                    s = cmp.mapping.confirm({ select = true }),
                    c = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = true }),
                }),
            }),
            sorting = {
                priority_weight = 2,
                comparators = {
                    cmp.config.compare.exact,

                    -- {{ if eq .enable_nvim_copilot true -}}
                    -- Custom comparitor from copilot_cmp
                    require("copilot_cmp.comparators").prioritize,
                    -- {{ end -}}

                    -- Mostly default sort order from cmp
                    cmp.config.compare.offset,
                    -- cmp.config.compare.scopes, --this is commented in nvim-cmp too
                    cmp.config.compare.score,
                    cmp.config.compare.recently_used,
                    cmp.config.compare.locality,
                    cmp.config.compare.kind,
                    cmp.config.compare.sort_text,
                    cmp.config.compare.length,
                    cmp.config.compare.order,
                },
            },
            sources = {
                -- LSP results should be first priority
                { name = "nvim_lsp",                group_index = 1 },

                { name = "nvim_lsp_signature_help", group_index = 2 },
                { name = "luasnip",                 group_index = 2 },
                -- {{ if eq .enable_nvim_copilot true }}
                { name = "copilot",                 group_index = 2 },
                -- {{ end }}
                { name = "path",                    group_index = 2 },
                { name = "buffer",                  group_index = 2, keyword_length = 5 },
            },
            -- sources = cmp.config.sources({
            --     { name = "nvim_lsp_signature_help" },
            --     { name = "nvim_lsp" },
            --     { name = "luasnip" },
            -- }, {
            --     { name = "path" },
            --     { name = "buffer", keyword_length = 5 },
            -- }),
            formatting = {
                format = require("lspkind").cmp_format({
                    mode = "symbol_text",
                    -- maxwidth = 50,
                    maxwidth = function()
                        return math.floor(0.45 * vim.o.columns)
                    end,
                    ellipsis_char = "...",
                    show_labelDetails = true,
                    symbol_map = {
                        -- {{ if eq .enable_nvim_copilot true }}
                        Copilot = " ",
                        -- {{ end }}
                    },
                }),
            },
            experimental = {
                ghost_text = {
                    hl_group = "LspCodeLens",
                },
            },
            window = {
                completion = cmp.config.window.bordered(),
                documentation = cmp.config.window.bordered(),
            },
        })
    end,
}