Skip to content

Commit

Permalink
Fix event hookup at the end of a document (#58477)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidwengier authored Dec 24, 2021
1 parent 678b269 commit 8fb8592
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ internal void EventHookupFoundInSession(EventHookupSession analyzedSession)
if (_toolTipPresenter == null &&
CurrentSession == analyzedSession &&
caretPoint.HasValue &&
analyzedSession.TrackingSpan.GetSpan(CurrentSession.TextView.TextSnapshot).Contains(caretPoint.Value))
IsCaretWithinSpanOrAtEnd(analyzedSession.TrackingSpan, analyzedSession.TextView.TextSnapshot, caretPoint.Value))
{
// Create a tooltip presenter that stays alive, even when the user types, without tracking the mouse.
_toolTipPresenter = _toolTipService.CreatePresenter(analyzedSession.TextView,
Expand Down Expand Up @@ -80,6 +80,28 @@ internal void EventHookupFoundInSession(EventHookupSession analyzedSession)
}
}

private static bool IsCaretWithinSpanOrAtEnd(ITrackingSpan trackingSpan, ITextSnapshot textSnapshot, SnapshotPoint caretPoint)
{
var snapshotSpan = trackingSpan.GetSpan(textSnapshot);

// If the caret is within the span, then we want to show the tooltip
if (snapshotSpan.Contains(caretPoint))
{
return true;
}

// Otherwise if the span is empty, and at the end of the file, and the caret
// is also at the end of the file, then show the tooltip.
if (snapshotSpan.IsEmpty &&
snapshotSpan.Start.Position == caretPoint.Position &&
caretPoint.Position == textSnapshot.Length)
{
return true;
}

return false;
}

internal void BeginSession(
EventHookupCommandHandler eventHookupCommandHandler,
ITextView textView,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,10 @@ public EventHookupSession(
{
var position = textView.GetCaretPoint(subjectBuffer).Value.Position;
_trackingPoint = textView.TextSnapshot.CreateTrackingPoint(position, PointTrackingMode.Negative);
_trackingSpan = textView.TextSnapshot.CreateTrackingSpan(new Span(position, 1), SpanTrackingMode.EdgeInclusive);

// If the caret is at the end of the document we just create an empty span
var length = textView.TextSnapshot.Length > position + 1 ? 1 : 0;
_trackingSpan = textView.TextSnapshot.CreateTrackingSpan(new Span(position, length), SpanTrackingMode.EdgeInclusive);

var asyncToken = asyncListener.BeginAsyncOperation(GetType().Name + ".Start");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,37 @@ public async Task EventHookupInTopLevelCode()
System.AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
void CurrentDomain_UnhandledException(object sender, System.UnhandledExceptionEventArgs e)
{
throw new System.NotImplementedException();
}";
testState.AssertCodeIs(expectedCode);
}

[WpfFact, Trait(Traits.Feature, Traits.Features.EventHookup)]
public async Task EventHookupAtEndOfDocument()
{
var markup = @"
System.AppDomain.CurrentDomain.UnhandledException +$$";
using var testState = EventHookupTestState.CreateTestState(markup);
testState.SendTypeChar('=');

await testState.WaitForAsynchronousOperationsAsync();
testState.AssertShowing("CurrentDomain_UnhandledException");

var expectedCode = @"
System.AppDomain.CurrentDomain.UnhandledException +=";
testState.AssertCodeIs(expectedCode);

testState.SendTab();
await testState.WaitForAsynchronousOperationsAsync();

expectedCode = @"
System.AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
void CurrentDomain_UnhandledException(object sender, System.UnhandledExceptionEventArgs e)
{
throw new System.NotImplementedException();
Expand Down

0 comments on commit 8fb8592

Please sign in to comment.