{ pkgs, config, helpers, lib, ... }: { imports = [ ./modules/commands.nix ./plugins/firenvim.nix ./plugins/headerguard.nix ./plugins/lsp-signature.nix ]; config = { colorschemes.tokyonight = { style = "night"; enable = true; }; autoGroups.BigFileOptimizer = {}; autoCmd = [ { event = ["BufNewFile" "BufRead"]; pattern = ["meson.build" "meson_options.txt" "meson.options"]; callback = let settings = { }; in helpers.mkRaw '' function(args) local match = vim.fs.find( {"meson_options.txt", "meson.options", ".git"}, {path = args.file, upward = true} )[1] local root_dir = match and vim.fn.fnamemodify(match, ":p:h") or nil vim.lsp.start({ name = "mesonlsp", cmd = {"${lib.getExe pkgs.mesonlsp}", "--lsp"}, root_dir = root_dir, settings = ${helpers.toLuaObject settings}, }) end ''; } { event = "BufReadPost"; pattern = [ "*.md" "*.rs" "*.lua" "*.sh" "*.bash" "*.zsh" "*.js" "*.jsx" "*.ts" "*.tsx" "*.c" ".h" "*.cc" ".hh" "*.cpp" ".cph" ]; group = "BigFileOptimizer"; callback = helpers.mkRaw '' function(auEvent) local bufferCurrentLinesCount = vim.api.nvim_buf_line_count(0) if bufferCurrentLinesCount > 2048 then vim.notify("bigfile: disabling features", vim.log.levels.WARN) vim.cmd("TSBufDisable refactor.highlight_definitions") vim.g.matchup_matchparen_enabled = 0 require("nvim-treesitter.configs").setup({ matchup = { enable = false } }) end end ''; } ]; globals = { neo_tree_remove_legacy_commands = 1; mapleader = " "; }; options = { termguicolors = true; number = true; tabstop = 4; shiftwidth = 4; scrolloff = 7; signcolumn = "yes"; cmdheight = 2; cot = ["menu" "menuone" "noselect"]; updatetime = 100; colorcolumn = "100"; # Too many false positives spell = false; listchars = "tab:>-,lead:·,nbsp:␣,trail:•"; fsync = true; timeout = true; timeoutlen = 300; }; commands = { "SpellFr" = "setlocal spelllang=fr"; }; filetype = { filename = { Jenkinsfile = "groovy"; }; extension = { lalrpop = "lalrpop"; }; }; keymaps = let modeKeys = mode: lib.attrsets.mapAttrsToList (key: action: { inherit key mode; } // ( if builtins.isString action then {inherit action;} else action )); nm = modeKeys ["n"]; vs = modeKeys ["v"]; in helpers.keymaps.mkKeymaps {options.silent = true;} (nm { "ft" = "Neotree"; "fG" = "Neotree git_status"; "fR" = "Neotree remote"; "fc" = "Neotree close"; "bp" = "Telescope buffers"; "" = "Telescope spell_suggest"; "mk" = "Telescope keymaps"; "fg" = "Telescope git_files"; "gr" = "Telescope lsp_references"; "gI" = "Telescope lsp_implementations"; "gW" = "Telescope lsp_workspace_symbols"; "gF" = "Telescope lsp_document_symbols"; "ge" = "Telescope diagnostics bufnr=0"; "gE" = "Telescope diagnostics"; "h" = { action = "lua vim.lsp.inlay_hint.enable(0, not vim.lsp.inlay_hint.is_enabled())"; options = { desc = "toggle inlay hints"; }; }; "zn" = "ZkNew { title = vim.fn.input('Title: ') }"; "zo" = "ZkNotes { sort = { 'modified' } }"; "zt" = "ZkTags"; "zf" = "ZkNotes { sort = { 'modified' }, match = { vim.fn.input('Search: ') } }"; "yH" = { action = "Telescope yank_history"; options.desc = "history"; }; }) ++ (vs { "zf" = "'<,'>ZkMatch"; }) ++ [ { key = "rn"; mode = ["n"]; action = '' function() return ":IncRename " .. vim.fn.expand("") end ''; lua = true; options.expr = true; } ]; plugins.nvim-osc52 = { enable = true; package = pkgs.vimPlugins.nvim-osc52; keymaps.enable = true; }; plugins.efmls-configs = { enable = true; toolPackages.mdformat = pkgs.mdformat.withPlugins (ps: with ps; [ # TODO: broken with update of mdformat # mdformat-gfm mdformat-frontmatter mdformat-footnote mdformat-tables mdit-py-plugins ]); setup = { sh = { #linter = "shellcheck"; formatter = "shfmt"; }; bash = { #linter = "shellcheck"; formatter = "shfmt"; }; c = { linter = "cppcheck"; }; markdown = { formatter = ["cbfmt" "mdformat"]; }; python = { formatter = "black"; }; nix = { linter = "statix"; }; lua = { formatter = "stylua"; }; html = { formatter = ["prettier" (helpers.mkRaw "djlint_fmt")]; }; htmldjango = { formatter = [(helpers.mkRaw "djlint_fmt")]; linter = "djlint"; }; json = { formatter = "prettier"; }; css = { formatter = "prettier"; }; ts = { formatter = "prettier"; }; gitcommit = { linter = "gitlint"; }; }; }; # plugins.null-ls = { # enable = true; # sources = { # diagnostics = { # gitlint.enable = true; # }; # code_actions = { # shellcheck.enable = true; # #gitsigns.enable = true; # }; # formatting = { # alejandra.enable = true; # }; # }; # }; plugins.gitsigns.enable = true; plugins.gitmessenger.enable = true; plugins.firenvim.enable = false; plugins.luasnip = { enable = true; }; extraConfigLuaPre = '' local has_words_before = function() unpack = unpack or table.unpack local line, col = unpack(vim.api.nvim_win_get_cursor(0)) return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil end local luasnip = require("luasnip") local efm_fs = require('efmls-configs.fs') local djlint_fmt = { formatCommand = string.format('%s --reformat ''${INPUT} -', efm_fs.executable('djlint')), formatStdin = true, } ''; plugins.cmp = { enable = true; settings = { snippet.expand = '' function(args) require('luasnip').lsp_expand(args.body) end ''; mapping = { "" = "cmp.mapping.confirm({select = true })"; "" = "cmp.mapping.scroll_docs(-4)"; "" = "cmp.mapping.scroll_docs(4)"; "" = "cmp.mapping.complete()"; "" = '' cmp.mapping(function(fallback) if cmp.visible() then cmp.select_next_item() -- You could replace the expand_or_jumpable() calls with expand_or_locally_jumpable() -- they way you will only jump inside the snippet region elseif luasnip.expand_or_locally_jumpable() then luasnip.expand_or_jump() elseif has_words_before() then cmp.complete() else fallback() end end, { "i", "s" }) ''; "" = '' cmp.mapping(function(fallback) if cmp.visible() then cmp.select_prev_item() elseif luasnip.jumpable(-1) then luasnip.jump(-1) else fallback() end end, { "i", "s" }) ''; "" = "cmp.mapping(cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Select }), {'i'})"; "" = "cmp.mapping(cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Select }), {'i'})"; }; sources = [ {name = "luasnip";} {name = "nvim_lsp";} {name = "path";} {name = "buffer";} {name = "calc";} {name = "git";} ]; }; filetype.sh = { sources = [ {name = "zsh";} ]; }; }; plugins.telescope = { enable = true; enabledExtensions = ["ui-select"]; extensionConfig = { ui-select = { __raw = '' require("telescope.themes").get_dropdown { -- even more opts } ''; }; }; extraOptions = { defaults.layout_strategy = "vertical"; }; }; extraFiles."queries/rust/injections.scm" = '' ;; extends ( (macro_invocation macro: ((scoped_identifier) @_sql_def) (token_tree (string_literal) @sql)) (#eq? @_sql_def "sqlx::query") ) ''; plugins.treesitter = { enable = true; indent = true; nixvimInjections = true; grammarPackages = with config.plugins.treesitter.package.passthru.builtGrammars; [ arduino bash c cpp cuda dart devicetree diff dockerfile gitattributes gitcommit gitignore git_rebase groovy html ini json lalrpop latex lua make markdown markdown_inline meson ninja nix python regex rst rust slint sql tlaplus toml vim vimdoc yaml ]; }; plugins.treesitter-refactor = { enable = true; highlightDefinitions = { enable = true; clearOnCursorMove = true; }; smartRename = { enable = true; }; navigation = { enable = true; }; }; plugins.treesitter-context = { enable = true; }; plugins.vim-matchup = { treesitterIntegration = { enable = true; includeMatchWords = true; }; enable = true; }; plugins.headerguard.enable = true; plugins.comment-nvim = { enable = true; }; plugins.neo-tree = { enable = true; }; plugins.plantuml-syntax.enable = true; plugins.indent-blankline = { enable = true; scope = { enabled = true; showStart = true; }; }; plugins.lsp = { enable = true; enabledServers = [ # { # name = "groovyls"; # extraOptions = { # cmd = ["${pkgs.groovy-language-server}/bin/groovy-language-server"]; # }; # } ]; keymaps = { silent = true; lspBuf = { "gd" = "definition"; "gD" = "declaration"; "ca" = "code_action"; "ff" = "format"; "K" = "hover"; }; }; servers = { nil_ls = { enable = true; settings = { formatting.command = ["${pkgs.alejandra}/bin/alejandra" "--quiet"]; }; }; bashls.enable = true; dartls.enable = true; clangd.enable = true; typst-lsp.enable = true; tsserver.enable = true; efm.extraOptions = { init_options = { documentFormatting = true; }; settings = { logLevel = 1; }; }; taplo.enable = true; lemminx.enable = true; ltex = { enable = true; onAttach.function = '' require("ltex_extra").setup{ load_langs = { "en-US", "fr-FR" }, path = ".ltex", } ''; filetypes = [ "bib" "gitcommit" "markdown" "org" "plaintex" "rst" "rnoweb" "tex" "pandoc" "typst" #"mail" ]; }; }; }; plugins.typst-vim.enable = true; plugins.rustaceanvim = { enable = true; server = { settings = { cargo.features = "all"; checkOnSave = true; check.command = "clippy"; rustc.source = "discover"; }; }; }; plugins.lspkind = { enable = true; cmp = { enable = true; }; }; plugins.nvim-lightbulb = { enable = true; settings.autocmd.enabled = true; }; plugins.lsp_signature = { #enable = true; }; plugins.inc-rename = { enable = true; }; plugins.clangd-extensions = { enable = true; enableOffsetEncodingWorkaround = true; ast = { roleIcons = { type = ""; declaration = ""; expression = ""; specifier = ""; statement = ""; templateArgument = ""; }; kindIcons = { compound = ""; recovery = ""; translationUnit = ""; packExpansion = ""; templateTypeParm = ""; templateTemplateParm = ""; templateParamObject = ""; }; }; }; # fidget = { # enable = true; # # sources.null-ls.ignore = true; # }; plugins.lualine = { enable = true; }; plugins.trouble = { enable = true; }; plugins.noice = { enable = true; messages = { view = "mini"; viewError = "mini"; viewWarn = "mini"; }; lsp.override = { "vim.lsp.util.convert_input_to_markdown_lines" = true; "vim.lsp.util.stylize_markdown" = true; "cmp.entry.get_documentation" = true; }; presets = { bottom_search = true; command_palette = true; long_message_to_split = true; inc_rename = true; lsp_doc_border = false; }; }; plugins.netman = { enable = false; package = pkgs.vimPlugins.netman-nvim; neoTreeIntegration = true; }; plugins.openscad = { enable = true; loadSnippets = true; keymaps.enable = true; }; extraConfigLuaPost = '' require("luasnip.loaders.from_snipmate").lazy_load() require("cmp_git").setup({}) vim.api.nvim_create_user_command("LtexLangChangeLanguage", function(data) local language = data.fargs[1] local bufnr = vim.api.nvim_get_current_buf() local client = vim.lsp.get_active_clients({ bufnr = bufnr, name = 'ltex' }) if #client == 0 then vim.notify("No ltex client attached") else client = client[1] client.config.settings = { ltex = { language = language } } client.notify('workspace/didChangeConfiguration', client.config.settings) vim.notify("Language changed to " .. language) end end, { nargs = 1, force = true, }) -- local null_ls = require("null-ls") -- local helpers = require("null-ls.helpers") -- -- local sca2d = { -- method = null_ls.methods.DIAGNOSTICS, -- filetypes = { "openscad" }, -- generator = null_ls.generator({ -- command = "sca2d", -- args = { "$FILENAME" }, -- from_stderr = false, -- to_stdin = true, -- format = "line", -- check_exit_code = function(code) -- return code <= 1 -- end, -- on_output = helpers.diagnostics.from_pattern( -- [[[^:]+:(%d+):(%d+): (%w)%d+: (.*)]], {"row", "col", "severity", "message"}, { -- severities = { -- F = helpers.diagnostics.severities["error"], -- E = helpers.diagnostics.severities["error"], -- W = helpers.diagnostics.severities["warning"], -- D = helpers.diagnostics.severities["warning"], -- I = helpers.diagnostics.severities["info"], -- }, -- }), -- }), -- } -- null_ls.register(sca2d) ''; plugins.zk = { enable = true; picker = "telescope"; }; plugins.which-key.enable = true; plugins.leap.enable = true; plugins.yanky = { enable = true; picker.telescope = { useDefaultMappings = true; enable = true; }; }; files."ftplugin/nix.lua" = { options = { tabstop = 2; shiftwidth = 2; expandtab = true; }; }; files."ftplugin/markdown.lua" = { extraConfigLua = '' if require("zk.util").notebook_root(vim.fn.expand('%:p')) ~= nil then local function map(...) vim.api.nvim_buf_set_keymap(0, ...) end local opts = { noremap=true, silent=false } -- Open the link under the caret. map("n", "", "lua vim.lsp.buf.definition()", opts) -- Create a new note after asking for its title. -- This overrides the global `zn` mapping to create the note in the same directory as the current buffer. map("n", "zn", "ZkNew { dir = vim.fn.expand('%:p:h'), title = vim.fn.input('Title: ') }", opts) -- Create a new note in the same directory as the current buffer, using the current selection for title. map("v", "znt", ":'<,'>ZkNewFromTitleSelection { dir = vim.fn.expand('%:p:h') }", opts) -- Create a new note in the same directory as the current buffer, using the current selection for note content and asking for its title. map("v", "znc", ":'<,'>ZkNewFromContentSelection { dir = vim.fn.expand('%:p:h'), title = vim.fn.input('Title: ') }", opts) -- Open notes linking to the current buffer. map("n", "zb", "ZkBacklinks", opts) -- Alternative for backlinks using pure LSP and showing the source context. --map('n', 'zb', 'lua vim.lsp.buf.references()', opts) -- Open notes linked by the current buffer. map("n", "zl", "ZkLinks", opts) -- Preview a linked note. map("n", "K", "lua vim.lsp.buf.hover()", opts) -- Open the code actions for a visual selection. map("v", "za", ":'<,'>lua vim.lsp.buf.range_code_action()", opts) end ''; }; extraPackages = with pkgs; [ /* sca2d */ djlint muon ]; extraPlugins = with pkgs.vimPlugins; [ telescope-ui-select-nvim vim-snippets markdown-preview-nvim vim-just ltex_extra-nvim ]; }; }