mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-12-28 00:52:29 +03:00
Merge pull request #1102 from atom/bo-add-replace
Add replace() to project and buffer
This commit is contained in:
commit
5f8e757f57
@ -31,7 +31,7 @@
|
||||
"pathwatcher": "0.9.0",
|
||||
"pegjs": "0.7.0",
|
||||
"q": "0.9.7",
|
||||
"scandal": "0.6.4",
|
||||
"scandal": "0.7.0",
|
||||
"season": "0.14.0",
|
||||
"semver": "1.1.4",
|
||||
"space-pen": "2.0.0",
|
||||
|
@ -296,6 +296,67 @@ describe "Project", ->
|
||||
expect(project.getPath()?).toBeFalsy()
|
||||
expect(project.getRootDirectory()?).toBeFalsy()
|
||||
|
||||
describe ".replace()", ->
|
||||
[filePath, commentFilePath, sampleContent, sampleCommentContent] = []
|
||||
|
||||
beforeEach ->
|
||||
project.setPath(project.resolve('../'))
|
||||
|
||||
filePath = project.resolve('sample.js')
|
||||
commentFilePath = project.resolve('sample-with-comments.js')
|
||||
sampleContent = fs.readFileSync(filePath).toString()
|
||||
sampleCommentContent = fs.readFileSync(commentFilePath).toString()
|
||||
|
||||
afterEach ->
|
||||
fs.writeFileSync(filePath, sampleContent)
|
||||
fs.writeFileSync(commentFilePath, sampleCommentContent)
|
||||
|
||||
describe "when called with unopened files", ->
|
||||
it "replaces properly", ->
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
project.replace /items/gi, 'items', [filePath], (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 1
|
||||
expect(results[0].filePath).toBe filePath
|
||||
expect(results[0].replacements).toBe 6
|
||||
|
||||
describe "when a buffer is already open", ->
|
||||
it "replaces properly and saves when not modified", ->
|
||||
editSession = project.openSync('sample.js')
|
||||
expect(editSession.isModified()).toBeFalsy()
|
||||
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
project.replace /items/gi, 'items', [filePath], (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 1
|
||||
expect(results[0].filePath).toBe filePath
|
||||
expect(results[0].replacements).toBe 6
|
||||
|
||||
expect(editSession.isModified()).toBeFalsy()
|
||||
|
||||
it "does NOT save when modified", ->
|
||||
editSession = project.openSync('sample.js')
|
||||
editSession.buffer.change([[0,0],[0,0]], 'omg')
|
||||
expect(editSession.isModified()).toBeTruthy()
|
||||
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
project.replace /items/gi, 'okthen', [filePath], (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 1
|
||||
expect(results[0].filePath).toBe filePath
|
||||
expect(results[0].replacements).toBe 6
|
||||
|
||||
expect(editSession.isModified()).toBeTruthy()
|
||||
|
||||
describe ".scan(options, callback)", ->
|
||||
describe "when called with a regex", ->
|
||||
it "calls the callback with all regex results in all files in the project", ->
|
||||
|
@ -336,6 +336,42 @@ class Project
|
||||
|
||||
deferred.promise
|
||||
|
||||
# Public: Performs a replace across all the specified files in the project.
|
||||
#
|
||||
# * regex: A RegExp to search with
|
||||
# * replacementText: Text to replace all matches of regex with
|
||||
# * filePaths: List of file path strings to run the replace on.
|
||||
# * iterator: A Function callback on each file with replacements. ({filePath, replacements}) ->
|
||||
replace: (regex, replacementText, filePaths, iterator) ->
|
||||
deferred = Q.defer()
|
||||
|
||||
openPaths = (buffer.getPath() for buffer in @buffers)
|
||||
outOfProcessPaths = _.difference(filePaths, openPaths)
|
||||
|
||||
inProcessFinished = !openPaths.length
|
||||
outOfProcessFinished = !outOfProcessPaths.length
|
||||
checkFinished = ->
|
||||
deferred.resolve() if outOfProcessFinished and inProcessFinished
|
||||
|
||||
unless outOfProcessFinished.length
|
||||
flags = 'g'
|
||||
flags += 'i' if regex.ignoreCase
|
||||
|
||||
task = Task.once require.resolve('./replace-handler'), outOfProcessPaths, regex.source, flags, replacementText, ->
|
||||
outOfProcessFinished = true
|
||||
checkFinished()
|
||||
|
||||
task.on 'replace:path-replaced', iterator
|
||||
|
||||
for buffer in @buffers
|
||||
replacements = buffer.replace(regex, replacementText, iterator)
|
||||
iterator({filePath: buffer.getPath(), replacements}) if replacements
|
||||
|
||||
inProcessFinished = true
|
||||
checkFinished()
|
||||
|
||||
deferred.promise
|
||||
|
||||
# Private:
|
||||
buildEditSessionForBuffer: (buffer, editSessionOptions) ->
|
||||
editSession = new EditSession(_.extend({buffer}, editSessionOptions))
|
||||
|
13
src/replace-handler.coffee
Normal file
13
src/replace-handler.coffee
Normal file
@ -0,0 +1,13 @@
|
||||
{PathReplacer} = require 'scandal'
|
||||
|
||||
module.exports = (filePaths, regexSource, regexFlags, replacementText) ->
|
||||
callback = @async()
|
||||
|
||||
replacer = new PathReplacer()
|
||||
regex = new RegExp(regexSource, regexFlags)
|
||||
|
||||
replacer.on 'path-replaced', (result) ->
|
||||
emit('replace:path-replaced', result)
|
||||
|
||||
replacer.replacePaths regex, replacementText, filePaths, ->
|
||||
callback()
|
@ -538,6 +538,25 @@ class TextBuffer
|
||||
result.lineTextOffset = 0
|
||||
iterator(result)
|
||||
|
||||
# Replace all matches of regex with replacementText
|
||||
#
|
||||
# regex: A {RegExp} representing the text to find
|
||||
# replacementText: A {String} representing the text to replace
|
||||
#
|
||||
# Returns the number of replacements made
|
||||
replace: (regex, replacementText) ->
|
||||
doSave = !@isModified()
|
||||
replacements = 0
|
||||
|
||||
@transact =>
|
||||
@scan regex, ({matchText, replace}) ->
|
||||
replace(matchText.replace(regex, replacementText))
|
||||
replacements++
|
||||
|
||||
@save() if doSave
|
||||
|
||||
replacements
|
||||
|
||||
# Scans for text in a given range, calling a function on each match.
|
||||
#
|
||||
# regex - A {RegExp} representing the text to find
|
||||
|
Loading…
Reference in New Issue
Block a user