From 3add3d06af15c0457075f994e0b4a91289737c74 Mon Sep 17 00:00:00 2001 From: Minijackson Date: Wed, 15 May 2024 22:03:04 +0200 Subject: common/vim: switch to nixvim --- common/default.nix | 1 + common/nixvim.nix | 508 +++++++++++++++++++++++++++++++++++++++++++++++++++++ common/vim.nix | 2 +- 3 files changed, 510 insertions(+), 1 deletion(-) create mode 100644 common/nixvim.nix (limited to 'common') diff --git a/common/default.nix b/common/default.nix index 16093b6..a791e8d 100644 --- a/common/default.nix +++ b/common/default.nix @@ -8,6 +8,7 @@ inputs: (import ./commandline.nix inputs) (import ./localization.nix inputs) (import ./nix.nix inputs) + (import ./nixvim.nix inputs) (import ./ssh.nix inputs) (import ./theme.nix inputs) (import ./tinc.nix inputs) diff --git a/common/nixvim.nix b/common/nixvim.nix new file mode 100644 index 0000000..cfb33bb --- /dev/null +++ b/common/nixvim.nix @@ -0,0 +1,508 @@ +inputs: +{ + config, + lib, + pkgs, + ... +}: + +let + inherit (inputs.nixvim.legacyPackages.x86_64-linux) makeNixvim; +in +{ + options.programs.nixvim = lib.mkOption { + type = lib.types.submodule { + freeformType = lib.types.anything; + config.finalPackage = makeNixvim (builtins.removeAttrs config.programs.nixvim [ "finalPackage" ]); + }; + }; + + config.programs.nixvim = { + # enable = true; + luaLoader.enable = true; + + globals = { + mapleader = ";"; + maplocalleader = ","; + }; + + opts = { + backup = true; + # Use `//` at the end to store the absolute file name + backupdir.__raw = "vim.fn.stdpath('data') .. '/backup//'"; + colorcolumn = "80"; + completeopt = [ + "menu" + "menuone" + "noinsert" + "noselect" + ]; + cursorline = true; + diffopt = [ + "internal" + "filler" + "closeoff" + "linematch:60" + ]; + grepformat = "%f:%l:%c:%m,%f:%l:%m,%f:%l%m,%f %l%m"; + grepprg = "${lib.getExe pkgs.ripgrep} --vim-grep --smart-case"; + ignorecase = true; + inccommand = "split"; + list = true; + listchars = { + extends = ">"; + nbsp = "+"; + precedes = "<"; + tab = " "; + trail = "-"; + }; + scrolloff = 3; + shiftwidth = 4; + shortmess = "ncAxoTOtfFli"; + showmode = false; + sidescrolloff = 5; + smartcase = true; + smartindent = true; + tabstop = 4; + title = true; + undofile = true; + updatetime = 1000; + wildmode = [ + "longest:full" + "full" + ]; + }; + + colorschemes.gruvbox = { + enable = true; + + settings = { + # bold = true; + # italics = true; + # underline = true; + # undercurl = true; + italic.strings = false; + overrides = { + GitSignsAdd.link = "GruvboxGreenSign"; + GitSignsChange.link = "GruvboxOrangeSign"; + GitSignsDelete.link = "GruvboxRedSign"; + IblScope.link = "GruvboxAqua"; + }; + }; + }; + + highlight = { + TSDefinition.link = "GruvboxBlueSign"; + TSDefinitionUsage.link = "GruvboxAquaSign"; + }; + + keymaps = [ + { + key = "fu"; + action = "require('telescope').extensions.undo.undo"; + lua = true; + options = { + silent = true; + desc = "Telescope undo"; + }; + } + + { + key = "-"; + action = "require('oil').open"; + lua = true; + options.desc = "Open parent directory"; + } + + # TODO: add "] " and "[ " + + # Gitsigns + + # TODO: that was not exactly that + # { + # key = "]g"; + # action = "require('gitsigns').next_hunk"; + # lua = true; + # } + + # TODO: noremap? buffer local? silent? + { + key = "gs"; + action = "require('gitsigns').stage_hunk"; + lua = true; + options.desc = "Stage hunk"; + } + + { + key = "gr"; + action = "require('gitsigns').reset_hunk"; + lua = true; + options.desc = "Reset hunk"; + } + + # TODO: visual stage/reset + + { + key = "gS"; + action = "require('gitsigns').stage_buffer"; + lua = true; + options.desc = "Stage buffer"; + } + + { + key = "gR"; + action = "require('gitsigns').reset_buffer"; + lua = true; + options.desc = "Stage buffer"; + } + + { + key = "gu"; + action = "require('gitsigns').undo_stage_hunk"; + lua = true; + options.desc = "Undo stage hunk"; + } + + { + key = "gp"; + action = "require('gitsigns').preview_hunk_inline"; + lua = true; + options.desc = "Preview hunk"; + } + + { + key = "gb"; + action = "function() require('gitsigns').blame_line { full = true } end"; + lua = true; + options.desc = "Blame line"; + } + ]; + + # TODO: + # extraPlugins = with pkgs.unstable.vimPlugins; [ + extraPlugins = with inputs.nixpkgs-unstable.legacyPackages.x86_64-linux.vimPlugins; [ + highlight-undo-nvim + vim-abolish + + # TODO: make that modular + playground + + vim-rhubarb + fugitive-gitlab-vim + ]; + + plugins = { + cmp = { + enable = true; + + settings = { + mapping.__raw = '' + cmp.mapping.preset.insert { + [''] = cmp.mapping.confirm({ select = false }), + + [""] = cmp.mapping(function(fallback) + local luasnip = require("luasnip") + if luasnip.locally_jumpable(1) then + luasnip.jump(1) + else + fallback() + end + end, { "i", "s" }), + + [""] = cmp.mapping(function(fallback) + local luasnip = require("luasnip") + if luasnip.locally_jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { "i", "s" }), + } + ''; + + snippet.expand = '' + function(args) + require('luasnip').lsp_expand(args.body) + end + ''; + + sources = [ + { name = "nvim_lsp"; } + { name = "nvim_lsp_signature_help"; } + { name = "cmp_pandoc"; } + # TODO: make this modular + { name = "crates"; } + { name = "luasnip"; } + { name = "calc"; } + { name = "path"; } + { name = "treesitter"; } + { name = "git"; } + { name = "tmux"; } + { name = "spell"; } + # Use \k for iskeyword because of UTF-8 + { + name = "buffer"; + option.keyword_pattern = ''\k\+''; + } + ]; + }; + }; + # cmp-buffer.enable = true; + # cmp-calc.enable = true; + # cmp-cmdline.enable = true; + # cmp-git.enable = true; + + comment.enable = true; + + dressing.enable = true; + + fidget = { + enable = true; + notification.overrideVimNotify = true; + }; + + # TODO: add xdg-open for :GBrowse? + fugitive.enable = true; + + gitignore.enable = true; + + gitsigns.enable = true; + + indent-blankline = { + enable = true; + settings.indent = { + char = "│"; + tab_char = "│"; + }; + }; + + lastplace.enable = true; + + lualine = { + enable = true; + iconsEnabled = false; + + componentSeparators.left = ""; + componentSeparators.right = ""; + + sectionSeparators.left = ""; + sectionSeparators.right = ""; + }; + + luasnip.enable = true; + + vim-matchup = { + enable = true; + treesitterIntegration.enable = true; + }; + + mini = { + enable = true; + modules = { + ai = { }; + align = { }; + bracketed = { }; + clue = { + triggers = [ + { + mode = "n"; + keys = "["; + } + { + mode = "n"; + keys = "]"; + } + { + mode = "n"; + keys = ""; + } + ]; + }; + surround = { }; + trailspace = { }; + }; + }; + + none-ls = { + enable = true; + sources = { + code_actions = { + gitrebase.enable = true; + gitsigns.enable = true; + # TODO: maybe? + #refactoring.enable = true; + statix.enable = true; + }; + + diagnostics = { + deadnix.enable = true; + statix.enable = true; + vale = { + enable = true; + withArgs = '' + { filetypes = { "markdown", "pandoc", "rst", "tex", "asciidoc" }, } + ''; + }; + }; + + formatting.shfmt.enable = true; + }; + }; + + nvim-osc52 = { + enable = true; + keymaps.enable = true; + }; + + oil.enable = true; + + # TODO: maybe + #refactoring.enable = true; + + spider = { + enable = true; + keymaps.motions = { + b = "b"; + e = "e"; + ge = "ge"; + w = "w"; + }; + }; + + telescope = { + enable = true; + settings = { }; + + extensions.undo.enable = true; + + keymapsSilent = true; + keymaps = { + "fb" = { + action = "buffers"; + options.desc = "Telescope buffers"; + }; + + "ff" = { + action = "find_files"; + options.desc = "Telescope find files"; + }; + + "fg" = { + action = "live_grep"; + options.desc = "Telescope live grep"; + }; + + "fh" = { + action = "help_tags"; + options.desc = "Telescope help tags"; + }; + + "fo" = { + action = "oldfiles"; + options.desc = "Telescope old files"; + }; + + "fs" = { + action = "spell_suggest"; + options.desc = "Telescope spell suggest"; + }; + + "ft" = { + action = "treesitter"; + options.desc = "Telescope treesitter"; + }; + + "fw" = { + action = "git_status"; + options.desc = "Telescope git status"; + }; + }; + }; + + treesitter = { + enable = true; + indent = true; + + incrementalSelection.enable = true; + nixvimInjections = true; + }; + + treesitter-context = { + enable = true; + settings = { + max_lines = 5; + min_window_height = 20; + }; + }; + + treesitter-refactor = { + enable = true; + highlightDefinitions.enable = true; + }; + + treesitter-textobjects = { + enable = true; + lspInterop = { + enable = true; + peekDefinitionCode = { + "df" = { + query = "@function.outer"; + desc = "Peek outer function"; + }; + "dF" = { + query = "@class.outer"; + desc = "Peek outer class"; + }; + }; + }; + select = { + enable = true; + lookahead = true; + # selectionModes = "V"; + keymaps = let + keymap = object: type: { + query = "@${object}.${type}"; + desc = "Select ${type} ${object}"; + }; + in { + "af" = keymap "function" "outer"; + "if" = keymap "function" "inner"; + "aF" = keymap "call" "outer"; + "iF" = keymap "call" "inner"; + "aC" = keymap "comment" "outer"; + "iC" = keymap "comment" "inner"; + "ab" = keymap "block" "outer"; + "ib" = keymap "block" "inner"; + "aa" = keymap "parameter" "outer"; + "ia" = keymap "parameter" "inner"; + }; + }; + }; + }; + + extraConfigLuaPost = '' + vim.api.nvim_create_autocmd("TextYankPost", { + desc = "Highlight yanked text", + callback = function() + vim.highlight.on_yank() + end, + }) + + require('highlight-undo').setup() + + + -- For fugitive's :GBrowse + + vim.api.nvim_create_user_command("Browse", function(opts) + local Job = require('plenary.job') + + Job:new({ + command = 'xdg-open', + args = { opts.args }, + }):start() + end, { nargs = 1 }) + ''; + }; + + config.environment.systemPackages = [config.programs.nixvim.finalPackage]; +} diff --git a/common/vim.nix b/common/vim.nix index 23aa7e9..10a8705 100644 --- a/common/vim.nix +++ b/common/vim.nix @@ -177,7 +177,7 @@ in { }; }; - environment.systemPackages = [myNeovim]; + # environment.systemPackages = [myNeovim]; environment.variables = { EDITOR = "nvim"; -- cgit v1.2.3