Пример #1
0
        public override CommandResult Invoke(Guid group, int id, object inputArg, ref object outputArg)
        {
            string originalText  = TargetBuffer.CurrentSnapshot.GetText();
            string formattedText = string.Empty;
            var    formatter     = new RFormatter(Shell.GetService <IREditorSettings>().FormatOptions);

            try {
                formattedText = formatter.Format(originalText);
            } catch (Exception ex) {
                Debug.Assert(false, "Formatter exception: ", ex.Message);
            }

            if (!string.IsNullOrEmpty(formattedText) && !string.Equals(formattedText, originalText, StringComparison.Ordinal))
            {
                var selectionTracker = new RSelectionTracker(TextView, TargetBuffer, new TextRange(0, TargetBuffer.CurrentSnapshot.Length));
                selectionTracker.StartTracking(automaticTracking: false);

                try {
                    using (var massiveChange = new MassiveChange(TextView, TargetBuffer, Shell, Resources.FormatDocument)) {
                        IREditorDocument document = REditorDocument.TryFromTextBuffer(TargetBuffer);
                        if (document != null)
                        {
                            document.EditorTree.Invalidate();
                        }

                        var caretPosition = TextView.Caret.Position.BufferPosition;
                        var viewPortLeft  = TextView.ViewportLeft;

                        RTokenizer tokenizer = new RTokenizer();
                        string     oldText   = TargetBuffer.CurrentSnapshot.GetText();
                        IReadOnlyTextRangeCollection <RToken> oldTokens = tokenizer.Tokenize(oldText);
                        IReadOnlyTextRangeCollection <RToken> newTokens = tokenizer.Tokenize(formattedText);

#if DEBUG
                        //if (oldTokens.Count != newTokens.Count) {
                        //    for (int i = 0; i < Math.Min(oldTokens.Count, newTokens.Count); i++) {
                        //        if (oldTokens[i].TokenType != newTokens[i].TokenType) {
                        //            Debug.Assert(false, Invariant($"Token type difference at {i}"));
                        //            break;
                        //        } else if (oldTokens[i].Length != newTokens[i].Length) {
                        //            Debug.Assert(false, Invariant($"token length difference at {i}"));
                        //            break;
                        //        }
                        //    }
                        //}
#endif
                        IncrementalTextChangeApplication.ApplyChangeByTokens(
                            TargetBuffer,
                            new TextStream(oldText), new TextStream(formattedText),
                            oldTokens, newTokens,
                            TextRange.FromBounds(0, oldText.Length),
                            Resources.FormatDocument, selectionTracker, Shell);
                    }
                } finally {
                    selectionTracker.EndTracking();
                }
                return(new CommandResult(CommandStatus.Supported, 0));
            }
            return(CommandResult.NotSupported);
        }
Пример #2
0
        public override CommandResult Invoke(Guid group, int id, object inputArg, ref object outputArg)
        {
            var originalText  = TargetBuffer.CurrentSnapshot.GetText();
            var formattedText = string.Empty;
            var formatter     = new RFormatter(Services.GetService <IREditorSettings>().FormatOptions);

            try {
                formattedText = formatter.Format(originalText);
            } catch (Exception ex) {
                Debug.Assert(false, "Formatter exception: ", ex.Message);
            }

            if (!string.IsNullOrEmpty(formattedText) && !string.Equals(formattedText, originalText, StringComparison.Ordinal))
            {
                var selectionTracker = new RSelectionTracker(TextView, TargetBuffer, new TextRange(0, TargetBuffer.CurrentSnapshot.Length));
                selectionTracker.StartTracking(automaticTracking: false);

                try {
                    using (var massiveChange = new MassiveChange(TextView, TargetBuffer, Services, Windows_Resources.FormatDocument)) {
                        var document = TargetBuffer.GetEditorDocument <IREditorDocument>();
                        document?.EditorTree?.Invalidate();

                        var tokenizer = new RTokenizer();
                        var oldText   = TargetBuffer.CurrentSnapshot.GetText();
                        var oldTokens = tokenizer.Tokenize(oldText);
                        var newTokens = tokenizer.Tokenize(formattedText);

#if DEBUG
                        //if (oldTokens.Count != newTokens.Count) {
                        //    for (int i = 0; i < Math.Min(oldTokens.Count, newTokens.Count); i++) {
                        //        if (oldTokens[i].TokenType != newTokens[i].TokenType) {
                        //            Debug.Assert(false, Invariant($"Token type difference at {i}"));
                        //            break;
                        //        } else if (oldTokens[i].Length != newTokens[i].Length) {
                        //            Debug.Assert(false, Invariant($"token length difference at {i}"));
                        //            break;
                        //        }
                        //    }
                        //}
#endif
                        var wsChangeHandler = Services.GetService <IIncrementalWhitespaceChangeHandler>();
                        wsChangeHandler.ApplyChange(
                            TargetBuffer.ToEditorBuffer(),
                            new TextStream(oldText), new TextStream(formattedText),
                            oldTokens, newTokens,
                            TextRange.FromBounds(0, oldText.Length),
                            Windows_Resources.FormatDocument, selectionTracker);
                    }
                } finally {
                    selectionTracker.EndTracking();
                }
                return(new CommandResult(CommandStatus.Supported, 0));
            }
            return(CommandResult.NotSupported);
        }
Пример #3
0
        public static bool FormatRangeExact(ITextView textView, ITextBuffer textBuffer,
                                            ITextRange formatRange, RFormatOptions options)
        {
            ITextSnapshot snapshot        = textBuffer.CurrentSnapshot;
            Span          spanToFormat    = new Span(formatRange.Start, formatRange.Length);
            string        spanText        = snapshot.GetText(spanToFormat.Start, spanToFormat.Length);
            string        trimmedSpanText = spanText.Trim();

            RFormatter formatter     = new RFormatter(options);
            string     formattedText = formatter.Format(trimmedSpanText);

            formattedText = formattedText.Trim(); // There may be inserted line breaks after {
            // Apply formatted text without indentation. We then will update the parse tree
            // so we can calculate proper line indents from the AST via the smart indenter.
            if (!spanText.Equals(formattedText, StringComparison.Ordinal))
            {
                // Extract existing indent before applying changes. Existing indent
                // may be used by the smart indenter for function argument lists.
                var startLine = snapshot.GetLineFromPosition(spanToFormat.Start);
                var originalIndentSizeInSpaces = IndentBuilder.TextIndentInSpaces(startLine.GetText(), options.IndentSize);

                var        selectionTracker = new RSelectionTracker(textView, textBuffer, formatRange);
                RTokenizer tokenizer        = new RTokenizer();
                IReadOnlyTextRangeCollection <RToken> oldTokens = tokenizer.Tokenize(spanText);
                IReadOnlyTextRangeCollection <RToken> newTokens = tokenizer.Tokenize(formattedText);

                IncrementalTextChangeApplication.ApplyChangeByTokens(
                    textBuffer,
                    new TextStream(spanText), new TextStream(formattedText),
                    oldTokens, newTokens,
                    formatRange,
                    Resources.AutoFormat, selectionTracker,
                    () => {
                    var ast = UpdateAst(textBuffer);
                    // Apply indentation
                    IndentLines(textView, textBuffer, new TextRange(formatRange.Start, formattedText.Length), ast, options, originalIndentSizeInSpaces);
                });

                return(true);
            }

            return(false);
        }
Пример #4
0
        public static bool FormatRangeExact(ITextView textView, ITextBuffer textBuffer, ITextRange formatRange,
                                            AstRoot ast, RFormatOptions options,
                                            int scopeStatementPosition, bool respectUserIndent = true)
        {
            ITextSnapshot snapshot        = textBuffer.CurrentSnapshot;
            Span          spanToFormat    = new Span(formatRange.Start, formatRange.Length);
            string        spanText        = snapshot.GetText(spanToFormat.Start, spanToFormat.Length);
            string        trimmedSpanText = spanText.Trim();

            if (trimmedSpanText == "}")
            {
                // Locate opening { and its statement
                var scopeNode = ast.GetNodeOfTypeFromPosition <IAstNodeWithScope>(spanToFormat.Start);
                if (scopeNode != null)
                {
                    scopeStatementPosition = scopeNode.Start;
                }
            }

            RFormatter formatter     = new RFormatter(options);
            string     formattedText = formatter.Format(trimmedSpanText);

            formattedText = formattedText.Trim(); // there may be inserted line breaks after {
            formattedText = IndentLines(textBuffer, spanToFormat.Start, ast, formattedText, options, scopeStatementPosition, respectUserIndent);

            if (!spanText.Equals(formattedText, StringComparison.Ordinal))
            {
                var        selectionTracker = new RSelectionTracker(textView, textBuffer);
                RTokenizer tokenizer        = new RTokenizer();
                IReadOnlyTextRangeCollection <RToken> oldTokens = tokenizer.Tokenize(spanText);
                IReadOnlyTextRangeCollection <RToken> newTokens = tokenizer.Tokenize(formattedText);
                IncrementalTextChangeApplication.ApplyChangeByTokens(
                    textBuffer,
                    new TextStream(spanText), new TextStream(formattedText),
                    oldTokens, newTokens,
                    formatRange,
                    Resources.AutoFormat, selectionTracker);
                return(true);
            }

            return(false);
        }