0

Using following test input:

***********
aaa
bbb
ccc
***********
ddd
eee
fff
-----------
ggg
hhh
iii
-----------
jjj
kkk
lll
-----------
***********
aaa
bbb
ccc
***********
ddd
eee
fff
-----------

Following method is close to what i'm looking for:

(i'm in need of using different ranges for each matches)

:execute 'g/ccc/-0,+0#' | execute 'g/eee/-1,+2#'

  4 ccc     <<----------- first returns lines with ccc, then with eee
 21 ccc
  6 ddd
  7 eee
  8 fff
  9 -----------
 23 ddd
 24 eee
 25 fff
 26 -----------  

Above output seems to show that the multiple global commands are executed sequentially. So, i get the "ccc" matches first from first global. Then comes the next set of matches from second global.

Is there way to run these global matches/commands on each lines in a single pass?

How would i go about getting following output instead?

  4 ccc
  6 ddd
  7 eee
  8 fff
  9 -----------
 21 ccc     <<-----------
 23 ddd
 24 eee
 25 fff
 26 -----------  
1

Yes, that's the way the :g command works. If you execute two :g commands after each other, do not be surprised, if they will be executed after each other :)

So you need to do it in one single pass. For that match the lines with a single :g command and then execute the # depending on the line content with different ranges. Something like this should work:

:g/eee\|ccc/if getline('.')=~'eee'|.-,.+2#|else|#|endif 

Note: No :exe needed in this case.

1
  • 1
    Though if i was writing it in this case i would go with … execute (getline('.') =~# 'eee' ? '-,+2' : '') '#' – D. Ben Knoble Jun 5 at 11:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.