kana / vim-textobj-line

Vim plugin: Text objects for the current line
http://www.vim.org/scripts/script.php?script_id=3886
178 stars 7 forks source link

Perform action on line and end in the next line #7

Open blasco opened 5 years ago

blasco commented 5 years ago

As mentioned in this issue: https://github.com/kana/vim-textobj-line/issues/3

I would like to be able to repeat customs operators over lines. My solution is something like this:

i: The text in the line, same as in here I: The text in the line plus trailing whitespaces a: the complete line, I should end in the next line.

I've managed to add the different modifiers

call textobj#user#plugin('line', {
\      'a': {'select': 'al', 'select-function': 'textobj#line#select_a'},
\      'i': {'select': 'il', 'select-function': 'textobj#line#select_i'},
\      'I': {'select': 'Il', 'select-function': 'textobj#line#select_I'},
\    })

But I don't know how to achieve the repeatability. I changed 'a' to 'V' mode, which now works with the delete operator, but not with other operators as I'm still in the same line.

I would like to end in the next line after applying the operation. Does this make sense and is it possible?

kana commented 5 years ago

Would you mind giving an example to reproduce the problem? It’s hard to answer, because there are several vague points in your description. (What is the custom operator you used? What is the new definition of textobj#line#select_a? And so on.)

blasco commented 5 years ago

I would like to be able to do something like "3gUal" and that it capitalizes the next following 3 lines:

line one line two line three 3gUal LINE ONE LINE TWO LINE THREE just as I would do with "3dd". The way that I've redefine them I can do "3dal" and it works as described, but only works with "d" operator. This are my current definitions: ``` function! textobj#line#select_a() "{{{2 if empty(getline('.')) return 0 endif normal! 0 let head_pos = getpos('.') normal! $ let tail_pos = getpos('.') return ['V', head_pos, tail_pos] endfunction function! textobj#line#select_i() "{{{2 if empty(getline('.')) return 0 endif normal! ^ let head_pos = getpos('.') normal! g_ let tail_pos = getpos('.') let non_blank_char_exists_p = getline('.')[head_pos[2] - 1] !~# '\s' return \ non_blank_char_exists_p \ ? ['v', head_pos, tail_pos] \ : 0 endfunction function! textobj#line#select_I() "{{{2 if empty(getline('.')) return 0 endif normal! 0 let head_pos = getpos('.') normal! $ let tail_pos = getpos('.') return ['v', head_pos, tail_pos] endfunction ```
kana commented 5 years ago

Okay, I got it.

First of all, a count in 3gUal doesn’t mean how many times to repeat in general. Even if that count just means a repeat count, there is no obvious way to support the repeating behavior for all custom text objects at a framework level. That’s why vim-textobj-user doesn’t handle count for custom text objects.

So that you have to write code to handle count in textobj#line#select_a.

blasco commented 5 years ago

Makes sense, then I'll try to add that functionality. Thank you for the guidance and inspiration kana.