# mini.ai: textobjects that go past brackets in Neovim

> mini.ai is a Neovim plugin from the mini.nvim library that extends and adds a and i textobjects, with builtins for brackets, quotes, function calls, arguments, tags and punctuation, plus user defined textobjects built from Lua patterns or treesitter queries.

**nvim-mini/mini.ai** — Neovim Lua plugin to extend and create `a`/`i` textobjects. Part of 'mini.nvim' library.

- Repository: https://github.com/nvim-mini/mini.ai
- Stars: 631 · Forks: 14
- Language: Lua
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/nvim-mini-mini-ai

## What a textobject plugin is for

Textobjects are the operators that select a syntactic unit rather than a character. You press a prefix, then a character, and the cursor jumps to a matching pair, a word, a quote, a paragraph, and the selection grows to cover it. The native Neovim set covers brackets, quotes, words, sentences and paragraphs, which handles a lot of editing but not the constructs that show up in real code: a function call with its arguments, a tag, a prompt, a run of punctuation. mini.ai is a plugin for extending and creating a and i textobjects, and it is part of the mini.nvim library. The README describes it as enhancing some builtin textobjects, such as `a(` and `a)`, creating new ones such as `a*`, `a<Space>`, `af` and `a?`, and allowing you to create your own, including ones based on treesitter. The distinction it draws between enhancing and creating is the useful part, because a plugin that only adds a few keys leaves you in the same mental model, while one that provides a spec system lets you define your own.

## The builtins you get without configuring anything

The feature list names the builtin textobjects, and the documentation pointer is `:h MiniAi-builtin-textobjects`. Balanced brackets, with and without whitespace, plus an alias. Balanced quotes plus an alias. The function call. The argument. The tag. A textobject derived from the user prompt. And a default for anything but Latin letters, which exists to fall back to the text objects help. That last one is a deliberate detail rather than an oversight, since Latin letters are exactly what the builtin word motions handle, so the default character set deliberately hands those cases back to Neovim instead of competing with it. On top of the builtins there are motions for jumping to the left or right edge of a textobject, and a set of specification generators to tweak some of the builtin textobjects, with the help for `MiniAi.gen_spec` and a treesitter helper `MiniAi.gen_spec.treesitter()`. So the extension path is a generator rather than a hand written matcher, which is what makes a user defined textobject composable with the builtins.

## The behaviour that makes textobjects pleasant

The customisation features listed under customizable creation are the same ones that separate a toy textobject plugin from one you would keep. Dot-repeat is supported, so a textobject can be repeated with the dot command rather than retyped. The `v:count` is supported, so a count prefixes the operation. There are different search methods, listed in `:h MiniAi.config`. Consecutive application is supported, meaning the selection updates without leaving Visual mode, which is the difference between one textobject per keystroke and a chain of them. And aliases for multiple textobjects are supported, so a single prefix can mean different things. Custom textobjects are created using Lua patterns and functions. This is the whole feature set, and it is worth noticing that none of it is about a language server or a parser, so the plugin works the same in a file with no syntax highlighting at all.

## The default config, and the options you will actually change

The default configuration is a table you do not need to copy into `setup()`, and it is small enough to read in full. The mappings block holds the prefixes and the next and last variants, and the goto motions:

```lua
  -- Module mappings. Use `''` (empty string) to disable one.
  mappings = {
    -- Main textobject prefixes
    around = 'a',
    inside = 'i',

    -- Next/last variants
    -- NOTE: This (deliberately) overrides Neovim>=0.12 built-in incremental
    -- selection mappings. See `:h MiniAi-default-an-in` for more details.
    around_next = 'an',
    inside_next = 'in',
    around_last = 'al',
    inside_last = 'il',
```

Three options in the full table matter more than the rest. The `n_lines` option sets the number of lines within which a textobject is searched, and its default is 50, which is a wide net and the first thing to lower if the plugin feels sluggish. The `search_method` option decides how an object is found, first inside the current line and then in the neighborhood, with the default being `cover_or_next` and the alternatives being `cover`, `cover_or_prev`, `cover_or_nearest`, `next`, `previous` and `nearest`. And the `silent` option, defaulting to false, controls whether non-error feedback is shown, which also affects the informational helper messages that appear after idle time if user input is required. The `custom_textobjects` table sits at the top, empty by default, and is where your own definitions go.

## Installing it, and the two branches

The plugin can be installed as part of the mini.nvim library, which is the recommended route, or as a standalone Git repository, and there are two branches. The `main` branch is the default and recommended and carries the latest development version, with all changes since the last stable release perceived as being in beta testing, meaning they have already passed alpha testing and are moderately settled. The `stable` branch is updated only upon releases with code tested during the public beta-testing phase in `main`. For lazy.nvim users the standalone plugin is one line:

```lua
{ 'nvim-mini/mini.ai', version = false },
```

And the stable branch is the same with a version pin of `*`. The vim.pack route for Neovim 0.12 and newer is `vim.pack.add({ 'https://github.com/nvim-mini/mini.ai' })`, while the stable branch there passes a version of `stable`, and the mini.deps route before Neovim 0.12 uses `add('nvim-mini/mini.ai')` with the stable branch using `add({ source = 'nvim-mini/mini.ai', checkout = 'stable' })`. One step applies to all of them: you have to call `require('mini.ai').setup()` to enable its functionality.

## A project that moved house, and what that means

There is a note in the README about the project's history that is worth reading for a reason beyond curiosity. This was previously hosted at a personal `echasnovski` GitHub account, and it was transferred to a dedicated organization to improve long term project stability, with a link to the discussion explaining the details. So the standalone repository you install from is a mirror of work that now happens inside the mini.nvim library, and the README says all contributions, issues, pull requests and discussions are done inside mini.nvim. That arrangement has a practical consequence for anyone filing a bug. The right place is the library repository, not the standalone one, and the documentation link to use when mentioning the module is the mini.nvim readme for mini.ai rather than this repository. The library is a good deal larger than any single module, and the whole library documentation covers the general design principles and the disable and configuration recipes.

## Where this is the wrong choice

The limits are mostly about overlap and about how the plugin fits your setup. First, the plugin does not replace the treesitter textobjects. The README lists nvim-treesitter-textobjects among the similar plugins, and the treesitter support in mini.ai is a generator for producing a spec, which is a different thing from a full treesitter integration. If your workflow already depends on treesitter's node based selection, running both is a source of overlapping prefixes. Second, the an and in mappings deliberately override the Neovim 0.12 built-in incremental selection mappings, so installing this on a recent Neovim means giving up something, and the README points at `:h MiniAi-default-an-in` for the details. Third, the defaults are opinionated in ways that need adjusting. A window of 50 lines and a search method of `cover_or_next` will feel slow in a long file, and a helper message appearing after idle time is the kind of thing that gets disabled. Fourth, the whole thing is Lua configuration, so a user who wanted textobjects without touching their config is looking at the wrong plugin, and the README lists other options in the similar plugins section, including a targets style plugin and a user textobject plugin.

## Conclusion

mini.ai fits a Neovim user who already lives in textobjects and wants a wider set than the built-in brackets and quotes, especially one who wants a function call or a tag as a unit of motion. It is the wrong choice if you want minimal configuration, because the default setup is a table of mappings, a search method and a line window that you will want to change, and it is the wrong choice if your workflow is already built on treesitter textobjects, since the plugin lists the treesitter plugin as a similar project. Before you configure it, decide which search method you want, because it determines what a textobject picks up when several candidates are nearby, and read the note about the an and in mappings overriding Neovim 0.12 built-ins. The last push was on 2026-10-13, the licence is MIT, and the plugin is maintained as part of the mini.nvim library.

## FAQ

### What does the mini.ai Neovim plugin add to the built-in textobjects?

It enhances some builtin textobjects such as `a(` and `a)`, creates new ones such as `a*`, `a<Space>`, `af` and `a?`, and lets you define your own, including ones based on treesitter through the `MiniAi.gen_spec.treesitter()` helper.

### How do I install mini.ai and enable it?

Install it as part of the mini.nvim library, which is the recommended route, or as a standalone Git repository from the `main` or `stable` branch using vim.pack, mini.deps or lazy.nvim. In every case you must call `require('mini.ai').setup()` to enable its functionality.

### What is the difference between the main and stable branches of mini.ai?

The `main` branch carries the latest development version, with changes since the last stable release in a beta testing phase. The `stable` branch is updated only upon releases, with code that has been tested during the public beta-testing phase in `main`.

### How does mini.ai find a textobject when several candidates are nearby?

Through the `search_method` option, which defaults to `cover_or_next` and searches first inside the current line and then in the neighborhood. The alternatives are `cover`, `cover_or_prev`, `cover_or_nearest`, `next`, `previous` and `nearest`, and the `n_lines` option sets how many lines around the cursor are searched, with a default of 50.

## Sources

- [Issues](https://github.com/nvim-mini/mini.ai/issues)
- [License: MIT](https://github.com/nvim-mini/mini.ai/blob/main/LICENSE)
- [nvim-mini/mini.ai on GitHub](https://github.com/nvim-mini/mini.ai)
- [README](https://github.com/nvim-mini/mini.ai/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nvim-mini-mini-ai
