Skip to content

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

Closed

Description

@DanTup

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!

Activity

  1. alexdima commented on Sep 22, 2017

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

  2. DanTup commented on Sep 22, 2017

    @DanTup
    ContributorAuthor

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

  3. alexdima commented on Sep 22, 2017

    @alexdima
    Member

    Yes, IMHO we need to address this.

  4. DanTup commented on Oct 20, 2017

    @DanTup
    ContributorAuthor

    Different issue, but I suspect will be fixed together - decorations don't get hidden when you collapse the code they're in? :/

    Screenshot

  5. alexdima commented on Oct 23, 2017

    @alexdima
    Member

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

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

  6. eamodio commented on Oct 23, 2017

    @eamodio
    Contributor

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

  7. DanTup commented on Oct 23, 2017

    @DanTup
    ContributorAuthor

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

  8. alexdima commented on Oct 23, 2017

    @alexdima
    Member

    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?
    

    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,
    }
    
  9. eamodio commented on Nov 14, 2017

    @eamodio
    Contributor

    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 Mark Carpenter Jr (@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

  10. DanTup commented on Nov 17, 2017

    @DanTup
    ContributorAuthor

    alexandrudima

    Danny Tuppeny (@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 :-)

  11. modified the milestones: On Deck, on Dec 12, 2017
  12. added
    *questionIssue represents a question, should be posted to StackOverflow (VS Code)
    and removed
    feature-requestRequest for new features or functionality
    debtCode quality issues
    editor-coreEditor basic functionality
    on Dec 12, 2017
  13. locked and limited conversation to collaborators on Jan 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

*questionIssue represents a question, should be posted to StackOverflow (VS Code)api

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions