public static async Task <IEnumerable <LinePositionSpanTextChange> > GetFormattingChanges(Document document, int start, int end, OmniSharpOptions omnisharpOptions, ILoggerFactory loggerFactory) { var optionSet = omnisharpOptions.FormattingOptions.EnableEditorConfigSupport ? await document.Project.Solution.Workspace.Options.WithEditorConfigOptions(document.FilePath, loggerFactory) : document.Project.Solution.Workspace.Options; var newDocument = await Formatter.FormatAsync(document, TextSpan.FromBounds(start, end), optionSet); return(await TextChanges.GetAsync(newDocument, document)); }
public async Task <RunCodeActionResponse> Handle(RunCodeActionRequest request) { var actions = new List <CodeAction>(); var context = await GetContext(request, actions); await GetContextualCodeActions(context); if (request.CodeAction > actions.Count()) { return(new RunCodeActionResponse()); } var action = actions.ElementAt(request.CodeAction); var operations = await action.GetOperationsAsync(CancellationToken.None); foreach (var o in operations) { o.Apply(_workspace, CancellationToken.None); } var oldDocument = context.Value.Document; var newDocument = _workspace.CurrentSolution.GetDocument(oldDocument.Id); var response = new RunCodeActionResponse(); if (!request.WantsTextChanges) { // return the text of the new document var newText = await newDocument.GetTextAsync(); response.Text = newText.ToString(); } else { // return the text changes response.Changes = await TextChanges.GetAsync(newDocument, oldDocument); } return(response); }
public async Task <FixUsingsResponse> Handle(FixUsingsRequest request) { var response = new FixUsingsResponse(); var oldDocument = _workspace.GetDocument(request.FileName); if (oldDocument != null) { var fixUsingsResponse = await new FixUsingsWorker(_providers) .FixUsingsAsync(oldDocument); response.AmbiguousResults = fixUsingsResponse.AmbiguousResults; if (request.ApplyTextChanges) { _workspace.TryApplyChanges(fixUsingsResponse.Document.Project.Solution); } var newDocument = fixUsingsResponse.Document; if (!request.WantsTextChanges) { // return the text of the new document var newText = await newDocument.GetTextAsync(); response.Buffer = newText.ToString(); } else { // return the text changes response.Changes = await TextChanges.GetAsync(newDocument, oldDocument); } } return(response); }
// public static async Task<IEnumerable<LinePositionSpanTextChange>> GetFormattingChangesAfterKeystroke(Document document, int position, char character) // { // if (character == '\n') // { // // format previous line on new line // var text = await document.GetTextAsync(); // var lines = text.Lines; // var targetLine = lines[lines.GetLineFromPosition(position).LineNumber - 1]; // if (!string.IsNullOrWhiteSpace(targetLine.Text.ToString(targetLine.Span))) // { // return await GetFormattingChanges(document, targetLine.Start, targetLine.End); // } // } // else if (character == '}' || character == ';') // { // // format after ; and } // var root = await document.GetSyntaxRootAsync(); // var node = FindFormatTarget(root, position); // if (node != null) // { // return await GetFormattingChanges(document, node.FullSpan.Start, node.FullSpan.End); // } // } // return Enumerable.Empty<LinePositionSpanTextChange>(); // } // public static SyntaxNode FindFormatTarget(SyntaxNode root, int position) // { // // todo@jo - refine this // var token = root.FindToken(position); // if (token.IsKind(SyntaxKind.EndOfFileToken)) // { // token = token.GetPreviousToken(); // } // switch (token.Kind()) // { // // ; -> use the statement // case SyntaxKind.SemicolonToken: // return token.Parent; // // } -> use the parent of the {}-block or // // just the parent (XYZDeclaration etc) // case SyntaxKind.CloseBraceToken: // var parent = token.Parent; // return parent.IsKind(SyntaxKind.Block) // ? parent.Parent // : parent; // case SyntaxKind.CloseParenToken: // if (token.GetPreviousToken().IsKind(SyntaxKind.SemicolonToken) && // token.Parent.IsKind(SyntaxKind.ForStatement)) // { // return token.Parent; // } // break; // } // return null; // } // public static async Task<IEnumerable<LinePositionSpanTextChange>> GetFormattingChanges(Document document, int start, int end) // { // var newDocument = await Formatter.FormatAsync(document, TextSpan.FromBounds(start, end), document.Project.Solution.Workspace.Options); // return await TextChanges.GetAsync(newDocument, document); // } // public static async Task<string> GetFormattedText(Document document) // { // var newDocument = await Formatter.FormatAsync(document, document.Project.Solution.Workspace.Options); // var text = await newDocument.GetTextAsync(); // return text.ToString(); // } public static async Task <IEnumerable <LinePositionSpanTextChange> > GetFormattedTextChanges(Document document) { var newDocument = await Formatter.FormatAsync(document, document.Project.Solution.Workspace.Options); return(await TextChanges.GetAsync(newDocument, document)); }
public static async Task <IEnumerable <LinePositionSpanTextChange> > GetFormattedTextChanges(Document document, OmniSharpOptions omnisharpOptions, ILoggerFactory loggerFactory) { var newDocument = await FormatDocument(document, omnisharpOptions, loggerFactory); return(await TextChanges.GetAsync(newDocument, document)); }
public static async Task <IEnumerable <LinePositionSpanTextChange> > GetFormattingChanges(Document document, int start, int end, OmniSharpOptions omnisharpOptions, ILoggerFactory loggerFactory) { var newDocument = await FormatDocument(document, omnisharpOptions, loggerFactory, TextSpan.FromBounds(start, end)); return(await TextChanges.GetAsync(newDocument, document)); }
private async Task <IEnumerable <ModifiedFileResponse> > GetFileChangesAsync(Solution newSolution, Solution oldSolution, string directory, bool wantTextChanges) { var filePathToResponseMap = new Dictionary <string, ModifiedFileResponse>(); var solutionChanges = newSolution.GetChanges(oldSolution); foreach (var projectChange in solutionChanges.GetProjectChanges()) { // Handle added documents foreach (var documentId in projectChange.GetAddedDocuments()) { var newDocument = newSolution.GetDocument(documentId); var text = await newDocument.GetTextAsync(); var newFilePath = newDocument.FilePath == null || !Path.IsPathRooted(newDocument.FilePath) ? Path.Combine(directory, newDocument.Name) : newDocument.FilePath; var modifiedFileResponse = new ModifiedFileResponse(newFilePath) { Changes = new[] { new LinePositionSpanTextChange { NewText = text.ToString() } } }; filePathToResponseMap[newFilePath] = modifiedFileResponse; // We must add new files to the workspace to ensure that they're present when the host editor // tries to modify them. This is a strange interaction because the workspace could be left // in an incomplete state if the host editor doesn't apply changes to the new file, but it's // what we've got today. if (this.Workspace.GetDocument(newFilePath) == null) { var fileInfo = new FileInfo(newFilePath); if (!fileInfo.Exists) { fileInfo.CreateText().Dispose(); } else { // The file already exists on disk? Ensure that it's zero-length. If so, we can still use it. if (fileInfo.Length > 0) { Logger.LogError($"File already exists on disk: '{newFilePath}'"); break; } } this.Workspace.AddDocument(projectChange.ProjectId, newFilePath, newDocument.SourceCodeKind); } else { // The file already exists in the workspace? We're in a bad state. Logger.LogError($"File already exists in workspace: '{newFilePath}'"); } } // Handle changed documents foreach (var documentId in projectChange.GetChangedDocuments()) { var newDocument = newSolution.GetDocument(documentId); var filePath = newDocument.FilePath; if (!filePathToResponseMap.TryGetValue(filePath, out var modifiedFileResponse)) { modifiedFileResponse = new ModifiedFileResponse(filePath); filePathToResponseMap[filePath] = modifiedFileResponse; } if (wantTextChanges) { var oldDocument = oldSolution.GetDocument(documentId); var linePositionSpanTextChanges = await TextChanges.GetAsync(newDocument, oldDocument); modifiedFileResponse.Changes = modifiedFileResponse.Changes != null ? modifiedFileResponse.Changes.Union(linePositionSpanTextChanges) : linePositionSpanTextChanges; } else { var text = await newDocument.GetTextAsync(); modifiedFileResponse.Buffer = text.ToString(); } } } return(filePathToResponseMap.Values); }
public async Task <RenameResponse> Handle(RenameRequest request) { var response = new RenameResponse(); var document = _workspace.GetDocument(request.FileName); if (document != null) { var sourceText = await document.GetTextAsync(); var position = sourceText.GetTextPosition(request); var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position); Solution solution = _workspace.CurrentSolution; if (symbol != null) { var options = new OmniSharpRenameOptions( RenameOverloads: _omniSharpOptions.RenameOptions.RenameOverloads, RenameInStrings: _omniSharpOptions.RenameOptions.RenameInStrings, RenameInComments: _omniSharpOptions.RenameOptions.RenameInComments); (solution, response.ErrorMessage) = await OmniSharpRenamer.RenameSymbolAsync(solution, symbol, request.RenameTo, options, nonConflictSymbols : null, CancellationToken.None); if (response.ErrorMessage is not null) { // An error occurred. There are no changes to report. return(response); } } var changes = new Dictionary <string, ModifiedFileResponse>(); var solutionChanges = solution.GetChanges(_workspace.CurrentSolution); foreach (var projectChange in solutionChanges.GetProjectChanges()) { foreach (var changedDocumentId in projectChange.GetChangedDocuments()) { var changedDocument = solution.GetDocument(changedDocumentId); if (!changes.TryGetValue(changedDocument.FilePath, out var modifiedFileResponse)) { modifiedFileResponse = new ModifiedFileResponse(changedDocument.FilePath); changes[changedDocument.FilePath] = modifiedFileResponse; } if (!request.WantsTextChanges) { var changedText = await changedDocument.GetTextAsync(); modifiedFileResponse.Buffer = changedText.ToString(); } else { var originalDocument = _workspace.CurrentSolution.GetDocument(changedDocumentId); var linePositionSpanTextChanges = await TextChanges.GetAsync(changedDocument, originalDocument); modifiedFileResponse.Changes = modifiedFileResponse.Changes != null ? modifiedFileResponse.Changes.Union(linePositionSpanTextChanges) : linePositionSpanTextChanges; } } } if (request.ApplyTextChanges) { // Attempt to update the workspace if (_workspace.TryApplyChanges(solution)) { response.Changes = changes.Values; } } else { response.Changes = changes.Values; } } return(response); }
public static async Task <IEnumerable <LinePositionSpanTextChange> > GetFormattingChanges(Document document, int start, int end) { var newDocument = await Formatter.FormatAsync(document, TextSpan.FromBounds(start, end), document.Project.Solution.Workspace.Options); return(await TextChanges.GetAsync(newDocument, document)); }
public async Task <RenameResponse> Handle(RenameRequest request) { var response = new RenameResponse(); var document = _workspace.GetDocument(request.FileName); if (document != null) { var sourceText = await document.GetTextAsync(); var position = sourceText.Lines.GetPosition(new LinePosition(request.Line, request.Column)); var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position); Solution solution = _workspace.CurrentSolution; if (symbol != null) { try { solution = await Renamer.RenameSymbolAsync(solution, symbol, request.RenameTo, _workspace.Options); } catch (ArgumentException e) { response.ErrorMessage = e.Message; } } var changes = new Dictionary <string, ModifiedFileResponse>(); var solutionChanges = solution.GetChanges(_workspace.CurrentSolution); foreach (var projectChange in solutionChanges.GetProjectChanges()) { foreach (var changedDocumentId in projectChange.GetChangedDocuments()) { var changedDocument = solution.GetDocument(changedDocumentId); if (!changes.TryGetValue(changedDocument.FilePath, out var modifiedFileResponse)) { modifiedFileResponse = new ModifiedFileResponse(changedDocument.FilePath); changes[changedDocument.FilePath] = modifiedFileResponse; } if (!request.WantsTextChanges) { var changedText = await changedDocument.GetTextAsync(); modifiedFileResponse.Buffer = changedText.ToString(); } else { var originalDocument = _workspace.CurrentSolution.GetDocument(changedDocumentId); var linePositionSpanTextChanges = await TextChanges.GetAsync(changedDocument, originalDocument); modifiedFileResponse.Changes = modifiedFileResponse.Changes != null ? modifiedFileResponse.Changes.Union(linePositionSpanTextChanges) : linePositionSpanTextChanges; } } } if (request.ApplyTextChanges) { // Attempt to update the workspace if (_workspace.TryApplyChanges(solution)) { response.Changes = changes.Values; } } else { response.Changes = changes.Values; } } return(response); }