mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-19 15:08:08 +03:00
WIP
Co-Authored-By: Rafael Oleza <rafeca@users.noreply.github.com>
This commit is contained in:
parent
b79d9088e2
commit
fd82a58f1d
40
package-lock.json
generated
40
package-lock.json
generated
@ -1534,11 +1534,11 @@
|
||||
"dependencies": {
|
||||
"etch": {
|
||||
"version": "0.9.0",
|
||||
"bundled": true
|
||||
"resolved": false
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.1",
|
||||
"bundled": true
|
||||
"resolved": false
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1824,11 +1824,11 @@
|
||||
"dependencies": {
|
||||
"underscore": {
|
||||
"version": "1.9.1",
|
||||
"bundled": true
|
||||
"resolved": false
|
||||
},
|
||||
"underscore-plus": {
|
||||
"version": "1.7.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"requires": {
|
||||
"underscore": "^1.9.1"
|
||||
}
|
||||
@ -2120,6 +2120,7 @@
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
|
||||
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"hoek": "2.x.x"
|
||||
}
|
||||
@ -2679,7 +2680,7 @@
|
||||
"dependencies": {
|
||||
"grim": {
|
||||
"version": "2.0.2",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"requires": {
|
||||
"event-kit": "^2.0.0"
|
||||
}
|
||||
@ -2832,22 +2833,22 @@
|
||||
"dependencies": {
|
||||
"etch": {
|
||||
"version": "0.9.0",
|
||||
"bundled": true
|
||||
"resolved": false
|
||||
},
|
||||
"grim": {
|
||||
"version": "2.0.2",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"requires": {
|
||||
"event-kit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"underscore": {
|
||||
"version": "1.9.1",
|
||||
"bundled": true
|
||||
"resolved": false
|
||||
},
|
||||
"underscore-plus": {
|
||||
"version": "1.7.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"requires": {
|
||||
"underscore": "^1.9.1"
|
||||
}
|
||||
@ -3184,11 +3185,11 @@
|
||||
"dependencies": {
|
||||
"underscore": {
|
||||
"version": "1.9.1",
|
||||
"bundled": true
|
||||
"resolved": false
|
||||
},
|
||||
"underscore-plus": {
|
||||
"version": "1.7.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"requires": {
|
||||
"underscore": "^1.9.1"
|
||||
}
|
||||
@ -3660,11 +3661,11 @@
|
||||
"dependencies": {
|
||||
"rimraf": {
|
||||
"version": "2.2.8",
|
||||
"bundled": true
|
||||
"resolved": false
|
||||
},
|
||||
"temp": {
|
||||
"version": "0.8.3",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"requires": {
|
||||
"os-tmpdir": "^1.0.0",
|
||||
"rimraf": "~2.2.6"
|
||||
@ -3867,7 +3868,8 @@
|
||||
"hoek": {
|
||||
"version": "2.16.3",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
|
||||
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
|
||||
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
|
||||
"optional": true
|
||||
},
|
||||
"home-or-tmp": {
|
||||
"version": "1.0.0",
|
||||
@ -4136,7 +4138,7 @@
|
||||
"resolved": "https://registry.npmjs.org/jasmine-focused/-/jasmine-focused-1.0.7.tgz",
|
||||
"integrity": "sha1-uDx1fIAOaOHW78GjoaE/85/23NI=",
|
||||
"requires": {
|
||||
"jasmine-node": "git+https://github.com/kevinsawicki/jasmine-node.git#81af4f953a2b7dfb5bde8331c05362a4b464c5ef",
|
||||
"jasmine-node": "jasmine-node@git+https://github.com/kevinsawicki/jasmine-node.git#81af4f953a2b7dfb5bde8331c05362a4b464c5ef",
|
||||
"underscore-plus": "1.x",
|
||||
"walkdir": "0.0.7"
|
||||
}
|
||||
@ -4719,11 +4721,11 @@
|
||||
"dependencies": {
|
||||
"underscore": {
|
||||
"version": "1.9.1",
|
||||
"bundled": true
|
||||
"resolved": false
|
||||
},
|
||||
"underscore-plus": {
|
||||
"version": "1.7.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"requires": {
|
||||
"underscore": "^1.9.1"
|
||||
}
|
||||
@ -4746,11 +4748,11 @@
|
||||
"dependencies": {
|
||||
"underscore": {
|
||||
"version": "1.9.1",
|
||||
"bundled": true
|
||||
"resolved": false
|
||||
},
|
||||
"underscore-plus": {
|
||||
"version": "1.7.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"requires": {
|
||||
"underscore": "^1.9.1"
|
||||
}
|
||||
|
@ -163,6 +163,7 @@
|
||||
"tree-view": "https://www.atom.io/api/packages/tree-view/versions/0.228.0/tarball",
|
||||
"typescript-simple": "1.0.0",
|
||||
"update-package-dependencies": "https://www.atom.io/api/packages/update-package-dependencies/versions/0.13.1/tarball",
|
||||
"vscode-ripgrep": "^1.2.5",
|
||||
"welcome": "https://www.atom.io/api/packages/welcome/versions/0.36.9/tarball",
|
||||
"whitespace": "https://www.atom.io/api/packages/whitespace/versions/0.37.7/tarball",
|
||||
"winreg": "^1.2.1",
|
||||
|
4
script/package-lock.json
generated
4
script/package-lock.json
generated
@ -901,6 +901,7 @@
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz",
|
||||
"integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"hoek": "0.9.x"
|
||||
}
|
||||
@ -3990,7 +3991,8 @@
|
||||
"hoek": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz",
|
||||
"integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU="
|
||||
"integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=",
|
||||
"optional": true
|
||||
},
|
||||
"home-or-tmp": {
|
||||
"version": "1.0.0",
|
||||
|
@ -2407,19 +2407,21 @@ describe('Workspace', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('::scan(regex, options, callback)', () => {
|
||||
describe('when called with a regex', () => {
|
||||
it('calls the callback with all regex results in all files in the project', () => {
|
||||
const results = []
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(
|
||||
for (const ripgrep of [true, /* false */]) {
|
||||
describe(`::scan(regex, options, callback) { ripgrep: ${ripgrep} }`, () => {
|
||||
function scan(regex, options, iterator) {
|
||||
return atom.workspace.scan(regex, {...options, ripgrep}, iterator)
|
||||
}
|
||||
|
||||
describe('when called with a regex', () => {
|
||||
fit('calls the callback with all regex results in all files in the project', async () => {
|
||||
const results = []
|
||||
await scan(
|
||||
/(a)+/,
|
||||
{ leadingContextLineCount: 1, trailingContextLineCount: 1 },
|
||||
result => results.push(result)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
runs(() => {
|
||||
expect(results).toHaveLength(3)
|
||||
expect(results[0].filePath).toBe(
|
||||
atom.project.getDirectories()[0].resolve('a')
|
||||
@ -2431,480 +2433,480 @@ describe('Workspace', () => {
|
||||
lineTextOffset: 0,
|
||||
range: [[0, 0], [0, 3]],
|
||||
leadingContextLines: [],
|
||||
trailingContextLines: ['cc aa cc']
|
||||
trailingContextLines: ripgrep ? [] : ['cc aa cc']
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('works with with escaped literals (like $ and ^)', () => {
|
||||
const results = []
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(
|
||||
/\$\w+/,
|
||||
{ leadingContextLineCount: 1, trailingContextLineCount: 1 },
|
||||
result => results.push(result)
|
||||
it('works with with escaped literals (like $ and ^)', () => {
|
||||
const results = []
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(
|
||||
/\$\w+/,
|
||||
{ leadingContextLineCount: 1, trailingContextLineCount: 1 },
|
||||
result => results.push(result)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
runs(() => {
|
||||
expect(results.length).toBe(1)
|
||||
const { filePath, matches } = results[0]
|
||||
expect(filePath).toBe(atom.project.getDirectories()[0].resolve('a'))
|
||||
expect(matches).toHaveLength(1)
|
||||
expect(matches[0]).toEqual({
|
||||
matchText: '$bill',
|
||||
lineText: 'dollar$bill',
|
||||
lineTextOffset: 0,
|
||||
range: [[2, 6], [2, 11]],
|
||||
leadingContextLines: ['cc aa cc'],
|
||||
trailingContextLines: []
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('works on evil filenames', () => {
|
||||
atom.config.set('core.excludeVcsIgnoredPaths', false)
|
||||
platform.generateEvilFiles()
|
||||
atom.project.setPaths([path.join(__dirname, 'fixtures', 'evil-files')])
|
||||
const paths = []
|
||||
let matches = []
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/evil/, result => {
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
})
|
||||
)
|
||||
|
||||
runs(() => {
|
||||
_.each(matches, m => expect(m.matchText).toEqual('evil'))
|
||||
|
||||
if (platform.isWindows()) {
|
||||
expect(paths.length).toBe(3)
|
||||
expect(paths[0]).toMatch(/a_file_with_utf8.txt$/)
|
||||
expect(paths[1]).toMatch(/file with spaces.txt$/)
|
||||
expect(path.basename(paths[2])).toBe('utfa\u0306.md')
|
||||
} else {
|
||||
expect(paths.length).toBe(5)
|
||||
expect(paths[0]).toMatch(/a_file_with_utf8.txt$/)
|
||||
expect(paths[1]).toMatch(/file with spaces.txt$/)
|
||||
expect(paths[2]).toMatch(/goddam\nnewlines$/m)
|
||||
expect(paths[3]).toMatch(/quote".txt$/m)
|
||||
expect(path.basename(paths[4])).toBe('utfa\u0306.md')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('ignores case if the regex includes the `i` flag', () => {
|
||||
const results = []
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/DOLLAR/i, result => results.push(result))
|
||||
)
|
||||
|
||||
runs(() => expect(results).toHaveLength(1))
|
||||
})
|
||||
|
||||
describe('when the core.excludeVcsIgnoredPaths config is truthy', () => {
|
||||
let projectPath
|
||||
let ignoredPath
|
||||
|
||||
beforeEach(() => {
|
||||
const sourceProjectPath = path.join(
|
||||
__dirname,
|
||||
'fixtures',
|
||||
'git',
|
||||
'working-dir'
|
||||
)
|
||||
projectPath = path.join(temp.mkdirSync('atom'))
|
||||
|
||||
const writerStream = fstream.Writer(projectPath)
|
||||
fstream.Reader(sourceProjectPath).pipe(writerStream)
|
||||
|
||||
waitsFor(done => {
|
||||
writerStream.on('close', done)
|
||||
writerStream.on('error', done)
|
||||
})
|
||||
|
||||
runs(() => {
|
||||
fs.renameSync(
|
||||
path.join(projectPath, 'git.git'),
|
||||
path.join(projectPath, '.git')
|
||||
)
|
||||
ignoredPath = path.join(projectPath, 'ignored.txt')
|
||||
fs.writeFileSync(ignoredPath, 'this match should not be included')
|
||||
expect(results.length).toBe(1)
|
||||
const { filePath, matches } = results[0]
|
||||
expect(filePath).toBe(atom.project.getDirectories()[0].resolve('a'))
|
||||
expect(matches).toHaveLength(1)
|
||||
expect(matches[0]).toEqual({
|
||||
matchText: '$bill',
|
||||
lineText: 'dollar$bill',
|
||||
lineTextOffset: 0,
|
||||
range: [[2, 6], [2, 11]],
|
||||
leadingContextLines: ['cc aa cc'],
|
||||
trailingContextLines: []
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
if (fs.existsSync(projectPath)) {
|
||||
fs.removeSync(projectPath)
|
||||
}
|
||||
it('works on evil filenames', () => {
|
||||
atom.config.set('core.excludeVcsIgnoredPaths', false)
|
||||
platform.generateEvilFiles()
|
||||
atom.project.setPaths([path.join(__dirname, 'fixtures', 'evil-files')])
|
||||
const paths = []
|
||||
let matches = []
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/evil/, result => {
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
})
|
||||
)
|
||||
|
||||
runs(() => {
|
||||
_.each(matches, m => expect(m.matchText).toEqual('evil'))
|
||||
|
||||
if (platform.isWindows()) {
|
||||
expect(paths.length).toBe(3)
|
||||
expect(paths[0]).toMatch(/a_file_with_utf8.txt$/)
|
||||
expect(paths[1]).toMatch(/file with spaces.txt$/)
|
||||
expect(path.basename(paths[2])).toBe('utfa\u0306.md')
|
||||
} else {
|
||||
expect(paths.length).toBe(5)
|
||||
expect(paths[0]).toMatch(/a_file_with_utf8.txt$/)
|
||||
expect(paths[1]).toMatch(/file with spaces.txt$/)
|
||||
expect(paths[2]).toMatch(/goddam\nnewlines$/m)
|
||||
expect(paths[3]).toMatch(/quote".txt$/m)
|
||||
expect(path.basename(paths[4])).toBe('utfa\u0306.md')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('excludes ignored files', () => {
|
||||
it('ignores case if the regex includes the `i` flag', () => {
|
||||
const results = []
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/DOLLAR/i, result => results.push(result))
|
||||
)
|
||||
|
||||
runs(() => expect(results).toHaveLength(1))
|
||||
})
|
||||
|
||||
describe('when the core.excludeVcsIgnoredPaths config is truthy', () => {
|
||||
let projectPath
|
||||
let ignoredPath
|
||||
|
||||
beforeEach(() => {
|
||||
const sourceProjectPath = path.join(
|
||||
__dirname,
|
||||
'fixtures',
|
||||
'git',
|
||||
'working-dir'
|
||||
)
|
||||
projectPath = path.join(temp.mkdirSync('atom'))
|
||||
|
||||
const writerStream = fstream.Writer(projectPath)
|
||||
fstream.Reader(sourceProjectPath).pipe(writerStream)
|
||||
|
||||
waitsFor(done => {
|
||||
writerStream.on('close', done)
|
||||
writerStream.on('error', done)
|
||||
})
|
||||
|
||||
runs(() => {
|
||||
fs.renameSync(
|
||||
path.join(projectPath, 'git.git'),
|
||||
path.join(projectPath, '.git')
|
||||
)
|
||||
ignoredPath = path.join(projectPath, 'ignored.txt')
|
||||
fs.writeFileSync(ignoredPath, 'this match should not be included')
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
if (fs.existsSync(projectPath)) {
|
||||
fs.removeSync(projectPath)
|
||||
}
|
||||
})
|
||||
|
||||
it('excludes ignored files', () => {
|
||||
atom.project.setPaths([projectPath])
|
||||
atom.config.set('core.excludeVcsIgnoredPaths', true)
|
||||
const resultHandler = jasmine.createSpy('result found')
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/match/, results => resultHandler())
|
||||
)
|
||||
|
||||
runs(() => expect(resultHandler).not.toHaveBeenCalled())
|
||||
})
|
||||
})
|
||||
|
||||
it('includes only files when a directory filter is specified', () => {
|
||||
const projectPath = path.join(path.join(__dirname, 'fixtures', 'dir'))
|
||||
atom.project.setPaths([projectPath])
|
||||
atom.config.set('core.excludeVcsIgnoredPaths', true)
|
||||
|
||||
const filePath = path.join(projectPath, 'a-dir', 'oh-git')
|
||||
|
||||
const paths = []
|
||||
let matches = []
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(
|
||||
/aaa/,
|
||||
{ paths: [`a-dir${path.sep}`] },
|
||||
result => {
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
runs(() => {
|
||||
expect(paths.length).toBe(1)
|
||||
expect(paths[0]).toBe(filePath)
|
||||
expect(matches.length).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
it("includes files and folders that begin with a '.'", () => {
|
||||
const projectPath = temp.mkdirSync('atom-spec-workspace')
|
||||
const filePath = path.join(projectPath, '.text')
|
||||
fs.writeFileSync(filePath, 'match this')
|
||||
atom.project.setPaths([projectPath])
|
||||
const paths = []
|
||||
let matches = []
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/match this/, result => {
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
})
|
||||
)
|
||||
|
||||
runs(() => {
|
||||
expect(paths.length).toBe(1)
|
||||
expect(paths[0]).toBe(filePath)
|
||||
expect(matches.length).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
it('excludes values in core.ignoredNames', () => {
|
||||
const ignoredNames = atom.config.get('core.ignoredNames')
|
||||
ignoredNames.push('a')
|
||||
atom.config.set('core.ignoredNames', ignoredNames)
|
||||
|
||||
const resultHandler = jasmine.createSpy('result found')
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/match/, results => resultHandler())
|
||||
atom.workspace.scan(/dollar/, results => resultHandler())
|
||||
)
|
||||
|
||||
runs(() => expect(resultHandler).not.toHaveBeenCalled())
|
||||
})
|
||||
})
|
||||
|
||||
it('includes only files when a directory filter is specified', () => {
|
||||
const projectPath = path.join(path.join(__dirname, 'fixtures', 'dir'))
|
||||
atom.project.setPaths([projectPath])
|
||||
it('scans buffer contents if the buffer is modified', () => {
|
||||
let editor = null
|
||||
const results = []
|
||||
|
||||
const filePath = path.join(projectPath, 'a-dir', 'oh-git')
|
||||
|
||||
const paths = []
|
||||
let matches = []
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(
|
||||
/aaa/,
|
||||
{ paths: [`a-dir${path.sep}`] },
|
||||
result => {
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
runs(() => {
|
||||
expect(paths.length).toBe(1)
|
||||
expect(paths[0]).toBe(filePath)
|
||||
expect(matches.length).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
it("includes files and folders that begin with a '.'", () => {
|
||||
const projectPath = temp.mkdirSync('atom-spec-workspace')
|
||||
const filePath = path.join(projectPath, '.text')
|
||||
fs.writeFileSync(filePath, 'match this')
|
||||
atom.project.setPaths([projectPath])
|
||||
const paths = []
|
||||
let matches = []
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/match this/, result => {
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
})
|
||||
)
|
||||
|
||||
runs(() => {
|
||||
expect(paths.length).toBe(1)
|
||||
expect(paths[0]).toBe(filePath)
|
||||
expect(matches.length).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
it('excludes values in core.ignoredNames', () => {
|
||||
const ignoredNames = atom.config.get('core.ignoredNames')
|
||||
ignoredNames.push('a')
|
||||
atom.config.set('core.ignoredNames', ignoredNames)
|
||||
|
||||
const resultHandler = jasmine.createSpy('result found')
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/dollar/, results => resultHandler())
|
||||
)
|
||||
|
||||
runs(() => expect(resultHandler).not.toHaveBeenCalled())
|
||||
})
|
||||
|
||||
it('scans buffer contents if the buffer is modified', () => {
|
||||
let editor = null
|
||||
const results = []
|
||||
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.open('a').then(o => {
|
||||
editor = o
|
||||
editor.setText('Elephant')
|
||||
})
|
||||
)
|
||||
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/a|Elephant/, result => results.push(result))
|
||||
)
|
||||
|
||||
runs(() => {
|
||||
expect(results).toHaveLength(3)
|
||||
const resultForA = _.find(
|
||||
results,
|
||||
({ filePath }) => path.basename(filePath) === 'a'
|
||||
)
|
||||
expect(resultForA.matches).toHaveLength(1)
|
||||
expect(resultForA.matches[0].matchText).toBe('Elephant')
|
||||
})
|
||||
})
|
||||
|
||||
it('ignores buffers outside the project', () => {
|
||||
let editor = null
|
||||
const results = []
|
||||
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.open(temp.openSync().path).then(o => {
|
||||
editor = o
|
||||
editor.setText('Elephant')
|
||||
})
|
||||
)
|
||||
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/Elephant/, result => results.push(result))
|
||||
)
|
||||
|
||||
runs(() => expect(results).toHaveLength(0))
|
||||
})
|
||||
|
||||
describe('when the project has multiple root directories', () => {
|
||||
let dir1
|
||||
let dir2
|
||||
let file1
|
||||
let file2
|
||||
|
||||
beforeEach(() => {
|
||||
dir1 = atom.project.getPaths()[0]
|
||||
file1 = path.join(dir1, 'a-dir', 'oh-git')
|
||||
|
||||
dir2 = temp.mkdirSync('a-second-dir')
|
||||
const aDir2 = path.join(dir2, 'a-dir')
|
||||
file2 = path.join(aDir2, 'a-file')
|
||||
fs.mkdirSync(aDir2)
|
||||
fs.writeFileSync(file2, 'ccc aaaa')
|
||||
|
||||
atom.project.addPath(dir2)
|
||||
})
|
||||
|
||||
it("searches matching files in all of the project's root directories", () => {
|
||||
const resultPaths = []
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/aaaa/, ({ filePath }) =>
|
||||
resultPaths.push(filePath)
|
||||
)
|
||||
atom.workspace.open('a').then(o => {
|
||||
editor = o
|
||||
editor.setText('Elephant')
|
||||
})
|
||||
)
|
||||
|
||||
runs(() => expect(resultPaths.sort()).toEqual([file1, file2].sort()))
|
||||
})
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/a|Elephant/, result => results.push(result))
|
||||
)
|
||||
|
||||
describe('when an inclusion path starts with the basename of a root directory', () => {
|
||||
it('interprets the inclusion path as starting from that directory', () => {
|
||||
waitsForPromise(() => {
|
||||
const resultPaths = []
|
||||
return atom.workspace
|
||||
.scan(/aaaa/, { paths: ['dir'] }, ({ filePath }) => {
|
||||
if (!resultPaths.includes(filePath)) {
|
||||
resultPaths.push(filePath)
|
||||
}
|
||||
})
|
||||
.then(() => expect(resultPaths).toEqual([file1]))
|
||||
})
|
||||
|
||||
waitsForPromise(() => {
|
||||
const resultPaths = []
|
||||
return atom.workspace
|
||||
.scan(
|
||||
/aaaa/,
|
||||
{ paths: [path.join('dir', 'a-dir')] },
|
||||
({ filePath }) => {
|
||||
if (!resultPaths.includes(filePath)) {
|
||||
resultPaths.push(filePath)
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(() => expect(resultPaths).toEqual([file1]))
|
||||
})
|
||||
|
||||
waitsForPromise(() => {
|
||||
const resultPaths = []
|
||||
return atom.workspace
|
||||
.scan(
|
||||
/aaaa/,
|
||||
{ paths: [path.basename(dir2)] },
|
||||
({ filePath }) => {
|
||||
if (!resultPaths.includes(filePath)) {
|
||||
resultPaths.push(filePath)
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(() => expect(resultPaths).toEqual([file2]))
|
||||
})
|
||||
|
||||
waitsForPromise(() => {
|
||||
const resultPaths = []
|
||||
return atom.workspace
|
||||
.scan(
|
||||
/aaaa/,
|
||||
{ paths: [path.join(path.basename(dir2), 'a-dir')] },
|
||||
({ filePath }) => {
|
||||
if (!resultPaths.includes(filePath)) {
|
||||
resultPaths.push(filePath)
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(() => expect(resultPaths).toEqual([file2]))
|
||||
})
|
||||
runs(() => {
|
||||
expect(results).toHaveLength(3)
|
||||
const resultForA = _.find(
|
||||
results,
|
||||
({ filePath }) => path.basename(filePath) === 'a'
|
||||
)
|
||||
expect(resultForA.matches).toHaveLength(1)
|
||||
expect(resultForA.matches[0].matchText).toBe('Elephant')
|
||||
})
|
||||
})
|
||||
|
||||
describe('when a custom directory searcher is registered', () => {
|
||||
let fakeSearch = null
|
||||
// Function that is invoked once all of the fields on fakeSearch are set.
|
||||
let onFakeSearchCreated = null
|
||||
it('ignores buffers outside the project', () => {
|
||||
let editor = null
|
||||
const results = []
|
||||
|
||||
class FakeSearch {
|
||||
constructor (options) {
|
||||
// Note that hoisting resolve and reject in this way is generally frowned upon.
|
||||
this.options = options
|
||||
this.promise = new Promise((resolve, reject) => {
|
||||
this.hoistedResolve = resolve
|
||||
this.hoistedReject = reject
|
||||
if (typeof onFakeSearchCreated === 'function') {
|
||||
onFakeSearchCreated(this)
|
||||
}
|
||||
})
|
||||
}
|
||||
then (...args) {
|
||||
return this.promise.then.apply(this.promise, args)
|
||||
}
|
||||
cancel () {
|
||||
this.cancelled = true
|
||||
// According to the spec for a DirectorySearcher, invoking `cancel()` should
|
||||
// resolve the thenable rather than reject it.
|
||||
this.hoistedResolve()
|
||||
}
|
||||
}
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.open(temp.openSync().path).then(o => {
|
||||
editor = o
|
||||
editor.setText('Elephant')
|
||||
})
|
||||
)
|
||||
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/Elephant/, result => results.push(result))
|
||||
)
|
||||
|
||||
runs(() => expect(results).toHaveLength(0))
|
||||
})
|
||||
|
||||
describe('when the project has multiple root directories', () => {
|
||||
let dir1
|
||||
let dir2
|
||||
let file1
|
||||
let file2
|
||||
|
||||
beforeEach(() => {
|
||||
fakeSearch = null
|
||||
onFakeSearchCreated = null
|
||||
atom.packages.serviceHub.provide(
|
||||
'atom.directory-searcher',
|
||||
'0.1.0',
|
||||
{
|
||||
canSearchDirectory (directory) {
|
||||
return directory.getPath() === dir1
|
||||
},
|
||||
search (directory, regex, options) {
|
||||
fakeSearch = new FakeSearch(options)
|
||||
return fakeSearch
|
||||
}
|
||||
}
|
||||
)
|
||||
dir1 = atom.project.getPaths()[0]
|
||||
file1 = path.join(dir1, 'a-dir', 'oh-git')
|
||||
|
||||
waitsFor(() => atom.workspace.directorySearchers.length > 0)
|
||||
dir2 = temp.mkdirSync('a-second-dir')
|
||||
const aDir2 = path.join(dir2, 'a-dir')
|
||||
file2 = path.join(aDir2, 'a-file')
|
||||
fs.mkdirSync(aDir2)
|
||||
fs.writeFileSync(file2, 'ccc aaaa')
|
||||
|
||||
atom.project.addPath(dir2)
|
||||
})
|
||||
|
||||
it('can override the DefaultDirectorySearcher on a per-directory basis', () => {
|
||||
const foreignFilePath = 'ssh://foreign-directory:8080/hello.txt'
|
||||
const numPathsSearchedInDir2 = 1
|
||||
const numPathsToPretendToSearchInCustomDirectorySearcher = 10
|
||||
const searchResult = {
|
||||
filePath: foreignFilePath,
|
||||
matches: [
|
||||
{
|
||||
lineText: 'Hello world',
|
||||
lineTextOffset: 0,
|
||||
matchText: 'Hello',
|
||||
range: [[0, 0], [0, 5]]
|
||||
}
|
||||
]
|
||||
}
|
||||
onFakeSearchCreated = fakeSearch => {
|
||||
fakeSearch.options.didMatch(searchResult)
|
||||
fakeSearch.options.didSearchPaths(
|
||||
numPathsToPretendToSearchInCustomDirectorySearcher
|
||||
)
|
||||
fakeSearch.hoistedResolve()
|
||||
}
|
||||
|
||||
it("searches matching files in all of the project's root directories", () => {
|
||||
const resultPaths = []
|
||||
const onPathsSearched = jasmine.createSpy('onPathsSearched')
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/aaaa/, { onPathsSearched }, ({ filePath }) =>
|
||||
atom.workspace.scan(/aaaa/, ({ filePath }) =>
|
||||
resultPaths.push(filePath)
|
||||
)
|
||||
)
|
||||
|
||||
runs(() => {
|
||||
expect(resultPaths.sort()).toEqual(
|
||||
[foreignFilePath, file2].sort()
|
||||
)
|
||||
// onPathsSearched should be called once by each DirectorySearcher. The order is not
|
||||
// guaranteed, so we can only verify the total number of paths searched is correct
|
||||
// after the second call.
|
||||
expect(onPathsSearched.callCount).toBe(2)
|
||||
expect(onPathsSearched.mostRecentCall.args[0]).toBe(
|
||||
numPathsToPretendToSearchInCustomDirectorySearcher +
|
||||
numPathsSearchedInDir2
|
||||
)
|
||||
})
|
||||
runs(() => expect(resultPaths.sort()).toEqual([file1, file2].sort()))
|
||||
})
|
||||
|
||||
it('can be cancelled when the object returned by scan() has its cancel() method invoked', () => {
|
||||
const thenable = atom.workspace.scan(/aaaa/, () => {})
|
||||
let resultOfPromiseSearch = null
|
||||
|
||||
waitsFor('fakeSearch to be defined', () => fakeSearch != null)
|
||||
|
||||
runs(() => {
|
||||
expect(fakeSearch.cancelled).toBe(undefined)
|
||||
thenable.cancel()
|
||||
expect(fakeSearch.cancelled).toBe(true)
|
||||
})
|
||||
|
||||
waitsForPromise(() =>
|
||||
thenable.then(promiseResult => {
|
||||
resultOfPromiseSearch = promiseResult
|
||||
describe('when an inclusion path starts with the basename of a root directory', () => {
|
||||
it('interprets the inclusion path as starting from that directory', () => {
|
||||
waitsForPromise(() => {
|
||||
const resultPaths = []
|
||||
return atom.workspace
|
||||
.scan(/aaaa/, { paths: ['dir'] }, ({ filePath }) => {
|
||||
if (!resultPaths.includes(filePath)) {
|
||||
resultPaths.push(filePath)
|
||||
}
|
||||
})
|
||||
.then(() => expect(resultPaths).toEqual([file1]))
|
||||
})
|
||||
)
|
||||
|
||||
runs(() => expect(resultOfPromiseSearch).toBe('cancelled'))
|
||||
waitsForPromise(() => {
|
||||
const resultPaths = []
|
||||
return atom.workspace
|
||||
.scan(
|
||||
/aaaa/,
|
||||
{ paths: [path.join('dir', 'a-dir')] },
|
||||
({ filePath }) => {
|
||||
if (!resultPaths.includes(filePath)) {
|
||||
resultPaths.push(filePath)
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(() => expect(resultPaths).toEqual([file1]))
|
||||
})
|
||||
|
||||
waitsForPromise(() => {
|
||||
const resultPaths = []
|
||||
return atom.workspace
|
||||
.scan(
|
||||
/aaaa/,
|
||||
{ paths: [path.basename(dir2)] },
|
||||
({ filePath }) => {
|
||||
if (!resultPaths.includes(filePath)) {
|
||||
resultPaths.push(filePath)
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(() => expect(resultPaths).toEqual([file2]))
|
||||
})
|
||||
|
||||
waitsForPromise(() => {
|
||||
const resultPaths = []
|
||||
return atom.workspace
|
||||
.scan(
|
||||
/aaaa/,
|
||||
{ paths: [path.join(path.basename(dir2), 'a-dir')] },
|
||||
({ filePath }) => {
|
||||
if (!resultPaths.includes(filePath)) {
|
||||
resultPaths.push(filePath)
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(() => expect(resultPaths).toEqual([file2]))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('will have the side-effect of failing the overall search if it fails', () => {
|
||||
// This provider's search should be cancelled when the first provider fails
|
||||
let cancelableSearch
|
||||
let fakeSearch2 = null
|
||||
atom.packages.serviceHub.provide(
|
||||
'atom.directory-searcher',
|
||||
'0.1.0',
|
||||
{
|
||||
canSearchDirectory (directory) {
|
||||
return directory.getPath() === dir2
|
||||
},
|
||||
search (directory, regex, options) {
|
||||
fakeSearch2 = new FakeSearch(options)
|
||||
return fakeSearch2
|
||||
}
|
||||
describe('when a custom directory searcher is registered', () => {
|
||||
let fakeSearch = null
|
||||
// Function that is invoked once all of the fields on fakeSearch are set.
|
||||
let onFakeSearchCreated = null
|
||||
|
||||
class FakeSearch {
|
||||
constructor (options) {
|
||||
// Note that hoisting resolve and reject in this way is generally frowned upon.
|
||||
this.options = options
|
||||
this.promise = new Promise((resolve, reject) => {
|
||||
this.hoistedResolve = resolve
|
||||
this.hoistedReject = reject
|
||||
if (typeof onFakeSearchCreated === 'function') {
|
||||
onFakeSearchCreated(this)
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
then (...args) {
|
||||
return this.promise.then.apply(this.promise, args)
|
||||
}
|
||||
cancel () {
|
||||
this.cancelled = true
|
||||
// According to the spec for a DirectorySearcher, invoking `cancel()` should
|
||||
// resolve the thenable rather than reject it.
|
||||
this.hoistedResolve()
|
||||
}
|
||||
}
|
||||
|
||||
let didReject = false
|
||||
const promise = (cancelableSearch = atom.workspace.scan(
|
||||
/aaaa/,
|
||||
() => {}
|
||||
))
|
||||
waitsFor('fakeSearch to be defined', () => fakeSearch != null)
|
||||
beforeEach(() => {
|
||||
fakeSearch = null
|
||||
onFakeSearchCreated = null
|
||||
atom.packages.serviceHub.provide(
|
||||
'atom.directory-searcher',
|
||||
'0.1.0',
|
||||
{
|
||||
canSearchDirectory (directory) {
|
||||
return directory.getPath() === dir1
|
||||
},
|
||||
search (directory, regex, options) {
|
||||
fakeSearch = new FakeSearch(options)
|
||||
return fakeSearch
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
runs(() => fakeSearch.hoistedReject())
|
||||
waitsFor(() => atom.workspace.directorySearchers.length > 0)
|
||||
})
|
||||
|
||||
waitsForPromise(() =>
|
||||
cancelableSearch.catch(() => {
|
||||
didReject = true
|
||||
it('can override the DefaultDirectorySearcher on a per-directory basis', () => {
|
||||
const foreignFilePath = 'ssh://foreign-directory:8080/hello.txt'
|
||||
const numPathsSearchedInDir2 = 1
|
||||
const numPathsToPretendToSearchInCustomDirectorySearcher = 10
|
||||
const searchResult = {
|
||||
filePath: foreignFilePath,
|
||||
matches: [
|
||||
{
|
||||
lineText: 'Hello world',
|
||||
lineTextOffset: 0,
|
||||
matchText: 'Hello',
|
||||
range: [[0, 0], [0, 5]]
|
||||
}
|
||||
]
|
||||
}
|
||||
onFakeSearchCreated = fakeSearch => {
|
||||
fakeSearch.options.didMatch(searchResult)
|
||||
fakeSearch.options.didSearchPaths(
|
||||
numPathsToPretendToSearchInCustomDirectorySearcher
|
||||
)
|
||||
fakeSearch.hoistedResolve()
|
||||
}
|
||||
|
||||
const resultPaths = []
|
||||
const onPathsSearched = jasmine.createSpy('onPathsSearched')
|
||||
waitsForPromise(() =>
|
||||
atom.workspace.scan(/aaaa/, { onPathsSearched }, ({ filePath }) =>
|
||||
resultPaths.push(filePath)
|
||||
)
|
||||
)
|
||||
|
||||
runs(() => {
|
||||
expect(resultPaths.sort()).toEqual(
|
||||
[foreignFilePath, file2].sort()
|
||||
)
|
||||
// onPathsSearched should be called once by each DirectorySearcher. The order is not
|
||||
// guaranteed, so we can only verify the total number of paths searched is correct
|
||||
// after the second call.
|
||||
expect(onPathsSearched.callCount).toBe(2)
|
||||
expect(onPathsSearched.mostRecentCall.args[0]).toBe(
|
||||
numPathsToPretendToSearchInCustomDirectorySearcher +
|
||||
numPathsSearchedInDir2
|
||||
)
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
waitsFor(done => promise.then(null, done))
|
||||
it('can be cancelled when the object returned by scan() has its cancel() method invoked', () => {
|
||||
const thenable = atom.workspace.scan(/aaaa/, () => {})
|
||||
let resultOfPromiseSearch = null
|
||||
|
||||
runs(() => {
|
||||
expect(didReject).toBe(true)
|
||||
expect(fakeSearch2.cancelled).toBe(true)
|
||||
waitsFor('fakeSearch to be defined', () => fakeSearch != null)
|
||||
|
||||
runs(() => {
|
||||
expect(fakeSearch.cancelled).toBe(undefined)
|
||||
thenable.cancel()
|
||||
expect(fakeSearch.cancelled).toBe(true)
|
||||
})
|
||||
|
||||
waitsForPromise(() =>
|
||||
thenable.then(promiseResult => {
|
||||
resultOfPromiseSearch = promiseResult
|
||||
})
|
||||
)
|
||||
|
||||
runs(() => expect(resultOfPromiseSearch).toBe('cancelled'))
|
||||
})
|
||||
|
||||
it('will have the side-effect of failing the overall search if it fails', () => {
|
||||
// This provider's search should be cancelled when the first provider fails
|
||||
let cancelableSearch
|
||||
let fakeSearch2 = null
|
||||
atom.packages.serviceHub.provide(
|
||||
'atom.directory-searcher',
|
||||
'0.1.0',
|
||||
{
|
||||
canSearchDirectory (directory) {
|
||||
return directory.getPath() === dir2
|
||||
},
|
||||
search (directory, regex, options) {
|
||||
fakeSearch2 = new FakeSearch(options)
|
||||
return fakeSearch2
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
let didReject = false
|
||||
const promise = (cancelableSearch = atom.workspace.scan(
|
||||
/aaaa/,
|
||||
() => {}
|
||||
))
|
||||
waitsFor('fakeSearch to be defined', () => fakeSearch != null)
|
||||
|
||||
runs(() => fakeSearch.hoistedReject())
|
||||
|
||||
waitsForPromise(() =>
|
||||
cancelableSearch.catch(() => {
|
||||
didReject = true
|
||||
})
|
||||
)
|
||||
|
||||
waitsFor(done => promise.then(null, done))
|
||||
|
||||
runs(() => {
|
||||
expect(didReject).toBe(true)
|
||||
expect(fakeSearch2.cancelled).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}) // Cancels other ongoing searches
|
||||
}) // Cancels other ongoing searches
|
||||
}
|
||||
|
||||
describe('::replace(regex, replacementText, paths, iterator)', () => {
|
||||
let fixturesDir, projectDir
|
||||
|
@ -71,7 +71,7 @@ module.exports = class DefaultDirectorySearcher {
|
||||
// * `filePath` {String} absolute path to the matching file.
|
||||
// * `matches` {Array} with object elements with the following keys:
|
||||
// * `lineText` {String} The full text of the matching line (without a line terminator character).
|
||||
// * `lineTextOffset` {Number} (This always seems to be 0?)
|
||||
// * `lineTextOffset` {Number} If > 0, the provided line text is truncated and starts at this offset
|
||||
// * `matchText` {String} The text that matched the `regex` used for the search.
|
||||
// * `range` {Range} Identifies the matching region in the file. (Likely as an array of numeric arrays.)
|
||||
// * `didError` {Function} call with an Error if there is a problem during the search.
|
||||
|
106
src/ripgrep-directory-searcher.js
Normal file
106
src/ripgrep-directory-searcher.js
Normal file
@ -0,0 +1,106 @@
|
||||
const { spawn } = require("child_process")
|
||||
|
||||
module.exports = class RipgrepDirectorySearcher {
|
||||
constructor() {
|
||||
this.rgPath = require('vscode-ripgrep').rgPath
|
||||
}
|
||||
|
||||
canSearchDirectory () {
|
||||
return true
|
||||
}
|
||||
|
||||
// Performs a text search for files in the specified `Directory`s, subject to the
|
||||
// specified parameters.
|
||||
//
|
||||
// Results are streamed back to the caller by invoking methods on the specified `options`,
|
||||
// such as `didMatch` and `didError`.
|
||||
//
|
||||
// * `directories` {Array} of {Directory} objects to search, all of which have been accepted by
|
||||
// this searcher's `canSearchDirectory()` predicate.
|
||||
// * `regex` {RegExp} to search with.
|
||||
// * `options` {Object} with the following properties:
|
||||
// * `didMatch` {Function} call with a search result structured as follows:
|
||||
// * `searchResult` {Object} with the following keys:
|
||||
// * `filePath` {String} absolute path to the matching file.
|
||||
// * `matches` {Array} with object elements with the following keys:
|
||||
// * `lineText` {String} The full text of the matching line (without a line terminator character).
|
||||
// * `lineTextOffset` {Number} Always 0, present for backwards compatibility
|
||||
// * `matchText` {String} The text that matched the `regex` used for the search.
|
||||
// * `range` {Range} Identifies the matching region in the file. (Likely as an array of numeric arrays.)
|
||||
// * `didError` {Function} call with an Error if there is a problem during the search.
|
||||
// * `didSearchPaths` {Function} periodically call with the number of paths searched thus far.
|
||||
// * `inclusions` {Array} of glob patterns (as strings) to search within. Note that this
|
||||
// array may be empty, indicating that all files should be searched.
|
||||
//
|
||||
// Each item in the array is a file/directory pattern, e.g., `src` to search in the "src"
|
||||
// directory or `*.js` to search all JavaScript files. In practice, this often comes from the
|
||||
// comma-delimited list of patterns in the bottom text input of the ProjectFindView dialog.
|
||||
// * `ignoreHidden` {boolean} whether to ignore hidden files.
|
||||
// * `excludeVcsIgnores` {boolean} whether to exclude VCS ignored paths.
|
||||
// * `exclusions` {Array} similar to inclusions
|
||||
// * `follow` {boolean} whether symlinks should be followed.
|
||||
//
|
||||
// Returns a *thenable* `DirectorySearch` that includes a `cancel()` method. If `cancel()` is
|
||||
// invoked before the `DirectorySearch` is determined, it will resolve the `DirectorySearch`.
|
||||
search (directories, regexp, options) {
|
||||
const paths = directories.map(d => d.getPath())
|
||||
|
||||
const args = ["--json", "--regexp", regexp.source]
|
||||
if (options.leadingContextLineCount) {
|
||||
args.push("--before-context", options.leadingContextLineCount)
|
||||
}
|
||||
if (options.trailingContextLineCount) {
|
||||
args.push("--after-context", options.trailingContextLineCount)
|
||||
}
|
||||
args.push(...paths)
|
||||
|
||||
console.log(args)
|
||||
|
||||
const child = spawn(this.rgPath, args, {
|
||||
stdio: ['pipe', 'pipe', 'inherit']
|
||||
})
|
||||
|
||||
const didMatch = options.didMatch || (() => {})
|
||||
|
||||
return new Promise(resolve => {
|
||||
let buffer = ''
|
||||
let pendingEvent
|
||||
child.stdout.on('data', chunk => {
|
||||
buffer += chunk;
|
||||
const lines = buffer.split('\n')
|
||||
buffer = lines.pop()
|
||||
for (const line of lines) {
|
||||
const message = JSON.parse(line)
|
||||
console.log(message);
|
||||
|
||||
if (message.type === 'begin') {
|
||||
pendingEvent = {
|
||||
filePath: message.data.path.text,
|
||||
matches: []
|
||||
}
|
||||
} else if (message.type === 'match') {
|
||||
const startRow = message.data.line_number - 1
|
||||
for (const submatch of message.data.submatches) {
|
||||
pendingEvent.matches.push({
|
||||
matchText: submatch.match.text,
|
||||
lineText: message.data.lines.text,
|
||||
lineTextOffset: 0,
|
||||
range: [[startRow, submatch.start], [startRow, submatch.end]],
|
||||
leadingContextLines: [],
|
||||
trailingContextLines: []
|
||||
})
|
||||
}
|
||||
} else if (message.type === 'end') {
|
||||
console.log('yielding', pendingEvent)
|
||||
didMatch(pendingEvent)
|
||||
pendingEvent = null
|
||||
} else if (message.type === 'summary') {
|
||||
resolve()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ const fs = require('fs-plus')
|
||||
const {Directory} = require('pathwatcher')
|
||||
const Grim = require('grim')
|
||||
const DefaultDirectorySearcher = require('./default-directory-searcher')
|
||||
const RipgrepDirectorySearcher = require('./ripgrep-directory-searcher')
|
||||
const Dock = require('./dock')
|
||||
const Model = require('./model')
|
||||
const StateStore = require('./state-store')
|
||||
@ -203,7 +204,8 @@ module.exports = class Workspace extends Model {
|
||||
this.destroyedItemURIs = []
|
||||
this.stoppedChangingActivePaneItemTimeout = null
|
||||
|
||||
this.defaultDirectorySearcher = new DefaultDirectorySearcher()
|
||||
this.scandalDirectorySearcher = new DefaultDirectorySearcher()
|
||||
this.ripgrepDirectorySearcher = new RipgrepDirectorySearcher()
|
||||
this.consumeServices(this.packageManager)
|
||||
|
||||
this.paneContainers = {
|
||||
@ -1853,7 +1855,7 @@ module.exports = class Workspace extends Model {
|
||||
// will be associated with an Array of Directory objects in the Map.
|
||||
const directoriesForSearcher = new Map()
|
||||
for (const directory of this.project.getDirectories()) {
|
||||
let searcher = this.defaultDirectorySearcher
|
||||
let searcher = options.ripgrep ? this.ripgrepDirectorySearcher : this.scandalDirectorySearcher
|
||||
for (const directorySearcher of this.directorySearchers) {
|
||||
if (directorySearcher.canSearchDirectory(directory)) {
|
||||
searcher = directorySearcher
|
||||
@ -1901,7 +1903,9 @@ module.exports = class Workspace extends Model {
|
||||
leadingContextLineCount: options.leadingContextLineCount || 0,
|
||||
trailingContextLineCount: options.trailingContextLineCount || 0,
|
||||
didMatch: result => {
|
||||
console.log("didMatch", result)
|
||||
if (!this.project.isPathModified(result.filePath)) {
|
||||
console.log("!!!!!!!!!!!!!!!!!!!!")
|
||||
return iterator(result)
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user