diff --git a/modules/programs/nvim/default.nix b/modules/programs/nvim/default.nix index f358ba5..208c58b 100644 --- a/modules/programs/nvim/default.nix +++ b/modules/programs/nvim/default.nix @@ -22,12 +22,6 @@ in ]; # programs.neovim = { - # enable = true; - # package = inputs.neovim-nightly-overlay.packages.${pkgs.system}.default; - # vimAlias = true; - # vimdiffAlias = true; - # withNodeJs = true; - # withPython3 = true; # extraPackages = with pkgs; # [ # alejandra @@ -49,263 +43,327 @@ in # taplo # yamllint # ]; - # extraLuaConfig = readFile ./options.lua; - # lazy.enable = true; # }; - programs.nixvim = { - enable = true; - package = inputs.neovim-nightly-overlay.packages.${pkgs.system}.default; - vimAlias = true; - - colorschemes.catppuccin.enable = true; - colorschemes.catppuccin.settings.flavour = "macchiato"; - - plugins.lualine.enable = true; - - plugins.cmp.autoEnableSources = true; - plugins.cmp.enable = true; - plugins.cmp.settings.sources = [ - { priority = 1; name = "async_path"; } - { priority = 1; name = "buffer"; } - { priority = 2; name = "nvim_lsp"; } - { priority = 3; name = "nvim_lsp_signature_help"; } - { priority = 4; name = "luasnip"; } - { priority = 4; name = "vimtex"; } - ]; - plugins.cmp.settings.mapping = { - __raw = '' - cmp.mapping.preset.insert({ - [''] = cmp.mapping.scroll_docs(-4), - [''] = cmp.mapping.scroll_docs(4), - [''] = cmp.mapping.complete(), - [''] = cmp.mapping.abort(), - [''] = cmp.mapping.confirm({ select = true }), - [""] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_next_item({ behavior = cmp.SelectBehavior.Select }) - elseif require("luasnip").locally_jumpable(1) then - require("luasnip").jump(1) - else - fallback() - end - end, { "i", "s" }), - [""] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_prev_item({ behavior = cmp.SelectBehavior.Select }) - elseif require("luasnip").locally_jumpable(-1) then - require("luasnip").jump(-1) - else - fallback() - end - end, { "i", "s" }), - [""] = cmp.mapping(function(fallback) - if require("luasnip").choice_active() then - require("luasnip").change_choice(1) - elseif require("luasnip").locally_jumpable(1) then - require("luasnip").jump(1) - else - fallback() - end - end, { "i", "s" }), - [""] = cmp.mapping(function(fallback) - if require("luasnip").choice_active() then - require("luasnip").change_choice(-1) - elseif require("luasnip").locally_jumpable(-1) then - require("luasnip").jump(-1) - else - fallback() - end - end, { "i", "s" }), - }) - ''; - }; - - plugins.luasnip.enable = true; - plugins.luasnip.settings = { - history = true; - update_events = "TextChanged,TextChangedI"; - delete_check_events = "TextChanged"; - ext_opts.__raw = ''{ + programs.nixvim = lib.mkMerge [ + { + enable = true; + package = inputs.neovim-nightly-overlay.packages.${pkgs.system}.default; + vimAlias = true; + extraConfigLuaPre = readFile ./options.lua; + performance = { + byteCompileLua = { + enable = true; + configs = true; + initLua = true; + nvimRuntime = true; + plugins = true; + }; + combinePlugins.enable = true; + }; + } + { + colorschemes.catppuccin = { + enable = true; + settings.flavour = "macchiato"; + }; + } + { + plugins.lualine.enable = true; + } + { + plugins.cmp = { + autoEnableSources = true; + enable = true; + settings.sources = [ + { priority = 1; name = "async_path"; } + { priority = 1; name = "buffer"; } + { priority = 2; name = "nvim_lsp"; } + { priority = 3; name = "nvim_lsp_signature_help"; } + { priority = 4; name = "luasnip"; } + { priority = 4; name = "vimtex"; } + ]; + settings.mapping = { + __raw = '' + cmp.mapping.preset.insert({ + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.abort(), + [''] = cmp.mapping.confirm({ select = true }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item({ behavior = cmp.SelectBehavior.Select }) + elseif require("luasnip").locally_jumpable(1) then + require("luasnip").jump(1) + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item({ behavior = cmp.SelectBehavior.Select }) + elseif require("luasnip").locally_jumpable(-1) then + require("luasnip").jump(-1) + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if require("luasnip").choice_active() then + require("luasnip").change_choice(1) + elseif require("luasnip").locally_jumpable(1) then + require("luasnip").jump(1) + else + fallback() + end + end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if require("luasnip").choice_active() then + require("luasnip").change_choice(-1) + elseif require("luasnip").locally_jumpable(-1) then + require("luasnip").jump(-1) + else + fallback() + end + end, { "i", "s" }), + }) + ''; + }; + }; + } + { + plugins.luasnip = { + enable = true; + settings = { + history = true; + update_events = "TextChanged,TextChangedI"; + delete_check_events = "TextChanged"; + ext_opts.__raw = ''{ [require("luasnip.util.types").choiceNode] = { active = { virt_text = { { "<--", "Error" } }, }, }, }''; - ft_func.__raw = ''require("luasnip.extras.filetype_functions").from_pos_or_filetype''; - }; - - plugins.lsp.enable = true; - plugins.lsp.inlayHints = true; - plugins.lsp.servers.nil-ls.enable = true; - plugins.lsp.servers.nixd.enable = true; - plugins.lsp.servers.nixd.extraOptions.settings.nixd = { - nixpkgs = { - expr = "import { }"; - }; - options = { - nixos = { - expr = ''(builtins.getFlake ("git+file://" + toString ./.)).nixosConfigurations.nixos-desktop.options''; - }; - "flake-parts" = { - expr = ''(builtins.getFlake ("git+file://" + toString ./.)).debug.options''; - }; - "flake-parts2" = { - expr = ''(builtins.getFlake ("git+file://" + toString ./.)).currentSystem.options''; + ft_func.__raw = ''require("luasnip.extras.filetype_functions").from_pos_or_filetype''; }; }; - }; - plugins.lspsaga = { - enable = true; - codeAction.keys.quit = ""; - lightbulb.virtualText = false; - }; - keymapsOnEvents = { - LspAttach = [ - { - key = "cc"; - action = "Lspsaga code_action"; - options.desc = "Code Action"; - options.buffer = true; - } - { - key = "gd"; - action = "Lspsaga goto_definition"; - options.desc = "Goto Definition"; - options.buffer = true; - } - { - key = "cr"; - action = "Lspsaga rename"; - options.desc = "Rename"; - options.buffer = true; - } - { - key = "K"; - action = "Lspsaga hover_doc"; - options.desc = "Hover"; - options.buffer = true; - } - ]; - }; - - plugins.nvim-ufo.enable = true; - - plugins.treesitter = { - enable = true; - folding = true; - nixvimInjections = true; - settings.indent.enable = true; - settings.highlight.enable = true; - }; - - plugins.which-key.enable = true; - plugins.lastplace.enable = true; - plugins.comment.enable = true; - plugins.ts-context-commentstring.enable = true; - - plugins.vimtex = { - enable = true; - settings.view_method = "zathura"; - }; - - plugins.todo-comments.enable = true; - plugins.todo-comments.keymaps.todoTelescope.key = "fc"; - - plugins.conform-nvim.enable = true; - plugins.conform-nvim.settings.formatters_by_ft = { - "*" = [ "codespell" "trim_whitespace" ]; - elixir = [ "mix" ]; - gleam = [ "gleam" ]; - go = [ "gofmt" ]; - json = [ "jq" ]; - lua = [ "stylua" ]; - nix = [ [ "nixpkgs_fmt" "alejandra" ] ]; - python = [ [ "ruff_fix" "isort" ] [ "ruff_format" "black" ] ]; - rust = [ "rustfmt" ]; - sh = [ "shfmt" ]; - tex = [ "latexindent" ]; - toml = [ "taplo" ]; - yaml = [ "yamlfix" ]; - }; - - keymaps = [ - { key = ""; action = "noh"; options.desc = "Escape and clear hlsearch"; mode = [ "i" "n" ]; } - ]; - opts.formatexpr = "v:lua.require'conform'.formatexpr()"; - - extraConfigLua = '' - vim.api.nvim_create_user_command("Format", function(opts) - require("conform").format({ formatters = opts.fargs }) - end, { - nargs = "+", - complete = function() - local names = formatters_by_ft[vim.bo.filetype] or formatters_by_ft["_"] or {} - names = vim.list_extend(names, formatters_by_ft["*"] or {}) - names = vim.tbl_flatten(names) - local formatters = vim.tbl_map(require("conform").get_formatter_info, names) - formatters = vim.tbl_filter(function(formatter) - return formatter.available - end, formatters) - return vim.tbl_map(function(formatter_info) - return formatter_info.name - end, formatters) - end, - }) - ''; - - plugins.oil.enable = true; - - plugins.telescope.enable = true; - plugins.telescope.extensions.fzf-native.enable = true; - plugins.telescope.keymaps = { - "ff" = { - action = "find_files"; - options.desc = "Find files"; - }; - "fb" = { - action = "buffers"; - options.desc = "Find buffers"; - }; - "fl" = { - action = "current_buffer_fuzzy_find"; - options.desc = "Search lines"; - }; - "fg" = { - action = "live_grep"; - options.desc = "Live grep"; - }; - "fh" = { - action = "help_tags"; - options.desc = "Help tags"; - }; - "fr" = { - action = "oldfiles"; - options.desc = "Recent files"; - }; - }; - - plugins.nvim-autopairs.enable = true; - - plugins.surround.enable = true; - - extraConfigLuaPre = readFile ./options.lua; - performance = { - byteCompileLua = { + } + { + plugins.lsp = { enable = true; - configs = true; - initLua = true; - nvimRuntime = true; - plugins = true; + inlayHints = true; + servers.nil-ls.enable = true; + servers.nixd.enable = true; + servers.nixd.extraOptions.settings.nixd = { + nixpkgs = { + expr = "import { }"; + }; + options = { + nixos = { + expr = ''(builtins.getFlake ("git+file://" + toString ./.)).nixosConfigurations.nixos-desktop.options''; + }; + "flake-parts" = { + expr = ''(builtins.getFlake ("git+file://" + toString ./.)).debug.options''; + }; + "flake-parts2" = { + expr = ''(builtins.getFlake ("git+file://" + toString ./.)).currentSystem.options''; + }; + }; + }; }; - combinePlugins.enable = true; - combinePlugins.standalonePlugins = [ + } + { + plugins.lspsaga = { + enable = true; + codeAction.keys.quit = ""; + lightbulb.virtualText = false; + }; + keymapsOnEvents = { + LspAttach = [ + { + key = "cc"; + action = "Lspsaga code_action"; + options.desc = "Code Action"; + options.buffer = true; + } + { + key = "gd"; + action = "Lspsaga goto_definition"; + options.desc = "Goto Definition"; + options.buffer = true; + } + { + key = "cr"; + action = "Lspsaga rename"; + options.desc = "Rename"; + options.buffer = true; + } + { + key = "K"; + action = "Lspsaga hover_doc"; + options.desc = "Hover"; + options.buffer = true; + } + ]; + }; + } + { + plugins.nvim-ufo.enable = true; + } + { + plugins.treesitter = { + enable = true; + folding = true; + nixvimInjections = true; + settings.indent.enable = true; + settings.highlight.enable = true; + }; + performance.combinePlugins.standalonePlugins = [ "nvim-treesitter" + ]; + } + { plugins.which-key.enable = true; } + { plugins.lastplace.enable = true; } + { plugins.comment.enable = true; } + { plugins.ts-context-commentstring.enable = true; } + { + plugins.vimtex = { + enable = true; + settings.view_method = "zathura"; + }; + } + { + plugins.todo-comments = { + enable = true; + keymaps.todoTelescope.key = "fc"; + }; + } + { + plugins.conform-nvim = { + enable = true; + settings.formatters_by_ft = { + "*" = [ "codespell" "trim_whitespace" ]; + elixir = [ "mix" ]; + gleam = [ "gleam" ]; + go = [ "gofmt" ]; + json = [ "jq" ]; + lua = [ "stylua" ]; + nix.__raw = ''{ "nixpkgs_fmt", "alejandra", stop_after_first=true }''; + python.__raw = '' + function(bufnr) + return { first("ruff_organize_imports", "isort"), first("ruff_format", "black")} + end + ''; + rust = [ "rustfmt" ]; + sh = [ "shfmt" ]; + tex = [ "latexindent" ]; + toml = [ "taplo" ]; + yaml = [ "yamlfix" ]; + }; + }; + opts.formatexpr = "v:lua.require'conform'.formatexpr()"; + extraConfigLuaPre = '' + ---@param bufnr integer + ---@param ... string + ---@return string + local function first(bufnr, ...) + local conform = require("conform") + for i = 1, select("#", ...) do + local formatter = select(i, ...) + if conform.get_formatter_info(formatter, bufnr).available then + return formatter + end + end + return select(1, ...) + end + + vim.api.nvim_create_user_command("Format", function(opts) + require("conform").format({ formatters = opts.fargs }) + end, { + nargs = "+", + complete = function() + local formatters_by_ft = require("conform").formatters_by_ft + local names = formatters_by_ft[vim.bo.filetype] or formatters_by_ft["_"] or {} + names = vim.list_extend(names, formatters_by_ft["*"] or {}) + names = vim.tbl_flatten(names) + local formatters = vim.tbl_map(require("conform").get_formatter_info, names) + formatters = vim.tbl_filter(function(formatter) + return formatter.available + end, formatters) + return vim.tbl_map(function(formatter_info) + return formatter_info.name + end, formatters) + end, + }) + ''; + performance.combinePlugins.standalonePlugins = [ "conform.nvim" ]; - }; - }; + keymaps = [ + { key = "cf"; action.__raw = ''function() require("conform").format() end''; options.desc = "Format current file"; } + ]; + } + { + keymaps = [ + { key = ""; action = "noh"; options.desc = "Escape and clear hlsearch"; mode = [ "i" "n" ]; } + ]; + } + { plugins.oil.enable = true; } + { + plugins.telescope = { + enable = true; + extensions.fzf-native.enable = true; + keymaps = { + "ff" = { + action = "find_files"; + options.desc = "Find files"; + }; + "fb" = { + action = "buffers"; + options.desc = "Find buffers"; + }; + "fl" = { + action = "current_buffer_fuzzy_find"; + options.desc = "Search lines"; + }; + "fg" = { + action = "live_grep"; + options.desc = "Live grep"; + }; + "fh" = { + action = "help_tags"; + options.desc = "Help tags"; + }; + "fr" = { + action = "oldfiles"; + options.desc = "Recent files"; + }; + }; + }; + } + { plugins.nvim-autopairs.enable = true; } + { plugins.surround.enable = true; } + { + plugins.lint.enable = true; + # TODO: add linters + plugins.lint.lintersByFt = { }; + } + { + plugins.marks.enable = true; + plugins.marks.defaultMappings = false; + } + { + plugins.hmts.enable = true; + performance.combinePlugins.standalonePlugins = [ "hmts.nvim" ]; + } + { plugins.gitsigns.enable = true; } + { plugins.fugitive.enable = true; } + { plugins.friendly-snippets.enable = true; } + { plugins.direnv.enable = true; } + { plugins.crates-nvim.enable = true; } + ]; }; }; } diff --git a/modules/programs/nvim/options.lua b/modules/programs/nvim/options.lua index a6dc719..9ae480b 100644 --- a/modules/programs/nvim/options.lua +++ b/modules/programs/nvim/options.lua @@ -23,7 +23,7 @@ vim.opt.termguicolors = true vim.opt.undofile = true vim.opt.undolevels = 10000 vim.opt.updatetime = 300 -vim.opt.foldlevel = 2 +vim.opt.foldlevel = 99 vim.opt_local.spell = true vim.opt_local.spelllang = { "en", "de_20" } -- all English regions and new German spelling