@@ -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
0 commit comments