diff --git a/nvim/lua/darcula/autocmds.lua b/nvim/lua/darcula/autocmds.lua index cb48895..f9e719c 100644 --- a/nvim/lua/darcula/autocmds.lua +++ b/nvim/lua/darcula/autocmds.lua @@ -128,36 +128,6 @@ utils.autocmd( end ) -if not NV_DARCULA_ENABLE_COC then - utils.autocmd( - group, - "User", - { - "MiniCompletionWindowOpen", - "MiniCompletionWindowUpdate" - }, - function(args) - local data = args.data - if not data or not data.win_id then - return - end - - if data.kind ~= "info" and data.kind ~= "signature" then - return - end - - if vim.api.nvim_win_is_valid(data.win_id) then - vim.api.nvim_win_set_config( - data.win_id, - { - title = "" - } - ) - end - end - ) -end - utils.autocmd( group, "BufEnter", diff --git a/nvim/lua/darcula/keymaps.lua b/nvim/lua/darcula/keymaps.lua index fcc61d0..0a24855 100644 --- a/nvim/lua/darcula/keymaps.lua +++ b/nvim/lua/darcula/keymaps.lua @@ -615,6 +615,14 @@ if not NV_DARCULA_ENABLE_COC then vim.lsp.buf.signature_help({border = "rounded", max_width = 120}) end ) + + km.set( + {"i", "n"}, + "", + function() + vim.lsp.buf.signature_help({border = "rounded", max_width = 120}) + end + ) end end @@ -668,48 +676,6 @@ if not NV_DARCULA_ENABLE_COC then end end -function M.mini() - if not NV_DARCULA_ENABLE_COC then - local map_multistep = require("mini.keymap").map_multistep - - map_multistep( - "i", - "", - { - "minisnippets_next", - "minisnippets_expand", - "pmenu_next" - } - ) - - map_multistep( - "i", - "", - { - "minisnippets_prev", - "pmenu_prev" - } - ) - - map_multistep( - "i", - "", - { - "pmenu_accept", - "minipairs_cr" - } - ) - - map_multistep( - "i", - "", - { - "minipairs_bs" - } - ) - end -end - function M.navigation() km.nmap( "", @@ -1441,7 +1407,6 @@ end if not NV_DARCULA_ENABLE_COC then M.mason() end - M.mini() M.navigation() M.nvim_dap() M.nvim_haven() diff --git a/nvim/lua/darcula/plugins.lua b/nvim/lua/darcula/plugins.lua index 1635a67..f934904 100644 --- a/nvim/lua/darcula/plugins.lua +++ b/nvim/lua/darcula/plugins.lua @@ -70,12 +70,20 @@ else vim.list_extend( packages, { + {src = "https://github.com/hrsh7th/nvim-cmp"}, + {src = "https://github.com/hrsh7th/cmp-buffer"}, + {src = "https://github.com/hrsh7th/cmp-calc"}, + {src = "https://github.com/abeldekat/cmp-mini-snippets"}, + {src = "https://github.com/hrsh7th/cmp-nvim-lsp"}, + {src = "https://github.com/hrsh7th/cmp-path"}, + {src = "https://github.com/rafamadriz/friendly-snippets"}, {src = "https://github.com/neovim/nvim-lspconfig"}, {src = "https://github.com/WhoIsSethDaniel/mason-tool-installer.nvim"}, {src = "https://github.com/akinsho/flutter-tools.nvim"}, {src = "https://github.com/kosayoda/nvim-lightbulb"}, {src = "https://github.com/mason-org/mason-lspconfig.nvim"}, - {src = "https://github.com/mason-org/mason.nvim"} + {src = "https://github.com/mason-org/mason.nvim"}, + {src = "https://github.com/ray-x/lsp_signature.nvim"} } ) end diff --git a/nvim/lua/darcula/setup/100_mason.lua b/nvim/lua/darcula/setup/100_mason.lua index 64b2e15..e6d6522 100644 --- a/nvim/lua/darcula/setup/100_mason.lua +++ b/nvim/lua/darcula/setup/100_mason.lua @@ -49,7 +49,7 @@ require("mason-tool-installer").setup { vim.lsp.config( "*", { - capabilities = require("mini.completion").get_lsp_capabilities() + capabilities = require("cmp_nvim_lsp").default_capabilities() } ) @@ -71,7 +71,7 @@ for _, name in pairs(NV_DARCULA_MASON_LSP_LIST) do settings = { Lua = { completion = { - callSnippet = "Both", + callSnippet = "Replace", keywordSnippet = "Both" }, diagnostics = {globals = NV_DARCULA_LUA_GLOBALS}, diff --git a/nvim/lua/darcula/setup/400_mini_completion.lua b/nvim/lua/darcula/setup/400_lsp_signature.lua similarity index 59% rename from nvim/lua/darcula/setup/400_mini_completion.lua rename to nvim/lua/darcula/setup/400_lsp_signature.lua index 63aad39..065e575 100644 --- a/nvim/lua/darcula/setup/400_mini_completion.lua +++ b/nvim/lua/darcula/setup/400_lsp_signature.lua @@ -3,7 +3,7 @@ -- Copyright © 2026 Scott E. Graves -- -- Permission is hereby granted, free of charge, to any person obtaining a copy of this software --- and associated documentation files (the “Software”), to deal in the Software without restriction, +-- and associated documentation files (the "Software"), to deal in the Software without restriction, -- including without limitation the rights to use, copy, modify, merge, publish, distribute, -- sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -- furnished to do so, subject to the following conditions: @@ -11,7 +11,7 @@ -- The above copyright notice and this permission notice shall be included in all copies or -- substantial portions of the Software. -- --- THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -- BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, @@ -21,21 +21,25 @@ if NV_DARCULA_ENABLE_COC then return end -require("mini.completion").setup { - delay = {completion = 100, info = 100, signature = 50}, - window = { - info = {height = 25, width = 120, border = "rounded"}, - signature = {height = 25, width = 120, border = "rounded"} - }, - lsp_completion = { - auto_setup = true, - source_func = "omnifunc" - }, - fallback_action = "", - mappings = { - force_twostep = "", - force_fallback = "", - scroll_down = "", - scroll_up = "" +require("lsp_signature").setup( + { + always_trigger = true, + auto_close_after = nil, + bind = true, + close_timeout = 4000, + doc_lines = 10, + fix_pos = true, + floating_window = true, + floating_window_above_cur_line = true, + handler_opts = { + border = "rounded" + }, + hi_parameter = "LspSignatureActiveParameter", + hint_enable = false, + max_height = 25, + max_width = 120, + padding = "", + timer_interval = 50, + wrap = true } -} +) diff --git a/nvim/lua/darcula/setup/400_nvim_cmp.lua b/nvim/lua/darcula/setup/400_nvim_cmp.lua new file mode 100644 index 0000000..34f9e9a --- /dev/null +++ b/nvim/lua/darcula/setup/400_nvim_cmp.lua @@ -0,0 +1,252 @@ +-- The MIT License (MIT) +-- +-- Copyright © 2026 Scott E. Graves +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy of this software +-- and associated documentation files (the "Software"), to deal in the Software without restriction, +-- including without limitation the rights to use, copy, modify, merge, publish, distribute, +-- sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +-- furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in all copies or +-- substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +-- BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +-- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-- +if NV_DARCULA_ENABLE_COC then + return +end + +local cmp = require("cmp") + +local has_words_before = function() + local line, col = unpack(vim.api.nvim_win_get_cursor(0)) + return + col ~= 0 and + vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match( + "%s" + ) == nil +end + +local can_expand_snippet = function() + return + _G.MiniSnippets ~= nil and + #MiniSnippets.expand({insert = false}) > 0 +end + +local has_snippet_session = function() + return + _G.MiniSnippets ~= nil and MiniSnippets.session.get() ~= nil +end + +local expand_snippet = function(args) + local insert = + MiniSnippets.config.expand.insert or MiniSnippets.default_insert + insert({body = args.body}) + cmp.resubscribe({"TextChangedI", "TextChangedP"}) + require("cmp.config").set_onetime({sources = {}}) +end + +local source_labels = { + buffer = "[Buffer]", + calc = "[Calc]", + mini_snippets = "[Snippet]", + nvim_lsp = "[LSP]", + path = "[Path]" +} + +local kind_highlights = { + Constant = "CocSymbolConstant", + Constructor = "CocSymbolConstructor", + Function = "CocSymbolFunction", + Method = "CocSymbolMethod" +} + +local format_item = function(entry, item) + local kind = item.kind + local icon, icon_hl = MiniIcons.get("lsp", kind) + local menu = item.menu or "" + local source = source_labels[entry.source.name] or ("[" .. entry.source.name .. "]") + + item.kind = icon .. " " .. kind + item.kind_hl_group = kind_highlights[kind] or icon_hl + item.menu = menu == "" and source or (menu .. " " .. source) + + return item +end + +local bordered_window = function(opts) + local window_opts = + vim.tbl_extend( + "force", + { + border = "rounded", + winblend = 0, + winhighlight = + "Normal:Pmenu,FloatBorder:FloatBorder,CursorLine:PmenuSel,Search:PmenuMatch" + }, + opts or {} + ) + return + vim.tbl_extend( + "force", + cmp.config.window.bordered(window_opts), + window_opts + ) +end + +cmp.setup( + { + completion = { + completeopt = "menu,menuone,noselect", + keyword_length = 1 + }, + confirmation = { + get_commit_characters = function() + return {} + end + }, + experimental = { + ghost_text = + NV_DARCULA_ENABLE_VIRTUAL_TEXT and + {hl_group = "DiagnosticVirtualTextInfo"} or + false + }, + formatting = { + expandable_indicator = true, + fields = {"abbr", "menu", "kind"}, + format = format_item + }, + mapping = { + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.abort(), + [""] = cmp.mapping.scroll_docs(4), + [""] = + cmp.mapping( + function(fallback) + if not cmp.visible() then + fallback() + return + end + + if cmp.get_active_entry() == nil then + cmp.abort() + return + end + + cmp.confirm( + { + behavior = cmp.ConfirmBehavior.Replace, + select = false + } + ) + end, + {"i", "s"} + ), + [""] = + cmp.mapping( + function(fallback) + if cmp.visible() then + cmp.select_prev_item({behavior = cmp.SelectBehavior.Insert}) + return + end + + if has_snippet_session() then + MiniSnippets.session.jump("prev") + return + end + + fallback() + end, + {"i", "s"} + ), + [""] = + cmp.mapping( + function(fallback) + if cmp.visible() then + cmp.select_next_item({behavior = cmp.SelectBehavior.Insert}) + return + end + + if can_expand_snippet() then + vim.schedule(MiniSnippets.expand) + return + end + + if has_snippet_session() then + MiniSnippets.session.jump("next") + return + end + + if has_words_before() then + cmp.complete() + return + end + + fallback() + end, + {"i", "s"} + ) + }, + matching = { + disallow_fuzzy_matching = false, + disallow_fullfuzzy_matching = false, + disallow_partial_fuzzy_matching = false, + disallow_partial_matching = false, + disallow_prefix_unmatching = false + }, + performance = { + max_view_entries = 256 + }, + preselect = cmp.PreselectMode.None, + snippet = { + expand = expand_snippet + }, + sources = + cmp.config.sources( + { + {name = "nvim_lsp", priority = 1000}, + {name = "mini_snippets", priority = 900}, + {name = "path", priority = 800}, + {name = "calc", priority = 700} + }, + { + { + name = "buffer", + priority = 500, + option = { + get_bufnrs = function() + return + vim.tbl_filter( + vim.api.nvim_buf_is_loaded, + vim.api.nvim_list_bufs() + ) + end + } + } + } + ), + view = { + docs = { + auto_open = true + }, + entries = { + selection_order = "top_down" + } + }, + window = { + completion = bordered_window(), + documentation = + bordered_window( + { + max_height = 25, + max_width = 120 + } + ) + } + } +)