1

Say that I want to highlight a region expressed in terms of two coordinates of the form (line, column), e.g. C1 = (l1, c1) to C2 = (l2, c2).

I read :h matchaddpos() but it seems that you can only specify entire lines or single characters to highlight, or you can express a range through starting position + length, which would lead to not very readable solutions, although the latest could be interesting as it would require the definition of a distance in the metric space built on the buffer’s coordinates set.

:h matchadd() requires a pattern but I am not sure how should I specify patterns for ranges expressed in terms of coordinates of the form (line, column).

3 Answers 3

1

To match from line 2 column 3 to line 4 column 5 (not included) you could use the following regular expression:

\%2l\%3c\_.*\%4l\%5c
  • \%2l match only on line 2
  • \%3c match only right before character 3
  • \_.* match any list of characters including new line

More information with:

  • :h /\%c
  • :h /\%l

You could then:

:call matchadd(group, '\%2l\%3c\_.*\%4l\%5c')

Where group is an highlighting group.

E.g:

:call matchadd("ErrorMsg", '\%2l\%3c\_.*\%4l\%5c')
5
  • Awesome! I'll take the regex as-is and I can understand what does it mean, but from a pedagogical standpoint it would be nice if you complete your answer by breaking down the regex explaining what each part does (possibly with reference to the :h pages) pages and finally showing how to apply it in the context of matchadd(). ;-)
    – Barzi2001
    May 28 at 17:38
  • 1
    Thanks for the feedback. I'll update the answer :-) May 28 at 17:51
  • 1
    Top! One small note: ErrorMsg should be quoted. ;-)
    – Barzi2001
    May 29 at 7:27
  • Thanks I couldn't test in front of the barbecue ;-) May 29 at 7:34
  • 1
    Ahahahah good one! I hope you enjoyed your bbq and had a great one! :D Thanks for your help! :)
    – Barzi2001
    May 29 at 7:35
3

You could use text properties, with the added benefit of not having to do as much bookkeeping to keep the highlight in place:

call prop_type_add('number', {'highlight': 'Constant'})
call prop_add(11, 12, #{type: 'number', end_lnum: 12, end_col: 13})
1

This could be a solution that, if on the one hand seems efficient due to the utilization of matchaddpos() instead of matchadd(), on the other hand it contains a number of for loops:

def BuildMatchPattern(l0: number, c0: number, l1: number, c1: number): list<any>
    # Say that we yanked from line 23, col 15 to line 26, col 19.
    # This function return the following list [[23, 15], 24, 25, [26, 19]]
    var match_pattern = []
    # Yank on one line
    if l0 == l1
        for c in range(c0, c1)
            add(match_pattern, [l0, c])
        endfor
    else
        # Yank on two consecutive lines
        # First line
        for c in range(c0, col('$'))
            add(match_pattern, [l0, c])
        endfor
        # Second line
        for c in range(1, c1)
            add(match_pattern, [l1, c])
        endfor
    endif

    # Yanked more than two lines (you must get the whole intermediate lines)
    if l1 - l0 >= 2
        for l in range(l0 + 1, l1 - 1)
            add(match_pattern, l)
        endfor
    endif
    return match_pattern
enddef

    matchaddpos('Visual', BuildMatchPattern(l0, c0, l1, c1))

Your Answer

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

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