diff --git a/nix/mkNeovim.nix b/nix/mkNeovim.nix index 1ba7e54..a60263b 100644 --- a/nix/mkNeovim.nix +++ b/nix/mkNeovim.nix @@ -1,150 +1,40 @@ -# Function for creating a Neovim derivation { pkgs, lib, - stdenv, - # Set by the overlay to ensure we use a compatible version of `wrapNeovimUnstable` - pkgs-wrapNeovim ? pkgs, }: -with lib; { - # NVIM_APPNAME - Defaults to 'nvim' if not set. - # If set to something else, this will also rename the binary. - appName ? "nvim", - # The Neovim package to wrap - neovim-unwrapped ? pkgs-wrapNeovim.neovim-unwrapped, - plugins ? [ ], # List of plugins - # List of dev plugins (will be bootstrapped) - useful for plugin developers - # { name = ; url = ; } - devPlugins ? [ ], - # Regexes for config files to ignore, relative to the nvim directory. - # e.g. [ "^plugin/neogit.lua" "^ftplugin/.*.lua" ] - ignoreConfigRegexes ? [ ], - extraPackages ? [ ], # Extra runtime dependencies (e.g. ripgrep, ...) - # The below arguments can typically be left as their defaults - # Additional lua packages (not plugins), e.g. from luarocks.org. - # e.g. p: [p.jsregexp] - extraLuaPackages ? p: [ ], - extraPython3Packages ? p: [ ], # Additional python 3 packages - withPython3 ? false, # Build Neovim with Python 3 support? - withRuby ? false, # Build Neovim with Ruby support? - withNodeJs ? false, # Build Neovim with NodeJS support? - withSqlite ? true, # Add sqlite? This is a dependency for some plugins - # You probably don't want to create vi or vim aliases - # if the appName is something different than "nvim" - viAlias ? appName == "nvim", # Add a "vi" binary to the build output as an alias? - vimAlias ? appName == "nvim", # Add a "vim" binary to the build output as an alias? + name ? "nvim", + plugins ? [ ], + packages ? [ ], wrapRc ? true, }: let - # This is the structure of a plugin definition. - # Each plugin in the `plugins` argument list can also be defined as this attrset - defaultPlugin = { - plugin = null; # e.g. nvim-lspconfig - config = null; # plugin config - # If `optional` is set to `false`, the plugin is installed in the 'start' packpath - # set to `true`, it is installed in the 'opt' packpath, and can be lazy loaded with - # ':packadd! {plugin-name} - optional = false; - runtime = { }; - }; - - externalPackages = extraPackages ++ (optionals withSqlite [ pkgs.sqlite ]); - - # Map all plugins to an attrset { plugin = ; config = ; optional = ; ... } - - # This nixpkgs util function creates an attrset - # that pkgs.wrapNeovimUnstable uses to configure the Neovim build. - neovimConfig = pkgs-wrapNeovim.neovimUtils.makeNeovimConfig { - inherit - extraPython3Packages - withPython3 - withRuby - withNodeJs - viAlias - vimAlias - ; - - plugins = (pkgs.neovimUtils.normalizePlugins plugins); - }; - - packDir = pkgs.neovimUtils.packDir { - iofq = pkgs.neovimUtils.normalizedPluginsToVimPackage (pkgs.neovimUtils.normalizePlugins plugins); - }; - - nvimRtp = stdenv.mkDerivation { + isNvim = (name == "nvim"); + nvimRtp = pkgs.stdenv.mkDerivation { name = "nvim-rtp"; src = ../nvim; - installPhase = '' mkdir -p $out/ cp -r . $out/ ''; }; - # 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 - initLua = '' - vim.opt.rtp:prepend('${nvimRtp}') - '' - + builtins.readFile ../nvim/init.lua; + wrapperArgs = '' + --set NVIM_APPNAME "${name}" + --prefix PATH : "${lib.makeBinPath packages}" + --set LIBSQLITE_CLIB_PATH "${pkgs.sqlite.out}/lib/libsqlite3.so" + --set LIBSQLITE "${pkgs.sqlite.out}/lib/libsqlite3.so" + ''; - # Add arguments to the Neovim wrapper script - extraMakeWrapperArgs = builtins.concatStringsSep " " ( - # Set the NVIM_APPNAME environment variable - (optional ( - appName != "nvim" && appName != null && appName != "" - ) ''--set NVIM_APPNAME "${appName}"'') - # Add external packages to the PATH - ++ (optional (externalPackages != [ ]) ''--prefix PATH : "${makeBinPath externalPackages}"'') - # Set the LIBSQLITE_CLIB_PATH if sqlite is enabled - ++ (optional withSqlite ''--set LIBSQLITE_CLIB_PATH "${pkgs.sqlite.out}/lib/libsqlite3.so"'') - # Set the LIBSQLITE environment variable if sqlite is enabled - ++ (optional withSqlite ''--set LIBSQLITE "${pkgs.sqlite.out}/lib/libsqlite3.so"'') - ); - - luaPackages = neovim-unwrapped.lua.pkgs; - resolvedExtraLuaPackages = extraLuaPackages luaPackages; - - # Native Lua libraries - extraMakeWrapperLuaCArgs = - optionalString (resolvedExtraLuaPackages != [ ]) - ''--suffix LUA_CPATH ";" "${ - concatMapStringsSep ";" luaPackages.getLuaCPath resolvedExtraLuaPackages - }"''; - - # Lua libraries - extraMakeWrapperLuaArgs = - optionalString (resolvedExtraLuaPackages != [ ]) - ''--suffix LUA_PATH ";" "${ - concatMapStringsSep ";" luaPackages.getLuaPath resolvedExtraLuaPackages - }"''; - - # wrapNeovimUnstable is the nixpkgs utility function for building a Neovim derivation. - neovim-wrapped = pkgs-wrapNeovim.wrapNeovimUnstable neovim-unwrapped ( - neovimConfig - // { - luaRcContent = initLua; - wrapperArgs = - escapeShellArgs neovimConfig.wrapperArgs - + " " - + extraMakeWrapperArgs - + " " - + extraMakeWrapperLuaCArgs - + " " - + extraMakeWrapperLuaArgs; - wrapRc = wrapRc; - } - ); - - isCustomAppName = appName != null && appName != "nvim"; + neovimConfig = pkgs.neovimUtils.makeNeovimConfig { + wrapRc = wrapRc; + withPython3 = false; + vimAlias = isNvim; + plugins = (pkgs.neovimUtils.normalizePlugins plugins); + customLuaRC = ''vim.opt.rtp:prepend('${nvimRtp}')'' + builtins.readFile ../nvim/init.lua; + extraMakeWrapperArgs = wrapperArgs; + }; in -neovim-wrapped.overrideAttrs (oa: { - buildPhase = - oa.buildPhase - # If a custom NVIM_APPNAME has been set, rename the `nvim` binary - + lib.optionalString isCustomAppName '' - mv $out/bin/nvim $out/bin/${lib.escapeShellArg appName} - ''; +(pkgs.wrapNeovimUnstable pkgs.neovim-unwrapped (neovimConfig)).overrideAttrs (oa: { + buildPhase = oa.buildPhase + lib.optionalString (!isNvim) ''mv $out/bin/nvim $out/bin/${name}''; }) diff --git a/nix/neovim-overlay.nix b/nix/neovim-overlay.nix index 5a2684e..3bb808e 100644 --- a/nix/neovim-overlay.nix +++ b/nix/neovim-overlay.nix @@ -1,12 +1,11 @@ # This overlay, when applied to nixpkgs, adds the final neovim derivation to nixpkgs. { inputs }: final: prev: -with final.pkgs.lib; let - mkNeovim = prev.callPackage ./mkNeovim.nix { pkgs-wrapNeovim = prev; }; + mkNeovim = prev.callPackage ./mkNeovim.nix { pkgs = prev; }; dart-nvim = inputs.dart.packages.x86_64-linux.default; - plugins = with final.vimPlugins; [ + plugins = with prev.vimPlugins; [ blink-cmp blink-ripgrep-nvim conform-nvim @@ -23,12 +22,13 @@ let snacks-nvim ]; - basePackages = with final; [ + basePackages = with prev; [ + sqlite ripgrep fd ]; # Extra packages that should be included on nixos but don't need to be bundled - extraPackages = with final; [ + extraPackages = with prev; [ # linters yamllint jq @@ -47,25 +47,21 @@ in { nvim-pkg = mkNeovim { inherit plugins; - extraPackages = basePackages ++ extraPackages; + packages = basePackages ++ extraPackages; }; nvim-min-pkg = mkNeovim { inherit plugins; - extraPackages = basePackages; + packages = basePackages; }; - # This is meant to be used within a devshell. - # Instead of loading the lua Neovim configuration from - # the Nix store, it is loaded from $XDG_CONFIG_HOME/nvim-dev nvim-dev = mkNeovim { inherit plugins; - extraPackages = basePackages ++ extraPackages; - appName = "nvim-dev"; + packages = basePackages ++ extraPackages; + name = "nvim-dev"; wrapRc = false; }; - # This can be symlinked in the devShell's shellHook nvim-luarc-json = final.mk-luarc-json { inherit plugins; }; diff --git a/nvim/init.lua b/nvim/init.lua index 708198b..bc4155b 100644 --- a/nvim/init.lua +++ b/nvim/init.lua @@ -1,3 +1,5 @@ +vim.cmd('colorscheme iofq') + vim.g.mapleader = ' ' vim.opt.autowrite = true vim.opt.backspace = 'indent,eol,start' @@ -42,8 +44,22 @@ vim.lsp.enable { 'basedpyright', } -vim.cmd('colorscheme iofq') -require('keymaps') +local map = vim.keymap.set +map('n', '\\t', function() -- Switch tab length on the fly + vim.o.tabstop = vim.o.tabstop == 8 and 2 or 2 * vim.o.tabstop + vim.notify('tabstop: ' .. vim.o.tabstop) +end) +map({ 'v', 'i' }, 'wq', 'l') +map('v', '<', '', '>gv') +map('n', 'n', 'nzz', { noremap = true }) +map('n', 'N', 'Nzz', { noremap = true }) +map('n', '', 'zz', { noremap = true }) +map('n', '', 'zz', { noremap = true }) +map('n', 'gq', vim.cmd.bdelete, { noremap = true }) +map('n', 'gQ', function() + vim.cmd('bufdo bdelete') +end, { noremap = true }) + require('autocmd') -require('mini') require('plugins') diff --git a/nvim/lua/autocmd.lua b/nvim/lua/autocmd.lua index a5e566d..41dd900 100644 --- a/nvim/lua/autocmd.lua +++ b/nvim/lua/autocmd.lua @@ -1,27 +1,26 @@ +local cmd = vim.api.nvim_create_autocmd -- open :h 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 = false - end +cmd('FileType', { + group = vim.api.nvim_create_augroup('help', { clear = true }), + pattern = 'help', + callback = function(_) + vim.cmd.only() + vim.keymap.set('n', 'q', vim.cmd.bdelete, { noremap = true }) + vim.bo.buflisted = false end, }) -- resize splits if window got resized -vim.api.nvim_create_autocmd({ 'VimResized' }, { +cmd({ 'VimResized' }, { group = vim.api.nvim_create_augroup('resize_splits', { clear = true }), callback = function() - local current_tab = vim.fn.tabpagenr() vim.cmd('tabdo wincmd =') - vim.cmd('tabnext ' .. current_tab) + vim.cmd('tabnext ' .. vim.fn.tabpagenr()) end, }) -- Check if we need to reload the file when it changed -vim.api.nvim_create_autocmd({ 'FocusGained', 'TermClose', 'TermLeave' }, { +cmd({ 'FocusGained', 'TermClose', 'TermLeave' }, { group = vim.api.nvim_create_augroup('check_reload', { clear = true }), callback = function() if vim.o.buftype ~= 'nofile' then @@ -31,36 +30,36 @@ vim.api.nvim_create_autocmd({ 'FocusGained', 'TermClose', 'TermLeave' }, { }) -- Init treesitter -vim.api.nvim_create_autocmd('FileType', { +cmd('FileType', { callback = function(event) local bufnr = event.buf vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" pcall(vim.treesitter.start, bufnr) - vim.keymap.set({'v','n'}, ']]', function() + vim.keymap.set({ 'v', 'n' }, ']]', function() require('nvim-treesitter-textobjects.move').goto_next_start('@function.outer', 'textobjects') - end, { buffer = bufnr, desc = 'next function def' }) - vim.keymap.set({'v','n'}, '[[', function() + end, { buffer = bufnr }) + vim.keymap.set({ 'v', 'n' }, '[[', function() require('nvim-treesitter-textobjects.move').goto_previous_start('@function.outer', 'textobjects') - end, { buffer = bufnr, desc = 'prev function def' }) - vim.keymap.set({'v','n'}, ']a', function() + end, { buffer = bufnr }) + vim.keymap.set({ 'v', 'n' }, ']a', function() require('nvim-treesitter-textobjects.move').goto_next_start('@parameter.inner', 'textobjects') - end, { buffer = bufnr, desc = 'next param def' }) - vim.keymap.set({'v','n'}, '[a', function() + end, { buffer = bufnr }) + vim.keymap.set({ 'v', 'n' }, '[a', function() require('nvim-treesitter-textobjects.move').goto_previous_start('@parameter.inner', 'textobjects') - end, { buffer = bufnr, desc = 'prev param def' }) - vim.keymap.set({'v','n'}, ']A', function() + end, { buffer = bufnr }) + vim.keymap.set({ 'v', 'n' }, ']A', function() require('nvim-treesitter-textobjects.swap').swap_next('@parameter.inner') - end, { buffer = bufnr, desc = 'swap next arg' }) - vim.keymap.set({'v','n'}, '[A', function() + end, { buffer = bufnr }) + vim.keymap.set({ 'v', 'n' }, '[A', function() require('nvim-treesitter-textobjects.swap').swap_previous('@parameter.inner') - end, { buffer = bufnr, desc = 'swap prev arg' }) + end, { buffer = bufnr }) end, }) -- Init LSP -vim.api.nvim_create_autocmd('LspAttach', { +cmd('LspAttach', { group = vim.api.nvim_create_augroup('UserLspConfig', {}), callback = function(ev) local client = vim.lsp.get_client_by_id(ev.data.client_id) @@ -69,24 +68,20 @@ vim.api.nvim_create_autocmd('LspAttach', { end vim.keymap.set('n', 'gO', function() Snacks.picker.lsp_symbols { focus = 'list' } - end, { buffer = ev.buf, desc = 'LSP symbols' }) + end, { buffer = ev.buf }) vim.keymap.set('n', 'grh', function() vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) - end, { buffer = ev.buf, desc = 'LSP hints toggle' }) - vim.keymap.set('n', 'grl', vim.lsp.codelens.run, { buffer = ev.buf, desc = 'vim.lsp.codelens.run()' }) + end, { buffer = ev.buf }) + vim.keymap.set('n', 'grl', vim.lsp.codelens.run, { buffer = ev.buf }) - vim.keymap.set('n', 'gre', function() - vim.diagnostic.setloclist() - end, { buffer = ev.buf, desc = 'LSP buffer diagnostics' }) - vim.keymap.set('n', 'grE', function() - vim.diagnostic.setqflist() - end, { buffer = ev.buf, desc = 'LSP diagnostics' }) + vim.keymap.set('n', 'gre', vim.diagnostic.setloclist, { buffer = ev.buf }) + vim.keymap.set('n', 'grE', vim.diagnostic.setqflist, { buffer = ev.buf }) -- Auto-refresh code lenses if client:supports_method('textDocument/codeLens') or client.server_capabilities.codeLensProvider then vim.lsp.codelens.refresh { bufnr = ev.buf } - vim.api.nvim_create_autocmd({ 'InsertLeave', 'TextChanged' }, { + cmd({ 'InsertLeave', 'TextChanged' }, { callback = function() vim.lsp.codelens.refresh { bufnr = ev.buf } end, diff --git a/nvim/lua/keymaps.lua b/nvim/lua/keymaps.lua deleted file mode 100644 index 62c630c..0000000 --- a/nvim/lua/keymaps.lua +++ /dev/null @@ -1,18 +0,0 @@ --- Switch tab length on the fly -vim.keymap.set('n', '\\t', function() - vim.o.tabstop = vim.o.tabstop == 8 and 2 or 2 * vim.o.tabstop - vim.notify('tabstop: ' .. vim.o.tabstop) -end, { silent = true, desc = 'toggle tabstop' }) -vim.keymap.set({ 'v', 'i' }, 'wq', 'l', { noremap = true, silent = true }) -vim.keymap.set('v', '<', '', '>gv') -vim.keymap.set('n', 'n', 'nzz', { noremap = true }) -vim.keymap.set('n', 'N', 'Nzz', { noremap = true }) -vim.keymap.set('n', '', 'zz', { noremap = true }) -vim.keymap.set('n', '', 'zz', { noremap = true }) -vim.keymap.set('v', '', ":m '>+1gv=gv", { desc = 'move selection down' }) -vim.keymap.set('v', '', ":m '<-2gv=gv", { desc = 'move selection up' }) -vim.keymap.set('n', 'gq', vim.cmd.bdelete, { noremap = true, silent = true, desc = 'close buffer' }) -vim.keymap.set('n', 'gQ', function() - vim.cmd('bufdo bdelete') -end, { noremap = true, silent = true, desc = 'close all buffers' }) diff --git a/nvim/lua/mini.lua b/nvim/lua/mini.lua deleted file mode 100644 index b1810d5..0000000 --- a/nvim/lua/mini.lua +++ /dev/null @@ -1,73 +0,0 @@ -require('mini.basics').setup { mappings = { windows = true } } -require('mini.icons').setup() - -vim.schedule(function() - require('mini.align').setup() - require('mini.pairs').setup() - require('mini.surround').setup() - require('mini.splitjoin').setup { detect = { separator = '[,;\n]' } } - - local ai = require('mini.ai') - ai.setup { - n_lines = 300, - custom_textobjects = { - i = require('mini.extra').gen_ai_spec.indent(), - a = ai.gen_spec.treesitter { a = '@parameter.outer', i = '@parameter.inner' }, - f = ai.gen_spec.treesitter { a = '@function.outer', i = '@function.inner' }, - }, - } - - require('mini.git').setup() - vim.keymap.set('n', 'go', function() - return MiniGit.show_at_cursor() - end, { noremap = true, desc = 'git show at cursor' }) - vim.keymap.set('n', 'gb', 'Git blame -- %', { desc = 'git blame' }) - - local jump = require('mini.jump2d') - jump.setup { - view = { n_steps_ahead = 1, dim = true }, - spotter = jump.gen_spotter.vimpattern(), - } - - local diff = require('mini.diff') - diff.setup { - source = { - require('lib.minidiff_jj').gen_source(), - diff.gen_source.git(), - }, - } - vim.keymap.set('n', 'gp', function() - MiniDiff.toggle_overlay(0) - end, { noremap = true, desc = 'git diff overlay' }) - - local files = require('mini.files') - files.setup { - mappings = { - go_in_plus = '', - }, - windows = { - preview = true, - width_preview = 50, - }, - } - vim.keymap.set('n', 'nc', function() - MiniFiles.open(vim.api.nvim_buf_get_name(0), false) -- open current buffer's dir - MiniFiles.reveal_cwd() - end, { desc = 'minifiles open' }) - - vim.keymap.set('n', '`', function() - local _, cur_entry_path = pcall(MiniFiles.get_fs_entry().path) - local cur_directory = vim.fs.dirname(cur_entry_path) - if cur_directory ~= '' then - vim.fn.chdir(cur_directory) - end - end) - - -- pass file rename events to LSP - vim.api.nvim_create_autocmd('User', { - pattern = 'MiniFilesActionRename', - callback = function(event) - Snacks.rename.on_rename_file(event.data.from, event.data.to) - end, - }) -end) diff --git a/nvim/lua/plugins.lua b/nvim/lua/plugins.lua index b00a3e4..f3e62b8 100644 --- a/nvim/lua/plugins.lua +++ b/nvim/lua/plugins.lua @@ -1,3 +1,8 @@ +local map = vim.keymap.set + +require('mini.basics').setup { mappings = { windows = true } } +require('mini.icons').setup() + require('dart').setup { tabline = { label_marked_fg = 'cyan', @@ -30,6 +35,7 @@ require('snacks').setup { }, smart = { multi = { + 'buffers', { source = 'files', hidden = true }, { source = 'git_files', untracked = true }, }, @@ -38,73 +44,39 @@ require('snacks').setup { }, } -vim.keymap.set({ 'n', 't' }, '', function() - Snacks.terminal.toggle() -end, { desc = 'terminal open' }) +map({ 'n', 't' }, '', Snacks.terminal.toggle) +map('n', 'ff', Snacks.picker.smart) +map('n', '', Snacks.picker.smart) +map('n', 'fa', Snacks.picker.grep) +map('n', 'f8', Snacks.picker.grep_word) +map('n', 'f?', Snacks.picker.pickers) +map('n', 'fu', Snacks.picker.undo) +map('n', 'fj', Snacks.picker.jumps) +map('n', 'f.', Snacks.picker.resume) +map('n', 'fb', Snacks.picker.buffers) +map('n', 'fq', Snacks.picker.qflist) +map('n', 'jf', require('lib.snacks_jj').status) -vim.keymap.set('n', 'ff', function() - Snacks.picker.smart() -end, { desc = 'Fuzzy find smart' }) - -vim.keymap.set('n', 'fa', function() - Snacks.picker.grep() -end, { desc = 'Fuzzy find grep' }) - -vim.keymap.set('n', 'f8', function() - Snacks.picker.grep_word() -end, { desc = 'Fuzzy find grep word' }) - -vim.keymap.set('n', 'f?', function() - Snacks.picker.pickers() -end, { desc = 'See all pickers' }) - -vim.keymap.set('n', 'fu', function() - Snacks.picker.undo() -end, { desc = 'Pick undotree' }) - -vim.keymap.set('n', 'fj', function() - Snacks.picker.jumps() -end, { desc = 'Pick jumps' }) - -vim.keymap.set('n', 'f.', function() - Snacks.picker.resume() -end, { desc = 'Fuzzy find resume' }) - -vim.keymap.set('n', 'fb', function() - Snacks.picker.buffers() -end, { desc = 'Fuzzy find buffers' }) - -vim.keymap.set('n', 'fq', function() - Snacks.picker.qflist() -end, { desc = 'pick quickfix list' }) - -vim.keymap.set('n', 'jf', function() - require('lib.snacks_jj').status() -end, { desc = 'pick notifications' }) vim.schedule(function() require('nvim-treesitter').setup() require('nvim-treesitter-textobjects').setup() require('render-markdown').setup() require('refactoring').setup() - vim.keymap.set('n', 'rr', function() - require('refactoring').select_refactor() - end, { desc = 'Refactor' }) - vim.keymap.set('n', 'rv', function() + map('n', 'rr', require('refactoring').select_refactor) + map('n', 'rv', function() require('refactoring').refactor('Inline Variable') - end, { desc = 'Inline Variable' }) + end) require('quicker').setup() - vim.keymap.set('n', 'qf', function() + map('n', 'qf', function() require('quicker').toggle { max_height = 20 } - end, { desc = 'Toggle qflist' }) + end) + local close = { { { 'n' }, 'q', vim.cmd.DiffviewClose, { desc = 'Close Diffview' } } } require('diffview').setup { - use_icons = false, enhanced_diff_hl = true, - default_args = { - DiffviewOpen = { '--imply-local' }, - }, + default_args = { DiffviewOpen = { '--imply-local' } }, view = { merge_tool = { layout = 'diff4_mixed', @@ -112,21 +84,19 @@ vim.schedule(function() }, }, keymaps = { - view = { - { { 'n' }, 'q', vim.cmd.DiffviewClose, { desc = 'Close Diffview' } }, - }, - file_panel = { - { { 'n' }, 'q', vim.cmd.DiffviewClose, { desc = 'Close Diffview' } }, - }, - file_history_panel = { - { { 'n' }, 'q', vim.cmd.DiffviewClose, { desc = 'Close Diffview' } }, - }, + view = close, + file_panel = close, + file_history_panel = close, }, } - vim.keymap.set('n', 'nb', vim.cmd.DiffviewOpen, { desc = 'diffview open' }) - vim.keymap.set('n', 'nH', vim.cmd.DiffviewFileHistory, { desc = 'diffview history' }) - vim.keymap.set('n', 'nh', 'DiffviewFileHistory %', { desc = 'diffview history' }) + map('n', 'nb', vim.cmd.DiffviewOpen) + map('n', 'nH', vim.cmd.DiffviewFileHistory) + map('n', 'nh', 'DiffviewFileHistory %') + map('n', 'go', function() + local id = vim.fn.expand('') + vim.cmd('DiffviewOpen ' .. id .. '~1' .. '..' .. id) + end) require('conform').setup { notify_no_formatters = false, @@ -146,14 +116,14 @@ vim.schedule(function() return { timeout_ms = 1500, lsp_format = 'fallback' } end, } - vim.keymap.set('n', '\\f', function() + map('n', '\\f', function() vim.b.disable_autoformat = not vim.b.disable_autoformat vim.notify(string.format('Buffer formatting disabled: %s', vim.b.disable_autoformat)) - end, { desc = 'toggle buffer formatting' }) - vim.keymap.set('n', '\\F', function() + end) + map('n', '\\F', function() vim.g.disable_autoformat = not vim.g.disable_autoformat vim.notify(string.format('Global formatting disabled: %s', vim.g.disable_autoformat)) - end, { desc = 'toggle global formatting' }) + end) require('lint').linters_by_ft = { docker = { 'hadolint' }, @@ -180,36 +150,10 @@ vim.schedule(function() enabled = function() return not vim.tbl_contains({ 'snacks_picker_input' }, vim.bo.filetype) end, - fuzzy = { - sorts = { - 'exact', - 'score', - 'sort_text', - }, - }, sources = { - default = { - 'lsp', - 'path', - 'snippets', - 'ripgrep', - 'buffer', - }, + default = { 'lsp', 'snippets', 'ripgrep', 'buffer' }, providers = { - lsp = { - fallbacks = {}, -- include buffer even when LSP is active - score_offset = 10, - }, - snippets = { - score_offset = -10, - }, - path = { - opts = { - get_cwd = function(_) - return vim.fn.getcwd() -- use nvim pwd instead of current file pwd - end, - }, - }, + lsp = { fallbacks = {} }, -- include buffer even when LSP is active ripgrep = { module = 'blink-ripgrep', name = 'rg', @@ -219,35 +163,94 @@ vim.schedule(function() }, }, cmdline = { - completion = { - menu = { - auto_show = true, - }, - }, + completion = { menu = { auto_show = true } }, }, completion = { - documentation = { - auto_show = true, - auto_show_delay_ms = 500, - }, + documentation = { auto_show = true }, menu = { draw = { - treesitter = { 'lsp' }, columns = { { 'label', 'label_description', gap = 1 }, { 'source_name', 'kind', gap = 1 }, }, }, }, - trigger = { - show_on_keyword = true, - }, }, signature = { enabled = true, - trigger = { - show_on_insert = true, - }, + trigger = { show_on_insert = true }, }, } end) + +vim.schedule(function() + require('mini.align').setup() + require('mini.pairs').setup() + require('mini.surround').setup() + require('mini.splitjoin').setup { detect = { separator = '[,;\n]' } } + + local ai = require('mini.ai') + ai.setup { + n_lines = 300, + custom_textobjects = { + i = require('mini.extra').gen_ai_spec.indent(), + a = ai.gen_spec.treesitter { a = '@parameter.outer', i = '@parameter.inner' }, + f = ai.gen_spec.treesitter { a = '@function.outer', i = '@function.inner' }, + }, + } + + require('mini.git').setup() + map('n', 'gb', 'Git blame -- %') + + local jump = require('mini.jump2d') + jump.setup { + view = { n_steps_ahead = 1, dim = true }, + spotter = jump.gen_spotter.vimpattern(), + } + + local diff = require('mini.diff') + diff.setup { + source = { + require('lib.minidiff_jj').gen_source(), + diff.gen_source.git(), + }, + } + map('n', 'gp', MiniDiff.toggle_overlay) + + require('mini.files').setup { + mappings = { go_in_plus = '' }, + windows = { + preview = true, + width_preview = 50, + }, + } + map('n', 'nc', function() + MiniFiles.open(vim.api.nvim_buf_get_name(0), false) -- open current buffer's dir + MiniFiles.reveal_cwd() + end) + vim.api.nvim_create_autocmd('User', { + pattern = 'MiniFilesBufferCreate', + callback = function(args) + map('n', 'nc', function() + MiniFiles.synchronize() + MiniFiles.close() + end, { buffer = args.data.buf_id }) + map('n', '`', function() + local _, cur_entry_path = pcall(MiniFiles.get_fs_entry().path) + local cur_directory = vim.fs.dirname(cur_entry_path) + if cur_directory ~= '' then + vim.fn.chdir(cur_directory) + end + end, { buffer = args.data.buf_id }) + end, + }) + + -- pass file rename events to LSP + vim.api.nvim_create_autocmd('User', { + group = vim.api.nvim_create_augroup('snacks_rename', { clear = true }), + pattern = 'MiniFilesActionRename', + callback = function(event) + Snacks.rename.on_rename_file(event.data.from, event.data.to) + end, + }) +end)