Skip to content

Commit 34aa22c

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

File tree

3 files changed

+53
-89
lines changed

3 files changed

+53
-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: 52 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
}
@@ -118,7 +113,7 @@ public RemoveTrailingWhitespacesPackage()
118113
/////////////////////////////////////////////////////////////////////////////
119114
// Overridden Package Implementation
120115
#region Package Members
121-
public DTE dte;
116+
public _DTE dte;
122117
public IVsRunningDocumentTable rdt;
123118
public IFindService findService;
124119
private uint rdtCookie;
@@ -130,7 +125,7 @@ public RemoveTrailingWhitespacesPackage()
130125
/// </summary>
131126
protected override async Task InitializeAsync(System.Threading.CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
132127
{
133-
dte = await GetServiceAsync(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
128+
dte = await GetServiceAsync(typeof(_DTE)) as _DTE;
134129
Assumes.Present(dte);
135130
rdt = await GetServiceAsync(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable;
136131
Assumes.Present(rdt);
@@ -186,7 +181,9 @@ private void OnRemoveTrailingWhitespacesPressed(object sender, EventArgs e)
186181
{
187182
if (dte.ActiveDocument == null) return;
188183
if (!(dte.ActiveDocument.Object() is TextDocument textDocument)) return;
189-
RemoveTrailingWhiteSpaces(textDocument);
184+
185+
uint docCookie = GetDocCookie(dte.ActiveDocument.FullName);
186+
RemoveTrailingWhiteSpaces(docCookie);
190187
}
191188

192189
private IFinder GetFinder(string findWhat, string replacement, ITextBuffer textBuffer)
@@ -196,33 +193,12 @@ private IFinder GetFinder(string findWhat, string replacement, ITextBuffer textB
196193
return finderFactory.Create(textBuffer.CurrentSnapshot);
197194
}
198195

199-
internal static ITextBuffer GettextBufferAt(TextDocument textDocument, IComponentModel componentModel, IServiceProvider serviceProvider)
196+
internal static ITextBuffer GettextBufferAt(IVsTextBuffer textBuffer, IComponentModel componentModel)
200197
{
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;
198+
var editorAdapterFactoryService = componentModel.GetService<IVsEditorAdaptersFactoryService>();
199+
return editorAdapterFactoryService.GetDataBuffer(textBuffer);
225200
}
201+
226202
private static void ReplaceAll(ITextBuffer textBuffer, IEnumerable<FinderReplacement> replacements)
227203
{
228204
if (replacements.Any())
@@ -239,9 +215,49 @@ private static void ReplaceAll(ITextBuffer textBuffer, IEnumerable<FinderReplace
239215
}
240216
}
241217

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

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)