mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-11 04:48:44 +03:00
Merge pull request #460 from github/nak-powered-search
Nak powered search
This commit is contained in:
commit
b6eed51eed
@ -13,6 +13,7 @@
|
||||
"coffee-cache": "0.1.0",
|
||||
"pegjs": "0.7.0",
|
||||
"async": "0.2.6",
|
||||
"nak": "git://github.com/kevinsawicki/nak.git",
|
||||
"spellchecker": "0.2.0",
|
||||
"plist": "git://github.com/nathansobo/node-plist.git",
|
||||
"space-pen": "git://github.com/nathansobo/space-pen.git"
|
||||
|
@ -191,8 +191,9 @@ class Project
|
||||
readPath(line) if state is 'readingPath'
|
||||
readLine(line) if state is 'readingLines'
|
||||
|
||||
command = require.resolve('ag')
|
||||
command = require.resolve('nak')
|
||||
args = ['--ackmate', regex.source, @getPath()]
|
||||
args.unshift("--addVCSIgnores") if config.get('core.excludeVcsIgnoredPaths')
|
||||
new BufferedProcess({command, args, stdout, exit})
|
||||
deferred
|
||||
|
||||
|
@ -120,6 +120,8 @@ class CommandPanelView extends View
|
||||
|
||||
execute: (command=@escapedCommand()) ->
|
||||
@loadingMessage.show()
|
||||
@previewList.hide()
|
||||
@previewHeader.hide()
|
||||
@errorMessages.empty()
|
||||
|
||||
try
|
||||
|
@ -8,7 +8,7 @@ class SelectAllMatchesInProject extends Command
|
||||
previewOperations: true
|
||||
|
||||
constructor: (pattern) ->
|
||||
@regex = new RegExp(pattern, 'g')
|
||||
@regex = new RegExp(pattern)
|
||||
|
||||
compile: (project, buffer, range) ->
|
||||
deferred = $.Deferred()
|
||||
|
@ -23,7 +23,7 @@ class Operation
|
||||
@getBufferRange() unless @preserveSelection
|
||||
|
||||
preview: ->
|
||||
range = @getBuffer().getMarkerRange(@getMarker())
|
||||
range = @getBufferRange()
|
||||
line = @getBuffer().lineForRow(range.start.row)
|
||||
prefix = line[0...range.start.column]
|
||||
match = line[range.start.column...range.end.column]
|
||||
|
@ -1,7 +1,6 @@
|
||||
$ = require 'jquery'
|
||||
ScrollView = require 'scroll-view'
|
||||
_ = require 'underscore'
|
||||
fsUtils = require 'fs-utils'
|
||||
PathView = require './path-view'
|
||||
OperationView = require './operation-view'
|
||||
|
||||
@ -22,7 +21,6 @@ class PreviewList extends ScrollView
|
||||
@on 'core:move-up', => @selectPreviousOperation(); false
|
||||
@on 'scroll', =>
|
||||
@renderOperations() if @scrollBottom() >= (@prop('scrollHeight'))
|
||||
|
||||
@command 'command-panel:collapse-all', => @collapseAllPaths()
|
||||
@command 'command-panel:expand-all', => @expandAllPaths()
|
||||
|
||||
|
@ -1,33 +1,33 @@
|
||||
_ = require 'underscore'
|
||||
fsUtils = require 'fs-utils'
|
||||
BufferedProcess = require 'buffered-process'
|
||||
|
||||
module.exports =
|
||||
class LoadPathsTask
|
||||
aborted: false
|
||||
|
||||
constructor: (@callback) ->
|
||||
|
||||
start: ->
|
||||
rootPath = project.getPath()
|
||||
ignoredNames = config.get('fuzzyFinder.ignoredNames') ? []
|
||||
ignoredNames = ignoredNames.concat(config.get('core.ignoredNames') ? [])
|
||||
ignoreGitIgnoredFiles = config.get('core.hideGitIgnoredFiles')
|
||||
|
||||
command = require.resolve 'nak'
|
||||
args = ['--list', rootPath]
|
||||
args.unshift('--addVCSIgnores') if config.get('core.excludeVcsIgnoredPaths')
|
||||
args.unshift('--ignore', ignoredNames.join(',')) if ignoredNames.length > 0
|
||||
args.unshift('--follow')
|
||||
|
||||
paths = []
|
||||
isIgnored = (path) ->
|
||||
path = path.substring(rootPath.length + 1)
|
||||
for segment in path.split('/')
|
||||
return true if _.contains(ignoredNames, segment)
|
||||
ignoreGitIgnoredFiles and git?.isPathIgnored(fsUtils.join(rootPath, path))
|
||||
onFile = (path) ->
|
||||
return if @aborted
|
||||
paths.push(path) unless isIgnored(path)
|
||||
onDirectory = (path) =>
|
||||
not @aborted and not isIgnored(path)
|
||||
onDone = =>
|
||||
@callback(paths) unless @aborted
|
||||
exit = (code) =>
|
||||
if code is 0
|
||||
@callback(paths)
|
||||
else
|
||||
@callback([])
|
||||
stdout = (data) ->
|
||||
paths.push(_.compact(data.split('\n'))...)
|
||||
|
||||
fsUtils.traverseTree(rootPath, onFile, onDirectory, onDone)
|
||||
@process = new BufferedProcess({command, args, stdout, exit})
|
||||
|
||||
abort: ->
|
||||
@aborted = true
|
||||
if @process?
|
||||
@process.kill()
|
||||
@process = null
|
||||
|
@ -43,7 +43,6 @@ describe 'FuzzyFinder', ->
|
||||
it "shows all relative file paths for the current project and selects the first", ->
|
||||
rootView.attachToDom()
|
||||
finderView.maxItems = Infinity
|
||||
jasmine.unspy(window, "setTimeout")
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
paths = null
|
||||
expect(finderView.find(".loading")).toBeVisible()
|
||||
@ -61,6 +60,17 @@ describe 'FuzzyFinder', ->
|
||||
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()
|
||||
|
||||
describe "when root view's project has no path", ->
|
||||
beforeEach ->
|
||||
project.setPath(null)
|
||||
@ -280,7 +290,6 @@ describe 'FuzzyFinder', ->
|
||||
describe "cached file paths", ->
|
||||
it "caches file paths after first time", ->
|
||||
spyOn(LoadPathsTask.prototype, "start").andCallThrough()
|
||||
jasmine.unspy(window, "setTimeout")
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
|
||||
waitsFor ->
|
||||
@ -300,7 +309,6 @@ describe 'FuzzyFinder', ->
|
||||
|
||||
it "doesn't cache buffer paths", ->
|
||||
spyOn(project, "getEditSessions").andCallThrough()
|
||||
jasmine.unspy(window, "setTimeout")
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
|
||||
waitsFor ->
|
||||
@ -320,7 +328,6 @@ describe 'FuzzyFinder', ->
|
||||
|
||||
it "busts the cache when the window gains focus", ->
|
||||
spyOn(LoadPathsTask.prototype, "start").andCallThrough()
|
||||
jasmine.unspy(window, "setTimeout")
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
|
||||
waitsFor ->
|
||||
@ -337,7 +344,6 @@ describe 'FuzzyFinder', ->
|
||||
describe "path ignoring", ->
|
||||
it "ignores paths that match entries in config.fuzzyFinder.ignoredNames", ->
|
||||
config.set("fuzzyFinder.ignoredNames", ["tree-view.js"])
|
||||
jasmine.unspy(window, "setTimeout")
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
finderView.maxItems = Infinity
|
||||
|
||||
@ -356,7 +362,6 @@ describe 'FuzzyFinder', ->
|
||||
|
||||
it "opens the fuzzy finder window when there are multiple matches", ->
|
||||
editor.setText("sample")
|
||||
jasmine.unspy(window, "setTimeout")
|
||||
rootView.trigger 'fuzzy-finder:find-under-cursor'
|
||||
|
||||
waitsFor ->
|
||||
@ -368,7 +373,6 @@ describe 'FuzzyFinder', ->
|
||||
|
||||
it "opens a file directly when there is a single match", ->
|
||||
editor.setText("sample.txt")
|
||||
jasmine.unspy(window, "setTimeout")
|
||||
rootView.trigger 'fuzzy-finder:find-under-cursor'
|
||||
|
||||
openedPath = null
|
||||
@ -386,7 +390,6 @@ describe 'FuzzyFinder', ->
|
||||
editor.setText("moogoogaipan")
|
||||
editor.setCursorBufferPosition([0,5])
|
||||
|
||||
jasmine.unspy(window, "setTimeout")
|
||||
rootView.trigger 'fuzzy-finder:find-under-cursor'
|
||||
|
||||
waitsFor ->
|
||||
|
@ -2,32 +2,36 @@ ChildProcess = require 'child_process'
|
||||
|
||||
module.exports =
|
||||
class BufferedProcess
|
||||
process: null
|
||||
killed: false
|
||||
|
||||
constructor: ({command, args, options, stdout, stderr, exit}={}) ->
|
||||
process = ChildProcess.spawn(command, args, options)
|
||||
@process = ChildProcess.spawn(command, args, options)
|
||||
|
||||
stdoutClosed = true
|
||||
stderrClosed = true
|
||||
processExited = true
|
||||
exitCode = 0
|
||||
triggerExitCallback = ->
|
||||
return if @killed
|
||||
if stdoutClosed and stderrClosed and processExited
|
||||
exit?(exitCode)
|
||||
|
||||
if stdout
|
||||
stdoutClosed = false
|
||||
@bufferStream process.stdout, stdout, ->
|
||||
@bufferStream @process.stdout, stdout, ->
|
||||
stdoutClosed = true
|
||||
triggerExitCallback()
|
||||
|
||||
if stderr
|
||||
stderrClosed = false
|
||||
@bufferStream process.stderr, stderr, ->
|
||||
@bufferStream @process.stderr, stderr, ->
|
||||
stderrClosed = true
|
||||
triggerExitCallback()
|
||||
|
||||
if exit
|
||||
processExited = false
|
||||
process.on 'exit', (code) ->
|
||||
@process.on 'exit', (code) ->
|
||||
exitCode = code
|
||||
processExited = true
|
||||
triggerExitCallback()
|
||||
@ -36,7 +40,8 @@ class BufferedProcess
|
||||
stream.setEncoding('utf8')
|
||||
buffered = ''
|
||||
|
||||
stream.on 'data', (data) ->
|
||||
stream.on 'data', (data) =>
|
||||
return if @killed
|
||||
buffered += data
|
||||
lastNewlineIndex = buffered.lastIndexOf('\n')
|
||||
if lastNewlineIndex isnt -1
|
||||
@ -44,5 +49,11 @@ class BufferedProcess
|
||||
buffered = buffered.substring(lastNewlineIndex + 1)
|
||||
|
||||
stream.on 'close', =>
|
||||
return if @killed
|
||||
onLines(buffered) if buffered.length > 0
|
||||
onDone()
|
||||
|
||||
kill: ->
|
||||
@killed = true
|
||||
@process.kill()
|
||||
@process = null
|
||||
|
2784
vendor/ack
vendored
2784
vendor/ack
vendored
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user