Saturday, June 23, 2012

Re: Going back to empty brackets and quotes

On Thu, Jun 21, 2012 at 10:40 PM, Christian Brabandt <cblists@256bit.org> wrote:
> Hi Dotan!
>
> On Do, 21 Jun 2012, Dotan Cohen wrote:
>
>> Hello, I have this terrific mapping which takes me back to the
>> previous empty brackets or quotes:
>> inoremap jk <c-o>?\({}\\|\[]\\|<>\\|><\\|()\\|""\\|''\\|><lt>\)?s+1<Return>
>>
>> This works great if there is no whitespace between the empty brackets
>> / quotes, so I added the whitespace check:
>> inoremap jk <c-o>?\({\s*}\\|\[\s*]\\|<\s*>\\|>\s*<\\|(\s*)\\|"\s*"\\|'\s*'\\|>
>>    \s*<lt>\)?s+1<Return>
>>
>> However, this new regex leaves the cursor at the first character
>> inside the brackets. I would like it to be at the half-way point, as
>> sometimes there is no whitespace, sometimes a single space, and
>> sometimes a double space depending on nestling:
>>
>> if (something) {}
>> if ( someFunc(something) ) {}
>> if (  someFunc(something)  ||  otherFunc(something)  )
>>
>> To write that code, I will do:
>> if () {}|
>>         ^ Here I press jk
>> if (  ) {}|
>>           ^ Here I press jk
>> if (    ) {}|
>>             ^ Here I press jk
>>
>> Is there any way to put the cursor right in the middle of the
>> brackets? I tried to write a function which would calculate the amount
>> of whitespace characters between the brackets and would then press
>> <Right> half that many times, but I completely failed. I then tried to
>> select until the next bracket, replace all double whitespace
>> characters with a single whitespace, set a mark, paste the
>> now-half-size selection again, and then return to the mark. That
>> didn't work out so well either! What approach should I be taking?
>
> I am not exactly sure, what an empty bracket is supposed to be, but this
> should get you a start:
>
> fun! s:SearchPair() abort
>    let spat='\([[({<>''"]\)'
>    let epat='\([])}<>''"]\)'
>    call search(spat. '\(\s\+'. epat. '\)\@=', 'bW')
>    exe ':norm! v/'. epat. "\<CR>\<ESC>"
>    let len = getpos("'>")[2] - getpos("'<")[2]
>    exe ":norm! ". (getpos("'<")[2] + len/2 + 1). "|"
> endfu
>
>
> inoremap jk <c-\><c-o>:call <sid>SearchPair()<cr>
>
>
> regards,
> Christian

Thank you Christian! This is a good start for me to build upon, it is
full of things that I am unfamiliar with. It is pretty broken for most
uses, but I think that I can learn from it, which I suspect was quite
the intent! The getpos line is obviously where the magic occurs. A few
questions:

What is <sid>?

How can I get the character that was matched by:
?\({\s*}\\|\[\s*]\\|<\s*>\\|>\s*<\\|(\s*)\\|"\s*"\\|'\s*'\\|>\s*<lt>\)?s+1<Return>
I would use this to try to find the next match and compute the
distance between them.

What is the mnemonic for spat and epat? I cannot figure out why you
choose those variable names! I feel that if I know what they stand for
then the search line will become clearer as I'm not sure why it is
built the way that it is.

Thank you!

--
Dotan Cohen

http://gibberish.co.il
http://what-is-what.com

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

No comments:

Post a Comment