Skip to content

Commit 450aa0b

Browse files
committed
Subscribed to all the necessary events.
1 parent 706250d commit 450aa0b

2 files changed

Lines changed: 48 additions & 51 deletions

File tree

src/GtmExtension/GtmExtension.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,11 @@
8686
<Reference Include="Microsoft.VisualStudio.CommandBars, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
8787
<EmbedInteropTypes>False</EmbedInteropTypes>
8888
</Reference>
89+
<Reference Include="Microsoft.VisualStudio.ComponentModelHost, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
8990
<Reference Include="Microsoft.VisualStudio.CoreUtility, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
9091
<HintPath>..\..\packages\Microsoft.VisualStudio.CoreUtility.15.0.26228\lib\net45\Microsoft.VisualStudio.CoreUtility.dll</HintPath>
9192
</Reference>
93+
<Reference Include="Microsoft.VisualStudio.Editor, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
9294
<Reference Include="Microsoft.VisualStudio.Imaging, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
9395
<HintPath>..\..\packages\Microsoft.VisualStudio.Imaging.15.0.26228\lib\net45\Microsoft.VisualStudio.Imaging.dll</HintPath>
9496
</Reference>
@@ -130,6 +132,9 @@
130132
<Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
131133
<HintPath>..\..\packages\Microsoft.VisualStudio.Shell.Interop.9.0.9.0.30729\lib\Microsoft.VisualStudio.Shell.Interop.9.0.dll</HintPath>
132134
</Reference>
135+
<Reference Include="Microsoft.VisualStudio.Text.Data, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
136+
<Reference Include="Microsoft.VisualStudio.Text.UI, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
137+
<Reference Include="Microsoft.VisualStudio.Text.UI.Wpf, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
133138
<Reference Include="Microsoft.VisualStudio.TextManager.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
134139
<HintPath>..\..\packages\Microsoft.VisualStudio.TextManager.Interop.7.10.6070\lib\Microsoft.VisualStudio.TextManager.Interop.dll</HintPath>
135140
</Reference>
@@ -149,6 +154,7 @@
149154
<EmbedInteropTypes>False</EmbedInteropTypes>
150155
</Reference>
151156
<Reference Include="System" />
157+
<Reference Include="System.ComponentModel.Composition" />
152158
<Reference Include="System.Data" />
153159
<Reference Include="System.Design" />
154160
<Reference Include="System.Drawing" />

src/GtmExtension/GtmPackage.cs

Lines changed: 42 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
using EnvDTE;
22
using Microsoft.VisualStudio;
3-
using Microsoft.VisualStudio.OLE.Interop;
3+
using Microsoft.VisualStudio.ComponentModelHost;
4+
using Microsoft.VisualStudio.Editor;
45
using Microsoft.VisualStudio.Shell;
56
using Microsoft.VisualStudio.Shell.Interop;
7+
using Microsoft.VisualStudio.Text;
8+
using Microsoft.VisualStudio.Text.Editor;
69
using Microsoft.VisualStudio.TextManager.Interop;
710
using System;
811
using System.ComponentModel;
912
using System.Diagnostics.CodeAnalysis;
13+
using System.Runtime.CompilerServices;
1014
using System.Runtime.InteropServices;
1115
using System.Threading;
1216
using Process = System.Diagnostics.Process;
@@ -33,20 +37,18 @@ namespace GtmExtension
3337
/// </remarks>
3438
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
3539
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // Info on this package for Help/About
36-
[Guid(GtmPackage.PackageGuidString)]
40+
[Guid(PackageGuidString)]
3741
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")]
3842
[ProvideAutoLoad(UIContextGuids80.SolutionExists, PackageAutoLoadFlags.BackgroundLoad)] // Load the extension when a solution is open.
39-
public sealed class GtmPackage : AsyncPackage, IVsTextViewEvents
43+
public sealed class GtmPackage : AsyncPackage
4044
{
4145
private string gtmExe;
4246
private IVsStatusbar statusBar;
43-
private TextEditorEvents textEditorEvents;
47+
private IVsEditorAdaptersFactoryService editor;
4448
private WindowEvents windowEvents;
4549
private DocumentEvents documentEvents;
46-
private Window previousWindow;
47-
private IVsTextView previousTextView;
48-
private uint previousCookie;
4950
private IVsTextManager textManager;
51+
private IWpfTextView wpfTextView;
5052

5153
/// <summary>
5254
/// GtmPackage GUID string.
@@ -173,74 +175,63 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke
173175
textManager = (IVsTextManager)await GetServiceAsync(typeof(SVsTextManager));
174176
if (textManager == null) { throw new InvalidOperationException("No TextManager."); }
175177

176-
// Subscribe to events.
177-
textEditorEvents = dte.Events.TextEditorEvents; // Don't get GC'ed!
178-
textEditorEvents.LineChanged += TextEditorEvents_LineChanged;
178+
// Get editor adapters.
179+
var componentModel = (IComponentModel)await GetServiceAsync(typeof(SComponentModel));
180+
if (componentModel == null) { throw new InvalidOperationException("No ComponentModel."); }
181+
editor = componentModel.GetService<IVsEditorAdaptersFactoryService>();
179182

183+
// Subscribe to events. We keep the events objects so that they don't get GC'ed.
180184
windowEvents = dte.Events.WindowEvents;
181185
windowEvents.WindowActivated += WindowEvents_WindowActivated;
182186

183187
documentEvents = dte.Events.DocumentEvents;
184188
documentEvents.DocumentSaved += DocumentEvents_DocumentSaved;
189+
190+
Subscribe();
185191
}
186192

187-
private void TextEditorEvents_LineChanged(TextPoint StartPoint, TextPoint EndPoint, int Hint)
193+
private void WindowEvents_WindowActivated(Window GotFocus, Window LostFocus)
188194
{
189-
statusBar.SetText("Text changed: " + StartPoint.Parent.Parent.FullName + " (" + DateTime.Now.ToLongTimeString() + ").");
195+
Subscribe();
190196
}
191-
private IConnectionPoint GetConnectionPoint(IVsTextView view)
197+
private string GetFilePath(ITextView textView)
192198
{
193-
if (view is IConnectionPointContainer cpc)
194-
{
195-
Guid riid = typeof(IVsTextViewEvents).GUID;
196-
cpc.FindConnectionPoint(ref riid, out IConnectionPoint cp);
197-
return cp;
198-
}
199-
else
200-
{
201-
throw new InvalidOperationException("No IConnectionPointContainer.");
202-
}
199+
return textView.TextBuffer.Properties.GetProperty<ITextDocument>(typeof(ITextDocument)).FilePath;
203200
}
204-
private void WindowEvents_WindowActivated(Window GotFocus, Window LostFocus)
201+
private void Subscribe()
205202
{
206203
// Unsubscribe the previously focused window.
207-
if (LostFocus != null && previousWindow != null)
204+
if (wpfTextView != null)
208205
{
209-
if (previousWindow != LostFocus)
210-
{
211-
throw new InvalidOperationException("Unknown previous window.");
212-
}
213-
214-
GetConnectionPoint(previousTextView).Unadvise(previousCookie);
206+
wpfTextView.Caret.PositionChanged -= Caret_PositionChanged;
207+
wpfTextView.LayoutChanged -= WpfTextView_LayoutChanged;
208+
wpfTextView = null;
215209
}
216210

217211
// Subsribe the currently focused window.
218-
if (GotFocus != null)
219-
{
220-
previousWindow = GotFocus;
221-
ErrorHandler.ThrowOnFailure(textManager.GetActiveView(0, null, out previousTextView));
222-
GetConnectionPoint(previousTextView).Advise(this, out previousCookie);
223-
}
212+
ErrorHandler.ThrowOnFailure(textManager.GetActiveView(0, null, out IVsTextView textView));
213+
wpfTextView = editor.GetWpfTextView(textView);
214+
wpfTextView.Caret.PositionChanged += Caret_PositionChanged;
215+
wpfTextView.LayoutChanged += WpfTextView_LayoutChanged;
216+
217+
Update(GetFilePath(wpfTextView));
224218
}
225-
private void DocumentEvents_DocumentSaved(Document Document)
219+
220+
private void WpfTextView_LayoutChanged(object sender, TextViewLayoutChangedEventArgs e)
226221
{
227-
statusBar.SetText("Document saved: " + Document.FullName + " (" + DateTime.Now.ToLongTimeString() + ").");
222+
Update(GetFilePath(wpfTextView));
228223
}
229-
#endregion
230-
231-
#region Implementation of `IVsTextViewEvents`
232-
public void OnSetFocus(IVsTextView pView) { }
233-
public void OnKillFocus(IVsTextView pView) { }
234-
public void OnSetBuffer(IVsTextView pView, IVsTextLines pBuffer) { }
235-
public void OnChangeScrollInfo(IVsTextView pView, int iBar, int iMinUnit, int iMaxUnits, int iVisibleUnits, int iFirstVisibleUnit)
224+
private void Caret_PositionChanged(object sender, CaretPositionChangedEventArgs e)
225+
{
226+
Update(GetFilePath(e.TextView));
227+
}
228+
private void DocumentEvents_DocumentSaved(Document Document)
236229
{
237-
// TODO: Doesn't fire.
238-
statusBar.SetText("Scrolling...");
230+
Update(Document.FullName);
239231
}
240-
public void OnChangeCaretLine(IVsTextView pView, int iNewLine, int iOldLine)
232+
private void Update(string path, [CallerMemberName] string message = null)
241233
{
242-
// TODO: Doesn't fire.
243-
statusBar.SetText("Changing caret...");
234+
statusBar.SetText(message + ": " + path + " (" + DateTime.Now.ToString("o") + ").");
244235
}
245236
#endregion
246237
}

0 commit comments

Comments
 (0)