From cfdb14cf768f2971f6efe2e333c620571f30fad1 Mon Sep 17 00:00:00 2001 From: Minijackson Date: Wed, 18 Jan 2023 13:39:42 +0100 Subject: vim: refactor, allowing different files like ftplugin --- common/vim.nix | 48 ++-- dotfiles/vim-dev.lua | 95 -------- dotfiles/vim.lua | 494 -------------------------------------- dotfiles/vim/ftplugin/nix.lua | 6 + dotfiles/vim/ftplugin/rust.lua | 18 ++ dotfiles/vim/lua/myConfig.lua | 495 +++++++++++++++++++++++++++++++++++++++ dotfiles/vim/lua/vim-dev.lua | 95 ++++++++ usecases/desktop/development.nix | 3 +- 8 files changed, 643 insertions(+), 611 deletions(-) delete mode 100644 dotfiles/vim-dev.lua delete mode 100644 dotfiles/vim.lua create mode 100644 dotfiles/vim/ftplugin/nix.lua create mode 100644 dotfiles/vim/ftplugin/rust.lua create mode 100644 dotfiles/vim/lua/myConfig.lua create mode 100644 dotfiles/vim/lua/vim-dev.lua diff --git a/common/vim.nix b/common/vim.nix index 2f36958..bebfb0e 100644 --- a/common/vim.nix +++ b/common/vim.nix @@ -12,8 +12,8 @@ inputs: { cfg = config.vim; - myConfigPackage = with lib; let - config = '' + variables = with lib; + pkgs.writeTextDir "lua/myVariables.lua" '' -- Autogenerated variables from the NixOS configuration ${(concatStringsSep @@ -21,35 +21,32 @@ inputs: { (mapAttrsToList (variable: value: "vim.g.${variable} = ${luaFormat.generate value}") cfg.variables))} + ''; - -- vim.lua from the NixOS configuration + extraConfig = pkgs.writeTextDir "lua/myExtraConfig.lua" '' + -- luaConfig from the NixOS configuration - ${builtins.readFile ../dotfiles/vim.lua} + ${cfg.luaConfig} + ''; - -- luaConfig from the NixOS configuration + myGeneratedConfigPackage = pkgs.symlinkJoin { + name = "myGeneratedConfig-nvim"; + paths = [variables extraConfig]; + }; - ${cfg.luaConfig} - ''; - in - pkgs.runCommand - "myConfig" - { - pname = "myConfig"; - inherit config; - passAsFile = ["config"]; - runLocal = true; - } - '' - mkdir -p "$out/lua" - mv "$configPath" "$out/lua/myConfig.lua" - ''; + myConfigPackage = pkgs.unstable.vimUtils.buildVimPluginFrom2Nix { + name = "myConfig-nvim"; + src = ../dotfiles/vim; + }; myNeovim = wrapNeovim neovim-unwrapped { configure = { inherit (config.vim) beforePlugins; customRC = '' + lua require("myVariables") lua require("myConfig") + lua require("myExtraConfig") ${cfg.extraConfig} ''; @@ -57,6 +54,7 @@ inputs: { packages.myVimPackage = with vimPlugins; { start = [ + myGeneratedConfigPackage myConfigPackage # Dependencies @@ -72,6 +70,15 @@ inputs: { diffview-nvim nvim-notify indent-blankline-nvim + (pkgs.unstable.vimUtils.buildVimPluginFrom2Nix { + name = "oil.nvim"; + src = pkgs.fetchFromGitHub { + owner = "stevearc"; + repo = "oil.nvim"; + rev = "abfc455f62dac385b0fc816f37c64dffead0bcf3"; + hash = "sha256-oA220nzaBlFnJ0s23oabIW3XV1tWml5kBuBkTImOPjM="; + }; + }) # Completion nvim-cmp @@ -92,7 +99,6 @@ inputs: { # Telescope telescope-nvim - telescope-file-browser-nvim telescope-ui-select-nvim # Treesitter diff --git a/dotfiles/vim-dev.lua b/dotfiles/vim-dev.lua deleted file mode 100644 index 33b46fd..0000000 --- a/dotfiles/vim-dev.lua +++ /dev/null @@ -1,95 +0,0 @@ -local lspconfig = require "lspconfig" - -local function on_attach(client, bufnr) - local opts = { noremap = true, silent = true, buffer = bufnr } - - local telescope_builtin = require "telescope.builtin" - - local function desc(tbl1, description) - return vim.tbl_extend("force", tbl1, { desc = description }) - end - - vim.keymap.set("n", "gD", vim.lsp.buf.declaration, desc(opts, "LSP declaration")) - vim.keymap.set("n", "gd", telescope_builtin.lsp_definitions, desc(opts, "LSP Definitions")) - vim.keymap.set("n", "K", vim.lsp.buf.hover, desc(opts, "LSP Hover")) - - vim.keymap.set("n", "gr", telescope_builtin.lsp_references, desc(opts, "LSP References")) - - vim.keymap.set("n", "sa", vim.lsp.buf.code_action, desc(opts, "LSP Code Actions")) - vim.keymap.set("v", "sa", vim.lsp.buf.range_code_action, desc(opts, "LSP Code Actions")) - vim.keymap.set("n", "se", vim.diagnostic.open_float, desc(opts, "Local Diagnostics")) - vim.keymap.set("n", "sE", telescope_builtin.diagnostics, desc(opts, "Global Diagnostics")) - vim.keymap.set("n", "sl", vim.diagnostic.setloclist, desc(opts, "Diagnostics set LocList")) - vim.keymap.set("n", "sq", vim.diagnostic.setqflist, desc(opts, "Diagnostics set QFList")) - vim.keymap.set("n", "sr", vim.lsp.buf.rename, desc(opts, "LSP Rename")) - vim.keymap.set("n", "ss", telescope_builtin.lsp_document_symbols, desc(opts, "LSP Document Symbols")) - vim.keymap.set("n", "sS", telescope_builtin.lsp_workspace_symbols, desc(opts, "LSP Workspace Symbols")) - - vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, desc(opts, "Goto Next Diagnostic")) - vim.keymap.set("n", "]d", vim.diagnostic.goto_next, desc(opts, "Goto Prev Diagnostic")) - - -- Capability specific - - if client.server_capabilities.documentFormattingProvider then - vim.keymap.set("n", "sf", vim.lsp.buf.formatting, desc(opts, "Format buffer")) - end - - -- Rust specific - vim.keymap.set("n", "sh", "RustToggleInlayHints", opts) - - require("lsp_signature").on_attach { - hint_prefix = "param: ", - } -end - -capabilities = require("cmp_nvim_lsp").default_capabilities() - -require("rust-tools").setup { - server = { - cmd = { vim.g.rust_analyzer_path }, - settings = { - ["rust-analyzer"] = { - checkOnSave = { - command = "clippy", - }, - experimental = { - procAttrMacros = true, - }, - }, - }, - on_attach = on_attach, - }, -} - -require("nlua.lsp.nvim").setup(lspconfig, { - cmd = { - string.format("%s/bin/lua-language-server", vim.g.sumneko_lua_base_path), - "-E", - string.format("%s/share/lua-language-server/main.lua", vim.g.sumneko_lua_base_path), - }, - on_attach = on_attach, -}) - --- Refactoring -require("refactoring").setup {} - --- Null LSP - -require("null-ls").setup({ - sources = { - require("null-ls").builtins.code_actions.gitrebase, - require("null-ls").builtins.code_actions.gitsigns, - require("null-ls").builtins.code_actions.refactoring.with { - filetypes = { "typescript", "javascript", "lua", "c", "cpp", "go", "python", "java", "php", "ruby" }, - }, - require("null-ls").builtins.code_actions.shellcheck, - require("null-ls").builtins.code_actions.statix, - require("null-ls").builtins.diagnostics.deadnix, - require("null-ls").builtins.diagnostics.shellcheck, - require("null-ls").builtins.diagnostics.statix, - require("null-ls").builtins.diagnostics.vale.with { - filetypes = { "markdown", "pandoc", "tex", "asciidoc" }, - }, - }, - on_attach = on_attach, -}) diff --git a/dotfiles/vim.lua b/dotfiles/vim.lua deleted file mode 100644 index defee0c..0000000 --- a/dotfiles/vim.lua +++ /dev/null @@ -1,494 +0,0 @@ --- Options ----------- - -vim.o.undofile = true -vim.o.backup = true -vim.opt.backupdir:remove "." - -vim.opt.shortmess:append "c" - -vim.o.mouse = "a" - -vim.o.ignorecase = true -vim.o.smartcase = true - -vim.o.smartindent = true - --- tabstop and shiftwidth are also set locally by individual filetypes - -vim.o.tabstop = 4 -vim.o.shiftwidth = 4 - -vim.opt.shortmess:append "A" - -vim.o.inccommand = "split" - -vim.o.scrolloff = 1 -vim.o.sidescrolloff = 5 - -vim.o.colorcolumn = "80" -vim.o.cursorline = true - -vim.o.title = true - -vim.opt.wildmode = { "longest:full", "full" } -vim.opt.completeopt = { "menu", "menuone", "preview", "noinsert", "noselect" } - --- Use ripgrep -vim.o.grepprg = vim.g.ripgrep_path .. " --vimgrep --smart-case" -vim.o.grepformat = "%f:%l:%c:%m," .. vim.o.grepformat - -vim.o.termguicolors = true -vim.o.background = "dark" - -vim.o.updatetime = 1000 - --- Mode already shown by the status line -vim.o.showmode = false - -vim.opt.listchars = { - extends = ">", - nbsp = "+", - precedes = "<", - tab = " ", - trail = "-", -} -vim.wo.list = true - --- Leaders ----------- - -vim.g.maplocalleader = "," -vim.g.mapleader = ";" - --- Misc -------- - --- From neovim#14420 --- Restores the position of previously opened files - --- Inspired by: https://github.com/ethanholz/nvim-lastplace - -local last_cursor_pos_augroup = vim.api.nvim_create_augroup("LastCursorPos", {}) -vim.api.nvim_create_autocmd("BufReadPost", { - group = last_cursor_pos_augroup, - desc = "Restore the position of previously opened files", - callback = function(opts) - if vim.tbl_contains({ "quickfix", "nofile", "help" }, vim.bo.buftype) then - return - end - - if vim.tbl_contains({ "gitcommit", "gitrebase", "svn", "hgcommit" }, vim.bo.filetype) then - return - end - - -- If a line has already been specified on the command line, we are done - -- nvim file +num - if vim.fn.line "." > 1 then - return - end - - -- If the last line is set and the less than the last line in the buffer - if vim.fn.line [['"]] > 0 and vim.fn.line [['"]] <= vim.fn.line "$" then - if vim.fn.line "w$" == vim.fn.line "$" then - -- if the last line in the current buffer is also the last line visible - -- in this window - vim.cmd [[normal! g`"]] - elseif vim.fn.line "$" - vim.fn.line [['"]] > ((vim.fn.line "w$" - vim.fn.line "w0") / 2) - 1 then - -- if we're not at the bottom of the file, center the cursor on the - -- screen after we make the jump - vim.cmd [[normal! g`"zz]] - else - -- otherwise, show as much context as we can by jumping to the end of - -- the file and then to the mark. If we pressed zz here, there would be - -- blank lines at the bottom of the screen. We intentionally leave the - -- last line blank by pressing so the user has a clue that they - -- are near the end of the file. - vim.cmd [[normal! G'"]] - end - end - end, -}) - -vim.api.nvim_create_autocmd("TextYankPost", { - desc = "Highlight yanked text", - callback = function(opts) - vim.highlight.on_yank() - end, -}) - -vim.g.tex_flavor = "latex" - -vim.g.gruvbox_italic = 1 -vim.cmd "colorscheme gruvbox" - --- Mappings ------------ - -local mapopts = { noremap = true, silent = true } - -vim.fn["camelcasemotion#CreateMotionMappings"] "" - -vim.keymap.set("n", "yof", function() - if vim.opt_local.formatoptions:get().a then - vim.opt_local.formatoptions:remove "a" - print ":setlocal formatoptions-=a" - else - vim.opt_local.formatoptions:append "a" - print ":setlocal formatoptions+=a" - end -end, mapopts) - --- Plugins ----------- - --- Impatient - -require("impatient") - --- Gitsigns - -require("gitsigns").setup { - keymaps = { - noremap = true, - buffer = true, - silent = true, - - ["n ]c"] = { expr = true, "&diff ? ']c' : 'lua require\"gitsigns\".next_hunk()'" }, - ["n [c"] = { expr = true, "&diff ? '[c' : 'lua require\"gitsigns\".prev_hunk()'" }, - - ["n hs"] = 'lua require"gitsigns".stage_hunk()', - ["n hu"] = 'lua require"gitsigns".undo_stage_hunk()', - ["n hr"] = 'lua require"gitsigns".reset_hunk()', - ["n hR"] = 'lua require"gitsigns".reset_buffer()', - ["n hp"] = 'lua require"gitsigns".preview_hunk()', - ["n hb"] = 'lua require"gitsigns".blame_line()', - - -- Text objects - ["o ih"] = ':lua require"gitsigns".select_hunk()', - ["x ih"] = ':lua require"gitsigns".select_hunk()', - }, -} - --- Treesitter - -require("nvim-treesitter.configs").setup { - parser_install_dir = vim.fn.stdpath("data") .. "/site", - highlight = { - enable = true, - }, - incremental_selection = { - enable = true, - keymaps = { - init_selection = "gnn", - node_incremental = "grn", - scope_incremental = "grc", - node_decremental = "grm", - }, - }, - indent = { - enable = true, - disable = { "rust" }, - }, - matchup = { - enable = true, - }, - refactor = { - highlight_definitions = { enable = true }, - navigation = { enable = true }, - }, - textobjects = { - lsp_interop = { - enable = true, - border = "none", - peek_definition_code = { - ["df"] = "@function.outer", - ["dF"] = "@class.outer", - }, - }, - - move = { - enable = true, - goto_next_start = { - ["]m"] = "@function.outer", - ["]]"] = "@class.outer", - }, - goto_next_end = { - ["]M"] = "@function.outer", - ["]["] = "@class.outer", - }, - goto_previous_start = { - ["[m"] = "@function.outer", - ["[["] = "@class.outer", - }, - goto_previous_end = { - ["[M"] = "@function.outer", - ["[]"] = "@class.outer", - }, - }, - - select = { - enable = true, - keymaps = { - -- You can use the capture groups defined in textobjects.scm - ["af"] = "@function.outer", - ["if"] = "@function.inner", - - ["aF"] = "@call.outer", - ["iF"] = "@call.inner", - - ["ac"] = "@class.outer", - ["ic"] = "@class.inner", - - ["aC"] = "@comment.outer", - ["iC"] = "@comment.inner", - - ["ab"] = "@block.outer", - ["ib"] = "@block.inner", - - ["aa"] = "@parameter.outer", - ["ia"] = "@parameter.inner", - }, - }, - - swap = { - enable = true, - swap_next = { - ["a"] = "@parameter.inner", - }, - swap_previous = { - ["A"] = "@parameter.inner", - }, - }, - }, -} - -vim.o.foldmethod = "expr" -vim.o.foldexpr = "nvim_treesitter#foldexpr()" -vim.o.foldlevel = 99 - -vim.api.nvim_set_hl(0, "TSCurrentScope", { - bg = vim.g.current_gruvbox_colors.dark0_soft[1], -}) - -vim.api.nvim_set_hl(0, "TSDefinition", { - bg = vim.g.current_gruvbox_colors.faded_blue[1], -}) - -vim.api.nvim_set_hl(0, "TSDefinitionUsage", { - bg = vim.g.current_gruvbox_colors.faded_aqua[1], -}) - --- Treesitter highlight groups - -vim.api.nvim_set_hl(0, "@attribute", { link = "Macro" }) -vim.api.nvim_set_hl(0, "@error", { link = "ErrorMsg" }) - -vim.api.nvim_set_hl(0, "@text.diff.add", { link = "diffAdded" }) -vim.api.nvim_set_hl(0, "@text.diff.delete", { link = "diffRemoved" }) - -vim.api.nvim_set_hl(0, "@text.strong", { bold = true }) -vim.api.nvim_set_hl(0, "@text.emphasis", { italic = true }) -vim.api.nvim_set_hl(0, "@text.underline", { underline = true }) -vim.api.nvim_set_hl(0, "@text.strike", { strikethrough = true }) -vim.api.nvim_set_hl(0, "@text.environment", { link = "Macro" }) - -vim.api.nvim_set_hl(0, "@text.note", { link = "ModeMsg" }) -vim.api.nvim_set_hl(0, "@text.warning", { link = "WarningMsg" }) -vim.api.nvim_set_hl(0, "@text.warning", { link = "ErrorMsg" }) - -vim.api.nvim_set_hl(0, "@tag.attribute", { link = "@attribute" }) -vim.api.nvim_set_hl(0, "@tag.delimiter", { link = "@punctuation.delimiter" }) - --- nvim-cmp - -local cmp = require "cmp" - -cmp.setup { - snippet = { - expand = function(args) - vim.fn["vsnip#anonymous"](args.body) - end, - }, - mapping = cmp.mapping.preset.insert { - [""] = cmp.mapping.confirm { select = false }, - }, - sources = cmp.config.sources({ - { name = "nvim_lsp" }, - { name = "vsnip" }, - { name = "latex_symbols" }, - { name = "calc" }, - }, { - { name = "path" }, - { name = "treesitter" }, - }, { - { name = "tmux" }, - { name = "spell" }, - -- Use \k for iskeyword because of UTF-8 - { name = "buffer", option = { keyword_pattern = [[\k\+]] } }, - }), -} - --- cmp.setup.cmdline("/", { --- sources = { --- { name = "buffer", option = { keyword_pattern = [[\k\+]] } }, --- }, --- mapping = cmp.mapping.preset.cmdline {}, --- }) - --- cmp.setup.cmdline(":", { --- sources = cmp.config.sources { --- { name = "cmdline" }, --- }, --- mapping = cmp.mapping.preset.cmdline {}, --- }) - --- Telescope - -require("telescope").setup { - extensions = { - file_browser = { - path = "%:p:h", - dir_icon = "D", - }, - ["ui-select"] = { - require("telescope.themes").get_dropdown(), - }, - }, -} - -require("telescope").load_extension "file_browser" -require("telescope").load_extension "ui-select" - -local telescope_builtin = require "telescope.builtin" -local telescope_extensions = require("telescope").extensions - -vim.keymap.set("n", "fb", telescope_builtin.buffers, mapopts) -vim.keymap.set("n", "ff", telescope_builtin.find_files, mapopts) -vim.keymap.set("n", "fg", telescope_builtin.live_grep, mapopts) -vim.keymap.set("n", "fh", telescope_builtin.help_tags, mapopts) -vim.keymap.set("n", "fo", telescope_builtin.oldfiles, mapopts) -vim.keymap.set("n", "fs", telescope_builtin.spell_suggest, mapopts) -vim.keymap.set("n", "ft", telescope_builtin.treesitter, mapopts) -vim.keymap.set("n", "-", telescope_extensions.file_browser.file_browser, mapopts) - --- Lualine - -require("lualine").setup { - options = { - component_separators = "", - icons_enabled = false, - section_separators = "", - }, - sections = { - lualine_c = { - "filename", - { - "lsp_progress", - display_components = { "lsp_client_name", { "title", "percentage", "message" } }, - }, - }, - }, -} - --- VSnip - -vim.keymap.set("i", "", "vsnip#jumpable(1) ? '(vsnip-jump-next)' : ''", { silent = true, expr = true }) -vim.keymap.set("s", "", "vsnip#jumpable(1) ? '(vsnip-jump-next)' : ''", { silent = true, expr = true }) - -vim.keymap.set( - "i", - "", - "vsnip#jumpable(-1) ? '(vsnip-jump-prev)' : ''", - { silent = true, expr = true } -) -vim.keymap.set( - "s", - "", - "vsnip#jumpable(-1) ? '(vsnip-jump-prev)' : ''", - { silent = true, expr = true } -) - --- OSCyank - --- Text yanked into the "t register gets copied using OSC52 escape sequences --- (e.g. goes through SSH) -vim.api.nvim_create_autocmd("TextYankPost", { - desc = "Setup for OSCYank", - callback = function(opts) - if vim.v.event.regname == "t" then - vim.cmd [[OSCYankReg t]] - end - end, -}) - --- Diffview - -require("diffview").setup { - use_icons = false, - enhanced_diff_hl = true, -} - --- Notify - -vim.cmd [[highlight link NotifyERRORBorder DiagnosticError]] -vim.cmd [[highlight link NotifyERRORIcon DiagnosticError]] -vim.cmd [[highlight link NotifyERRORTitle DiagnosticError]] - -vim.cmd [[highlight link NotifyWARNBorder DiagnosticWarn]] -vim.cmd [[highlight link NotifyWARNIcon DiagnosticWarn]] -vim.cmd [[highlight link NotifyWARNTitle DiagnosticWarn]] - -vim.cmd [[highlight link NotifyINFOBorder DiagnosticInfo]] -vim.cmd [[highlight link NotifyINFOIcon DiagnosticInfo]] -vim.cmd [[highlight link NotifyINFOTitle DiagnosticInfo]] - -vim.cmd [[highlight link NotifyDEBUGBorder DiagnosticHint]] -vim.cmd [[highlight link NotifyDEBUGIcon DiagnosticHint]] -vim.cmd [[highlight link NotifyDEBUGTitle DiagnosticHint]] - -vim.cmd [[highlight link NotifyDEBUGBorder GruvboxPurple]] -vim.cmd [[highlight link NotifyDEBUGIcon GruvboxPurple]] -vim.cmd [[highlight link NotifyDEBUGTitle GruvboxPurple]] - -require("notify").setup { stages = "static" } - -vim.notify = require("notify") - --- Comment - -require("Comment").setup {} - --- Indent Blankline - -vim.api.nvim_set_hl(0, "IndentBlanklineContextChar", { - fg = vim.g.current_gruvbox_colors.aqua[1], -}) - -require("indent_blankline").setup { - show_current_context = true, - show_current_context_start = true, -} - --- Local config - -function isModuleAvailable(name) - if package.loaded[name] then - return true - else - for _, searcher in ipairs(package.searchers or package.loaders) do - local loader = searcher(name) - if type(loader) == "function" then - package.preload[name] = loader - return true - end - end - return false - end -end - -vim.opt.runtimepath:append "~/.config/nvim" - -if isModuleAvailable "local_config" then - require "local_config" -end diff --git a/dotfiles/vim/ftplugin/nix.lua b/dotfiles/vim/ftplugin/nix.lua new file mode 100644 index 0000000..7401054 --- /dev/null +++ b/dotfiles/vim/ftplugin/nix.lua @@ -0,0 +1,6 @@ +vim.bo.expandtab = true +vim.bo.shiftwidth = 2 +vim.bo.softtabstop = 2 + +vim.opt_local.comments = { ":#", "s1:/*", "ex:*/", } +vim.bo.commentstring = "# %s" diff --git a/dotfiles/vim/ftplugin/rust.lua b/dotfiles/vim/ftplugin/rust.lua new file mode 100644 index 0000000..23a46f1 --- /dev/null +++ b/dotfiles/vim/ftplugin/rust.lua @@ -0,0 +1,18 @@ +-- TODO: suffixes, includes + +vim.bo.expandtab = true +vim.bo.shiftwidth = 4 +vim.bo.softtabstop = 4 +vim.bo.textwidth = 99 + +vim.opt_local.comments = { + "s0:/*!", + "ex:*/", + "s1:/*", + "mb:*", + "ex:*/", + ":///", + "://!", + "://", +} +vim.bo.commentstring = "// %s" diff --git a/dotfiles/vim/lua/myConfig.lua b/dotfiles/vim/lua/myConfig.lua new file mode 100644 index 0000000..58c6f6d --- /dev/null +++ b/dotfiles/vim/lua/myConfig.lua @@ -0,0 +1,495 @@ +-- Options +---------- + +vim.o.undofile = true +vim.o.backup = true +vim.opt.backupdir:remove "." + +vim.opt.shortmess:append "c" + +vim.o.mouse = "a" + +vim.o.ignorecase = true +vim.o.smartcase = true + +vim.o.smartindent = true +-- TODO: check that +vim.o.cindent = true + +-- tabstop and shiftwidth are also set locally by individual filetypes + +vim.o.tabstop = 4 +vim.o.shiftwidth = 4 + +vim.opt.shortmess:append "A" + +vim.o.inccommand = "split" + +vim.o.scrolloff = 1 +vim.o.sidescrolloff = 5 + +vim.o.colorcolumn = "80" +vim.o.cursorline = true + +vim.o.title = true + +vim.opt.wildmode = { "longest:full", "full" } +vim.opt.completeopt = { "menu", "menuone", "preview", "noinsert", "noselect" } + +-- Use ripgrep +vim.o.grepprg = vim.g.ripgrep_path .. " --vimgrep --smart-case" +vim.o.grepformat = "%f:%l:%c:%m," .. vim.o.grepformat + +vim.o.termguicolors = true +vim.o.background = "dark" + +vim.o.updatetime = 1000 + +-- Mode already shown by the status line +vim.o.showmode = false + +vim.opt.listchars = { + extends = ">", + nbsp = "+", + precedes = "<", + tab = " ", + trail = "-", +} +vim.wo.list = true + +-- Leaders +---------- + +vim.g.maplocalleader = "," +vim.g.mapleader = ";" + +-- Misc +------- + +-- From neovim#14420 +-- Restores the position of previously opened files + +-- Inspired by: https://github.com/ethanholz/nvim-lastplace + +local last_cursor_pos_augroup = vim.api.nvim_create_augroup("LastCursorPos", {}) +vim.api.nvim_create_autocmd("BufReadPost", { + group = last_cursor_pos_augroup, + desc = "Restore the position of previously opened files", + callback = function(opts) + if vim.tbl_contains({ "quickfix", "nofile", "help" }, vim.bo.buftype) then + return + end + + if vim.tbl_contains({ "gitcommit", "gitrebase", "svn", "hgcommit" }, vim.bo.filetype) then + return + end + + -- If a line has already been specified on the command line, we are done + -- nvim file +num + if vim.fn.line "." > 1 then + return + end + + -- If the last line is set and the less than the last line in the buffer + if vim.fn.line [['"]] > 0 and vim.fn.line [['"]] <= vim.fn.line "$" then + if vim.fn.line "w$" == vim.fn.line "$" then + -- if the last line in the current buffer is also the last line visible + -- in this window + vim.cmd [[normal! g`"]] + elseif vim.fn.line "$" - vim.fn.line [['"]] > ((vim.fn.line "w$" - vim.fn.line "w0") / 2) - 1 then + -- if we're not at the bottom of the file, center the cursor on the + -- screen after we make the jump + vim.cmd [[normal! g`"zz]] + else + -- otherwise, show as much context as we can by jumping to the end of + -- the file and then to the mark. If we pressed zz here, there would be + -- blank lines at the bottom of the screen. We intentionally leave the + -- last line blank by pressing so the user has a clue that they + -- are near the end of the file. + vim.cmd [[normal! G'"]] + end + end + end, +}) + +vim.api.nvim_create_autocmd("TextYankPost", { + desc = "Highlight yanked text", + callback = function(opts) + vim.highlight.on_yank() + end, +}) + +vim.g.tex_flavor = "latex" + +vim.g.gruvbox_italic = 1 +vim.cmd "colorscheme gruvbox" + +-- Mappings +----------- + +local mapopts = { noremap = true, silent = true } + +vim.fn["camelcasemotion#CreateMotionMappings"] "" + +vim.keymap.set("n", "yof", function() + if vim.opt_local.formatoptions:get().a then + vim.opt_local.formatoptions:remove "a" + print ":setlocal formatoptions-=a" + else + vim.opt_local.formatoptions:append "a" + print ":setlocal formatoptions+=a" + end +end, mapopts) + +-- Plugins +---------- + +-- Impatient + +require("impatient") + +-- Gitsigns + +require("gitsigns").setup { + keymaps = { + noremap = true, + buffer = true, + silent = true, + + ["n ]c"] = { expr = true, "&diff ? ']c' : 'lua require\"gitsigns\".next_hunk()'" }, + ["n [c"] = { expr = true, "&diff ? '[c' : 'lua require\"gitsigns\".prev_hunk()'" }, + + ["n hs"] = 'lua require"gitsigns".stage_hunk()', + ["n hu"] = 'lua require"gitsigns".undo_stage_hunk()', + ["n hr"] = 'lua require"gitsigns".reset_hunk()', + ["n hR"] = 'lua require"gitsigns".reset_buffer()', + ["n hp"] = 'lua require"gitsigns".preview_hunk()', + ["n hb"] = 'lua require"gitsigns".blame_line()', + + -- Text objects + ["o ih"] = ':lua require"gitsigns".select_hunk()', + ["x ih"] = ':lua require"gitsigns".select_hunk()', + }, +} + +-- Treesitter + +require("nvim-treesitter.configs").setup { + parser_install_dir = vim.fn.stdpath("data") .. "/site", + highlight = { + enable = true, + }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = "gnn", + node_incremental = "grn", + scope_incremental = "grc", + node_decremental = "grm", + }, + }, + indent = { + enable = true, + disable = { "rust" }, + }, + matchup = { + enable = true, + }, + refactor = { + highlight_definitions = { enable = true }, + navigation = { enable = true }, + }, + textobjects = { + lsp_interop = { + enable = true, + border = "none", + peek_definition_code = { + ["df"] = "@function.outer", + ["dF"] = "@class.outer", + }, + }, + + move = { + enable = true, + goto_next_start = { + ["]m"] = "@function.outer", + ["]]"] = "@class.outer", + }, + goto_next_end = { + ["]M"] = "@function.outer", + ["]["] = "@class.outer", + }, + goto_previous_start = { + ["[m"] = "@function.outer", + ["[["] = "@class.outer", + }, + goto_previous_end = { + ["[M"] = "@function.outer", + ["[]"] = "@class.outer", + }, + }, + + select = { + enable = true, + keymaps = { + -- You can use the capture groups defined in textobjects.scm + ["af"] = "@function.outer", + ["if"] = "@function.inner", + + ["aF"] = "@call.outer", + ["iF"] = "@call.inner", + + ["ac"] = "@class.outer", + ["ic"] = "@class.inner", + + ["aC"] = "@comment.outer", + ["iC"] = "@comment.inner", + + ["ab"] = "@block.outer", + ["ib"] = "@block.inner", + + ["aa"] = "@parameter.outer", + ["ia"] = "@parameter.inner", + }, + }, + + swap = { + enable = true, + swap_next = { + ["a"] = "@parameter.inner", + }, + swap_previous = { + ["A"] = "@parameter.inner", + }, + }, + }, +} + +vim.o.foldmethod = "expr" +vim.o.foldexpr = "nvim_treesitter#foldexpr()" +vim.o.foldlevel = 99 + +vim.api.nvim_set_hl(0, "TSCurrentScope", { + bg = vim.g.current_gruvbox_colors.dark0_soft[1], +}) + +vim.api.nvim_set_hl(0, "TSDefinition", { + bg = vim.g.current_gruvbox_colors.faded_blue[1], +}) + +vim.api.nvim_set_hl(0, "TSDefinitionUsage", { + bg = vim.g.current_gruvbox_colors.faded_aqua[1], +}) + +-- Treesitter highlight groups + +vim.api.nvim_set_hl(0, "@attribute", { link = "Macro" }) +vim.api.nvim_set_hl(0, "@error", { link = "ErrorMsg" }) + +vim.api.nvim_set_hl(0, "@text.diff.add", { link = "diffAdded" }) +vim.api.nvim_set_hl(0, "@text.diff.delete", { link = "diffRemoved" }) + +vim.api.nvim_set_hl(0, "@text.strong", { bold = true }) +vim.api.nvim_set_hl(0, "@text.emphasis", { italic = true }) +vim.api.nvim_set_hl(0, "@text.underline", { underline = true }) +vim.api.nvim_set_hl(0, "@text.strike", { strikethrough = true }) +vim.api.nvim_set_hl(0, "@text.environment", { link = "Macro" }) + +vim.api.nvim_set_hl(0, "@text.note", { link = "ModeMsg" }) +vim.api.nvim_set_hl(0, "@text.warning", { link = "WarningMsg" }) +vim.api.nvim_set_hl(0, "@text.warning", { link = "ErrorMsg" }) + +vim.api.nvim_set_hl(0, "@tag.attribute", { link = "@attribute" }) +vim.api.nvim_set_hl(0, "@tag.delimiter", { link = "@punctuation.delimiter" }) + +-- nvim-cmp + +local cmp = require "cmp" + +cmp.setup { + snippet = { + expand = function(args) + vim.fn["vsnip#anonymous"](args.body) + end, + }, + mapping = cmp.mapping.preset.insert { + [""] = cmp.mapping.confirm { select = false }, + }, + sources = cmp.config.sources({ + { name = "nvim_lsp" }, + { name = "vsnip" }, + { name = "latex_symbols" }, + { name = "calc" }, + }, { + { name = "path" }, + { name = "treesitter" }, + }, { + { name = "tmux" }, + { name = "spell" }, + -- Use \k for iskeyword because of UTF-8 + { name = "buffer", option = { keyword_pattern = [[\k\+]] } }, + }), +} + +-- cmp.setup.cmdline("/", { +-- sources = { +-- { name = "buffer", option = { keyword_pattern = [[\k\+]] } }, +-- }, +-- mapping = cmp.mapping.preset.cmdline {}, +-- }) + +-- cmp.setup.cmdline(":", { +-- sources = cmp.config.sources { +-- { name = "cmdline" }, +-- }, +-- mapping = cmp.mapping.preset.cmdline {}, +-- }) + +-- Telescope + +require("telescope").setup { + extensions = { + ["ui-select"] = { + require("telescope.themes").get_dropdown(), + }, + }, +} + +require("telescope").load_extension "ui-select" + +local telescope_builtin = require("telescope.builtin") + +vim.keymap.set("n", "fb", telescope_builtin.buffers, mapopts) +vim.keymap.set("n", "ff", telescope_builtin.find_files, mapopts) +vim.keymap.set("n", "fg", telescope_builtin.live_grep, mapopts) +vim.keymap.set("n", "fh", telescope_builtin.help_tags, mapopts) +vim.keymap.set("n", "fo", telescope_builtin.oldfiles, mapopts) +vim.keymap.set("n", "fs", telescope_builtin.spell_suggest, mapopts) +vim.keymap.set("n", "ft", telescope_builtin.treesitter, mapopts) + +-- Oil.nvim + +require("oil").setup() + +vim.keymap.set("n", "-", require("oil").open, { desc = "Open parent directory" }) + +-- Lualine + +require("lualine").setup { + options = { + component_separators = "", + icons_enabled = false, + section_separators = "", + }, + sections = { + lualine_c = { + "filename", + { + "lsp_progress", + display_components = { "lsp_client_name", { "title", "percentage", "message" } }, + }, + }, + }, +} + +-- VSnip + +vim.keymap.set("i", "", "vsnip#jumpable(1) ? '(vsnip-jump-next)' : ''", { silent = true, expr = true }) +vim.keymap.set("s", "", "vsnip#jumpable(1) ? '(vsnip-jump-next)' : ''", { silent = true, expr = true }) + +vim.keymap.set( + "i", + "", + "vsnip#jumpable(-1) ? '(vsnip-jump-prev)' : ''", + { silent = true, expr = true } +) +vim.keymap.set( + "s", + "", + "vsnip#jumpable(-1) ? '(vsnip-jump-prev)' : ''", + { silent = true, expr = true } +) + +-- OSCyank + +-- Text yanked into the "t register gets copied using OSC52 escape sequences +-- (e.g. goes through SSH) +vim.api.nvim_create_autocmd("TextYankPost", { + desc = "Setup for OSCYank", + callback = function(opts) + if vim.v.event.regname == "t" then + vim.cmd [[OSCYankReg t]] + end + end, +}) + +-- Diffview + +require("diffview").setup { + use_icons = false, + enhanced_diff_hl = true, +} + +-- Notify + +vim.cmd [[highlight link NotifyERRORBorder DiagnosticError]] +vim.cmd [[highlight link NotifyERRORIcon DiagnosticError]] +vim.cmd [[highlight link NotifyERRORTitle DiagnosticError]] + +vim.cmd [[highlight link NotifyWARNBorder DiagnosticWarn]] +vim.cmd [[highlight link NotifyWARNIcon DiagnosticWarn]] +vim.cmd [[highlight link NotifyWARNTitle DiagnosticWarn]] + +vim.cmd [[highlight link NotifyINFOBorder DiagnosticInfo]] +vim.cmd [[highlight link NotifyINFOIcon DiagnosticInfo]] +vim.cmd [[highlight link NotifyINFOTitle DiagnosticInfo]] + +vim.cmd [[highlight link NotifyDEBUGBorder DiagnosticHint]] +vim.cmd [[highlight link NotifyDEBUGIcon DiagnosticHint]] +vim.cmd [[highlight link NotifyDEBUGTitle DiagnosticHint]] + +vim.cmd [[highlight link NotifyDEBUGBorder GruvboxPurple]] +vim.cmd [[highlight link NotifyDEBUGIcon GruvboxPurple]] +vim.cmd [[highlight link NotifyDEBUGTitle GruvboxPurple]] + +require("notify").setup { stages = "static" } + +vim.notify = require("notify") + +-- Comment + +require("Comment").setup {} + +-- Indent Blankline + +vim.api.nvim_set_hl(0, "IndentBlanklineContextChar", { + fg = vim.g.current_gruvbox_colors.aqua[1], +}) + +require("indent_blankline").setup { + show_current_context = true, + show_current_context_start = true, +} + +-- Local config + +function isModuleAvailable(name) + if package.loaded[name] then + return true + else + for _, searcher in ipairs(package.searchers or package.loaders) do + local loader = searcher(name) + if type(loader) == "function" then + package.preload[name] = loader + return true + end + end + return false + end +end + +vim.opt.runtimepath:append "~/.config/nvim" + +if isModuleAvailable "local_config" then + require "local_config" +end diff --git a/dotfiles/vim/lua/vim-dev.lua b/dotfiles/vim/lua/vim-dev.lua new file mode 100644 index 0000000..a852447 --- /dev/null +++ b/dotfiles/vim/lua/vim-dev.lua @@ -0,0 +1,95 @@ +local lspconfig = require "lspconfig" + +local function on_attach(client, bufnr) + local opts = { noremap = true, silent = true, buffer = bufnr } + + local telescope_builtin = require "telescope.builtin" + + local function desc(tbl1, description) + return vim.tbl_extend("force", tbl1, { desc = description }) + end + + vim.keymap.set("n", "gD", vim.lsp.buf.declaration, desc(opts, "LSP declaration")) + vim.keymap.set("n", "gd", telescope_builtin.lsp_definitions, desc(opts, "LSP Definitions")) + vim.keymap.set("n", "K", vim.lsp.buf.hover, desc(opts, "LSP Hover")) + + vim.keymap.set("n", "gr", telescope_builtin.lsp_references, desc(opts, "LSP References")) + + vim.keymap.set("n", "sa", vim.lsp.buf.code_action, desc(opts, "LSP Code Actions")) + vim.keymap.set("v", "sa", vim.lsp.buf.range_code_action, desc(opts, "LSP Code Actions")) + vim.keymap.set("n", "se", vim.diagnostic.open_float, desc(opts, "Local Diagnostics")) + vim.keymap.set("n", "sE", telescope_builtin.diagnostics, desc(opts, "Global Diagnostics")) + vim.keymap.set("n", "sl", vim.diagnostic.setloclist, desc(opts, "Diagnostics set LocList")) + vim.keymap.set("n", "sq", vim.diagnostic.setqflist, desc(opts, "Diagnostics set QFList")) + vim.keymap.set("n", "sr", vim.lsp.buf.rename, desc(opts, "LSP Rename")) + vim.keymap.set("n", "ss", telescope_builtin.lsp_document_symbols, desc(opts, "LSP Document Symbols")) + vim.keymap.set("n", "sS", telescope_builtin.lsp_workspace_symbols, desc(opts, "LSP Workspace Symbols")) + + vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, desc(opts, "Goto Next Diagnostic")) + vim.keymap.set("n", "]d", vim.diagnostic.goto_next, desc(opts, "Goto Prev Diagnostic")) + + -- Capability specific + + if client.server_capabilities.documentFormattingProvider then + vim.keymap.set("n", "sf", vim.lsp.buf.formatting, desc(opts, "Format buffer")) + end + + -- Rust specific + vim.keymap.set("n", "sh", "RustToggleInlayHints", opts) + + require("lsp_signature").on_attach { + hint_prefix = "param: ", + } +end + +local capabilities = require("cmp_nvim_lsp").default_capabilities() + +require("rust-tools").setup { + server = { + cmd = { vim.g.rust_analyzer_path }, + settings = { + ["rust-analyzer"] = { + checkOnSave = { + command = "clippy", + }, + experimental = { + procAttrMacros = true, + }, + }, + }, + on_attach = on_attach, + }, +} + +require("nlua.lsp.nvim").setup(lspconfig, { + cmd = { + string.format("%s/bin/lua-language-server", vim.g.sumneko_lua_base_path), + "-E", + string.format("%s/share/lua-language-server/main.lua", vim.g.sumneko_lua_base_path), + }, + on_attach = on_attach, +}) + +-- Refactoring +require("refactoring").setup {} + +-- Null LSP + +require("null-ls").setup({ + sources = { + require("null-ls").builtins.code_actions.gitrebase, + require("null-ls").builtins.code_actions.gitsigns, + require("null-ls").builtins.code_actions.refactoring.with { + filetypes = { "typescript", "javascript", "lua", "c", "cpp", "go", "python", "java", "php", "ruby" }, + }, + require("null-ls").builtins.code_actions.shellcheck, + require("null-ls").builtins.code_actions.statix, + require("null-ls").builtins.diagnostics.deadnix, + require("null-ls").builtins.diagnostics.shellcheck, + require("null-ls").builtins.diagnostics.statix, + require("null-ls").builtins.diagnostics.vale.with { + filetypes = { "markdown", "pandoc", "tex", "asciidoc" }, + }, + }, + on_attach = on_attach, +}) diff --git a/usecases/desktop/development.nix b/usecases/desktop/development.nix index 8fc2c85..c07a1a9 100644 --- a/usecases/desktop/development.nix +++ b/usecases/desktop/development.nix @@ -100,7 +100,8 @@ in (mapAttrsToList lspconfigFor config.vim.lsp); in mkMerge [ - (readFile ../../dotfiles/vim-dev.lua) + "require('vim-dev')" + "local lspconfig = require('lspconfig')" lspconfig ]; }; -- cgit v1.2.3