-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Apply Diff feature #20
Conversation
if (docView?.TextView == null) return false; | ||
|
||
// any interactions with the `IVsTextView` should be done on the main thread | ||
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It only throws an exception when right-clicking the diff view. I wonder why it doesn't execute on the main thread, only for the diff view?
Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault(assembly => assembly.GetName().Name == name); | ||
|
||
Type type = assembly?.GetType("Microsoft.VisualStudio.Text.Editor.AggregateFocusInterceptor"); | ||
_fnSetInterceptsAggregateFocus = type?.GetMethod("SetInterceptsAggregateFocus", BindingFlags.Static | BindingFlags.Public); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to get the internal SetInterceptsAggregateFocus
method using reflection, rather than adding a reference to the assembly.
This PR's complexity makes it hard to comment on the code because we wouldn't be able to see the general picture of it. So I'll leave a short write-up on the inner workings of it here instead. The core foundationsThis relies heavily on a public interface of Visual Studio that lets us seemingly create a difference view without doing the heavy lifting ourselves: It is implemented in the class The internal class DifferenceViewer : IWpfDifferenceViewer, IDifferenceViewer, IPropertyOwner, IDifferenceViewer3, IDifferenceViewer2, IViewSynchronizationManager Once created, we can display it using its In order to display it on top of the text editor, we can create a The icing on the cakeThere are four initial problems with this approach:
The solution for each problem is as described below: 1. Make the right view editable
2. Handle commands correctly
3. Fix the selection highlight
4. Properly display the adornment
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Truly incredible work
The technologies:
IWpfDifferenceViewerFactoryService.CreateDifferenceView
method, we can create a difference view and place it in a window.IAdornmentLayer.AddAdornment
, we can make the difference window appears on top of the text editor.ILineTransformSource
to extend the space between the lines to compensate for any extra height of the diff window.IVsTextView.AddCommandFilter
can be used to hook up the diff view to the command chain of the host view.AggregateFocusInterceptor.SetInterceptsAggregateFocus
was used to achieve proper focuses for the diff view, this is optional, and the feature works just fine even if that failed.Check list:
-
and+
of the diff view to make the code align with the original codeRecording.2023-12-12.070015.mp4