Saturday, June 23, 2012

Re: Going back to empty brackets and quotes

On Sat, Jun 23, 2012 at 10:18 PM, Christian Brabandt <cblists@256bit.org> wrote:
> Hi Dotan!
>
> On Sa, 23 Jun 2012, Dotan Cohen wrote:
>
>> 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>
>>
>> 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:
>>


Thanks, Christian!


>> What is <sid>?
>
> <sid> is a way to prevent polluting the global Vim namespace with names
> from functions and plugins. It get resolved by Vim to something like
> <snr>XXX_<functionname>, where XXX is the name, that you can find in the
> output of :scriptnames (which tells you the order of loaded files). See
> als :h <sid>
>

Thanks. That is an interesting solution to the namespaces issue, I
will have to read more about that.


>> How can I get the character that was matched by:
>> ?\({\s*}\\|\[\s*]\\|<\s*>\\|>\s*<\\|(\s*)\\|"\s*"\\|'\s*'\\|>\s*<lt>\)?s+1<Return>
>
> Not sure. May be using matchstr() function and a like. It is hard to
> read, especially since you had to double the backslashes.
>

Yes, I figured that it was a mess! I basically matches these character
pairs, separated by whitespace:
{} [] <> >< () "" ''


>> 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.
>
> That is easy. It is StartPATtern and EndPattern (e.g. Start would be the
> opening paranthesis and End would be the closing paranthesis).
>

Ah! I figured that it was start* and end*! Thanks.


> If you describe in detail, what the function does and what you expect
> (best would be with sample text), I might be able to improve the
> version.
>

I would like the function to search backwards in the text for the
above-mentioned character pairs. If such a pair is found (separated by
possible whitespace), then I would like the cursor to be moved to the
character location halfway between them. If no pairs are found, then
the function would silently do nothing.

However, don't start coding! Although I appreciate code samples of
course, my real goal is to figure out how to write this function on my
own. I had no idea where to start so I asked the list. But you have
given me very specific tips and I can probably take it from here.
Thank you very much, your assistance and advice is very much
appreciated!

Have a peaceful week! I will update the thread when I have something
concrete that works. 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