return {
  "hrsh7th/nvim-cmp",
  event = "InsertEnter",
  dependencies = {
    "hrsh7th/cmp-buffer",
    "hrsh7th/cmp-path",
    "hrsh7th/cmp-nvim-lsp",
    "hrsh7th/cmp-nvim-lua",
    -- "hrsh7th/cmp-cmdline",
    "saadparwaiz1/cmp_luasnip",
    "delphinus/cmp-ctags",
    "onsails/lspkind.nvim",
    { "L3MON4D3/LuaSnip", run = "make install_jsregexp" },
    {
      "windwp/nvim-autopairs",
      event = "InsertEnter",
      opts = function()
        local npairs = require("nvim-autopairs")
        npairs.setup({ fast_wrap = {}, disable_filetype = { "TelescopePrompt", "vim" } })

        local Rule = require("nvim-autopairs.rule")
        npairs.add_rule(Rule("<", ">", "rust"))

        require("cmp").event:on("confirm_done", require("nvim-autopairs.completion.cmp").on_confirm_done())
      end,
    },
    {
      "zbirenbaum/copilot-cmp",
      dependencies = {
        "zbirenbaum/copilot.lua",
        opts = {
          suggestion = { enabled = false },
          panel = { enabled = false },
        },
      },
      config = true,
    },
    {
      "Exafunction/codeium.nvim",
      event = "InsertEnter",
      config = true,
    },
  },
  config = function()
    local cmp = require("cmp")
    local luasnip = require("luasnip")
    -- local lspkind = require("lspkind")

    local check_backspace = function()
      local col = vim.fn.col(".") - 1
      return col == 0 or vim.fn.getline("."):sub(col, col):match("%s")
    end

    local has_words_before = function()
      if vim.api.nvim_buf_get_option(0, "buftype") == "prompt" then
        return false
      end
      ---@diagnostic disable-next-line: deprecated
      local line, col = unpack(vim.api.nvim_win_get_cursor(0))
      return col ~= 0 and vim.api.nvim_buf_get_text(0, line - 1, 0, line - 1, col, {})[1]:match("^%s*$") == nil
    end

    local compare = require("cmp.config.compare")
    local types = require("cmp.types")
    local function deprioritize_snippet(entry1, entry2)
      if entry1:get_kind() == types.lsp.CompletionItemKind.Snippet then
        return false
      end
      if entry2:get_kind() == types.lsp.CompletionItemKind.Snippet then
        return true
      end
    end

    -- cmp.setup.cmdline("/", {
    -- 	mapping = cmp.mapping.preset.cmdline(),
    -- 	sources = { name = "buffer" },
    -- })
    --
    -- cmp.setup.cmdline(":", {
    -- 	mapping = cmp.mapping.preset.cmdline(),
    -- 	sources = cmp.config.sources({ name = "path" }, { name = "cmdline", option = { ignore_cmds = { "Man", "!" } } }),
    -- })

    require("cmp").setup({
      snippet = {
        expand = function(args)
          luasnip.lsp_expand(args.body)
        end,
      },
      mapping = cmp.mapping.preset.insert({
        ["<C-k>"] = cmp.mapping(cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Select }), { "i", "c" }),
        ["<C-j>"] = cmp.mapping(cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Select }), { "i", "c" }),
        ["<C-n>"] = cmp.mapping(cmp.mapping.scroll_docs(-1), { "i", "c" }),
        ["<C-m>"] = cmp.mapping(cmp.mapping.scroll_docs(1), { "i", "c" }),
        ["<C-Space>"] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }),
        ["<C-c>"] = cmp.mapping({
          i = cmp.mapping.abort(),
          c = cmp.mapping.close(),
        }),
        ["<CR>"] = cmp.mapping.confirm({
          -- behavior = cmp.ConfirmBehavior.Replace,
          select = false,
        }),
        ["<Tab>"] = vim.schedule_wrap(function(fallback)
          if cmp.visible() and has_words_before() then
            cmp.select_next_item({ behavior = cmp.SelectBehavior.Select })
          elseif luasnip.jumpable(1) then
            luasnip.jump(1)
          elseif luasnip.expand_or_jumpable() then
            luasnip.expand_or_jump()
          elseif luasnip.expandable() then
            luasnip.expand()
          elseif check_backspace() then
            -- cmp.complete()
            fallback()
          else
            fallback()
          end
        end, {
          "i",
          "s",
        }),
        ["<S-Tab>"] = cmp.mapping(function(fallback)
          if cmp.visible() then
            cmp.select_prev_item({ behavior = cmp.SelectBehavior.Select })
          elseif luasnip.jumpable(-1) then
            luasnip.jump(-1)
          else
            fallback()
          end
        end, {
          "i",
          "s",
        }),
      }),
      formatting = {
        fields = { "kind", "abbr" },
        format = function(entry, vim_item)
          -- -- With Icon
          -- local kind = lspkind.cmp_format({
          -- 	symbol_map = { Copilot = "", Codeium = "", Snippet = "", Keyword = "" },
          -- 	preset = "codicons",
          -- 	maxwidth = 40,
          -- })(entry, vim_item)
          -- local strings = vim.split(vim_item.kind, "%s+", { trimempty = true })
          -- kind.kind = " " .. string.format(" %s │", strings[1], strings[2]) .. " "
          -- return kind

          -- Simple/Old Style
          local kind_icons = {
            Class = " ",
            Color = " ",
            Constant = " ",
            Constructor = " ",
            Enum = "了 ",
            EnumMember = " ",
            Field = " ",
            File = " ",
            Folder = " ",
            Function = " ",
            Interface = "ﰮ ",
            Keyword = " ",
            Method = "ƒ ",
            Module = " ",
            Property = " ",
            Snippet = "﬌ ",
            Struct = " ",
            Text = " ",
            Unit = " ",
            Value = " ",
            Variable = " ",
          }
          vim_item.kind = string.format("%s", kind_icons[vim_item.kind])
          return vim_item
        end,
      },
      sources = {
        { name = "crates",      group_index = 1 },
        { name = "copilot",     max_item_count = 3, trigger_characters = { { ".", ":", "(", "'", '"', "[", ",", "#", "*", "@", "|", "=", "-", "{", "/", "\\", "+", "?" } }, group_index = 2 },
        { name = "nvim_lsp",    group_index = 2 },
        { name = "cmp_tabnine", group_index = 2 },
        { name = "codeium",     max_item_count = 2, group_index = 2 },
        { name = "nvim_lua",    group_index = 2 },
        { name = "buffer",      group_index = 2 },
        { name = "luasnip",     group_index = 2 },
        { name = "path",        group_index = 2 },
      },
      preselect = cmp.PreselectMode.None,
      confirm_opts = {
        -- behavior = cmp.ConfirmBehavior.Replace,
        select = false,
      },
      completion = {
        completeopt = "menu,menuone,noinsert",
        -- keyword_length = 1,
      },
      window = {
        documentation = {
          border = "rounded",
          winhighlight = "Normal:CmpNormal,FloatBorder:CmpBorder,CursorLine:CmpSelection,Search:None",
          scrollbar = false,
          col_offset = 0,
        },
        completion = {
          border = "rounded",
          winhighlight = "Normal:CmpNormal,FloatBorder:CmpBorder,CursorLine:CmpSelection,Search:None",
          scrollbar = false,
          col_offset = 0,
          side_padding = 0,
        },
      },
      sorting = {
        priority_weight = 2,
        comparators = {
          deprioritize_snippet,
          compare.exact,
          require("copilot_cmp.comparators").prioritize,
          require("copilot_cmp.comparators").score,
          compare.offset,
          -- compare.scopes,
          compare.score,
          compare.recently_used,
          -- require("clangd_extensions.cmp_scores"),
          compare.locality,
          -- compare.kind,
          compare.sort_text,
          compare.length,
          compare.order,
        },
      },
      experimental = {
        ghost_text = true,
        native_menu = false,
      },
    })
  end,
}
