mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2025-01-08 16:19:17 +03:00
Use the silver searcher to implement global search
Parsing uses a simple state machine in `Project.scan`.
This commit is contained in:
parent
f37330a218
commit
239cba25e4
@ -128,12 +128,12 @@ describe "Project", ->
|
||||
runs ->
|
||||
expect(matches[0]).toEqual
|
||||
path: project.resolve('a')
|
||||
match: ['aaa', 'a']
|
||||
match: 'aaa'
|
||||
range: [[0, 0], [0, 3]]
|
||||
|
||||
expect(matches[1]).toEqual
|
||||
path: project.resolve('a')
|
||||
match: ['aa', 'a']
|
||||
match: 'aa'
|
||||
range: [[1, 3], [1, 5]]
|
||||
|
||||
it "works on evil filenames", ->
|
||||
@ -147,11 +147,9 @@ describe "Project", ->
|
||||
|
||||
runs ->
|
||||
expect(paths.length).toBe 5
|
||||
matches.forEach (match) -> expect(match).toEqual ['evil']
|
||||
matches.forEach (match) -> expect(match).toEqual 'evil'
|
||||
expect(paths[0]).toMatch /a_file_with_utf8.txt$/
|
||||
expect(paths[1]).toMatch /file with spaces.txt$/
|
||||
expect(paths[2]).toMatch /goddam\nnewlines$/m
|
||||
expect(paths[3]).toMatch /quote".txt$/m
|
||||
expect(fs.base(paths[4])).toBe "utfa\u0306.md"
|
||||
|
||||
|
||||
|
@ -138,32 +138,58 @@ class Project
|
||||
|
||||
scan: (regex, iterator) ->
|
||||
regex = new RegExp(regex.source, 'g')
|
||||
command = "#{require.resolve('ack')} --all --match \"#{regex.source}\" \"#{@getPath()}\""
|
||||
command = "#{require.resolve('ag')} --ackmate \"#{regex.source}\" \"#{@getPath()}\""
|
||||
bufferedData = ""
|
||||
|
||||
console.log command
|
||||
promise = ChildProcess.exec command , bufferLines: true, stdout: (data) ->
|
||||
bufferedData += data
|
||||
currentIndex = 0
|
||||
while currentIndex < bufferedData.length
|
||||
pathEndIndex = bufferedData.indexOf('\0', currentIndex)
|
||||
break unless pathEndIndex >= 0
|
||||
lineNumberEndIndex = bufferedData.indexOf('\0', pathEndIndex + 1)
|
||||
lineEndIndex = bufferedData.indexOf('\n', lineNumberEndIndex + 1)
|
||||
state = 'readingPath'
|
||||
path = null
|
||||
|
||||
readPath = (line) ->
|
||||
if /^[0-9,; ]+:/.test(line)
|
||||
state = 'readingLines'
|
||||
else if /^:/.test line
|
||||
path = line.substr(1)
|
||||
else
|
||||
path += ('\n' + line)
|
||||
|
||||
readLine = (line) ->
|
||||
if line.length == 0
|
||||
state = 'readingPath'
|
||||
path = null
|
||||
else
|
||||
colonIndex = line.indexOf(':')
|
||||
matchInfo = line.substring(0, colonIndex)
|
||||
lineText = line.substring(colonIndex + 1)
|
||||
readMatches(matchInfo, lineText)
|
||||
|
||||
readMatches = (matchInfo, lineText) ->
|
||||
[lineNumber, matchPositionsText] = matchInfo.match(/(\d+);(.+)/)[1..]
|
||||
row = parseInt(lineNumber) - 1
|
||||
|
||||
|
||||
|
||||
matchPositions = matchPositionsText.split(',').map (positionText) -> positionText.split(' ').map (pos) -> parseInt(pos)
|
||||
|
||||
for [column, length] in matchPositions
|
||||
range = new Range([row, column], [row, column + length])
|
||||
match = lineText.substr(column, length)
|
||||
iterator({path, range, match})
|
||||
|
||||
ChildProcess.exec command , bufferLines: true, stdout: (data) ->
|
||||
lines = data.split('\n')
|
||||
try
|
||||
for line in lines
|
||||
readPath(line) if state is 'readingPath'
|
||||
readLine(line) if state is 'readingLines'
|
||||
catch e
|
||||
console.log e.stack
|
||||
|
||||
|
||||
|
||||
path = bufferedData.substring(currentIndex, pathEndIndex)
|
||||
row = parseInt(bufferedData.substring(pathEndIndex + 1, lineNumberEndIndex)) - 1
|
||||
line = bufferedData.substring(lineNumberEndIndex + 1, lineEndIndex)
|
||||
|
||||
while match = regex.exec(line)
|
||||
range = new Range([row, match.index], [row, match.index + match[0].length])
|
||||
iterator({path, match, range})
|
||||
|
||||
currentIndex = lineEndIndex + 1
|
||||
|
||||
bufferedData = bufferedData.substring(currentIndex)
|
||||
|
||||
promise.done -> console.log "DONE"
|
||||
|
||||
|
||||
_.extend Project.prototype, EventEmitter
|
||||
|
Loading…
Reference in New Issue
Block a user