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.
This commit is contained in:
Kevin Sawicki
2013-02-02 12:47:46 -08:00
parent a3b95a923d
commit 5cd3c04702
6 changed files with 79 additions and 36 deletions

View File

@@ -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?

View File

@@ -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()

View File

@@ -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")

View File

@@ -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) =>

View File

@@ -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)

View File

@@ -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)