Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/contrib/find/test/browser/findModel.test.ts
4780 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import assert from 'assert';
7
import { DisposableStore } from '../../../../../base/common/lifecycle.js';
8
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
9
import { CoreNavigationCommands } from '../../../../browser/coreCommands.js';
10
import { IActiveCodeEditor, ICodeEditor } from '../../../../browser/editorBrowser.js';
11
import { Position } from '../../../../common/core/position.js';
12
import { Range } from '../../../../common/core/range.js';
13
import { Selection } from '../../../../common/core/selection.js';
14
import { PieceTreeTextBufferBuilder } from '../../../../common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.js';
15
import { FindModelBoundToEditorModel } from '../../browser/findModel.js';
16
import { FindReplaceState } from '../../browser/findState.js';
17
import { withTestCodeEditor } from '../../../../test/browser/testCodeEditor.js';
18
19
suite('FindModel', () => {
20
21
let disposables: DisposableStore;
22
23
setup(() => {
24
disposables = new DisposableStore();
25
});
26
27
teardown(() => {
28
disposables.dispose();
29
});
30
31
ensureNoDisposablesAreLeakedInTestSuite();
32
33
function findTest(testName: string, callback: (editor: IActiveCodeEditor) => void): void {
34
test(testName, () => {
35
const textArr = [
36
'// my cool header',
37
'#include "cool.h"',
38
'#include <iostream>',
39
'',
40
'int main() {',
41
' cout << "hello world, Hello!" << endl;',
42
' cout << "hello world again" << endl;',
43
' cout << "Hello world again" << endl;',
44
' cout << "helloworld again" << endl;',
45
'}',
46
'// blablablaciao',
47
''
48
];
49
withTestCodeEditor(textArr, {}, (editor) => callback(editor as IActiveCodeEditor));
50
51
const text = textArr.join('\n');
52
const ptBuilder = new PieceTreeTextBufferBuilder();
53
ptBuilder.acceptChunk(text.substr(0, 94));
54
ptBuilder.acceptChunk(text.substr(94, 101));
55
ptBuilder.acceptChunk(text.substr(195, 59));
56
const factory = ptBuilder.finish();
57
withTestCodeEditor(
58
factory,
59
{},
60
(editor) => callback(editor as IActiveCodeEditor)
61
);
62
});
63
}
64
65
function fromRange(rng: Range): number[] {
66
return [rng.startLineNumber, rng.startColumn, rng.endLineNumber, rng.endColumn];
67
}
68
69
function _getFindState(editor: ICodeEditor) {
70
const model = editor.getModel()!;
71
const currentFindMatches: Range[] = [];
72
const allFindMatches: Range[] = [];
73
74
for (const dec of model.getAllDecorations()) {
75
if (dec.options.className === 'currentFindMatch') {
76
currentFindMatches.push(dec.range);
77
allFindMatches.push(dec.range);
78
} else if (dec.options.className === 'findMatch') {
79
allFindMatches.push(dec.range);
80
}
81
}
82
83
currentFindMatches.sort(Range.compareRangesUsingStarts);
84
allFindMatches.sort(Range.compareRangesUsingStarts);
85
86
return {
87
highlighted: currentFindMatches.map(fromRange),
88
findDecorations: allFindMatches.map(fromRange)
89
};
90
}
91
92
function assertFindState(editor: ICodeEditor, cursor: number[], highlighted: number[] | null, findDecorations: number[][]): void {
93
assert.deepStrictEqual(fromRange(editor.getSelection()!), cursor, 'cursor');
94
95
const expectedState = {
96
highlighted: highlighted ? [highlighted] : [],
97
findDecorations: findDecorations
98
};
99
assert.deepStrictEqual(_getFindState(editor), expectedState, 'state');
100
}
101
102
findTest('incremental find from beginning of file', (editor) => {
103
editor.setPosition({ lineNumber: 1, column: 1 });
104
const findState = disposables.add(new FindReplaceState());
105
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
106
107
// simulate typing the search string
108
findState.change({ searchString: 'H' }, true);
109
assertFindState(
110
editor,
111
[1, 12, 1, 13],
112
[1, 12, 1, 13],
113
[
114
[1, 12, 1, 13],
115
[2, 16, 2, 17],
116
[6, 14, 6, 15],
117
[6, 27, 6, 28],
118
[7, 14, 7, 15],
119
[8, 14, 8, 15],
120
[9, 14, 9, 15]
121
]
122
);
123
124
// simulate typing the search string
125
findState.change({ searchString: 'He' }, true);
126
assertFindState(
127
editor,
128
[1, 12, 1, 14],
129
[1, 12, 1, 14],
130
[
131
[1, 12, 1, 14],
132
[6, 14, 6, 16],
133
[6, 27, 6, 29],
134
[7, 14, 7, 16],
135
[8, 14, 8, 16],
136
[9, 14, 9, 16]
137
]
138
);
139
140
// simulate typing the search string
141
findState.change({ searchString: 'Hello' }, true);
142
assertFindState(
143
editor,
144
[6, 14, 6, 19],
145
[6, 14, 6, 19],
146
[
147
[6, 14, 6, 19],
148
[6, 27, 6, 32],
149
[7, 14, 7, 19],
150
[8, 14, 8, 19],
151
[9, 14, 9, 19]
152
]
153
);
154
155
// simulate toggling on `matchCase`
156
findState.change({ matchCase: true }, true);
157
assertFindState(
158
editor,
159
[6, 27, 6, 32],
160
[6, 27, 6, 32],
161
[
162
[6, 27, 6, 32],
163
[8, 14, 8, 19]
164
]
165
);
166
167
// simulate typing the search string
168
findState.change({ searchString: 'hello' }, true);
169
assertFindState(
170
editor,
171
[6, 14, 6, 19],
172
[6, 14, 6, 19],
173
[
174
[6, 14, 6, 19],
175
[7, 14, 7, 19],
176
[9, 14, 9, 19]
177
]
178
);
179
180
// simulate toggling on `wholeWord`
181
findState.change({ wholeWord: true }, true);
182
assertFindState(
183
editor,
184
[6, 14, 6, 19],
185
[6, 14, 6, 19],
186
[
187
[6, 14, 6, 19],
188
[7, 14, 7, 19]
189
]
190
);
191
192
// simulate toggling off `matchCase`
193
findState.change({ matchCase: false }, true);
194
assertFindState(
195
editor,
196
[6, 14, 6, 19],
197
[6, 14, 6, 19],
198
[
199
[6, 14, 6, 19],
200
[6, 27, 6, 32],
201
[7, 14, 7, 19],
202
[8, 14, 8, 19]
203
]
204
);
205
206
// simulate toggling off `wholeWord`
207
findState.change({ wholeWord: false }, true);
208
assertFindState(
209
editor,
210
[6, 14, 6, 19],
211
[6, 14, 6, 19],
212
[
213
[6, 14, 6, 19],
214
[6, 27, 6, 32],
215
[7, 14, 7, 19],
216
[8, 14, 8, 19],
217
[9, 14, 9, 19]
218
]
219
);
220
221
// simulate adding a search scope
222
findState.change({ searchScope: [new Range(8, 1, 10, 1)] }, true);
223
assertFindState(
224
editor,
225
[8, 14, 8, 19],
226
[8, 14, 8, 19],
227
[
228
[8, 14, 8, 19],
229
[9, 14, 9, 19]
230
]
231
);
232
233
// simulate removing the search scope
234
findState.change({ searchScope: null }, true);
235
assertFindState(
236
editor,
237
[6, 14, 6, 19],
238
[6, 14, 6, 19],
239
[
240
[6, 14, 6, 19],
241
[6, 27, 6, 32],
242
[7, 14, 7, 19],
243
[8, 14, 8, 19],
244
[9, 14, 9, 19]
245
]
246
);
247
248
findModel.dispose();
249
findState.dispose();
250
});
251
252
findTest('find model removes its decorations', (editor) => {
253
const findState = disposables.add(new FindReplaceState());
254
findState.change({ searchString: 'hello' }, false);
255
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
256
257
assert.strictEqual(findState.matchesCount, 5);
258
assertFindState(
259
editor,
260
[1, 1, 1, 1],
261
null,
262
[
263
[6, 14, 6, 19],
264
[6, 27, 6, 32],
265
[7, 14, 7, 19],
266
[8, 14, 8, 19],
267
[9, 14, 9, 19]
268
]
269
);
270
271
findModel.dispose();
272
findState.dispose();
273
274
assertFindState(
275
editor,
276
[1, 1, 1, 1],
277
null,
278
[]
279
);
280
});
281
282
findTest('find model updates state matchesCount', (editor) => {
283
const findState = disposables.add(new FindReplaceState());
284
findState.change({ searchString: 'hello' }, false);
285
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
286
287
assert.strictEqual(findState.matchesCount, 5);
288
assertFindState(
289
editor,
290
[1, 1, 1, 1],
291
null,
292
[
293
[6, 14, 6, 19],
294
[6, 27, 6, 32],
295
[7, 14, 7, 19],
296
[8, 14, 8, 19],
297
[9, 14, 9, 19]
298
]
299
);
300
301
findState.change({ searchString: 'helloo' }, false);
302
assert.strictEqual(findState.matchesCount, 0);
303
assertFindState(
304
editor,
305
[1, 1, 1, 1],
306
null,
307
[]
308
);
309
310
findModel.dispose();
311
findState.dispose();
312
});
313
314
findTest('find model reacts to position change', (editor) => {
315
const findState = disposables.add(new FindReplaceState());
316
findState.change({ searchString: 'hello' }, false);
317
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
318
319
assertFindState(
320
editor,
321
[1, 1, 1, 1],
322
null,
323
[
324
[6, 14, 6, 19],
325
[6, 27, 6, 32],
326
[7, 14, 7, 19],
327
[8, 14, 8, 19],
328
[9, 14, 9, 19]
329
]
330
);
331
332
editor.trigger('mouse', CoreNavigationCommands.MoveTo.id, {
333
position: new Position(6, 20)
334
});
335
336
assertFindState(
337
editor,
338
[6, 20, 6, 20],
339
null,
340
[
341
[6, 14, 6, 19],
342
[6, 27, 6, 32],
343
[7, 14, 7, 19],
344
[8, 14, 8, 19],
345
[9, 14, 9, 19]
346
]
347
);
348
349
findState.change({ searchString: 'Hello' }, true);
350
assertFindState(
351
editor,
352
[6, 27, 6, 32],
353
[6, 27, 6, 32],
354
[
355
[6, 14, 6, 19],
356
[6, 27, 6, 32],
357
[7, 14, 7, 19],
358
[8, 14, 8, 19],
359
[9, 14, 9, 19]
360
]
361
);
362
363
findModel.dispose();
364
findState.dispose();
365
});
366
367
findTest('find model next', (editor) => {
368
const findState = disposables.add(new FindReplaceState());
369
findState.change({ searchString: 'hello', wholeWord: true }, false);
370
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
371
372
assertFindState(
373
editor,
374
[1, 1, 1, 1],
375
null,
376
[
377
[6, 14, 6, 19],
378
[6, 27, 6, 32],
379
[7, 14, 7, 19],
380
[8, 14, 8, 19]
381
]
382
);
383
384
findModel.moveToNextMatch();
385
assertFindState(
386
editor,
387
[6, 14, 6, 19],
388
[6, 14, 6, 19],
389
[
390
[6, 14, 6, 19],
391
[6, 27, 6, 32],
392
[7, 14, 7, 19],
393
[8, 14, 8, 19]
394
]
395
);
396
397
findModel.moveToNextMatch();
398
assertFindState(
399
editor,
400
[6, 27, 6, 32],
401
[6, 27, 6, 32],
402
[
403
[6, 14, 6, 19],
404
[6, 27, 6, 32],
405
[7, 14, 7, 19],
406
[8, 14, 8, 19]
407
]
408
);
409
410
findModel.moveToNextMatch();
411
assertFindState(
412
editor,
413
[7, 14, 7, 19],
414
[7, 14, 7, 19],
415
[
416
[6, 14, 6, 19],
417
[6, 27, 6, 32],
418
[7, 14, 7, 19],
419
[8, 14, 8, 19]
420
]
421
);
422
423
findModel.moveToNextMatch();
424
assertFindState(
425
editor,
426
[8, 14, 8, 19],
427
[8, 14, 8, 19],
428
[
429
[6, 14, 6, 19],
430
[6, 27, 6, 32],
431
[7, 14, 7, 19],
432
[8, 14, 8, 19]
433
]
434
);
435
436
findModel.moveToNextMatch();
437
assertFindState(
438
editor,
439
[6, 14, 6, 19],
440
[6, 14, 6, 19],
441
[
442
[6, 14, 6, 19],
443
[6, 27, 6, 32],
444
[7, 14, 7, 19],
445
[8, 14, 8, 19]
446
]
447
);
448
449
findModel.dispose();
450
findState.dispose();
451
});
452
453
findTest('find model next stays in scope', (editor) => {
454
const findState = disposables.add(new FindReplaceState());
455
findState.change({ searchString: 'hello', wholeWord: true, searchScope: [new Range(7, 1, 9, 1)] }, false);
456
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
457
458
assertFindState(
459
editor,
460
[1, 1, 1, 1],
461
null,
462
[
463
[7, 14, 7, 19],
464
[8, 14, 8, 19]
465
]
466
);
467
468
findModel.moveToNextMatch();
469
assertFindState(
470
editor,
471
[7, 14, 7, 19],
472
[7, 14, 7, 19],
473
[
474
[7, 14, 7, 19],
475
[8, 14, 8, 19]
476
]
477
);
478
479
findModel.moveToNextMatch();
480
assertFindState(
481
editor,
482
[8, 14, 8, 19],
483
[8, 14, 8, 19],
484
[
485
[7, 14, 7, 19],
486
[8, 14, 8, 19]
487
]
488
);
489
490
findModel.moveToNextMatch();
491
assertFindState(
492
editor,
493
[7, 14, 7, 19],
494
[7, 14, 7, 19],
495
[
496
[7, 14, 7, 19],
497
[8, 14, 8, 19]
498
]
499
);
500
501
findModel.dispose();
502
findState.dispose();
503
});
504
505
findTest('multi-selection find model next stays in scope (overlap)', (editor) => {
506
const findState = disposables.add(new FindReplaceState());
507
findState.change({ searchString: 'hello', wholeWord: true, searchScope: [new Range(7, 1, 8, 2), new Range(8, 1, 9, 1)] }, false);
508
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
509
510
assertFindState(
511
editor,
512
[1, 1, 1, 1],
513
null,
514
[
515
[7, 14, 7, 19],
516
[8, 14, 8, 19]
517
]
518
);
519
520
findModel.moveToNextMatch();
521
assertFindState(
522
editor,
523
[7, 14, 7, 19],
524
[7, 14, 7, 19],
525
[
526
[7, 14, 7, 19],
527
[8, 14, 8, 19]
528
]
529
);
530
531
findModel.moveToNextMatch();
532
assertFindState(
533
editor,
534
[8, 14, 8, 19],
535
[8, 14, 8, 19],
536
[
537
[7, 14, 7, 19],
538
[8, 14, 8, 19]
539
]
540
);
541
542
findModel.moveToNextMatch();
543
assertFindState(
544
editor,
545
[7, 14, 7, 19],
546
[7, 14, 7, 19],
547
[
548
[7, 14, 7, 19],
549
[8, 14, 8, 19]
550
]
551
);
552
553
findModel.dispose();
554
findState.dispose();
555
});
556
557
findTest('multi-selection find model next stays in scope', (editor) => {
558
const findState = disposables.add(new FindReplaceState());
559
findState.change({ searchString: 'hello', matchCase: true, wholeWord: false, searchScope: [new Range(6, 1, 7, 38), new Range(9, 3, 9, 38)] }, false);
560
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
561
562
assertFindState(
563
editor,
564
[1, 1, 1, 1],
565
null,
566
[
567
[6, 14, 6, 19],
568
// `matchCase: false` would
569
// find this match as well:
570
// [6, 27, 6, 32],
571
[7, 14, 7, 19],
572
// `wholeWord: true` would
573
// exclude this match:
574
[9, 14, 9, 19],
575
]
576
);
577
578
findModel.moveToNextMatch();
579
assertFindState(
580
editor,
581
[6, 14, 6, 19],
582
[6, 14, 6, 19],
583
[
584
[6, 14, 6, 19],
585
[7, 14, 7, 19],
586
[9, 14, 9, 19],
587
]
588
);
589
590
findModel.moveToNextMatch();
591
assertFindState(
592
editor,
593
[7, 14, 7, 19],
594
[7, 14, 7, 19],
595
[
596
[6, 14, 6, 19],
597
[7, 14, 7, 19],
598
[9, 14, 9, 19],
599
]
600
);
601
602
findModel.moveToNextMatch();
603
assertFindState(
604
editor,
605
[9, 14, 9, 19],
606
[9, 14, 9, 19],
607
[
608
[6, 14, 6, 19],
609
[7, 14, 7, 19],
610
[9, 14, 9, 19],
611
]
612
);
613
614
findModel.moveToNextMatch();
615
assertFindState(
616
editor,
617
[6, 14, 6, 19],
618
[6, 14, 6, 19],
619
[
620
[6, 14, 6, 19],
621
[7, 14, 7, 19],
622
[9, 14, 9, 19],
623
]
624
);
625
626
findModel.dispose();
627
findState.dispose();
628
});
629
630
findTest('find model prev', (editor) => {
631
const findState = disposables.add(new FindReplaceState());
632
findState.change({ searchString: 'hello', wholeWord: true }, false);
633
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
634
635
assertFindState(
636
editor,
637
[1, 1, 1, 1],
638
null,
639
[
640
[6, 14, 6, 19],
641
[6, 27, 6, 32],
642
[7, 14, 7, 19],
643
[8, 14, 8, 19]
644
]
645
);
646
647
findModel.moveToPrevMatch();
648
assertFindState(
649
editor,
650
[8, 14, 8, 19],
651
[8, 14, 8, 19],
652
[
653
[6, 14, 6, 19],
654
[6, 27, 6, 32],
655
[7, 14, 7, 19],
656
[8, 14, 8, 19]
657
]
658
);
659
660
findModel.moveToPrevMatch();
661
assertFindState(
662
editor,
663
[7, 14, 7, 19],
664
[7, 14, 7, 19],
665
[
666
[6, 14, 6, 19],
667
[6, 27, 6, 32],
668
[7, 14, 7, 19],
669
[8, 14, 8, 19]
670
]
671
);
672
673
findModel.moveToPrevMatch();
674
assertFindState(
675
editor,
676
[6, 27, 6, 32],
677
[6, 27, 6, 32],
678
[
679
[6, 14, 6, 19],
680
[6, 27, 6, 32],
681
[7, 14, 7, 19],
682
[8, 14, 8, 19]
683
]
684
);
685
686
findModel.moveToPrevMatch();
687
assertFindState(
688
editor,
689
[6, 14, 6, 19],
690
[6, 14, 6, 19],
691
[
692
[6, 14, 6, 19],
693
[6, 27, 6, 32],
694
[7, 14, 7, 19],
695
[8, 14, 8, 19]
696
]
697
);
698
699
findModel.moveToPrevMatch();
700
assertFindState(
701
editor,
702
[8, 14, 8, 19],
703
[8, 14, 8, 19],
704
[
705
[6, 14, 6, 19],
706
[6, 27, 6, 32],
707
[7, 14, 7, 19],
708
[8, 14, 8, 19]
709
]
710
);
711
712
findModel.dispose();
713
findState.dispose();
714
});
715
716
findTest('find model prev stays in scope', (editor) => {
717
const findState = disposables.add(new FindReplaceState());
718
findState.change({ searchString: 'hello', wholeWord: true, searchScope: [new Range(7, 1, 9, 1)] }, false);
719
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
720
721
assertFindState(
722
editor,
723
[1, 1, 1, 1],
724
null,
725
[
726
[7, 14, 7, 19],
727
[8, 14, 8, 19]
728
]
729
);
730
731
findModel.moveToPrevMatch();
732
assertFindState(
733
editor,
734
[8, 14, 8, 19],
735
[8, 14, 8, 19],
736
[
737
[7, 14, 7, 19],
738
[8, 14, 8, 19]
739
]
740
);
741
742
findModel.moveToPrevMatch();
743
assertFindState(
744
editor,
745
[7, 14, 7, 19],
746
[7, 14, 7, 19],
747
[
748
[7, 14, 7, 19],
749
[8, 14, 8, 19]
750
]
751
);
752
753
findModel.moveToPrevMatch();
754
assertFindState(
755
editor,
756
[8, 14, 8, 19],
757
[8, 14, 8, 19],
758
[
759
[7, 14, 7, 19],
760
[8, 14, 8, 19]
761
]
762
);
763
764
findModel.dispose();
765
findState.dispose();
766
});
767
768
findTest('find model next/prev with no matches', (editor) => {
769
const findState = disposables.add(new FindReplaceState());
770
findState.change({ searchString: 'helloo', wholeWord: true }, false);
771
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
772
773
assertFindState(
774
editor,
775
[1, 1, 1, 1],
776
null,
777
[]
778
);
779
780
findModel.moveToNextMatch();
781
assertFindState(
782
editor,
783
[1, 1, 1, 1],
784
null,
785
[]
786
);
787
788
findModel.moveToPrevMatch();
789
assertFindState(
790
editor,
791
[1, 1, 1, 1],
792
null,
793
[]
794
);
795
796
findModel.dispose();
797
findState.dispose();
798
});
799
800
findTest('find model next/prev respects cursor position', (editor) => {
801
const findState = disposables.add(new FindReplaceState());
802
findState.change({ searchString: 'hello', wholeWord: true }, false);
803
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
804
805
assertFindState(
806
editor,
807
[1, 1, 1, 1],
808
null,
809
[
810
[6, 14, 6, 19],
811
[6, 27, 6, 32],
812
[7, 14, 7, 19],
813
[8, 14, 8, 19]
814
]
815
);
816
817
editor.trigger('mouse', CoreNavigationCommands.MoveTo.id, {
818
position: new Position(6, 20)
819
});
820
assertFindState(
821
editor,
822
[6, 20, 6, 20],
823
null,
824
[
825
[6, 14, 6, 19],
826
[6, 27, 6, 32],
827
[7, 14, 7, 19],
828
[8, 14, 8, 19]
829
]
830
);
831
832
findModel.moveToNextMatch();
833
assertFindState(
834
editor,
835
[6, 27, 6, 32],
836
[6, 27, 6, 32],
837
[
838
[6, 14, 6, 19],
839
[6, 27, 6, 32],
840
[7, 14, 7, 19],
841
[8, 14, 8, 19]
842
]
843
);
844
845
findModel.dispose();
846
findState.dispose();
847
});
848
849
findTest('find ^', (editor) => {
850
const findState = disposables.add(new FindReplaceState());
851
findState.change({ searchString: '^', isRegex: true }, false);
852
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
853
854
assertFindState(
855
editor,
856
[1, 1, 1, 1],
857
null,
858
[
859
[1, 1, 1, 1],
860
[2, 1, 2, 1],
861
[3, 1, 3, 1],
862
[4, 1, 4, 1],
863
[5, 1, 5, 1],
864
[6, 1, 6, 1],
865
[7, 1, 7, 1],
866
[8, 1, 8, 1],
867
[9, 1, 9, 1],
868
[10, 1, 10, 1],
869
[11, 1, 11, 1],
870
[12, 1, 12, 1],
871
]
872
);
873
874
findModel.moveToNextMatch();
875
assertFindState(
876
editor,
877
[2, 1, 2, 1],
878
[2, 1, 2, 1],
879
[
880
[1, 1, 1, 1],
881
[2, 1, 2, 1],
882
[3, 1, 3, 1],
883
[4, 1, 4, 1],
884
[5, 1, 5, 1],
885
[6, 1, 6, 1],
886
[7, 1, 7, 1],
887
[8, 1, 8, 1],
888
[9, 1, 9, 1],
889
[10, 1, 10, 1],
890
[11, 1, 11, 1],
891
[12, 1, 12, 1],
892
]
893
);
894
895
findModel.moveToNextMatch();
896
assertFindState(
897
editor,
898
[3, 1, 3, 1],
899
[3, 1, 3, 1],
900
[
901
[1, 1, 1, 1],
902
[2, 1, 2, 1],
903
[3, 1, 3, 1],
904
[4, 1, 4, 1],
905
[5, 1, 5, 1],
906
[6, 1, 6, 1],
907
[7, 1, 7, 1],
908
[8, 1, 8, 1],
909
[9, 1, 9, 1],
910
[10, 1, 10, 1],
911
[11, 1, 11, 1],
912
[12, 1, 12, 1],
913
]
914
);
915
916
findModel.dispose();
917
findState.dispose();
918
});
919
920
findTest('find $', (editor) => {
921
const findState = disposables.add(new FindReplaceState());
922
findState.change({ searchString: '$', isRegex: true }, false);
923
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
924
925
assertFindState(
926
editor,
927
[1, 1, 1, 1],
928
null,
929
[
930
[1, 18, 1, 18],
931
[2, 18, 2, 18],
932
[3, 20, 3, 20],
933
[4, 1, 4, 1],
934
[5, 13, 5, 13],
935
[6, 43, 6, 43],
936
[7, 41, 7, 41],
937
[8, 41, 8, 41],
938
[9, 40, 9, 40],
939
[10, 2, 10, 2],
940
[11, 17, 11, 17],
941
[12, 1, 12, 1],
942
]
943
);
944
945
findModel.moveToNextMatch();
946
assertFindState(
947
editor,
948
[1, 18, 1, 18],
949
[1, 18, 1, 18],
950
[
951
[1, 18, 1, 18],
952
[2, 18, 2, 18],
953
[3, 20, 3, 20],
954
[4, 1, 4, 1],
955
[5, 13, 5, 13],
956
[6, 43, 6, 43],
957
[7, 41, 7, 41],
958
[8, 41, 8, 41],
959
[9, 40, 9, 40],
960
[10, 2, 10, 2],
961
[11, 17, 11, 17],
962
[12, 1, 12, 1],
963
]
964
);
965
966
findModel.moveToNextMatch();
967
assertFindState(
968
editor,
969
[2, 18, 2, 18],
970
[2, 18, 2, 18],
971
[
972
[1, 18, 1, 18],
973
[2, 18, 2, 18],
974
[3, 20, 3, 20],
975
[4, 1, 4, 1],
976
[5, 13, 5, 13],
977
[6, 43, 6, 43],
978
[7, 41, 7, 41],
979
[8, 41, 8, 41],
980
[9, 40, 9, 40],
981
[10, 2, 10, 2],
982
[11, 17, 11, 17],
983
[12, 1, 12, 1],
984
]
985
);
986
987
findModel.moveToNextMatch();
988
assertFindState(
989
editor,
990
[3, 20, 3, 20],
991
[3, 20, 3, 20],
992
[
993
[1, 18, 1, 18],
994
[2, 18, 2, 18],
995
[3, 20, 3, 20],
996
[4, 1, 4, 1],
997
[5, 13, 5, 13],
998
[6, 43, 6, 43],
999
[7, 41, 7, 41],
1000
[8, 41, 8, 41],
1001
[9, 40, 9, 40],
1002
[10, 2, 10, 2],
1003
[11, 17, 11, 17],
1004
[12, 1, 12, 1],
1005
]
1006
);
1007
1008
findModel.dispose();
1009
findState.dispose();
1010
});
1011
1012
findTest('find next ^$', (editor) => {
1013
const findState = disposables.add(new FindReplaceState());
1014
findState.change({ searchString: '^$', isRegex: true }, false);
1015
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1016
1017
assertFindState(
1018
editor,
1019
[1, 1, 1, 1],
1020
null,
1021
[
1022
[4, 1, 4, 1],
1023
[12, 1, 12, 1],
1024
]
1025
);
1026
1027
findModel.moveToNextMatch();
1028
assertFindState(
1029
editor,
1030
[4, 1, 4, 1],
1031
[4, 1, 4, 1],
1032
[
1033
[4, 1, 4, 1],
1034
[12, 1, 12, 1],
1035
]
1036
);
1037
1038
findModel.moveToNextMatch();
1039
assertFindState(
1040
editor,
1041
[12, 1, 12, 1],
1042
[12, 1, 12, 1],
1043
[
1044
[4, 1, 4, 1],
1045
[12, 1, 12, 1],
1046
]
1047
);
1048
1049
findModel.moveToNextMatch();
1050
assertFindState(
1051
editor,
1052
[4, 1, 4, 1],
1053
[4, 1, 4, 1],
1054
[
1055
[4, 1, 4, 1],
1056
[12, 1, 12, 1],
1057
]
1058
);
1059
1060
findModel.dispose();
1061
findState.dispose();
1062
});
1063
1064
findTest('find .*', (editor) => {
1065
const findState = disposables.add(new FindReplaceState());
1066
findState.change({ searchString: '.*', isRegex: true }, false);
1067
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1068
1069
assertFindState(
1070
editor,
1071
[1, 1, 1, 1],
1072
null,
1073
[
1074
[1, 1, 1, 18],
1075
[2, 1, 2, 18],
1076
[3, 1, 3, 20],
1077
[4, 1, 4, 1],
1078
[5, 1, 5, 13],
1079
[6, 1, 6, 43],
1080
[7, 1, 7, 41],
1081
[8, 1, 8, 41],
1082
[9, 1, 9, 40],
1083
[10, 1, 10, 2],
1084
[11, 1, 11, 17],
1085
[12, 1, 12, 1],
1086
]
1087
);
1088
1089
findModel.dispose();
1090
findState.dispose();
1091
});
1092
1093
findTest('find next ^.*$', (editor) => {
1094
const findState = disposables.add(new FindReplaceState());
1095
findState.change({ searchString: '^.*$', isRegex: true }, false);
1096
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1097
1098
assertFindState(
1099
editor,
1100
[1, 1, 1, 1],
1101
null,
1102
[
1103
[1, 1, 1, 18],
1104
[2, 1, 2, 18],
1105
[3, 1, 3, 20],
1106
[4, 1, 4, 1],
1107
[5, 1, 5, 13],
1108
[6, 1, 6, 43],
1109
[7, 1, 7, 41],
1110
[8, 1, 8, 41],
1111
[9, 1, 9, 40],
1112
[10, 1, 10, 2],
1113
[11, 1, 11, 17],
1114
[12, 1, 12, 1],
1115
]
1116
);
1117
1118
findModel.moveToNextMatch();
1119
assertFindState(
1120
editor,
1121
[1, 1, 1, 18],
1122
[1, 1, 1, 18],
1123
[
1124
[1, 1, 1, 18],
1125
[2, 1, 2, 18],
1126
[3, 1, 3, 20],
1127
[4, 1, 4, 1],
1128
[5, 1, 5, 13],
1129
[6, 1, 6, 43],
1130
[7, 1, 7, 41],
1131
[8, 1, 8, 41],
1132
[9, 1, 9, 40],
1133
[10, 1, 10, 2],
1134
[11, 1, 11, 17],
1135
[12, 1, 12, 1],
1136
]
1137
);
1138
1139
findModel.moveToNextMatch();
1140
assertFindState(
1141
editor,
1142
[2, 1, 2, 18],
1143
[2, 1, 2, 18],
1144
[
1145
[1, 1, 1, 18],
1146
[2, 1, 2, 18],
1147
[3, 1, 3, 20],
1148
[4, 1, 4, 1],
1149
[5, 1, 5, 13],
1150
[6, 1, 6, 43],
1151
[7, 1, 7, 41],
1152
[8, 1, 8, 41],
1153
[9, 1, 9, 40],
1154
[10, 1, 10, 2],
1155
[11, 1, 11, 17],
1156
[12, 1, 12, 1],
1157
]
1158
);
1159
1160
findModel.dispose();
1161
findState.dispose();
1162
});
1163
1164
findTest('find prev ^.*$', (editor) => {
1165
const findState = disposables.add(new FindReplaceState());
1166
findState.change({ searchString: '^.*$', isRegex: true }, false);
1167
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1168
1169
assertFindState(
1170
editor,
1171
[1, 1, 1, 1],
1172
null,
1173
[
1174
[1, 1, 1, 18],
1175
[2, 1, 2, 18],
1176
[3, 1, 3, 20],
1177
[4, 1, 4, 1],
1178
[5, 1, 5, 13],
1179
[6, 1, 6, 43],
1180
[7, 1, 7, 41],
1181
[8, 1, 8, 41],
1182
[9, 1, 9, 40],
1183
[10, 1, 10, 2],
1184
[11, 1, 11, 17],
1185
[12, 1, 12, 1],
1186
]
1187
);
1188
1189
findModel.moveToPrevMatch();
1190
assertFindState(
1191
editor,
1192
[12, 1, 12, 1],
1193
[12, 1, 12, 1],
1194
[
1195
[1, 1, 1, 18],
1196
[2, 1, 2, 18],
1197
[3, 1, 3, 20],
1198
[4, 1, 4, 1],
1199
[5, 1, 5, 13],
1200
[6, 1, 6, 43],
1201
[7, 1, 7, 41],
1202
[8, 1, 8, 41],
1203
[9, 1, 9, 40],
1204
[10, 1, 10, 2],
1205
[11, 1, 11, 17],
1206
[12, 1, 12, 1],
1207
]
1208
);
1209
1210
findModel.moveToPrevMatch();
1211
assertFindState(
1212
editor,
1213
[11, 1, 11, 17],
1214
[11, 1, 11, 17],
1215
[
1216
[1, 1, 1, 18],
1217
[2, 1, 2, 18],
1218
[3, 1, 3, 20],
1219
[4, 1, 4, 1],
1220
[5, 1, 5, 13],
1221
[6, 1, 6, 43],
1222
[7, 1, 7, 41],
1223
[8, 1, 8, 41],
1224
[9, 1, 9, 40],
1225
[10, 1, 10, 2],
1226
[11, 1, 11, 17],
1227
[12, 1, 12, 1],
1228
]
1229
);
1230
1231
findModel.dispose();
1232
findState.dispose();
1233
});
1234
1235
findTest('find prev ^$', (editor) => {
1236
const findState = disposables.add(new FindReplaceState());
1237
findState.change({ searchString: '^$', isRegex: true }, false);
1238
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1239
1240
assertFindState(
1241
editor,
1242
[1, 1, 1, 1],
1243
null,
1244
[
1245
[4, 1, 4, 1],
1246
[12, 1, 12, 1],
1247
]
1248
);
1249
1250
findModel.moveToPrevMatch();
1251
assertFindState(
1252
editor,
1253
[12, 1, 12, 1],
1254
[12, 1, 12, 1],
1255
[
1256
[4, 1, 4, 1],
1257
[12, 1, 12, 1],
1258
]
1259
);
1260
1261
findModel.moveToPrevMatch();
1262
assertFindState(
1263
editor,
1264
[4, 1, 4, 1],
1265
[4, 1, 4, 1],
1266
[
1267
[4, 1, 4, 1],
1268
[12, 1, 12, 1],
1269
]
1270
);
1271
1272
findModel.moveToPrevMatch();
1273
assertFindState(
1274
editor,
1275
[12, 1, 12, 1],
1276
[12, 1, 12, 1],
1277
[
1278
[4, 1, 4, 1],
1279
[12, 1, 12, 1],
1280
]
1281
);
1282
1283
findModel.dispose();
1284
findState.dispose();
1285
});
1286
1287
findTest('replace hello', (editor) => {
1288
const findState = disposables.add(new FindReplaceState());
1289
findState.change({ searchString: 'hello', replaceString: 'hi', wholeWord: true }, false);
1290
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1291
1292
assertFindState(
1293
editor,
1294
[1, 1, 1, 1],
1295
null,
1296
[
1297
[6, 14, 6, 19],
1298
[6, 27, 6, 32],
1299
[7, 14, 7, 19],
1300
[8, 14, 8, 19]
1301
]
1302
);
1303
1304
editor.trigger('mouse', CoreNavigationCommands.MoveTo.id, {
1305
position: new Position(6, 20)
1306
});
1307
assertFindState(
1308
editor,
1309
[6, 20, 6, 20],
1310
null,
1311
[
1312
[6, 14, 6, 19],
1313
[6, 27, 6, 32],
1314
[7, 14, 7, 19],
1315
[8, 14, 8, 19]
1316
]
1317
);
1318
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hello world, Hello!" << endl;');
1319
1320
findModel.replace();
1321
assertFindState(
1322
editor,
1323
[6, 27, 6, 32],
1324
[6, 27, 6, 32],
1325
[
1326
[6, 14, 6, 19],
1327
[6, 27, 6, 32],
1328
[7, 14, 7, 19],
1329
[8, 14, 8, 19]
1330
]
1331
);
1332
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hello world, Hello!" << endl;');
1333
1334
findModel.replace();
1335
assertFindState(
1336
editor,
1337
[7, 14, 7, 19],
1338
[7, 14, 7, 19],
1339
[
1340
[6, 14, 6, 19],
1341
[7, 14, 7, 19],
1342
[8, 14, 8, 19]
1343
]
1344
);
1345
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hello world, hi!" << endl;');
1346
1347
findModel.replace();
1348
assertFindState(
1349
editor,
1350
[8, 14, 8, 19],
1351
[8, 14, 8, 19],
1352
[
1353
[6, 14, 6, 19],
1354
[8, 14, 8, 19]
1355
]
1356
);
1357
assert.strictEqual(editor.getModel()!.getLineContent(7), ' cout << "hi world again" << endl;');
1358
1359
findModel.replace();
1360
assertFindState(
1361
editor,
1362
[6, 14, 6, 19],
1363
[6, 14, 6, 19],
1364
[
1365
[6, 14, 6, 19]
1366
]
1367
);
1368
assert.strictEqual(editor.getModel()!.getLineContent(8), ' cout << "hi world again" << endl;');
1369
1370
findModel.replace();
1371
assertFindState(
1372
editor,
1373
[6, 16, 6, 16],
1374
null,
1375
[]
1376
);
1377
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hi world, hi!" << endl;');
1378
1379
findModel.dispose();
1380
findState.dispose();
1381
});
1382
1383
findTest('replace bla', (editor) => {
1384
const findState = disposables.add(new FindReplaceState());
1385
findState.change({ searchString: 'bla', replaceString: 'ciao' }, false);
1386
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1387
1388
assertFindState(
1389
editor,
1390
[1, 1, 1, 1],
1391
null,
1392
[
1393
[11, 4, 11, 7],
1394
[11, 7, 11, 10],
1395
[11, 10, 11, 13]
1396
]
1397
);
1398
1399
findModel.replace();
1400
assertFindState(
1401
editor,
1402
[11, 4, 11, 7],
1403
[11, 4, 11, 7],
1404
[
1405
[11, 4, 11, 7],
1406
[11, 7, 11, 10],
1407
[11, 10, 11, 13]
1408
]
1409
);
1410
assert.strictEqual(editor.getModel()!.getLineContent(11), '// blablablaciao');
1411
1412
findModel.replace();
1413
assertFindState(
1414
editor,
1415
[11, 8, 11, 11],
1416
[11, 8, 11, 11],
1417
[
1418
[11, 8, 11, 11],
1419
[11, 11, 11, 14]
1420
]
1421
);
1422
assert.strictEqual(editor.getModel()!.getLineContent(11), '// ciaoblablaciao');
1423
1424
findModel.replace();
1425
assertFindState(
1426
editor,
1427
[11, 12, 11, 15],
1428
[11, 12, 11, 15],
1429
[
1430
[11, 12, 11, 15]
1431
]
1432
);
1433
assert.strictEqual(editor.getModel()!.getLineContent(11), '// ciaociaoblaciao');
1434
1435
findModel.replace();
1436
assertFindState(
1437
editor,
1438
[11, 16, 11, 16],
1439
null,
1440
[]
1441
);
1442
assert.strictEqual(editor.getModel()!.getLineContent(11), '// ciaociaociaociao');
1443
1444
findModel.dispose();
1445
findState.dispose();
1446
});
1447
1448
findTest('replaceAll hello', (editor) => {
1449
const findState = disposables.add(new FindReplaceState());
1450
findState.change({ searchString: 'hello', replaceString: 'hi', wholeWord: true }, false);
1451
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1452
1453
assertFindState(
1454
editor,
1455
[1, 1, 1, 1],
1456
null,
1457
[
1458
[6, 14, 6, 19],
1459
[6, 27, 6, 32],
1460
[7, 14, 7, 19],
1461
[8, 14, 8, 19]
1462
]
1463
);
1464
1465
editor.trigger('mouse', CoreNavigationCommands.MoveTo.id, {
1466
position: new Position(6, 20)
1467
});
1468
assertFindState(
1469
editor,
1470
[6, 20, 6, 20],
1471
null,
1472
[
1473
[6, 14, 6, 19],
1474
[6, 27, 6, 32],
1475
[7, 14, 7, 19],
1476
[8, 14, 8, 19]
1477
]
1478
);
1479
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hello world, Hello!" << endl;');
1480
1481
findModel.replaceAll();
1482
assertFindState(
1483
editor,
1484
[6, 17, 6, 17],
1485
null,
1486
[]
1487
);
1488
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hi world, hi!" << endl;');
1489
assert.strictEqual(editor.getModel()!.getLineContent(7), ' cout << "hi world again" << endl;');
1490
assert.strictEqual(editor.getModel()!.getLineContent(8), ' cout << "hi world again" << endl;');
1491
1492
findModel.dispose();
1493
findState.dispose();
1494
});
1495
1496
findTest('replaceAll two spaces with one space', (editor) => {
1497
const findState = disposables.add(new FindReplaceState());
1498
findState.change({ searchString: ' ', replaceString: ' ' }, false);
1499
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1500
1501
assertFindState(
1502
editor,
1503
[1, 1, 1, 1],
1504
null,
1505
[
1506
[6, 1, 6, 3],
1507
[6, 3, 6, 5],
1508
[7, 1, 7, 3],
1509
[7, 3, 7, 5],
1510
[8, 1, 8, 3],
1511
[8, 3, 8, 5],
1512
[9, 1, 9, 3],
1513
[9, 3, 9, 5]
1514
]
1515
);
1516
1517
findModel.replaceAll();
1518
assertFindState(
1519
editor,
1520
[1, 1, 1, 1],
1521
null,
1522
[
1523
[6, 1, 6, 3],
1524
[7, 1, 7, 3],
1525
[8, 1, 8, 3],
1526
[9, 1, 9, 3]
1527
]
1528
);
1529
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hello world, Hello!" << endl;');
1530
assert.strictEqual(editor.getModel()!.getLineContent(7), ' cout << "hello world again" << endl;');
1531
assert.strictEqual(editor.getModel()!.getLineContent(8), ' cout << "Hello world again" << endl;');
1532
assert.strictEqual(editor.getModel()!.getLineContent(9), ' cout << "helloworld again" << endl;');
1533
1534
findModel.dispose();
1535
findState.dispose();
1536
});
1537
1538
findTest('replaceAll bla', (editor) => {
1539
const findState = disposables.add(new FindReplaceState());
1540
findState.change({ searchString: 'bla', replaceString: 'ciao' }, false);
1541
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1542
1543
assertFindState(
1544
editor,
1545
[1, 1, 1, 1],
1546
null,
1547
[
1548
[11, 4, 11, 7],
1549
[11, 7, 11, 10],
1550
[11, 10, 11, 13]
1551
]
1552
);
1553
1554
findModel.replaceAll();
1555
assertFindState(
1556
editor,
1557
[1, 1, 1, 1],
1558
null,
1559
[]
1560
);
1561
assert.strictEqual(editor.getModel()!.getLineContent(11), '// ciaociaociaociao');
1562
1563
findModel.dispose();
1564
findState.dispose();
1565
});
1566
1567
findTest('replaceAll bla with \\t\\n', (editor) => {
1568
const findState = disposables.add(new FindReplaceState());
1569
findState.change({ searchString: 'bla', replaceString: '<\\n\\t>', isRegex: true }, false);
1570
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1571
1572
assertFindState(
1573
editor,
1574
[1, 1, 1, 1],
1575
null,
1576
[
1577
[11, 4, 11, 7],
1578
[11, 7, 11, 10],
1579
[11, 10, 11, 13]
1580
]
1581
);
1582
1583
findModel.replaceAll();
1584
assertFindState(
1585
editor,
1586
[1, 1, 1, 1],
1587
null,
1588
[]
1589
);
1590
assert.strictEqual(editor.getModel()!.getLineContent(11), '// <');
1591
assert.strictEqual(editor.getModel()!.getLineContent(12), '\t><');
1592
assert.strictEqual(editor.getModel()!.getLineContent(13), '\t><');
1593
assert.strictEqual(editor.getModel()!.getLineContent(14), '\t>ciao');
1594
1595
findModel.dispose();
1596
findState.dispose();
1597
});
1598
1599
findTest('issue #3516: "replace all" moves page/cursor/focus/scroll to the place of the last replacement', (editor) => {
1600
const findState = disposables.add(new FindReplaceState());
1601
findState.change({ searchString: 'include', replaceString: 'bar' }, false);
1602
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1603
1604
assertFindState(
1605
editor,
1606
[1, 1, 1, 1],
1607
null,
1608
[
1609
[2, 2, 2, 9],
1610
[3, 2, 3, 9]
1611
]
1612
);
1613
1614
findModel.replaceAll();
1615
assertFindState(
1616
editor,
1617
[1, 1, 1, 1],
1618
null,
1619
[]
1620
);
1621
1622
assert.strictEqual(editor.getModel()!.getLineContent(2), '#bar "cool.h"');
1623
assert.strictEqual(editor.getModel()!.getLineContent(3), '#bar <iostream>');
1624
1625
findModel.dispose();
1626
findState.dispose();
1627
});
1628
1629
findTest('listens to model content changes', (editor) => {
1630
const findState = disposables.add(new FindReplaceState());
1631
findState.change({ searchString: 'hello', replaceString: 'hi', wholeWord: true }, false);
1632
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1633
1634
assertFindState(
1635
editor,
1636
[1, 1, 1, 1],
1637
null,
1638
[
1639
[6, 14, 6, 19],
1640
[6, 27, 6, 32],
1641
[7, 14, 7, 19],
1642
[8, 14, 8, 19]
1643
]
1644
);
1645
1646
editor.getModel()!.setValue('hello\nhi');
1647
assertFindState(
1648
editor,
1649
[1, 1, 1, 1],
1650
null,
1651
[]
1652
);
1653
1654
findModel.dispose();
1655
findState.dispose();
1656
});
1657
1658
findTest('selectAllMatches', (editor) => {
1659
const findState = disposables.add(new FindReplaceState());
1660
findState.change({ searchString: 'hello', replaceString: 'hi', wholeWord: true }, false);
1661
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1662
1663
assertFindState(
1664
editor,
1665
[1, 1, 1, 1],
1666
null,
1667
[
1668
[6, 14, 6, 19],
1669
[6, 27, 6, 32],
1670
[7, 14, 7, 19],
1671
[8, 14, 8, 19]
1672
]
1673
);
1674
1675
findModel.selectAllMatches();
1676
1677
assert.deepStrictEqual(editor.getSelections()!.map(s => s.toString()), [
1678
new Selection(6, 14, 6, 19),
1679
new Selection(6, 27, 6, 32),
1680
new Selection(7, 14, 7, 19),
1681
new Selection(8, 14, 8, 19)
1682
].map(s => s.toString()));
1683
1684
assertFindState(
1685
editor,
1686
[6, 14, 6, 19],
1687
null,
1688
[
1689
[6, 14, 6, 19],
1690
[6, 27, 6, 32],
1691
[7, 14, 7, 19],
1692
[8, 14, 8, 19]
1693
]
1694
);
1695
1696
findModel.dispose();
1697
findState.dispose();
1698
});
1699
1700
findTest('issue #14143 selectAllMatches should maintain primary cursor if feasible', (editor) => {
1701
const findState = disposables.add(new FindReplaceState());
1702
findState.change({ searchString: 'hello', replaceString: 'hi', wholeWord: true }, false);
1703
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1704
1705
assertFindState(
1706
editor,
1707
[1, 1, 1, 1],
1708
null,
1709
[
1710
[6, 14, 6, 19],
1711
[6, 27, 6, 32],
1712
[7, 14, 7, 19],
1713
[8, 14, 8, 19]
1714
]
1715
);
1716
1717
editor.setSelection(new Range(7, 14, 7, 19));
1718
1719
findModel.selectAllMatches();
1720
1721
assert.deepStrictEqual(editor.getSelections()!.map(s => s.toString()), [
1722
new Selection(7, 14, 7, 19),
1723
new Selection(6, 14, 6, 19),
1724
new Selection(6, 27, 6, 32),
1725
new Selection(8, 14, 8, 19)
1726
].map(s => s.toString()));
1727
1728
assert.deepStrictEqual(editor.getSelection()!.toString(), new Selection(7, 14, 7, 19).toString());
1729
1730
assertFindState(
1731
editor,
1732
[7, 14, 7, 19],
1733
null,
1734
[
1735
[6, 14, 6, 19],
1736
[6, 27, 6, 32],
1737
[7, 14, 7, 19],
1738
[8, 14, 8, 19]
1739
]
1740
);
1741
1742
findModel.dispose();
1743
findState.dispose();
1744
});
1745
1746
findTest('issue #1914: NPE when there is only one find match', (editor) => {
1747
const findState = disposables.add(new FindReplaceState());
1748
findState.change({ searchString: 'cool.h' }, false);
1749
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1750
1751
assertFindState(
1752
editor,
1753
[1, 1, 1, 1],
1754
null,
1755
[
1756
[2, 11, 2, 17]
1757
]
1758
);
1759
1760
findModel.moveToNextMatch();
1761
assertFindState(
1762
editor,
1763
[2, 11, 2, 17],
1764
[2, 11, 2, 17],
1765
[
1766
[2, 11, 2, 17]
1767
]
1768
);
1769
1770
findModel.moveToNextMatch();
1771
assertFindState(
1772
editor,
1773
[2, 11, 2, 17],
1774
[2, 11, 2, 17],
1775
[
1776
[2, 11, 2, 17]
1777
]
1778
);
1779
1780
findModel.dispose();
1781
findState.dispose();
1782
});
1783
1784
findTest('replace when search string has look ahed regex', (editor) => {
1785
const findState = disposables.add(new FindReplaceState());
1786
findState.change({ searchString: 'hello(?=\\sworld)', replaceString: 'hi', isRegex: true }, false);
1787
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1788
1789
assertFindState(
1790
editor,
1791
[1, 1, 1, 1],
1792
null,
1793
[
1794
[6, 14, 6, 19],
1795
[7, 14, 7, 19],
1796
[8, 14, 8, 19]
1797
]
1798
);
1799
1800
findModel.replace();
1801
1802
assertFindState(
1803
editor,
1804
[6, 14, 6, 19],
1805
[6, 14, 6, 19],
1806
[
1807
[6, 14, 6, 19],
1808
[7, 14, 7, 19],
1809
[8, 14, 8, 19]
1810
]
1811
);
1812
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hello world, Hello!" << endl;');
1813
1814
findModel.replace();
1815
assertFindState(
1816
editor,
1817
[7, 14, 7, 19],
1818
[7, 14, 7, 19],
1819
[
1820
[7, 14, 7, 19],
1821
[8, 14, 8, 19]
1822
]
1823
);
1824
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hi world, Hello!" << endl;');
1825
1826
findModel.replace();
1827
assertFindState(
1828
editor,
1829
[8, 14, 8, 19],
1830
[8, 14, 8, 19],
1831
[
1832
[8, 14, 8, 19]
1833
]
1834
);
1835
assert.strictEqual(editor.getModel()!.getLineContent(7), ' cout << "hi world again" << endl;');
1836
1837
findModel.replace();
1838
assertFindState(
1839
editor,
1840
[8, 16, 8, 16],
1841
null,
1842
[]
1843
);
1844
assert.strictEqual(editor.getModel()!.getLineContent(8), ' cout << "hi world again" << endl;');
1845
1846
findModel.dispose();
1847
findState.dispose();
1848
});
1849
1850
findTest('replace when search string has look ahed regex and cursor is at the last find match', (editor) => {
1851
const findState = disposables.add(new FindReplaceState());
1852
findState.change({ searchString: 'hello(?=\\sworld)', replaceString: 'hi', isRegex: true }, false);
1853
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1854
1855
editor.trigger('mouse', CoreNavigationCommands.MoveTo.id, {
1856
position: new Position(8, 14)
1857
});
1858
1859
assertFindState(
1860
editor,
1861
[8, 14, 8, 14],
1862
null,
1863
[
1864
[6, 14, 6, 19],
1865
[7, 14, 7, 19],
1866
[8, 14, 8, 19]
1867
]
1868
);
1869
1870
findModel.replace();
1871
1872
assertFindState(
1873
editor,
1874
[8, 14, 8, 19],
1875
[8, 14, 8, 19],
1876
[
1877
[6, 14, 6, 19],
1878
[7, 14, 7, 19],
1879
[8, 14, 8, 19]
1880
]
1881
);
1882
1883
assert.strictEqual(editor.getModel()!.getLineContent(8), ' cout << "Hello world again" << endl;');
1884
1885
findModel.replace();
1886
assertFindState(
1887
editor,
1888
[6, 14, 6, 19],
1889
[6, 14, 6, 19],
1890
[
1891
[6, 14, 6, 19],
1892
[7, 14, 7, 19],
1893
]
1894
);
1895
assert.strictEqual(editor.getModel()!.getLineContent(8), ' cout << "hi world again" << endl;');
1896
1897
findModel.replace();
1898
assertFindState(
1899
editor,
1900
[7, 14, 7, 19],
1901
[7, 14, 7, 19],
1902
[
1903
[7, 14, 7, 19]
1904
]
1905
);
1906
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hi world, Hello!" << endl;');
1907
1908
findModel.replace();
1909
assertFindState(
1910
editor,
1911
[7, 16, 7, 16],
1912
null,
1913
[]
1914
);
1915
assert.strictEqual(editor.getModel()!.getLineContent(7), ' cout << "hi world again" << endl;');
1916
1917
findModel.dispose();
1918
findState.dispose();
1919
});
1920
1921
findTest('replaceAll when search string has look ahed regex', (editor) => {
1922
const findState = disposables.add(new FindReplaceState());
1923
findState.change({ searchString: 'hello(?=\\sworld)', replaceString: 'hi', isRegex: true }, false);
1924
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1925
1926
assertFindState(
1927
editor,
1928
[1, 1, 1, 1],
1929
null,
1930
[
1931
[6, 14, 6, 19],
1932
[7, 14, 7, 19],
1933
[8, 14, 8, 19]
1934
]
1935
);
1936
1937
findModel.replaceAll();
1938
1939
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hi world, Hello!" << endl;');
1940
assert.strictEqual(editor.getModel()!.getLineContent(7), ' cout << "hi world again" << endl;');
1941
assert.strictEqual(editor.getModel()!.getLineContent(8), ' cout << "hi world again" << endl;');
1942
1943
assertFindState(
1944
editor,
1945
[1, 1, 1, 1],
1946
null,
1947
[]
1948
);
1949
1950
findModel.dispose();
1951
findState.dispose();
1952
});
1953
1954
findTest('replace when search string has look ahed regex and replace string has capturing groups', (editor) => {
1955
const findState = disposables.add(new FindReplaceState());
1956
findState.change({ searchString: 'hel(lo)(?=\\sworld)', replaceString: 'hi$1', isRegex: true }, false);
1957
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
1958
1959
assertFindState(
1960
editor,
1961
[1, 1, 1, 1],
1962
null,
1963
[
1964
[6, 14, 6, 19],
1965
[7, 14, 7, 19],
1966
[8, 14, 8, 19]
1967
]
1968
);
1969
1970
findModel.replace();
1971
1972
assertFindState(
1973
editor,
1974
[6, 14, 6, 19],
1975
[6, 14, 6, 19],
1976
[
1977
[6, 14, 6, 19],
1978
[7, 14, 7, 19],
1979
[8, 14, 8, 19]
1980
]
1981
);
1982
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hello world, Hello!" << endl;');
1983
1984
findModel.replace();
1985
assertFindState(
1986
editor,
1987
[7, 14, 7, 19],
1988
[7, 14, 7, 19],
1989
[
1990
[7, 14, 7, 19],
1991
[8, 14, 8, 19]
1992
]
1993
);
1994
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hilo world, Hello!" << endl;');
1995
1996
findModel.replace();
1997
assertFindState(
1998
editor,
1999
[8, 14, 8, 19],
2000
[8, 14, 8, 19],
2001
[
2002
[8, 14, 8, 19]
2003
]
2004
);
2005
assert.strictEqual(editor.getModel()!.getLineContent(7), ' cout << "hilo world again" << endl;');
2006
2007
findModel.replace();
2008
assertFindState(
2009
editor,
2010
[8, 18, 8, 18],
2011
null,
2012
[]
2013
);
2014
assert.strictEqual(editor.getModel()!.getLineContent(8), ' cout << "hilo world again" << endl;');
2015
2016
findModel.dispose();
2017
findState.dispose();
2018
});
2019
2020
findTest('replaceAll when search string has look ahed regex and replace string has capturing groups', (editor) => {
2021
const findState = disposables.add(new FindReplaceState());
2022
findState.change({ searchString: 'wo(rl)d(?=.*;$)', replaceString: 'gi$1', isRegex: true }, false);
2023
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
2024
2025
assertFindState(
2026
editor,
2027
[1, 1, 1, 1],
2028
null,
2029
[
2030
[6, 20, 6, 25],
2031
[7, 20, 7, 25],
2032
[8, 20, 8, 25],
2033
[9, 19, 9, 24]
2034
]
2035
);
2036
2037
findModel.replaceAll();
2038
2039
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hello girl, Hello!" << endl;');
2040
assert.strictEqual(editor.getModel()!.getLineContent(7), ' cout << "hello girl again" << endl;');
2041
assert.strictEqual(editor.getModel()!.getLineContent(8), ' cout << "Hello girl again" << endl;');
2042
assert.strictEqual(editor.getModel()!.getLineContent(9), ' cout << "hellogirl again" << endl;');
2043
2044
assertFindState(
2045
editor,
2046
[1, 1, 1, 1],
2047
null,
2048
[]
2049
);
2050
2051
findModel.dispose();
2052
findState.dispose();
2053
});
2054
2055
findTest('replaceAll when search string is multiline and has look ahed regex and replace string has capturing groups', (editor) => {
2056
const findState = disposables.add(new FindReplaceState());
2057
findState.change({ searchString: 'wo(rl)d(.*;\\n)(?=.*hello)', replaceString: 'gi$1$2', isRegex: true, matchCase: true }, false);
2058
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
2059
2060
assertFindState(
2061
editor,
2062
[1, 1, 1, 1],
2063
null,
2064
[
2065
[6, 20, 7, 1],
2066
[8, 20, 9, 1]
2067
]
2068
);
2069
2070
findModel.replaceAll();
2071
2072
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hello girl, Hello!" << endl;');
2073
assert.strictEqual(editor.getModel()!.getLineContent(8), ' cout << "Hello girl again" << endl;');
2074
2075
assertFindState(
2076
editor,
2077
[1, 1, 1, 1],
2078
null,
2079
[]
2080
);
2081
2082
findModel.dispose();
2083
findState.dispose();
2084
});
2085
2086
findTest('replaceAll preserving case', (editor) => {
2087
const findState = disposables.add(new FindReplaceState());
2088
findState.change({ searchString: 'hello', replaceString: 'goodbye', isRegex: false, matchCase: false, preserveCase: true }, false);
2089
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
2090
2091
assertFindState(
2092
editor,
2093
[1, 1, 1, 1],
2094
null,
2095
[
2096
[6, 14, 6, 19],
2097
[6, 27, 6, 32],
2098
[7, 14, 7, 19],
2099
[8, 14, 8, 19],
2100
[9, 14, 9, 19],
2101
]
2102
);
2103
2104
findModel.replaceAll();
2105
2106
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "goodbye world, Goodbye!" << endl;');
2107
assert.strictEqual(editor.getModel()!.getLineContent(7), ' cout << "goodbye world again" << endl;');
2108
assert.strictEqual(editor.getModel()!.getLineContent(8), ' cout << "Goodbye world again" << endl;');
2109
assert.strictEqual(editor.getModel()!.getLineContent(9), ' cout << "goodbyeworld again" << endl;');
2110
2111
assertFindState(
2112
editor,
2113
[1, 1, 1, 1],
2114
null,
2115
[]
2116
);
2117
2118
findModel.dispose();
2119
findState.dispose();
2120
});
2121
2122
findTest('issue #18711 replaceAll with empty string', (editor) => {
2123
const findState = disposables.add(new FindReplaceState());
2124
findState.change({ searchString: 'hello', replaceString: '', wholeWord: true }, false);
2125
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
2126
2127
assertFindState(
2128
editor,
2129
[1, 1, 1, 1],
2130
null,
2131
[
2132
[6, 14, 6, 19],
2133
[6, 27, 6, 32],
2134
[7, 14, 7, 19],
2135
[8, 14, 8, 19]
2136
]
2137
);
2138
2139
findModel.replaceAll();
2140
assertFindState(
2141
editor,
2142
[1, 1, 1, 1],
2143
null,
2144
[]
2145
);
2146
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << " world, !" << endl;');
2147
assert.strictEqual(editor.getModel()!.getLineContent(7), ' cout << " world again" << endl;');
2148
assert.strictEqual(editor.getModel()!.getLineContent(8), ' cout << " world again" << endl;');
2149
2150
findModel.dispose();
2151
findState.dispose();
2152
});
2153
2154
findTest('issue #32522 replaceAll with ^ on more than 1000 matches', (editor) => {
2155
let initialText = '';
2156
for (let i = 0; i < 1100; i++) {
2157
initialText += 'line' + i + '\n';
2158
}
2159
editor.getModel()!.setValue(initialText);
2160
const findState = disposables.add(new FindReplaceState());
2161
findState.change({ searchString: '^', replaceString: 'a ', isRegex: true }, false);
2162
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
2163
2164
findModel.replaceAll();
2165
2166
let expectedText = '';
2167
for (let i = 0; i < 1100; i++) {
2168
expectedText += 'a line' + i + '\n';
2169
}
2170
expectedText += 'a ';
2171
assert.strictEqual(editor.getModel()!.getValue(), expectedText);
2172
2173
findModel.dispose();
2174
findState.dispose();
2175
});
2176
2177
findTest('issue #19740 Find and replace capture group/backreference inserts `undefined` instead of empty string', (editor) => {
2178
const findState = disposables.add(new FindReplaceState());
2179
findState.change({ searchString: 'hello(z)?', replaceString: 'hi$1', isRegex: true, matchCase: true }, false);
2180
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
2181
2182
assertFindState(
2183
editor,
2184
[1, 1, 1, 1],
2185
null,
2186
[
2187
[6, 14, 6, 19],
2188
[7, 14, 7, 19],
2189
[9, 14, 9, 19]
2190
]
2191
);
2192
2193
findModel.replaceAll();
2194
assertFindState(
2195
editor,
2196
[1, 1, 1, 1],
2197
null,
2198
[]
2199
);
2200
assert.strictEqual(editor.getModel()!.getLineContent(6), ' cout << "hi world, Hello!" << endl;');
2201
assert.strictEqual(editor.getModel()!.getLineContent(7), ' cout << "hi world again" << endl;');
2202
assert.strictEqual(editor.getModel()!.getLineContent(9), ' cout << "hiworld again" << endl;');
2203
2204
findModel.dispose();
2205
findState.dispose();
2206
});
2207
2208
findTest('issue #27083. search scope works even if it is a single line', (editor) => {
2209
const findState = disposables.add(new FindReplaceState());
2210
findState.change({ searchString: 'hello', wholeWord: true, searchScope: [new Range(7, 1, 8, 1)] }, false);
2211
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
2212
2213
assertFindState(
2214
editor,
2215
[1, 1, 1, 1],
2216
null,
2217
[
2218
[7, 14, 7, 19]
2219
]
2220
);
2221
2222
findModel.dispose();
2223
findState.dispose();
2224
});
2225
2226
findTest('issue #3516: Control behavior of "Next" operations (not looping back to beginning)', (editor) => {
2227
const findState = disposables.add(new FindReplaceState());
2228
findState.change({ searchString: 'hello', loop: false }, false);
2229
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
2230
2231
assert.strictEqual(findState.matchesCount, 5);
2232
2233
// Test next operations
2234
assert.strictEqual(findState.matchesPosition, 0);
2235
assert.strictEqual(findState.canNavigateForward(), true);
2236
assert.strictEqual(findState.canNavigateBack(), true);
2237
2238
findModel.moveToNextMatch();
2239
assert.strictEqual(findState.matchesPosition, 1);
2240
assert.strictEqual(findState.canNavigateForward(), true);
2241
assert.strictEqual(findState.canNavigateBack(), false);
2242
2243
findModel.moveToNextMatch();
2244
assert.strictEqual(findState.matchesPosition, 2);
2245
assert.strictEqual(findState.canNavigateForward(), true);
2246
assert.strictEqual(findState.canNavigateBack(), true);
2247
2248
findModel.moveToNextMatch();
2249
assert.strictEqual(findState.matchesPosition, 3);
2250
assert.strictEqual(findState.canNavigateForward(), true);
2251
assert.strictEqual(findState.canNavigateBack(), true);
2252
2253
findModel.moveToNextMatch();
2254
assert.strictEqual(findState.matchesPosition, 4);
2255
assert.strictEqual(findState.canNavigateForward(), true);
2256
assert.strictEqual(findState.canNavigateBack(), true);
2257
2258
findModel.moveToNextMatch();
2259
assert.strictEqual(findState.matchesPosition, 5);
2260
assert.strictEqual(findState.canNavigateForward(), false);
2261
assert.strictEqual(findState.canNavigateBack(), true);
2262
2263
findModel.moveToNextMatch();
2264
assert.strictEqual(findState.matchesPosition, 5);
2265
assert.strictEqual(findState.canNavigateForward(), false);
2266
assert.strictEqual(findState.canNavigateBack(), true);
2267
2268
findModel.moveToNextMatch();
2269
assert.strictEqual(findState.matchesPosition, 5);
2270
assert.strictEqual(findState.canNavigateForward(), false);
2271
assert.strictEqual(findState.canNavigateBack(), true);
2272
2273
// Test previous operations
2274
findModel.moveToPrevMatch();
2275
assert.strictEqual(findState.matchesPosition, 4);
2276
assert.strictEqual(findState.canNavigateForward(), true);
2277
assert.strictEqual(findState.canNavigateBack(), true);
2278
2279
findModel.moveToPrevMatch();
2280
assert.strictEqual(findState.matchesPosition, 3);
2281
assert.strictEqual(findState.canNavigateForward(), true);
2282
assert.strictEqual(findState.canNavigateBack(), true);
2283
2284
findModel.moveToPrevMatch();
2285
assert.strictEqual(findState.matchesPosition, 2);
2286
assert.strictEqual(findState.canNavigateForward(), true);
2287
assert.strictEqual(findState.canNavigateBack(), true);
2288
2289
findModel.moveToPrevMatch();
2290
assert.strictEqual(findState.matchesPosition, 1);
2291
assert.strictEqual(findState.canNavigateForward(), true);
2292
assert.strictEqual(findState.canNavigateBack(), false);
2293
2294
findModel.moveToPrevMatch();
2295
assert.strictEqual(findState.matchesPosition, 1);
2296
assert.strictEqual(findState.canNavigateForward(), true);
2297
assert.strictEqual(findState.canNavigateBack(), false);
2298
2299
findModel.moveToPrevMatch();
2300
assert.strictEqual(findState.matchesPosition, 1);
2301
assert.strictEqual(findState.canNavigateForward(), true);
2302
assert.strictEqual(findState.canNavigateBack(), false);
2303
2304
});
2305
2306
findTest('issue #3516: Control behavior of "Next" operations (looping back to beginning)', (editor) => {
2307
const findState = disposables.add(new FindReplaceState());
2308
findState.change({ searchString: 'hello' }, false);
2309
const findModel = disposables.add(new FindModelBoundToEditorModel(editor, findState));
2310
2311
assert.strictEqual(findState.matchesCount, 5);
2312
2313
// Test next operations
2314
assert.strictEqual(findState.matchesPosition, 0);
2315
assert.strictEqual(findState.canNavigateForward(), true);
2316
assert.strictEqual(findState.canNavigateBack(), true);
2317
2318
findModel.moveToNextMatch();
2319
assert.strictEqual(findState.matchesPosition, 1);
2320
assert.strictEqual(findState.canNavigateForward(), true);
2321
assert.strictEqual(findState.canNavigateBack(), true);
2322
2323
findModel.moveToNextMatch();
2324
assert.strictEqual(findState.matchesPosition, 2);
2325
assert.strictEqual(findState.canNavigateForward(), true);
2326
assert.strictEqual(findState.canNavigateBack(), true);
2327
2328
findModel.moveToNextMatch();
2329
assert.strictEqual(findState.matchesPosition, 3);
2330
assert.strictEqual(findState.canNavigateForward(), true);
2331
assert.strictEqual(findState.canNavigateBack(), true);
2332
2333
findModel.moveToNextMatch();
2334
assert.strictEqual(findState.matchesPosition, 4);
2335
assert.strictEqual(findState.canNavigateForward(), true);
2336
assert.strictEqual(findState.canNavigateBack(), true);
2337
2338
findModel.moveToNextMatch();
2339
assert.strictEqual(findState.matchesPosition, 5);
2340
assert.strictEqual(findState.canNavigateForward(), true);
2341
assert.strictEqual(findState.canNavigateBack(), true);
2342
2343
findModel.moveToNextMatch();
2344
assert.strictEqual(findState.matchesPosition, 1);
2345
assert.strictEqual(findState.canNavigateForward(), true);
2346
assert.strictEqual(findState.canNavigateBack(), true);
2347
2348
findModel.moveToNextMatch();
2349
assert.strictEqual(findState.matchesPosition, 2);
2350
assert.strictEqual(findState.canNavigateForward(), true);
2351
assert.strictEqual(findState.canNavigateBack(), true);
2352
2353
// Test previous operations
2354
findModel.moveToPrevMatch();
2355
assert.strictEqual(findState.matchesPosition, 1);
2356
assert.strictEqual(findState.canNavigateForward(), true);
2357
assert.strictEqual(findState.canNavigateBack(), true);
2358
2359
findModel.moveToPrevMatch();
2360
assert.strictEqual(findState.matchesPosition, 5);
2361
assert.strictEqual(findState.canNavigateForward(), true);
2362
assert.strictEqual(findState.canNavigateBack(), true);
2363
2364
findModel.moveToPrevMatch();
2365
assert.strictEqual(findState.matchesPosition, 4);
2366
assert.strictEqual(findState.canNavigateForward(), true);
2367
assert.strictEqual(findState.canNavigateBack(), true);
2368
2369
findModel.moveToPrevMatch();
2370
assert.strictEqual(findState.matchesPosition, 3);
2371
assert.strictEqual(findState.canNavigateForward(), true);
2372
assert.strictEqual(findState.canNavigateBack(), true);
2373
2374
findModel.moveToPrevMatch();
2375
assert.strictEqual(findState.matchesPosition, 2);
2376
assert.strictEqual(findState.canNavigateForward(), true);
2377
assert.strictEqual(findState.canNavigateBack(), true);
2378
2379
findModel.moveToPrevMatch();
2380
assert.strictEqual(findState.matchesPosition, 1);
2381
assert.strictEqual(findState.canNavigateForward(), true);
2382
assert.strictEqual(findState.canNavigateBack(), true);
2383
2384
});
2385
2386
});
2387
2388