diff options
Diffstat (limited to '.config/nvim/lua/core/cmp.lua')
-rw-r--r-- | .config/nvim/lua/core/cmp.lua | 309 |
1 files changed, 0 insertions, 309 deletions
diff --git a/.config/nvim/lua/core/cmp.lua b/.config/nvim/lua/core/cmp.lua deleted file mode 100644 index fe4119f..0000000 --- a/.config/nvim/lua/core/cmp.lua +++ /dev/null @@ -1,309 +0,0 @@ -local M = {} -M.methods = {} - ----checks if the character preceding the cursor is a space character ----@return boolean true if it is a space character, false otherwise -local check_backspace = function() - local col = vim.fn.col "." - 1 - return col == 0 or vim.fn.getline("."):sub(col, col):match "%s" -end -M.methods.check_backspace = check_backspace - -local function T(str) - return vim.api.nvim_replace_termcodes(str, true, true, true) -end - ----wraps vim.fn.feedkeys while replacing key codes with escape codes ----Ex: feedkeys("<CR>", "n") becomes feedkeys("^M", "n") ----@param key string ----@param mode string -local function feedkeys(key, mode) - vim.fn.feedkeys(T(key), mode) -end -M.methods.feedkeys = feedkeys - ----checks if emmet_ls is available and active in the buffer ----@return boolean true if available, false otherwise -local is_emmet_active = function() - local clients = vim.lsp.buf_get_clients() - - for _, client in pairs(clients) do - if client.name == "emmet_ls" then - return true - end - end - return false -end -M.methods.is_emmet_active = is_emmet_active - ----when inside a snippet, seeks to the nearest luasnip field if possible, and checks if it is jumpable ----@param dir number 1 for forward, -1 for backward; defaults to 1 ----@return boolean true if a jumpable luasnip field is found while inside a snippet -local function jumpable(dir) - local luasnip_ok, luasnip = pcall(require, "luasnip") - if not luasnip_ok then - return - end - - local win_get_cursor = vim.api.nvim_win_get_cursor - local get_current_buf = vim.api.nvim_get_current_buf - - local function inside_snippet() - -- for outdated versions of luasnip - if not luasnip.session.current_nodes then - return false - end - - local node = luasnip.session.current_nodes[get_current_buf()] - if not node then - return false - end - - local snip_begin_pos, snip_end_pos = node.parent.snippet.mark:pos_begin_end() - local pos = win_get_cursor(0) - pos[1] = pos[1] - 1 -- LuaSnip is 0-based not 1-based like nvim for rows - return pos[1] >= snip_begin_pos[1] and pos[1] <= snip_end_pos[1] - end - - ---sets the current buffer's luasnip to the one nearest the cursor - ---@return boolean true if a node is found, false otherwise - local function seek_luasnip_cursor_node() - -- for outdated versions of luasnip - if not luasnip.session.current_nodes then - return false - end - - local pos = win_get_cursor(0) - pos[1] = pos[1] - 1 - local node = luasnip.session.current_nodes[get_current_buf()] - if not node then - return false - end - - local snippet = node.parent.snippet - local exit_node = snippet.insert_nodes[0] - - -- exit early if we're past the exit node - if exit_node then - local exit_pos_end = exit_node.mark:pos_end() - if - (pos[1] > exit_pos_end[1]) - or (pos[1] == exit_pos_end[1] and pos[2] > exit_pos_end[2]) - then - snippet:remove_from_jumplist() - luasnip.session.current_nodes[get_current_buf()] = nil - - return false - end - end - - node = snippet.inner_first:jump_into(1, true) - while node ~= nil and node.next ~= nil and node ~= snippet do - local n_next = node.next - local next_pos = n_next and n_next.mark:pos_begin() - local candidate = n_next ~= snippet and next_pos and (pos[1] < next_pos[1]) - or (pos[1] == next_pos[1] and pos[2] < next_pos[2]) - - -- Past unmarked exit node, exit early - if n_next == nil or n_next == snippet.next then - snippet:remove_from_jumplist() - luasnip.session.current_nodes[get_current_buf()] = nil - - return false - end - - if candidate then - luasnip.session.current_nodes[get_current_buf()] = node - return true - end - - local ok - ok, node = pcall(node.jump_from, node, 1, true) -- no_move until last stop - if not ok then - snippet:remove_from_jumplist() - luasnip.session.current_nodes[get_current_buf()] = nil - - return false - end - end - - -- No candidate, but have an exit node - if exit_node then - -- to jump to the exit node, seek to snippet - luasnip.session.current_nodes[get_current_buf()] = snippet - return true - end - - -- No exit node, exit from snippet - snippet:remove_from_jumplist() - luasnip.session.current_nodes[get_current_buf()] = nil - return false - end - - if dir == -1 then - return inside_snippet() and luasnip.jumpable(-1) - else - return inside_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable() - end -end -M.methods.jumpable = jumpable - -M.config = function() - local status_cmp_ok, cmp = pcall(require, "cmp") - if not status_cmp_ok then - return - end - local status_luasnip_ok, luasnip = pcall(require, "luasnip") - if not status_luasnip_ok then - return - end - - options.builtin.cmp = { - confirm_opts = { - behavior = cmp.ConfirmBehavior.Replace, - select = false, - }, - completion = { - ---@usage The minimum length of a word to complete on. - keyword_length = 1, - }, - experimental = { - ghost_text = true, - native_menu = false, - }, - formatting = { - fields = { "kind", "abbr", "menu" }, - kind_icons = { - Class = " ", - Color = " ", - Constant = "ﲀ ", - Constructor = " ", - Enum = "練", - EnumMember = " ", - Event = " ", - Field = " ", - File = "", - Folder = " ", - Function = " ", - Interface = "ﰮ ", - Keyword = " ", - Method = " ", - Module = " ", - Operator = "", - Property = " ", - Reference = " ", - Snippet = " ", - Struct = " ", - Text = " ", - TypeParameter = " ", - Unit = "塞", - Value = " ", - Variable = " ", - }, - source_names = { - nvim_lsp = "(LSP)", - path = "(Path)", - calc = "(Calc)", - cmp_tabnine = "(Tabnine)", - vsnip = "(Snippet)", - luasnip = "(Snippet)", - buffer = "(Buffer)", - }, - duplicates = { - buffer = 1, - path = 1, - nvim_lsp = 0, - luasnip = 1, - }, - duplicates_default = 0, - format = function(entry, vim_item) - vim_item.kind = options.builtin.cmp.formatting.kind_icons[vim_item.kind] - vim_item.menu = options.builtin.cmp.formatting.source_names[entry.source.name] - vim_item.dup = options.builtin.cmp.formatting.duplicates[entry.source.name] - or options.builtin.cmp.formatting.duplicates_default - return vim_item - end, - }, - snippet = { - expand = function(args) - require("luasnip").lsp_expand(args.body) - end, - }, - documentation = { - border = { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, - }, - sources = { - { name = "nvim_lsp" }, - { name = "path" }, - { name = "luasnip" }, - { name = "cmp_tabnine" }, - { name = "nvim_lua" }, - { name = "buffer", keyword_length = 5 }, - { name = "calc" }, - { name = "treesitter" }, - { name = "crates" }, - }, - mapping = { - ["<C-k>"] = cmp.mapping.select_prev_item(), - ["<C-j>"] = cmp.mapping.select_next_item(), - ["<C-d>"] = cmp.mapping.scroll_docs(-4), - ["<C-f>"] = cmp.mapping.scroll_docs(4), - -- TODO: potentially fix emmet nonsense - ["<Tab>"] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_next_item() - elseif luasnip.expandable() then - luasnip.expand() - elseif jumpable() then - luasnip.jump(1) - elseif check_backspace() then - fallback() - elseif is_emmet_active() then - return vim.fn["cmp#complete"]() - else - fallback() - end - end, { - "i", - "s", - }), - ["<S-Tab>"] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_prev_item() - elseif jumpable(-1) then - luasnip.jump(-1) - else - fallback() - end - end, { - "i", - "s", - }), - - ["<C-Space>"] = cmp.mapping.complete(), - ["<C-e>"] = cmp.mapping.abort(), - ["<CR>"] = cmp.mapping(function(fallback) - if cmp.visible() and cmp.confirm(options.builtin.cmp.confirm_opts) then - if jumpable() then - luasnip.jump(1) - end - return - end - - if jumpable() then - if not luasnip.jump(1) then - fallback() - end - else - fallback() - end - end), - }, - } -end - -M.setup = function() - require("cmp").setup(options.builtin.cmp) -end - -return M |