public void ExecuteCommand(PasteCommandArgs args, Action nextHandler)
 {
     _waitIndicator.Wait(
         title: EditorFeaturesResources.Format_Paste,
         message: EditorFeaturesResources.Formatting_pasted_text,
         allowCancel: true,
         action: c => ExecuteCommandWorker(args, nextHandler, c.CancellationToken));
 }
        private void ExecuteCommandWorker(PasteCommandArgs args, Action nextHandler, CancellationToken cancellationToken)
        {
            var caretPosition = args.TextView.GetCaretPoint(args.SubjectBuffer);

            nextHandler();

            if (!args.SubjectBuffer.CanApplyChangeDocumentToWorkspace())
            {
                return;
            }

            if (!args.SubjectBuffer.GetOption(FeatureOnOffOptions.FormatOnPaste) ||
                !caretPosition.HasValue)
            {
                return;
            }

            var trackingSpan = caretPosition.Value.Snapshot.CreateTrackingSpan(caretPosition.Value.Position, 0, SpanTrackingMode.EdgeInclusive);

            var document = args.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
            if (document == null)
            {
                return;
            }

            var formattingRuleService = document.Project.Solution.Workspace.Services.GetService<IHostDependentFormattingRuleFactoryService>();
            if (formattingRuleService != null && formattingRuleService.ShouldNotFormatOrCommitOnPaste(document))
            {
                return;
            }

            var formattingService = document.GetLanguageService<IEditorFormattingService>();
            if (formattingService == null || !formattingService.SupportsFormatOnPaste)
            {
                return;
            }

            var span = trackingSpan.GetSpan(args.SubjectBuffer.CurrentSnapshot).Span.ToTextSpan();
            var changes = formattingService.GetFormattingChangesOnPasteAsync(document, span, cancellationToken).WaitAndGetResult(cancellationToken);
            if (changes.Count == 0)
            {
                return;
            }

            document.Project.Solution.Workspace.ApplyTextChanges(document.Id, changes, cancellationToken);
        }
 public CommandState GetCommandState(PasteCommandArgs args, Func<CommandState> nextHandler)
 {
     return nextHandler();
 }
        protected static async Task AssertFormatWithPasteOrReturnAsync(string expectedWithMarker, string codeWithMarker, bool allowDocumentChanges, bool isPaste = true)
        {
            using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(codeWithMarker))
            {
                workspace.CanApplyChangeDocument = allowDocumentChanges;

                // set up caret position
                var testDocument = workspace.Documents.Single();
                var view = testDocument.GetTextView();
                view.Caret.MoveTo(new SnapshotPoint(view.TextSnapshot, testDocument.CursorPosition.Value));

                // get original buffer
                var buffer = workspace.Documents.First().GetTextBuffer();

                var optionService = workspace.Services.GetService<IOptionService>();
                if (isPaste)
                {
                    optionService.SetOptions(optionService.GetOptions().WithChangedOption(FeatureOnOffOptions.FormatOnPaste, LanguageNames.CSharp, true));
                    var commandHandler = new FormatCommandHandler(TestWaitIndicator.Default, null, null);
                    var commandArgs = new PasteCommandArgs(view, view.TextBuffer);
                    commandHandler.ExecuteCommand(commandArgs, () => { });
                }
                else
                {
                    // Return Key Command
                    var textUndoHistory = new Mock<ITextUndoHistoryRegistry>();
                    var editorOperationsFactory = new Mock<IEditorOperationsFactoryService>();
                    var editorOperations = new Mock<IEditorOperations>();
                    editorOperationsFactory.Setup(x => x.GetEditorOperations(testDocument.GetTextView())).Returns(editorOperations.Object);
                    var commandHandler = new FormatCommandHandler(TestWaitIndicator.Default, textUndoHistory.Object, editorOperationsFactory.Object);
                    var commandArgs = new ReturnKeyCommandArgs(view, view.TextBuffer);
                    commandHandler.ExecuteCommand(commandArgs, () => { });
                }

                string expected;
                int expectedPosition;
                MarkupTestFile.GetPosition(expectedWithMarker, out expected, out expectedPosition);

                Assert.Equal(expected, view.TextSnapshot.GetText());

                var caretPosition = view.Caret.Position.BufferPosition.Position;
                Assert.True(expectedPosition == caretPosition,
                    string.Format("Caret positioned incorrectly. Should have been {0}, but was {1}.", expectedPosition, caretPosition));
            }
        }