4

I'd like to test the range pattern, same as Vim highlights the text while searching (e.g. :/), but for the range command instead.

So in other words, instead of executing:

:/<head/,/\/head>/d

I'd like to test only /<head/,/\/head>/ range pattern in form of highlight to check whether the pattern is correct, before I'm going to run any command on that range.

Sample text to play with can be retrieved by: vim http://www.example.com/.

2 Answers 2

7

A

If you just want to quickly confirm the validity of the range (and it isn't too long), you can use the built-in :print or :number:

:/<head/,/\/head>/print

B

Another idea would be (mis-)using the visual selection. The following custom command creates a linewise selection of the passed range:

":[range]SelectRange    Create a linewise visual selection of [range].
command! -bar -range SelectRange execute "normal! m'" | call cursor(<line1>, 1) | execute 'normal! V' | call cursor(<line2>, 1)

:/<head/,/\/head>/SelectRange

C

If you really want some (semi-permanent) highlighting, you can use :match with one of the following custom commands:

hi link Match Search

":[range]MatchLines [{group}]
"           Highlight the lines in [range] with the "Match" group /
"           {group}. This only considers the line numbers, not their
"           contents.
command! -bar -range -nargs=? MatchLines execute 'match' (empty(<q-args>) ? 'Match' : <q-args>) printf('/\%%>%dl\%%<%dl/', (<line1> - 1), (<line2> + 1))

":[range]MatchRange [{group}]
"           Highlight the content of the lines in [range] with the
"           "Match" group / {group}. This considers the current
"           content of the lines (also elsewhere in the buffer).
command! -bar -range -nargs=? MatchRange execute 'match' (empty(<q-args>) ? 'Match' : <q-args>) '/\V\^' . join(map(getline(<line1>, <line2>), 'escape(v:val, "\\/")'), '\n') . '\$/'

Clear with :match

5
  • 1
    @kenorb: You need to execute the :command! ... line. To make this permanent, put the line into your ~/.vimrc. Commented Nov 15, 2016 at 11:39
  • 1
    @kenorb: Oh, the default highlight group is missing: :hi link Match Search. either define that, or pass a custom {group} to the commands. Added that to the answer. Commented Nov 15, 2016 at 12:06
  • 1
    @kenorb: Ah, good catch; / needs to be escaped, too. See my edit. Commented Nov 15, 2016 at 12:38
  • I'm having trouble understanding how this works. Will it solve the following problem: if I type :'a,'bs/dog/cat/gc I'd like to just highlight the occurences of dog between 'a and 'b and not everywhere in the text. Seems like you are trying to do the same thing, but I don't know how to implement it. Thanks!
    – Leo Simon
    Commented Jan 11, 2017 at 0:00
  • @LeoSimon: No, this answer is about highlighting a whole set of lines; it just uses the trick of search highlighting to achieve that. What you want is difficult to achieve, as the search highlighting does not consider the range. You'd have to insert that limitation into the search pattern itself (via /\%>'a\%<'b.../), but that's impractical. Commented Jan 11, 2017 at 7:38
1

Currently I only know the following way by using multi-line match (\_.\{-}), e.g.:

/<head\_.\{-}\/head>

So basically the syntax is:

/pattern1\_.\{-}pattern2

The disadvantage of above method is that the range needs to be rewritten into search pattern, especially it's a trouble for more complex range patterns, as you've to change the syntax.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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