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 FormatSingleCharacter(ref string text, int start) { Debug.Assert(start > 0); Debug.Assert(start < text.Length); char c = text[start - 1]; if (c == Characters.LoopStart && _SyntaxValidationResult.IsSuccessOrEmptyScript) { int depth = text.CalculateIndentationDepth(start - 1); ITextRange range = Document.GetRange(start - 1, start); string autocomplete; // Handle the two possible bracket formatting options. If the bracket needs // to go on a new line, check for edge cases and then prepare the new text // with the leading new line. Otherwise, simply replace the open bracket // on the same line and insert the autocomplete text. Using a single replacement // improves performance, as the color can be applied in a single pass. if (BracketsFormattingStyle == BracketsFormattingStyle.NewLine && start > 1 && text[start - 2] != Characters.CarriageReturn) { autocomplete = CodeGenerator.GetBracketAutocompleteText(BracketsFormattingStyle.NewLine, depth); } else { autocomplete = CodeGenerator.GetBracketAutocompleteText(BracketsFormattingStyle.SameLine, depth); } // Set the autocomplete text and color it range.SetText(TextSetOptions.None, autocomplete); range.CharacterFormat.ForegroundColor = SyntaxHighlightTheme.GetColor(Characters.LoopStart); // Move the selection at the end of the added line between the brackets. // Start is the position right after the first inserted bracket, which was replaced. // It gets shifted ahead by the length of the replacement text, minus the number of // tabs before the closing bracket, and 3 which is the number of additional characters // that were inserted with respect to the end: the first replaced bracket, // the closing bracket, and the new line before the line with the last bracket. Document.Selection.StartPosition = Document.Selection.EndPosition = start + autocomplete.Length - (depth + 3); text = Document.GetText(); } else if (c == Characters.CarriageReturn && _SyntaxValidationResult.IsSuccessOrEmptyScript) { int depth = text.CalculateIndentationDepth(start); string autocomplete = new string(Characters.Tab, depth); // Simply insert the tabs at the current selection, then collapse it Document.Selection.Text = autocomplete; Document.Selection.StartPosition = Document.Selection.EndPosition; text = Document.GetText(); } else { Document.SetRangeColor(start - 1, start, SyntaxHighlightTheme.GetColor(c)); } }
private void ClearStyle(ITextRange range) { var start = Math.Min(range.StartPosition, range.EndPosition); var end = Math.Max(range.StartPosition, range.EndPosition); range.SetRange(start, end); range.CharacterFormat = Document.GetDefaultCharacterFormat(); range.GetText(TextGetOptions.NoHidden, out string text); range.SetText(TextSetOptions.Unlink, text); range.SetRange(start, start + text.Length); }