You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow decorations to be anchored to the end of lines #34441
I'm using text editor decorations to annotate the closing brackets of nested constructs to improve code readability for things like Flutter widgets (these methods have lots of nested calls, similar to React render methods):
Originally I anchored the decorations to the closing bracket, but when multiple items ended on the same line it was strange to have the decorations inserted between the users characters. So I tweaked this to instead always anchor them at the last character of the line, and stack them up (they appear as // a // b // c).
It all generally works great, however because they're not actually anchored to the end of the line, but rather the character that happens to be at the end of the line, it's possible for the user to put the cursor behind the last character and type a new character, which appears after the decoration (for a brief period, until it gets updated by my code):
I don't think I can really fix this, unless Code had support for anchoring a decoration to the end of the line properly (without me just using the last character).
Is this something you'd consider? I appreciate I might not be using decorations for whatever it was designed for, but this feature has very positive feedback, I'd really like to make it work!
Inline decorations are currently implemented quite poorly at this time via CSS before and after selectors.
This is unfortunately one of the quirks that happens because of the poor implementation.
The only way out is to reimplement on our side how inline decorations work, such that they are part of the view rendering logic and not something plucked on top via before/after selectors.
alexandrudima Thanks, sounds promising! I had tried different values, however I think it was before anchoring at the end of the line - maybe now ClosedOpen will solve the issue (assuming putting the cursor after the last character on the line will result in insertions before the decoration). I'll try it out and post back.
Eric Amodio (@eamodio) The comment on the surrounding type is slightly better than the one on the enum:
Customize the growing behavior of the decoration when edits occur at the edges of the decoration's range. Defaults to DecorationRangeBehavior.OpenOpen.
I believe the idea is that when the cursor is at the edge of a decoration and the user types a new character, should the it become part of the range, or not (Closed means not, Open means it should - the enum names represent the start and end).
You can think of decorations as an interval over text, with their boundaries always between characters:
Hello |world|, how are you?
The decoration above would sit on top of world.
Decorations always have special cases when editing occurs precisely at their bounds. For example, when placing the cursor between d and , and typing x, should the decoration grow or should it stay put:
case 1: the decoration grows: Hello |worldx|, how are you?
case 2: the decoration stays put: Hello |world|x, how are you?
One way to think about it is that each boundary can "stick" to the character before or to the character after.
Turns out there are two cases for the start and two cases for the end of the decoration. Something like this:
case 1: Hello (world], how are you?
case 2: Hello (world), how are you?
case 3: Hello [world], how are you?
case 4: Hello [world), how are you?
Johannes Rieken (@jrieken) and I have struggled for a few tens of minutes to come up with good names for the enum values, we decided to go with these math-type open/close when we opened them up in the API (I think it was a PR that did the real work, we just renamed them) :
/**
* Describes the behavior of decorations when typing/editing at their edges.
*/
export enum DecorationRangeBehavior {
/**
* The decoration's range will widen when edits occur at the start or end.
*/
OpenOpen = 0,
/**
* The decoration's range will not widen when edits occur at the start of end.
*/
ClosedClosed = 1,
/**
* The decoration's range will widen when edits occur at the start, but not at the end.
*/
OpenClosed = 2,
/**
* The decoration's range will widen when edits occur at the end, but not at the start.
*/
ClosedOpen = 3
}
export enum TrackedRangeStickiness {
AlwaysGrowsWhenTypingAtEdges = 0,
NeverGrowsWhenTypingAtEdges = 1,
GrowsOnlyWhenTypingBefore = 2,
GrowsOnlyWhenTypingAfter = 3,
}
Reacted by Danny Tuppeny, Eric Amodio and Sean Poulter
I think this is another instance of this issue -- FYI GitLens does now specify DecorationRangeBehavior.ClosedClosed but it doesn't seem to have helped the issue.
Nope, it's the line annotations from gitlens, I have a better understanding of what's occuring now. It does happen at what seems like random so it's hard to capture the behavior through Peek to create a gif.
This occurs in CSS JS HTML and PHP files.
While coding the line annotation (the light gray entry that has the user's name time of last commit and the commit title) will appear, this forces the cursor to the end of the annotation, the annotation will then disappear just as quickly as it appeared but leave behind excessive white space. What I would assume is padding around the annotation.
In cases where the line is long and is approaching the softwrap bar, the annotation will actually ignore the softwrap and cause the workspace to scroll horizontally. What it seems like is occurring is the cursor is getting pushed into the great beyond past the softwrap and forces the view to scroll.
Also, I managed to get a partial instance of this occurring...
Activity
alexdima commentedon Sep 22, 2017
Inline decorations are currently implemented quite poorly at this time via CSS before and after selectors.
This is unfortunately one of the quirks that happens because of the poor implementation.
The only way out is to reimplement on our side how inline decorations work, such that they are part of the view rendering logic and not something plucked on top via before/after selectors.
DanTup commentedon Sep 22, 2017
Do you think this is something that's likely to happen in the near future?
alexdima commentedon Sep 22, 2017
Yes, IMHO we need to address this.
DanTup commentedon Oct 20, 2017
Different issue, but I suspect will be fixed together - decorations don't get hidden when you collapse the code they're in? :/
alexdima commentedon Oct 23, 2017
After PR #36410, decorations in collapsed ranges will be correctly ignored.
Danny Tuppeny (@DanTup) Have you tried experimenting with
rangeBehavior: DecorationRangeBehaviorfor controlling the decorations stickiness ?eamodio commentedon Oct 23, 2017
alexandrudima is there any good documentation on that enum? I'm not sure I understand the values.
DanTup commentedon Oct 23, 2017
alexandrudima Thanks, sounds promising! I had tried different values, however I think it was before anchoring at the end of the line - maybe now ClosedOpen will solve the issue (assuming putting the cursor after the last character on the line will result in insertions before the decoration). I'll try it out and post back.
Eric Amodio (@eamodio) The comment on the surrounding type is slightly better than the one on the enum:
I believe the idea is that when the cursor is at the edge of a decoration and the user types a new character, should the it become part of the range, or not (Closed means not, Open means it should - the enum names represent the start and end).
alexdima commentedon Oct 23, 2017
That enum maps its values to TrackedRangeStickiness
You can think of decorations as an interval over text, with their boundaries always between characters:
The decoration above would sit on top of
world.Decorations always have special cases when editing occurs precisely at their bounds. For example, when placing the cursor between
dand,and typingx, should the decoration grow or should it stay put:One way to think about it is that each boundary can "stick" to the character before or to the character after.
Turns out there are two cases for the start and two cases for the end of the decoration. Something like this:
Johannes Rieken (@jrieken) and I have struggled for a few tens of minutes to come up with good names for the enum values, we decided to go with these math-type open/close when we opened them up in the API (I think it was a PR that did the real work, we just renamed them) :
eamodio commentedon Nov 14, 2017
I think this is another instance of this issue -- FYI GitLens does now specify
DecorationRangeBehavior.ClosedClosedbut it doesn't seem to have helped the issue.Originally from Mark Carpenter Jr (@mcarpenterjr) @ gitkraken/vscode-gitlens#176 (comment)
DanTup commentedon Nov 17, 2017
alexandrudima
Finally got round to this. Setting ClosedOpen does seem to stop the issue and so far I haven't found any negative side-effects :-)