Merge branch 'master' into as-snapshot-atom-environment

This commit is contained in:
Antonio Scandurra
2017-03-16 21:08:41 +01:00
17 changed files with 189 additions and 163 deletions

View File

@@ -137,6 +137,7 @@
{ label: 'Open In &Dev Mode…', command: 'application:open-dev' }
{ label: '&Reload Window', command: 'window:reload' }
{ label: 'Run Package &Specs', command: 'window:run-package-specs' }
{ label: 'Run &Benchmarks', command: 'window:run-benchmarks' }
{ label: 'Toggle Developer &Tools', command: 'window:toggle-dev-tools' }
]
}

View File

@@ -136,6 +136,7 @@
{ label: 'Open In &Dev Mode…', command: 'application:open-dev' }
{ label: '&Reload Window', command: 'window:reload' }
{ label: 'Run Package &Specs', command: 'window:run-package-specs' }
{ label: 'Run &Benchmarks', command: 'window:run-benchmarks' }
{ label: 'Toggle Developer &Tools', command: 'window:toggle-dev-tools' }
]
}

View File

@@ -12,7 +12,7 @@
"url": "https://github.com/atom/atom/issues"
},
"license": "MIT",
"electronVersion": "1.3.13",
"electronVersion": "1.3.14",
"dependencies": {
"async": "0.2.6",
"atom-keymap": "8.0.2",
@@ -68,16 +68,16 @@
"random-words": "0.0.1",
"resolve": "^1.1.6",
"runas": "^3.1",
"scandal": "^3.0.0",
"scandal": "^3.1.0",
"scoped-property-store": "^0.17.0",
"scrollbar-style": "^3.2",
"season": "^6.0.0",
"semver": "^4.3.3",
"service-hub": "^0.7.2",
"service-hub": "^0.7.3",
"sinon": "1.17.4",
"source-map-support": "^0.3.2",
"temp": "0.8.1",
"text-buffer": "11.3.0",
"text-buffer": "11.4.0",
"typescript-simple": "1.0.0",
"underscore-plus": "^1.6.6",
"winreg": "^1.2.1",
@@ -98,10 +98,10 @@
"solarized-light-syntax": "1.1.2",
"about": "1.7.5",
"archive-view": "0.63.1",
"autocomplete-atom-api": "0.10.0",
"autocomplete-css": "0.15.1",
"autocomplete-html": "0.7.2",
"autocomplete-plus": "2.34.2",
"autocomplete-atom-api": "0.10.1",
"autocomplete-css": "0.15.2",
"autocomplete-html": "0.7.3",
"autocomplete-plus": "2.35.0",
"autocomplete-snippets": "1.11.0",
"autoflow": "0.29.0",
"autosave": "0.24.1",
@@ -114,13 +114,13 @@
"dev-live-reload": "0.47.1",
"encoding-selector": "0.23.2",
"exception-reporting": "0.41.3",
"find-and-replace": "0.207.2",
"find-and-replace": "0.207.3",
"fuzzy-finder": "1.5.1",
"git-diff": "1.3.4",
"go-to-line": "0.32.0",
"grammar-selector": "0.49.3",
"image-view": "0.61.2",
"incompatible-packages": "0.27.1",
"incompatible-packages": "0.27.2",
"keybinding-resolver": "0.36.4",
"line-ending-selector": "0.6.2",
"link": "0.31.3",

View File

@@ -10,7 +10,7 @@ const spawnSync = require('./spawn-sync')
const CONFIG = require('../config')
module.exports = function (packagedAppPath, codeSign) {
module.exports = (packagedAppPath, codeSign) => {
const archSuffix = process.arch === 'ia32' ? '' : '-' + process.arch
const options = {
appDirectory: packagedAppPath,
@@ -23,7 +23,7 @@ module.exports = function (packagedAppPath, codeSign) {
}
const signing = codeSign && (process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL || process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH)
let certPath = process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH;
let certPath = process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH
if (signing) {
if (!certPath) {
@@ -42,7 +42,7 @@ module.exports = function (packagedAppPath, codeSign) {
console.log('Skipping code-signing. Specify the --code-sign option and provide a ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL environment variable to perform code-signing'.gray)
}
const cleanUp = function () {
const cleanUp = () => {
if (fs.existsSync(certPath) && !process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH) {
console.log(`Deleting certificate at ${certPath}`)
fs.removeSync(certPath)
@@ -57,7 +57,7 @@ module.exports = function (packagedAppPath, codeSign) {
}
// Squirrel signs its own copy of the executables but we need them for the portable ZIP
const extractSignedExes = function() {
const extractSignedExes = () => {
if (signing) {
for (let nupkgPath of glob.sync(`${CONFIG.buildOutputPath}/*-full.nupkg`)) {
if (nupkgPath.includes(CONFIG.appMetadata.version)) {
@@ -73,12 +73,9 @@ module.exports = function (packagedAppPath, codeSign) {
console.log(`Creating Windows Installer for ${packagedAppPath}`)
return electronInstaller.createWindowsInstaller(options)
.then(extractSignedExes, function (error) {
console.log(`Extracting signed executables failed:\n${error}`)
cleanUp()
})
.then(cleanUp, function (error) {
console.log(`Windows installer creation failed:\n${error}`)
.then(extractSignedExes)
.then(cleanUp, error => {
cleanUp()
return Promise.reject(error)
})
}

View File

@@ -5,7 +5,7 @@ const path = require('path')
const syncRequest = require('sync-request')
module.exports = function (downloadURL, destinationPath) {
console.log(`Dowloading file from GitHub Repository to ${destinationPath}`)
console.log(`Downloading file from GitHub Repository to ${destinationPath}`)
const response = syncRequest('GET', downloadURL, {
'headers': {'Accept': 'application/vnd.github.v3.raw', 'User-Agent': 'Atom Build'}
})

View File

@@ -14,79 +14,75 @@ describe "FileSystemBlobStore", ->
fs.removeSync(storageDirectory)
it "is empty when the file doesn't exist", ->
expect(blobStore.get("foo", "invalidation-key-1")).toBeUndefined()
expect(blobStore.get("bar", "invalidation-key-2")).toBeUndefined()
expect(blobStore.get("foo")).toBeUndefined()
expect(blobStore.get("bar")).toBeUndefined()
it "allows to read and write buffers from/to memory without persisting them", ->
blobStore.set("foo", "invalidation-key-1", new Buffer("foo"))
blobStore.set("bar", "invalidation-key-2", new Buffer("bar"))
blobStore.set("foo", new Buffer("foo"))
blobStore.set("bar", new Buffer("bar"))
expect(blobStore.get("foo", "invalidation-key-1")).toEqual(new Buffer("foo"))
expect(blobStore.get("bar", "invalidation-key-2")).toEqual(new Buffer("bar"))
expect(blobStore.get("foo")).toEqual(new Buffer("foo"))
expect(blobStore.get("bar")).toEqual(new Buffer("bar"))
expect(blobStore.get("foo", "unexisting-key")).toBeUndefined()
expect(blobStore.get("bar", "unexisting-key")).toBeUndefined()
expect(blobStore.get("baz")).toBeUndefined()
expect(blobStore.get("qux")).toBeUndefined()
it "persists buffers when saved and retrieves them on load, giving priority to in-memory ones", ->
blobStore.set("foo", "invalidation-key-1", new Buffer("foo"))
blobStore.set("bar", "invalidation-key-2", new Buffer("bar"))
blobStore.set("foo", new Buffer("foo"))
blobStore.set("bar", new Buffer("bar"))
blobStore.save()
blobStore = FileSystemBlobStore.load(storageDirectory)
expect(blobStore.get("foo", "invalidation-key-1")).toEqual(new Buffer("foo"))
expect(blobStore.get("bar", "invalidation-key-2")).toEqual(new Buffer("bar"))
expect(blobStore.get("foo", "unexisting-key")).toBeUndefined()
expect(blobStore.get("bar", "unexisting-key")).toBeUndefined()
expect(blobStore.get("foo")).toEqual(new Buffer("foo"))
expect(blobStore.get("bar")).toEqual(new Buffer("bar"))
expect(blobStore.get("baz")).toBeUndefined()
expect(blobStore.get("qux")).toBeUndefined()
blobStore.set("foo", "new-key", new Buffer("changed"))
blobStore.set("foo", new Buffer("changed"))
expect(blobStore.get("foo", "new-key")).toEqual(new Buffer("changed"))
expect(blobStore.get("foo", "invalidation-key-1")).toBeUndefined()
expect(blobStore.get("foo")).toEqual(new Buffer("changed"))
it "persists in-memory and previously stored buffers, and deletes unused keys when saved", ->
blobStore.set("foo", "invalidation-key-1", new Buffer("foo"))
blobStore.set("bar", "invalidation-key-2", new Buffer("bar"))
blobStore.set("foo", new Buffer("foo"))
blobStore.set("bar", new Buffer("bar"))
blobStore.save()
blobStore = FileSystemBlobStore.load(storageDirectory)
blobStore.set("bar", "invalidation-key-3", new Buffer("changed"))
blobStore.set("qux", "invalidation-key-4", new Buffer("qux"))
blobStore.set("bar", new Buffer("changed"))
blobStore.set("qux", new Buffer("qux"))
blobStore.save()
blobStore = FileSystemBlobStore.load(storageDirectory)
expect(blobStore.get("foo", "invalidation-key-1")).toBeUndefined()
expect(blobStore.get("bar", "invalidation-key-3")).toEqual(new Buffer("changed"))
expect(blobStore.get("qux", "invalidation-key-4")).toEqual(new Buffer("qux"))
expect(blobStore.get("foo", "unexisting-key")).toBeUndefined()
expect(blobStore.get("bar", "invalidation-key-2")).toBeUndefined()
expect(blobStore.get("qux", "unexisting-key")).toBeUndefined()
expect(blobStore.get("foo")).toBeUndefined()
expect(blobStore.get("bar")).toEqual(new Buffer("changed"))
expect(blobStore.get("qux")).toEqual(new Buffer("qux"))
it "allows to delete keys from both memory and stored buffers", ->
blobStore.set("a", "invalidation-key-1", new Buffer("a"))
blobStore.set("b", "invalidation-key-2", new Buffer("b"))
blobStore.set("a", new Buffer("a"))
blobStore.set("b", new Buffer("b"))
blobStore.save()
blobStore = FileSystemBlobStore.load(storageDirectory)
blobStore.get("a", "invalidation-key-1") # prevent the key from being deleted on save
blobStore.set("b", "invalidation-key-3", new Buffer("b"))
blobStore.set("c", "invalidation-key-4", new Buffer("c"))
blobStore.get("a") # prevent the key from being deleted on save
blobStore.set("b", new Buffer("b"))
blobStore.set("c", new Buffer("c"))
blobStore.delete("b")
blobStore.delete("c")
blobStore.save()
blobStore = FileSystemBlobStore.load(storageDirectory)
expect(blobStore.get("a", "invalidation-key-1")).toEqual(new Buffer("a"))
expect(blobStore.get("b", "invalidation-key-2")).toBeUndefined()
expect(blobStore.get("b", "invalidation-key-3")).toBeUndefined()
expect(blobStore.get("c", "invalidation-key-4")).toBeUndefined()
expect(blobStore.get("a")).toEqual(new Buffer("a"))
expect(blobStore.get("b")).toBeUndefined()
expect(blobStore.get("b")).toBeUndefined()
expect(blobStore.get("c")).toBeUndefined()
it "ignores errors when loading an invalid blob store", ->
blobStore.set("a", "invalidation-key-1", new Buffer("a"))
blobStore.set("b", "invalidation-key-2", new Buffer("b"))
blobStore.set("a", new Buffer("a"))
blobStore.set("b", new Buffer("b"))
blobStore.save()
# Simulate corruption
@@ -96,14 +92,14 @@ describe "FileSystemBlobStore", ->
blobStore = FileSystemBlobStore.load(storageDirectory)
expect(blobStore.get("a", "invalidation-key-1")).toBeUndefined()
expect(blobStore.get("b", "invalidation-key-2")).toBeUndefined()
expect(blobStore.get("a")).toBeUndefined()
expect(blobStore.get("b")).toBeUndefined()
blobStore.set("a", "invalidation-key-1", new Buffer("x"))
blobStore.set("b", "invalidation-key-2", new Buffer("y"))
blobStore.set("a", new Buffer("x"))
blobStore.set("b", new Buffer("y"))
blobStore.save()
blobStore = FileSystemBlobStore.load(storageDirectory)
expect(blobStore.get("a", "invalidation-key-1")).toEqual(new Buffer("x"))
expect(blobStore.get("b", "invalidation-key-2")).toEqual(new Buffer("y"))
expect(blobStore.get("a")).toEqual(new Buffer("x"))
expect(blobStore.get("b")).toEqual(new Buffer("y"))

View File

@@ -9,16 +9,18 @@ describe "NativeCompileCache", ->
beforeEach ->
cachedFiles = []
fakeCacheStore = jasmine.createSpyObj("cache store", ["set", "get", "has", "delete"])
fakeCacheStore.has.andCallFake (cacheKey, invalidationKey) ->
fakeCacheStore.get(cacheKey, invalidationKey)?
fakeCacheStore.get.andCallFake (cacheKey, invalidationKey) ->
fakeCacheStore.has.andCallFake (cacheKey) ->
fakeCacheStore.get(cacheKey)?
fakeCacheStore.get.andCallFake (cacheKey) ->
for entry in cachedFiles by -1
continue if entry.cacheKey isnt cacheKey
continue if entry.invalidationKey isnt invalidationKey
return entry.cacheBuffer
return
fakeCacheStore.set.andCallFake (cacheKey, invalidationKey, cacheBuffer) ->
cachedFiles.push({cacheKey, invalidationKey, cacheBuffer})
fakeCacheStore.set.andCallFake (cacheKey, cacheBuffer) ->
cachedFiles.push({cacheKey, cacheBuffer})
nativeCompileCache.setCacheStore(fakeCacheStore)
nativeCompileCache.setV8Version("a-v8-version")
@@ -29,13 +31,10 @@ describe "NativeCompileCache", ->
fn2 = require('./fixtures/native-cache/file-2')
expect(cachedFiles.length).toBe(2)
expect(cachedFiles[0].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-1'))
expect(cachedFiles[0].cacheBuffer).toBeInstanceOf(Uint8Array)
expect(cachedFiles[0].cacheBuffer.length).toBeGreaterThan(0)
expect(fn1()).toBe(1)
expect(cachedFiles[1].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-2'))
expect(cachedFiles[1].cacheBuffer).toBeInstanceOf(Uint8Array)
expect(cachedFiles[1].cacheBuffer.length).toBeGreaterThan(0)
expect(fn2()).toBe(2)
@@ -51,7 +50,6 @@ describe "NativeCompileCache", ->
fn4 = require('./fixtures/native-cache/file-4')
expect(cachedFiles.length).toBe(1)
expect(cachedFiles[0].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-4'))
expect(cachedFiles[0].cacheBuffer).toBeInstanceOf(Uint8Array)
expect(cachedFiles[0].cacheBuffer.length).toBeGreaterThan(0)
expect(fn4()).toBe("file-4")
@@ -61,8 +59,6 @@ describe "NativeCompileCache", ->
fn4 = require('./fixtures/native-cache/file-4')
expect(cachedFiles.length).toBe(2)
expect(cachedFiles[1].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-4'))
expect(cachedFiles[1].invalidationKey).not.toBe(cachedFiles[0].invalidationKey)
expect(cachedFiles[1].cacheBuffer).toBeInstanceOf(Uint8Array)
expect(cachedFiles[1].cacheBuffer.length).toBeGreaterThan(0)
@@ -79,7 +75,6 @@ describe "NativeCompileCache", ->
fn5 = require('./fixtures/native-cache/file-5')
expect(cachedFiles.length).toBe(1)
expect(cachedFiles[0].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-5'))
expect(cachedFiles[0].cacheBuffer).toBeInstanceOf(Uint8Array)
expect(cachedFiles[0].cacheBuffer.length).toBeGreaterThan(0)
expect(fn5()).toBe("file-5")
@@ -89,8 +84,6 @@ describe "NativeCompileCache", ->
fn5 = require('./fixtures/native-cache/file-5')
expect(cachedFiles.length).toBe(2)
expect(cachedFiles[1].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-5'))
expect(cachedFiles[1].invalidationKey).not.toBe(cachedFiles[0].invalidationKey)
expect(cachedFiles[1].cacheBuffer).toBeInstanceOf(Uint8Array)
expect(cachedFiles[1].cacheBuffer.length).toBeGreaterThan(0)
@@ -100,5 +93,5 @@ describe "NativeCompileCache", ->
fn3 = require('./fixtures/native-cache/file-3')
expect(fakeCacheStore.delete).toHaveBeenCalledWith(require.resolve('./fixtures/native-cache/file-3'))
expect(fakeCacheStore.delete).toHaveBeenCalled()
expect(fn3()).toBe(3)

View File

@@ -4868,8 +4868,8 @@ describe "TextEditor", ->
editor.replaceSelectedText {}, -> '123'
expect(buffer.lineForRow(0)).toBe '123var quicksort = function () {'
editor.replaceSelectedText {selectWordIfEmpty: true}, -> 'var'
editor.setCursorBufferPosition([0])
editor.replaceSelectedText {selectWordIfEmpty: true}, -> 'var'
expect(buffer.lineForRow(0)).toBe 'var quicksort = function () {'
editor.setCursorBufferPosition([10])
@@ -4882,6 +4882,12 @@ describe "TextEditor", ->
editor.replaceSelectedText {}, -> 'ia'
expect(buffer.lineForRow(0)).toBe 'via quicksort = function () {'
it "replaces the selected text and selects the replacement text", ->
editor.setSelectedBufferRange([[0, 4], [0, 9]])
editor.replaceSelectedText {}, -> 'whatnot'
expect(buffer.lineForRow(0)).toBe 'var whatnotsort = function () {'
expect(editor.getSelectedBufferRange()).toEqual [[0, 4], [0, 11]]
describe ".transpose()", ->
it "swaps two characters", ->
editor.buffer.setText("abc")
@@ -4902,7 +4908,7 @@ describe "TextEditor", ->
editor.setCursorScreenPosition([0, 1])
editor.upperCase()
expect(editor.lineTextForBufferRow(0)).toBe 'ABC'
expect(editor.getSelectedBufferRange()).toEqual [[0, 1], [0, 1]]
expect(editor.getSelectedBufferRange()).toEqual [[0, 0], [0, 3]]
describe "when there is a selection", ->
it "upper cases the current selection", ->
@@ -4919,7 +4925,7 @@ describe "TextEditor", ->
editor.setCursorScreenPosition([0, 1])
editor.lowerCase()
expect(editor.lineTextForBufferRow(0)).toBe 'abc'
expect(editor.getSelectedBufferRange()).toEqual [[0, 1], [0, 1]]
expect(editor.getSelectedBufferRange()).toEqual [[0, 0], [0, 3]]
describe "when there is a selection", ->
it "lower cases the current selection", ->

View File

@@ -1337,7 +1337,9 @@ i = /test/; #FIXME\
it('calls the callback with all regex results in all files in the project', () => {
const results = []
waitsForPromise(() =>
atom.workspace.scan(/(a)+/, result => results.push(result))
atom.workspace.scan(
/(a)+/, {leadingContextLineCount: 1, trailingContextLineCount: 1},
result => results.push(result))
)
runs(() => {
@@ -1350,14 +1352,16 @@ i = /test/; #FIXME\
lineTextOffset: 0,
range: [[0, 0], [0, 3]],
leadingContextLines: [],
trailingContextLines: []
trailingContextLines: ['cc aa cc']
})
})
})
it('works with with escaped literals (like $ and ^)', () => {
const results = []
waitsForPromise(() => atom.workspace.scan(/\$\w+/, result => results.push(result)))
waitsForPromise(() => atom.workspace.scan(
/\$\w+/, {leadingContextLineCount: 1, trailingContextLineCount: 1},
result => results.push(result)))
runs(() => {
expect(results.length).toBe(1)
@@ -1369,7 +1373,7 @@ i = /test/; #FIXME\
lineText: 'dollar$bill',
lineTextOffset: 0,
range: [[2, 6], [2, 11]],
leadingContextLines: [],
leadingContextLines: ['cc aa cc'],
trailingContextLines: []
})
})

View File

@@ -11,13 +11,16 @@ class DirectorySearch
excludeVcsIgnores: options.excludeVcsIgnores
globalExclusions: options.exclusions
follow: options.follow
searchOptions =
leadingContextLineCount: options.leadingContextLineCount
trailingContextLineCount: options.trailingContextLineCount
@task = new Task(require.resolve('./scan-handler'))
@task.on 'scan:result-found', options.didMatch
@task.on 'scan:file-error', options.didError
@task.on 'scan:paths-searched', options.didSearchPaths
@promise = new Promise (resolve, reject) =>
@task.on('task:cancelled', reject)
@task.start rootPaths, regex.source, scanHandlerOptions, =>
@task.start rootPaths, regex.source, scanHandlerOptions, searchOptions, =>
@task.terminate()
resolve()

View File

@@ -14,14 +14,12 @@ class FileSystemBlobStore {
constructor (directory) {
this.blobFilename = path.join(directory, 'BLOB')
this.blobMapFilename = path.join(directory, 'MAP')
this.invalidationKeysFilename = path.join(directory, 'INVKEYS')
this.lockFilename = path.join(directory, 'LOCK')
this.reset()
}
reset () {
this.inMemoryBlobs = new Map()
this.invalidationKeys = {}
this.storedBlob = new Buffer(0)
this.storedBlobMap = {}
this.usedKeys = new Set()
@@ -34,14 +32,10 @@ class FileSystemBlobStore {
if (!fs.existsSync(this.blobFilename)) {
return
}
if (!fs.existsSync(this.invalidationKeysFilename)) {
return
}
try {
this.storedBlob = fs.readFileSync(this.blobFilename)
this.storedBlobMap = JSON.parse(fs.readFileSync(this.blobMapFilename))
this.invalidationKeys = JSON.parse(fs.readFileSync(this.invalidationKeysFilename))
} catch (e) {
this.reset()
}
@@ -51,7 +45,6 @@ class FileSystemBlobStore {
let dump = this.getDump()
let blobToStore = Buffer.concat(dump[0])
let mapToStore = JSON.stringify(dump[1])
let invalidationKeysToStore = JSON.stringify(this.invalidationKeys)
let acquiredLock = false
try {
@@ -60,7 +53,6 @@ class FileSystemBlobStore {
fs.writeFileSync(this.blobFilename, blobToStore)
fs.writeFileSync(this.blobMapFilename, mapToStore)
fs.writeFileSync(this.invalidationKeysFilename, invalidationKeysToStore)
} catch (error) {
// Swallow the exception silently only if we fail to acquire the lock.
if (error.code !== 'EEXIST') {
@@ -73,22 +65,19 @@ class FileSystemBlobStore {
}
}
has (key, invalidationKey) {
let containsKey = this.inMemoryBlobs.has(key) || this.storedBlobMap.hasOwnProperty(key)
let isValid = this.invalidationKeys[key] === invalidationKey
return containsKey && isValid
has (key) {
return this.inMemoryBlobs.has(key) || this.storedBlobMap.hasOwnProperty(key)
}
get (key, invalidationKey) {
if (this.has(key, invalidationKey)) {
get (key) {
if (this.has(key)) {
this.usedKeys.add(key)
return this.getFromMemory(key) || this.getFromStorage(key)
}
}
set (key, invalidationKey, buffer) {
set (key, buffer) {
this.usedKeys.add(key)
this.invalidationKeys[key] = invalidationKey
return this.inMemoryBlobs.set(key, buffer)
}

View File

@@ -291,7 +291,9 @@ class AtomApplication
@restart()
@disposable.add ipcHelpers.on ipcMain, 'resolve-proxy', (event, requestId, url) ->
event.sender.session.resolveProxy url, (proxy) -> event.sender.send('did-resolve-proxy', requestId, proxy)
event.sender.session.resolveProxy url, (proxy) ->
unless event.sender.isDestroyed()
event.sender.send('did-resolve-proxy', requestId, proxy)
@disposable.add ipcHelpers.on ipcMain, 'did-change-history-manager', (event) =>
for atomWindow in @windows

View File

@@ -60,11 +60,10 @@ class NativeCompileCache {
// create wrapper function
let wrapper = Module.wrap(content)
let cacheKey = filename
let invalidationKey = computeHash(wrapper + self.v8Version)
let cacheKey = computeHash(wrapper + self.v8Version)
let compiledWrapper = null
if (self.cacheStore.has(cacheKey, invalidationKey)) {
let buffer = self.cacheStore.get(cacheKey, invalidationKey)
if (self.cacheStore.has(cacheKey)) {
let buffer = self.cacheStore.get(cacheKey)
let compilationResult = cachedVm.runInThisContextCached(wrapper, filename, buffer)
compiledWrapper = compilationResult.result
if (compilationResult.wasRejected) {
@@ -79,7 +78,7 @@ class NativeCompileCache {
throw err
}
if (compilationResult.cacheBuffer) {
self.cacheStore.set(cacheKey, invalidationKey, compilationResult.cacheBuffer)
self.cacheStore.set(cacheKey, compilationResult.cacheBuffer)
}
compiledWrapper = compilationResult.result
}

View File

@@ -2,13 +2,13 @@ path = require "path"
async = require "async"
{PathSearcher, PathScanner, search} = require 'scandal'
module.exports = (rootPaths, regexSource, options) ->
module.exports = (rootPaths, regexSource, options, searchOptions={}) ->
callback = @async()
PATHS_COUNTER_SEARCHED_CHUNK = 50
pathsSearched = 0
searcher = new PathSearcher()
searcher = new PathSearcher(searchOptions)
searcher.on 'file-error', ({code, path, message}) ->
emit('scan:file-error', {code, path, message})

View File

@@ -1328,12 +1328,12 @@ class TextEditor extends Model
replaceSelectedText: (options={}, fn) ->
{selectWordIfEmpty} = options
@mutateSelectedText (selection) ->
range = selection.getBufferRange()
selection.getBufferRange()
if selectWordIfEmpty and selection.isEmpty()
selection.selectWord()
text = selection.getText()
selection.deleteSelectedText()
selection.insertText(fn(text))
range = selection.insertText(fn(text))
selection.setBufferRange(range)
# Split multi-line selections into one selection per line.
@@ -2826,6 +2826,11 @@ class TextEditor extends Model
# {::backwardsScanInBufferRange} to avoid tripping over your own changes.
#
# * `regex` A {RegExp} to search for.
# * `options` (optional) {Object}
# * `leadingContextLineCount` {Number} default `0`; The number of lines
# before the matched line to include in the results object.
# * `trailingContextLineCount` {Number} default `0`; The number of lines
# after the matched line to include in the results object.
# * `iterator` A {Function} that's called on each match
# * `object` {Object}
# * `match` The current regular expression match.
@@ -2833,7 +2838,12 @@ class TextEditor extends Model
# * `range` The {Range} of the match.
# * `stop` Call this {Function} to terminate the scan.
# * `replace` Call this {Function} with a {String} to replace the match.
scan: (regex, iterator) -> @buffer.scan(regex, iterator)
scan: (regex, options={}, iterator) ->
if _.isFunction(options)
iterator = options
options = {}
@buffer.scan(regex, options, iterator)
# Essential: Scan regular expression matches in a given range, calling the given
# iterator function on each match.

View File

@@ -515,9 +515,8 @@ module.exports = class Workspace extends Model {
//
// Returns a {Promise} that resolves to the {TextEditor} for the file URI.
open (uri_, options = {}) {
const { searchAllPanes } = options
const { split } = options
const uri = this.project.resolvePath(uri_)
const {searchAllPanes, split} = options
if (!atom.config.get('core.allowPendingPaneItems')) {
options.pending = false
@@ -530,7 +529,7 @@ module.exports = class Workspace extends Model {
}
let pane
if (searchAllPanes) { pane = this.paneContainer.paneForURI(uri) }
if (searchAllPanes) { pane = this.paneForURI(uri) }
if (pane == null) {
switch (split) {
case 'left':
@@ -551,7 +550,16 @@ module.exports = class Workspace extends Model {
}
}
return this.openURIInPane(uri, pane, options)
let item
if (uri != null) {
item = pane.itemForURI(uri)
}
if (item == null) {
item = this.createItemForURI(uri, options)
}
return Promise.resolve(item)
.then(item => this.openItem(item, Object.assign({pane, uri}, options)))
}
// Open Atom's license in the active pane.
@@ -601,26 +609,28 @@ module.exports = class Workspace extends Model {
}
openURIInPane (uri, pane, options = {}) {
const activatePane = options.activatePane != null ? options.activatePane : true
const activateItem = options.activateItem != null ? options.activateItem : true
let item
if (uri != null) {
item = pane.itemForURI(uri)
if (item == null) {
for (let opener of this.getOpeners()) {
item = opener(uri, options)
if (item != null) break
}
} else if (!options.pending && (pane.getPendingItem() === item)) {
pane.clearPendingItem()
}
if (item == null) {
item = this.createItemForURI(uri, options)
}
return Promise.resolve(item)
.then(item => this.openItem(item, Object.assign({pane, uri}, options)))
}
// Returns a {Promise} that resolves to the {TextEditor} (or other item) for the given URI.
createItemForURI (uri, options) {
if (uri != null) {
for (let opener of this.getOpeners()) {
const item = opener(uri, options)
if (item != null) return Promise.resolve(item)
}
}
try {
if (item == null) {
item = this.openTextFile(uri, options)
}
return this.openTextFile(uri, options)
} catch (error) {
switch (error.code) {
case 'CANCELLED':
@@ -648,40 +658,46 @@ module.exports = class Workspace extends Model {
throw error
}
}
}
return Promise.resolve(item)
.then(item => {
let initialColumn
if (pane.isDestroyed()) {
return item
}
openItem (item, options = {}) {
const {pane} = options
this.itemOpened(item)
if (activateItem) {
pane.activateItem(item, {pending: options.pending})
}
if (activatePane) {
pane.activate()
}
if (item == null) return undefined
if (pane.isDestroyed()) return item
let initialLine = initialColumn = 0
if (!Number.isNaN(options.initialLine)) {
initialLine = options.initialLine
}
if (!Number.isNaN(options.initialColumn)) {
initialColumn = options.initialColumn
}
if ((initialLine >= 0) || (initialColumn >= 0)) {
if (typeof item.setCursorBufferPosition === 'function') {
item.setCursorBufferPosition([initialLine, initialColumn])
}
}
if (!options.pending && (pane.getPendingItem() === item)) {
pane.clearPendingItem()
}
const index = pane.getActiveItemIndex()
this.emitter.emit('did-open', {uri, pane, item, index})
return item
const activatePane = options.activatePane != null ? options.activatePane : true
const activateItem = options.activateItem != null ? options.activateItem : true
this.itemOpened(item)
if (activateItem) {
pane.activateItem(item, {pending: options.pending})
}
if (activatePane) {
pane.activate()
}
let initialColumn = 0
let initialLine = 0
if (!Number.isNaN(options.initialLine)) {
initialLine = options.initialLine
}
if (!Number.isNaN(options.initialColumn)) {
initialColumn = options.initialColumn
}
if ((initialLine >= 0) || (initialColumn >= 0)) {
if (typeof item.setCursorBufferPosition === 'function') {
item.setCursorBufferPosition([initialLine, initialColumn])
}
)
}
const index = pane.getActiveItemIndex()
const uri = options.uri == null && typeof item.getURI === 'function' ? item.getURI() : options.uri
this.emitter.emit('did-open', {uri, pane, item, index})
return item
}
openTextFile (uri, options) {
@@ -1190,6 +1206,10 @@ module.exports = class Workspace extends Model {
// * `paths` An {Array} of glob patterns to search within.
// * `onPathsSearched` (optional) {Function} to be periodically called
// with number of paths searched.
// * `leadingContextLineCount` {Number} default `0`; The number of lines
// before the matched line to include in the results object.
// * `trailingContextLineCount` {Number} default `0`; The number of lines
// after the matched line to include in the results object.
// * `iterator` {Function} callback on each file found.
//
// Returns a {Promise} with a `cancel()` method that will cancel all
@@ -1249,6 +1269,8 @@ module.exports = class Workspace extends Model {
excludeVcsIgnores: this.config.get('core.excludeVcsIgnoredPaths'),
exclusions: this.config.get('core.ignoredNames'),
follow: this.config.get('core.followSymlinks'),
leadingContextLineCount: options.leadingContextLineCount || 0,
trailingContextLineCount: options.trailingContextLineCount || 0,
didMatch: result => {
if (!this.project.isPathModified(result.filePath)) {
return iterator(result)

View File

@@ -38,7 +38,10 @@
} else if (useSnapshot) {
Module.prototype.require = function (module) {
const absoluteFilePath = Module._resolveFilename(module, this, false)
const relativeFilePath = path.relative(entryPointDirPath, absoluteFilePath)
let relativeFilePath = path.relative(entryPointDirPath, absoluteFilePath)
if (process.platform === 'win32') {
relativeFilePath = relativeFilePath.replace(/\\/g, '/')
}
let cachedModule = snapshotResult.customRequire.cache[relativeFilePath] // eslint-disable-line no-undef
if (!cachedModule) {
cachedModule = {exports: Module._load(module, this, false)}