mirror of
https://github.com/atom/atom.git
synced 2026-01-22 13:28:01 -05:00
Two things:
1. Update documentation for `default-directory-search.coffee`. 2. Ensure that multiple `DirectorySearch` searches are run in series rather than in parallel to conserve resources.
This commit is contained in:
@@ -1,32 +1,73 @@
|
||||
{EventEmitter} = require 'events'
|
||||
Task = require './task'
|
||||
|
||||
# Public:
|
||||
# Maintain a queue of ids of searches to run. When a search is complete, the active
|
||||
# search is cleared and the next search (if any) in the queue is notified to run.
|
||||
# This ensures there is at most one scan-handler task running at a time.
|
||||
searchQueue = []
|
||||
nextId = 1
|
||||
activeSearchId = 0
|
||||
emitter = new EventEmitter
|
||||
|
||||
onSearchFinished = () ->
|
||||
activeSearchId = null
|
||||
runNextSearch()
|
||||
|
||||
runNextSearch = () ->
|
||||
unless activeSearchId
|
||||
activeSearchId = searchQueue.shift()
|
||||
emitter.emit(activeSearchId, null) if activeSearchId
|
||||
|
||||
enqueue = (id) ->
|
||||
searchQueue.push(id)
|
||||
runNextSearch()
|
||||
|
||||
|
||||
# Public: Searches local files for lines matching a specified regex.
|
||||
#
|
||||
# Implements thenable so it can be used with `Promise.all()`.
|
||||
class DirectorySearch
|
||||
# Public:
|
||||
constructor: (directory, options) ->
|
||||
# Public: Creates a new DirectorySearch that will not start running until the
|
||||
# `emitter` that is private to this file emits an event with the specified `id`.
|
||||
constructor: (directory, options, id) ->
|
||||
@task = new Task(require.resolve('./scan-handler'))
|
||||
rootPaths = [directory.getPath()]
|
||||
@promise = new Promise (resolve, reject) =>
|
||||
@task.start(rootPaths, options.regexSource, options, resolve)
|
||||
@task.on('task:cancelled', reject)
|
||||
emitter.once id, =>
|
||||
@task.start(rootPaths, options.regexSource, options, resolve)
|
||||
|
||||
# Public:
|
||||
# Public: Implementation of `then()` to satisfy the *thenable* contract.
|
||||
# This makes it possible to use a `DirectorySearch` with `Promise.all()`.
|
||||
#
|
||||
# Returns `Promise`.
|
||||
then: (args...) ->
|
||||
@promise.then.apply(@promise, args)
|
||||
|
||||
# Public:
|
||||
# Public: Get notified when a search result is found.
|
||||
#
|
||||
# * `callback` {Function} called 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} (This always seems to be 0?)
|
||||
# * `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.)
|
||||
#
|
||||
# Returns `Disposable`.
|
||||
onDidMatch: (callback) ->
|
||||
@task.on 'scan:result-found', callback
|
||||
|
||||
# Public:
|
||||
# Public: Get notified about any search errors.
|
||||
#
|
||||
# * `callback` {Function} called with an Error if there is a problem during the search.
|
||||
#
|
||||
# Returns `Disposable`.
|
||||
onDidError: (callback) ->
|
||||
@task.on 'scan:file-error', callback
|
||||
|
||||
# Public:
|
||||
# Public: Get notified with the number of paths searched thus far.
|
||||
#
|
||||
# * `callback` {Function} called with the number of paths searched thus far.
|
||||
#
|
||||
@@ -34,10 +75,11 @@ class DirectorySearch
|
||||
onDidSearchPaths: (callback) ->
|
||||
@task.on 'scan:paths-searched', callback
|
||||
|
||||
# Public:
|
||||
# Public: Cancels the search.
|
||||
cancel: ->
|
||||
# This will cause @promise to reject.
|
||||
@task.cancel()
|
||||
null
|
||||
|
||||
|
||||
# Default provider for the `atom.directory-searcher` service.
|
||||
@@ -53,37 +95,31 @@ class DefaultDirectorySearcher
|
||||
# Public: Performs a text search for files in the specified `Directory`, subject to the
|
||||
# specified parameters.
|
||||
#
|
||||
# Results are streamed back to the caller via `recordSearchResult()` and `recordSearchError()`.
|
||||
# Results are streamed back to the caller by adding callbacks to the `DirectorySearch` returned by
|
||||
# this method.
|
||||
#
|
||||
# * `directory` {Directory} that has been accepted by this provider's `canSearchDirectory()`
|
||||
# predicate.
|
||||
# (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:
|
||||
# * `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?)
|
||||
# * `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.)
|
||||
# * `onSearchError` {Function} Should be called to report a search error.
|
||||
# * `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}
|
||||
# * `ignoreCase` {boolean} reflects whether the regex should be run with the `i` option.
|
||||
# * `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}
|
||||
# * `excludeVcsIgnores` {boolean}
|
||||
# * `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
|
||||
# * `follow` {boolean} whether symlinks should be followed.
|
||||
#
|
||||
# Returns a `DirectorySearch` that includes a `cancel()` method. If invoked before the `Proimse` is
|
||||
# determined, it will reject the `Promise`.
|
||||
# Returns a *thenable* `DirectorySearch` that includes a `cancel()` method. If `cancel()` is
|
||||
# invoked before the `DirectorySearch` is determined, it will reject the `DirectorySearch`.
|
||||
search: (directory, options) ->
|
||||
new DirectorySearch(directory, options)
|
||||
id = nextId
|
||||
nextId += 1
|
||||
directorySearch = new DirectorySearch(directory, options, id)
|
||||
directorySearch.then(onSearchFinished, onSearchFinished)
|
||||
enqueue(id)
|
||||
directorySearch
|
||||
|
||||
Reference in New Issue
Block a user