Skip to content

Commit

Permalink
Avoid timing bug and add progress (can be very slow for large files)
Browse files Browse the repository at this point in the history
  • Loading branch information
GrahamTheCoder committed Sep 7, 2020
1 parent 9854857 commit 1f48c01
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

### Vsix

* Add "Paste as VB/C#" to "Paste special" menu [#622](https://github.com/icsharpcode/CodeConverter/pull/622)

### VB -> C#

Expand Down
39 changes: 29 additions & 10 deletions Vsix/CodeConversion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,7 @@ private async Task<ConversionResult> ConvertFileTextAsync<TLanguageConversion>(s
if (selected.Length > 0 && documentText.Length >= selected.End) {
documentText = documentText.Substring(selected.Start, selected.Length);
}

var textConversionOptions = new TextConversionOptions(DefaultReferences.NetStandard2, documentPath) {
AbandonOptionalTasksAfter = await GetAbandonOptionalTasksAfterAsync()
};
var convertTextOnly = await ProjectConversion.ConvertTextAsync<TLanguageConversion>(documentText, textConversionOptions, CreateOutputWindowProgress(), cancellationToken);
var convertTextOnly = await ConvertTextAsync<TLanguageConversion>(documentText, cancellationToken, documentPath);
convertTextOnly.SourcePathOrNull = documentPath;
return convertTextOnly;
}
Expand Down Expand Up @@ -309,14 +305,37 @@ public static bool IsVBFileName(string fileName)
return false;
}

public async Task ConvertTextBestEffortAsync<TLanguageConversion>(CancellationToken cancellationToken) where TLanguageConversion : ILanguageConversion, new()
public async Task PasteAsAsync<TLanguageConversion>(CancellationToken cancellationToken) where TLanguageConversion : ILanguageConversion, new()
{
var caretPosition = await VisualStudioInteraction.GetCaretPositionAsync(_serviceProvider);

await _outputWindow.WriteToOutputWindowAsync("Converting clipboard text...", true, true);

await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
string text = Clipboard.GetText();
var convertTextOnly = await ProjectConversion.ConvertTextAsync<TLanguageConversion>(text,
new TextConversionOptions(DefaultReferences.NetStandard2),
cancellationToken: cancellationToken);
await VisualStudioInteraction.WriteToCurrentWindowAsync(_serviceProvider, convertTextOnly.ConvertedCode);

var convertTextOnly = await _joinableTaskFactory.RunAsync(async () =>
await ConvertTextAsync<TLanguageConversion>(text, cancellationToken)
);

await caretPosition.InsertAsync(convertTextOnly.ConvertedCode);

}

private async Task<ConversionResult> ConvertTextAsync<TLanguageConversion>(string text,
CancellationToken cancellationToken, string documentPath = null) where TLanguageConversion : ILanguageConversion, new()
{
return await ProjectConversion.ConvertTextAsync<TLanguageConversion>(text,
await CreateTextConversionOptionsAsync(documentPath),
cancellationToken: cancellationToken,
progress: CreateOutputWindowProgress());
}

private async Task<TextConversionOptions> CreateTextConversionOptionsAsync(string documentPath = null)
{
return new TextConversionOptions(DefaultReferences.NetStandard2, documentPath) {
AbandonOptionalTasksAfter = await GetAbandonOptionalTasksAfterAsync()
};
}
}
}
2 changes: 1 addition & 1 deletion Vsix/PasteAsCS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ await VisualStudioInteraction.GetFirstSelectedSpanInCurrentViewAsync(ServiceProv
private async Task CodeEditorMenuItemCallbackAsync(CancellationToken cancellationToken)
{
try {
await _codeConversion.ConvertTextBestEffortAsync<VBToCSConversion>(cancellationToken);
await _codeConversion.PasteAsAsync<VBToCSConversion>(cancellationToken);
} catch (Exception ex) {
await VisualStudioInteraction.ShowExceptionAsync(ex);
}
Expand Down
2 changes: 1 addition & 1 deletion Vsix/PasteAsVB.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ await VisualStudioInteraction.GetFirstSelectedSpanInCurrentViewAsync(ServiceProv
private async Task CodeEditorMenuItemCallbackAsync(CancellationToken cancellationToken)
{
try {
await _codeConversion.ConvertTextBestEffortAsync<CSToVBConversion>(cancellationToken);
await _codeConversion.PasteAsAsync<CSToVBConversion>(cancellationToken);
} catch (Exception ex) {
await VisualStudioInteraction.ShowExceptionAsync(ex);
}
Expand Down
36 changes: 29 additions & 7 deletions Vsix/VisualStudioInteraction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,35 @@ public static async Task WriteStatusBarTextAsync(IAsyncServiceProvider servicePr

}

public static async Task<CaretPosition> GetCaretPositionAsync(IAsyncServiceProvider serviceProvider)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(CancelAllToken);
var viewHost = await GetCurrentViewHostAsync(serviceProvider,false);
ITextEdit edit = viewHost.TextView.TextBuffer.CreateEdit();
var caretPositionAsync = new CaretPosition(edit, viewHost.TextView.Caret.Position.BufferPosition.Position);
await TaskScheduler.Default;
return caretPositionAsync;
}

internal class CaretPosition
{
private readonly ITextEdit _textEdit;
private readonly int _position;

public CaretPosition(ITextEdit textEdit, int position)
{
_textEdit = textEdit;
_position = position;
}

public async Task InsertAsync(string text)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(CancelAllToken);
_textEdit.Insert(_position, text);
_textEdit.Apply();
}
}

private static async Task<VsDocument> GetSingleSelectedItemOrDefaultAsync()
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(CancelAllToken);
Expand Down Expand Up @@ -273,13 +302,6 @@ private static async Task<ITextSelection> GetSelectionInCurrentViewAsync(IAsyncS
var viewHost = await GetCurrentViewHostAsync(serviceProvider, predicate, mustHaveFocus);
return viewHost?.TextView.Selection;
}

public static async Task WriteToCurrentWindowAsync(IAsyncServiceProvider serviceProvider, string text)
{
var viewHost = await GetCurrentViewHostAsync(serviceProvider,false);
viewHost.TextView.TextBuffer.Insert(viewHost.TextView.Caret.Position.BufferPosition, text);

}
private static async Task<IWpfTextViewHost> GetCurrentViewHostAsync(IAsyncServiceProvider serviceProvider,
Func<string, bool> predicate, bool mustHaveFocus)
{
Expand Down

0 comments on commit 1f48c01

Please sign in to comment.