From 0352e8e4d33f4ef7f96b19c49b97d0f78bf36024 Mon Sep 17 00:00:00 2001 From: Julia Lange Date: Tue, 16 Apr 2024 04:36:26 -0700 Subject: [PATCH] Neovim, refactor to use modules, lua, and LSP Refactors the neovim config to use nix modules, and changes the plugins to favor the builtin neovim LSP over COC. Changes all code to use lua code instead of vimscript. --- hmModules/apps/neovim/default.nix | 139 ++++++++++---------- hmModules/apps/neovim/init.vim | 68 ---------- hmModules/apps/neovim/options.lua | 57 ++++++++ hmModules/apps/neovim/plugin/lsp.nix | 49 +++++++ hmModules/apps/neovim/plugin/nvimcmp.nix | 72 ++++++++++ hmModules/apps/neovim/plugin/telescope.nix | 40 ++++++ hmModules/apps/neovim/plugin/treesitter.nix | 30 +++++ systems/pan/default.nix | 16 +++ 8 files changed, 337 insertions(+), 134 deletions(-) delete mode 100644 hmModules/apps/neovim/init.vim create mode 100644 hmModules/apps/neovim/options.lua create mode 100644 hmModules/apps/neovim/plugin/lsp.nix create mode 100644 hmModules/apps/neovim/plugin/nvimcmp.nix create mode 100644 hmModules/apps/neovim/plugin/telescope.nix create mode 100644 hmModules/apps/neovim/plugin/treesitter.nix diff --git a/hmModules/apps/neovim/default.nix b/hmModules/apps/neovim/default.nix index e8a805e..91b38c6 100644 --- a/hmModules/apps/neovim/default.nix +++ b/hmModules/apps/neovim/default.nix @@ -3,84 +3,91 @@ { options.neovim = { enable = lib.mkEnableOption "Enables neovim"; + languages = { + nix.enable = lib.mkEnableOption "Enables nix support"; + }; + plugins = { + comments.enable = lib.mkEnableOption "Enables nvim-comment"; + fugitive.enable = lib.mkEnableOption "Enables git-fugitive"; + lualine.enable = lib.mkEnableOption "Enables lualine"; + luasnip.enable = lib.mkEnableOption "Enables luasnip snippets"; + nvimcmp.enable = lib.mkEnableOption "Enables nvim completion"; + telescope = { + enable = lib.mkEnableOption "Enables telescope"; + fzf.enable = lib.mkEnableOption "Enables telescope-fzf"; + }; + treesitter.enable = lib.mkEnableOption "Enables treesitter"; + }; }; + imports = [ + ./plugin/lsp.nix + ./plugin/nvimcmp.nix + ./plugin/telescope.nix + ./plugin/treesitter.nix + ]; + config = lib.mkIf config.neovim.enable { home.sessionVariables = { EDITOR = "nvim"; VISUAL = "nvim"; }; + programs.neovim = { enable = true; - extraConfig = '' - ${builtins.readFile ./init.vim} + viAlias = true; + vimAlias = true; + vimdiffAlias = true; + + extraLuaConfig = '' + ${builtins.readFile ./options.lua} ''; - plugins = with pkgs.vimPlugins; [ - { # Personal Wiki - plugin = vimwiki; - config = '' - let g:vimwiki_list = [{'path': '~/dox/wiki', 'links_space_char': '_', - \ 'ext': '.md', 'syntax': 'markdown'}] - ''; - } - { # NNN in vim - plugin = nnn-vim; - config = '' - let g:nnn#layout = { 'window': { - \ 'width': 0.35, - \ 'height': 0.5, - \ 'xoffset': 1.0, - \ 'highlight': 'Debug' } } " hover window - let g:nnn#action = { - \ '': 'tab split', - \ '': 'split', - \ '': 'vsplit' } - let g:nnn#command = 'nnn -HoeT v' - let g:nnn#replace_netrw = 1 - ''; - } - { # Fuzzy searches - plugin = fzf-vim; - config = '' - map :Files - map :Ag - ''; - } - { # Auto completions - plugin = coc-nvim; - config = '' - function! s:check_back_space() abort - let col = col('.') - 1 - return !col || getline('.')[col - 1] =~# '\s' - endfunction - inoremap - \ pumvisible() ? "\" : - \ check_back_space() ? "\" : - \ coc#refresh() - inoremap pumvisible() ? "\" : "\" - ''; - } - vim-commentary # multi-line comments - vim-fugitive # Git Plugin - vimtex # Latex support - tagbar # File tagging - - # === LOOK AND FEEL === - { # Status Bar - plugin = vim-airline; - config = '' - let g:airline#extensions#tagbar#flags = 'fs' - ''; - } - { # Rainbow Parenthesis - plugin = rainbow; - config = '' - let g:rainbow_actve = 1 - ''; - } - vim-polyglot # Syntax Highlighting + extraPackages = with pkgs; [ + (lib.mkIf config.neovim.languages.nix.enable nil) ]; + + # Additional packages are added through imports + plugins = let + lopts = lib.lists.optionals; + cfgp = config.neovim.plugins; + cfgl = config.neovim.languages; + + comments = lopts cfgp.comments.enable (with pkgs.vimPlugins; [ + { + plugin = comment-nvim; + type = "lua"; + config = "require(\"Comment\").setup()"; + } + ]); + + fugitive = lopts cfgp.fugitive.enable (with pkgs.vimPlugins; [ + vim-fugitive + ]); + + luasnip-pkg = lopts cfgp.luasnip.enable (with pkgs.vimPlugins; [ + luasnip + friendly-snippets + (lib.mkIf cfgp.nvimcmp.enable cmp_luasnip) + ]); + + lualine = lopts cfgp.lualine.enable (with pkgs.vimPlugins; [ + { + plugin = lualine-nvim; + type = "lua"; + config = '' + require("lualine").setup({ + icons_enabled = true, + }) + ''; + } + nvim-web-devicons + ]); + + nix-pkg = lopts cfgl.nix.enable (with pkgs.vimPlugins; [ + vim-nix + ]); + in comments ++ fugitive ++ luasnip-pkg ++ lualine ++ nix-pkg; }; }; } diff --git a/hmModules/apps/neovim/init.vim b/hmModules/apps/neovim/init.vim deleted file mode 100644 index d8b95c9..0000000 --- a/hmModules/apps/neovim/init.vim +++ /dev/null @@ -1,68 +0,0 @@ -syntax on -let mapleader =" " -set encoding=utf-8 -set nocompatible -filetype plugin on -set list - -set updatetime=300 - -" Easy Split Navigation -nnoremap -nnoremap -nnoremap -nnoremap - -" Indentation -" set tabstop=2 softtabstop=0 shiftwidth=2 smarttab expandtab -set tabstop=8 softtabstop=0 shiftwidth=8 - -" Searching -set smartcase - -" Backups -set noswapfile -set nobackup -set undodir=~/.config/nvim/undodir -set undofile - -" Right column at 80 lines for good coding practice. -set colorcolumn=80 -"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" - -" QoL -set showmatch " Show matching Brackets -set number relativenumber " Side numbers - -" Fuzzy finding by allowing searching into subfolders -set path+=** -set wildmenu -" use :find to find, and * to make it fuzzy. -" Also make use of :b. - -" Delete trailing white space and newlines at end of file on save. -autocmd BufWritePre * %s/\s\+$//e -autocmd BufWritePre * %s/\n\+\%$//e - -" Easy copy and pasting to external programs -map "+yy -map "+P - -autocmd BufRead,BufNewFile *.md call WritingMode() -autocmd BufRead,BufNewFile *.tex call WritingMode() -autocmd BufRead,BufNewFile *.svx call WritingMode() - -autocmd BufRead,BufNewFile *.py call PythonMode() - -function! WritingMode() - setlocal textwidth=80 - setlocal wrap linebreak nolist - setlocal whichwrap+=<,>,h,l - nnoremap j gj - nnoremap k gk - setlocal spell spelllang=en_us -endfunction -function! PythonMode() - setlocal foldmethod=indent - setlocal foldlevel=99 -endfunction diff --git a/hmModules/apps/neovim/options.lua b/hmModules/apps/neovim/options.lua new file mode 100644 index 0000000..9043756 --- /dev/null +++ b/hmModules/apps/neovim/options.lua @@ -0,0 +1,57 @@ +-- Globals +vim.g.mapleader = ' ' +vim.g.maplocalleader = ' ' +vim.opt.list = true +vim.bo.filetype = true +vim.opt.updatetime = 300 + +-- Indentations +vim.opt.tabstop = 2 +vim.opt.softtabstop = 0 +vim.opt.shiftwidth = 2 +vim.opt.smarttab = true +vim.opt.expandtab = true + +-- Style +vim.opt.colorcolumn = "80" +vim.opt.showmatch = true +vim.opt.number = true +vim.opt.relativenumber = true + +-- Easy Split Navigation +-- nnoremap +-- nnoremap +-- nnoremap +-- nnoremap + +-- Searching +vim.opt.smartcase = true + +-- Backups +vim.opt.swapfile = false +vim.opt.backup = false +vim.opt.undofile = true +vim.opt.undodir = '/home/pan/.config/nvim/undodir' + +-- Easy copy and pasting to external programs +-- map "+yy +-- map "+P + +-- autocmd BufRead,BufNewFile *.md call WritingMode() +-- autocmd BufRead,BufNewFile *.tex call WritingMode() +-- autocmd BufRead,BufNewFile *.svx call WritingMode() + +-- autocmd BufRead,BufNewFile *.py call PythonMode() + +-- function! WritingMode() + -- setlocal textwidth=80 + -- setlocal wrap linebreak nolist + -- setlocal whichwrap+=<,>,h,l + -- nnoremap j gj + -- nnoremap k gk + -- setlocal spell spelllang=en_us +-- endfunction +-- function! PythonMode() + -- setlocal foldmethod=indent + -- setlocal foldlevel=99 +-- endfunction diff --git a/hmModules/apps/neovim/plugin/lsp.nix b/hmModules/apps/neovim/plugin/lsp.nix new file mode 100644 index 0000000..ae3806a --- /dev/null +++ b/hmModules/apps/neovim/plugin/lsp.nix @@ -0,0 +1,49 @@ +{ config, pkgs, lib, ... }: + +{ + config = lib.mkIf config.neovim.enable { + programs.neovim.plugins = let + cfgp = config.neovim.plugins; + cfgl = config.neovim.languages; + + configText = '' + local on_attach = function(_, bufnr) + + local bufmap = function(keys, func) + vim.keymap.set('n', keys, func, { buffer = bufnr }) + end + + bufmap('r', vim.lsp.buf.rename) + bufmap('a', vim.lsp.buf.code_action) + + bufmap('gd', vim.lsp.buf.definition) + bufmap('gD', vim.lsp.buf.declaration) + bufmap('gI', vim.lsp.buf.implementation) + bufmap('D', vim.lsp.buf.type_definition) + + '' + lib.strings.optionalString cfgp.telescope.enable '' + bufmap('gr', require('telescope.builtin').lsp_references) + bufmap('s', require('telescope.builtin').lsp_document_symbols) + bufmap('S', require('telescope.builtin').lsp_dynamic_workspace_symbols) + '' + '' + + bufmap('K', vim.lsp.buf.hover) + + vim.api.nvim_buf_create_user_command(bufnr, 'Format', function(_) + vim.lsp.buf.format() + end, {}) + end + + local capabilities = vim.lsp.protocol.make_client_capabilities() + '' + lib.strings.optionalString cfgl.nix.enable '' + require('lspconfig').nil_ls.setup {} + ''; + in with pkgs.vimPlugins; [ + { + plugin = nvim-lspconfig; + type = "lua"; + config = configText; + } + ]; + }; +} diff --git a/hmModules/apps/neovim/plugin/nvimcmp.nix b/hmModules/apps/neovim/plugin/nvimcmp.nix new file mode 100644 index 0000000..82098ef --- /dev/null +++ b/hmModules/apps/neovim/plugin/nvimcmp.nix @@ -0,0 +1,72 @@ +{ config, pkgs, lib, ... }: + +let + cfgp = config.neovim.plugins; +in { + config = lib.mkIf (config.neovim.enable && cfgp.nvimcmp.enable) { + programs.neovim.plugins = let + + configText = '' + local cmp = require('cmp') + '' + lib.strings.optionalString cfgp.luasnip.enable '' + local luasnip = require('luasnip') + + require('luasnip.loaders.from_vscode').lazy_load() + luasnip.config.setup {} + '' + '' + + cmp.setup { + mapping = cmp.mapping.preset.insert { + [''] = cmp.mapping.select_next_item(), + [''] = cmp.mapping.select_prev_item(), + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete {}, + [''] = cmp.mapping.confirm { + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }, + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + '' + lib.strings.optionalString cfgp.luasnip.enable '' + elseif luasnip.expand_or_locally_jumpable() then + luasnip.expand_or_jump() + '' + '' + else + fallback() + end + end, { 'i', 's' }), + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + '' + lib.strings.optionalString cfgp.luasnip.enable '' + elseif luasnip.locally_jumpable(-1) then + luasnip.jump(-1) + '' + '' + else + fallback() + end + end, { 'i', 's' }), + }, + '' + lib.strings.optionalString cfgp.luasnip.enable '' + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + sources = { + { name = 'luasnip' }, + }, + '' + '' + } + ''; + in with pkgs.vimPlugins; [ + { + plugin = nvim-cmp; + type = "lua"; + config = configText; + } + ]; + }; +} diff --git a/hmModules/apps/neovim/plugin/telescope.nix b/hmModules/apps/neovim/plugin/telescope.nix new file mode 100644 index 0000000..26178ef --- /dev/null +++ b/hmModules/apps/neovim/plugin/telescope.nix @@ -0,0 +1,40 @@ +{ config, pkgs, lib, ... }: + +let + cfgp = config.neovim.plugins; +in { + config = lib.mkIf (config.neovim.enable && cfgp.telescope.enable) { + programs.neovim.plugins = let + configText = '' + require('telescope').setup({ + extensions = { + '' + lib.strings.optionalString cfgp.telescope.fzf.enable '' + fzf = { + fuzzy = true, -- false will only do exact matching + override_generic_sorter = true, -- override the generic sorter + override_file_sorter = true, -- override the file sorter + case_mode = "smart_case", -- or "ignore_case" or "respect_case" + -- the default case_mode is "smart_case" + } + '' + '' + } + }) + + '' + lib.strings.optionalString cfgp.telescope.fzf.enable '' + require('telescope').load_extension('fzf') + ''; + in with pkgs.vimPlugins; [ + { + plugin = telescope-nvim; + type = "lua"; + config = configText; + } + (lib.mkIf cfgp.nvimcmp.enable telescope-fzf-native-nvim) + ]; + + home.packages = with pkgs; [ + (lib.mkIf cfgp.telescope.fzf.enable fzf) + ]; + + }; +} diff --git a/hmModules/apps/neovim/plugin/treesitter.nix b/hmModules/apps/neovim/plugin/treesitter.nix new file mode 100644 index 0000000..bf828b8 --- /dev/null +++ b/hmModules/apps/neovim/plugin/treesitter.nix @@ -0,0 +1,30 @@ +{ config, pkgs, lib, ... }: + +let + cfgp = config.neovim.plugins; + cfgl = config.neovim.languages; +in { + config = lib.mkIf (config.neovim.enable && cfgp.treesitter.enable) { + programs.neovim.plugins = let + configText = '' + require('nvim-treesitter.configs').setup { + ensure_installed = {}, + + auto_install = false, + + highlight = { enable = true }, + + indent = { enable = true }, + } + ''; + + treeplugs = p: lib.lists.optional cfgl.nix.enable p.tree-sitter-nix; + in with pkgs.vimPlugins; [ + { + plugin = (nvim-treesitter.withPlugins treeplugs); + type = "lua"; + config = configText; + } + ]; + }; +} diff --git a/systems/pan/default.nix b/systems/pan/default.nix index 8947e74..fa85073 100644 --- a/systems/pan/default.nix +++ b/systems/pan/default.nix @@ -27,6 +27,22 @@ feh.enable = true; neovim.enable = true; + neovim.languages = { + nix.enable = true; + }; + neovim.plugins = { + comments.enable = true; + fugitive.enable = true; + lualine.enable = true; + luasnip.enable = true; + nvimcmp.enable = true; + telescope = { + enable = true; + fzf.enable = true; + }; + treesitter.enable = true; + }; + lf.enable = true; lf.hiddenfiles = [ "${config.home.homeDirectory}/.librewolf"