{"id":13412919,"url":"https://github.com/chrisgrieser/nvim-various-textobjs","last_synced_at":"2025-10-25T10:01:53.999Z","repository":{"id":106951214,"uuid":"579999297","full_name":"chrisgrieser/nvim-various-textobjs","owner":"chrisgrieser","description":"Bundle of more than 30 new text objects for Neovim.","archived":false,"fork":false,"pushed_at":"2025-05-03T18:36:34.000Z","size":630,"stargazers_count":679,"open_issues_count":2,"forks_count":22,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-05-10T07:03:55.517Z","etag":null,"topics":["indentation","neovim","nvim","nvim-plugin","text-obj","text-object","text-objects"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chrisgrieser.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"custom":"https://www.paypal.me/ChrisGrieser","ko_fi":"pseudometa"}},"created_at":"2022-12-19T13:21:41.000Z","updated_at":"2025-05-07T22:45:41.000Z","dependencies_parsed_at":"2023-11-22T16:06:25.116Z","dependency_job_id":"a657ba75-8af3-4307-8408-b8dfc23526b3","html_url":"https://github.com/chrisgrieser/nvim-various-textobjs","commit_stats":{"total_commits":509,"total_committers":20,"mean_commits":25.45,"dds":0.06876227897838905,"last_synced_commit":"cc33e0a6681bbe913de515ac1a68492d50cbf949"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisgrieser%2Fnvim-various-textobjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisgrieser%2Fnvim-various-textobjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisgrieser%2Fnvim-various-textobjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisgrieser%2Fnvim-various-textobjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chrisgrieser","download_url":"https://codeload.github.com/chrisgrieser/nvim-various-textobjs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254301431,"owners_count":22047904,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["indentation","neovim","nvim","nvim-plugin","text-obj","text-object","text-objects"],"created_at":"2024-07-30T20:01:31.093Z","updated_at":"2025-10-25T10:01:53.992Z","avatar_url":"https://github.com/chrisgrieser.png","language":"Lua","funding_links":["https://www.paypal.me/ChrisGrieser","https://ko-fi.com/pseudometa","https://ko-fi.com/Y8Y86SQ91'"],"categories":["Editing Support","Lua"],"sub_categories":["Scrollbar"],"readme":"\u003c!-- LTeX: enabled=false --\u003e\n# nvim-various-textobjs 🟪🔷🟡\n\u003c!-- LTeX: enabled=true --\u003e\n\u003ca href=\"https://dotfyle.com/plugins/chrisgrieser/nvim-various-textobjs\"\u003e\n\u003cimg alt=\"badge\" src=\"https://dotfyle.com/plugins/chrisgrieser/nvim-various-textobjs/shield\"/\u003e\u003c/a\u003e\n\nBundle of more than 30 new text objects for Neovim.\n\n## Table of contents\n\n\u003c!-- toc --\u003e\n\n- [List of text objects](#list-of-text-objects)\n- [Installation](#installation)\n- [Configuration](#configuration)\n\t* [Options](#options)\n\t* [Use your own keybindings](#use-your-own-keybindings)\n- [Advanced usage / API](#advanced-usage--api)\n\t* [Dynamically switch text object settings](#dynamically-switch-text-object-settings)\n\t* [`ii` on unindented line should select entire buffer](#ii-on-unindented-line-should-select-entire-buffer)\n\t* [Smarter `gx` \u0026 `gf`](#smarter-gx--gf)\n\t* [Delete surrounding indentation](#delete-surrounding-indentation)\n\t* [Yank surrounding indentation](#yank-surrounding-indentation)\n\t* [Indent last paste](#indent-last-paste)\n\t* [Go to next occurrence of a text object](#go-to-next-occurrence-of-a-text-object)\n\t* [Other ideas?](#other-ideas)\n- [Limitations \u0026 non-goals](#limitations--non-goals)\n- [Other text object plugins](#other-text-object-plugins)\n- [Credits](#credits)\n\n\u003c!-- tocstop --\u003e\n\n## List of text objects\n\u003c!-- LTeX: enabled=false --\u003e\n\n| text object              | description                                                                                                                 | inner / outer                                                                             | forward-seeking    |     default keymaps      |\n| :----------------------- | :-------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------- | :--------------    | :----------------------: |\n| `indentation`            | surrounding lines with same or higher indentation                                                                           | [see overview from vim-indent-object](https://github.com/michaeljsmith/vim-indent-object) | \\-                 | `ii`, `ai`, `aI`, (`iI`) |\n| `restOfIndentation`      | lines downwards with same or higher indentation                                                                             | \\-                                                                                        | \\-                 |           `R`            |\n| `greedyOuterIndentation` | outer indentation, expanded to blank lines; useful to get functions with annotations                                        | outer includes a blank (like `ap`/`ip`)                                                   | \\-                 |        `ag`/`ig`         |\n| `subword`                | segment of a camelCase, snake_case, and kebab-case words                                                                    | outer includes trailing/leading `_` or `-`                                                | \\-                 |        `iS`/`aS`         |\n| `toNextClosingBracket`   | from cursor to next closing `]`, `)`, or `}`, can span multiple lines                                                       | \\-                                                                                        | small              |           `C`            |\n| `toNextQuotationMark`    | from cursor to next unescaped `\"`, `'`, or `` ` ``, can span multiple lines                                                 | \\-                                                                                        | small              |           `Q`            |\n| `anyQuote`               | between any unescaped `\"`, `'`, or `` ` `` in one line                                                                      | outer includes the quotation marks                                                        | small              |        `iq`/`aq`         |\n| `anyBracket`             | between any `()`, `[]`, or `{}` in one line                                                                                 | outer includes the brackets                                                               | small              |        `io`/`ao`         |\n| `restOfParagraph`        | like `}`, but linewise                                                                                                      | \\-                                                                                        | \\-                 |           `r`            |\n| `entireBuffer`           | entire buffer as one text object                                                                                            | \\-                                                                                        | \\-                 |           `gG`           |\n| `nearEoL`                | from cursor position to end of line minus one character                                                                     | \\-                                                                                        | \\-                 |           `n`            |\n| `lineCharacterwise`      | current line, but characterwise                                                                                             | outer includes indentation \u0026 trailing spaces                                              | small, if on blank |        `i_`/`a_`         |\n| `column`                 | column down until indent or shorter line; accepts `{count}` for multiple columns                                            | \\-                                                                                        | \\-                 |           `\\|`           |\n| `value`                  | value of key-value pair, or right side of assignment, excluding trailing comment (does not work for multi-line assignments) | outer includes trailing `,` or `;`                                                        | small              |        `iv`/`av`         |\n| `key`                    | key of key-value pair, or left side of an assignment                                                                        | outer includes the `=` or `:`                                                             | small              |        `ik`/`ak`         |\n| `url`                    | `http` links or any other protocol                                                                                          | \\-                                                                                        | big                |           `L`            |\n| `number`                 | numbers, similar to `\u003cC-a\u003e`                                                                                                 | inner: only digits, outer: number including minus sign and decimal *point*                | small              |        `in`/`an`         |\n| `diagnostic`             | nvim diagnostic                                                                                                             | \\-                                                                                        | ∞                  |           `!`            |\n| `closedFold`             | closed fold                                                                                                                 | outer includes one line after the last folded line                                        | big                |        `iz`/`az`         |\n| `chainMember`            | section of a chain connected with `.` (or `:`) like `foo.bar` or `foo.baz(para)`                                            | outer includes one `.` (or `:`)                                                           | small              |        `im`/`am`         |\n| `visibleInWindow`        | all lines visible in the current window                                                                                     | \\-                                                                                        | \\-                 |           `gw`           |\n| `restOfWindow`           | from the cursorline to the last line in the window                                                                          | \\-                                                                                        | \\-                 |           `gW`           |\n| `lastChange`             | last non-deletion-change, yank, or paste (paste-manipulation plugins may interfere)                                         | \\-                                                                                        | \\-                 |           `g;`           |\n| `notebookCell`           | cell delimited by [double percent comment][jupytext], such as `# %%`                                                        | outer includes the top cell border                                                        | \\-                 |        `iN`/`aN`         |\n| `emoji`                  | single emoji (or Nerdfont glyph)                                                                                            | \\-                                                                                        | small              |           `.`            |\n| `argument`               | comma-separated argument (not as accurate as the treesitter-textobjects, use as fallback)                                   | outer includes the `,`                                                                    | small              |        `i,`/`a,`         |\n| `filepath`               | unix-filepath; supports `~` or `$HOME`, but not spaces in the filepath.                                                     | inner is only the filename                                                                | big                |        `iF`/`aF`         |\n| `color`                  | hex; rgb or hsl in CSS format; ANSI color code                                                                              | inner includes only the color value                                                       | small              |        `i#`/`a#`         |\n| `doubleSquareBrackets`   | text enclosed by `[[]]`                                                                                                     | outer includes the 4 square brackets                                                      | small              |        `iD`/`aD`         |\n\n[jupytext]: https://jupytext.readthedocs.io/en/latest/formats-scripts.html#the-percent-format\n\n\u003e [!TIP]\n\u003e For some text objects, you can also use `caW` or `cl` if your cursor is\n\u003e standing on the object in question. However, these text objects become useful\n\u003e when utilizing their forward-seeking behavior: Objects like `cL` (`url`) or `c.`\n\u003e (`emoji`) will seek forward to the next occurrence and then change them in one\n\u003e go. This saves you the need to navigate to them before you can use `caW` or\n\u003e `cl`.\n\n| filetype-specific text objects | description                                                                                        | inner / outer                                   | forward-seeking |   default keymaps   | filetypes (for default keymaps)     |\n| :----------------------------- | :------------------------------------------------------------------------------------------------- | :-----------------------------------------------| :-------------- | :-----------------: | :---------------------------------- |\n| `mdLink`                       | Markdown link like `[title](url)`                                                                  | inner is only the link title (between the `[]`) | small           |      `il`/`al`      | `markdown`                          |\n| `mdEmphasis`                   | Markdown text enclosed by `*`, `**`, `_`, `__`, `~~`, or `==`                                      | inner is only the emphasis content              | small           |      `ie`/`ae`      | `markdown`                          |\n| `mdFencedCodeBlock`            | Markdown fenced code (enclosed by three backticks)                                                 | outer includes the enclosing backticks          | big             |      `iC`/`aC`      | `markdown`                          |\n| `cssSelector`                  | class in CSS such as `.my-class`                                                                   | outer includes trailing comma and space         | small           |      `ic`/`ac`      | `css`, `scss`                       |\n| `htmlAttribute`                | attribute in HTML/XML like `href=\"foobar.com\"`                                                     | inner is only the value inside the quotes       | small           |      `ix`/`ax`      | `html`, `xml`, `css`, `scss`, `vue`, `svelte` |\n| `shellPipe`                    | segment until/after a pipe character (`\\|`)                                                        | outer includes the pipe                         | small           |      `iP`/`aP`      | `bash`, `zsh`, `fish`, `sh`         |\n\n\u003c!-- LTeX: enabled=true --\u003e\n\n## Installation\n**Variant 1:** Have `nvim-various-textobjs` set up all the keybindings from the\ntable above for you.\n\n```lua\n-- lazy.nvim\n{\n\t\"chrisgrieser/nvim-various-textobjs\",\n\tevent = \"VeryLazy\",\n\topts = { \n\t\tkeymaps = {\n\t\t\tuseDefaults = true \n\t\t}\n\t},\n},\n\n-- packer\nuse {\n\t\"chrisgrieser/nvim-various-textobjs\",\n\tconfig = function () \n\t\trequire(\"various-textobjs\").setup({ \n\t\t\tkeymaps = {\n\t\t\t\tuseDefaults = true \n\t\t\t}\n\t\t})\n\tend,\n}\n```\n\n**Variant 2:** Use your own keybindings. See the\n[Configuration](#use-your-own-keybindings) section for information on how to set\nyour own keymaps.\n\n```lua\n-- lazy.nvim\n{\n\t\"chrisgrieser/nvim-various-textobjs\",\n\tkeys = {\n\t\t-- ...\n\t},\n},\n\n-- packer\nuse { \"chrisgrieser/nvim-various-textobjs\" }\n```\n\n\u003e [!TIP]\n\u003e You can also use the `keymaps.disabledDefaults` config option to disable\n\u003e only *some* default keymaps.\n\n## Configuration\n\n### Options\nThe `.setup()` call is optional if you do not want to use the default keymaps.\n\n```lua\n-- default config\nrequire(\"various-textobjs\").setup {\n\tkeymaps = {\n\t\t-- See overview table in README for the defaults. (Note that lazy-loading\n\t\t-- this plugin, the default keymaps cannot be set up. if you set this to\n\t\t-- `true`, you thus need to add `lazy = false` to your lazy.nvim config.)\n\t\tuseDefaults = false,\n\n\t\t-- disable only some default keymaps, for example { \"ai\", \"!\" }\n\t\t-- (only relevant when you set `useDefaults = true`)\n\t\t---@type string[]\n\t\tdisabledDefaults = {},\n\t},\n\n\tforwardLooking = {\n\t\t-- Number of lines to seek forwards for a text object. See the overview\n\t\t-- table in the README for which text object uses which value.\n\t\tsmall = 5,\n\t\tbig = 15,\n\t},\n\tbehavior = {\n\t\t-- save position in jumplist when using text objects\n\t\tjumplist = true,\n\t},\n\n\t-- extra configuration for specific text objects\n\ttextobjs = {\n\t\tindentation = {\n\t\t\t-- `false`: only indentation decreases delimit the text object\n\t\t\t-- `true`: indentation decreases as well as blank lines serve as delimiter\n\t\t\tblanksAreDelimiter = false,\n\t\t},\n\t\tsubword = {\n\t\t\t-- When deleting the start of a camelCased word, the result should\n\t\t\t-- still be camelCased and not PascalCased (see #113).\n\t\t\tnoCamelToPascalCase = true,\n\t\t},\n\t\tdiagnostic = {\n\t\t\twrap = true,\n\t\t},\n\t\turl = {\n\t\t\tpatterns = {\n\t\t\t\t[[%l%l%l+://[^%s)%]}\"'`\u003e]+]],\n\t\t\t},\n\t\t},\n\t},\n\n\tnotify = {\n\t\ticon = \"󰠱\", -- only used with notification plugins like `nvim-notify`\n\t\twhenObjectNotFound = true,\n\t},\n\n\t-- show debugging messages on use of certain text objects\n\tdebug = false,\n}\n```\n\n### Use your own keybindings\nIf you want to set your own keybindings, you can do so by calling the respective\nfunctions. The function names correspond to the text object names from the\n[overview table](#list-of-text-objects).\n\n\u003e [!NOTE]\n\u003e For dot-repeat to work, you have to call the motions as Ex-commands. Using\n\u003e `function() require(\"various-textobjs\").diagnostic() end` as third argument of\n\u003e the keymap will not work.\n\n```lua\n-- example: `U` for url textobj\nvim.keymap.set({ \"o\", \"x\" }, \"U\", '\u003ccmd\u003elua require(\"various-textobjs\").url()\u003cCR\u003e')\n\n-- example: `as` for outer subword, `is` for inner subword\nvim.keymap.set({ \"o\", \"x\" }, \"as\", '\u003ccmd\u003elua require(\"various-textobjs\").subword(\"outer\")\u003cCR\u003e')\nvim.keymap.set({ \"o\", \"x\" }, \"is\", '\u003ccmd\u003elua require(\"various-textobjs\").subword(\"inner\")\u003cCR\u003e')\n```\n\nFor most text objects, there is only one parameter which accepts `\"inner\"` or\n`\"outer\"`. The exceptions are the `indentation` and `column` text objects:\n\n```lua\n-- THE INDENTATION TEXTOBJ requires two parameters, the first for exclusion of\n-- the starting border, the second for the exclusion of ending border\nvim.keymap.set(\n\t{ \"o\", \"x\" },\n\t\"ii\",\n\t'\u003ccmd\u003elua require(\"various-textobjs\").indentation(\"inner\", \"inner\")\u003cCR\u003e'\n)\nvim.keymap.set(\n\t{ \"o\", \"x\" },\n\t\"ai\",\n\t'\u003ccmd\u003elua require(\"various-textobjs\").indentation(\"outer\", \"inner\")\u003cCR\u003e'\n)\n```\n\n```lua\n-- THE COLUMN TEXTOBJ takes an optional parameter for direction:\n-- \"down\" (default), \"up\", \"both\"\nvim.keymap.set({ \"o\", \"x\" }, \"|\", '\u003ccmd\u003elua require(\"various-textobjs\").column(\"down\")\u003cCR\u003e')\nvim.keymap.set({ \"o\", \"x\" }, \"a|\", '\u003ccmd\u003elua require(\"various-textobjs\").column(\"both\")\u003cCR\u003e')\n```\n\n## Advanced usage / API\nAll text objects can also be used as an API to modify their behavior or create\ncustom commands. Here are some examples:\n\n### Dynamically switch text object settings\nSome text objects have specific settings allowing you to configure their\nbehavior. In case you want to have two keymaps, one for each behavior, you can\nuse this plugin's `setup` call before calling the respective text object.\n\n```lua\n-- Example: one keymap for `http` urls only, one for `ftp` urls only\nvim.keymap.set({ \"o\", \"x\" }, \"H\", function()\n\trequire(\"various-textobjs\").setup {\n\t\ttextobjs = {\n\t\t\turl = {\n\t\t\t\tpatterns = { [[https?://[^%s)%]}\"'`\u003e]+]] },\n\t\t\t},\n\t\t},\n\t}\n\treturn \"\u003ccmd\u003elua require('various-textobjs').url()\u003cCR\u003e\"\nend, { expr = true, desc = \"http-url textobj\" })\n\nvim.keymap.set({ \"o\", \"x\" }, \"F\", function()\n\trequire(\"various-textobjs\").setup {\n\t\ttextobjs = {\n\t\t\turl = {\n\t\t\t\tpatterns = { [[ftp://[^%s)%]}\"'`\u003e]+]] },\n\t\t\t},\n\t\t},\n\t}\n\treturn \"\u003ccmd\u003elua require('various-textobjs').url()\u003cCR\u003e\"\nend, { expr = true, desc = \"ftp-url textobj\" })\n```\n\n### `ii` on unindented line should select entire buffer\nUsing a simple if-else-block, you can create a hybrid of the inner indentation\ntext object and the entire-buffer text object, if you prefer that kind of\nbehavior:\n\n```lua\n-- when on unindented line, `ii` should select entire buffer\nvim.keymap.set(\"o\", \"ii\", function()\n\tif vim.fn.indent(\".\") == 0 then\n\t\trequire(\"various-textobjs\").entireBuffer()\n\telse\n\t\trequire(\"various-textobjs\").indentation(\"inner\", \"inner\")\n\tend\nend)\n```\n\n### Smarter `gx` \u0026 `gf`\nThe code below retrieves the next URL (within the amount of lines configured in\nthe `setup` call), and opens it in your browser. As opposed to vim's built-in\n`gx`, this is **forward-seeking**, meaning your cursor does not have to stand on\nthe URL.\n\n```lua\nvim.keymap.set(\"n\", \"gx\", function()\n\trequire(\"various-textobjs\").url() -- select URL\n\n\tlocal foundURL = vim.fn.mode() == \"v\" -- only switches to visual mode when textobj found\n\tif not foundURL then return end\n\n\tlocal url = vim.fn.getregion(vim.fn.getpos(\".\"), vim.fn.getpos(\"v\"), { type = \"v\" })[1]\n\tvim.ui.open(url) -- requires nvim 0.10\n\tvim.cmd.normal { \"v\", bang = true } -- leave visual mode\nend, { desc = \"URL Opener\" })\n```\n\nSimilarly, we can also create a forward-looking version of `gf`:\n\n```lua\nvim.keymap.set(\"n\", \"gf\", function()\n\trequire(\"various-textobjs\").filepath(\"outer\") -- select filepath\n\n\tlocal foundPath = vim.fn.mode() == \"v\" -- only switches to visual mode when textobj found\n\tif not foundPath then return end\n\n\tlocal path = vim.fn.getregion(vim.fn.getpos(\".\"), vim.fn.getpos(\"v\"), { type = \"v\" })[1]\n\n\tlocal exists = vim.uv.fs_stat(vim.fs.normalize(path)) ~= nil\n\tif exists then\n\t\tvim.ui.open(path)\n\telse\n\t\tvim.notify(\"Path does not exist.\", vim.log.levels.WARN)\n\tend\nend, { desc = \"URL Opener\" })\n```\n\n### Delete surrounding indentation\nUsing the indentation text object, you can also create custom indentation-related\nutilities. A common operation is to remove the line before and after an\nindentation. Take for example this case where you are removing the `foo`\ncondition:\n\n```lua\n-- before\nif foo then\n\tprint(\"bar\") -- \u003c- cursor is on this line\n\tprint(\"baz\")\nend\n\n-- after\nprint(\"bar\")\nprint(\"baz\")\n```\n\nThe code below achieves this by dedenting the inner indentation text object\n(essentially running `\u003cii`), and deleting the two lines surrounding it. As for\nthe mapping, `dsi` should make sense since this command is similar to the `ds`\noperator from [vim-surround](https://github.com/tpope/vim-surround) but\nperformed on an indentation text object. (It is also an intuitive mnemonic:\nDelete Surrounding Indentation.)\n\n```lua\nvim.keymap.set(\"n\", \"dsi\", function()\n\t-- select outer indentation\n\trequire(\"various-textobjs\").indentation(\"outer\", \"outer\")\n\n\t-- plugin only switches to visual mode when a textobj has been found\n\tlocal indentationFound = vim.fn.mode():find(\"V\")\n\tif not indentationFound then return end\n\n\t-- dedent indentation\n\tvim.cmd.normal { \"\u003c\", bang = true }\n\n\t-- delete surrounding lines\n\tlocal endBorderLn = vim.api.nvim_buf_get_mark(0, \"\u003e\")[1]\n\tlocal startBorderLn = vim.api.nvim_buf_get_mark(0, \"\u003c\")[1]\n\tvim.cmd(tostring(endBorderLn) .. \" delete\") -- delete end first so line index is not shifted\n\tvim.cmd(tostring(startBorderLn) .. \" delete\")\nend, { desc = \"Delete Surrounding Indentation\" })\n```\n\n### Yank surrounding indentation\nSimilarly, you can also create a `ysii` command to yank the two lines surrounding\nan indentation text object. (Not using `ysi`, since that blocks surround\ncommands like `ysi)`). Using `nvim_win_[gs]et_cursor()`, you make the\noperation sticky, meaning the cursor is not moved.\n\n```lua\n-- NOTE this function uses `vim.hl.range` requires nvim 0.11\nvim.keymap.set(\"n\", \"ysii\", function()\n\tlocal startPos = vim.api.nvim_win_get_cursor(0)\n\n\t-- identify start- and end-border\n\trequire(\"various-textobjs\").indentation(\"outer\", \"outer\")\n\tlocal indentationFound = vim.fn.mode():find(\"V\")\n\tif not indentationFound then return end\n\tvim.cmd.normal { \"V\", bang = true } -- leave visual mode so the '\u003c '\u003e marks are set\n\n\t-- copy them into the + register\n\tlocal startLn = vim.api.nvim_buf_get_mark(0, \"\u003c\")[1] - 1\n\tlocal endLn = vim.api.nvim_buf_get_mark(0, \"\u003e\")[1] - 1\n\tlocal startLine = vim.api.nvim_buf_get_lines(0, startLn, startLn + 1, false)[1]\n\tlocal endLine = vim.api.nvim_buf_get_lines(0, endLn, endLn + 1, false)[1]\n\tvim.fn.setreg(\"+\", startLine .. \"\\n\" .. endLine .. \"\\n\")\n\n\t-- highlight yanked text\n\tlocal dur = 1500\n\tlocal ns = vim.api.nvim_create_namespace(\"ysii\")\n\tlocal bufnr = vim.api.nvim_get_current_buf()\n\tvim.hl.range(bufnr, ns, \"IncSearch\", { startLn, 0 }, { startLn, -1 }, { timeout = dur })\n\tvim.hl.range(bufnr, ns, \"IncSearch\", { endLn, 0 }, { endLn, -1 }, { timeout = dur })\n\n\t-- restore cursor position\n\tvim.api.nvim_win_set_cursor(0, startPos)\nend, { desc = \"Yank surrounding indentation\" })\n```\n\n### Indent last paste\nThe `lastChange` text object can be used to indent the last text that was pasted.\nThis is useful in languages such as Python where indentation is meaningful and\nthus formatters are not able to automatically indent everything for you.\n\nIf you do not use `P` for upwards paste, \"shift paste\" serves as a great\nmnemonic.\n\n```lua\nvim.keymap.set(\"n\", \"P\", function()\n\trequire(\"various-textobjs\").lastChange()\n\tlocal changeFound = vim.fn.mode():find(\"v\")\n\tif changeFound then vim.cmd.normal { \"\u003e\", bang = true } end\nend\n```\n\n### Go to next occurrence of a text object\nWhen called in normal mode, `nvim-various-textobjs` selects the next occurrence\nof the *characterwise* text object. Thus, you can create custom motions that go\nto the next occurrence of the text object:\n\n```lua\nlocal function gotoNextInnerNumber()\n\trequire(\"various-textobjs\").number(\"inner\")\n\tlocal mode = vim.fn.mode()\n\tif mode:find(\"[Vv]\") then -- only switches to visual when textobj found\n\t\tvim.cmd.normal { mode, bang = true } -- leaves visual mode\n\tend\nend\n```\n\nNote that the primary concern of `nvim-various-textobjs` are text objects and\nnot motions, so this will not work for all text objects with many exceptions\nlike subwords. For subwords, it is recommended to use a motion plugin like\n[nvim-spider](https://github.com/chrisgrieser/nvim-spider) instead.\n\n### Other ideas?\nIf you have some other useful ideas, feel free to [share them in this repo's\ndiscussion\npage](https://github.com/chrisgrieser/nvim-various-textobjs/discussions).\n\n## Limitations \u0026 non-goals\n- This plugin uses pattern matching, so it can be inaccurate in some edge cases.\n- Counts are not supported for most text objects.\n- Most characterwise text objects do not match multi-line objects. Most notably,\n  this affects the `value` text object.\n- [nvim-treesitter-textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects)\n  already does an excellent job when it comes to using Treesitter for text\n  objects, such as function arguments or loops. This plugin's goal is therefore\n  not to provide text objects already offered by `nvim-treesitter-textobjects`.\n- Some text objects (`argument`, `key`, `value`) are also offered by\n  `nvim-treesitter-textobjects`, and usually, the treesitter version of them is\n  more accurate, since `nvim-various-textobjs` uses pattern matching, which can\n  only get you so far. However, `nvim-treesitter-textobjects` does not support\n  all objects for all languages, so `nvim-various-textobjs` version exists to\n  provide a fallback for those languages.\n\n## Other text object plugins\n- [treesitter-textobjects](https://github.com/nvim-treesitter/nvim-treesitter-textobjects)\n- [treesitter-textsubjects](https://github.com/RRethy/nvim-treesitter-textsubjects)\n- [mini.ai](https://github.com/echasnovski/mini.nvim/blob/main/readmes/mini-ai.md)\n\n## Credits\n**Thanks**  \n- To the `Valuable Dev` for [their blog post on how to get started with creating\n  custom text objects](https://thevaluable.dev/vim-create-text-objects/).\n- [To `@vypxl` and `@ii14` for figuring out dot-repeatability.](https://github.com/chrisgrieser/nvim-spider/pull/4)\n\nIn my day job, I am a sociologist studying the social mechanisms underlying the\ndigital economy. For my PhD project, I investigate the governance of the app\neconomy and how software ecosystems manage the tension between innovation and\ncompatibility. If you are interested in this subject, feel free to get in touch.\n\n- [Website](https://chris-grieser.de/)\n- [Mastodon](https://pkm.social/@pseudometa)\n- [ResearchGate](https://www.researchgate.net/profile/Christopher-Grieser)\n- [LinkedIn](https://www.linkedin.com/in/christopher-grieser-ba693b17a/)\n\n\u003ca href='https://ko-fi.com/Y8Y86SQ91' target='_blank'\u003e\u003cimg height='36'\nstyle='border:0px;height:36px;' src='https://cdn.ko-fi.com/cdn/kofi1.png?v=3'\nborder='0' alt='Buy Me a Coffee at ko-fi.com' /\u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisgrieser%2Fnvim-various-textobjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrisgrieser%2Fnvim-various-textobjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisgrieser%2Fnvim-various-textobjs/lists"}