From 9ece2e5369de46962422837be3dce3b8e889805d Mon Sep 17 00:00:00 2001 From: Christian Chiarulli Date: Tue, 7 Sep 2021 19:23:14 -0400 Subject: feat: compe -> cmp (#1496) --- lua/core/cmp.lua | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 lua/core/cmp.lua (limited to 'lua/core/cmp.lua') diff --git a/lua/core/cmp.lua b/lua/core/cmp.lua new file mode 100644 index 00000000..7f912544 --- /dev/null +++ b/lua/core/cmp.lua @@ -0,0 +1,123 @@ +local M = {} + +local check_backspace = function() + local col = vim.fn.col "." - 1 + return col == 0 or vim.fn.getline("."):sub(col, col):match "%s" +end + +local function T(str) + return vim.api.nvim_replace_termcodes(str, true, true, true) +end + +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.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 + lvim.builtin.cmp = { + formatting = { + format = function(entry, vim_item) + local icons = require("lsp.kind").icons + vim_item.kind = icons[vim_item.kind] + vim_item.menu = ({ + nvim_lsp = "(LSP)", + emoji = "(Emoji)", + path = "(Path)", + calc = "(Calc)", + cmp_tabnine = "(Tabnine)", + vsnip = "(Snippet)", + luasnip = "(Snippet)", + buffer = "(Buffer)", + })[entry.source.name] + vim_item.dup = ({ + buffer = 1, + path = 1, + nvim_lsp = 0, + })[entry.source.name] or 0 + 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" }, + { name = "calc" }, + { name = "emoji" }, + { name = "treesitter" }, + { name = "crates" }, + }, + mapping = { + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.scroll_docs(4), + -- TODO: potentially fix emmet nonsense + [""] = cmp.mapping(function() + if vim.fn.pumvisible() == 1 then + vim.fn.feedkeys(T "", "n") + elseif luasnip.expand_or_jumpable() then + vim.fn.feedkeys(T "luasnip-expand-or-jump", "") + elseif check_backspace() then + vim.fn.feedkeys(T "", "n") + elseif is_emmet_active() then + return vim.fn["cmp#complete"]() + else + vim.fn.feedkeys(T "", "n") + end + end, { + "i", + "s", + }), + [""] = cmp.mapping(function(fallback) + if vim.fn.pumvisible() == 1 then + vim.fn.feedkeys(T "", "n") + elseif luasnip.jumpable(-1) then + vim.fn.feedkeys(T "luasnip-jump-prev", "") + else + fallback() + end + end, { + "i", + "s", + }), + + [""] = cmp.mapping.complete(), + [""] = cmp.mapping.close(), + [""] = cmp.mapping.confirm { + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }, + }, + } + + M.setup = function() + require("luasnip/loaders/from_vscode").lazy_load() + require("cmp").setup(lvim.builtin.cmp) + end +end + +return M -- cgit v1.2.3 From ac32f2e64d61291ba4969599827eef515712d5d8 Mon Sep 17 00:00:00 2001 From: Christian Chiarulli Date: Thu, 9 Sep 2021 09:25:12 -0400 Subject: fix: move setup function outside of config function --- lua/core/cmp.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lua/core/cmp.lua') diff --git a/lua/core/cmp.lua b/lua/core/cmp.lua index 7f912544..acfb05ae 100644 --- a/lua/core/cmp.lua +++ b/lua/core/cmp.lua @@ -113,11 +113,11 @@ M.config = function() }, }, } +end - M.setup = function() - require("luasnip/loaders/from_vscode").lazy_load() - require("cmp").setup(lvim.builtin.cmp) - end +M.setup = function() + require("luasnip/loaders/from_vscode").lazy_load() + require("cmp").setup(lvim.builtin.cmp) end return M -- cgit v1.2.3 From f0b30f0a83988e6194970838656f9d4e8250e547 Mon Sep 17 00:00:00 2001 From: Christian Chiarulli Date: Tue, 14 Sep 2021 01:33:40 -0400 Subject: fix: no preselect for up/down, c-j/c-k and tab/s-tab --- lua/core/cmp.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lua/core/cmp.lua') diff --git a/lua/core/cmp.lua b/lua/core/cmp.lua index acfb05ae..928b7e3a 100644 --- a/lua/core/cmp.lua +++ b/lua/core/cmp.lua @@ -78,7 +78,7 @@ M.config = function() -- TODO: potentially fix emmet nonsense [""] = cmp.mapping(function() if vim.fn.pumvisible() == 1 then - vim.fn.feedkeys(T "", "n") + vim.fn.feedkeys(T "", "n") elseif luasnip.expand_or_jumpable() then vim.fn.feedkeys(T "luasnip-expand-or-jump", "") elseif check_backspace() then @@ -94,7 +94,7 @@ M.config = function() }), [""] = cmp.mapping(function(fallback) if vim.fn.pumvisible() == 1 then - vim.fn.feedkeys(T "", "n") + vim.fn.feedkeys(T "", "n") elseif luasnip.jumpable(-1) then vim.fn.feedkeys(T "luasnip-jump-prev", "") else -- cgit v1.2.3 From fbfd8c1fc3d0df1e2169df64c2264de7e23a9105 Mon Sep 17 00:00:00 2001 From: Chase Colman <5411+chase@users.noreply.github.com> Date: Tue, 21 Sep 2021 14:54:47 +0800 Subject: feature: allow cmp confirm options to be configurable (#1523) --- lua/core/cmp.lua | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'lua/core/cmp.lua') diff --git a/lua/core/cmp.lua b/lua/core/cmp.lua index 928b7e3a..2bc724fb 100644 --- a/lua/core/cmp.lua +++ b/lua/core/cmp.lua @@ -30,6 +30,10 @@ M.config = function() return end lvim.builtin.cmp = { + confirm_opts = { + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }, formatting = { format = function(entry, vim_item) local icons = require("lsp.kind").icons @@ -107,10 +111,15 @@ M.config = function() [""] = cmp.mapping.complete(), [""] = cmp.mapping.close(), - [""] = cmp.mapping.confirm { - behavior = cmp.ConfirmBehavior.Replace, - select = true, - }, + [""] = cmp.mapping(function(fallback) + if not require("cmp").confirm(lvim.builtin.cmp.confirm_opts) then + if luasnip.jumpable() then + vim.fn.feedkeys(T "luasnip-jump-next", "") + else + fallback() + end + end + end), }, } end -- cgit v1.2.3 From d01ba08eaec1640ac2d038893525b3ba0af25813 Mon Sep 17 00:00:00 2001 From: kylo252 <59826753+kylo252@users.noreply.github.com> Date: Sun, 3 Oct 2021 16:13:46 +0200 Subject: refactor: auto-generate language configuration (#1584) Refactor the monolithic `lvim.lang` design into a more modular approach. IMPORTANT: run `:LvimUpdate` in order to generate the new ftplugin template files. --- lua/core/cmp.lua | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'lua/core/cmp.lua') diff --git a/lua/core/cmp.lua b/lua/core/cmp.lua index 2bc724fb..965285c7 100644 --- a/lua/core/cmp.lua +++ b/lua/core/cmp.lua @@ -35,9 +35,35 @@ M.config = function() select = true, }, formatting = { + 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 = " ", + }, format = function(entry, vim_item) - local icons = require("lsp.kind").icons - vim_item.kind = icons[vim_item.kind] + vim_item.kind = lvim.builtin.cmp.formatting.kind_icons[vim_item.kind] vim_item.menu = ({ nvim_lsp = "(LSP)", emoji = "(Emoji)", -- cgit v1.2.3 From 85e7b7804a2c9d6847ff978c82bb3a3ac16d757f Mon Sep 17 00:00:00 2001 From: Abouzar Parvan Date: Fri, 8 Oct 2021 22:24:55 +0330 Subject: fix: don't use the cmp floating window (#1715) --- lua/core/cmp.lua | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lua/core/cmp.lua') diff --git a/lua/core/cmp.lua b/lua/core/cmp.lua index 965285c7..b058bd6a 100644 --- a/lua/core/cmp.lua +++ b/lua/core/cmp.lua @@ -34,6 +34,10 @@ M.config = function() behavior = cmp.ConfirmBehavior.Replace, select = true, }, + experimental = { + ghost_text = false, + native_menu = true, + }, formatting = { kind_icons = { Class = " ", -- cgit v1.2.3 From 82b7a35858479223c1e34bea2f64451ecf1e5f66 Mon Sep 17 00:00:00 2001 From: Chase Colman <5411+chase@users.noreply.github.com> Date: Sun, 10 Oct 2021 02:47:01 +0800 Subject: fix(cmp/autopairs): prevent out of bounds jump and re-enable jump after confirm (#1708) --- lua/core/cmp.lua | 128 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 113 insertions(+), 15 deletions(-) (limited to 'lua/core/cmp.lua') diff --git a/lua/core/cmp.lua b/lua/core/cmp.lua index b058bd6a..d5d92314 100644 --- a/lua/core/cmp.lua +++ b/lua/core/cmp.lua @@ -29,14 +29,106 @@ M.config = function() if not status_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 + lvim.builtin.cmp = { confirm_opts = { behavior = cmp.ConfirmBehavior.Replace, - select = true, + select = false, }, experimental = { - ghost_text = false, - native_menu = true, + ghost_text = true, + native_menu = false, }, formatting = { kind_icons = { @@ -111,10 +203,12 @@ M.config = function() [""] = cmp.mapping.scroll_docs(4), -- TODO: potentially fix emmet nonsense [""] = cmp.mapping(function() - if vim.fn.pumvisible() == 1 then - vim.fn.feedkeys(T "", "n") - elseif luasnip.expand_or_jumpable() then - vim.fn.feedkeys(T "luasnip-expand-or-jump", "") + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.expandable() then + luasnip.expand() + elseif inside_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable() then + luasnip.jump(1) elseif check_backspace() then vim.fn.feedkeys(T "", "n") elseif is_emmet_active() then @@ -127,10 +221,10 @@ M.config = function() "s", }), [""] = cmp.mapping(function(fallback) - if vim.fn.pumvisible() == 1 then - vim.fn.feedkeys(T "", "n") - elseif luasnip.jumpable(-1) then - vim.fn.feedkeys(T "luasnip-jump-prev", "") + if cmp.visible() then + cmp.select_prev_item() + elseif inside_snippet() and luasnip.jumpable(-1) then + luasnip.jump(-1) else fallback() end @@ -142,12 +236,16 @@ M.config = function() [""] = cmp.mapping.complete(), [""] = cmp.mapping.close(), [""] = cmp.mapping(function(fallback) - if not require("cmp").confirm(lvim.builtin.cmp.confirm_opts) then - if luasnip.jumpable() then - vim.fn.feedkeys(T "luasnip-jump-next", "") - else + if cmp.visible() and cmp.confirm(lvim.builtin.cmp.confirm_opts) then + return + end + + if inside_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable() then + if not luasnip.jump(1) then fallback() end + else + fallback() end end), }, -- cgit v1.2.3