diff --git a/README.md b/README.md index 53d45fa..2768641 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,39 @@ -## nvim.nix - personal Neovim config that runs on nixOS but doesn't sacrifice portability +## nvim.nix - personal Neovim config. First-class nix support, but doesn't sacrifice portability ## Usage +Try it out! ```bash -nix run "github:iofq/nvim.nix" #neovim +nix run "github:iofq/nvim.nix" #nvim-min +``` + +Or use in a flake: +```nix +nvim = { + url = "github:iofq/nvim.nix"; +}; +... +pkgs = import nixpkgs { + overlays = [inputs.nvim.overlays.default] +} +... in configuration.nix +environment.systemPackages = with pkgs; [nvim]; ``` Or, grab an AppImage from the Releases page. ## What the hell? -This is a flake to build a Neovim package that includes my custom Lua config and dependencies. It then is bundled via CI into an AppImage. +This is a flake to build a Neovim package that includes my custom Lua config and dependencies. It then is bundled via Github Actions CI into an AppImage. ## Why the hell though? -I use these AppImages because I develop in a number of airgapped environments that make traditional dotfile management a nightmare. Downloading a single AppImage and copying it around is a more suckless way of managing this. +I use these AppImages because I develop in a number of airgapped environments that make traditional dotfile management a nightmare. Downloading a single AppImage and copying it around is a more suckless way of managing this, especially because the non `-min` AppImage on the releases page includes runtime tooling like linters, LSPs, debuggers, etc, that can't be installed using `meson.nvim` without internet. A single ~200mb AppImage contains my entire IDE! + +The config uses `lazy.nvim` for loading lua modules, meaning we still get its awesome dependency ordering and lazy loading, and the entire config in the `nvim/` dir can actually be slapped into `~/.config/nvim` and work out of the box in a non-nix setting, using Lazy to download plugins. + +For best performance, extract the AppImage using `./nvim.AppImage --appimage-extract`, then run the resulting AppRun binary inside the folder. This prevents you from having to extract the whole AppImage on startup each time which HEAVILY speeds up launch times, at the cost of more disk space usage. ## kickstart-nix-nvim -This repo is based off https://github.com/nix-community/kickstart-nix.nvim +This repo is based off https://github.com/nix-community/kickstart-nix.nvim, with some changes to enable `lazy.nvim` instead of neovim's native plugin loading. + +The trick for enabling both nix and non-nix usage: in `mkNeovim.nix`, we prepend a `lazy_opts` variable to `init.lua` with some nix-specific Lazy configuration (we make Lazy treat each neovim plugin installed via nix as a local "dev" plugin, and show it where to find the lua files in the nix path via `packpath`). Later in the init file, we check for the existence of this variable. If it already is set, we know we're running from a nix config and can setup Lazy accordingly. If not, we can bootstrap Lazy for non-nix usage. diff --git a/flake.lock b/flake.lock index 49d6df2..2898d1d 100644 --- a/flake.lock +++ b/flake.lock @@ -99,12 +99,30 @@ "type": "github" } }, + "nvim-early-retirement": { + "flake": false, + "locked": { + "lastModified": 1723897376, + "narHash": "sha256-+W3AG99nzgr36t9Sg192hb/MH8s0uGAPD0cLBnil+og=", + "owner": "chrisgrieser", + "repo": "nvim-early-retirement", + "rev": "2c36a5671b9d8f0d9e11b77c5a55de802bc45e34", + "type": "github" + }, + "original": { + "owner": "chrisgrieser", + "repo": "nvim-early-retirement", + "type": "github" + } + }, "root": { "inputs": { "flake-utils": "flake-utils", "gen-luarc": "gen-luarc", "nixpkgs": "nixpkgs_2", - "snipe-nvim": "snipe-nvim" + "nvim-early-retirement": "nvim-early-retirement", + "snipe-nvim": "snipe-nvim", + "workspace-diagnostics-nvim": "workspace-diagnostics-nvim" } }, "snipe-nvim": { @@ -137,6 +155,22 @@ "repo": "default", "type": "github" } + }, + "workspace-diagnostics-nvim": { + "flake": false, + "locked": { + "lastModified": 1723294887, + "narHash": "sha256-lBj4KUPmmhtpffYky/HpaTwY++d/Q9socp/Ys+4VeX0=", + "owner": "artemave", + "repo": "workspace-diagnostics.nvim", + "rev": "573ff93c47898967efdfbc6587a1a39e3c2d365e", + "type": "github" + }, + "original": { + "owner": "artemave", + "repo": "workspace-diagnostics.nvim", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index a7a38fe..b6eafa1 100644 --- a/flake.nix +++ b/flake.nix @@ -9,6 +9,14 @@ url = "github:leath-dub/snipe.nvim"; flake = false; }; + nvim-early-retirement = { + url = "github:chrisgrieser/nvim-early-retirement"; + flake = false; + }; + workspace-diagnostics-nvim = { + url = "github:artemave/workspace-diagnostics.nvim"; + flake = false; + }; }; outputs = inputs @ { diff --git a/nix/mkNeovim.nix b/nix/mkNeovim.nix index 898b312..289c987 100644 --- a/nix/mkNeovim.nix +++ b/nix/mkNeovim.nix @@ -91,60 +91,38 @@ with lib; src = nvimRtpSrc; buildPhase = '' - mkdir -p $out/nvim mkdir -p $out/lua - rm init.lua ''; installPhase = '' - cp -r after $out/after - rm -r after cp -r lua $out/lua rm -r lua - cp -r * $out/nvim ''; }; # The final init.lua content that we pass to the Neovim wrapper. # It wraps the user init.lua, prepends the lua lib directory to the RTP # and prepends the nvim and after directory to the RTP - # It also adds logic for bootstrapping dev plugins (for plugin developers) - initLua = - '' - vim.loader.enable() - -- prepend lua directory + initLua = '' vim.opt.rtp:prepend('${nvimRtp}/lua') - '' - # Wrap init.lua - + (builtins.readFile ../nvim/init.lua) - # Bootstrap/load dev plugins - + optionalString (devPlugins != []) ( - '' - local dev_pack_path = vim.fn.stdpath('data') .. '/site/pack/dev' - local dev_plugins_dir = dev_pack_path .. '/opt' - local dev_plugin_path - '' - + strings.concatMapStringsSep - "\n" - (plugin: '' - dev_plugin_path = dev_plugins_dir .. '/${plugin.name}' - if vim.fn.empty(vim.fn.glob(dev_plugin_path)) > 0 then - vim.notify('Bootstrapping dev plugin ${plugin.name} ...', vim.log.levels.INFO) - vim.cmd('!${pkgs.git}/bin/git clone ${plugin.url} ' .. dev_plugin_path) - end - vim.cmd('packadd! ${plugin.name}') - '') - devPlugins - ) - # Prepend nvim and after directories to the runtimepath - # NOTE: This is done after init.lua, - # because of a bug in Neovim that can cause filetype plugins - # to be sourced prematurely, see https://github.com/neovim/neovim/issues/19008 - # We prepend to ensure that user ftplugins are sourced before builtin ftplugins. - + '' - vim.opt.rtp:prepend('${nvimRtp}/nvim') - vim.opt.rtp:prepend('${nvimRtp}/after') - ''; + lazy_opts = { + performance = { + reset_packpath = false, + rtp = { reset = false, }, + }, + dev = { + path = "${pkgs.neovimUtils.packDir neovimConfig.packpathDirs}/pack/myNeovimPackages/start", + patterns = {""}, + }, + install = { missing = false, }, + spec = {{ import = "plugins" }}, + disabled_plugins = { + "netrwPlugin", + "tutor", + "zipPlugin", + }, + } + '' + (builtins.readFile ../nvim/init.lua); # Add arguments to the Neovim wrapper script extraMakeWrapperArgs = builtins.concatStringsSep " " ( diff --git a/nix/neovim-overlay.nix b/nix/neovim-overlay.nix index 40896cb..d4cb123 100644 --- a/nix/neovim-overlay.nix +++ b/nix/neovim-overlay.nix @@ -11,6 +11,8 @@ with final.pkgs.lib; let version = src.lastModifiedDate; }; snipe-nvim = mkNvimPlugin inputs.snipe-nvim "snipe-nvim"; + nvim-early-retirement = mkNvimPlugin inputs.nvim-early-retirement "nvim-early-retirement"; + workspace-diagnostics-nvim = mkNvimPlugin inputs.workspace-diagnostics-nvim "workspace-diagnostics-nvim"; mkNeovim = pkgs.callPackage ./mkNeovim.nix { inherit pkgs-wrapNeovim; }; @@ -26,7 +28,7 @@ with final.pkgs.lib; let eyeliner-nvim friendly-snippets gitsigns-nvim - lualine-nvim + lazy-nvim luasnip markview-nvim mini-nvim @@ -35,8 +37,13 @@ with final.pkgs.lib; let none-ls-nvim nightfox-nvim nvim-cmp + nvim-dap + nvim-dap-go + nvim-dap-ui + nvim-early-retirement nvim-lspconfig nvim-neoclip-lua + nvim-nio nvim-treesitter-context nvim-treesitter-textobjects (nvim-treesitter.withPlugins(p: with p; [ @@ -68,6 +75,7 @@ with final.pkgs.lib; let ])) nvim-web-devicons oil-nvim + outline-nvim scope-nvim snipe-nvim telescope-fzf-native-nvim @@ -75,29 +83,38 @@ with final.pkgs.lib; let toggleterm-nvim trouble-nvim undotree - which-key-nvim + workspace-diagnostics-nvim ]; - extraPackages = with pkgs; [ + basePackages = with pkgs; [ ripgrep - yamllint + ]; + extraPackages = with pkgs; [ + # linters puppet-lint + yamllint + + # LSPs gopls - python312Packages.jedi-language-server + lua-language-server nil phpactor + python312Packages.jedi-language-server + + # debuggers + delve ]; in { nvim-pkg = mkNeovim { plugins = all-plugins; appName = "nvim"; - inherit extraPackages; + extraPackages = basePackages ++ extraPackages; }; nvim-min-pkg = mkNeovim { plugins = all-plugins; appName = "nvim"; - extraPackages = []; + extraPackages = basePackages; }; nvim-luarc-json = final.mk-luarc-json { diff --git a/nvim/after/README.md b/nvim/after/README.md deleted file mode 100644 index a4b4ff2..0000000 --- a/nvim/after/README.md +++ /dev/null @@ -1,8 +0,0 @@ -## `after` directory - -Scripts put in - -- `after/plugin` will be sourced *after* init.lua - or any other scripts are sourced during startup. -- `after/ftplugin` will be sourced when opening a - filetype, *after* any other `ftplugin` scripts are sourced. diff --git a/nvim/after/plugin/color.lua b/nvim/after/plugin/color.lua deleted file mode 100644 index 0013e1b..0000000 --- a/nvim/after/plugin/color.lua +++ /dev/null @@ -1,31 +0,0 @@ -vim.cmd('colorscheme terafox') -vim.api.nvim_set_hl(0, 'GitSignsAdd', { fg = 'green', bold = true }) -vim.api.nvim_set_hl(0, 'GitSignsDelete', { fg = 'red', bold = true }) -vim.api.nvim_set_hl(0, 'GitSignsChange', { fg = 'green', bold = true }) -vim.api.nvim_set_hl(0, 'EyelinerPrimary', { underline = true }) -vim.api.nvim_set_hl(0, 'EyelinerSecondary', { underline = true }) - -vim.keymap.set('n', 'aa', 'AerialToggle!', { desc = 'Toggle Aerial' }) -vim.keymap.set('n', 'nb', vim.cmd.DiffviewOpen, { noremap = true, desc = '[g]it [d]iffview open' }) -vim.keymap.set( - 'n', - 'de', - 'Trouble diagnostics toggle focus=true filter.buf=0', - { noremap = true, desc = 'Trouble diagnostics' } -) - -local ts = require('telescope') -ts.load_extension('aerial') -vim.keymap.set( - 'n', - 'fs', - ts.extensions.aerial.aerial, - { noremap = true, silent = true, desc = 'Fuzzy find treesitter objects' } -) -ts.load_extension('scope') -vim.keymap.set( - 'n', - 'fb', - 'Telescope scope buffers', - { noremap = true, silent = true, desc = 'Pick buffers (scope.nvim)' } -) diff --git a/nvim/ftplugin/.gitkeep b/nvim/ftplugin/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/nvim/init.lua b/nvim/init.lua index 39aba7e..cb810f8 100644 --- a/nvim/init.lua +++ b/nvim/init.lua @@ -1,75 +1,27 @@ --- vim settings ++ mini.nvim.basics ----------------------------------------- -vim.opt.backspace = 'indent,eol,start' -vim.opt.clipboard = 'unnamedplus' -vim.opt.completeopt = 'menuone' -vim.opt.expandtab = true -- insert tabs as spaces -vim.opt.inccommand = 'split' -- incremental live completion -vim.opt.laststatus = 1 -vim.opt.list = true -vim.opt.nrformats:append('alpha') -- let Ctrl-a do letters as well -vim.opt.path:append('**') -- enable fuzzy :find ing -vim.opt.relativenumber = true -vim.opt.shadafile = 'NONE' -- disable shada -vim.opt.shiftwidth = 0 -- >> shifts by tabstop -vim.opt.showmatch = true -- highlight matching brackets -vim.opt.showmode = true -vim.opt.softtabstop = -1 -- backspace removes tabstop -vim.opt.swapfile = false -vim.opt.tabstop = 2 -- 2 space tabs are based -vim.opt.updatetime = 250 -- decrease update time -vim.opt.virtualedit = 'onemore' -vim.g.fzf_layout = { window = { width = 0.9, height = 0.6 } } - --- no highlight floats -vim.cmd([[ hi NormalFloat ctermbg=none ]]) - --- Switch tab length on the fly -vim.keymap.set('n', '\\t', function() - vim.o.tabstop = vim.o.tabstop == 2 and 4 or 2 -end, { silent = true, desc = 'toggle tabstop' }) - --- autocmd ----------------------------------------- -local undopath = '~/.local/share/nvim/undo' -vim.api.nvim_create_autocmd('VimEnter', { - command = 'silent !mkdir -p ' .. undopath, - group = vim.api.nvim_create_augroup('Init', {}), -}) - --- Configure Neovim diagnostic messages -local function prefix_diagnostic(prefix, diagnostic) - return string.format(prefix .. ' %s', diagnostic.message) +vim.g.mapleader = ' ' +-- If lazy_opts is set, we're running in wrapped neovim via nix +if not lazy_opts then + -- Bootstrapping lazy.nvim + local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim' + if not vim.loop.fs_stat(lazypath) then + vim.fn.system { + 'git', + 'clone', + '--filter=blob:none', + 'https://github.com/folke/lazy.nvim.git', + '--branch=stable', -- latest stable release + lazypath, + } + end + vim.opt.rtp:prepend(lazypath) + lazy_opts = { + spec = { { import = 'plugins' } }, + disabled_plugins = { + 'netrwPlugin', + 'tutor', + 'zipPlugin', + }, + } end -vim.diagnostic.config { - virtual_text = { - prefix = '', - format = function(diagnostic) - local severity = diagnostic.severity - if severity == vim.diagnostic.severity.ERROR then - return prefix_diagnostic('󰅚', diagnostic) - end - if severity == vim.diagnostic.severity.WARN then - return prefix_diagnostic('⚠', diagnostic) - end - if severity == vim.diagnostic.severity.INFO then - return prefix_diagnostic('ⓘ', diagnostic) - end - if severity == vim.diagnostic.severity.HINT then - return prefix_diagnostic('󰌶', diagnostic) - end - return prefix_diagnostic('■', diagnostic) - end, - }, - update_in_insert = false, - underline = true, - severity_sort = true, - float = { - focusable = false, - style = 'minimal', - border = 'rounded', - source = 'if_many', - header = '', - prefix = '', - }, -} +require('lazy').setup(lazy_opts) +require('config') diff --git a/nvim/lua/.gitkeep b/nvim/lua/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/nvim/lua/config/init.lua b/nvim/lua/config/init.lua new file mode 100644 index 0000000..71c116f --- /dev/null +++ b/nvim/lua/config/init.lua @@ -0,0 +1,92 @@ +vim.opt.backspace = 'indent,eol,start' +vim.opt.clipboard = 'unnamedplus' +vim.opt.completeopt = 'menuone' +vim.opt.expandtab = true -- insert tabs as spaces +vim.opt.inccommand = 'split' -- incremental live completion +vim.opt.laststatus = 1 +vim.opt.list = true +vim.opt.nrformats:append('alpha') -- let Ctrl-a do letters as well +vim.opt.path:append('**') -- enable fuzzy :find ing +vim.opt.relativenumber = true +vim.opt.shadafile = 'NONE' -- disable shada +vim.opt.shiftwidth = 0 -- >> shifts by tabstop +vim.opt.showmatch = true -- highlight matching brackets +vim.opt.showmode = true +vim.opt.signcolumn = 'no' +vim.opt.spell = false +vim.opt.softtabstop = -1 -- backspace removes tabstop +vim.opt.swapfile = false +vim.opt.tabstop = 2 -- 2 space tabs are based +vim.opt.updatetime = 250 -- decrease update time +vim.opt.virtualedit = 'onemore' +vim.opt.wrap = true +vim.g.fzf_layout = { window = { width = 0.9, height = 0.6 } } + +-- Switch tab length on the fly +vim.keymap.set('n', '\\t', function() + vim.o.tabstop = vim.o.tabstop == 2 and 4 or 2 +end, { silent = true, desc = 'toggle tabstop' }) + +-- autocmd +---------------------------------------- +local undopath = '~/.local/share/nvim/undo' +vim.api.nvim_create_autocmd('VimEnter', { + command = 'silent !mkdir -p ' .. undopath, + group = vim.api.nvim_create_augroup('Init', {}), +}) +-- open :g in buffers +vim.api.nvim_create_autocmd('BufWinEnter', { + pattern = '*', + callback = function(event) + if vim.bo[event.buf].filetype == 'help' then + vim.cmd.only() + vim.keymap.set('n', 'q', vim.cmd.bdelete, { noremap = true, silent = true }) + vim.bo.buflisted = true + end + end, +}) + +-- Configure Neovim diagnostic messages +local function prefix_diagnostic(prefix, diagnostic) + return string.format(prefix .. ' %s', diagnostic.message) +end +vim.diagnostic.config { + virtual_text = { + prefix = '', + format = function(diagnostic) + local severity = diagnostic.severity + if severity == vim.diagnostic.severity.ERROR then + return prefix_diagnostic('󰅚', diagnostic) + end + if severity == vim.diagnostic.severity.WARN then + return prefix_diagnostic('⚠', diagnostic) + end + if severity == vim.diagnostic.severity.INFO then + return prefix_diagnostic('ⓘ', diagnostic) + end + if severity == vim.diagnostic.severity.HINT then + return prefix_diagnostic('󰌶', diagnostic) + end + return prefix_diagnostic('■', diagnostic) + end, + }, + update_in_insert = false, + underline = true, + severity_sort = true, + float = { + focusable = false, + style = 'minimal', + border = 'rounded', + source = 'if_many', + header = '', + prefix = '', + }, +} + +-- random keymaps +vim.keymap.set('n', 'gq', vim.cmd.bdelete, { silent = true }) +vim.keymap.set('n', 'gr', 'gT', { noremap = true, silent = true }) +vim.keymap.set('n', 'n', 'nzz', { noremap = true, silent = true }) +vim.keymap.set('n', 'N', 'Nzz', { noremap = true, silent = true }) +vim.keymap.set({ 'v', 'i' }, 'wq', 'l', { noremap = true, silent = true }) +vim.keymap.set('n', 'x', '"rd', { remap = true, silent = true }) diff --git a/nvim/lua/plugins/completion.lua b/nvim/lua/plugins/completion.lua new file mode 100644 index 0000000..fc4dcc7 --- /dev/null +++ b/nvim/lua/plugins/completion.lua @@ -0,0 +1,98 @@ +return { + { + 'hrsh7th/nvim-cmp', + event = 'VeryLazy', + dependencies = { + 'hrsh7th/cmp-buffer', + 'hrsh7th/cmp-cmdline', + 'hrsh7th/cmp-path', + 'hrsh7th/cmp-nvim-lsp', + 'ray-x/cmp-treesitter', + 'L3MON4D3/LuaSnip', + 'saadparwaiz1/cmp_luasnip', + }, + config = function() + local cmp = require('cmp') + cmp.setup { + snippet = { + expand = function(args) + require('luasnip').lsp_expand(args.body) + end, + }, + experimental = { + native_menu = false, + ghost_text = true, + }, + 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. + }, + sources = cmp.config.sources({ + { name = 'nvim_lsp' }, + { name = 'luasnip' }, + }, { + { name = 'buffer' }, + }), + } + + cmp.setup.cmdline({ '/', '?' }, { + mapping = cmp.mapping.preset.cmdline(), + sources = { + { name = 'buffer' }, + }, + }) + + cmp.setup.cmdline(':', { + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ + { name = 'path' }, + }, { + { name = 'cmdline' }, + }), + matching = { disallow_symbol_nonprefix_matching = false }, + }) + end, + }, + { + 'L3MON4D3/LuaSnip', + event = 'VeryLazy', + dependencies = { 'rafamadriz/friendly-snippets' }, + config = function() + local ls = require('luasnip') + ls.config.set_config { + history = true, + updateevents = 'TextChanged, TextChangedI', + } + require('luasnip.loaders.from_vscode').lazy_load() + + vim.keymap.set({ 'i', 's' }, '', function() + if ls.expand_or_jumpable() then + ls.expand_or_jump() + end + end, { silent = true }) + + vim.keymap.set({ 'i', 's' }, '', function() + if ls.jumpable(-1) then + ls.jump(-1) + end + end, { silent = true }) + + vim.keymap.set({ 'i', 's' }, '', function() + if ls.choice_active() then + ls.change_choice(1) + end + end, { silent = true }) + + -------------------- + -- Snippets -- + -------------------- + local fmta = require('luasnip.extras.fmt').fmta + ls.add_snippets('go', { + ls.snippet('ie', fmta('if err != nil {\n\treturn \n}', { err = ls.insert_node(1, 'err') })), + }) + end, + }, +} diff --git a/nvim/lua/plugins/debug.lua b/nvim/lua/plugins/debug.lua new file mode 100644 index 0000000..9de41c8 --- /dev/null +++ b/nvim/lua/plugins/debug.lua @@ -0,0 +1,61 @@ +return { + { + 'rcarriga/nvim-dap-ui', + event = 'VeryLazy', + dependencies = { + 'nvim-neotest/nvim-nio', + }, + }, + { + 'mfussenegger/nvim-dap', + event = 'VeryLazy', + dependencies = { + 'leoluz/nvim-dap-go', + 'rcarriga/nvim-dap-ui', + }, + config = function() + local d = require('dap') + local w = require('dap.ui.widgets') + local ui = require('dapui') + require('dap-go').setup() + ui.setup() + + local scopes = nil + vim.keymap.set('n', 'za', function() + ui.toggle() + end, { desc = 'toggle dapui' }) + vim.keymap.set('n', 'zz', function() + scopes = w.sidebar(w.scopes, {}, 'split') + d.continue() + end, { desc = 'start debugger' }) + vim.keymap.set('n', 'zn', function() + d.step_over() + end, { desc = 'step over' }) + vim.keymap.set('n', 'zi', function() + d.step_into() + end, { desc = 'step into' }) + vim.keymap.set('n', 'zo', function() + d.step_out() + end, { desc = 'step out' }) + vim.keymap.set('n', 'zx', function() + d.toggle_breakpoint() + end, { desc = 'toggle_breakpoint' }) + vim.keymap.set('n', 'zr', function() + d.run_last() + end, { desc = 'run prev' }) + vim.keymap.set({ 'n', 'v' }, 'zh', function() + ui.eval() + end, { desc = 'hover' }) + vim.keymap.set({ 'n', 'v' }, 'zp', function() + require('dap.ui.widgets').preview() + end, { desc = 'preview' }) + vim.keymap.set('n', 'zf', function() + local widgets = require('dap.ui.widgets') + widgets.centered_float(widgets.frames) + end, { desc = 'view frames' }) + vim.keymap.set('n', 'zs', function() + scopes.toggle() + end, { desc = 'toggle scope view' }) + end, + }, +} diff --git a/nvim/lua/plugins/lsp.lua b/nvim/lua/plugins/lsp.lua new file mode 100644 index 0000000..fbbdcf9 --- /dev/null +++ b/nvim/lua/plugins/lsp.lua @@ -0,0 +1,197 @@ +return { + { + 'folke/trouble.nvim', + event = 'VeryLazy', + dependencies = { + 'artemave/workspace-diagnostics.nvim', + }, + config = function() + require('trouble').setup() + vim.keymap.set( + 'n', + 'de', + 'Trouble diagnostics toggle focus=true', + { noremap = true, desc = 'Trouble diagnostics' } + ) + vim.keymap.set( + 'n', + 'dE', + 'Trouble diagnostics toggle focus=true filter.buf=0', + { noremap = true, desc = 'Trouble diagnostics (currrent buffer)' } + ) + vim.keymap.set('n', 'dw', function() + for _, client in ipairs(vim.lsp.get_clients { bufnr = 0 }) do + require('workspace-diagnostics').populate_workspace_diagnostics(client, 0) + end + end, { noremap = true, desc = 'Populate Trouble workspace diagnostics' }) + end, + }, + { + 'neovim/nvim-lspconfig', + event = 'VeryLazy', + dependencies = { + 'hrsh7th/cmp-nvim-lsp', + }, + config = function() + local lspconfig = require('lspconfig') + lspconfig.util.default_config.capabilities = vim.tbl_deep_extend( + 'force', + lspconfig.util.default_config.capabilities, + require('cmp_nvim_lsp').default_capabilities() + ) + + lspconfig.gopls.setup { + settings = { + gopls = { + gofumpt = true, + codelenses = { + gc_details = true, + test = true, + }, + analyses = { + unusedvariable = true, + shadow = true, + }, + hints = { + assignVariableTypes = true, + constantValues = true, + functionTypeParameters = true, + rangeVariableTypes = true, + }, + usePlaceholders = true, + staticcheck = true, + }, + }, + on_attach = function() + vim.api.nvim_command('au BufWritePre lua vim.lsp.buf.format { async = false }') + end, + } + lspconfig.jedi_language_server.setup {} + lspconfig.nil_ls.setup {} + lspconfig.phpactor.setup {} + lspconfig.lua_ls.setup { + on_init = function(client) + local path = client.workspace_folders[1].name + if vim.loop.fs_stat(path .. '/.luarc.json') or vim.loop.fs_stat(path .. '/.luarc.jsonc') then + return + end + + client.config.settings.Lua = vim.tbl_deep_extend('force', client.config.settings.Lua, { + runtime = { + version = 'LuaJIT', + }, + workspace = { + checkThirdParty = false, + library = { + vim.env.VIMRUNTIME, + }, + }, + }) + end, + settings = { + Lua = {}, + }, + } + vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Prev diagnostic' }) + vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Next diagnostic' }) + + vim.api.nvim_create_autocmd('LspAttach', { + group = vim.api.nvim_create_augroup('UserLspConfig', {}), + callback = function(ev) + local bufnr = ev.buf + local client = vim.lsp.get_client_by_id(ev.data.client_id) + require('workspace-diagnostics').populate_workspace_diagnostics(client, bufnr) + vim.keymap.set( + 'n', + 'K', + vim.lsp.buf.hover, + { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP hover' } + ) + vim.keymap.set( + 'n', + 'rn', + vim.lsp.buf.rename, + { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP Rename' } + ) + vim.keymap.set( + { 'n', 'v' }, + 'da', + vim.lsp.buf.code_action, + { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP code action' } + ) + vim.keymap.set( + 'n', + 'dd', + 'Telescope lsp_definitions', + { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP definitions' } + ) + vim.keymap.set( + 'n', + 'di', + 'Telescope lsp_implementations', + { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP implementations' } + ) + vim.keymap.set( + 'n', + 'dr', + 'Telescope lsp_references', + { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP references' } + ) + vim.keymap.set( + 'n', + 'dt', + 'Telescope lsp_type_definitions', + { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP type defs' } + ) + vim.keymap.set( + 'n', + 'ds', + 'Telescope lsp_document_symbols', + { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP symbols' } + ) + vim.keymap.set( + 'n', + 'dl', + vim.lsp.codelens.run, + { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP codelens' } + ) + vim.keymap.set('n', 'dh', function() + vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) + end, { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP hints toggle' }) + vim.keymap.set('n', 'df', function() + vim.lsp.buf.format { async = true } + end, { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP format' }) + -- Auto-refresh code lenses + if not client then + return + end + local group = vim.api.nvim_create_augroup(string.format('lsp-%s-%s', bufnr, client.id), {}) + if client.server_capabilities.codeLensProvider then + vim.api.nvim_create_autocmd({ 'InsertLeave', 'BufWritePost', 'TextChanged' }, { + group = group, + callback = function() + vim.lsp.codelens.refresh { bufnr = bufnr } + end, + buffer = bufnr, + }) + vim.lsp.codelens.refresh { bufnr = bufnr } + end + end, + }) + vim.api.nvim_exec_autocmds('FileType', {}) + end, + }, + { + 'nvimtools/none-ls.nvim', + event = 'VeryLazy', + config = function() + local null = require('null-ls') + null.setup { + sources = { + null.builtins.diagnostics.puppet_lint, + null.builtins.diagnostics.yamllint, + }, + } + end, + }, +} diff --git a/nvim/lua/plugins/mini.lua b/nvim/lua/plugins/mini.lua new file mode 100644 index 0000000..ad495c8 --- /dev/null +++ b/nvim/lua/plugins/mini.lua @@ -0,0 +1,155 @@ +return { + { + 'echasnovski/mini.nvim', + event = 'VeryLazy', + config = function() + require('mini.ai').setup() + require('mini.comment').setup() + require('mini.pairs').setup() + require('mini.statusline').setup { + content = { + active = function() + local mode, mode_hl = MiniStatusline.section_mode {} + local git = function() + local summary = vim.b.gitsigns_head + if summary == nil then + return '' + end + summary = '~' .. summary + + return summary == '' and '' or summary + end + local diff = function() + local summary = vim.b.gitsigns_status + if summary == nil then + return '' + end + + return summary + end + local diagnostics = MiniStatusline.section_diagnostics { trunc_width = 75 } + local filename = MiniStatusline.section_filename { trunc_width = 140 } + local search = MiniStatusline.section_searchcount { trunc_width = 75 } + + return MiniStatusline.combine_groups { + { hl = mode_hl, strings = { mode } }, + '%<', -- Mark general truncate point + { hl = 'MiniStatuslineFilename', strings = { filename } }, + '%=', -- End left alignment + { hl = 'MiniStatusDevinfo', strings = { git(), diff(), diagnostics } }, + { hl = mode_hl, strings = { search } }, + } + end, + inactive = function() + local filename = MiniStatusline.section_filename { trunc_width = 140 } + + return MiniStatusline.combine_groups { + { hl = 'MiniStatuslineFilename', strings = { filename } }, + } + end, + }, + } + vim.opt.showmode = false + + local miniclue = require('mini.clue') + miniclue.setup { + triggers = { + { mode = 'n', keys = '' }, + { mode = 'n', keys = 'g' }, + { mode = 'n', keys = "'" }, + { mode = 'n', keys = '`' }, + { mode = 'n', keys = '"' }, + { mode = 'n', keys = '' }, + { mode = 'n', keys = 'z' }, + }, + + clues = { + miniclue.gen_clues.g(), + miniclue.gen_clues.marks(), + miniclue.gen_clues.registers(), + miniclue.gen_clues.windows(), + miniclue.gen_clues.z(), + }, + } + -- Add surrounding with sa + -- Delete surrounding with sd. + -- Replace surrounding with sr. + -- Find surrounding with sf or sF (move cursor right or left). + -- Highlight surrounding with sh. + -- 'f' - function call (string of alphanumeric symbols or '_' or '.' followed by balanced '()'). In "input" finds function call, in "output" prompts user to enter function name. + -- 't' - tag. In "input" finds tag with same identifier, in "output" prompts user to enter tag name. + -- All symbols in brackets '()', '[]', '{}', '<>". + -- '?' - interactive. Prompts user to enter left and right parts. + require('mini.surround').setup() + + require('mini.trailspace').setup() + vim.api.nvim_create_user_command('Trim', function() + require('mini.trailspace').trim() + end, {}) + + -- prefix \ + -- `b` - |'background'|. + -- `c` - |'cursorline'|. + -- `C` - |'cursorcolumn'|. + -- `d` - diagnostic (via |vim.diagnostic.enable()| and |vim.diagnostic.disable()|). + -- `h` - |'hlsearch'| (or |v:hlsearch| to be precise). + -- `i` - |'ignorecase'|. + -- `l` - |'list'|. + -- `n` - |'number'|. + -- `r` - |'relativenumber'|. + -- `s` - |'spell'|. + -- `w` - |'wrap'|. + require('mini.basics').setup { + mappings = { + windows = true, + }, + } + + local map = require('mini.map') + map.setup { + symbols = { + scroll_line = '┃', + scroll_view = '', + }, + integrations = { + map.gen_integration.builtin_search(), + map.gen_integration.diagnostic(), + map.gen_integration.gitsigns(), + }, + window = { + show_integration_count = false, + winblend = 0, + width = 5, + }, + } + vim.keymap.set('n', 'nm', map.toggle, { noremap = true, desc = 'minimap open' }) + + -- gS + require('mini.splitjoin').setup { + detect = { separator = '[,;\n]' }, + } + + -- Replace text with register 'gr', + -- Sort text 'gs', + require('mini.operators').setup() + require('mini.jump2d').setup { mappings = { start_jumping = 'S' } } + + local indent = require('mini.indentscope') + indent.setup { + draw = { delay = 0 }, + } + indent.gen_animation.none() + + require('mini.notify').setup { + window = { + winblend = 0, + config = { + anchor = 'SE', + border = 'double', + row = vim.o.lines, + }, + }, + } + end, + }, +} diff --git a/nvim/lua/plugins/misc.lua b/nvim/lua/plugins/misc.lua new file mode 100644 index 0000000..95bc26d --- /dev/null +++ b/nvim/lua/plugins/misc.lua @@ -0,0 +1,220 @@ +return { + { + 'danymat/neogen', + keys = { + { 'nd', 'Neogen', { noremap = true, silent = true, desc = 'Neogen - gen comments' } }, + }, + }, + { + 'akinsho/toggleterm.nvim', + event = 'VeryLazy', + opts = { + open_mapping = [[]], + direction = 'float', + close_on_exit = true, + autochdir = true, + }, + }, + { + 'jinh0/eyeliner.nvim', + event = 'VeryLazy', + config = function() + vim.api.nvim_set_hl(0, 'EyelinerPrimary', { underline = true }) + vim.api.nvim_set_hl(0, 'EyelinerSecondary', { underline = true }) + end, + }, + { 'OXY2DEV/markview.nvim', event = 'VeryLazy' }, + { 'tiagovla/scope.nvim', event = 'VeryLazy' }, + { + 'chrisgrieser/nvim-early-retirement', + event = 'VeryLazy', + opts = { minimumBufferNum = 6 }, + }, + { + 'AckslD/nvim-neoclip.lua', + event = 'VeryLazy', + dependencies = { + 'nvim-telescope/telescope.nvim', + }, + opts = { + default_register = '+', + }, + config = function(_, opts) + require('neoclip').setup(opts) + vim.keymap.set( + 'n', + 'fp', + 'Telescope neoclip', + { noremap = true, silent = true, desc = 'Pick clipboard history' } + ) + end, + }, + { + 'leath-dub/snipe.nvim', + event = 'VeryLazy', + opts = { + ui = { + position = 'center', + }, + sort = 'last', + }, + config = function(_, opts) + local snipe = require('snipe') + snipe.setup(opts) + vim.keymap.set( + 'n', + 'fb', + snipe.open_buffer_menu, + { noremap = true, silent = true, desc = 'Pick buffers (snipe.nvim)' } + ) + end, + }, + { + 'sindrets/diffview.nvim', + event = 'VeryLazy', + opts = { + enhanced_diff_hl = true, + default_args = { + DiffviewOpen = { '--imply-local' }, + }, + }, + config = function() + vim.keymap.set('n', 'nb', vim.cmd.DiffviewOpen, { noremap = true, desc = 'diffview open' }) + end, + }, + { + 'NeogitOrg/neogit', + opts = { + disable_builtin_notifications = true, + integrations = { + diffview = true, + telescope = true, + fzf_lua = true, + }, + }, + keys = { + { + 'ng', + function() + require('neogit').open() + end, + { noremap = true, silent = true, desc = 'Neogit' }, + }, + }, + }, + { + 'stevearc/oil.nvim', + opts = { + watch_for_changes = true, + columns = { + 'permissions', + 'size', + }, + view_options = { + show_hidden = true, + }, + keymaps = { + ['wq'] = 'actions.close', + }, + }, + keys = { + { + 'nc', + function() + require('oil').toggle_float() + end, + { noremap = true, silent = true }, + }, + }, + }, + { + 'mbbill/undotree', + event = 'VeryLazy', + keys = { + { 'nu', 'UndotreeToggle' }, + }, + config = function() + vim.g.undotree_ShortIndicators = 1 + vim.g.undotree_SetFocusWhenToggle = 1 + end, + }, + { + 'EdenEast/nightfox.nvim', + lazy = false, + priority = 10000, + opts = { + options = { + transparent = true, + terminal_colors = false, + }, + }, + config = function(_, opts) + require('nightfox').setup(opts) + vim.cmd('colorscheme terafox') + vim.api.nvim_set_hl(0, 'MiniNotifyNormal', { bg = 'none' }) + vim.api.nvim_set_hl(0, 'MiniNotifyTitle', { bg = 'none' }) + vim.api.nvim_set_hl(0, 'MiniNotifyBorder', { bg = 'none' }) + vim.api.nvim_set_hl(0, 'MiniMapNormal', { bg = 'none' }) + vim.api.nvim_set_hl(0, 'MiniClueNormal', { bg = 'none' }) + vim.api.nvim_set_hl(0, 'StatusLine', { bg = 'none' }) + vim.api.nvim_set_hl(0, 'StatusLineNC', { bg = 'none' }) + vim.api.nvim_set_hl(0, 'GitSignsAdd', { fg = 'green', bold = true }) + vim.api.nvim_set_hl(0, 'GitSignsDelete', { fg = 'red', bold = true }) + vim.api.nvim_set_hl(0, 'GitSignsChange', { fg = 'green', bold = true }) + end, + }, + { + 'lewis6991/gitsigns.nvim', + event = 'VeryLazy', + opts = { + signcolumn = false, + numhl = true, + on_attach = function() + local gs = package.loaded.gitsigns + vim.keymap.set('n', 'gg', gs.preview_hunk, { desc = 'git preview hunk' }) + vim.keymap.set('n', 'gr', gs.reset_hunk, { desc = 'git reset hunk' }) + vim.keymap.set('n', 'gb', function() + gs.blame_line { full = true } + end, { desc = 'git blame_line' }) + vim.keymap.set('v', 'gr', function() + gs.reset_hunk { vim.fn.line('.'), vim.fn.line('v') } + end, { desc = 'git reset hunk' }) + + -- Navigation + vim.keymap.set('n', ']g', function() + if vim.wo.diff then + return ']c' + end + vim.schedule(function() + gs.next_hunk() + end) + return '' + end, { expr = true }) + + vim.keymap.set('n', '[g', function() + if vim.wo.diff then + return '[c' + end + vim.schedule(function() + gs.prev_hunk() + end) + return '' + end, { expr = true }) + end, + }, + }, + { + 'hedyhli/outline.nvim', + cmd = { 'Outline', 'OutlineOpen' }, + keys = { + { 'no', 'Outline', desc = 'Toggle outline' }, + }, + opts = { + outline_window = { + position = 'left', + width = 30, + auto_close = true, + }, + }, + }, +} diff --git a/nvim/lua/plugins/telescope.lua b/nvim/lua/plugins/telescope.lua new file mode 100644 index 0000000..e6321aa --- /dev/null +++ b/nvim/lua/plugins/telescope.lua @@ -0,0 +1,95 @@ +return { + { + 'nvim-telescope/telescope-fzf-native.nvim', + event = 'VeryLazy', + build = 'make', + }, + { + 'nvim-telescope/telescope.nvim', + event = 'VeryLazy', + dependencies = { + 'nvim-lua/plenary.nvim', + 'nvim-telescope/telescope-fzf-native.nvim', + 'nvim-tree/nvim-web-devicons', + 'nvim-treesitter/nvim-treesitter', + 'tiagovla/scope.nvim', + }, + config = function() + local telescope = require('telescope') + local actions = require('telescope.actions') + telescope.setup { + defaults = { + layout_strategy = 'vertical', + layout_config = { width = 0.90 }, + prompt_title = false, + results_title = false, + preview_title = false, + vimgrep_arguments = { + 'rg', + '-L', + '--color=never', + '--no-heading', + '--hidden', + '--with-filename', + '--line-number', + '--column', + '--smart-case', + }, + preview = { treesitter = true }, + path_display = { 'truncate' }, + mappings = { + i = { + ['wq'] = actions.close, + [''] = actions.close, + [''] = actions.move_selection_previous, + [''] = actions.move_selection_next, + }, + }, + }, + } + telescope.load_extension('fzf') + telescope.load_extension('scope') + + local b = require('telescope.builtin') + -- Fall back to find_files if not in a git repo + local project_files = function() + local opts = {} -- define here if you want to define something + local ok = pcall(b.git_files, opts) + if not ok then + b.find_files(opts) + end + end + + vim.keymap.set('n', 'ff', project_files, { noremap = true, silent = true, desc = 'Fuzzy find git files' }) + vim.keymap.set('n', 'fg', b.find_files, { noremap = true, silent = true, desc = 'Fuzzy find files' }) + vim.keymap.set( + 'n', + 'fc', + b.command_history, + { noremap = true, silent = true, desc = 'Fuzzy find command_history' } + ) + vim.keymap.set('n', 'fa', b.live_grep, { noremap = true, silent = true, desc = 'Fuzzy find grep' }) + vim.keymap.set( + 'n', + 'f8', + b.grep_string, + { noremap = true, silent = true, desc = 'Fuzzy find grep current word' } + ) + vim.keymap.set('n', 'fq', b.quickfix, { noremap = true, silent = true, desc = 'Fuzzy find quickfix' }) + vim.keymap.set('n', 'f?', b.builtin, { noremap = true, silent = true, desc = 'See all pickers' }) + vim.keymap.set('n', 'f', b.resume, { noremap = true, silent = true, desc = 'Fuzzy find resume' }) + vim.keymap.set( + 'n', + 'fs', + b.lsp_document_symbols, + { noremap = true, silent = true, desc = 'Fuzzy find treesitter objects' } + ) + vim.keymap.set( + 'n', + '', + 'Telescope scope buffers', + { noremap = true, silent = true, desc = 'Pick buffers (scope.nvim)' } + ) + end, + }, +} diff --git a/nvim/lua/plugins/treesitter.lua b/nvim/lua/plugins/treesitter.lua new file mode 100644 index 0000000..44c53e5 --- /dev/null +++ b/nvim/lua/plugins/treesitter.lua @@ -0,0 +1,77 @@ +return { + { + 'nvim-treesitter/nvim-treesitter', + event = 'VeryLazy', + dependencies = { + 'nvim-treesitter/nvim-treesitter-context', + 'nvim-treesitter/nvim-treesitter-textobjects', + }, + config = function() + require('nvim-treesitter.configs').setup { + ensure_installed = {}, + highlight = { + enable = true, + disable = function(_, buf) + local max_filesize = 100 * 1024 -- 100 KiB + local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf)) + if ok and stats and stats.size > max_filesize then + return true + end + end, + additional_vim_regex_highlighting = false, + }, + indent = { + enable = true, + }, + autopairs = { + enable = true, + }, + textobjects = { + select = { + enable = true, + lookahead = true, + keymaps = { + ['af'] = '@function.outer', + ['if'] = '@function.inner', + ['aa'] = '@statement.outer', + ['ia'] = '@parameter.inner', + }, + }, + move = { + enable = true, + goto_next_start = { + [']a'] = '@parameter.inner', + [']f'] = '@function.outer', + }, + goto_previous_start = { + ['[a'] = '@parameter.inner', + ['[f'] = '@function.outer', + }, + }, + swap = { + enable = true, + swap_next = { + ['s]'] = '@parameter.inner', + }, + swap_previous = { + ['s['] = '@parameter.inner', + }, + }, + }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = '', + node_incremental = '', + node_decremental = '', + }, + }, + } + + require('treesitter-context').setup { + max_lines = 2, + min_window_height = 50, + } + end, + }, +} diff --git a/nvim/plugin/aerial.lua b/nvim/plugin/aerial.lua deleted file mode 100644 index 4e27aa7..0000000 --- a/nvim/plugin/aerial.lua +++ /dev/null @@ -1,16 +0,0 @@ -if vim.g.did_load_aerial_plugin then - return -end -vim.g.did_load_aerial_plugin = true - -require('aerial').setup { - autojump = true, - on_attach = function(bufnr) - vim.keymap.set('n', '[[', 'AerialPrev', { buffer = bufnr }) - vim.keymap.set('n', ']]', 'AerialNext', { buffer = bufnr }) - end, - close_autonatic_events = { - unfocus, - switch_buffer, - }, -} diff --git a/nvim/plugin/colors.lua b/nvim/plugin/colors.lua deleted file mode 100644 index 3986737..0000000 --- a/nvim/plugin/colors.lua +++ /dev/null @@ -1,11 +0,0 @@ -if vim.g.did_load_colors_plugin then - return -end -vim.g.did_load_colors_plugin = true - -require('nightfox').setup { - options = { - transparent = true, -- Disable setting background - terminal_colors = false, -- Set terminal colors (vim.g.terminal_color_*) used in `:terminal` - }, -} diff --git a/nvim/plugin/completion.lua b/nvim/plugin/completion.lua deleted file mode 100644 index 5e3e1b4..0000000 --- a/nvim/plugin/completion.lua +++ /dev/null @@ -1,47 +0,0 @@ -if vim.g.did_load_completion_plugin then - return -end -vim.g.did_load_completion_plugin = true -local cmp = require('cmp') - -cmp.setup { - snippet = { - expand = function(args) - require('luasnip').lsp_expand(args.body) - end, - }, - experimental = { - native_menu = false, - ghost_text = true, - }, - 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. - }, - sources = cmp.config.sources({ - { name = 'nvim_lsp' }, - { name = 'luasnip' }, - }, { - { name = 'buffer' }, - }), -} - -cmp.setup.cmdline({ '/', '?' }, { - mapping = cmp.mapping.preset.cmdline(), - sources = { - { name = 'buffer' }, - }, -}) - -cmp.setup.cmdline(':', { - mapping = cmp.mapping.preset.cmdline(), - sources = cmp.config.sources({ - { name = 'path' }, - }, { - { name = 'cmdline' }, - }), - matching = { disallow_symbol_nonprefix_matching = false }, -}) diff --git a/nvim/plugin/gitsigns.lua b/nvim/plugin/gitsigns.lua deleted file mode 100644 index 5dd0de8..0000000 --- a/nvim/plugin/gitsigns.lua +++ /dev/null @@ -1,40 +0,0 @@ -if vim.g.did_load_gitsigns_plugin then - return -end -vim.g.did_load_gitsigns_plugin = true - -require('gitsigns').setup { - signcolumn = false, - numhl = true, - on_attach = function() - local gs = package.loaded.gitsigns - vim.keymap.set('n', 'gg', gs.preview_hunk, { desc = 'git preview hunk' }) - vim.keymap.set('n', 'gb', function() - gs.blame_line { full = true } - end, { desc = 'git blame_line' }) - vim.keymap.set('n', 'gr', gs.reset_hunk, { desc = 'git reset hunk' }) - vim.keymap.set('v', 'gr', function() - gs.reset_hunk { vim.fn.line('.'), vim.fn.line('v') } - end, { desc = 'git reset hunk' }) - -- Navigation - vim.keymap.set('n', ']g', function() - if vim.wo.diff then - return ']c' - end - vim.schedule(function() - gs.next_hunk() - end) - return '' - end, { expr = true }) - - vim.keymap.set('n', '[g', function() - if vim.wo.diff then - return '[c' - end - vim.schedule(function() - gs.prev_hunk() - end) - return '' - end, { expr = true }) - end, -} diff --git a/nvim/plugin/keymaps.lua b/nvim/plugin/keymaps.lua deleted file mode 100644 index 6e4bcf9..0000000 --- a/nvim/plugin/keymaps.lua +++ /dev/null @@ -1,13 +0,0 @@ -vim.keymap.set('n', 'tt', vim.cmd.tabnext, { silent = true }) -vim.keymap.set('n', 'tr', vim.cmd.tabprev, { silent = true }) -vim.keymap.set('n', 'gt', vim.cmd.bnext, { silent = true }) -vim.keymap.set('n', 'gr', vim.cmd.bprev, { noremap = true, silent = true }) -vim.keymap.set('n', 'gq', vim.cmd.bdelete, { silent = true }) -vim.keymap.set('n', 'n', 'nzz', { noremap = true, silent = true }) -vim.keymap.set('n', 'N', 'Nzz', { noremap = true, silent = true }) -vim.keymap.set('n', '', 'zz') -vim.keymap.set('n', '', 'zz') -vim.keymap.set('n', '', 'zz') -vim.keymap.set('n', '', 'zz') -vim.keymap.set({ 'v', 'i' }, 'wq', 'l', { noremap = true, silent = true }) -vim.keymap.set('n', 'x', '"rd', { remap = true, silent = true }) diff --git a/nvim/plugin/lsp.lua b/nvim/plugin/lsp.lua deleted file mode 100644 index 887b316..0000000 --- a/nvim/plugin/lsp.lua +++ /dev/null @@ -1,138 +0,0 @@ -if vim.g.did_load_lsp_plugin then - return -end -vim.g.did_load_lsp_plugin = true - --- Setup language servers. -local lspconfig = require('lspconfig') -local capabilities = require('cmp_nvim_lsp').default_capabilities() - -lspconfig.gopls.setup { - settings = { - gopls = { - gofumpt = true, - codelenses = { - gc_details = true, - test = true, - }, - analyses = { - unusedvariable = true, - shadow = true, - }, - hints = { - assignVariableTypes = true, - constantValues = true, - functionTypeParameters = true, - rangeVariableTypes = true, - }, - usePlaceholders = true, - staticcheck = true, - }, - }, - capabilities = capabilities, - on_attach = function(_, bufnr) - capabilities = capabilities - vim.api.nvim_command('au BufWritePre lua vim.lsp.buf.format { async = false }') - end, -} -lspconfig.jedi_language_server.setup { capabilities = capabilities } -lspconfig.nil_ls.setup { capabilities = capabilities } -lspconfig.phpactor.setup { capabilities = capabilities } - -vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Prev diagnostic' }) -vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Next diagnostic' }) - -vim.diagnostic.config { - virtual_text = true, - underline = true, - update_in_insert = false, -} --- Use LspAttach autocommand to only map the following keys --- after the language server attaches to the current buffer -vim.api.nvim_create_autocmd('LspAttach', { - group = vim.api.nvim_create_augroup('UserLspConfig', {}), - callback = function(ev) - local bufnr = ev.buf - local client = vim.lsp.get_client_by_id(ev.data.client_id) - -- Buffer local mappings. - -- See `:help vim.lsp.*` for documentation on any of the below functions - vim.keymap.set('n', 'K', vim.lsp.buf.hover, { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP hover' }) - vim.keymap.set( - 'n', - 'rn', - vim.lsp.buf.rename, - { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP Rename' } - ) - vim.keymap.set( - { 'n', 'v' }, - 'da', - vim.lsp.buf.code_action, - { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP code action' } - ) - vim.keymap.set( - 'n', - 'dd', - 'Telescope lsp_definitions', - { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP definitions' } - ) - vim.keymap.set( - 'n', - 'di', - 'Telescope lsp_implementations', - { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP implementations' } - ) - vim.keymap.set( - 'n', - 'dr', - 'Telescope lsp_references', - { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP references' } - ) - vim.keymap.set( - 'n', - 'dt', - 'Telescope lsp_type_definitions', - { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP type defs' } - ) - vim.keymap.set( - 'n', - 'ds', - 'Telescope lsp_document_symbols', - { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP symbols' } - ) - vim.keymap.set( - 'n', - 'dl', - vim.lsp.codelens.run, - { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP codelens' } - ) - vim.keymap.set('n', 'dh', function() - vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) - end, { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP hints toggle' }) - vim.keymap.set('n', 'df', function() - vim.lsp.buf.format { async = true } - end, { buffer = ev.buf, noremap = true, silent = true, desc = 'LSP format' }) - -- Auto-refresh code lenses - if not client then - return - end - local group = vim.api.nvim_create_augroup(string.format('lsp-%s-%s', bufnr, client.id), {}) - if client.server_capabilities.codeLensProvider then - vim.api.nvim_create_autocmd({ 'InsertLeave', 'BufWritePost', 'TextChanged' }, { - group = group, - callback = function() - vim.lsp.codelens.refresh { bufnr = bufnr } - end, - buffer = bufnr, - }) - vim.lsp.codelens.refresh { bufnr = bufnr } - end - end, -}) - -local none = require('null-ls') -none.setup { - sources = { - none.builtins.diagnostics.puppet_lint, - none.builtins.diagnostics.yamllint, - }, -} diff --git a/nvim/plugin/lualine.lua b/nvim/plugin/lualine.lua deleted file mode 100644 index a7c1653..0000000 --- a/nvim/plugin/lualine.lua +++ /dev/null @@ -1,18 +0,0 @@ -if vim.g.did_load_lualine_plugin then - return -end -vim.g.did_load_lualine_plugin = true - -vim.schedule(function() - require('lualine').setup { - globalstatus = true, - extensions = { 'oil', 'trouble', 'aerial', 'fzf', 'toggleterm', 'quickfix' }, - sections = { - lualine_x = { 'filetype' }, - }, - tabline = { - lualine_a = { 'buffers' }, - lualine_z = { 'tabs' }, - }, - } -end) diff --git a/nvim/plugin/luasnip.lua b/nvim/plugin/luasnip.lua deleted file mode 100644 index 4fc038b..0000000 --- a/nvim/plugin/luasnip.lua +++ /dev/null @@ -1,37 +0,0 @@ -if vim.g.did_load_luasnip_plugin then - return -end -vim.g.did_load_luasnip_plugin = true - -local ls = require('luasnip') -ls.config.set_config { - history = true, - updateevents = 'TextChanged, TextChangedI', -} -require('luasnip.loaders.from_vscode').lazy_load() - -vim.keymap.set({ 'i', 's' }, '', function() - if ls.expand_or_jumpable() then - ls.expand_or_jump() - end -end, { silent = true }) - -vim.keymap.set({ 'i', 's' }, '', function() - if ls.jumpable(-1) then - ls.jump(-1) - end -end, { silent = true }) - -vim.keymap.set({ 'i', 's' }, '', function() - if ls.choice_active() then - ls.change_choice(1) - end -end, { silent = true }) - --------------------- --- Snippets -- --------------------- -local fmta = require('luasnip.extras.fmt').fmta -ls.add_snippets('go', { - ls.snippet('ie', fmta('if err != nil {\n\treturn \n}', { err = ls.insert_node(1, 'err') })), -}) diff --git a/nvim/plugin/mini.lua b/nvim/plugin/mini.lua deleted file mode 100644 index aedb8c5..0000000 --- a/nvim/plugin/mini.lua +++ /dev/null @@ -1,67 +0,0 @@ -if vim.g.did_load_mini_plugin then - return -end -vim.g.did_load_mini_plugin = true - --- din( dina -require('mini.ai').setup() --- gc gcc -require('mini.comment').setup() - --- Add surrounding with sa --- Delete surrounding with sd. --- Replace surrounding with sr. --- Find surrounding with sf or sF (move cursor right or left). --- Highlight surrounding with sh. --- 'f' - function call (string of alphanumeric symbols or '_' or '.' followed by balanced '()'). In "input" finds function call, in "output" prompts user to enter function name. --- 't' - tag. In "input" finds tag with same identifier, in "output" prompts user to enter tag name. --- All symbols in brackets '()', '[]', '{}', '<>". --- '?' - interactive. Prompts user to enter left and right parts. -require('mini.surround').setup() - --- :Trim -require('mini.trailspace').setup() -vim.api.nvim_create_user_command('Trim', function() - require('mini.trailspace').trim() -end, {}) - --- prefix \ --- `b` - |'background'|. --- `c` - |'cursorline'|. --- `C` - |'cursorcolumn'|. --- `d` - diagnostic (via |vim.diagnostic.enable()| and |vim.diagnostic.disable()|). --- `h` - |'hlsearch'| (or |v:hlsearch| to be precise). --- `i` - |'ignorecase'|. --- `l` - |'list'|. --- `n` - |'number'|. --- `r` - |'relativenumber'|. --- `s` - |'spell'|. --- `w` - |'wrap'|. -require('mini.basics').setup { - mappings = { - windows = true, - }, -} - --- gS -require('mini.splitjoin').setup { - detect = { - separator = '[,;\n]', - }, -} - -require('mini.pairs').setup() -vim.cmd([[ hi MiniCursorwordCurrent ctermfg=240 ]]) - -require('mini.jump2d').setup { - mappings = { start_jumping = 'S' }, -} - -indent = require('mini.indentscope') -indent.setup { - options = { try_as_border = false }, - draw = { delay = 0 }, -} -indent.gen_animation.none() - -require('mini.icons').setup() diff --git a/nvim/plugin/misc.lua b/nvim/plugin/misc.lua deleted file mode 100644 index acb37ef..0000000 --- a/nvim/plugin/misc.lua +++ /dev/null @@ -1,45 +0,0 @@ -if vim.g.did_load_plugins_plugin then - return -end -vim.g.did_load_plugins_plugin = true - --- many plugins annoyingly require a call to a 'setup' function to be loaded, --- even with default configs - -require('neogen').setup {} -vim.keymap.set('n', 'nd', 'Neogen', { noremap = true, silent = true, desc = 'Neogen - gen comments' }) - -require('toggleterm').setup { - open_mapping = [[]], - direction = 'float', - close_on_exit = true, - autochdir = true, -} - -require('which-key').setup { - preset = 'helix', -} -require('trouble').setup {} -require('eyeliner').setup {} -require('markview').setup() -require('scope').setup {} -require('neoclip').setup { default_register = '+' } -vim.keymap.set( - 'n', - 'fp', - 'Telescope neoclip', - { noremap = true, silent = true, desc = 'Pick clipboard history' } -) -local snipe = require('snipe') -snipe.setup { - ui = { - position = 'center', - }, - sort = 'last', -} -vim.keymap.set( - 'n', - '', - snipe.open_buffer_menu, - { noremap = true, silent = true, desc = 'Pick buffers (snipe.nvim)' } -) diff --git a/nvim/plugin/neogit.lua b/nvim/plugin/neogit.lua deleted file mode 100644 index 533fe8f..0000000 --- a/nvim/plugin/neogit.lua +++ /dev/null @@ -1,20 +0,0 @@ -if vim.g.did_load_neogit_plugin then - return -end -vim.g.did_load_neogit_plugin = true -require('diffview').setup { - enhanced_diff_hl = true, - default_args = { - DiffviewOpen = { '--imply-local' }, - }, -} -local neogit = require('neogit') -neogit.setup { - disable_builtin_notifications = true, - integrations = { - diffview = true, - telescope = true, - fzf_lua = true, - }, -} -vim.keymap.set('n', 'ng', neogit.open, { noremap = true, silent = true, desc = 'Neogit' }) diff --git a/nvim/plugin/oil.lua b/nvim/plugin/oil.lua deleted file mode 100644 index 1c4a521..0000000 --- a/nvim/plugin/oil.lua +++ /dev/null @@ -1,23 +0,0 @@ -if vim.g.did_load_oil_plugin then - return -end -vim.g.did_load_oil_plugin = true - -local oil = require('oil') -oil.setup { - watch_for_changes = true, - columns = { - 'permissions', - 'size', - }, - view_options = { - show_hidden = true, - }, - keymaps = { - ['wq'] = 'actions.close', - }, -} -vim.keymap.set('n', 'c', oil.toggle_float, { noremap = true, silent = true }) -vim.keymap.set('n', 'u', 'UndotreeToggle') -vim.g.undotree_ShortIndicators = 1 -vim.g.undotree_SetFocusWhenToggle = 1 diff --git a/nvim/plugin/telescope.lua b/nvim/plugin/telescope.lua deleted file mode 100644 index 7182b81..0000000 --- a/nvim/plugin/telescope.lua +++ /dev/null @@ -1,70 +0,0 @@ -if vim.g.did_load_telescope_plugin then - return -end -vim.g.did_load_telescope_plugin = true - -local telescope = require('telescope.builtin') - --- Fall back to find_files if not in a git repo -local project_files = function() - local opts = {} -- define here if you want to define something - local ok = pcall(telescope.git_files, opts) - if not ok then - telescope.find_files(opts) - end -end - -vim.keymap.set('n', 'ff', project_files, { noremap = true, silent = true, desc = 'Fuzzy find git files' }) -vim.keymap.set('n', 'fg', telescope.find_files, { noremap = true, silent = true, desc = 'Fuzzy find files' }) -vim.keymap.set( - 'n', - 'fc', - telescope.command_history, - { noremap = true, silent = true, desc = 'Fuzzy find command_history' } -) -vim.keymap.set('n', 'fa', telescope.live_grep, { noremap = true, silent = true, desc = 'Fuzzy find grep' }) -vim.keymap.set( - 'n', - 'f8', - telescope.grep_string, - { noremap = true, silent = true, desc = 'Fuzzy find grep current word' } -) -vim.keymap.set('n', 'fq', telescope.quickfix, { noremap = true, silent = true, desc = 'Fuzzy find quickfix' }) -vim.keymap.set('n', 'f', telescope.resume, { noremap = true, silent = true, desc = 'Fuzzy find resume' }) - -local telescope = require('telescope') -telescope.setup { - defaults = { - layout_strategy = 'vertical', - layout_config = { width = 0.90 }, - prompt_title = false, - results_title = false, - preview_title = false, - vimgrep_arguments = { - 'rg', - '-L', - '--color=never', - '--no-heading', - '--hidden', - '--with-filename', - '--line-number', - '--column', - '--smart-case', - }, - preview = { - treesitter = true, - }, - path_display = { - 'truncate', - }, - mappings = { - i = { - ['wq'] = require('telescope.actions').close, - [''] = require('telescope.actions').close, - [''] = require('telescope.actions').move_selection_previous, - [''] = require('telescope.actions').move_selection_next, - }, - }, - }, -} -telescope.load_extension('fzf') diff --git a/nvim/plugin/treesitter.lua b/nvim/plugin/treesitter.lua deleted file mode 100644 index 0444ac3..0000000 --- a/nvim/plugin/treesitter.lua +++ /dev/null @@ -1,65 +0,0 @@ -if vim.g.did_load_treesitter_plugin then - return -end -vim.g.did_load_treesitter_plugin = true - -require('nvim-treesitter.configs').setup { - ensure_installed = {}, - highlight = { - enable = true, - disable = function(_, buf) - local max_filesize = 100 * 1024 -- 100 KiB - local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf)) - if ok and stats and stats.size > max_filesize then - return true - end - end, - }, - indent = { - enable = true, - }, - textobjects = { - select = { - enable = true, - lookahead = true, - keymaps = { - ['af'] = '@function.outer', - ['if'] = '@function.inner', - ['aa'] = '@statement.outer', - ['ia'] = '@parameter.inner', - }, - }, - move = { - enable = true, - set_jumps = true, -- whether to set jumps in the jumplist - goto_next_start = { - [']a'] = '@parameter.inner', - }, - goto_previous_start = { - ['[a'] = '@parameter.inner', - }, - }, - swap = { - enable = true, - swap_next = { - ['s]'] = '@parameter.inner', - }, - swap_previous = { - ['s['] = '@parameter.inner', - }, - }, - }, - incremental_selection = { - enable = true, - keymaps = { - init_selection = '', - node_incremental = '', - node_decremental = '', - }, - }, -} - -require('treesitter-context').setup { - max_lines = 2, - min_window_height = 50, -} diff --git a/nvim/plugin/which-key.lua b/nvim/plugin/which-key.lua deleted file mode 100644 index 89030a5..0000000 --- a/nvim/plugin/which-key.lua +++ /dev/null @@ -1,3 +0,0 @@ -require('which-key').setup { - preset = 'helix', -}