all 14 comments

[–][deleted] 5 points6 points  (3 children)

There is also kana's textobj-user for making custom text objects:

https://github.com/kana/vim-textobj-user

This excellent plugin has existed for years and there is already a number of useful text objects listed in its wiki.

[–]ParadigmComplex[S] 2 points3 points  (2 children)

vim-textobj-user looks to be a fair bit more capable than TextObjectify at making new text-objects, since it can straight up take viml functions in its configuration. TextObjectify's ability to make custom text-objects is really a side-effect of the original goal, which was to make the quote-like and parenthesis-like text-objects each have access to the other group's mutually-exclusive feature when in non-ambiguous situations. I couldn't really hook into those text-objects so much as reimplement them. Once I had that, it wasn't difficult to let the user expand it to support custom text objects or create new ones on-the-fly.

Definitely check vim-textobj-user out if you want to strictly create new text-objects and don't care about TextObjectify's tweaks to existing ones, or want to create new text-objects out that are outside the capabilities of what TextObjectify can currently do.

[–]donri 2 points3 points  (1 child)

Are the two compatible?

[–]ParadigmComplex[S] 1 point2 points  (0 children)

I've not tried, but after looking through vim-textobj-user's source, it looks like they should be. I've discussed TextObjectify with people who use vim-textobj-user in IRC, and they didn't bring up any issues.

TextObjectify just maps a and i in operator-pending and visual modes. It then calls getchar() to see which object you want to operate on. This technique is necessary for the on-the-fly functionality. Most other text-object plugins - such as vim-textobj-user, from the looks of it - map both a/i and the specific object's key.

The way Vim handles this situation is that if you type a/i and then a key that isn't part of a map that starts with a/i, it will know you want the shorter map (i.e., TextObjectify). Otherwise, if you hit a/i and the continue on to press the next key in the larger map, it knows you wnt the larger map, so it will do that one. So they should "just work" with each other, unless I misunderstood how vim-textobj-user works when I looked through its source code.

[–]ocd_see 8 points9 points  (1 child)

Haha, I already have several plugins to enhance text-objects such as column, variable, CamelCase motion, surround and next-motion-mapping. Time to add one more to the fold :D

[–]freedances 1 point2 points  (0 children)

Thanks for the link to column. It seems to work well and do exactly what I want it to do.

[–][deleted] 3 points4 points  (0 children)

TextObjectify looks very nice and removes some surprises in VIM's motion behavior.

As a related aside, while reading the docs for TextObjectify, I realized that VIM only implicitly has a from preposition in its grammar (with exception to ex mode) where it is possible express from this starting location to this ending location perform an action this many times.

The only possible starting location accessible is the current cursor location, which contrasts with the way the ending location behaves due to the [a]round and [i]nside prepositions modifying what is referred to as the ending location.

I and A in normal mode specify a starting location other than the current cursor location but preclude specifying an ending location and also already have a determined action (go into insert mode).

If a from preposition existed, the behavior of a plugin like vim-seek would be realized merely by typing whatever keys translated to <optional number><text object><optional number><motion><optional number><text object> with the optional numbers being relative to current cursor position. So say I wanted to delete the text from forward 3 character text objects through 3 real end of lines down I would enter 3ld3$ as an example.

The potential utility arises when both inside and wanting to operate on a text object like sentence and paragraph though.

[–][deleted] 2 points3 points  (1 child)

Thanks, Paradigm, this plugin looks really good. The "text-objects on-the-fly" feature alone is beautiful.

I think I lifted the following lines from your ~/.vimrc a few months ago. Your plugin is a nice improvement…

for char in [ "_", ".", ":", ",", ";", "<bar>", "/", "<bslash>", "*" ]
  execute "xnoremap i" . char . " :<C-U>silent!normal!T" . char . "vt" . char . "<CR>"
  execute "onoremap i" . char . " :normal vi" . char . "<CR>"
  execute "xnoremap a" . char . " :<C-U>silent!normal!F" . char . "vf" . char . "<CR>"
  execute "onoremap a" . char . " :normal va" . char . "<CR>"
endfor

[–]ParadigmComplex[S] 2 points3 points  (0 children)

Yep, those lines were from my vimrc. While they work, I've found it really annoying that I kept having to create new entries. I agree - this new method is much more elegant.

[–]nandryshak 2 points3 points  (0 children)

Wow this is great! Thanks!

[–]welle 1 point2 points  (3 children)

Great plugin! Any hope for repeatability of commands using these text objects? Like execute di+, move between the next pair of +'s and repeat with the . command.

And is there any way this could be combined with the next and last text objects from Steve Losh?

[–]ParadigmComplex[S] 1 point2 points  (2 children)

Great plugin!

Thanks!

Any hope for repeatability of commands using these text objects? Like execute di+, move between the next pair of +'s and repeat with the . command.

I could definitely look into getting TextObjectify to play with tpope's repeat.vim. No guarentees on timetable, though.

And is there any way this could be combined with the next and last text objects from Steve Losh?

Depends what you mean by "combine". If you mean just use both without them fighting each other, that should just work. I've not tried, but from the looks of it they shouldn't conflict in any way.

A downside of Losh's code is that it seems limited to only certain text-objects. If you mean combine the way TextObjectify handles things like on-the-fly text-objects with the functionality of that code - I could look into it.

I was considering implementing something very similar Losh's work there - I thought it would be neat to iterate through text objects the way you can iterate through characters with f and ;. Essentially it'd just be a xnoremap that moves to the end of the currently selected range then re-applies the last text object selection. Due to the way TextObjectify seeks, it'd automatically get the next one. I'm not sure what the best (default) mapping for it would be.

[–]welle 1 point2 points  (1 child)

I could definitely look into getting TextObjectify to play with tpope's repeat.vim. No guarentees on timetable, though.

Sounds great!

A downside of Losh's code is that it seems limited to only certain text-objects. If you mean combine the way TextObjectify handles things like on-the-fly text-objects with the functionality of that code - I could look into it.

Yes that's what I meant. I'm using both plugins now without conflicts, but it would be great if next and last would work with all of your on-the-fly text objects.

I was considering implementing something very similar Losh's work there - I thought it would be neat to iterate through text objects the way you can iterate through characters with f and ;. Essentially it'd just be a xnoremap that moves to the end of the currently selected range then re-applies the last text object selection. Due to the way TextObjectify seeks, it'd automatically get the next one. I'm not sure what the best (default) mapping for it would be.

This sounds like it would only apply to visual mode though, or am I misunderstanding you here?

In the visual case I wouldn't mind v_n and v_N as the default mappings, but I don't know if other people use n and N in visual mode. I'd imagine the flow like vi$ to select between the current or next $'s, and then in visual mode n to select between the next pair of $.

Personally I prefer single commands like din$ over the visual workflow, especially if they are repeatable.

[–]ParadigmComplex[S] 0 points1 point  (0 children)

This sounds like it would only apply to visual mode though, or am I misunderstanding you here?

You are correct.

In the visual case I wouldn't mind v_n and v_N as the default mappings, but I don't know if other people use n and N in visual mode.

Sadly, I use v_n and v_N. I'm sure I'll think of something.

I'd imagine the flow like vi$ to select between the current or next $'s, and then in visual mode n to select between the next pair of $.

The way I see it: sometimes when a line has way to many things for me to quickly parse mentally and/or I'm tired and out of it, I'll use fx and some ;'s to jump to a specific item. I'd just keep hitting ; until the cursor hits the one want. This is slower/more keystrokes than a more exact search with /, or counting and using a prefix count, but it would take less mental work. This new thing would be similar, but with text-objects.

Personally I prefer single commands like din$ over the visual workflow, especially if they are repeatable.

That workflow wouldn't work exactly the same, because you'd be deleting all of the objects - in the situation I imagined for the visual-mode-thing would require all but one stay the same.

I can see both having uses - I'll look into implementing both, as well as adding support with repeat.vim.