diff .chezmoitemplates/init.lua @ 760:b64652ec91cb

feat: migrate to lazy.nvim plugin manager
author zegervdv <zegervdv@me.com>
date Sun, 12 Mar 2023 17:32:18 +0100
parents b9d3378f6c9e
children ec5b57266af2
line wrap: on
line diff
--- a/.chezmoitemplates/init.lua	Sat Mar 11 10:37:51 2023 +0100
+++ b/.chezmoitemplates/init.lua	Sun Mar 12 17:32:18 2023 +0100
@@ -2,786 +2,728 @@
 -- Neovim dotfiles
 --
 --
-local execute = vim.api.nvim_command
-local fn = vim.fn
-
 local home = os.getenv 'HOME'
 if home == nil then home = os.getenv 'USERPROFILE' end
 
--- Bootstrap package manager
-local install_path = fn.stdpath 'data' .. '/site/pack/packer/opt/packer.nvim'
+-- Bootstrap lazy
+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)
+
+-- Set leader to space
+vim.g.mapleader = ' '
 
-if fn.empty(fn.glob(install_path)) > 0 then
-  execute('!git clone https://github.com/wbthomason/packer.nvim ' .. install_path)
-end
+require('lazy').setup {
+  -- General plugins
+  { 'tpope/vim-sensible' },
+  { 'tpope/vim-repeat' },
+  { 'tpope/vim-rsi' },
+  { 'sgur/vim-editorconfig' },
+  {
+    'ojroques/nvim-osc52',
+    config = function()
+      require('osc52').setup { trim = true }
+      local copy = function(lines, _) require('osc52').copy(table.concat(lines, '\n')) end
+      local paste = function() return { vim.fn.split(vim.fn.getreg '', '\n'), vim.fn.getregtype '' } end
+      vim.g.clipboard = {
+        name = 'osc52',
+        copy = { ['+'] = copy, ['*'] = copy },
+        paste = { ['+'] = paste, ['*'] = paste },
+      }
+    end,
+  },
 
--- Packer configuration is compiled and only needs to be loaded on changes
-vim.cmd.packadd 'packer.nvim'
+  {
+    'tpope/vim-eunuch',
+    cmd = {
+      'Delete',
+      'Unlink',
+      'Move',
+      'Rename',
+      'Mkdir',
+      'Chmod',
+      'Cfind',
+      'Clocate',
+      'Lfind',
+      'Llocate',
+      'SudoEdit',
+      'SudoWrite',
+      'Wall',
+    },
+  },
 
-local local_plugin = function(name)
-  local path = home .. '/Projects/' .. name
-  if vim.fn.isdirectory(path) > 0 then
-    return path
-  else
-    return 'zegervdv/' .. name
-  end
-end
+  -- Smooth scrolling
+  {
+    'karb94/neoscroll.nvim',
+    config = function() require('neoscroll').setup {} end,
+  },
+
+  -- Faster lua package loading (until 15436 is merged)
+  -- {
+  --   'lewis6991/impatient.nvim',
+  --   module = { 'impatient' },
+  --   setup = function() require 'impatient' end,
+  -- },
+
+  -- Library with lua functions
+  { 'nvim-lua/plenary.nvim' },
+
+  -- Spelling/autocorrection
+  { 'tpope/vim-abolish' },
+
+  -- Git/VCS
+  { 'vim-scripts/gitignore' },
 
-require('packer').startup {
-  function(use)
-    use { 'wbthomason/packer.nvim', opt = true }
+  { 'tpope/vim-git', ft = { 'gitcommit', 'gitrebase' } },
+  {
+    'sindrets/diffview.nvim',
+    config = function()
+      require('diffview').setup {
+        use_icons = false,
+        icons = {
+          folder_closed = '+',
+          folder_open = '-',
+        },
+        signs = {
+          fold_closed = '+',
+          fold_open = '-',
+          done = '✓',
+        },
+        hg_cmd = { 'chg' },
+        view = {
+          merge_tool = {
+            layout = 'diff4_mixed',
+          },
+        },
+      }
+      local wk = require 'which-key'
+      wk.register { ['<leader>d'] = { name = 'Diffview' } }
+      vim.keymap.set('n', '<leader>do', '<cmd>DiffviewOpen<CR>', { desc = 'Open Diffview' })
+      vim.keymap.set('n', '<leader>df', '<cmd>DiffviewFileHistory %<CR>', { desc = 'Show history for current file' })
+      vim.keymap.set('n', '<leader>dh', ':DiffviewFileHistory ', { desc = 'Show history' })
+      vim.keymap.set('n', '<leader>dc', '<cmd>DiffviewClose<CR>', { desc = 'Close Diffview window' })
+    end,
+  },
+
+  -- Comments
+  {
+    'numToStr/Comment.nvim',
+    config = function()
+      local ft = require 'Comment.ft'
+      ft.systemverilog = { '//%s', '/*%s*/' }
+      ft.verilog = { '//%s', '/*%s*/' }
 
-    -- General plugins
-    use { 'tpope/vim-sensible' }
-    use { 'tpope/vim-repeat' }
-    use { 'tpope/vim-rsi' }
-    use { 'sgur/vim-editorconfig' }
-    use {
-      'ojroques/nvim-osc52',
-      config = function()
-        require('osc52').setup { trim = true }
-        local copy = function(lines, _) require('osc52').copy(table.concat(lines, '\n')) end
-        local paste = function() return { vim.fn.split(vim.fn.getreg '', '\n'), vim.fn.getregtype '' } end
-        vim.g.clipboard = {
-          name = 'osc52',
-          copy = { ['+'] = copy, ['*'] = copy },
-          paste = { ['+'] = paste, ['*'] = paste },
-        }
-      end,
-    }
+      require('Comment').setup {
+        padding = true,
+        sticky = true,
+        ignore = '^(%s*)$',
+        mappings = {
+          basic = true,
+          extra = true,
+        },
+      }
+    end,
+    keys = {
+      { 'n', 'gc', 'Comment toggle' },
+      { 'n', 'gb', 'Comment Block toggle' },
+      { 'v', 'gc', 'Comment toggle' },
+      { 'v', 'gb', 'Comment block toggle' },
+    },
+  },
+
+  -- Parentheses etc
+  {
+    'kylechui/nvim-surround',
+    config = function() require('nvim-surround').setup() end,
+  },
+  {
+    'windwp/nvim-autopairs',
+    config = function()
+      local npairs = require 'nvim-autopairs'
+      local Rule = require 'nvim-autopairs.rule'
+
+      local cmp = require 'nvim-autopairs.completion.cmp'
+
+      require('cmp').event:on('confirm_done', cmp.on_confirm_done())
+
+      npairs.setup {
+        ignored_next_char = string.gsub([[ [%w%%%'%[%.] ]], '%s+', ''),
+        enable_afterquote = false,
+      }
+
+      npairs.add_rules {
+        Rule(' ', ' '):with_pair(function(opts)
+          local pair = opts.line:sub(opts.col - 1, opts.col)
+          return vim.tbl_contains({ '()', '[]', '{}' }, pair)
+        end),
+        Rule('( ', ' )')
+          :with_pair(function() return false end)
+          :with_move(function(opts) return opts.prev_char:match '.%)' ~= nil end)
+          :use_key ')',
+        Rule('{ ', ' }')
+          :with_pair(function() return false end)
+          :with_move(function(opts) return opts.prev_char:match '.%}' ~= nil end)
+          :use_key '}',
+        Rule('[ ', ' ]')
+          :with_pair(function() return false end)
+          :with_move(function(opts) return opts.prev_char:match '.%]' ~= nil end)
+          :use_key ']',
+      }
 
-    use {
-      'tpope/vim-eunuch',
-      cmd = {
-        'Delete',
-        'Unlink',
-        'Move',
-        'Rename',
-        'Mkdir',
-        'Chmod',
-        'Cfind',
-        'Clocate',
-        'Lfind',
-        'Llocate',
-        'SudoEdit',
-        'SudoWrite',
-        'Wall',
-      },
-    }
+      npairs.get_rule('`'):with_pair(function() return vim.bo.filetype ~= 'systemverilog' end)
+
+      npairs.get_rule("'")[1]:with_pair(function() return vim.bo.filetype ~= 'systemverilog' end)
+    end,
+  },
+
+  -- Moving around within lines
+  { 'wellle/targets.vim', event = 'InsertEnter *' },
+
+  -- Search
+  -- Opening files
+  { 'wsdjeg/vim-fetch' },
+
+  -- session management
+  {
+    'folke/persistence.nvim',
+    event = 'BufReadPre',
+    module = 'persistence',
+    config = function() require('persistence').setup() end,
+  },
+
+  -- Indent lines
+  {
+    'lukas-reineke/indent-blankline.nvim',
+    config = function()
+      vim.g.indent_blankline_buftype_exclude = { 'terminal', 'help', 'nofile' }
+      vim.g.indent_blankline_show_first_indent_level = false
+      vim.g.indent_blankline_char = '│'
+    end,
+  },
 
-    -- Smooth scrolling
-    use {
-      'karb94/neoscroll.nvim',
-      config = function() require('neoscroll').setup {} end,
-    }
+  -- Increment/decrement
+  {
+    'zegervdv/nrpattern.nvim',
+    branch = 'lua',
+    dependencies = 'tpope/vim-repeat',
+    config = function()
+      local nrpattern = require 'nrpattern'
+      local defaults = require 'nrpattern.default'
+
+      defaults[{ 'input', 'output' }] = { priority = 12, filetypes = { 'verilog', 'systemverilog' } }
+      defaults[{ "'1", "'0" }] = { priority = 9, filetypes = { 'verilog', 'systemverilog' } }
+
+      nrpattern.setup(defaults)
+    end,
+  },
+
+  -- Tmux
+  {
+    'numtostr/navigator.nvim',
+    config = function()
+      require('Navigator').setup { auto_save = 'current', disable_on_zoom = true }
 
-    -- Faster lua package loading (until 15436 is merged)
-    use {
-      'lewis6991/impatient.nvim',
-      module = { 'impatient' },
-      setup = function() require 'impatient' end,
-    }
+      local nmap = function(lhs, rhs, opts) return vim.keymap.set('n', lhs, rhs, opts) end
+      nmap('<c-h>', require('Navigator').left, { silent = true })
+      nmap('<c-j>', require('Navigator').down, { silent = true })
+      nmap('<c-k>', require('Navigator').up, { silent = true })
+      nmap('<c-l>', require('Navigator').right, { silent = true })
+    end,
+  },
 
-    -- Library with lua functions
-    use { 'nvim-lua/plenary.nvim' }
+  -- Keymap help
+  {
+    'folke/which-key.nvim',
+    config = function()
+      require('which-key').setup {
+        plugins = {
+          spelling = {
+            enabled = true,
+            suggestions = 20,
+          },
+        },
+        triggers = { '<leader>', 'g', '<c-w>', '"', '`', 'z' },
+      }
+    end,
+  },
 
-    -- Spelling/autocorrection
-    use { 'tpope/vim-abolish' }
+  -- Completion/snippets/LSP
+  { 'neovim/nvim-lspconfig' },
+  {
+    'hrsh7th/nvim-cmp',
+    dependencies = {
+      'hrsh7th/cmp-buffer',
+      'hrsh7th/cmp-nvim-lsp',
+      'saadparwaiz1/cmp_luasnip',
+      'hrsh7th/cmp-path',
+      'hrsh7th/cmp-cmdline',
+      'hrsh7th/cmp-nvim-lsp-signature-help',
+    },
+    config = function()
+      local cmp = require 'cmp'
+      local luasnip = require 'luasnip'
+
+      local has_words_before = function()
+        local line, col = unpack(vim.api.nvim_win_get_cursor(0))
+        return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match '%s' == nil
+      end
 
-    -- Git/VCS
-    use { 'vim-scripts/gitignore' }
-    use {
-      'zegervdv/settle.nvim',
-      opt = true,
-      cmd = { 'SettleInit' },
+      cmp.setup {
+        snippet = {
+          expand = function(args) luasnip.lsp_expand(args.body) end,
+        },
+        mapping = {
+          ['<C-p>'] = { i = cmp.mapping.select_prev_item() },
+          ['<C-n>'] = { i = cmp.mapping.select_next_item() },
+          ['<C-d>'] = { i = cmp.mapping.scroll_docs(-4) },
+          ['<C-y>'] = { i = cmp.mapping.complete() },
+          ['<C-e>'] = { i = cmp.mapping.close() },
+          ['<CR>'] = { i = cmp.mapping.confirm { behavior = cmp.ConfirmBehavior.Replace } },
+          ['<C-k>'] = { i = cmp.mapping.confirm { behavior = cmp.ConfirmBehavior.Replace } },
+        },
+        sources = {
+          { name = 'nvim_lsp' },
+          { name = 'nvim_lsp_signature_help' },
+          { name = 'buffer', keyword_length = 5 },
+          { name = 'luasnip' },
+          { name = 'path' },
+        },
+        experimental = {
+          native_menu = false,
+          ghost_text = true,
+        },
+      }
+
+      cmp.setup.cmdline(':', {
+        mapping = cmp.mapping.preset.cmdline {
+          ['<C-p>'] = { c = cmp.mapping.select_prev_item() },
+          ['<C-n>'] = { c = cmp.mapping.select_next_item() },
+          ['<C-y>'] = { c = cmp.mapping.complete() },
+        },
+        sources = cmp.config.sources({
+          { name = 'path' },
+        }, {
+          { name = 'cmdline', keyword_length = 4 },
+        }),
+      })
+    end,
+  },
+  {
+    {
+      'nvim-treesitter/nvim-treesitter',
       config = function()
-        require('settle').setup {
-          wrap = true,
-          symbol = '▊',
-          pre_hook = function()
-            -- disable dirvish
-            vim.api.nvim_del_keymap('n', '-')
-          end,
-        }
-      end,
-    }
-    use { 'tpope/vim-git', ft = { 'gitcommit', 'gitrebase' } }
-    use {
-      local_plugin 'diffview.nvim',
-      config = function()
-        require('diffview').setup {
-          use_icons = false,
-          icons = {
-            folder_closed = '+',
-            folder_open = '-',
+        require 'nvim-treesitter.highlight'
+
+        require('nvim-treesitter.configs').setup {
+          ensure_installed = {
+            'python',
+            'lua',
+            'verilog',
+            'json',
+            'yaml',
+            'bash',
+            'dockerfile',
+            'c',
+            'cpp',
+            'regex',
+            'markdown',
+            'rst',
+            'beancount',
           },
-          signs = {
-            fold_closed = '+',
-            fold_open = '-',
-            done = '✓',
+          indent = {
+            enable = false,
+          },
+          highlight = {
+            enable = true,
+            disable = { 'systemverilog', 'verilog' },
           },
-          hg_cmd = { 'chg' },
-          view = {
-            merge_tool = {
-              layout = 'diff4_mixed',
+          incremental_selection = {
+            enable = true,
+            keymaps = {
+              init_selection = 'gnn',
+              node_incremental = 'grn',
+              scope_incremental = 'grc',
+              node_decremental = 'grm',
             },
           },
-        }
-        local wk = require 'which-key'
-        wk.register { ['<leader>d'] = { name = 'Diffview' } }
-        vim.keymap.set('n', '<leader>do', '<cmd>DiffviewOpen<CR>', { desc = 'Open Diffview' })
-        vim.keymap.set('n', '<leader>df', '<cmd>DiffviewFileHistory %<CR>', { desc = 'Show history for current file' })
-        vim.keymap.set('n', '<leader>dh', ':DiffviewFileHistory ', { desc = 'Show history' })
-        vim.keymap.set('n', '<leader>dc', '<cmd>DiffviewClose<CR>', { desc = 'Close Diffview window' })
-      end,
-    }
-
-    -- Comments
-    use {
-      'numToStr/Comment.nvim',
-      config = function()
-        local ft = require 'Comment.ft'
-        ft.systemverilog = { '//%s', '/*%s*/' }
-        ft.verilog = { '//%s', '/*%s*/' }
-
-        require('Comment').setup {
-          padding = true,
-          sticky = true,
-          ignore = '^(%s*)$',
-          mappings = {
-            basic = true,
-            extra = true,
-          },
-        }
-      end,
-      keys = {
-        { 'n', 'gc', 'Comment toggle' },
-        { 'n', 'gb', 'Comment Block toggle' },
-        { 'v', 'gc', 'Comment toggle' },
-        { 'v', 'gb', 'Comment block toggle' },
-      },
-    }
-
-    -- Parentheses etc
-    use { 'kylechui/nvim-surround', config = function() require('nvim-surround').setup() end }
-    use {
-      'windwp/nvim-autopairs',
-      config = function()
-        local npairs = require 'nvim-autopairs'
-        local Rule = require 'nvim-autopairs.rule'
-
-        local cmp = require 'nvim-autopairs.completion.cmp'
-
-        require('cmp').event:on('confirm_done', cmp.on_confirm_done())
-
-        npairs.setup {
-          ignored_next_char = string.gsub([[ [%w%%%'%[%.] ]], '%s+', ''),
-          enable_afterquote = false,
-        }
-
-        npairs.add_rules {
-          Rule(' ', ' '):with_pair(function(opts)
-            local pair = opts.line:sub(opts.col - 1, opts.col)
-            return vim.tbl_contains({ '()', '[]', '{}' }, pair)
-          end),
-          Rule('( ', ' )')
-            :with_pair(function() return false end)
-            :with_move(function(opts) return opts.prev_char:match '.%)' ~= nil end)
-            :use_key ')',
-          Rule('{ ', ' }')
-            :with_pair(function() return false end)
-            :with_move(function(opts) return opts.prev_char:match '.%}' ~= nil end)
-            :use_key '}',
-          Rule('[ ', ' ]')
-            :with_pair(function() return false end)
-            :with_move(function(opts) return opts.prev_char:match '.%]' ~= nil end)
-            :use_key ']',
-        }
-
-        npairs.get_rule('`'):with_pair(function() return vim.bo.filetype ~= 'systemverilog' end)
-
-        npairs.get_rule("'")[1]:with_pair(function() return vim.bo.filetype ~= 'systemverilog' end)
-      end,
-      after = { 'nvim-cmp' },
-    }
-
-    -- Moving around within lines
-    use { 'wellle/targets.vim', event = 'InsertEnter *' }
-
-    -- Search
-    -- Opening files
-    use { 'wsdjeg/vim-fetch' }
-
-    -- session management
-    use {
-      'folke/persistence.nvim',
-      event = 'BufReadPre',
-      module = 'persistence',
-      config = function() require('persistence').setup() end,
-    }
-
-    -- Indent lines
-    use {
-      'lukas-reineke/indent-blankline.nvim',
-      config = function()
-        vim.g.indent_blankline_buftype_exclude = { 'terminal', 'help', 'nofile' }
-        vim.g.indent_blankline_show_first_indent_level = false
-        vim.g.indent_blankline_char = '│'
-      end,
-    }
-
-    -- Increment/decrement
-    use {
-      'zegervdv/nrpattern.nvim',
-      branch = 'lua',
-      requires = 'tpope/vim-repeat',
-      config = function()
-        local nrpattern = require 'nrpattern'
-        local defaults = require 'nrpattern.default'
-
-        defaults[{ 'input', 'output' }] = { priority = 12, filetypes = { 'verilog', 'systemverilog' } }
-        defaults[{ "'1", "'0" }] = { priority = 9, filetypes = { 'verilog', 'systemverilog' } }
-
-        nrpattern.setup(defaults)
-      end,
-    }
-
-    -- Tmux
-    use {
-      'numtostr/navigator.nvim',
-      config = function()
-        require('Navigator').setup { auto_save = 'current', disable_on_zoom = true }
-
-        local nmap = function(lhs, rhs, opts) return vim.keymap.set('n', lhs, rhs, opts) end
-        nmap('<c-h>', require('Navigator').left, { silent = true })
-        nmap('<c-j>', require('Navigator').down, { silent = true })
-        nmap('<c-k>', require('Navigator').up, { silent = true })
-        nmap('<c-l>', require('Navigator').right, { silent = true })
-      end,
-    }
-
-    -- Keymap help
-    use {
-      'folke/which-key.nvim',
-      config = function()
-        require('which-key').setup {
-          plugins = {
-            spelling = {
-              enabled = true,
-              suggestions = 20,
+          refactor = {
+            highlight_definitions = { enable = true },
+            smart_rename = { enable = true, keymaps = { smart_rename = 'gsr' } },
+            navigation = {
+              enable = true,
+              keymaps = { goto_definition = 'gnd', list_definitions = 'gnD' },
             },
           },
-          triggers = { '<leader>', 'g', '<c-w>', '"', '`', 'z' },
-        }
-      end,
-    }
-
-    -- Completion/snippets/LSP
-    use { 'neovim/nvim-lspconfig' }
-    use {
-      'hrsh7th/nvim-cmp',
-      requires = {
-        'hrsh7th/cmp-buffer',
-        'hrsh7th/cmp-nvim-lsp',
-        'saadparwaiz1/cmp_luasnip',
-        'hrsh7th/cmp-path',
-        'hrsh7th/cmp-cmdline',
-        'hrsh7th/cmp-nvim-lsp-signature-help',
-      },
-      config = function()
-        local cmp = require 'cmp'
-        local luasnip = require 'luasnip'
-
-        local has_words_before = function()
-          local line, col = unpack(vim.api.nvim_win_get_cursor(0))
-          return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match '%s' == nil
-        end
-
-        cmp.setup {
-          snippet = {
-            expand = function(args) luasnip.lsp_expand(args.body) end,
-          },
-          mapping = {
-            ['<C-p>'] = { i = cmp.mapping.select_prev_item() },
-            ['<C-n>'] = { i = cmp.mapping.select_next_item() },
-            ['<C-d>'] = { i = cmp.mapping.scroll_docs(-4) },
-            ['<C-y>'] = { i = cmp.mapping.complete() },
-            ['<C-e>'] = { i = cmp.mapping.close() },
-            ['<CR>'] = { i = cmp.mapping.confirm { behavior = cmp.ConfirmBehavior.Replace } },
-            ['<C-k>'] = { i = cmp.mapping.confirm { behavior = cmp.ConfirmBehavior.Replace } },
-          },
-          sources = {
-            { name = 'nvim_lsp' },
-            { name = 'nvim_lsp_signature_help' },
-            { name = 'buffer', keyword_length = 5 },
-            { name = 'luasnip' },
-            { name = 'path' },
-          },
-          experimental = {
-            native_menu = false,
-            ghost_text = true,
-          },
-        }
-
-        cmp.setup.cmdline(':', {
-          mapping = cmp.mapping.preset.cmdline {
-            ['<C-p>'] = { c = cmp.mapping.select_prev_item() },
-            ['<C-n>'] = { c = cmp.mapping.select_next_item() },
-            ['<C-y>'] = { c = cmp.mapping.complete() },
-          },
-          sources = cmp.config.sources({
-            { name = 'path' },
-          }, {
-            { name = 'cmdline', keyword_length = 4 },
-          }),
-        })
-      end,
-      after = 'luasnip',
-    }
-    use {
-      {
-        'nvim-treesitter/nvim-treesitter',
-        run = ':TSUpdate',
-        config = function()
-          require 'nvim-treesitter.highlight'
-
-          require('nvim-treesitter.configs').setup {
-            ensure_installed = {
-              'python',
-              'lua',
-              'verilog',
-              'json',
-              'yaml',
-              'bash',
-              'dockerfile',
-              'c',
-              'cpp',
-              'regex',
-              'markdown',
-              'rst',
-              'beancount',
+          textobjects = {
+            move = {
+              enable = true,
+              goto_next_start = { [']]'] = '@block.outer' },
+              goto_previous_start = { ['[['] = '@block.outer' },
+              goto_next_end = { [']['] = '@block.outer' },
+              goto_previous_end = { ['[]'] = '@block.outer' },
             },
-            indent = {
-              enable = false,
-            },
-            highlight = {
+            select = {
               enable = true,
-              disable = { 'systemverilog', 'verilog' },
-            },
-            incremental_selection = {
-              enable = true,
+              lookahead = true,
               keymaps = {
-                init_selection = 'gnn',
-                node_incremental = 'grn',
-                scope_incremental = 'grc',
-                node_decremental = 'grm',
-              },
-            },
-            refactor = {
-              highlight_definitions = { enable = true },
-              smart_rename = { enable = true, keymaps = { smart_rename = 'gsr' } },
-              navigation = {
-                enable = true,
-                keymaps = { goto_definition = 'gnd', list_definitions = 'gnD' },
+                ['af'] = '@function.outer',
+                ['if'] = '@function.inner',
+                ['ab'] = '@block.outer',
+                ['ib'] = '@block.inner',
               },
             },
-            textobjects = {
-              move = {
-                enable = true,
-                goto_next_start = { [']]'] = '@block.outer' },
-                goto_previous_start = { ['[['] = '@block.outer' },
-                goto_next_end = { [']['] = '@block.outer' },
-                goto_previous_end = { ['[]'] = '@block.outer' },
-              },
-              select = {
-                enable = true,
-                lookahead = true,
-                keymaps = {
-                  ['af'] = '@function.outer',
-                  ['if'] = '@function.inner',
-                  ['ab'] = '@block.outer',
-                  ['ib'] = '@block.inner',
-                },
-              },
-            },
-            playground = { enable = true, disable = {}, updatetime = 25, persist_queries = false },
-          }
-        end,
-      },
-      'nvim-treesitter/nvim-treesitter-refactor',
-      'nvim-treesitter/nvim-treesitter-textobjects',
-      { 'nvim-treesitter/playground', opt = true },
-    }
-    use { 'L3MON4D3/luasnip' }
-    use {
-      'rmagatti/goto-preview',
-      config = function() require('goto-preview').setup {} end,
-    }
-    use {
-      'jose-elias-alvarez/null-ls.nvim',
-      requires = 'nvim-lua/plenary.nvim',
-    }
-    use { 'folke/neodev.nvim' }
-    use {
-      'smjonas/inc-rename.nvim',
-      config = function()
-        require('inc_rename').setup {
-          post_hook = function(result)
-            local changed = {}
-            for uri, changes in pairs(result.changes or result.documentChanges) do
-              local bufnr = vim.uri_to_bufnr(uri)
-              for _, edits in ipairs(changes) do
-                table.insert(changed, {
-                  bufnr = bufnr,
-                  lnum = edits.range.start.line + 1,
-                  col = edits.range.start.character + 1,
-                  text = vim.api.nvim_buf_get_lines(bufnr, edits.range.start.line, edits.range.start.line + 1, false)[1],
-                })
-              end
-            end
-            vim.fn.setqflist(changed, 'r')
-          end,
+          },
+          playground = { enable = true, disable = {}, updatetime = 25, persist_queries = false },
         }
       end,
-    }
-    use {
-      'joechrisellis/lsp-format-modifications.nvim',
-      requires = { 'nvim-lua/plenary.nvim' },
-    }
-    use {
-      'vigoux/notifier.nvim',
-      config = function() require('notifier').setup { status_width = 70 } end,
-    }
-    use {
-      'https://git.sr.ht/~whynothugo/lsp_lines.nvim',
-      disable = true,
-      config = function()
-        require('lsp_lines').setup()
-        vim.diagnostic.config { virtual_lines = false, virtual_text = false }
-        vim.keymap.set(
-          'n',
-          'g?',
-          function() require('lsp_lines').toggle() end,
-          { desc = 'Toggle LSP diagnostic lines' }
-        )
-      end,
-    }
-
-    use {
-      'ThePrimeagen/refactoring.nvim',
-      after = 'which-key.nvim',
-      requires = {
-        'nvim-lua/plenary.nvim',
-        'nvim-treesitter/nvim-treesitter',
-      },
-      config = function()
-        local refactoring = require 'refactoring'
-        local wk = require 'which-key'
-
-        refactoring.setup {}
-
-        wk.register { ['<leader>r'] = { name = 'Refactoring' } }
+    },
+    'nvim-treesitter/nvim-treesitter-refactor',
+    'nvim-treesitter/nvim-treesitter-textobjects',
+    { 'nvim-treesitter/playground' },
+  },
+  { 'L3MON4D3/luasnip' },
+  {
+    'rmagatti/goto-preview',
+    config = function() require('goto-preview').setup {} end,
+  },
+  {
+    'jose-elias-alvarez/null-ls.nvim',
+    dependencies = 'nvim-lua/plenary.nvim',
+  },
+  { 'folke/neodev.nvim', version = '2.5.x' },
+  {
+    'smjonas/inc-rename.nvim',
+    config = function()
+      require('inc_rename').setup {
+        post_hook = function(result)
+          local changed = {}
+          for uri, changes in pairs(result.changes or result.documentChanges) do
+            local bufnr = vim.uri_to_bufnr(uri)
+            for _, edits in ipairs(changes) do
+              table.insert(changed, {
+                bufnr = bufnr,
+                lnum = edits.range.start.line + 1,
+                col = edits.range.start.character + 1,
+                text = vim.api.nvim_buf_get_lines(bufnr, edits.range.start.line, edits.range.start.line + 1, false)[1],
+              })
+            end
+          end
+          vim.fn.setqflist(changed, 'r')
+        end,
+      }
+    end,
+  },
+  {
+    'joechrisellis/lsp-format-modifications.nvim',
+    dependencies = { 'nvim-lua/plenary.nvim' },
+  },
+  {
+    'vigoux/notifier.nvim',
+    config = function() require('notifier').setup { status_width = 70 } end,
+  },
 
-        local maps = {
-          { mode = 'v', key = 'e', name = 'Extract Function' },
-          { mode = 'v', key = 'f', name = 'Extract Function To File' },
-          { mode = 'v', key = 'v', name = 'Extract Variable' },
-          { mode = 'v', key = 'i', name = 'Inline Variable' },
-          { mode = 'n', key = 'b', name = 'Extract Block' },
-          { mode = 'n', key = 'bf', name = 'Extract Block To File' },
-          { mode = 'n', key = 'i', name = 'Inline Variable' },
-        }
-        for _, map in ipairs(maps) do
-          vim.keymap.set(
-            map.mode,
-            '<leader>r' .. map.key,
-            function() refactoring.refactor(map.name) end,
-            { desc = map.name, silent = true, expr = false }
-          )
-        end
-        vim.keymap.set(
-          'n',
-          '<leader>rpp',
-          function() refactoring.debug.printf { below = false } end,
-          { desc = 'Add debug print statement', silent = true }
-        )
-        vim.keymap.set(
-          'n',
-          '<leader>rpv',
-          function() refactoring.debug.print_var { normal = true } end,
-          { desc = 'Print variable', silent = true }
-        )
+  {
+    'ThePrimeagen/refactoring.nvim',
+    dependencies = {
+      'nvim-lua/plenary.nvim',
+      'nvim-treesitter/nvim-treesitter',
+    },
+    config = function()
+      local refactoring = require 'refactoring'
+      local wk = require 'which-key'
+
+      refactoring.setup {}
+
+      wk.register { ['<leader>r'] = { name = 'Refactoring' } }
+
+      local maps = {
+        { mode = 'v', key = 'e', name = 'Extract Function' },
+        { mode = 'v', key = 'f', name = 'Extract Function To File' },
+        { mode = 'v', key = 'v', name = 'Extract Variable' },
+        { mode = 'v', key = 'i', name = 'Inline Variable' },
+        { mode = 'n', key = 'b', name = 'Extract Block' },
+        { mode = 'n', key = 'bf', name = 'Extract Block To File' },
+        { mode = 'n', key = 'i', name = 'Inline Variable' },
+      }
+      for _, map in ipairs(maps) do
         vim.keymap.set(
-          'v',
-          '<leader>rpv',
-          function() refactoring.debug.print_var() end,
-          { desc = 'Print variable', silent = true }
-        )
-        vim.keymap.set(
-          'n',
-          '<leader>rpc',
-          function() refactoring.debug.cleanup {} end,
-          { desc = 'Clean up debug prints', silent = true }
+          map.mode,
+          '<leader>r' .. map.key,
+          function() refactoring.refactor(map.name) end,
+          { desc = map.name, silent = true, expr = false }
         )
-      end,
-    }
-
-    use {
-      'ibhagwan/fzf-lua',
-      config = function()
-        local fzf = require 'fzf-lua'
-        fzf.setup {
-          winopts = {
-            border = 'single',
-          },
-        }
-        fzf.register_ui_select()
-
-        local grep_opts = function(pattern)
-          local utils = require 'fzf-lua.utils'
-          local config = require 'fzf-lua.config'
-
-          local args = utils.input 'rg opts> '
-          local rg_opts = config.globals.grep.rg_opts .. ' ' .. args
-          local opts = config.normalize_opts({ rg_opts = rg_opts }, config.globals.grep)
+      end
+      vim.keymap.set(
+        'n',
+        '<leader>rpp',
+        function() refactoring.debug.printf { below = false } end,
+        { desc = 'Add debug print statement', silent = true }
+      )
+      vim.keymap.set(
+        'n',
+        '<leader>rpv',
+        function() refactoring.debug.print_var { normal = true } end,
+        { desc = 'Print variable', silent = true }
+      )
+      vim.keymap.set(
+        'v',
+        '<leader>rpv',
+        function() refactoring.debug.print_var() end,
+        { desc = 'Print variable', silent = true }
+      )
+      vim.keymap.set(
+        'n',
+        '<leader>rpc',
+        function() refactoring.debug.cleanup {} end,
+        { desc = 'Clean up debug prints', silent = true }
+      )
+    end,
+  },
 
-          opts.search = pattern
-          fzf.live_grep(opts)
-        end
-        local get_selected_word = function()
-          local start_pos = vim.fn.getpos "'["
-          local end_pos = vim.fn.getpos "']"
-          local start_line = math.min(start_pos[2], end_pos[2]) - 1
-          local end_line = math.max(start_pos[2], end_pos[2])
-          local start_col = math.min(start_pos[3], end_pos[3])
-          local end_col = math.max(start_pos[3], end_pos[3])
+  {
+    'ibhagwan/fzf-lua',
+    config = function()
+      local fzf = require 'fzf-lua'
+      fzf.setup {
+        winopts = {
+          border = 'single',
+        },
+      }
+      fzf.register_ui_select()
 
-          local line = vim.api.nvim_buf_get_lines(0, start_line, end_line, true)
-          return line[1]:sub(start_col, end_col)
-        end
+      local grep_opts = function(pattern)
+        local utils = require 'fzf-lua.utils'
+        local config = require 'fzf-lua.config'
 
-        vim.keymap.set({ 'n' }, '<leader>fg', function() grep_opts() end, { desc = 'Live grep prompting for options' })
-        vim.keymap.set({ 'n' }, '<leader>ff', function() fzf.files() end, { desc = 'Search for files' })
-
-        function _G.__live_grep(motion)
-          local word = get_selected_word()
-          fzf.live_grep { search = word }
-        end
+        local args = utils.input 'rg opts> '
+        local rg_opts = config.globals.grep.rg_opts .. ' ' .. args
+        local opts = config.normalize_opts({ rg_opts = rg_opts }, config.globals.grep)
 
-        vim.keymap.set({ 'x', 'n' }, 'gs', function()
-          vim.o.operatorfunc = 'v:lua.__live_grep'
-          return 'g@'
-        end, { expr = true, desc = 'Live grep for word' })
+        opts.search = pattern
+        fzf.live_grep(opts)
+      end
+      local get_selected_word = function()
+        local start_pos = vim.fn.getpos "'["
+        local end_pos = vim.fn.getpos "']"
+        local start_line = math.min(start_pos[2], end_pos[2]) - 1
+        local end_line = math.max(start_pos[2], end_pos[2])
+        local start_col = math.min(start_pos[3], end_pos[3])
+        local end_col = math.max(start_pos[3], end_pos[3])
 
-        function _G.__live_grep_opts(motion)
-          local word = get_selected_word()
-          grep_opts(word)
-        end
+        local line = vim.api.nvim_buf_get_lines(0, start_line, end_line, true)
+        return line[1]:sub(start_col, end_col)
+      end
 
-        vim.keymap.set({ 'x', 'n' }, 'gt', function()
-          vim.o.operatorfunc = 'v:lua.__live_grep_opts'
-          return 'g@'
-        end, { expr = true, desc = 'Live grep for word with options' })
-      end,
-    }
+      vim.keymap.set({ 'n' }, '<leader>fg', function() grep_opts() end, { desc = 'Live grep prompting for options' })
+      vim.keymap.set({ 'n' }, '<leader>ff', function() fzf.files() end, { desc = 'Search for files' })
+
+      function _G.__live_grep(motion)
+        local word = get_selected_word()
+        fzf.live_grep { search = word }
+      end
 
-    use { 'vimjas/vim-python-pep8-indent', ft = { 'python' } }
+      vim.keymap.set({ 'x', 'n' }, 'gs', function()
+        vim.o.operatorfunc = 'v:lua.__live_grep'
+        return 'g@'
+      end, { expr = true, desc = 'Live grep for word' })
 
-    use {
-      'rebelot/heirline.nvim',
-      after = { 'espresso-tutti-colori.nvim', 'catppuccin' },
-      config = function()
-        local utils = require 'heirline.utils'
-        local conditions = require 'heirline.conditions'
+      function _G.__live_grep_opts(motion)
+        local word = get_selected_word()
+        grep_opts(word)
+      end
 
-        local colors
-        if os.getenv 'DARKMODE' then
-          colors = require('catppuccin.palettes').get_palette 'mocha'
-        else
-          colors = require('tutti-colori.colors').setup()
-        end
-        colors.diag_warn = utils.get_highlight('DiagnosticSignWarn').fg
-        colors.diag_error = utils.get_highlight('DiagnosticSignError').fg
+      vim.keymap.set({ 'x', 'n' }, 'gt', function()
+        vim.o.operatorfunc = 'v:lua.__live_grep_opts'
+        return 'g@'
+      end, { expr = true, desc = 'Live grep for word with options' })
+    end,
+  },
 
-        require('heirline').load_colors(colors)
+  { 'vimjas/vim-python-pep8-indent', ft = { 'python' } },
 
-        local align = { provider = '%=' }
-        local space = { provider = ' ' }
-        local lbound = { provider = '▊ ', hl = { fg = 'blue', bg = 'bg' } }
-        local rbound = { provider = ' ▊', hl = { fg = 'blue', bg = 'bg' } }
+  {
+    'rebelot/heirline.nvim',
+    config = function()
+      local utils = require 'heirline.utils'
+      local conditions = require 'heirline.conditions'
 
-        local FileNameBlock = {
-          init = function(self) self.filename = vim.api.nvim_buf_get_name(0) end,
-        }
+      local colors
+      if os.getenv 'DARKMODE' then
+        colors = require('catppuccin.palettes').get_palette 'macchiato'
+      else
+        colors = require('tutti-colori.colors').setup()
+      end
 
-        local FileName = {
-          provider = function(self)
-            local filename = vim.fn.fnamemodify(self.filename, ':.')
-            if filename == '' then return '[No Name]' end
-
-            if not conditions.width_percent_below(#filename, 0.25) then filename = vim.fn.pathshorten(filename) end
+      colors.diag_warn = utils.get_highlight('DiagnosticSignWarn').fg
+      colors.diag_error = utils.get_highlight('DiagnosticSignError').fg
 
-            return filename
-          end,
-          hl = { fg = 'blue' },
-        }
+      require('heirline').load_colors(colors)
+
+      local align = { provider = '%=' }
+      local space = { provider = ' ' }
+      local lbound = { provider = '▊ ', hl = { fg = 'blue', bg = 'bg' } }
+      local rbound = { provider = ' ▊', hl = { fg = 'blue', bg = 'bg' } }
+
+      local FileNameBlock = {
+        init = function(self) self.filename = vim.api.nvim_buf_get_name(0) end,
+      }
 
-        local FileFlags = {
-          {
-            provider = function()
-              if vim.bo.modified then return ' [+]' end
-            end,
-            hl = { fg = 'green' },
-          },
-          {
-            provider = function()
-              if not vim.bo.modifiable or vim.bo.readonly then return ' RO' end
-            end,
-            hl = { fg = 'orange' },
-          },
-        }
+      local FileName = {
+        provider = function(self)
+          local filename = vim.fn.fnamemodify(self.filename, ':.')
+          if filename == '' then return '[No Name]' end
+
+          if not conditions.width_percent_below(#filename, 0.25) then filename = vim.fn.pathshorten(filename) end
 
-        FileNameBlock = utils.insert(FileNameBlock, FileName, unpack(FileFlags), { provider = '%<' })
-
-        local Ruler = { provider = '%l : %c  %P' }
+          return filename
+        end,
+        hl = { fg = 'blue' },
+      }
 
-        local Lsp = {
-          condition = conditions.lsp_attached,
-          update = { 'LspAttach', 'LspDetach' },
+      local FileFlags = {
+        {
           provider = function()
-            local names = {}
-            for _, server in pairs(vim.lsp.get_active_clients { bufnr = 0 }) do
-              table.insert(names, server.name)
-            end
-            return table.concat(names, ', ')
+            if vim.bo.modified then return ' [+]' end
           end,
           hl = { fg = 'green' },
-        }
-
-        local Diagnostics = {
-          condition = conditions.has_diagnostics,
-          init = function(self)
-            self.errors = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.ERROR })
-            self.warnings = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.WARN })
+        },
+        {
+          provider = function()
+            if not vim.bo.modifiable or vim.bo.readonly then return ' RO' end
           end,
-          update = { 'DiagnosticChanged', 'BufEnter' },
-          {
-            provider = function(self) return self.errors > 0 and self.errors .. ' ' end,
-            hl = { fg = 'diag_error' },
-          },
-          {
-            provider = function(self) return self.warnings > 0 and self.warnings .. ' ' end,
-          },
-          hl = { fg = 'diag_warn' },
-          on_click = {
-            callback = function()
-              local diagnostics = vim.diagnostic.get(0, { severity = { min = vim.diagnostic.severity.WARN } })
-              vim.fn.setqflist(vim.diagnostic.toqflist(diagnostics))
-              vim.cmd.copen { mods = { split = 'botright' } }
-            end,
-            name = 'heirline_diagnostics',
-          },
-        }
+          hl = { fg = 'orange' },
+        },
+      }
+
+      FileNameBlock = utils.insert(FileNameBlock, FileName, unpack(FileFlags), { provider = '%<' })
+
+      local Ruler = { provider = '%l : %c  %P' }
+
+      local Lsp = {
+        condition = conditions.lsp_attached,
+        update = { 'LspAttach', 'LspDetach' },
+        provider = function()
+          local names = {}
+          for _, server in pairs(vim.lsp.get_active_clients { bufnr = 0 }) do
+            table.insert(names, server.name)
+          end
+          return table.concat(names, ', ')
+        end,
+        hl = { fg = 'green' },
+      }
 
-        local Window = {
-          provider = function() return '- ' .. vim.api.nvim_win_get_number(0) .. ' -' end,
-          hl = { fg = 'blue' },
-        }
+      local Diagnostics = {
+        condition = conditions.has_diagnostics,
+        init = function(self)
+          self.errors = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.ERROR })
+          self.warnings = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.WARN })
+        end,
+        update = { 'DiagnosticChanged', 'BufEnter' },
+        {
+          provider = function(self) return self.errors > 0 and self.errors .. ' ' end,
+          hl = { fg = 'diag_error' },
+        },
+        {
+          provider = function(self) return self.warnings > 0 and self.warnings .. ' ' end,
+        },
+        hl = { fg = 'diag_warn' },
+        on_click = {
+          callback = function()
+            local diagnostics = vim.diagnostic.get(0, { severity = { min = vim.diagnostic.severity.WARN } })
+            vim.fn.setqflist(vim.diagnostic.toqflist(diagnostics))
+            vim.cmd.copen { mods = { split = 'botright' } }
+          end,
+          name = 'heirline_diagnostics',
+        },
+      }
 
-        local statusline_default = { lbound, FileNameBlock, align, Diagnostics, Lsp, space, Ruler, rbound }
-        local statusline_inactive = {
-          condition = function() return not conditions.is_active() end,
-          lbound,
-          FileNameBlock,
-          align,
-          Window,
-          rbound,
-        }
-        local statusline = {
-          fallthrough = false,
-          hl = { bg = 'bg' },
-          statusline_inactive,
-          statusline_default,
-        }
-
-        require('heirline').setup { statusline = statusline }
-      end,
-    }
+      local Window = {
+        provider = function() return '- ' .. vim.api.nvim_win_get_number(0) .. ' -' end,
+        hl = { fg = 'blue' },
+      }
 
-    -- File navigation
-    use {
-      'elihunter173/dirbuf.nvim',
-      opt = true,
-      config = function()
-        require('dirbuf').setup {
-          hash_padding = 2,
-          show_hidden = true,
-        }
-      end,
-    }
+      local statusline_default = { lbound, FileNameBlock, align, Diagnostics, Lsp, space, Ruler, rbound }
+      local statusline_inactive = {
+        condition = function() return not conditions.is_active() end,
+        lbound,
+        FileNameBlock,
+        align,
+        Window,
+        rbound,
+      }
+      local statusline = {
+        fallthrough = false,
+        hl = { bg = 'bg' },
+        statusline_inactive,
+        statusline_default,
+      }
 
-    -- Colorscheme
-    use {
-      local_plugin 'espresso-tutti-colori.nvim',
-      disable = os.getenv 'DARKMODE',
-      config = function()
-        require('tutti-colori').setup()
-        require('tutti-colori').load()
-      end,
-    }
-    use {
-      'catppuccin/nvim',
-      as = 'catppuccin',
-      config = function()
-        require('catppuccin').setup {
-          flavour = 'mocha',
-        }
-      end,
-    }
+      require('heirline').setup { statusline = statusline }
+    end,
+  },
+
+  -- File navigation
+  {
+    'elihunter173/dirbuf.nvim',
+    config = function()
+      require('dirbuf').setup {
+        hash_padding = 2,
+        show_hidden = true,
+      }
+    end,
+  },
 
-    -- Terminal
-    use {
-      'akinsho/nvim-toggleterm.lua',
-      config = function()
-        require('toggleterm').setup {
-          size = 15,
-          open_mapping = [[<F12>]],
-          shade_filetypes = { 'none' },
-          shade_terminals = true,
-          persist_size = true,
-          direction = 'horizontal',
-        }
-      end,
-      keys = { [[<F12>]] },
-    }
+  -- Colorscheme
+  {
+    'zegervdv/espresso-tutti-colori.nvim',
+    name = 'tutti-colori',
+    cond = not os.getenv 'DARKMODE',
+    config = function()
+      require('tutti-colori').setup()
+      require('tutti-colori').load()
+    end,
+    priority = 1000,
+    lazy = false,
+  },
+  {
+    'catppuccin/nvim',
+    name = 'catppuccin',
+    cond = not not os.getenv 'DARKMODE',
+    config = function()
+      require('catppuccin').setup {
+        flavour = 'macchiato',
+      }
+      vim.cmd.colorscheme 'catppuccin-macchiato'
+    end,
+    priority = 1000,
+    lazy = false,
+  },
 
-    -- Integration with external tools
-    use {
-      'glacambre/firenvim',
-      run = function() vim.fn['firenvim#install'](0) end,
-      config = function()
-        vim.g.firenvim_config = {
-          localSettings = {
-            ['.*'] = {
-              takeover = 'never',
-            },
+  -- Integration with external tools
+  {
+    'glacambre/firenvim',
+    build = function() vim.fn['firenvim#install'](0) end,
+    config = function()
+      vim.g.firenvim_config = {
+        localSettings = {
+          ['.*'] = {
+            takeover = 'never',
           },
-        }
-      end,
-    }
-  end,
-  config = { snapshot_path = vim.fn.stdpath 'config' },
+        },
+      }
+    end,
+  },
 }
 
-vim.cmd.packadd 'dirbuf.nvim'
-
-if os.getenv 'DARKMODE' then
-  vim.cmd.colorscheme 'catppuccin'
-else
-  require('tutti-colori').setup()
-  vim.cmd.colorscheme 'espresso-tutti-colori'
-end
-
 -- Configuration
 vim.opt.backspace = { 'indent', 'eol', 'start' } -- Backspace everything
 
@@ -983,9 +925,6 @@
 -- General keymaps
 local map = vim.keymap.set
 
--- Set leader to space
-vim.g.mapleader = ' '
-
 -- Move while in insert mode
 map('i', '<C-f>', '<right>')