nvim-lua / wishlist

A public catalogue of Lua plugins Neovim users would like to see exist
MIT License
235 stars 0 forks source link

Enhanced Text Objects #26

Open jebaum opened 3 years ago

jebaum commented 3 years ago

What? An enhancement to vim/neovim's built in text objects to include seeking forward and backward over multiple lines, and selecting context specific objects like function arguments, array entries, etc, as well as generic text objects like words, inside parens, brackets...

Why? Makes working with code much more pleasant and reduces the amount of movement keys you need to press to make the changes you want to.

Potential existing implementations: This is what I have in mind, that I currently use: https://github.com/wellle/targets.vim It doesn't get updated anymore and has several outstanding bugs These also exist: https://github.com/nvim-treesitter/nvim-treesitter-textobjects https://github.com/RRethy/nvim-treesitter-textsubjects

But those last two deal with a limited set of programming language specific constructs like parameters, function bodies, etc. Those are also excellent to have, but this is more about generic text objects that are built into vim like iw, i(, i{, etc (as well as the seeking behavior that targets.vim implements). Objects like i" for example could benefit from treesitter integration, as frequently they will behave incorrectly on nested quotes, or in vimscript files where " is the comment character.

*Potential pitfalls:* As targets.vim shows, implementing this in a way that handles all edge cases intuitively is extremely difficult. In vimscript particularly, manipulating buffer contents with commands in plugins also can have unexpected side effects for the user. My hope would be that it's somewhat easier to achieve consistency and lack of unintended side effects with a lua plugin.

ggandor commented 3 years ago

Count me in! (I mean, I'd be happy to work on this, though not as the owner/leader I think.)

zegervdv commented 3 years ago

You might find some inspiration in my nrpattern.nvim plugin.
The basic problem is the same: find the current line and column of the cursor and search for a pattern to the right (or left). In my case it was numbers, but for a targets.vim replacement that would be parentheses, brackets, quotes etc. Or if you find a better way to solve such a problem, let me know :)

matu3ba commented 3 years ago

context specific objects like function arguments, array entries, etc, as well as generic text objects like words, inside parens, brackets...

array entries => a[5] may be an array or vector or map etc. Conditional compilation (macros etc) may define it differently.

I think it would be easier to implement this with curated treesitter queries for iterating through (sub)object selections. So something like treesitter std lua functions with a minimal visual selection after running the function. Inspiration could be taken from plenary.nvim.

As I understand it you want 0. detect conflicts and abort on invalid syntax, 1. iterate functionality through (sub)object selections, 2. index retrieval from (sub)object selection, 3. tree modifications towards the chosen next index and (sub)object selection xor moving a substructure "upwards in the AST", 4. define common operations on that

step 3: Do you want to generalize the list of text objects to simpler ones or just replicate the behavior with treesitter queries and buffer checks?

    Pair text objects
    Quote text objects
    Separator text objects
    Argument text objects
    Tag text objects

step 4: Why is a visual selection of the text not sufficient? One should then apply treesitter modifications defined in 3. or select a subpart of the visual selection.

NOTE: Multiselections must be visualised or the whole editing becomes a mess, when operating on the AST. NOTE2: I dont understand how arithmetic operations apply here.

echasnovski commented 2 years ago

I've recently released mini.ai - module of 'mini.nvim' for extending and creating a/i textobjects. This is basically an extended 'targets.vim', but in Lua and a bit different.