From 0630bce95c6dadc6f212f4129528043ecef47edd Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Wed, 3 Jun 2015 23:29:56 -0400 Subject: [PATCH] Two things: * Removed the `Directory` argument to `didSearchPaths`. Now each searcher gets its own instance of `didSearchPaths` that is parameterized by provider. * Simplified `DefaultDirectorySearcher.search()` so it creates one `DirectorySearch` rather than one per `Directory` passed to `search()`. --- spec/workspace-spec.coffee | 7 ++++--- src/default-directory-searcher.coffee | 26 ++++++++++------------- src/workspace.coffee | 30 +++++++++++++-------------- 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 7e7ee406a..4666177c6 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -952,7 +952,9 @@ describe "Workspace", -> onFakeSearchCreated?(this) then: (args...) -> @promise.then.apply(@promise, args) - cancel: -> @cancelled = true + cancel: -> + @cancelled = true + @hoistedReject() beforeEach -> fakeSearch = null @@ -978,8 +980,7 @@ describe "Workspace", -> ] onFakeSearchCreated = (fakeSearch) -> fakeSearch.options.didMatch(searchResult) - directory1 = atom.project.getDirectories()[atom.project.getPaths().indexOf(dir1)] - fakeSearch.options.didSearchPaths(directory1, numPathsToPretendToSearchInCustomDirectorySearcher) + fakeSearch.options.didSearchPaths(numPathsToPretendToSearchInCustomDirectorySearcher) fakeSearch.hoistedResolve() resultPaths = [] diff --git a/src/default-directory-searcher.coffee b/src/default-directory-searcher.coffee index 4767a0313..a5f113eeb 100644 --- a/src/default-directory-searcher.coffee +++ b/src/default-directory-searcher.coffee @@ -4,7 +4,7 @@ Task = require './task' # # Implements thenable so it can be used with `Promise.all()`. class DirectorySearch - constructor: (directory, regex, options) -> + constructor: (rootPaths, regex, options) -> scanHandlerOptions = ignoreCase: regex.ignoreCase inclusions: options.inclusions @@ -15,10 +15,10 @@ class DirectorySearch @task = new Task(require.resolve('./scan-handler')) @task.on 'scan:result-found', options.didMatch @task.on 'scan:file-error', options.didError - @task.on 'scan:paths-searched', (count) -> options.didSearchPaths(directory, count) + @task.on 'scan:paths-searched', options.didSearchPaths @promise = new Promise (resolve, reject) => @task.on('task:cancelled', reject) - @task.start([directory.getPath()], regex.source, scanHandlerOptions, resolve) + @task.start(rootPaths, regex.source, scanHandlerOptions, resolve) # Public: Implementation of `then()` to satisfy the *thenable* contract. # This makes it possible to use a `DirectorySearch` with `Promise.all()`. @@ -64,7 +64,6 @@ class DefaultDirectorySearcher # * `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. - # This takes two arguments: the `Directory` and the count. # * `inclusions` {Array} of glob patterns (as strings) to search within. Note that this # array may be empty, indicating that all files should be searched. # @@ -79,21 +78,18 @@ class DefaultDirectorySearcher # Returns a *thenable* `DirectorySearch` that includes a `cancel()` method. If `cancel()` is # invoked before the `DirectorySearch` is determined, it will reject the `DirectorySearch`. search: (directories, regex, options) -> - # Make a mutable copy of the directories array. - directories = directories.slice(0) + rootPaths = directories.map (directory) -> directory.getPath() isCancelled = false + directorySearch = new DirectorySearch(rootPaths, regex, options) promise = new Promise (resolve, reject) -> - run = -> + directorySearch.then resolve, -> if isCancelled - reject() - else if directories.length - directory = directories.shift() - thenable = new DirectorySearch(directory, regex, options) - thenable.then(run, reject) - else resolve() - run() + else + reject() return { then: promise.then.bind(promise) - cancel: -> isCancelled = true + cancel: -> + isCancelled = true + directorySearch.cancel() } diff --git a/src/workspace.coffee b/src/workspace.coffee index 61c16a5c1..23cf25620 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -831,32 +831,30 @@ class Workspace extends Model onPathsSearchedOption = options.onPathsSearched totalNumberOfPathsSearched = 0 numberOfPathsSearchedForDirectory = new Map() - onPathsSearched = (directory, numberOfPathsSearched) -> - oldValue = numberOfPathsSearchedForDirectory.get(directory) + onPathsSearched = (searcher, numberOfPathsSearched) -> + oldValue = numberOfPathsSearchedForDirectory.get(searcher) if oldValue totalNumberOfPathsSearched -= oldValue - numberOfPathsSearchedForDirectory.set(directory, numberOfPathsSearched) + numberOfPathsSearchedForDirectory.set(searcher, numberOfPathsSearched) totalNumberOfPathsSearched += numberOfPathsSearched onPathsSearchedOption(totalNumberOfPathsSearched) else onPathsSearched = -> - # Build up the options object that will be shared by all searchers. - searchOptions = - inclusions: options.paths or [] - includeHidden: true - excludeVcsIgnores: atom.config.get('core.excludeVcsIgnoredPaths') - exclusions: atom.config.get('core.ignoredNames') - follow: atom.config.get('core.followSymlinks') - didMatch: (result) -> - iterator(result) unless atom.project.isPathModified(result.filePath) - didError: (error) -> - iterator(null, error) - didSearchPaths: onPathsSearched - # Kick off all of the searches and unify them into one Promise. allSearches = [] directoriesForSearcher.forEach (directories, searcher) -> + searchOptions = + inclusions: options.paths or [] + includeHidden: true + excludeVcsIgnores: atom.config.get('core.excludeVcsIgnoredPaths') + exclusions: atom.config.get('core.ignoredNames') + follow: atom.config.get('core.followSymlinks') + didMatch: (result) -> + iterator(result) unless atom.project.isPathModified(result.filePath) + didError: (error) -> + iterator(null, error) + didSearchPaths: (count) -> onPathsSearched(searcher, count) directorySearcher = searcher.search(directories, regex, searchOptions) allSearches.push(directorySearcher) searchPromise = Promise.all(allSearches)