{ config, pkgs, lib, ... }: { options = { host.nvim.enable-completions = (lib.mkEnableOption "basic completion in nvim") // { default = config.nvim.enable-treesitter || config.nvim.enable-lsp; }; }; config = lib.mkIf config.host.nvim.enable-completions { programs.nixvim = { plugins.luasnip.enable = true; plugins.friendly-snippets.enable = true; plugins.cmp = { enable = true; autoEnableSources = true; settings = { sources = [ {name = "luasnip";} {name = "treesitter";} {name = "path";} {name = "emoji";} {name = "buffer";} {name = "latex_symbols";} {name = "digraphs";} {name = "spell";} ]; snippet = { expand = "function(args) require('luasnip').lsp_expand(args.body) end"; }; mapping = { "" = "cmp.mapping.complete()"; "" = "cmp.mapping.scroll_docs(-4)"; "" = "cmp.mapping.close()"; "" = "cmp.mapping.scroll_docs(4)"; "" = "cmp.mapping.confirm({ select = false })"; "" = '' function(fallback) if cmp.visible() then cmp.select_next_item() elseif require("luasnip").expand_or_jumpable() then vim.fn.feedkeys(vim.api.nvim_replace_termcodes("luasnip-expand-or-jump", true, true, true), "") else fallback() end end ''; "" = '' function(fallback) if cmp.visible() then cmp.select_prev_item() elseif require("luasnip").jumpable(-1) then vim.fn.feedkeys(vim.api.nvim_replace_termcodes("luasnip-jump-prev", true, true, true), "") else fallback() end end ''; }; }; }; }; }; }