{ config, lib, pkgs, ... }: with pkgs.vimPlugins; [ { # # shows which keybindings trigger which actions. # Ctrl+k to show all keybingings. # e.g. hit `g`, and then 1000ms later you'll see a menu showing where in the file you can go # debug: `:checkhealth which-key` plugin = which-key-nvim; config = '' local wk = require("which-key") -- in "n"ormal mode, Ctrl+k will show all keybindings vim.api.nvim_set_keymap("n", "", "", { callback=wk.show, desc = "show keybinds" }) -- or \, because `\` *already* shows keybinds (but only those under \) vim.api.nvim_set_keymap("n", "", "", { callback=wk.show, desc = "show keybinds" }) ''; } { # LSP-capable code completion: # type half a symbol, then `Ctrl+Space` to show autocomplete options, then `Enter` to autocomplete it. # TODO: how to get incremental completion w/o requiring Ctrl+Space? plugin = nvim-cmp; config = '' local cmp = require("cmp") cmp.setup { snippet = { expand = function(args) vim.snippet.expand(args.body) end, }, window = { -- completion = cmp.config.window.bordered(), -- documentation = cmp.config.window.bordered(), }, mapping = 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 }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. -- alternate mappings: -- [''] = cmp.mapping.select_next_item({ -- behavior = cmp.SelectBehavior.Insert } -- ), -- [''] = cmp.mapping.select_prev_item({ -- behavior = cmp.SelectBehavior.Insert } -- ), -- [''] = cmp.mapping.close(), }, sources = cmp.config.sources({ { name = 'nvim_lsp' }, }, { { name = 'buffer' }, }) } ''; } { # used by nvim-cmp to find symbols in other buffers plugin = cmp-buffer; } { # used by nvim-cmp to find symbols in the LSP plugin = cmp-nvim-lsp; } { # Language Server Plugin config: # - # - docs: `:help lspconfig` # - debug: `:LspInfo` # # usage: # - for completion menu # e.g. `os.path.` to show available os.path items in python plugin = nvim-lspconfig; config = '' local lspconfig = require("lspconfig") local cmp_nvim_lsp = require("cmp_nvim_lsp") local capabilities = cmp_nvim_lsp.default_capabilities() '' + lib.optionalString config.sane.programs.bash-language-server.enabled '' -- bash language server -- repo: lspconfig.bashls.setup { capabilities = capabilities, filetypes = { "bash", "sh", "zsh" }, -- defaults to just `sh` handlers = { -- the info and warnings are noisy and outright wrong most of the time -- so disable all diagnostics. -- source: -- more: ['textDocument/publishDiagnostics'] = function() end }, } '' + lib.optionalString config.sane.programs.clang-tools.enabled '' -- c/c++ language server lspconfig.clangd.setup { capabilities = capabilities, } '' + lib.optionalString config.sane.programs.ltex-ls.enabled '' -- LaTeX / html / markdown spellchecker -- repo: lspconfig.ltex.setup { capabilities = capabilities, } '' + lib.optionalString config.sane.programs.lua-language-server.enabled '' -- Lua language server lspconfig.lua_ls.setup { capabilities = capabilities, } '' + lib.optionalString config.sane.programs.marksman.enabled '' -- Markdown language server -- repo: -- an alternative, specialized for PKMs: lspconfig.marksman.setup { capabilities = capabilities, } '' + lib.optionalString config.sane.programs.nil.enabled '' -- nix language server -- repo: -- features: -- a newer alternative is `nixd`: lspconfig.nil_ls.setup { capabilities = capabilities, } '' + lib.optionalString config.sane.programs.nixd.enabled '' -- nix language server -- repo: -- this is a bit nicer than `nil`, noting things like redundant parens, unused args, ... lspconfig.nixd.setup { capabilities = capabilities, } '' + lib.optionalString config.sane.programs.openscad-lsp.enabled '' -- openscad (.scad) language server -- repo: lspconfig.openscad_lsp.setup { capabilities = capabilities, } '' + lib.optionalString config.sane.programs.pyright.enabled '' -- python language server lspconfig.pyright.setup { capabilities = capabilities, } '' + lib.optionalString config.sane.programs.rust-analyzer.enabled '' -- Rust language server -- note: this requires `cargo`, and features are a bit eh... -- - thinks that `None` doesn't exist -- - can't autocomplete `std::` imports -- - but it CAN autocomplete stuff from non-std libraries (?) lspconfig.rust_analyzer.setup { capabilities = capabilities, } '' + lib.optionalString config.sane.programs.typescript-language-server.enabled '' -- Typescript language server -- repo: -- requires tsconfig.json or jsconfig.json in the toplevel of the project directory lspconfig.ts_ls.setup { capabilities = capabilities, } '' + lib.optionalString config.sane.programs.vala-language-server.enabled '' -- Vala (gtk gui language) language server lspconfig.vala_ls.setup { capabilities = capabilities, } ''; } { # docs: fzf-vim (fuzzy finder): https://github.com/junegunn/fzf.vim # `:Rg ` to search the current directory and navigate to results # - or `:RG ` to re-launch `rg` on every keystroke (better results; slower) # - or `:Ag ` plugin = fzf-vim; } { # treesitter syntax highlighting: https://nixos.wiki/wiki/Tree_sitters # docs: https://github.com/nvim-treesitter/nvim-treesitter # config taken from: https://github.com/i077/system/blob/master/modules/home/neovim/default.nix # this is required for tree-sitter to even highlight # XXX(2024/06/03): `unison` removed because it doesn't cross compile (to armv7l-hf-multiplatform) plugin = nvim-treesitter.withPlugins (_: (lib.filter (p: p.pname != "unison-grammar") nvim-treesitter.allGrammars) ++ [ # XXX: this is apparently not enough to enable syntax highlighting! # nvim-treesitter ships its own queries which may be distinct from e.g. helix. # the queries aren't included when i ship the grammar in this manner pkgs.tree-sitter-nix-shell.nvimPlugin ]); type = "lua"; config = '' -- lifted mostly from readme: require'nvim-treesitter.configs'.setup { highlight = { enable = true, -- disable treesitter on Rust so that we can use SyntaxRange -- and leverage TeX rendering in rust projects disable = { "rust", "tex", "latex" }, -- disable = { "tex", "latex" }, -- true to also use builtin vim syntax highlighting when treesitter fails additional_vim_regex_highlighting = false }, incremental_selection = { enable = true, keymaps = { init_selection = "gnn", node_incremental = "grn", scope_incremental = "grc", node_decremental = "grm" } }, indent = { enable = true, disable = {} } } vim.o.foldmethod = 'expr' vim.o.foldexpr = 'nvim_treesitter#foldexpr()' ''; } { # show commit which last modified text under the cursor. # trigger with `:GitMessenger` or `gm` (i.e. `\gm`) plugin = git-messenger-vim; } { # docs: tex-conceal-vim: https://github.com/KeitaNakamura/tex-conceal.vim/ plugin = tex-conceal-vim; type = "viml"; config = '' " present prettier fractions let g:tex_conceal_frac=1 ''; } { # source: # search Dash/Zeal docsets with `:Dasht` plugin = vim-dasht; type = "viml"; config = '' " query the word under the cursor: `\K` (in related docsets) nnoremap K :call Dasht(dasht#cursor_search_terms()) " input a string to query (in related docsets) nnoremap k :Dasht " query *ALL* docsets with `\\k` nnoremap k :Dasht! ''; } { # source: # fixes auto-indent (incl tab size) when editing .nix files plugin = vim-nix; } { # docs: surround-nvim: https://github.com/ur4ltz/surround.nvim/ # docs: vim-surround: https://github.com/tpope/vim-surround plugin = vim-surround; } { plugin = vim-SyntaxRange; type = "viml"; config = '' " enable markdown-style codeblock highlighting for tex code autocmd BufEnter * call SyntaxRange#Include('```tex', '```', 'tex', 'NonText') " autocmd Syntax tex set conceallevel=2 ''; } ]