Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Commit bdfdddd

Browse files
authored
Merge pull request #1086 from atom/ripgrep-option
Add config option to use `ripgrep` for scanning files
2 parents d4bcc42 + 8f0aa2d commit bdfdddd

File tree

5 files changed

+54
-12
lines changed

5 files changed

+54
-12
lines changed

docs/events.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Currently Find and Replace does not log any counter events.
1717
|-------|-------|
1818
| `ec` | `time-to-search`
1919
| `ev` | Number of found results
20+
| `el` | Search system in use (`ripgrep` or `standard`)
2021

2122
## Standard events
2223

lib/project/results-model.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,15 @@ module.exports = class ResultsModel {
216216
const trailingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountAfter')
217217

218218
const startTime = Date.now()
219+
const useRipgrep = atom.config.get('find-and-replace.useRipgrep')
219220

220221
this.inProgressSearchPromise = atom.workspace.scan(
221222
this.regex,
222223
{
223224
paths: searchPaths,
224225
onPathsSearched,
225226
leadingContextLineCount,
227+
ripgrep: useRipgrep,
226228
trailingContextLineCount
227229
},
228230
(result, error) => {
@@ -244,7 +246,11 @@ module.exports = class ResultsModel {
244246
} else {
245247
const resultsSummary = this.getResultsSummary()
246248

247-
this.metricsReporter.sendSearchEvent(Date.now() - startTime, resultsSummary.matchCount)
249+
this.metricsReporter.sendSearchEvent(
250+
Date.now() - startTime,
251+
resultsSummary.matchCount,
252+
useRipgrep ? 'ripgrep' : 'standard'
253+
)
248254
this.inProgressSearchPromise = null
249255
this.emitter.emit('did-finish-searching', resultsSummary)
250256
}

lib/reporter-proxy.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ module.exports = class ReporterProxy {
1919
delete this.reporter
2020
}
2121

22-
sendSearchEvent (duration, numResults) {
22+
sendSearchEvent (duration, numResults, crawler) {
2323
const metadata = {
2424
ec: 'time-to-search',
25-
ev: numResults
25+
ev: numResults,
26+
el: crawler
2627
}
2728

2829
this._addTiming(duration, metadata)

package.json

+6
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@
125125
"title": "Show Search Wrap Icon",
126126
"description": "Display a visual cue over the editor when looping through search results."
127127
},
128+
"useRipgrep": {
129+
"type": "boolean",
130+
"default": false,
131+
"title": "Use ripgrep",
132+
"description": "Use the experimental `ripgrep` search crawler. This will make searches substantially faster on large projects."
133+
},
128134
"autocompleteSearches": {
129135
"type": "boolean",
130136
"default": false,

spec/project-find-view-spec.js

+37-9
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ const ResultsPaneView = require('../lib/project/results-pane');
99
const etch = require('etch');
1010
const {beforeEach, it, fit, ffit, fffit, conditionPromise} = require('./async-spec-helpers')
1111

12-
describe('ProjectFindView', () => {
12+
for (const ripgrep of [false, true]) {
13+
describe(`ProjectFindView (ripgrep=${ripgrep})`, () => {
1314
const {stoppedChangingDelay} = TextBuffer.prototype;
1415
let activationPromise, searchPromise, editor, editorElement, findView,
1516
projectFindView, workspaceElement;
@@ -33,7 +34,14 @@ describe('ProjectFindView', () => {
3334
return getExistingResultsPane().refs.resultsView;
3435
}
3536

37+
function waitForSearchResults() {
38+
return conditionPromise(
39+
() => projectFindView.refs.descriptionLabel.textContent.includes('results found')
40+
)
41+
}
42+
3643
beforeEach(() => {
44+
atom.config.set('find-and-replace.useRipgrep', ripgrep)
3745
workspaceElement = atom.views.getView(atom.workspace);
3846
atom.config.set('core.excludeVcsIgnoredPaths', false);
3947
atom.project.setPaths([path.join(__dirname, 'fixtures')]);
@@ -278,6 +286,8 @@ describe('ProjectFindView', () => {
278286

279287
describe("when the find string contains an escaped char", () => {
280288
beforeEach(() => {
289+
jasmine.useRealClock()
290+
281291
let projectPath = temp.mkdirSync("atom");
282292
fs.writeFileSync(path.join(projectPath, "tabs.txt"), "\t\n\\\t\n\\\\t");
283293
atom.project.setPaths([projectPath]);
@@ -396,6 +406,7 @@ describe('ProjectFindView', () => {
396406
beforeEach(() => {
397407
workspaceElement.style.height = '1000px';
398408
atom.commands.dispatch(editorElement, 'project-find:show');
409+
jasmine.useRealClock()
399410
});
400411

401412
it("splits when option is right", async () => {
@@ -451,6 +462,7 @@ describe('ProjectFindView', () => {
451462

452463
await etch.update(resultsView1);
453464
await etch.update(resultsView2);
465+
await waitForSearchResults();
454466

455467
const resultCount = resultsPaneView1.querySelectorAll('.match-row').length;
456468
expect(resultCount).toBeGreaterThan(0);
@@ -690,11 +702,16 @@ describe('ProjectFindView', () => {
690702
});
691703

692704
describe("when project-find:confirm is triggered", () => {
705+
beforeEach(() => {
706+
jasmine.useRealClock()
707+
});
708+
693709
it("displays the results and no errors", async () => {
694710
projectFindView.findEditor.setText('items');
695711
atom.commands.dispatch(projectFindView.element, 'project-find:confirm');
696712

697713
await searchPromise;
714+
await waitForSearchResults();
698715

699716
const resultsView = getResultsView();
700717
await resultsView.heightInvalidationPromise
@@ -707,6 +724,7 @@ describe('ProjectFindView', () => {
707724
describe("when core:confirm is triggered", () => {
708725
beforeEach(() => {
709726
atom.commands.dispatch(workspaceElement, 'project-find:show')
727+
jasmine.useRealClock()
710728
});
711729

712730
describe("when the there search field is empty", () => {
@@ -799,21 +817,29 @@ describe('ProjectFindView', () => {
799817
expect(listView.element.querySelectorAll(".path-row")[1].parentElement).toHaveClass('selected');
800818

801819
editor.setText('there is one "items" in this file');
802-
advanceClock(editor.getBuffer().stoppedChangingDelay);
803820
await etch.getScheduler().getNextUpdatePromise()
804-
expect(resultsPaneView.refs.previewCount.textContent).toBe("8 results found in 2 files for items");
821+
await searchPromise;
822+
823+
await conditionPromise(
824+
() => resultsPaneView.refs.previewCount.textContent === "8 results found in 2 files for items"
825+
)
826+
805827
expect(listView.element.querySelectorAll(".path-row")[1].parentElement).toHaveClass('selected');
806828

807829
// Ensure the newly added item can be opened.
808830
await resultsView.moveDown()
809831
atom.commands.dispatch(resultsView.element, 'core:confirm');
810-
await new Promise(resolve => editor.onDidChangeSelectionRange(resolve));
811-
expect(editor.getSelectedText()).toBe("items")
832+
await waitForSearchResults();
833+
await conditionPromise(
834+
() => editor.getSelectedText() === "items"
835+
)
812836

813837
editor.setText('no matches in this file');
814-
advanceClock(editor.getBuffer().stoppedChangingDelay);
815-
await etch.getScheduler().getNextUpdatePromise()
816-
expect(resultsPaneView.refs.previewCount.textContent).toBe("7 results found in 1 file for items");
838+
await waitForSearchResults();
839+
840+
await conditionPromise(
841+
() => resultsPaneView.refs.previewCount.textContent === "7 results found in 1 file for items"
842+
)
817843
});
818844

819845
it("doesn't update the results list when a buffer outside the project changes", async () => {
@@ -826,7 +852,6 @@ describe('ProjectFindView', () => {
826852
const resultsPaneView = getExistingResultsPane();
827853

828854
await resultsView.heightInvalidationPromise
829-
console.log(resultsView.refs.listView.element)
830855
expect(resultsView.refs.listView.element.querySelectorAll(".list-item")).toHaveLength(13);
831856
expect(resultsPaneView.refs.previewCount.textContent).toBe("13 results found in 2 files for items");
832857

@@ -1087,6 +1112,7 @@ describe('ProjectFindView', () => {
10871112
});
10881113

10891114
it('highlights the search results in the selected file', async () => {
1115+
jasmine.useRealClock();
10901116
// Process here is to
10911117
// * open samplejs
10921118
// * run a search that has sample js results
@@ -1100,6 +1126,7 @@ describe('ProjectFindView', () => {
11001126
projectFindView.findEditor.setText('item');
11011127
atom.commands.dispatch(projectFindView.element, 'core:confirm');
11021128
await searchPromise;
1129+
await waitForSearchResults();
11031130

11041131
const resultsView = getResultsView();
11051132
resultsView.scrollToBottom(); // To load ALL the results
@@ -1630,6 +1657,7 @@ describe('ProjectFindView', () => {
16301657
});
16311658
});
16321659
});
1660+
}
16331661

16341662
function simulateResizeEvent(element) {
16351663
Array.from(element.children).forEach((child) => {

0 commit comments

Comments
 (0)