mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-21 07:58:04 +03:00
Merge branch 'master' into async-git-bumps
This commit is contained in:
commit
95cdbde1ec
@ -406,10 +406,6 @@ Please open an issue on `atom/atom` if you have suggestions for new labels, and
|
||||
|
||||
| Label name | `atom/atom` :mag_right: | `atom`‑org :mag_right: | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `in-progress` | [search][search-atom-repo-label-in-progress] | [search][search-atom-org-label-in-progress] | Tasks which the Atom core team is working on currently. |
|
||||
| `on-deck` | [search][search-atom-repo-label-on-deck] | [search][search-atom-org-label-on-deck] | Tasks which the Atom core team plans to work on next. |
|
||||
| `shipping` | [search][search-atom-repo-label-shipping] | [search][search-atom-org-label-shipping] | Tasks which the Atom core team completed and will be released in one of the next releases. |
|
||||
| `post-1.0-roadmap` | [search][search-atom-repo-label-post-1.0-roadmap] | [search][search-atom-org-label-post-1.0-roadmap] | The Atom core team's roadmap post version 1.0.0. |
|
||||
| `atom` | [search][search-atom-repo-label-atom] | [search][search-atom-org-label-atom] | Topics discussed for prioritization at the next meeting of Atom core team members. |
|
||||
|
||||
#### Pull Request Labels
|
||||
@ -498,14 +494,6 @@ Please open an issue on `atom/atom` if you have suggestions for new labels, and
|
||||
[search-atom-org-label-deprecation-help]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Adeprecation-help
|
||||
[search-atom-repo-label-electron]: https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Fatom+is%3Aopen+label%3Aelectron
|
||||
[search-atom-org-label-electron]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aelectron
|
||||
[search-atom-repo-label-on-deck]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aon-deck
|
||||
[search-atom-org-label-on-deck]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aon-deck
|
||||
[search-atom-repo-label-in-progress]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Ain-progress
|
||||
[search-atom-org-label-in-progress]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Ain-progress
|
||||
[search-atom-repo-label-shipping]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Ashipping
|
||||
[search-atom-org-label-shipping]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Ashipping
|
||||
[search-atom-repo-label-post-1.0-roadmap]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Apost-1.0-roadmap
|
||||
[search-atom-org-label-post-1.0-roadmap]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Apost-1.0-roadmap
|
||||
[search-atom-repo-label-atom]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aatom
|
||||
[search-atom-org-label-atom]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aatom
|
||||
[search-atom-repo-label-work-in-progress]: https://github.com/pulls?q=is%3Aopen+is%3Apr+repo%3Aatom%2Fatom+label%3Awork-in-progress
|
||||
|
@ -25,7 +25,7 @@
|
||||
"grunt-contrib-less": "~0.8.0",
|
||||
"grunt-cson": "0.16.0",
|
||||
"grunt-download-electron": "^2.1.1",
|
||||
"grunt-electron-installer": "1.0.6",
|
||||
"grunt-electron-installer": "1.2.2",
|
||||
"grunt-lesslint": "0.17.0",
|
||||
"grunt-peg": "~1.1.0",
|
||||
"grunt-shell": "~0.3.1",
|
||||
|
@ -1,5 +1,6 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
temp = require('temp').track()
|
||||
|
||||
_ = require 'underscore-plus'
|
||||
async = require 'async'
|
||||
@ -94,7 +95,7 @@ module.exports = (grunt) ->
|
||||
if process.platform in ['darwin', 'linux']
|
||||
options =
|
||||
cmd: appPath
|
||||
args: ['--test', "--resource-path=#{resourcePath}", coreSpecsPath]
|
||||
args: ['--test', "--resource-path=#{resourcePath}", coreSpecsPath, "--user-data-dir=#{temp.mkdirSync('atom-user-data-dir')}"]
|
||||
opts:
|
||||
env: _.extend({}, process.env,
|
||||
ATOM_INTEGRATION_TESTS_ENABLED: true
|
||||
|
@ -12,7 +12,7 @@
|
||||
"url": "https://github.com/atom/atom/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"electronVersion": "0.34.5",
|
||||
"electronVersion": "0.36.7",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^6.2.0",
|
||||
@ -54,7 +54,7 @@
|
||||
"service-hub": "^0.7.0",
|
||||
"source-map-support": "^0.3.2",
|
||||
"temp": "0.8.1",
|
||||
"text-buffer": "8.3.0",
|
||||
"text-buffer": "8.3.1",
|
||||
"typescript-simple": "1.0.0",
|
||||
"underscore-plus": "^1.6.6",
|
||||
"yargs": "^3.23.0"
|
||||
@ -173,7 +173,8 @@
|
||||
"runs",
|
||||
"spyOn",
|
||||
"waitsFor",
|
||||
"waitsForPromise"
|
||||
"waitsForPromise",
|
||||
"indexedDB"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
37
script/clean
37
script/clean
@ -4,15 +4,16 @@ var fs = require('fs');
|
||||
var path = require('path');
|
||||
var os = require('os');
|
||||
|
||||
var removeCommand = process.platform === 'win32' ? 'rmdir /S /Q ' : 'rm -rf ';
|
||||
var isWindows = process.platform === 'win32';
|
||||
var removeCommand = isWindows ? 'rmdir /S /Q ' : 'rm -rf ';
|
||||
var productName = require('../package.json').productName;
|
||||
|
||||
process.chdir(path.dirname(__dirname));
|
||||
var home = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'];
|
||||
var home = process.env[isWindows ? 'USERPROFILE' : 'HOME'];
|
||||
var tmpdir = os.tmpdir();
|
||||
|
||||
// Windows: Use START as a way to ignore error if Atom.exe isnt running
|
||||
var killatom = process.platform === 'win32' ? 'START taskkill /F /IM ' + productName + '.exe' : 'pkill -9 ' + productName + ' || true';
|
||||
var killatom = isWindows ? 'START taskkill /F /IM ' + productName + '.exe' : 'pkill -9 ' + productName + ' || true';
|
||||
|
||||
var commands = [
|
||||
killatom,
|
||||
@ -39,12 +40,32 @@ var run = function() {
|
||||
|
||||
if (Array.isArray(next)) {
|
||||
var pathToRemove = path.resolve.apply(path.resolve, next);
|
||||
if (fs.existsSync(pathToRemove))
|
||||
next = removeCommand + pathToRemove;
|
||||
else
|
||||
if (fs.existsSync(pathToRemove)) {
|
||||
if (isWindows) {
|
||||
removeFolderRecursive(pathToRemove);
|
||||
} else {
|
||||
next = removeCommand + pathToRemove;
|
||||
cp.safeExec(next, run);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return run();
|
||||
}
|
||||
}
|
||||
|
||||
cp.safeExec(next, run);
|
||||
else
|
||||
cp.safeExec(next, run);
|
||||
};
|
||||
run();
|
||||
|
||||
// Windows has a 260-char path limit for rmdir etc. Just recursively delete in Node.
|
||||
var removeFolderRecursive = function(folderPath) {
|
||||
fs.readdirSync(folderPath).forEach(function(entry, index) {
|
||||
var entryPath = path.join(folderPath, entry);
|
||||
if (fs.lstatSync(entryPath).isDirectory()) {
|
||||
removeFolderRecursive(entryPath);
|
||||
} else {
|
||||
fs.unlinkSync(entryPath);
|
||||
}
|
||||
});
|
||||
fs.rmdirSync(folderPath);
|
||||
};
|
||||
|
@ -152,6 +152,8 @@ describe "AtomEnvironment", ->
|
||||
atom.enablePersistence = false
|
||||
|
||||
it "selects the state based on the current project paths", ->
|
||||
jasmine.useRealClock()
|
||||
|
||||
[dir1, dir2] = [temp.mkdirSync("dir1-"), temp.mkdirSync("dir2-")]
|
||||
|
||||
loadSettings = _.extend atom.getLoadSettings(),
|
||||
@ -159,20 +161,40 @@ describe "AtomEnvironment", ->
|
||||
windowState: null
|
||||
|
||||
spyOn(atom, 'getLoadSettings').andCallFake -> loadSettings
|
||||
spyOn(atom.getStorageFolder(), 'getPath').andReturn(temp.mkdirSync("storage-dir-"))
|
||||
spyOn(atom, 'serialize').andReturn({stuff: 'cool'})
|
||||
spyOn(atom, 'deserialize')
|
||||
|
||||
atom.state.stuff = "cool"
|
||||
atom.project.setPaths([dir1, dir2])
|
||||
atom.saveStateSync()
|
||||
# State persistence will fail if other Atom instances are running
|
||||
waitsForPromise ->
|
||||
atom.stateStore.connect().then (isConnected) ->
|
||||
expect(isConnected).toBe true
|
||||
|
||||
atom.state = {}
|
||||
atom.loadStateSync()
|
||||
expect(atom.state.stuff).toBeUndefined()
|
||||
waitsForPromise ->
|
||||
atom.saveState().then ->
|
||||
atom.loadState()
|
||||
|
||||
loadSettings.initialPaths = [dir2, dir1]
|
||||
atom.state = {}
|
||||
atom.loadStateSync()
|
||||
expect(atom.state.stuff).toBe("cool")
|
||||
runs ->
|
||||
expect(atom.deserialize).not.toHaveBeenCalled()
|
||||
|
||||
waitsForPromise ->
|
||||
loadSettings.initialPaths = [dir2, dir1]
|
||||
atom.loadState()
|
||||
runs ->
|
||||
expect(atom.deserialize).toHaveBeenCalledWith({stuff: 'cool'})
|
||||
|
||||
it "saves state on keydown and mousedown events", ->
|
||||
spyOn(atom, 'saveState')
|
||||
|
||||
keydown = new KeyboardEvent('keydown')
|
||||
atom.document.dispatchEvent(keydown)
|
||||
advanceClock atom.saveStateDebounceInterval
|
||||
expect(atom.saveState).toHaveBeenCalled()
|
||||
|
||||
mousedown = new MouseEvent('mousedown')
|
||||
atom.document.dispatchEvent(mousedown)
|
||||
advanceClock atom.saveStateDebounceInterval
|
||||
expect(atom.saveState).toHaveBeenCalled()
|
||||
|
||||
describe "openInitialEmptyEditorIfNecessary", ->
|
||||
describe "when there are no paths set", ->
|
||||
@ -230,23 +252,6 @@ describe "AtomEnvironment", ->
|
||||
|
||||
atomEnvironment.destroy()
|
||||
|
||||
it "saves the serialized state of the window so it can be deserialized after reload", ->
|
||||
atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, window, document})
|
||||
spyOn(atomEnvironment, 'saveStateSync')
|
||||
|
||||
workspaceState = atomEnvironment.workspace.serialize()
|
||||
grammarsState = {grammarOverridesByPath: atomEnvironment.grammars.grammarOverridesByPath}
|
||||
projectState = atomEnvironment.project.serialize()
|
||||
|
||||
atomEnvironment.unloadEditorWindow()
|
||||
|
||||
expect(atomEnvironment.state.workspace).toEqual workspaceState
|
||||
expect(atomEnvironment.state.grammars).toEqual grammarsState
|
||||
expect(atomEnvironment.state.project).toEqual projectState
|
||||
expect(atomEnvironment.saveStateSync).toHaveBeenCalled()
|
||||
|
||||
atomEnvironment.destroy()
|
||||
|
||||
describe "::destroy()", ->
|
||||
it "does not throw exceptions when unsubscribing from ipc events (regression)", ->
|
||||
configDirPath = temp.mkdirSync()
|
||||
|
@ -172,7 +172,7 @@ class AtomReporter
|
||||
listen document, 'click', '.stack-trace', (event) ->
|
||||
event.currentTarget.classList.toggle('expanded')
|
||||
|
||||
@reloadButton.addEventListener('click', -> require('ipc').send('call-window-method', 'restart'))
|
||||
@reloadButton.addEventListener('click', -> require('electron').ipcRenderer.send('call-window-method', 'restart'))
|
||||
|
||||
updateSpecCounts: ->
|
||||
if @skippedCount
|
||||
|
@ -15,6 +15,8 @@ ChromedriverPort = 9515
|
||||
ChromedriverURLBase = "/wd/hub"
|
||||
ChromedriverStatusURL = "http://localhost:#{ChromedriverPort}#{ChromedriverURLBase}/status"
|
||||
|
||||
userDataDir = temp.mkdirSync('atom-user-data-dir')
|
||||
|
||||
chromeDriverUp = (done) ->
|
||||
checkStatus = ->
|
||||
http
|
||||
@ -48,7 +50,7 @@ buildAtomClient = (args, env) ->
|
||||
"atom-env=#{map(env, (value, key) -> "#{key}=#{value}").join(" ")}"
|
||||
"dev"
|
||||
"safe"
|
||||
"user-data-dir=#{temp.mkdirSync('atom-user-data-dir')}"
|
||||
"user-data-dir=#{userDataDir}"
|
||||
"socket-path=#{SocketPath}"
|
||||
])
|
||||
|
||||
@ -124,7 +126,7 @@ buildAtomClient = (args, env) ->
|
||||
|
||||
.addCommand "simulateQuit", (done) ->
|
||||
@execute -> atom.unloadEditorWindow()
|
||||
.execute -> require("remote").require("app").emit("before-quit")
|
||||
.execute -> require("electron").remote.app.emit("before-quit")
|
||||
.call(done)
|
||||
|
||||
module.exports = (args, env, fn) ->
|
||||
|
@ -28,13 +28,12 @@ describe "Starting Atom", ->
|
||||
it "opens the parent directory and creates an empty text editor", ->
|
||||
runAtom [path.join(tempDirPath, "new-file")], {ATOM_HOME: atomHome}, (client) ->
|
||||
client
|
||||
.waitForPaneItemCount(1, 1000)
|
||||
|
||||
.treeViewRootDirectories()
|
||||
.then ({value}) -> expect(value).toEqual([tempDirPath])
|
||||
|
||||
.waitForExist("atom-text-editor", 5000)
|
||||
.then (exists) -> expect(exists).toBe true
|
||||
.waitForPaneItemCount(1, 1000)
|
||||
.click("atom-text-editor")
|
||||
.keys("Hello!")
|
||||
.execute -> atom.workspace.getActiveTextEditor().getText()
|
||||
@ -153,6 +152,8 @@ describe "Starting Atom", ->
|
||||
.waitForPaneItemCount(0, 3000)
|
||||
.execute -> atom.workspace.open()
|
||||
.waitForPaneItemCount(1, 3000)
|
||||
.keys("Hello!")
|
||||
.waitUntil((-> Promise.resolve(false)), 1100)
|
||||
|
||||
runAtom [tempDirPath], {ATOM_HOME: atomHome}, (client) ->
|
||||
client
|
||||
|
@ -1,7 +1,7 @@
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
ipc = require 'ipc'
|
||||
{ipcRenderer} = require 'electron'
|
||||
|
||||
module.exports = ({logFile, headless, testPaths, buildAtomEnvironment}) ->
|
||||
window[key] = value for key, value of require '../vendor/jasmine'
|
||||
@ -88,7 +88,7 @@ buildTerminalReporter = (logFile, resolveWithExitCode) ->
|
||||
if logStream?
|
||||
fs.writeSync(logStream, str)
|
||||
else
|
||||
ipc.send 'write-to-stderr', str
|
||||
ipcRenderer.send 'write-to-stderr', str
|
||||
|
||||
{TerminalReporter} = require 'jasmine-tagged'
|
||||
new TerminalReporter
|
||||
|
@ -463,17 +463,6 @@ describe "LanguageMode", ->
|
||||
fold2 = editor.tokenizedLineForScreenRow(5).fold
|
||||
expect(fold2).toBeFalsy()
|
||||
|
||||
describe ".isFoldableAtBufferRow(bufferRow)", ->
|
||||
it "returns true if the line starts a multi-line comment", ->
|
||||
expect(languageMode.isFoldableAtBufferRow(1)).toBe true
|
||||
expect(languageMode.isFoldableAtBufferRow(6)).toBe true
|
||||
expect(languageMode.isFoldableAtBufferRow(17)).toBe false
|
||||
|
||||
it "does not return true for a line in the middle of a comment that's followed by an indented line", ->
|
||||
expect(languageMode.isFoldableAtBufferRow(7)).toBe false
|
||||
editor.buffer.insert([8, 0], ' ')
|
||||
expect(languageMode.isFoldableAtBufferRow(7)).toBe false
|
||||
|
||||
describe "css", ->
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
|
@ -446,16 +446,15 @@ describe "PackageManager", ->
|
||||
pack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-serialization").then (p) -> pack = p
|
||||
|
||||
runs ->
|
||||
expect(pack.mainModule.someNumber).not.toBe 77
|
||||
pack.mainModule.someNumber = 77
|
||||
atom.packages.deactivatePackage("package-with-serialization")
|
||||
spyOn(pack.mainModule, 'activate').andCallThrough()
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-serialization")
|
||||
runs ->
|
||||
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-serialization")
|
||||
runs ->
|
||||
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
|
||||
|
||||
it "invokes ::onDidActivatePackage listeners with the activated package", ->
|
||||
activatedPackage = null
|
||||
@ -819,6 +818,34 @@ describe "PackageManager", ->
|
||||
expect(atom.packages.isPackageActive("package-with-missing-provided-services")).toBe true
|
||||
expect(addErrorHandler.callCount).toBe 0
|
||||
|
||||
describe "::serialize", ->
|
||||
it "does not serialize packages that threw an error during activation", ->
|
||||
spyOn(console, 'warn')
|
||||
badPack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p
|
||||
|
||||
runs ->
|
||||
spyOn(badPack.mainModule, 'serialize').andCallThrough()
|
||||
|
||||
atom.packages.serialize()
|
||||
expect(badPack.mainModule.serialize).not.toHaveBeenCalled()
|
||||
|
||||
it "absorbs exceptions that are thrown by the package module's serialize method", ->
|
||||
spyOn(console, 'error')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-serialize-error')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-serialization')
|
||||
|
||||
runs ->
|
||||
atom.packages.serialize()
|
||||
expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined()
|
||||
expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
|
||||
describe "::deactivatePackage(id)", ->
|
||||
afterEach ->
|
||||
atom.packages.unloadPackages()
|
||||
@ -850,33 +877,6 @@ describe "PackageManager", ->
|
||||
expect(badPack.mainModule.deactivate).not.toHaveBeenCalled()
|
||||
expect(atom.packages.isPackageActive("package-that-throws-on-activate")).toBeFalsy()
|
||||
|
||||
it "does not serialize packages that have not been activated called on their main module", ->
|
||||
spyOn(console, 'warn')
|
||||
badPack = null
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p
|
||||
|
||||
runs ->
|
||||
spyOn(badPack.mainModule, 'serialize').andCallThrough()
|
||||
|
||||
atom.packages.deactivatePackage("package-that-throws-on-activate")
|
||||
expect(badPack.mainModule.serialize).not.toHaveBeenCalled()
|
||||
|
||||
it "absorbs exceptions that are thrown by the package module's serialize method", ->
|
||||
spyOn(console, 'error')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-serialize-error')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-serialization')
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackages()
|
||||
expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined()
|
||||
expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
|
||||
it "absorbs exceptions that are thrown by the package module's deactivate method", ->
|
||||
spyOn(console, 'error')
|
||||
|
||||
|
61
spec/state-store-spec.js
Normal file
61
spec/state-store-spec.js
Normal file
@ -0,0 +1,61 @@
|
||||
/** @babel */
|
||||
import {it, fit, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers'
|
||||
|
||||
const StateStore = require('../src/state-store.js')
|
||||
|
||||
describe("StateStore", () => {
|
||||
let databaseName = `test-database-${Date.now()}`
|
||||
let version = 1
|
||||
|
||||
it("can save and load states", () => {
|
||||
const store = new StateStore(databaseName, version)
|
||||
return store.save('key', {foo:'bar'})
|
||||
.then(() => store.load('key'))
|
||||
.then((state) => {
|
||||
expect(state).toEqual({foo:'bar'})
|
||||
})
|
||||
})
|
||||
|
||||
it("resolves with null when a non-existent key is loaded", () => {
|
||||
const store = new StateStore(databaseName, version)
|
||||
return store.load('no-such-key').then((value) => {
|
||||
expect(value).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
it("can clear the state object store", () => {
|
||||
const store = new StateStore(databaseName, version)
|
||||
return store.save('key', {foo:'bar'})
|
||||
.then(() => store.count())
|
||||
.then((count) =>
|
||||
expect(count).toBe(1)
|
||||
)
|
||||
.then(() => store.clear())
|
||||
.then(() => store.count())
|
||||
.then((count) => {
|
||||
expect(count).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe("when there is an error reading from the database", () => {
|
||||
it("rejects the promise returned by load", () => {
|
||||
const store = new StateStore(databaseName, version)
|
||||
|
||||
const fakeErrorEvent = {target: {errorCode: "Something bad happened"}}
|
||||
|
||||
spyOn(IDBObjectStore.prototype, 'get').andCallFake((key) => {
|
||||
let request = {}
|
||||
process.nextTick(() => request.onerror(fakeErrorEvent))
|
||||
return request
|
||||
})
|
||||
|
||||
return store.load('nonexistentKey')
|
||||
.then(() => {
|
||||
throw new Error("Promise should have been rejected")
|
||||
})
|
||||
.catch((event) => {
|
||||
expect(event).toBe(fakeErrorEvent)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
@ -2151,10 +2151,11 @@ describe('TextEditorComponent', function () {
|
||||
item.style.height = itemHeight + 'px'
|
||||
wrapperNode.style.width = windowWidth + 'px'
|
||||
wrapperNode.style.height = windowHeight + 'px'
|
||||
atom.setWindowDimensions({
|
||||
await atom.setWindowDimensions({
|
||||
width: windowWidth,
|
||||
height: windowHeight
|
||||
})
|
||||
|
||||
component.measureDimensions()
|
||||
component.measureWindowSize()
|
||||
await nextViewUpdatePromise()
|
||||
@ -4834,7 +4835,7 @@ describe('TextEditorComponent', function () {
|
||||
|
||||
it('pastes the previously selected text at the clicked location', async function () {
|
||||
let clipboardWrittenTo = false
|
||||
spyOn(require('ipc'), 'send').andCallFake(function (eventName, selectedText) {
|
||||
spyOn(require('electron').ipcRenderer, 'send').andCallFake(function (eventName, selectedText) {
|
||||
if (eventName === 'write-text-to-selection-clipboard') {
|
||||
require('../src/safe-clipboard').writeText(selectedText, 'selection')
|
||||
clipboardWrittenTo = true
|
||||
|
@ -202,8 +202,7 @@ describe "TokenizedBuffer", ->
|
||||
expect(tokenizedBuffer.firstInvalidRow()).toBe 3
|
||||
|
||||
advanceClock()
|
||||
# we discover that row 2 starts a foldable region when line 3 gets tokenized
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 2, end: 7, delta: 0)
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 3, end: 7, delta: 0)
|
||||
expect(tokenizedBuffer.firstInvalidRow()).toBe 8
|
||||
|
||||
describe "when there is a buffer change surrounding an invalid row", ->
|
||||
@ -253,7 +252,7 @@ describe "TokenizedBuffer", ->
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
delete event.bufferChange
|
||||
expect(event).toEqual(start: 1, end: 2, delta: 0)
|
||||
expect(event).toEqual(start: 2, end: 2, delta: 0)
|
||||
changeHandler.reset()
|
||||
|
||||
advanceClock()
|
||||
@ -263,8 +262,7 @@ describe "TokenizedBuffer", ->
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
delete event.bufferChange
|
||||
# we discover that row 2 starts a foldable region when line 3 gets tokenized
|
||||
expect(event).toEqual(start: 2, end: 5, delta: 0)
|
||||
expect(event).toEqual(start: 3, end: 5, delta: 0)
|
||||
|
||||
it "resumes highlighting with the state of the previous line", ->
|
||||
buffer.insert([0, 0], '/*')
|
||||
@ -292,7 +290,7 @@ describe "TokenizedBuffer", ->
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
delete event.bufferChange
|
||||
expect(event).toEqual(start: 0, end: 3, delta: -2) # starts at 0 because foldable on row 0 becomes false
|
||||
expect(event).toEqual(start: 1, end: 3, delta: -2)
|
||||
|
||||
describe "when the change invalidates the tokenization of subsequent lines", ->
|
||||
it "schedules the invalidated lines to be tokenized in the background", ->
|
||||
@ -305,7 +303,7 @@ describe "TokenizedBuffer", ->
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
delete event.bufferChange
|
||||
expect(event).toEqual(start: 1, end: 3, delta: -1)
|
||||
expect(event).toEqual(start: 2, end: 3, delta: -1)
|
||||
changeHandler.reset()
|
||||
|
||||
advanceClock()
|
||||
@ -314,8 +312,7 @@ describe "TokenizedBuffer", ->
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
delete event.bufferChange
|
||||
# we discover that row 2 starts a foldable region when line 3 gets tokenized
|
||||
expect(event).toEqual(start: 2, end: 4, delta: 0)
|
||||
expect(event).toEqual(start: 3, end: 4, delta: 0)
|
||||
|
||||
describe "when lines are both updated and inserted", ->
|
||||
it "updates tokens to reflect the change", ->
|
||||
@ -339,7 +336,7 @@ describe "TokenizedBuffer", ->
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
delete event.bufferChange
|
||||
expect(event).toEqual(start: 0, end: 2, delta: 2) # starts at 0 because .foldable becomes false on row 0
|
||||
expect(event).toEqual(start: 1, end: 2, delta: 2)
|
||||
|
||||
describe "when the change invalidates the tokenization of subsequent lines", ->
|
||||
it "schedules the invalidated lines to be tokenized in the background", ->
|
||||
@ -350,7 +347,7 @@ describe "TokenizedBuffer", ->
|
||||
expect(changeHandler).toHaveBeenCalled()
|
||||
[event] = changeHandler.argsForCall[0]
|
||||
delete event.bufferChange
|
||||
expect(event).toEqual(start: 1, end: 2, delta: 2)
|
||||
expect(event).toEqual(start: 2, end: 2, delta: 2)
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[0].scopes).toEqual ['source.js', 'comment.block.js', 'punctuation.definition.comment.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
|
||||
@ -894,7 +891,7 @@ describe "TokenizedBuffer", ->
|
||||
buffer.setTextInRange([[7, 0], [8, 65]], ' ok')
|
||||
|
||||
delete changeHandler.argsForCall[0][0].bufferChange
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 4, end: 10, delta: -1) # starts at row 4 because it became foldable
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 5, end: 10, delta: -1)
|
||||
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(6).indentLevel).toBe 2
|
||||
@ -903,7 +900,7 @@ describe "TokenizedBuffer", ->
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(9).indentLevel).toBe 2
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(10).indentLevel).toBe 2 # }
|
||||
|
||||
describe ".foldable on tokenized lines", ->
|
||||
describe "::isFoldableAtRow(row)", ->
|
||||
changes = null
|
||||
|
||||
beforeEach ->
|
||||
@ -915,74 +912,66 @@ describe "TokenizedBuffer", ->
|
||||
buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert
|
||||
})
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
tokenizedBuffer.onDidChange (change) ->
|
||||
delete change.bufferChange
|
||||
changes.push(change)
|
||||
|
||||
it "sets .foldable to true on the first line of multi-line comments", ->
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(13).foldable).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(14).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(15).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(16).foldable).toBe false
|
||||
it "includes the first line of multi-line comments", ->
|
||||
expect(tokenizedBuffer.isFoldableAtRow(0)).toBe true
|
||||
expect(tokenizedBuffer.isFoldableAtRow(1)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(2)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(3)).toBe true # because of indent
|
||||
expect(tokenizedBuffer.isFoldableAtRow(13)).toBe true
|
||||
expect(tokenizedBuffer.isFoldableAtRow(14)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(15)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(16)).toBe false
|
||||
|
||||
buffer.insert([0, Infinity], '\n')
|
||||
expect(changes).toEqual [{start: 0, end: 1, delta: 1}]
|
||||
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(0)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(1)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(2)).toBe true
|
||||
expect(tokenizedBuffer.isFoldableAtRow(3)).toBe false
|
||||
|
||||
changes = []
|
||||
buffer.undo()
|
||||
expect(changes).toEqual [{start: 0, end: 2, delta: -1}]
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent
|
||||
|
||||
it "sets .foldable to true on non-comment lines that precede an increase in indentation", ->
|
||||
expect(tokenizedBuffer.isFoldableAtRow(0)).toBe true
|
||||
expect(tokenizedBuffer.isFoldableAtRow(1)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(2)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(3)).toBe true # because of indent
|
||||
|
||||
it "includes non-comment lines that precede an increase in indentation", ->
|
||||
buffer.insert([2, 0], ' ') # commented lines preceding an indent aren't foldable
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(4).foldable).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(5).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false
|
||||
|
||||
changes = []
|
||||
expect(tokenizedBuffer.isFoldableAtRow(1)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(2)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(3)).toBe true
|
||||
expect(tokenizedBuffer.isFoldableAtRow(4)).toBe true
|
||||
expect(tokenizedBuffer.isFoldableAtRow(5)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(6)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(7)).toBe true
|
||||
expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false
|
||||
|
||||
buffer.insert([7, 0], ' ')
|
||||
expect(changes).toEqual [{start: 6, end: 7, delta: 0}]
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false
|
||||
|
||||
changes = []
|
||||
expect(tokenizedBuffer.isFoldableAtRow(6)).toBe true
|
||||
expect(tokenizedBuffer.isFoldableAtRow(7)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false
|
||||
|
||||
buffer.undo()
|
||||
expect(changes).toEqual [{start: 6, end: 7, delta: 0}]
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false
|
||||
|
||||
changes = []
|
||||
expect(tokenizedBuffer.isFoldableAtRow(6)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(7)).toBe true
|
||||
expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false
|
||||
|
||||
buffer.insert([7, 0], " \n x\n")
|
||||
expect(changes).toEqual [{start: 6, end: 7, delta: 2}]
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false
|
||||
|
||||
changes = []
|
||||
expect(tokenizedBuffer.isFoldableAtRow(6)).toBe true
|
||||
expect(tokenizedBuffer.isFoldableAtRow(7)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false
|
||||
|
||||
buffer.insert([9, 0], " ")
|
||||
expect(changes).toEqual [{start: 9, end: 9, delta: 0}]
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false
|
||||
expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false
|
||||
|
||||
expect(tokenizedBuffer.isFoldableAtRow(6)).toBe true
|
||||
expect(tokenizedBuffer.isFoldableAtRow(7)).toBe false
|
||||
expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false
|
||||
|
||||
describe "when the buffer is configured with the null grammar", ->
|
||||
it "uses the placeholder tokens and does not actually tokenize using the grammar", ->
|
||||
|
@ -4,7 +4,7 @@ fs = require 'fs-plus'
|
||||
temp = require 'temp'
|
||||
TextEditor = require '../src/text-editor'
|
||||
WindowEventHandler = require '../src/window-event-handler'
|
||||
ipc = require 'ipc'
|
||||
{ipcRenderer} = require 'electron'
|
||||
|
||||
describe "WindowEventHandler", ->
|
||||
[projectPath, windowEventHandler] = []
|
||||
@ -53,7 +53,7 @@ describe "WindowEventHandler", ->
|
||||
describe "beforeunload event", ->
|
||||
beforeEach ->
|
||||
jasmine.unspy(TextEditor.prototype, "shouldPromptToSave")
|
||||
spyOn(ipc, 'send')
|
||||
spyOn(ipcRenderer, 'send')
|
||||
|
||||
describe "when pane items are modified", ->
|
||||
editor = null
|
||||
@ -65,13 +65,13 @@ describe "WindowEventHandler", ->
|
||||
spyOn(atom.workspace, 'confirmClose').andReturn(true)
|
||||
window.dispatchEvent(new CustomEvent('beforeunload'))
|
||||
expect(atom.workspace.confirmClose).toHaveBeenCalled()
|
||||
expect(ipc.send).not.toHaveBeenCalledWith('did-cancel-window-unload')
|
||||
expect(ipcRenderer.send).not.toHaveBeenCalledWith('did-cancel-window-unload')
|
||||
|
||||
it "cancels the unload if the user selects cancel", ->
|
||||
spyOn(atom.workspace, 'confirmClose').andReturn(false)
|
||||
window.dispatchEvent(new CustomEvent('beforeunload'))
|
||||
expect(atom.workspace.confirmClose).toHaveBeenCalled()
|
||||
expect(ipc.send).toHaveBeenCalledWith('did-cancel-window-unload')
|
||||
expect(ipcRenderer.send).toHaveBeenCalledWith('did-cancel-window-unload')
|
||||
|
||||
describe "when a link is clicked", ->
|
||||
it "opens the http/https links in an external application", ->
|
||||
|
@ -1,4 +1,4 @@
|
||||
ipc = require 'ipc'
|
||||
{ipcRenderer} = require 'electron'
|
||||
path = require 'path'
|
||||
temp = require('temp').track()
|
||||
|
||||
@ -127,35 +127,35 @@ describe "WorkspaceElement", ->
|
||||
describe "the 'window:run-package-specs' command", ->
|
||||
it "runs the package specs for the active item's project path, or the first project path", ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
spyOn(ipc, 'send')
|
||||
spyOn(ipcRenderer, 'send')
|
||||
|
||||
# No project paths. Don't try to run specs.
|
||||
atom.commands.dispatch(workspaceElement, "window:run-package-specs")
|
||||
expect(ipc.send).not.toHaveBeenCalledWith("run-package-specs")
|
||||
expect(ipcRenderer.send).not.toHaveBeenCalledWith("run-package-specs")
|
||||
|
||||
projectPaths = [temp.mkdirSync("dir1-"), temp.mkdirSync("dir2-")]
|
||||
atom.project.setPaths(projectPaths)
|
||||
|
||||
# No active item. Use first project directory.
|
||||
atom.commands.dispatch(workspaceElement, "window:run-package-specs")
|
||||
expect(ipc.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec"))
|
||||
ipc.send.reset()
|
||||
expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec"))
|
||||
ipcRenderer.send.reset()
|
||||
|
||||
# Active item doesn't implement ::getPath(). Use first project directory.
|
||||
item = document.createElement("div")
|
||||
atom.workspace.getActivePane().activateItem(item)
|
||||
atom.commands.dispatch(workspaceElement, "window:run-package-specs")
|
||||
expect(ipc.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec"))
|
||||
ipc.send.reset()
|
||||
expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec"))
|
||||
ipcRenderer.send.reset()
|
||||
|
||||
# Active item has no path. Use first project directory.
|
||||
item.getPath = -> null
|
||||
atom.commands.dispatch(workspaceElement, "window:run-package-specs")
|
||||
expect(ipc.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec"))
|
||||
ipc.send.reset()
|
||||
expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec"))
|
||||
ipcRenderer.send.reset()
|
||||
|
||||
# Active item has path. Use project path for item path.
|
||||
item.getPath = -> path.join(projectPaths[1], "a-file.txt")
|
||||
atom.commands.dispatch(workspaceElement, "window:run-package-specs")
|
||||
expect(ipc.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[1], "spec"))
|
||||
ipc.send.reset()
|
||||
expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[1], "spec"))
|
||||
ipcRenderer.send.reset()
|
||||
|
@ -585,6 +585,22 @@ describe "Workspace", ->
|
||||
open = -> workspace.open('file1', workspace.getActivePane())
|
||||
expect(open).toThrow()
|
||||
|
||||
describe "when the file is already open in pending state", ->
|
||||
it "should terminate the pending state", ->
|
||||
editor = null
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.js', pending: true).then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.isPending()).toBe true
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.js').then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.isPending()).toBe false
|
||||
|
||||
describe "::reopenItem()", ->
|
||||
it "opens the uri associated with the last closed pane that isn't currently open", ->
|
||||
pane = workspace.getActivePane()
|
||||
@ -1532,3 +1548,14 @@ describe "Workspace", ->
|
||||
|
||||
atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow()
|
||||
expect(atom.close).toHaveBeenCalled()
|
||||
|
||||
describe "when the core.allowPendingPaneItems option is falsey", ->
|
||||
it "does not open item with `pending: true` option as pending", ->
|
||||
editor = null
|
||||
atom.config.set('core.allowPendingPaneItems', false)
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.js', pending: true).then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.isPending()).toBeFalsy()
|
||||
|
@ -1,69 +1,67 @@
|
||||
_ = require 'underscore-plus'
|
||||
ipc = require 'ipc'
|
||||
remote = require 'remote'
|
||||
shell = require 'shell'
|
||||
webFrame = require 'web-frame'
|
||||
{ipcRenderer, remote, shell, webFrame} = require 'electron'
|
||||
ipcHelpers = require './ipc-helpers'
|
||||
{Disposable} = require 'event-kit'
|
||||
{getWindowLoadSettings, setWindowLoadSettings} = require './window-load-settings-helpers'
|
||||
|
||||
module.exports =
|
||||
class ApplicationDelegate
|
||||
open: (params) ->
|
||||
ipc.send('open', params)
|
||||
ipcRenderer.send('open', params)
|
||||
|
||||
pickFolder: (callback) ->
|
||||
responseChannel = "atom-pick-folder-response"
|
||||
ipc.on responseChannel, (path) ->
|
||||
ipc.removeAllListeners(responseChannel)
|
||||
ipcRenderer.on responseChannel, (event, path) ->
|
||||
ipcRenderer.removeAllListeners(responseChannel)
|
||||
callback(path)
|
||||
ipc.send("pick-folder", responseChannel)
|
||||
ipcRenderer.send("pick-folder", responseChannel)
|
||||
|
||||
getCurrentWindow: ->
|
||||
remote.getCurrentWindow()
|
||||
|
||||
closeWindow: ->
|
||||
ipc.send("call-window-method", "close")
|
||||
ipcRenderer.send("call-window-method", "close")
|
||||
|
||||
getWindowSize: ->
|
||||
[width, height] = remote.getCurrentWindow().getSize()
|
||||
{width, height}
|
||||
|
||||
setWindowSize: (width, height) ->
|
||||
remote.getCurrentWindow().setSize(width, height)
|
||||
ipcHelpers.call('set-window-size', width, height)
|
||||
|
||||
getWindowPosition: ->
|
||||
[x, y] = remote.getCurrentWindow().getPosition()
|
||||
{x, y}
|
||||
|
||||
setWindowPosition: (x, y) ->
|
||||
ipc.send("call-window-method", "setPosition", x, y)
|
||||
ipcHelpers.call('set-window-position', x, y)
|
||||
|
||||
centerWindow: ->
|
||||
ipc.send("call-window-method", "center")
|
||||
ipcHelpers.call('center-window')
|
||||
|
||||
focusWindow: ->
|
||||
ipc.send("call-window-method", "focus")
|
||||
ipcHelpers.call('focus-window')
|
||||
|
||||
showWindow: ->
|
||||
ipc.send("call-window-method", "show")
|
||||
ipcHelpers.call('show-window')
|
||||
|
||||
hideWindow: ->
|
||||
ipc.send("call-window-method", "hide")
|
||||
ipcHelpers.call('hide-window')
|
||||
|
||||
restartWindow: ->
|
||||
ipc.send("call-window-method", "restart")
|
||||
reloadWindow: ->
|
||||
ipcRenderer.send("call-window-method", "reload")
|
||||
|
||||
isWindowMaximized: ->
|
||||
remote.getCurrentWindow().isMaximized()
|
||||
|
||||
maximizeWindow: ->
|
||||
ipc.send("call-window-method", "maximize")
|
||||
ipcRenderer.send("call-window-method", "maximize")
|
||||
|
||||
isWindowFullScreen: ->
|
||||
remote.getCurrentWindow().isFullScreen()
|
||||
|
||||
setWindowFullScreen: (fullScreen=false) ->
|
||||
ipc.send("call-window-method", "setFullScreen", fullScreen)
|
||||
ipcRenderer.send("call-window-method", "setFullScreen", fullScreen)
|
||||
|
||||
openWindowDevTools: ->
|
||||
new Promise (resolve) ->
|
||||
@ -75,7 +73,7 @@ class ApplicationDelegate
|
||||
resolve()
|
||||
else
|
||||
remote.getCurrentWindow().once("devtools-opened", -> resolve())
|
||||
ipc.send("call-window-method", "openDevTools")
|
||||
ipcRenderer.send("call-window-method", "openDevTools")
|
||||
|
||||
closeWindowDevTools: ->
|
||||
new Promise (resolve) ->
|
||||
@ -87,7 +85,7 @@ class ApplicationDelegate
|
||||
resolve()
|
||||
else
|
||||
remote.getCurrentWindow().once("devtools-closed", -> resolve())
|
||||
ipc.send("call-window-method", "closeDevTools")
|
||||
ipcRenderer.send("call-window-method", "closeDevTools")
|
||||
|
||||
toggleWindowDevTools: ->
|
||||
new Promise (resolve) =>
|
||||
@ -101,16 +99,16 @@ class ApplicationDelegate
|
||||
@openWindowDevTools().then(resolve)
|
||||
|
||||
executeJavaScriptInWindowDevTools: (code) ->
|
||||
ipc.send("call-window-method", "executeJavaScriptInDevTools", code)
|
||||
ipcRenderer.send("execute-javascript-in-dev-tools", code)
|
||||
|
||||
setWindowDocumentEdited: (edited) ->
|
||||
ipc.send("call-window-method", "setDocumentEdited", edited)
|
||||
ipcRenderer.send("call-window-method", "setDocumentEdited", edited)
|
||||
|
||||
setRepresentedFilename: (filename) ->
|
||||
ipc.send("call-window-method", "setRepresentedFilename", filename)
|
||||
ipcRenderer.send("call-window-method", "setRepresentedFilename", filename)
|
||||
|
||||
addRecentDocument: (filename) ->
|
||||
ipc.send("add-recent-document", filename)
|
||||
ipcRenderer.send("add-recent-document", filename)
|
||||
|
||||
setRepresentedDirectoryPaths: (paths) ->
|
||||
loadSettings = getWindowLoadSettings()
|
||||
@ -118,14 +116,13 @@ class ApplicationDelegate
|
||||
setWindowLoadSettings(loadSettings)
|
||||
|
||||
setAutoHideWindowMenuBar: (autoHide) ->
|
||||
ipc.send("call-window-method", "setAutoHideMenuBar", autoHide)
|
||||
ipcRenderer.send("call-window-method", "setAutoHideMenuBar", autoHide)
|
||||
|
||||
setWindowMenuBarVisibility: (visible) ->
|
||||
remote.getCurrentWindow().setMenuBarVisibility(visible)
|
||||
|
||||
getPrimaryDisplayWorkAreaSize: ->
|
||||
screen = remote.require 'screen'
|
||||
screen.getPrimaryDisplay().workAreaSize
|
||||
remote.screen.getPrimaryDisplay().workAreaSize
|
||||
|
||||
confirm: ({message, detailedMessage, buttons}) ->
|
||||
buttons ?= {}
|
||||
@ -134,8 +131,7 @@ class ApplicationDelegate
|
||||
else
|
||||
buttonLabels = Object.keys(buttons)
|
||||
|
||||
dialog = remote.require('dialog')
|
||||
chosen = dialog.showMessageBox(remote.getCurrentWindow(), {
|
||||
chosen = remote.dialog.showMessageBox(remote.getCurrentWindow(), {
|
||||
type: 'info'
|
||||
message: message
|
||||
detail: detailedMessage
|
||||
@ -157,42 +153,47 @@ class ApplicationDelegate
|
||||
params = _.clone(params)
|
||||
params.title ?= 'Save File'
|
||||
params.defaultPath ?= getWindowLoadSettings().initialPaths[0]
|
||||
dialog = remote.require('dialog')
|
||||
dialog.showSaveDialog remote.getCurrentWindow(), params
|
||||
remote.dialog.showSaveDialog remote.getCurrentWindow(), params
|
||||
|
||||
playBeepSound: ->
|
||||
shell.beep()
|
||||
|
||||
onDidOpenLocations: (callback) ->
|
||||
outerCallback = (message, detail) ->
|
||||
outerCallback = (event, message, detail) ->
|
||||
if message is 'open-locations'
|
||||
callback(detail)
|
||||
|
||||
ipc.on('message', outerCallback)
|
||||
ipcRenderer.on('message', outerCallback)
|
||||
new Disposable ->
|
||||
ipc.removeListener('message', outerCallback)
|
||||
ipcRenderer.removeListener('message', outerCallback)
|
||||
|
||||
onUpdateAvailable: (callback) ->
|
||||
outerCallback = (message, detail) ->
|
||||
outerCallback = (event, message, detail) ->
|
||||
if message is 'update-available'
|
||||
callback(detail)
|
||||
|
||||
ipc.on('message', outerCallback)
|
||||
ipcRenderer.on('message', outerCallback)
|
||||
new Disposable ->
|
||||
ipc.removeListener('message', outerCallback)
|
||||
ipcRenderer.removeListener('message', outerCallback)
|
||||
|
||||
onApplicationMenuCommand: (callback) ->
|
||||
ipc.on('command', callback)
|
||||
outerCallback = (event, args...) ->
|
||||
callback(args...)
|
||||
|
||||
ipcRenderer.on('command', outerCallback)
|
||||
new Disposable ->
|
||||
ipc.removeListener('command', callback)
|
||||
ipcRenderer.removeListener('command', outerCallback)
|
||||
|
||||
onContextMenuCommand: (callback) ->
|
||||
ipc.on('context-command', callback)
|
||||
outerCallback = (event, args...) ->
|
||||
callback(args...)
|
||||
|
||||
ipcRenderer.on('context-command', outerCallback)
|
||||
new Disposable ->
|
||||
ipc.removeListener('context-command', callback)
|
||||
ipcRenderer.removeListener('context-command', outerCallback)
|
||||
|
||||
didCancelWindowUnload: ->
|
||||
ipc.send('did-cancel-window-unload')
|
||||
ipcRenderer.send('did-cancel-window-unload')
|
||||
|
||||
openExternal: (url) ->
|
||||
shell.openExternal(url)
|
||||
|
@ -1,16 +1,16 @@
|
||||
crypto = require 'crypto'
|
||||
path = require 'path'
|
||||
ipc = require 'ipc'
|
||||
{ipcRenderer} = require 'electron'
|
||||
|
||||
_ = require 'underscore-plus'
|
||||
{deprecate} = require 'grim'
|
||||
{CompositeDisposable, Emitter} = require 'event-kit'
|
||||
{CompositeDisposable, Disposable, Emitter} = require 'event-kit'
|
||||
fs = require 'fs-plus'
|
||||
{mapSourcePosition} = require 'source-map-support'
|
||||
Model = require './model'
|
||||
WindowEventHandler = require './window-event-handler'
|
||||
StylesElement = require './styles-element'
|
||||
StorageFolder = require './storage-folder'
|
||||
StateStore = require './state-store'
|
||||
{getWindowLoadSettings, setWindowLoadSettings} = require './window-load-settings-helpers'
|
||||
registerDefaultCommands = require './register-default-commands'
|
||||
|
||||
@ -111,6 +111,8 @@ class AtomEnvironment extends Model
|
||||
# Public: A {Workspace} instance
|
||||
workspace: null
|
||||
|
||||
saveStateDebounceInterval: 1000
|
||||
|
||||
###
|
||||
Section: Construction and Destruction
|
||||
###
|
||||
@ -119,14 +121,16 @@ class AtomEnvironment extends Model
|
||||
constructor: (params={}) ->
|
||||
{@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params
|
||||
|
||||
@state = {version: @constructor.version}
|
||||
|
||||
@loadTime = null
|
||||
{devMode, safeMode, resourcePath} = @getLoadSettings()
|
||||
{devMode, safeMode, resourcePath, clearWindowState} = @getLoadSettings()
|
||||
|
||||
@emitter = new Emitter
|
||||
@disposables = new CompositeDisposable
|
||||
|
||||
@stateStore = new StateStore('AtomEnvironments', 1)
|
||||
|
||||
@stateStore.clear() if clearWindowState
|
||||
|
||||
@deserializers = new DeserializerManager(this)
|
||||
@deserializeTimings = {}
|
||||
|
||||
@ -200,19 +204,28 @@ class AtomEnvironment extends Model
|
||||
@registerDefaultViewProviders()
|
||||
|
||||
@installUncaughtErrorHandler()
|
||||
@attachSaveStateListeners()
|
||||
@installWindowEventHandler()
|
||||
|
||||
@observeAutoHideMenuBar()
|
||||
|
||||
checkPortableHomeWritable = ->
|
||||
responseChannel = "check-portable-home-writable-response"
|
||||
ipc.on responseChannel, (response) ->
|
||||
ipc.removeAllListeners(responseChannel)
|
||||
ipcRenderer.on responseChannel, (event, response) ->
|
||||
ipcRenderer.removeAllListeners(responseChannel)
|
||||
atom.notifications.addWarning("#{response.message.replace(/([\\\.+\\-_#!])/g, '\\$1')}") if not response.writable
|
||||
ipc.send('check-portable-home-writable', responseChannel)
|
||||
ipcRenderer.send('check-portable-home-writable', responseChannel)
|
||||
|
||||
checkPortableHomeWritable()
|
||||
|
||||
attachSaveStateListeners: ->
|
||||
debouncedSaveState = _.debounce((=> @saveState()), @saveStateDebounceInterval)
|
||||
@document.addEventListener('mousedown', debouncedSaveState, true)
|
||||
@document.addEventListener('keydown', debouncedSaveState, true)
|
||||
@disposables.add new Disposable =>
|
||||
@document.removeEventListener('mousedown', debouncedSaveState, true)
|
||||
@document.removeEventListener('keydown', debouncedSaveState, true)
|
||||
|
||||
setConfigSchema: ->
|
||||
@config.setSchema null, {type: 'object', properties: _.clone(require('./config-schema'))}
|
||||
|
||||
@ -302,9 +315,6 @@ class AtomEnvironment extends Model
|
||||
@views.clear()
|
||||
@registerDefaultViewProviders()
|
||||
|
||||
@state.packageStates = {}
|
||||
delete @state.workspace
|
||||
|
||||
destroy: ->
|
||||
return if not @project
|
||||
|
||||
@ -497,7 +507,7 @@ class AtomEnvironment extends Model
|
||||
|
||||
# Extended: Reload the current window.
|
||||
reload: ->
|
||||
@applicationDelegate.restartWindow()
|
||||
@applicationDelegate.reloadWindow()
|
||||
|
||||
# Extended: Returns a {Boolean} that is `true` if the current window is maximized.
|
||||
isMaximized: ->
|
||||
@ -524,16 +534,18 @@ class AtomEnvironment extends Model
|
||||
|
||||
# Restore the window to its previous dimensions and show it.
|
||||
#
|
||||
# Also restores the full screen and maximized state on the next tick to
|
||||
# Restores the full screen and maximized state after the window has resized to
|
||||
# prevent resize glitches.
|
||||
displayWindow: ->
|
||||
dimensions = @restoreWindowDimensions()
|
||||
@show()
|
||||
@focus()
|
||||
|
||||
setImmediate =>
|
||||
@setFullScreen(true) if @workspace?.fullScreen
|
||||
@maximize() if dimensions?.maximized and process.platform isnt 'darwin'
|
||||
@restoreWindowDimensions().then (dimensions) =>
|
||||
steps = [
|
||||
@restoreWindowBackground(),
|
||||
@show(),
|
||||
@focus()
|
||||
]
|
||||
steps.push(@setFullScreen(true)) if @workspace.fullScreen
|
||||
steps.push(@maximize()) if dimensions?.maximized and process.platform isnt 'darwin'
|
||||
Promise.all(steps)
|
||||
|
||||
if @isFirstLoad()
|
||||
loadSettings = getWindowLoadSettings()
|
||||
@ -566,12 +578,14 @@ class AtomEnvironment extends Model
|
||||
# * `width` The new width.
|
||||
# * `height` The new height.
|
||||
setWindowDimensions: ({x, y, width, height}) ->
|
||||
steps = []
|
||||
if width? and height?
|
||||
@setSize(width, height)
|
||||
steps.push(@setSize(width, height))
|
||||
if x? and y?
|
||||
@setPosition(x, y)
|
||||
steps.push(@setPosition(x, y))
|
||||
else
|
||||
@center()
|
||||
steps.push(@center())
|
||||
Promise.all(steps)
|
||||
|
||||
# Returns true if the dimensions are useable, false if they should be ignored.
|
||||
# Work around for https://github.com/atom/atom-shell/issues/473
|
||||
@ -607,16 +621,22 @@ class AtomEnvironment extends Model
|
||||
# But after that, e.g., when the window's been reloaded, we want to use the
|
||||
# dimensions we've saved for it.
|
||||
if not @isFirstLoad()
|
||||
dimensions = @state.windowDimensions
|
||||
dimensions = @windowDimensions
|
||||
|
||||
unless @isValidDimensions(dimensions)
|
||||
dimensions = @getDefaultWindowDimensions()
|
||||
@setWindowDimensions(dimensions)
|
||||
dimensions
|
||||
@setWindowDimensions(dimensions).then -> dimensions
|
||||
|
||||
storeWindowDimensions: ->
|
||||
dimensions = @getWindowDimensions()
|
||||
@state.windowDimensions = dimensions if @isValidDimensions(dimensions)
|
||||
@windowDimensions = dimensions if @isValidDimensions(dimensions)
|
||||
|
||||
restoreWindowBackground: ->
|
||||
if backgroundColor = window.localStorage.getItem('atom:window-background-color')
|
||||
@backgroundStylesheet = document.createElement('style')
|
||||
@backgroundStylesheet.type = 'text/css'
|
||||
@backgroundStylesheet.innerText = 'html, body { background: ' + backgroundColor + ' !important; }'
|
||||
document.head.appendChild(@backgroundStylesheet)
|
||||
|
||||
storeWindowBackground: ->
|
||||
return if @inSpecMode()
|
||||
@ -642,6 +662,7 @@ class AtomEnvironment extends Model
|
||||
@packages.loadPackages()
|
||||
|
||||
@document.body.appendChild(@views.getView(@workspace))
|
||||
@backgroundStylesheet?.remove()
|
||||
|
||||
@watchProjectPath()
|
||||
|
||||
@ -653,17 +674,20 @@ class AtomEnvironment extends Model
|
||||
|
||||
@openInitialEmptyEditorIfNecessary()
|
||||
|
||||
serialize: ->
|
||||
version: @constructor.version
|
||||
project: @project.serialize()
|
||||
workspace: @workspace.serialize()
|
||||
packageStates: @packages.serialize()
|
||||
grammars: {grammarOverridesByPath: @grammars.grammarOverridesByPath}
|
||||
fullScreen: @isFullScreen()
|
||||
windowDimensions: @windowDimensions
|
||||
|
||||
unloadEditorWindow: ->
|
||||
return if not @project
|
||||
|
||||
@storeWindowBackground()
|
||||
@state.grammars = {grammarOverridesByPath: @grammars.grammarOverridesByPath}
|
||||
@state.project = @project.serialize()
|
||||
@state.workspace = @workspace.serialize()
|
||||
@packages.deactivatePackages()
|
||||
@state.packageStates = @packages.packageStates
|
||||
@state.fullScreen = @isFullScreen()
|
||||
@saveStateSync()
|
||||
@saveBlobStoreSync()
|
||||
|
||||
openInitialEmptyEditorIfNecessary: ->
|
||||
@ -797,45 +821,54 @@ class AtomEnvironment extends Model
|
||||
|
||||
@blobStore.save()
|
||||
|
||||
saveStateSync: ->
|
||||
return unless @enablePersistence
|
||||
saveState: ->
|
||||
return Promise.resolve() unless @enablePersistence
|
||||
state = @serialize()
|
||||
|
||||
if storageKey = @getStateKey(@project?.getPaths())
|
||||
@getStorageFolder().store(storageKey, @state)
|
||||
@stateStore.save(storageKey, state)
|
||||
else
|
||||
@getCurrentWindow().loadSettings.windowState = JSON.stringify(@state)
|
||||
@getCurrentWindow().loadSettings.windowState = JSON.stringify(state)
|
||||
Promise.resolve()
|
||||
|
||||
loadStateSync: ->
|
||||
return unless @enablePersistence
|
||||
loadState: ->
|
||||
return Promise.resolve() unless @enablePersistence
|
||||
|
||||
startTime = Date.now()
|
||||
|
||||
statePromise = null
|
||||
if stateKey = @getStateKey(@getLoadSettings().initialPaths)
|
||||
if state = @getStorageFolder().load(stateKey)
|
||||
@state = state
|
||||
statePromise = @stateStore.load(stateKey)
|
||||
|
||||
if not @state? and windowState = @getLoadSettings().windowState
|
||||
if not statePromise? and windowState = @getLoadSettings().windowState
|
||||
try
|
||||
if state = JSON.parse(@getLoadSettings().windowState)
|
||||
@state = state
|
||||
statePromise = Promise.resolve(JSON.parse(@getLoadSettings().windowState))
|
||||
catch error
|
||||
console.warn "Error parsing window state: #{statePath} #{error.stack}", error
|
||||
|
||||
@deserializeTimings.atom = Date.now() - startTime
|
||||
if statePromise?
|
||||
statePromise.then (state) =>
|
||||
@deserializeTimings.atom = Date.now() - startTime
|
||||
@deserialize(state) if state?
|
||||
else
|
||||
Promise.resolve()
|
||||
|
||||
if grammarOverridesByPath = @state.grammars?.grammarOverridesByPath
|
||||
deserialize: (state) ->
|
||||
if grammarOverridesByPath = state.grammars?.grammarOverridesByPath
|
||||
@grammars.grammarOverridesByPath = grammarOverridesByPath
|
||||
|
||||
@setFullScreen(@state.fullScreen)
|
||||
@setFullScreen(state.fullScreen)
|
||||
|
||||
@packages.packageStates = @state.packageStates ? {}
|
||||
@windowDimensions = state.windowDimensions if state.windowDimensions
|
||||
|
||||
@packages.packageStates = state.packageStates ? {}
|
||||
|
||||
startTime = Date.now()
|
||||
@project.deserialize(@state.project, @deserializers) if @state.project?
|
||||
@project.deserialize(state.project, @deserializers) if state.project?
|
||||
@deserializeTimings.project = Date.now() - startTime
|
||||
|
||||
startTime = Date.now()
|
||||
@workspace.deserialize(@state.workspace, @deserializers) if @state.workspace?
|
||||
@workspace.deserialize(state.workspace, @deserializers) if state.workspace?
|
||||
@deserializeTimings.workspace = Date.now() - startTime
|
||||
|
||||
getStateKey: (paths) ->
|
||||
@ -848,9 +881,6 @@ class AtomEnvironment extends Model
|
||||
getConfigDirPath: ->
|
||||
@configDirPath ?= process.env.ATOM_HOME
|
||||
|
||||
getStorageFolder: ->
|
||||
@storageFolder ?= new StorageFolder(@getConfigDirPath())
|
||||
|
||||
getUserInitScriptPath: ->
|
||||
initScriptPath = fs.resolve(@getConfigDirPath(), 'init', ['js', 'coffee'])
|
||||
initScriptPath ? path.join(@getConfigDirPath(), 'init.coffee')
|
||||
|
@ -1,6 +1,4 @@
|
||||
app = require 'app'
|
||||
ipc = require 'ipc'
|
||||
Menu = require 'menu'
|
||||
{app, Menu} = require 'electron'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
# Used to manage the global application menu.
|
||||
|
@ -2,14 +2,10 @@ AtomWindow = require './atom-window'
|
||||
ApplicationMenu = require './application-menu'
|
||||
AtomProtocolHandler = require './atom-protocol-handler'
|
||||
AutoUpdateManager = require './auto-update-manager'
|
||||
BrowserWindow = require 'browser-window'
|
||||
StorageFolder = require '../storage-folder'
|
||||
Menu = require 'menu'
|
||||
app = require 'app'
|
||||
dialog = require 'dialog'
|
||||
shell = require 'shell'
|
||||
ipcHelpers = require '../ipc-helpers'
|
||||
{BrowserWindow, Menu, app, dialog, ipcMain, shell} = require 'electron'
|
||||
fs = require 'fs-plus'
|
||||
ipc = require 'ipc'
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
net = require 'net'
|
||||
@ -51,7 +47,7 @@ class AtomApplication
|
||||
client = net.connect {path: options.socketPath}, ->
|
||||
client.write JSON.stringify(options), ->
|
||||
client.end()
|
||||
app.terminate()
|
||||
app.quit()
|
||||
|
||||
client.on 'error', createAtomApplication
|
||||
|
||||
@ -65,7 +61,7 @@ class AtomApplication
|
||||
exit: (status) -> app.exit(status)
|
||||
|
||||
constructor: (options) ->
|
||||
{@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, timeout} = options
|
||||
{@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, timeout, clearWindowState} = options
|
||||
|
||||
@socketPath = null if options.test
|
||||
|
||||
@ -89,16 +85,16 @@ class AtomApplication
|
||||
else
|
||||
@loadState(options) or @openPath(options)
|
||||
|
||||
openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout}) ->
|
||||
openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearWindowState}) ->
|
||||
if test
|
||||
@runTests({headless: true, devMode, @resourcePath, executedFrom, pathsToOpen, logFile, timeout})
|
||||
else if pathsToOpen.length > 0
|
||||
@openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup})
|
||||
@openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState})
|
||||
else if urlsToOpen.length > 0
|
||||
@openUrl({urlToOpen, devMode, safeMode}) for urlToOpen in urlsToOpen
|
||||
else
|
||||
# Always open a editor window if this is the first instance of Atom.
|
||||
@openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup})
|
||||
@openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState})
|
||||
|
||||
# Public: Removes the {AtomWindow} from the global window list.
|
||||
removeWindow: (window) ->
|
||||
@ -212,7 +208,6 @@ class AtomApplication
|
||||
@openPathOnEvent('application:open-license', path.join(process.resourcesPath, 'LICENSE.md'))
|
||||
|
||||
app.on 'before-quit', =>
|
||||
@saveState(false)
|
||||
@quitting = true
|
||||
|
||||
app.on 'will-quit', =>
|
||||
@ -232,7 +227,7 @@ class AtomApplication
|
||||
@emit('application:new-window')
|
||||
|
||||
# A request from the associated render process to open a new render process.
|
||||
ipc.on 'open', (event, options) =>
|
||||
ipcMain.on 'open', (event, options) =>
|
||||
window = @windowForEvent(event)
|
||||
if options?
|
||||
if typeof options.pathsToOpen is 'string'
|
||||
@ -245,44 +240,65 @@ class AtomApplication
|
||||
else
|
||||
@promptForPathToOpen('all', {window})
|
||||
|
||||
ipc.on 'update-application-menu', (event, template, keystrokesByCommand) =>
|
||||
ipcMain.on 'update-application-menu', (event, template, keystrokesByCommand) =>
|
||||
win = BrowserWindow.fromWebContents(event.sender)
|
||||
@applicationMenu.update(win, template, keystrokesByCommand)
|
||||
|
||||
ipc.on 'run-package-specs', (event, packageSpecPath) =>
|
||||
ipcMain.on 'run-package-specs', (event, packageSpecPath) =>
|
||||
@runTests({resourcePath: @devResourcePath, pathsToOpen: [packageSpecPath], headless: false})
|
||||
|
||||
ipc.on 'command', (event, command) =>
|
||||
ipcMain.on 'command', (event, command) =>
|
||||
@emit(command)
|
||||
|
||||
ipc.on 'window-command', (event, command, args...) ->
|
||||
ipcMain.on 'window-command', (event, command, args...) ->
|
||||
win = BrowserWindow.fromWebContents(event.sender)
|
||||
win.emit(command, args...)
|
||||
|
||||
ipc.on 'call-window-method', (event, method, args...) ->
|
||||
ipcMain.on 'call-window-method', (event, method, args...) ->
|
||||
win = BrowserWindow.fromWebContents(event.sender)
|
||||
win[method](args...)
|
||||
|
||||
ipc.on 'pick-folder', (event, responseChannel) =>
|
||||
ipcMain.on 'pick-folder', (event, responseChannel) =>
|
||||
@promptForPath "folder", (selectedPaths) ->
|
||||
event.sender.send(responseChannel, selectedPaths)
|
||||
|
||||
ipc.on 'did-cancel-window-unload', =>
|
||||
ipcHelpers.respondTo 'set-window-size', (win, width, height) ->
|
||||
win.setSize(width, height)
|
||||
|
||||
ipcHelpers.respondTo 'set-window-position', (win, x, y) ->
|
||||
win.setPosition(x, y)
|
||||
|
||||
ipcHelpers.respondTo 'center-window', (win) ->
|
||||
win.center()
|
||||
|
||||
ipcHelpers.respondTo 'focus-window', (win) ->
|
||||
win.focus()
|
||||
|
||||
ipcHelpers.respondTo 'show-window', (win) ->
|
||||
win.show()
|
||||
|
||||
ipcHelpers.respondTo 'hide-window', (win) ->
|
||||
win.hide()
|
||||
|
||||
ipcMain.on 'did-cancel-window-unload', =>
|
||||
@quitting = false
|
||||
|
||||
clipboard = require '../safe-clipboard'
|
||||
ipc.on 'write-text-to-selection-clipboard', (event, selectedText) ->
|
||||
ipcMain.on 'write-text-to-selection-clipboard', (event, selectedText) ->
|
||||
clipboard.writeText(selectedText, 'selection')
|
||||
|
||||
ipc.on 'write-to-stdout', (event, output) ->
|
||||
ipcMain.on 'write-to-stdout', (event, output) ->
|
||||
process.stdout.write(output)
|
||||
|
||||
ipc.on 'write-to-stderr', (event, output) ->
|
||||
ipcMain.on 'write-to-stderr', (event, output) ->
|
||||
process.stderr.write(output)
|
||||
|
||||
ipc.on 'add-recent-document', (event, filename) ->
|
||||
ipcMain.on 'add-recent-document', (event, filename) ->
|
||||
app.addRecentDocument(filename)
|
||||
|
||||
ipcMain.on 'execute-javascript-in-dev-tools', (event, code) ->
|
||||
event.sender.devToolsWebContents?.executeJavaScript(code)
|
||||
|
||||
setupDockMenu: ->
|
||||
if process.platform is 'darwin'
|
||||
dockMenu = Menu.buildFromTemplate [
|
||||
@ -350,7 +366,7 @@ class AtomApplication
|
||||
_.find @windows, (atomWindow) ->
|
||||
atomWindow.devMode is devMode and atomWindow.containsPaths(pathsToOpen)
|
||||
|
||||
# Returns the {AtomWindow} for the given ipc event.
|
||||
# Returns the {AtomWindow} for the given ipcMain event.
|
||||
windowForEvent: ({sender}) ->
|
||||
window = BrowserWindow.fromWebContents(sender)
|
||||
_.find @windows, ({browserWindow}) -> window is browserWindow
|
||||
@ -387,8 +403,8 @@ class AtomApplication
|
||||
# :safeMode - Boolean to control the opened window's safe mode.
|
||||
# :profileStartup - Boolean to control creating a profile of the startup time.
|
||||
# :window - {AtomWindow} to open file paths in.
|
||||
openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window} = {}) ->
|
||||
@openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window})
|
||||
openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState} = {}) ->
|
||||
@openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState})
|
||||
|
||||
# Public: Opens multiple paths, in existing windows if possible.
|
||||
#
|
||||
@ -400,9 +416,10 @@ class AtomApplication
|
||||
# :safeMode - Boolean to control the opened window's safe mode.
|
||||
# :windowDimensions - Object with height and width keys.
|
||||
# :window - {AtomWindow} to open file paths in.
|
||||
openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window}={}) ->
|
||||
openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearWindowState}={}) ->
|
||||
devMode = Boolean(devMode)
|
||||
safeMode = Boolean(safeMode)
|
||||
clearWindowState = Boolean(clearWindowState)
|
||||
locationsToOpen = (@locationForPathToOpen(pathToOpen, executedFrom) for pathToOpen in pathsToOpen)
|
||||
pathsToOpen = (locationToOpen.pathToOpen for locationToOpen in locationsToOpen)
|
||||
|
||||
@ -435,7 +452,7 @@ class AtomApplication
|
||||
windowInitializationScript ?= require.resolve('../initialize-application-window')
|
||||
resourcePath ?= @resourcePath
|
||||
windowDimensions ?= @getDimensionsForNewWindow()
|
||||
openedWindow = new AtomWindow({locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup})
|
||||
openedWindow = new AtomWindow({locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearWindowState})
|
||||
|
||||
if pidToKillWhenClosed?
|
||||
@pidsToOpenWindows[pidToKillWhenClosed] = openedWindow
|
||||
@ -472,7 +489,7 @@ class AtomApplication
|
||||
if loadSettings = window.getLoadSettings()
|
||||
states.push(initialPaths: loadSettings.initialPaths)
|
||||
if states.length > 0 or allowEmpty
|
||||
@storageFolder.store('application.json', states)
|
||||
@storageFolder.storeSync('application.json', states)
|
||||
|
||||
loadState: (options) ->
|
||||
if (states = @storageFolder.load('application.json'))?.length > 0
|
||||
|
@ -1,6 +1,6 @@
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
ipc = require 'ipc'
|
||||
{ipcMain} = require 'electron'
|
||||
|
||||
module.exports =
|
||||
class AtomPortable
|
||||
@ -30,6 +30,6 @@ class AtomPortable
|
||||
catch error
|
||||
message = "Failed to use portable Atom home directory (#{@getPortableAtomHomePath()}). Using the default instead (#{defaultHome}). #{error.message}"
|
||||
|
||||
ipc.on 'check-portable-home-writable', (event) ->
|
||||
ipcMain.on 'check-portable-home-writable', (event) ->
|
||||
event.sender.send 'check-portable-home-writable-response', {writable, message}
|
||||
writable
|
||||
|
@ -1,7 +1,6 @@
|
||||
app = require 'app'
|
||||
{app, protocol} = require 'electron'
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
protocol = require 'protocol'
|
||||
|
||||
# Handles requests with 'atom' protocol.
|
||||
#
|
||||
|
@ -1,6 +1,4 @@
|
||||
BrowserWindow = require 'browser-window'
|
||||
app = require 'app'
|
||||
dialog = require 'dialog'
|
||||
{BrowserWindow, app, dialog} = require 'electron'
|
||||
path = require 'path'
|
||||
fs = require 'fs'
|
||||
url = require 'url'
|
||||
@ -50,6 +48,7 @@ class AtomWindow
|
||||
loadSettings.safeMode ?= false
|
||||
loadSettings.atomHome = process.env.ATOM_HOME
|
||||
loadSettings.firstLoad = true
|
||||
loadSettings.clearWindowState ?= false
|
||||
|
||||
# Only send to the first non-spec window created
|
||||
if @constructor.includeShellLoadTime and not @isSpec
|
||||
@ -82,7 +81,7 @@ class AtomWindow
|
||||
loadSettings = _.clone(loadSettingsObj)
|
||||
delete loadSettings['windowState']
|
||||
|
||||
@browserWindow.loadUrl url.format
|
||||
@browserWindow.loadURL url.format
|
||||
protocol: 'file'
|
||||
pathname: "#{@resourcePath}/static/index.html"
|
||||
slashes: true
|
||||
@ -90,7 +89,7 @@ class AtomWindow
|
||||
|
||||
getLoadSettings: ->
|
||||
if @browserWindow.webContents? and not @browserWindow.webContents.isLoading()
|
||||
hash = url.parse(@browserWindow.webContents.getUrl()).hash.substr(1)
|
||||
hash = url.parse(@browserWindow.webContents.getURL()).hash.substr(1)
|
||||
JSON.parse(decodeURIComponent(hash))
|
||||
|
||||
hasProjectPath: -> @getLoadSettings().initialPaths?.length > 0
|
||||
@ -122,6 +121,9 @@ class AtomWindow
|
||||
false
|
||||
|
||||
handleEvents: ->
|
||||
@browserWindow.on 'close', ->
|
||||
global.atomApplication.saveState(false)
|
||||
|
||||
@browserWindow.on 'closed', =>
|
||||
global.atomApplication.removeWindow(this)
|
||||
|
||||
@ -145,10 +147,10 @@ class AtomWindow
|
||||
detail: 'Please report this issue to https://github.com/atom/atom'
|
||||
switch chosen
|
||||
when 0 then @browserWindow.destroy()
|
||||
when 1 then @browserWindow.restart()
|
||||
when 1 then @browserWindow.reload()
|
||||
|
||||
@browserWindow.webContents.on 'will-navigate', (event, url) =>
|
||||
unless url is @browserWindow.webContents.getUrl()
|
||||
unless url is @browserWindow.webContents.getURL()
|
||||
event.preventDefault()
|
||||
|
||||
@setupContextMenu()
|
||||
@ -221,6 +223,6 @@ class AtomWindow
|
||||
|
||||
isSpecWindow: -> @isSpec
|
||||
|
||||
reload: -> @browserWindow.restart()
|
||||
reload: -> @browserWindow.reload()
|
||||
|
||||
toggleDevTools: -> @browserWindow.toggleDevTools()
|
||||
|
@ -29,13 +29,13 @@ class AutoUpdateManager
|
||||
if process.platform is 'win32'
|
||||
autoUpdater = require './auto-updater-win32'
|
||||
else
|
||||
autoUpdater = require 'auto-updater'
|
||||
{autoUpdater} = require 'electron'
|
||||
|
||||
autoUpdater.on 'error', (event, message) =>
|
||||
@setState(ErrorState)
|
||||
console.error "Error Downloading Update: #{message}"
|
||||
|
||||
autoUpdater.setFeedUrl @feedUrl
|
||||
autoUpdater.setFeedURL @feedUrl
|
||||
|
||||
autoUpdater.on 'checking-for-update', =>
|
||||
@setState(CheckingState)
|
||||
@ -104,7 +104,7 @@ class AutoUpdateManager
|
||||
|
||||
onUpdateNotAvailable: =>
|
||||
autoUpdater.removeListener 'error', @onUpdateError
|
||||
dialog = require 'dialog'
|
||||
{dialog} = require 'electron'
|
||||
dialog.showMessageBox
|
||||
type: 'info'
|
||||
buttons: ['OK']
|
||||
@ -115,7 +115,7 @@ class AutoUpdateManager
|
||||
|
||||
onUpdateError: (event, message) =>
|
||||
autoUpdater.removeListener 'update-not-available', @onUpdateNotAvailable
|
||||
dialog = require 'dialog'
|
||||
{dialog} = require 'electron'
|
||||
dialog.showMessageBox
|
||||
type: 'warning'
|
||||
buttons: ['OK']
|
||||
|
@ -5,13 +5,13 @@ SquirrelUpdate = require './squirrel-update'
|
||||
class AutoUpdater
|
||||
_.extend @prototype, EventEmitter.prototype
|
||||
|
||||
setFeedUrl: (@updateUrl) ->
|
||||
setFeedURL: (@updateUrl) ->
|
||||
|
||||
quitAndInstall: ->
|
||||
if SquirrelUpdate.existsSync()
|
||||
SquirrelUpdate.restartAtom(require('app'))
|
||||
SquirrelUpdate.restartAtom(require('electron').app)
|
||||
else
|
||||
require('auto-updater').quitAndInstall()
|
||||
require('electron').autoUpdater.quitAndInstall()
|
||||
|
||||
downloadUpdate: (callback) ->
|
||||
SquirrelUpdate.spawn ['--download', @updateUrl], (error, stdout) ->
|
||||
|
@ -1,4 +1,4 @@
|
||||
Menu = require 'menu'
|
||||
{Menu} = require 'electron'
|
||||
|
||||
module.exports =
|
||||
class ContextMenu
|
||||
|
@ -4,8 +4,7 @@ process.on 'uncaughtException', (error={}) ->
|
||||
console.log(error.message) if error.message?
|
||||
console.log(error.stack) if error.stack?
|
||||
|
||||
crashReporter = require 'crash-reporter'
|
||||
app = require 'app'
|
||||
{crashReporter, app} = require 'electron'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
yargs = require 'yargs'
|
||||
@ -32,6 +31,9 @@ start = ->
|
||||
app.on 'open-url', addUrlToOpen
|
||||
app.on 'will-finish-launching', setupCrashReporter
|
||||
|
||||
if args.userDataDir?
|
||||
app.setPath('userData', args.userDataDir)
|
||||
|
||||
app.on 'ready', ->
|
||||
app.removeListener 'open-file', addPathToOpen
|
||||
app.removeListener 'open-url', addUrlToOpen
|
||||
@ -54,12 +56,12 @@ handleStartupEventWithSquirrel = ->
|
||||
SquirrelUpdate.handleStartupEvent(app, squirrelCommand)
|
||||
|
||||
setupCrashReporter = ->
|
||||
crashReporter.start(productName: 'Atom', companyName: 'GitHub')
|
||||
crashReporter.start(productName: 'Atom', companyName: 'GitHub', submitURL: 'http://54.249.141.255:1127/post')
|
||||
|
||||
setupAtomHome = ({setPortable}) ->
|
||||
return if process.env.ATOM_HOME
|
||||
|
||||
atomHome = path.join(app.getHomeDir(), '.atom')
|
||||
atomHome = path.join(app.getPath('home'), '.atom')
|
||||
AtomPortable = require './atom-portable'
|
||||
|
||||
if setPortable and not AtomPortable.isPortableInstall(process.platform, process.env.ATOM_HOME, atomHome)
|
||||
@ -119,6 +121,8 @@ parseCommandLine = ->
|
||||
options.alias('v', 'version').boolean('v').describe('v', 'Print the version.')
|
||||
options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.')
|
||||
options.string('socket-path')
|
||||
options.string('user-data-dir')
|
||||
options.boolean('clear-window-state').describe('clear-window-state', 'Delete all Atom environment state.')
|
||||
|
||||
args = options.argv
|
||||
|
||||
@ -140,9 +144,11 @@ parseCommandLine = ->
|
||||
pidToKillWhenClosed = args['pid'] if args['wait']
|
||||
logFile = args['log-file']
|
||||
socketPath = args['socket-path']
|
||||
userDataDir = args['user-data-dir']
|
||||
profileStartup = args['profile-startup']
|
||||
clearWindowState = args['clear-window-state']
|
||||
urlsToOpen = []
|
||||
devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getHomeDir(), 'github', 'atom')
|
||||
devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getPath('home'), 'github', 'atom')
|
||||
setPortable = args.portable
|
||||
|
||||
if args['resource-path']
|
||||
@ -164,6 +170,7 @@ parseCommandLine = ->
|
||||
|
||||
{resourcePath, devResourcePath, pathsToOpen, urlsToOpen, executedFrom, test,
|
||||
version, pidToKillWhenClosed, devMode, safeMode, newWindow,
|
||||
logFile, socketPath, profileStartup, timeout, setPortable}
|
||||
logFile, socketPath, userDataDir, profileStartup, timeout, setPortable,
|
||||
clearWindowState}
|
||||
|
||||
start()
|
||||
|
@ -20,6 +20,7 @@ else
|
||||
fileKeyPath = 'HKCU\\Software\\Classes\\*\\shell\\Atom'
|
||||
directoryKeyPath = 'HKCU\\Software\\Classes\\directory\\shell\\Atom'
|
||||
backgroundKeyPath = 'HKCU\\Software\\Classes\\directory\\background\\shell\\Atom'
|
||||
applicationsKeyPath = 'HKCU\\Software\\Classes\\Applications\\atom.exe'
|
||||
environmentKeyPath = 'HKCU\\Environment'
|
||||
|
||||
# Spawn a command and invoke the callback when it completes with an error
|
||||
@ -64,6 +65,10 @@ installContextMenu = (callback) ->
|
||||
args.push('/f')
|
||||
spawnReg(args, callback)
|
||||
|
||||
installFileHandler = (callback) ->
|
||||
args = ["#{applicationsKeyPath}\\shell\\open\\command", '/ve', '/d', "\"#{process.execPath}\" \"%1\""]
|
||||
addToRegistry(args, callback)
|
||||
|
||||
installMenu = (keyPath, arg, callback) ->
|
||||
args = [keyPath, '/ve', '/d', 'Open with Atom']
|
||||
addToRegistry args, ->
|
||||
@ -74,7 +79,8 @@ installContextMenu = (callback) ->
|
||||
|
||||
installMenu fileKeyPath, '%1', ->
|
||||
installMenu directoryKeyPath, '%1', ->
|
||||
installMenu(backgroundKeyPath, '%V', callback)
|
||||
installMenu backgroundKeyPath, '%V', ->
|
||||
installFileHandler(callback)
|
||||
|
||||
isAscii = (text) ->
|
||||
index = 0
|
||||
@ -124,7 +130,8 @@ uninstallContextMenu = (callback) ->
|
||||
|
||||
deleteFromRegistry fileKeyPath, ->
|
||||
deleteFromRegistry directoryKeyPath, ->
|
||||
deleteFromRegistry(backgroundKeyPath, callback)
|
||||
deleteFromRegistry backgroundKeyPath, ->
|
||||
deleteFromRegistry(applicationsKeyPath, callback)
|
||||
|
||||
# Add atom and apm to the PATH
|
||||
#
|
||||
|
@ -108,6 +108,10 @@ module.exports =
|
||||
description: 'Automatically update Atom when a new release is available.'
|
||||
type: 'boolean'
|
||||
default: true
|
||||
allowPendingPaneItems:
|
||||
description: 'Allow items to be previewed without adding them to a pane permanently, such as when single clicking files in the tree view.'
|
||||
type: 'boolean'
|
||||
default: true
|
||||
|
||||
editor:
|
||||
type: 'object'
|
||||
|
@ -4,7 +4,7 @@ CSON = require 'season'
|
||||
fs = require 'fs-plus'
|
||||
{calculateSpecificity, validateSelector} = require 'clear-cut'
|
||||
{Disposable} = require 'event-kit'
|
||||
remote = require 'remote'
|
||||
{remote} = require 'electron'
|
||||
MenuHelpers = require './menu-helpers'
|
||||
|
||||
platformContextMenu = require('../package.json')?._atomMenu?['context-menu']
|
||||
|
@ -413,6 +413,9 @@ class DisplayBuffer extends Model
|
||||
isFoldedAtScreenRow: (screenRow) ->
|
||||
@largestFoldContainingBufferRow(@bufferRowForScreenRow(screenRow))?
|
||||
|
||||
isFoldableAtBufferRow: (row) ->
|
||||
@tokenizedBuffer.isFoldableAtRow(row)
|
||||
|
||||
# Destroys the fold with the given id
|
||||
destroyFoldWithId: (id) ->
|
||||
@foldsByMarkerId[id]?.destroy()
|
||||
|
@ -23,12 +23,12 @@ module.exports = ({blobStore}) ->
|
||||
enablePersistence: true
|
||||
})
|
||||
|
||||
atom.loadStateSync()
|
||||
atom.displayWindow()
|
||||
atom.startEditorWindow()
|
||||
atom.loadState().then ->
|
||||
atom.displayWindow().then ->
|
||||
atom.startEditorWindow()
|
||||
|
||||
# Workaround for focus getting cleared upon window creation
|
||||
windowFocused = ->
|
||||
window.removeEventListener('focus', windowFocused)
|
||||
setTimeout (-> document.querySelector('atom-workspace').focus()), 0
|
||||
window.addEventListener('focus', windowFocused)
|
||||
# Workaround for focus getting cleared upon window creation
|
||||
windowFocused = ->
|
||||
window.removeEventListener('focus', windowFocused)
|
||||
setTimeout (-> document.querySelector('atom-workspace').focus()), 0
|
||||
window.addEventListener('focus', windowFocused)
|
||||
|
@ -4,17 +4,17 @@ cloneObject = (object) ->
|
||||
clone
|
||||
|
||||
module.exports = ({blobStore}) ->
|
||||
{crashReporter, remote} = require 'electron'
|
||||
# Start the crash reporter before anything else.
|
||||
require('crash-reporter').start(productName: 'Atom', companyName: 'GitHub')
|
||||
remote = require 'remote'
|
||||
crashReporter.start(productName: 'Atom', companyName: 'GitHub', submitURL: 'http://54.249.141.255:1127/post')
|
||||
|
||||
exitWithStatusCode = (status) ->
|
||||
remote.require('app').emit('will-quit')
|
||||
remote.app.emit('will-quit')
|
||||
remote.process.exit(status)
|
||||
|
||||
try
|
||||
path = require 'path'
|
||||
ipc = require 'ipc'
|
||||
{ipcRenderer} = require 'electron'
|
||||
{getWindowLoadSettings} = require './window-load-settings-helpers'
|
||||
AtomEnvironment = require '../src/atom-environment'
|
||||
ApplicationDelegate = require '../src/application-delegate'
|
||||
@ -29,15 +29,15 @@ module.exports = ({blobStore}) ->
|
||||
handleKeydown = (event) ->
|
||||
# Reload: cmd-r / ctrl-r
|
||||
if (event.metaKey or event.ctrlKey) and event.keyCode is 82
|
||||
ipc.send('call-window-method', 'restart')
|
||||
ipcRenderer.send('call-window-method', 'reload')
|
||||
|
||||
# Toggle Dev Tools: cmd-alt-i / ctrl-alt-i
|
||||
if (event.metaKey or event.ctrlKey) and event.altKey and event.keyCode is 73
|
||||
ipc.send('call-window-method', 'toggleDevTools')
|
||||
ipcRenderer.send('call-window-method', 'toggleDevTools')
|
||||
|
||||
# Reload: cmd-w / ctrl-w
|
||||
if (event.metaKey or event.ctrlKey) and event.keyCode is 87
|
||||
ipc.send('call-window-method', 'close')
|
||||
ipcRenderer.send('call-window-method', 'close')
|
||||
|
||||
window.addEventListener('keydown', handleKeydown, true)
|
||||
|
||||
@ -68,7 +68,8 @@ module.exports = ({blobStore}) ->
|
||||
logFile, headless, testPaths, buildAtomEnvironment, buildDefaultApplicationDelegate, legacyTestRunner
|
||||
})
|
||||
|
||||
promise.then(exitWithStatusCode) if getWindowLoadSettings().headless
|
||||
promise.then (statusCode) ->
|
||||
exitWithStatusCode(statusCode) if getWindowLoadSettings().headless
|
||||
catch error
|
||||
if getWindowLoadSettings().headless
|
||||
console.error(error.stack ? error)
|
||||
|
40
src/ipc-helpers.js
Normal file
40
src/ipc-helpers.js
Normal file
@ -0,0 +1,40 @@
|
||||
var ipcRenderer = null
|
||||
var ipcMain = null
|
||||
var BrowserWindow = null
|
||||
|
||||
exports.call = function (methodName, ...args) {
|
||||
if (!ipcRenderer) {
|
||||
ipcRenderer = require('electron').ipcRenderer
|
||||
}
|
||||
|
||||
var responseChannel = getResponseChannel(methodName)
|
||||
|
||||
return new Promise(function (resolve) {
|
||||
ipcRenderer.on(responseChannel, function (event, result) {
|
||||
ipcRenderer.removeAllListeners(responseChannel)
|
||||
resolve(result)
|
||||
})
|
||||
|
||||
ipcRenderer.send(methodName, ...args)
|
||||
})
|
||||
}
|
||||
|
||||
exports.respondTo = function (methodName, callback) {
|
||||
if (!ipcMain) {
|
||||
var electron = require('electron')
|
||||
ipcMain = electron.ipcMain
|
||||
BrowserWindow = electron.BrowserWindow
|
||||
}
|
||||
|
||||
var responseChannel = getResponseChannel(methodName)
|
||||
|
||||
ipcMain.on(methodName, function (event, ...args) {
|
||||
var browserWindow = BrowserWindow.fromWebContents(event.sender)
|
||||
var result = callback(browserWindow, ...args)
|
||||
event.sender.send(responseChannel, result)
|
||||
})
|
||||
}
|
||||
|
||||
function getResponseChannel (methodName) {
|
||||
return 'ipc-helpers-' + methodName + '-response'
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
path = require 'path'
|
||||
|
||||
_ = require 'underscore-plus'
|
||||
ipc = require 'ipc'
|
||||
{ipcRenderer} = require 'electron'
|
||||
CSON = require 'season'
|
||||
fs = require 'fs-plus'
|
||||
{Disposable} = require 'event-kit'
|
||||
@ -191,7 +191,7 @@ class MenuManager
|
||||
|
||||
sendToBrowserProcess: (template, keystrokesByCommand) ->
|
||||
keystrokesByCommand = @filterMultipleKeystroke(keystrokesByCommand)
|
||||
ipc.send 'update-application-menu', template, keystrokesByCommand
|
||||
ipcRenderer.send 'update-application-menu', template, keystrokesByCommand
|
||||
|
||||
# Get an {Array} of {String} classes for the given element.
|
||||
classesForElement: (element) ->
|
||||
|
@ -208,7 +208,7 @@ registerBuiltins = (devMode) ->
|
||||
cache.builtins[builtin] = path.join(commonRoot, "#{builtin}.js")
|
||||
|
||||
rendererRoot = path.join(atomShellRoot, 'renderer', 'api', 'lib')
|
||||
rendererBuiltins = ['ipc', 'remote']
|
||||
rendererBuiltins = ['ipc-renderer', 'remote']
|
||||
for builtin in rendererBuiltins
|
||||
cache.builtins[builtin] = path.join(rendererRoot, "#{builtin}.js")
|
||||
|
||||
|
@ -357,7 +357,9 @@ class PackageManager
|
||||
packagePaths = @getAvailablePackagePaths()
|
||||
packagePaths = packagePaths.filter (packagePath) => not @isPackageDisabled(path.basename(packagePath))
|
||||
packagePaths = _.uniq packagePaths, (packagePath) -> path.basename(packagePath)
|
||||
@loadPackage(packagePath) for packagePath in packagePaths
|
||||
@config.transact =>
|
||||
@loadPackage(packagePath) for packagePath in packagePaths
|
||||
return
|
||||
@emitter.emit 'did-load-initial-packages'
|
||||
|
||||
loadPackage: (nameOrPath) ->
|
||||
@ -467,6 +469,14 @@ class PackageManager
|
||||
return unless hook? and _.isString(hook) and hook.length > 0
|
||||
@activationHookEmitter.on(hook, callback)
|
||||
|
||||
serialize: ->
|
||||
for pack in @getActivePackages()
|
||||
@serializePackage(pack)
|
||||
@packageStates
|
||||
|
||||
serializePackage: (pack) ->
|
||||
@setPackageState(pack.name, state) if state = pack.serialize?()
|
||||
|
||||
# Deactivate all packages
|
||||
deactivatePackages: ->
|
||||
@config.transact =>
|
||||
@ -478,8 +488,7 @@ class PackageManager
|
||||
# Deactivate the package with the given name
|
||||
deactivatePackage: (name) ->
|
||||
pack = @getLoadedPackage(name)
|
||||
if @isPackageActive(name)
|
||||
@setPackageState(pack.name, state) if state = pack.serialize?()
|
||||
@serializePackage(pack) if @isPackageActive(pack.name)
|
||||
pack.deactivate()
|
||||
delete @activePackages[pack.name]
|
||||
delete @activatingPackages[pack.name]
|
||||
|
@ -1,4 +1,4 @@
|
||||
ipc = require 'ipc'
|
||||
{ipcRenderer} = require 'electron'
|
||||
|
||||
module.exports = ({commandRegistry, commandInstaller, config}) ->
|
||||
commandRegistry.add 'atom-workspace',
|
||||
@ -18,30 +18,30 @@ module.exports = ({commandRegistry, commandInstaller, config}) ->
|
||||
'window:increase-font-size': -> @getModel().increaseFontSize()
|
||||
'window:decrease-font-size': -> @getModel().decreaseFontSize()
|
||||
'window:reset-font-size': -> @getModel().resetFontSize()
|
||||
'application:about': -> ipc.send('command', 'application:about')
|
||||
'application:show-preferences': -> ipc.send('command', 'application:show-settings')
|
||||
'application:show-settings': -> ipc.send('command', 'application:show-settings')
|
||||
'application:quit': -> ipc.send('command', 'application:quit')
|
||||
'application:hide': -> ipc.send('command', 'application:hide')
|
||||
'application:hide-other-applications': -> ipc.send('command', 'application:hide-other-applications')
|
||||
'application:install-update': -> ipc.send('command', 'application:install-update')
|
||||
'application:unhide-all-applications': -> ipc.send('command', 'application:unhide-all-applications')
|
||||
'application:new-window': -> ipc.send('command', 'application:new-window')
|
||||
'application:new-file': -> ipc.send('command', 'application:new-file')
|
||||
'application:open': -> ipc.send('command', 'application:open')
|
||||
'application:open-file': -> ipc.send('command', 'application:open-file')
|
||||
'application:open-folder': -> ipc.send('command', 'application:open-folder')
|
||||
'application:open-dev': -> ipc.send('command', 'application:open-dev')
|
||||
'application:open-safe': -> ipc.send('command', 'application:open-safe')
|
||||
'application:about': -> ipcRenderer.send('command', 'application:about')
|
||||
'application:show-preferences': -> ipcRenderer.send('command', 'application:show-settings')
|
||||
'application:show-settings': -> ipcRenderer.send('command', 'application:show-settings')
|
||||
'application:quit': -> ipcRenderer.send('command', 'application:quit')
|
||||
'application:hide': -> ipcRenderer.send('command', 'application:hide')
|
||||
'application:hide-other-applications': -> ipcRenderer.send('command', 'application:hide-other-applications')
|
||||
'application:install-update': -> ipcRenderer.send('command', 'application:install-update')
|
||||
'application:unhide-all-applications': -> ipcRenderer.send('command', 'application:unhide-all-applications')
|
||||
'application:new-window': -> ipcRenderer.send('command', 'application:new-window')
|
||||
'application:new-file': -> ipcRenderer.send('command', 'application:new-file')
|
||||
'application:open': -> ipcRenderer.send('command', 'application:open')
|
||||
'application:open-file': -> ipcRenderer.send('command', 'application:open-file')
|
||||
'application:open-folder': -> ipcRenderer.send('command', 'application:open-folder')
|
||||
'application:open-dev': -> ipcRenderer.send('command', 'application:open-dev')
|
||||
'application:open-safe': -> ipcRenderer.send('command', 'application:open-safe')
|
||||
'application:add-project-folder': -> atom.addProjectFolder()
|
||||
'application:minimize': -> ipc.send('command', 'application:minimize')
|
||||
'application:zoom': -> ipc.send('command', 'application:zoom')
|
||||
'application:bring-all-windows-to-front': -> ipc.send('command', 'application:bring-all-windows-to-front')
|
||||
'application:open-your-config': -> ipc.send('command', 'application:open-your-config')
|
||||
'application:open-your-init-script': -> ipc.send('command', 'application:open-your-init-script')
|
||||
'application:open-your-keymap': -> ipc.send('command', 'application:open-your-keymap')
|
||||
'application:open-your-snippets': -> ipc.send('command', 'application:open-your-snippets')
|
||||
'application:open-your-stylesheet': -> ipc.send('command', 'application:open-your-stylesheet')
|
||||
'application:minimize': -> ipcRenderer.send('command', 'application:minimize')
|
||||
'application:zoom': -> ipcRenderer.send('command', 'application:zoom')
|
||||
'application:bring-all-windows-to-front': -> ipcRenderer.send('command', 'application:bring-all-windows-to-front')
|
||||
'application:open-your-config': -> ipcRenderer.send('command', 'application:open-your-config')
|
||||
'application:open-your-init-script': -> ipcRenderer.send('command', 'application:open-your-init-script')
|
||||
'application:open-your-keymap': -> ipcRenderer.send('command', 'application:open-your-keymap')
|
||||
'application:open-your-snippets': -> ipcRenderer.send('command', 'application:open-your-snippets')
|
||||
'application:open-your-stylesheet': -> ipcRenderer.send('command', 'application:open-your-stylesheet')
|
||||
'application:open-license': -> @getModel().openLicense()
|
||||
'window:run-package-specs': -> @runPackageSpecs()
|
||||
'window:focus-next-pane': -> @getModel().activateNextPane()
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Using clipboard in renderer process is not safe on Linux.
|
||||
module.exports =
|
||||
if process.platform is 'linux' and process.type is 'renderer'
|
||||
require('remote').require('clipboard')
|
||||
require('electron').remote.clipboard
|
||||
else
|
||||
require('clipboard')
|
||||
require('electron').clipboard
|
||||
|
@ -755,7 +755,7 @@ class Selection extends Model
|
||||
#
|
||||
# * `otherSelection` A {Selection} to compare against
|
||||
compare: (otherSelection) ->
|
||||
@getBufferRange().compare(otherSelection.getBufferRange())
|
||||
@marker.compare(otherSelection.marker)
|
||||
|
||||
###
|
||||
Section: Private Utilities
|
||||
|
91
src/state-store.js
Normal file
91
src/state-store.js
Normal file
@ -0,0 +1,91 @@
|
||||
'use strict'
|
||||
|
||||
module.exports =
|
||||
class StateStore {
|
||||
constructor (databaseName, version) {
|
||||
this.dbPromise = new Promise((resolve) => {
|
||||
let dbOpenRequest = indexedDB.open(databaseName, version)
|
||||
dbOpenRequest.onupgradeneeded = (event) => {
|
||||
let db = event.target.result
|
||||
db.createObjectStore('states')
|
||||
}
|
||||
dbOpenRequest.onsuccess = () => {
|
||||
resolve(dbOpenRequest.result)
|
||||
}
|
||||
dbOpenRequest.onerror = (error) => {
|
||||
console.error('Could not connect to indexedDB', error)
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
connect () {
|
||||
return this.dbPromise.then(db => !!db)
|
||||
}
|
||||
|
||||
save (key, value) {
|
||||
return this.dbPromise.then(db => {
|
||||
if (!db) return
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
var request = db.transaction(['states'], 'readwrite')
|
||||
.objectStore('states')
|
||||
.put({value: value, storedAt: new Date().toString()}, key)
|
||||
|
||||
request.onsuccess = resolve
|
||||
request.onerror = reject
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
load (key) {
|
||||
return this.dbPromise.then(db => {
|
||||
if (!db) return
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
var request = db.transaction(['states'])
|
||||
.objectStore('states')
|
||||
.get(key)
|
||||
|
||||
request.onsuccess = (event) => {
|
||||
let result = event.target.result
|
||||
resolve(result ? result.value : null)
|
||||
}
|
||||
|
||||
request.onerror = (event) => reject(event)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
clear () {
|
||||
return this.dbPromise.then(db => {
|
||||
if (!db) return
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
var request = db.transaction(['states'], 'readwrite')
|
||||
.objectStore('states')
|
||||
.clear()
|
||||
|
||||
request.onsuccess = resolve
|
||||
request.onerror = reject
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
count () {
|
||||
return this.dbPromise.then(db => {
|
||||
if (!db) return
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
var request = db.transaction(['states'])
|
||||
.objectStore('states')
|
||||
.count()
|
||||
|
||||
request.onsuccess = () => {
|
||||
resolve(request.result)
|
||||
}
|
||||
request.onerror = reject
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ class StorageFolder
|
||||
constructor: (containingPath) ->
|
||||
@path = path.join(containingPath, "storage") if containingPath?
|
||||
|
||||
store: (name, object) ->
|
||||
storeSync: (name, object) ->
|
||||
return unless @path?
|
||||
|
||||
fs.writeFileSync(@pathForKey(name), JSON.stringify(object), 'utf8')
|
||||
|
@ -2,7 +2,7 @@ _ = require 'underscore-plus'
|
||||
scrollbarStyle = require 'scrollbar-style'
|
||||
{Range, Point} = require 'text-buffer'
|
||||
{CompositeDisposable} = require 'event-kit'
|
||||
ipc = require 'ipc'
|
||||
{ipcRenderer} = require 'electron'
|
||||
|
||||
TextEditorPresenter = require './text-editor-presenter'
|
||||
GutterContainerComponent = require './gutter-container-component'
|
||||
@ -279,10 +279,10 @@ class TextEditorComponent
|
||||
writeSelectedTextToSelectionClipboard = =>
|
||||
return if @editor.isDestroyed()
|
||||
if selectedText = @editor.getSelectedText()
|
||||
# This uses ipc.send instead of clipboard.writeText because
|
||||
# clipboard.writeText is a sync ipc call on Linux and that
|
||||
# This uses ipcRenderer.send instead of clipboard.writeText because
|
||||
# clipboard.writeText is a sync ipcRenderer call on Linux and that
|
||||
# will slow down selections.
|
||||
ipc.send('write-text-to-selection-clipboard', selectedText)
|
||||
ipcRenderer.send('write-text-to-selection-clipboard', selectedText)
|
||||
@disposables.add @editor.onDidChangeSelectionRange ->
|
||||
clearTimeout(timeoutId)
|
||||
timeoutId = setTimeout(writeSelectedTextToSelectionClipboard)
|
||||
|
@ -432,18 +432,14 @@ class TextEditorPresenter
|
||||
return
|
||||
|
||||
updateCursorsState: ->
|
||||
@state.content.cursors = {}
|
||||
@updateCursorState(cursor) for cursor in @model.cursors # using property directly to avoid allocation
|
||||
return
|
||||
|
||||
updateCursorState: (cursor) ->
|
||||
return unless @startRow? and @endRow? and @hasPixelRectRequirements() and @baseCharacterWidth?
|
||||
screenRange = cursor.getScreenRange()
|
||||
return unless cursor.isVisible() and @startRow <= screenRange.start.row < @endRow
|
||||
|
||||
pixelRect = @pixelRectForScreenRange(screenRange)
|
||||
pixelRect.width = Math.round(@baseCharacterWidth) if pixelRect.width is 0
|
||||
@state.content.cursors[cursor.id] = pixelRect
|
||||
@state.content.cursors = {}
|
||||
for cursor in @model.cursorsForScreenRowRange(@startRow, @endRow - 1) when cursor.isVisible()
|
||||
pixelRect = @pixelRectForScreenRange(cursor.getScreenRange())
|
||||
pixelRect.width = Math.round(@baseCharacterWidth) if pixelRect.width is 0
|
||||
@state.content.cursors[cursor.id] = pixelRect
|
||||
return
|
||||
|
||||
updateOverlaysState: ->
|
||||
return unless @hasOverlayPositionRequirements()
|
||||
@ -603,7 +599,14 @@ class TextEditorPresenter
|
||||
|
||||
if endRow > startRow
|
||||
bufferRows = @model.bufferRowsForScreenRows(startRow, endRow - 1)
|
||||
previousBufferRow = -1
|
||||
foldable = false
|
||||
for bufferRow, i in bufferRows
|
||||
# don't compute foldability more than once per buffer row
|
||||
if previousBufferRow isnt bufferRow
|
||||
foldable = @model.isFoldableAtBufferRow(bufferRow)
|
||||
previousBufferRow = bufferRow
|
||||
|
||||
if bufferRow is lastBufferRow
|
||||
softWrapped = true
|
||||
else
|
||||
@ -613,7 +616,6 @@ class TextEditorPresenter
|
||||
screenRow = startRow + i
|
||||
line = @model.tokenizedLineForScreenRow(screenRow)
|
||||
decorationClasses = @lineNumberDecorationClassesForRow(screenRow)
|
||||
foldable = @model.isFoldableAtScreenRow(screenRow)
|
||||
blockDecorationsBeforeCurrentScreenRowHeight = @lineTopIndex.pixelPositionAfterBlocksForRow(screenRow) - @lineTopIndex.pixelPositionBeforeBlocksForRow(screenRow)
|
||||
blockDecorationsHeight = blockDecorationsBeforeCurrentScreenRowHeight
|
||||
if screenRow % @tileSize isnt 0
|
||||
|
@ -109,6 +109,7 @@ class TextEditor extends Model
|
||||
@emitter = new Emitter
|
||||
@disposables = new CompositeDisposable
|
||||
@cursors = []
|
||||
@cursorsByMarkerId = new Map
|
||||
@selections = []
|
||||
|
||||
buffer ?= new TextBuffer
|
||||
@ -1944,10 +1945,18 @@ class TextEditor extends Model
|
||||
getCursorsOrderedByBufferPosition: ->
|
||||
@getCursors().sort (a, b) -> a.compare(b)
|
||||
|
||||
cursorsForScreenRowRange: (startScreenRow, endScreenRow) ->
|
||||
cursors = []
|
||||
for marker in @selectionsMarkerLayer.findMarkers(intersectsScreenRowRange: [startScreenRow, endScreenRow])
|
||||
if cursor = @cursorsByMarkerId.get(marker.id)
|
||||
cursors.push(cursor)
|
||||
cursors
|
||||
|
||||
# Add a cursor based on the given {TextEditorMarker}.
|
||||
addCursor: (marker) ->
|
||||
cursor = new Cursor(editor: this, marker: marker, config: @config)
|
||||
@cursors.push(cursor)
|
||||
@cursorsByMarkerId.set(marker.id, cursor)
|
||||
@decorateMarker(marker, type: 'line-number', class: 'cursor-line')
|
||||
@decorateMarker(marker, type: 'line-number', class: 'cursor-line-no-selection', onlyHead: true, onlyEmpty: true)
|
||||
@decorateMarker(marker, type: 'line', class: 'cursor-line', onlyEmpty: true)
|
||||
@ -2446,6 +2455,7 @@ class TextEditor extends Model
|
||||
removeSelection: (selection) ->
|
||||
_.remove(@cursors, selection.cursor)
|
||||
_.remove(@selections, selection)
|
||||
@cursorsByMarkerId.delete(selection.cursor.marker.id)
|
||||
@emitter.emit 'did-remove-cursor', selection.cursor
|
||||
@emitter.emit 'did-remove-selection', selection
|
||||
|
||||
@ -2929,8 +2939,7 @@ class TextEditor extends Model
|
||||
#
|
||||
# Returns a {Boolean}.
|
||||
isFoldableAtBufferRow: (bufferRow) ->
|
||||
# @languageMode.isFoldableAtBufferRow(bufferRow)
|
||||
@displayBuffer.tokenizedBuffer.tokenizedLineForRow(bufferRow)?.foldable ? false
|
||||
@displayBuffer.isFoldableAtBufferRow(bufferRow)
|
||||
|
||||
# Extended: Determine whether the given row in screen coordinates is foldable.
|
||||
#
|
||||
|
@ -210,8 +210,6 @@ class TokenizedBuffer extends Model
|
||||
@validateRow(endRow)
|
||||
@invalidateRow(endRow + 1) unless filledRegion
|
||||
|
||||
[startRow, endRow] = @updateFoldableStatus(startRow, endRow)
|
||||
|
||||
event = {start: startRow, end: endRow, delta: 0}
|
||||
@emitter.emit 'did-change', event
|
||||
|
||||
@ -271,9 +269,6 @@ class TokenizedBuffer extends Model
|
||||
if newEndStack and not _.isEqual(newEndStack, previousEndStack)
|
||||
@invalidateRow(end + delta + 1)
|
||||
|
||||
[start, end] = @updateFoldableStatus(start, end + delta)
|
||||
end -= delta
|
||||
|
||||
event = {start, end, delta, bufferChange: e}
|
||||
@emitter.emit 'did-change', event
|
||||
|
||||
@ -287,23 +282,6 @@ class TokenizedBuffer extends Model
|
||||
|
||||
row - increment
|
||||
|
||||
updateFoldableStatus: (startRow, endRow) ->
|
||||
return [startRow, endRow] if @largeFileMode
|
||||
|
||||
scanStartRow = @buffer.previousNonBlankRow(startRow) ? startRow
|
||||
scanStartRow-- while scanStartRow > 0 and @tokenizedLineForRow(scanStartRow).isComment()
|
||||
scanEndRow = @buffer.nextNonBlankRow(endRow) ? endRow
|
||||
|
||||
for row in [scanStartRow..scanEndRow] by 1
|
||||
foldable = @isFoldableAtRow(row)
|
||||
line = @tokenizedLineForRow(row)
|
||||
unless line.foldable is foldable
|
||||
line.foldable = foldable
|
||||
startRow = Math.min(startRow, row)
|
||||
endRow = Math.max(endRow, row)
|
||||
|
||||
[startRow, endRow]
|
||||
|
||||
isFoldableAtRow: (row) ->
|
||||
if @largeFileMode
|
||||
false
|
||||
|
@ -33,7 +33,6 @@ class TokenizedLine
|
||||
endOfLineInvisibles: null
|
||||
lineIsWhitespaceOnly: false
|
||||
firstNonWhitespaceIndex: 0
|
||||
foldable: false
|
||||
|
||||
constructor: (properties) ->
|
||||
@id = idCounter++
|
||||
@ -492,15 +491,20 @@ class TokenizedLine
|
||||
@endOfLineInvisibles.push(eol) if eol
|
||||
|
||||
isComment: ->
|
||||
return @isCommentLine if @isCommentLine?
|
||||
|
||||
@isCommentLine = false
|
||||
iterator = @getTokenIterator()
|
||||
while iterator.next()
|
||||
scopes = iterator.getScopes()
|
||||
continue if scopes.length is 1
|
||||
continue unless NonWhitespaceRegex.test(iterator.getText())
|
||||
for scope in scopes
|
||||
return true if CommentScopeRegex.test(scope)
|
||||
if CommentScopeRegex.test(scope)
|
||||
@isCommentLine = true
|
||||
break
|
||||
break
|
||||
false
|
||||
@isCommentLine
|
||||
|
||||
isOnlyWhitespace: ->
|
||||
@lineIsWhitespaceOnly
|
||||
|
@ -1,4 +1,4 @@
|
||||
remote = require 'remote'
|
||||
{remote} = require 'electron'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
windowLoadSettings = null
|
||||
|
@ -1,4 +1,4 @@
|
||||
ipc = require 'ipc'
|
||||
{ipcRenderer} = require 'electron'
|
||||
path = require 'path'
|
||||
{Disposable, CompositeDisposable} = require 'event-kit'
|
||||
Grim = require 'grim'
|
||||
@ -117,6 +117,6 @@ class WorkspaceElement extends HTMLElement
|
||||
[projectPath] = @project.relativizePath(activePath)
|
||||
else
|
||||
[projectPath] = @project.getPaths()
|
||||
ipc.send('run-package-specs', path.join(projectPath, 'spec')) if projectPath
|
||||
ipcRenderer.send('run-package-specs', path.join(projectPath, 'spec')) if projectPath
|
||||
|
||||
module.exports = WorkspaceElement = document.registerElement 'atom-workspace', prototype: WorkspaceElement.prototype
|
||||
|
@ -414,6 +414,9 @@ class Workspace extends Model
|
||||
split = options.split
|
||||
uri = @project.resolvePath(uri)
|
||||
|
||||
if not atom.config.get('core.allowPendingPaneItems')
|
||||
options.pending = false
|
||||
|
||||
# Avoid adding URLs as recent documents to work-around this Spotlight crash:
|
||||
# https://github.com/atom/atom/issues/10071
|
||||
if uri? and not url.parse(uri).protocol?
|
||||
@ -473,7 +476,8 @@ class Workspace extends Model
|
||||
activateItem = options.activateItem ? true
|
||||
|
||||
if uri?
|
||||
item = pane.itemForURI(uri)
|
||||
if item = pane.itemForURI(uri)
|
||||
item.terminatePendingState?() if item.isPending?() and not options.pending
|
||||
item ?= opener(uri, options) for opener in @getOpeners() when not item
|
||||
|
||||
try
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src *; script-src 'self'; style-src 'self' 'unsafe-inline';">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src *; img-src data: *; script-src 'self'; style-src 'self' 'unsafe-inline';">
|
||||
<script src="index.js"></script>
|
||||
</head>
|
||||
<body tabindex="-1">
|
||||
|
@ -54,7 +54,7 @@
|
||||
}
|
||||
|
||||
function handleSetupError (error) {
|
||||
var currentWindow = require('remote').getCurrentWindow()
|
||||
var currentWindow = require('electron').remote.getCurrentWindow()
|
||||
currentWindow.setSize(800, 600)
|
||||
currentWindow.center()
|
||||
currentWindow.show()
|
||||
@ -71,9 +71,10 @@
|
||||
ModuleCache.add(loadSettings.resourcePath)
|
||||
|
||||
// Start the crash reporter before anything else.
|
||||
require('crash-reporter').start({
|
||||
require('electron').crashReporter.start({
|
||||
productName: 'Atom',
|
||||
companyName: 'GitHub',
|
||||
submitURL: 'http://54.249.141.255:1127/post',
|
||||
// By explicitly passing the app version here, we could save the call
|
||||
// of "require('remote').require('app').getVersion()".
|
||||
extra: {_version: loadSettings.appVersion}
|
||||
@ -83,8 +84,9 @@
|
||||
setupCsonCache(CompileCache.getCacheDirectory())
|
||||
|
||||
var initialize = require(loadSettings.windowInitializationScript)
|
||||
initialize({blobStore: blobStore})
|
||||
require('ipc').sendChannel('window-command', 'window:loaded')
|
||||
return initialize({blobStore: blobStore}).then(function () {
|
||||
require('electron').ipcRenderer.send('window-command', 'window:loaded')
|
||||
})
|
||||
}
|
||||
|
||||
function setupCsonCache (cacheDir) {
|
||||
@ -112,19 +114,15 @@
|
||||
function profileStartup (loadSettings, initialTime) {
|
||||
function profile () {
|
||||
console.profile('startup')
|
||||
try {
|
||||
var startTime = Date.now()
|
||||
setupWindow(loadSettings)
|
||||
var startTime = Date.now()
|
||||
setupWindow(loadSettings).then(function () {
|
||||
setLoadTime(Date.now() - startTime + initialTime)
|
||||
} catch (error) {
|
||||
handleSetupError(error)
|
||||
} finally {
|
||||
console.profileEnd('startup')
|
||||
console.log('Switch to the Profiles tab to view the created startup profile')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var currentWindow = require('remote').getCurrentWindow()
|
||||
var currentWindow = require('electron').remote.getCurrentWindow()
|
||||
if (currentWindow.devToolsWebContents) {
|
||||
profile()
|
||||
} else {
|
||||
@ -145,31 +143,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function setupWindowBackground () {
|
||||
if (loadSettings && loadSettings.isSpec) {
|
||||
return
|
||||
}
|
||||
|
||||
var backgroundColor = window.localStorage.getItem('atom:window-background-color')
|
||||
if (!backgroundColor) {
|
||||
return
|
||||
}
|
||||
|
||||
var backgroundStylesheet = document.createElement('style')
|
||||
backgroundStylesheet.type = 'text/css'
|
||||
backgroundStylesheet.innerText = 'html, body { background: ' + backgroundColor + ' !important; }'
|
||||
document.head.appendChild(backgroundStylesheet)
|
||||
|
||||
// Remove once the page loads
|
||||
window.addEventListener('load', function loadWindow () {
|
||||
window.removeEventListener('load', loadWindow, false)
|
||||
setTimeout(function () {
|
||||
backgroundStylesheet.remove()
|
||||
backgroundStylesheet = null
|
||||
}, 1000)
|
||||
}, false)
|
||||
}
|
||||
|
||||
var setupAtomHome = function () {
|
||||
if (process.env.ATOM_HOME) {
|
||||
return
|
||||
@ -185,5 +158,4 @@
|
||||
|
||||
parseLoadSettings()
|
||||
setupAtomHome()
|
||||
setupWindowBackground()
|
||||
})()
|
||||
|
Loading…
Reference in New Issue
Block a user