diff --git a/src/packages/fuzzy-finder/lib/fuzzy-finder-view.coffee b/src/packages/fuzzy-finder/lib/fuzzy-finder-view.coffee index bc48601b6..704b7f5d8 100644 --- a/src/packages/fuzzy-finder/lib/fuzzy-finder-view.coffee +++ b/src/packages/fuzzy-finder/lib/fuzzy-finder-view.coffee @@ -22,9 +22,11 @@ class FuzzyFinderView extends SelectList reloadProjectPaths: true filterKey: 'projectRelativePath' - initialize: -> + initialize: (@projectPaths)-> super + @reloadProjectPaths = false if @projectPaths?.length > 0 + @subscribe $(window), 'focus', => @reloadProjectPaths = true @observeConfig 'fuzzy-finder.ignoredNames', => @reloadProjectPaths = true rootView.eachPane (pane) -> @@ -214,15 +216,13 @@ class FuzzyFinderView extends SelectList @loadingBadge.text("") if @reloadProjectPaths - @loadPathsTask?.abort() - callback = (paths) => + @loadPathsTask?.terminate() + @loadPathsTask = LoadPathsTask.once (paths) => @projectPaths = paths @reloadProjectPaths = false @populateProjectPaths(options) - @loadPathsTask = new LoadPathsTask(callback) - @loadPathsTask.on 'paths-loaded', (paths) => + @loadPathsTask.on 'load-paths:paths-loaded', (paths) => @loadingBadge.text(humanize.intcomma(paths.length)) - @loadPathsTask.start() populateOpenBufferPaths: -> editSessions = project.getEditSessions().filter (editSession) -> @@ -239,10 +239,8 @@ class FuzzyFinderView extends SelectList @setArray(_.uniq(@paths)) - detach: -> - super - - @loadPathsTask?.abort() + afterRemove: -> + @loadPathsTask?.terminate() attach: -> super diff --git a/src/packages/fuzzy-finder/lib/fuzzy-finder.coffee b/src/packages/fuzzy-finder/lib/fuzzy-finder.coffee index 600352579..e9f2428b6 100644 --- a/src/packages/fuzzy-finder/lib/fuzzy-finder.coffee +++ b/src/packages/fuzzy-finder/lib/fuzzy-finder.coffee @@ -16,15 +16,14 @@ module.exports = @createView().toggleGitFinder() if project.getPath()? - LoadPathsTask = require 'fuzzy-finder/lib/load-paths-task' - @loadPathsTask = new LoadPathsTask((paths) => @projectPaths = paths) - @loadPathsTask.start() + LoadPathsTask = require './load-paths-task' + @loadPathsTask = LoadPathsTask.once (paths) => @projectPaths = paths for editSession in project.getEditSessions() editSession.lastOpened = state[editSession.getPath()] deactivate: -> - @loadPathsTask?.abort() + @loadPathsTask?.terminate() @loadPathsTask = null @fuzzyFinderView?.cancel() @fuzzyFinderView = null @@ -40,10 +39,7 @@ module.exports = createView: -> unless @fuzzyFinderView - @loadPathsTask?.abort() + @loadPathsTask?.terminate() FuzzyFinderView = require './fuzzy-finder-view' - @fuzzyFinderView = new FuzzyFinderView() - if @projectPaths?.length > 0 and not @fuzzyFinderView.projectPaths? - @fuzzyFinderView.projectPaths = @projectPaths - @fuzzyFinderView.reloadProjectPaths = false + @fuzzyFinderView = new FuzzyFinderView(@projectPaths) @fuzzyFinderView diff --git a/src/packages/fuzzy-finder/lib/load-paths-handler.coffee b/src/packages/fuzzy-finder/lib/load-paths-handler.coffee index 01c28f3e6..f01172931 100644 --- a/src/packages/fuzzy-finder/lib/load-paths-handler.coffee +++ b/src/packages/fuzzy-finder/lib/load-paths-handler.coffee @@ -6,12 +6,14 @@ Git = require 'git' class PathLoader asyncCallsInProgress: 0 pathsChunkSize: 100 - paths: [] + paths: null repo: null rootPath: null ignoredNames: null + callback: null - constructor: (@rootPath, ignoreVcsIgnores=false, @ignoredNames=[]) -> + constructor: (@rootPath, ignoreVcsIgnores=false, @ignoredNames=[], @callback) -> + @paths = [] @repo = Git.open(@rootPath, refreshOnWindowFocus: false) if ignoreVcsIgnores @ignoredNames.sort() @@ -24,13 +26,13 @@ class PathLoader asyncCallDone: -> if --@asyncCallsInProgress is 0 @repo?.destroy() - callTaskMethod('pathsLoaded', @paths) - callTaskMethod('pathLoadingComplete') + emit('load-paths:paths-found', @paths) + @callback() pathLoaded: (path) -> @paths.push(path) unless @isIgnored(path) if @paths.length is @pathsChunkSize - callTaskMethod('pathsLoaded', @paths) + emit('load-paths:paths-found', @paths) @paths = [] loadPath: (path) -> @@ -58,7 +60,7 @@ class PathLoader load: -> @loadFolder(@rootPath) -module.exports = - loadPaths: (rootPath, ignoreVcsIgnores, ignoredNames) -> - pathLoader = new PathLoader(rootPath, ignoreVcsIgnores, ignoredNames) - pathLoader.load() +module.exports = (rootPath, ignoreVcsIgnores, ignoredNames) -> + callback = @async() + pathLoader = new PathLoader(rootPath, ignoreVcsIgnores, ignoredNames, callback) + pathLoader.load() diff --git a/src/packages/fuzzy-finder/lib/load-paths-task.coffee b/src/packages/fuzzy-finder/lib/load-paths-task.coffee index 5f2bd3d8c..ab464184d 100644 --- a/src/packages/fuzzy-finder/lib/load-paths-task.coffee +++ b/src/packages/fuzzy-finder/lib/load-paths-task.coffee @@ -1,21 +1,18 @@ Task = require 'task' module.exports = -class LoadPathsTask extends Task - constructor: (@callback) -> - super(require.resolve('./load-paths-handler')) - - started: -> - @paths = [] +class LoadPathsTask + @once: (callback) -> + projectPaths = [] + taskPath = require.resolve('./load-paths-handler') ignoredNames = config.get('fuzzyFinder.ignoredNames') ? [] ignoredNames = ignoredNames.concat(config.get('core.ignoredNames') ? []) ignoreVcsIgnores = config.get('core.excludeVcsIgnoredPaths') - @callWorkerMethod('loadPaths', project.getPath(), ignoreVcsIgnores, ignoredNames) - pathsLoaded: (paths) -> - @paths.push(paths...) - @trigger 'paths-loaded', @paths + task = Task.once taskPath, project.getPath(), ignoreVcsIgnores, ignoredNames, -> + callback(projectPaths) - pathLoadingComplete: -> - @callback(@paths) - @done() + task.on 'load-paths:paths-found', (paths) => + projectPaths.push(paths...) + + task diff --git a/src/packages/fuzzy-finder/spec/fuzzy-finder-spec.coffee b/src/packages/fuzzy-finder/spec/fuzzy-finder-spec.coffee index 421e547bd..085c785d8 100644 --- a/src/packages/fuzzy-finder/spec/fuzzy-finder-spec.coffee +++ b/src/packages/fuzzy-finder/spec/fuzzy-finder-spec.coffee @@ -55,6 +55,7 @@ describe 'FuzzyFinder', -> true runs -> + expect(paths.length).toBeGreaterThan 0 expect(finderView.list.children('li').length).toBe paths.length for filePath in paths expect(finderView.list.find("li:contains(#{path.basename(filePath)})")).toExist() @@ -301,15 +302,15 @@ describe 'FuzzyFinder', -> describe "cached file paths", -> it "caches file paths after first time", -> - spyOn(LoadPathsTask.prototype, "start").andCallThrough() + spyOn(LoadPathsTask, "once").andCallThrough() rootView.trigger 'fuzzy-finder:toggle-file-finder' waitsFor -> finderView.list.children('li').length > 0 runs -> - expect(finderView.loadPathsTask.start).toHaveBeenCalled() - finderView.loadPathsTask.start.reset() + expect(LoadPathsTask.once).toHaveBeenCalled() + LoadPathsTask.once.reset() rootView.trigger 'fuzzy-finder:toggle-file-finder' rootView.trigger 'fuzzy-finder:toggle-file-finder' @@ -317,7 +318,7 @@ describe 'FuzzyFinder', -> finderView.list.children('li').length > 0 runs -> - expect(finderView.loadPathsTask.start).not.toHaveBeenCalled() + expect(LoadPathsTask.once).not.toHaveBeenCalled() it "doesn't cache buffer paths", -> spyOn(project, "getEditSessions").andCallThrough() @@ -339,19 +340,19 @@ describe 'FuzzyFinder', -> expect(project.getEditSessions).toHaveBeenCalled() it "busts the cache when the window gains focus", -> - spyOn(LoadPathsTask.prototype, "start").andCallThrough() + spyOn(LoadPathsTask, "once").andCallThrough() rootView.trigger 'fuzzy-finder:toggle-file-finder' waitsFor -> finderView.list.children('li').length > 0 runs -> - expect(finderView.loadPathsTask.start).toHaveBeenCalled() - finderView.loadPathsTask.start.reset() + expect(LoadPathsTask.once).toHaveBeenCalled() + LoadPathsTask.once.reset() $(window).trigger 'focus' rootView.trigger 'fuzzy-finder:toggle-file-finder' rootView.trigger 'fuzzy-finder:toggle-file-finder' - expect(finderView.loadPathsTask.start).toHaveBeenCalled() + expect(LoadPathsTask.once).toHaveBeenCalled() describe "path ignoring", -> it "ignores paths that match entries in config.fuzzyFinder.ignoredNames", -> diff --git a/src/stdlib/task.coffee b/src/stdlib/task.coffee index d09d38191..9a180168b 100644 --- a/src/stdlib/task.coffee +++ b/src/stdlib/task.coffee @@ -4,6 +4,12 @@ EventEmitter = require 'event-emitter' module.exports = class Task + @once: (taskPath, args...) -> + task = new Task(taskPath) + task.one 'task:completed', -> task.terminate() + task.start(args...) + task + callback: null constructor: (taskPath) -> @@ -12,7 +18,9 @@ class Task require('coffee-cache').setCacheDir('/tmp/atom-coffee-cache'); require('task-bootstrap'); """ + taskPath = require.resolve(taskPath) + env = _.extend({}, process.env, {taskPath, userAgent: navigator.userAgent}) args = [bootstrap, '--harmony_collections'] @childProcess = child_process.fork '--eval', args, {env, cwd: __dirname} @@ -20,7 +28,7 @@ class Task @on "task:log", -> console.log(arguments...) @on "task:warn", -> console.warn(arguments...) @on "task:error", -> console.error(arguments...) - @on "task:completed", (args...) => @callback(args...) + @on "task:completed", (args...) => @callback?(args...) @handleEvents() @@ -33,7 +41,7 @@ class Task throw new Error("Cannot start terminated process") unless @childProcess? @handleEvents() - @callback = args.pop() + @callback = args.pop() if _.isFunction(args[args.length - 1]) @childProcess.send({args}) terminate: -> diff --git a/src/task-bootstrap.coffee b/src/task-bootstrap.coffee index d09203ad0..662ebb208 100644 --- a/src/task-bootstrap.coffee +++ b/src/task-bootstrap.coffee @@ -29,8 +29,13 @@ setupGlobals = -> handleEvents = -> process.on 'uncaughtException', (error) -> console.error(error.message) process.on 'message', ({args}) -> - result = handler(args...) - emit('task:completed', result) + isAsync = false + async = -> + isAsync = true + (result) -> + emit('task:completed', result) + result = handler.bind({async})(args...) + emit('task:completed', result) unless isAsync setupGlobals() handleEvents()