@@ -15,6 +15,15 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
15
15
/// </summary>
16
16
public partial class RichSuggestBox
17
17
{
18
+ private void CreateSingleEdit ( Action editAction )
19
+ {
20
+ _ignoreChange = true ;
21
+ editAction . Invoke ( ) ;
22
+ TextDocument . EndUndoGroup ( ) ;
23
+ TextDocument . BeginUndoGroup ( ) ;
24
+ _ignoreChange = false ;
25
+ }
26
+
18
27
private void ExpandSelectionOnPartialTokenSelect ( ITextSelection selection , ITextRange tokenRange )
19
28
{
20
29
switch ( selection . Type )
@@ -82,47 +91,11 @@ private void InvokeTokenPointerOver(PointerPoint pointer)
82
91
}
83
92
}
84
93
85
- private bool TryCommitSuggestionIntoDocument ( ITextRange range , string displayText , Guid id , ITextCharacterFormat format , bool addTrailingSpace = true )
86
- {
87
- // We don't want to set text when the display text doesn't change since it may lead to unexpected caret move.
88
- range . GetText ( TextGetOptions . NoHidden , out var existingText ) ;
89
- if ( existingText != displayText )
90
- {
91
- range . SetText ( TextSetOptions . Unhide , displayText ) ;
92
- }
93
-
94
- var formatBefore = range . CharacterFormat . GetClone ( ) ;
95
- range . CharacterFormat . SetClone ( format ) ;
96
- PadRange ( range , formatBefore ) ;
97
- range . Link = $ "\" { id } \" ";
98
-
99
- // In some rare case, setting Link can fail. Only observed when interacting with Undo/Redo feature.
100
- if ( range . Link != $ "\" { id } \" ")
101
- {
102
- range . Delete ( TextRangeUnit . Story , - 1 ) ;
103
- return false ;
104
- }
105
-
106
- if ( addTrailingSpace )
107
- {
108
- var clone = range . GetClone ( ) ;
109
- clone . Collapse ( false ) ;
110
- clone . SetText ( TextSetOptions . Unhide , " " ) ;
111
- clone . Collapse ( false ) ;
112
- TextDocument . Selection . SetRange ( clone . EndPosition , clone . EndPosition ) ;
113
- }
114
-
115
- return true ;
116
- }
117
-
118
94
private void ValidateTokensInDocument ( )
119
95
{
120
- lock ( _tokensLock )
96
+ foreach ( var ( _ , token ) in _tokens )
121
97
{
122
- foreach ( var ( _, token ) in _tokens )
123
- {
124
- token . Active = false ;
125
- }
98
+ token . Active = false ;
126
99
}
127
100
128
101
ForEachLinkInDocument ( TextDocument , ValidateTokenFromRange ) ;
@@ -138,18 +111,15 @@ private void ValidateTokenFromRange(ITextRange range)
138
111
// Check for duplicate tokens. This can happen if the user copies and pastes the token multiple times.
139
112
if ( token . Active && token . RangeStart != range . StartPosition && token . RangeEnd != range . EndPosition )
140
113
{
141
- lock ( _tokensLock )
114
+ var guid = Guid . NewGuid ( ) ;
115
+ if ( TryCommitSuggestionIntoDocument ( range , token . DisplayText , guid , CreateTokenFormat ( range ) , false ) )
142
116
{
143
- var guid = Guid . NewGuid ( ) ;
144
- if ( TryCommitSuggestionIntoDocument ( range , token . DisplayText , guid , CreateTokenFormat ( range ) , false ) )
145
- {
146
- token = new RichSuggestToken ( guid , token . DisplayText ) { Active = true , Item = token . Item } ;
147
- token . UpdateTextRange ( range ) ;
148
- _tokens . Add ( range . Link , token ) ;
149
- }
150
-
151
- return ;
117
+ token = new RichSuggestToken ( guid , token . DisplayText ) { Active = true , Item = token . Item } ;
118
+ token . UpdateTextRange ( range ) ;
119
+ _tokens . Add ( range . Link , token ) ;
152
120
}
121
+
122
+ return ;
153
123
}
154
124
155
125
if ( token . ToString ( ) != range . Text )
@@ -163,6 +133,39 @@ private void ValidateTokenFromRange(ITextRange range)
163
133
token . Active = true ;
164
134
}
165
135
136
+ private bool TryCommitSuggestionIntoDocument ( ITextRange range , string displayText , Guid id , ITextCharacterFormat format , bool addTrailingSpace )
137
+ {
138
+ // We don't want to set text when the display text doesn't change since it may lead to unexpected caret move.
139
+ range . GetText ( TextGetOptions . NoHidden , out var existingText ) ;
140
+ if ( existingText != displayText )
141
+ {
142
+ range . SetText ( TextSetOptions . Unhide , displayText ) ;
143
+ }
144
+
145
+ var formatBefore = range . CharacterFormat . GetClone ( ) ;
146
+ range . CharacterFormat . SetClone ( format ) ;
147
+ PadRange ( range , formatBefore ) ;
148
+ range . Link = $ "\" { id } \" ";
149
+
150
+ // In some rare case, setting Link can fail. Only observed when interacting with Undo/Redo feature.
151
+ if ( range . Link != $ "\" { id } \" ")
152
+ {
153
+ range . Delete ( TextRangeUnit . Story , - 1 ) ;
154
+ return false ;
155
+ }
156
+
157
+ if ( addTrailingSpace )
158
+ {
159
+ var clone = range . GetClone ( ) ;
160
+ clone . Collapse ( false ) ;
161
+ clone . SetText ( TextSetOptions . Unhide , " " ) ;
162
+ clone . Collapse ( false ) ;
163
+ TextDocument . Selection . SetRange ( clone . EndPosition , clone . EndPosition ) ;
164
+ }
165
+
166
+ return true ;
167
+ }
168
+
166
169
private bool TryExtractQueryFromSelection ( out string prefix , out string query , out ITextRange range )
167
170
{
168
171
prefix = string . Empty ;
0 commit comments