From d0bb6d84ba42d0a2980514d1777ee0b15b2b490e Mon Sep 17 00:00:00 2001 From: Job79 Date: Mon, 1 Jun 2026 21:02:04 +0200 Subject: [PATCH 1/9] refactor: switch to minimax --- .gitignore | 8 - after/ftplugin/markdown.lua | 42 ++ after/lsp/lua_ls.lua | 35 ++ after/snippets/lua.json | 4 + init.lua | 124 +++++- lazy-lock.json | 34 -- lazyvim.json | 10 - lua/config/lazy.lua | 43 -- lua/config/options.lua | 4 - lua/plugins/ai.lua | 32 -- lua/plugins/colorscheme.lua | 7 - lua/plugins/disabled.lua | 25 -- lua/plugins/php.lua | 136 ------ nvim-pack-lock.json | 32 ++ plugin/10_options.lua | 129 ++++++ plugin/20_keymaps.lua | 249 +++++++++++ plugin/30_mini.lua | 803 ++++++++++++++++++++++++++++++++++++ plugin/40_plugins.lua | 141 +++++++ 18 files changed, 1558 insertions(+), 300 deletions(-) delete mode 100644 .gitignore create mode 100644 after/ftplugin/markdown.lua create mode 100644 after/lsp/lua_ls.lua create mode 100644 after/snippets/lua.json delete mode 100644 lazy-lock.json delete mode 100644 lazyvim.json delete mode 100644 lua/config/lazy.lua delete mode 100644 lua/config/options.lua delete mode 100644 lua/plugins/ai.lua delete mode 100644 lua/plugins/colorscheme.lua delete mode 100644 lua/plugins/disabled.lua delete mode 100644 lua/plugins/php.lua create mode 100644 nvim-pack-lock.json create mode 100644 plugin/10_options.lua create mode 100644 plugin/20_keymaps.lua create mode 100644 plugin/30_mini.lua create mode 100644 plugin/40_plugins.lua diff --git a/.gitignore b/.gitignore deleted file mode 100644 index cc5457a..0000000 --- a/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -tt.* -.tests -doc/tags -debug -.repro -foo.* -*.log -data diff --git a/after/ftplugin/markdown.lua b/after/ftplugin/markdown.lua new file mode 100644 index 0000000..be6d298 --- /dev/null +++ b/after/ftplugin/markdown.lua @@ -0,0 +1,42 @@ +-- ┌─────────────────────────┐ +-- │ Filetype config example │ +-- └─────────────────────────┘ +-- +-- This is an example of a configuration that will apply only to a particular +-- filetype, which is the same as file's basename ('markdown' in this example; +-- which is for '*.md' files). +-- +-- It can contain any code which will be usually executed when the file is opened +-- (strictly speaking, on every 'filetype' option value change to target value). +-- Usually it needs to define buffer/window local options and variables. +-- So instead of `vim.o` to set options, use `vim.bo` for buffer-local options and +-- `vim.cmd('setlocal ...')` for window-local options (currently more robust). +-- +-- This is also a good place to set buffer-local 'mini.nvim' variables. +-- See `:h mini.nvim-buffer-local-config` and `:h mini.nvim-disabling-recipes`. + +-- Enable spelling and wrap for window +vim.cmd('setlocal spell wrap') + +-- Fold with tree-sitter +vim.cmd('setlocal foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr()') + +-- Disable built-in `gO` mapping in favor of 'mini.basics' +vim.keymap.del('n', 'gO', { buffer = 0 }) + +-- Set markdown-specific surrounding in 'mini.surround' +vim.b.minisurround_config = { + custom_surroundings = { + -- Markdown link. Common usage: + -- `saiwL` + [type/paste link] + - add link + -- `sdL` - delete link + -- `srLL` + [type/paste link] + - replace link + L = { + input = { '%[().-()%]%(.-%)' }, + output = function() + local link = require('mini.surround').user_input('Link: ') + return { left = '[', right = '](' .. link .. ')' } + end, + }, + }, +} diff --git a/after/lsp/lua_ls.lua b/after/lsp/lua_ls.lua new file mode 100644 index 0000000..08acbcd --- /dev/null +++ b/after/lsp/lua_ls.lua @@ -0,0 +1,35 @@ +-- ┌────────────────────┐ +-- │ LSP config example │ +-- └────────────────────┘ +-- +-- This file contains configuration of 'lua_ls' language server. +-- Source: https://github.com/LuaLS/lua-language-server +-- +-- It is used by `:h vim.lsp.enable()` and `:h vim.lsp.config()`. +-- See `:h vim.lsp.Config` and `:h vim.lsp.ClientConfig` for all available fields. +-- +-- This config is designed for Lua's activity around Neovim. It provides only +-- basic config and can be further improved. +return { + on_attach = function(client, buf_id) + -- Reduce very long list of triggers for better 'mini.completion' experience + client.server_capabilities.completionProvider.triggerCharacters = + { '.', ':', '#', '(' } + + -- Use this function to define buffer-local mappings and behavior that depend + -- on attached client or only makes sense if there is language server attached. + end, + -- LuaLS Structure of these settings comes from LuaLS, not Neovim + settings = { + Lua = { + -- Define runtime properties. Use 'LuaJIT', as it is built into Neovim. + runtime = { version = 'LuaJIT', path = vim.split(package.path, ';') }, + workspace = { + -- Don't analyze code from submodules + ignoreSubmodules = true, + -- Add Neovim's methods for easier code writing + library = { vim.env.VIMRUNTIME }, + }, + }, + }, +} diff --git a/after/snippets/lua.json b/after/snippets/lua.json new file mode 100644 index 0000000..9bb78a6 --- /dev/null +++ b/after/snippets/lua.json @@ -0,0 +1,4 @@ +{ + "local": { "prefix": "l", "body": "local $1 = $0" }, + "Remove prefixes": { "prefix": ["lfu", "ll", "lpca"] } +} diff --git a/init.lua b/init.lua index 55b8979..d9f0b93 100644 --- a/init.lua +++ b/init.lua @@ -1 +1,123 @@ -require("config.lazy") +-- ┌────────────────────┐ +-- │ Welcome to MiniMax │ +-- └────────────────────┘ +-- +-- This is a config designed to mostly use MINI. It provides out of the box +-- a stable, polished, and feature rich Neovim experience. Its structure: +-- +-- ├ init.lua Initial (this) file executed during startup +-- ├ plugin/ Files automatically sourced during startup +-- ├── 10_options.lua Built-in Neovim behavior +-- ├── 20_keymaps.lua Custom mappings +-- ├── 30_mini.lua MINI configuration +-- ├── 40_plugins.lua Plugins outside of MINI +-- ├ snippets/ User defined snippets (has demo file) +-- ├ after/ Files to override behavior added by plugins +-- ├── ftplugin/ Files for filetype behavior (has demo file) +-- ├── lsp/ Language server configurations (has demo file) +-- ├── snippets/ Higher priority snippet files (has demo file) +-- +-- Config files are meant to be read, preferably inside a Neovim instance running +-- this config and opened at its root. This will help you better understand your +-- setup. Start with this file. Any order is possible, prefer the one listed above. +-- Ways of navigating your config: +-- - `` + `e` + (one of) `iokmp` - edit 'init.lua' or 'plugin/' files. +-- - Inside config directory: `ff` (picker) or `ed` (explorer) +-- - Navigate existing buffers with `[b`, `]b`, or `fb`. +-- +-- Config files are also meant to be customized. Initially it is a baseline of +-- a working config based on MINI. Modify it to make it yours. Some approaches: +-- - Modify already existing files in a way that keeps them consistent. +-- - Add new files in a way that keeps config consistent. +-- Usually inside 'plugin/' or 'after/'. +-- +-- Documentation comments like this can be found throughout the config. +-- Common conventions: +-- +-- - See `:h key-notation` for key notation used. +-- - `:h xxx` means "documentation of helptag xxx". Either type text directly +-- followed by Enter or type `fh` to open a helptag fuzzy picker. +-- - "Type `fh`" means "press , followed by f, followed by h". +-- Unless said otherwise, it assumes that Normal mode is current. +-- - "See 'path/to/file'" means see open file at described path and read it. +-- - `:SomeCommand ...` or `:lua ...` means execute mentioned command. + +-- ┌────────────────┐ +-- │ Plugin manager │ +-- └────────────────┘ +-- +-- This config uses `vim.pack` - built-in plugin manager. Its main entry +-- point is a `vim.pack.add()` function, which acts like a "smarter `:packadd`": +-- load plugin after making sure it is installed from source. The state of +-- installed plugins is recorded in the lockfile named 'nvim-pack-lock.json'. +-- Example usage: +-- - `vim.pack.add({ ... })` - use inside config to add one or more plugins. +-- - `:lua vim.pack.update()` - update all plugins; execute `:write` to confirm. +-- - `:lua vim.pack.del({ ... })` - delete specific plugins. +-- +-- See also: +-- - `:h vim.pack-examples` - how to use it +-- - `:h vim.pack-lockfile` - lockfile info +-- - `:h vim.pack-events` - available events and plugin hooks examples +-- - `:h vim.pack.update()` - more details about confirmation step + +-- Define config table to be able to pass data between scripts +-- It is a global variable which can be use both as `_G.Config` and `Config` +_G.Config = {} + +-- Define custom autocommand group and helper to create an autocommand. +-- Autocommands are Neovim's way to define actions that are executed on events +-- (like creating a buffer, setting an option, etc.). +-- +-- See also: +-- - `:h autocommand` +-- - `:h nvim_create_augroup()` +-- - `:h nvim_create_autocmd()` +local gr = vim.api.nvim_create_augroup('custom-config', {}) +Config.new_autocmd = function(event, pattern, callback, desc) + local opts = { group = gr, pattern = pattern, callback = callback, desc = desc } + vim.api.nvim_create_autocmd(event, opts) +end + +-- Define custom `vim.pack.add()` hook helper. Plugin data is passed as +-- argument to the callback. See `:h vim.pack-events`. +-- Example usage: see 'plugin/40_plugins.lua'. +-- If any plugin requires installation hooks, add them after this function +-- and before the first `vim.pack.add()` call. +Config.on_packchanged = function(plugin_name, kinds, callback, desc) + local f = function(ev) + local name, kind = ev.data.spec.name, ev.data.kind + if not (name == plugin_name and vim.tbl_contains(kinds, kind)) then return end + if not ev.data.active then vim.cmd.packadd(plugin_name) end + callback(ev.data) + end + Config.new_autocmd('PackChanged', '*', f, desc) +end + +-- 'mini.nvim' - all-in-one plugin powering most MiniMax features. +-- See 'plugin/30_mini.lua' for how it is used. +-- Load now to have 'mini.misc' available for custom loading helpers. +vim.pack.add({ 'https://github.com/nvim-mini/mini.nvim' }) + +-- Loading helpers used to organize config into fail-safe parts. Example usage: +-- - `now` - execute immediately. Use for what must be executed during startup. +-- Like colorscheme, statusline, tabline, dashboard, etc. +-- - `later` - execute a bit later. Use for things not needed during startup. +-- - `now_if_args` - use only if needed during startup when Neovim is started +-- like `nvim -- path/to/file`, but otherwise delaying is fine. +-- - Others are better used only if the above is not enough for good performance. +-- Use only if you are comfortable with adding complexity to your config: +-- - `on_event` - execute once on a first matched event. Like "delay until +-- first Insert mode enter": `on_event('InsertEnter', function() ... end)`. +-- - `on_filetype` - execute once on a first matched filetype. Like "delay +-- until first Lua file": `on_filetype('lua', function() ... end)`. +-- +-- See also: +-- - `:h MiniMisc.safely()` +-- - 'plugin/30_mini.lua' and 'plugin/40_plugins.lua' +local misc = require('mini.misc') +Config.now = function(f) misc.safely('now', f) end +Config.later = function(f) misc.safely('later', f) end +Config.now_if_args = vim.fn.argc(-1) > 0 and Config.now or Config.later +Config.on_event = function(ev, f) misc.safely('event:' .. ev, f) end +Config.on_filetype = function(ft, f) misc.safely('filetype:' .. ft, f) end diff --git a/lazy-lock.json b/lazy-lock.json deleted file mode 100644 index 6abc9f2..0000000 --- a/lazy-lock.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "LazyVim": { "branch": "main", "commit": "fca0af57cc3851b14f96a795a9c9bfafc5096dd1" }, - "blink.cmp": { "branch": "main", "commit": "451168851e8e2466bc97ee3e026c3dcb9141ce07" }, - "catppuccin": { "branch": "main", "commit": "c4d475e4b5684747cde9b3f849186af7837d4397" }, - "codecompanion.nvim": { "branch": "main", "commit": "d5551b1aac60e164fb569eba422ea9b65cd2d6f4" }, - "conform.nvim": { "branch": "master", "commit": "086a40dc7ed8242c03be9f47fbcee68699cc2395" }, - "friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" }, - "gitsigns.nvim": { "branch": "main", "commit": "7c4faa3540d0781a28588cafbd4dd187a28ac6e3" }, - "laravel.nvim": { "branch": "main", "commit": "ef06a69137ed09a72addc0c6f967aaea7d891a63" }, - "lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" }, - "lazydev.nvim": { "branch": "main", "commit": "ff2cbcba459b637ec3fd165a2be59b7bbaeedf0d" }, - "lualine.nvim": { "branch": "master", "commit": "47f91c416daef12db467145e16bed5bbfe00add8" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "a979821a975897b88493843301950c456a725982" }, - "mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" }, - "mini.ai": { "branch": "main", "commit": "4b0a6207341d895b6cfe9bcb1e4d3e8607bfe4f4" }, - "mini.icons": { "branch": "main", "commit": "5b9076dae1bfbe47ba4a14bc8b967cde0ab5d77e" }, - "mini.pairs": { "branch": "main", "commit": "b7fde3719340946feb75017ef9d75edebdeb0566" }, - "noice.nvim": { "branch": "main", "commit": "7bfd942445fb63089b59f97ca487d605e715f155" }, - "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" }, - "nvim-lint": { "branch": "master", "commit": "606b823a57b027502a9ae00978ebf4f5d5158098" }, - "nvim-lspconfig": { "branch": "master", "commit": "841c6d4139aedb8a3f2baf30cef5327371385b93" }, - "nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" }, - "nvim-treesitter": { "branch": "main", "commit": "e5f65e31a5ec0e8526b2311ff8c7aaea4a581c82" }, - "nvim-treesitter-textobjects": { "branch": "main", "commit": "93d60a475f0b08a8eceb99255863977d3a25f310" }, - "nvim-ts-autotag": { "branch": "main", "commit": "8e1c0a389f20bf7f5b0dd0e00306c1247bda2595" }, - "persistence.nvim": { "branch": "main", "commit": "b20b2a7887bd39c1a356980b45e03250f3dce49c" }, - "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" }, - "rose-pine": { "branch": "main", "commit": "cf2a288696b03d0934da713d66c6d71557b5c997" }, - "snacks.nvim": { "branch": "main", "commit": "ad9ede6a9cddf16cedbd31b8932d6dcdee9b716e" }, - "tokyonight.nvim": { "branch": "main", "commit": "5da1b76e64daf4c5d410f06bcb6b9cb640da7dfd" }, - "trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" }, - "ts-comments.nvim": { "branch": "main", "commit": "123a9fb12e7229342f807ec9e6de478b1102b041" }, - "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" } -} diff --git a/lazyvim.json b/lazyvim.json deleted file mode 100644 index d8bcaf6..0000000 --- a/lazyvim.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extras": [ - - ], - "install_version": 8, - "news": { - "NEWS.md": "11866" - }, - "version": 8 -} \ No newline at end of file diff --git a/lua/config/lazy.lua b/lua/config/lazy.lua deleted file mode 100644 index ede6149..0000000 --- a/lua/config/lazy.lua +++ /dev/null @@ -1,43 +0,0 @@ -local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" -if not (vim.uv or vim.loop).fs_stat(lazypath) then - local lazyrepo = "https://github.com/folke/lazy.nvim.git" - local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) - if vim.v.shell_error ~= 0 then - vim.api.nvim_echo({ - { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, - { out, "WarningMsg" }, - { "\nPress any key to exit..." }, - }, true, {}) - vim.fn.getchar() - os.exit(1) - end -end -vim.opt.rtp:prepend(lazypath) - -require("lazy").setup({ - spec = { - { "LazyVim/LazyVim", import = "lazyvim.plugins" }, - { import = "plugins" }, - }, - defaults = { - lazy = false, - version = false, - }, - install = {}, - checker = { - enabled = true, - notify = true, - }, - performance = { - rtp = { - disabled_plugins = { - "gzip", - "netrwPlugin", - "tarPlugin", - "tohtml", - "tutor", - "zipPlugin", - }, - }, - }, -}) diff --git a/lua/config/options.lua b/lua/config/options.lua deleted file mode 100644 index 6d8fca0..0000000 --- a/lua/config/options.lua +++ /dev/null @@ -1,4 +0,0 @@ -vim.o.tw = 60 -vim.o.clipboard = "" -vim.g.snacks_animate = false -vim.g.lazyvim_php_lsp = "intelephense" diff --git a/lua/plugins/ai.lua b/lua/plugins/ai.lua deleted file mode 100644 index 166412d..0000000 --- a/lua/plugins/ai.lua +++ /dev/null @@ -1,32 +0,0 @@ -return { - { - "olimorris/codecompanion.nvim", - dependencies = { - "nvim-lua/plenary.nvim", - "nvim-treesitter/nvim-treesitter", - }, - opts = {}, - keys = { - { "aa", "CodeCompanionChat", mode = { "n", "v" }, desc = "Toggle Chat" }, - { - "ap", - function() - local mode = vim.api.nvim_get_mode().mode - vim.ui.input({ prompt = "AI Prompt: " }, function(input) - if not input or input == "" then - return - end - - if mode:match("[vV]") then - vim.cmd("'<,'>CodeCompanion " .. input) - else - vim.cmd("CodeCompanion #{buffer} " .. input) - end - end) - end, - mode = { "n", "v" }, - desc = "AI Prompt", - }, - }, - }, -} diff --git a/lua/plugins/colorscheme.lua b/lua/plugins/colorscheme.lua deleted file mode 100644 index 4b17922..0000000 --- a/lua/plugins/colorscheme.lua +++ /dev/null @@ -1,7 +0,0 @@ -return { - { "rose-pine/neovim", name = "rose-pine" }, - { - "LazyVim/LazyVim", - opts = { colorscheme = "rose-pine" }, - }, -} diff --git a/lua/plugins/disabled.lua b/lua/plugins/disabled.lua deleted file mode 100644 index 401608e..0000000 --- a/lua/plugins/disabled.lua +++ /dev/null @@ -1,25 +0,0 @@ -return { - { - "folke/snacks.nvim", - opts = { - dashboard = { enabled = false }, - explorer = { trash = false }, - }, - }, - { - "neovim/nvim-lspconfig", - opts = { - inlay_hints = { enabled = false }, - }, - }, - { "akinsho/bufferline.nvim", enabled = false }, - { "folke/flash.nvim", enabled = false }, - { "rafamadriz/friendly-snippets", enabled = false }, - - { "catppuccin/nvim", enabled = false }, - { "folke/tokyonight.nvim", enabled = false }, - - { "folke/todo-comments.nvim", enabled = false }, - { "folke/ts-comments.nvim", enabled = false }, - { "MagicDuck/grug-far.nvim", enabled = false }, -} diff --git a/lua/plugins/php.lua b/lua/plugins/php.lua deleted file mode 100644 index 6924904..0000000 --- a/lua/plugins/php.lua +++ /dev/null @@ -1,136 +0,0 @@ -return { - { - -- Set Laravel Pint as the default PHP formatter with PHP CS Fixer as a fall back. - "stevearc/conform.nvim", - optional = true, - opts = { - formatters_by_ft = { - php = { { "pint", "php_cs_fixer" } }, - }, - }, - }, - { - -- Remove phpcs linter. - "mfussenegger/nvim-lint", - optional = true, - opts = { - linters_by_ft = { - php = {}, - }, - }, - }, - { - "adalessa/laravel.nvim", - dependencies = { - "MunifTanjim/nui.nvim", - "nvim-lua/plenary.nvim", - "nvim-neotest/nvim-nio", - }, - ft = { "php", "blade" }, - event = { - "BufEnter composer.json", - }, - keys = { - { - "ll", - function() - Laravel.pickers.laravel() - end, - desc = "Laravel: Open Laravel Picker", - }, - { - "", - function() - Laravel.commands.run("view:finder") - end, - desc = "Laravel: Open View Finder", - }, - { - "la", - function() - Laravel.pickers.artisan() - end, - desc = "Laravel: Open Artisan Picker", - }, - { - "lt", - function() - Laravel.commands.run("actions") - end, - desc = "Laravel: Open Actions Picker", - }, - { - "lr", - function() - Laravel.pickers.routes() - end, - desc = "Laravel: Open Routes Picker", - }, - { - "lh", - function() - Laravel.run("artisan docs") - end, - desc = "Laravel: Open Documentation", - }, - { - "lm", - function() - Laravel.pickers.make() - end, - desc = "Laravel: Open Make Picker", - }, - { - "lc", - function() - Laravel.pickers.commands() - end, - desc = "Laravel: Open Commands Picker", - }, - { - "lo", - function() - Laravel.pickers.resources() - end, - desc = "Laravel: Open Resources Picker", - }, - { - "lp", - function() - Laravel.commands.run("command_center") - end, - desc = "Laravel: Open Command Center", - }, - { - "lu", - function() - Laravel.commands.run("hub") - end, - desc = "Laravel Artisan hub", - }, - { - "gf", - function() - local ok, res = pcall(function() - if Laravel.app("gf").cursorOnResource() then - return "lua Laravel.commands.run('gf')" - end - end) - if not ok or not res then - return "gf" - end - return res - end, - expr = true, - noremap = true, - }, - }, - opts = { - features = { - pickers = { - provider = "snacks", - }, - }, - }, - }, -} diff --git a/nvim-pack-lock.json b/nvim-pack-lock.json new file mode 100644 index 0000000..1f49d7c --- /dev/null +++ b/nvim-pack-lock.json @@ -0,0 +1,32 @@ +{ + "plugins": { + "conform.nvim": { + "rev": "619363c30309d29ffa631e67c8183f2a72caa373", + "src": "https://github.com/stevearc/conform.nvim" + }, + "friendly-snippets": { + "rev": "6cd7280adead7f586db6fccbd15d2cac7e2188b9", + "src": "https://github.com/rafamadriz/friendly-snippets" + }, + "mason.nvim": { + "rev": "16ba83bfc8a25f52bb545134f5bee082b195c460", + "src": "https://github.com/mason-org/mason.nvim" + }, + "mini.nvim": { + "rev": "232ceeb14f7f7e849056309b85cb2fed712db46f", + "src": "https://github.com/nvim-mini/mini.nvim" + }, + "nvim-lspconfig": { + "rev": "9573948c38bfabeec353ae7dd7d3ffec4c506a6b", + "src": "https://github.com/neovim/nvim-lspconfig" + }, + "nvim-treesitter": { + "rev": "4916d6592ede8c07973490d9322f187e07dfefac", + "src": "https://github.com/nvim-treesitter/nvim-treesitter" + }, + "nvim-treesitter-textobjects": { + "rev": "851e865342e5a4cb1ae23d31caf6e991e1c99f1e", + "src": "https://github.com/nvim-treesitter/nvim-treesitter-textobjects" + } + } +} diff --git a/plugin/10_options.lua b/plugin/10_options.lua new file mode 100644 index 0000000..0e734e4 --- /dev/null +++ b/plugin/10_options.lua @@ -0,0 +1,129 @@ +-- ┌──────────────────────────┐ +-- │ Built-in Neovim behavior │ +-- └──────────────────────────┘ +-- +-- This file defines Neovim's built-in behavior. The goal is to improve overall +-- usability in a way that works best with MINI. +-- +-- Here `vim.o.xxx = value` sets default value of option `xxx` to `value`. +-- See `:h 'xxx'` (replace `xxx` with actual option name). +-- +-- Option values can be customized on a per buffer or window basis. +-- See 'after/ftplugin/' for common example. +-- +-- Notes: +-- - Some options (like `:h 'exrc'`) need to be set before this file is sourced. +-- Set them directly at the bottom of the 'init.lua' file. + +-- stylua: ignore start +-- The next part (until `-- stylua: ignore end`) is aligned manually for easier +-- reading. Consider preserving this or remove `-- stylua` lines to autoformat. + +-- General ==================================================================== +vim.g.mapleader = ' ' -- Use `` as key + +vim.o.mouse = 'a' -- Enable mouse +vim.o.mousescroll = 'ver:25,hor:6' -- Customize mouse scroll +vim.o.switchbuf = 'usetab' -- Use already opened buffers when switching +vim.o.undofile = true -- Enable persistent undo + +vim.o.shada = "'100,<50,s10,:1000,/100,@100,h" -- Limit ShaDa file (for startup) + +-- Enable all filetype plugins and syntax (if not enabled, for better startup) +vim.cmd('filetype plugin indent on') +if vim.fn.exists('syntax_on') ~= 1 then vim.cmd('syntax enable') end + +-- UI ========================================================================= +vim.o.breakindent = true -- Indent wrapped lines to match line start +vim.o.breakindentopt = 'list:-1' -- Add padding for lists (if 'wrap' is set) +vim.o.colorcolumn = '+1' -- Draw column on the right of maximum width +vim.o.cursorline = true -- Enable current line highlighting +vim.o.linebreak = true -- Wrap lines at 'breakat' (if 'wrap' is set) +vim.o.list = true -- Show helpful text indicators +vim.o.number = true -- Show line numbers +vim.o.pumborder = 'single' -- Use border in popup menu +vim.o.pumheight = 10 -- Make popup menu smaller +vim.o.pummaxwidth = 100 -- Make popup menu not too wide +vim.o.ruler = false -- Don't show cursor coordinates +vim.o.shortmess = 'CFOSWaco' -- Disable some built-in completion messages +vim.o.showmode = false -- Don't show mode in command line +vim.o.signcolumn = 'yes' -- Always show signcolumn (less flicker) +vim.o.splitbelow = true -- Horizontal splits will be below +vim.o.splitkeep = 'screen' -- Reduce scroll during window split +vim.o.splitright = true -- Vertical splits will be to the right +vim.o.winborder = 'single' -- Use border in floating windows +vim.o.wrap = false -- Don't visually wrap lines (toggle with \w) + +vim.o.cursorlineopt = 'screenline,number' -- Show cursor line per screen line + +-- Special UI symbols. More is set via 'mini.basics' later. +vim.o.fillchars = 'eob: ,fold:╌' +vim.o.listchars = 'extends:…,nbsp:␣,precedes:…,tab:> ' + +-- Folds (see `:h fold-commands`, `:h zM`, `:h zR`, `:h zA`, `:h zj`) +vim.o.foldlevel = 10 -- Fold nothing by default; set to 0 or 1 to fold +vim.o.foldmethod = 'indent' -- Fold based on indent level +vim.o.foldnestmax = 10 -- Limit number of fold levels +vim.o.foldtext = '' -- Show text under fold with its highlighting + +-- Editing ==================================================================== +vim.o.autoindent = true -- Use auto indent +vim.o.expandtab = true -- Convert tabs to spaces +vim.o.formatoptions = 'rqnl1j'-- Improve comment editing +vim.o.ignorecase = true -- Ignore case during search +vim.o.incsearch = true -- Show search matches while typing +vim.o.infercase = true -- Infer case in built-in completion +vim.o.shiftwidth = 2 -- Use this number of spaces for indentation +vim.o.smartcase = true -- Respect case if search pattern has upper case +vim.o.smartindent = true -- Make indenting smart +vim.o.spelloptions = 'camel' -- Treat camelCase word parts as separate words +vim.o.tabstop = 2 -- Show tab as this number of spaces +vim.o.virtualedit = 'block' -- Allow going past end of line in blockwise mode + +vim.o.iskeyword = '@,48-57,_,192-255,-' -- Treat dash as `word` textobject part + +-- Pattern for a start of numbered list (used in `gw`). This reads as +-- "Start of list item is: at least one special character (digit, -, +, *) +-- possibly followed by punctuation (. or `)`) followed by at least one space". +vim.o.formatlistpat = [[^\s*[0-9\-\+\*]\+[\.\)]*\s\+]] + +-- Built-in completion +vim.o.complete = '.,w,b,kspell' -- Use less sources +vim.o.completeopt = 'menuone,noselect,fuzzy,nosort' -- Use custom behavior +vim.o.completetimeout = 100 -- Limit sources delay + +-- Autocommands =============================================================== + +-- Don't auto-wrap comments and don't insert comment leader after hitting 'o'. +-- Do on `FileType` to always override these changes from filetype plugins. +local f = function() vim.cmd('setlocal formatoptions-=c formatoptions-=o') end +Config.new_autocmd('FileType', nil, f, "Proper 'formatoptions'") + +-- There are other autocommands created by 'mini.basics'. See 'plugin/30_mini.lua'. + +-- Diagnostics ================================================================ + +-- Neovim has built-in support for showing diagnostic messages. This configures +-- a more conservative display while still being useful. +-- See `:h vim.diagnostic` and `:h vim.diagnostic.config()`. +local diagnostic_opts = { + -- Show signs on top of any other sign, but only for warnings and errors + signs = { priority = 9999, severity = { min = 'WARN', max = 'ERROR' } }, + + -- Show all diagnostics as underline (for their messages type `ld`) + underline = { severity = { min = 'HINT', max = 'ERROR' } }, + + -- Show more details immediately for errors on the current line + virtual_lines = false, + virtual_text = { + current_line = true, + severity = { min = 'ERROR', max = 'ERROR' }, + }, + + -- Don't update diagnostics when typing + update_in_insert = false, +} + +-- Use `later()` to avoid sourcing `vim.diagnostic` on startup +Config.later(function() vim.diagnostic.config(diagnostic_opts) end) +-- stylua: ignore end diff --git a/plugin/20_keymaps.lua b/plugin/20_keymaps.lua new file mode 100644 index 0000000..31fdb47 --- /dev/null +++ b/plugin/20_keymaps.lua @@ -0,0 +1,249 @@ +-- ┌─────────────────┐ +-- │ Custom mappings │ +-- └─────────────────┘ +-- +-- This file contains definitions of custom general and Leader mappings. + +-- General mappings =========================================================== + +-- Use this section to add custom general mappings. See `:h vim.keymap.set()`. + +-- An example helper to create a Normal mode mapping +local nmap = function(lhs, rhs, desc) + -- See `:h vim.keymap.set()` + vim.keymap.set('n', lhs, rhs, { desc = desc }) +end + +-- Paste linewise before/after current line +-- Usage: `yiw` to yank a word and `]p` to put it on the next line. +nmap('[p', 'exe "iput! " . v:register', 'Paste Above') +nmap(']p', 'exe "iput " . v:register', 'Paste Below') + +-- Many general mappings are created by 'mini.basics'. See 'plugin/30_mini.lua' + +-- stylua: ignore start +-- The next part (until `-- stylua: ignore end`) is aligned manually for easier +-- reading. Consider preserving this or remove `-- stylua` lines to autoformat. + +-- Leader mappings ============================================================ + +-- Neovim has the concept of a Leader key (see `:h `). It is a configurable +-- key that is primarily used for "workflow" mappings (opposed to text editing). +-- Like "open file explorer", "create scratch buffer", "pick from buffers". +-- +-- In 'plugin/10_options.lua' is set to , i.e. press +-- whenever there is a suggestion to press . +-- +-- This config uses a "two key Leader mappings" approach: first key describes +-- semantic group, second key executes an action. Both keys are usually chosen +-- to create some kind of mnemonic. +-- Example: `f` groups "find" type of actions; `ff` - find files. +-- Use this section to add Leader mappings in a structural manner. +-- +-- Usually if there are global and local kinds of actions, lowercase second key +-- denotes global and uppercase - local. +-- Example: `fs` / `fS` - find workspace/document LSP symbols. +-- +-- Many of the mappings use 'mini.nvim' modules set up in 'plugin/30_mini.lua'. + +-- Create a global table with information about Leader groups in certain modes. +-- This is used to provide 'mini.clue' with extra clues. +-- Add an entry if you create a new group. +Config.leader_group_clues = { + { mode = 'n', keys = 'b', desc = '+Buffer' }, + { mode = 'n', keys = 'e', desc = '+Explore/Edit' }, + { mode = 'n', keys = 'f', desc = '+Find' }, + { mode = 'n', keys = 'g', desc = '+Git' }, + { mode = 'n', keys = 'l', desc = '+Language' }, + { mode = 'n', keys = 'm', desc = '+Map' }, + { mode = 'n', keys = 'o', desc = '+Other' }, + { mode = 'n', keys = 's', desc = '+Session' }, + { mode = 'n', keys = 't', desc = '+Terminal' }, + { mode = 'n', keys = 'v', desc = '+Visits' }, + + { mode = 'x', keys = 'g', desc = '+Git' }, + { mode = 'x', keys = 'l', desc = '+Language' }, +} + +-- Helpers for a more concise `` mappings. +-- Most of the mappings use `...` string as a right hand side (RHS) in +-- an attempt to be more concise yet descriptive. See `:h `. +-- This approach also doesn't require the underlying commands/functions to exist +-- during mapping creation: a "lazy loading" approach to improve startup time. +local nmap_leader = function(suffix, rhs, desc) + vim.keymap.set('n', '' .. suffix, rhs, { desc = desc }) +end +local xmap_leader = function(suffix, rhs, desc) + vim.keymap.set('x', '' .. suffix, rhs, { desc = desc }) +end + +-- b is for 'Buffer'. Common usage: +-- - `bs` - create scratch (temporary) buffer +-- - `ba` - navigate to the alternative buffer +-- - `bw` - wipeout (fully delete) current buffer +local new_scratch_buffer = function() + vim.api.nvim_win_set_buf(0, vim.api.nvim_create_buf(true, true)) +end + +nmap_leader('ba', 'b#', 'Alternate') +nmap_leader('bd', 'lua MiniBufremove.delete()', 'Delete') +nmap_leader('bD', 'lua MiniBufremove.delete(0, true)', 'Delete!') +nmap_leader('bs', new_scratch_buffer, 'Scratch') +nmap_leader('bw', 'lua MiniBufremove.wipeout()', 'Wipeout') +nmap_leader('bW', 'lua MiniBufremove.wipeout(0, true)', 'Wipeout!') + +-- e is for 'Explore' and 'Edit'. Common usage: +-- - `ed` - open explorer at current working directory +-- - `ef` - open directory of current file (needs to be present on disk) +-- - `ei` - edit 'init.lua' +-- - All mappings that use `edit_plugin_file` - edit 'plugin/' config files +local edit_plugin_file = function(filename) + return string.format('edit %s/plugin/%s', vim.fn.stdpath('config'), filename) +end +local explore_at_file = 'lua MiniFiles.open(vim.api.nvim_buf_get_name(0))' +local explore_quickfix = function() + vim.cmd(vim.fn.getqflist({ winid = true }).winid ~= 0 and 'cclose' or 'copen') +end +local explore_locations = function() + vim.cmd(vim.fn.getloclist(0, { winid = true }).winid ~= 0 and 'lclose' or 'lopen') +end + +nmap_leader('ed', 'lua MiniFiles.open()', 'Directory') +nmap_leader('ef', explore_at_file, 'File directory') +nmap_leader('ei', 'edit $MYVIMRC', 'init.lua') +nmap_leader('ek', edit_plugin_file('20_keymaps.lua'), 'Keymaps config') +nmap_leader('em', edit_plugin_file('30_mini.lua'), 'MINI config') +nmap_leader('en', 'lua MiniNotify.show_history()', 'Notifications') +nmap_leader('eo', edit_plugin_file('10_options.lua'), 'Options config') +nmap_leader('ep', edit_plugin_file('40_plugins.lua'), 'Plugins config') +nmap_leader('eq', explore_quickfix, 'Quickfix list') +nmap_leader('eQ', explore_locations, 'Location list') + +-- f is for 'Fuzzy Find'. Common usage: +-- - `ff` - find files; for best performance requires `ripgrep` +-- - `fg` - find inside files; requires `ripgrep` +-- - `fh` - find help tag +-- - `fr` - resume latest picker +-- - `fv` - all visited paths; requires 'mini.visits' +-- +-- All these use 'mini.pick'. See `:h MiniPick-overview` for an overview. +local pick_added_hunks_buf = 'Pick git_hunks path="%" scope="staged"' +local pick_workspace_symbols_live = 'Pick lsp scope="workspace_symbol_live"' + +nmap_leader('f/', 'Pick history scope="/"', '"/" history') +nmap_leader('f:', 'Pick history scope=":"', '":" history') +nmap_leader('fa', 'Pick git_hunks scope="staged"', 'Added hunks (all)') +nmap_leader('fA', pick_added_hunks_buf, 'Added hunks (buf)') +nmap_leader('fb', 'Pick buffers', 'Buffers') +nmap_leader('fc', 'Pick git_commits', 'Commits (all)') +nmap_leader('fC', 'Pick git_commits path="%"', 'Commits (buf)') +nmap_leader('fd', 'Pick diagnostic scope="all"', 'Diagnostic workspace') +nmap_leader('fD', 'Pick diagnostic scope="current"', 'Diagnostic buffer') +nmap_leader('ff', 'Pick files', 'Files') +nmap_leader('fg', 'Pick grep_live', 'Grep live') +nmap_leader('fG', 'Pick grep pattern=""', 'Grep current word') +nmap_leader('fh', 'Pick help', 'Help tags') +nmap_leader('fH', 'Pick hl_groups', 'Highlight groups') +nmap_leader('fl', 'Pick buf_lines scope="all"', 'Lines (all)') +nmap_leader('fL', 'Pick buf_lines scope="current"', 'Lines (buf)') +nmap_leader('fm', 'Pick git_hunks', 'Modified hunks (all)') +nmap_leader('fM', 'Pick git_hunks path="%"', 'Modified hunks (buf)') +nmap_leader('fr', 'Pick resume', 'Resume') +nmap_leader('fR', 'Pick lsp scope="references"', 'References (LSP)') +nmap_leader('fs', pick_workspace_symbols_live, 'Symbols workspace (live)') +nmap_leader('fS', 'Pick lsp scope="document_symbol"', 'Symbols document') +nmap_leader('fv', 'Pick visit_paths cwd=""', 'Visit paths (all)') +nmap_leader('fV', 'Pick visit_paths', 'Visit paths (cwd)') + +-- g is for 'Git'. Common usage: +-- - `gs` - show information at cursor +-- - `go` - toggle 'mini.diff' overlay to show in-buffer unstaged changes +-- - `gd` - show unstaged changes as a patch in separate tabpage +-- - `gL` - show Git log of current file +local git_log_cmd = [[Git log --pretty=format:\%h\ \%as\ │\ \%s --topo-order]] +local git_log_buf_cmd = git_log_cmd .. ' --follow -- %' + +nmap_leader('ga', 'Git diff --cached', 'Added diff') +nmap_leader('gA', 'Git diff --cached -- %', 'Added diff buffer') +nmap_leader('gc', 'Git commit', 'Commit') +nmap_leader('gC', 'Git commit --amend', 'Commit amend') +nmap_leader('gd', 'Git diff', 'Diff') +nmap_leader('gD', 'Git diff -- %', 'Diff buffer') +nmap_leader('gl', '' .. git_log_cmd .. '', 'Log') +nmap_leader('gL', '' .. git_log_buf_cmd .. '', 'Log buffer') +nmap_leader('go', 'lua MiniDiff.toggle_overlay()', 'Toggle overlay') +nmap_leader('gs', 'lua MiniGit.show_at_cursor()', 'Show at cursor') + +xmap_leader('gs', 'lua MiniGit.show_at_cursor()', 'Show at selection') + +-- l is for 'Language'. Common usage: +-- - `ld` - show more diagnostic details in a floating window +-- - `lr` - perform rename via LSP +-- - `ls` - navigate to source definition of symbol under cursor +-- +-- NOTE: most LSP mappings represent a more structured way of replacing built-in +-- LSP mappings (like `:h gra` and others). This is needed because `gr` is mapped +-- by an "replace" operator in 'mini.operators' (which is more commonly used). +nmap_leader('la', 'lua vim.lsp.buf.code_action()', 'Actions') +nmap_leader('ld', 'lua vim.diagnostic.open_float()', 'Diagnostic popup') +nmap_leader('lf', 'lua require("conform").format()', 'Format') +nmap_leader('li', 'lua vim.lsp.buf.implementation()', 'Implementation') +nmap_leader('lh', 'lua vim.lsp.buf.hover()', 'Hover') +nmap_leader('ll', 'lua vim.lsp.codelens.run()', 'Lens') +nmap_leader('lr', 'lua vim.lsp.buf.rename()', 'Rename') +nmap_leader('lR', 'lua vim.lsp.buf.references()', 'References') +nmap_leader('ls', 'lua vim.lsp.buf.definition()', 'Source definition') +nmap_leader('lt', 'lua vim.lsp.buf.type_definition()', 'Type definition') + +xmap_leader('lf', 'lua require("conform").format()', 'Format selection') + +-- m is for 'Map'. Common usage: +-- - `mt` - toggle map from 'mini.map' (closed by default) +-- - `mf` - focus on the map for fast navigation +-- - `ms` - change map's side (if it covers something underneath) +nmap_leader('mf', 'lua MiniMap.toggle_focus()', 'Focus (toggle)') +nmap_leader('mr', 'lua MiniMap.refresh()', 'Refresh') +nmap_leader('ms', 'lua MiniMap.toggle_side()', 'Side (toggle)') +nmap_leader('mt', 'lua MiniMap.toggle()', 'Toggle') + +-- o is for 'Other'. Common usage: +-- - `oz` - toggle between "zoomed" and regular view of current buffer +nmap_leader('or', 'lua MiniMisc.resize_window()', 'Resize to default width') +nmap_leader('ot', 'lua MiniTrailspace.trim()', 'Trim trailspace') +nmap_leader('oz', 'lua MiniMisc.zoom()', 'Zoom toggle') + +-- s is for 'Session'. Common usage: +-- - `sn` - start new session +-- - `sr` - read previously started session +-- - `sR` - restart Neovim preserving current session +local session_new = 'vim.ui.input({ prompt = "Session name: " }, MiniSessions.write)' + +nmap_leader('sd', 'lua MiniSessions.select("delete")', 'Delete') +nmap_leader('sn', 'lua ' .. session_new .. '', 'New') +nmap_leader('sr', 'lua MiniSessions.select("read")', 'Read') +nmap_leader('sR', 'lua MiniSessions.restart()', 'Restart') +nmap_leader('sw', 'lua MiniSessions.write()', 'Write current') + +-- t is for 'Terminal' +nmap_leader('tT', 'horizontal term', 'Terminal (horizontal)') +nmap_leader('tt', 'vertical term', 'Terminal (vertical)') + +-- v is for 'Visits'. Common usage: +-- - `vv` - add "core" label to current file. +-- - `vV` - remove "core" label to current file. +-- - `vc` - pick among all files with "core" label. +local make_pick_core = function(cwd, desc) + return function() + local sort_latest = MiniVisits.gen_sort.default({ recency_weight = 1 }) + local local_opts = { cwd = cwd, filter = 'core', sort = sort_latest } + MiniExtra.pickers.visit_paths(local_opts, { source = { name = desc } }) + end +end + +nmap_leader('vc', make_pick_core('', 'Core visits (all)'), 'Core visits (all)') +nmap_leader('vC', make_pick_core(nil, 'Core visits (cwd)'), 'Core visits (cwd)') +nmap_leader('vv', 'lua MiniVisits.add_label("core")', 'Add "core" label') +nmap_leader('vV', 'lua MiniVisits.remove_label("core")', 'Remove "core" label') +nmap_leader('vl', 'lua MiniVisits.add_label()', 'Add label') +nmap_leader('vL', 'lua MiniVisits.remove_label()', 'Remove label') +-- stylua: ignore end diff --git a/plugin/30_mini.lua b/plugin/30_mini.lua new file mode 100644 index 0000000..fd26c55 --- /dev/null +++ b/plugin/30_mini.lua @@ -0,0 +1,803 @@ +-- ┌────────────────────┐ +-- │ MINI configuration │ +-- └────────────────────┘ +-- +-- This file contains configuration of the MINI parts of the config. +-- It contains only configs for the 'mini.nvim' plugin (installed in 'init.lua'). +-- +-- 'mini.nvim' is a library of modules. Each is enabled independently via +-- `require('mini.xxx').setup()` convention. It creates all intended side effects: +-- mappings, autocommands, highlight groups, etc. It also creates a global +-- `MiniXxx` table that can be later used to access module's features. +-- +-- Every module's `setup()` function accepts an optional `config` table to +-- adjust its behavior. See the structure of this table at `:h MiniXxx.config`. +-- +-- See `:h mini.nvim-general-principles` for more general principles. +-- +-- Here each module's `setup()` has a brief explanation of what the module is for, +-- its usage examples (uses Leader mappings from 'plugin/20_keymaps.lua'), and +-- possible directions for more info. +-- For more info about a module see its help page (`:h mini.xxx` for 'mini.xxx'). + +-- To minimize the time until first screen draw, modules are enabled in two steps: +-- - Step one enables everything that is needed for first draw with `now()`. +-- Sometimes needed only if Neovim is started as `nvim -- path/to/file`. +-- - Everything else is delayed until the first draw with `later()`. +local now, now_if_args, later = Config.now, Config.now_if_args, Config.later + +-- Step one =================================================================== +-- Enable 'base16' color scheme. +now(function() + require("mini.base16").setup({ + palette = { + base00 = "#191724", + base01 = "#1e1b2a", + base02 = "#403d52", + base03 = "#6e6a86", + base04 = "#908caa", + base05 = "#e0def4", + base06 = "#e0def4", + base07 = "#524f67", + base08 = "#ebbcba", + base09 = "#f6c177", + base0A = "#f6c177", + base0B = "#31748f", + base0C = "#9ccfd8", + base0D = "#c4a7e7", + base0E = "#c4a7e7", + base0F = "#eb6f92", + }, + }) +end) + +-- Common configuration presets. Example usage: +-- - `` in Insert mode - save and go to Normal mode +-- - `go` / `gO` - insert empty line before/after in Normal mode +-- - `gy` / `gp` - copy / paste from system clipboard +-- - `\` + key - toggle common options. Like `\h` toggles highlighting search. +-- - `` (four combos) - navigate between windows. +-- - `` in Insert/Command mode - navigate in that mode. +-- +-- See also: +-- - `:h MiniBasics.config.options` - list of adjusted options +-- - `:h MiniBasics.config.mappings` - list of created mappings +-- - `:h MiniBasics.config.autocommands` - list of created autocommands +now(function() + require("mini.basics").setup({ + -- Manage options in 'plugin/10_options.lua' for didactic purposes + options = { basic = false }, + mappings = { + -- Create `` mappings for window navigation + windows = true, + -- Create `` mappings for navigation in Insert and Command modes + move_with_alt = true, + }, + }) +end) + +-- Icon provider. Usually no need to use manually. It is used by plugins like +-- 'mini.pick', 'mini.files', 'mini.statusline', and others. +now(function() + -- Set up to not prefer extension-based icon for some extensions + local ext3_blocklist = { scm = true, txt = true, yml = true } + local ext4_blocklist = { json = true, yaml = true } + require("mini.icons").setup({ + use_file_extension = function(ext, _) + return not (ext3_blocklist[ext:sub(-3)] or ext4_blocklist[ext:sub(-4)]) + end, + }) + + -- Mock 'nvim-tree/nvim-web-devicons' for plugins without 'mini.icons' support. + -- Not needed for 'mini.nvim' or MiniMax, but might be useful for others. + later(MiniIcons.mock_nvim_web_devicons) + + -- Add LSP kind icons. Useful for 'mini.completion'. + later(MiniIcons.tweak_lsp_kind) +end) + +-- Notifications provider. Shows all kinds of notifications in the upper right +-- corner (by default). Example usage: +-- - `:h vim.notify()` - show notification (hides automatically) +-- - `en` - show notification history +-- +-- See also: +-- - `:h MiniNotify.config` for some of common configuration examples. +now(function() + require("mini.notify").setup() +end) + +-- Session management. A thin wrapper around `:h mksession` that consistently +-- manages session files. Example usage: +-- - `sn` - start new session +-- - `sr` - read previously started session +-- - `sd` - delete previously started session +now(function() + require("mini.sessions").setup() +end) + +-- Start screen. This is what is shown when you open Neovim like `nvim`. +-- Example usage: +-- - Type prefix keys to limit available candidates +-- - Navigate down/up with `` and `` +-- - Press `` to select an entry +-- +-- See also: +-- - `:h MiniStarter-example-config` - non-default config examples +-- - `:h MiniStarter-lifecycle` - how to work with Starter buffer +now(function() + require("mini.starter").setup() +end) + +-- Statusline. Sets `:h 'statusline'` to show more info in a line below window. +-- Example usage: +-- - Left most section indicates current mode (text + highlighting). +-- - Second from left section shows "developer info": Git, diff, diagnostics, LSP. +-- - Center section shows the name of displayed buffer. +-- - Second to right section shows more buffer info. +-- - Right most section shows current cursor coordinates and search results. +-- +-- See also: +-- - `:h MiniStatusline-example-content` - example of default content. Use it to +-- configure a custom statusline by setting `config.content.active` function. +now(function() + require("mini.statusline").setup() +end) + +-- Tabline. Sets `:h 'tabline'` to show all listed buffers in a line at the top. +-- Buffers are ordered as they were created. Navigate with `[b` and `]b`. +now(function() + require("mini.tabline").setup() +end) + +-- Step one or two ============================================================ +-- Load now if Neovim is started like `nvim -- path/to/file`, otherwise - later. +-- This ensures a correct behavior for files opened during startup. + +-- Completion and signature help. Implements async "two stage" autocompletion: +-- - Based on attached LSP servers that support completion. +-- - Fallback (based on built-in keyword completion) if there is no LSP candidates. +-- +-- Example usage in Insert mode with attached LSP: +-- - Start typing text that should be recognized by LSP (like variable name). +-- - After 100ms a popup menu with candidates appears. +-- - Press `` / `` to navigate down/up the list. These are set up +-- in 'mini.keymap'. You can also use `` / ``. +-- - During navigation there is an info window to the right showing extra info +-- that the LSP server can provide about the candidate. It appears after the +-- candidate stays selected for 100ms. Use `` / `` to scroll it. +-- - Navigating to an entry also changes buffer text. If you are happy with it, +-- keep typing after it. To discard completion completely, press ``. +-- - After pressing special trigger(s), usually `(`, a window appears that shows +-- the signature of the current function/method. It gets updated as you type +-- showing the currently active parameter. +-- +-- Example usage in Insert mode without an attached LSP or in places not +-- supported by the LSP (like comments): +-- - Start typing a word that is present in current or opened buffers. +-- - After 100ms popup menu with candidates appears. +-- - Navigate with `` / `` or `` / ``. This also updates +-- buffer text. If happy with choice, keep typing. Stop with ``. +-- +-- It also works with snippet candidates provided by LSP server. Best experience +-- when paired with 'mini.snippets' (which is set up in this file). +now_if_args(function() + -- Customize post-processing of LSP responses for a better user experience. + -- Don't show 'Text' suggestions (usually noisy) and show snippets last. + local process_items_opts = { kind_priority = { Text = -1, Snippet = 99 } } + local process_items = function(items, base) + return MiniCompletion.default_process_items(items, base, process_items_opts) + end + require("mini.completion").setup({ + lsp_completion = { + -- Without this config autocompletion is set up through `:h 'completefunc'`. + -- Although not needed, setting up through `:h 'omnifunc'` is cleaner + -- (sets up only when needed) and makes it possible to use ``. + source_func = "omnifunc", + auto_setup = false, + process_items = process_items, + }, + }) + + -- Set 'omnifunc' for LSP completion only when needed. + local on_attach = function(ev) + vim.bo[ev.buf].omnifunc = "v:lua.MiniCompletion.completefunc_lsp" + end + Config.new_autocmd("LspAttach", nil, on_attach, "Set 'omnifunc'") + + -- Advertise to servers that Neovim now supports certain set of completion and + -- signature features through 'mini.completion'. + vim.lsp.config("*", { capabilities = MiniCompletion.get_lsp_capabilities() }) +end) + +-- Navigate and manipulate file system +-- +-- Navigation is done using column view (Miller columns) to display nested +-- directories, they are displayed in floating windows in top left corner. +-- +-- Manipulate files and directories by editing text as regular buffers. +-- +-- Example usage: +-- - `ed` - open current working directory +-- - `ef` - open directory of current file (needs to be present on disk) +-- +-- Basic navigation: +-- - `l` - go in entry at cursor: navigate into directory or open file +-- - `h` - go out of focused directory +-- - Navigate window as any regular buffer +-- - Press `g?` inside explorer to see more mappings +-- +-- Basic manipulation: +-- - After any following action, press `=` in Normal mode to synchronize, read +-- carefully about actions, press `y` or `` to confirm +-- - New entry: press `o` and type its name; end with `/` to create directory +-- - Rename: press `C` and type new name +-- - Delete: type `dd` +-- - Move/copy: type `dd`/`yy`, navigate to target directory, press `p` +-- +-- See also: +-- - `:h MiniFiles-navigation` - more details about how to navigate +-- - `:h MiniFiles-manipulation` - more details about how to manipulate +-- - `:h MiniFiles-examples` - examples of common setups +now_if_args(function() + -- Enable directory/file preview + require("mini.files").setup({ windows = { preview = true } }) + + -- Add common bookmarks for every explorer. Example usage inside explorer: + -- - `'c` to navigate into your config directory + -- - `g?` to see available bookmarks + local add_marks = function() + MiniFiles.set_bookmark("c", vim.fn.stdpath("config"), { desc = "Config" }) + local vimpack_plugins = vim.fn.stdpath("data") .. "/site/pack/core/opt" + MiniFiles.set_bookmark("p", vimpack_plugins, { desc = "Plugins" }) + MiniFiles.set_bookmark("w", vim.fn.getcwd, { desc = "Working directory" }) + end + Config.new_autocmd("User", "MiniFilesExplorerOpen", add_marks, "Add bookmarks") +end) + +-- Miscellaneous small but useful functions. Example usage: +-- - `oz` - toggle between "zoomed" and regular view of current buffer +-- - `or` - resize window to its "editable width" +-- - `:lua put_text(vim.lsp.get_clients())` - put output of a function below +-- cursor in current buffer. Useful for a detailed exploration. +-- - `:lua put(MiniMisc.stat_summary(MiniMisc.bench_time(f, 100)))` - run +-- function `f` 100 times and report statistical summary of execution times +now_if_args(function() + -- Makes `:h MiniMisc.put()` and `:h MiniMisc.put_text()` public + require("mini.misc").setup() + + -- Change current working directory based on the current file path. It + -- searches up the file tree until the first root marker ('.git' or 'Makefile') + -- and sets their parent directory as a current directory. + -- This is helpful when simultaneously dealing with files from several projects. + MiniMisc.setup_auto_root() + + -- Restore latest cursor position on file open + MiniMisc.setup_restore_cursor() + + -- Synchronize terminal emulator background with Neovim's background to remove + -- possibly different color padding around Neovim instance + MiniMisc.setup_termbg_sync() +end) + +-- Step two =================================================================== + +-- Extra 'mini.nvim' functionality. +-- +-- See also: +-- - `:h MiniExtra.pickers` - pickers. Most are mapped in `f` group. +-- Calling `setup()` makes 'mini.pick' respect 'mini.extra' pickers. +-- - `:h MiniExtra.gen_ai_spec` - 'mini.ai' textobject specifications +-- - `:h MiniExtra.gen_highlighter` - 'mini.hipatterns' highlighters +later(function() + require("mini.extra").setup() +end) + +-- Extend and create a/i textobjects, like `:h a(`, `:h a'`, and more). +-- Contains not only `a` and `i` type of textobjects, but also their "next" and +-- "last" variants that will explicitly search for textobjects after and before +-- cursor. Example usage: +-- - `ci)` - *c*hange *i*inside parenthesis (`)`) +-- - `di(` - *d*elete *i*inside padded parenthesis (`(`) +-- - `yaq` - *y*ank *a*round *q*uote (any of "", '', or ``) +-- - `vif` - *v*isually select *i*inside *f*unction call +-- - `cina` - *c*hange *i*nside *n*ext *a*rgument +-- - `valaala` - *v*isually select *a*round *l*ast (i.e. previous) *a*rgument +-- and then again reselect *a*round new *l*ast *a*rgument +-- +-- See also: +-- - `:h text-objects` - general info about what textobjects are +-- - `:h MiniAi-builtin-textobjects` - list of all supported textobjects +-- - `:h MiniAi-textobject-specification` - examples of custom textobjects +later(function() + local ai = require("mini.ai") + ai.setup({ + -- 'mini.ai' can be extended with custom textobjects + custom_textobjects = { + -- Make `aB` / `iB` act on around/inside whole *b*uffer + B = MiniExtra.gen_ai_spec.buffer(), + -- For more complicated textobjects that require structural awareness, + -- use tree-sitter. This example makes `aF`/`iF` mean around/inside function + -- definition (not call). See `:h MiniAi.gen_spec.treesitter()` for details. + F = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }), + }, + + -- 'mini.ai' by default mostly mimics built-in search behavior: first try + -- to find textobject covering cursor, then try to find to the right. + -- Although this works in most cases, some are confusing. It is more robust to + -- always try to search only covering textobject and explicitly ask to search + -- for next (`an`/`in`) or last (`al`/`il`). + -- Try this. If you don't like it - delete next line and this comment. + search_method = "cover", + }) +end) + +-- Align text interactively. Example usage: +-- - `gaip,` - `ga` (align operator) *i*nside *p*aragraph by comma +-- - `gAip` - start interactive alignment on the paragraph. Choose how to +-- split, justify, and merge string parts. Press `` to make it permanent, +-- press `` to go back to initial state. +-- +-- See also: +-- - `:h MiniAlign-example` - hands-on list of examples to practice aligning +-- - `:h MiniAlign.gen_step` - list of support step customizations +-- - `:h MiniAlign-algorithm` - how alignment is done on algorithmic level +later(function() + require("mini.align").setup() +end) + +-- Animate common Neovim actions. Like cursor movement, scroll, window resize, +-- window open, window close. Animations are done based on Neovim events and +-- don't require custom mappings. +-- +-- It is not enabled by default because its effects are a matter of taste. +-- Also scroll and resize have some unwanted side effects (see `:h mini.animate`). +-- Uncomment next line (use `gcc`) to enable. +-- later(function() require('mini.animate').setup() end) + +-- Go forward/backward with square brackets. Implements consistent sets of mappings +-- for selected targets (like buffers, diagnostic, quickfix list entries, etc.). +-- Example usage: +-- - `]b` - go to next buffer +-- - `[j` - go to previous jump inside current buffer +-- - `[Q` - go to first entry of quickfix list +-- - `]X` - go to last conflict marker in a buffer +-- +-- See also: +-- - `:h MiniBracketed` - overall mapping design and list of targets +later(function() + require("mini.bracketed").setup() +end) + +-- Remove buffers. Opened files occupy space in tabline and buffer picker. +-- When not needed, they can be removed. Example usage: +-- - `bw` - completely wipeout current buffer (see `:h :bwipeout`) +-- - `bW` - completely wipeout current buffer even if it has changes +-- - `bd` - delete current buffer (see `:h :bdelete`) +later(function() + require("mini.bufremove").setup() +end) + +-- Show next key clues in a bottom right window. Requires explicit opt-in for +-- keys that act as clue trigger. Example usage: +-- - Press `` and wait for 1 second. A window with information about +-- next available keys should appear. +-- - Press one of the listed keys. Window updates immediately to show information +-- about new next available keys. You can press `` to go back in key sequence. +-- - Press keys until they resolve into some mapping. +-- +-- Note: it is designed to work in buffers for normal files. It doesn't work in +-- special buffers (like for 'mini.starter' or 'mini.files') to not conflict +-- with its local mappings. +-- +-- See also: +-- - `:h MiniClue-examples` - examples of common setups +-- - `:h MiniClue.ensure_buf_triggers()` - use it to enable triggers in buffer +-- - `:h MiniClue.set_mapping_desc()` - change mapping description not from config +later(function() + local miniclue = require("mini.clue") + -- stylua: ignore + miniclue.setup({ + -- Define which clues to show. By default shows only clues for custom mappings + -- (uses `desc` field from the mapping; takes precedence over custom clue). + clues = { + -- This is defined in 'plugin/20_keymaps.lua' with Leader group descriptions + Config.leader_group_clues, + miniclue.gen_clues.builtin_completion(), + miniclue.gen_clues.g(), + miniclue.gen_clues.marks(), + miniclue.gen_clues.registers(), + miniclue.gen_clues.square_brackets(), + -- This creates a submode for window resize mappings. Try the following: + -- - Press `s` to make a window split. + -- - Press `+` to increase height. Clue window still shows clues as if + -- `` is pressed again. Keep pressing just `+` to increase height. + -- Try pressing `-` to decrease height. + -- - Stop submode either by `` or by any key that is not in submode. + miniclue.gen_clues.windows({ submode_resize = true }), + miniclue.gen_clues.z(), + }, + -- Explicitly opt-in for set of common keys to trigger clue window + triggers = { + { mode = { 'n', 'x' }, keys = '' }, -- Leader triggers + { mode = 'n', keys = '\\' }, -- mini.basics + { mode = { 'n', 'x' }, keys = '[' }, -- mini.bracketed + { mode = { 'n', 'x' }, keys = ']' }, + { mode = 'i', keys = '' }, -- Built-in completion + { mode = { 'n', 'x' }, keys = 'g' }, -- `g` key + { mode = { 'n', 'x' }, keys = "'" }, -- Marks + { mode = { 'n', 'x' }, keys = '`' }, + { mode = { 'n', 'x' }, keys = '"' }, -- Registers + { mode = { 'i', 'c' }, keys = '' }, + { mode = 'n', keys = '' }, -- Window commands + { mode = { 'n', 'x' }, keys = 's' }, -- `s` key (mini.surround, etc.) + { mode = { 'n', 'x' }, keys = 'z' }, -- `z` key + }, + }) +end) + +-- Command line tweaks. Improves command line editing with: +-- - Autocompletion. Basically an automated `:h cmdline-completion`. +-- - Autocorrection of words as-you-type. Like `:W`->`:w`, `:lau`->`:lua`, etc. +-- - Autopeek command range (like line number at the start) as-you-type. +later(function() + require("mini.cmdline").setup() +end) + +-- Comment lines. Provides functionality to work with commented lines. +-- Uses `:h 'commentstring'` option to infer comment structure. +-- Example usage: +-- - `gcip` - toggle comment (`gc`) *i*inside *p*aragraph +-- - `vapgc` - *v*isually select *a*round *p*aragraph and toggle comment (`gc`) +-- - `gcgc` - uncomment (`gc`, operator) comment block at cursor (`gc`, textobject) +-- +-- The built-in `:h commenting` is based on 'mini.comment'. Yet this module is +-- still enabled as it provides more customization opportunities. +later(function() + require("mini.comment").setup() +end) + +-- Autohighlight word under cursor with a customizable delay. +-- Word boundaries are defined based on `:h 'iskeyword'` option. +-- +-- later(function() +-- require("mini.cursorword").setup() +-- end) + +-- Work with diff hunks that represent the difference between the buffer text and +-- some reference text set by a source. Default source uses text from Git index. +-- Also provides summary info used in developer section of 'mini.statusline'. +-- Example usage: +-- - `ghip` - apply hunks (`gh`) within *i*nside *p*aragraph +-- - `gHG` - reset hunks (`gH`) from cursor until end of buffer (`G`) +-- - `ghgh` - apply (`gh`) hunk at cursor (`gh`) +-- - `gHgh` - reset (`gH`) hunk at cursor (`gh`) +-- - `go` - toggle overlay +-- +-- See also: +-- - `:h MiniDiff-overview` - overview of how module works +-- - `:h MiniDiff-diff-summary` - available summary information +-- - `:h MiniDiff.gen_source` - available built-in sources +later(function() + require("mini.diff").setup() +end) + +-- Git integration for more straightforward Git actions based on Neovim's state. +-- It is not meant as a fully featured Git client, only to provide helpers that +-- integrate better with Neovim. Example usage: +-- - `gs` - show information at cursor +-- - `gd` - show unstaged changes as a patch in separate tabpage +-- - `gL` - show Git log of current file +-- - `:Git help git` - show output of `git help git` inside Neovim +-- +-- See also: +-- - `:h MiniGit-examples` - examples of common setups +-- - `:h :Git` - more details about `:Git` user command +-- - `:h MiniGit.show_at_cursor()` - what information at cursor is shown +later(function() + require("mini.git").setup() +end) + +-- Highlight patterns in text. Like `TODO`/`NOTE` or color hex codes. +-- Example usage: +-- - `:Pick hipatterns` - pick among all highlighted patterns +-- +-- See also: +-- - `:h MiniHipatterns-examples` - examples of common setups +later(function() + local hipatterns = require("mini.hipatterns") + local hi_words = MiniExtra.gen_highlighter.words + hipatterns.setup({ + highlighters = { + -- Highlight a fixed set of common words. Will be highlighted in any place, + -- not like "only in comments". + fixme = hi_words({ "FIXME", "Fixme", "fixme" }, "MiniHipatternsFixme"), + hack = hi_words({ "HACK", "Hack", "hack" }, "MiniHipatternsHack"), + todo = hi_words({ "TODO", "Todo", "todo" }, "MiniHipatternsTodo"), + note = hi_words({ "NOTE", "Note", "note" }, "MiniHipatternsNote"), + + -- Highlight hex color string (#aabbcc) with that color as a background + hex_color = hipatterns.gen_highlighter.hex_color(), + }, + }) +end) + +-- Visualize and work with indent scope. It visualizes indent scope "at cursor" +-- with animated vertical line. Provides relevant motions and textobjects. +-- Example usage: +-- - `cii` - *c*hange *i*nside *i*ndent scope +-- - `Vaiai` - *V*isually select *a*round *i*ndent scope and then again +-- reselect *a*round new *i*indent scope +-- - `[i` / `]i` - navigate to scope's top / bottom +-- +-- See also: +-- - `:h MiniIndentscope.gen_animation` - available animation rules +later(function() + require("mini.indentscope").setup() +end) + +-- Jump to next/previous single character. It implements "smarter `fFtT` keys" +-- (see `:h f`) that work across multiple lines, start "jumping mode", and +-- highlight all target matches. Example usage: +-- - `fxff` - move *f*orward onto next character "x", then next, and next again +-- - `dt)` - *d*elete *t*ill next closing parenthesis (`)`) +later(function() + require("mini.jump").setup() +end) + +-- Jump within visible lines to pre-defined spots via iterative label filtering. +-- Spots are computed by a configurable spotter function. Example usage: +-- - Lock eyes on desired location to jump +-- - `` - start jumping; this shows character labels over target spots +-- - Type character that appears over desired location; number of target spots +-- should be reduced +-- - Keep typing labels until target spot is unique to perform the jump +-- +-- See also: +-- - `:h MiniJump2d.gen_spotter` - list of available spotters +later(function() + require("mini.jump2d").setup() +end) + +-- Special key mappings. Provides helpers to map: +-- - Multi-step actions. Apply action 1 if condition is met; else apply +-- action 2 if condition is met; etc. +-- - Combos. Sequence of keys where each acts immediately plus execute extra +-- action if all are typed fast enough. Useful for Insert mode mappings to not +-- introduce delay when typing mapping keys without intention to execute action. +-- +-- See also: +-- - `:h MiniKeymap-examples` - examples of common setups +-- - `:h MiniKeymap.map_multistep()` - map multi-step action +-- - `:h MiniKeymap.map_combo()` - map combo +later(function() + require("mini.keymap").setup() + -- Navigate 'mini.completion' menu with `` / `` + MiniKeymap.map_multistep("i", "", { "pmenu_next" }) + MiniKeymap.map_multistep("i", "", { "pmenu_prev" }) + -- On `` try to accept current completion item, fall back to accounting + -- for pairs from 'mini.pairs' + MiniKeymap.map_multistep("i", "", { "pmenu_accept", "minipairs_cr" }) + -- On `` just try to account for pairs from 'mini.pairs' + MiniKeymap.map_multistep("i", "", { "minipairs_bs" }) +end) + +-- Move any selection in any direction. Example usage in Normal mode: +-- - ``/`` - move current line down / up +-- - ``/`` - decrease / increase indent of current line +-- +-- Example usage in Visual mode: +-- - ``/``/``/`` - move selection left/down/up/right +later(function() + require("mini.move").setup() +end) + +-- Text edit operators. All operators have mappings for: +-- - Regular operator (waits for motion/textobject to use) +-- - Current line action (repeat second character of operator to activate) +-- - Act on visual selection (type operator in Visual mode) +-- +-- Example usage: +-- - `griw` - replace (`gr`) *i*inside *w*ord +-- - `gmm` - multiple/duplicate (`gm`) current line (extra `m`) +-- - `vipgs` - *v*isually select *i*nside *p*aragraph and sort it (`gs`) +-- - `gxiww.` - exchange (`gx`) *i*nside *w*ord with next word (`w` to navigate +-- to it and `.` to repeat exchange operator) +-- - `g==` - execute current line as Lua code and replace with its output. +-- For example, typing `g==` over line `vim.lsp.get_clients()` shows +-- information about all available LSP clients. +-- +-- See also: +-- - `:h MiniOperators-mappings` - overview of how mappings are created +-- - `:h MiniOperators-overview` - overview of present operators +later(function() + require("mini.operators").setup() + + -- Create mappings for swapping adjacent arguments. Notes: + -- - Relies on `a` argument textobject from 'mini.ai'. + -- - It is not 100% reliable, but mostly works. + -- - It overrides `:h (` and `:h )`. + -- Explanation: `gx`-`ia`-`gx`-`ila` <=> exchange current and last argument + -- Usage: when on `a` in `(aa, bb)` press `)` followed by `(`. + vim.keymap.set("n", "(", "gxiagxila", { remap = true, desc = "Swap arg left" }) + vim.keymap.set("n", ")", "gxiagxina", { remap = true, desc = "Swap arg right" }) +end) + +-- Autopairs functionality. Insert pair when typing opening character and go over +-- right character if it is already to cursor's right. Also provides mappings for +-- `` and `` to perform extra actions when inside pair. +-- Example usage in Insert mode: +-- - `(` - insert "()" and put cursor between them +-- - `)` when there is ")" to the right - jump over ")" without inserting new one +-- - `(` - always insert a single "(" literally. This is useful since +-- 'mini.pairs' doesn't provide particularly smart behavior, like auto balancing +later(function() + -- Create pairs not only in Insert, but also in Command line mode + require("mini.pairs").setup({ modes = { command = true } }) +end) + +-- Pick anything with single window layout and fast matching. This is one of +-- the main usability improvements as it powers a lot of "find things quickly" +-- workflows. How to use a picker: +-- - Start picker, usually with `:Pick ` command. Like `:Pick files`. +-- It shows a single window in the bottom left corner filled with possible items +-- to choose from. Current item has special full line highlighting. +-- At the top there is a current query used to filter+sort items. +-- - Type characters (appear at top) to narrow down items. There is fuzzy matching: +-- characters may not match one-by-one, but they should be in correct order. +-- - Navigate down/up with ``/``. +-- - Press `` to show item's preview. `` again goes back to items. +-- - Press `` to show picker's info. `` again goes back to items. +-- - Press `` to choose an item. The exact action depends on the picker: `files` +-- picker opens a selected file, `help` picker opens help page on selected tag. +-- To close picker without choosing an item, press ``. +-- +-- Example usage: +-- - `ff` - *f*ind *f*iles; for best performance requires `ripgrep` +-- - `fg` - *f*ind inside files (a.k.a. "to *g*rep"); requires `ripgrep` +-- - `fh` - *f*ind *h*elp tag +-- - `fr` - *r*esume latest picker +-- - `:h vim.ui.select()` - implemented with 'mini.pick' +-- +-- See also: +-- - `:h MiniPick-overview` - overview of picker functionality +-- - `:h MiniPick-examples` - examples of common setups +-- - `:h MiniPick.builtin` and `:h MiniExtra.pickers` - available pickers; +-- Execute one either with Lua function, `:Pick ` command, or +-- one of `f` mappings defined in 'plugin/20_keymaps.lua' +later(function() + require("mini.pick").setup() +end) + +-- Manage and expand snippets (templates for a frequently used text). +-- Typical workflow is to type snippet's (configurable) prefix and expand it +-- into a snippet session. +-- +-- How to manage snippets: +-- - 'mini.snippets' itself doesn't come with preconfigured snippets. Instead there +-- is a flexible system of how snippets are prepared before expanding. +-- They can come from pre-defined path on disk, 'snippets/' directories inside +-- config or plugins, defined inside `setup()` call directly. +-- - This config, however, does come with snippet configuration: +-- - 'snippets/global.json' is a file with global snippets that will be +-- available in any buffer +-- - 'after/snippets/lua.json' defines personal snippets for Lua language +-- - 'friendly-snippets' plugin configured in 'plugin/40_plugins.lua' provides +-- a collection of language snippets +-- +-- How to expand a snippet in Insert mode: +-- - If you know snippet's prefix, type it as a word and press ``. Snippet's +-- body should be inserted instead of the prefix. +-- - If you don't remember snippet's prefix, type only part of it (or none at all) +-- and press ``. It should show picker with all snippets that have prefixes +-- matching typed characters (or all snippets if none was typed). +-- Choose one and its body should be inserted instead of previously typed text. +-- +-- How to navigate during snippet session: +-- - Snippets can contain tabstops - places for user to interactively adjust text. +-- Each tabstop is highlighted depending on session progression - whether tabstop +-- is current, was or was not visited. If tabstop doesn't yet have text, it is +-- visualized with special "ghost" inline text: • and ∎ by default. +-- - Type necessary text at current tabstop and navigate to next/previous one +-- by pressing `` / ``. +-- - Repeat previous step until you reach special final tabstop, usually denoted +-- by ∎ symbol. If you spotted a mistake in an earlier tabstop, navigate to it +-- and return back to the final tabstop. +-- - To end a snippet session when at final tabstop, keep typing or go into +-- Normal mode. To force end snippet session, press ``. +-- +-- See also: +-- - `:h MiniSnippets-overview` - overview of how module works +-- - `:h MiniSnippets-examples` - examples of common setups +-- - `:h MiniSnippets-session` - details about snippet session +-- - `:h MiniSnippets.gen_loader` - list of available loaders +later(function() + -- Define language patterns to work better with 'friendly-snippets' + local latex_patterns = { "latex/**/*.json", "**/latex.json" } + local lang_patterns = { + tex = latex_patterns, + plaintex = latex_patterns, + -- Recognize special injected language of markdown tree-sitter parser + markdown_inline = { "markdown.json" }, + } + + local snippets = require("mini.snippets") + local config_path = vim.fn.stdpath("config") + snippets.setup({ + snippets = { + -- Always load 'snippets/global.json' from config directory + snippets.gen_loader.from_file(config_path .. "/snippets/global.json"), + -- Load from 'snippets/' directory of plugins, like 'friendly-snippets' + snippets.gen_loader.from_lang({ lang_patterns = lang_patterns }), + }, + }) + + -- By default snippets available at cursor are not shown as candidates in + -- 'mini.completion' menu. This requires a dedicated in-process LSP server + -- that will provide them. To have that, uncomment next line (use `gcc`). + -- MiniSnippets.start_lsp_server() +end) + +-- Split and join arguments (regions inside brackets between allowed separators). +-- It uses Lua patterns to find arguments, which means it works in comments and +-- strings but can be not as accurate as tree-sitter based solutions. +-- Each action can be configured with hooks (like add/remove trailing comma). +-- Example usage: +-- - `gS` - toggle between joined (all in one line) and split (each on a separate +-- line and indented) arguments. It is dot-repeatable (see `:h .`). +-- +-- See also: +-- - `:h MiniSplitjoin.gen_hook` - list of available hooks +later(function() + require("mini.splitjoin").setup() +end) + +-- Surround actions: add/delete/replace/find/highlight. Working with surroundings +-- is surprisingly common: surround word with quotes, replace `)` with `]`, etc. +-- This module comes with many built-in surroundings, each identified by a single +-- character. It searches only for surrounding that covers cursor and comes with +-- a special "next" / "last" versions of actions to search forward or backward +-- (just like 'mini.ai'). All text editing actions are dot-repeatable (see `:h .`). +-- +-- Example usage (this may feel intimidating at first, but after practice it +-- becomes second nature during text editing): +-- - `saiw)` - *s*urround *a*dd for *i*nside *w*ord parenthesis (`)`) +-- - `sdf` - *s*urround *d*elete *f*unction call (like `f(var)` -> `var`) +-- - `srb[` - *s*urround *r*eplace *b*racket (any of [], (), {}) with padded `[` +-- - `sf*` - *s*urround *f*ind right part of `*` pair (like bold in markdown) +-- - `shf` - *s*urround *h*ighlight current *f*unction call +-- - `srn{{` - *s*urround *r*eplace *n*ext curly bracket `{` with padded `{` +-- - `sdl'` - *s*urround *d*elete *l*ast quote pair (`'`) +-- - `vaWsa` - *v*isually select *a*round *W*ORD and *s*urround *a*dd +-- spaces (``) +-- +-- See also: +-- - `:h MiniSurround-builtin-surroundings` - list of all supported surroundings +-- - `:h MiniSurround-surrounding-specification` - examples of custom surroundings +-- - `:h MiniSurround-vim-surround-config` - alternative set of action mappings +later(function() + require("mini.surround").setup() +end) + +-- Highlight and remove trailspace. Temporarily stops highlighting in Insert mode +-- to reduce noise when typing. Example usage: +-- - `ot` - trim all trailing whitespace in a buffer +later(function() + require("mini.trailspace").setup() +end) + +-- Track and reuse file system visits. Every file/directory visit is persistently +-- tracked on disk to later reuse: show in special frecency order, etc. It also +-- supports adding labels to visited paths to quickly navigate between them. +-- Example usage: +-- - `fv` - find across all visits +-- - `vv` / `vV` - add/remove special "core" label to current file +-- - `vc` / `vC` - show files with "core" label; all or added within +-- current working directory +-- +-- See also: +-- - `:h MiniVisits-overview` - overview of how module works +-- - `:h MiniVisits-examples` - examples of common setups +later(function() + require("mini.visits").setup() +end) diff --git a/plugin/40_plugins.lua b/plugin/40_plugins.lua new file mode 100644 index 0000000..f14418a --- /dev/null +++ b/plugin/40_plugins.lua @@ -0,0 +1,141 @@ +local add = vim.pack.add +local now_if_args, later = Config.now_if_args, Config.later + +now_if_args(function() + -- Define hook to update tree-sitter parsers after plugin is updated + local ts_update = function() + vim.cmd("TSUpdate") + end + Config.on_packchanged("nvim-treesitter", { "update" }, ts_update, ":TSUpdate") + + add({ + "https://github.com/nvim-treesitter/nvim-treesitter", + "https://github.com/nvim-treesitter/nvim-treesitter-textobjects", + }) + + local languages = { + "lua", + "vimdoc", + "markdown", + "go", + "yaml", + "html", + } + local isnt_installed = function(lang) + return #vim.api.nvim_get_runtime_file("parser/" .. lang .. ".*", false) == 0 + end + local to_install = vim.tbl_filter(isnt_installed, languages) + if #to_install > 0 then + require("nvim-treesitter").install(to_install) + end + + -- Enable tree-sitter after opening a file for a target language + local filetypes = {} + for _, lang in ipairs(languages) do + for _, ft in ipairs(vim.treesitter.language.get_filetypes(lang)) do + table.insert(filetypes, ft) + end + end + local ts_start = function(ev) + vim.treesitter.start(ev.buf) + end + Config.new_autocmd("FileType", filetypes, ts_start, "Start tree-sitter") +end) + +-- Language servers =========================================================== + +-- Language Server Protocol (LSP) is a set of conventions that power creation of +-- language specific tools. It requires two parts: +-- - Server - program that performs language specific computations. +-- - Client - program that asks server for computations and shows results. +-- +-- Here Neovim itself is a client (see `:h vim.lsp`). Language servers need to +-- be installed separately based on your OS, CLI tools, and preferences. +-- See note about 'mason.nvim' at the bottom of the file. +-- +-- Neovim's team collects commonly used configurations for most language servers +-- inside 'neovim/nvim-lspconfig' plugin. +-- +-- Add it now if file (and not 'mini.starter') is shown after startup. +-- +-- Troubleshooting: +-- - Run `:checkhealth vim.lsp` to see potential issues. +now_if_args(function() + add({ "https://github.com/neovim/nvim-lspconfig" }) + + -- Use `:h vim.lsp.enable()` to automatically enable language server based on + -- the rules provided by 'nvim-lspconfig'. + vim.lsp.enable({ + "gopls", + "lua_ls", + "yamlls", + }) + + -- Use `:h vim.lsp.config()` or 'after/lsp/' directory to configure servers. + -- Uncomment and tweak the following `vim.lsp.enable()` call to enable servers. + -- vim.lsp.config({ + -- -- For example, if `lua-language-server` is installed, use `'lua_ls'` entry + -- }) +end) + +-- Formatting ================================================================= + +-- Programs dedicated to text formatting (a.k.a. formatters) are very useful. +-- Neovim has built-in tools for text formatting (see `:h gq` and `:h 'formatprg'`). +-- They can be used to configure external programs, but it might become tedious. +-- +-- The 'stevearc/conform.nvim' plugin is a good and maintained solution for easier +-- formatting setup. +later(function() + add({ "https://github.com/stevearc/conform.nvim" }) + + -- See also: + -- - `:h Conform` + -- - `:h conform-options` + -- - `:h conform-formatters` + require("conform").setup({ + default_format_opts = { + -- Allow formatting from LSP server if no dedicated formatter is available + lsp_format = "fallback", + }, + format_on_save = { + lsp_format = "fallback", + timeout_ms = 500, + }, + -- Map of filetype to formatters + -- Make sure that necessary CLI tool is available + -- formatters_by_ft = { lua = { 'stylua' } }, + formatters_by_ft = { + go = { "gofumpt", "goimports" }, + lua = { "stylua" }, + }, + }) +end) + +-- Snippets =================================================================== + +-- Although 'mini.snippets' provides functionality to manage snippet files, it +-- deliberately doesn't come with those. +-- +-- The 'rafamadriz/friendly-snippets' is currently the largest collection of +-- snippet files. They are organized in 'snippets/' directory (mostly) per language. +-- 'mini.snippets' is designed to work with it as seamlessly as possible. +-- See `:h MiniSnippets.gen_loader.from_lang()`. +-- later(function() +-- add({ "https://github.com/rafamadriz/friendly-snippets" }) +-- end) + +-- Honorable mentions ========================================================= + +-- 'mason-org/mason.nvim' (a.k.a. "Mason") is a great tool (package manager) for +-- installing external language servers, formatters, and linters. It provides +-- a unified interface for installing, updating, and deleting such programs. +-- +-- The caveat is that these programs will be set up to be mostly used inside Neovim. +-- If you need them to work elsewhere, consider using other package managers. +-- +-- You can use it like so: +now_if_args(function() + add({ "https://github.com/mason-org/mason.nvim" }) + require("mason").setup() +end) -- 2.54.0 From 60d4cf6d266a147113c7a93893b3952209e1f781 Mon Sep 17 00:00:00 2001 From: Job79 Date: Wed, 24 Jun 2026 19:45:01 +0200 Subject: [PATCH 2/9] refactor: init.lua --- init.lua | 137 +++++++-------------------------------------- plugin/30_mini.lua | 2 + 2 files changed, 21 insertions(+), 118 deletions(-) diff --git a/init.lua b/init.lua index d9f0b93..e231e35 100644 --- a/init.lua +++ b/init.lua @@ -1,123 +1,24 @@ --- ┌────────────────────┐ --- │ Welcome to MiniMax │ --- └────────────────────┘ --- --- This is a config designed to mostly use MINI. It provides out of the box --- a stable, polished, and feature rich Neovim experience. Its structure: --- --- ├ init.lua Initial (this) file executed during startup --- ├ plugin/ Files automatically sourced during startup --- ├── 10_options.lua Built-in Neovim behavior --- ├── 20_keymaps.lua Custom mappings --- ├── 30_mini.lua MINI configuration --- ├── 40_plugins.lua Plugins outside of MINI --- ├ snippets/ User defined snippets (has demo file) --- ├ after/ Files to override behavior added by plugins --- ├── ftplugin/ Files for filetype behavior (has demo file) --- ├── lsp/ Language server configurations (has demo file) --- ├── snippets/ Higher priority snippet files (has demo file) --- --- Config files are meant to be read, preferably inside a Neovim instance running --- this config and opened at its root. This will help you better understand your --- setup. Start with this file. Any order is possible, prefer the one listed above. --- Ways of navigating your config: --- - `` + `e` + (one of) `iokmp` - edit 'init.lua' or 'plugin/' files. --- - Inside config directory: `ff` (picker) or `ed` (explorer) --- - Navigate existing buffers with `[b`, `]b`, or `fb`. --- --- Config files are also meant to be customized. Initially it is a baseline of --- a working config based on MINI. Modify it to make it yours. Some approaches: --- - Modify already existing files in a way that keeps them consistent. --- - Add new files in a way that keeps config consistent. --- Usually inside 'plugin/' or 'after/'. --- --- Documentation comments like this can be found throughout the config. --- Common conventions: --- --- - See `:h key-notation` for key notation used. --- - `:h xxx` means "documentation of helptag xxx". Either type text directly --- followed by Enter or type `fh` to open a helptag fuzzy picker. --- - "Type `fh`" means "press , followed by f, followed by h". --- Unless said otherwise, it assumes that Normal mode is current. --- - "See 'path/to/file'" means see open file at described path and read it. --- - `:SomeCommand ...` or `:lua ...` means execute mentioned command. - --- ┌────────────────┐ --- │ Plugin manager │ --- └────────────────┘ --- --- This config uses `vim.pack` - built-in plugin manager. Its main entry --- point is a `vim.pack.add()` function, which acts like a "smarter `:packadd`": --- load plugin after making sure it is installed from source. The state of --- installed plugins is recorded in the lockfile named 'nvim-pack-lock.json'. --- Example usage: --- - `vim.pack.add({ ... })` - use inside config to add one or more plugins. --- - `:lua vim.pack.update()` - update all plugins; execute `:write` to confirm. --- - `:lua vim.pack.del({ ... })` - delete specific plugins. --- --- See also: --- - `:h vim.pack-examples` - how to use it --- - `:h vim.pack-lockfile` - lockfile info --- - `:h vim.pack-events` - available events and plugin hooks examples --- - `:h vim.pack.update()` - more details about confirmation step - --- Define config table to be able to pass data between scripts --- It is a global variable which can be use both as `_G.Config` and `Config` -_G.Config = {} - --- Define custom autocommand group and helper to create an autocommand. --- Autocommands are Neovim's way to define actions that are executed on events --- (like creating a buffer, setting an option, etc.). --- --- See also: --- - `:h autocommand` --- - `:h nvim_create_augroup()` --- - `:h nvim_create_autocmd()` -local gr = vim.api.nvim_create_augroup('custom-config', {}) -Config.new_autocmd = function(event, pattern, callback, desc) - local opts = { group = gr, pattern = pattern, callback = callback, desc = desc } - vim.api.nvim_create_autocmd(event, opts) +-- Modules ===================================================================== +vim.loader.enable() +vim.opt.runtimepath:remove("/usr/share/nvim/site") +vim.opt.runtimepath:remove("/usr/share/nvim/site/after") +for _, m in ipairs({ "netrw", "netrwPlugin", "gzip", "tarPlugin", "zipPlugin", "tutor_mode_plugin" }) do + vim.g["loaded_" .. m] = 1 -- Block unused built-in modules end --- Define custom `vim.pack.add()` hook helper. Plugin data is passed as --- argument to the callback. See `:h vim.pack-events`. --- Example usage: see 'plugin/40_plugins.lua'. --- If any plugin requires installation hooks, add them after this function --- and before the first `vim.pack.add()` call. -Config.on_packchanged = function(plugin_name, kinds, callback, desc) - local f = function(ev) - local name, kind = ev.data.spec.name, ev.data.kind - if not (name == plugin_name and vim.tbl_contains(kinds, kind)) then return end - if not ev.data.active then vim.cmd.packadd(plugin_name) end - callback(ev.data) +-- Config Global =============================================================== +vim.pack.add({ "https://github.com/nvim-mini/mini.nvim" }) +local misc = require("mini.misc") +local gr = vim.api.nvim_create_augroup("custom-config", {}) + +_G.Config = { + now = function(f) misc.safely("now", f) end, + later = function(f) misc.safely("later", f) end, + on_event = function(ev, f) misc.safely("event:" .. ev, f) end, + on_filetype = function(ft, f) misc.safely("filetype:" .. ft, f) end, + autocmd = function(event, pattern, callback, desc) + vim.api.nvim_create_autocmd(event, { group = gr, pattern = pattern, callback = callback, desc = desc }) end - Config.new_autocmd('PackChanged', '*', f, desc) -end +} --- 'mini.nvim' - all-in-one plugin powering most MiniMax features. --- See 'plugin/30_mini.lua' for how it is used. --- Load now to have 'mini.misc' available for custom loading helpers. -vim.pack.add({ 'https://github.com/nvim-mini/mini.nvim' }) - --- Loading helpers used to organize config into fail-safe parts. Example usage: --- - `now` - execute immediately. Use for what must be executed during startup. --- Like colorscheme, statusline, tabline, dashboard, etc. --- - `later` - execute a bit later. Use for things not needed during startup. --- - `now_if_args` - use only if needed during startup when Neovim is started --- like `nvim -- path/to/file`, but otherwise delaying is fine. --- - Others are better used only if the above is not enough for good performance. --- Use only if you are comfortable with adding complexity to your config: --- - `on_event` - execute once on a first matched event. Like "delay until --- first Insert mode enter": `on_event('InsertEnter', function() ... end)`. --- - `on_filetype` - execute once on a first matched filetype. Like "delay --- until first Lua file": `on_filetype('lua', function() ... end)`. --- --- See also: --- - `:h MiniMisc.safely()` --- - 'plugin/30_mini.lua' and 'plugin/40_plugins.lua' -local misc = require('mini.misc') -Config.now = function(f) misc.safely('now', f) end -Config.later = function(f) misc.safely('later', f) end Config.now_if_args = vim.fn.argc(-1) > 0 and Config.now or Config.later -Config.on_event = function(ev, f) misc.safely('event:' .. ev, f) end -Config.on_filetype = function(ft, f) misc.safely('filetype:' .. ft, f) end diff --git a/plugin/30_mini.lua b/plugin/30_mini.lua index fd26c55..107ea7e 100644 --- a/plugin/30_mini.lua +++ b/plugin/30_mini.lua @@ -478,6 +478,8 @@ end) -- - `:h MiniDiff-overview` - overview of how module works -- - `:h MiniDiff-diff-summary` - available summary information -- - `:h MiniDiff.gen_source` - available built-in sources +-- Show di +later(function() require('mini.diff').setup() end) later(function() require("mini.diff").setup() end) -- 2.54.0 From 8a784825196371fd628e6918eb31818a7c9d02dd Mon Sep 17 00:00:00 2001 From: Job79 Date: Wed, 24 Jun 2026 19:45:20 +0200 Subject: [PATCH 3/9] refactor: remove after --- after/ftplugin/markdown.lua | 42 ------------------------------------- after/lsp/lua_ls.lua | 35 ------------------------------- after/snippets/lua.json | 4 ---- 3 files changed, 81 deletions(-) delete mode 100644 after/ftplugin/markdown.lua delete mode 100644 after/lsp/lua_ls.lua delete mode 100644 after/snippets/lua.json diff --git a/after/ftplugin/markdown.lua b/after/ftplugin/markdown.lua deleted file mode 100644 index be6d298..0000000 --- a/after/ftplugin/markdown.lua +++ /dev/null @@ -1,42 +0,0 @@ --- ┌─────────────────────────┐ --- │ Filetype config example │ --- └─────────────────────────┘ --- --- This is an example of a configuration that will apply only to a particular --- filetype, which is the same as file's basename ('markdown' in this example; --- which is for '*.md' files). --- --- It can contain any code which will be usually executed when the file is opened --- (strictly speaking, on every 'filetype' option value change to target value). --- Usually it needs to define buffer/window local options and variables. --- So instead of `vim.o` to set options, use `vim.bo` for buffer-local options and --- `vim.cmd('setlocal ...')` for window-local options (currently more robust). --- --- This is also a good place to set buffer-local 'mini.nvim' variables. --- See `:h mini.nvim-buffer-local-config` and `:h mini.nvim-disabling-recipes`. - --- Enable spelling and wrap for window -vim.cmd('setlocal spell wrap') - --- Fold with tree-sitter -vim.cmd('setlocal foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr()') - --- Disable built-in `gO` mapping in favor of 'mini.basics' -vim.keymap.del('n', 'gO', { buffer = 0 }) - --- Set markdown-specific surrounding in 'mini.surround' -vim.b.minisurround_config = { - custom_surroundings = { - -- Markdown link. Common usage: - -- `saiwL` + [type/paste link] + - add link - -- `sdL` - delete link - -- `srLL` + [type/paste link] + - replace link - L = { - input = { '%[().-()%]%(.-%)' }, - output = function() - local link = require('mini.surround').user_input('Link: ') - return { left = '[', right = '](' .. link .. ')' } - end, - }, - }, -} diff --git a/after/lsp/lua_ls.lua b/after/lsp/lua_ls.lua deleted file mode 100644 index 08acbcd..0000000 --- a/after/lsp/lua_ls.lua +++ /dev/null @@ -1,35 +0,0 @@ --- ┌────────────────────┐ --- │ LSP config example │ --- └────────────────────┘ --- --- This file contains configuration of 'lua_ls' language server. --- Source: https://github.com/LuaLS/lua-language-server --- --- It is used by `:h vim.lsp.enable()` and `:h vim.lsp.config()`. --- See `:h vim.lsp.Config` and `:h vim.lsp.ClientConfig` for all available fields. --- --- This config is designed for Lua's activity around Neovim. It provides only --- basic config and can be further improved. -return { - on_attach = function(client, buf_id) - -- Reduce very long list of triggers for better 'mini.completion' experience - client.server_capabilities.completionProvider.triggerCharacters = - { '.', ':', '#', '(' } - - -- Use this function to define buffer-local mappings and behavior that depend - -- on attached client or only makes sense if there is language server attached. - end, - -- LuaLS Structure of these settings comes from LuaLS, not Neovim - settings = { - Lua = { - -- Define runtime properties. Use 'LuaJIT', as it is built into Neovim. - runtime = { version = 'LuaJIT', path = vim.split(package.path, ';') }, - workspace = { - -- Don't analyze code from submodules - ignoreSubmodules = true, - -- Add Neovim's methods for easier code writing - library = { vim.env.VIMRUNTIME }, - }, - }, - }, -} diff --git a/after/snippets/lua.json b/after/snippets/lua.json deleted file mode 100644 index 9bb78a6..0000000 --- a/after/snippets/lua.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "local": { "prefix": "l", "body": "local $1 = $0" }, - "Remove prefixes": { "prefix": ["lfu", "ll", "lpca"] } -} -- 2.54.0 From 46099012696cb6e4111173ba1a318f5cc9221c16 Mon Sep 17 00:00:00 2001 From: Job79 Date: Wed, 24 Jun 2026 19:45:37 +0200 Subject: [PATCH 4/9] refactor: update plugins --- nvim-pack-lock.json | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/nvim-pack-lock.json b/nvim-pack-lock.json index 1f49d7c..6b343ea 100644 --- a/nvim-pack-lock.json +++ b/nvim-pack-lock.json @@ -1,32 +1,36 @@ { "plugins": { + "arborist.nvim": { + "rev": "fdeef56c2840c6772b9f68c5774ed87e9340ec7d", + "src": "https://github.com/arborist-ts/arborist.nvim" + }, + "codecompanion.nvim": { + "rev": "635f001598d811c6ea256bc863b3d503c3a88d43", + "src": "https://github.com/olimorris/codecompanion.nvim" + }, "conform.nvim": { "rev": "619363c30309d29ffa631e67c8183f2a72caa373", "src": "https://github.com/stevearc/conform.nvim" }, - "friendly-snippets": { - "rev": "6cd7280adead7f586db6fccbd15d2cac7e2188b9", - "src": "https://github.com/rafamadriz/friendly-snippets" + "kanagawa.nvim": { + "rev": "bb85e4bfc8d89b0e62c8fa53ccdd13d12e2f77b3", + "src": "https://github.com/rebelot/kanagawa.nvim" }, "mason.nvim": { - "rev": "16ba83bfc8a25f52bb545134f5bee082b195c460", + "rev": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d", "src": "https://github.com/mason-org/mason.nvim" }, "mini.nvim": { - "rev": "232ceeb14f7f7e849056309b85cb2fed712db46f", + "rev": "c594be5b095204e99473825ec2dee872e7409a4d", "src": "https://github.com/nvim-mini/mini.nvim" }, "nvim-lspconfig": { - "rev": "9573948c38bfabeec353ae7dd7d3ffec4c506a6b", + "rev": "bfcc0171a43f22afa61d927ffe9fcb6cb85dc99e", "src": "https://github.com/neovim/nvim-lspconfig" }, - "nvim-treesitter": { - "rev": "4916d6592ede8c07973490d9322f187e07dfefac", - "src": "https://github.com/nvim-treesitter/nvim-treesitter" - }, - "nvim-treesitter-textobjects": { - "rev": "851e865342e5a4cb1ae23d31caf6e991e1c99f1e", - "src": "https://github.com/nvim-treesitter/nvim-treesitter-textobjects" + "plenary.nvim": { + "rev": "74b06c6c75e4eeb3108ec01852001636d85a932b", + "src": "https://github.com/nvim-lua/plenary.nvim" } } } -- 2.54.0 From e7e37c8dc8008d6efeb80bd29b8f6761d0842c84 Mon Sep 17 00:00:00 2001 From: Job79 Date: Wed, 24 Jun 2026 19:47:32 +0200 Subject: [PATCH 5/9] refactor: options --- plugin/10_options.lua | 166 ++++++++++++------------------------------ 1 file changed, 47 insertions(+), 119 deletions(-) diff --git a/plugin/10_options.lua b/plugin/10_options.lua index 0e734e4..78acb27 100644 --- a/plugin/10_options.lua +++ b/plugin/10_options.lua @@ -1,129 +1,57 @@ --- ┌──────────────────────────┐ --- │ Built-in Neovim behavior │ --- └──────────────────────────┘ --- --- This file defines Neovim's built-in behavior. The goal is to improve overall --- usability in a way that works best with MINI. --- --- Here `vim.o.xxx = value` sets default value of option `xxx` to `value`. --- See `:h 'xxx'` (replace `xxx` with actual option name). --- --- Option values can be customized on a per buffer or window basis. --- See 'after/ftplugin/' for common example. --- --- Notes: --- - Some options (like `:h 'exrc'`) need to be set before this file is sourced. --- Set them directly at the bottom of the 'init.lua' file. +-- General ===================================================================== +vim.g.mapleader = ' ' -- Use `` as key +vim.o.undofile = true -- Enable persistent undo --- stylua: ignore start --- The next part (until `-- stylua: ignore end`) is aligned manually for easier --- reading. Consider preserving this or remove `-- stylua` lines to autoformat. +-- UI ========================================================================== +vim.o.breakindent = true -- Indent wrapped lines to match line start +vim.o.breakindentopt = 'list:-1' -- Add padding for lists (if 'wrap' is set) +vim.o.cursorline = true -- Enable current line highlighting +vim.o.linebreak = true -- Wrap lines at 'breakat' (if 'wrap' is set) +vim.o.list = true -- Show helpful text indicators +vim.o.number = true -- Show line numbers +vim.o.pumheight = 10 -- Make popup menu smaller +vim.o.pummaxwidth = 100 -- Make popup menu not too wide +vim.o.shortmess = 'CFOSWaco' -- Disable some built-in completion messages +vim.o.signcolumn = 'yes' -- Always show signcolumn (less flicker) +vim.o.splitbelow = true -- Horizontal splits will be below +vim.o.splitkeep = 'screen' -- Reduce scroll during window split +vim.o.splitright = true -- Vertical splits will be to the right +vim.o.wrap = false -- Don't visually wrap lines (toggle with \w) +vim.o.cmdheight = 0 -- Hide the command line when not in use. --- General ==================================================================== -vim.g.mapleader = ' ' -- Use `` as key +-- Editing ===================================================================== +vim.o.expandtab = true -- Convert tabs to spaces +vim.o.formatoptions = 'rqnl1j' -- Improve comment editing +vim.o.ignorecase = true -- Ignore case during search +vim.o.infercase = true -- Infer case in built-in completion +vim.o.shiftwidth = 2 -- Use this number of spaces for indentation +vim.o.smartcase = true -- Respect case if search pattern has upper case +vim.o.spelloptions = 'camel' -- Treat camelCase word parts as separate words +vim.o.tabstop = 2 -- Show tab as this number of spaces +vim.o.virtualedit = 'block' -- Allow going past end of line in blockwise mode -vim.o.mouse = 'a' -- Enable mouse -vim.o.mousescroll = 'ver:25,hor:6' -- Customize mouse scroll -vim.o.switchbuf = 'usetab' -- Use already opened buffers when switching -vim.o.undofile = true -- Enable persistent undo - -vim.o.shada = "'100,<50,s10,:1000,/100,@100,h" -- Limit ShaDa file (for startup) - --- Enable all filetype plugins and syntax (if not enabled, for better startup) -vim.cmd('filetype plugin indent on') -if vim.fn.exists('syntax_on') ~= 1 then vim.cmd('syntax enable') end - --- UI ========================================================================= -vim.o.breakindent = true -- Indent wrapped lines to match line start -vim.o.breakindentopt = 'list:-1' -- Add padding for lists (if 'wrap' is set) -vim.o.colorcolumn = '+1' -- Draw column on the right of maximum width -vim.o.cursorline = true -- Enable current line highlighting -vim.o.linebreak = true -- Wrap lines at 'breakat' (if 'wrap' is set) -vim.o.list = true -- Show helpful text indicators -vim.o.number = true -- Show line numbers -vim.o.pumborder = 'single' -- Use border in popup menu -vim.o.pumheight = 10 -- Make popup menu smaller -vim.o.pummaxwidth = 100 -- Make popup menu not too wide -vim.o.ruler = false -- Don't show cursor coordinates -vim.o.shortmess = 'CFOSWaco' -- Disable some built-in completion messages -vim.o.showmode = false -- Don't show mode in command line -vim.o.signcolumn = 'yes' -- Always show signcolumn (less flicker) -vim.o.splitbelow = true -- Horizontal splits will be below -vim.o.splitkeep = 'screen' -- Reduce scroll during window split -vim.o.splitright = true -- Vertical splits will be to the right -vim.o.winborder = 'single' -- Use border in floating windows -vim.o.wrap = false -- Don't visually wrap lines (toggle with \w) - -vim.o.cursorlineopt = 'screenline,number' -- Show cursor line per screen line - --- Special UI symbols. More is set via 'mini.basics' later. -vim.o.fillchars = 'eob: ,fold:╌' -vim.o.listchars = 'extends:…,nbsp:␣,precedes:…,tab:> ' - --- Folds (see `:h fold-commands`, `:h zM`, `:h zR`, `:h zA`, `:h zj`) -vim.o.foldlevel = 10 -- Fold nothing by default; set to 0 or 1 to fold -vim.o.foldmethod = 'indent' -- Fold based on indent level -vim.o.foldnestmax = 10 -- Limit number of fold levels -vim.o.foldtext = '' -- Show text under fold with its highlighting - --- Editing ==================================================================== -vim.o.autoindent = true -- Use auto indent -vim.o.expandtab = true -- Convert tabs to spaces -vim.o.formatoptions = 'rqnl1j'-- Improve comment editing -vim.o.ignorecase = true -- Ignore case during search -vim.o.incsearch = true -- Show search matches while typing -vim.o.infercase = true -- Infer case in built-in completion -vim.o.shiftwidth = 2 -- Use this number of spaces for indentation -vim.o.smartcase = true -- Respect case if search pattern has upper case -vim.o.smartindent = true -- Make indenting smart -vim.o.spelloptions = 'camel' -- Treat camelCase word parts as separate words -vim.o.tabstop = 2 -- Show tab as this number of spaces -vim.o.virtualedit = 'block' -- Allow going past end of line in blockwise mode - -vim.o.iskeyword = '@,48-57,_,192-255,-' -- Treat dash as `word` textobject part - --- Pattern for a start of numbered list (used in `gw`). This reads as --- "Start of list item is: at least one special character (digit, -, +, *) --- possibly followed by punctuation (. or `)`) followed by at least one space". -vim.o.formatlistpat = [[^\s*[0-9\-\+\*]\+[\.\)]*\s\+]] +-- Pattern for a start of numbered list (used in `gw`). +vim.o.formatlistpat = [[^\s*[0-9\-\+\*]\+[\.\)]*\s\+]] -- Built-in completion vim.o.complete = '.,w,b,kspell' -- Use less sources vim.o.completeopt = 'menuone,noselect,fuzzy,nosort' -- Use custom behavior vim.o.completetimeout = 100 -- Limit sources delay --- Autocommands =============================================================== +-- Autocommands ================================================================ +Config.autocmd('TextYankPost', '*', function() vim.hl.hl_op() end, 'Highlight yanked text') +Config.autocmd('TermOpen', '*', function() vim.cmd('startinsert') end, 'Start insert mode when terminal opens') --- Don't auto-wrap comments and don't insert comment leader after hitting 'o'. --- Do on `FileType` to always override these changes from filetype plugins. -local f = function() vim.cmd('setlocal formatoptions-=c formatoptions-=o') end -Config.new_autocmd('FileType', nil, f, "Proper 'formatoptions'") - --- There are other autocommands created by 'mini.basics'. See 'plugin/30_mini.lua'. - --- Diagnostics ================================================================ - --- Neovim has built-in support for showing diagnostic messages. This configures --- a more conservative display while still being useful. --- See `:h vim.diagnostic` and `:h vim.diagnostic.config()`. -local diagnostic_opts = { - -- Show signs on top of any other sign, but only for warnings and errors - signs = { priority = 9999, severity = { min = 'WARN', max = 'ERROR' } }, - - -- Show all diagnostics as underline (for their messages type `ld`) - underline = { severity = { min = 'HINT', max = 'ERROR' } }, - - -- Show more details immediately for errors on the current line - virtual_lines = false, - virtual_text = { - current_line = true, - severity = { min = 'ERROR', max = 'ERROR' }, - }, - - -- Don't update diagnostics when typing - update_in_insert = false, -} - --- Use `later()` to avoid sourcing `vim.diagnostic` on startup -Config.later(function() vim.diagnostic.config(diagnostic_opts) end) --- stylua: ignore end +-- Diagnostics ================================================================= +Config.later(function() + vim.diagnostic.config({ + signs = { priority = 9999, severity = { min = 'WARN', max = 'ERROR' } }, + underline = { severity = { min = 'HINT', max = 'ERROR' } }, + virtual_lines = false, + virtual_text = { + current_line = true, + severity = { min = 'ERROR', max = 'ERROR' }, + }, + update_in_insert = false, + }) +end) -- 2.54.0 From 0b90092ff8c38f341ccb3c7dadef65069508f254 Mon Sep 17 00:00:00 2001 From: Job79 Date: Wed, 24 Jun 2026 20:34:11 +0200 Subject: [PATCH 6/9] refactor: temp --- lua/just.lua | 39 ++ lua/terminal.lua | 13 + plugin/20_keymaps.lua | 342 +++++------------ plugin/30_mini.lua | 837 ++++-------------------------------------- plugin/40_plugins.lua | 224 +++++------ 5 files changed, 321 insertions(+), 1134 deletions(-) create mode 100644 lua/just.lua create mode 100644 lua/terminal.lua diff --git a/lua/just.lua b/lua/just.lua new file mode 100644 index 0000000..e0f8f2e --- /dev/null +++ b/lua/just.lua @@ -0,0 +1,39 @@ +local function run_task(cmd) + local buf = vim.api.nvim_create_buf(true, true) + vim.api.nvim_buf_set_name(buf, "just://" .. cmd) + vim.notify("󰑮 Running: " .. cmd) + + vim.api.nvim_buf_call(buf, function() + vim.fn.jobstart(cmd, { + term = true, + on_exit = function(_, code) + if code == 0 then + vim.notify("󰄬 " .. cmd .. " success") + vim.schedule(function() + pcall(vim.api.nvim_buf_delete, buf, { force = true }) + end) + else + vim.notify("󰅚 " .. cmd .. " failed (" .. code .. ")", 4) + end + end, + }) + end) +end + +function pick_just_task() + local obj = vim.system({ "just", "--summary" }, { text = true }):wait() + if obj.code ~= 0 or not obj.stdout or obj.stdout == "" then + return vim.notify("No recipes or justfile found", 3) + end + + local recipes = vim.split(vim.trim(obj.stdout), "%s+") + require("mini.pick").start({ + source = { + items = recipes, + name = "󱁤 Just Tasks", + choose = function(choice) + run_task("just " .. choice) + end, + }, + }) +end diff --git a/lua/terminal.lua b/lua/terminal.lua new file mode 100644 index 0000000..036e593 --- /dev/null +++ b/lua/terminal.lua @@ -0,0 +1,13 @@ +local M = {} + +--- Opens a TUI application in a new scratch buffer and deletes the buffer on exit. +function M.open_terminal_app(cmd) + vim.cmd("enew") + vim.fn.termopen(cmd, { + on_exit = function() + vim.cmd("bdelete!") + end, + }) +end + +return M diff --git a/plugin/20_keymaps.lua b/plugin/20_keymaps.lua index 31fdb47..2615bf3 100644 --- a/plugin/20_keymaps.lua +++ b/plugin/20_keymaps.lua @@ -1,249 +1,109 @@ --- ┌─────────────────┐ --- │ Custom mappings │ --- └─────────────────┘ --- --- This file contains definitions of custom general and Leader mappings. - --- General mappings =========================================================== - --- Use this section to add custom general mappings. See `:h vim.keymap.set()`. - --- An example helper to create a Normal mode mapping -local nmap = function(lhs, rhs, desc) - -- See `:h vim.keymap.set()` - vim.keymap.set('n', lhs, rhs, { desc = desc }) -end - --- Paste linewise before/after current line --- Usage: `yiw` to yank a word and `]p` to put it on the next line. -nmap('[p', 'exe "iput! " . v:register', 'Paste Above') -nmap(']p', 'exe "iput " . v:register', 'Paste Below') - --- Many general mappings are created by 'mini.basics'. See 'plugin/30_mini.lua' - --- stylua: ignore start --- The next part (until `-- stylua: ignore end`) is aligned manually for easier --- reading. Consider preserving this or remove `-- stylua` lines to autoformat. - --- Leader mappings ============================================================ - --- Neovim has the concept of a Leader key (see `:h `). It is a configurable --- key that is primarily used for "workflow" mappings (opposed to text editing). --- Like "open file explorer", "create scratch buffer", "pick from buffers". --- --- In 'plugin/10_options.lua' is set to , i.e. press --- whenever there is a suggestion to press . --- --- This config uses a "two key Leader mappings" approach: first key describes --- semantic group, second key executes an action. Both keys are usually chosen --- to create some kind of mnemonic. --- Example: `f` groups "find" type of actions; `ff` - find files. --- Use this section to add Leader mappings in a structural manner. --- --- Usually if there are global and local kinds of actions, lowercase second key --- denotes global and uppercase - local. --- Example: `fs` / `fS` - find workspace/document LSP symbols. --- --- Many of the mappings use 'mini.nvim' modules set up in 'plugin/30_mini.lua'. - --- Create a global table with information about Leader groups in certain modes. --- This is used to provide 'mini.clue' with extra clues. --- Add an entry if you create a new group. +-- Clues ======================================================================= Config.leader_group_clues = { - { mode = 'n', keys = 'b', desc = '+Buffer' }, - { mode = 'n', keys = 'e', desc = '+Explore/Edit' }, - { mode = 'n', keys = 'f', desc = '+Find' }, - { mode = 'n', keys = 'g', desc = '+Git' }, - { mode = 'n', keys = 'l', desc = '+Language' }, - { mode = 'n', keys = 'm', desc = '+Map' }, - { mode = 'n', keys = 'o', desc = '+Other' }, - { mode = 'n', keys = 's', desc = '+Session' }, - { mode = 'n', keys = 't', desc = '+Terminal' }, - { mode = 'n', keys = 'v', desc = '+Visits' }, - - { mode = 'x', keys = 'g', desc = '+Git' }, - { mode = 'x', keys = 'l', desc = '+Language' }, + { mode = "n", keys = "a", desc = "+AI" }, + { mode = "n", keys = "b", desc = "+Buffer" }, + { mode = "n", keys = "d", desc = "+Debug" }, + { mode = "n", keys = "e", desc = "+Explore" }, + { mode = "n", keys = "f", desc = "+Find" }, + { mode = "n", keys = "g", desc = "+Git" }, + { mode = "n", keys = "h", desc = "+Http" }, + { mode = "n", keys = "l", desc = "+Language" }, + { mode = "n", keys = "r", desc = "+Run" }, + { mode = "n", keys = "s", desc = "+Session" }, + { mode = "n", keys = "t", desc = "+Terminal" }, + { mode = "x", keys = "g", desc = "+Git" }, + { mode = "x", keys = "l", desc = "+Language" }, } --- Helpers for a more concise `` mappings. --- Most of the mappings use `...` string as a right hand side (RHS) in --- an attempt to be more concise yet descriptive. See `:h `. --- This approach also doesn't require the underlying commands/functions to exist --- during mapping creation: a "lazy loading" approach to improve startup time. -local nmap_leader = function(suffix, rhs, desc) - vim.keymap.set('n', '' .. suffix, rhs, { desc = desc }) -end -local xmap_leader = function(suffix, rhs, desc) - vim.keymap.set('x', '' .. suffix, rhs, { desc = desc }) -end +-- Helpers ===================================================================== +local nmap = function(lhs, rhs, desc) vim.keymap.set("n", lhs, rhs, { desc = desc }) end +local nmap_leader = function(suffix, rhs, desc) vim.keymap.set("n", "" .. suffix, rhs, { desc = desc }) end +local xmap_leader = function(suffix, rhs, desc) vim.keymap.set("x", "" .. suffix, rhs, { desc = desc }) end --- b is for 'Buffer'. Common usage: --- - `bs` - create scratch (temporary) buffer --- - `ba` - navigate to the alternative buffer --- - `bw` - wipeout (fully delete) current buffer -local new_scratch_buffer = function() - vim.api.nvim_win_set_buf(0, vim.api.nvim_create_buf(true, true)) -end - -nmap_leader('ba', 'b#', 'Alternate') -nmap_leader('bd', 'lua MiniBufremove.delete()', 'Delete') -nmap_leader('bD', 'lua MiniBufremove.delete(0, true)', 'Delete!') -nmap_leader('bs', new_scratch_buffer, 'Scratch') -nmap_leader('bw', 'lua MiniBufremove.wipeout()', 'Wipeout') -nmap_leader('bW', 'lua MiniBufremove.wipeout(0, true)', 'Wipeout!') - --- e is for 'Explore' and 'Edit'. Common usage: --- - `ed` - open explorer at current working directory --- - `ef` - open directory of current file (needs to be present on disk) --- - `ei` - edit 'init.lua' --- - All mappings that use `edit_plugin_file` - edit 'plugin/' config files -local edit_plugin_file = function(filename) - return string.format('edit %s/plugin/%s', vim.fn.stdpath('config'), filename) -end -local explore_at_file = 'lua MiniFiles.open(vim.api.nvim_buf_get_name(0))' -local explore_quickfix = function() - vim.cmd(vim.fn.getqflist({ winid = true }).winid ~= 0 and 'cclose' or 'copen') -end -local explore_locations = function() - vim.cmd(vim.fn.getloclist(0, { winid = true }).winid ~= 0 and 'lclose' or 'lopen') -end - -nmap_leader('ed', 'lua MiniFiles.open()', 'Directory') -nmap_leader('ef', explore_at_file, 'File directory') -nmap_leader('ei', 'edit $MYVIMRC', 'init.lua') -nmap_leader('ek', edit_plugin_file('20_keymaps.lua'), 'Keymaps config') -nmap_leader('em', edit_plugin_file('30_mini.lua'), 'MINI config') -nmap_leader('en', 'lua MiniNotify.show_history()', 'Notifications') -nmap_leader('eo', edit_plugin_file('10_options.lua'), 'Options config') -nmap_leader('ep', edit_plugin_file('40_plugins.lua'), 'Plugins config') -nmap_leader('eq', explore_quickfix, 'Quickfix list') -nmap_leader('eQ', explore_locations, 'Location list') - --- f is for 'Fuzzy Find'. Common usage: --- - `ff` - find files; for best performance requires `ripgrep` --- - `fg` - find inside files; requires `ripgrep` --- - `fh` - find help tag --- - `fr` - resume latest picker --- - `fv` - all visited paths; requires 'mini.visits' --- --- All these use 'mini.pick'. See `:h MiniPick-overview` for an overview. -local pick_added_hunks_buf = 'Pick git_hunks path="%" scope="staged"' -local pick_workspace_symbols_live = 'Pick lsp scope="workspace_symbol_live"' - -nmap_leader('f/', 'Pick history scope="/"', '"/" history') -nmap_leader('f:', 'Pick history scope=":"', '":" history') -nmap_leader('fa', 'Pick git_hunks scope="staged"', 'Added hunks (all)') -nmap_leader('fA', pick_added_hunks_buf, 'Added hunks (buf)') -nmap_leader('fb', 'Pick buffers', 'Buffers') -nmap_leader('fc', 'Pick git_commits', 'Commits (all)') -nmap_leader('fC', 'Pick git_commits path="%"', 'Commits (buf)') -nmap_leader('fd', 'Pick diagnostic scope="all"', 'Diagnostic workspace') -nmap_leader('fD', 'Pick diagnostic scope="current"', 'Diagnostic buffer') -nmap_leader('ff', 'Pick files', 'Files') -nmap_leader('fg', 'Pick grep_live', 'Grep live') -nmap_leader('fG', 'Pick grep pattern=""', 'Grep current word') -nmap_leader('fh', 'Pick help', 'Help tags') -nmap_leader('fH', 'Pick hl_groups', 'Highlight groups') -nmap_leader('fl', 'Pick buf_lines scope="all"', 'Lines (all)') -nmap_leader('fL', 'Pick buf_lines scope="current"', 'Lines (buf)') -nmap_leader('fm', 'Pick git_hunks', 'Modified hunks (all)') -nmap_leader('fM', 'Pick git_hunks path="%"', 'Modified hunks (buf)') -nmap_leader('fr', 'Pick resume', 'Resume') -nmap_leader('fR', 'Pick lsp scope="references"', 'References (LSP)') -nmap_leader('fs', pick_workspace_symbols_live, 'Symbols workspace (live)') -nmap_leader('fS', 'Pick lsp scope="document_symbol"', 'Symbols document') -nmap_leader('fv', 'Pick visit_paths cwd=""', 'Visit paths (all)') -nmap_leader('fV', 'Pick visit_paths', 'Visit paths (cwd)') - --- g is for 'Git'. Common usage: --- - `gs` - show information at cursor --- - `go` - toggle 'mini.diff' overlay to show in-buffer unstaged changes --- - `gd` - show unstaged changes as a patch in separate tabpage --- - `gL` - show Git log of current file -local git_log_cmd = [[Git log --pretty=format:\%h\ \%as\ │\ \%s --topo-order]] -local git_log_buf_cmd = git_log_cmd .. ' --follow -- %' - -nmap_leader('ga', 'Git diff --cached', 'Added diff') -nmap_leader('gA', 'Git diff --cached -- %', 'Added diff buffer') -nmap_leader('gc', 'Git commit', 'Commit') -nmap_leader('gC', 'Git commit --amend', 'Commit amend') -nmap_leader('gd', 'Git diff', 'Diff') -nmap_leader('gD', 'Git diff -- %', 'Diff buffer') -nmap_leader('gl', '' .. git_log_cmd .. '', 'Log') -nmap_leader('gL', '' .. git_log_buf_cmd .. '', 'Log buffer') -nmap_leader('go', 'lua MiniDiff.toggle_overlay()', 'Toggle overlay') -nmap_leader('gs', 'lua MiniGit.show_at_cursor()', 'Show at cursor') - -xmap_leader('gs', 'lua MiniGit.show_at_cursor()', 'Show at selection') - --- l is for 'Language'. Common usage: --- - `ld` - show more diagnostic details in a floating window --- - `lr` - perform rename via LSP --- - `ls` - navigate to source definition of symbol under cursor --- --- NOTE: most LSP mappings represent a more structured way of replacing built-in --- LSP mappings (like `:h gra` and others). This is needed because `gr` is mapped --- by an "replace" operator in 'mini.operators' (which is more commonly used). -nmap_leader('la', 'lua vim.lsp.buf.code_action()', 'Actions') -nmap_leader('ld', 'lua vim.diagnostic.open_float()', 'Diagnostic popup') -nmap_leader('lf', 'lua require("conform").format()', 'Format') -nmap_leader('li', 'lua vim.lsp.buf.implementation()', 'Implementation') -nmap_leader('lh', 'lua vim.lsp.buf.hover()', 'Hover') -nmap_leader('ll', 'lua vim.lsp.codelens.run()', 'Lens') -nmap_leader('lr', 'lua vim.lsp.buf.rename()', 'Rename') -nmap_leader('lR', 'lua vim.lsp.buf.references()', 'References') -nmap_leader('ls', 'lua vim.lsp.buf.definition()', 'Source definition') -nmap_leader('lt', 'lua vim.lsp.buf.type_definition()', 'Type definition') - -xmap_leader('lf', 'lua require("conform").format()', 'Format selection') - --- m is for 'Map'. Common usage: --- - `mt` - toggle map from 'mini.map' (closed by default) --- - `mf` - focus on the map for fast navigation --- - `ms` - change map's side (if it covers something underneath) -nmap_leader('mf', 'lua MiniMap.toggle_focus()', 'Focus (toggle)') -nmap_leader('mr', 'lua MiniMap.refresh()', 'Refresh') -nmap_leader('ms', 'lua MiniMap.toggle_side()', 'Side (toggle)') -nmap_leader('mt', 'lua MiniMap.toggle()', 'Toggle') - --- o is for 'Other'. Common usage: --- - `oz` - toggle between "zoomed" and regular view of current buffer -nmap_leader('or', 'lua MiniMisc.resize_window()', 'Resize to default width') -nmap_leader('ot', 'lua MiniTrailspace.trim()', 'Trim trailspace') -nmap_leader('oz', 'lua MiniMisc.zoom()', 'Zoom toggle') - --- s is for 'Session'. Common usage: --- - `sn` - start new session --- - `sr` - read previously started session --- - `sR` - restart Neovim preserving current session -local session_new = 'vim.ui.input({ prompt = "Session name: " }, MiniSessions.write)' - -nmap_leader('sd', 'lua MiniSessions.select("delete")', 'Delete') -nmap_leader('sn', 'lua ' .. session_new .. '', 'New') -nmap_leader('sr', 'lua MiniSessions.select("read")', 'Read') -nmap_leader('sR', 'lua MiniSessions.restart()', 'Restart') -nmap_leader('sw', 'lua MiniSessions.write()', 'Write current') - --- t is for 'Terminal' -nmap_leader('tT', 'horizontal term', 'Terminal (horizontal)') -nmap_leader('tt', 'vertical term', 'Terminal (vertical)') - --- v is for 'Visits'. Common usage: --- - `vv` - add "core" label to current file. --- - `vV` - remove "core" label to current file. --- - `vc` - pick among all files with "core" label. -local make_pick_core = function(cwd, desc) +local function lazy_setup(name, action) return function() - local sort_latest = MiniVisits.gen_sort.default({ recency_weight = 1 }) - local local_opts = { cwd = cwd, filter = 'core', sort = sort_latest } - MiniExtra.pickers.visit_paths(local_opts, { source = { name = desc } }) + if Config and type(Config["setup_" .. name]) == "function" then + Config["setup_" .. name]() + end + action() end end -nmap_leader('vc', make_pick_core('', 'Core visits (all)'), 'Core visits (all)') -nmap_leader('vC', make_pick_core(nil, 'Core visits (cwd)'), 'Core visits (cwd)') -nmap_leader('vv', 'lua MiniVisits.add_label("core")', 'Add "core" label') -nmap_leader('vV', 'lua MiniVisits.remove_label("core")', 'Remove "core" label') -nmap_leader('vl', 'lua MiniVisits.add_label()', 'Add label') -nmap_leader('vL', 'lua MiniVisits.remove_label()', 'Remove label') --- stylua: ignore end +-- AI ===================================================================== +nmap_leader("aa", lazy_setup("codecompanion", function() require("codecompanion").toggle_chat() end), + "Open CodeCompanion") + +-- Buffers ===================================================================== +nmap_leader("bd", function() vim.cmd("bd") end, "Delete") +nmap_leader("bD", function() vim.cmd("bd!") end, "Delete!") +nmap_leader("bw", function() vim.cmd("bw") end, "Wipeout") +nmap_leader("bW", function() vim.cmd("bw!") end, "Wipeout!") +nmap_leader("bo", function() vim.cmd("%bd|e#") end, "Close all but current") + +-- Debug ===================================================================== +nmap_leader("db", lazy_setup("dap", function() require("dap").toggle_breakpoint() end), "Toggle Breakpoint") +nmap_leader("dc", lazy_setup("dap", function() require("dap").continue() end), "Run/Continue") +nmap_leader("dC", lazy_setup("dap", function() require("dap").run_to_cursor() end), "Run to Cursor") +nmap_leader("de", lazy_setup("dap", function() require("dap.ui.widgets").hover() end), "Inspect") +nmap_leader("dt", lazy_setup("dap", function() require("dap").terminate() end), "Terminate") + +-- Explore ===================================================================== +nmap_leader("ed", function() MiniFiles.open() end, "Directory") +nmap_leader("ef", function() MiniFiles.open(vim.api.nvim_buf_get_name(0)) end, "File directory") +nmap_leader("en", function() MiniNotify.show_history() end, "Notifications") + +-- Find ===================================================================== +nmap_leader("f/", function() MiniPick.builtin.history({ scope = "/" }) end, '"/" history') +nmap_leader("f:", function() MiniPick.builtin.history({ scope = ":" }) end, '":" history') +nmap_leader("fb", function() MiniPick.builtin.buffers() end, "Buffers") +nmap_leader("fc", function() MiniPick.builtin.git_commits() end, "Commits (all)") +nmap_leader("fC", function() MiniPick.builtin.git_commits({ path = "%" }) end, "Commits (buf)") +nmap_leader("fd", function() MiniPick.builtin.diagnostic({ scope = "all" }) end, "Diagnostic workspace") +nmap_leader("fD", function() MiniPick.builtin.diagnostic({ scope = "current" }) end, "Diagnostic buffer") +nmap_leader("ff", function() MiniPick.builtin.files() end, "Files") +nmap_leader("fg", function() MiniPick.builtin.grep_live() end, "Grep live") +nmap_leader("fG", function() MiniPick.builtin.grep({ pattern = vim.fn.expand("") }) end, "Grep current word") +nmap_leader("fh", function() MiniPick.builtin.help() end, "Help tags") +nmap_leader("fl", function() MiniPick.builtin.buf_lines({ scope = "all" }) end, "Lines (all)") +nmap_leader("fL", function() MiniPick.builtin.buf_lines({ scope = "current" }) end, "Lines (buf)") +nmap_leader("fr", function() MiniPick.builtin.resume() end, "Resume") +nmap_leader("fs", function() MiniPick.builtin.lsp({ scope = "workspace_symbol_live" }) end, "Symbols workspace (live)") +nmap_leader("fS", function() MiniPick.builtin.lsp({ scope = "document_symbol" }) end, "Symbols document") + +-- Git ===================================================================== +nmap_leader("go", function() MiniDiff.toggle_overlay() end, "Toggle overlay") + +-- HTTP ===================================================================== +nmap_leader("hr", lazy_setup("kulala", function() require("kulala").run() end), "Send HTTP request") + +-- Language ===================================================================== +nmap_leader("la", vim.lsp.buf.code_action, "Actions") +nmap_leader("ld", vim.diagnostic.open_float, "Diagnostic popup") +nmap_leader("lf", function() require("conform").format() end, "Format") +nmap_leader("li", vim.lsp.buf.implementation, "Implementation") +nmap_leader("lh", vim.lsp.buf.hover, "Hover") +nmap_leader("ll", vim.lsp.codelens.run, "Lens") +nmap_leader("lr", vim.lsp.buf.rename, "Rename") +nmap_leader("lR", vim.lsp.buf.references, "References") +nmap_leader("ls", vim.lsp.buf.definition, "Source definition") +nmap_leader("lt", vim.lsp.buf.type_definition, "Type definition") +xmap_leader("lf", function() require("conform").format() end, "Format selection") + +-- Run ===================================================================== +nmap_leader("r", function() require("just").pick_just_task() end, "Run Just Task") + +-- Session ===================================================================== +nmap_leader("sd", function() MiniSessions.select("delete") end, "Delete") +nmap_leader("sn", function() vim.ui.input({ prompt = "Session name: " }, MiniSessions.write) end, "New") +nmap_leader("sr", function() MiniSessions.select("read") end, "Read") +nmap_leader("sR", function() MiniSessions.restart() end, "Restart") +nmap_leader("sw", function() MiniSessions.write() end, "Write current") + +-- Terminal ===================================================================== +nmap_leader("tT", function() vim.cmd("horizontal term") end, "Terminal (horizontal)") +nmap_leader("tt", function() vim.cmd("vertical term") end, "Terminal (vertical)") +nmap_leader("tg", function() require("terminal").open_terminal_app("lazygit") end, "LazyGit") +nmap_leader("ts", function() require("terminal").open_terminal_app("lazysql") end, "LazySQL") + +-- Overwrites ===================================================================== +nmap("", function() vim.cmd("nohlsearch") end, "Clear search highlights") diff --git a/plugin/30_mini.lua b/plugin/30_mini.lua index 107ea7e..2114724 100644 --- a/plugin/30_mini.lua +++ b/plugin/30_mini.lua @@ -1,805 +1,122 @@ --- ┌────────────────────┐ --- │ MINI configuration │ --- └────────────────────┘ --- --- This file contains configuration of the MINI parts of the config. --- It contains only configs for the 'mini.nvim' plugin (installed in 'init.lua'). --- --- 'mini.nvim' is a library of modules. Each is enabled independently via --- `require('mini.xxx').setup()` convention. It creates all intended side effects: --- mappings, autocommands, highlight groups, etc. It also creates a global --- `MiniXxx` table that can be later used to access module's features. --- --- Every module's `setup()` function accepts an optional `config` table to --- adjust its behavior. See the structure of this table at `:h MiniXxx.config`. --- --- See `:h mini.nvim-general-principles` for more general principles. --- --- Here each module's `setup()` has a brief explanation of what the module is for, --- its usage examples (uses Leader mappings from 'plugin/20_keymaps.lua'), and --- possible directions for more info. --- For more info about a module see its help page (`:h mini.xxx` for 'mini.xxx'). +-- UI ========================================================================== +Config.now(function() + -- Global icon provider. + require('mini.icons').setup() + Config.later(MiniIcons.tweak_lsp_kind) --- To minimize the time until first screen draw, modules are enabled in two steps: --- - Step one enables everything that is needed for first draw with `now()`. --- Sometimes needed only if Neovim is started as `nvim -- path/to/file`. --- - Everything else is delayed until the first draw with `later()`. -local now, now_if_args, later = Config.now, Config.now_if_args, Config.later + -- Notifications. + require('mini.notify').setup() --- Step one =================================================================== --- Enable 'base16' color scheme. -now(function() - require("mini.base16").setup({ - palette = { - base00 = "#191724", - base01 = "#1e1b2a", - base02 = "#403d52", - base03 = "#6e6a86", - base04 = "#908caa", - base05 = "#e0def4", - base06 = "#e0def4", - base07 = "#524f67", - base08 = "#ebbcba", - base09 = "#f6c177", - base0A = "#f6c177", - base0B = "#31748f", - base0C = "#9ccfd8", - base0D = "#c4a7e7", - base0E = "#c4a7e7", - base0F = "#eb6f92", - }, - }) + -- Start screen. + require('mini.starter').setup() + + -- Statusline. + require('mini.statusline').setup() end) --- Common configuration presets. Example usage: --- - `` in Insert mode - save and go to Normal mode --- - `go` / `gO` - insert empty line before/after in Normal mode --- - `gy` / `gp` - copy / paste from system clipboard --- - `\` + key - toggle common options. Like `\h` toggles highlighting search. --- - `` (four combos) - navigate between windows. --- - `` in Insert/Command mode - navigate in that mode. --- --- See also: --- - `:h MiniBasics.config.options` - list of adjusted options --- - `:h MiniBasics.config.mappings` - list of created mappings --- - `:h MiniBasics.config.autocommands` - list of created autocommands -now(function() - require("mini.basics").setup({ - -- Manage options in 'plugin/10_options.lua' for didactic purposes - options = { basic = false }, - mappings = { - -- Create `` mappings for window navigation - windows = true, - -- Create `` mappings for navigation in Insert and Command modes - move_with_alt = true, - }, - }) -end) +Config.later(function() + -- Git diff indicators. + require('mini.diff').setup() --- Icon provider. Usually no need to use manually. It is used by plugins like --- 'mini.pick', 'mini.files', 'mini.statusline', and others. -now(function() - -- Set up to not prefer extension-based icon for some extensions - local ext3_blocklist = { scm = true, txt = true, yml = true } - local ext4_blocklist = { json = true, yaml = true } - require("mini.icons").setup({ - use_file_extension = function(ext, _) - return not (ext3_blocklist[ext:sub(-3)] or ext4_blocklist[ext:sub(-4)]) - end, - }) - - -- Mock 'nvim-tree/nvim-web-devicons' for plugins without 'mini.icons' support. - -- Not needed for 'mini.nvim' or MiniMax, but might be useful for others. - later(MiniIcons.mock_nvim_web_devicons) - - -- Add LSP kind icons. Useful for 'mini.completion'. - later(MiniIcons.tweak_lsp_kind) -end) - --- Notifications provider. Shows all kinds of notifications in the upper right --- corner (by default). Example usage: --- - `:h vim.notify()` - show notification (hides automatically) --- - `en` - show notification history --- --- See also: --- - `:h MiniNotify.config` for some of common configuration examples. -now(function() - require("mini.notify").setup() -end) - --- Session management. A thin wrapper around `:h mksession` that consistently --- manages session files. Example usage: --- - `sn` - start new session --- - `sr` - read previously started session --- - `sd` - delete previously started session -now(function() - require("mini.sessions").setup() -end) - --- Start screen. This is what is shown when you open Neovim like `nvim`. --- Example usage: --- - Type prefix keys to limit available candidates --- - Navigate down/up with `` and `` --- - Press `` to select an entry --- --- See also: --- - `:h MiniStarter-example-config` - non-default config examples --- - `:h MiniStarter-lifecycle` - how to work with Starter buffer -now(function() - require("mini.starter").setup() -end) - --- Statusline. Sets `:h 'statusline'` to show more info in a line below window. --- Example usage: --- - Left most section indicates current mode (text + highlighting). --- - Second from left section shows "developer info": Git, diff, diagnostics, LSP. --- - Center section shows the name of displayed buffer. --- - Second to right section shows more buffer info. --- - Right most section shows current cursor coordinates and search results. --- --- See also: --- - `:h MiniStatusline-example-content` - example of default content. Use it to --- configure a custom statusline by setting `config.content.active` function. -now(function() - require("mini.statusline").setup() -end) - --- Tabline. Sets `:h 'tabline'` to show all listed buffers in a line at the top. --- Buffers are ordered as they were created. Navigate with `[b` and `]b`. -now(function() - require("mini.tabline").setup() -end) - --- Step one or two ============================================================ --- Load now if Neovim is started like `nvim -- path/to/file`, otherwise - later. --- This ensures a correct behavior for files opened during startup. - --- Completion and signature help. Implements async "two stage" autocompletion: --- - Based on attached LSP servers that support completion. --- - Fallback (based on built-in keyword completion) if there is no LSP candidates. --- --- Example usage in Insert mode with attached LSP: --- - Start typing text that should be recognized by LSP (like variable name). --- - After 100ms a popup menu with candidates appears. --- - Press `` / `` to navigate down/up the list. These are set up --- in 'mini.keymap'. You can also use `` / ``. --- - During navigation there is an info window to the right showing extra info --- that the LSP server can provide about the candidate. It appears after the --- candidate stays selected for 100ms. Use `` / `` to scroll it. --- - Navigating to an entry also changes buffer text. If you are happy with it, --- keep typing after it. To discard completion completely, press ``. --- - After pressing special trigger(s), usually `(`, a window appears that shows --- the signature of the current function/method. It gets updated as you type --- showing the currently active parameter. --- --- Example usage in Insert mode without an attached LSP or in places not --- supported by the LSP (like comments): --- - Start typing a word that is present in current or opened buffers. --- - After 100ms popup menu with candidates appears. --- - Navigate with `` / `` or `` / ``. This also updates --- buffer text. If happy with choice, keep typing. Stop with ``. --- --- It also works with snippet candidates provided by LSP server. Best experience --- when paired with 'mini.snippets' (which is set up in this file). -now_if_args(function() - -- Customize post-processing of LSP responses for a better user experience. - -- Don't show 'Text' suggestions (usually noisy) and show snippets last. - local process_items_opts = { kind_priority = { Text = -1, Snippet = 99 } } - local process_items = function(items, base) - return MiniCompletion.default_process_items(items, base, process_items_opts) - end - require("mini.completion").setup({ - lsp_completion = { - -- Without this config autocompletion is set up through `:h 'completefunc'`. - -- Although not needed, setting up through `:h 'omnifunc'` is cleaner - -- (sets up only when needed) and makes it possible to use ``. - source_func = "omnifunc", - auto_setup = false, - process_items = process_items, - }, - }) - - -- Set 'omnifunc' for LSP completion only when needed. - local on_attach = function(ev) - vim.bo[ev.buf].omnifunc = "v:lua.MiniCompletion.completefunc_lsp" - end - Config.new_autocmd("LspAttach", nil, on_attach, "Set 'omnifunc'") - - -- Advertise to servers that Neovim now supports certain set of completion and - -- signature features through 'mini.completion'. - vim.lsp.config("*", { capabilities = MiniCompletion.get_lsp_capabilities() }) -end) - --- Navigate and manipulate file system --- --- Navigation is done using column view (Miller columns) to display nested --- directories, they are displayed in floating windows in top left corner. --- --- Manipulate files and directories by editing text as regular buffers. --- --- Example usage: --- - `ed` - open current working directory --- - `ef` - open directory of current file (needs to be present on disk) --- --- Basic navigation: --- - `l` - go in entry at cursor: navigate into directory or open file --- - `h` - go out of focused directory --- - Navigate window as any regular buffer --- - Press `g?` inside explorer to see more mappings --- --- Basic manipulation: --- - After any following action, press `=` in Normal mode to synchronize, read --- carefully about actions, press `y` or `` to confirm --- - New entry: press `o` and type its name; end with `/` to create directory --- - Rename: press `C` and type new name --- - Delete: type `dd` --- - Move/copy: type `dd`/`yy`, navigate to target directory, press `p` --- --- See also: --- - `:h MiniFiles-navigation` - more details about how to navigate --- - `:h MiniFiles-manipulation` - more details about how to manipulate --- - `:h MiniFiles-examples` - examples of common setups -now_if_args(function() - -- Enable directory/file preview - require("mini.files").setup({ windows = { preview = true } }) - - -- Add common bookmarks for every explorer. Example usage inside explorer: - -- - `'c` to navigate into your config directory - -- - `g?` to see available bookmarks - local add_marks = function() - MiniFiles.set_bookmark("c", vim.fn.stdpath("config"), { desc = "Config" }) - local vimpack_plugins = vim.fn.stdpath("data") .. "/site/pack/core/opt" - MiniFiles.set_bookmark("p", vimpack_plugins, { desc = "Plugins" }) - MiniFiles.set_bookmark("w", vim.fn.getcwd, { desc = "Working directory" }) - end - Config.new_autocmd("User", "MiniFilesExplorerOpen", add_marks, "Add bookmarks") -end) - --- Miscellaneous small but useful functions. Example usage: --- - `oz` - toggle between "zoomed" and regular view of current buffer --- - `or` - resize window to its "editable width" --- - `:lua put_text(vim.lsp.get_clients())` - put output of a function below --- cursor in current buffer. Useful for a detailed exploration. --- - `:lua put(MiniMisc.stat_summary(MiniMisc.bench_time(f, 100)))` - run --- function `f` 100 times and report statistical summary of execution times -now_if_args(function() - -- Makes `:h MiniMisc.put()` and `:h MiniMisc.put_text()` public - require("mini.misc").setup() - - -- Change current working directory based on the current file path. It - -- searches up the file tree until the first root marker ('.git' or 'Makefile') - -- and sets their parent directory as a current directory. - -- This is helpful when simultaneously dealing with files from several projects. - MiniMisc.setup_auto_root() - - -- Restore latest cursor position on file open - MiniMisc.setup_restore_cursor() - - -- Synchronize terminal emulator background with Neovim's background to remove - -- possibly different color padding around Neovim instance - MiniMisc.setup_termbg_sync() -end) - --- Step two =================================================================== - --- Extra 'mini.nvim' functionality. --- --- See also: --- - `:h MiniExtra.pickers` - pickers. Most are mapped in `f` group. --- Calling `setup()` makes 'mini.pick' respect 'mini.extra' pickers. --- - `:h MiniExtra.gen_ai_spec` - 'mini.ai' textobject specifications --- - `:h MiniExtra.gen_highlighter` - 'mini.hipatterns' highlighters -later(function() - require("mini.extra").setup() -end) - --- Extend and create a/i textobjects, like `:h a(`, `:h a'`, and more). --- Contains not only `a` and `i` type of textobjects, but also their "next" and --- "last" variants that will explicitly search for textobjects after and before --- cursor. Example usage: --- - `ci)` - *c*hange *i*inside parenthesis (`)`) --- - `di(` - *d*elete *i*inside padded parenthesis (`(`) --- - `yaq` - *y*ank *a*round *q*uote (any of "", '', or ``) --- - `vif` - *v*isually select *i*inside *f*unction call --- - `cina` - *c*hange *i*nside *n*ext *a*rgument --- - `valaala` - *v*isually select *a*round *l*ast (i.e. previous) *a*rgument --- and then again reselect *a*round new *l*ast *a*rgument --- --- See also: --- - `:h text-objects` - general info about what textobjects are --- - `:h MiniAi-builtin-textobjects` - list of all supported textobjects --- - `:h MiniAi-textobject-specification` - examples of custom textobjects -later(function() - local ai = require("mini.ai") - ai.setup({ - -- 'mini.ai' can be extended with custom textobjects - custom_textobjects = { - -- Make `aB` / `iB` act on around/inside whole *b*uffer - B = MiniExtra.gen_ai_spec.buffer(), - -- For more complicated textobjects that require structural awareness, - -- use tree-sitter. This example makes `aF`/`iF` mean around/inside function - -- definition (not call). See `:h MiniAi.gen_spec.treesitter()` for details. - F = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }), - }, - - -- 'mini.ai' by default mostly mimics built-in search behavior: first try - -- to find textobject covering cursor, then try to find to the right. - -- Although this works in most cases, some are confusing. It is more robust to - -- always try to search only covering textobject and explicitly ask to search - -- for next (`an`/`in`) or last (`al`/`il`). - -- Try this. If you don't like it - delete next line and this comment. - search_method = "cover", - }) -end) - --- Align text interactively. Example usage: --- - `gaip,` - `ga` (align operator) *i*nside *p*aragraph by comma --- - `gAip` - start interactive alignment on the paragraph. Choose how to --- split, justify, and merge string parts. Press `` to make it permanent, --- press `` to go back to initial state. --- --- See also: --- - `:h MiniAlign-example` - hands-on list of examples to practice aligning --- - `:h MiniAlign.gen_step` - list of support step customizations --- - `:h MiniAlign-algorithm` - how alignment is done on algorithmic level -later(function() - require("mini.align").setup() -end) - --- Animate common Neovim actions. Like cursor movement, scroll, window resize, --- window open, window close. Animations are done based on Neovim events and --- don't require custom mappings. --- --- It is not enabled by default because its effects are a matter of taste. --- Also scroll and resize have some unwanted side effects (see `:h mini.animate`). --- Uncomment next line (use `gcc`) to enable. --- later(function() require('mini.animate').setup() end) - --- Go forward/backward with square brackets. Implements consistent sets of mappings --- for selected targets (like buffers, diagnostic, quickfix list entries, etc.). --- Example usage: --- - `]b` - go to next buffer --- - `[j` - go to previous jump inside current buffer --- - `[Q` - go to first entry of quickfix list --- - `]X` - go to last conflict marker in a buffer --- --- See also: --- - `:h MiniBracketed` - overall mapping design and list of targets -later(function() - require("mini.bracketed").setup() -end) - --- Remove buffers. Opened files occupy space in tabline and buffer picker. --- When not needed, they can be removed. Example usage: --- - `bw` - completely wipeout current buffer (see `:h :bwipeout`) --- - `bW` - completely wipeout current buffer even if it has changes --- - `bd` - delete current buffer (see `:h :bdelete`) -later(function() - require("mini.bufremove").setup() -end) - --- Show next key clues in a bottom right window. Requires explicit opt-in for --- keys that act as clue trigger. Example usage: --- - Press `` and wait for 1 second. A window with information about --- next available keys should appear. --- - Press one of the listed keys. Window updates immediately to show information --- about new next available keys. You can press `` to go back in key sequence. --- - Press keys until they resolve into some mapping. --- --- Note: it is designed to work in buffers for normal files. It doesn't work in --- special buffers (like for 'mini.starter' or 'mini.files') to not conflict --- with its local mappings. --- --- See also: --- - `:h MiniClue-examples` - examples of common setups --- - `:h MiniClue.ensure_buf_triggers()` - use it to enable triggers in buffer --- - `:h MiniClue.set_mapping_desc()` - change mapping description not from config -later(function() - local miniclue = require("mini.clue") - -- stylua: ignore + -- Keymap hints. + local miniclue = require('mini.clue') miniclue.setup({ - -- Define which clues to show. By default shows only clues for custom mappings - -- (uses `desc` field from the mapping; takes precedence over custom clue). clues = { - -- This is defined in 'plugin/20_keymaps.lua' with Leader group descriptions Config.leader_group_clues, miniclue.gen_clues.builtin_completion(), miniclue.gen_clues.g(), miniclue.gen_clues.marks(), miniclue.gen_clues.registers(), miniclue.gen_clues.square_brackets(), - -- This creates a submode for window resize mappings. Try the following: - -- - Press `s` to make a window split. - -- - Press `+` to increase height. Clue window still shows clues as if - -- `` is pressed again. Keep pressing just `+` to increase height. - -- Try pressing `-` to decrease height. - -- - Stop submode either by `` or by any key that is not in submode. miniclue.gen_clues.windows({ submode_resize = true }), miniclue.gen_clues.z(), }, - -- Explicitly opt-in for set of common keys to trigger clue window triggers = { { mode = { 'n', 'x' }, keys = '' }, -- Leader triggers - { mode = 'n', keys = '\\' }, -- mini.basics + { mode = 'n', keys = '\\' }, -- mini.basics { mode = { 'n', 'x' }, keys = '[' }, -- mini.bracketed { mode = { 'n', 'x' }, keys = ']' }, - { mode = 'i', keys = '' }, -- Built-in completion + { mode = 'i', keys = '' }, -- Built-in completion { mode = { 'n', 'x' }, keys = 'g' }, -- `g` key { mode = { 'n', 'x' }, keys = "'" }, -- Marks { mode = { 'n', 'x' }, keys = '`' }, { mode = { 'n', 'x' }, keys = '"' }, -- Registers { mode = { 'i', 'c' }, keys = '' }, - { mode = 'n', keys = '' }, -- Window commands + { mode = 'n', keys = '' }, -- Window commands { mode = { 'n', 'x' }, keys = 's' }, -- `s` key (mini.surround, etc.) { mode = { 'n', 'x' }, keys = 'z' }, -- `z` key }, }) end) --- Command line tweaks. Improves command line editing with: --- - Autocompletion. Basically an automated `:h cmdline-completion`. --- - Autocorrection of words as-you-type. Like `:W`->`:w`, `:lau`->`:lua`, etc. --- - Autopeek command range (like line number at the start) as-you-type. -later(function() - require("mini.cmdline").setup() +-- Editing ===================================================================== +Config.later(function() + -- Enhanced text objects (a/i). + require('mini.ai').setup() + + -- Auto-close brackets and quotes. + require('mini.pairs').setup() + + -- Surround functionality (add/delete/replace). + require('mini.surround').setup() end) --- Comment lines. Provides functionality to work with commented lines. --- Uses `:h 'commentstring'` option to infer comment structure. --- Example usage: --- - `gcip` - toggle comment (`gc`) *i*inside *p*aragraph --- - `vapgc` - *v*isually select *a*round *p*aragraph and toggle comment (`gc`) --- - `gcgc` - uncomment (`gc`, operator) comment block at cursor (`gc`, textobject) --- --- The built-in `:h commenting` is based on 'mini.comment'. Yet this module is --- still enabled as it provides more customization opportunities. -later(function() - require("mini.comment").setup() +-- Navigation ================================================================== +Config.now_if_args(function() + -- File system explorer. + require('mini.files').setup() + local add_marks = function() + MiniFiles.set_bookmark('c', vim.fn.stdpath('config'), { desc = 'Config' }) + MiniFiles.set_bookmark('w', vim.fn.getcwd, { desc = 'Working directory' }) + end + Config.autocmd('User', 'MiniFilesExplorerOpen', add_marks, 'Add default marks') end) --- Autohighlight word under cursor with a customizable delay. --- Word boundaries are defined based on `:h 'iskeyword'` option. --- --- later(function() --- require("mini.cursorword").setup() --- end) +Config.later(function() + -- Fuzzy picker. + require('mini.pick').setup() --- Work with diff hunks that represent the difference between the buffer text and --- some reference text set by a source. Default source uses text from Git index. --- Also provides summary info used in developer section of 'mini.statusline'. --- Example usage: --- - `ghip` - apply hunks (`gh`) within *i*nside *p*aragraph --- - `gHG` - reset hunks (`gH`) from cursor until end of buffer (`G`) --- - `ghgh` - apply (`gh`) hunk at cursor (`gh`) --- - `gHgh` - reset (`gH`) hunk at cursor (`gh`) --- - `go` - toggle overlay --- --- See also: --- - `:h MiniDiff-overview` - overview of how module works --- - `:h MiniDiff-diff-summary` - available summary information --- - `:h MiniDiff.gen_source` - available built-in sources --- Show di -later(function() require('mini.diff').setup() end) -later(function() - require("mini.diff").setup() + -- Square bracket navigation. + require('mini.bracketed').setup() end) --- Git integration for more straightforward Git actions based on Neovim's state. --- It is not meant as a fully featured Git client, only to provide helpers that --- integrate better with Neovim. Example usage: --- - `gs` - show information at cursor --- - `gd` - show unstaged changes as a patch in separate tabpage --- - `gL` - show Git log of current file --- - `:Git help git` - show output of `git help git` inside Neovim --- --- See also: --- - `:h MiniGit-examples` - examples of common setups --- - `:h :Git` - more details about `:Git` user command --- - `:h MiniGit.show_at_cursor()` - what information at cursor is shown -later(function() - require("mini.git").setup() +-- Completion ================================================================== +Config.now_if_args(function() + -- Autocompletion and signature help. + require('mini.completion').setup({ + lsp_completion = { + source_func = 'omnifunc', + auto_setup = false, + process_items = function(items, base) + return MiniCompletion.default_process_items(items, base, { kind_priority = { Text = -1 } }) + end, + }, + }) + + -- Set 'omnifunc' for LSP completion only when needed. + local on_attach = function(ev) + vim.bo[ev.buf].omnifunc = 'v:lua.MiniCompletion.completefunc_lsp' + end + Config.autocmd('LspAttach', nil, on_attach, "Set 'omnifunc'") + + -- Advertise to servers that Neovim supports certain set of completion features. + vim.lsp.config('*', { capabilities = MiniCompletion.get_lsp_capabilities() }) end) --- Highlight patterns in text. Like `TODO`/`NOTE` or color hex codes. --- Example usage: --- - `:Pick hipatterns` - pick among all highlighted patterns --- --- See also: --- - `:h MiniHipatterns-examples` - examples of common setups -later(function() - local hipatterns = require("mini.hipatterns") - local hi_words = MiniExtra.gen_highlighter.words - hipatterns.setup({ - highlighters = { - -- Highlight a fixed set of common words. Will be highlighted in any place, - -- not like "only in comments". - fixme = hi_words({ "FIXME", "Fixme", "fixme" }, "MiniHipatternsFixme"), - hack = hi_words({ "HACK", "Hack", "hack" }, "MiniHipatternsHack"), - todo = hi_words({ "TODO", "Todo", "todo" }, "MiniHipatternsTodo"), - note = hi_words({ "NOTE", "Note", "note" }, "MiniHipatternsNote"), - - -- Highlight hex color string (#aabbcc) with that color as a background - hex_color = hipatterns.gen_highlighter.hex_color(), - }, - }) +-- Workspace & Utilities ======================================================= +Config.now(function() + -- Session management. + require('mini.sessions').setup() end) --- Visualize and work with indent scope. It visualizes indent scope "at cursor" --- with animated vertical line. Provides relevant motions and textobjects. --- Example usage: --- - `cii` - *c*hange *i*nside *i*ndent scope --- - `Vaiai` - *V*isually select *a*round *i*ndent scope and then again --- reselect *a*round new *i*indent scope --- - `[i` / `]i` - navigate to scope's top / bottom --- --- See also: --- - `:h MiniIndentscope.gen_animation` - available animation rules -later(function() - require("mini.indentscope").setup() +Config.now_if_args(function() + -- Miscellaneous utility functions. + require('mini.misc').setup() + MiniMisc.setup_auto_root() + MiniMisc.setup_restore_cursor() end) --- Jump to next/previous single character. It implements "smarter `fFtT` keys" --- (see `:h f`) that work across multiple lines, start "jumping mode", and --- highlight all target matches. Example usage: --- - `fxff` - move *f*orward onto next character "x", then next, and next again --- - `dt)` - *d*elete *t*ill next closing parenthesis (`)`) -later(function() - require("mini.jump").setup() -end) - --- Jump within visible lines to pre-defined spots via iterative label filtering. --- Spots are computed by a configurable spotter function. Example usage: --- - Lock eyes on desired location to jump --- - `` - start jumping; this shows character labels over target spots --- - Type character that appears over desired location; number of target spots --- should be reduced --- - Keep typing labels until target spot is unique to perform the jump --- --- See also: --- - `:h MiniJump2d.gen_spotter` - list of available spotters -later(function() - require("mini.jump2d").setup() -end) - --- Special key mappings. Provides helpers to map: --- - Multi-step actions. Apply action 1 if condition is met; else apply --- action 2 if condition is met; etc. --- - Combos. Sequence of keys where each acts immediately plus execute extra --- action if all are typed fast enough. Useful for Insert mode mappings to not --- introduce delay when typing mapping keys without intention to execute action. --- --- See also: --- - `:h MiniKeymap-examples` - examples of common setups --- - `:h MiniKeymap.map_multistep()` - map multi-step action --- - `:h MiniKeymap.map_combo()` - map combo -later(function() - require("mini.keymap").setup() - -- Navigate 'mini.completion' menu with `` / `` - MiniKeymap.map_multistep("i", "", { "pmenu_next" }) - MiniKeymap.map_multistep("i", "", { "pmenu_prev" }) - -- On `` try to accept current completion item, fall back to accounting - -- for pairs from 'mini.pairs' - MiniKeymap.map_multistep("i", "", { "pmenu_accept", "minipairs_cr" }) - -- On `` just try to account for pairs from 'mini.pairs' - MiniKeymap.map_multistep("i", "", { "minipairs_bs" }) -end) - --- Move any selection in any direction. Example usage in Normal mode: --- - ``/`` - move current line down / up --- - ``/`` - decrease / increase indent of current line --- --- Example usage in Visual mode: --- - ``/``/``/`` - move selection left/down/up/right -later(function() - require("mini.move").setup() -end) - --- Text edit operators. All operators have mappings for: --- - Regular operator (waits for motion/textobject to use) --- - Current line action (repeat second character of operator to activate) --- - Act on visual selection (type operator in Visual mode) --- --- Example usage: --- - `griw` - replace (`gr`) *i*inside *w*ord --- - `gmm` - multiple/duplicate (`gm`) current line (extra `m`) --- - `vipgs` - *v*isually select *i*nside *p*aragraph and sort it (`gs`) --- - `gxiww.` - exchange (`gx`) *i*nside *w*ord with next word (`w` to navigate --- to it and `.` to repeat exchange operator) --- - `g==` - execute current line as Lua code and replace with its output. --- For example, typing `g==` over line `vim.lsp.get_clients()` shows --- information about all available LSP clients. --- --- See also: --- - `:h MiniOperators-mappings` - overview of how mappings are created --- - `:h MiniOperators-overview` - overview of present operators -later(function() - require("mini.operators").setup() - - -- Create mappings for swapping adjacent arguments. Notes: - -- - Relies on `a` argument textobject from 'mini.ai'. - -- - It is not 100% reliable, but mostly works. - -- - It overrides `:h (` and `:h )`. - -- Explanation: `gx`-`ia`-`gx`-`ila` <=> exchange current and last argument - -- Usage: when on `a` in `(aa, bb)` press `)` followed by `(`. - vim.keymap.set("n", "(", "gxiagxila", { remap = true, desc = "Swap arg left" }) - vim.keymap.set("n", ")", "gxiagxina", { remap = true, desc = "Swap arg right" }) -end) - --- Autopairs functionality. Insert pair when typing opening character and go over --- right character if it is already to cursor's right. Also provides mappings for --- `` and `` to perform extra actions when inside pair. --- Example usage in Insert mode: --- - `(` - insert "()" and put cursor between them --- - `)` when there is ")" to the right - jump over ")" without inserting new one --- - `(` - always insert a single "(" literally. This is useful since --- 'mini.pairs' doesn't provide particularly smart behavior, like auto balancing -later(function() - -- Create pairs not only in Insert, but also in Command line mode - require("mini.pairs").setup({ modes = { command = true } }) -end) - --- Pick anything with single window layout and fast matching. This is one of --- the main usability improvements as it powers a lot of "find things quickly" --- workflows. How to use a picker: --- - Start picker, usually with `:Pick ` command. Like `:Pick files`. --- It shows a single window in the bottom left corner filled with possible items --- to choose from. Current item has special full line highlighting. --- At the top there is a current query used to filter+sort items. --- - Type characters (appear at top) to narrow down items. There is fuzzy matching: --- characters may not match one-by-one, but they should be in correct order. --- - Navigate down/up with ``/``. --- - Press `` to show item's preview. `` again goes back to items. --- - Press `` to show picker's info. `` again goes back to items. --- - Press `` to choose an item. The exact action depends on the picker: `files` --- picker opens a selected file, `help` picker opens help page on selected tag. --- To close picker without choosing an item, press ``. --- --- Example usage: --- - `ff` - *f*ind *f*iles; for best performance requires `ripgrep` --- - `fg` - *f*ind inside files (a.k.a. "to *g*rep"); requires `ripgrep` --- - `fh` - *f*ind *h*elp tag --- - `fr` - *r*esume latest picker --- - `:h vim.ui.select()` - implemented with 'mini.pick' --- --- See also: --- - `:h MiniPick-overview` - overview of picker functionality --- - `:h MiniPick-examples` - examples of common setups --- - `:h MiniPick.builtin` and `:h MiniExtra.pickers` - available pickers; --- Execute one either with Lua function, `:Pick ` command, or --- one of `f` mappings defined in 'plugin/20_keymaps.lua' -later(function() - require("mini.pick").setup() -end) - --- Manage and expand snippets (templates for a frequently used text). --- Typical workflow is to type snippet's (configurable) prefix and expand it --- into a snippet session. --- --- How to manage snippets: --- - 'mini.snippets' itself doesn't come with preconfigured snippets. Instead there --- is a flexible system of how snippets are prepared before expanding. --- They can come from pre-defined path on disk, 'snippets/' directories inside --- config or plugins, defined inside `setup()` call directly. --- - This config, however, does come with snippet configuration: --- - 'snippets/global.json' is a file with global snippets that will be --- available in any buffer --- - 'after/snippets/lua.json' defines personal snippets for Lua language --- - 'friendly-snippets' plugin configured in 'plugin/40_plugins.lua' provides --- a collection of language snippets --- --- How to expand a snippet in Insert mode: --- - If you know snippet's prefix, type it as a word and press ``. Snippet's --- body should be inserted instead of the prefix. --- - If you don't remember snippet's prefix, type only part of it (or none at all) --- and press ``. It should show picker with all snippets that have prefixes --- matching typed characters (or all snippets if none was typed). --- Choose one and its body should be inserted instead of previously typed text. --- --- How to navigate during snippet session: --- - Snippets can contain tabstops - places for user to interactively adjust text. --- Each tabstop is highlighted depending on session progression - whether tabstop --- is current, was or was not visited. If tabstop doesn't yet have text, it is --- visualized with special "ghost" inline text: • and ∎ by default. --- - Type necessary text at current tabstop and navigate to next/previous one --- by pressing `` / ``. --- - Repeat previous step until you reach special final tabstop, usually denoted --- by ∎ symbol. If you spotted a mistake in an earlier tabstop, navigate to it --- and return back to the final tabstop. --- - To end a snippet session when at final tabstop, keep typing or go into --- Normal mode. To force end snippet session, press ``. --- --- See also: --- - `:h MiniSnippets-overview` - overview of how module works --- - `:h MiniSnippets-examples` - examples of common setups --- - `:h MiniSnippets-session` - details about snippet session --- - `:h MiniSnippets.gen_loader` - list of available loaders -later(function() - -- Define language patterns to work better with 'friendly-snippets' - local latex_patterns = { "latex/**/*.json", "**/latex.json" } - local lang_patterns = { - tex = latex_patterns, - plaintex = latex_patterns, - -- Recognize special injected language of markdown tree-sitter parser - markdown_inline = { "markdown.json" }, - } - - local snippets = require("mini.snippets") - local config_path = vim.fn.stdpath("config") - snippets.setup({ - snippets = { - -- Always load 'snippets/global.json' from config directory - snippets.gen_loader.from_file(config_path .. "/snippets/global.json"), - -- Load from 'snippets/' directory of plugins, like 'friendly-snippets' - snippets.gen_loader.from_lang({ lang_patterns = lang_patterns }), - }, - }) - - -- By default snippets available at cursor are not shown as candidates in - -- 'mini.completion' menu. This requires a dedicated in-process LSP server - -- that will provide them. To have that, uncomment next line (use `gcc`). - -- MiniSnippets.start_lsp_server() -end) - --- Split and join arguments (regions inside brackets between allowed separators). --- It uses Lua patterns to find arguments, which means it works in comments and --- strings but can be not as accurate as tree-sitter based solutions. --- Each action can be configured with hooks (like add/remove trailing comma). --- Example usage: --- - `gS` - toggle between joined (all in one line) and split (each on a separate --- line and indented) arguments. It is dot-repeatable (see `:h .`). --- --- See also: --- - `:h MiniSplitjoin.gen_hook` - list of available hooks -later(function() - require("mini.splitjoin").setup() -end) - --- Surround actions: add/delete/replace/find/highlight. Working with surroundings --- is surprisingly common: surround word with quotes, replace `)` with `]`, etc. --- This module comes with many built-in surroundings, each identified by a single --- character. It searches only for surrounding that covers cursor and comes with --- a special "next" / "last" versions of actions to search forward or backward --- (just like 'mini.ai'). All text editing actions are dot-repeatable (see `:h .`). --- --- Example usage (this may feel intimidating at first, but after practice it --- becomes second nature during text editing): --- - `saiw)` - *s*urround *a*dd for *i*nside *w*ord parenthesis (`)`) --- - `sdf` - *s*urround *d*elete *f*unction call (like `f(var)` -> `var`) --- - `srb[` - *s*urround *r*eplace *b*racket (any of [], (), {}) with padded `[` --- - `sf*` - *s*urround *f*ind right part of `*` pair (like bold in markdown) --- - `shf` - *s*urround *h*ighlight current *f*unction call --- - `srn{{` - *s*urround *r*eplace *n*ext curly bracket `{` with padded `{` --- - `sdl'` - *s*urround *d*elete *l*ast quote pair (`'`) --- - `vaWsa` - *v*isually select *a*round *W*ORD and *s*urround *a*dd --- spaces (``) --- --- See also: --- - `:h MiniSurround-builtin-surroundings` - list of all supported surroundings --- - `:h MiniSurround-surrounding-specification` - examples of custom surroundings --- - `:h MiniSurround-vim-surround-config` - alternative set of action mappings -later(function() - require("mini.surround").setup() -end) - --- Highlight and remove trailspace. Temporarily stops highlighting in Insert mode --- to reduce noise when typing. Example usage: --- - `ot` - trim all trailing whitespace in a buffer -later(function() - require("mini.trailspace").setup() -end) - --- Track and reuse file system visits. Every file/directory visit is persistently --- tracked on disk to later reuse: show in special frecency order, etc. It also --- supports adding labels to visited paths to quickly navigate between them. --- Example usage: --- - `fv` - find across all visits --- - `vv` / `vV` - add/remove special "core" label to current file --- - `vc` / `vC` - show files with "core" label; all or added within --- current working directory --- --- See also: --- - `:h MiniVisits-overview` - overview of how module works --- - `:h MiniVisits-examples` - examples of common setups -later(function() - require("mini.visits").setup() +Config.later(function() + -- Extra functionality (pickers, clues). + require('mini.extra').setup() end) diff --git a/plugin/40_plugins.lua b/plugin/40_plugins.lua index f14418a..eab067a 100644 --- a/plugin/40_plugins.lua +++ b/plugin/40_plugins.lua @@ -1,141 +1,99 @@ -local add = vim.pack.add -local now_if_args, later = Config.now_if_args, Config.later - -now_if_args(function() - -- Define hook to update tree-sitter parsers after plugin is updated - local ts_update = function() - vim.cmd("TSUpdate") - end - Config.on_packchanged("nvim-treesitter", { "update" }, ts_update, ":TSUpdate") - - add({ - "https://github.com/nvim-treesitter/nvim-treesitter", - "https://github.com/nvim-treesitter/nvim-treesitter-textobjects", - }) - - local languages = { - "lua", - "vimdoc", - "markdown", - "go", - "yaml", - "html", - } - local isnt_installed = function(lang) - return #vim.api.nvim_get_runtime_file("parser/" .. lang .. ".*", false) == 0 - end - local to_install = vim.tbl_filter(isnt_installed, languages) - if #to_install > 0 then - require("nvim-treesitter").install(to_install) - end - - -- Enable tree-sitter after opening a file for a target language - local filetypes = {} - for _, lang in ipairs(languages) do - for _, ft in ipairs(vim.treesitter.language.get_filetypes(lang)) do - table.insert(filetypes, ft) - end - end - local ts_start = function(ev) - vim.treesitter.start(ev.buf) - end - Config.new_autocmd("FileType", filetypes, ts_start, "Start tree-sitter") +-- Colortheme ================================================================== +Config.now(function() + vim.pack.add({ "https://github.com/rebelot/kanagawa.nvim" }) + require("kanagawa").setup({ compile = true }) + vim.cmd("colo kanagawa") end) --- Language servers =========================================================== - --- Language Server Protocol (LSP) is a set of conventions that power creation of --- language specific tools. It requires two parts: --- - Server - program that performs language specific computations. --- - Client - program that asks server for computations and shows results. --- --- Here Neovim itself is a client (see `:h vim.lsp`). Language servers need to --- be installed separately based on your OS, CLI tools, and preferences. --- See note about 'mason.nvim' at the bottom of the file. --- --- Neovim's team collects commonly used configurations for most language servers --- inside 'neovim/nvim-lspconfig' plugin. --- --- Add it now if file (and not 'mini.starter') is shown after startup. --- --- Troubleshooting: --- - Run `:checkhealth vim.lsp` to see potential issues. -now_if_args(function() - add({ "https://github.com/neovim/nvim-lspconfig" }) - - -- Use `:h vim.lsp.enable()` to automatically enable language server based on - -- the rules provided by 'nvim-lspconfig'. - vim.lsp.enable({ - "gopls", - "lua_ls", - "yamlls", - }) - - -- Use `:h vim.lsp.config()` or 'after/lsp/' directory to configure servers. - -- Uncomment and tweak the following `vim.lsp.enable()` call to enable servers. - -- vim.lsp.config({ - -- -- For example, if `lua-language-server` is installed, use `'lua_ls'` entry - -- }) +-- Mason ==================================================================== +Config.now_if_args(function() + vim.pack.add({ "https://github.com/mason-org/mason.nvim" }) + require("mason").setup() end) --- Formatting ================================================================= - --- Programs dedicated to text formatting (a.k.a. formatters) are very useful. --- Neovim has built-in tools for text formatting (see `:h gq` and `:h 'formatprg'`). --- They can be used to configure external programs, but it might become tedious. --- --- The 'stevearc/conform.nvim' plugin is a good and maintained solution for easier --- formatting setup. -later(function() - add({ "https://github.com/stevearc/conform.nvim" }) - - -- See also: - -- - `:h Conform` - -- - `:h conform-options` - -- - `:h conform-formatters` - require("conform").setup({ - default_format_opts = { - -- Allow formatting from LSP server if no dedicated formatter is available - lsp_format = "fallback", - }, - format_on_save = { - lsp_format = "fallback", - timeout_ms = 500, - }, - -- Map of filetype to formatters - -- Make sure that necessary CLI tool is available - -- formatters_by_ft = { lua = { 'stylua' } }, - formatters_by_ft = { - go = { "gofumpt", "goimports" }, - lua = { "stylua" }, - }, - }) +-- Treesitter ================================================================== +Config.now_if_args(function() + vim.pack.add({ "https://github.com/arborist-ts/arborist.nvim" }) + require("arborist").setup() end) --- Snippets =================================================================== +-- LSP ========================================================================= +Config.now_if_args(function() + vim.pack.add({ "https://github.com/neovim/nvim-lspconfig" }) --- Although 'mini.snippets' provides functionality to manage snippet files, it --- deliberately doesn't come with those. --- --- The 'rafamadriz/friendly-snippets' is currently the largest collection of --- snippet files. They are organized in 'snippets/' directory (mostly) per language. --- 'mini.snippets' is designed to work with it as seamlessly as possible. --- See `:h MiniSnippets.gen_loader.from_lang()`. --- later(function() --- add({ "https://github.com/rafamadriz/friendly-snippets" }) --- end) - --- Honorable mentions ========================================================= - --- 'mason-org/mason.nvim' (a.k.a. "Mason") is a great tool (package manager) for --- installing external language servers, formatters, and linters. It provides --- a unified interface for installing, updating, and deleting such programs. --- --- The caveat is that these programs will be set up to be mostly used inside Neovim. --- If you need them to work elsewhere, consider using other package managers. --- --- You can use it like so: -now_if_args(function() - add({ "https://github.com/mason-org/mason.nvim" }) - require("mason").setup() + vim.lsp.enable({ + "ansiblels", + "gopls", + "intelephense", + "lua_ls", + "tailwindcss", + "vtsls", + }) end) + +-- Conform ===================================================================== +Config.now_if_args(function() + vim.pack.add({ "https://github.com/stevearc/conform.nvim" }) + + require("conform").setup({ + default_format_opts = { lsp_format = "fallback" }, + format_on_save = { + lsp_format = "fallback", + timeout_ms = 500, + }, + formatters_by_ft = { + go = { "gofumpt", "goimports" }, + php = { "php_cs_fixer" }, + }, + }) +end) + +-- DAP ========================================================================= +function Config.setup_dap() + if package.loaded["dap"] then + return + end + + vim.pack.add({ "https://github.com/mfussenegger/nvim-dap" }) + + local dap = require("dap") + + dap.adapters.php = { + type = "executable", + command = "node", + args = { vim.fn.stdpath("data") .. "/mason/packages/php-debug-adapter/extension/out/phpDebug.js" }, + } + + dap.adapters.go = { + type = "server", + host = "127.0.0.1", + port = "${port}", + } +end + +-- Kulala ====================================================================== +function Config.setup_kulala() + if package.loaded["kulala"] then + return + end + + vim.pack.add({ "https://github.com/mistweaverco/kulala.nvim" }) + require("kulala").setup({ default_env = "dev" }) +end + +-- CodeCompanion =============================================================== +function Config.setup_codecompanion() + if package.loaded["codecompanion"] then + return + end + + vim.pack.add({ + "https://github.com/nvim-lua/plenary.nvim", + "https://github.com/olimorris/codecompanion.nvim" + }) + require("codecompanion").setup({ + completion = { + provider = "native" + } + }) +end -- 2.54.0 From 1bb7c081863f4f75aa5713492ddf9c35e09818fe Mon Sep 17 00:00:00 2001 From: Job79 Date: Tue, 18 Aug 2026 20:15:09 +0200 Subject: [PATCH 7/9] fix: add laravel and switch back to standard treesitter --- nvim-pack-lock.json | 34 +++++++++++++++++++++---------- plugin/20_keymaps.lua | 4 ---- plugin/40_plugins.lua | 47 +++++++++++++++++++++++++++++-------------- 3 files changed, 55 insertions(+), 30 deletions(-) diff --git a/nvim-pack-lock.json b/nvim-pack-lock.json index 6b343ea..902b9d9 100644 --- a/nvim-pack-lock.json +++ b/nvim-pack-lock.json @@ -1,33 +1,45 @@ { "plugins": { - "arborist.nvim": { - "rev": "fdeef56c2840c6772b9f68c5774ed87e9340ec7d", - "src": "https://github.com/arborist-ts/arborist.nvim" - }, - "codecompanion.nvim": { - "rev": "635f001598d811c6ea256bc863b3d503c3a88d43", - "src": "https://github.com/olimorris/codecompanion.nvim" - }, "conform.nvim": { - "rev": "619363c30309d29ffa631e67c8183f2a72caa373", + "rev": "016802de402556da54c36bd7359b441266b01cdd", "src": "https://github.com/stevearc/conform.nvim" }, "kanagawa.nvim": { "rev": "bb85e4bfc8d89b0e62c8fa53ccdd13d12e2f77b3", "src": "https://github.com/rebelot/kanagawa.nvim" }, + "laravel.nvim": { + "rev": "c0b171c8f9f0b5914f12b197711b93aa2c4047d3", + "src": "https://github.com/adalessa/laravel.nvim" + }, "mason.nvim": { "rev": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d", "src": "https://github.com/mason-org/mason.nvim" }, "mini.nvim": { - "rev": "c594be5b095204e99473825ec2dee872e7409a4d", + "rev": "e58ad4b0c9e9376096b9704f98fc00d4c9448870", "src": "https://github.com/nvim-mini/mini.nvim" }, + "nui.nvim": { + "rev": "a25dd472316d806eb38a5dd667c2e40da5570c75", + "src": "https://github.com/MunifTanjim/nui.nvim" + }, "nvim-lspconfig": { - "rev": "bfcc0171a43f22afa61d927ffe9fcb6cb85dc99e", + "rev": "0662886bc0a4e0c199dec65cee23a4319dd79f55", "src": "https://github.com/neovim/nvim-lspconfig" }, + "nvim-nio": { + "rev": "edcc181a875301dd21840189aa2f2f9ad69fc172", + "src": "https://github.com/nvim-neotest/nvim-nio" + }, + "nvim-treesitter": { + "rev": "074aa4422bf029908338e855d0c0f71470a971bb", + "src": "https://github.com/nvim-treesitter/nvim-treesitter" + }, + "nvim-treesitter-textobjects": { + "rev": "898ee307df58f854d11cd7edd06472574d48014e", + "src": "https://github.com/nvim-treesitter/nvim-treesitter-textobjects" + }, "plenary.nvim": { "rev": "74b06c6c75e4eeb3108ec01852001636d85a932b", "src": "https://github.com/nvim-lua/plenary.nvim" diff --git a/plugin/20_keymaps.lua b/plugin/20_keymaps.lua index 2615bf3..11b5c37 100644 --- a/plugin/20_keymaps.lua +++ b/plugin/20_keymaps.lua @@ -29,10 +29,6 @@ local function lazy_setup(name, action) end end --- AI ===================================================================== -nmap_leader("aa", lazy_setup("codecompanion", function() require("codecompanion").toggle_chat() end), - "Open CodeCompanion") - -- Buffers ===================================================================== nmap_leader("bd", function() vim.cmd("bd") end, "Delete") nmap_leader("bD", function() vim.cmd("bd!") end, "Delete!") diff --git a/plugin/40_plugins.lua b/plugin/40_plugins.lua index eab067a..320d2d6 100644 --- a/plugin/40_plugins.lua +++ b/plugin/40_plugins.lua @@ -13,8 +13,30 @@ end) -- Treesitter ================================================================== Config.now_if_args(function() - vim.pack.add({ "https://github.com/arborist-ts/arborist.nvim" }) - require("arborist").setup() + vim.pack.add({ + 'https://github.com/nvim-treesitter/nvim-treesitter', + 'https://github.com/nvim-treesitter/nvim-treesitter-textobjects', + }) + + local languages = { + 'lua', + 'go', + 'php', + 'sql', + 'javascript', + 'typescript', + 'tsx', + 'dockerfile', + 'yaml', + 'markdown', + } + local isnt_installed = function(lang) + return #vim.api.nvim_get_runtime_file('parser/' .. lang .. '.*', false) == 0 + end + local to_install = vim.tbl_filter(isnt_installed, languages) + if #to_install > 0 then require('nvim-treesitter').install(to_install) end + + Config.autocmd('FileType', languages, function(ev) vim.treesitter.start(ev.buf) end, 'Start tree-sitter') end) -- LSP ========================================================================= @@ -81,19 +103,14 @@ function Config.setup_kulala() require("kulala").setup({ default_env = "dev" }) end --- CodeCompanion =============================================================== -function Config.setup_codecompanion() - if package.loaded["codecompanion"] then - return - end - +-- Laravel ===================================================================== +Config.now_if_args(function() vim.pack.add({ + "https://github.com/MunifTanjim/nui.nvim", "https://github.com/nvim-lua/plenary.nvim", - "https://github.com/olimorris/codecompanion.nvim" + "https://github.com/nvim-neotest/nvim-nio", + "https://github.com/adalessa/laravel.nvim", }) - require("codecompanion").setup({ - completion = { - provider = "native" - } - }) -end + + require("laravel").setup({}) +end) -- 2.54.0 From 9f74d7a7a162f61a1a9a5fdd21797cbce0e711ba Mon Sep 17 00:00:00 2001 From: Job Jobse Date: Sat, 29 Aug 2026 13:03:23 +0200 Subject: [PATCH 8/9] refactor: small fixes --- init.lua | 4 +- lua/just.lua | 44 ++++++++-------- lua/terminal.lua | 2 +- nvim-pack-lock.json | 34 ++++++++++-- plugin/10_options.lua | 35 +++++++------ plugin/20_keymaps.lua | 118 ++++++++++++++++++++++++------------------ plugin/30_mini.lua | 12 ++--- plugin/40_plugins.lua | 100 ++++++++++++++++++++--------------- 8 files changed, 206 insertions(+), 143 deletions(-) diff --git a/init.lua b/init.lua index e231e35..e8f08a6 100644 --- a/init.lua +++ b/init.lua @@ -16,8 +16,8 @@ _G.Config = { later = function(f) misc.safely("later", f) end, on_event = function(ev, f) misc.safely("event:" .. ev, f) end, on_filetype = function(ft, f) misc.safely("filetype:" .. ft, f) end, - autocmd = function(event, pattern, callback, desc) - vim.api.nvim_create_autocmd(event, { group = gr, pattern = pattern, callback = callback, desc = desc }) + autocmd = function(event, pattern, callback, desc, once) + vim.api.nvim_create_autocmd(event, { group = gr, pattern = pattern, callback = callback, desc = desc, once = once }) end } diff --git a/lua/just.lua b/lua/just.lua index e0f8f2e..0989601 100644 --- a/lua/just.lua +++ b/lua/just.lua @@ -1,29 +1,29 @@ -local function run_task(cmd) - local buf = vim.api.nvim_create_buf(true, true) - vim.api.nvim_buf_set_name(buf, "just://" .. cmd) - vim.notify("󰑮 Running: " .. cmd) +local M = {} - vim.api.nvim_buf_call(buf, function() - vim.fn.jobstart(cmd, { - term = true, - on_exit = function(_, code) - if code == 0 then - vim.notify("󰄬 " .. cmd .. " success") - vim.schedule(function() - pcall(vim.api.nvim_buf_delete, buf, { force = true }) - end) - else - vim.notify("󰅚 " .. cmd .. " failed (" .. code .. ")", 4) - end - end, - }) - end) +local function run_task(cmd) + vim.notify("󰑮 Running: " .. cmd) + vim.cmd("enew") + + local buf = vim.api.nvim_get_current_buf() + pcall(vim.api.nvim_buf_set_name, buf, "just://" .. cmd) + + vim.fn.termopen(cmd, { + on_exit = function(_, code) + if code == 0 then + vim.notify("󰄬 " .. cmd .. " success") + pcall(vim.cmd, "bdelete!") + else + vim.notify("󰅚 " .. cmd .. " failed (" .. code .. ")", vim.log.levels.ERROR) + end + end, + }) end -function pick_just_task() +--- Interactive picker for selecting and running tasks defined in a Justfile. +function M.pick_just_task() local obj = vim.system({ "just", "--summary" }, { text = true }):wait() if obj.code ~= 0 or not obj.stdout or obj.stdout == "" then - return vim.notify("No recipes or justfile found", 3) + return vim.notify("No recipes or justfile found", vim.log.levels.WARN) end local recipes = vim.split(vim.trim(obj.stdout), "%s+") @@ -37,3 +37,5 @@ function pick_just_task() }, }) end + +return M diff --git a/lua/terminal.lua b/lua/terminal.lua index 036e593..6ac792f 100644 --- a/lua/terminal.lua +++ b/lua/terminal.lua @@ -5,7 +5,7 @@ function M.open_terminal_app(cmd) vim.cmd("enew") vim.fn.termopen(cmd, { on_exit = function() - vim.cmd("bdelete!") + pcall(vim.cmd, "bdelete!") end, }) end diff --git a/nvim-pack-lock.json b/nvim-pack-lock.json index 902b9d9..06936ae 100644 --- a/nvim-pack-lock.json +++ b/nvim-pack-lock.json @@ -4,12 +4,20 @@ "rev": "016802de402556da54c36bd7359b441266b01cdd", "src": "https://github.com/stevearc/conform.nvim" }, + "flutter-tools.nvim": { + "rev": "0867b346e9a60753080168188c8f1ee6be40b767", + "src": "https://github.com/nvim-flutter/flutter-tools.nvim" + }, "kanagawa.nvim": { "rev": "bb85e4bfc8d89b0e62c8fa53ccdd13d12e2f77b3", "src": "https://github.com/rebelot/kanagawa.nvim" }, + "kulala.nvim": { + "rev": "232a9939919fe9bc88d573bce92de50f2f160c60", + "src": "https://github.com/mistweaverco/kulala.nvim" + }, "laravel.nvim": { - "rev": "c0b171c8f9f0b5914f12b197711b93aa2c4047d3", + "rev": "6afb2a00530f67e7f49cf1c1ef9acc9e7c2ac72e", "src": "https://github.com/adalessa/laravel.nvim" }, "mason.nvim": { @@ -17,15 +25,31 @@ "src": "https://github.com/mason-org/mason.nvim" }, "mini.nvim": { - "rev": "e58ad4b0c9e9376096b9704f98fc00d4c9448870", + "rev": "fb2bbae327f3c306f3c825031345b89dd176ce60", "src": "https://github.com/nvim-mini/mini.nvim" }, + "neovim": { + "rev": "ff483051a47e27d84bdef47703538df1ed9f4a47", + "src": "https://github.com/rose-pine/neovim" + }, + "nightfox.nvim": { + "rev": "4dacd3f0185a2227bdf3b6c0975a8f0bf87cac9a", + "src": "https://github.com/EdenEast/nightfox.nvim" + }, "nui.nvim": { - "rev": "a25dd472316d806eb38a5dd667c2e40da5570c75", + "rev": "10fc361835c856ba4233ef5ea135b919bf3dce97", "src": "https://github.com/MunifTanjim/nui.nvim" }, + "nvim": { + "rev": "edefef779ab08ce1a4a404713e3012b0d202bd35", + "src": "https://github.com/catppuccin/nvim" + }, + "nvim-dap": { + "rev": "9e848e09a697ee95302a3ef2dd43fd6eb709e570", + "src": "https://github.com/mfussenegger/nvim-dap" + }, "nvim-lspconfig": { - "rev": "0662886bc0a4e0c199dec65cee23a4319dd79f55", + "rev": "684cb45c2faa24ce463b4fe9aaf011bfe1e0fb26", "src": "https://github.com/neovim/nvim-lspconfig" }, "nvim-nio": { @@ -33,7 +57,7 @@ "src": "https://github.com/nvim-neotest/nvim-nio" }, "nvim-treesitter": { - "rev": "074aa4422bf029908338e855d0c0f71470a971bb", + "rev": "8b98b4470eb326f1c7b50dae79f8c963568e5720", "src": "https://github.com/nvim-treesitter/nvim-treesitter" }, "nvim-treesitter-textobjects": { diff --git a/plugin/10_options.lua b/plugin/10_options.lua index 78acb27..a278fb3 100644 --- a/plugin/10_options.lua +++ b/plugin/10_options.lua @@ -1,23 +1,24 @@ -- General ===================================================================== -vim.g.mapleader = ' ' -- Use `` as key -vim.o.undofile = true -- Enable persistent undo +vim.g.mapleader = ' ' -- Use `` as key +vim.o.undofile = true -- Enable persistent undo -- UI ========================================================================== -vim.o.breakindent = true -- Indent wrapped lines to match line start -vim.o.breakindentopt = 'list:-1' -- Add padding for lists (if 'wrap' is set) -vim.o.cursorline = true -- Enable current line highlighting -vim.o.linebreak = true -- Wrap lines at 'breakat' (if 'wrap' is set) -vim.o.list = true -- Show helpful text indicators -vim.o.number = true -- Show line numbers -vim.o.pumheight = 10 -- Make popup menu smaller -vim.o.pummaxwidth = 100 -- Make popup menu not too wide -vim.o.shortmess = 'CFOSWaco' -- Disable some built-in completion messages -vim.o.signcolumn = 'yes' -- Always show signcolumn (less flicker) -vim.o.splitbelow = true -- Horizontal splits will be below -vim.o.splitkeep = 'screen' -- Reduce scroll during window split -vim.o.splitright = true -- Vertical splits will be to the right -vim.o.wrap = false -- Don't visually wrap lines (toggle with \w) -vim.o.cmdheight = 0 -- Hide the command line when not in use. +vim.o.breakindent = true -- Indent wrapped lines to match line start +vim.o.breakindentopt = 'list:-1' -- Add padding for lists (if 'wrap' is set) +vim.o.cursorline = true -- Enable current line highlighting +vim.o.linebreak = true -- Wrap lines at 'breakat' (if 'wrap' is set) +vim.o.list = true -- Show helpful text indicators +vim.o.number = true -- Show line numbers +vim.o.pumheight = 10 -- Make popup menu smaller +vim.o.pummaxwidth = 100 -- Make popup menu not too wide +vim.o.shortmess = 'CFOSWaco' -- Disable some built-in completion messages +vim.o.signcolumn = 'yes' -- Always show signcolumn (less flicker) +vim.o.splitbelow = true -- Horizontal splits will be below +vim.o.splitkeep = 'screen' -- Reduce scroll during window split +vim.o.splitright = true -- Vertical splits will be to the right +vim.o.wrap = false -- Don't visually wrap lines (toggle with \w) +vim.o.cmdheight = 0 -- Hide the command line when not in use +vim.cmd('syntax off') -- Disable legacy syntax highlighting -- Editing ===================================================================== vim.o.expandtab = true -- Convert tabs to spaces diff --git a/plugin/20_keymaps.lua b/plugin/20_keymaps.lua index 11b5c37..546b581 100644 --- a/plugin/20_keymaps.lua +++ b/plugin/20_keymaps.lua @@ -1,6 +1,5 @@ -- Clues ======================================================================= Config.leader_group_clues = { - { mode = "n", keys = "a", desc = "+AI" }, { mode = "n", keys = "b", desc = "+Buffer" }, { mode = "n", keys = "d", desc = "+Debug" }, { mode = "n", keys = "e", desc = "+Explore" }, @@ -16,46 +15,63 @@ Config.leader_group_clues = { } -- Helpers ===================================================================== -local nmap = function(lhs, rhs, desc) vim.keymap.set("n", lhs, rhs, { desc = desc }) end -local nmap_leader = function(suffix, rhs, desc) vim.keymap.set("n", "" .. suffix, rhs, { desc = desc }) end -local xmap_leader = function(suffix, rhs, desc) vim.keymap.set("x", "" .. suffix, rhs, { desc = desc }) end - -local function lazy_setup(name, action) +local function lazy_wrap(name, action) return function() - if Config and type(Config["setup_" .. name]) == "function" then - Config["setup_" .. name]() - end + if Config["setup_" .. name] then Config["setup_" .. name]() end action() end end --- Buffers ===================================================================== -nmap_leader("bd", function() vim.cmd("bd") end, "Delete") -nmap_leader("bD", function() vim.cmd("bd!") end, "Delete!") -nmap_leader("bw", function() vim.cmd("bw") end, "Wipeout") -nmap_leader("bW", function() vim.cmd("bw!") end, "Wipeout!") -nmap_leader("bo", function() vim.cmd("%bd|e#") end, "Close all but current") +local nmap = function(lhs, rhs, desc, plugin) + local final_rhs = plugin and lazy_wrap(plugin, rhs) or rhs + vim.keymap.set("n", lhs, final_rhs, { desc = desc }) +end --- Debug ===================================================================== -nmap_leader("db", lazy_setup("dap", function() require("dap").toggle_breakpoint() end), "Toggle Breakpoint") -nmap_leader("dc", lazy_setup("dap", function() require("dap").continue() end), "Run/Continue") -nmap_leader("dC", lazy_setup("dap", function() require("dap").run_to_cursor() end), "Run to Cursor") -nmap_leader("de", lazy_setup("dap", function() require("dap.ui.widgets").hover() end), "Inspect") -nmap_leader("dt", lazy_setup("dap", function() require("dap").terminate() end), "Terminate") +local nmap_leader = function(suffix, rhs, desc, plugin) + local final_rhs = plugin and lazy_wrap(plugin, rhs) or rhs + vim.keymap.set("n", "" .. suffix, final_rhs, { desc = desc }) +end + +local xmap_leader = function(suffix, rhs, desc, plugin) + local final_rhs = plugin and lazy_wrap(plugin, rhs) or rhs + vim.keymap.set("x", "" .. suffix, final_rhs, { desc = desc }) +end + +-- Buffers ===================================================================== +nmap_leader("bd", function() pcall(vim.cmd, "bdelete") end, "Delete") +nmap_leader("bD", function() pcall(vim.cmd, "bdelete!") end, "Delete!") +nmap_leader("bw", function() pcall(vim.cmd, "bwipeout") end, "Wipeout") +nmap_leader("bW", function() pcall(vim.cmd, "bwipeout!") end, "Wipeout!") +nmap_leader("bo", function() + local current = vim.api.nvim_get_current_buf() + for _, buf in ipairs(vim.api.nvim_list_bufs()) do + if buf ~= current and vim.api.nvim_buf_is_loaded(buf) and vim.bo[buf].buflisted then + pcall(vim.api.nvim_buf_delete, buf, { force = false }) + end + end +end, "Close all but current") + +-- Debug ======================================================================= +nmap_leader("db", function() require("dap").toggle_breakpoint() end, "Toggle Breakpoint", "dap") +nmap_leader("dc", function() require("dap").continue() end, "Run/Continue", "dap") +nmap_leader("dC", function() require("dap").run_to_cursor() end, "Run to Cursor", "dap") +nmap_leader("de", function() require("dap.ui.widgets").hover() end, "Inspect", "dap") +nmap_leader("dt", function() require("dap").terminate() end, "Terminate", "dap") -- Explore ===================================================================== nmap_leader("ed", function() MiniFiles.open() end, "Directory") -nmap_leader("ef", function() MiniFiles.open(vim.api.nvim_buf_get_name(0)) end, "File directory") +nmap_leader("ef", + function() MiniFiles.open(vim.uv.fs_stat(vim.api.nvim_buf_get_name(0)) and vim.api.nvim_buf_get_name(0) or nil) end, + "File directory") nmap_leader("en", function() MiniNotify.show_history() end, "Notifications") --- Find ===================================================================== -nmap_leader("f/", function() MiniPick.builtin.history({ scope = "/" }) end, '"/" history') -nmap_leader("f:", function() MiniPick.builtin.history({ scope = ":" }) end, '":" history') +-- Find ======================================================================== +nmap_leader("f:", function() MiniExtra.pickers.history({ scope = ":" }) end, '":" history') nmap_leader("fb", function() MiniPick.builtin.buffers() end, "Buffers") -nmap_leader("fc", function() MiniPick.builtin.git_commits() end, "Commits (all)") -nmap_leader("fC", function() MiniPick.builtin.git_commits({ path = "%" }) end, "Commits (buf)") -nmap_leader("fd", function() MiniPick.builtin.diagnostic({ scope = "all" }) end, "Diagnostic workspace") -nmap_leader("fD", function() MiniPick.builtin.diagnostic({ scope = "current" }) end, "Diagnostic buffer") +nmap_leader("fc", function() MiniExtra.pickers.git_commits() end, "Commits (all)") +nmap_leader("fC", function() MiniExtra.pickers.git_commits({ path = "%" }) end, "Commits (buf)") +nmap_leader("fd", function() MiniExtra.pickers.diagnostic({ scope = "all" }) end, "Diagnostic workspace") +nmap_leader("fD", function() MiniExtra.pickers.diagnostic({ scope = "current" }) end, "Diagnostic buffer") nmap_leader("ff", function() MiniPick.builtin.files() end, "Files") nmap_leader("fg", function() MiniPick.builtin.grep_live() end, "Grep live") nmap_leader("fG", function() MiniPick.builtin.grep({ pattern = vim.fn.expand("") }) end, "Grep current word") @@ -63,29 +79,33 @@ nmap_leader("fh", function() MiniPick.builtin.help() end, "Help tags") nmap_leader("fl", function() MiniPick.builtin.buf_lines({ scope = "all" }) end, "Lines (all)") nmap_leader("fL", function() MiniPick.builtin.buf_lines({ scope = "current" }) end, "Lines (buf)") nmap_leader("fr", function() MiniPick.builtin.resume() end, "Resume") -nmap_leader("fs", function() MiniPick.builtin.lsp({ scope = "workspace_symbol_live" }) end, "Symbols workspace (live)") -nmap_leader("fS", function() MiniPick.builtin.lsp({ scope = "document_symbol" }) end, "Symbols document") +nmap_leader("fs", function() MiniExtra.pickers.lsp({ scope = "workspace_symbol_live" }) end, "Symbols workspace (live)") +nmap_leader("fS", function() MiniExtra.pickers.lsp({ scope = "document_symbol" }) end, "Symbols document") +nmap_leader("f:", function() MiniExtra.pickers.history({ scope = ":" }) end, '":" history') +nmap_leader("f;", function() MiniExtra.pickers.history({ scope = ":" }) end, "Command history") --- Git ===================================================================== +-- Git ========================================================================= nmap_leader("go", function() MiniDiff.toggle_overlay() end, "Toggle overlay") +nmap_leader("gs", function() MiniGit.show_at_cursor() end, "Show at cursor") +xmap_leader("gs", function() MiniGit.show_at_cursor() end, "Show at selection") --- HTTP ===================================================================== -nmap_leader("hr", lazy_setup("kulala", function() require("kulala").run() end), "Send HTTP request") +-- HTTP ======================================================================== +nmap_leader("hr", function() require("kulala").run() end, "Send HTTP request", "kulala") --- Language ===================================================================== -nmap_leader("la", vim.lsp.buf.code_action, "Actions") -nmap_leader("ld", vim.diagnostic.open_float, "Diagnostic popup") -nmap_leader("lf", function() require("conform").format() end, "Format") -nmap_leader("li", vim.lsp.buf.implementation, "Implementation") -nmap_leader("lh", vim.lsp.buf.hover, "Hover") -nmap_leader("ll", vim.lsp.codelens.run, "Lens") -nmap_leader("lr", vim.lsp.buf.rename, "Rename") -nmap_leader("lR", vim.lsp.buf.references, "References") -nmap_leader("ls", vim.lsp.buf.definition, "Source definition") -nmap_leader("lt", vim.lsp.buf.type_definition, "Type definition") -xmap_leader("lf", function() require("conform").format() end, "Format selection") +-- Language ==================================================================== +nmap_leader("la", function() vim.lsp.buf.code_action() end, "Actions") +nmap_leader("ld", function() vim.diagnostic.open_float() end, "Diagnostic popup") +nmap_leader("lf", function() require("conform").format({ async = true }) end, "Format") +nmap_leader("li", function() vim.lsp.buf.implementation() end, "Implementation") +nmap_leader("lh", function() vim.lsp.buf.hover() end, "Hover") +nmap_leader("ll", function() vim.lsp.codelens.run() end, "Lens") +nmap_leader("lr", function() vim.lsp.buf.rename() end, "Rename") +nmap_leader("lR", function() vim.lsp.buf.references() end, "References") +nmap_leader("ls", function() vim.lsp.buf.definition() end, "Source definition") +nmap_leader("lt", function() vim.lsp.buf.type_definition() end, "Type definition") +xmap_leader("lf", function() require("conform").format({ async = true }) end, "Format selection") --- Run ===================================================================== +-- Run ========================================================================= nmap_leader("r", function() require("just").pick_just_task() end, "Run Just Task") -- Session ===================================================================== @@ -95,11 +115,11 @@ nmap_leader("sr", function() MiniSessions.select("read") end, "Read") nmap_leader("sR", function() MiniSessions.restart() end, "Restart") nmap_leader("sw", function() MiniSessions.write() end, "Write current") --- Terminal ===================================================================== +-- Terminal ==================================================================== nmap_leader("tT", function() vim.cmd("horizontal term") end, "Terminal (horizontal)") nmap_leader("tt", function() vim.cmd("vertical term") end, "Terminal (vertical)") nmap_leader("tg", function() require("terminal").open_terminal_app("lazygit") end, "LazyGit") nmap_leader("ts", function() require("terminal").open_terminal_app("lazysql") end, "LazySQL") --- Overwrites ===================================================================== +-- Overwrites ================================================================== nmap("", function() vim.cmd("nohlsearch") end, "Clear search highlights") diff --git a/plugin/30_mini.lua b/plugin/30_mini.lua index 2114724..60f3715 100644 --- a/plugin/30_mini.lua +++ b/plugin/30_mini.lua @@ -12,11 +12,15 @@ Config.now(function() -- Statusline. require('mini.statusline').setup() + + -- Session management. + require('mini.sessions').setup() end) Config.later(function() -- Git diff indicators. require('mini.diff').setup() + require('mini.git').setup() -- Keymap hints. local miniclue = require('mini.clue') @@ -67,6 +71,7 @@ Config.now_if_args(function() require('mini.files').setup() local add_marks = function() MiniFiles.set_bookmark('c', vim.fn.stdpath('config'), { desc = 'Config' }) + MiniFiles.set_bookmark('d', vim.fn.expand('~/Documents'), { desc = 'Documents' }) MiniFiles.set_bookmark('w', vim.fn.getcwd, { desc = 'Working directory' }) end Config.autocmd('User', 'MiniFilesExplorerOpen', add_marks, 'Add default marks') @@ -103,12 +108,7 @@ Config.now_if_args(function() vim.lsp.config('*', { capabilities = MiniCompletion.get_lsp_capabilities() }) end) --- Workspace & Utilities ======================================================= -Config.now(function() - -- Session management. - require('mini.sessions').setup() -end) - +-- Utilities =================================================================== Config.now_if_args(function() -- Miscellaneous utility functions. require('mini.misc').setup() diff --git a/plugin/40_plugins.lua b/plugin/40_plugins.lua index 320d2d6..0cbb551 100644 --- a/plugin/40_plugins.lua +++ b/plugin/40_plugins.lua @@ -1,14 +1,13 @@ -- Colortheme ================================================================== Config.now(function() - vim.pack.add({ "https://github.com/rebelot/kanagawa.nvim" }) - require("kanagawa").setup({ compile = true }) - vim.cmd("colo kanagawa") -end) - --- Mason ==================================================================== -Config.now_if_args(function() - vim.pack.add({ "https://github.com/mason-org/mason.nvim" }) - require("mason").setup() + vim.pack.add({ "https://github.com/rose-pine/neovim" }) + require("rose-pine").setup({ + enable = { + legacy_highlights = false, + migrations = false, + }, + }) + vim.cmd("colorscheme rose-pine") end) -- Treesitter ================================================================== @@ -18,25 +17,34 @@ Config.now_if_args(function() 'https://github.com/nvim-treesitter/nvim-treesitter-textobjects', }) - local languages = { - 'lua', - 'go', - 'php', - 'sql', - 'javascript', - 'typescript', - 'tsx', - 'dockerfile', - 'yaml', - 'markdown', - } - local isnt_installed = function(lang) - return #vim.api.nvim_get_runtime_file('parser/' .. lang .. '.*', false) == 0 - end - local to_install = vim.tbl_filter(isnt_installed, languages) - if #to_install > 0 then require('nvim-treesitter').install(to_install) end + vim.treesitter.language.register('tsx', { 'typescriptreact' }) - Config.autocmd('FileType', languages, function(ev) vim.treesitter.start(ev.buf) end, 'Start tree-sitter') + local filetypes = { + 'html', 'css', 'lua', 'go', 'php', 'blade', 'sql', 'javascript', + 'typescript', 'typescriptreact', 'dockerfile', 'yaml', 'markdown', 'dart', + 'json', 'xml', 'toml', 'bash', 'gitcommit', 'diff', 'regex', 'zsh' + } + + Config.autocmd('FileType', filetypes, function(ev) + if pcall(vim.treesitter.start, ev.buf) then + if vim.bo[ev.buf].filetype == 'php' then + -- fixes broken indentation on `o` in php buffers + vim.bo[ev.buf].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" + end + end + end, 'Start tree-sitter') + + Config.later(function() + require('nvim-treesitter').install(vim.tbl_map(function(ft) + return vim.treesitter.language.get_lang(ft) or ft + end, filetypes)) + end) +end) + +-- Mason ======================================================================= +Config.now_if_args(function() + vim.pack.add({ "https://github.com/mason-org/mason.nvim" }) + require("mason").setup() end) -- LSP ========================================================================= @@ -49,11 +57,12 @@ Config.now_if_args(function() "intelephense", "lua_ls", "tailwindcss", - "vtsls", + "tsc", + "dartls" }) end) --- Conform ===================================================================== +-- Formatting ================================================================== Config.now_if_args(function() vim.pack.add({ "https://github.com/stevearc/conform.nvim" }) @@ -61,7 +70,7 @@ Config.now_if_args(function() default_format_opts = { lsp_format = "fallback" }, format_on_save = { lsp_format = "fallback", - timeout_ms = 500, + timeout_ms = 1000, }, formatters_by_ft = { go = { "gofumpt", "goimports" }, @@ -72,20 +81,15 @@ end) -- DAP ========================================================================= function Config.setup_dap() - if package.loaded["dap"] then - return - end - + Config.setup_dap = nil vim.pack.add({ "https://github.com/mfussenegger/nvim-dap" }) local dap = require("dap") - dap.adapters.php = { type = "executable", command = "node", args = { vim.fn.stdpath("data") .. "/mason/packages/php-debug-adapter/extension/out/phpDebug.js" }, } - dap.adapters.go = { type = "server", host = "127.0.0.1", @@ -95,16 +99,14 @@ end -- Kulala ====================================================================== function Config.setup_kulala() - if package.loaded["kulala"] then - return - end - + Config.setup_kulala = nil vim.pack.add({ "https://github.com/mistweaverco/kulala.nvim" }) require("kulala").setup({ default_env = "dev" }) end -- Laravel ===================================================================== -Config.now_if_args(function() +function Config.setup_laravel() + Config.setup_laravel = nil vim.pack.add({ "https://github.com/MunifTanjim/nui.nvim", "https://github.com/nvim-lua/plenary.nvim", @@ -113,4 +115,18 @@ Config.now_if_args(function() }) require("laravel").setup({}) -end) +end + +-- Flutter ===================================================================== +function Config.setup_flutter() + Config.setup_flutter = nil + vim.pack.add({ + "https://github.com/nvim-lua/plenary.nvim", + "https://github.com/nvim-flutter/flutter-tools.nvim", + }) + + require("flutter-tools").setup({ lsp = { color_capabilities = true } }) +end + +Config.autocmd('FileType', 'php', Config.setup_laravel, "Setup laravel", true) +Config.autocmd('FileType', 'dart', Config.setup_flutter, "Setup flutter", true) -- 2.54.0 From 4e1096361533ad1ffd5577b293f05454ebd7ef0f Mon Sep 17 00:00:00 2001 From: Job Jobse Date: Sat, 29 Aug 2026 14:15:21 +0200 Subject: [PATCH 9/9] feat: add statuscolumn --- plugin/30_mini.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugin/30_mini.lua b/plugin/30_mini.lua index 60f3715..86e0f47 100644 --- a/plugin/30_mini.lua +++ b/plugin/30_mini.lua @@ -13,6 +13,9 @@ Config.now(function() -- Statusline. require('mini.statusline').setup() + -- Statuscolumn. + require('mini.statuscolumn').setup() + -- Session management. require('mini.sessions').setup() end) -- 2.54.0