99using Microsoft . VisualStudio . OLE . Interop ;
1010using Microsoft . VisualStudio . Shell ;
1111using System . ComponentModel ;
12+ using System . Linq ;
1213using EnvDTE ;
1314
1415namespace Predelnik . RemoveTrailingWhitespaces
@@ -26,6 +27,51 @@ public bool RemoveTrailingWhitespacesOnSave
2627 }
2728 } ;
2829
30+ internal class RunningDocTableEvents : IVsRunningDocTableEvents3
31+ {
32+ RemoveTrailingWhitespacesPackage _pkg ;
33+
34+ public RunningDocTableEvents ( RemoveTrailingWhitespacesPackage pkg )
35+ {
36+ _pkg = pkg ;
37+ }
38+
39+ public int OnBeforeSave ( uint docCookie )
40+ {
41+ if ( _pkg . removeOnSave ( ) )
42+ {
43+ RunningDocumentInfo runningDocumentInfo = _pkg . rdt . GetDocumentInfo ( docCookie ) ;
44+ EnvDTE . Document document = _pkg . dte . Documents . OfType < EnvDTE . Document > ( ) . SingleOrDefault ( x => x . FullName == runningDocumentInfo . Moniker ) ;
45+ var textDoc = document . Object ( "TextDocument" ) as TextDocument ;
46+ if ( textDoc != null )
47+ RemoveTrailingWhitespacesPackage . removeTrailingWhiteSpaces ( textDoc ) ;
48+ }
49+ return VSConstants . S_OK ;
50+ }
51+
52+ public int OnAfterAttributeChange ( uint docCookie , uint grfAttribs ) { return VSConstants . S_OK ; }
53+ public int OnAfterAttributeChangeEx ( uint docCookie , uint grfAttribs , IVsHierarchy pHierOld ,
54+ uint itemidOld , string pszMkDocumentOld , IVsHierarchy pHierNew ,
55+ uint itemidNew , string pszMkDocumentNew )
56+ {
57+ return VSConstants . S_OK ;
58+ }
59+
60+ public int OnAfterDocumentWindowHide ( uint docCookie , IVsWindowFrame pFrame ) { return VSConstants . S_OK ; }
61+ public int OnAfterFirstDocumentLock ( uint docCookie , uint dwRDTLockType , uint dwReadLocksRemaining , uint dwEditLocksRemaining )
62+ {
63+ return VSConstants . S_OK ;
64+ }
65+
66+ public int OnAfterSave ( uint docCookie ) { return VSConstants . S_OK ; }
67+ public int OnBeforeDocumentWindowShow ( uint docCookie , int fFirstShow , IVsWindowFrame pFrame ) { return VSConstants . S_OK ; }
68+
69+ public int OnBeforeLastDocumentUnlock ( uint docCookie , uint dwRDTLockType , uint dwReadLocksRemaining , uint dwEditLocksRemaining )
70+ {
71+ return VSConstants . S_OK ;
72+ }
73+ }
74+
2975 /// <summary>
3076 /// This is the class that implements the package exposed by this assembly.
3177 ///
@@ -64,11 +110,10 @@ public RemoveTrailingWhitespacesPackage()
64110 /////////////////////////////////////////////////////////////////////////////
65111 // Overridden Package Implementation
66112 #region Package Members
67- private DTE _dte ;
113+ public DTE dte ;
68114 private Properties _props ;
69- DocumentEvents _docEvents ;
70- Events _events ;
71115 bool _actionAppliedFlag = false ;
116+ public RunningDocumentTable rdt ;
72117
73118 /// <summary>
74119 /// Initialization of the package; this method is called right after the package is sited, so this is the place
@@ -78,11 +123,10 @@ protected override void Initialize()
78123 {
79124 Debug . WriteLine ( string . Format ( CultureInfo . CurrentCulture , "Entering Initialize() of: {0}" , this . ToString ( ) ) ) ;
80125 base . Initialize ( ) ;
81- _dte = GetGlobalService ( typeof ( EnvDTE . DTE ) ) as EnvDTE . DTE ;
82- _props = _dte . get_Properties ( "Remove Trailing Whitespaces" , "Options" ) ;
83- _events = _dte . Events ;
84- _docEvents = _events . DocumentEvents ;
85- _docEvents . DocumentSaved += onDocumentSaved ;
126+ dte = GetGlobalService ( typeof ( EnvDTE . DTE ) ) as EnvDTE . DTE ;
127+ _props = dte . get_Properties ( "Remove Trailing Whitespaces" , "Options" ) ;
128+ rdt = new RunningDocumentTable ( this ) ;
129+ rdt . Advise ( new RunningDocTableEvents ( this ) ) ;
86130 var mcs = GetService ( typeof ( IMenuCommandService ) ) as OleMenuCommandService ;
87131 if ( mcs != null )
88132 {
@@ -105,7 +149,7 @@ private void onBeforeQueryStatus(object sender, EventArgs e)
105149
106150 private bool isNeededForActiveDocument ( )
107151 {
108- var doc = _dte . ActiveDocument ;
152+ var doc = dte . ActiveDocument ;
109153 if ( doc == null )
110154 {
111155 return false ;
@@ -127,43 +171,18 @@ private bool isNeededForActiveDocument()
127171
128172 private void onRemoveTrailingWhitespacesPressed ( object sender , EventArgs e )
129173 {
130- if ( _dte . ActiveDocument == null ) return ;
131- var textDocument = _dte . ActiveDocument . Object ( ) as TextDocument ;
174+ if ( dte . ActiveDocument == null ) return ;
175+ var textDocument = dte . ActiveDocument . Object ( ) as TextDocument ;
132176 if ( textDocument == null ) return ;
133177 removeTrailingWhiteSpaces ( textDocument ) ;
134178 }
135179
136- private void onDocumentSaved ( Document Document )
137- {
138- if ( Document == null || ! removeOnSave ( ) )
139- return ;
140- var textDocument = Document . Object ( ) as TextDocument ;
141- if ( textDocument == null ) return ;
142-
143- if ( ! _actionAppliedFlag )
144- {
145- try
146- {
147- removeTrailingWhiteSpaces ( textDocument ) ;
148- _actionAppliedFlag = true ;
149- Document . Save ( ) ;
150- }
151- catch ( Exception ex )
152- {
153- Debug . Print ( "Trailing Whitespace Removal Exception: " + ex . Message ) ;
154- }
155- }
156- else
157- _actionAppliedFlag = false ;
158-
159- }
160-
161- private static void removeTrailingWhiteSpaces ( TextDocument textDocument )
180+ public static void removeTrailingWhiteSpaces ( TextDocument textDocument )
162181 {
163182 textDocument . ReplacePattern ( "[^\\ S\\ r\\ n]+(?=\\ r?$)" , "" , ( int ) vsFindOptions . vsFindOptionsRegularExpression ) ;
164183 }
165184
166- private bool removeOnSave ( )
185+ public bool removeOnSave ( )
167186 {
168187 return ( bool ) _props . Item ( "RemoveTrailingWhitespacesOnSave" ) . Value ;
169188 }
0 commit comments