From f6c565b83a8214c1c3864374f7660191ff1ccd55 Mon Sep 17 00:00:00 2001 From: Brent Date: Sun, 27 Aug 2017 11:12:31 -0400 Subject: [PATCH 1/8] results-model.coffee -> results-model.js --- lib/project/results-model.coffee | 283 ------------------------- lib/project/results-model.js | 343 +++++++++++++++++++++++++++++++ 2 files changed, 343 insertions(+), 283 deletions(-) delete mode 100644 lib/project/results-model.coffee create mode 100644 lib/project/results-model.js diff --git a/lib/project/results-model.coffee b/lib/project/results-model.coffee deleted file mode 100644 index 3169fa69..00000000 --- a/lib/project/results-model.coffee +++ /dev/null @@ -1,283 +0,0 @@ -_ = require 'underscore-plus' -{Emitter, TextEditor} = require 'atom' -escapeHelper = require '../escape-helper' - -class Result - @create: (result) -> - if result?.matches?.length - matches = result.matches.map((m) -> - return { - matchText: m.matchText, - lineText: m.lineText, - lineTextOffset: m.lineTextOffset, - range: m.range, - leadingContextLines: m.leadingContextLines, - trailingContextLines: m.trailingContextLines - } - ) - new Result({filePath: result.filePath, matches}) - else - null - - constructor: (result) -> - _.extend(this, result) - -module.exports = -class ResultsModel - constructor: (@findOptions) -> - @emitter = new Emitter - - atom.workspace.getCenter().observeActivePaneItem (item) => - if item instanceof TextEditor - item.onDidStopChanging => @onContentsModified(item) - - @clear() - - onDidClear: (callback) -> - @emitter.on 'did-clear', callback - - onDidClearSearchState: (callback) -> - @emitter.on 'did-clear-search-state', callback - - onDidClearReplacementState: (callback) -> - @emitter.on 'did-clear-replacement-state', callback - - onDidSearchPaths: (callback) -> - @emitter.on 'did-search-paths', callback - - onDidErrorForPath: (callback) -> - @emitter.on 'did-error-for-path', callback - - onDidNoopSearch: (callback) -> - @emitter.on 'did-noop-search', callback - - onDidStartSearching: (callback) -> - @emitter.on 'did-start-searching', callback - - onDidCancelSearching: (callback) -> - @emitter.on 'did-cancel-searching', callback - - onDidFinishSearching: (callback) -> - @emitter.on 'did-finish-searching', callback - - onDidStartReplacing: (callback) -> - @emitter.on 'did-start-replacing', callback - - onDidFinishReplacing: (callback) -> - @emitter.on 'did-finish-replacing', callback - - onDidSearchPath: (callback) -> - @emitter.on 'did-search-path', callback - - onDidReplacePath: (callback) -> - @emitter.on 'did-replace-path', callback - - onDidAddResult: (callback) -> - @emitter.on 'did-add-result', callback - - onDidRemoveResult: (callback) -> - @emitter.on 'did-remove-result', callback - - clear: -> - @clearSearchState() - @clearReplacementState() - @emitter.emit 'did-clear', @getResultsSummary() - - clearSearchState: -> - @pathCount = 0 - @matchCount = 0 - @regex = null - @results = {} - @paths = [] - @active = false - @searchErrors = null - - if @inProgressSearchPromise? - @inProgressSearchPromise.cancel() - @inProgressSearchPromise = null - - @emitter.emit 'did-clear-search-state', @getResultsSummary() - - clearReplacementState: -> - @replacePattern = null - @replacedPathCount = null - @replacementCount = null - @replacementErrors = null - @emitter.emit 'did-clear-replacement-state', @getResultsSummary() - - shouldRerunSearch: (findPattern, pathsPattern, replacePattern, options={}) -> - {onlyRunIfChanged} = options - if onlyRunIfChanged and findPattern? and pathsPattern? and findPattern is @lastFindPattern and pathsPattern is @lastPathsPattern - false - else - true - - search: (findPattern, pathsPattern, replacePattern, options={}) -> - unless @shouldRerunSearch(findPattern, pathsPattern, replacePattern, options) - @emitter.emit 'did-noop-search' - return Promise.resolve() - - {keepReplacementState} = options - if keepReplacementState - @clearSearchState() - else - @clear() - - @lastFindPattern = findPattern - @lastPathsPattern = pathsPattern - @findOptions.set(_.extend({findPattern, replacePattern, pathsPattern}, options)) - @regex = @findOptions.getFindPatternRegex() - - @active = true - searchPaths = @pathsArrayFromPathsPattern(pathsPattern) - - onPathsSearched = (numberOfPathsSearched) => - @emitter.emit 'did-search-paths', numberOfPathsSearched - - leadingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountBefore') - trailingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountAfter') - @inProgressSearchPromise = atom.workspace.scan @regex, {paths: searchPaths, onPathsSearched, leadingContextLineCount, trailingContextLineCount}, (result, error) => - if result - @setResult(result.filePath, Result.create(result)) - else - @searchErrors ?= [] - @searchErrors.push(error) - @emitter.emit 'did-error-for-path', error - - @emitter.emit 'did-start-searching', @inProgressSearchPromise - @inProgressSearchPromise.then (message) => - if message is 'cancelled' - @emitter.emit 'did-cancel-searching' - else - @inProgressSearchPromise = null - @emitter.emit 'did-finish-searching', @getResultsSummary() - - replace: (pathsPattern, replacePattern, replacementPaths) -> - return unless @findOptions.findPattern and @regex? - - @findOptions.set({replacePattern, pathsPattern}) - - replacePattern = escapeHelper.unescapeEscapeSequence(replacePattern) if @findOptions.useRegex - - @active = false # not active until the search is finished - @replacedPathCount = 0 - @replacementCount = 0 - - promise = atom.workspace.replace @regex, replacePattern, replacementPaths, (result, error) => - if result - if result.replacements - @replacedPathCount++ - @replacementCount += result.replacements - @emitter.emit 'did-replace-path', result - else - @replacementErrors ?= [] - @replacementErrors.push(error) - @emitter.emit 'did-error-for-path', error - - @emitter.emit 'did-start-replacing', promise - promise.then => - @emitter.emit 'did-finish-replacing', @getResultsSummary() - @search(@findOptions.findPattern, @findOptions.pathsPattern, @findOptions.replacePattern, {keepReplacementState: true}) - .catch (e) -> - console.error e.stack - - setActive: (isActive) -> - @active = isActive if (isActive and @findOptions.findPattern) or not isActive - - getActive: -> @active - - getFindOptions: -> @findOptions - - getLastFindPattern: -> @lastFindPattern - - getResultsSummary: -> - findPattern = @lastFindPattern ? @findOptions.findPattern - replacePattern = @findOptions.replacePattern - { - findPattern - replacePattern - @pathCount - @matchCount - @searchErrors - @replacedPathCount - @replacementCount - @replacementErrors - } - - getPathCount: -> - @pathCount - - getMatchCount: -> - @matchCount - - getPaths: -> - @paths - - getResult: (filePath) -> - @results[filePath] - - getResultAt: (index) -> - @results[@paths[index]] - - setResult: (filePath, result) -> - if result - @addResult(filePath, result) - else - @removeResult(filePath) - - addResult: (filePath, result) -> - filePathInsertedIndex = null - filePathUpdatedIndex = null - if @results[filePath] - @matchCount -= @results[filePath].matches.length - filePathUpdatedIndex = @paths.indexOf(filePath) - else - @pathCount++ - filePathInsertedIndex = binaryIndex(@paths, filePath, stringCompare) - @paths.splice(filePathInsertedIndex, 0, filePath) - - @matchCount += result.matches.length - - @results[filePath] = result - @emitter.emit 'did-add-result', {filePath, result, filePathInsertedIndex, filePathUpdatedIndex} - - removeResult: (filePath) -> - if @results[filePath] - @pathCount-- - @matchCount -= @results[filePath].matches.length - - filePathRemovedIndex = @paths.indexOf(filePath) - @paths = _.without(@paths, filePath) - delete @results[filePath] - @emitter.emit 'did-remove-result', {filePath, filePathRemovedIndex} - - onContentsModified: (editor) => - return unless @active and @regex - return unless editor.getPath() - - matches = [] - leadingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountBefore') - trailingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountAfter') - editor.scan @regex, {leadingContextLineCount, trailingContextLineCount}, (match) -> - matches.push(match) - - result = Result.create({filePath: editor.getPath(), matches}) - @setResult(editor.getPath(), result) - @emitter.emit 'did-finish-searching', @getResultsSummary() - - pathsArrayFromPathsPattern: (pathsPattern) -> - (inputPath.trim() for inputPath in pathsPattern.trim().split(',') when inputPath) - -stringCompare = (a, b) -> a.localeCompare(b) - -binaryIndex = (array, value, comparator) -> - # Lifted from underscore's _.sortedIndex ; adds a flexible comparator - low = 0 - high = array.length - while low < high - mid = Math.floor((low + high) / 2) - if comparator(array[mid], value) < 0 - low = mid + 1 - else - high = mid - low diff --git a/lib/project/results-model.js b/lib/project/results-model.js new file mode 100644 index 00000000..c6f7ed9d --- /dev/null +++ b/lib/project/results-model.js @@ -0,0 +1,343 @@ +let ResultsModel; +const _ = require('underscore-plus'); +const {Emitter, TextEditor} = require('atom'); +const escapeHelper = require('../escape-helper'); + +class Result { + static create(result) { + if (result && result.matches && result.matches.length) { + const matches = result.matches.map(m => + ({ + matchText: m.matchText, + lineText: m.lineText, + lineTextOffset: m.lineTextOffset, + range: m.range, + leadingContextLines: m.leadingContextLines, + trailingContextLines: m.trailingContextLines + }) + ); + return new Result({filePath: result.filePath, matches}); + } else { + return null; + } + } + + constructor(result) { + _.extend(this, result); + } +} + +module.exports = +(ResultsModel = class ResultsModel { + constructor(findOptions) { + this.onContentsModified = this.onContentsModified.bind(this); + this.findOptions = findOptions; + this.emitter = new Emitter; + + atom.workspace.getCenter().observeActivePaneItem(item => { + if (item instanceof TextEditor) { + return item.onDidStopChanging(() => this.onContentsModified(item)); + } + }); + + this.clear(); + } + + onDidClear(callback) { + return this.emitter.on('did-clear', callback); + } + + onDidClearSearchState(callback) { + return this.emitter.on('did-clear-search-state', callback); + } + + onDidClearReplacementState(callback) { + return this.emitter.on('did-clear-replacement-state', callback); + } + + onDidSearchPaths(callback) { + return this.emitter.on('did-search-paths', callback); + } + + onDidErrorForPath(callback) { + return this.emitter.on('did-error-for-path', callback); + } + + onDidNoopSearch(callback) { + return this.emitter.on('did-noop-search', callback); + } + + onDidStartSearching(callback) { + return this.emitter.on('did-start-searching', callback); + } + + onDidCancelSearching(callback) { + return this.emitter.on('did-cancel-searching', callback); + } + + onDidFinishSearching(callback) { + return this.emitter.on('did-finish-searching', callback); + } + + onDidStartReplacing(callback) { + return this.emitter.on('did-start-replacing', callback); + } + + onDidFinishReplacing(callback) { + return this.emitter.on('did-finish-replacing', callback); + } + + onDidSearchPath(callback) { + return this.emitter.on('did-search-path', callback); + } + + onDidReplacePath(callback) { + return this.emitter.on('did-replace-path', callback); + } + + onDidAddResult(callback) { + return this.emitter.on('did-add-result', callback); + } + + onDidRemoveResult(callback) { + return this.emitter.on('did-remove-result', callback); + } + + clear() { + this.clearSearchState(); + this.clearReplacementState(); + return this.emitter.emit('did-clear', this.getResultsSummary()); + } + + clearSearchState() { + this.pathCount = 0; + this.matchCount = 0; + this.regex = null; + this.results = {}; + this.paths = []; + this.active = false; + this.searchErrors = null; + + if (this.inProgressSearchPromise != null) { + this.inProgressSearchPromise.cancel(); + this.inProgressSearchPromise = null; + } + + return this.emitter.emit('did-clear-search-state', this.getResultsSummary()); + } + + clearReplacementState() { + this.replacePattern = null; + this.replacedPathCount = null; + this.replacementCount = null; + this.replacementErrors = null; + return this.emitter.emit('did-clear-replacement-state', this.getResultsSummary()); + } + + shouldRerunSearch(findPattern, pathsPattern, replacePattern, options) { + if (options == null) { options = {}; } + const {onlyRunIfChanged} = options; + return !(onlyRunIfChanged && (findPattern != null) && (pathsPattern != null) + && (findPattern === this.lastFindPattern) && (pathsPattern === this.lastPathsPattern)); + } + + search(findPattern, pathsPattern, replacePattern, options) { + if (options == null) { options = {}; } + if (!this.shouldRerunSearch(findPattern, pathsPattern, replacePattern, options)) { + this.emitter.emit('did-noop-search'); + return Promise.resolve(); + } + + const {keepReplacementState} = options; + if (keepReplacementState) { + this.clearSearchState(); + } else { + this.clear(); + } + + this.lastFindPattern = findPattern; + this.lastPathsPattern = pathsPattern; + this.findOptions.set(_.extend({findPattern, replacePattern, pathsPattern}, options)); + this.regex = this.findOptions.getFindPatternRegex(); + + this.active = true; + const searchPaths = this.pathsArrayFromPathsPattern(pathsPattern); + + const onPathsSearched = numberOfPathsSearched => { + return this.emitter.emit('did-search-paths', numberOfPathsSearched); + }; + + const leadingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountBefore'); + const trailingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountAfter'); + this.inProgressSearchPromise = atom.workspace.scan(this.regex, {paths: searchPaths, + onPathsSearched, leadingContextLineCount, trailingContextLineCount}, (result, error) => { + if (result) { + return this.setResult(result.filePath, Result.create(result)); + } else { + if (this.searchErrors == null) { this.searchErrors = []; } + this.searchErrors.push(error); + return this.emitter.emit('did-error-for-path', error); + } + }); + + this.emitter.emit('did-start-searching', this.inProgressSearchPromise); + return this.inProgressSearchPromise.then(message => { + if (message === 'cancelled') { + return this.emitter.emit('did-cancel-searching'); + } else { + this.inProgressSearchPromise = null; + return this.emitter.emit('did-finish-searching', this.getResultsSummary()); + } + }); + } + + replace(pathsPattern, replacePattern, replacementPaths) { + if (!this.findOptions.findPattern || (this.regex == null)) { return; } + + this.findOptions.set({replacePattern, pathsPattern}); + + if (this.findOptions.useRegex) { replacePattern = escapeHelper.unescapeEscapeSequence(replacePattern); } + + this.active = false; // not active until the search is finished + this.replacedPathCount = 0; + this.replacementCount = 0; + + const promise = atom.workspace.replace(this.regex, replacePattern, replacementPaths, (result, error) => { + if (result) { + if (result.replacements) { + this.replacedPathCount++; + this.replacementCount += result.replacements; + } + return this.emitter.emit('did-replace-path', result); + } else { + if (this.replacementErrors == null) { this.replacementErrors = []; } + this.replacementErrors.push(error); + return this.emitter.emit('did-error-for-path', error); + } + }); + + this.emitter.emit('did-start-replacing', promise); + return promise.then(() => { + this.emitter.emit('did-finish-replacing', this.getResultsSummary()); + return this.search(this.findOptions.findPattern, this.findOptions.pathsPattern, + this.findOptions.replacePattern, {keepReplacementState: true}); + }).catch(e => console.error(e.stack)); + } + + setActive(isActive) { + if ((isActive && this.findOptions.findPattern) || !isActive) { return this.active = isActive; } + } + + getActive() { return this.active; } + + getFindOptions() { return this.findOptions; } + + getLastFindPattern() { return this.lastFindPattern; } + + getResultsSummary() { + const findPattern = this.lastFindPattern != null ? this.lastFindPattern : this.findOptions.findPattern; + const { replacePattern } = this.findOptions; + return { + findPattern, + replacePattern, + pathCount: this.pathCount, + matchCount: this.matchCount, + searchErrors: this.searchErrors, + replacedPathCount: this.replacedPathCount, + replacementCount: this.replacementCount, + replacementErrors: this.replacementErrors + }; + } + + getPathCount() { + return this.pathCount; + } + + getMatchCount() { + return this.matchCount; + } + + getPaths() { + return this.paths; + } + + getResult(filePath) { + return this.results[filePath]; + } + + getResultAt(index) { + return this.results[this.paths[index]]; + } + + setResult(filePath, result) { + if (result) { + return this.addResult(filePath, result); + } else { + return this.removeResult(filePath); + } + } + + addResult(filePath, result) { + let filePathInsertedIndex = null; + let filePathUpdatedIndex = null; + if (this.results[filePath]) { + this.matchCount -= this.results[filePath].matches.length; + filePathUpdatedIndex = this.paths.indexOf(filePath); + } else { + this.pathCount++; + filePathInsertedIndex = binaryIndex(this.paths, filePath, stringCompare); + this.paths.splice(filePathInsertedIndex, 0, filePath); + } + + this.matchCount += result.matches.length; + + this.results[filePath] = result; + return this.emitter.emit('did-add-result', {filePath, result, filePathInsertedIndex, filePathUpdatedIndex}); + } + + removeResult(filePath) { + if (this.results[filePath]) { + this.pathCount--; + this.matchCount -= this.results[filePath].matches.length; + + const filePathRemovedIndex = this.paths.indexOf(filePath); + this.paths = _.without(this.paths, filePath); + delete this.results[filePath]; + return this.emitter.emit('did-remove-result', {filePath, filePathRemovedIndex}); + } + } + + onContentsModified(editor) { + if (!this.active || !this.regex || !editor.getPath()) { return; } + + const matches = []; + const leadingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountBefore'); + const trailingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountAfter'); + editor.scan(this.regex, {leadingContextLineCount, trailingContextLineCount}, match => matches.push(match)); + + const result = Result.create({filePath: editor.getPath(), matches}); + this.setResult(editor.getPath(), result); + return this.emitter.emit('did-finish-searching', this.getResultsSummary()); + } + + pathsArrayFromPathsPattern(pathsPattern) { + return pathsPattern.trim().split(',').map((inputPath) => inputPath.trim()); + } +}); + +var stringCompare = (a, b) => a.localeCompare(b); + +var binaryIndex = function(array, value, comparator) { + // Lifted from underscore's _.sortedIndex ; adds a flexible comparator + let low = 0; + let high = array.length; + while (low < high) { + const mid = Math.floor((low + high) / 2); + if (comparator(array[mid], value) < 0) { + low = mid + 1; + } else { + high = mid; + } + } + return low; +}; From b0766867a59f2caf412882d627409ca258c5c77f Mon Sep 17 00:00:00 2001 From: Brent Date: Sat, 2 Sep 2017 08:17:36 -0500 Subject: [PATCH 2/8] npm standard --fix the only command line output that I left is "atom undefined" --- lib/project/results-model.js | 373 ++++++++++++++++++----------------- 1 file changed, 188 insertions(+), 185 deletions(-) diff --git a/lib/project/results-model.js b/lib/project/results-model.js index c6f7ed9d..408fe001 100644 --- a/lib/project/results-model.js +++ b/lib/project/results-model.js @@ -1,10 +1,9 @@ -let ResultsModel; -const _ = require('underscore-plus'); -const {Emitter, TextEditor} = require('atom'); -const escapeHelper = require('../escape-helper'); +const _ = require('underscore-plus') +const {Emitter, TextEditor} = require('atom') +const escapeHelper = require('../escape-helper') class Result { - static create(result) { + static create (result) { if (result && result.matches && result.matches.length) { const matches = result.matches.map(m => ({ @@ -15,228 +14,232 @@ class Result { leadingContextLines: m.leadingContextLines, trailingContextLines: m.trailingContextLines }) - ); - return new Result({filePath: result.filePath, matches}); + ) + return new Result({filePath: result.filePath, matches}) } else { - return null; + return null } } - constructor(result) { - _.extend(this, result); + constructor (result) { + _.extend(this, result) } } -module.exports = -(ResultsModel = class ResultsModel { - constructor(findOptions) { - this.onContentsModified = this.onContentsModified.bind(this); - this.findOptions = findOptions; - this.emitter = new Emitter; +module.exports = class ResultsModel { + constructor (findOptions) { + this.onContentsModified = this.onContentsModified.bind(this) + this.findOptions = findOptions + this.emitter = new Emitter() atom.workspace.getCenter().observeActivePaneItem(item => { if (item instanceof TextEditor) { - return item.onDidStopChanging(() => this.onContentsModified(item)); + return item.onDidStopChanging(() => this.onContentsModified(item)) } - }); + }) - this.clear(); + this.clear() } - onDidClear(callback) { - return this.emitter.on('did-clear', callback); + onDidClear (callback) { + return this.emitter.on('did-clear', callback) } - onDidClearSearchState(callback) { - return this.emitter.on('did-clear-search-state', callback); + onDidClearSearchState (callback) { + return this.emitter.on('did-clear-search-state', callback) } - onDidClearReplacementState(callback) { - return this.emitter.on('did-clear-replacement-state', callback); + onDidClearReplacementState (callback) { + return this.emitter.on('did-clear-replacement-state', callback) } - onDidSearchPaths(callback) { - return this.emitter.on('did-search-paths', callback); + onDidSearchPaths (callback) { + return this.emitter.on('did-search-paths', callback) } - onDidErrorForPath(callback) { - return this.emitter.on('did-error-for-path', callback); + onDidErrorForPath (callback) { + return this.emitter.on('did-error-for-path', callback) } - onDidNoopSearch(callback) { - return this.emitter.on('did-noop-search', callback); + onDidNoopSearch (callback) { + return this.emitter.on('did-noop-search', callback) } - onDidStartSearching(callback) { - return this.emitter.on('did-start-searching', callback); + onDidStartSearching (callback) { + return this.emitter.on('did-start-searching', callback) } - onDidCancelSearching(callback) { - return this.emitter.on('did-cancel-searching', callback); + onDidCancelSearching (callback) { + return this.emitter.on('did-cancel-searching', callback) } - onDidFinishSearching(callback) { - return this.emitter.on('did-finish-searching', callback); + onDidFinishSearching (callback) { + return this.emitter.on('did-finish-searching', callback) } - onDidStartReplacing(callback) { - return this.emitter.on('did-start-replacing', callback); + onDidStartReplacing (callback) { + return this.emitter.on('did-start-replacing', callback) } - onDidFinishReplacing(callback) { - return this.emitter.on('did-finish-replacing', callback); + onDidFinishReplacing (callback) { + return this.emitter.on('did-finish-replacing', callback) } - onDidSearchPath(callback) { - return this.emitter.on('did-search-path', callback); + onDidSearchPath (callback) { + return this.emitter.on('did-search-path', callback) } - onDidReplacePath(callback) { - return this.emitter.on('did-replace-path', callback); + onDidReplacePath (callback) { + return this.emitter.on('did-replace-path', callback) } - onDidAddResult(callback) { - return this.emitter.on('did-add-result', callback); + onDidAddResult (callback) { + return this.emitter.on('did-add-result', callback) } - onDidRemoveResult(callback) { - return this.emitter.on('did-remove-result', callback); + onDidRemoveResult (callback) { + return this.emitter.on('did-remove-result', callback) } - clear() { - this.clearSearchState(); - this.clearReplacementState(); - return this.emitter.emit('did-clear', this.getResultsSummary()); + clear () { + this.clearSearchState() + this.clearReplacementState() + return this.emitter.emit('did-clear', this.getResultsSummary()) } - clearSearchState() { - this.pathCount = 0; - this.matchCount = 0; - this.regex = null; - this.results = {}; - this.paths = []; - this.active = false; - this.searchErrors = null; + clearSearchState () { + this.pathCount = 0 + this.matchCount = 0 + this.regex = null + this.results = {} + this.paths = [] + this.active = false + this.searchErrors = null if (this.inProgressSearchPromise != null) { - this.inProgressSearchPromise.cancel(); - this.inProgressSearchPromise = null; + this.inProgressSearchPromise.cancel() + this.inProgressSearchPromise = null } - return this.emitter.emit('did-clear-search-state', this.getResultsSummary()); + return this.emitter.emit('did-clear-search-state', this.getResultsSummary()) } - clearReplacementState() { - this.replacePattern = null; - this.replacedPathCount = null; - this.replacementCount = null; - this.replacementErrors = null; - return this.emitter.emit('did-clear-replacement-state', this.getResultsSummary()); + clearReplacementState () { + this.replacePattern = null + this.replacedPathCount = null + this.replacementCount = null + this.replacementErrors = null + return this.emitter.emit('did-clear-replacement-state', this.getResultsSummary()) } - shouldRerunSearch(findPattern, pathsPattern, replacePattern, options) { - if (options == null) { options = {}; } - const {onlyRunIfChanged} = options; - return !(onlyRunIfChanged && (findPattern != null) && (pathsPattern != null) - && (findPattern === this.lastFindPattern) && (pathsPattern === this.lastPathsPattern)); + shouldRerunSearch (findPattern, pathsPattern, replacePattern, options) { + if (options == null) { options = {} } + const {onlyRunIfChanged} = options + return !(onlyRunIfChanged && (findPattern != null) && (pathsPattern != null) && + (findPattern === this.lastFindPattern) && (pathsPattern === this.lastPathsPattern)) } - search(findPattern, pathsPattern, replacePattern, options) { - if (options == null) { options = {}; } + search (findPattern, pathsPattern, replacePattern, options) { + if (options == null) { options = {} } if (!this.shouldRerunSearch(findPattern, pathsPattern, replacePattern, options)) { - this.emitter.emit('did-noop-search'); - return Promise.resolve(); + this.emitter.emit('did-noop-search') + return Promise.resolve() } - const {keepReplacementState} = options; + const {keepReplacementState} = options if (keepReplacementState) { - this.clearSearchState(); + this.clearSearchState() } else { - this.clear(); + this.clear() } - this.lastFindPattern = findPattern; - this.lastPathsPattern = pathsPattern; - this.findOptions.set(_.extend({findPattern, replacePattern, pathsPattern}, options)); - this.regex = this.findOptions.getFindPatternRegex(); + this.lastFindPattern = findPattern + this.lastPathsPattern = pathsPattern + this.findOptions.set(_.extend({findPattern, replacePattern, pathsPattern}, options)) + this.regex = this.findOptions.getFindPatternRegex() - this.active = true; - const searchPaths = this.pathsArrayFromPathsPattern(pathsPattern); + this.active = true + const searchPaths = this.pathsArrayFromPathsPattern(pathsPattern) const onPathsSearched = numberOfPathsSearched => { - return this.emitter.emit('did-search-paths', numberOfPathsSearched); - }; + return this.emitter.emit('did-search-paths', numberOfPathsSearched) + } - const leadingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountBefore'); - const trailingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountAfter'); + const leadingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountBefore') + const trailingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountAfter') this.inProgressSearchPromise = atom.workspace.scan(this.regex, {paths: searchPaths, - onPathsSearched, leadingContextLineCount, trailingContextLineCount}, (result, error) => { - if (result) { - return this.setResult(result.filePath, Result.create(result)); - } else { - if (this.searchErrors == null) { this.searchErrors = []; } - this.searchErrors.push(error); - return this.emitter.emit('did-error-for-path', error); - } - }); + onPathsSearched, + leadingContextLineCount, + trailingContextLineCount}, (result, error) => { + if (result) { + return this.setResult(result.filePath, Result.create(result)) + } else { + if (this.searchErrors == null) { this.searchErrors = [] } + this.searchErrors.push(error) + return this.emitter.emit('did-error-for-path', error) + } + }) - this.emitter.emit('did-start-searching', this.inProgressSearchPromise); + this.emitter.emit('did-start-searching', this.inProgressSearchPromise) return this.inProgressSearchPromise.then(message => { if (message === 'cancelled') { - return this.emitter.emit('did-cancel-searching'); + return this.emitter.emit('did-cancel-searching') } else { - this.inProgressSearchPromise = null; - return this.emitter.emit('did-finish-searching', this.getResultsSummary()); + this.inProgressSearchPromise = null + return this.emitter.emit('did-finish-searching', this.getResultsSummary()) } - }); + }) } - replace(pathsPattern, replacePattern, replacementPaths) { - if (!this.findOptions.findPattern || (this.regex == null)) { return; } + replace (pathsPattern, replacePattern, replacementPaths) { + if (!this.findOptions.findPattern || (this.regex == null)) { return } - this.findOptions.set({replacePattern, pathsPattern}); + this.findOptions.set({replacePattern, pathsPattern}) - if (this.findOptions.useRegex) { replacePattern = escapeHelper.unescapeEscapeSequence(replacePattern); } + if (this.findOptions.useRegex) { replacePattern = escapeHelper.unescapeEscapeSequence(replacePattern) } - this.active = false; // not active until the search is finished - this.replacedPathCount = 0; - this.replacementCount = 0; + this.active = false // not active until the search is finished + this.replacedPathCount = 0 + this.replacementCount = 0 const promise = atom.workspace.replace(this.regex, replacePattern, replacementPaths, (result, error) => { if (result) { if (result.replacements) { - this.replacedPathCount++; - this.replacementCount += result.replacements; + this.replacedPathCount++ + this.replacementCount += result.replacements } - return this.emitter.emit('did-replace-path', result); + return this.emitter.emit('did-replace-path', result) } else { - if (this.replacementErrors == null) { this.replacementErrors = []; } - this.replacementErrors.push(error); - return this.emitter.emit('did-error-for-path', error); + if (this.replacementErrors == null) { this.replacementErrors = [] } + this.replacementErrors.push(error) + return this.emitter.emit('did-error-for-path', error) } - }); + }) - this.emitter.emit('did-start-replacing', promise); + this.emitter.emit('did-start-replacing', promise) return promise.then(() => { - this.emitter.emit('did-finish-replacing', this.getResultsSummary()); + this.emitter.emit('did-finish-replacing', this.getResultsSummary()) return this.search(this.findOptions.findPattern, this.findOptions.pathsPattern, - this.findOptions.replacePattern, {keepReplacementState: true}); - }).catch(e => console.error(e.stack)); + this.findOptions.replacePattern, {keepReplacementState: true}) + }).catch(e => console.error(e.stack)) } - setActive(isActive) { - if ((isActive && this.findOptions.findPattern) || !isActive) { return this.active = isActive; } + setActive (isActive) { + if ((isActive && this.findOptions.findPattern) || !isActive) { + this.active = isActive + return isActive + } } - getActive() { return this.active; } + getActive () { return this.active } - getFindOptions() { return this.findOptions; } + getFindOptions () { return this.findOptions } - getLastFindPattern() { return this.lastFindPattern; } + getLastFindPattern () { return this.lastFindPattern } - getResultsSummary() { - const findPattern = this.lastFindPattern != null ? this.lastFindPattern : this.findOptions.findPattern; - const { replacePattern } = this.findOptions; + getResultsSummary () { + const findPattern = this.lastFindPattern != null ? this.lastFindPattern : this.findOptions.findPattern + const { replacePattern } = this.findOptions return { findPattern, replacePattern, @@ -246,98 +249,98 @@ module.exports = replacedPathCount: this.replacedPathCount, replacementCount: this.replacementCount, replacementErrors: this.replacementErrors - }; + } } - getPathCount() { - return this.pathCount; + getPathCount () { + return this.pathCount } - getMatchCount() { - return this.matchCount; + getMatchCount () { + return this.matchCount } - getPaths() { - return this.paths; + getPaths () { + return this.paths } - getResult(filePath) { - return this.results[filePath]; + getResult (filePath) { + return this.results[filePath] } - getResultAt(index) { - return this.results[this.paths[index]]; + getResultAt (index) { + return this.results[this.paths[index]] } - setResult(filePath, result) { + setResult (filePath, result) { if (result) { - return this.addResult(filePath, result); + return this.addResult(filePath, result) } else { - return this.removeResult(filePath); + return this.removeResult(filePath) } } - addResult(filePath, result) { - let filePathInsertedIndex = null; - let filePathUpdatedIndex = null; + addResult (filePath, result) { + let filePathInsertedIndex = null + let filePathUpdatedIndex = null if (this.results[filePath]) { - this.matchCount -= this.results[filePath].matches.length; - filePathUpdatedIndex = this.paths.indexOf(filePath); + this.matchCount -= this.results[filePath].matches.length + filePathUpdatedIndex = this.paths.indexOf(filePath) } else { - this.pathCount++; - filePathInsertedIndex = binaryIndex(this.paths, filePath, stringCompare); - this.paths.splice(filePathInsertedIndex, 0, filePath); + this.pathCount++ + filePathInsertedIndex = binaryIndex(this.paths, filePath, stringCompare) + this.paths.splice(filePathInsertedIndex, 0, filePath) } - this.matchCount += result.matches.length; + this.matchCount += result.matches.length - this.results[filePath] = result; - return this.emitter.emit('did-add-result', {filePath, result, filePathInsertedIndex, filePathUpdatedIndex}); + this.results[filePath] = result + return this.emitter.emit('did-add-result', {filePath, result, filePathInsertedIndex, filePathUpdatedIndex}) } - removeResult(filePath) { + removeResult (filePath) { if (this.results[filePath]) { - this.pathCount--; - this.matchCount -= this.results[filePath].matches.length; + this.pathCount-- + this.matchCount -= this.results[filePath].matches.length - const filePathRemovedIndex = this.paths.indexOf(filePath); - this.paths = _.without(this.paths, filePath); - delete this.results[filePath]; - return this.emitter.emit('did-remove-result', {filePath, filePathRemovedIndex}); + const filePathRemovedIndex = this.paths.indexOf(filePath) + this.paths = _.without(this.paths, filePath) + delete this.results[filePath] + return this.emitter.emit('did-remove-result', {filePath, filePathRemovedIndex}) } } - onContentsModified(editor) { - if (!this.active || !this.regex || !editor.getPath()) { return; } + onContentsModified (editor) { + if (!this.active || !this.regex || !editor.getPath()) { return } - const matches = []; - const leadingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountBefore'); - const trailingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountAfter'); - editor.scan(this.regex, {leadingContextLineCount, trailingContextLineCount}, match => matches.push(match)); + const matches = [] + const leadingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountBefore') + const trailingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountAfter') + editor.scan(this.regex, {leadingContextLineCount, trailingContextLineCount}, match => matches.push(match)) - const result = Result.create({filePath: editor.getPath(), matches}); - this.setResult(editor.getPath(), result); - return this.emitter.emit('did-finish-searching', this.getResultsSummary()); + const result = Result.create({filePath: editor.getPath(), matches}) + this.setResult(editor.getPath(), result) + return this.emitter.emit('did-finish-searching', this.getResultsSummary()) } - pathsArrayFromPathsPattern(pathsPattern) { - return pathsPattern.trim().split(',').map((inputPath) => inputPath.trim()); + pathsArrayFromPathsPattern (pathsPattern) { + return pathsPattern.trim().split(',').map((inputPath) => inputPath.trim()) } -}); +} -var stringCompare = (a, b) => a.localeCompare(b); +var stringCompare = (a, b) => a.localeCompare(b) -var binaryIndex = function(array, value, comparator) { +var binaryIndex = function (array, value, comparator) { // Lifted from underscore's _.sortedIndex ; adds a flexible comparator - let low = 0; - let high = array.length; + let low = 0 + let high = array.length while (low < high) { - const mid = Math.floor((low + high) / 2); + const mid = Math.floor((low + high) / 2) if (comparator(array[mid], value) < 0) { - low = mid + 1; + low = mid + 1 } else { - high = mid; + high = mid } } - return low; -}; + return low +} From 5d18365cceac9a66487dd449a30a9025d994e508 Mon Sep 17 00:00:00 2001 From: Jason Rudolph Date: Tue, 5 Sep 2017 09:17:40 -0400 Subject: [PATCH 3/8] :art: Tweak formatting of long argument list --- lib/project/results-model.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/project/results-model.js b/lib/project/results-model.js index 408fe001..053e651d 100644 --- a/lib/project/results-model.js +++ b/lib/project/results-model.js @@ -167,10 +167,15 @@ module.exports = class ResultsModel { const leadingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountBefore') const trailingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountAfter') - this.inProgressSearchPromise = atom.workspace.scan(this.regex, {paths: searchPaths, - onPathsSearched, - leadingContextLineCount, - trailingContextLineCount}, (result, error) => { + this.inProgressSearchPromise = atom.workspace.scan( + this.regex, + { + paths: searchPaths, + onPathsSearched, + leadingContextLineCount, + trailingContextLineCount + }, + (result, error) => { if (result) { return this.setResult(result.filePath, Result.create(result)) } else { From f078cdc976e996841ae7fae30cafa0e2c4167f4f Mon Sep 17 00:00:00 2001 From: Jason Rudolph Date: Tue, 5 Sep 2017 09:22:13 -0400 Subject: [PATCH 4/8] :art: Tweak formatting of long argument list --- lib/project/results-model.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/project/results-model.js b/lib/project/results-model.js index 053e651d..a47cf3b2 100644 --- a/lib/project/results-model.js +++ b/lib/project/results-model.js @@ -321,7 +321,10 @@ module.exports = class ResultsModel { const matches = [] const leadingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountBefore') const trailingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountAfter') - editor.scan(this.regex, {leadingContextLineCount, trailingContextLineCount}, match => matches.push(match)) + editor.scan(this.regex, + {leadingContextLineCount, trailingContextLineCount}, + (match) => matches.push(match) + ) const result = Result.create({filePath: editor.getPath(), matches}) this.setResult(editor.getPath(), result) From e69742463aff69da4c4d5e4f0201d3e507aba624 Mon Sep 17 00:00:00 2001 From: Jason Rudolph Date: Tue, 5 Sep 2017 09:09:33 -0400 Subject: [PATCH 5/8] Remove unnecessary return statement --- lib/project/results-model.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/project/results-model.js b/lib/project/results-model.js index a47cf3b2..32777ea5 100644 --- a/lib/project/results-model.js +++ b/lib/project/results-model.js @@ -34,7 +34,7 @@ module.exports = class ResultsModel { atom.workspace.getCenter().observeActivePaneItem(item => { if (item instanceof TextEditor) { - return item.onDidStopChanging(() => this.onContentsModified(item)) + item.onDidStopChanging(() => this.onContentsModified(item)) } }) From f79d1bab09490bec485972cf38936ce607848693 Mon Sep 17 00:00:00 2001 From: Jason Rudolph Date: Tue, 5 Sep 2017 09:11:37 -0400 Subject: [PATCH 6/8] Remove unnecessary return statements re: Emitter::emit --- lib/project/results-model.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/project/results-model.js b/lib/project/results-model.js index 32777ea5..675c4502 100644 --- a/lib/project/results-model.js +++ b/lib/project/results-model.js @@ -104,7 +104,7 @@ module.exports = class ResultsModel { clear () { this.clearSearchState() this.clearReplacementState() - return this.emitter.emit('did-clear', this.getResultsSummary()) + this.emitter.emit('did-clear', this.getResultsSummary()) } clearSearchState () { @@ -121,7 +121,7 @@ module.exports = class ResultsModel { this.inProgressSearchPromise = null } - return this.emitter.emit('did-clear-search-state', this.getResultsSummary()) + this.emitter.emit('did-clear-search-state', this.getResultsSummary()) } clearReplacementState () { @@ -129,7 +129,7 @@ module.exports = class ResultsModel { this.replacedPathCount = null this.replacementCount = null this.replacementErrors = null - return this.emitter.emit('did-clear-replacement-state', this.getResultsSummary()) + this.emitter.emit('did-clear-replacement-state', this.getResultsSummary()) } shouldRerunSearch (findPattern, pathsPattern, replacePattern, options) { @@ -162,7 +162,7 @@ module.exports = class ResultsModel { const searchPaths = this.pathsArrayFromPathsPattern(pathsPattern) const onPathsSearched = numberOfPathsSearched => { - return this.emitter.emit('did-search-paths', numberOfPathsSearched) + this.emitter.emit('did-search-paths', numberOfPathsSearched) } const leadingContextLineCount = atom.config.get('find-and-replace.searchContextLineCountBefore') @@ -181,17 +181,17 @@ module.exports = class ResultsModel { } else { if (this.searchErrors == null) { this.searchErrors = [] } this.searchErrors.push(error) - return this.emitter.emit('did-error-for-path', error) + this.emitter.emit('did-error-for-path', error) } }) this.emitter.emit('did-start-searching', this.inProgressSearchPromise) return this.inProgressSearchPromise.then(message => { if (message === 'cancelled') { - return this.emitter.emit('did-cancel-searching') + this.emitter.emit('did-cancel-searching') } else { this.inProgressSearchPromise = null - return this.emitter.emit('did-finish-searching', this.getResultsSummary()) + this.emitter.emit('did-finish-searching', this.getResultsSummary()) } }) } @@ -213,11 +213,11 @@ module.exports = class ResultsModel { this.replacedPathCount++ this.replacementCount += result.replacements } - return this.emitter.emit('did-replace-path', result) + this.emitter.emit('did-replace-path', result) } else { if (this.replacementErrors == null) { this.replacementErrors = [] } this.replacementErrors.push(error) - return this.emitter.emit('did-error-for-path', error) + this.emitter.emit('did-error-for-path', error) } }) @@ -300,7 +300,7 @@ module.exports = class ResultsModel { this.matchCount += result.matches.length this.results[filePath] = result - return this.emitter.emit('did-add-result', {filePath, result, filePathInsertedIndex, filePathUpdatedIndex}) + this.emitter.emit('did-add-result', {filePath, result, filePathInsertedIndex, filePathUpdatedIndex}) } removeResult (filePath) { @@ -311,7 +311,7 @@ module.exports = class ResultsModel { const filePathRemovedIndex = this.paths.indexOf(filePath) this.paths = _.without(this.paths, filePath) delete this.results[filePath] - return this.emitter.emit('did-remove-result', {filePath, filePathRemovedIndex}) + this.emitter.emit('did-remove-result', {filePath, filePathRemovedIndex}) } } @@ -328,7 +328,7 @@ module.exports = class ResultsModel { const result = Result.create({filePath: editor.getPath(), matches}) this.setResult(editor.getPath(), result) - return this.emitter.emit('did-finish-searching', this.getResultsSummary()) + this.emitter.emit('did-finish-searching', this.getResultsSummary()) } pathsArrayFromPathsPattern (pathsPattern) { From acc548426d26f38b9c6dbafb92b884f6de00d1b8 Mon Sep 17 00:00:00 2001 From: Jason Rudolph Date: Tue, 5 Sep 2017 09:19:43 -0400 Subject: [PATCH 7/8] Remove unnecessary return statement --- lib/project/results-model.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/project/results-model.js b/lib/project/results-model.js index 675c4502..f14a1534 100644 --- a/lib/project/results-model.js +++ b/lib/project/results-model.js @@ -232,7 +232,6 @@ module.exports = class ResultsModel { setActive (isActive) { if ((isActive && this.findOptions.findPattern) || !isActive) { this.active = isActive - return isActive } } From 478d93d0c2951315c1263e7fb85d7e3a16b4a04b Mon Sep 17 00:00:00 2001 From: Jason Rudolph Date: Tue, 5 Sep 2017 09:20:56 -0400 Subject: [PATCH 8/8] Remove unnecessary return statements in ::setResult() --- lib/project/results-model.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/project/results-model.js b/lib/project/results-model.js index f14a1534..72cd63aa 100644 --- a/lib/project/results-model.js +++ b/lib/project/results-model.js @@ -177,7 +177,7 @@ module.exports = class ResultsModel { }, (result, error) => { if (result) { - return this.setResult(result.filePath, Result.create(result)) + this.setResult(result.filePath, Result.create(result)) } else { if (this.searchErrors == null) { this.searchErrors = [] } this.searchErrors.push(error) @@ -278,9 +278,9 @@ module.exports = class ResultsModel { setResult (filePath, result) { if (result) { - return this.addResult(filePath, result) + this.addResult(filePath, result) } else { - return this.removeResult(filePath) + this.removeResult(filePath) } }