matchaddpos(): a mini-review

293 views
Skip to first unread message

LCD 47

unread,
Jun 30, 2014, 9:41:14 AM6/30/14
to vim...@googlegroups.com
The initial motivation for adding the matchaddpos() function was
to speed up highlighting in syntastic, so I tried to make syntastic
actually use it where appropriate. As it turned out, that isn't really
feasible, partly because of the structure of syntastic (not relevant
on this list), but also partly because of what I claim to be a number
of flaws in the design of matchaddpos(). What follows are my (random)
thoughts on the matter.

First, the interface:

matchaddpos({group}, {pos}[, {priority}[, {id}]])

Here, {pos} is a list of lists. In principle this allows one to set a
number of highlight patterns at once; in practice, it means:

* call matchaddpos("group", [a]) - highlights line a
* call matchaddpos("group", [[a]]) - also highlights line a
* call matchaddpos("group", [a, b]) - highlights lines a and b
* call matchaddpos("group", [[a, b]]) - highlights one byte at position (a, b)
* call matchaddpos("group", [[a, b, c]]) - highlights c bytes at position (a, b)

This is (1) ugly, (2) inconsistent with matchadd(), which can only
handle one pattern at a time, (3) it adds an artificial limitation to
8 patterns per call, and (4) it doesn't offer any simple replacement
for matchadd("group", '\m\%5c') (that is highlighting columns, top
to bottom). Perhaps a better choice would have been to make {pos} a
dictionary (or a list of such, if you absolutely can't help it), with
all elements optional, like this:

{ 'line': 3, 'col': 5, 'len': 2 }

Back to {pos}: the column number is a byte offset. Since there
are no standard functions to convert between screen columns and
byte offsets, this means one gets the pleasure to deal with tabs,
multi-byte strings, concealed characters, and the like. If {pos} were a
dictionary, as suggested above, handling virtual columns could be added
with a 'vcol' field (again, optional). Please note that matchadd()
handles things like '\%5v' just fine.

Then, the lengths is a byte count. This means that if the character
at the beginning of a highlight happens to be multi-byte and the length
is 1, the line is highlighted to the end. I believe this is a bug.
Again, matchadd() handles this situation gracefully.

Then, getmatches() returns both matchadd() patterns and
matchaddpos() patterns, but setmatches() can only handle old-style
matchadd() patterns. This means it's no longer possible to use
getmatches() and setmatches() to save and restore patterns. I suppose
this could be fixed, by making setmatches() look at patterns it has to
restore: the ones that have a 'pattern' are matchadd() patterns, the
ones that have 'pos1' and friends are matchaddpos() patterns.

Last but not least: is there any reason why this is a separate
function, instead of an optimisation inside matchadd()? There are
a finite number of common fixed position patterns, so it should be
possible to just look at the patterns passed to matchadd(), and treat
them specially if they involve only fixed positions. It's really,
really much more of a pain to leave this to end the user.

/lcd

Bram Moolenaar

unread,
Jul 1, 2014, 11:43:26 AM7/1/14
to LCD 47, vim...@googlegroups.com

lcd wrote:

> The initial motivation for adding the matchaddpos() function was
> to speed up highlighting in syntastic, so I tried to make syntastic
> actually use it where appropriate. As it turned out, that isn't really
> feasible, partly because of the structure of syntastic (not relevant
> on this list), but also partly because of what I claim to be a number
> of flaws in the design of matchaddpos(). What follows are my (random)
> thoughts on the matter.

I thought the original reason was to speed up highlighting matches with
the matchparen plugin. But that doesn't matter.

> First, the interface:
>
> matchaddpos({group}, {pos}[, {priority}[, {id}]])
>
> Here, {pos} is a list of lists. In principle this allows one to set a
> number of highlight patterns at once; in practice, it means:
>
> * call matchaddpos("group", [a]) - highlights line a
> * call matchaddpos("group", [[a]]) - also highlights line a
> * call matchaddpos("group", [a, b]) - highlights lines a and b
> * call matchaddpos("group", [[a, b]]) - highlights one byte at position (a, b)
> * call matchaddpos("group", [[a, b, c]]) - highlights c bytes at position (a, b)
>
> This is (1) ugly, (2) inconsistent with matchadd(), which can only
> handle one pattern at a time, (3) it adds an artificial limitation to
> 8 patterns per call, and (4) it doesn't offer any simple replacement
> for matchadd("group", '\m\%5c') (that is highlighting columns, top
> to bottom). Perhaps a better choice would have been to make {pos} a
> dictionary (or a list of such, if you absolutely can't help it), with
> all elements optional, like this:
>
> { 'line': 3, 'col': 5, 'len': 2 }

The main thing was to highlight one or a few characters at a fixed
position in the text. Such as a parenthesis. Text is usually located
by byte index, not character index, since it's quicker.

Being able to highlight a whole line was added by the implementor and
comes almost for free. Being able to highlight a column would be much
more difficult and also less efficient, since it requires updating many
screen lines when a change is made. Might as well keep using the old
way for that.

The syntax is a bit strange, that's true.

The limit of 8 makes the implementation simpler, and I can't think of a
reason why someone would want to highlight more than 2 or 3 matches,
thus 8 seems like it's sufficient.

> Back to {pos}: the column number is a byte offset. Since there
> are no standard functions to convert between screen columns and
> byte offsets, this means one gets the pleasure to deal with tabs,
> multi-byte strings, concealed characters, and the like. If {pos} were a
> dictionary, as suggested above, handling virtual columns could be added
> with a 'vcol' field (again, optional). Please note that matchadd()
> handles things like '\%5v' just fine.

Is there a problem with using virtcol() before passing the position to
matchaddpos()? Passing the screen column makes things much more
complicatet, but it would be possible.

> Then, the lengths is a byte count. This means that if the character
> at the beginning of a highlight happens to be multi-byte and the length
> is 1, the line is highlighted to the end. I believe this is a bug.
> Again, matchadd() handles this situation gracefully.

That's a bug.

> Then, getmatches() returns both matchadd() patterns and
> matchaddpos() patterns, but setmatches() can only handle old-style
> matchadd() patterns. This means it's no longer possible to use
> getmatches() and setmatches() to save and restore patterns. I suppose
> this could be fixed, by making setmatches() look at patterns it has to
> restore: the ones that have a 'pattern' are matchadd() patterns, the
> ones that have 'pos1' and friends are matchaddpos() patterns.

That should be fixed.

> Last but not least: is there any reason why this is a separate
> function, instead of an optimisation inside matchadd()? There are
> a finite number of common fixed position patterns, so it should be
> possible to just look at the patterns passed to matchadd(), and treat
> them specially if they involve only fixed positions. It's really,
> really much more of a pain to leave this to end the user.

Parsing the pattern is difficult, and for a script writer creating the
pattern is a hassle. Passing the position with numbers is much simpler
on both sides.

--
"Hegel was right when he said that we learn from history that man can
never learn anything from history." (George Bernard Shaw)

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

LCD 47

unread,
Jul 1, 2014, 1:54:06 PM7/1/14
to vim...@googlegroups.com
On 1 July 2014, Bram Moolenaar <Br...@moolenaar.net> wrote:
> lcd wrote:
[...]
> > First, the interface:
> >
> > matchaddpos({group}, {pos}[, {priority}[, {id}]])
> >
> > Here, {pos} is a list of lists. In principle this allows one to set
> > a number of highlight patterns at once; in practice, it means:
> >
> > * call matchaddpos("group", [a]) - highlights line a
> > * call matchaddpos("group", [[a]]) - also highlights line a
> > * call matchaddpos("group", [a, b]) - highlights lines a and b
> > * call matchaddpos("group", [[a, b]]) - highlights one byte at position (a, b)
> > * call matchaddpos("group", [[a, b, c]]) - highlights c bytes at position (a, b)
> >
> > This is (1) ugly, (2) inconsistent with matchadd(), which
> > can only handle one pattern at a time, (3) it adds an artificial
> > limitation to 8 patterns per call, and (4) it doesn't offer any
> > simple replacement for matchadd("group", '\m\%5c') (that is
> > highlighting columns, top to bottom). Perhaps a better choice would
> > have been to make {pos} a dictionary (or a list of such, if you
> > absolutely can't help it), with all elements optional, like this:
> >
> > { 'line': 3, 'col': 5, 'len': 2 }
>
> The main thing was to highlight one or a few characters at a fixed
> position in the text. Such as a parenthesis. Text is usually located
> by byte index, not character index, since it's quicker.

True -- unless the column number comes from somewhere else, such as
a compiler's error message. Sometimes you don't get to choose.

[...]
> The limit of 8 makes the implementation simpler, and I can't think of
> a reason why someone would want to highlight more than 2 or 3 matches,
> thus 8 seems like it's sufficient.

So what? Once part of Vim, matchaddpos() is just another function,
two weeks from now nobody will remember why it was added. Sooner or
later somebody will find a creative way to abuse it, and will find
himself banging his head against the desk because of this limitation.
And in this particular case it's a limitation that could have been
avoided basically for free. *shrug*

> > Back to {pos}: the column number is a byte offset. Since there
> > are no standard functions to convert between screen columns and
> > byte offsets, this means one gets the pleasure to deal with tabs,
> > multi-byte strings, concealed characters, and the like. If {pos}
> > were a dictionary, as suggested above, handling virtual columns
> > could be added with a 'vcol' field (again, optional). Please note
> > that matchadd() handles things like '\%5v' just fine.
>
> Is there a problem with using virtcol() before passing the position
> to matchaddpos()? Passing the screen column makes things much more
> complicatet, but it would be possible.

The problem with virtcol() (and most similar functions, for that
matter) is that it isn't independent of the surrounding context.
It requires either the cursor, or a mark to be set to the position
you care about. In a script this is horribly intrusive: I have to
save either the cursor or a mark, set things up for virtcol(), find
out the position, then restore the cursor or mark. I just want to
convert between screen columns and byte offsets, dammit! It's a length
calculation, why on Earth should I care where the cursor and / or the
marks are?

[...]
> > Last but not least: is there any reason why this is a separate
> > function, instead of an optimisation inside matchadd()? There are
> > a finite number of common fixed position patterns, so it should be
> > possible to just look at the patterns passed to matchadd(), and
> > treat them specially if they involve only fixed positions. It's
> > really, really much more of a pain to leave this to end the user.
>
> Parsing the pattern is difficult, and for a script writer creating
> the pattern is a hassle. Passing the position with numbers is much
> simpler on both sides.

It's simpler in simple contexts. In more complicated contexts it's
less useful, because it plays by very different rules than matchadd().

/lcd

Christian Brabandt

unread,
Jul 1, 2014, 2:00:32 PM7/1/14
to vim...@googlegroups.com
Hi

Disclaimer: I haven't looked into matchaddpo() yet, but plan to use it in several
plugins I maintain.
It isn't. Off the top of my mind, I could think of those situations:
- Highlight marks
- Highlight quickfix items (the syntastic use case)
- highlight changes of the buffer (by keeping track of the '[ and ']
marks). This doesn't work perfectly, since those marks are way too
often reset when editing a buffer, but could still be useful.
Almost all of them could grow easily beyond 8, I think.

BTW: what happens to the highlighting after one changes the buffer? E.g.
if I add a matchaddpos() at line 5, column 5 and afterwards add a line
below 3, will then line 6, column 5 be highlighted or line 5? Both could
be useful, I suppose...

Best,
Christian
--
Wenn wir keine Fehler hätten, würden wir nicht mit so großem
Vergnügen Fehler bei anderen entdecken.
-- François de La Rochefoucauld

Павлов Николай Александрович

unread,
Jul 1, 2014, 2:14:06 PM7/1/14
to vim...@googlegroups.com, LCD 47
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
virtcol() does accept lists (line and column pairs).

>you care about. In a script this is horribly intrusive: I have to
>save either the cursor or a mark, set things up for virtcol(), find
>out the position, then restore the cursor or mark. I just want to
>convert between screen columns and byte offsets, dammit! It's a length

virtcol([linenr, col]) will do. The opposite conversion (screen column to byte index) is much more complicated.

>calculation, why on Earth should I care where the cursor and / or the
>marks are?

You should not care. You should read documentation.

>
>[...]
>> > Last but not least: is there any reason why this is a separate
>> > function, instead of an optimisation inside matchadd()? There are
>> > a finite number of common fixed position patterns, so it should be
>> > possible to just look at the patterns passed to matchadd(), and
>> > treat them specially if they involve only fixed positions. It's
>> > really, really much more of a pain to leave this to end the user.
>>
>> Parsing the pattern is difficult, and for a script writer creating
>> the pattern is a hassle. Passing the position with numbers is much
>> simpler on both sides.
>
> It's simpler in simple contexts. In more complicated contexts it's
>less useful, because it plays by very different rules than matchadd().
>
> /lcd
-----BEGIN PGP SIGNATURE-----
Version: APG v1.1.1

iQI1BAEBCgAfBQJTsvpiGBxaeVggPHp5eC52aW1AZ21haWwuY29tPgAKCRCf3UKj
HhHSvsIxD/9epkAOLmd7uYuuZoFu72i9904UjwMdRhPRUzXh6M2UQlEKB1MWxVNZ
HlgELFYX70g8fFrVrxZgWm77UCq8ON7SzUyZf11z4hxygUFoOm3Fr2F1WBvrB0jn
292G0N4F1nIpcqWvdnLbcS0PHPL9Ykv00wuAGt/hLRIO1jDjCUExlaumIotOxzW5
x0TmGrD54coe+e1CEugnnu80W/yoFHOymlBlfXPm+373cO1BB2zYSZMts8ZJxo9p
R8c7TQHyQ7fGYGU8guUIwLsWkele0h5LGJ8+h8+u53hqlGqx5pQfrZpGoG4AMFZQ
+s96UE21w78L0dDjaFnYAo75Ehx0FL66z/eDxgVPhu8FUJMb/UmcpWUACv3xIR8J
pYsGNvobbP7Wx807TKzgsOVA0fdtjkTRasjnqfIKZc/6E6GVS56SrnsB02EEO+xv
//NczJdBNTcOzRv1HqKmpynVczGqsYX/FEAWQOxZ+X8NvqDQwM9phhHy6Q0DvCrv
3AU8jHjUwwnt1gJ4FlOBnv+iTDdq30zXU4SKC7fWgP3FmOxPGWUBgQoTXckDWAj7
NJvR2f7Z/sVOe7oGqcFFLexmzqRjbUxfWquqCeL/iDcHfb89mZypkuZtxIhn/pnq
Be5Ot5DxrgK5NHgydta2AbpCtrQSM7Zzcsfas/SrX5HKP5j+MY5iAQ==
=+pXF
-----END PGP SIGNATURE-----

LCD 47

unread,
Jul 1, 2014, 2:42:23 PM7/1/14
to vim...@googlegroups.com
On 1 July 2014, Павлов Николай Александрович
<zyx...@gmail.com> wrote:
> On July 1, 2014 9:54:00 PM GMT+03:00, LCD 47 <lcd...@gmail.com> wrote:
[...]
> > The problem with virtcol() (and most similar functions, for that
> >matter) is that it isn't independent of the surrounding context. It
> >requires either the cursor, or a mark to be set to the position
>
> virtcol() does accept lists (line and column pairs).

Well, somehow I managed to overlook this for years. Thank you for
enlightening me, I suppose I'm too old to be allowed around Vim code
these days.

> >you care about. In a script this is horribly intrusive: I have to
> >save either the cursor or a mark, set things up for virtcol(), find
> >out the position, then restore the cursor or mark. I just want to
> >convert between screen columns and byte offsets, dammit! It's a
> >length
>
> virtcol([linenr, col]) will do. The opposite conversion (screen column
> to byte index) is much more complicated.

Of course, you're right: virtcol() is useless in the context of the
initial discussion, you need to convert coordinates the other way around
to translate a '\%...v' for matchaddpos().

> >calculation, why on Earth should I care where the cursor and / or the
> >marks are?
>
> You should not care. You should read documentation.

You think so? After all, I managed to find out about the cursor and
marks using my ESP abilities. ;)

/lcd

LCD 47

unread,
Jul 1, 2014, 2:51:29 PM7/1/14
to vim...@googlegroups.com
On 1 July 2014, Christian Brabandt <cbl...@256bit.org> wrote:
[...]
> BTW: what happens to the highlighting after one changes the
> buffer? E.g. if I add a matchaddpos() at line 5, column 5 and
> afterwards add a line below 3, will then line 6, column 5 be
> highlighted or line 5? Both could be useful, I suppose...

As it is now, the highlight stays at line 5, column 5. I think
there was a recent patch to make it move along with the text it
highlights (which would be a lot more useful, IMO).

/lcd

Alexey Radkov

unread,
Jul 1, 2014, 3:01:39 PM7/1/14
to vim_dev
I wonder how could it be implemented (just thought to add this functionality to matchaddpos())?

Imagine situation: you add a match at line 5, then delete the whole line 5 (rdeletee this match now or store somewhere?), then make undo (returning back that line 5). Will the match be restored? If so then we should track all history of buffer change, in other words we have to implement semantical binding between match and buffer, whereas now its technically bound to a simple number.


    /lcd

--
--
You received this message from the "vim_dev" 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_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

LCD 47

unread,
Jul 1, 2014, 3:16:24 PM7/1/14
to vim_dev
On 1 July 2014, Alexey Radkov <alexey...@gmail.com> wrote:
> 2014-07-01 22:51 GMT+04:00 LCD 47 <lcd...@gmail.com>:
> > On 1 July 2014, Christian Brabandt <cbl...@256bit.org> wrote:
> [...]
> > > BTW: what happens to the highlighting after one changes the
> > > buffer? E.g. if I add a matchaddpos() at line 5, column 5 and
> > > afterwards add a line below 3, will then line 6, column 5 be
> > > highlighted or line 5? Both could be useful, I suppose...
> >
> > As it is now, the highlight stays at line 5, column 5. I think
> > there was a recent patch to make it move along with the text it
> > highlights (which would be a lot more useful, IMO).
> >
>
> I wonder how could it be implemented (just thought to add this
> functionality to matchaddpos())?
>
> Imagine situation: you add a match at line 5, then delete the whole
> line 5 (rdeletee this match now or store somewhere?), then make undo
> (returning back that line 5). Will the match be restored?

Yes, I'd say it should be restored.

> If so then we should track all history of buffer change, in other
> words we have to implement semantical binding between match and
> buffer, whereas now its technically bound to a simple number.

How about adding highlighting adds / removals to the undo list.
That way, when you delete line 5, the highlights on line 5 would be
deleted and the operation written to undo stack, then line 5 would be
deleted, and the operation written to the undo stack. When you undo
the operation first the line would be restored from the stack, then the
highlights. No need to track anything.

/lcd

Alexey Radkov

unread,
Jul 2, 2014, 4:13:21 AM7/2/14
to vim_dev
Hi Christian.

Number 8 is not a "global" limitation. This is limited number of positions that one call to matchaddpos() may use simultaneously. You can use multiple matchaddpos() to highlight as many positions as you want. This "compound" multi-positions design was chosen to emulate old matchparens regexp for 3match that declared two positions combined with \|. In principle 2 max "compound" positions were enough for that.

The whole matchaddpos() was implemented with matchparen plugin and fast parens highlight in mind hence those "flaws" in its design which make its using not convenient for other plugins. Probably it could 1. be renamed to matchparen() to prevent from giving it too many hopes, or (better?) 2. keep its current name but fix all those "flaws" in it.


BTW: what happens to the highlighting after one changes the buffer? E.g.
if I add a matchaddpos() at line 5, column 5 and afterwards add a line
below 3, will then line 6, column 5 be highlighted or line 5? Both could
be useful, I suppose...

In principle it could be implemented, but ... It's not required by matchparen plugin. If we chose 2nd way from my previous comment then implementation of this would make sense and benefit.


Best,
Christian
--
Wenn wir keine Fehler hätten, würden wir nicht mit so großem
Vergnügen Fehler bei anderen entdecken.
                -- François de La Rochefoucauld
--
--
You received this message from the "vim_dev" 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_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Cheers, Alexey.

Bram Moolenaar

unread,
Jul 2, 2014, 7:37:29 AM7/2/14
to LCD 47, vim...@googlegroups.com
No, the position is fixed.

I'm not sure how useful it is to adjust the positions for
inserted/deleted lines. First of all, if the text is changed, the
positions may be invalid anyway, e.g., when highlighting () pairs
inserting/deleting a ( or ) requires updating the positions.
And keeping the column updated when inserting/deleting characters is
very complicated, it's not even done for marks.

Better just make clear the position is fixed and the script writer will
have to handle text changes.

--
No letters of the alphabet were harmed in the creation of this message.

LCD 47

unread,
Jul 2, 2014, 9:39:45 AM7/2/14
to vim...@googlegroups.com
On 2 July 2014, Bram Moolenaar <Br...@moolenaar.net> wrote:
>
> Lcd wrote:
>
> > On 1 July 2014, Christian Brabandt <cbl...@256bit.org> wrote:
> > [...]
> > > BTW: what happens to the highlighting after one changes the
> > > buffer? E.g. if I add a matchaddpos() at line 5, column 5 and
> > > afterwards add a line below 3, will then line 6, column 5 be
> > > highlighted or line 5? Both could be useful, I suppose...
> >
> > As it is now, the highlight stays at line 5, column 5. I think
> > there was a recent patch to make it move along with the text it
> > highlights (which would be a lot more useful, IMO).
>
> No, the position is fixed.
>
> I'm not sure how useful it is to adjust the positions for
> inserted/deleted lines.
[...]

Still, leaving phantom highlights behind is annoying, and definitely
not useful. Can we at least have an option to remove the highlight when
it becomes invalid? This situation is a pain to detect in a script, and
it should be much easier to deal with at the source.

/lcd

Павлов Николай Александрович

unread,
Jul 4, 2014, 11:28:22 AM7/4/14
to vim...@googlegroups.com, LCD 47
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

On July 1, 2014 9:54:00 PM GMT+03:00, LCD 47 <lcd...@gmail.com> wrote:
*Virtual* column number? Compiler author must be crazy to write this, and as explained in the other thread (with a new patch for matchaddpos() to support screen cells) it is incorrect to blindly use it without setting settings to exactly those of the compiler.

Can you please read that thread and explain whether and why you needed screen cells? I have a discussion there with an explanation why screen cells are inappropriate for matchaddpos(). OP was saying that you requested it, but I do not see why.
-----BEGIN PGP SIGNATURE-----
Version: APG v1.1.1

iQI1BAEBCgAfBQJTtsgLGBxaeVggPHp5eC52aW1AZ21haWwuY29tPgAKCRCf3UKj
HhHSvvDAD/4hDK2LgDnx9E+Cdju2R9XlcGP8mofbBq6boOcrnEy/PrEfsINP5LkT
qXnmCqwDDXMxf9/YduaGfZAbMyVUSILFqDntN0LoM2kH/k0pIpXyKmoA9NzWz0RU
ZIpAqd5cPC1pnW2PH8j73l1Lb7JXorAVBnzGa2By2fZZQ0rirS+jnFcn+OaTz9c/
Sc/LuizcLIROLPYs6Rv2my9BfqkCfkByZDx+XBTgpYxr4W7w4E/NEI9sJDpr72Lp
4+YRSloXTSyrbqYFoa27Og4GXtGgjRl3YKbY0C45YssaJkpsTWt91P3VHBaLY6/h
u9P9t7XtaeToQyI6BJAFIKj9oXeM8FT/wKiDPEkmirkprf/ulEF0rYBKrymQP8WL
QGW5l6UjnwxkH2+cuT2gkf6S8R4mw8Mwds728idk9pOE+boG2eg+EO5kkTt64TXS
VwfGVtrvNEe3VpEbJlHRTAYLKPrfHOkXPcZgyApORM1G6za0Lt4elwC6ePECJ/Uh
LjXkXKX535xBvE8K0nv/k8cSntfSy+2gDEfZZhubU6SnUzKWwV0Ry5ylOZIXOIf7
yinw3hz7VAtKP+fsKuOjORn1EvCo1bA4uVhS0Khl6855zgT2/+RA3yhtEFmHHlT9
LdL62x8XnDj7q8ONUwt9cTWCPfIu2BmzL5xjdkHzmVrwKLIdNHvYwQ==
=ywVE
-----END PGP SIGNATURE-----

LCD 47

unread,
Jul 4, 2014, 12:48:43 PM7/4/14
to vim...@googlegroups.com
On 4 July 2014, Павлов Николай Александрович
<zyx...@gmail.com> wrote:
> On July 1, 2014 9:54:00 PM GMT+03:00, LCD 47 <lcd...@gmail.com> wrote:
> >On 1 July 2014, Bram Moolenaar <Br...@moolenaar.net> wrote:
> >> The main thing was to highlight one or a few characters at a fixed
> >> position in the text. Such as a parenthesis. Text is usually
> >> located by byte index, not character index, since it's quicker.
> >
> > True -- unless the column number comes from somewhere else, such
> >as a compiler's error message. Sometimes you don't get to choose.
>
> *Virtual* column number?

Yes.

> Compiler author must be crazy to write this, and as explained in the
> other thread (with a new patch for matchaddpos() to support screen
> cells) it is incorrect to blindly use it without setting settings to
> exactly those of the compiler.

I agree 100% that it's broken. They still do it.

For what it's worth, I had to look at the sources at many of said
compilers to get syntastic to understand their output, and using virtual
columns isn't *that* far fetched. Most of the time they just expand
tabs while parsing and don't bother keeping track of the original
offset. When they run into an error they just compute the column number
by adding the lengths of the whitespace and the tokens parsed so far.

Double width characters is a different story. Some compilers use
Unicode codepoints, others byte length, which is, again, broken. Still,
Vim's virtual columns is yet the best approximation of it.

> Can you please read that thread and explain whether and why you needed
> screen cells? I have a discussion there with an explanation why screen
> cells are inappropriate for matchaddpos(). OP was saying that you
> requested it, but I do not see why.

It might be needed because (1) some compilers *do* produce error
messages in virtual columns, and (2) if you get an offset in virtual
columns you *can't* translate it to a byte offset to feed matchaddpos(),
as you pointed out in a previous message (not with a reasonable effort
that is).

/lcd

ZyX

unread,
Jul 4, 2014, 1:34:15 PM7/4/14
to vim...@googlegroups.com
> I agree 100% that it's broken. They still do it.
>
> For what it's worth, I had to look at the sources at many of said
> compilers to get syntastic to understand their output, and using virtual
> columns isn't *that* far fetched. Most of the time they just expand
> tabs while parsing and don't bother keeping track of the original
> offset. When they run into an error they just compute the column number
> by adding the lengths of the whitespace and the tokens parsed so far.
>
> Double width characters is a different story. Some compilers use
> Unicode codepoints, others byte length, which is, again, broken. Still,
> Vim's virtual columns is yet the best approximation of it.

I think the best solution is proposed colnr() function: check out [that thread][1]. virtcol to byte offset transformation is useful not only for matchaddpos(). I had to write it in [translit3][2] and that variant is rather slow. Your proposal will fix matchaddpos() for one given use-case and only matchaddpos() and only under very limited conditions. colnr() is not so limited.

I say that you are seeking answer in a wrong direction.

[1]: https://groups.google.com/forum/#!topic/vim_dev/2DYfyTuo7G0
[2]: https://sourceforge.net/p/translit3/code/ci/040e92e8021320740109067dbe2fb43e50fbba94/tree/autoload/translit3.vim#l2262

LCD 47

unread,
Jul 6, 2014, 10:27:34 AM7/6/14
to vim...@googlegroups.com
On 4 July 2014, ZyX <zyx...@gmail.com> wrote:
> > I agree 100% that it's broken. They still do it.
> >
> > For what it's worth, I had to look at the sources at many of
> > said compilers to get syntastic to understand their output, and
> > using virtual columns isn't *that* far fetched. Most of the time
> > they just expand tabs while parsing and don't bother keeping track
> > of the original offset. When they run into an error they just
> > compute the column number by adding the lengths of the whitespace
> > and the tokens parsed so far.
> >
> > Double width characters is a different story. Some compilers
> > use Unicode codepoints, others byte length, which is, again, broken.
> > Still, Vim's virtual columns is yet the best approximation of it.
>
> I think the best solution is proposed colnr() function: check out
> [that thread][1]. virtcol to byte offset transformation is useful not
> only for matchaddpos().

Yes, a colnr() function would be useful, both in this situation and
by itself.

> I had to write it in [translit3][2] and that variant is rather
> slow. Your proposal will fix matchaddpos() for one given use-case and
> only matchaddpos() and only under very limited conditions. colnr() is
> not so limited.

I'm afraid you lost me here. I just pointed out a number of (what I
consider to be) problems with the design of matchaddpos(), which I found
when I actually tried to use the function. I never attempetd to suggest
any solutions.

Your colnr() might be, IMO, a reasonable solution for one of the
problems I noted. It doesn't address any of the others.
/lcd

Павлов Николай Александрович

unread,
Jul 6, 2014, 4:00:28 PM7/6/14
to vim...@googlegroups.com, LCD 47
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Absence of some colnr() features is not only a matchaddpos() problem. It is helpful for one of matchaddpos() problems you pointed out, but it is not the only scope where this function is useful. Fix to matchaddpos() to accept dictionary with vcol, on the other side, is only useful for matchaddpos().
-----BEGIN PGP SIGNATURE-----
Version: APG v1.1.1

iQI1BAEBCgAfBQJTuarNGBxaeVggPHp5eC52aW1AZ21haWwuY29tPgAKCRCf3UKj
HhHSvh1LD/wN4veq+vWKGR/XlGFqy03o9HEee2Zw807fv8/zBuhvfHFdXoNHb+FV
B4ZtaUEeEofrWorr2RxLQQ8Z8N7rHfLyz9zjUbXzCBqF/KPYACKW2sdXYXKi5nTI
lNHku1O6ohe3/WzrcXD5/vjiXNNhqIbzU9+Xoq5Kr43MzHphsQAp38CUgcni78Rd
qXaOllrN/ep2I6gBKCeQ4xCjvoNBLT8+ef1eci9yaDR7W4ry+DybRpzx2P1n2BNl
PwsSS+tDH45hjgr6huCMftYsZJRONM5te7FQRW+GEIhL3fmbeKL3imhCtsZAP+2M
5TwrIzRGyg/9JzUawwDa0W1EJ6BUvL6h57tGb/hV605XU+z5/NdL2mEgpc1BNbtu
7kPSDMKPxJJPD5NcGl2x6Syg7GxUrdXDXUfwrrx9wzEYoz0NsoBgI2QsCVZz7061
qQRBpXkVEVcM1abEA7dMVuF5giN5U86IHW8w0Xd4mdOLY4yLisPgA1m0iFCDHatt
ykOtm4sB6N9FTWP9QuFclvL0hyB/j9FyTl72fCduxfZPIR+PaJKrshcbNXslXE4e
qgw5g7wH/yryEjidja3RAyWkVc7McUsEKjgz6Y+Gl1/Tenjibyo8LoP1nBhlhBDl
cqcYvTOOtB5APUMMn4ZodsPxoT8qWGnGQGwZzfVHcb+mGeza82Vchw==
=D961
-----END PGP SIGNATURE-----

Reply all
Reply to author
Forward
0 new messages