From 5cd3c047021e99d35febf2f51c879bdff76b056d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Sat, 2 Feb 2013 12:47:46 -0800 Subject: [PATCH] Load fuzzy finder paths in web worker at startup Previously the paths were first loaded when the fuzzy finder view was first attached. Now a web worker is started when the package activates that sets the paths on the fuzzy finder view the first time it displays if the worker has completed by the time an event occurs that displays the view. --- src/app/git.coffee | 12 +++--- src/packages/fuzzy-finder/index.coffee | 12 +++++- .../spec/fuzzy-finder-spec.coffee | 40 +++++++++---------- .../fuzzy-finder/src/fuzzy-finder-view.coffee | 14 +++---- .../src/load-paths-handler.coffee | 20 ++++++++++ .../fuzzy-finder/src/load-paths-task.coffee | 17 ++++++++ 6 files changed, 79 insertions(+), 36 deletions(-) create mode 100644 src/packages/fuzzy-finder/src/load-paths-handler.coffee create mode 100644 src/packages/fuzzy-finder/src/load-paths-task.coffee diff --git a/src/app/git.coffee b/src/app/git.coffee index f862fe6b8..db1376b17 100644 --- a/src/app/git.coffee +++ b/src/app/git.coffee @@ -1,4 +1,3 @@ -$ = require 'jquery' _ = require 'underscore' Subscriber = require 'subscriber' GitRepository = require 'git-repository' @@ -6,9 +5,9 @@ GitRepository = require 'git-repository' module.exports = class Git - @open: (path) -> + @open: (path, options) -> try - new Git(path) + new Git(path, options) catch e null @@ -24,9 +23,12 @@ class Git working_dir_typechange: 1 << 10 ignore: 1 << 14 - constructor: (path) -> + constructor: (path, options={}) -> @repo = new GitRepository(path) - @subscribe $(window), 'focus', => @refreshIndex() + refreshIndexOnFocus = options.refreshIndexOnFocus ? true + if refreshIndexOnFocus + $ = require 'jquery' + @subscribe $(window), 'focus', => @refreshIndex() getRepo: -> unless @repo? diff --git a/src/packages/fuzzy-finder/index.coffee b/src/packages/fuzzy-finder/index.coffee index 1d815057e..5e4338fc8 100644 --- a/src/packages/fuzzy-finder/index.coffee +++ b/src/packages/fuzzy-finder/index.coffee @@ -1,8 +1,8 @@ DeferredAtomPackage = require 'deferred-atom-package' +LoadPathsTask = require './src/load-paths-task' module.exports = class FuzzyFinder extends DeferredAtomPackage - loadEvents: [ 'fuzzy-finder:toggle-file-finder' 'fuzzy-finder:toggle-buffer-finder' @@ -11,7 +11,17 @@ class FuzzyFinder extends DeferredAtomPackage instanceClass: 'fuzzy-finder/src/fuzzy-finder-view' + activate: (rootView) -> + super + + callback = (paths) => @projectPaths = paths + new LoadPathsTask(rootView, callback).start() + onLoadEvent: (event, instance) -> + if @projectPaths? and not @instance.projectPaths? + @instance.projectPaths = @projectPaths + @instance.reloadProjectPaths = false; + switch event.type when 'fuzzy-finder:toggle-file-finder' instance.toggleFileFinder() diff --git a/src/packages/fuzzy-finder/spec/fuzzy-finder-spec.coffee b/src/packages/fuzzy-finder/spec/fuzzy-finder-spec.coffee index ad40e0010..76f8bd476 100644 --- a/src/packages/fuzzy-finder/spec/fuzzy-finder-spec.coffee +++ b/src/packages/fuzzy-finder/spec/fuzzy-finder-spec.coffee @@ -1,5 +1,6 @@ RootView = require 'root-view' FuzzyFinder = require 'fuzzy-finder/src/fuzzy-finder-view' +LoadPathsTask = require 'fuzzy-finder/src/load-paths-task' $ = require 'jquery' {$$} = require 'space-pen' fs = require 'fs' @@ -48,14 +49,13 @@ describe 'FuzzyFinder', -> expect(finder.find(".loading")).toBeVisible() expect(finder.find(".loading")).toHaveText "Indexing..." - waitsForPromise -> - rootView.project.getFilePaths().done (foundPaths) -> paths = foundPaths - - waitsFor -> - finder.list.children('li').length > 0 + waitsFor "all project paths to load", 5000, -> + if finder.projectPaths?.length > 0 + paths = finder.projectPaths + true runs -> - expect(finder.list.children('li').length).toBe paths.length, finder.maxResults + expect(finder.list.children('li').length).toBe paths.length for path in paths expect(finder.list.find("li:contains(#{fs.base(path)})")).toExist() expect(finder.list.children().first()).toHaveClass 'selected' @@ -222,15 +222,15 @@ describe 'FuzzyFinder', -> describe "cached file paths", -> it "caches file paths after first time", -> - spyOn(rootView.project, "getFilePaths").andCallThrough() + spyOn(LoadPathsTask.prototype, "start").andCallThrough() rootView.trigger 'fuzzy-finder:toggle-file-finder' waitsFor -> finder.list.children('li').length > 0 runs -> - expect(rootView.project.getFilePaths).toHaveBeenCalled() - rootView.project.getFilePaths.reset() + expect(finder.loadPathsTask.start).toHaveBeenCalled() + finder.loadPathsTask.start.reset() rootView.trigger 'fuzzy-finder:toggle-file-finder' rootView.trigger 'fuzzy-finder:toggle-file-finder' @@ -238,45 +238,44 @@ describe 'FuzzyFinder', -> finder.list.children('li').length > 0 runs -> - expect(rootView.project.getFilePaths).not.toHaveBeenCalled() + expect(finder.loadPathsTask.start).not.toHaveBeenCalled() it "doesn't cache buffer paths", -> - spyOn(rootView.project, "getFilePaths").andCallThrough() + spyOn(rootView, "getOpenBufferPaths").andCallThrough() rootView.trigger 'fuzzy-finder:toggle-buffer-finder' waitsFor -> finder.list.children('li').length > 0 runs -> - expect(rootView.project.getFilePaths).not.toHaveBeenCalled() - rootView.project.getFilePaths.reset() + expect(rootView.getOpenBufferPaths).toHaveBeenCalled() + rootView.getOpenBufferPaths.reset() + rootView.trigger 'fuzzy-finder:toggle-buffer-finder' rootView.trigger 'fuzzy-finder:toggle-buffer-finder' - rootView.trigger 'fuzzy-finder:toggle-file-finder' waitsFor -> finder.list.children('li').length > 0 runs -> - expect(rootView.project.getFilePaths).toHaveBeenCalled() + expect(rootView.getOpenBufferPaths).toHaveBeenCalled() it "busts the cache when the window gains focus", -> - spyOn(rootView.project, "getFilePaths").andCallThrough() + spyOn(LoadPathsTask.prototype, "start").andCallThrough() rootView.trigger 'fuzzy-finder:toggle-file-finder' waitsFor -> finder.list.children('li').length > 0 runs -> - expect(rootView.project.getFilePaths).toHaveBeenCalled() - rootView.project.getFilePaths.reset() + expect(finder.loadPathsTask.start).toHaveBeenCalled() + finder.loadPathsTask.start.reset() $(window).trigger 'focus' rootView.trigger 'fuzzy-finder:toggle-file-finder' rootView.trigger 'fuzzy-finder:toggle-file-finder' - expect(rootView.project.getFilePaths).toHaveBeenCalled() + expect(finder.loadPathsTask.start).toHaveBeenCalled() describe "path ignoring", -> it "ignores paths that match entries in config.fuzzyFinder.ignoredNames", -> - spyOn(rootView.project, "getFilePaths").andCallThrough() config.set("fuzzyFinder.ignoredNames", ["tree-view.js"]) rootView.trigger 'fuzzy-finder:toggle-file-finder' finder.maxItems = Infinity @@ -293,7 +292,6 @@ describe 'FuzzyFinder', -> beforeEach -> editor = rootView.getActiveEditor() rootView.attachToDom() - spyOn(rootView.project, "getFilePaths").andCallThrough() it "opens the fuzzy finder window when there are multiple matches", -> editor.setText("sample") diff --git a/src/packages/fuzzy-finder/src/fuzzy-finder-view.coffee b/src/packages/fuzzy-finder/src/fuzzy-finder-view.coffee index 2365fc4d7..ac5a3a3a5 100644 --- a/src/packages/fuzzy-finder/src/fuzzy-finder-view.coffee +++ b/src/packages/fuzzy-finder/src/fuzzy-finder-view.coffee @@ -3,6 +3,7 @@ SelectList = require 'select-list' _ = require 'underscore' $ = require 'jquery' fs = require 'fs' +LoadPathsTask = require 'fuzzy-finder/src/load-paths-task' module.exports = class FuzzyFinderView extends SelectList @@ -126,16 +127,9 @@ class FuzzyFinderView extends SelectList @setLoading("Indexing...") if @reloadProjectPaths - @rootView.project.getFilePaths().done (paths) => - ignoredNames = config.get("fuzzyFinder.ignoredNames") or [] - ignoredNames = ignoredNames.concat(config.get("core.ignoredNames") or []) + @loadPathsTask?.terminate() + callback = (paths) => @projectPaths = paths - if ignoredNames - @projectPaths = @projectPaths.filter (path) -> - for segment in path.split("/") - return false if _.contains(ignoredNames, segment) - return true - @reloadProjectPaths = false listedItems = if options.filter? @@ -146,6 +140,8 @@ class FuzzyFinderView extends SelectList @setArray(listedItems) options.done(listedItems) if options.done? + @loadPathsTask = new LoadPathsTask(@rootView, callback) + @loadPathsTask.start() populateOpenBufferPaths: -> @paths = @rootView.getOpenBufferPaths().map (path) => diff --git a/src/packages/fuzzy-finder/src/load-paths-handler.coffee b/src/packages/fuzzy-finder/src/load-paths-handler.coffee new file mode 100644 index 000000000..41ed34fa8 --- /dev/null +++ b/src/packages/fuzzy-finder/src/load-paths-handler.coffee @@ -0,0 +1,20 @@ +fs = require 'fs' +_ = require 'underscore' +Git = require 'git' + +module.exports = + loadPaths: (rootPath, ignoredNames, ignoreGitIgnoredFiles) -> + paths = [] + repo = Git.open(rootPath, refreshIndexOnFocus: false) if ignoreGitIgnoredFiles + isIgnored = (path) -> + for segment in path.split('/') + return true if _.contains(ignoredNames, segment) + return true if repo?.isPathIgnored(fs.join(rootPath, path)) + false + onFile = (path) -> + paths.push(path) unless isIgnored(path) + onDirectory = (path) -> + not isIgnored(path) + fs.traverseTree(rootPath, onFile, onDirectory) + repo?.destroy() + callTaskMethod('pathsLoaded', paths) diff --git a/src/packages/fuzzy-finder/src/load-paths-task.coffee b/src/packages/fuzzy-finder/src/load-paths-task.coffee new file mode 100644 index 000000000..7f7a31baa --- /dev/null +++ b/src/packages/fuzzy-finder/src/load-paths-task.coffee @@ -0,0 +1,17 @@ +Task = require 'task' + +module.exports = +class LoadPathsTask extends Task + constructor: (@rootView, @callback)-> + super('fuzzy-finder/src/load-paths-handler') + + started: -> + ignoredNames = config.get("fuzzyFinder.ignoredNames") ? [] + ignoredNames = ignoredNames.concat(config.get("core.ignoredNames") ? []) + ignoreGitIgnoredFiles = config.get("core.hideGitIgnoredFiles") + rootPath = @rootView.project.getPath() + @callWorkerMethod('loadPaths', rootPath, ignoredNames, ignoreGitIgnoredFiles) + + pathsLoaded: (paths) -> + @terminate() + @callback(paths)