Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow decorations to be anchored to the end of lines #34441

Closed
DanTup opened this issue Sep 15, 2017 · 10 comments
Closed

Allow decorations to be anchored to the end of lines #34441

DanTup opened this issue Sep 15, 2017 · 10 comments
Assignees
Labels
api *question Issue represents a question, should be posted to StackOverflow (VS Code)
Milestone

Comments

@DanTup
Copy link
Contributor

DanTup commented Sep 15, 2017

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):

Dart Code 'closing labels'

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):

Typing behind the labels

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!

@alexdima
Copy link
Member

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.

@alexdima alexdima added the feature-request Request for new features or functionality label Sep 22, 2017
@alexdima alexdima added this to the On Deck milestone Sep 22, 2017
@DanTup
Copy link
Contributor Author

DanTup commented Sep 22, 2017

Do you think this is something that's likely to happen in the near future?

@alexdima
Copy link
Member

Yes, IMHO we need to address this.

@alexdima alexdima added the debt Code quality issues label Sep 22, 2017
@DanTup
Copy link
Contributor Author

DanTup commented 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? :/

Screenshot

@alexdima
Copy link
Member

After PR #36410, decorations in collapsed ranges will be correctly ignored.

@DanTup Have you tried experimenting with rangeBehavior: DecorationRangeBehavior for controlling the decorations stickiness ?

@eamodio
Copy link
Contributor

eamodio commented Oct 23, 2017

@alexandrudima is there any good documentation on that enum? I'm not sure I understand the values.

@DanTup
Copy link
Contributor Author

DanTup commented 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.

@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).

@alexdima
Copy link
Member

alexdima commented 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:

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?

@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,
}

@eamodio
Copy link
Contributor

eamodio commented Nov 14, 2017

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.

Originally from @mcarpenterjr @ gitkraken/vscode-gitlens#176 (comment)

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...
wooo

@DanTup
Copy link
Contributor Author

DanTup commented Nov 17, 2017

@alexandrudima

@DanTup Have you tried experimenting with rangeBehavior: DecorationRangeBehavior for controlling the decorations stickiness ?

Finally got round to this. Setting ClosedOpen does seem to stop the issue and so far I haven't found any negative side-effects :-)

@alexdima alexdima modified the milestones: On Deck, December 2017/January 2018 Dec 12, 2017
@alexdima alexdima added *question Issue represents a question, should be posted to StackOverflow (VS Code) api and removed feature-request Request for new features or functionality debt Code quality issues editor editor-core Editor basic functionality labels Dec 12, 2017
@vscodebot vscodebot bot locked and limited conversation to collaborators Jan 29, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api *question Issue represents a question, should be posted to StackOverflow (VS Code)
Projects
None yet
Development

No branches or pull requests

3 participants