TextSegmentCollection - unexpected behaviour when replacing text #331
Labels
No labels
Area-Accessibility
Area-Build
Area-CodeCompletion
Area-Document
Area-Documentation
Area-Editing
Area-Folding
Area-Highlighting
Area-i18n
Area-Indentation
Area-NetFx
Area-Rendering
Area-Search
Area-Snippets
dependencies
duplicate
Feedback Needed
help wanted
invalid
Issue-Bug
Issue-Discussion
Issue-Enhancement
Issue-Performance
Issue-Question
on-hold
Resolution-Answered
Resolution-By Design
Resolution-Duplicate
Resolution-Fixed
Resolution-Won't Fix
Up-for-Grabs
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-icsharpcode/AvalonEdit#331
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
I've come across an issue which I suspect is caused by the internal implementation of
TextSegmentCollection.ReplaceText, specifically this sectiongithub.com/icsharpcode/AvalonEdit@47f61e9427/ICSharpCode.AvalonEdit/Document/TextSegmentCollection.cs (L200-L203)A segment gets removed from the collection, then manipulated, then re-added to the collection.
If there is any logic reacting to the in-between manipulation, it may behave unexpectedly, since the segment is not a member of the collection (at that time).
My problem were Segments (specifically TextMarkers) which got replaced in their entirety, but would claim not to be members of their corresponding collection during a
TextSegment.OnSegmentChangedinvocation, only to "magically" reappear during later calls (specifically redraws). See https://github.com/icsharpcode/AvalonEdit/discussions/327There may be some hacky ways to work around the problem (sadly there are no "added/removed" triggers for the segment collection.. and it's sealed...). One could post some handler via Dispatcher to "recheck" a segment... but that's... messy.
A clean solution to my mind would be adding
BeginChange()/EndChange()methods toTextSegment(similar to what exists forTextDocument) which suppress allOnSegmentChangedinvocations and rework theReplaceTextmethod to use those methods:That would defer any
OnSegmentChangedinvocation until the segment is once again in an expected state.See https://github.com/icsharpcode/AvalonEdit/discussions/327#discussioncomment-1873085 as GitHub does not add a reference to the discussion apparently.
For a prototype implementation of my suggested changes see
github.com/DoctorVanGogh/AvalonEdit@db4368916fIt keeps the "replace text" operation atomic in regards to any attached (overridden) logic on
TextSegment.OnSegmentChanged.Edit: Also created a unit test to show my failure case:
github.com/DoctorVanGogh/AvalonEdit@2834f6900a