@@ -5,16 +5,57 @@ const escapeHelper = require('../escape-helper')
5
5
class Result {
6
6
static create ( result ) {
7
7
if ( result && result . matches && result . matches . length ) {
8
- const matches = result . matches . map ( m =>
9
- ( {
10
- matchText : m . matchText ,
11
- lineText : m . lineText ,
12
- lineTextOffset : m . lineTextOffset ,
13
- range : Range . fromObject ( m . range ) ,
14
- leadingContextLines : m . leadingContextLines ,
15
- trailingContextLines : m . trailingContextLines
16
- } )
17
- )
8
+ const matches = [ ]
9
+
10
+ for ( const m of result . matches ) {
11
+ const range = Range . fromObject ( m . range )
12
+ const matchSplit = m . matchText . split ( '\n' )
13
+ const linesSplit = m . lineText . split ( '\n' )
14
+
15
+ // If the result spans across multiple lines, process each of
16
+ // them separately by creating separate `matches` objects for
17
+ // each line on the match.
18
+ for ( let row = range . start . row ; row <= range . end . row ; row ++ ) {
19
+ const lineText = linesSplit [ row - range . start . row ]
20
+ const matchText = matchSplit [ row - range . start . row ]
21
+
22
+ // When receiving multiline results from opened buffers, only
23
+ // the first result line is provided on the `lineText` property.
24
+ // This makes it impossible to properly render the part of the result
25
+ // that's part of other lines.
26
+ // In order to prevent an error we just need to ignore these parts.
27
+ if ( lineText === undefined || matchText === undefined ) {
28
+ continue
29
+ }
30
+
31
+ // Adapt the range column number based on which line we're at:
32
+ // - the first line of a multiline result will always start at the range start
33
+ // and will end at the end of the line.
34
+ // - middle lines will start at 0 and end at the end of the line
35
+ // - last line will start at 0 and end at the range end.
36
+ const startColumn = row === range . start . row ? range . start . column : 0
37
+ const endColumn = row === range . end . row ? range . end . column : lineText . length
38
+
39
+ matches . push ( {
40
+ matchText,
41
+ lineText,
42
+ lineTextOffset : m . lineTextOffset ,
43
+ range : {
44
+ start : {
45
+ row,
46
+ column : startColumn
47
+ } ,
48
+ end : {
49
+ row,
50
+ column : endColumn
51
+ }
52
+ } ,
53
+ leadingContextLines : m . leadingContextLines ,
54
+ trailingContextLines : m . trailingContextLines
55
+ } )
56
+ }
57
+ }
58
+
18
59
return new Result ( { filePath : result . filePath , matches} )
19
60
} else {
20
61
return null
@@ -146,7 +187,7 @@ module.exports = class ResultsModel {
146
187
)
147
188
}
148
189
149
- search ( findPattern , pathsPattern , replacePattern , options = { } ) {
190
+ async search ( findPattern , pathsPattern , replacePattern , options = { } ) {
150
191
if ( ! this . shouldRerunSearch ( findPattern , pathsPattern , options ) ) {
151
192
this . emitter . emit ( 'did-noop-search' )
152
193
return Promise . resolve ( )
@@ -195,17 +236,18 @@ module.exports = class ResultsModel {
195
236
} )
196
237
197
238
this . emitter . emit ( 'did-start-searching' , this . inProgressSearchPromise )
198
- return this . inProgressSearchPromise . then ( message => {
199
- if ( message === 'cancelled' ) {
200
- this . emitter . emit ( 'did-cancel-searching' )
201
- } else {
202
- const resultsSummary = this . getResultsSummary ( )
203
239
204
- this . metricsReporter . sendSearchEvent ( Date . now ( ) - startTime , resultsSummary . matchCount )
205
- this . inProgressSearchPromise = null
206
- this . emitter . emit ( 'did-finish-searching' , resultsSummary )
207
- }
208
- } )
240
+ const message = await this . inProgressSearchPromise
241
+
242
+ if ( message === 'cancelled' ) {
243
+ this . emitter . emit ( 'did-cancel-searching' )
244
+ } else {
245
+ const resultsSummary = this . getResultsSummary ( )
246
+
247
+ this . metricsReporter . sendSearchEvent ( Date . now ( ) - startTime , resultsSummary . matchCount )
248
+ this . inProgressSearchPromise = null
249
+ this . emitter . emit ( 'did-finish-searching' , resultsSummary )
250
+ }
209
251
}
210
252
211
253
replace ( pathsPattern , replacePattern , replacementPaths ) {
0 commit comments