summary refs log tree commit diff
path: root/.config/nvim/lua/plugins
diff options
context:
space:
mode:
Diffstat (limited to '.config/nvim/lua/plugins')
-rw-r--r--.config/nvim/lua/plugins/blink.lua94
-rw-r--r--.config/nvim/lua/plugins/calcium.lua15
-rw-r--r--.config/nvim/lua/plugins/colorizer.lua15
-rw-r--r--.config/nvim/lua/plugins/fzf.lua103
-rw-r--r--.config/nvim/lua/plugins/gentoo.lua15
-rw-r--r--.config/nvim/lua/plugins/git.lua116
-rw-r--r--.config/nvim/lua/plugins/icons.lua13
-rw-r--r--.config/nvim/lua/plugins/indent.lua30
-rw-r--r--.config/nvim/lua/plugins/lsp.lua6
-rw-r--r--.config/nvim/lua/plugins/markdown.lua82
-rw-r--r--.config/nvim/lua/plugins/mini.lua26
-rw-r--r--.config/nvim/lua/plugins/oil.lua21
-rw-r--r--.config/nvim/lua/plugins/snippets.lua13
-rw-r--r--.config/nvim/lua/plugins/treesitter.lua93
-rw-r--r--.config/nvim/lua/plugins/whichkey.lua10
15 files changed, 652 insertions, 0 deletions
diff --git a/.config/nvim/lua/plugins/blink.lua b/.config/nvim/lua/plugins/blink.lua
new file mode 100644
index 0000000..1122bcc
--- /dev/null
+++ b/.config/nvim/lua/plugins/blink.lua
@@ -0,0 +1,94 @@
+return {
+  {
+    'saghen/blink.cmp',
+    version = '1.*',
+
+    lazy = false,
+
+    dependencies = {
+      { 'L3MON4D3/LuaSnip' },
+    },
+
+    init = function()
+      vim.opt.completeopt = { 'menu', 'menuone', 'noselect' }
+      vim.opt.shortmess:append('c')
+      vim.opt.pumheight = 20 -- max height of completion window
+
+      local hl = vim.api.nvim_set_hl
+      hl(0, 'BlinkCmpSource', { link = 'Comment', force = true })
+      hl(0, 'BlinkCmpLabelDescription', { link = 'Comment', force = true })
+    end,
+
+    opts_extend = { 'sources.default' },
+
+    opts = {
+      -- TODO:
+      -- 'prefer_rust_with_warning', requires nightly rust, due to:
+      -- https://github.com/rust-lang/rust/issues/86656
+      fuzzy = { 
+        implementation = 'lua',
+        sorts = {
+          function(a, b)
+            local prio = {
+              snippets = 99,
+              -- everyting else 0
+            }
+            local a_priority = prio[a.source_id] or 0
+            local b_priority = prio[b.source_id] or 0
+            if a_priority ~= b_priority then return a_priority > b_priority end
+          end,
+          -- defaults
+          'score',
+          'sort_text'
+        },
+      },
+
+      appearance = {
+        -- fallback to cmp highlight names
+        use_nvim_cmp_as_default = true,
+        -- adjusts spacing to ensure icons are aligned
+        -- nerd_font_variant = 'normal',
+      },
+
+      sources = {
+        providers = {
+          buffer = { min_keyword_length = 3 },
+        },
+      },
+
+      completion = {
+        documentation = { auto_show = true },
+        menu = {
+          draw = {
+            columns = {
+              { 'kind_icon' },
+              { 'label', 'label_description', gap = 1 },
+              { 'source_name' },
+            },
+          },
+        },
+      },
+
+      signature = {
+        enabled = true,
+        window = { scrollbar = false }, -- BUG: weird artifacts
+      },
+
+      keymap = {
+        ['<C-space>'] = { 'show', 'show_documentation', 'hide_documentation' },
+        ['<C-e>'] = { 'cancel', 'fallback' },
+        ['<C-y>'] = { 'select_and_accept' },
+        ['<C-p>'] = { 'select_prev', 'fallback' },
+        ['<C-n>'] = { 'select_next', 'fallback' },
+        ['<C-b>'] = { 'scroll_documentation_up', 'fallback' },
+        ['<C-f>'] = { 'scroll_documentation_down', 'fallback' },
+        ['<Tab>'] = { 'select_and_accept', 'fallback' },
+        ['<C-j>'] = { 'snippet_forward', 'fallback' },
+        ['<C-k>'] = { 'snippet_backward', 'fallback' },
+        -- ['<C-l>'] = { 'show', 'hide', 'fallback' },
+      },
+
+      snippets = { preset = 'luasnip' },
+    },
+  },
+}
diff --git a/.config/nvim/lua/plugins/calcium.lua b/.config/nvim/lua/plugins/calcium.lua
new file mode 100644
index 0000000..f0ab78c
--- /dev/null
+++ b/.config/nvim/lua/plugins/calcium.lua
@@ -0,0 +1,15 @@
+return {
+  {
+    'necrom4/calcium.nvim',
+    cmd = {'Calcium'},
+    opts = {
+      notifications = false,
+      default_mode = 'replace',
+    },
+    keys = {
+      { mode = {'n', 'v'}, 'gl', '<nop>', desc = 'Calcium' },
+      { mode = {'n', 'v'}, 'glr', ':Calcium replace<cr>', desc = 'Calcium replace', silent = true },
+      { mode = {'n', 'v'}, 'gla', ':Calcium append<cr>', desc = 'Calcium append', silent = true },
+    },
+  }
+}
diff --git a/.config/nvim/lua/plugins/colorizer.lua b/.config/nvim/lua/plugins/colorizer.lua
new file mode 100644
index 0000000..2608ae6
--- /dev/null
+++ b/.config/nvim/lua/plugins/colorizer.lua
@@ -0,0 +1,15 @@
+return {
+  {
+    'NvChad/nvim-colorizer.lua',
+    -- 'norcalli/nvim-colorizer.lua',
+    lazy = false,
+    opts = {
+      name = true,
+      RRGGBB = true,
+      RRGGBBAA = true,
+      rgb_fn = true,
+      hsl_fn = true,
+      mode = 'background',
+    },
+  },
+}
diff --git a/.config/nvim/lua/plugins/fzf.lua b/.config/nvim/lua/plugins/fzf.lua
new file mode 100644
index 0000000..efee6ef
--- /dev/null
+++ b/.config/nvim/lua/plugins/fzf.lua
@@ -0,0 +1,103 @@
+return {
+  {
+    enabled = true,
+    'ibhagwan/fzf-lua',
+    lazy = false,
+    dependencies = {
+      'echasnovski/mini.icons',
+    },
+    config = function()
+      local fzf = require('fzf-lua')
+      fzf.register_ui_select()
+      fzf.setup({
+        -- PROFILE
+        { 'default' },
+        -- OPTIONS
+        winopts = {
+          split = 'belowright 20new',
+          border = 'none',
+          preview = {
+            border = 'none',
+          },
+          -- on_create = function() end,
+        },
+        keymap = {
+          fzf = {
+            true,
+            ['ctrl-n'] = 'down',
+            ['ctrl-p'] = 'up',
+          },
+        },
+        -- actions = {
+        --   files = {
+        --     ['ctrl-q'] = { fn = fzf.actions.file_sel_to_qf },
+        --   },
+        -- },
+        fzf_colors = true,
+        -- PICKER CONFIG
+        files = {
+          file_icons = true,
+        },
+        marks = {
+          marks = '[a-zA-Z]',
+        }
+      })
+    end,
+    keys = {
+      { mode = 'n', ';<space>', '<cmd>FzfLua<cr>', desc = 'fzf: select' },
+      { mode = 'n', ';/', '<cmd>FzfLua blines<cr>', desc = 'fzf: current_buffer_fuzzy_find' },
+      { mode = 'n', ';b', '<cmd>FzfLua buffers<cr>', desc = 'fzf: buffers' },
+      { mode = 'n', ';f', '<cmd>FzfLua files<cr>', desc = 'fzf: find_files' },
+      { mode = 'n', ';g', '<cmd>FzfLua live_grep<cr>', desc = 'fzf: live_grep' },
+      { mode = 'n', ';d', '<cmd>FzfLua diagnostics_workspace<cr>', desc = 'fzf: workspace diagnostics' },
+      { mode = 'n', ';D', '<cmd>FzfLua diagnostics_document<cr>', desc = 'fzf: document diagnostics' },
+      { mode = 'n', ';h', '<cmd>FzfLua helptags<cr>', desc = 'fzf: help' },
+      { mode = 'n', ';s', '<cmd>FzfLua lsp_document_symbols<cr>', desc = 'fzf: document symbols' },
+      { mode = 'n', ';w', '<cmd>FzfLua lsp_live_workspace_symbols<cr>', desc = 'fzf: workspace symbols' },
+      { mode = 'n', ';m', '<cmd>FzfLua marks<cr>', desc = 'fzf: marks' },
+      {
+        mode = 'n',
+        ';v',
+        function()
+          require('fzf-lua').files({ cwd = vim.fn.stdpath('config') })
+        end,
+        desc = 'fzf: vim_config',
+      },
+      -- {
+      --   mode = 'n',
+      --   ';;t',
+      --   '<cmd>Telescope<cr>',
+      --   desc = 'telescope: select (interactive)',
+      -- },
+      {
+        mode = 'n',
+        ';;f',
+        function()
+          local dir
+          if vim.opt.filetype:get() == 'oil' then
+            dir = require('oil').get_current_dir()
+          else
+            dir = vim.fn.expand('%:p:h')
+          end
+          -- require('fzf-lua').files({ cwd = dir })
+          _G.feedkeys(':Fzf files cwd=' .. dir)
+        end,
+        desc = 'fzf: files (interactive)',
+      },
+      {
+        mode = 'n',
+        ';;g',
+        function()
+          local dir
+          if vim.opt.filetype:get() == 'oil' then
+            dir = require('oil').get_current_dir()
+          else
+            dir = vim.fn.expand('%:p:h')
+          end
+          _G.feedkeys(':Fzf live_grep cwd=' .. dir)
+        end,
+        desc = 'fzf: grep (interactive)',
+      },
+    },
+  },
+}
diff --git a/.config/nvim/lua/plugins/gentoo.lua b/.config/nvim/lua/plugins/gentoo.lua
new file mode 100644
index 0000000..470e6de
--- /dev/null
+++ b/.config/nvim/lua/plugins/gentoo.lua
@@ -0,0 +1,15 @@
+return {
+  {
+    'gentoo/gentoo-syntax',
+    -- ft = { 'ebuild' },
+    -- init = function()
+    --   vim.api.nvim_create_autocmd('LspAttach', {
+    --     callback = function(args)
+    --       if vim.opt.filetype == 'ebuild' then
+    --         vim.lsp.stop_client(vim.lsp.get_clients({ bufnr = args.bufnr }))
+    --       end
+    --     end,
+    --   })
+    -- end,
+  },
+}
diff --git a/.config/nvim/lua/plugins/git.lua b/.config/nvim/lua/plugins/git.lua
new file mode 100644
index 0000000..2561ad9
--- /dev/null
+++ b/.config/nvim/lua/plugins/git.lua
@@ -0,0 +1,116 @@
+return {
+  {
+    'lewis6991/gitsigns.nvim',
+    lazy = false,
+    opts = {
+      debug_mode = false,
+    },
+    keys = {
+      {
+        ']c',
+        function()
+          if vim.wo.diff then
+            vim.cmd.normal({ ']c', bang = true })
+          else
+            require('gitsigns').nav_hunk('next')
+          end
+        end,
+        desc = 'Gitsigns: next hunk',
+      },
+      {
+        '[c',
+        function()
+          if vim.wo.diff then
+            vim.cmd.normal({ '[c', bang = true })
+          else
+            require('gitsigns').nav_hunk('prev')
+          end
+        end,
+        desc = 'Gitsigns: prev hunk',
+      },
+      { '<leader>g', '<nop>', desc = 'git' },
+      { '<leader>g<space>', '<cmd>Gitsigns<cr>', desc = 'Gitsigns: select action' },
+      { '<leader>gb', '<cmd>Gitsigns blame<cr>', desc = 'Gitsigns: blame' },
+      { '<leader>ga', '<cmd>Gitsigns stage_hunk<cr>', desc = 'Gitsigns: stage hunk' },
+      { '<leader>ga', ':Gitsigns stage_hunk<cr>', desc = 'Gitsigns: stage hunk', mode = 'x' },
+      { '<leader>gd', ':Gitsigns diffthis<cr>', desc = 'Gitsigns: diff' },
+      {
+        ';c',
+        function()
+          require('gitsigns').setqflist('all', { open = false })
+          require('fzf-lua').quickfix({ prompt = 'Git changesets' })
+        end,
+        desc = 'Gitsigns: list hunks',
+      },
+    },
+  },
+
+  {
+    'linrongbin16/gitlinker.nvim',
+    cmd = { 'GitLink' },
+    dependencies = { 'nvim-lua/plenary.nvim' },
+    opts = {
+      message = true,
+    },
+    keys = {
+      {
+        '<leader>gl',
+        vim.cmd.GitLink,
+        desc = 'GitLinker: clipboard',
+      },
+    },
+  },
+
+  {
+    'moyiz/git-dev.nvim',
+    lazy = true,
+    cmd = { 'GitDevOpen', 'GitDevCleanAll' },
+    opts = {
+      read_only = false,
+    },
+  },
+
+  {
+    'isakbm/gitgraph.nvim',
+    dependencies = { 'sindrets/diffview.nvim' },
+    opts = {
+      symbols = {
+        merge_commit = 'M',
+        commit = '∙',
+      },
+      format = {
+        timestamp = '%d-%m-%Y %H:%M:%S %z',
+        fields = { 'hash', 'timestamp', 'author', 'branch_name', 'tag' },
+      },
+    },
+    init = vim.schedule_wrap(function()
+      vim.api.nvim_set_hl(0, 'GitGraphBranch1', { fg = 'NvimLightGray1' })
+      vim.api.nvim_set_hl(0, 'GitGraphBranch2', { fg = 'NvimLightMagenta' })
+      vim.api.nvim_set_hl(0, 'GitGraphBranch3', { fg = 'NvimLightRed' })
+      vim.api.nvim_set_hl(0, 'GitGraphBranch4', { fg = 'NvimDarkCyan' })
+      vim.api.nvim_set_hl(0, 'GitGraphBranch5', { fg = 'NvimDarkYellow' })
+      vim.api.nvim_set_hl(0, 'GitGraphHash', { fg = 'NvimLightMagenta' })
+      vim.api.nvim_set_hl(0, 'GitGraphAuthor', { fg = 'NvimLightGray4', italic = true })
+      vim.api.nvim_set_hl(0, 'GitGraphTimestamp', { fg = 'NvimLightCyan' })
+      vim.api.nvim_set_hl(0, 'GitGraphBranchName', { fg = 'NvimLightYellow' })
+      vim.api.nvim_set_hl(0, 'GitGraphBranchTag', { fg = 'NvimLightYellow' })
+      vim.api.nvim_set_hl(0, 'GitGraphBranchMsg', { link = 'Normal' })
+      -- vim.api.nvim_create_autocmd('FileType', {
+      --   pattern = { 'gitgraph' },
+      --   callback = function()
+      --     vim.keymap.set('n', 'q', '<cmd>bdel!<cr>', { silent = true, buffer = 0 })
+      --   end,
+      --   group = vim.api.nvim_create_augroup('GitGraph'),
+      -- })
+    end),
+    keys = {
+      {
+        'g-',
+        function()
+          require('gitgraph').draw({}, { all = true, max_count = 5000 })
+        end,
+        desc = 'GitGraph: view log',
+      },
+    },
+  },
+}
diff --git a/.config/nvim/lua/plugins/icons.lua b/.config/nvim/lua/plugins/icons.lua
new file mode 100644
index 0000000..9a597ab
--- /dev/null
+++ b/.config/nvim/lua/plugins/icons.lua
@@ -0,0 +1,13 @@
+return {
+  {
+    'echasnovski/mini.icons',
+    version = false,
+    events = { 'VeryLazy' },
+    -- opts = {},
+    config = function(_, opts)
+      require('mini.icons').setup(opts)
+      ---@diagnostic disable-next-line: undefined-global
+      MiniIcons.mock_nvim_web_devicons()
+    end,
+  },
+}
diff --git a/.config/nvim/lua/plugins/indent.lua b/.config/nvim/lua/plugins/indent.lua
new file mode 100644
index 0000000..e247c5a
--- /dev/null
+++ b/.config/nvim/lua/plugins/indent.lua
@@ -0,0 +1,30 @@
+return {
+  -- show indents using virtual text
+  {
+    'lukas-reineke/indent-blankline.nvim',
+    lazy = false,
+    main = 'ibl',
+    opts = {
+      indent = {
+        char = '▏',
+      },
+      scope = {
+        enabled = true,
+        show_start = false,
+        show_end = false,
+        char = '▌',
+      },
+    },
+  },
+  -- detect indent from the buffer contents
+  {
+    enabled = false,
+    'NMAC427/guess-indent.nvim',
+    lazy = false,
+    opts = {
+      auto_cmd = true,
+      filetype_exclude = { 'netrw', 'tutor', 'dirbuf', 'nvimtree', 'oil' },
+      buftype_exclude = { 'help', 'nofile', 'terminal', 'prompt' },
+    },
+  },
+}
diff --git a/.config/nvim/lua/plugins/lsp.lua b/.config/nvim/lua/plugins/lsp.lua
new file mode 100644
index 0000000..aebf3c4
--- /dev/null
+++ b/.config/nvim/lua/plugins/lsp.lua
@@ -0,0 +1,6 @@
+return {
+  {
+    'neovim/nvim-lspconfig',
+    version = '^2.0',
+  }
+}
diff --git a/.config/nvim/lua/plugins/markdown.lua b/.config/nvim/lua/plugins/markdown.lua
new file mode 100644
index 0000000..b21255e
--- /dev/null
+++ b/.config/nvim/lua/plugins/markdown.lua
@@ -0,0 +1,82 @@
+return {
+  {
+    -- handy markdown commands
+    'tadmccorkle/markdown.nvim',
+    ft = { 'markdown' },
+    opts = {
+      mappings = false,
+      on_attach = function(buf)
+        local set = function(mode, lhs, rhs, desc)
+          vim.keymap.set(mode, lhs, rhs, { buffer = buf, desc = 'Markdown: ' .. desc })
+        end
+        set('n', 'nio', '<cmd>MDListItemBelow<cr>', 'Insert list item below')
+        set('n', 'niO', '<cmd>MDListItemAbove<cr>', 'Insert list item above')
+        set({ 'n', 'v', 'x', 'i' }, '<m-x>', '<cmd>MDTaskToggle<cr>', 'Toggle task')
+        set('x', '<m-l>', '<esc>gv<plug>(markdown_add_link_visual)', 'Make link')
+      end,
+    },
+  },
+  {
+    -- pretty markdown
+    'MeanderingProgrammer/markdown.nvim',
+    name = 'render-markdown', -- needed if used together with markdown.nvim above
+    main = 'render-markdown',
+    dependencies = {
+      'nvim-treesitter/nvim-treesitter',
+      'echasnovski/mini.icons',
+    },
+    ft = { 'markdown' },
+    opts = {
+      completions = { blink = { enabled = true } },
+      sign = { enabled = true },
+      indent = { enabled = false },
+      heading = {
+        width = 'block',
+        icons = {
+          '▒ ',
+          '▒▒ ',
+          '▒▒▒ ',
+          '▒▒▒▒ ',
+          '▒▒▒▒▒ ',
+          '▒▒▒▒▒▒ ',
+        },
+        signs = { 'ⅰ', 'ⅱ', 'ⅲ', 'ⅳ', 'ⅴ', 'ⅵ' },
+        backgrounds = {},
+        foregrounds = {},
+      },
+      bullet = {
+        icons = { '* ', '-', '>' },
+      },
+      checkbox = {
+        checked = { icon = '  󰄲 ' },
+        unchecked = { icon = '  󰄱 ' },
+        custom = {
+          todo = { raw = '[-]', rendered = '  󰔟 ', highlight = 'RenderMarkdownTodo' },
+        },
+      },
+      code = {
+        width = 'block',
+        border = 'thin',
+        disable_background = true,
+      },
+    },
+    init = vim.schedule_wrap(function()
+      local hl = vim.api.nvim_set_hl
+      hl(0, '@markup.bold', { link = 'markdownBold', force = true })
+      hl(0, '@markup.italic', { link = 'markdownItalic', force = true })
+
+      -- hl(0, 'RenderMarkdownH1', { fg = 'NvimLightCyan' })
+      -- hl(0, 'RenderMarkdownH1Bg', { bg = 'NvimDarkCyan' })
+      -- hl(0, 'RenderMarkdownH2', { fg = 'NvimLightMagenta' })
+      -- hl(0, 'RenderMarkdownH2Bg', { bg = 'NvimDarkMagenta' })
+      -- hl(0, 'RenderMarkdownH3', { fg = 'NvimLightYellow' })
+      -- hl(0, 'RenderMarkdownH3Bg', { bg = 'NvimDarkYellow' })
+      -- hl(0, 'RenderMarkdownH4', { fg = 'NvimLightBlue' })
+      -- hl(0, 'RenderMarkdownH4Bg', { bg = 'NvimDarkBlue' })
+      -- hl(0, 'RenderMarkdownH5', { fg = 'NvimLightRed' })
+      -- hl(0, 'RenderMarkdownH5Bg', { bg = 'NvimDarkRed' })
+
+      hl(0, 'RenderMarkdownBullet', { link = '@markup.list', force = true })
+    end),
+  },
+}
diff --git a/.config/nvim/lua/plugins/mini.lua b/.config/nvim/lua/plugins/mini.lua
new file mode 100644
index 0000000..fb4c9a6
--- /dev/null
+++ b/.config/nvim/lua/plugins/mini.lua
@@ -0,0 +1,26 @@
+return {
+  {
+    'echasnovski/mini.align',
+    version = false,
+    lazy = false,
+    opts = {},
+  },
+  {
+    'echasnovski/mini.ai',
+    version = false,
+    lazy = false,
+    opts = {},
+  },
+  {
+    'echasnovski/mini.surround',
+    version = false,
+    lazy = false,
+    opts = {},
+  },
+  {
+    'echasnovski/mini.operators',
+    version = false,
+    lazy = false,
+    opts = {},
+  },
+}
diff --git a/.config/nvim/lua/plugins/oil.lua b/.config/nvim/lua/plugins/oil.lua
new file mode 100644
index 0000000..401fe8b
--- /dev/null
+++ b/.config/nvim/lua/plugins/oil.lua
@@ -0,0 +1,21 @@
+return {
+  {
+    'stevearc/oil.nvim',
+    lazy = false,
+    opts = {
+      keymaps = {
+        ['gt'] = {
+          function()
+            local cwd = require('oil').get_current_dir()
+            vim.cmd('silent !footclient --no-wait -D ' .. cwd)
+          end,
+          nowait = true,
+          desc = 'Open current directory with foot',
+        },
+      },
+    },
+    keys = {
+      { mode = 'n', '-', '<cmd>Oil<cr>', desc = 'oil: open parent directory' },
+    },
+  },
+}
diff --git a/.config/nvim/lua/plugins/snippets.lua b/.config/nvim/lua/plugins/snippets.lua
new file mode 100644
index 0000000..97a4455
--- /dev/null
+++ b/.config/nvim/lua/plugins/snippets.lua
@@ -0,0 +1,13 @@
+return {
+  {
+    'L3MON4D3/LuaSnip',
+    version = 'v2.*',
+    build = 'make install_jsregexp',
+    config = function()
+      require('config.snippets')
+    end,
+    dependencies = {
+      "rafamadriz/friendly-snippets",
+    },
+  }
+}
diff --git a/.config/nvim/lua/plugins/treesitter.lua b/.config/nvim/lua/plugins/treesitter.lua
new file mode 100644
index 0000000..93f396d
--- /dev/null
+++ b/.config/nvim/lua/plugins/treesitter.lua
@@ -0,0 +1,93 @@
+return {
+  {
+    'nvim-treesitter/nvim-treesitter',
+    branch = 'master',
+    dependencies = {
+      { 'nvim-treesitter/nvim-treesitter-refactor', lazy = false },
+      { 'nvim-treesitter/nvim-treesitter-textobjects', lazy = false },
+      -- { 'nvim-treesitter/playground', cmd = { 'TSPlayground' } },
+    },
+    lazy = false,
+    build = ':TSUpdate',
+    config = function(_, opts)
+      require('nvim-treesitter.configs').setup(opts)
+
+      -- use bash parser for gentoo ebuilds
+      vim.treesitter.language.register('bash', 'ebuild')
+    end,
+    opts = {
+      ensure_installed = {
+        'bash',
+        'c',
+        'cmake',
+        'comment',
+        'cpp',
+        'css',
+        'dockerfile',
+        'go',
+        'gomod',
+        'gotmpl',
+        'gowork',
+        'html',
+        'javascript',
+        'json',
+        'jsonc',
+        'lua',
+        'make',
+        'markdown',
+        'markdown_inline',
+        'ninja',
+        'python',
+        'regex',
+        'rust',
+        'scss',
+        'sql',
+        'todotxt',
+        'toml',
+        'typescript',
+        'typst',
+        'vim',
+        'vimdoc',
+        'yaml',
+        'zig',
+      },
+      highlight = {
+        enable = true,
+        additional_vim_regex_highlighting = { 'markdown' },
+      },
+      indent = {
+        enable = true,
+      },
+      refactor = {
+        navigation = {
+          enable = true,
+        },
+        smart_rename = {
+          enable = true,
+        },
+      },
+      textobjects = {
+        select = {
+          enable = true,
+          keymaps = {
+            ['ib'] = '@block.inner',
+            ['ab'] = '@block.outer',
+            -- ['ic'] = '@conditional.inner',
+            -- ['ac'] = '@conditional.outer',
+            ['if'] = '@function.inner',
+            ['af'] = '@function.outer',
+            ['il'] = '@loop.inner',
+            ['al'] = '@loop.outer',
+            ['is'] = '@scopename.inner',
+            ['as'] = '@scopename.outer',
+            ['ic'] = '@comment.inner',
+            ['ac'] = '@comment.outer',
+          },
+          selection_mode = {
+            ['@comment.outer'] = 'V',
+          },
+        },
+      },
+    },
+  },
+}
diff --git a/.config/nvim/lua/plugins/whichkey.lua b/.config/nvim/lua/plugins/whichkey.lua
new file mode 100644
index 0000000..dc21eda
--- /dev/null
+++ b/.config/nvim/lua/plugins/whichkey.lua
@@ -0,0 +1,10 @@
+return {
+  {
+    'folke/which-key.nvim',
+    event = 'VeryLazy',
+    opts = {
+      sort = { 'alphanum' },
+      icons = { separator = '→ ', group = '🞱 ' },
+    },
+  },
+}