I'm trying to make a text-object that is a paragraph surrounded by lines containing %. To test something simpler, I tried:

call textobj#user#plugin('pc', {
\   'code': {
\     'pattern': ['%<', '%'],
\     'scan': 'nearest',
\     'region-type': 'V',
\     'select-i': 'ir',
\   },
\ })

which works, but if I use % instead of %<, it doesn't. Must the patterns be different? Why?

  • 3
    Because there is no way to know when you are inside the pattern, or between two other %-delimited regions? You could use something like this, perhaps: github.com/kana/vim-textobj-syntax – VanLaser Feb 28 '16 at 12:23
  • @VanLaser, yes, but maybe it could assume that one is inside, behave like the paragraph object. – Toothrot Feb 28 '16 at 12:30
  • It could, but AFAIK it doesn't. I think if it finds the starting pattern, it simply doesn't 'move' the selection to the end pattern, if it's the same one. – VanLaser Feb 28 '16 at 12:41
  • I think that it first searches before the cursor for the start pattern, then searches the end pattern, and it cancels selection if the end pattern is not after the original cursor position. But I don't have the patience to look into the code, feel free to do so :) – VanLaser Feb 28 '16 at 12:59

This is actually a know issue (see issues #2 and #15 in the plugin bug tracker).

The author of the plugin suggested a workaround of the following form:

call textobj#user#plugin('handyobjects', {
\   'underscores_a': {
\     'select': 'ar',
\     '*pattern*': '%[^%]*%'
\   },
\   'underscores_i': {
\     'select': 'ir',
\     '*pattern*': '%\zs[^%]\+\ze%'
\   },
\ })

The idea is not to use a beginning and a ending pattern but just one regex to match the region:

  • For the ar motion the regex %[^%]*% defines a region starting with a % followed by anything which is not % repeated zero or more times (i.e. [^$]*) followed by another %.

  • For the ir motion the regex is more or less the same but the match excludes the delimitating % characters thanks to \zs and \ze.

So it is possible to use the same pattern for begin and end but you need to use only one regex.

Important note This is a workaround and it has a major drawback: I wasn't able to use it to match a region on several lines (which can be a problem in some cases).

Edit In some cases it is possible to create text objects which matches the same pattern on different lines. Here is what the author suggested to match two _ on different lines:

call textobj#user#plugin('handyobjects', {
\   'underscores_a': {
\     'select': 'au',
\     'pattern': '_\_[^_]*_'
\   },
\   'underscores_i': {
\     'select': 'iu',
\     'pattern': '_\zs\_[^_]\+\ze_'
\   },
\ })

Note That after a really quick test I wasn't able to make it work with % characters but I guess it what because of some escaping problem or something like this. I think that with some work on the regex it is possible to do it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.