From 8003f152422820fd401921a440bdcce5ebf0abc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20B=C3=B6hme?= Date: Thu, 1 Feb 2024 12:33:35 +0100 Subject: [PATCH 1/5] feat(nvim): add cmp spell and signature plugins --- modules/programs/nvim/plugins/coding.nix | 2 ++ modules/programs/nvim/plugins/lua/nvim-cmp.lua | 2 ++ 2 files changed, 4 insertions(+) diff --git a/modules/programs/nvim/plugins/coding.nix b/modules/programs/nvim/plugins/coding.nix index 358f578..c38452c 100644 --- a/modules/programs/nvim/plugins/coding.nix +++ b/modules/programs/nvim/plugins/coding.nix @@ -83,6 +83,8 @@ with builtins; { plugin = cmp-cmdline; } { plugin = cmp-nvim-lsp; } { plugin = cmp_luasnip; } + { plugin = cmp-spell; } + { plugin = cmp-nvim-lsp-signature-help; } { plugin = copilot-cmp; opts = { }; diff --git a/modules/programs/nvim/plugins/lua/nvim-cmp.lua b/modules/programs/nvim/plugins/lua/nvim-cmp.lua index abe86bb..2c2d075 100644 --- a/modules/programs/nvim/plugins/lua/nvim-cmp.lua +++ b/modules/programs/nvim/plugins/lua/nvim-cmp.lua @@ -55,9 +55,11 @@ cmp.setup({ sources = { { name = "async_path", priority = 1 }, { name = "buffer", priority = 1 }, + { name = "spell", priority = 1 }, { name = "luasnip", priority = 2 }, { name = "copilot", priority = 3 }, { name = "nvim_lsp", priority = 3 }, + { name = "nvim_lsp_signature_help", priority = 3 }, }, }) From 659e719c47a5ec9a9090ef72e07989583b976d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20B=C3=B6hme?= Date: Thu, 1 Feb 2024 12:40:39 +0100 Subject: [PATCH 2/5] feat(fish)!: enable transient starship prompt --- modules/profiles/base.nix | 2 +- modules/programs/fish.nix | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/profiles/base.nix b/modules/profiles/base.nix index f7abc2e..6ebdd46 100644 --- a/modules/profiles/base.nix +++ b/modules/profiles/base.nix @@ -172,7 +172,6 @@ in programs = { mtr.enable = true; - starship.enable = true; command-not-found.enable = false; }; @@ -207,6 +206,7 @@ in "--cmd c" ]; }; + starship.enable = true; }; home = { username = "moritz"; diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index c29dd7c..8934508 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -114,6 +114,7 @@ in ''; }; }; + starship.enableTransience = true; }; }; }; From e87d0c7ec30f4c87e6e8acc010fbb020cefe5531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20B=C3=B6hme?= Date: Sat, 10 Feb 2024 18:22:09 +0100 Subject: [PATCH 3/5] feat(nvim): add luasnip snippets --- modules/programs/nvim/default.nix | 5 + modules/programs/nvim/plugins/coding.nix | 22 +- modules/programs/nvim/plugins/lua/luasnip.lua | 24 +++ .../programs/nvim/plugins/lua/nvim-cmp.lua | 58 +++--- .../programs/nvim/plugins/snippets/python.lua | 194 ++++++++++++++++++ 5 files changed, 260 insertions(+), 43 deletions(-) create mode 100644 modules/programs/nvim/plugins/lua/luasnip.lua create mode 100644 modules/programs/nvim/plugins/snippets/python.lua diff --git a/modules/programs/nvim/default.nix b/modules/programs/nvim/default.nix index 721b184..6d30aaf 100644 --- a/modules/programs/nvim/default.nix +++ b/modules/programs/nvim/default.nix @@ -19,6 +19,11 @@ in ) ]; + xdg.configFile."nvim/snippets" = { + recursive = true; + source = ./plugins/snippets; + }; + programs.neovim = { enable = true; package = inputs.neovim-nightly-overlay.packages.${pkgs.system}.default; diff --git a/modules/programs/nvim/plugins/coding.nix b/modules/programs/nvim/plugins/coding.nix index c38452c..0cff981 100644 --- a/modules/programs/nvim/plugins/coding.nix +++ b/modules/programs/nvim/plugins/coding.nix @@ -85,26 +85,12 @@ with builtins; { plugin = cmp_luasnip; } { plugin = cmp-spell; } { plugin = cmp-nvim-lsp-signature-help; } - { - plugin = copilot-cmp; - opts = { }; - dependencies = [ - { - plugin = copilot-lua; - opts = { - suggestion = { enabled = false; }; - panel = { enabled = false; }; - }; - conf = /* lua */ '' - require("copilot").setup(opts) - vim.cmd("Copilot disable") - ''; - } - ]; - } { plugin = friendly-snippets; } { plugin = lspkind-nvim; } - { plugin = luasnip; } + { + plugin = luasnip; + conf = readFile ./lua/luasnip.lua; + } ]; } { diff --git a/modules/programs/nvim/plugins/lua/luasnip.lua b/modules/programs/nvim/plugins/lua/luasnip.lua new file mode 100644 index 0000000..c391b09 --- /dev/null +++ b/modules/programs/nvim/plugins/lua/luasnip.lua @@ -0,0 +1,24 @@ +local ls = require("luasnip") +local types = require("luasnip.util.types") + +-- Every unspecified option will be set to the default. +ls.setup({ + history = true, + + -- Update more often, :h events for more info. + update_events = "TextChanged,TextChangedI", + -- Snippets aren't automatically removed if their text is deleted. + -- `delete_check_events` determines on which events (:h events) a check for + -- deleted snippets is performed. + -- This can be especially useful when `history` is enabled. + delete_check_events = "TextChanged", + ext_opts = { + [types.choiceNode] = { + active = { + virt_text = { { "<--", "Error" } }, + }, + }, + }, +}) + +require("luasnip.loaders.from_lua").load({ paths = "~/.config/nvim/snippets" }) diff --git a/modules/programs/nvim/plugins/lua/nvim-cmp.lua b/modules/programs/nvim/plugins/lua/nvim-cmp.lua index 2c2d075..4b9c067 100644 --- a/modules/programs/nvim/plugins/lua/nvim-cmp.lua +++ b/modules/programs/nvim/plugins/lua/nvim-cmp.lua @@ -2,23 +2,12 @@ local cmp = require("cmp") local luasnip = require("luasnip") require("luasnip.loaders.from_vscode").lazy_load() -local has_words_before = function() - if vim.api.nvim_buf_get_option(0, "buftype") == "prompt" then - return false - end - 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 - cmp.setup({ formatting = { format = require("lspkind").cmp_format({ mode = "symbol", -- show only symbol annotations maxwidth = 50, -- prevent the popup from showing more than provided characters ellipsis_char = "...", -- when popup menu exceed maxwidth, the truncated part would show ellipsis_char instead - symbol_map = { - Copilot = "", - }, }), }, snippet = { @@ -31,36 +20,55 @@ cmp.setup({ [""] = cmp.mapping.scroll_docs(-4), [""] = cmp.mapping.scroll_docs(4), [""] = cmp.mapping.complete(), - [""] = cmp.mapping.abort(), + [""] = cmp.mapping.abort(), [""] = cmp.mapping.confirm({ select = true }), [""] = cmp.mapping(function(fallback) - if cmp.visible() and has_words_before() then + if luasnip.jumpable(1) then + luasnip.jump(1) + elseif cmp.visible() then cmp.select_next_item({ behavior = cmp.SelectBehavior.Select }) - elseif luasnip.expand_or_jumpable() then - luasnip.expand_or_jump() else fallback() end end, { "i", "s" }), [""] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_prev_item() - elseif luasnip.jumpable(-1) then + if luasnip.jumpable(-1) then luasnip.jump(-1) + elseif cmp.visible() then + cmp.select_prev_item({ behavior = cmp.SelectBehavior.Select }) + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if luasnip.choice_active() then + luasnip.change_choice(1) + elseif cmp.visible() then + cmp.select_next_item({ behavior = cmp.SelectBehavior.Select }) + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if luasnip.choice_active() then + luasnip.change_choice(-1) + elseif cmp.visible() then + cmp.select_prev_item({ behavior = cmp.SelectBehavior.Select }) else fallback() end end, { "i", "s" }), }), - sources = { + sources = cmp.config.sources({ { name = "async_path", priority = 1 }, - { name = "buffer", priority = 1 }, - { name = "spell", priority = 1 }, - { name = "luasnip", priority = 2 }, - { name = "copilot", priority = 3 }, - { name = "nvim_lsp", priority = 3 }, + { name = "nvim_lsp", priority = 2 }, { name = "nvim_lsp_signature_help", priority = 3 }, - }, + { name = "luasnip", priority = 4 }, + }, { + { name = "async_path" }, + { name = "buffer" }, + { name = "spell" }, + }), }) -- Set configuration for specific filetype. diff --git a/modules/programs/nvim/plugins/snippets/python.lua b/modules/programs/nvim/plugins/snippets/python.lua new file mode 100644 index 0000000..f370ef4 --- /dev/null +++ b/modules/programs/nvim/plugins/snippets/python.lua @@ -0,0 +1,194 @@ +local ls = require("luasnip") +local s = ls.snippet +local sn = ls.snippet_node +local isn = ls.indent_snippet_node +local t = ls.text_node +local i = ls.insert_node +local f = ls.function_node +local c = ls.choice_node +local d = ls.dynamic_node +local r = ls.restore_node +local events = require("luasnip.util.events") +local ai = require("luasnip.nodes.absolute_indexer") +local extras = require("luasnip.extras") +local l = extras.lambda +local rep = extras.rep +local p = extras.partial +local m = extras.match +local n = extras.nonempty +local dl = extras.dynamic_lambda +local fmt = require("luasnip.extras.fmt").fmt +local fmta = require("luasnip.extras.fmt").fmta +local conds = require("luasnip.extras.expand_conditions") +local postfix = require("luasnip.extras.postfix").postfix +local types = require("luasnip.util.types") +local parse = require("luasnip.util.parser").parse_snippet +local ms = ls.multi_snippet +local k = require("luasnip.nodes.key_indexer").new_key + +local arg_template = [[ + {arg}: {type} +]] + +local function pyarg() + return sn( + nil, + fmt(arg_template, { + arg = i(1, "arg"), + type = i(2, "Any"), + }) + ) +end + +local function pyargs(_, _, _, user_args) + local choices = { + sn(nil, i(1)), + sn(nil, { + not user_args and t(", ") or t(""), + d(1, pyarg), + d(2, pyargs, { user_args = { false } }), + }), + } + -- switch order for first call + if user_args then + local fst, snd = unpack(choices) + choices = { snd, fst } + end + + return sn(nil, c(1, choices)) +end + +local def_template = [[ +def {fname}({args}) -> {rtype}: + """ + {docs} + """ + {final} +]] + +local def = s( + "def", + fmt(def_template, { + fname = i(1, "fname"), + args = d(2, pyargs, nil, { user_args = { true } }), + rtype = i(3, "None"), + docs = i(4, "Documentation"), + final = i(5, "pass"), + }, { priority = 1001 }) +) + +local defs_template = [[ +def {mname}(self, {args}) -> {rtype}: + """ + {docs} + """ + {final} +]] + +local defs = s( + "defs", + fmt(defs_template, { + mname = i(1, "mname"), + args = d(2, pyargs, nil, { user_args = { true } }), + rtype = i(3, "None"), + docs = i(4, "Documentation"), + final = i(5, "pass"), + }, { priority = 1001 }) +) + +local enum_template = [[ +for {i}, {value} in enumerate({iter}): + {final} +]] + +local dot_enum = postfix(".enum", { + d(1, function(_, parent) + return sn( + 1, + fmt(enum_template, { + i = i(1, "i"), + value = i(2, "value"), + iter = t(parent.env.POSTFIX_MATCH), + final = i(3, "pass"), + }) + ) + end), +}) + +local enum = s( + "enum", + fmt(enum_template, { + i = i(1, "i"), + value = i(2, "value"), + iter = i(3, "iter"), + final = i(4, "pass"), + }) +) + +local for_template = [[ +for {item} in {iter}: + {final} +]] + +local dot_for = postfix(".for", { + d(1, function(_, parent) + return sn( + 1, + fmt(for_template, { + item = i(1, "item"), + iter = t(parent.env.POSTFIX_MATCH), + final = i(2, "pass"), + }) + ) + end), +}) + +local items_template = [[ +for {key}, {value} in {iter}: + {final} +]] + +local dot_items = postfix(".items", { + d(1, function(_, parent) + return sn( + 1, + fmt(items_template, { + key = i(1, "key"), + value = i(2, "value"), + iter = t(parent.env.POSTFIX_MATCH), + final = i(3, "pass"), + }) + ) + end), +}) + +local try_template = [[ +try: + {raises} +except {exception} as {ename}: + {final} +]] + +local dot_try = postfix(".try", { + d(1, function(_, parent) + return sn( + 1, + fmt(try_template, { + raises = t(parent.env.POSTFIX_MATCH), + exception = i(1, "Exception"), + ename = i(2, "e"), + final = i(3, "pass"), + }) + ) + end), +}) + +return { + def, + defs, + dot_enum, + dot_for, + dot_items, + dot_try, + enum, +} From 96697c684cd1980e8a4cfd746e053b605645e49d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20B=C3=B6hme?= Date: Sun, 11 Feb 2024 21:13:50 +0100 Subject: [PATCH 4/5] feat(nvim): improve cmp + luasnip keybinds --- .../programs/nvim/plugins/lua/nvim-cmp.lua | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/modules/programs/nvim/plugins/lua/nvim-cmp.lua b/modules/programs/nvim/plugins/lua/nvim-cmp.lua index 4b9c067..19d9ffe 100644 --- a/modules/programs/nvim/plugins/lua/nvim-cmp.lua +++ b/modules/programs/nvim/plugins/lua/nvim-cmp.lua @@ -10,6 +10,9 @@ cmp.setup({ ellipsis_char = "...", -- when popup menu exceed maxwidth, the truncated part would show ellipsis_char instead }), }, + enabled = function() + return not luasnip.jumpable(1) + end, snippet = { -- REQUIRED - you must specify a snippet engine expand = function(args) @@ -23,19 +26,19 @@ cmp.setup({ [""] = cmp.mapping.abort(), [""] = cmp.mapping.confirm({ select = true }), [""] = cmp.mapping(function(fallback) - if luasnip.jumpable(1) then - luasnip.jump(1) - elseif cmp.visible() then + if cmp.visible() then cmp.select_next_item({ behavior = cmp.SelectBehavior.Select }) + elseif luasnip.jumpable(1) then + luasnip.jump(1) else fallback() end end, { "i", "s" }), [""] = cmp.mapping(function(fallback) - if luasnip.jumpable(-1) then - luasnip.jump(-1) - elseif cmp.visible() then + if cmp.visible() then cmp.select_prev_item({ behavior = cmp.SelectBehavior.Select }) + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) else fallback() end @@ -43,8 +46,6 @@ cmp.setup({ [""] = cmp.mapping(function(fallback) if luasnip.choice_active() then luasnip.change_choice(1) - elseif cmp.visible() then - cmp.select_next_item({ behavior = cmp.SelectBehavior.Select }) else fallback() end @@ -52,8 +53,6 @@ cmp.setup({ [""] = cmp.mapping(function(fallback) if luasnip.choice_active() then luasnip.change_choice(-1) - elseif cmp.visible() then - cmp.select_prev_item({ behavior = cmp.SelectBehavior.Select }) else fallback() end From a14f999ab9c839516de431ca2b8e82413a7c4dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20B=C3=B6hme?= Date: Sun, 11 Feb 2024 21:14:21 +0100 Subject: [PATCH 5/5] feat(nvim): add python snippets --- .../programs/nvim/plugins/snippets/python.lua | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/modules/programs/nvim/plugins/snippets/python.lua b/modules/programs/nvim/plugins/snippets/python.lua index f370ef4..6453645 100644 --- a/modules/programs/nvim/plugins/snippets/python.lua +++ b/modules/programs/nvim/plugins/snippets/python.lua @@ -183,6 +183,51 @@ local dot_try = postfix(".try", { end), }) +local parr = s( + "parr", + fmt( + [[ + :param {name}: {description} + :type {name}: {type} + ]], + { + name = i(1, "name"), + description = i(2, "description"), + type = i(3, "type"), + }, + { + repeat_duplicates = true, + } + ) +) + +local retr = s( + "retr", + fmt( + [[ + :return: {description} + :rtype: {rtype} + ]], + { + description = i(1, "description"), + rtype = i(2, "rtype"), + } + ) +) + +local raisr = s( + "raisr", + fmt( + [[ + :raises {exception}: {description} + ]], + { + exception = i(1, "Exception"), + description = i(2, "description"), + } + ) +) + return { def, defs, @@ -191,4 +236,7 @@ return { dot_items, dot_try, enum, + parr, + retr, + raisr, }