Tuesday, October 22, 2013

Re: Place a sign on each line between two regexps

On Tuesday, October 22, 2013 5:57:58 PM UTC+2, Ben Fritz wrote:
> On Tuesday, October 22, 2013 8:04:19 AM UTC-5, esquifit wrote:
[...]
>
> :g#start#+1,/end/-1normal! @q
>
> Again I use # for the delimiter for the :g command. The :g command will
> run a command on every line matching "start" because that is the pattern
> I give it. The command it runs is the same :normal command, but it will
> execute on every line in a range. The range is defined to run starting
> from "+1": i.e. from the next line after the one the :g command is
> currently running on; i.e. the first line below "start".

Thanks for the detail explanation. Apart from my mistake of forgetting the 'normal' before @q, the paragraph above was enlightening for me. Empirically I knew that, generally speaking,

:g/pat1/;/pat2/cmd

works and I was misled thinking that the 'g' modified the behaviour or the
range /pat1/;/pat2/ to which the cmd applies so that all regions delimited
between those patters would be taken into account (instead of only the first
one, which is what happens if you don't use 'g'). As I know understand from
your explanation, the proper way to look at it is:

Wrong interpretation
:g modifier
/start/+1,/end/-1 range
normal! @q command
Correct interpretation
:g/start/ global line selector
+1,/end/-1 range
normal! @q command


> :g#start#let line=line('.')+1 | while getline(line)!~'end' | exe 'sign
> place 1 name=Foo line='.line.' file='.expand('%:p') | let line+=1 | endwhile

I won't argue the merits of this line. I just don't like it. Not for a quick
one-time hack.

>
> Or maybe a normal command with a range:
>
> :g#start#+1,/end/-1normal! :exe 'sign place 1 name=Foo line='.line('.').'
> file='.expand('%:p')^M

This is indeed similar to what I originally intended. The 'normal :exe'
does the trick of avoiding the E418 about ranges not supported by exe, but
for some reason the whole line doesn't work. Even a simpler thing like

:g/START/;/END/normal :exe 'echo '.line('.')

doesn't yield any result.

> Or, make a function:
>
> function! PlaceSigns(linenum)
> let line=a:linenum+1
> while getline(line)!~'end'
> exe 'sign place 1 name=Foo line='.line.' file='.expand('%:p')
> let line+=1
> endwhile
> endfun
>
> :g#start#call PlaceSigns(line('.'))

I also thought of this but I didn't know how to pass the line number as a
parameter. I have still to test it.

Thanks again for your insight and the time you put into the answer.

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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

No comments: