Saturday, June 23, 2012

Re: Going back to empty brackets and quotes

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:
>
> 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>

> 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.

> 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).

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.

regards,
Christian
--

--
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: