mirror of
https://github.com/atom/atom.git
synced 2026-01-22 21:38:10 -05:00
Change DirectorySearcher to return a DirectorySearch.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
{Disposable} = require 'event-kit'
|
||||
Workspace = require '../src/workspace'
|
||||
Pane = require '../src/pane'
|
||||
{View} = require '../src/space-pen-extensions'
|
||||
@@ -943,9 +944,13 @@ describe "Workspace", ->
|
||||
foreignFilePath = 'ssh://foreign-directory:8080/hello.txt'
|
||||
numPathsSearchedInDir2 = 1
|
||||
numPathsToPretendToSearchInCustomDirectorySearcher = 10
|
||||
class CustomDirectorySearcher
|
||||
canSearchDirectory: (directory) -> directory.getPath() is dir1
|
||||
search: (directory, regexSource, onSearchResult, onSearchError, onPathsSearched, options) ->
|
||||
class CustomDirectorySearch
|
||||
constructor: () ->
|
||||
@promise = Promise.resolve()
|
||||
then: (args...) ->
|
||||
@promise.then.apply(@promise, args)
|
||||
onDidMatch: (callback) ->
|
||||
# Invoke the callback with the only result we plan to return.
|
||||
searchResult1 =
|
||||
filePath: foreignFilePath,
|
||||
matches: [
|
||||
@@ -956,11 +961,20 @@ describe "Workspace", ->
|
||||
range: [[0, 0], [0, 5]],
|
||||
}
|
||||
]
|
||||
onSearchResult(searchResult1)
|
||||
onPathsSearched(numPathsToPretendToSearchInCustomDirectorySearcher)
|
||||
promise = Promise.resolve()
|
||||
promise.cancel = ->
|
||||
promise
|
||||
callback(searchResult1)
|
||||
new Disposable
|
||||
onDidError: (callback) ->
|
||||
new Disposable
|
||||
onDidSearchPaths: (callback) ->
|
||||
# Invoke the callback with the one notification we plan to send.
|
||||
callback(numPathsToPretendToSearchInCustomDirectorySearcher)
|
||||
new Disposable
|
||||
cancel: ->
|
||||
|
||||
class CustomDirectorySearcher
|
||||
canSearchDirectory: (directory) -> directory.getPath() is dir1
|
||||
search: (directory, options) ->
|
||||
new CustomDirectorySearch
|
||||
|
||||
atom.packages.serviceHub.provide(
|
||||
"atom.directory-searcher", "0.1.0", new CustomDirectorySearcher())
|
||||
@@ -982,16 +996,27 @@ describe "Workspace", ->
|
||||
|
||||
it "can be cancelled by cancelling one of the DirectorySearchers", ->
|
||||
customDirectorySearcherPromiseInstance = null
|
||||
class CustomDirectorySearchToCancel
|
||||
constructor: () ->
|
||||
# Note that hoisting reject in this way is generally frowned upon.
|
||||
@promise = new Promise (resolve, reject) =>
|
||||
@hoistedReject = reject
|
||||
customDirectorySearcherPromiseInstance = this
|
||||
then: (args...) ->
|
||||
@promise.then.apply(@promise, args)
|
||||
onDidMatch: (callback) ->
|
||||
new Disposable
|
||||
onDidError: (callback) ->
|
||||
new Disposable
|
||||
onDidSearchPaths: (callback) ->
|
||||
new Disposable
|
||||
cancel: ->
|
||||
@hoistedReject()
|
||||
|
||||
class CustomDirectorySearcherToCancel
|
||||
canSearchDirectory: (directory) -> directory.getPath() is dir1
|
||||
search: (directory, regexSource, onSearchResult, onSearchError, onPathsSearched, options) ->
|
||||
# Note that hoisting reject in this way is generally frowned upon.
|
||||
hoistedReject = null
|
||||
promise = new Promise (resolve, reject) ->
|
||||
hoistedReject = reject
|
||||
promise.cancel = -> hoistedReject()
|
||||
customDirectorySearcherPromiseInstance = promise
|
||||
promise
|
||||
search: (directory, options) ->
|
||||
new CustomDirectorySearchToCancel
|
||||
|
||||
atom.packages.serviceHub.provide(
|
||||
"atom.directory-searcher", "0.1.0", new CustomDirectorySearcherToCancel())
|
||||
|
||||
@@ -1,5 +1,47 @@
|
||||
Task = require './task'
|
||||
|
||||
# Public:
|
||||
# Implements thenable so it can be used with `Promise.all()`.
|
||||
class DirectorySearch
|
||||
# Public:
|
||||
constructor: (directory, options) ->
|
||||
@task = new Task(require.resolve('./scan-handler'))
|
||||
rootPaths = [directory.getPath()]
|
||||
@promise = new Promise (resolve, reject) =>
|
||||
myResolve = (arg) ->
|
||||
resolve(arg)
|
||||
@task.start(rootPaths, options.regexSource, options, myResolve)
|
||||
@task.on('task:cancelled', reject)
|
||||
|
||||
# Public:
|
||||
# Returns `Promise`.
|
||||
then: (args...) ->
|
||||
@promise.then.apply(@promise, args)
|
||||
|
||||
# Public:
|
||||
# Returns `Disposable`.
|
||||
onDidMatch: (callback) ->
|
||||
@task.on 'scan:result-found', callback
|
||||
|
||||
# Public:
|
||||
# Returns `Disposable`.
|
||||
onDidError: (callback) ->
|
||||
@task.on 'scan:file-error', callback
|
||||
|
||||
# Public:
|
||||
#
|
||||
# * `callback` {Function} called with the number of paths searched thus far.
|
||||
#
|
||||
# Returns `Disposable`.
|
||||
onDidSearchPaths: (callback) ->
|
||||
@task.on 'scan:paths-searched', callback
|
||||
|
||||
# Public:
|
||||
cancel: ->
|
||||
# This will cause @promise to reject.
|
||||
@task.cancel()
|
||||
|
||||
|
||||
# Default provider for the `atom.directory-searcher` service.
|
||||
module.exports =
|
||||
class DefaultDirectorySearcher
|
||||
@@ -17,7 +59,6 @@ class DefaultDirectorySearcher
|
||||
#
|
||||
# * `directory` {Directory} that has been accepted by this provider's `canSearchDirectory()`
|
||||
# predicate.
|
||||
# * `regexSource` {String} regex to search with. Produced via `RegExp::source`.
|
||||
# (Note this reflects the "Use Regex" option exposed via the ProjectFindView UI.)
|
||||
# * `onSearchResult` {Function} Should be called with each matching search result.
|
||||
# * `searchResult` {Object} with the following keys:
|
||||
@@ -31,6 +72,7 @@ class DefaultDirectorySearcher
|
||||
# * `onPathsSearched` {Function} callback that should be invoked periodically with the number of
|
||||
# paths searched.
|
||||
# * `options` {Object} with the following properties:
|
||||
# * `regexSource` {String} regex to search with. Produced via `RegExp::source`.
|
||||
# * `ignoreCase` {boolean}
|
||||
# * `inclusions` {Array} of glob patterns (as strings) to search within. Note that this
|
||||
# array may be empty, indicating that all files should be searched.
|
||||
@@ -43,19 +85,7 @@ class DefaultDirectorySearcher
|
||||
# * `exclusions` {Array} similar to inclusions
|
||||
# * `follow` {boolean} whether symlinks should be followed
|
||||
#
|
||||
# Returns a `Promise` that includes a `cancel()` method. If invoked before the `Proimse` is
|
||||
# Returns a `DirectorySearch` that includes a `cancel()` method. If invoked before the `Proimse` is
|
||||
# determined, it will reject the `Promise`.
|
||||
search: (directory, regexSource, onSearchResult, onSearchError, onPathsSearched, options) ->
|
||||
task = null
|
||||
rootPaths = [directory.getPath()]
|
||||
promise = new Promise (resolve, reject) ->
|
||||
task = Task.once require.resolve('./scan-handler'), rootPaths, regexSource, options, resolve
|
||||
task.on 'task:cancelled', reject
|
||||
promise.cancel = ->
|
||||
task.cancel()
|
||||
|
||||
task.on 'scan:result-found', onSearchResult
|
||||
task.on 'scan:file-error', onSearchError
|
||||
task.on 'scan:paths-searched', onPathsSearched
|
||||
|
||||
promise
|
||||
search: (directory, options) ->
|
||||
new DirectorySearch(directory, options)
|
||||
|
||||
@@ -803,13 +803,14 @@ class Workspace extends Model
|
||||
# * `onPathsSearched` (optional) {Function}
|
||||
# * `iterator` {Function} callback on each file found
|
||||
#
|
||||
# Returns a `Promise` with a `cancel()` method.
|
||||
# Returns a `Promise`.
|
||||
scan: (regex, options={}, iterator) ->
|
||||
if _.isFunction(options)
|
||||
iterator = options
|
||||
options = {}
|
||||
|
||||
searchOptions =
|
||||
regexSource: regex.source
|
||||
ignoreCase: regex.ignoreCase
|
||||
inclusions: options.paths or []
|
||||
includeHidden: true
|
||||
@@ -855,18 +856,22 @@ class Workspace extends Model
|
||||
|
||||
# Kick off all of the searches and unify them into one Promise.
|
||||
allSearchPromises = []
|
||||
disposables = new CompositeDisposable
|
||||
for entry in searchersAndDirectories
|
||||
{searcher, directory} = entry
|
||||
directorySearcher = searcher.search(directory, searchOptions)
|
||||
disposables.add(directorySearcher.onDidMatch(onSearchResult))
|
||||
disposables.add(directorySearcher.onDidError(onSearchError))
|
||||
recordNumberOfPathsSearched = onPathsSearched.bind(undefined, directory)
|
||||
allSearchPromises.push(searcher.search(
|
||||
directory,
|
||||
regex.source,
|
||||
onSearchResult,
|
||||
onSearchError,
|
||||
recordNumberOfPathsSearched,
|
||||
searchOptions))
|
||||
disposables.add(directorySearcher.onDidSearchPaths(recordNumberOfPathsSearched))
|
||||
allSearchPromises.push(directorySearcher)
|
||||
searchPromise = Promise.all(allSearchPromises)
|
||||
|
||||
# Make sure to clean up the disposables once the searchPromise is determined.
|
||||
disposeAll = (args...) ->
|
||||
disposables.dispose()
|
||||
searchPromise.then(disposeAll, disposeAll)
|
||||
|
||||
for buffer in atom.project.getBuffers() when buffer.isModified()
|
||||
filePath = buffer.getPath()
|
||||
continue unless atom.project.contains(filePath)
|
||||
|
||||
Reference in New Issue
Block a user