Skip to content

Commit 3d0d336

Browse files
Fixed: removing trailing workspaces did not work on document save
1 parent 934f165 commit 3d0d336

File tree

3 files changed

+58
-89
lines changed

3 files changed

+58
-89
lines changed

RemoveTrailingWhitespaces/RemoveTrailingWhitespaces.csproj

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -62,58 +62,6 @@
6262
<WarningLevel>4</WarningLevel>
6363
<RunCodeAnalysis>true</RunCodeAnalysis>
6464
</PropertyGroup>
65-
<ItemGroup>
66-
<Reference Include="envdte100, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
67-
<EmbedInteropTypes>True</EmbedInteropTypes>
68-
</Reference>
69-
<Reference Include="envdte80, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
70-
<EmbedInteropTypes>True</EmbedInteropTypes>
71-
</Reference>
72-
<Reference Include="envdte90, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
73-
<EmbedInteropTypes>True</EmbedInteropTypes>
74-
</Reference>
75-
<Reference Include="Microsoft.CSharp" />
76-
<Reference Include="Microsoft.VisualStudio.OLE.Interop" />
77-
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0" />
78-
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.11.0" />
79-
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.12.0" />
80-
<Reference Include="Microsoft.VisualStudio.Shell.Interop, Version=17.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
81-
<Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0, Version=17.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
82-
<Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0, Version=17.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
83-
<Reference Include="Microsoft.VisualStudio.TextManager.Interop, Version=17.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
84-
<Reference Include="Microsoft.VisualStudio.TextManager.Interop.12.0, Version=17.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
85-
<Reference Include="netstandard" />
86-
<Reference Include="PresentationCore" />
87-
<Reference Include="PresentationFramework" />
88-
<Reference Include="System" />
89-
<Reference Include="System.ComponentModel.Composition" />
90-
<Reference Include="System.Configuration" />
91-
<Reference Include="System.Core" />
92-
<Reference Include="System.Data" />
93-
<Reference Include="System.Data.Linq" />
94-
<Reference Include="System.Design" />
95-
<Reference Include="System.Drawing" />
96-
<Reference Include="System.Drawing.Design" />
97-
<Reference Include="System.Management" />
98-
<Reference Include="System.Numerics" />
99-
<Reference Include="System.Transactions" />
100-
<Reference Include="System.Windows.Forms" />
101-
<Reference Include="System.Xaml" />
102-
<Reference Include="System.Xml" />
103-
<Reference Include="UIAutomationProvider" />
104-
<Reference Include="WindowsBase" />
105-
</ItemGroup>
106-
<ItemGroup>
107-
<COMReference Include="stdole">
108-
<Guid>{00020430-0000-0000-C000-000000000046}</Guid>
109-
<VersionMajor>2</VersionMajor>
110-
<VersionMinor>0</VersionMinor>
111-
<Lcid>0</Lcid>
112-
<WrapperTool>primary</WrapperTool>
113-
<Isolated>False</Isolated>
114-
<EmbedInteropTypes>False</EmbedInteropTypes>
115-
</COMReference>
116-
</ItemGroup>
11765
<ItemGroup>
11866
<Compile Include="Guids.cs" />
11967
<Compile Include="PkcCmdIDList.cs" />

RemoveTrailingWhitespaces/RemoveTrailingWhitespacesPackage.cs

Lines changed: 57 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,7 @@ public int OnBeforeSave(uint docCookie)
4747
{
4848
if (_pkg.RemoveOnSave())
4949
{
50-
RunningDocumentInfo runningDocumentInfo = new RunningDocumentInfo(_pkg.rdt, docCookie);
51-
EnvDTE.Document document = _pkg.dte.Documents.OfType<EnvDTE.Document>().SingleOrDefault(x => x.FullName == runningDocumentInfo.Moniker);
52-
if (document == null)
53-
return VSConstants.S_OK;
54-
if (document.Object("TextDocument") is TextDocument textDoc)
55-
_pkg.RemoveTrailingWhiteSpaces(textDoc);
50+
_pkg.RemoveTrailingWhiteSpaces(docCookie);
5651
}
5752
return VSConstants.S_OK;
5853
}
@@ -100,6 +95,11 @@ public int OnBeforeLastDocumentUnlock(uint docCookie, uint dwRDTLockType, uint d
10095
[ProvideOptionPage(typeof(OptionsPage), "Remove Trailing Whitespaces", "Options", 1000, 1001, true)]
10196
[ProvideMenuResource("Menus.ctmenu", 1)]
10297
[ProvideAutoLoad("{f1536ef8-92ec-443c-9ed7-fdadf150da82}", PackageAutoLoadFlags.BackgroundLoad)]
98+
[ProvideUIContextRule("{f1536ef8-92ec-443c-9ed7-fdadf150da82}",
99+
name: "Trigger for autoloading the RemoveTrailingWhitespaces extension",
100+
expression: "DocOpen",
101+
termNames: new[] { "DocOpen" },
102+
termValues: new[] { "HierSingleSelectionName:.$" })]
103103
public sealed class RemoveTrailingWhitespacesPackage : AsyncPackage
104104
{
105105
/// <summary>
@@ -118,7 +118,7 @@ public RemoveTrailingWhitespacesPackage()
118118
/////////////////////////////////////////////////////////////////////////////
119119
// Overridden Package Implementation
120120
#region Package Members
121-
public DTE dte;
121+
public _DTE dte;
122122
public IVsRunningDocumentTable rdt;
123123
public IFindService findService;
124124
private uint rdtCookie;
@@ -130,7 +130,7 @@ public RemoveTrailingWhitespacesPackage()
130130
/// </summary>
131131
protected override async Task InitializeAsync(System.Threading.CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
132132
{
133-
dte = await GetServiceAsync(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
133+
dte = await GetServiceAsync(typeof(_DTE)) as _DTE;
134134
Assumes.Present(dte);
135135
rdt = await GetServiceAsync(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable;
136136
Assumes.Present(rdt);
@@ -186,7 +186,9 @@ private void OnRemoveTrailingWhitespacesPressed(object sender, EventArgs e)
186186
{
187187
if (dte.ActiveDocument == null) return;
188188
if (!(dte.ActiveDocument.Object() is TextDocument textDocument)) return;
189-
RemoveTrailingWhiteSpaces(textDocument);
189+
190+
uint docCookie = GetDocCookie(dte.ActiveDocument.FullName);
191+
RemoveTrailingWhiteSpaces(docCookie);
190192
}
191193

192194
private IFinder GetFinder(string findWhat, string replacement, ITextBuffer textBuffer)
@@ -196,33 +198,12 @@ private IFinder GetFinder(string findWhat, string replacement, ITextBuffer textB
196198
return finderFactory.Create(textBuffer.CurrentSnapshot);
197199
}
198200

199-
internal static ITextBuffer GettextBufferAt(TextDocument textDocument, IComponentModel componentModel, IServiceProvider serviceProvider)
201+
internal static ITextBuffer GettextBufferAt(IVsTextBuffer textBuffer, IComponentModel componentModel)
200202
{
201-
ThreadHelper.ThrowIfNotOnUIThread();
202-
IVsWindowFrame windowFrame;
203-
if (VsShellUtilities.IsDocumentOpen(
204-
serviceProvider,
205-
textDocument.Parent.FullName,
206-
Guid.Empty,
207-
out var _,
208-
out var _,
209-
out windowFrame))
210-
{
211-
IVsTextView view = VsShellUtilities.GetTextView(windowFrame);
212-
IVsTextLines lines;
213-
if (view.GetBuffer(out lines) == 0)
214-
{
215-
var buffer = lines as IVsTextBuffer;
216-
if (buffer != null)
217-
{
218-
var editorAdapterFactoryService = componentModel.GetService<IVsEditorAdaptersFactoryService>();
219-
return editorAdapterFactoryService.GetDataBuffer(buffer);
220-
}
221-
}
222-
}
223-
224-
return null;
203+
var editorAdapterFactoryService = componentModel.GetService<IVsEditorAdaptersFactoryService>();
204+
return editorAdapterFactoryService.GetDataBuffer(textBuffer);
225205
}
206+
226207
private static void ReplaceAll(ITextBuffer textBuffer, IEnumerable<FinderReplacement> replacements)
227208
{
228209
if (replacements.Any())
@@ -239,9 +220,49 @@ private static void ReplaceAll(ITextBuffer textBuffer, IEnumerable<FinderReplace
239220
}
240221
}
241222

242-
public void RemoveTrailingWhiteSpaces(TextDocument textDocument)
223+
public uint GetDocCookie(string docFullName)
243224
{
244-
var textBuffer = GettextBufferAt(textDocument, componentModel, this);
225+
IVsHierarchy hierarchy = null;
226+
uint itemid = 0;
227+
IntPtr docDataUnk = IntPtr.Zero;
228+
uint lockCookie = 0;
229+
230+
IEnumRunningDocuments allDocs;
231+
if (VSConstants.S_OK != rdt.GetRunningDocumentsEnum(out allDocs))
232+
return 0;
233+
uint[] array = new uint[1];
234+
uint pceltFetched = 0;
235+
while (VSConstants.S_OK == allDocs.Next(1, array, out pceltFetched) && (pceltFetched == 1))
236+
{
237+
uint pgrfRDTFlags;
238+
uint pdwReadLocks;
239+
uint pdwEditLocks;
240+
string pbstrMkDocument;
241+
IVsHierarchy ppHier;
242+
uint pitemid;
243+
IntPtr ppunkDocData;
244+
rdt.GetDocumentInfo(array[0], out pgrfRDTFlags, out pdwReadLocks, out pdwEditLocks, out pbstrMkDocument, out ppHier, out pitemid, out ppunkDocData);
245+
if (pbstrMkDocument == docFullName)
246+
return array[0];
247+
}
248+
249+
return 0;
250+
}
251+
252+
public void RemoveTrailingWhiteSpaces(uint docCookie)
253+
{
254+
RunningDocumentInfo runningDocumentInfo = new RunningDocumentInfo(rdt, docCookie);
255+
256+
IVsHierarchy hierarchy = null;
257+
uint itemid = 0;
258+
IntPtr docDataUnk = IntPtr.Zero;
259+
uint lockCookie = 0;
260+
261+
int hr = rdt.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_ReadLock, runningDocumentInfo.Moniker, out hierarchy, out itemid, out docDataUnk, out lockCookie);
262+
if (hr != VSConstants.S_OK || !(Marshal.GetUniqueObjectForIUnknown(docDataUnk) is IVsTextBuffer vsTextBuffer))
263+
return;
264+
265+
var textBuffer = GettextBufferAt(vsTextBuffer, componentModel);
245266
ReplaceAll(textBuffer, GetFinder("[^\\S\\r\\n]+(?=\\r?$)", "", textBuffer).FindForReplaceAll());
246267
}
247268

RemoveTrailingWhitespaces/source.extension.vsixmanifest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
33
<Metadata>
4-
<Identity Id="22c372db-a793-4294-9fdb-83228aaf2a23" Version="1.05" Language="en-US" Publisher="Predelnik" />
4+
<Identity Id="22c372db-a793-4294-9fdb-83228aaf2a23" Version="1.06" Language="en-US" Publisher="Predelnik" />
55
<DisplayName>RemoveTrailingWhitespaces</DisplayName>
66
<Description>Trailing whitespace removal tool. Removes either manually or on file save.</Description>
77
<License>LICENSE.txt</License>

0 commit comments

Comments
 (0)