return { { -- Autocompletion 'hrsh7th/nvim-cmp', event = 'InsertEnter', dependencies = { -- Snippet Engine & its associated nvim-cmp source { 'L3MON4D3/LuaSnip', build = (function() -- Build Step is needed for regex support in snippets. -- This step is not supported in many windows environments. -- Remove the below condition to re-enable on windows. if vim.fn.has 'win32' == 1 or vim.fn.executable 'make' == 0 then return end return 'make install_jsregexp' end)(), dependencies = { -- `friendly-snippets` contains a variety of premade snippets. -- See the README about individual language/framework/plugin snippets: -- https://github.com/rafamadriz/friendly-snippets -- { -- 'rafamadriz/friendly-snippets', -- config = function() -- require('luasnip.loaders.from_vscode').lazy_load() -- end, -- }, }, }, 'saadparwaiz1/cmp_luasnip', -- Adds other completion capabilities. -- nvim-cmp does not ship with all sources by default. They are split -- into multiple repos for maintenance purposes. 'hrsh7th/cmp-nvim-lsp', 'hrsh7th/cmp-path', 'hrsh7th/cmp-nvim-lsp-signature-help', { -- 'milanglacier/minuet-ai.nvim', -- dir = '~/code/minuet-ai.nvim', url = 'ssh://git@code.blarg.ca:2250/gered/minuet-ai.git', branch = 'openai_fim_fn_customizations', config = function() local function get_stop_tokens(model) if model:match '^codellama' then return { '\n\n', '' } elseif model:match '^qwen' then return { '<|endoftext|>' } elseif model:match '^starcoder' then return { '', '', '', '', '<|endoftext|>' } elseif model:match '^codestral' then return { '[INST]', '[/INST]', '[PREFIX]', '[MIDDLE]', '[SUFFIX]' } elseif model:match '^deepseek%-coder' then return nil elseif model:match '^granite%-code' then return { 'System:', 'Question:', 'Answer:' } end end local function get_fim_prompt(model, prefix, suffix) if model:match '^codellama' then return '
 ' .. prefix .. ' ' .. suffix .. ' '
            elseif model:match '^qwen' then
              return '<|fim_prefix|>' .. prefix .. '<|fim_suffix|>' .. suffix .. '<|fim_middle|>'
            elseif model:match '^starcoder' then
              return '' .. prefix .. '' .. suffix .. ''
            elseif model:match '^codestral' then
              return '[SUFFIX]' .. suffix .. '[PREFIX]' .. prefix
            elseif model:match '^deepseek%-coder' then
              return '<|fim▁begin|>' .. prefix .. '<|fim▁hole|>' .. suffix .. '<|fim▁end|>'
            elseif model:match '^granite%-code' then
              return ' ' .. prefix .. ' ' .. suffix .. ''
            end
          end

          local llama_base_url = os.getenv 'LLAMA_API_BASE' or 'http://localhost:11434'
          local model = 'codellama:13b-code-q4_K_M'
          -- local model = 'qwen2.5-coder:7b-base-q4_K_M'
          -- local model = 'starcoder2:7b-q4_K_M'
          -- local model = 'codestral:22b-v0.1-q4_K_M'
          -- local model = 'deepseek-coder-v2:16b-lite-base-q4_K_M-fixed'
          -- local model = 'granite-code:8b-base-q4_K_M'

          require('minuet').setup {
            enabled = true,
            provider = 'openai_fim_compatible',
            context_window = 12800,
            context_ratio = 0.75,
            throttle = 1000,
            debounce = 400,
            notify = 'verbose',
            request_timeout = 60,
            add_single_line_entry = false,
            n_completions = 1,
            provider_options = {
              openai_fim_compatible = {
                model = model,
                end_point = llama_base_url .. '/v1/chat/completions',
                api_key = 'LLAMA_API_KEY',
                name = 'Ollama',
                stream = false,
                optional = {
                  stop = get_stop_tokens(model),
                  max_tokens = 256,
                  temperature = 0.2,
                  n = 1,
                },
                prompt_fn = function(data, options, prefix, suffix)
                  data.messages = {
                    {
                      role = 'user',
                      content = get_fim_prompt(model, prefix, suffix),
                    },
                  }
                  --data.prompt = prefix
                  --data.suffix = suffix
                end,
                get_text_fn = function(json)
                  return json.choices[1].message.content
                  --return json.choices[1].text
                end,
              },
            },
          }
        end,
      },
    },
    config = function()
      -- See `:help cmp`
      local cmp = require 'cmp'
      local types = require 'cmp.types'
      local luasnip = require 'luasnip'
      luasnip.config.setup {}

      cmp.setup {
        snippet = {
          expand = function(args)
            luasnip.lsp_expand(args.body)
          end,
        },
        completion = { completeopt = 'menu,menuone,noinsert' },

        -- For an understanding of why these mappings were
        -- chosen, you will need to read `:help ins-completion`
        --
        -- No, but seriously. Please read `:help ins-completion`, it is really good!
        mapping = cmp.mapping.preset.insert {
          -- Disable use of  and  for navigation within a completion list.
          [''] = cmp.mapping.close(),
          [''] = cmp.mapping.close(),

          -- Identical to old  key behavior
          [''] = cmp.mapping.select_next_item { behavior = types.cmp.SelectBehavior.Select },
          -- Identical to old  key behavior
          [''] = cmp.mapping.select_prev_item { behavior = types.cmp.SelectBehavior.Select },

          -- Select the [n]ext item
          [''] = cmp.mapping.select_next_item(),
          -- Select the [p]revious item
          [''] = cmp.mapping.select_prev_item(),

          -- Scroll the documentation window [b]ack / [f]orward
          [''] = cmp.mapping.scroll_docs(-4),
          [''] = cmp.mapping.scroll_docs(4),

          -- Accept ([y]es) the completion.
          --  This will auto-import if your LSP supports it.
          --  This will expand snippets if the LSP sent a snippet.
          [''] = cmp.mapping.confirm { select = true },

          -- Cancel/abort any selected/partial completion and close the completion list.
          [''] = cmp.mapping.abort(),

          -- If you prefer more traditional completion keymaps,
          -- you can uncomment the following lines
          --[''] = cmp.mapping.confirm { select = true },
          --[''] = cmp.mapping.select_next_item(),
          --[''] = cmp.mapping.select_prev_item(),

          -- Manually trigger a completion from nvim-cmp.
          --  Generally you don't need this, because nvim-cmp will display
          --  completions whenever it has completion options available.
          [''] = cmp.mapping.complete {},

          -- Think of  as moving to the right of your snippet expansion.
          --  So if you have a snippet that's like:
          --  function $name($args)
          --    $body
          --  end
          --
          --  will move you to the right of each of the expansion locations.
          --  is similar, except moving you backwards.
          [''] = cmp.mapping(function()
            if luasnip.expand_or_locally_jumpable() then
              luasnip.expand_or_jump()
            end
          end, { 'i', 's' }),
          [''] = cmp.mapping(function()
            if luasnip.locally_jumpable(-1) then
              luasnip.jump(-1)
            end
          end, { 'i', 's' }),

          -- explicit keybinding for minuet-ai completions
          [''] = require('minuet').make_cmp_map(),

          -- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see:
          --    https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps
        },
        sources = {
          {
            name = 'lazydev',
            -- set group index to 0 to skip loading LuaLS completions as lazydev recommends it
            group_index = 0,
          },
          {
            name = 'nvim_lsp',
            entry_filter = function(entry, ctx)
              -- do not show snippets in the completion list
              return require('cmp').lsp.CompletionItemKind.Snippet ~= entry:get_kind()
            end,
          },
          { name = 'luasnip' },
          { name = 'path' },
          { name = 'nvim_lsp_signature_help' },
        },
      }
    end,
  },
}

-- vim: ts=2 sts=2 sw=2 et