Pull out fuzzy-finder package into a separate repo

This commit is contained in:
Kevin Sawicki
2013-08-13 11:49:25 -07:00
parent 257722f82e
commit 80a6999af4
9 changed files with 1 additions and 1003 deletions

View File

@@ -72,6 +72,7 @@
"bracket-matcher": "0.1.0",
"command-logger": "0.1.0",
"command-palette": "0.1.0",
"fuzzy-finder": "0.1.0",
"editor-stats": "0.1.0",
"gfm": "0.1.0",
"git-diff": "0.1.0",

View File

@@ -1,5 +0,0 @@
'body':
'meta-t': 'fuzzy-finder:toggle-file-finder'
'meta-b': 'fuzzy-finder:toggle-buffer-finder'
'ctrl-.': 'fuzzy-finder:find-under-cursor'
'meta-B': 'fuzzy-finder:toggle-git-status-finder'

View File

@@ -1,252 +0,0 @@
{View, $$} = require 'space-pen'
SelectList = require 'select-list'
_ = require 'underscore'
$ = require 'jquery'
humanize = require 'humanize-plus'
fsUtils = require 'fs-utils'
path = require 'path'
PathLoader = require './path-loader'
Point = require 'point'
module.exports =
class FuzzyFinderView extends SelectList
filenameRegex: /[\w\.\-\/\\]+/
finderMode: null
@viewClass: ->
[super, 'fuzzy-finder', 'overlay', 'from-top'].join(' ')
allowActiveEditorChange: null
maxItems: 10
projectPaths: null
reloadProjectPaths: true
filterKey: 'projectRelativePath'
initialize: (@projectPaths)->
super
@reloadProjectPaths = false if @projectPaths?.length > 0
@subscribe $(window), 'focus', => @reloadProjectPaths = true
@observeConfig 'fuzzy-finder.ignoredNames', => @reloadProjectPaths = true
rootView.eachPane (pane) ->
pane.activeItem.lastOpened = (new Date) - 1
pane.on 'pane:active-item-changed', (e, item) -> item.lastOpened = (new Date) - 1
@miniEditor.command 'pane:split-left', =>
@splitOpenPath (pane, session) -> pane.splitLeft(session)
@miniEditor.command 'pane:split-right', =>
@splitOpenPath (pane, session) -> pane.splitRight(session)
@miniEditor.command 'pane:split-down', =>
@splitOpenPath (pane, session) -> pane.splitDown(session)
@miniEditor.command 'pane:split-up', =>
@splitOpenPath (pane, session) -> pane.splitUp(session)
itemForElement: ({filePath, projectRelativePath}) ->
$$ ->
@li class: 'two-lines', =>
if git?
status = git.statuses[filePath]
if git.isStatusNew(status)
@div class: 'status new'
else if git.isStatusModified(status)
@div class: 'status modified'
ext = path.extname(filePath)
if fsUtils.isReadmePath(filePath)
typeClass = 'readme-name'
else if fsUtils.isCompressedExtension(ext)
typeClass = 'compressed-name'
else if fsUtils.isImageExtension(ext)
typeClass = 'image-name'
else if fsUtils.isPdfExtension(ext)
typeClass = 'pdf-name'
else if fsUtils.isBinaryExtension(ext)
typeClass = 'binary-name'
else
typeClass = 'text-name'
@div path.basename(filePath), class: "primary-line file #{typeClass}"
@div projectRelativePath, class: 'secondary-line path'
openPath: (filePath, lineNumber) ->
return unless filePath
rootView.open(filePath, {@allowActiveEditorChange})
@moveToLine(lineNumber)
moveToLine: (lineNumber=-1) ->
return unless lineNumber >= 0
if editor = rootView.getActiveView()
position = new Point(lineNumber)
editor.scrollToBufferPosition(position, center: true)
editor.setCursorBufferPosition(position)
editor.moveCursorToFirstCharacterOfLine()
splitOpenPath: (fn) ->
{filePath} = @getSelectedElement()
return unless filePath
lineNumber = @getLineNumber()
if pane = rootView.getActivePane()
fn(pane, project.open(filePath))
@moveToLine(lineNumber)
else
@openPath(filePath, lineNumber)
confirmed : ({filePath}) ->
return unless filePath
if fsUtils.isDirectorySync(filePath)
@setError('Selected path is a directory')
setTimeout((=> @setError()), 2000)
else
lineNumber = @getLineNumber()
@cancel()
@openPath(filePath, lineNumber)
toggleFileFinder: ->
@finderMode = 'file'
if @hasParent()
@cancel()
else
return unless project.getPath()?
@allowActiveEditorChange = false
@populateProjectPaths()
@attach()
toggleBufferFinder: ->
@finderMode = 'buffer'
if @hasParent()
@cancel()
else
@allowActiveEditorChange = true
@populateOpenBufferPaths()
@attach() if @paths?.length
toggleGitFinder: ->
@finderMode = 'git'
if @hasParent()
@cancel()
else
return unless project.getPath()? and git?
@allowActiveEditorChange = false
@populateGitStatusPaths()
@attach()
getEmptyMessage: (itemCount) ->
if itemCount is 0
switch @finderMode
when 'git'
'Nothing to commit, working directory clean'
when 'buffer'
'No open editors'
when 'file'
'Project is empty'
else
super
else
super
findUnderCursor: ->
if @hasParent()
@cancel()
else
return unless project.getPath()?
@allowActiveEditorChange = false
editor = rootView.getActiveView()
currentWord = editor.getWordUnderCursor(wordRegex: @filenameRegex)
if currentWord.length == 0
@attach()
@setError("The cursor is not over a filename")
else
@populateProjectPaths filter: currentWord, done: (paths) =>
if paths.length == 0
@attach()
@setError("No files match '#{currentWord}'")
else if paths.length == 1
rootView.open(paths[0])
else
@attach()
@miniEditor.setText(currentWord)
getFilterQuery: ->
query = super
colon = query.indexOf(':')
if colon is -1
query
else
query[0...colon]
getLineNumber: ->
query = @miniEditor.getText()
colon = query.indexOf(':')
if colon is -1
-1
else
parseInt(query[colon+1..]) - 1
setArray: (paths) ->
projectRelativePaths = paths.map (filePath) ->
projectRelativePath = project.relativize(filePath)
{filePath, projectRelativePath}
super(projectRelativePaths)
populateGitStatusPaths: ->
paths = []
paths.push(filePath) for filePath, status of git.statuses when fsUtils.isFileSync(filePath)
@setArray(paths)
populateProjectPaths: (options = {}) ->
if @projectPaths?
listedItems =
if options.filter?
@projectPaths.filter (filePath) ->
filePath.indexOf(options.filter) >= 0
else
@projectPaths
@setArray(listedItems)
options.done(listedItems) if options.done?
else
@setLoading("Indexing project...")
@loadingBadge.text("")
if @reloadProjectPaths
@loadPathsTask?.terminate()
@loadPathsTask = PathLoader.startTask (paths) =>
@projectPaths = paths
@reloadProjectPaths = false
@populateProjectPaths(options)
pathsFound = 0
@loadPathsTask.on 'load-paths:paths-found', (paths) =>
pathsFound += paths.length
@loadingBadge.text(humanize.intcomma(pathsFound))
populateOpenBufferPaths: ->
editSessions = project.getEditSessions().filter (editSession) ->
editSession.getPath()?
editSessions = _.sortBy editSessions, (editSession) =>
if editSession is rootView.getActivePaneItem()
0
else
-(editSession.lastOpened or 1)
@paths = []
@paths.push(editSession.getPath()) for editSession in editSessions
@setArray(_.uniq(@paths))
beforeRemove: ->
@loadPathsTask?.terminate()
attach: ->
super
rootView.append(this)
@miniEditor.focus()

View File

@@ -1,48 +0,0 @@
_ = require 'underscore'
module.exports =
projectPaths: null
fuzzyFinderView: null
loadPathsTask: null
activate: (state) ->
rootView.command 'fuzzy-finder:toggle-file-finder', =>
@createView().toggleFileFinder()
rootView.command 'fuzzy-finder:toggle-buffer-finder', =>
@createView().toggleBufferFinder()
rootView.command 'fuzzy-finder:find-under-cursor', =>
@createView().findUnderCursor()
rootView.command 'fuzzy-finder:toggle-git-status-finder', =>
@createView().toggleGitFinder()
if project.getPath()?
PathLoader = require './path-loader'
@loadPathsTask = PathLoader.startTask (paths) => @projectPaths = paths
for editSession in project.getEditSessions()
editSession.lastOpened = state[editSession.getPath()]
deactivate: ->
if @loadPathsTask?
@loadPathsTask.terminate()
@loadPathsTask = null
if @fuzzyFinderView?
@fuzzyFinderView.cancel()
@fuzzyFinderView.remove()
@fuzzyFinderView = null
@projectPaths = null
serialize: ->
if @fuzzyFinderView?
paths = {}
for editSession in project.getEditSessions()
path = editSession.getPath()
paths[path] = editSession.lastOpened if path?
paths
createView: ->
unless @fuzzyFinderView
@loadPathsTask?.terminate()
FuzzyFinderView = require './fuzzy-finder-view'
@fuzzyFinderView = new FuzzyFinderView(@projectPaths)
@fuzzyFinderView

View File

@@ -1,58 +0,0 @@
fs = require 'fs'
path = require 'path'
_ = require 'underscore'
Git = require 'git'
asyncCallsInProgress = 0
pathsChunkSize = 100
paths = []
repo = null
ignoredNames = null
callback = null
isIgnored = (loadedPath) ->
repo?.isPathIgnored(loadedPath) or _.indexOf(ignoredNames, path.basename(loadedPath), true) isnt -1
asyncCallStarting = ->
asyncCallsInProgress++
asyncCallDone = ->
if --asyncCallsInProgress is 0
repo?.destroy()
emit('load-paths:paths-found', paths)
callback()
pathLoaded = (path) ->
paths.push(path) unless isIgnored(path)
if paths.length is pathsChunkSize
emit('load-paths:paths-found', paths)
paths = []
loadPath = (path) ->
asyncCallStarting()
fs.lstat path, (error, stats) ->
unless error?
if stats.isSymbolicLink()
asyncCallStarting()
fs.stat path, (error, stats) ->
unless error?
pathLoaded(path) if stats.isFile()
asyncCallDone()
else if stats.isDirectory()
loadFolder(path) unless isIgnored(path)
else if stats.isFile()
pathLoaded(path)
asyncCallDone()
loadFolder = (folderPath) ->
asyncCallStarting()
fs.readdir folderPath, (error, children=[]) ->
loadPath(path.join(folderPath, childName)) for childName in children
asyncCallDone()
module.exports = (rootPath, ignoreVcsIgnores, ignore) ->
ignoredNames = ignore
callback = @async()
repo = Git.open(rootPath, refreshOnWindowFocus: false) if ignoreVcsIgnores
ignoredNames.sort()
loadFolder(rootPath)

View File

@@ -1,17 +0,0 @@
Task = require 'task'
module.exports =
startTask: (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')
task = Task.once taskPath, project.getPath(), ignoreVcsIgnores, ignoredNames, ->
callback(projectPaths)
task.on 'load-paths:paths-found', (paths) =>
projectPaths.push(paths...)
task

View File

@@ -1,2 +0,0 @@
'main': './lib/fuzzy-finder'
'description': 'Open an editor to a file in the project with `cmd-t`.'

View File

@@ -1,554 +0,0 @@
RootView = require 'root-view'
FuzzyFinder = require 'fuzzy-finder/lib/fuzzy-finder-view'
PathLoader = require 'fuzzy-finder/lib/path-loader'
_ = require 'underscore'
$ = require 'jquery'
{$$} = require 'space-pen'
fsUtils = require 'fs-utils'
path = require 'path'
describe 'FuzzyFinder', ->
[finderView] = []
beforeEach ->
window.rootView = new RootView
rootView.open('sample.js')
rootView.enableKeymap()
finderView = atom.activatePackage("fuzzy-finder").mainModule.createView()
describe "file-finder behavior", ->
describe "toggling", ->
describe "when the root view's project has a path", ->
it "shows the FuzzyFinder or hides it and returns focus to the active editor if it already showing", ->
rootView.attachToDom()
expect(rootView.find('.fuzzy-finder')).not.toExist()
rootView.getActiveView().splitRight()
[editor1, editor2] = rootView.getEditors()
expect(rootView.find('.fuzzy-finder')).not.toExist()
rootView.trigger 'fuzzy-finder:toggle-file-finder'
expect(rootView.find('.fuzzy-finder')).toExist()
expect(finderView.miniEditor.isFocused).toBeTruthy()
expect(editor1.isFocused).toBeFalsy()
expect(editor2.isFocused).toBeFalsy()
finderView.miniEditor.insertText('this should not show up next time we toggle')
rootView.trigger 'fuzzy-finder:toggle-file-finder'
expect(editor1.isFocused).toBeFalsy()
expect(editor2.isFocused).toBeTruthy()
expect(rootView.find('.fuzzy-finder')).not.toExist()
rootView.trigger 'fuzzy-finder:toggle-file-finder'
expect(finderView.miniEditor.getText()).toBe ''
it "shows all relative file paths for the current project and selects the first", ->
rootView.attachToDom()
finderView.maxItems = Infinity
rootView.trigger 'fuzzy-finder:toggle-file-finder'
paths = null
expect(finderView.find(".loading")).toBeVisible()
expect(finderView.find(".loading").text().length).toBeGreaterThan 0
waitsFor "all project paths to load", 5000, ->
unless finderView.reloadProjectPaths
paths = finderView.projectPaths
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()
expect(finderView.list.children().first()).toHaveClass 'selected'
expect(finderView.find(".loading")).not.toBeVisible()
it "includes symlinked file paths", ->
rootView.attachToDom()
finderView.maxItems = Infinity
rootView.trigger 'fuzzy-finder:toggle-file-finder'
waitsFor "all project paths to load", 5000, ->
not finderView.reloadProjectPaths
runs ->
expect(finderView.list.find("li:contains(symlink-to-file)")).toExist()
it "excludes symlinked folder paths", ->
rootView.attachToDom()
finderView.maxItems = Infinity
rootView.trigger 'fuzzy-finder:toggle-file-finder'
waitsFor "all project paths to load", 5000, ->
not finderView.reloadProjectPaths
runs ->
expect(finderView.list.find("li:contains(symlink-to-dir)")).not.toExist()
describe "when root view's project has no path", ->
beforeEach ->
project.setPath(null)
it "does not open the FuzzyFinder", ->
expect(rootView.find('.fuzzy-finder')).not.toExist()
rootView.trigger 'fuzzy-finder:toggle-file-finder'
expect(rootView.find('.fuzzy-finder')).not.toExist()
describe "when a path selection is confirmed", ->
it "opens the file associated with that path in the editor", ->
rootView.attachToDom()
editor1 = rootView.getActiveView()
editor2 = editor1.splitRight()
expect(rootView.getActiveView()).toBe editor2
rootView.trigger 'fuzzy-finder:toggle-file-finder'
expectedPath = project.resolve('dir/a')
finderView.confirmed({filePath: expectedPath})
expect(finderView.hasParent()).toBeFalsy()
expect(editor1.getPath()).not.toBe expectedPath
expect(editor2.getPath()).toBe expectedPath
expect(editor2.isFocused).toBeTruthy()
describe "when the selected path is a directory", ->
it "leaves the the tree view open, doesn't open the path in the editor, and displays an error", ->
rootView.attachToDom()
editorPath = rootView.getActiveView().getPath()
rootView.trigger 'fuzzy-finder:toggle-file-finder'
finderView.confirmed({filePath: project.resolve('dir')})
expect(finderView.hasParent()).toBeTruthy()
expect(rootView.getActiveView().getPath()).toBe editorPath
expect(finderView.error.text().length).toBeGreaterThan 0
advanceClock(2000)
expect(finderView.error.text().length).toBe 0
describe "buffer-finder behavior", ->
describe "toggling", ->
describe "when there are pane items with paths", ->
beforeEach ->
rootView.open('sample.txt')
it "shows the FuzzyFinder if it isn't showing, or hides it and returns focus to the active editor", ->
rootView.attachToDom()
expect(rootView.find('.fuzzy-finder')).not.toExist()
rootView.getActiveView().splitRight()
[editor1, editor2] = rootView.getEditors()
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
expect(rootView.find('.fuzzy-finder')).toExist()
expect(rootView.find('.fuzzy-finder input:focus')).toExist()
finderView.miniEditor.insertText('this should not show up next time we toggle')
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
expect(editor1.isFocused).toBeFalsy()
expect(editor2.isFocused).toBeTruthy()
expect(rootView.find('.fuzzy-finder')).not.toExist()
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
expect(finderView.miniEditor.getText()).toBe ''
it "lists the paths of the current items, sorted by most recently opened but with the current item last", ->
rootView.attachToDom()
rootView.open 'sample-with-tabs.coffee'
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
expect(_.pluck(finderView.list.find('li > div.file'), 'outerText')).toEqual ['sample.txt', 'sample.js', 'sample-with-tabs.coffee']
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
rootView.open 'sample.txt'
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
expect(_.pluck(finderView.list.find('li > div.file'), 'outerText')).toEqual ['sample-with-tabs.coffee', 'sample.js', 'sample.txt']
expect(finderView.list.children().first()).toHaveClass 'selected'
it "serializes the list of paths and their last opened time", ->
rootView.open 'sample-with-tabs.coffee'
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
rootView.open 'sample.js'
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
rootView.open()
atom.deactivatePackage('fuzzy-finder')
states = _.map atom.getPackageState('fuzzy-finder'), (path, time) -> [ path, time ]
expect(states.length).toBe 3
states = _.sortBy states, (path, time) -> -time
paths = [ 'sample-with-tabs.coffee', 'sample.txt', 'sample.js' ]
for [time, bufferPath] in states
expect(_.last bufferPath.split '/').toBe paths.shift()
expect(time).toBeGreaterThan 50000
describe "when there are only panes with anonymous items", ->
it "does not open", ->
rootView.getActivePane().remove()
rootView.open()
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
expect(rootView.find('.fuzzy-finder')).not.toExist()
describe "when there are no pane items", ->
it "does not open", ->
rootView.getActivePane().remove()
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
expect(rootView.find('.fuzzy-finder')).not.toExist()
describe "when multiple sessions are opened on the same path", ->
it "does not display duplicates for that path in the list", ->
rootView.open 'sample.js'
rootView.getActivePane().splitRight()
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
expect(_.pluck(finderView.list.find('li > div.file'), 'outerText')).toEqual ['sample.js']
describe "when a path selection is confirmed", ->
[editor1, editor2] = []
beforeEach ->
rootView.attachToDom()
editor1 = rootView.getActiveView()
editor2 = editor1.splitRight()
expect(rootView.getActiveView()).toBe editor2
rootView.open('sample.txt')
editor2.trigger 'pane:show-previous-item'
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
describe "when the active pane has an item for the selected path", ->
it "switches to the item for the selected path", ->
expectedPath = project.resolve('sample.txt')
finderView.confirmed({filePath: expectedPath})
expect(finderView.hasParent()).toBeFalsy()
expect(editor1.getPath()).not.toBe expectedPath
expect(editor2.getPath()).toBe expectedPath
expect(editor2.isFocused).toBeTruthy()
describe "when the active pane does not have an item for the selected path", ->
it "adds a new item to the active pane for the selcted path", ->
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
editor1.focus()
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
expect(rootView.getActiveView()).toBe editor1
expectedPath = project.resolve('sample.txt')
finderView.confirmed({filePath: expectedPath})
expect(finderView.hasParent()).toBeFalsy()
expect(editor1.getPath()).toBe expectedPath
expect(editor1.isFocused).toBeTruthy()
describe "git-status-finder behavior", ->
[originalText, originalPath, newPath] = []
beforeEach ->
editor = rootView.getActiveView()
originalText = editor.getText()
originalPath = editor.getPath()
fsUtils.writeSync(originalPath, 'making a change for the better')
git.getPathStatus(originalPath)
newPath = project.resolve('newsample.js')
fsUtils.writeSync(newPath, '')
git.getPathStatus(newPath)
afterEach ->
fsUtils.writeSync(originalPath, originalText)
fsUtils.remove(newPath) if fsUtils.exists(newPath)
it "displays all new and modified paths", ->
expect(rootView.find('.fuzzy-finder')).not.toExist()
rootView.trigger 'fuzzy-finder:toggle-git-status-finder'
expect(rootView.find('.fuzzy-finder')).toExist()
expect(finderView.find('.file').length).toBe 2
expect(finderView.find('.status.modified').length).toBe 1
expect(finderView.find('.status.new').length).toBe 1
describe "common behavior between file and buffer finder", ->
describe "when the fuzzy finder is cancelled", ->
describe "when an editor is open", ->
it "detaches the finder and focuses the previously focused element", ->
rootView.attachToDom()
activeEditor = rootView.getActiveView()
activeEditor.focus()
rootView.trigger 'fuzzy-finder:toggle-file-finder'
expect(finderView.hasParent()).toBeTruthy()
expect(activeEditor.isFocused).toBeFalsy()
expect(finderView.miniEditor.isFocused).toBeTruthy()
finderView.cancel()
expect(finderView.hasParent()).toBeFalsy()
expect(activeEditor.isFocused).toBeTruthy()
expect(finderView.miniEditor.isFocused).toBeFalsy()
describe "when no editors are open", ->
it "detaches the finder and focuses the previously focused element", ->
rootView.attachToDom()
rootView.getActivePane().remove()
inputView = $$ -> @input()
rootView.append(inputView)
inputView.focus()
rootView.trigger 'fuzzy-finder:toggle-file-finder'
expect(finderView.hasParent()).toBeTruthy()
expect(finderView.miniEditor.isFocused).toBeTruthy()
finderView.cancel()
expect(finderView.hasParent()).toBeFalsy()
expect(document.activeElement).toBe inputView[0]
expect(finderView.miniEditor.isFocused).toBeFalsy()
describe "cached file paths", ->
it "caches file paths after first time", ->
spyOn(PathLoader, "startTask").andCallThrough()
rootView.trigger 'fuzzy-finder:toggle-file-finder'
waitsFor ->
finderView.list.children('li').length > 0
runs ->
expect(PathLoader.startTask).toHaveBeenCalled()
PathLoader.startTask.reset()
rootView.trigger 'fuzzy-finder:toggle-file-finder'
rootView.trigger 'fuzzy-finder:toggle-file-finder'
waitsFor ->
finderView.list.children('li').length > 0
runs ->
expect(PathLoader.startTask).not.toHaveBeenCalled()
it "doesn't cache buffer paths", ->
spyOn(project, "getEditSessions").andCallThrough()
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
waitsFor ->
finderView.list.children('li').length > 0
runs ->
expect(project.getEditSessions).toHaveBeenCalled()
project.getEditSessions.reset()
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
waitsFor ->
finderView.list.children('li').length > 0
runs ->
expect(project.getEditSessions).toHaveBeenCalled()
it "busts the cache when the window gains focus", ->
spyOn(PathLoader, "startTask").andCallThrough()
rootView.trigger 'fuzzy-finder:toggle-file-finder'
waitsFor ->
finderView.list.children('li').length > 0
runs ->
expect(PathLoader.startTask).toHaveBeenCalled()
PathLoader.startTask.reset()
$(window).trigger 'focus'
rootView.trigger 'fuzzy-finder:toggle-file-finder'
rootView.trigger 'fuzzy-finder:toggle-file-finder'
expect(PathLoader.startTask).toHaveBeenCalled()
describe "path ignoring", ->
it "ignores paths that match entries in config.fuzzyFinder.ignoredNames", ->
config.set("fuzzyFinder.ignoredNames", ["tree-view.js"])
rootView.trigger 'fuzzy-finder:toggle-file-finder'
finderView.maxItems = Infinity
waitsFor ->
finderView.list.children('li').length > 0
runs ->
expect(finderView.list.find("li:contains(tree-view.js)")).not.toExist()
describe "when core.excludeVcsIgnoredPaths is set to true", ->
ignoreFile = null
beforeEach ->
ignoreFile = path.join(project.getPath(), '.gitignore')
fsUtils.writeSync(ignoreFile, 'sample.js')
config.set("core.excludeVcsIgnoredPaths", true)
afterEach ->
fsUtils.remove(ignoreFile) if fsUtils.exists(ignoreFile)
it "ignores paths that are git ignored", ->
rootView.trigger 'fuzzy-finder:toggle-file-finder'
finderView.maxItems = Infinity
waitsFor ->
finderView.list.children('li').length > 0
runs ->
expect(finderView.list.find("li:contains(sample.js)")).not.toExist()
describe "fuzzy find by content under cursor", ->
editor = null
beforeEach ->
editor = rootView.getActiveView()
rootView.attachToDom()
it "opens the fuzzy finder window when there are multiple matches", ->
editor.setText("sample")
rootView.trigger 'fuzzy-finder:find-under-cursor'
waitsFor ->
finderView.list.children('li').length > 0
runs ->
expect(finderView).toBeVisible()
expect(rootView.find('.fuzzy-finder input:focus')).toExist()
it "opens a file directly when there is a single match", ->
editor.setText("sample.txt")
rootView.trigger 'fuzzy-finder:find-under-cursor'
openedPath = null
spyOn(rootView, "open").andCallFake (path) ->
openedPath = path
waitsFor ->
openedPath != null
runs ->
expect(finderView).not.toBeVisible()
expect(openedPath).toBe project.resolve("sample.txt")
it "displays an error when the word under the cursor doesn't match any files", ->
editor.setText("moogoogaipan")
editor.setCursorBufferPosition([0,5])
rootView.trigger 'fuzzy-finder:find-under-cursor'
waitsFor ->
finderView.is(':visible')
runs ->
expect(finderView.error.text().length).toBeGreaterThan 0
it "displays error when there is no word under the cursor", ->
editor.setText("&&&&&&&&&&&&&&& sample")
editor.setCursorBufferPosition([0,5])
rootView.trigger 'fuzzy-finder:find-under-cursor'
waitsFor ->
finderView.is(':visible')
runs ->
expect(finderView.error.text().length).toBeGreaterThan 0
describe "opening a path into a split", ->
it "opens the path by splitting the active editor left", ->
expect(rootView.getPanes().length).toBe 1
pane = rootView.getActivePane()
spyOn(pane, "splitLeft").andCallThrough()
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
{filePath} = finderView.getSelectedElement()
finderView.miniEditor.trigger 'pane:split-left'
expect(rootView.getPanes().length).toBe 2
expect(pane.splitLeft).toHaveBeenCalled()
expect(rootView.getActiveView().getPath()).toBe project.resolve(filePath)
it "opens the path by splitting the active editor right", ->
expect(rootView.getPanes().length).toBe 1
pane = rootView.getActivePane()
spyOn(pane, "splitRight").andCallThrough()
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
{filePath} = finderView.getSelectedElement()
finderView.miniEditor.trigger 'pane:split-right'
expect(rootView.getPanes().length).toBe 2
expect(pane.splitRight).toHaveBeenCalled()
expect(rootView.getActiveView().getPath()).toBe project.resolve(filePath)
it "opens the path by splitting the active editor up", ->
expect(rootView.getPanes().length).toBe 1
pane = rootView.getActivePane()
spyOn(pane, "splitUp").andCallThrough()
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
{filePath} = finderView.getSelectedElement()
finderView.miniEditor.trigger 'pane:split-up'
expect(rootView.getPanes().length).toBe 2
expect(pane.splitUp).toHaveBeenCalled()
expect(rootView.getActiveView().getPath()).toBe project.resolve(filePath)
it "opens the path by splitting the active editor down", ->
expect(rootView.getPanes().length).toBe 1
pane = rootView.getActivePane()
spyOn(pane, "splitDown").andCallThrough()
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
{filePath} = finderView.getSelectedElement()
finderView.miniEditor.trigger 'pane:split-down'
expect(rootView.getPanes().length).toBe 2
expect(pane.splitDown).toHaveBeenCalled()
expect(rootView.getActiveView().getPath()).toBe project.resolve(filePath)
describe "git status decorations", ->
[originalText, originalPath, editor, newPath] = []
beforeEach ->
editor = rootView.getActiveView()
originalText = editor.getText()
originalPath = editor.getPath()
newPath = project.resolve('newsample.js')
fsUtils.writeSync(newPath, '')
afterEach ->
fsUtils.writeSync(originalPath, originalText)
fsUtils.remove(newPath) if fsUtils.exists(newPath)
describe "when a modified file is shown in the list", ->
it "displays the modified icon", ->
editor.setText('modified')
editor.activeEditSession.save()
git.getPathStatus(editor.getPath())
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
expect(finderView.find('.status.modified').length).toBe 1
expect(finderView.find('.status.modified').closest('li').find('.file').text()).toBe 'sample.js'
describe "when a new file is shown in the list", ->
it "displays the new icon", ->
rootView.open('newsample.js')
git.getPathStatus(editor.getPath())
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
expect(finderView.find('.status.new').length).toBe 1
expect(finderView.find('.status.new').closest('li').find('.file').text()).toBe 'newsample.js'
describe "when the filter text contains a colon followed by a number", ->
it "opens the selected path to that line number", ->
rootView.attachToDom()
expect(rootView.find('.fuzzy-finder')).not.toExist()
[editor] = rootView.getEditors()
expect(editor.getCursorBufferPosition()).toEqual [0, 0]
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
expect(rootView.find('.fuzzy-finder')).toExist()
finderView.miniEditor.insertText(':4')
finderView.trigger 'core:confirm'
expect(editor.getCursorBufferPosition()).toEqual [3, 4]
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
expect(rootView.find('.fuzzy-finder')).toExist()
finderView.miniEditor.insertText(':10')
finderView.miniEditor.trigger 'pane:split-left'
expect(rootView.getActiveView()).not.toBe editor
expect(rootView.getActiveView().getCursorBufferPosition()).toEqual [9, 2]

View File

@@ -1,67 +0,0 @@
@import "octicon-utf-codes.less";
@import "octicon-mixins.less";
.fuzzy-finder {
&.select-list li {
padding: 5px 10px 5px 10px;
}
.path {
color: rgba(0, 0, 0, 0.5);
margin-left: 26px;
font-size: .9em;
}
.status {
.icon(16px);
margin-left: 5px;
color: #9d9d9d;
float: right;
&.new:before {
position: relative;
top: 3px;
content: @diff-added;
}
&.modified:before {
position: relative;
top: 3px;
content: @diff-modified;
}
}
.file {
&:before {
.icon(16px);
margin-right: 5px;
margin-left: 5px;
color: #9d9d9d;
}
&.text-name:before {
content: @file-text;
}
&.image-name:before {
content: @file-media;
}
&.compressed-name:before {
content: @file-zip;
}
&.pdf-name:before {
content: @file-pdf;
}
&.readme-name:before {
content: @book;
}
&.binary-name:before {
content: @file-binary;
}
}
}