-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathDiffViewerToolWindow.cs
More file actions
179 lines (148 loc) · 5.43 KB
/
DiffViewerToolWindow.cs
File metadata and controls
179 lines (148 loc) · 5.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/* *******************************************************************************************************************
* Application: ClaudeCodeExtension
*
* Autor: Daniel Carvalho Liedke
*
* Copyright © Daniel Carvalho Liedke 2026
* Usage and reproduction in any manner whatsoever without the written permission of Daniel Carvalho Liedke is strictly forbidden.
*
* Purpose: Tool window for displaying file diffs in Visual Studio
*
* *******************************************************************************************************************/
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Input;
namespace ClaudeCodeVS
{
/// <summary>
/// Tool window for displaying file changes and diffs
/// </summary>
[Guid("A1B2C3D4-E5F6-7890-ABCD-EF1234567890")]
public class DiffViewerToolWindow : ToolWindowPane, IVsWindowFrameNotify, IVsWindowFrameNotify2
{
private DiffViewerControl _diffViewerControl;
private bool _isVisible;
private uint _notifyCookie;
/// <summary>
/// Gets the diff viewer control
/// </summary>
public DiffViewerControl DiffViewerControl => _diffViewerControl;
/// <summary>
/// Gets whether the window is currently visible
/// </summary>
public bool IsWindowVisible => _isVisible;
/// <summary>
/// Fired when window visibility changes
/// </summary>
public event EventHandler<bool> VisibilityChanged;
public DiffViewerToolWindow() : base(null)
{
this.Caption = "Code Changes";
this.BitmapImageMoniker = KnownMonikers.FileGroupDefault;
_diffViewerControl = new DiffViewerControl();
this.Content = _diffViewerControl;
// Handle Ctrl+F at the tool window level
_diffViewerControl.PreviewKeyDown += OnDiffViewerPreviewKeyDown;
}
private void OnDiffViewerPreviewKeyDown(object sender, KeyEventArgs e)
{
ThreadHelper.ThrowIfNotOnUIThread();
// Intercept Ctrl+F before VS handles it
if (e.Key == Key.F && Keyboard.Modifiers == ModifierKeys.Control)
{
_diffViewerControl.ActivateSearch();
e.Handled = true;
}
}
/// <summary>
/// Called when the tool window is created - subscribe to frame notifications
/// </summary>
public override void OnToolWindowCreated()
{
base.OnToolWindowCreated();
ThreadHelper.ThrowIfNotOnUIThread();
// Subscribe to window frame notifications
if (Frame is IVsWindowFrame2 windowFrame2)
{
windowFrame2.Advise(this, out _notifyCookie);
}
// Check initial visibility
if (Frame is IVsWindowFrame windowFrame)
{
_isVisible = windowFrame.IsVisible() == VSConstants.S_OK;
}
}
/// <summary>
/// Called when the window is closed
/// </summary>
protected override void OnClose()
{
ThreadHelper.ThrowIfNotOnUIThread();
// Unsubscribe from notifications
if (_notifyCookie != 0 && Frame is IVsWindowFrame2 windowFrame2)
{
windowFrame2.Unadvise(_notifyCookie);
_notifyCookie = 0;
}
if (_isVisible)
{
_isVisible = false;
VisibilityChanged?.Invoke(this, false);
}
base.OnClose();
}
#region IVsWindowFrameNotify Implementation
public int OnShow(int fShow)
{
var frameShow = (__FRAMESHOW)fShow;
bool nowVisible = frameShow == __FRAMESHOW.FRAMESHOW_WinShown ||
frameShow == __FRAMESHOW.FRAMESHOW_WinRestored ||
frameShow == __FRAMESHOW.FRAMESHOW_WinMaximized ||
frameShow == __FRAMESHOW.FRAMESHOW_TabActivated;
bool nowHidden = frameShow == __FRAMESHOW.FRAMESHOW_WinHidden ||
frameShow == __FRAMESHOW.FRAMESHOW_WinMinimized ||
frameShow == __FRAMESHOW.FRAMESHOW_TabDeactivated;
if (nowVisible && !_isVisible)
{
_isVisible = true;
VisibilityChanged?.Invoke(this, true);
}
else if (nowHidden && _isVisible)
{
_isVisible = false;
VisibilityChanged?.Invoke(this, false);
}
return VSConstants.S_OK;
}
public int OnMove()
{
return VSConstants.S_OK;
}
public int OnSize()
{
return VSConstants.S_OK;
}
public int OnDockableChange(int fDockable)
{
return VSConstants.S_OK;
}
#endregion
#region IVsWindowFrameNotify2 Implementation
public int OnClose(ref uint pgrfSaveOptions)
{
if (_isVisible)
{
_isVisible = false;
VisibilityChanged?.Invoke(this, false);
}
return VSConstants.S_OK;
}
#endregion
}
}