Exemplo n.º 1
0
        private bool TryCommitSuggestionIntoDocument(ITextRange range, string displayText, Guid id, ITextCharacterFormat format, bool addTrailingSpace = true)
        {
            // We don't want to set text when the display text doesn't change since it may lead to unexpected caret move.
            range.GetText(TextGetOptions.NoHidden, out var existingText);
            if (existingText != displayText)
            {
                range.SetText(TextSetOptions.Unhide, displayText);
            }

            var formatBefore = range.CharacterFormat.GetClone();

            range.CharacterFormat.SetClone(format);
            PadRange(range, formatBefore);
            range.Link = $"\"{id}\"";

            // In some rare case, setting Link can fail. Only observed when interacting with Undo/Redo feature.
            if (range.Link != $"\"{id}\"")
            {
                range.Delete(TextRangeUnit.Story, -1);
                return(false);
            }

            if (addTrailingSpace)
            {
                var clone = range.GetClone();
                clone.Collapse(false);
                clone.SetText(TextSetOptions.Unhide, " ");
                clone.Collapse(false);
                TextDocument.Selection.SetRange(clone.EndPosition, clone.EndPosition);
            }

            return(true);
        }
        private void ValidateTokenFromRange(ITextRange range)
        {
            if (range.Length == 0 || !TryGetTokenFromRange(range, out var token))
            {
                return;
            }

            // Check for duplicate tokens. This can happen if the user copies and pastes the token multiple times.
            if (token.Active && token.RangeStart != range.StartPosition && token.RangeEnd != range.EndPosition)
            {
                var guid = Guid.NewGuid();
                if (TryCommitSuggestionIntoDocument(range, token.DisplayText, guid, CreateTokenFormat(range), false))
                {
                    token = new RichSuggestToken(guid, token.DisplayText)
                    {
                        Active = true, Item = token.Item
                    };
                    token.UpdateTextRange(range);
                    _tokens.Add(range.Link, token);
                }

                return;
            }

            if (token.ToString() != range.Text)
            {
                range.Delete(TextRangeUnit.Story, 0);
                token.Active = false;
                return;
            }

            token.UpdateTextRange(range);
            token.Active = true;
        }