2
2
using System . Collections . Generic ;
3
3
using System . Linq ;
4
4
using System . Text . RegularExpressions ;
5
- using Antlr4 . Runtime ;
6
- using Rubberduck . Common ;
7
5
using Rubberduck . Parsing ;
8
- using Rubberduck . Parsing . Symbols ;
6
+ using Rubberduck . Parsing . Grammar ;
9
7
using Rubberduck . Parsing . VBA ;
10
8
using Rubberduck . VBEditor ;
11
9
using Rubberduck . VBEditor . SafeComWrappers ;
@@ -17,14 +15,12 @@ namespace Rubberduck.Navigation.RegexSearchReplace
17
15
public class RegexSearchReplace : IRegexSearchReplace
18
16
{
19
17
private readonly IVBE _vbe ;
20
- private readonly IDeclarationFinderProvider _declarationFinderProvider ;
21
18
private readonly ISelectionService _selectionService ;
22
19
private readonly ISelectedDeclarationProvider _selectedDeclarationProvider ;
23
20
24
- public RegexSearchReplace ( IVBE vbe , IDeclarationFinderProvider declarationFinderProvider , ISelectionService selectionService , ISelectedDeclarationProvider selectedDeclarationProvider )
21
+ public RegexSearchReplace ( IVBE vbe , ISelectionService selectionService , ISelectedDeclarationProvider selectedDeclarationProvider )
25
22
{
26
23
_vbe = vbe ;
27
- _declarationFinderProvider = declarationFinderProvider ;
28
24
_selectionService = selectionService ;
29
25
_selectedDeclarationProvider = selectedDeclarationProvider ;
30
26
_search = new Dictionary < RegexSearchReplaceScope , Func < string , IEnumerable < RegexSearchResult > > >
@@ -84,22 +80,80 @@ private IEnumerable<RegexSearchResult> GetResultsFromModule(ICodeModule module,
84
80
// VBA uses 1-based indexing
85
81
for ( var i = 1 ; i <= module . CountOfLines ; i ++ )
86
82
{
87
- var matches =
88
- Regex . Matches ( module . GetLines ( i , 1 ) , searchPattern )
89
- . OfType < Match > ( )
83
+ var codeLine = module . GetLines ( i , 1 ) ;
84
+ var matches = LineMatches ( codeLine , searchPattern )
90
85
. Select ( m => new RegexSearchResult ( m , module , i ) ) ;
91
86
92
87
results . AddRange ( matches ) ;
93
88
}
94
89
return results ;
95
90
}
96
91
92
+ private IEnumerable < Match > LineMatches ( string line , string searchPattern )
93
+ {
94
+ return Regex . Matches ( line , searchPattern )
95
+ . OfType < Match > ( ) ;
96
+ }
97
+
98
+ private IEnumerable < Match > LineMatches ( string line , int startColumn , int ? endColumn , string searchPattern )
99
+ {
100
+ var shortenedLine = endColumn . HasValue
101
+ ? line . Substring ( startColumn - 1 , endColumn . Value - startColumn + 1 )
102
+ : line . Substring ( startColumn - 1 ) ;
103
+ return LineMatches ( shortenedLine , searchPattern ) ;
104
+ }
105
+
106
+ private IEnumerable < RegexSearchResult > GetResultsFromModule ( ICodeModule module , string searchPattern , Selection selection )
107
+ {
108
+ var startLine = selection . StartLine > 1
109
+ ? selection . StartLine
110
+ : 1 ;
111
+
112
+ var moduleLines = module . CountOfLines ;
113
+ var stopLine = selection . EndLine < moduleLines
114
+ ? selection . EndLine
115
+ : moduleLines ;
116
+
117
+ if ( startLine > stopLine )
118
+ {
119
+ return new List < RegexSearchResult > ( ) ;
120
+ }
121
+
122
+ if ( startLine == stopLine )
123
+ {
124
+ return LineMatches ( module . GetLines ( startLine , 1 ) , selection . StartColumn , null , searchPattern )
125
+ . Select ( m => new RegexSearchResult ( m , module , startLine , selection . StartColumn - 1 ) )
126
+ . ToList ( ) ;
127
+ }
128
+
129
+ var results = new List < RegexSearchResult > ( ) ;
130
+
131
+ var firstLineMatches = LineMatches ( module . GetLines ( startLine , 1 ) , selection . StartColumn , selection . EndColumn , searchPattern )
132
+ . Select ( m => new RegexSearchResult ( m , module , startLine ) ) ;
133
+ results . AddRange ( firstLineMatches ) ;
134
+
135
+ for ( var lineIndex = startLine + 1 ; lineIndex < stopLine ; lineIndex ++ )
136
+ {
137
+ var codeLine = module . GetLines ( lineIndex , 1 ) ;
138
+ var matches = LineMatches ( codeLine , searchPattern )
139
+ . Select ( m => new RegexSearchResult ( m , module , lineIndex ) ) ;
140
+
141
+ results . AddRange ( matches ) ;
142
+ }
143
+
144
+ var lastLineMatches = LineMatches ( module . GetLines ( stopLine , 1 ) , 1 , selection . EndColumn , searchPattern )
145
+ . Select ( m => new RegexSearchResult ( m , module , stopLine ) ) ;
146
+ results . AddRange ( lastLineMatches ) ;
147
+
148
+ return results ;
149
+ }
150
+
97
151
private void SetSelection ( RegexSearchResult item )
98
152
{
99
153
_selectionService . TrySetActiveSelection ( item . Module . QualifiedModuleName , item . Selection ) ;
100
154
}
101
155
102
- private List < RegexSearchResult > SearchSelection ( string searchPattern )
156
+ private IEnumerable < RegexSearchResult > SearchSelection ( string searchPattern )
103
157
{
104
158
using ( var pane = _vbe . ActiveCodePane )
105
159
{
@@ -110,23 +164,30 @@ private List<RegexSearchResult> SearchSelection(string searchPattern)
110
164
111
165
using ( var module = pane . CodeModule )
112
166
{
113
- var results = GetResultsFromModule ( module , searchPattern ) ;
114
- return results . Where ( r => pane . Selection . Contains ( r . Selection ) ) . ToList ( ) ;
167
+ return GetResultsFromModule ( module , searchPattern , pane . Selection ) ;
115
168
}
116
169
}
117
170
}
118
171
119
- private List < RegexSearchResult > SearchCurrentBlock ( string searchPattern )
172
+ private IEnumerable < RegexSearchResult > SearchCurrentBlock ( string searchPattern )
120
173
{
121
- var declarationTypes = new [ ]
122
- {
123
- DeclarationType . Event ,
124
- DeclarationType . Function ,
125
- DeclarationType . Procedure ,
126
- DeclarationType . PropertyGet ,
127
- DeclarationType . PropertyLet ,
128
- DeclarationType . PropertySet
129
- } ;
174
+ var activeSelection = _selectionService . ActiveSelection ( ) ;
175
+ if ( ! activeSelection . HasValue )
176
+ {
177
+ return new List < RegexSearchResult > ( ) ;
178
+ }
179
+
180
+ var block = _selectedDeclarationProvider
181
+ . SelectedMember ( activeSelection . Value )
182
+ ? . Context
183
+ . GetSmallestDescendentContainingSelection < VBAParser . BlockContext > ( activeSelection . Value . Selection ) ;
184
+
185
+ if ( block == null )
186
+ {
187
+ return new List < RegexSearchResult > ( ) ;
188
+ }
189
+
190
+ var blockSelection = block . GetSelection ( ) ;
130
191
131
192
using ( var pane = _vbe . ActiveCodePane )
132
193
{
@@ -137,24 +198,8 @@ private List<RegexSearchResult> SearchCurrentBlock(string searchPattern)
137
198
138
199
using ( var module = pane . CodeModule )
139
200
{
140
- var results = GetResultsFromModule ( module , searchPattern ) ;
141
-
142
- var qualifiedSelection = pane . GetQualifiedSelection ( ) ;
143
-
144
- if ( ! qualifiedSelection . HasValue )
145
- {
146
- return new List < RegexSearchResult > ( ) ;
147
- }
148
-
149
- var block = ( ParserRuleContext ) _declarationFinderProvider . DeclarationFinder
150
- . AllDeclarations
151
- . FindTarget ( qualifiedSelection . Value , declarationTypes )
152
- . Context
153
- . Parent ;
154
- var selection = new Selection ( block . Start . Line , block . Start . Column , block . Stop . Line ,
155
- block . Stop . Column ) ;
156
-
157
- return results . Where ( r => selection . Contains ( r . Selection ) ) . ToList ( ) ;
201
+ //FIXME: This is a catastrophe waiting to happen since the module, which will get disposed, is saved on the result.
202
+ return GetResultsFromModule ( module , searchPattern , blockSelection ) ;
158
203
}
159
204
}
160
205
}
0 commit comments