mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-19 23:17:16 +03:00
Merge branch 'master' into wl-build-on-node-7
This commit is contained in:
commit
27c66300e4
@ -30,6 +30,7 @@ cache:
|
||||
- apm/node_modules
|
||||
- script/node_modules
|
||||
- ~/.atom/compile-cache
|
||||
- ~/.atom/snapshot-cache
|
||||
|
||||
notifications:
|
||||
email:
|
||||
|
@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "1.15.3"
|
||||
"atom-package-manager": "1.17.0"
|
||||
}
|
||||
}
|
||||
|
@ -52,3 +52,4 @@ cache:
|
||||
- '%APPVEYOR_BUILD_FOLDER%\electron'
|
||||
- '%USERPROFILE%\.atom\.apm'
|
||||
- '%USERPROFILE%\.atom\compile-cache'
|
||||
- '%USERPROFILE%\.atom\snapshot-cache'
|
||||
|
@ -29,6 +29,7 @@ dependencies:
|
||||
- script/node_modules
|
||||
- node_modules
|
||||
- ~/.atom/compile-cache
|
||||
- ~/.atom/snapshot-cache
|
||||
|
||||
test:
|
||||
override:
|
||||
|
@ -10,7 +10,7 @@ In this directory you can only find very specific build and API level documentat
|
||||
|
||||
Instructions for building Atom on various platforms from source.
|
||||
|
||||
* [macOS](./build-instructions/macos.md)
|
||||
* [macOS](./build-instructions/macOS.md)
|
||||
* [Windows](./build-instructions/windows.md)
|
||||
* [Linux](./build-instructions/linux.md)
|
||||
* [FreeBSD](./build-instructions/freebsd.md)
|
||||
|
@ -137,6 +137,7 @@
|
||||
{ label: 'Open In &Dev Mode…', command: 'application:open-dev' }
|
||||
{ label: '&Reload Window', command: 'window:reload' }
|
||||
{ label: 'Run Package &Specs', command: 'window:run-package-specs' }
|
||||
{ label: 'Run &Benchmarks', command: 'window:run-benchmarks' }
|
||||
{ label: 'Toggle Developer &Tools', command: 'window:toggle-dev-tools' }
|
||||
]
|
||||
}
|
||||
|
@ -136,6 +136,7 @@
|
||||
{ label: 'Open In &Dev Mode…', command: 'application:open-dev' }
|
||||
{ label: '&Reload Window', command: 'window:reload' }
|
||||
{ label: 'Run Package &Specs', command: 'window:run-package-specs' }
|
||||
{ label: 'Run &Benchmarks', command: 'window:run-benchmarks' }
|
||||
{ label: 'Toggle Developer &Tools', command: 'window:toggle-dev-tools' }
|
||||
]
|
||||
}
|
||||
|
155
package.json
155
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "1.16.0-dev",
|
||||
"version": "1.17.0-dev",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/main-process/main.js",
|
||||
"repository": {
|
||||
@ -12,46 +12,35 @@
|
||||
"url": "https://github.com/atom/atom/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"electronVersion": "1.3.13",
|
||||
"electronVersion": "1.3.14",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "7.1.20",
|
||||
"atom-select-list": "0.0.12",
|
||||
"atom-keymap": "8.1.0",
|
||||
"atom-select-list": "0.0.15",
|
||||
"atom-ui": "0.4.1",
|
||||
"babel-core": "6.22.1",
|
||||
"babel-plugin-add-module-exports": "0.2.1",
|
||||
"babel-plugin-transform-async-to-generator": "6.22.0",
|
||||
"babel-plugin-transform-class-properties": "6.23.0",
|
||||
"babel-plugin-transform-decorators-legacy": "1.3.4",
|
||||
"babel-plugin-transform-do-expressions": "6.22.0",
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "6.23.0",
|
||||
"babel-plugin-transform-export-extensions": "6.22.0",
|
||||
"babel-plugin-transform-flow-strip-types": "6.22.0",
|
||||
"babel-plugin-transform-function-bind": "6.22.0",
|
||||
"babel-plugin-transform-object-rest-spread": "6.23.0",
|
||||
"babel-plugin-transform-react-jsx": "6.23.0",
|
||||
"babel-core": "5.8.38",
|
||||
"cached-run-in-this-context": "0.4.1",
|
||||
"chai": "3.5.0",
|
||||
"chart.js": "^2.3.0",
|
||||
"clear-cut": "^2.0.1",
|
||||
"clear-cut": "^2.0.2",
|
||||
"coffee-script": "1.11.1",
|
||||
"color": "^0.7.3",
|
||||
"dedent": "^0.6.0",
|
||||
"devtron": "1.3.0",
|
||||
"event-kit": "^2.1.0",
|
||||
"find-parent-dir": "^0.3.0",
|
||||
"first-mate": "6.1.0",
|
||||
"fs-plus": "2.9.2",
|
||||
"first-mate": "7.0.2",
|
||||
"fs-plus": "^3.0.0",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "^2.1",
|
||||
"git-utils": "4.1.2",
|
||||
"git-utils": "5.0.0",
|
||||
"glob": "^7.1.1",
|
||||
"grim": "1.5.0",
|
||||
"jasmine-json": "~0.0",
|
||||
"jasmine-tagged": "^1.1.4",
|
||||
"jquery": "2.1.4",
|
||||
"key-path-helpers": "^0.4.0",
|
||||
"less-cache": "0.23",
|
||||
"less-cache": "1.0.0",
|
||||
"line-top-index": "0.2.0",
|
||||
"marked": "^0.3.6",
|
||||
"minimatch": "^3.0.3",
|
||||
@ -60,23 +49,23 @@
|
||||
"normalize-package-data": "^2.0.0",
|
||||
"nslog": "^3",
|
||||
"oniguruma": "6.1.0",
|
||||
"pathwatcher": "6.8.0",
|
||||
"pathwatcher": "7.0.0",
|
||||
"postcss": "5.2.4",
|
||||
"postcss-selector-parser": "2.2.1",
|
||||
"property-accessors": "^1.1.3",
|
||||
"random-words": "0.0.1",
|
||||
"resolve": "^1.1.6",
|
||||
"runas": "^3.1",
|
||||
"scandal": "2.2.2",
|
||||
"scandal": "^3.1.0",
|
||||
"scoped-property-store": "^0.17.0",
|
||||
"scrollbar-style": "^3.2",
|
||||
"season": "^5.4.1",
|
||||
"season": "^6.0.0",
|
||||
"semver": "^4.3.3",
|
||||
"service-hub": "^0.7.2",
|
||||
"service-hub": "^0.7.3",
|
||||
"sinon": "1.17.4",
|
||||
"source-map-support": "^0.3.2",
|
||||
"temp": "0.8.1",
|
||||
"text-buffer": "10.3.12",
|
||||
"text-buffer": "11.4.0",
|
||||
"typescript-simple": "1.0.0",
|
||||
"underscore-plus": "^1.6.6",
|
||||
"winreg": "^1.2.1",
|
||||
@ -89,90 +78,90 @@
|
||||
"atom-light-ui": "0.46.0",
|
||||
"base16-tomorrow-dark-theme": "1.5.0",
|
||||
"base16-tomorrow-light-theme": "1.5.0",
|
||||
"one-dark-ui": "1.9.1",
|
||||
"one-light-ui": "1.9.1",
|
||||
"one-dark-ui": "1.9.2",
|
||||
"one-light-ui": "1.9.2",
|
||||
"one-dark-syntax": "1.7.1",
|
||||
"one-light-syntax": "1.7.1",
|
||||
"solarized-dark-syntax": "1.1.2",
|
||||
"solarized-light-syntax": "1.1.2",
|
||||
"about": "1.7.2",
|
||||
"archive-view": "0.62.2",
|
||||
"autocomplete-atom-api": "0.10.0",
|
||||
"autocomplete-css": "0.15.0",
|
||||
"autocomplete-html": "0.7.2",
|
||||
"autocomplete-plus": "2.34.2",
|
||||
"about": "1.7.5",
|
||||
"archive-view": "0.63.1",
|
||||
"autocomplete-atom-api": "0.10.1",
|
||||
"autocomplete-css": "0.16.1",
|
||||
"autocomplete-html": "0.7.3",
|
||||
"autocomplete-plus": "2.35.0",
|
||||
"autocomplete-snippets": "1.11.0",
|
||||
"autoflow": "0.29.0",
|
||||
"autosave": "0.24.0",
|
||||
"background-tips": "0.26.1",
|
||||
"bookmarks": "0.44.1",
|
||||
"bracket-matcher": "0.85.3",
|
||||
"command-palette": "0.40.2",
|
||||
"autosave": "0.24.1",
|
||||
"background-tips": "0.26.2",
|
||||
"bookmarks": "0.44.2",
|
||||
"bracket-matcher": "0.85.4",
|
||||
"command-palette": "0.40.3",
|
||||
"dalek": "0.2.0",
|
||||
"deprecation-cop": "0.56.2",
|
||||
"dev-live-reload": "0.47.0",
|
||||
"encoding-selector": "0.23.1",
|
||||
"exception-reporting": "0.41.1",
|
||||
"find-and-replace": "0.206.3",
|
||||
"fuzzy-finder": "1.4.1",
|
||||
"git-diff": "1.3.1",
|
||||
"deprecation-cop": "0.56.5",
|
||||
"dev-live-reload": "0.47.1",
|
||||
"encoding-selector": "0.23.2",
|
||||
"exception-reporting": "0.41.3",
|
||||
"find-and-replace": "0.207.3",
|
||||
"fuzzy-finder": "1.5.2",
|
||||
"git-diff": "1.3.4",
|
||||
"go-to-line": "0.32.0",
|
||||
"grammar-selector": "0.49.2",
|
||||
"image-view": "0.61.0",
|
||||
"incompatible-packages": "0.27.0",
|
||||
"keybinding-resolver": "0.36.1",
|
||||
"line-ending-selector": "0.6.1",
|
||||
"link": "0.31.2",
|
||||
"markdown-preview": "0.159.7",
|
||||
"metrics": "1.2.1",
|
||||
"notifications": "0.66.2",
|
||||
"grammar-selector": "0.49.3",
|
||||
"image-view": "0.61.2",
|
||||
"incompatible-packages": "0.27.2",
|
||||
"keybinding-resolver": "0.37.0",
|
||||
"line-ending-selector": "0.6.2",
|
||||
"link": "0.31.3",
|
||||
"markdown-preview": "0.159.10",
|
||||
"metrics": "1.2.2",
|
||||
"notifications": "0.67.1",
|
||||
"open-on-github": "1.2.1",
|
||||
"package-generator": "1.1.0",
|
||||
"settings-view": "0.247.0",
|
||||
"snippets": "1.0.5",
|
||||
"spell-check": "0.71.0",
|
||||
"status-bar": "1.8.1",
|
||||
"styleguide": "0.49.2",
|
||||
"symbols-view": "0.114.0",
|
||||
"tabs": "0.104.1",
|
||||
"package-generator": "1.1.1",
|
||||
"settings-view": "0.249.1",
|
||||
"snippets": "1.1.3",
|
||||
"spell-check": "0.71.3",
|
||||
"status-bar": "1.8.4",
|
||||
"styleguide": "0.49.4",
|
||||
"symbols-view": "0.115.3",
|
||||
"tabs": "0.104.4",
|
||||
"timecop": "0.36.0",
|
||||
"tree-view": "0.214.1",
|
||||
"update-package-dependencies": "0.10.0",
|
||||
"welcome": "0.36.1",
|
||||
"tree-view": "0.215.3",
|
||||
"update-package-dependencies": "0.11.0",
|
||||
"welcome": "0.36.2",
|
||||
"whitespace": "0.36.2",
|
||||
"wrap-guide": "0.39.1",
|
||||
"language-c": "0.56.0",
|
||||
"wrap-guide": "0.40.1",
|
||||
"language-c": "0.57.0",
|
||||
"language-clojure": "0.22.2",
|
||||
"language-coffee-script": "0.48.4",
|
||||
"language-coffee-script": "0.48.6",
|
||||
"language-csharp": "0.14.2",
|
||||
"language-css": "0.42.0",
|
||||
"language-gfm": "0.88.0",
|
||||
"language-css": "0.42.1",
|
||||
"language-gfm": "0.88.1",
|
||||
"language-git": "0.19.0",
|
||||
"language-go": "0.43.1",
|
||||
"language-html": "0.47.2",
|
||||
"language-hyperlink": "0.16.1",
|
||||
"language-java": "0.26.0",
|
||||
"language-javascript": "0.126.0",
|
||||
"language-json": "0.18.3",
|
||||
"language-less": "0.30.1",
|
||||
"language-java": "0.27.0",
|
||||
"language-javascript": "0.126.1",
|
||||
"language-json": "0.19.0",
|
||||
"language-less": "0.32.0",
|
||||
"language-make": "0.22.3",
|
||||
"language-mustache": "0.13.1",
|
||||
"language-objective-c": "0.15.1",
|
||||
"language-perl": "0.37.0",
|
||||
"language-php": "0.37.4",
|
||||
"language-property-list": "0.9.0",
|
||||
"language-php": "0.37.5",
|
||||
"language-property-list": "0.9.1",
|
||||
"language-python": "0.45.2",
|
||||
"language-ruby": "0.70.5",
|
||||
"language-ruby": "0.71.0",
|
||||
"language-ruby-on-rails": "0.25.2",
|
||||
"language-sass": "0.57.1",
|
||||
"language-sass": "0.59.0",
|
||||
"language-shellscript": "0.25.0",
|
||||
"language-source": "0.9.0",
|
||||
"language-sql": "0.25.3",
|
||||
"language-text": "0.7.1",
|
||||
"language-sql": "0.25.4",
|
||||
"language-text": "0.7.2",
|
||||
"language-todo": "0.29.1",
|
||||
"language-toml": "0.18.1",
|
||||
"language-xml": "0.34.16",
|
||||
"language-yaml": "0.28.0"
|
||||
"language-xml": "0.35.0",
|
||||
"language-yaml": "0.29.0"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -7,7 +7,11 @@ URL: https://atom.io/
|
||||
AutoReqProv: no # Avoid libchromiumcontent.so missing dependency
|
||||
Prefix: <%= installDir %>
|
||||
|
||||
%ifarch i386 i486 i586 i686
|
||||
Requires: lsb-core-noarch, libXss.so.1
|
||||
%else
|
||||
Requires: lsb-core-noarch, libXss.so.1()(64bit)
|
||||
%endif
|
||||
|
||||
%description
|
||||
<%= description %>
|
||||
|
@ -35,6 +35,7 @@ const dumpSymbols = require('./lib/dump-symbols')
|
||||
const generateAPIDocs = require('./lib/generate-api-docs')
|
||||
const generateMetadata = require('./lib/generate-metadata')
|
||||
const generateModuleCache = require('./lib/generate-module-cache')
|
||||
const generateStartupSnapshot = require('./lib/generate-startup-snapshot')
|
||||
const installApplication = require('./lib/install-application')
|
||||
const packageApplication = require('./lib/package-application')
|
||||
const prebuildLessCache = require('./lib/prebuild-less-cache')
|
||||
@ -61,6 +62,7 @@ generateMetadata()
|
||||
generateAPIDocs()
|
||||
dumpSymbols()
|
||||
.then(packageApplication)
|
||||
.then(packagedAppPath => generateStartupSnapshot(packagedAppPath).then(() => packagedAppPath))
|
||||
.then(packagedAppPath => {
|
||||
if (process.platform === 'darwin') {
|
||||
if (argv.codeSign) {
|
||||
|
@ -7,16 +7,27 @@ const semver = require('semver')
|
||||
module.exports = function () {
|
||||
// Chromedriver should be specified as ~x.y where x and y match Electron major/minor
|
||||
const chromedriverVer = buildMetadata.dependencies['electron-chromedriver']
|
||||
const mksnapshotVer = buildMetadata.dependencies['electron-mksnapshot']
|
||||
|
||||
// Always use tilde on electron-chromedriver so that it can pick up the best patch vesion
|
||||
if (!chromedriverVer.startsWith('~')) {
|
||||
throw new Error(`electron-chromedriver version in script/package.json should start with a tilde to match latest patch version.`)
|
||||
}
|
||||
|
||||
if (!mksnapshotVer.startsWith('~')) {
|
||||
throw new Error(`electron-mksnapshot version in script/package.json should start with a tilde to match latest patch version.`)
|
||||
}
|
||||
|
||||
const electronVer = CONFIG.appMetadata.electronVersion
|
||||
if (!semver.satisfies(electronVer, chromedriverVer)) {
|
||||
throw new Error(`electron-chromedriver ${chromedriverVer} incompatible with electron ${electronVer}.\n` +
|
||||
'Did you upgrade electron in package.json and forget to upgrade electron-chromedriver in ' +
|
||||
`script/package.json to '~${semver.major(electronVer)}.${semver.minor(electronVer)}' ?`)
|
||||
}
|
||||
|
||||
if (!semver.satisfies(electronVer, mksnapshotVer)) {
|
||||
throw new Error(`electron-mksnapshot ${mksnapshotVer} incompatible with electron ${electronVer}.\n` +
|
||||
'Did you upgrade electron in package.json and forget to upgrade electron-mksnapshot in ' +
|
||||
`script/package.json to '~${semver.major(electronVer)}.${semver.minor(electronVer)}' ?`)
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ module.exports = function (packagedAppPath) {
|
||||
|
||||
console.log(`Copying icon into "${debianPackageIconsDirPath}"`)
|
||||
fs.copySync(
|
||||
path.join(packagedAppPath, 'resources', 'app.asar.unpacked', 'resources', 'atom.png'),
|
||||
path.join(packagedAppPath, 'resources', 'app', 'resources', 'atom.png'),
|
||||
path.join(debianPackageIconsDirPath, `${atomExecutableName}.png`)
|
||||
)
|
||||
|
||||
|
@ -10,7 +10,7 @@ const spawnSync = require('./spawn-sync')
|
||||
|
||||
const CONFIG = require('../config')
|
||||
|
||||
module.exports = function (packagedAppPath, codeSign) {
|
||||
module.exports = (packagedAppPath, codeSign) => {
|
||||
const archSuffix = process.arch === 'ia32' ? '' : '-' + process.arch
|
||||
const options = {
|
||||
appDirectory: packagedAppPath,
|
||||
@ -42,7 +42,7 @@ module.exports = function (packagedAppPath, codeSign) {
|
||||
console.log('Skipping code-signing. Specify the --code-sign option and provide a ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL environment variable to perform code-signing'.gray)
|
||||
}
|
||||
|
||||
const cleanUp = function () {
|
||||
const cleanUp = () => {
|
||||
if (fs.existsSync(certPath) && !process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH) {
|
||||
console.log(`Deleting certificate at ${certPath}`)
|
||||
fs.removeSync(certPath)
|
||||
@ -57,7 +57,7 @@ module.exports = function (packagedAppPath, codeSign) {
|
||||
}
|
||||
|
||||
// Squirrel signs its own copy of the executables but we need them for the portable ZIP
|
||||
const extractSignedExes = function () {
|
||||
const extractSignedExes = () => {
|
||||
if (signing) {
|
||||
for (let nupkgPath of glob.sync(`${CONFIG.buildOutputPath}/*-full.nupkg`)) {
|
||||
if (nupkgPath.includes(CONFIG.appMetadata.version)) {
|
||||
@ -73,12 +73,9 @@ module.exports = function (packagedAppPath, codeSign) {
|
||||
|
||||
console.log(`Creating Windows Installer for ${packagedAppPath}`)
|
||||
return electronInstaller.createWindowsInstaller(options)
|
||||
.then(extractSignedExes, function (error) {
|
||||
console.log(`Extracting signed executables failed:\n${error}`)
|
||||
cleanUp()
|
||||
})
|
||||
.then(cleanUp, function (error) {
|
||||
console.log(`Windows installer creation failed:\n${error}`)
|
||||
.then(extractSignedExes)
|
||||
.then(cleanUp, error => {
|
||||
cleanUp()
|
||||
return Promise.reject(error)
|
||||
})
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ const path = require('path')
|
||||
const syncRequest = require('sync-request')
|
||||
|
||||
module.exports = function (downloadURL, destinationPath) {
|
||||
console.log(`Dowloading file from GitHub Repository to ${destinationPath}`)
|
||||
console.log(`Downloading file from GitHub Repository to ${destinationPath}`)
|
||||
const response = syncRequest('GET', downloadURL, {
|
||||
'headers': {'Accept': 'application/vnd.github.v3.raw', 'User-Agent': 'Atom Build'}
|
||||
})
|
||||
|
@ -28,7 +28,7 @@ function buildBundledPackagesMetadata () {
|
||||
const packageMetadataPath = path.join(packagePath, 'package.json')
|
||||
const packageMetadata = JSON.parse(fs.readFileSync(packageMetadataPath, 'utf8'))
|
||||
normalizePackageData(packageMetadata, (msg) => {
|
||||
throw new Error(`Invalid package metadata. ${packageName}: ${msg}`)
|
||||
console.warn(`Invalid package metadata. ${packageMetadata.name}: ${msg}`)
|
||||
}, true)
|
||||
if (packageMetadata.repository && packageMetadata.repository.url && packageMetadata.repository.type === 'git') {
|
||||
packageMetadata.repository.url = packageMetadata.repository.url.replace(/^git\+/, '')
|
||||
|
86
script/lib/generate-startup-snapshot.js
Normal file
86
script/lib/generate-startup-snapshot.js
Normal file
@ -0,0 +1,86 @@
|
||||
const childProcess = require('child_process')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const electronLink = require('electron-link')
|
||||
const CONFIG = require('../config')
|
||||
const vm = require('vm')
|
||||
|
||||
module.exports = function (packagedAppPath) {
|
||||
const snapshotScriptPath = path.join(CONFIG.buildOutputPath, 'startup.js')
|
||||
const coreModules = new Set(['electron', 'atom', 'shell', 'WNdb', 'lapack', 'remote'])
|
||||
const baseDirPath = path.join(CONFIG.intermediateAppPath, 'static')
|
||||
let processedFiles = 0
|
||||
|
||||
return electronLink({
|
||||
baseDirPath,
|
||||
mainPath: path.resolve(baseDirPath, '..', 'src', 'initialize-application-window.js'),
|
||||
cachePath: path.join(CONFIG.atomHomeDirPath, 'snapshot-cache'),
|
||||
shouldExcludeModule: (modulePath) => {
|
||||
if (processedFiles > 0) {
|
||||
process.stdout.write('\r')
|
||||
}
|
||||
process.stdout.write(`Generating snapshot script at "${snapshotScriptPath}" (${++processedFiles})`)
|
||||
|
||||
const relativePath = path.relative(baseDirPath, modulePath)
|
||||
return (
|
||||
modulePath.endsWith('.node') ||
|
||||
coreModules.has(modulePath) ||
|
||||
(relativePath.startsWith(path.join('..', 'src')) && relativePath.endsWith('-element.js')) ||
|
||||
relativePath == path.join('..', 'exports', 'atom.js') ||
|
||||
relativePath == path.join('..', 'src', 'electron-shims.js') ||
|
||||
relativePath == path.join('..', 'src', 'safe-clipboard.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'atom-keymap', 'lib', 'command-event.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'babel-core', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'cached-run-in-this-context', 'lib', 'main.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'coffee-script', 'lib', 'coffee-script', 'register.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'cson-parser', 'node_modules', 'coffee-script', 'lib', 'coffee-script', 'register.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'decompress-zip', 'lib', 'decompress-zip.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'debug', 'node.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'git-utils', 'lib', 'git.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'glob', 'glob.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'graceful-fs', 'graceful-fs.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'htmlparser2', 'lib', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'iconv-lite', 'encodings', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'less', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'less', 'lib', 'less', 'fs.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'less', 'lib', 'less-node', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'less', 'node_modules', 'graceful-fs', 'graceful-fs.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'superstring', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'oniguruma', 'lib', 'oniguruma.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'request', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'resolve', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'resolve', 'lib', 'core.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'settings-view', 'node_modules', 'glob', 'glob.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'spellchecker', 'lib', 'spellchecker.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'spelling-manager', 'node_modules', 'natural', 'lib', 'natural', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'tar', 'tar.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'temp', 'lib', 'temp.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'tmp', 'lib', 'tmp.js')
|
||||
)
|
||||
}
|
||||
}).then((snapshotScript) => {
|
||||
fs.writeFileSync(snapshotScriptPath, snapshotScript)
|
||||
process.stdout.write('\n')
|
||||
|
||||
console.log('Verifying if snapshot can be executed via `mksnapshot`')
|
||||
vm.runInNewContext(snapshotScript, undefined, {filename: snapshotScriptPath, displayErrors: true})
|
||||
|
||||
const generatedStartupBlobPath = path.join(CONFIG.buildOutputPath, 'snapshot_blob.bin')
|
||||
console.log(`Generating startup blob at "${generatedStartupBlobPath}"`)
|
||||
childProcess.execFileSync(
|
||||
path.join(CONFIG.repositoryRootPath, 'script', 'node_modules', 'electron-mksnapshot', 'bin', 'mksnapshot'),
|
||||
[snapshotScriptPath, '--startup_blob', generatedStartupBlobPath]
|
||||
)
|
||||
|
||||
let startupBlobDestinationPath
|
||||
if (process.platform === 'darwin') {
|
||||
startupBlobDestinationPath = `${packagedAppPath}/Contents/Frameworks/Electron Framework.framework/Resources/snapshot_blob.bin`
|
||||
} else {
|
||||
startupBlobDestinationPath = path.join(packagedAppPath, 'snapshot_blob.bin')
|
||||
}
|
||||
|
||||
console.log(`Moving generated startup blob into "${startupBlobDestinationPath}"`)
|
||||
fs.unlinkSync(startupBlobDestinationPath)
|
||||
fs.renameSync(generatedStartupBlobPath, startupBlobDestinationPath)
|
||||
})
|
||||
}
|
@ -19,7 +19,6 @@ module.exports = function () {
|
||||
'app-copyright': `Copyright © 2014-${(new Date()).getFullYear()} GitHub, Inc. All rights reserved.`,
|
||||
'app-version': CONFIG.appMetadata.version,
|
||||
'arch': process.platform === 'darwin' ? 'x64' : process.arch, // OS X is 64-bit only
|
||||
'asar': {unpack: buildAsarUnpackGlobExpression()},
|
||||
'build-version': CONFIG.appMetadata.version,
|
||||
'download': {cache: CONFIG.electronDownloadPath},
|
||||
'dir': CONFIG.intermediateAppPath,
|
||||
@ -96,20 +95,6 @@ function chmodNodeFiles (packagedAppPath) {
|
||||
childProcess.execSync(`find "${packagedAppPath}" -type f -name *.node -exec chmod a-x {} \\;`)
|
||||
}
|
||||
|
||||
function buildAsarUnpackGlobExpression () {
|
||||
const unpack = [
|
||||
'*.node',
|
||||
'ctags-config',
|
||||
'ctags-darwin',
|
||||
'ctags-linux',
|
||||
'ctags-win32.exe',
|
||||
path.join('**', 'node_modules', 'spellchecker', '**'),
|
||||
path.join('**', 'resources', 'atom.png')
|
||||
]
|
||||
|
||||
return `{${unpack.join(',')}}`
|
||||
}
|
||||
|
||||
function getAppName () {
|
||||
if (process.platform === 'darwin') {
|
||||
return CONFIG.channel === 'beta' ? 'Atom Beta' : 'Atom'
|
||||
|
@ -3,17 +3,20 @@
|
||||
"description": "Atom build scripts",
|
||||
"dependencies": {
|
||||
"async": "2.0.1",
|
||||
"babel-core": "5.8.38",
|
||||
"coffeelint": "1.15.7",
|
||||
"colors": "1.1.2",
|
||||
"csslint": "1.0.2",
|
||||
"donna": "1.0.13",
|
||||
"electron-chromedriver": "~1.3",
|
||||
"electron-link": "0.0.20",
|
||||
"electron-mksnapshot": "~1.3",
|
||||
"electron-packager": "7.3.0",
|
||||
"electron-winstaller": "2.5.1",
|
||||
"fs-extra": "0.30.0",
|
||||
"glob": "7.0.3",
|
||||
"joanna": "0.0.8",
|
||||
"legal-eagle": "0.13.0",
|
||||
"legal-eagle": "0.14.0",
|
||||
"lodash.template": "4.4.0",
|
||||
"minidump": "0.9.0",
|
||||
"mkdirp": "0.5.1",
|
||||
|
@ -126,6 +126,7 @@ describe "AtomEnvironment", ->
|
||||
|
||||
beforeEach ->
|
||||
errors = []
|
||||
spyOn(atom, 'isReleasedVersion').andReturn(true)
|
||||
atom.onDidFailAssertion (error) -> errors.push(error)
|
||||
|
||||
describe "if the condition is false", ->
|
||||
@ -147,6 +148,11 @@ describe "AtomEnvironment", ->
|
||||
atom.assert(false, "a == b", {foo: 'bar'})
|
||||
expect(errors[0].metadata).toEqual {foo: 'bar'}
|
||||
|
||||
describe "when Atom has been built from source", ->
|
||||
it "throws an error", ->
|
||||
atom.isReleasedVersion.andReturn(false)
|
||||
expect(-> atom.assert(false, 'testing')).toThrow('Assertion failed: testing')
|
||||
|
||||
describe "if the condition is true", ->
|
||||
it "does nothing", ->
|
||||
result = atom.assert(true, "a == b")
|
||||
@ -334,7 +340,8 @@ describe "AtomEnvironment", ->
|
||||
it "saves the BlobStore so it can be loaded after reload", ->
|
||||
configDirPath = temp.mkdirSync('atom-spec-environment')
|
||||
fakeBlobStore = jasmine.createSpyObj("blob store", ["save"])
|
||||
atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, enablePersistence: true, configDirPath, blobStore: fakeBlobStore, window, document})
|
||||
atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, enablePersistence: true})
|
||||
atomEnvironment.initialize({configDirPath, blobStore: fakeBlobStore, window, document})
|
||||
|
||||
atomEnvironment.unloadEditorWindow()
|
||||
|
||||
@ -351,7 +358,8 @@ describe "AtomEnvironment", ->
|
||||
head: document.createElement('head')
|
||||
body: document.createElement('body')
|
||||
}
|
||||
atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, window, document: fakeDocument})
|
||||
atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate})
|
||||
atomEnvironment.initialize({window, document: fakeDocument})
|
||||
spyOn(atomEnvironment.packages, 'getAvailablePackagePaths').andReturn []
|
||||
spyOn(atomEnvironment, 'displayWindow').andReturn Promise.resolve()
|
||||
atomEnvironment.startEditorWindow()
|
||||
|
@ -11,9 +11,8 @@ describe('AutoUpdateManager (renderer)', () => {
|
||||
let autoUpdateManager
|
||||
|
||||
beforeEach(() => {
|
||||
autoUpdateManager = new AutoUpdateManager({
|
||||
applicationDelegate: atom.applicationDelegate
|
||||
})
|
||||
autoUpdateManager = new AutoUpdateManager({applicationDelegate: atom.applicationDelegate})
|
||||
autoUpdateManager.initialize()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -25,7 +25,8 @@ describe "CommandInstaller on #darwin", ->
|
||||
|
||||
it "shows an error dialog when installing commands interactively fails", ->
|
||||
appDelegate = jasmine.createSpyObj("appDelegate", ["confirm"])
|
||||
installer = new CommandInstaller("2.0.2", appDelegate)
|
||||
installer = new CommandInstaller(appDelegate)
|
||||
installer.initialize("2.0.2")
|
||||
spyOn(installer, "installAtomCommand").andCallFake (__, callback) -> callback(new Error("an error"))
|
||||
|
||||
installer.installShellCommandsInteractively()
|
||||
@ -48,7 +49,8 @@ describe "CommandInstaller on #darwin", ->
|
||||
|
||||
it "shows a success dialog when installing commands interactively succeeds", ->
|
||||
appDelegate = jasmine.createSpyObj("appDelegate", ["confirm"])
|
||||
installer = new CommandInstaller("2.0.2", appDelegate)
|
||||
installer = new CommandInstaller(appDelegate)
|
||||
installer.initialize("2.0.2")
|
||||
spyOn(installer, "installAtomCommand").andCallFake (__, callback) -> callback()
|
||||
spyOn(installer, "installApmCommand").andCallFake (__, callback) -> callback()
|
||||
|
||||
@ -61,7 +63,8 @@ describe "CommandInstaller on #darwin", ->
|
||||
|
||||
describe "when using a stable version of atom", ->
|
||||
beforeEach ->
|
||||
installer = new CommandInstaller("2.0.2")
|
||||
installer = new CommandInstaller()
|
||||
installer.initialize("2.0.2")
|
||||
|
||||
it "symlinks the atom command as 'atom'", ->
|
||||
installedAtomPath = path.join(installationPath, 'atom')
|
||||
@ -91,7 +94,8 @@ describe "CommandInstaller on #darwin", ->
|
||||
|
||||
describe "when using a beta version of atom", ->
|
||||
beforeEach ->
|
||||
installer = new CommandInstaller("2.2.0-beta.0")
|
||||
installer = new CommandInstaller()
|
||||
installer.initialize("2.2.0-beta.0")
|
||||
|
||||
it "symlinks the atom command as 'atom-beta'", ->
|
||||
installedAtomPath = path.join(installationPath, 'atom-beta')
|
||||
|
@ -5,7 +5,8 @@ describe "ContextMenuManager", ->
|
||||
|
||||
beforeEach ->
|
||||
{resourcePath} = atom.getLoadSettings()
|
||||
contextMenu = new ContextMenuManager({resourcePath, keymapManager: atom.keymaps})
|
||||
contextMenu = new ContextMenuManager({keymapManager: atom.keymaps})
|
||||
contextMenu.initialize({resourcePath})
|
||||
|
||||
parent = document.createElement("div")
|
||||
child = document.createElement("div")
|
||||
|
@ -3,7 +3,10 @@ const DOMElementPool = require ('../src/dom-element-pool')
|
||||
describe('DOMElementPool', function () {
|
||||
let domElementPool
|
||||
|
||||
beforeEach(() => { domElementPool = new DOMElementPool() })
|
||||
beforeEach(() => {
|
||||
domElementPool = new DOMElementPool()
|
||||
spyOn(atom, 'isReleasedVersion').andReturn(true)
|
||||
})
|
||||
|
||||
it('builds DOM nodes, recycling them when they are freed', function () {
|
||||
let elements
|
||||
|
@ -14,78 +14,75 @@ describe "FileSystemBlobStore", ->
|
||||
fs.removeSync(storageDirectory)
|
||||
|
||||
it "is empty when the file doesn't exist", ->
|
||||
expect(blobStore.get("foo", "invalidation-key-1")).toBeUndefined()
|
||||
expect(blobStore.get("bar", "invalidation-key-2")).toBeUndefined()
|
||||
expect(blobStore.get("foo")).toBeUndefined()
|
||||
expect(blobStore.get("bar")).toBeUndefined()
|
||||
|
||||
it "allows to read and write buffers from/to memory without persisting them", ->
|
||||
blobStore.set("foo", "invalidation-key-1", new Buffer("foo"))
|
||||
blobStore.set("bar", "invalidation-key-2", new Buffer("bar"))
|
||||
blobStore.set("foo", new Buffer("foo"))
|
||||
blobStore.set("bar", new Buffer("bar"))
|
||||
|
||||
expect(blobStore.get("foo", "invalidation-key-1")).toEqual(new Buffer("foo"))
|
||||
expect(blobStore.get("bar", "invalidation-key-2")).toEqual(new Buffer("bar"))
|
||||
expect(blobStore.get("foo")).toEqual(new Buffer("foo"))
|
||||
expect(blobStore.get("bar")).toEqual(new Buffer("bar"))
|
||||
|
||||
expect(blobStore.get("foo", "unexisting-key")).toBeUndefined()
|
||||
expect(blobStore.get("bar", "unexisting-key")).toBeUndefined()
|
||||
expect(blobStore.get("baz")).toBeUndefined()
|
||||
expect(blobStore.get("qux")).toBeUndefined()
|
||||
|
||||
it "persists buffers when saved and retrieves them on load, giving priority to in-memory ones", ->
|
||||
blobStore.set("foo", "invalidation-key-1", new Buffer("foo"))
|
||||
blobStore.set("bar", "invalidation-key-2", new Buffer("bar"))
|
||||
blobStore.set("foo", new Buffer("foo"))
|
||||
blobStore.set("bar", new Buffer("bar"))
|
||||
blobStore.save()
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
|
||||
expect(blobStore.get("foo", "invalidation-key-1")).toEqual(new Buffer("foo"))
|
||||
expect(blobStore.get("bar", "invalidation-key-2")).toEqual(new Buffer("bar"))
|
||||
expect(blobStore.get("foo", "unexisting-key")).toBeUndefined()
|
||||
expect(blobStore.get("bar", "unexisting-key")).toBeUndefined()
|
||||
expect(blobStore.get("foo")).toEqual(new Buffer("foo"))
|
||||
expect(blobStore.get("bar")).toEqual(new Buffer("bar"))
|
||||
expect(blobStore.get("baz")).toBeUndefined()
|
||||
expect(blobStore.get("qux")).toBeUndefined()
|
||||
|
||||
blobStore.set("foo", "new-key", new Buffer("changed"))
|
||||
blobStore.set("foo", new Buffer("changed"))
|
||||
|
||||
expect(blobStore.get("foo", "new-key")).toEqual(new Buffer("changed"))
|
||||
expect(blobStore.get("foo", "invalidation-key-1")).toBeUndefined()
|
||||
expect(blobStore.get("foo")).toEqual(new Buffer("changed"))
|
||||
|
||||
it "persists both in-memory and previously stored buffers when saved", ->
|
||||
blobStore.set("foo", "invalidation-key-1", new Buffer("foo"))
|
||||
blobStore.set("bar", "invalidation-key-2", new Buffer("bar"))
|
||||
it "persists in-memory and previously stored buffers, and deletes unused keys when saved", ->
|
||||
blobStore.set("foo", new Buffer("foo"))
|
||||
blobStore.set("bar", new Buffer("bar"))
|
||||
blobStore.save()
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
blobStore.set("bar", "invalidation-key-3", new Buffer("changed"))
|
||||
blobStore.set("qux", "invalidation-key-4", new Buffer("qux"))
|
||||
blobStore.set("bar", new Buffer("changed"))
|
||||
blobStore.set("qux", new Buffer("qux"))
|
||||
blobStore.save()
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
|
||||
expect(blobStore.get("foo", "invalidation-key-1")).toEqual(new Buffer("foo"))
|
||||
expect(blobStore.get("bar", "invalidation-key-3")).toEqual(new Buffer("changed"))
|
||||
expect(blobStore.get("qux", "invalidation-key-4")).toEqual(new Buffer("qux"))
|
||||
expect(blobStore.get("foo", "unexisting-key")).toBeUndefined()
|
||||
expect(blobStore.get("bar", "invalidation-key-2")).toBeUndefined()
|
||||
expect(blobStore.get("qux", "unexisting-key")).toBeUndefined()
|
||||
expect(blobStore.get("foo")).toBeUndefined()
|
||||
expect(blobStore.get("bar")).toEqual(new Buffer("changed"))
|
||||
expect(blobStore.get("qux")).toEqual(new Buffer("qux"))
|
||||
|
||||
it "allows to delete keys from both memory and stored buffers", ->
|
||||
blobStore.set("a", "invalidation-key-1", new Buffer("a"))
|
||||
blobStore.set("b", "invalidation-key-2", new Buffer("b"))
|
||||
blobStore.set("a", new Buffer("a"))
|
||||
blobStore.set("b", new Buffer("b"))
|
||||
blobStore.save()
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
|
||||
blobStore.set("b", "invalidation-key-3", new Buffer("b"))
|
||||
blobStore.set("c", "invalidation-key-4", new Buffer("c"))
|
||||
blobStore.get("a") # prevent the key from being deleted on save
|
||||
blobStore.set("b", new Buffer("b"))
|
||||
blobStore.set("c", new Buffer("c"))
|
||||
blobStore.delete("b")
|
||||
blobStore.delete("c")
|
||||
blobStore.save()
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
|
||||
expect(blobStore.get("a", "invalidation-key-1")).toEqual(new Buffer("a"))
|
||||
expect(blobStore.get("b", "invalidation-key-2")).toBeUndefined()
|
||||
expect(blobStore.get("b", "invalidation-key-3")).toBeUndefined()
|
||||
expect(blobStore.get("c", "invalidation-key-4")).toBeUndefined()
|
||||
expect(blobStore.get("a")).toEqual(new Buffer("a"))
|
||||
expect(blobStore.get("b")).toBeUndefined()
|
||||
expect(blobStore.get("b")).toBeUndefined()
|
||||
expect(blobStore.get("c")).toBeUndefined()
|
||||
|
||||
it "ignores errors when loading an invalid blob store", ->
|
||||
blobStore.set("a", "invalidation-key-1", new Buffer("a"))
|
||||
blobStore.set("b", "invalidation-key-2", new Buffer("b"))
|
||||
blobStore.set("a", new Buffer("a"))
|
||||
blobStore.set("b", new Buffer("b"))
|
||||
blobStore.save()
|
||||
|
||||
# Simulate corruption
|
||||
@ -95,14 +92,14 @@ describe "FileSystemBlobStore", ->
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
|
||||
expect(blobStore.get("a", "invalidation-key-1")).toBeUndefined()
|
||||
expect(blobStore.get("b", "invalidation-key-2")).toBeUndefined()
|
||||
expect(blobStore.get("a")).toBeUndefined()
|
||||
expect(blobStore.get("b")).toBeUndefined()
|
||||
|
||||
blobStore.set("a", "invalidation-key-1", new Buffer("x"))
|
||||
blobStore.set("b", "invalidation-key-2", new Buffer("y"))
|
||||
blobStore.set("a", new Buffer("x"))
|
||||
blobStore.set("b", new Buffer("y"))
|
||||
blobStore.save()
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
|
||||
expect(blobStore.get("a", "invalidation-key-1")).toEqual(new Buffer("x"))
|
||||
expect(blobStore.get("b", "invalidation-key-2")).toEqual(new Buffer("y"))
|
||||
expect(blobStore.get("a")).toEqual(new Buffer("x"))
|
||||
expect(blobStore.get("b")).toEqual(new Buffer("y"))
|
||||
|
@ -31,11 +31,6 @@ describe "GitRepository", ->
|
||||
expect(-> new GitRepository(path.join(temp.dir, 'nogit.txt'))).toThrow()
|
||||
|
||||
describe ".getPath()", ->
|
||||
it "returns the repository path for a .git directory path with a file", ->
|
||||
return if process.platform is 'win32' #Win32TestFailures - libgit2 does not detect files in .git folders
|
||||
repo = new GitRepository(path.join(__dirname, 'fixtures', 'git', 'master.git', 'HEAD'))
|
||||
expect(repo.getPath()).toBe path.join(__dirname, 'fixtures', 'git', 'master.git')
|
||||
|
||||
it "returns the repository path for a .git directory path with a directory", ->
|
||||
repo = new GitRepository(path.join(__dirname, 'fixtures', 'git', 'master.git', 'objects'))
|
||||
expect(repo.getPath()).toBe path.join(__dirname, 'fixtures', 'git', 'master.git')
|
||||
|
@ -4,27 +4,24 @@ import {it, fit, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers'
|
||||
import {Emitter, Disposable, CompositeDisposable} from 'event-kit'
|
||||
|
||||
import {HistoryManager, HistoryProject} from '../src/history-manager'
|
||||
import StateStore from '../src/state-store'
|
||||
|
||||
describe("HistoryManager", () => {
|
||||
let historyManager, commandRegistry, project, localStorage, stateStore
|
||||
let historyManager, commandRegistry, project, stateStore
|
||||
let commandDisposable, projectDisposable
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(async () => {
|
||||
commandDisposable = jasmine.createSpyObj('Disposable', ['dispose'])
|
||||
commandRegistry = jasmine.createSpyObj('CommandRegistry', ['add'])
|
||||
commandRegistry.add.andReturn(commandDisposable)
|
||||
|
||||
localStorage = jasmine.createSpyObj('LocalStorage', ['getItem', 'setItem'])
|
||||
localStorage.items = {
|
||||
history: JSON.stringify({
|
||||
projects: [
|
||||
{ paths: ['/1', 'c:\\2'], lastOpened: new Date(2016, 9, 17, 17, 16, 23) },
|
||||
{ paths: ['/test'], lastOpened: new Date(2016, 9, 17, 11, 12, 13) }
|
||||
]
|
||||
})
|
||||
}
|
||||
localStorage.getItem.andCallFake((key) => localStorage.items[key])
|
||||
localStorage.setItem.andCallFake((key, value) => localStorage.items[key] = value)
|
||||
stateStore = new StateStore('history-manager-test', 1)
|
||||
await stateStore.save('history-manager', {
|
||||
projects: [
|
||||
{paths: ['/1', 'c:\\2'], lastOpened: new Date(2016, 9, 17, 17, 16, 23)},
|
||||
{paths: ['/test'], lastOpened: new Date(2016, 9, 17, 11, 12, 13)}
|
||||
]
|
||||
})
|
||||
|
||||
projectDisposable = jasmine.createSpyObj('Disposable', ['dispose'])
|
||||
project = jasmine.createSpyObj('Project', ['onDidChangePaths'])
|
||||
@ -33,14 +30,20 @@ describe("HistoryManager", () => {
|
||||
return projectDisposable
|
||||
})
|
||||
|
||||
historyManager = new HistoryManager({project, commands:commandRegistry, localStorage})
|
||||
historyManager = new HistoryManager({stateStore, project, commands: commandRegistry})
|
||||
historyManager.initialize(window.localStorage)
|
||||
await historyManager.loadState()
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
await stateStore.clear()
|
||||
})
|
||||
|
||||
describe("constructor", () => {
|
||||
it("registers the 'clear-project-history' command function", () => {
|
||||
expect(commandRegistry.add).toHaveBeenCalled()
|
||||
const cmdCall = commandRegistry.add.calls[0]
|
||||
expect(cmdCall.args.length).toBe(2)
|
||||
expect(cmdCall.args.length).toBe(3)
|
||||
expect(cmdCall.args[0]).toBe('atom-workspace')
|
||||
expect(typeof cmdCall.args[1]['application:clear-project-history']).toBe('function')
|
||||
})
|
||||
@ -65,33 +68,28 @@ describe("HistoryManager", () => {
|
||||
})
|
||||
|
||||
describe("clearProjects", () => {
|
||||
it("clears the list of projects", () => {
|
||||
it("clears the list of projects", async () => {
|
||||
expect(historyManager.getProjects().length).not.toBe(0)
|
||||
historyManager.clearProjects()
|
||||
await historyManager.clearProjects()
|
||||
expect(historyManager.getProjects().length).toBe(0)
|
||||
})
|
||||
|
||||
it("saves the state", () => {
|
||||
expect(localStorage.setItem).not.toHaveBeenCalled()
|
||||
historyManager.clearProjects()
|
||||
expect(localStorage.setItem).toHaveBeenCalled()
|
||||
expect(localStorage.setItem.calls[0].args[0]).toBe('history')
|
||||
it("saves the state", async () => {
|
||||
await historyManager.clearProjects()
|
||||
const historyManager2 = new HistoryManager({stateStore, localStorage: window.localStorage, project, commands: commandRegistry})
|
||||
await historyManager2.loadState()
|
||||
expect(historyManager.getProjects().length).toBe(0)
|
||||
})
|
||||
|
||||
it("fires the onDidChangeProjects event", () => {
|
||||
expect(localStorage.setItem).not.toHaveBeenCalled()
|
||||
historyManager.clearProjects()
|
||||
expect(localStorage.setItem).toHaveBeenCalled()
|
||||
expect(localStorage.setItem.calls[0].args[0]).toBe('history')
|
||||
it("fires the onDidChangeProjects event", async () => {
|
||||
const didChangeSpy = jasmine.createSpy()
|
||||
historyManager.onDidChangeProjects(didChangeSpy)
|
||||
await historyManager.clearProjects()
|
||||
expect(historyManager.getProjects().length).toBe(0)
|
||||
expect(didChangeSpy).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
it("loads state", () => {
|
||||
expect(localStorage.getItem).toHaveBeenCalledWith('history')
|
||||
})
|
||||
|
||||
it("listens to project.onDidChangePaths adding a new project", () => {
|
||||
const start = new Date()
|
||||
project.didChangePathsListener(['/a/new', '/path/or/two'])
|
||||
@ -112,61 +110,61 @@ describe("HistoryManager", () => {
|
||||
})
|
||||
|
||||
describe("loadState", () => {
|
||||
it("defaults to an empty array if no state", () => {
|
||||
localStorage.items.history = null
|
||||
historyManager.loadState()
|
||||
it("defaults to an empty array if no state", async () => {
|
||||
await stateStore.clear()
|
||||
await historyManager.loadState()
|
||||
expect(historyManager.getProjects()).toEqual([])
|
||||
})
|
||||
|
||||
it("defaults to an empty array if no projects", () => {
|
||||
localStorage.items.history = JSON.stringify('')
|
||||
historyManager.loadState()
|
||||
it("defaults to an empty array if no projects", async () => {
|
||||
await stateStore.save('history-manager', {})
|
||||
await historyManager.loadState()
|
||||
expect(historyManager.getProjects()).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe("addProject", () => {
|
||||
it("adds a new project to the end", () => {
|
||||
it("adds a new project to the end", async () => {
|
||||
const date = new Date(2010, 10, 9, 8, 7, 6)
|
||||
historyManager.addProject(['/a/b'], date)
|
||||
await historyManager.addProject(['/a/b'], date)
|
||||
const projects = historyManager.getProjects()
|
||||
expect(projects.length).toBe(3)
|
||||
expect(projects[2].paths).toEqual(['/a/b'])
|
||||
expect(projects[2].lastOpened).toBe(date)
|
||||
})
|
||||
|
||||
it("adds a new project to the start", () => {
|
||||
it("adds a new project to the start", async () => {
|
||||
const date = new Date()
|
||||
historyManager.addProject(['/so/new'], date)
|
||||
await historyManager.addProject(['/so/new'], date)
|
||||
const projects = historyManager.getProjects()
|
||||
expect(projects.length).toBe(3)
|
||||
expect(projects[0].paths).toEqual(['/so/new'])
|
||||
expect(projects[0].lastOpened).toBe(date)
|
||||
})
|
||||
|
||||
it("updates an existing project and moves it to the start", () => {
|
||||
it("updates an existing project and moves it to the start", async () => {
|
||||
const date = new Date()
|
||||
historyManager.addProject(['/test'], date)
|
||||
await historyManager.addProject(['/test'], date)
|
||||
const projects = historyManager.getProjects()
|
||||
expect(projects.length).toBe(2)
|
||||
expect(projects[0].paths).toEqual(['/test'])
|
||||
expect(projects[0].lastOpened).toBe(date)
|
||||
})
|
||||
|
||||
it("fires the onDidChangeProjects event when adding a project", () => {
|
||||
it("fires the onDidChangeProjects event when adding a project", async () => {
|
||||
const didChangeSpy = jasmine.createSpy()
|
||||
const beforeCount = historyManager.getProjects().length
|
||||
historyManager.onDidChangeProjects(didChangeSpy)
|
||||
historyManager.addProject(['/test-new'], new Date())
|
||||
await historyManager.addProject(['/test-new'], new Date())
|
||||
expect(didChangeSpy).toHaveBeenCalled()
|
||||
expect(historyManager.getProjects().length).toBe(beforeCount + 1)
|
||||
})
|
||||
|
||||
it("fires the onDidChangeProjects event when updating a project", () => {
|
||||
it("fires the onDidChangeProjects event when updating a project", async () => {
|
||||
const didChangeSpy = jasmine.createSpy()
|
||||
const beforeCount = historyManager.getProjects().length
|
||||
historyManager.onDidChangeProjects(didChangeSpy)
|
||||
historyManager.addProject(['/test'], new Date())
|
||||
await historyManager.addProject(['/test'], new Date())
|
||||
expect(didChangeSpy).toHaveBeenCalled()
|
||||
expect(historyManager.getProjects().length).toBe(beforeCount)
|
||||
})
|
||||
@ -186,14 +184,12 @@ describe("HistoryManager", () => {
|
||||
})
|
||||
|
||||
describe("saveState" ,() => {
|
||||
it("saves the state", () => {
|
||||
historyManager.addProject(["/save/state"])
|
||||
historyManager.saveState()
|
||||
expect(localStorage.setItem).toHaveBeenCalled()
|
||||
expect(localStorage.setItem.calls[0].args[0]).toBe('history')
|
||||
expect(localStorage.items['history']).toContain('/save/state')
|
||||
historyManager.loadState()
|
||||
expect(historyManager.getProjects()[0].paths).toEqual(['/save/state'])
|
||||
it("saves the state", async () => {
|
||||
await historyManager.addProject(["/save/state"])
|
||||
await historyManager.saveState()
|
||||
const historyManager2 = new HistoryManager({stateStore, localStorage: window.localStorage, project, commands: commandRegistry})
|
||||
await historyManager2.loadState()
|
||||
expect(historyManager2.getProjects()[0].paths).toEqual(['/save/state'])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -112,7 +112,7 @@ describe("FileRecoveryService", () => {
|
||||
const mockWindow = {}
|
||||
const filePath = temp.path()
|
||||
fs.writeFileSync(filePath, "content")
|
||||
fs.chmodSync(filePath, 0o444)
|
||||
fs.chmodSync(filePath, 0444)
|
||||
|
||||
let logs = []
|
||||
this.stub(console, 'log', (message) => logs.push(message))
|
||||
|
@ -5,11 +5,8 @@ describe "MenuManager", ->
|
||||
menu = null
|
||||
|
||||
beforeEach ->
|
||||
menu = new MenuManager(
|
||||
resourcePath: atom.getLoadSettings().resourcePath
|
||||
keymapManager: atom.keymaps
|
||||
packageManager: atom.packages
|
||||
)
|
||||
menu = new MenuManager({keymapManager: atom.keymaps, packageManager: atom.packages})
|
||||
menu.initialize({resourcePath: atom.getLoadSettings().resourcePath})
|
||||
|
||||
describe "::add(items)", ->
|
||||
it "can add new menus that can be removed with the returned disposable", ->
|
||||
|
@ -9,16 +9,18 @@ describe "NativeCompileCache", ->
|
||||
beforeEach ->
|
||||
cachedFiles = []
|
||||
fakeCacheStore = jasmine.createSpyObj("cache store", ["set", "get", "has", "delete"])
|
||||
fakeCacheStore.has.andCallFake (cacheKey, invalidationKey) ->
|
||||
fakeCacheStore.get(cacheKey, invalidationKey)?
|
||||
fakeCacheStore.get.andCallFake (cacheKey, invalidationKey) ->
|
||||
|
||||
fakeCacheStore.has.andCallFake (cacheKey) ->
|
||||
fakeCacheStore.get(cacheKey)?
|
||||
|
||||
fakeCacheStore.get.andCallFake (cacheKey) ->
|
||||
for entry in cachedFiles by -1
|
||||
continue if entry.cacheKey isnt cacheKey
|
||||
continue if entry.invalidationKey isnt invalidationKey
|
||||
return entry.cacheBuffer
|
||||
return
|
||||
fakeCacheStore.set.andCallFake (cacheKey, invalidationKey, cacheBuffer) ->
|
||||
cachedFiles.push({cacheKey, invalidationKey, cacheBuffer})
|
||||
|
||||
fakeCacheStore.set.andCallFake (cacheKey, cacheBuffer) ->
|
||||
cachedFiles.push({cacheKey, cacheBuffer})
|
||||
|
||||
nativeCompileCache.setCacheStore(fakeCacheStore)
|
||||
nativeCompileCache.setV8Version("a-v8-version")
|
||||
@ -29,13 +31,10 @@ describe "NativeCompileCache", ->
|
||||
fn2 = require('./fixtures/native-cache/file-2')
|
||||
|
||||
expect(cachedFiles.length).toBe(2)
|
||||
|
||||
expect(cachedFiles[0].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-1'))
|
||||
expect(cachedFiles[0].cacheBuffer).toBeInstanceOf(Uint8Array)
|
||||
expect(cachedFiles[0].cacheBuffer.length).toBeGreaterThan(0)
|
||||
expect(fn1()).toBe(1)
|
||||
|
||||
expect(cachedFiles[1].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-2'))
|
||||
expect(cachedFiles[1].cacheBuffer).toBeInstanceOf(Uint8Array)
|
||||
expect(cachedFiles[1].cacheBuffer.length).toBeGreaterThan(0)
|
||||
expect(fn2()).toBe(2)
|
||||
@ -51,7 +50,6 @@ describe "NativeCompileCache", ->
|
||||
fn4 = require('./fixtures/native-cache/file-4')
|
||||
|
||||
expect(cachedFiles.length).toBe(1)
|
||||
expect(cachedFiles[0].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-4'))
|
||||
expect(cachedFiles[0].cacheBuffer).toBeInstanceOf(Uint8Array)
|
||||
expect(cachedFiles[0].cacheBuffer.length).toBeGreaterThan(0)
|
||||
expect(fn4()).toBe("file-4")
|
||||
@ -61,8 +59,6 @@ describe "NativeCompileCache", ->
|
||||
fn4 = require('./fixtures/native-cache/file-4')
|
||||
|
||||
expect(cachedFiles.length).toBe(2)
|
||||
expect(cachedFiles[1].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-4'))
|
||||
expect(cachedFiles[1].invalidationKey).not.toBe(cachedFiles[0].invalidationKey)
|
||||
expect(cachedFiles[1].cacheBuffer).toBeInstanceOf(Uint8Array)
|
||||
expect(cachedFiles[1].cacheBuffer.length).toBeGreaterThan(0)
|
||||
|
||||
@ -79,7 +75,6 @@ describe "NativeCompileCache", ->
|
||||
fn5 = require('./fixtures/native-cache/file-5')
|
||||
|
||||
expect(cachedFiles.length).toBe(1)
|
||||
expect(cachedFiles[0].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-5'))
|
||||
expect(cachedFiles[0].cacheBuffer).toBeInstanceOf(Uint8Array)
|
||||
expect(cachedFiles[0].cacheBuffer.length).toBeGreaterThan(0)
|
||||
expect(fn5()).toBe("file-5")
|
||||
@ -89,8 +84,6 @@ describe "NativeCompileCache", ->
|
||||
fn5 = require('./fixtures/native-cache/file-5')
|
||||
|
||||
expect(cachedFiles.length).toBe(2)
|
||||
expect(cachedFiles[1].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-5'))
|
||||
expect(cachedFiles[1].invalidationKey).not.toBe(cachedFiles[0].invalidationKey)
|
||||
expect(cachedFiles[1].cacheBuffer).toBeInstanceOf(Uint8Array)
|
||||
expect(cachedFiles[1].cacheBuffer.length).toBeGreaterThan(0)
|
||||
|
||||
@ -100,5 +93,5 @@ describe "NativeCompileCache", ->
|
||||
|
||||
fn3 = require('./fixtures/native-cache/file-3')
|
||||
|
||||
expect(fakeCacheStore.delete).toHaveBeenCalledWith(require.resolve('./fixtures/native-cache/file-3'))
|
||||
expect(fakeCacheStore.delete).toHaveBeenCalled()
|
||||
expect(fn3()).toBe(3)
|
||||
|
@ -23,6 +23,7 @@ describe "PaneContainer", ->
|
||||
serialize: -> deserializer: 'Item'
|
||||
|
||||
containerA = new PaneContainer(params)
|
||||
containerA.initialize()
|
||||
pane1A = containerA.getActivePane()
|
||||
pane1A.addItem(new Item)
|
||||
pane2A = pane1A.splitRight(items: [new Item])
|
||||
@ -33,6 +34,7 @@ describe "PaneContainer", ->
|
||||
expect(pane3A.focused).toBe true
|
||||
|
||||
containerB = new PaneContainer(params)
|
||||
containerB.initialize()
|
||||
containerB.deserialize(containerA.serialize(), atom.deserializers)
|
||||
[pane1B, pane2B, pane3B] = containerB.getPanes()
|
||||
expect(pane3B.focused).toBe true
|
||||
@ -42,6 +44,7 @@ describe "PaneContainer", ->
|
||||
expect(containerA.getActivePane()).toBe pane3A
|
||||
|
||||
containerB = new PaneContainer(params)
|
||||
containerB.initialize()
|
||||
containerB.deserialize(containerA.serialize(), atom.deserializers)
|
||||
[pane1B, pane2B, pane3B] = containerB.getPanes()
|
||||
expect(containerB.getActivePane()).toBe pane3B
|
||||
@ -51,6 +54,7 @@ describe "PaneContainer", ->
|
||||
state = containerA.serialize()
|
||||
state.activePaneId = -22
|
||||
containerB = new PaneContainer(params)
|
||||
containerB.initialize()
|
||||
containerB.deserialize(state, atom.deserializers)
|
||||
expect(containerB.getActivePane()).toBe containerB.getPanes()[0]
|
||||
|
||||
@ -62,6 +66,7 @@ describe "PaneContainer", ->
|
||||
it "leaves the empty panes intact", ->
|
||||
state = containerA.serialize()
|
||||
containerB = new PaneContainer(params)
|
||||
containerB.initialize()
|
||||
containerB.deserialize(state, atom.deserializers)
|
||||
[leftPane, column] = containerB.getRoot().getChildren()
|
||||
[topPane, bottomPane] = column.getChildren()
|
||||
@ -76,6 +81,7 @@ describe "PaneContainer", ->
|
||||
|
||||
state = containerA.serialize()
|
||||
containerB = new PaneContainer(params)
|
||||
containerB.initialize()
|
||||
containerB.deserialize(state, atom.deserializers)
|
||||
[leftPane, rightPane] = containerB.getRoot().getChildren()
|
||||
|
||||
@ -84,6 +90,7 @@ describe "PaneContainer", ->
|
||||
|
||||
it "does not allow the root pane to be destroyed", ->
|
||||
container = new PaneContainer(params)
|
||||
container.initialize()
|
||||
container.getRoot().destroy()
|
||||
expect(container.getRoot()).toBeDefined()
|
||||
expect(container.getRoot().isDestroyed()).toBe false
|
||||
@ -93,6 +100,7 @@ describe "PaneContainer", ->
|
||||
|
||||
beforeEach ->
|
||||
container = new PaneContainer(params)
|
||||
container.initialize()
|
||||
pane1 = container.getRoot()
|
||||
|
||||
it "returns the first pane if no pane has been made active", ->
|
||||
@ -122,6 +130,7 @@ describe "PaneContainer", ->
|
||||
|
||||
beforeEach ->
|
||||
container = new PaneContainer(params)
|
||||
container.initialize()
|
||||
container.getRoot().addItems([new Object, new Object])
|
||||
container.getRoot().splitRight(items: [new Object, new Object])
|
||||
[pane1, pane2] = container.getPanes()
|
||||
@ -144,6 +153,7 @@ describe "PaneContainer", ->
|
||||
|
||||
beforeEach ->
|
||||
container = new PaneContainer(root: new Pane(items: [new Object, new Object]))
|
||||
container.initialize()
|
||||
container.getRoot().splitRight(items: [new Object, new Object])
|
||||
[pane1, pane2] = container.getPanes()
|
||||
|
||||
@ -165,6 +175,7 @@ describe "PaneContainer", ->
|
||||
describe "::observePanes()", ->
|
||||
it "invokes observers with all current and future panes", ->
|
||||
container = new PaneContainer(params)
|
||||
container.initialize()
|
||||
container.getRoot().splitRight()
|
||||
[pane1, pane2] = container.getPanes()
|
||||
|
||||
@ -179,6 +190,7 @@ describe "PaneContainer", ->
|
||||
describe "::observePaneItems()", ->
|
||||
it "invokes observers with all current and future pane items", ->
|
||||
container = new PaneContainer(params)
|
||||
container.initialize()
|
||||
container.getRoot().addItems([new Object, new Object])
|
||||
container.getRoot().splitRight(items: [new Object])
|
||||
[pane1, pane2] = container.getPanes()
|
||||
@ -199,6 +211,7 @@ describe "PaneContainer", ->
|
||||
getURI: -> 'test'
|
||||
|
||||
container = new PaneContainer(params)
|
||||
container.initialize()
|
||||
container.getRoot().splitRight()
|
||||
[pane1, pane2] = container.getPanes()
|
||||
pane1.addItem(new TestItem)
|
||||
@ -219,6 +232,7 @@ describe "PaneContainer", ->
|
||||
describe "::onDidAddPane(callback)", ->
|
||||
it "invokes the given callback when panes are added", ->
|
||||
container = new PaneContainer(params)
|
||||
container.initialize()
|
||||
events = []
|
||||
container.onDidAddPane (event) ->
|
||||
expect(event.pane in container.getPanes()).toBe true
|
||||
@ -238,6 +252,7 @@ describe "PaneContainer", ->
|
||||
isDestroyed: -> @_isDestroyed
|
||||
|
||||
container = new PaneContainer(params)
|
||||
container.initialize()
|
||||
events = []
|
||||
container.onWillDestroyPane (event) ->
|
||||
itemsDestroyed = (item.isDestroyed() for item in event.pane.getItems())
|
||||
@ -254,6 +269,7 @@ describe "PaneContainer", ->
|
||||
describe "::onDidDestroyPane(callback)", ->
|
||||
it "invokes the given callback when panes are destroyed", ->
|
||||
container = new PaneContainer(params)
|
||||
container.initialize()
|
||||
events = []
|
||||
container.onDidDestroyPane (event) ->
|
||||
expect(event.pane in container.getPanes()).toBe false
|
||||
@ -270,6 +286,7 @@ describe "PaneContainer", ->
|
||||
|
||||
it "invokes the given callback when the container is destroyed", ->
|
||||
container = new PaneContainer(params)
|
||||
container.initialize()
|
||||
events = []
|
||||
container.onDidDestroyPane (event) ->
|
||||
expect(event.pane in container.getPanes()).toBe false
|
||||
@ -286,6 +303,7 @@ describe "PaneContainer", ->
|
||||
describe "::onWillDestroyPaneItem() and ::onDidDestroyPaneItem", ->
|
||||
it "invokes the given callbacks when an item will be destroyed on any pane", ->
|
||||
container = new PaneContainer(params)
|
||||
container.initialize()
|
||||
pane1 = container.getRoot()
|
||||
item1 = new Object
|
||||
item2 = new Object
|
||||
@ -313,6 +331,7 @@ describe "PaneContainer", ->
|
||||
describe "::saveAll()", ->
|
||||
it "saves all modified pane items", ->
|
||||
container = new PaneContainer(params)
|
||||
container.initialize()
|
||||
pane1 = container.getRoot()
|
||||
pane2 = pane1.splitRight()
|
||||
|
||||
@ -354,6 +373,7 @@ describe "PaneContainer", ->
|
||||
copy: -> new TestItem(@id)
|
||||
|
||||
container = new PaneContainer(params)
|
||||
container.initialize()
|
||||
pane1 = container.getRoot()
|
||||
item1 = new TestItem('1')
|
||||
pane2 = pane1.splitRight(items: [item1])
|
||||
|
@ -1,137 +0,0 @@
|
||||
Panel = require '../src/panel'
|
||||
PanelContainer = require '../src/panel-container'
|
||||
|
||||
describe "PanelContainerElement", ->
|
||||
[jasmineContent, element, container] = []
|
||||
|
||||
class TestPanelContainerItem
|
||||
constructior: ->
|
||||
|
||||
class TestPanelContainerItemElement extends HTMLElement
|
||||
createdCallback: ->
|
||||
@classList.add('test-root')
|
||||
initialize: (@model) ->
|
||||
this
|
||||
|
||||
TestPanelContainerItemElement = document.registerElement 'atom-test-container-item-element', prototype: TestPanelContainerItemElement.prototype
|
||||
|
||||
beforeEach ->
|
||||
jasmineContent = document.body.querySelector('#jasmine-content')
|
||||
|
||||
atom.views.addViewProvider TestPanelContainerItem, (model) ->
|
||||
new TestPanelContainerItemElement().initialize(model)
|
||||
|
||||
container = new PanelContainer({location: 'left'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it 'has a location class with value from the model', ->
|
||||
expect(element).toHaveClass 'left'
|
||||
|
||||
it 'removes the element when the container is destroyed', ->
|
||||
expect(element.parentNode).toBe jasmineContent
|
||||
container.destroy()
|
||||
expect(element.parentNode).not.toBe jasmineContent
|
||||
|
||||
describe "adding and removing panels", ->
|
||||
it "allows panels to be inserted at any position", ->
|
||||
panel1 = new Panel({item: new TestPanelContainerItem(), priority: 10})
|
||||
panel2 = new Panel({item: new TestPanelContainerItem(), priority: 5})
|
||||
panel3 = new Panel({item: new TestPanelContainerItem(), priority: 8})
|
||||
|
||||
container.addPanel(panel1)
|
||||
container.addPanel(panel2)
|
||||
container.addPanel(panel3)
|
||||
|
||||
expect(element.childNodes[2].getModel()).toBe(panel1)
|
||||
expect(element.childNodes[1].getModel()).toBe(panel3)
|
||||
expect(element.childNodes[0].getModel()).toBe(panel2)
|
||||
|
||||
describe "when the container is at the left location", ->
|
||||
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe 1
|
||||
expect(element.childNodes[0]).toHaveClass 'left'
|
||||
expect(element.childNodes[0]).toHaveClass 'tool-panel' # legacy selector support
|
||||
expect(element.childNodes[0]).toHaveClass 'panel-left' # legacy selector support
|
||||
|
||||
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
|
||||
|
||||
panel2 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel2)
|
||||
expect(element.childNodes.length).toBe 2
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel2).style.display).not.toBe 'none'
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe 1
|
||||
|
||||
panel2.destroy()
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
describe "when the container is at the bottom location", ->
|
||||
beforeEach ->
|
||||
container = new PanelContainer({location: 'bottom'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
panel1 = new Panel({item: new TestPanelContainerItem(), className: 'one'})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe 1
|
||||
expect(element.childNodes[0]).toHaveClass 'bottom'
|
||||
expect(element.childNodes[0]).toHaveClass 'tool-panel' # legacy selector support
|
||||
expect(element.childNodes[0]).toHaveClass 'panel-bottom' # legacy selector support
|
||||
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'one'
|
||||
|
||||
panel2 = new Panel({item: new TestPanelContainerItem(), className: 'two'})
|
||||
container.addPanel(panel2)
|
||||
expect(element.childNodes.length).toBe 2
|
||||
expect(atom.views.getView(panel2)).toHaveClass 'two'
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe 1
|
||||
|
||||
panel2.destroy()
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
describe "when the container is modal", ->
|
||||
beforeEach ->
|
||||
container = new PanelContainer({location: 'modal'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it "allows only one panel to be visible at a time", ->
|
||||
panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe 'none'
|
||||
|
||||
panel2 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel2)
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).toBe 'none'
|
||||
expect(atom.views.getView(panel2).style.display).not.toBe 'none'
|
||||
|
||||
panel1.show()
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel2).style.display).toBe 'none'
|
||||
|
||||
it "adds the 'modal' class to panels", ->
|
||||
panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'modal'
|
||||
|
||||
# legacy selector support
|
||||
expect(atom.views.getView(panel1)).not.toHaveClass 'tool-panel'
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'overlay'
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'from-top'
|
165
spec/panel-container-element-spec.js
Normal file
165
spec/panel-container-element-spec.js
Normal file
@ -0,0 +1,165 @@
|
||||
'use strict'
|
||||
|
||||
/* global HTMLElement */
|
||||
|
||||
const Panel = require('../src/panel')
|
||||
const PanelContainer = require('../src/panel-container')
|
||||
|
||||
describe('PanelContainerElement', () => {
|
||||
let jasmineContent, element, container
|
||||
|
||||
class TestPanelContainerItem {
|
||||
}
|
||||
|
||||
class TestPanelContainerItemElement_ extends HTMLElement {
|
||||
createdCallback () {
|
||||
this.classList.add('test-root')
|
||||
}
|
||||
initialize (model) {
|
||||
this.model = model
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
const TestPanelContainerItemElement = document.registerElement(
|
||||
'atom-test-container-item-element',
|
||||
{prototype: TestPanelContainerItemElement_.prototype}
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
jasmineContent = document.body.querySelector('#jasmine-content')
|
||||
|
||||
atom.views.addViewProvider(
|
||||
TestPanelContainerItem,
|
||||
model => new TestPanelContainerItemElement().initialize(model)
|
||||
)
|
||||
|
||||
container = new PanelContainer({location: 'left'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
})
|
||||
|
||||
it('has a location class with value from the model', () => {
|
||||
expect(element).toHaveClass('left')
|
||||
})
|
||||
|
||||
it('removes the element when the container is destroyed', () => {
|
||||
expect(element.parentNode).toBe(jasmineContent)
|
||||
container.destroy()
|
||||
expect(element.parentNode).not.toBe(jasmineContent)
|
||||
})
|
||||
|
||||
describe('adding and removing panels', () => {
|
||||
it('allows panels to be inserted at any position', () => {
|
||||
const panel1 = new Panel({item: new TestPanelContainerItem(), priority: 10})
|
||||
const panel2 = new Panel({item: new TestPanelContainerItem(), priority: 5})
|
||||
const panel3 = new Panel({item: new TestPanelContainerItem(), priority: 8})
|
||||
|
||||
container.addPanel(panel1)
|
||||
container.addPanel(panel2)
|
||||
container.addPanel(panel3)
|
||||
|
||||
expect(element.childNodes[2].getModel()).toBe(panel1)
|
||||
expect(element.childNodes[1].getModel()).toBe(panel3)
|
||||
expect(element.childNodes[0].getModel()).toBe(panel2)
|
||||
})
|
||||
|
||||
describe('when the container is at the left location', () =>
|
||||
it('adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed', () => {
|
||||
expect(element.childNodes.length).toBe(0)
|
||||
|
||||
const panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe(1)
|
||||
expect(element.childNodes[0]).toHaveClass('left')
|
||||
expect(element.childNodes[0]).toHaveClass('tool-panel') // legacy selector support
|
||||
expect(element.childNodes[0]).toHaveClass('panel-left') // legacy selector support
|
||||
|
||||
expect(element.childNodes[0].tagName).toBe('ATOM-PANEL')
|
||||
|
||||
const panel2 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel2)
|
||||
expect(element.childNodes.length).toBe(2)
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe('none')
|
||||
expect(atom.views.getView(panel2).style.display).not.toBe('none')
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe(1)
|
||||
|
||||
panel2.destroy()
|
||||
expect(element.childNodes.length).toBe(0)
|
||||
})
|
||||
)
|
||||
|
||||
describe('when the container is at the bottom location', () => {
|
||||
beforeEach(() => {
|
||||
container = new PanelContainer({location: 'bottom'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
})
|
||||
|
||||
it('adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed', () => {
|
||||
expect(element.childNodes.length).toBe(0)
|
||||
|
||||
const panel1 = new Panel({item: new TestPanelContainerItem(), className: 'one'})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe(1)
|
||||
expect(element.childNodes[0]).toHaveClass('bottom')
|
||||
expect(element.childNodes[0]).toHaveClass('tool-panel') // legacy selector support
|
||||
expect(element.childNodes[0]).toHaveClass('panel-bottom') // legacy selector support
|
||||
expect(element.childNodes[0].tagName).toBe('ATOM-PANEL')
|
||||
expect(atom.views.getView(panel1)).toHaveClass('one')
|
||||
|
||||
const panel2 = new Panel({item: new TestPanelContainerItem(), className: 'two'})
|
||||
container.addPanel(panel2)
|
||||
expect(element.childNodes.length).toBe(2)
|
||||
expect(atom.views.getView(panel2)).toHaveClass('two')
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe(1)
|
||||
|
||||
panel2.destroy()
|
||||
expect(element.childNodes.length).toBe(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the container is modal', () => {
|
||||
beforeEach(() => {
|
||||
container = new PanelContainer({location: 'modal'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
})
|
||||
|
||||
it('allows only one panel to be visible at a time', () => {
|
||||
const panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe('none')
|
||||
|
||||
const panel2 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel2)
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).toBe('none')
|
||||
expect(atom.views.getView(panel2).style.display).not.toBe('none')
|
||||
|
||||
panel1.show()
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe('none')
|
||||
expect(atom.views.getView(panel2).style.display).toBe('none')
|
||||
})
|
||||
|
||||
it("adds the 'modal' class to panels", () => {
|
||||
const panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
|
||||
expect(atom.views.getView(panel1)).toHaveClass('modal')
|
||||
|
||||
// legacy selector support
|
||||
expect(atom.views.getView(panel1)).not.toHaveClass('tool-panel')
|
||||
expect(atom.views.getView(panel1)).toHaveClass('overlay')
|
||||
expect(atom.views.getView(panel1)).toHaveClass('from-top')
|
||||
})
|
||||
})
|
||||
})
|
@ -1,96 +0,0 @@
|
||||
Panel = require '../src/panel'
|
||||
PanelContainer = require '../src/panel-container'
|
||||
|
||||
describe "PanelContainer", ->
|
||||
[container] = []
|
||||
|
||||
class TestPanelItem
|
||||
constructior: ->
|
||||
|
||||
beforeEach ->
|
||||
container = new PanelContainer
|
||||
|
||||
describe "::addPanel(panel)", ->
|
||||
it 'emits an onDidAddPanel event with the index the panel was inserted at', ->
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
|
||||
panel1 = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(panel1)
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel: panel1, index: 0})
|
||||
|
||||
panel2 = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(panel2)
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel: panel2, index: 1})
|
||||
|
||||
describe "when a panel is destroyed", ->
|
||||
it 'emits an onDidRemovePanel event with the index of the removed item', ->
|
||||
container.onDidRemovePanel removePanelSpy = jasmine.createSpy()
|
||||
|
||||
panel1 = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(panel1)
|
||||
panel2 = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(panel2)
|
||||
|
||||
expect(removePanelSpy).not.toHaveBeenCalled()
|
||||
|
||||
panel2.destroy()
|
||||
expect(removePanelSpy).toHaveBeenCalledWith({panel: panel2, index: 1})
|
||||
|
||||
panel1.destroy()
|
||||
expect(removePanelSpy).toHaveBeenCalledWith({panel: panel1, index: 0})
|
||||
|
||||
describe "panel priority", ->
|
||||
describe 'left / top panel container', ->
|
||||
[initialPanel] = []
|
||||
beforeEach ->
|
||||
# 'left' logic is the same as 'top'
|
||||
container = new PanelContainer({location: 'left'})
|
||||
initialPanel = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(initialPanel)
|
||||
|
||||
describe 'when a panel with low priority is added', ->
|
||||
it 'is inserted at the beginning of the list', ->
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 0)
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
expect(container.getPanels()[0]).toBe panel
|
||||
|
||||
describe 'when a panel with priority between two other panels is added', ->
|
||||
it 'is inserted at the between the two panels', ->
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 1000)
|
||||
container.addPanel(panel)
|
||||
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 101)
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 1})
|
||||
expect(container.getPanels()[1]).toBe panel
|
||||
|
||||
describe 'right / bottom panel container', ->
|
||||
[initialPanel] = []
|
||||
beforeEach ->
|
||||
# 'bottom' logic is the same as 'right'
|
||||
container = new PanelContainer({location: 'right'})
|
||||
initialPanel = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(initialPanel)
|
||||
|
||||
describe 'when a panel with high priority is added', ->
|
||||
it 'is inserted at the beginning of the list', ->
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 1000)
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
expect(container.getPanels()[0]).toBe panel
|
||||
|
||||
describe 'when a panel with low priority is added', ->
|
||||
it 'is inserted at the end of the list', ->
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 0)
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 1})
|
||||
expect(container.getPanels()[1]).toBe panel
|
142
spec/panel-container-spec.js
Normal file
142
spec/panel-container-spec.js
Normal file
@ -0,0 +1,142 @@
|
||||
'use strict'
|
||||
|
||||
const Panel = require('../src/panel')
|
||||
const PanelContainer = require('../src/panel-container')
|
||||
|
||||
describe('PanelContainer', () => {
|
||||
let container
|
||||
|
||||
class TestPanelItem {
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
container = new PanelContainer()
|
||||
})
|
||||
|
||||
describe('::addPanel(panel)', () => {
|
||||
it('emits an onDidAddPanel event with the index the panel was inserted at', () => {
|
||||
const addPanelSpy = jasmine.createSpy()
|
||||
container.onDidAddPanel(addPanelSpy)
|
||||
|
||||
const panel1 = new Panel({item: new TestPanelItem()})
|
||||
container.addPanel(panel1)
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel: panel1, index: 0})
|
||||
|
||||
const panel2 = new Panel({item: new TestPanelItem()})
|
||||
container.addPanel(panel2)
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel: panel2, index: 1})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when a panel is destroyed', () => {
|
||||
it('emits an onDidRemovePanel event with the index of the removed item', () => {
|
||||
const removePanelSpy = jasmine.createSpy()
|
||||
container.onDidRemovePanel(removePanelSpy)
|
||||
|
||||
const panel1 = new Panel({item: new TestPanelItem()})
|
||||
container.addPanel(panel1)
|
||||
const panel2 = new Panel({item: new TestPanelItem()})
|
||||
container.addPanel(panel2)
|
||||
|
||||
expect(removePanelSpy).not.toHaveBeenCalled()
|
||||
|
||||
panel2.destroy()
|
||||
expect(removePanelSpy).toHaveBeenCalledWith({panel: panel2, index: 1})
|
||||
|
||||
panel1.destroy()
|
||||
expect(removePanelSpy).toHaveBeenCalledWith({panel: panel1, index: 0})
|
||||
})
|
||||
})
|
||||
|
||||
describe('::destroy()', () => {
|
||||
it('destroys the container and all of its panels', () => {
|
||||
const destroyedPanels = []
|
||||
|
||||
const panel1 = new Panel({item: new TestPanelItem()})
|
||||
panel1.onDidDestroy(() => { destroyedPanels.push(panel1) })
|
||||
container.addPanel(panel1)
|
||||
|
||||
const panel2 = new Panel({item: new TestPanelItem()})
|
||||
panel2.onDidDestroy(() => { destroyedPanels.push(panel2) })
|
||||
container.addPanel(panel2)
|
||||
|
||||
container.destroy()
|
||||
|
||||
expect(container.getPanels().length).toBe(0)
|
||||
expect(destroyedPanels).toEqual([panel1, panel2])
|
||||
})
|
||||
})
|
||||
|
||||
describe('panel priority', () => {
|
||||
describe('left / top panel container', () => {
|
||||
let initialPanel
|
||||
beforeEach(() => {
|
||||
// 'left' logic is the same as 'top'
|
||||
container = new PanelContainer({location: 'left'})
|
||||
initialPanel = new Panel({item: new TestPanelItem()})
|
||||
container.addPanel(initialPanel)
|
||||
})
|
||||
|
||||
describe('when a panel with low priority is added', () => {
|
||||
it('is inserted at the beginning of the list', () => {
|
||||
const addPanelSpy = jasmine.createSpy()
|
||||
container.onDidAddPanel(addPanelSpy)
|
||||
const panel = new Panel({item: new TestPanelItem(), priority: 0})
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
expect(container.getPanels()[0]).toBe(panel)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when a panel with priority between two other panels is added', () => {
|
||||
it('is inserted at the between the two panels', () => {
|
||||
const addPanelSpy = jasmine.createSpy()
|
||||
let panel = new Panel({item: new TestPanelItem(), priority: 1000})
|
||||
container.addPanel(panel)
|
||||
|
||||
container.onDidAddPanel(addPanelSpy)
|
||||
panel = new Panel({item: new TestPanelItem(), priority: 101})
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 1})
|
||||
expect(container.getPanels()[1]).toBe(panel)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('right / bottom panel container', () => {
|
||||
let initialPanel
|
||||
beforeEach(() => {
|
||||
// 'bottom' logic is the same as 'right'
|
||||
container = new PanelContainer({location: 'right'})
|
||||
initialPanel = new Panel({item: new TestPanelItem()})
|
||||
container.addPanel(initialPanel)
|
||||
})
|
||||
|
||||
describe('when a panel with high priority is added', () => {
|
||||
it('is inserted at the beginning of the list', () => {
|
||||
const addPanelSpy = jasmine.createSpy()
|
||||
container.onDidAddPanel(addPanelSpy)
|
||||
const panel = new Panel({item: new TestPanelItem(), priority: 1000})
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
expect(container.getPanels()[0]).toBe(panel)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when a panel with low priority is added', () => {
|
||||
it('is inserted at the end of the list', () => {
|
||||
const addPanelSpy = jasmine.createSpy()
|
||||
container.onDidAddPanel(addPanelSpy)
|
||||
const panel = new Panel({item: new TestPanelItem(), priority: 0})
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 1})
|
||||
expect(container.getPanels()[1]).toBe(panel)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
@ -28,7 +28,13 @@ describe "TextEditor", ->
|
||||
editor.foldBufferRow(4)
|
||||
expect(editor.isFoldedAtBufferRow(4)).toBeTruthy()
|
||||
|
||||
editor2 = TextEditor.deserialize(editor.serialize(), atom)
|
||||
editor2 = TextEditor.deserialize(editor.serialize(), {
|
||||
assert: atom.assert,
|
||||
textEditors: atom.textEditors,
|
||||
project: {
|
||||
bufferForIdSync: (id) -> TextBuffer.deserialize(editor.buffer.serialize())
|
||||
}
|
||||
})
|
||||
|
||||
expect(editor2.id).toBe editor.id
|
||||
expect(editor2.getBuffer().getPath()).toBe editor.getBuffer().getPath()
|
||||
@ -4862,8 +4868,8 @@ describe "TextEditor", ->
|
||||
editor.replaceSelectedText {}, -> '123'
|
||||
expect(buffer.lineForRow(0)).toBe '123var quicksort = function () {'
|
||||
|
||||
editor.replaceSelectedText {selectWordIfEmpty: true}, -> 'var'
|
||||
editor.setCursorBufferPosition([0])
|
||||
editor.replaceSelectedText {selectWordIfEmpty: true}, -> 'var'
|
||||
expect(buffer.lineForRow(0)).toBe 'var quicksort = function () {'
|
||||
|
||||
editor.setCursorBufferPosition([10])
|
||||
@ -4876,6 +4882,12 @@ describe "TextEditor", ->
|
||||
editor.replaceSelectedText {}, -> 'ia'
|
||||
expect(buffer.lineForRow(0)).toBe 'via quicksort = function () {'
|
||||
|
||||
it "replaces the selected text and selects the replacement text", ->
|
||||
editor.setSelectedBufferRange([[0, 4], [0, 9]])
|
||||
editor.replaceSelectedText {}, -> 'whatnot'
|
||||
expect(buffer.lineForRow(0)).toBe 'var whatnotsort = function () {'
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[0, 4], [0, 11]]
|
||||
|
||||
describe ".transpose()", ->
|
||||
it "swaps two characters", ->
|
||||
editor.buffer.setText("abc")
|
||||
@ -4896,7 +4908,7 @@ describe "TextEditor", ->
|
||||
editor.setCursorScreenPosition([0, 1])
|
||||
editor.upperCase()
|
||||
expect(editor.lineTextForBufferRow(0)).toBe 'ABC'
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[0, 1], [0, 1]]
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[0, 0], [0, 3]]
|
||||
|
||||
describe "when there is a selection", ->
|
||||
it "upper cases the current selection", ->
|
||||
@ -4913,7 +4925,7 @@ describe "TextEditor", ->
|
||||
editor.setCursorScreenPosition([0, 1])
|
||||
editor.lowerCase()
|
||||
expect(editor.lineTextForBufferRow(0)).toBe 'abc'
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[0, 1], [0, 1]]
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[0, 0], [0, 3]]
|
||||
|
||||
describe "when there is a selection", ->
|
||||
it "lower cases the current selection", ->
|
||||
|
@ -194,10 +194,10 @@ describe "atom.themes", ->
|
||||
expect(element.getAttribute('source-path')).toEqualPath lessPath
|
||||
expect(element.textContent).toBe """
|
||||
#header {
|
||||
color: #4d926f;
|
||||
color: #4D926F;
|
||||
}
|
||||
h2 {
|
||||
color: #4d926f;
|
||||
color: #4D926F;
|
||||
}
|
||||
|
||||
"""
|
||||
|
@ -5,6 +5,7 @@ describe "ViewRegistry", ->
|
||||
|
||||
beforeEach ->
|
||||
registry = new ViewRegistry
|
||||
registry.initialize()
|
||||
|
||||
afterEach ->
|
||||
registry.clearDocumentRequests()
|
||||
|
@ -15,7 +15,8 @@ describe "WindowEventHandler", ->
|
||||
loadSettings.initialPath = initialPath
|
||||
loadSettings
|
||||
atom.project.destroy()
|
||||
windowEventHandler = new WindowEventHandler({atomEnvironment: atom, applicationDelegate: atom.applicationDelegate, window, document})
|
||||
windowEventHandler = new WindowEventHandler({atomEnvironment: atom, applicationDelegate: atom.applicationDelegate})
|
||||
windowEventHandler.initialize(window, document)
|
||||
|
||||
afterEach ->
|
||||
windowEventHandler.unsubscribe()
|
||||
|
@ -1,210 +0,0 @@
|
||||
{ipcRenderer} = require 'electron'
|
||||
path = require 'path'
|
||||
temp = require('temp').track()
|
||||
{Disposable} = require 'event-kit'
|
||||
|
||||
describe "WorkspaceElement", ->
|
||||
afterEach ->
|
||||
temp.cleanupSync()
|
||||
|
||||
describe "when the workspace element is focused", ->
|
||||
it "transfers focus to the active pane", ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
activePaneElement = atom.views.getView(atom.workspace.getActivePane())
|
||||
document.body.focus()
|
||||
expect(document.activeElement).not.toBe(activePaneElement)
|
||||
workspaceElement.focus()
|
||||
expect(document.activeElement).toBe(activePaneElement)
|
||||
|
||||
describe "the scrollbar visibility class", ->
|
||||
it "has a class based on the style of the scrollbar", ->
|
||||
observeCallback = null
|
||||
scrollbarStyle = require 'scrollbar-style'
|
||||
spyOn(scrollbarStyle, 'observePreferredScrollbarStyle').andCallFake (cb) ->
|
||||
observeCallback = cb
|
||||
new Disposable(->)
|
||||
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
observeCallback('legacy')
|
||||
expect(workspaceElement.className).toMatch 'scrollbars-visible-always'
|
||||
|
||||
observeCallback('overlay')
|
||||
expect(workspaceElement).toHaveClass 'scrollbars-visible-when-scrolling'
|
||||
|
||||
describe "editor font styling", ->
|
||||
[editor, editorElement, workspaceElement] = []
|
||||
|
||||
beforeEach ->
|
||||
waitsForPromise -> atom.workspace.open('sample.js')
|
||||
|
||||
runs ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
editor = atom.workspace.getActiveTextEditor()
|
||||
editorElement = atom.views.getView(editor)
|
||||
|
||||
it "updates the font-size based on the 'editor.fontSize' config value", ->
|
||||
initialCharWidth = editor.getDefaultCharWidth()
|
||||
expect(getComputedStyle(editorElement).fontSize).toBe atom.config.get('editor.fontSize') + 'px'
|
||||
atom.config.set('editor.fontSize', atom.config.get('editor.fontSize') + 5)
|
||||
expect(getComputedStyle(editorElement).fontSize).toBe atom.config.get('editor.fontSize') + 'px'
|
||||
expect(editor.getDefaultCharWidth()).toBeGreaterThan initialCharWidth
|
||||
|
||||
it "updates the font-family based on the 'editor.fontFamily' config value", ->
|
||||
initialCharWidth = editor.getDefaultCharWidth()
|
||||
fontFamily = atom.config.get('editor.fontFamily')
|
||||
fontFamily += ', "Apple Color Emoji"' if process.platform is 'darwin'
|
||||
expect(getComputedStyle(editorElement).fontFamily).toBe fontFamily
|
||||
|
||||
atom.config.set('editor.fontFamily', 'sans-serif')
|
||||
fontFamily = atom.config.get('editor.fontFamily')
|
||||
fontFamily += ', "Apple Color Emoji"' if process.platform is 'darwin'
|
||||
expect(getComputedStyle(editorElement).fontFamily).toBe fontFamily
|
||||
expect(editor.getDefaultCharWidth()).not.toBe initialCharWidth
|
||||
|
||||
it "updates the line-height based on the 'editor.lineHeight' config value", ->
|
||||
initialLineHeight = editor.getLineHeightInPixels()
|
||||
atom.config.set('editor.lineHeight', '30px')
|
||||
expect(getComputedStyle(editorElement).lineHeight).toBe atom.config.get('editor.lineHeight')
|
||||
expect(editor.getLineHeightInPixels()).not.toBe initialLineHeight
|
||||
|
||||
it "increases or decreases the font size when a ctrl-mousewheel event occurs", ->
|
||||
atom.config.set('editor.zoomFontWhenCtrlScrolling', true)
|
||||
atom.config.set('editor.fontSize', 12)
|
||||
|
||||
# Zoom out
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: -10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(11)
|
||||
|
||||
# Zoom in
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
# Not on an atom-text-editor
|
||||
workspaceElement.dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
# No ctrl key
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
atom.config.set('editor.zoomFontWhenCtrlScrolling', false)
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
describe 'panel containers', ->
|
||||
it 'inserts panel container elements in the correct places in the DOM', ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
|
||||
leftContainer = workspaceElement.querySelector('atom-panel-container.left')
|
||||
rightContainer = workspaceElement.querySelector('atom-panel-container.right')
|
||||
expect(leftContainer.nextSibling).toBe workspaceElement.verticalAxis
|
||||
expect(rightContainer.previousSibling).toBe workspaceElement.verticalAxis
|
||||
|
||||
topContainer = workspaceElement.querySelector('atom-panel-container.top')
|
||||
bottomContainer = workspaceElement.querySelector('atom-panel-container.bottom')
|
||||
expect(topContainer.nextSibling).toBe workspaceElement.paneContainer
|
||||
expect(bottomContainer.previousSibling).toBe workspaceElement.paneContainer
|
||||
|
||||
headerContainer = workspaceElement.querySelector('atom-panel-container.header')
|
||||
footerContainer = workspaceElement.querySelector('atom-panel-container.footer')
|
||||
expect(headerContainer.nextSibling).toBe workspaceElement.horizontalAxis
|
||||
expect(footerContainer.previousSibling).toBe workspaceElement.horizontalAxis
|
||||
|
||||
modalContainer = workspaceElement.querySelector('atom-panel-container.modal')
|
||||
expect(modalContainer.parentNode).toBe workspaceElement
|
||||
|
||||
it 'stretches header/footer panels to the workspace width', ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
expect(workspaceElement.offsetWidth).toBeGreaterThan(0)
|
||||
|
||||
headerItem = document.createElement('div')
|
||||
atom.workspace.addHeaderPanel({item: headerItem})
|
||||
expect(headerItem.offsetWidth).toEqual(workspaceElement.offsetWidth)
|
||||
|
||||
footerItem = document.createElement('div')
|
||||
atom.workspace.addFooterPanel({item: footerItem})
|
||||
expect(footerItem.offsetWidth).toEqual(workspaceElement.offsetWidth)
|
||||
|
||||
it 'shrinks horizontal axis according to header/footer panels height', ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
workspaceElement.style.height = '100px'
|
||||
horizontalAxisElement = workspaceElement.querySelector('atom-workspace-axis.horizontal')
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
|
||||
originalHorizontalAxisHeight = horizontalAxisElement.offsetHeight
|
||||
expect(workspaceElement.offsetHeight).toBeGreaterThan(0)
|
||||
expect(originalHorizontalAxisHeight).toBeGreaterThan(0)
|
||||
|
||||
headerItem = document.createElement('div')
|
||||
headerItem.style.height = '10px'
|
||||
atom.workspace.addHeaderPanel({item: headerItem})
|
||||
expect(headerItem.offsetHeight).toBeGreaterThan(0)
|
||||
|
||||
footerItem = document.createElement('div')
|
||||
footerItem.style.height = '15px'
|
||||
atom.workspace.addFooterPanel({item: footerItem})
|
||||
expect(footerItem.offsetHeight).toBeGreaterThan(0)
|
||||
|
||||
expect(horizontalAxisElement.offsetHeight).toEqual(originalHorizontalAxisHeight - headerItem.offsetHeight - footerItem.offsetHeight)
|
||||
|
||||
describe "the 'window:toggle-invisibles' command", ->
|
||||
it "shows/hides invisibles in all open and future editors", ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe false
|
||||
atom.commands.dispatch(workspaceElement, 'window:toggle-invisibles')
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe true
|
||||
atom.commands.dispatch(workspaceElement, 'window:toggle-invisibles')
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe false
|
||||
|
||||
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(ipcRenderer, 'send')
|
||||
|
||||
# No project paths. Don't try to run specs.
|
||||
atom.commands.dispatch(workspaceElement, "window: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(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(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(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(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[1], "spec"))
|
||||
ipcRenderer.send.reset()
|
232
spec/workspace-element-spec.js
Normal file
232
spec/workspace-element-spec.js
Normal file
@ -0,0 +1,232 @@
|
||||
'use strict'
|
||||
|
||||
/* global getComputedStyle, WheelEvent */
|
||||
|
||||
const {ipcRenderer} = require('electron')
|
||||
const path = require('path')
|
||||
const temp = require('temp').track()
|
||||
const {Disposable} = require('event-kit')
|
||||
|
||||
describe('WorkspaceElement', () => {
|
||||
afterEach(() => { temp.cleanupSync() })
|
||||
|
||||
describe('when the workspace element is focused', () => {
|
||||
it('transfers focus to the active pane', () => {
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
const activePaneElement = atom.views.getView(atom.workspace.getActivePane())
|
||||
document.body.focus()
|
||||
expect(document.activeElement).not.toBe(activePaneElement)
|
||||
workspaceElement.focus()
|
||||
expect(document.activeElement).toBe(activePaneElement)
|
||||
})
|
||||
})
|
||||
|
||||
describe('the scrollbar visibility class', () => {
|
||||
it('has a class based on the style of the scrollbar', () => {
|
||||
let observeCallback
|
||||
const scrollbarStyle = require('scrollbar-style')
|
||||
spyOn(scrollbarStyle, 'observePreferredScrollbarStyle').andCallFake(cb => {
|
||||
observeCallback = cb
|
||||
return new Disposable(() => {})
|
||||
})
|
||||
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
observeCallback('legacy')
|
||||
expect(workspaceElement.className).toMatch('scrollbars-visible-always')
|
||||
|
||||
observeCallback('overlay')
|
||||
expect(workspaceElement).toHaveClass('scrollbars-visible-when-scrolling')
|
||||
})
|
||||
})
|
||||
|
||||
describe('editor font styling', () => {
|
||||
let editor, editorElement, workspaceElement
|
||||
|
||||
beforeEach(() => {
|
||||
waitsForPromise(() => atom.workspace.open('sample.js'))
|
||||
|
||||
runs(() => {
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
editor = atom.workspace.getActiveTextEditor()
|
||||
editorElement = atom.views.getView(editor)
|
||||
})
|
||||
})
|
||||
|
||||
it("updates the font-size based on the 'editor.fontSize' config value", () => {
|
||||
const initialCharWidth = editor.getDefaultCharWidth()
|
||||
expect(getComputedStyle(editorElement).fontSize).toBe(atom.config.get('editor.fontSize') + 'px')
|
||||
atom.config.set('editor.fontSize', atom.config.get('editor.fontSize') + 5)
|
||||
expect(getComputedStyle(editorElement).fontSize).toBe(atom.config.get('editor.fontSize') + 'px')
|
||||
expect(editor.getDefaultCharWidth()).toBeGreaterThan(initialCharWidth)
|
||||
})
|
||||
|
||||
it("updates the font-family based on the 'editor.fontFamily' config value", () => {
|
||||
const initialCharWidth = editor.getDefaultCharWidth()
|
||||
let fontFamily = atom.config.get('editor.fontFamily')
|
||||
expect(getComputedStyle(editorElement).fontFamily).toBe(fontFamily)
|
||||
|
||||
atom.config.set('editor.fontFamily', 'sans-serif')
|
||||
fontFamily = atom.config.get('editor.fontFamily')
|
||||
expect(getComputedStyle(editorElement).fontFamily).toBe(fontFamily)
|
||||
expect(editor.getDefaultCharWidth()).not.toBe(initialCharWidth)
|
||||
})
|
||||
|
||||
it("updates the line-height based on the 'editor.lineHeight' config value", () => {
|
||||
const initialLineHeight = editor.getLineHeightInPixels()
|
||||
atom.config.set('editor.lineHeight', '30px')
|
||||
expect(getComputedStyle(editorElement).lineHeight).toBe(atom.config.get('editor.lineHeight'))
|
||||
expect(editor.getLineHeightInPixels()).not.toBe(initialLineHeight)
|
||||
})
|
||||
|
||||
it('increases or decreases the font size when a ctrl-mousewheel event occurs', () => {
|
||||
atom.config.set('editor.zoomFontWhenCtrlScrolling', true)
|
||||
atom.config.set('editor.fontSize', 12)
|
||||
|
||||
// Zoom out
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: -10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(11)
|
||||
|
||||
// Zoom in
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
// Not on an atom-text-editor
|
||||
workspaceElement.dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
// No ctrl key
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
atom.config.set('editor.zoomFontWhenCtrlScrolling', false)
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
})
|
||||
})
|
||||
|
||||
describe('panel containers', () => {
|
||||
it('inserts panel container elements in the correct places in the DOM', () => {
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
|
||||
const leftContainer = workspaceElement.querySelector('atom-panel-container.left')
|
||||
const rightContainer = workspaceElement.querySelector('atom-panel-container.right')
|
||||
expect(leftContainer.nextSibling).toBe(workspaceElement.verticalAxis)
|
||||
expect(rightContainer.previousSibling).toBe(workspaceElement.verticalAxis)
|
||||
|
||||
const topContainer = workspaceElement.querySelector('atom-panel-container.top')
|
||||
const bottomContainer = workspaceElement.querySelector('atom-panel-container.bottom')
|
||||
expect(topContainer.nextSibling).toBe(workspaceElement.paneContainer)
|
||||
expect(bottomContainer.previousSibling).toBe(workspaceElement.paneContainer)
|
||||
|
||||
const headerContainer = workspaceElement.querySelector('atom-panel-container.header')
|
||||
const footerContainer = workspaceElement.querySelector('atom-panel-container.footer')
|
||||
expect(headerContainer.nextSibling).toBe(workspaceElement.horizontalAxis)
|
||||
expect(footerContainer.previousSibling).toBe(workspaceElement.horizontalAxis)
|
||||
|
||||
const modalContainer = workspaceElement.querySelector('atom-panel-container.modal')
|
||||
expect(modalContainer.parentNode).toBe(workspaceElement)
|
||||
})
|
||||
|
||||
it('stretches header/footer panels to the workspace width', () => {
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
expect(workspaceElement.offsetWidth).toBeGreaterThan(0)
|
||||
|
||||
const headerItem = document.createElement('div')
|
||||
atom.workspace.addHeaderPanel({item: headerItem})
|
||||
expect(headerItem.offsetWidth).toEqual(workspaceElement.offsetWidth)
|
||||
|
||||
const footerItem = document.createElement('div')
|
||||
atom.workspace.addFooterPanel({item: footerItem})
|
||||
expect(footerItem.offsetWidth).toEqual(workspaceElement.offsetWidth)
|
||||
})
|
||||
|
||||
it('shrinks horizontal axis according to header/footer panels height', () => {
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
workspaceElement.style.height = '100px'
|
||||
const horizontalAxisElement = workspaceElement.querySelector('atom-workspace-axis.horizontal')
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
|
||||
const originalHorizontalAxisHeight = horizontalAxisElement.offsetHeight
|
||||
expect(workspaceElement.offsetHeight).toBeGreaterThan(0)
|
||||
expect(originalHorizontalAxisHeight).toBeGreaterThan(0)
|
||||
|
||||
const headerItem = document.createElement('div')
|
||||
headerItem.style.height = '10px'
|
||||
atom.workspace.addHeaderPanel({item: headerItem})
|
||||
expect(headerItem.offsetHeight).toBeGreaterThan(0)
|
||||
|
||||
const footerItem = document.createElement('div')
|
||||
footerItem.style.height = '15px'
|
||||
atom.workspace.addFooterPanel({item: footerItem})
|
||||
expect(footerItem.offsetHeight).toBeGreaterThan(0)
|
||||
|
||||
expect(horizontalAxisElement.offsetHeight).toEqual(originalHorizontalAxisHeight - headerItem.offsetHeight - footerItem.offsetHeight)
|
||||
})
|
||||
})
|
||||
|
||||
describe("the 'window:toggle-invisibles' command", () => {
|
||||
it('shows/hides invisibles in all open and future editors', () => {
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe(false)
|
||||
atom.commands.dispatch(workspaceElement, 'window:toggle-invisibles')
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe(true)
|
||||
atom.commands.dispatch(workspaceElement, 'window:toggle-invisibles')
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe("the 'window:run-package-specs' command", () => {
|
||||
it("runs the package specs for the active item's project path, or the first project path", () => {
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
spyOn(ipcRenderer, 'send')
|
||||
|
||||
// No project paths. Don't try to run specs.
|
||||
atom.commands.dispatch(workspaceElement, 'window:run-package-specs')
|
||||
expect(ipcRenderer.send).not.toHaveBeenCalledWith('run-package-specs')
|
||||
|
||||
const 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(ipcRenderer.send).toHaveBeenCalledWith('run-package-specs', path.join(projectPaths[0], 'spec'))
|
||||
ipcRenderer.send.reset()
|
||||
|
||||
// Active item doesn't implement ::getPath(). Use first project directory.
|
||||
const item = document.createElement('div')
|
||||
atom.workspace.getActivePane().activateItem(item)
|
||||
atom.commands.dispatch(workspaceElement, 'window:run-package-specs')
|
||||
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(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(ipcRenderer.send).toHaveBeenCalledWith('run-package-specs', path.join(projectPaths[1], 'spec'))
|
||||
ipcRenderer.send.reset()
|
||||
})
|
||||
})
|
||||
})
|
File diff suppressed because it is too large
Load Diff
2091
spec/workspace-spec.js
Normal file
2091
spec/workspace-spec.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
_ = require 'underscore-plus'
|
||||
{screen, ipcRenderer, remote, shell, webFrame} = require 'electron'
|
||||
{ipcRenderer, remote, shell} = require 'electron'
|
||||
ipcHelpers = require './ipc-helpers'
|
||||
{Disposable} = require 'event-kit'
|
||||
getWindowLoadSettings = require './get-window-load-settings'
|
||||
@ -80,6 +80,12 @@ class ApplicationDelegate
|
||||
setWindowFullScreen: (fullScreen=false) ->
|
||||
ipcHelpers.call('window-method', 'setFullScreen', fullScreen)
|
||||
|
||||
onDidEnterFullScreen: (callback) ->
|
||||
ipcHelpers.on(ipcRenderer, 'did-enter-full-screen', callback)
|
||||
|
||||
onDidLeaveFullScreen: (callback) ->
|
||||
ipcHelpers.on(ipcRenderer, 'did-leave-full-screen', callback)
|
||||
|
||||
openWindowDevTools: ->
|
||||
# Defer DevTools interaction to the next tick, because using them during
|
||||
# event handling causes some wrong input events to be triggered on
|
||||
@ -254,20 +260,6 @@ class ApplicationDelegate
|
||||
openExternal: (url) ->
|
||||
shell.openExternal(url)
|
||||
|
||||
disableZoom: ->
|
||||
outerCallback = ->
|
||||
webFrame.setZoomLevelLimits(1, 1)
|
||||
|
||||
outerCallback()
|
||||
# Set the limits every time a display is added or removed, otherwise the
|
||||
# configuration gets reset to the default, which allows zooming the
|
||||
# webframe.
|
||||
screen.on('display-added', outerCallback)
|
||||
screen.on('display-removed', outerCallback)
|
||||
new Disposable ->
|
||||
screen.removeListener('display-added', outerCallback)
|
||||
screen.removeListener('display-removed', outerCallback)
|
||||
|
||||
checkForUpdate: ->
|
||||
ipcRenderer.send('command', 'application:check-for-update')
|
||||
|
||||
@ -285,3 +277,14 @@ class ApplicationDelegate
|
||||
|
||||
emitDidSavePath: (path) ->
|
||||
ipcRenderer.sendSync('did-save-path', path)
|
||||
|
||||
resolveProxy: (requestId, url) ->
|
||||
ipcRenderer.send('resolve-proxy', requestId, url)
|
||||
|
||||
onDidResolveProxy: (callback) ->
|
||||
outerCallback = (event, requestId, proxy) ->
|
||||
callback(requestId, proxy)
|
||||
|
||||
ipcRenderer.on('did-resolve-proxy', outerCallback)
|
||||
new Disposable ->
|
||||
ipcRenderer.removeListener('did-resolve-proxy', outerCallback)
|
||||
|
@ -13,6 +13,7 @@ StateStore = require './state-store'
|
||||
StorageFolder = require './storage-folder'
|
||||
registerDefaultCommands = require './register-default-commands'
|
||||
{updateProcessEnv} = require './update-process-env'
|
||||
ConfigSchema = require './config-schema'
|
||||
|
||||
DeserializerManager = require './deserializer-manager'
|
||||
ViewRegistry = require './view-registry'
|
||||
@ -131,64 +132,45 @@ class AtomEnvironment extends Model
|
||||
|
||||
# Call .loadOrCreate instead
|
||||
constructor: (params={}) ->
|
||||
{@blobStore, @applicationDelegate, @window, @document, @clipboard, @configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params
|
||||
{@applicationDelegate, @clipboard, @enablePersistence, onlyLoadBaseStyleSheets} = params
|
||||
|
||||
@nextProxyRequestId = 0
|
||||
@unloaded = false
|
||||
@loadTime = null
|
||||
{devMode, safeMode, resourcePath, clearWindowState} = @getLoadSettings()
|
||||
|
||||
@emitter = new Emitter
|
||||
@disposables = new CompositeDisposable
|
||||
@deserializers = new DeserializerManager(this)
|
||||
@deserializeTimings = {}
|
||||
@views = new ViewRegistry(this)
|
||||
@notifications = new NotificationManager
|
||||
|
||||
@stateStore = new StateStore('AtomEnvironments', 1)
|
||||
|
||||
if clearWindowState
|
||||
@getStorageFolder().clear()
|
||||
@stateStore.clear()
|
||||
|
||||
@deserializers = new DeserializerManager(this)
|
||||
@deserializeTimings = {}
|
||||
|
||||
@views = new ViewRegistry(this)
|
||||
|
||||
@notifications = new NotificationManager
|
||||
|
||||
@config = new Config({@configDirPath, resourcePath, notificationManager: @notifications, @enablePersistence})
|
||||
@setConfigSchema()
|
||||
|
||||
@keymaps = new KeymapManager({@configDirPath, resourcePath, notificationManager: @notifications})
|
||||
@config = new Config({notificationManager: @notifications, @enablePersistence})
|
||||
@config.setSchema null, {type: 'object', properties: _.clone(ConfigSchema)}
|
||||
|
||||
@keymaps = new KeymapManager({notificationManager: @notifications})
|
||||
@tooltips = new TooltipManager(keymapManager: @keymaps, viewRegistry: @views)
|
||||
|
||||
@commands = new CommandRegistry
|
||||
@commands.attach(@window)
|
||||
|
||||
@grammars = new GrammarRegistry({@config})
|
||||
|
||||
@styles = new StyleManager({@configDirPath})
|
||||
|
||||
@styles = new StyleManager()
|
||||
@packages = new PackageManager({
|
||||
devMode, @configDirPath, resourcePath, safeMode, @config, styleManager: @styles,
|
||||
@config, styleManager: @styles,
|
||||
commandRegistry: @commands, keymapManager: @keymaps, notificationManager: @notifications,
|
||||
grammarRegistry: @grammars, deserializerManager: @deserializers, viewRegistry: @views
|
||||
})
|
||||
|
||||
@themes = new ThemeManager({
|
||||
packageManager: @packages, @configDirPath, resourcePath, safeMode, @config,
|
||||
styleManager: @styles, notificationManager: @notifications, viewRegistry: @views
|
||||
packageManager: @packages, @config, styleManager: @styles,
|
||||
notificationManager: @notifications, viewRegistry: @views
|
||||
})
|
||||
|
||||
@menu = new MenuManager({resourcePath, keymapManager: @keymaps, packageManager: @packages})
|
||||
|
||||
@contextMenu = new ContextMenuManager({resourcePath, devMode, keymapManager: @keymaps})
|
||||
|
||||
@menu = new MenuManager({keymapManager: @keymaps, packageManager: @packages})
|
||||
@contextMenu = new ContextMenuManager({keymapManager: @keymaps})
|
||||
@packages.setMenuManager(@menu)
|
||||
@packages.setContextMenuManager(@contextMenu)
|
||||
@packages.setThemeManager(@themes)
|
||||
|
||||
@project = new Project({notificationManager: @notifications, packageManager: @packages, @config, @applicationDelegate})
|
||||
|
||||
@commandInstaller = new CommandInstaller(@getVersion(), @applicationDelegate)
|
||||
@commandInstaller = new CommandInstaller(@applicationDelegate)
|
||||
|
||||
@textEditors = new TextEditorRegistry({
|
||||
@config, grammarRegistry: @grammars, assert: @assert.bind(this),
|
||||
@ -205,6 +187,57 @@ class AtomEnvironment extends Model
|
||||
|
||||
@autoUpdater = new AutoUpdateManager({@applicationDelegate})
|
||||
|
||||
if @keymaps.canLoadBundledKeymapsFromMemory()
|
||||
@keymaps.loadBundledKeymaps()
|
||||
|
||||
@registerDefaultCommands()
|
||||
@registerDefaultOpeners()
|
||||
@registerDefaultDeserializers()
|
||||
@registerDefaultViewProviders()
|
||||
|
||||
@windowEventHandler = new WindowEventHandler({atomEnvironment: this, @applicationDelegate})
|
||||
|
||||
@history = new HistoryManager({@project, @commands, @stateStore})
|
||||
# Keep instances of HistoryManager in sync
|
||||
@disposables.add @history.onDidChangeProjects (e) =>
|
||||
@applicationDelegate.didChangeHistoryManager() unless e.reloaded
|
||||
|
||||
initialize: (params={}) ->
|
||||
{@window, @document, @blobStore, @configDirPath, onlyLoadBaseStyleSheets} = params
|
||||
{devMode, safeMode, resourcePath, clearWindowState} = @getLoadSettings()
|
||||
|
||||
if clearWindowState
|
||||
@getStorageFolder().clear()
|
||||
@stateStore.clear()
|
||||
|
||||
@views.initialize()
|
||||
|
||||
ConfigSchema.projectHome = {
|
||||
type: 'string',
|
||||
default: path.join(fs.getHomeDirectory(), 'github'),
|
||||
description: 'The directory where projects are assumed to be located. Packages created using the Package Generator will be stored here by default.'
|
||||
}
|
||||
@config.initialize({@configDirPath, resourcePath, projectHomeSchema: ConfigSchema.projectHome})
|
||||
|
||||
@menu.initialize({resourcePath})
|
||||
@contextMenu.initialize({resourcePath, devMode})
|
||||
|
||||
@keymaps.configDirPath = @configDirPath
|
||||
@keymaps.resourcePath = resourcePath
|
||||
@keymaps.devMode = devMode
|
||||
unless @keymaps.canLoadBundledKeymapsFromMemory()
|
||||
@keymaps.loadBundledKeymaps()
|
||||
|
||||
@commands.attach(@window)
|
||||
|
||||
@styles.initialize({@configDirPath})
|
||||
@packages.initialize({devMode, @configDirPath, resourcePath, safeMode})
|
||||
@themes.initialize({@configDirPath, resourcePath, safeMode})
|
||||
|
||||
@commandInstaller.initialize(@getVersion())
|
||||
@workspace.initialize()
|
||||
@autoUpdater.initialize()
|
||||
|
||||
@config.load()
|
||||
|
||||
@themes.loadBaseStylesheets()
|
||||
@ -215,30 +248,17 @@ class AtomEnvironment extends Model
|
||||
@stylesElement = @styles.buildStylesElement()
|
||||
@document.head.appendChild(@stylesElement)
|
||||
|
||||
@disposables.add(@applicationDelegate.disableZoom())
|
||||
|
||||
@keymaps.subscribeToFileReadFailure()
|
||||
@keymaps.loadBundledKeymaps()
|
||||
|
||||
@registerDefaultCommands()
|
||||
@registerDefaultOpeners()
|
||||
@registerDefaultDeserializers()
|
||||
@registerDefaultViewProviders()
|
||||
|
||||
@installUncaughtErrorHandler()
|
||||
@attachSaveStateListeners()
|
||||
@installWindowEventHandler()
|
||||
@windowEventHandler.initialize(@window, @document)
|
||||
|
||||
@observeAutoHideMenuBar()
|
||||
|
||||
@history = new HistoryManager({@project, @commands, localStorage})
|
||||
# Keep instances of HistoryManager in sync
|
||||
@history.onDidChangeProjects (e) =>
|
||||
@applicationDelegate.didChangeHistoryManager() unless e.reloaded
|
||||
@history.initialize(@window.localStorage)
|
||||
@disposables.add @applicationDelegate.onDidChangeHistoryManager(=> @history.loadState())
|
||||
|
||||
new ReopenProjectMenuManager({@menu, @commands, @history, @config, open: (paths) => @open(pathsToOpen: paths)})
|
||||
|
||||
attachSaveStateListeners: ->
|
||||
saveState = _.debounce((=>
|
||||
window.requestIdleCallback => @saveState({isUnloading: false}) unless @unloaded
|
||||
@ -249,9 +269,6 @@ class AtomEnvironment extends Model
|
||||
@document.removeEventListener('mousedown', saveState, true)
|
||||
@document.removeEventListener('keydown', saveState, true)
|
||||
|
||||
setConfigSchema: ->
|
||||
@config.setSchema null, {type: 'object', properties: _.clone(require('./config-schema'))}
|
||||
|
||||
registerDefaultDeserializers: ->
|
||||
@deserializers.add(Workspace)
|
||||
@deserializers.add(PaneContainer)
|
||||
@ -304,7 +321,7 @@ class AtomEnvironment extends Model
|
||||
@registerDefaultDeserializers()
|
||||
|
||||
@config.clear()
|
||||
@setConfigSchema()
|
||||
@config.setSchema null, {type: 'object', properties: _.clone(ConfigSchema)}
|
||||
|
||||
@keymaps.clear()
|
||||
@keymaps.loadBundledKeymaps()
|
||||
@ -716,7 +733,14 @@ class AtomEnvironment extends Model
|
||||
|
||||
@openInitialEmptyEditorIfNecessary()
|
||||
|
||||
Promise.all([loadStatePromise, updateProcessEnvPromise])
|
||||
loadHistoryPromise = @history.loadState().then =>
|
||||
@reopenProjectMenuManager = new ReopenProjectMenuManager({
|
||||
@menu, @commands, @history, @config,
|
||||
open: (paths) => @open(pathsToOpen: paths)
|
||||
})
|
||||
@reopenProjectMenuManager.update()
|
||||
|
||||
Promise.all([loadStatePromise, loadHistoryPromise, updateProcessEnvPromise])
|
||||
|
||||
serialize: (options) ->
|
||||
version: @constructor.version
|
||||
@ -736,6 +760,10 @@ class AtomEnvironment extends Model
|
||||
@saveBlobStoreSync()
|
||||
@unloaded = true
|
||||
|
||||
saveBlobStoreSync: ->
|
||||
if @enablePersistence
|
||||
@blobStore.save()
|
||||
|
||||
openInitialEmptyEditorIfNecessary: ->
|
||||
return unless @config.get('core.openEmptyEditorOnStart')
|
||||
if @getLoadSettings().initialPaths?.length is 0 and @workspace.getPaneItems().length is 0
|
||||
@ -747,7 +775,10 @@ class AtomEnvironment extends Model
|
||||
@lastUncaughtError = Array::slice.call(arguments)
|
||||
[message, url, line, column, originalError] = @lastUncaughtError
|
||||
|
||||
{line, column} = mapSourcePosition({source: url, line, column})
|
||||
{line, column, source} = mapSourcePosition({source: url, line, column})
|
||||
|
||||
if url is '<embedded>'
|
||||
url = source
|
||||
|
||||
eventObject = {message, url, line, column, originalError}
|
||||
|
||||
@ -765,10 +796,12 @@ class AtomEnvironment extends Model
|
||||
@window.onerror = @previousWindowErrorHandler
|
||||
|
||||
installWindowEventHandler: ->
|
||||
@windowEventHandler = new WindowEventHandler({atomEnvironment: this, @applicationDelegate, @window, @document})
|
||||
@windowEventHandler = new WindowEventHandler({atomEnvironment: this, @applicationDelegate})
|
||||
@windowEventHandler.initialize(@window, @document)
|
||||
|
||||
uninstallWindowEventHandler: ->
|
||||
@windowEventHandler?.unsubscribe()
|
||||
@windowEventHandler = null
|
||||
|
||||
###
|
||||
Section: Messaging the User
|
||||
@ -840,6 +873,8 @@ class AtomEnvironment extends Model
|
||||
error.metadata = callbackOrMetadata
|
||||
|
||||
@emitter.emit 'did-fail-assertion', error
|
||||
unless @isReleasedVersion()
|
||||
throw error
|
||||
|
||||
false
|
||||
|
||||
@ -867,11 +902,6 @@ class AtomEnvironment extends Model
|
||||
showSaveDialogSync: (options={}) ->
|
||||
@applicationDelegate.showSaveDialog(options)
|
||||
|
||||
saveBlobStoreSync: ->
|
||||
return unless @enablePersistence
|
||||
|
||||
@blobStore.save()
|
||||
|
||||
saveState: (options) ->
|
||||
new Promise (resolve, reject) =>
|
||||
if @enablePersistence and @project
|
||||
@ -988,6 +1018,16 @@ class AtomEnvironment extends Model
|
||||
|
||||
return
|
||||
|
||||
resolveProxy: (url) ->
|
||||
return new Promise (resolve, reject) =>
|
||||
requestId = @nextProxyRequestId++
|
||||
disposable = @applicationDelegate.onDidResolveProxy (id, proxy) ->
|
||||
if id is requestId
|
||||
disposable.dispose()
|
||||
resolve(proxy)
|
||||
|
||||
@applicationDelegate.resolveProxy(requestId, url)
|
||||
|
||||
# Preserve this deprecation until 2.0. Sorry. Should have removed Q sooner.
|
||||
Promise.prototype.done = (callback) ->
|
||||
deprecate("Atom now uses ES6 Promises instead of Q. Call promise.then instead of promise.done")
|
||||
|
@ -7,21 +7,23 @@ export default class AutoUpdateManager {
|
||||
this.applicationDelegate = applicationDelegate
|
||||
this.subscriptions = new CompositeDisposable()
|
||||
this.emitter = new Emitter()
|
||||
}
|
||||
|
||||
initialize () {
|
||||
this.subscriptions.add(
|
||||
applicationDelegate.onDidBeginCheckingForUpdate(() => {
|
||||
this.applicationDelegate.onDidBeginCheckingForUpdate(() => {
|
||||
this.emitter.emit('did-begin-checking-for-update')
|
||||
}),
|
||||
applicationDelegate.onDidBeginDownloadingUpdate(() => {
|
||||
this.applicationDelegate.onDidBeginDownloadingUpdate(() => {
|
||||
this.emitter.emit('did-begin-downloading-update')
|
||||
}),
|
||||
applicationDelegate.onDidCompleteDownloadingUpdate((details) => {
|
||||
this.applicationDelegate.onDidCompleteDownloadingUpdate((details) => {
|
||||
this.emitter.emit('did-complete-downloading-update', details)
|
||||
}),
|
||||
applicationDelegate.onUpdateNotAvailable(() => {
|
||||
this.applicationDelegate.onUpdateNotAvailable(() => {
|
||||
this.emitter.emit('update-not-available')
|
||||
}),
|
||||
applicationDelegate.onUpdateError(() => {
|
||||
this.applicationDelegate.onUpdateError(() => {
|
||||
this.emitter.emit('update-error')
|
||||
})
|
||||
)
|
||||
|
20
src/babel.js
20
src/babel.js
@ -6,7 +6,6 @@ var defaultOptions = require('../static/babelrc.json')
|
||||
|
||||
var babel = null
|
||||
var babelVersionDirectory = null
|
||||
var options = null
|
||||
|
||||
var PREFIXES = [
|
||||
'/** @babel */',
|
||||
@ -48,27 +47,16 @@ exports.compile = function (sourceCode, filePath) {
|
||||
var noop = function () {}
|
||||
Logger.prototype.debug = noop
|
||||
Logger.prototype.verbose = noop
|
||||
|
||||
options = {ast: false, babelrc: false}
|
||||
for (var key in defaultOptions) {
|
||||
if (key === 'plugins') {
|
||||
const plugins = []
|
||||
for (const [pluginName, pluginOptions] of defaultOptions[key]) {
|
||||
plugins.push([require.resolve(`babel-plugin-${pluginName}`), pluginOptions])
|
||||
}
|
||||
options[key] = plugins
|
||||
} else {
|
||||
options[key] = defaultOptions[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
filePath = 'file:///' + path.resolve(filePath).replace(/\\/g, '/')
|
||||
}
|
||||
|
||||
options.filename = filePath
|
||||
|
||||
var options = {filename: filePath}
|
||||
for (var key in defaultOptions) {
|
||||
options[key] = defaultOptions[key]
|
||||
}
|
||||
return babel.transform(sourceCode, options).code
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,9 @@ symlinkCommandWithPrivilegeSync = (sourcePath, destinationPath) ->
|
||||
|
||||
module.exports =
|
||||
class CommandInstaller
|
||||
constructor: (@appVersion, @applicationDelegate) ->
|
||||
constructor: (@applicationDelegate) ->
|
||||
|
||||
initialize: (@appVersion) ->
|
||||
|
||||
getInstallDirectory: ->
|
||||
"/usr/local/bin"
|
||||
|
@ -91,19 +91,20 @@ class CommandRegistry
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to remove the
|
||||
# added command handler(s).
|
||||
add: (target, commandName, callback) ->
|
||||
add: (target, commandName, callback, throwOnInvalidSelector = true) ->
|
||||
if typeof commandName is 'object'
|
||||
commands = commandName
|
||||
throwOnInvalidSelector = callback
|
||||
disposable = new CompositeDisposable
|
||||
for commandName, callback of commands
|
||||
disposable.add @add(target, commandName, callback)
|
||||
disposable.add @add(target, commandName, callback, throwOnInvalidSelector)
|
||||
return disposable
|
||||
|
||||
if typeof callback isnt 'function'
|
||||
throw new Error("Can't register a command with non-function callback.")
|
||||
|
||||
if typeof target is 'string'
|
||||
validateSelector(target)
|
||||
validateSelector(target) if throwOnInvalidSelector
|
||||
@addSelectorBasedListener(target, commandName, callback)
|
||||
else
|
||||
@addInlineListener(target, commandName, callback)
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
var path = require('path')
|
||||
var fs = require('fs-plus')
|
||||
var sourceMapSupport = require('source-map-support')
|
||||
|
||||
var PackageTranspilationRegistry = require('./package-transpilation-registry')
|
||||
var CSON = null
|
||||
@ -113,109 +114,119 @@ function writeCachedJavascript (relativeCachePath, code) {
|
||||
|
||||
var INLINE_SOURCE_MAP_REGEXP = /\/\/[#@]\s*sourceMappingURL=([^'"\n]+)\s*$/mg
|
||||
|
||||
require('source-map-support').install({
|
||||
handleUncaughtExceptions: false,
|
||||
exports.install = function (resourcesPath, nodeRequire) {
|
||||
sourceMapSupport.install({
|
||||
handleUncaughtExceptions: false,
|
||||
|
||||
// Most of this logic is the same as the default implementation in the
|
||||
// source-map-support module, but we've overridden it to read the javascript
|
||||
// code from our cache directory.
|
||||
retrieveSourceMap: function (filePath) {
|
||||
if (!cacheDirectory || !fs.isFileSync(filePath)) {
|
||||
return null
|
||||
}
|
||||
// Most of this logic is the same as the default implementation in the
|
||||
// source-map-support module, but we've overridden it to read the javascript
|
||||
// code from our cache directory.
|
||||
retrieveSourceMap: function (filePath) {
|
||||
if (filePath === '<embedded>') {
|
||||
return {
|
||||
map: snapshotResult.sourceMap, // eslint-disable-line no-undef
|
||||
url: path.join(resourcesPath, 'app', 'static', 'index.js')
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
var sourceCode = fs.readFileSync(filePath, 'utf8')
|
||||
} catch (error) {
|
||||
console.warn('Error reading source file', error.stack)
|
||||
return null
|
||||
}
|
||||
if (!cacheDirectory || !fs.isFileSync(filePath)) {
|
||||
return null
|
||||
}
|
||||
|
||||
var compiler = COMPILERS[path.extname(filePath)]
|
||||
if (!compiler) compiler = COMPILERS['.js']
|
||||
try {
|
||||
var sourceCode = fs.readFileSync(filePath, 'utf8')
|
||||
} catch (error) {
|
||||
console.warn('Error reading source file', error.stack)
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
var fileData = readCachedJavascript(compiler.getCachePath(sourceCode, filePath))
|
||||
} catch (error) {
|
||||
console.warn('Error reading compiled file', error.stack)
|
||||
return null
|
||||
}
|
||||
var compiler = COMPILERS[path.extname(filePath)]
|
||||
if (!compiler) compiler = COMPILERS['.js']
|
||||
|
||||
if (fileData == null) {
|
||||
return null
|
||||
}
|
||||
try {
|
||||
var fileData = readCachedJavascript(compiler.getCachePath(sourceCode, filePath))
|
||||
} catch (error) {
|
||||
console.warn('Error reading compiled file', error.stack)
|
||||
return null
|
||||
}
|
||||
|
||||
var match, lastMatch
|
||||
INLINE_SOURCE_MAP_REGEXP.lastIndex = 0
|
||||
while ((match = INLINE_SOURCE_MAP_REGEXP.exec(fileData))) {
|
||||
lastMatch = match
|
||||
}
|
||||
if (lastMatch == null) {
|
||||
return null
|
||||
}
|
||||
if (fileData == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
var sourceMappingURL = lastMatch[1]
|
||||
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1)
|
||||
var match, lastMatch
|
||||
INLINE_SOURCE_MAP_REGEXP.lastIndex = 0
|
||||
while ((match = INLINE_SOURCE_MAP_REGEXP.exec(fileData))) {
|
||||
lastMatch = match
|
||||
}
|
||||
if (lastMatch == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
var sourceMap = JSON.parse(new Buffer(rawData, 'base64'))
|
||||
} catch (error) {
|
||||
console.warn('Error parsing source map', error.stack)
|
||||
return null
|
||||
}
|
||||
var sourceMappingURL = lastMatch[1]
|
||||
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1)
|
||||
|
||||
return {
|
||||
map: sourceMap,
|
||||
url: null
|
||||
}
|
||||
}
|
||||
})
|
||||
try {
|
||||
var sourceMap = JSON.parse(new Buffer(rawData, 'base64'))
|
||||
} catch (error) {
|
||||
console.warn('Error parsing source map', error.stack)
|
||||
return null
|
||||
}
|
||||
|
||||
var prepareStackTraceWithSourceMapping = Error.prepareStackTrace
|
||||
var prepareStackTrace = prepareStackTraceWithSourceMapping
|
||||
|
||||
function prepareStackTraceWithRawStackAssignment (error, frames) {
|
||||
if (error.rawStack) { // avoid infinite recursion
|
||||
return prepareStackTraceWithSourceMapping(error, frames)
|
||||
} else {
|
||||
error.rawStack = frames
|
||||
return prepareStackTrace(error, frames)
|
||||
}
|
||||
}
|
||||
|
||||
Error.stackTraceLimit = 30
|
||||
|
||||
Object.defineProperty(Error, 'prepareStackTrace', {
|
||||
get: function () {
|
||||
return prepareStackTraceWithRawStackAssignment
|
||||
},
|
||||
|
||||
set: function (newValue) {
|
||||
prepareStackTrace = newValue
|
||||
process.nextTick(function () {
|
||||
prepareStackTrace = prepareStackTraceWithSourceMapping
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Error.prototype.getRawStack = function () { // eslint-disable-line no-extend-native
|
||||
// Access this.stack to ensure prepareStackTrace has been run on this error
|
||||
// because it assigns this.rawStack as a side-effect
|
||||
this.stack
|
||||
return this.rawStack
|
||||
}
|
||||
|
||||
Object.keys(COMPILERS).forEach(function (extension) {
|
||||
var compiler = COMPILERS[extension]
|
||||
|
||||
Object.defineProperty(require.extensions, extension, {
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
value: function (module, filePath) {
|
||||
var code = compileFileAtPath(compiler, filePath, extension)
|
||||
return module._compile(code, filePath)
|
||||
return {
|
||||
map: sourceMap,
|
||||
url: null
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
var prepareStackTraceWithSourceMapping = Error.prepareStackTrace
|
||||
var prepareStackTrace = prepareStackTraceWithSourceMapping
|
||||
|
||||
function prepareStackTraceWithRawStackAssignment (error, frames) {
|
||||
if (error.rawStack) { // avoid infinite recursion
|
||||
return prepareStackTraceWithSourceMapping(error, frames)
|
||||
} else {
|
||||
error.rawStack = frames
|
||||
return prepareStackTrace(error, frames)
|
||||
}
|
||||
}
|
||||
|
||||
Error.stackTraceLimit = 30
|
||||
|
||||
Object.defineProperty(Error, 'prepareStackTrace', {
|
||||
get: function () {
|
||||
return prepareStackTraceWithRawStackAssignment
|
||||
},
|
||||
|
||||
set: function (newValue) {
|
||||
prepareStackTrace = newValue
|
||||
process.nextTick(function () {
|
||||
prepareStackTrace = prepareStackTraceWithSourceMapping
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Error.prototype.getRawStack = function () { // eslint-disable-line no-extend-native
|
||||
// Access this.stack to ensure prepareStackTrace has been run on this error
|
||||
// because it assigns this.rawStack as a side-effect
|
||||
this.stack
|
||||
return this.rawStack
|
||||
}
|
||||
|
||||
Object.keys(COMPILERS).forEach(function (extension) {
|
||||
var compiler = COMPILERS[extension]
|
||||
|
||||
Object.defineProperty(nodeRequire.extensions, extension, {
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
value: function (module, filePath) {
|
||||
var code = compileFileAtPath(compiler, filePath, extension)
|
||||
return module._compile(code, filePath)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
exports.supportedExtensions = Object.keys(COMPILERS)
|
||||
exports.resetCacheStats()
|
||||
|
@ -1,8 +1,3 @@
|
||||
/** @babel */
|
||||
|
||||
import path from 'path'
|
||||
import fs from 'fs-plus'
|
||||
|
||||
// This is loaded by atom-environment.coffee. See
|
||||
// https://atom.io/docs/api/latest/Config for more information about config
|
||||
// schemas.
|
||||
@ -58,11 +53,6 @@ const configSchema = {
|
||||
},
|
||||
description: 'Names of UI and syntax themes which will be used when Atom starts.'
|
||||
},
|
||||
projectHome: {
|
||||
type: 'string',
|
||||
default: path.join(fs.getHomeDirectory(), 'github'),
|
||||
description: 'The directory where projects are assumed to be located. Packages created using the Package Generator will be stored here by default.'
|
||||
},
|
||||
audioBeep: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
@ -506,4 +496,4 @@ if (process.platform === 'darwin') {
|
||||
}
|
||||
}
|
||||
|
||||
export default configSchema
|
||||
module.exports = configSchema
|
||||
|
@ -398,11 +398,16 @@ class Config
|
||||
value
|
||||
|
||||
# Created during initialization, available as `atom.config`
|
||||
constructor: ({@configDirPath, @resourcePath, @notificationManager, @enablePersistence}={}) ->
|
||||
constructor: ({@notificationManager, @enablePersistence}={}) ->
|
||||
@clear()
|
||||
|
||||
initialize: ({@configDirPath, @resourcePath, projectHomeSchema}) ->
|
||||
if @enablePersistence?
|
||||
@configFilePath = fs.resolve(@configDirPath, 'config', ['json', 'cson'])
|
||||
@configFilePath ?= path.join(@configDirPath, 'config.cson')
|
||||
@clear()
|
||||
|
||||
@schema.properties.core.properties.projectHome = projectHomeSchema
|
||||
@defaultSettings.core.projectHome = projectHomeSchema.default
|
||||
|
||||
clear: ->
|
||||
@emitter = new Emitter
|
||||
@ -839,7 +844,7 @@ class Config
|
||||
relativePath = sourcePath.substring(templateConfigDirPath.length + 1)
|
||||
destinationPath = path.join(@configDirPath, relativePath)
|
||||
queue.push({sourcePath, destinationPath})
|
||||
fs.traverseTree(templateConfigDirPath, onConfigDirFile, (path) -> true)
|
||||
fs.traverseTree(templateConfigDirPath, onConfigDirFile, ((path) -> true), (->))
|
||||
|
||||
loadUserConfig: ->
|
||||
return if @shouldNotAccessFileSystem()
|
||||
|
@ -40,15 +40,17 @@ platformContextMenu = require('../package.json')?._atomMenu?['context-menu']
|
||||
# {::add} for more information.
|
||||
module.exports =
|
||||
class ContextMenuManager
|
||||
constructor: ({@resourcePath, @devMode, @keymapManager}) ->
|
||||
constructor: ({@keymapManager}) ->
|
||||
@definitions = {'.overlayer': []} # TODO: Remove once color picker package stops touching private data
|
||||
@clear()
|
||||
|
||||
@keymapManager.onDidLoadBundledKeymaps => @loadPlatformItems()
|
||||
|
||||
initialize: ({@resourcePath, @devMode}) ->
|
||||
|
||||
loadPlatformItems: ->
|
||||
if platformContextMenu?
|
||||
@add(platformContextMenu)
|
||||
@add(platformContextMenu, @devMode ? false)
|
||||
else
|
||||
menusDirPath = path.join(@resourcePath, 'menus')
|
||||
platformMenuPath = fs.resolve(menusDirPath, process.platform, ['cson', 'json'])
|
||||
@ -107,11 +109,11 @@ class ContextMenuManager
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to remove the
|
||||
# added menu items.
|
||||
add: (itemsBySelector) ->
|
||||
add: (itemsBySelector, throwOnInvalidSelector = true) ->
|
||||
addedItemSets = []
|
||||
|
||||
for selector, items of itemsBySelector
|
||||
validateSelector(selector)
|
||||
validateSelector(selector) if throwOnInvalidSelector
|
||||
itemSet = new ContextMenuItemSet(selector, items)
|
||||
addedItemSets.push(itemSet)
|
||||
@itemSets.push(itemSet)
|
||||
@ -206,14 +208,17 @@ class ContextMenuManager
|
||||
clear: ->
|
||||
@activeElement = null
|
||||
@itemSets = []
|
||||
@add 'atom-workspace': [{
|
||||
label: 'Inspect Element'
|
||||
command: 'application:inspect'
|
||||
devMode: true
|
||||
created: (event) ->
|
||||
{pageX, pageY} = event
|
||||
@commandDetail = {x: pageX, y: pageY}
|
||||
}]
|
||||
inspectElement = {
|
||||
'atom-workspace': [{
|
||||
label: 'Inspect Element'
|
||||
command: 'application:inspect'
|
||||
devMode: true
|
||||
created: (event) ->
|
||||
{pageX, pageY} = event
|
||||
@commandDetail = {x: pageX, y: pageY}
|
||||
}]
|
||||
}
|
||||
@add(inspectElement, false)
|
||||
|
||||
class ContextMenuItemSet
|
||||
constructor: (@selector, @items) ->
|
||||
|
@ -11,13 +11,16 @@ class DirectorySearch
|
||||
excludeVcsIgnores: options.excludeVcsIgnores
|
||||
globalExclusions: options.exclusions
|
||||
follow: options.follow
|
||||
searchOptions =
|
||||
leadingContextLineCount: options.leadingContextLineCount
|
||||
trailingContextLineCount: options.trailingContextLineCount
|
||||
@task = new Task(require.resolve('./scan-handler'))
|
||||
@task.on 'scan:result-found', options.didMatch
|
||||
@task.on 'scan:file-error', options.didError
|
||||
@task.on 'scan:paths-searched', options.didSearchPaths
|
||||
@promise = new Promise (resolve, reject) =>
|
||||
@task.on('task:cancelled', reject)
|
||||
@task.start rootPaths, regex.source, scanHandlerOptions, =>
|
||||
@task.start rootPaths, regex.source, scanHandlerOptions, searchOptions, =>
|
||||
@task.terminate()
|
||||
resolve()
|
||||
|
||||
|
@ -14,16 +14,15 @@ class FileSystemBlobStore {
|
||||
constructor (directory) {
|
||||
this.blobFilename = path.join(directory, 'BLOB')
|
||||
this.blobMapFilename = path.join(directory, 'MAP')
|
||||
this.invalidationKeysFilename = path.join(directory, 'INVKEYS')
|
||||
this.lockFilename = path.join(directory, 'LOCK')
|
||||
this.reset()
|
||||
}
|
||||
|
||||
reset () {
|
||||
this.inMemoryBlobs = new Map()
|
||||
this.invalidationKeys = {}
|
||||
this.storedBlob = new Buffer(0)
|
||||
this.storedBlobMap = {}
|
||||
this.usedKeys = new Set()
|
||||
}
|
||||
|
||||
load () {
|
||||
@ -33,14 +32,10 @@ class FileSystemBlobStore {
|
||||
if (!fs.existsSync(this.blobFilename)) {
|
||||
return
|
||||
}
|
||||
if (!fs.existsSync(this.invalidationKeysFilename)) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
this.storedBlob = fs.readFileSync(this.blobFilename)
|
||||
this.storedBlobMap = JSON.parse(fs.readFileSync(this.blobMapFilename))
|
||||
this.invalidationKeys = JSON.parse(fs.readFileSync(this.invalidationKeysFilename))
|
||||
} catch (e) {
|
||||
this.reset()
|
||||
}
|
||||
@ -50,7 +45,6 @@ class FileSystemBlobStore {
|
||||
let dump = this.getDump()
|
||||
let blobToStore = Buffer.concat(dump[0])
|
||||
let mapToStore = JSON.stringify(dump[1])
|
||||
let invalidationKeysToStore = JSON.stringify(this.invalidationKeys)
|
||||
|
||||
let acquiredLock = false
|
||||
try {
|
||||
@ -59,7 +53,6 @@ class FileSystemBlobStore {
|
||||
|
||||
fs.writeFileSync(this.blobFilename, blobToStore)
|
||||
fs.writeFileSync(this.blobMapFilename, mapToStore)
|
||||
fs.writeFileSync(this.invalidationKeysFilename, invalidationKeysToStore)
|
||||
} catch (error) {
|
||||
// Swallow the exception silently only if we fail to acquire the lock.
|
||||
if (error.code !== 'EEXIST') {
|
||||
@ -72,20 +65,19 @@ class FileSystemBlobStore {
|
||||
}
|
||||
}
|
||||
|
||||
has (key, invalidationKey) {
|
||||
let containsKey = this.inMemoryBlobs.has(key) || this.storedBlobMap.hasOwnProperty(key)
|
||||
let isValid = this.invalidationKeys[key] === invalidationKey
|
||||
return containsKey && isValid
|
||||
has (key) {
|
||||
return this.inMemoryBlobs.has(key) || this.storedBlobMap.hasOwnProperty(key)
|
||||
}
|
||||
|
||||
get (key, invalidationKey) {
|
||||
if (this.has(key, invalidationKey)) {
|
||||
get (key) {
|
||||
if (this.has(key)) {
|
||||
this.usedKeys.add(key)
|
||||
return this.getFromMemory(key) || this.getFromStorage(key)
|
||||
}
|
||||
}
|
||||
|
||||
set (key, invalidationKey, buffer) {
|
||||
this.invalidationKeys[key] = invalidationKey
|
||||
set (key, buffer) {
|
||||
this.usedKeys.add(key)
|
||||
return this.inMemoryBlobs.set(key, buffer)
|
||||
}
|
||||
|
||||
@ -119,11 +111,13 @@ class FileSystemBlobStore {
|
||||
}
|
||||
|
||||
for (let key of this.inMemoryBlobs.keys()) {
|
||||
dump(key, this.getFromMemory.bind(this))
|
||||
if (this.usedKeys.has(key)) {
|
||||
dump(key, this.getFromMemory.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
for (let key of Object.keys(this.storedBlobMap)) {
|
||||
if (!blobMap[key]) {
|
||||
if (!blobMap[key] && this.usedKeys.has(key)) {
|
||||
dump(key, this.getFromStorage.bind(this))
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ let windowLoadSettings = null
|
||||
|
||||
module.exports = () => {
|
||||
if (!windowLoadSettings) {
|
||||
windowLoadSettings = remote.getCurrentWindow().loadSettings
|
||||
windowLoadSettings = JSON.parse(remote.getCurrentWindow().loadSettingsJSON)
|
||||
}
|
||||
return windowLoadSettings
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ PathSplitRegex = new RegExp("[/.]")
|
||||
module.exports =
|
||||
class GrammarRegistry extends FirstMate.GrammarRegistry
|
||||
constructor: ({@config}={}) ->
|
||||
super(maxTokensPerLine: 100)
|
||||
super(maxTokensPerLine: 100, maxLineLength: 1000)
|
||||
|
||||
createToken: (value, scopes) -> new Token({value, scopes})
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/** @babel */
|
||||
|
||||
import {Emitter} from 'event-kit'
|
||||
import {Emitter, CompositeDisposable} from 'event-kit'
|
||||
|
||||
// Extended: History manager for remembering which projects have been opened.
|
||||
//
|
||||
@ -8,12 +8,21 @@ import {Emitter} from 'event-kit'
|
||||
//
|
||||
// The project history is used to enable the 'Reopen Project' menu.
|
||||
export class HistoryManager {
|
||||
constructor ({project, commands, localStorage}) {
|
||||
this.localStorage = localStorage
|
||||
commands.add('atom-workspace', {'application:clear-project-history': this.clearProjects.bind(this)})
|
||||
constructor ({project, commands, stateStore}) {
|
||||
this.stateStore = stateStore
|
||||
this.emitter = new Emitter()
|
||||
this.loadState()
|
||||
project.onDidChangePaths((projectPaths) => this.addProject(projectPaths))
|
||||
this.projects = []
|
||||
this.disposables = new CompositeDisposable()
|
||||
this.disposables.add(commands.add('atom-workspace', {'application:clear-project-history': this.clearProjects.bind(this)}, false))
|
||||
this.disposables.add(project.onDidChangePaths((projectPaths) => this.addProject(projectPaths)))
|
||||
}
|
||||
|
||||
initialize (localStorage) {
|
||||
this.localStorage = localStorage
|
||||
}
|
||||
|
||||
destroy () {
|
||||
this.disposables.dispose()
|
||||
}
|
||||
|
||||
// Public: Obtain a list of previously opened projects.
|
||||
@ -27,9 +36,12 @@ export class HistoryManager {
|
||||
//
|
||||
// Note: This is not a privacy function - other traces will still exist,
|
||||
// e.g. window state.
|
||||
clearProjects () {
|
||||
//
|
||||
// Return a {Promise} that resolves when the history has been successfully
|
||||
// cleared.
|
||||
async clearProjects () {
|
||||
this.projects = []
|
||||
this.saveState()
|
||||
await this.saveState()
|
||||
this.didChangeProjects()
|
||||
}
|
||||
|
||||
@ -46,7 +58,7 @@ export class HistoryManager {
|
||||
this.emitter.emit('did-change-projects', args || { reloaded: false })
|
||||
}
|
||||
|
||||
addProject (paths, lastOpened) {
|
||||
async addProject (paths, lastOpened) {
|
||||
if (paths.length === 0) return
|
||||
|
||||
let project = this.getProject(paths)
|
||||
@ -57,11 +69,11 @@ export class HistoryManager {
|
||||
project.lastOpened = lastOpened || new Date()
|
||||
this.projects.sort((a, b) => b.lastOpened - a.lastOpened)
|
||||
|
||||
this.saveState()
|
||||
await this.saveState()
|
||||
this.didChangeProjects()
|
||||
}
|
||||
|
||||
removeProject (paths) {
|
||||
async removeProject (paths) {
|
||||
if (paths.length === 0) return
|
||||
|
||||
let project = this.getProject(paths)
|
||||
@ -70,7 +82,7 @@ export class HistoryManager {
|
||||
let index = this.projects.indexOf(project)
|
||||
this.projects.splice(index, 1)
|
||||
|
||||
this.saveState()
|
||||
await this.saveState()
|
||||
this.didChangeProjects()
|
||||
}
|
||||
|
||||
@ -84,31 +96,23 @@ export class HistoryManager {
|
||||
return null
|
||||
}
|
||||
|
||||
loadState () {
|
||||
const state = JSON.parse(this.localStorage.getItem('history'))
|
||||
if (state && state.projects) {
|
||||
this.projects = state.projects.filter(p => Array.isArray(p.paths) && p.paths.length > 0).map(p => new HistoryProject(p.paths, new Date(p.lastOpened)))
|
||||
this.didChangeProjects({ reloaded: true })
|
||||
async loadState () {
|
||||
let history = await this.stateStore.load('history-manager')
|
||||
if (!history) {
|
||||
history = JSON.parse(this.localStorage.getItem('history'))
|
||||
}
|
||||
|
||||
if (history && history.projects) {
|
||||
this.projects = history.projects.filter(p => Array.isArray(p.paths) && p.paths.length > 0).map(p => new HistoryProject(p.paths, new Date(p.lastOpened)))
|
||||
this.didChangeProjects({reloaded: true})
|
||||
} else {
|
||||
this.projects = []
|
||||
}
|
||||
}
|
||||
|
||||
saveState () {
|
||||
const state = JSON.stringify({
|
||||
projects: this.projects.map(p => ({
|
||||
paths: p.paths, lastOpened: p.lastOpened
|
||||
}))
|
||||
})
|
||||
this.localStorage.setItem('history', state)
|
||||
}
|
||||
|
||||
async importProjectHistory () {
|
||||
for (let project of await HistoryImporter.getAllProjects()) {
|
||||
this.addProject(project.paths, project.lastOpened)
|
||||
}
|
||||
this.saveState()
|
||||
this.didChangeProjects()
|
||||
async saveState () {
|
||||
const projects = this.projects.map(p => ({paths: p.paths, lastOpened: p.lastOpened}))
|
||||
await this.stateStore.save('history-manager', {projects})
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,32 +136,3 @@ export class HistoryProject {
|
||||
set lastOpened (lastOpened) { this._lastOpened = lastOpened }
|
||||
get lastOpened () { return this._lastOpened }
|
||||
}
|
||||
|
||||
class HistoryImporter {
|
||||
static async getStateStoreCursor () {
|
||||
const db = await atom.stateStore.dbPromise
|
||||
const store = db.transaction(['states']).objectStore('states')
|
||||
return store.openCursor()
|
||||
}
|
||||
|
||||
static async getAllProjects (stateStore) {
|
||||
const request = await HistoryImporter.getStateStoreCursor()
|
||||
return new Promise((resolve, reject) => {
|
||||
const rows = []
|
||||
request.onerror = reject
|
||||
request.onsuccess = event => {
|
||||
const cursor = event.target.result
|
||||
if (cursor) {
|
||||
let project = cursor.value.value.project
|
||||
let storedAt = cursor.value.storedAt
|
||||
if (project && project.paths && storedAt) {
|
||||
rows.push(new HistoryProject(project.paths, new Date(Date.parse(storedAt))))
|
||||
}
|
||||
cursor.continue()
|
||||
} else {
|
||||
resolve(rows)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,69 @@
|
||||
AtomEnvironment = require './atom-environment'
|
||||
ApplicationDelegate = require './application-delegate'
|
||||
Clipboard = require './clipboard'
|
||||
TextEditor = require './text-editor'
|
||||
TextEditorComponent = require './text-editor-component'
|
||||
FileSystemBlobStore = require './file-system-blob-store'
|
||||
NativeCompileCache = require './native-compile-cache'
|
||||
CompileCache = require './compile-cache'
|
||||
ModuleCache = require './module-cache'
|
||||
|
||||
require('about')
|
||||
require('archive-view')
|
||||
require('autocomplete-atom-api')
|
||||
require('autocomplete-css')
|
||||
require('autocomplete-html')
|
||||
require('autocomplete-plus')
|
||||
require('autocomplete-snippets')
|
||||
require('autoflow')
|
||||
require('autosave')
|
||||
require('background-tips')
|
||||
require('bookmarks')
|
||||
require('bracket-matcher')
|
||||
require('command-palette')
|
||||
require('deprecation-cop')
|
||||
require('dev-live-reload')
|
||||
require('encoding-selector')
|
||||
require('exception-reporting')
|
||||
require('dalek')
|
||||
require('find-and-replace')
|
||||
require('fuzzy-finder')
|
||||
require('git-diff')
|
||||
require('go-to-line')
|
||||
require('grammar-selector')
|
||||
require('image-view')
|
||||
require('incompatible-packages')
|
||||
require('keybinding-resolver')
|
||||
require('line-ending-selector')
|
||||
require('link')
|
||||
require('markdown-preview')
|
||||
require('metrics')
|
||||
require('notifications')
|
||||
require('open-on-github')
|
||||
require('package-generator')
|
||||
require('settings-view')
|
||||
require('snippets')
|
||||
require('spell-check')
|
||||
require('status-bar')
|
||||
require('styleguide')
|
||||
require('symbols-view')
|
||||
require('tabs')
|
||||
require('timecop')
|
||||
require('tree-view')
|
||||
require('update-package-dependencies')
|
||||
require('welcome')
|
||||
require('whitespace')
|
||||
require('wrap-guide')
|
||||
|
||||
clipboard = new Clipboard
|
||||
TextEditor.setClipboard(clipboard)
|
||||
|
||||
window.atom = new AtomEnvironment({
|
||||
clipboard,
|
||||
applicationDelegate: new ApplicationDelegate,
|
||||
enablePersistence: true
|
||||
})
|
||||
|
||||
# Like sands through the hourglass, so are the days of our lives.
|
||||
module.exports = ({blobStore}) ->
|
||||
{updateProcessEnv} = require('./update-process-env')
|
||||
@ -16,23 +82,13 @@ module.exports = ({blobStore}) ->
|
||||
# Make React faster
|
||||
process.env.NODE_ENV ?= 'production' unless devMode
|
||||
|
||||
AtomEnvironment = require './atom-environment'
|
||||
ApplicationDelegate = require './application-delegate'
|
||||
Clipboard = require './clipboard'
|
||||
TextEditor = require './text-editor'
|
||||
|
||||
clipboard = new Clipboard
|
||||
TextEditor.setClipboard(clipboard)
|
||||
|
||||
window.atom = new AtomEnvironment({
|
||||
window, document, clipboard, blobStore,
|
||||
applicationDelegate: new ApplicationDelegate,
|
||||
window.atom.initialize({
|
||||
window, document, blobStore,
|
||||
configDirPath: process.env.ATOM_HOME,
|
||||
enablePersistence: true,
|
||||
env: process.env
|
||||
})
|
||||
|
||||
atom.startEditorWindow().then ->
|
||||
window.atom.startEditorWindow().then ->
|
||||
# Workaround for focus getting cleared upon window creation
|
||||
windowFocused = ->
|
||||
window.removeEventListener('focus', windowFocused)
|
||||
|
@ -56,14 +56,16 @@ export default async function () {
|
||||
TextEditor.setClipboard(clipboard)
|
||||
|
||||
const applicationDelegate = new ApplicationDelegate()
|
||||
global.atom = new AtomEnvironment({
|
||||
const environmentParams = {
|
||||
applicationDelegate,
|
||||
window,
|
||||
document,
|
||||
clipboard,
|
||||
configDirPath: process.env.ATOM_HOME,
|
||||
enablePersistence: false
|
||||
})
|
||||
}
|
||||
global.atom = new AtomEnvironment(environmentParams)
|
||||
global.atom.initialize(environmentParams)
|
||||
|
||||
// Prevent benchmarks from modifying application menus
|
||||
global.atom.menu.sendToBrowserProcess = function () { }
|
||||
|
@ -79,7 +79,9 @@ module.exports = ({blobStore}) ->
|
||||
params.clipboard = clipboard unless params.hasOwnProperty("clipboard")
|
||||
params.blobStore = blobStore unless params.hasOwnProperty("blobStore")
|
||||
params.onlyLoadBaseStyleSheets = true unless params.hasOwnProperty("onlyLoadBaseStyleSheets")
|
||||
new AtomEnvironment(params)
|
||||
atomEnvironment = new AtomEnvironment(params)
|
||||
atomEnvironment.initialize(params)
|
||||
atomEnvironment
|
||||
|
||||
promise = testRunner({
|
||||
logFile, headless, testPaths, buildAtomEnvironment, buildDefaultApplicationDelegate, legacyTestRunner
|
||||
|
@ -11,13 +11,16 @@ KeymapManager::onDidLoadBundledKeymaps = (callback) ->
|
||||
KeymapManager::onDidLoadUserKeymap = (callback) ->
|
||||
@emitter.on 'did-load-user-keymap', callback
|
||||
|
||||
KeymapManager::canLoadBundledKeymapsFromMemory = ->
|
||||
bundledKeymaps?
|
||||
|
||||
KeymapManager::loadBundledKeymaps = ->
|
||||
keymapsPath = path.join(@resourcePath, 'keymaps')
|
||||
if bundledKeymaps?
|
||||
for keymapName, keymap of bundledKeymaps
|
||||
keymapPath = path.join(keymapsPath, keymapName)
|
||||
@add(keymapPath, keymap)
|
||||
keymapPath = "core/#{keymapName}"
|
||||
@add(keymapPath, keymap, 0, @devMode ? false)
|
||||
else
|
||||
keymapsPath = path.join(@resourcePath, 'keymaps')
|
||||
@loadKeymap(keymapsPath)
|
||||
|
||||
@emitter.emit 'did-load-bundled-keymaps'
|
||||
|
@ -2,24 +2,24 @@ CursorsComponent = require './cursors-component'
|
||||
LinesTileComponent = require './lines-tile-component'
|
||||
TiledComponent = require './tiled-component'
|
||||
|
||||
DummyLineNode = document.createElement('div')
|
||||
DummyLineNode.className = 'line'
|
||||
DummyLineNode.style.position = 'absolute'
|
||||
DummyLineNode.style.visibility = 'hidden'
|
||||
DummyLineNode.appendChild(document.createElement('span'))
|
||||
DummyLineNode.appendChild(document.createElement('span'))
|
||||
DummyLineNode.appendChild(document.createElement('span'))
|
||||
DummyLineNode.appendChild(document.createElement('span'))
|
||||
DummyLineNode.children[0].textContent = 'x'
|
||||
DummyLineNode.children[1].textContent = '我'
|
||||
DummyLineNode.children[2].textContent = 'ハ'
|
||||
DummyLineNode.children[3].textContent = '세'
|
||||
|
||||
module.exports =
|
||||
class LinesComponent extends TiledComponent
|
||||
placeholderTextDiv: null
|
||||
|
||||
constructor: ({@views, @presenter, @domElementPool, @assert}) ->
|
||||
@DummyLineNode = document.createElement('div')
|
||||
@DummyLineNode.className = 'line'
|
||||
@DummyLineNode.style.position = 'absolute'
|
||||
@DummyLineNode.style.visibility = 'hidden'
|
||||
@DummyLineNode.appendChild(document.createElement('span'))
|
||||
@DummyLineNode.appendChild(document.createElement('span'))
|
||||
@DummyLineNode.appendChild(document.createElement('span'))
|
||||
@DummyLineNode.appendChild(document.createElement('span'))
|
||||
@DummyLineNode.children[0].textContent = 'x'
|
||||
@DummyLineNode.children[1].textContent = '我'
|
||||
@DummyLineNode.children[2].textContent = 'ハ'
|
||||
@DummyLineNode.children[3].textContent = '세'
|
||||
|
||||
@domNode = document.createElement('div')
|
||||
@domNode.classList.add('lines')
|
||||
@tilesNode = document.createElement("div")
|
||||
@ -78,15 +78,15 @@ class LinesComponent extends TiledComponent
|
||||
getTilesNode: -> @tilesNode
|
||||
|
||||
measureLineHeightAndDefaultCharWidth: ->
|
||||
@domNode.appendChild(DummyLineNode)
|
||||
@domNode.appendChild(@DummyLineNode)
|
||||
|
||||
lineHeightInPixels = DummyLineNode.getBoundingClientRect().height
|
||||
defaultCharWidth = DummyLineNode.children[0].getBoundingClientRect().width
|
||||
doubleWidthCharWidth = DummyLineNode.children[1].getBoundingClientRect().width
|
||||
halfWidthCharWidth = DummyLineNode.children[2].getBoundingClientRect().width
|
||||
koreanCharWidth = DummyLineNode.children[3].getBoundingClientRect().width
|
||||
lineHeightInPixels = @DummyLineNode.getBoundingClientRect().height
|
||||
defaultCharWidth = @DummyLineNode.children[0].getBoundingClientRect().width
|
||||
doubleWidthCharWidth = @DummyLineNode.children[1].getBoundingClientRect().width
|
||||
halfWidthCharWidth = @DummyLineNode.children[2].getBoundingClientRect().width
|
||||
koreanCharWidth = @DummyLineNode.children[3].getBoundingClientRect().width
|
||||
|
||||
@domNode.removeChild(DummyLineNode)
|
||||
@domNode.removeChild(@DummyLineNode)
|
||||
|
||||
@presenter.setLineHeight(lineHeightInPixels)
|
||||
@presenter.setBaseCharacterWidth(defaultCharWidth, doubleWidthCharWidth, halfWidthCharWidth, koreanCharWidth)
|
||||
|
@ -6,8 +6,8 @@ StorageFolder = require '../storage-folder'
|
||||
Config = require '../config'
|
||||
FileRecoveryService = require './file-recovery-service'
|
||||
ipcHelpers = require '../ipc-helpers'
|
||||
{BrowserWindow, Menu, app, dialog, ipcMain, shell} = require 'electron'
|
||||
{CompositeDisposable} = require 'event-kit'
|
||||
{BrowserWindow, Menu, app, dialog, ipcMain, shell, screen} = require 'electron'
|
||||
{CompositeDisposable, Disposable} = require 'event-kit'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
@ -17,6 +17,7 @@ url = require 'url'
|
||||
_ = require 'underscore-plus'
|
||||
FindParentDir = null
|
||||
Resolve = null
|
||||
ConfigSchema = require '../config-schema'
|
||||
|
||||
LocationSuffixRegExp = /(:\d+)(:\d+)?$/
|
||||
|
||||
@ -68,11 +69,22 @@ class AtomApplication
|
||||
@pidsToOpenWindows = {}
|
||||
@windows = []
|
||||
|
||||
@config = new Config({configDirPath: process.env.ATOM_HOME, @resourcePath, enablePersistence: true})
|
||||
@config.setSchema null, {type: 'object', properties: _.clone(require('../config-schema'))}
|
||||
@config = new Config({enablePersistence: true})
|
||||
@config.setSchema null, {type: 'object', properties: _.clone(ConfigSchema)}
|
||||
ConfigSchema.projectHome = {
|
||||
type: 'string',
|
||||
default: path.join(fs.getHomeDirectory(), 'github'),
|
||||
description: 'The directory where projects are assumed to be located. Packages created using the Package Generator will be stored here by default.'
|
||||
}
|
||||
@config.initialize({configDirPath: process.env.ATOM_HOME, @resourcePath, projectHomeSchema: ConfigSchema.projectHome})
|
||||
@config.load()
|
||||
@fileRecoveryService = new FileRecoveryService(path.join(process.env.ATOM_HOME, "recovery"))
|
||||
@storageFolder = new StorageFolder(process.env.ATOM_HOME)
|
||||
@autoUpdateManager = new AutoUpdateManager(
|
||||
@version,
|
||||
options.test or options.benchmark or options.benchmarkTest,
|
||||
@config
|
||||
)
|
||||
|
||||
@disposable = new CompositeDisposable
|
||||
@handleEvents()
|
||||
@ -89,12 +101,10 @@ class AtomApplication
|
||||
if process.platform is 'darwin' and @config.get('core.useCustomTitleBar')
|
||||
@config.unset('core.useCustomTitleBar')
|
||||
@config.set('core.titleBar', 'custom')
|
||||
|
||||
|
||||
@config.onDidChange 'core.titleBar', @promptForRestart.bind(this)
|
||||
|
||||
@autoUpdateManager = new AutoUpdateManager(
|
||||
@version, options.test or options.benchmark or options.benchmarkTest, @resourcePath, @config
|
||||
)
|
||||
process.nextTick => @autoUpdateManager.initialize()
|
||||
@applicationMenu = new ApplicationMenu(@version, @autoUpdateManager)
|
||||
@atomProtocolHandler = new AtomProtocolHandler(@resourcePath, @safeMode)
|
||||
|
||||
@ -280,6 +290,11 @@ class AtomApplication
|
||||
@disposable.add ipcHelpers.on ipcMain, 'restart-application', =>
|
||||
@restart()
|
||||
|
||||
@disposable.add ipcHelpers.on ipcMain, 'resolve-proxy', (event, requestId, url) ->
|
||||
event.sender.session.resolveProxy url, (proxy) ->
|
||||
unless event.sender.isDestroyed()
|
||||
event.sender.send('did-resolve-proxy', requestId, proxy)
|
||||
|
||||
@disposable.add ipcHelpers.on ipcMain, 'did-change-history-manager', (event) =>
|
||||
for atomWindow in @windows
|
||||
webContents = atomWindow.browserWindow.webContents
|
||||
@ -394,6 +409,8 @@ class AtomApplication
|
||||
@disposable.add ipcHelpers.on ipcMain, 'did-change-paths', =>
|
||||
@saveState(false)
|
||||
|
||||
@disposable.add(@disableZoomOnDisplayChange())
|
||||
|
||||
setupDockMenu: ->
|
||||
if process.platform is 'darwin'
|
||||
dockMenu = Menu.buildFromTemplate [
|
||||
@ -812,3 +829,17 @@ class AtomApplication
|
||||
args.push("--resource-path=#{@resourcePath}")
|
||||
app.relaunch({args})
|
||||
app.quit()
|
||||
|
||||
disableZoomOnDisplayChange: ->
|
||||
outerCallback = =>
|
||||
for window in @windows
|
||||
window.disableZoom()
|
||||
|
||||
# Set the limits every time a display is added or removed, otherwise the
|
||||
# configuration gets reset to the default, which allows zooming the
|
||||
# webframe.
|
||||
screen.on('display-added', outerCallback)
|
||||
screen.on('display-removed', outerCallback)
|
||||
new Disposable ->
|
||||
screen.removeListener('display-added', outerCallback)
|
||||
screen.removeListener('display-removed', outerCallback)
|
||||
|
@ -83,12 +83,18 @@ class AtomWindow
|
||||
@representedDirectoryPaths = loadSettings.initialPaths
|
||||
@env = loadSettings.env if loadSettings.env?
|
||||
|
||||
@browserWindow.loadSettings = loadSettings
|
||||
@browserWindow.loadSettingsJSON = JSON.stringify(loadSettings)
|
||||
|
||||
@browserWindow.on 'window:loaded', =>
|
||||
@emit 'window:loaded'
|
||||
@resolveLoadedPromise()
|
||||
|
||||
@browserWindow.on 'enter-full-screen', =>
|
||||
@browserWindow.webContents.send('did-enter-full-screen')
|
||||
|
||||
@browserWindow.on 'leave-full-screen', =>
|
||||
@browserWindow.webContents.send('did-leave-full-screen')
|
||||
|
||||
@browserWindow.loadURL url.format
|
||||
protocol: 'file'
|
||||
pathname: "#{@resourcePath}/static/index.html"
|
||||
@ -101,6 +107,7 @@ class AtomWindow
|
||||
|
||||
hasPathToOpen = not (locationsToOpen.length is 1 and not locationsToOpen[0].pathToOpen?)
|
||||
@openLocations(locationsToOpen) if hasPathToOpen and not @isSpecWindow()
|
||||
@disableZoom()
|
||||
|
||||
@atomApplication.addWindow(this)
|
||||
|
||||
@ -303,3 +310,6 @@ class AtomWindow
|
||||
@atomApplication.saveState()
|
||||
|
||||
copy: -> @browserWindow.copy()
|
||||
|
||||
disableZoom: ->
|
||||
@browserWindow.webContents.setZoomLevelLimits(1, 1)
|
||||
|
@ -14,12 +14,11 @@ module.exports =
|
||||
class AutoUpdateManager
|
||||
Object.assign @prototype, EventEmitter.prototype
|
||||
|
||||
constructor: (@version, @testMode, resourcePath, @config) ->
|
||||
constructor: (@version, @testMode, @config) ->
|
||||
@state = IdleState
|
||||
@iconPath = path.resolve(__dirname, '..', '..', 'resources', 'atom.png')
|
||||
process.nextTick => @setupAutoUpdater()
|
||||
|
||||
setupAutoUpdater: ->
|
||||
initialize: ->
|
||||
if process.platform is 'win32'
|
||||
archSuffix = if process.arch is 'ia32' then '' else '-' + process.arch
|
||||
@feedUrl = "https://atom.io/api/updates#{archSuffix}?version=#{@version}"
|
||||
|
@ -1,3 +1,7 @@
|
||||
if (typeof snapshotResult !== 'undefined') {
|
||||
snapshotResult.setGlobals(global, process, global, {}, require) // eslint-disable-line no-undef
|
||||
}
|
||||
|
||||
const startTime = Date.now()
|
||||
|
||||
const electron = require('electron')
|
||||
|
@ -83,4 +83,5 @@ function handleStartupEventWithSquirrel () {
|
||||
function setupCompileCache () {
|
||||
const CompileCache = require('../compile-cache')
|
||||
CompileCache.setAtomHomeDirectory(process.env.ATOM_HOME)
|
||||
CompileCache.install(process.resourcesPath, require)
|
||||
}
|
||||
|
@ -60,12 +60,17 @@ platformMenu = require('../package.json')?._atomMenu?.menu
|
||||
module.exports =
|
||||
class MenuManager
|
||||
constructor: ({@resourcePath, @keymapManager, @packageManager}) ->
|
||||
@initialized = false
|
||||
@pendingUpdateOperation = null
|
||||
@template = []
|
||||
@keymapManager.onDidLoadBundledKeymaps => @loadPlatformItems()
|
||||
@keymapManager.onDidReloadKeymap => @update()
|
||||
@packageManager.onDidActivateInitialPackages => @sortPackagesMenu()
|
||||
|
||||
initialize: ({@resourcePath}) ->
|
||||
@keymapManager.onDidReloadKeymap => @update()
|
||||
@update()
|
||||
@initialized = true
|
||||
|
||||
# Public: Adds the given items to the application menu.
|
||||
#
|
||||
# ## Examples
|
||||
@ -89,7 +94,7 @@ class MenuManager
|
||||
add: (items) ->
|
||||
items = _.deepClone(items)
|
||||
@merge(@template, item) for item in items
|
||||
@update()
|
||||
@update() if @initialized
|
||||
new Disposable => @remove(items)
|
||||
|
||||
remove: (items) ->
|
||||
|
@ -20,7 +20,7 @@ class Range extends semver.Range
|
||||
@unmatchedVersions.add(version)
|
||||
matches
|
||||
|
||||
nativeModules = process.binding('natives')
|
||||
nativeModules = null
|
||||
|
||||
cache =
|
||||
builtins: {}
|
||||
@ -171,6 +171,7 @@ resolveModulePath = (relativePath, parentModule) ->
|
||||
return unless relativePath
|
||||
return unless parentModule?.filename
|
||||
|
||||
nativeModules ?= process.binding('natives')
|
||||
return if nativeModules.hasOwnProperty(relativePath)
|
||||
return if relativePath[0] is '.'
|
||||
return if isAbsolute(relativePath)
|
||||
@ -212,35 +213,6 @@ registerBuiltins = (devMode) ->
|
||||
for builtin in rendererBuiltins
|
||||
cache.builtins[builtin] = path.join(rendererRoot, "#{builtin}.js")
|
||||
|
||||
if cache.debug
|
||||
cache.findPathCount = 0
|
||||
cache.findPathTime = 0
|
||||
cache.loadCount = 0
|
||||
cache.requireTime = 0
|
||||
global.moduleCache = cache
|
||||
|
||||
originalLoad = Module::load
|
||||
Module::load = ->
|
||||
cache.loadCount++
|
||||
originalLoad.apply(this, arguments)
|
||||
|
||||
originalRequire = Module::require
|
||||
Module::require = ->
|
||||
startTime = Date.now()
|
||||
exports = originalRequire.apply(this, arguments)
|
||||
cache.requireTime += Date.now() - startTime
|
||||
exports
|
||||
|
||||
originalFindPath = Module._findPath
|
||||
Module._findPath = (request, paths) ->
|
||||
cacheKey = JSON.stringify({request, paths})
|
||||
cache.findPathCount++ unless Module._pathCache[cacheKey]
|
||||
|
||||
startTime = Date.now()
|
||||
foundPath = originalFindPath.apply(global, arguments)
|
||||
cache.findPathTime += Date.now() - startTime
|
||||
foundPath
|
||||
|
||||
exports.create = (modulePath) ->
|
||||
fs = require 'fs-plus'
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
const Module = require('module')
|
||||
const path = require('path')
|
||||
const cachedVm = require('cached-run-in-this-context')
|
||||
@ -38,7 +36,6 @@ class NativeCompileCache {
|
||||
|
||||
overrideModuleCompile () {
|
||||
let self = this
|
||||
let resolvedArgv = null
|
||||
// Here we override Node's module.js
|
||||
// (https://github.com/atom/node/blob/atom/lib/module.js#L378), changing
|
||||
// only the bits that affect compilation in order to use the cached one.
|
||||
@ -63,11 +60,10 @@ class NativeCompileCache {
|
||||
// create wrapper function
|
||||
let wrapper = Module.wrap(content)
|
||||
|
||||
let cacheKey = filename
|
||||
let invalidationKey = computeHash(wrapper + self.v8Version)
|
||||
let cacheKey = computeHash(wrapper + self.v8Version)
|
||||
let compiledWrapper = null
|
||||
if (self.cacheStore.has(cacheKey, invalidationKey)) {
|
||||
let buffer = self.cacheStore.get(cacheKey, invalidationKey)
|
||||
if (self.cacheStore.has(cacheKey)) {
|
||||
let buffer = self.cacheStore.get(cacheKey)
|
||||
let compilationResult = cachedVm.runInThisContextCached(wrapper, filename, buffer)
|
||||
compiledWrapper = compilationResult.result
|
||||
if (compilationResult.wasRejected) {
|
||||
@ -82,29 +78,11 @@ class NativeCompileCache {
|
||||
throw err
|
||||
}
|
||||
if (compilationResult.cacheBuffer) {
|
||||
self.cacheStore.set(cacheKey, invalidationKey, compilationResult.cacheBuffer)
|
||||
self.cacheStore.set(cacheKey, compilationResult.cacheBuffer)
|
||||
}
|
||||
compiledWrapper = compilationResult.result
|
||||
}
|
||||
if (global.v8debug) {
|
||||
if (!resolvedArgv) {
|
||||
// we enter the repl if we're not given a filename argument.
|
||||
if (process.argv[1]) {
|
||||
resolvedArgv = Module._resolveFilename(process.argv[1], null)
|
||||
} else {
|
||||
resolvedArgv = 'repl'
|
||||
}
|
||||
}
|
||||
|
||||
// Set breakpoint on module start
|
||||
if (filename === resolvedArgv) {
|
||||
// Installing this dummy debug event listener tells V8 to start
|
||||
// the debugger. Without it, the setBreakPoint() fails with an
|
||||
// 'illegal access' error.
|
||||
global.v8debug.Debug.setListener(function () {})
|
||||
global.v8debug.Debug.setBreakPoint(compiledWrapper, 0, 0)
|
||||
}
|
||||
}
|
||||
let args = [moduleSelf.exports, require, moduleSelf, filename, dirname, process, global]
|
||||
return compiledWrapper.apply(moduleSelf.exports, args)
|
||||
}
|
||||
|
@ -30,9 +30,8 @@ module.exports =
|
||||
class PackageManager
|
||||
constructor: (params) ->
|
||||
{
|
||||
configDirPath, @devMode, safeMode, @resourcePath, @config, @styleManager,
|
||||
@notificationManager, @keymapManager, @commandRegistry, @grammarRegistry,
|
||||
@deserializerManager, @viewRegistry
|
||||
@config, @styleManager, @notificationManager, @keymapManager,
|
||||
@commandRegistry, @grammarRegistry, @deserializerManager, @viewRegistry
|
||||
} = params
|
||||
|
||||
@emitter = new Emitter
|
||||
@ -40,11 +39,6 @@ class PackageManager
|
||||
@packageDirPaths = []
|
||||
@deferredActivationHooks = []
|
||||
@triggeredActivationHooks = new Set()
|
||||
if configDirPath? and not safeMode
|
||||
if @devMode
|
||||
@packageDirPaths.push(path.join(configDirPath, "dev", "packages"))
|
||||
@packageDirPaths.push(path.join(configDirPath, "packages"))
|
||||
|
||||
@packagesCache = require('../package.json')?._atomPackages ? {}
|
||||
@initialPackagesLoaded = false
|
||||
@initialPackagesActivated = false
|
||||
@ -57,6 +51,13 @@ class PackageManager
|
||||
@packageActivators = []
|
||||
@registerPackageActivator(this, ['atom', 'textmate'])
|
||||
|
||||
initialize: (params) ->
|
||||
{configDirPath, @devMode, safeMode, @resourcePath} = params
|
||||
if configDirPath? and not safeMode
|
||||
if @devMode
|
||||
@packageDirPaths.push(path.join(configDirPath, "dev", "packages"))
|
||||
@packageDirPaths.push(path.join(configDirPath, "packages"))
|
||||
|
||||
setContextMenuManager: (@contextMenuManager) ->
|
||||
|
||||
setMenuManager: (@menuManager) ->
|
||||
|
@ -42,7 +42,8 @@ class Package
|
||||
@metadata ?= @packageManager.loadPackageMetadata(@path)
|
||||
@bundledPackage = @packageManager.isBundledPackagePath(@path)
|
||||
@name = @metadata?.name ? path.basename(@path)
|
||||
ModuleCache.add(@path, @metadata)
|
||||
unless @bundledPackage
|
||||
ModuleCache.add(@path, @metadata)
|
||||
@reset()
|
||||
|
||||
###
|
||||
@ -502,7 +503,7 @@ class Package
|
||||
path.join(@path, @metadata.main)
|
||||
else
|
||||
path.join(@path, 'index')
|
||||
@mainModulePath = fs.resolveExtension(mainModulePath, ["", _.keys(require.extensions)...])
|
||||
@mainModulePath = fs.resolveExtension(mainModulePath, ["", CompileCache.supportedExtensions...])
|
||||
|
||||
activationShouldBeDeferred: ->
|
||||
@hasActivationCommands() or @hasActivationHooks()
|
||||
|
@ -21,9 +21,11 @@ class PaneContainer extends Model
|
||||
|
||||
@setRoot(new Pane({container: this, @config, applicationDelegate, notificationManager, deserializerManager}))
|
||||
@setActivePane(@getRoot())
|
||||
@monitorActivePaneItem()
|
||||
@monitorPaneItems()
|
||||
|
||||
initialize: ->
|
||||
@monitorActivePaneItem()
|
||||
|
||||
serialize: (params) ->
|
||||
deserializer: 'PaneContainer'
|
||||
version: @serializationVersion
|
||||
|
@ -1,45 +0,0 @@
|
||||
{CompositeDisposable} = require 'event-kit'
|
||||
|
||||
class PanelContainerElement extends HTMLElement
|
||||
createdCallback: ->
|
||||
@subscriptions = new CompositeDisposable
|
||||
|
||||
initialize: (@model, {@views}) ->
|
||||
throw new Error("Must pass a views parameter when initializing PanelContainerElements") unless @views?
|
||||
|
||||
@subscriptions.add @model.onDidAddPanel(@panelAdded.bind(this))
|
||||
@subscriptions.add @model.onDidDestroy(@destroyed.bind(this))
|
||||
@classList.add(@model.getLocation())
|
||||
this
|
||||
|
||||
getModel: -> @model
|
||||
|
||||
panelAdded: ({panel, index}) ->
|
||||
panelElement = @views.getView(panel)
|
||||
panelElement.classList.add(@model.getLocation())
|
||||
if @model.isModal()
|
||||
panelElement.classList.add("overlay", "from-top")
|
||||
else
|
||||
panelElement.classList.add("tool-panel", "panel-#{@model.getLocation()}")
|
||||
|
||||
if index >= @childNodes.length
|
||||
@appendChild(panelElement)
|
||||
else
|
||||
referenceItem = @childNodes[index]
|
||||
@insertBefore(panelElement, referenceItem)
|
||||
|
||||
if @model.isModal()
|
||||
@hideAllPanelsExcept(panel)
|
||||
@subscriptions.add panel.onDidChangeVisible (visible) =>
|
||||
@hideAllPanelsExcept(panel) if visible
|
||||
|
||||
destroyed: ->
|
||||
@subscriptions.dispose()
|
||||
@parentNode?.removeChild(this)
|
||||
|
||||
hideAllPanelsExcept: (excludedPanel) ->
|
||||
for panel in @model.getPanels()
|
||||
panel.hide() unless panel is excludedPanel
|
||||
return
|
||||
|
||||
module.exports = PanelContainerElement = document.registerElement 'atom-panel-container', prototype: PanelContainerElement.prototype
|
65
src/panel-container-element.js
Normal file
65
src/panel-container-element.js
Normal file
@ -0,0 +1,65 @@
|
||||
'use strict'
|
||||
|
||||
/* global HTMLElement */
|
||||
|
||||
const {CompositeDisposable} = require('event-kit')
|
||||
|
||||
class PanelContainerElement extends HTMLElement {
|
||||
createdCallback () {
|
||||
this.subscriptions = new CompositeDisposable()
|
||||
}
|
||||
|
||||
initialize (model, {views}) {
|
||||
this.model = model
|
||||
this.views = views
|
||||
if (this.views == null) {
|
||||
throw new Error('Must pass a views parameter when initializing PanelContainerElements')
|
||||
}
|
||||
|
||||
this.subscriptions.add(this.model.onDidAddPanel(this.panelAdded.bind(this)))
|
||||
this.subscriptions.add(this.model.onDidDestroy(this.destroyed.bind(this)))
|
||||
this.classList.add(this.model.getLocation())
|
||||
return this
|
||||
}
|
||||
|
||||
getModel () { return this.model }
|
||||
|
||||
panelAdded ({panel, index}) {
|
||||
const panelElement = this.views.getView(panel)
|
||||
panelElement.classList.add(this.model.getLocation())
|
||||
if (this.model.isModal()) {
|
||||
panelElement.classList.add('overlay', 'from-top')
|
||||
} else {
|
||||
panelElement.classList.add('tool-panel', `panel-${this.model.getLocation()}`)
|
||||
}
|
||||
|
||||
if (index >= this.childNodes.length) {
|
||||
this.appendChild(panelElement)
|
||||
} else {
|
||||
const referenceItem = this.childNodes[index]
|
||||
this.insertBefore(panelElement, referenceItem)
|
||||
}
|
||||
|
||||
if (this.model.isModal()) {
|
||||
this.hideAllPanelsExcept(panel)
|
||||
this.subscriptions.add(panel.onDidChangeVisible(visible => {
|
||||
if (visible) { this.hideAllPanelsExcept(panel) }
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
destroyed () {
|
||||
this.subscriptions.dispose()
|
||||
if (this.parentNode != null) {
|
||||
this.parentNode.removeChild(this)
|
||||
}
|
||||
}
|
||||
|
||||
hideAllPanelsExcept (excludedPanel) {
|
||||
for (let panel of this.model.getPanels()) {
|
||||
if (panel !== excludedPanel) { panel.hide() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = document.registerElement('atom-panel-container', {prototype: PanelContainerElement.prototype})
|
@ -1,71 +0,0 @@
|
||||
{Emitter, CompositeDisposable} = require 'event-kit'
|
||||
|
||||
module.exports =
|
||||
class PanelContainer
|
||||
constructor: ({@location}={}) ->
|
||||
@emitter = new Emitter
|
||||
@subscriptions = new CompositeDisposable
|
||||
@panels = []
|
||||
|
||||
destroy: ->
|
||||
panel.destroy() for panel in @getPanels()
|
||||
@subscriptions.dispose()
|
||||
@emitter.emit 'did-destroy', this
|
||||
@emitter.dispose()
|
||||
|
||||
###
|
||||
Section: Event Subscription
|
||||
###
|
||||
|
||||
onDidAddPanel: (callback) ->
|
||||
@emitter.on 'did-add-panel', callback
|
||||
|
||||
onDidRemovePanel: (callback) ->
|
||||
@emitter.on 'did-remove-panel', callback
|
||||
|
||||
onDidDestroy: (callback) ->
|
||||
@emitter.on 'did-destroy', callback
|
||||
|
||||
###
|
||||
Section: Panels
|
||||
###
|
||||
|
||||
getLocation: -> @location
|
||||
|
||||
isModal: -> @location is 'modal'
|
||||
|
||||
getPanels: -> @panels
|
||||
|
||||
addPanel: (panel) ->
|
||||
@subscriptions.add panel.onDidDestroy(@panelDestroyed.bind(this))
|
||||
|
||||
index = @getPanelIndex(panel)
|
||||
if index is @panels.length
|
||||
@panels.push(panel)
|
||||
else
|
||||
@panels.splice(index, 0, panel)
|
||||
|
||||
@emitter.emit 'did-add-panel', {panel, index}
|
||||
panel
|
||||
|
||||
panelForItem: (item) ->
|
||||
for panel in @panels
|
||||
return panel if panel.getItem() is item
|
||||
null
|
||||
|
||||
panelDestroyed: (panel) ->
|
||||
index = @panels.indexOf(panel)
|
||||
if index > -1
|
||||
@panels.splice(index, 1)
|
||||
@emitter.emit 'did-remove-panel', {panel, index}
|
||||
|
||||
getPanelIndex: (panel) ->
|
||||
priority = panel.getPriority()
|
||||
if @location in ['bottom', 'right']
|
||||
for p, i in @panels by -1
|
||||
return i + 1 if priority < p.getPriority()
|
||||
0
|
||||
else
|
||||
for p, i in @panels
|
||||
return i if priority < p.getPriority()
|
||||
@panels.length
|
91
src/panel-container.js
Normal file
91
src/panel-container.js
Normal file
@ -0,0 +1,91 @@
|
||||
'use strict'
|
||||
|
||||
const {Emitter, CompositeDisposable} = require('event-kit')
|
||||
|
||||
module.exports = class PanelContainer {
|
||||
constructor ({location} = {}) {
|
||||
this.location = location
|
||||
this.emitter = new Emitter()
|
||||
this.subscriptions = new CompositeDisposable()
|
||||
this.panels = []
|
||||
}
|
||||
|
||||
destroy () {
|
||||
for (let panel of this.getPanels()) { panel.destroy() }
|
||||
this.subscriptions.dispose()
|
||||
this.emitter.emit('did-destroy', this)
|
||||
this.emitter.dispose()
|
||||
}
|
||||
|
||||
/*
|
||||
Section: Event Subscription
|
||||
*/
|
||||
|
||||
onDidAddPanel (callback) {
|
||||
return this.emitter.on('did-add-panel', callback)
|
||||
}
|
||||
|
||||
onDidRemovePanel (callback) {
|
||||
return this.emitter.on('did-remove-panel', callback)
|
||||
}
|
||||
|
||||
onDidDestroy (callback) {
|
||||
return this.emitter.on('did-destroy', callback)
|
||||
}
|
||||
|
||||
/*
|
||||
Section: Panels
|
||||
*/
|
||||
|
||||
getLocation () { return this.location }
|
||||
|
||||
isModal () { return this.location === 'modal' }
|
||||
|
||||
getPanels () { return this.panels.slice() }
|
||||
|
||||
addPanel (panel) {
|
||||
this.subscriptions.add(panel.onDidDestroy(this.panelDestroyed.bind(this)))
|
||||
|
||||
const index = this.getPanelIndex(panel)
|
||||
if (index === this.panels.length) {
|
||||
this.panels.push(panel)
|
||||
} else {
|
||||
this.panels.splice(index, 0, panel)
|
||||
}
|
||||
|
||||
this.emitter.emit('did-add-panel', {panel, index})
|
||||
return panel
|
||||
}
|
||||
|
||||
panelForItem (item) {
|
||||
for (let panel of this.panels) {
|
||||
if (panel.getItem() === item) { return panel }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
panelDestroyed (panel) {
|
||||
const index = this.panels.indexOf(panel)
|
||||
if (index > -1) {
|
||||
this.panels.splice(index, 1)
|
||||
this.emitter.emit('did-remove-panel', {panel, index})
|
||||
}
|
||||
}
|
||||
|
||||
getPanelIndex (panel) {
|
||||
const priority = panel.getPriority()
|
||||
if (['bottom', 'right'].includes(this.location)) {
|
||||
for (let i = this.panels.length - 1; i >= 0; i--) {
|
||||
const p = this.panels[i]
|
||||
if (priority < p.getPriority()) { return i + 1 }
|
||||
}
|
||||
return 0
|
||||
} else {
|
||||
for (let i = 0; i < this.panels.length; i++) {
|
||||
const p = this.panels[i]
|
||||
if (priority < p.getPriority()) { return i }
|
||||
}
|
||||
return this.panels.length
|
||||
}
|
||||
}
|
||||
}
|
@ -2,223 +2,260 @@
|
||||
Grim = require 'grim'
|
||||
|
||||
module.exports = ({commandRegistry, commandInstaller, config, notificationManager, project, clipboard}) ->
|
||||
commandRegistry.add 'atom-workspace',
|
||||
'pane:show-next-recently-used-item': -> @getModel().getActivePane().activateNextRecentlyUsedItem()
|
||||
'pane:show-previous-recently-used-item': -> @getModel().getActivePane().activatePreviousRecentlyUsedItem()
|
||||
'pane:move-active-item-to-top-of-stack': -> @getModel().getActivePane().moveActiveItemToTopOfStack()
|
||||
'pane:show-next-item': -> @getModel().getActivePane().activateNextItem()
|
||||
'pane:show-previous-item': -> @getModel().getActivePane().activatePreviousItem()
|
||||
'pane:show-item-1': -> @getModel().getActivePane().activateItemAtIndex(0)
|
||||
'pane:show-item-2': -> @getModel().getActivePane().activateItemAtIndex(1)
|
||||
'pane:show-item-3': -> @getModel().getActivePane().activateItemAtIndex(2)
|
||||
'pane:show-item-4': -> @getModel().getActivePane().activateItemAtIndex(3)
|
||||
'pane:show-item-5': -> @getModel().getActivePane().activateItemAtIndex(4)
|
||||
'pane:show-item-6': -> @getModel().getActivePane().activateItemAtIndex(5)
|
||||
'pane:show-item-7': -> @getModel().getActivePane().activateItemAtIndex(6)
|
||||
'pane:show-item-8': -> @getModel().getActivePane().activateItemAtIndex(7)
|
||||
'pane:show-item-9': -> @getModel().getActivePane().activateLastItem()
|
||||
'pane:move-item-right': -> @getModel().getActivePane().moveItemRight()
|
||||
'pane:move-item-left': -> @getModel().getActivePane().moveItemLeft()
|
||||
'window:increase-font-size': -> @getModel().increaseFontSize()
|
||||
'window:decrease-font-size': -> @getModel().decreaseFontSize()
|
||||
'window:reset-font-size': -> @getModel().resetFontSize()
|
||||
'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': ->
|
||||
defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0]
|
||||
ipcRenderer.send('open-command', 'application:open', defaultPath)
|
||||
'application:open-file': ->
|
||||
defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0]
|
||||
ipcRenderer.send('open-command', 'application:open-file', defaultPath)
|
||||
'application:open-folder': ->
|
||||
defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0]
|
||||
ipcRenderer.send('open-command', 'application:open-folder', defaultPath)
|
||||
'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': -> 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:run-benchmarks': -> @runBenchmarks()
|
||||
'window:focus-next-pane': -> @getModel().activateNextPane()
|
||||
'window:focus-previous-pane': -> @getModel().activatePreviousPane()
|
||||
'window:focus-pane-above': -> @focusPaneViewAbove()
|
||||
'window:focus-pane-below': -> @focusPaneViewBelow()
|
||||
'window:focus-pane-on-left': -> @focusPaneViewOnLeft()
|
||||
'window:focus-pane-on-right': -> @focusPaneViewOnRight()
|
||||
'window:move-active-item-to-pane-above': -> @moveActiveItemToPaneAbove()
|
||||
'window:move-active-item-to-pane-below': -> @moveActiveItemToPaneBelow()
|
||||
'window:move-active-item-to-pane-on-left': -> @moveActiveItemToPaneOnLeft()
|
||||
'window:move-active-item-to-pane-on-right': -> @moveActiveItemToPaneOnRight()
|
||||
'window:copy-active-item-to-pane-above': -> @moveActiveItemToPaneAbove(keepOriginal: true)
|
||||
'window:copy-active-item-to-pane-below': -> @moveActiveItemToPaneBelow(keepOriginal: true)
|
||||
'window:copy-active-item-to-pane-on-left': -> @moveActiveItemToPaneOnLeft(keepOriginal: true)
|
||||
'window:copy-active-item-to-pane-on-right': -> @moveActiveItemToPaneOnRight(keepOriginal: true)
|
||||
'window:save-all': -> @getModel().saveAll()
|
||||
'window:toggle-invisibles': -> config.set("editor.showInvisibles", not config.get("editor.showInvisibles"))
|
||||
'window:log-deprecation-warnings': -> Grim.logDeprecations()
|
||||
'window:toggle-auto-indent': -> config.set("editor.autoIndent", not config.get("editor.autoIndent"))
|
||||
'pane:reopen-closed-item': -> @getModel().reopenItem()
|
||||
'core:close': -> @getModel().closeActivePaneItemOrEmptyPaneOrWindow()
|
||||
'core:save': -> @getModel().saveActivePaneItem()
|
||||
'core:save-as': -> @getModel().saveActivePaneItemAs()
|
||||
commandRegistry.add(
|
||||
'atom-workspace',
|
||||
{
|
||||
'pane:show-next-recently-used-item': -> @getModel().getActivePane().activateNextRecentlyUsedItem()
|
||||
'pane:show-previous-recently-used-item': -> @getModel().getActivePane().activatePreviousRecentlyUsedItem()
|
||||
'pane:move-active-item-to-top-of-stack': -> @getModel().getActivePane().moveActiveItemToTopOfStack()
|
||||
'pane:show-next-item': -> @getModel().getActivePane().activateNextItem()
|
||||
'pane:show-previous-item': -> @getModel().getActivePane().activatePreviousItem()
|
||||
'pane:show-item-1': -> @getModel().getActivePane().activateItemAtIndex(0)
|
||||
'pane:show-item-2': -> @getModel().getActivePane().activateItemAtIndex(1)
|
||||
'pane:show-item-3': -> @getModel().getActivePane().activateItemAtIndex(2)
|
||||
'pane:show-item-4': -> @getModel().getActivePane().activateItemAtIndex(3)
|
||||
'pane:show-item-5': -> @getModel().getActivePane().activateItemAtIndex(4)
|
||||
'pane:show-item-6': -> @getModel().getActivePane().activateItemAtIndex(5)
|
||||
'pane:show-item-7': -> @getModel().getActivePane().activateItemAtIndex(6)
|
||||
'pane:show-item-8': -> @getModel().getActivePane().activateItemAtIndex(7)
|
||||
'pane:show-item-9': -> @getModel().getActivePane().activateLastItem()
|
||||
'pane:move-item-right': -> @getModel().getActivePane().moveItemRight()
|
||||
'pane:move-item-left': -> @getModel().getActivePane().moveItemLeft()
|
||||
'window:increase-font-size': -> @getModel().increaseFontSize()
|
||||
'window:decrease-font-size': -> @getModel().decreaseFontSize()
|
||||
'window:reset-font-size': -> @getModel().resetFontSize()
|
||||
'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': ->
|
||||
defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0]
|
||||
ipcRenderer.send('open-command', 'application:open', defaultPath)
|
||||
'application:open-file': ->
|
||||
defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0]
|
||||
ipcRenderer.send('open-command', 'application:open-file', defaultPath)
|
||||
'application:open-folder': ->
|
||||
defaultPath = atom.workspace.getActiveTextEditor()?.getPath() ? atom.project.getPaths()?[0]
|
||||
ipcRenderer.send('open-command', 'application:open-folder', defaultPath)
|
||||
'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': -> 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:run-benchmarks': -> @runBenchmarks()
|
||||
'window:focus-next-pane': -> @getModel().activateNextPane()
|
||||
'window:focus-previous-pane': -> @getModel().activatePreviousPane()
|
||||
'window:focus-pane-above': -> @focusPaneViewAbove()
|
||||
'window:focus-pane-below': -> @focusPaneViewBelow()
|
||||
'window:focus-pane-on-left': -> @focusPaneViewOnLeft()
|
||||
'window:focus-pane-on-right': -> @focusPaneViewOnRight()
|
||||
'window:move-active-item-to-pane-above': -> @moveActiveItemToPaneAbove()
|
||||
'window:move-active-item-to-pane-below': -> @moveActiveItemToPaneBelow()
|
||||
'window:move-active-item-to-pane-on-left': -> @moveActiveItemToPaneOnLeft()
|
||||
'window:move-active-item-to-pane-on-right': -> @moveActiveItemToPaneOnRight()
|
||||
'window:copy-active-item-to-pane-above': -> @moveActiveItemToPaneAbove(keepOriginal: true)
|
||||
'window:copy-active-item-to-pane-below': -> @moveActiveItemToPaneBelow(keepOriginal: true)
|
||||
'window:copy-active-item-to-pane-on-left': -> @moveActiveItemToPaneOnLeft(keepOriginal: true)
|
||||
'window:copy-active-item-to-pane-on-right': -> @moveActiveItemToPaneOnRight(keepOriginal: true)
|
||||
'window:save-all': -> @getModel().saveAll()
|
||||
'window:toggle-invisibles': -> config.set("editor.showInvisibles", not config.get("editor.showInvisibles"))
|
||||
'window:log-deprecation-warnings': -> Grim.logDeprecations()
|
||||
'window:toggle-auto-indent': -> config.set("editor.autoIndent", not config.get("editor.autoIndent"))
|
||||
'pane:reopen-closed-item': -> @getModel().reopenItem()
|
||||
'core:close': -> @getModel().closeActivePaneItemOrEmptyPaneOrWindow()
|
||||
'core:save': -> @getModel().saveActivePaneItem()
|
||||
'core:save-as': -> @getModel().saveActivePaneItemAs()
|
||||
},
|
||||
false
|
||||
)
|
||||
|
||||
|
||||
if process.platform is 'darwin'
|
||||
commandRegistry.add 'atom-workspace', 'window:install-shell-commands', ->
|
||||
commandInstaller.installShellCommandsInteractively()
|
||||
commandRegistry.add(
|
||||
'atom-workspace',
|
||||
'window:install-shell-commands',
|
||||
(-> commandInstaller.installShellCommandsInteractively()),
|
||||
false
|
||||
)
|
||||
|
||||
commandRegistry.add 'atom-pane',
|
||||
'pane:save-items': -> @getModel().saveItems()
|
||||
'pane:split-left': -> @getModel().splitLeft()
|
||||
'pane:split-right': -> @getModel().splitRight()
|
||||
'pane:split-up': -> @getModel().splitUp()
|
||||
'pane:split-down': -> @getModel().splitDown()
|
||||
'pane:split-left-and-copy-active-item': -> @getModel().splitLeft(copyActiveItem: true)
|
||||
'pane:split-right-and-copy-active-item': -> @getModel().splitRight(copyActiveItem: true)
|
||||
'pane:split-up-and-copy-active-item': -> @getModel().splitUp(copyActiveItem: true)
|
||||
'pane:split-down-and-copy-active-item': -> @getModel().splitDown(copyActiveItem: true)
|
||||
'pane:split-left-and-move-active-item': -> @getModel().splitLeft(moveActiveItem: true)
|
||||
'pane:split-right-and-move-active-item': -> @getModel().splitRight(moveActiveItem: true)
|
||||
'pane:split-up-and-move-active-item': -> @getModel().splitUp(moveActiveItem: true)
|
||||
'pane:split-down-and-move-active-item': -> @getModel().splitDown(moveActiveItem: true)
|
||||
'pane:close': -> @getModel().close()
|
||||
'pane:close-other-items': -> @getModel().destroyInactiveItems()
|
||||
'pane:increase-size': -> @getModel().increaseSize()
|
||||
'pane:decrease-size': -> @getModel().decreaseSize()
|
||||
|
||||
commandRegistry.add 'atom-text-editor', stopEventPropagation(
|
||||
'core:undo': -> @undo()
|
||||
'core:redo': -> @redo()
|
||||
'core:move-left': -> @moveLeft()
|
||||
'core:move-right': -> @moveRight()
|
||||
'core:select-left': -> @selectLeft()
|
||||
'core:select-right': -> @selectRight()
|
||||
'core:select-up': -> @selectUp()
|
||||
'core:select-down': -> @selectDown()
|
||||
'core:select-all': -> @selectAll()
|
||||
'editor:select-word': -> @selectWordsContainingCursors()
|
||||
'editor:consolidate-selections': (event) -> event.abortKeyBinding() unless @consolidateSelections()
|
||||
'editor:move-to-beginning-of-next-paragraph': -> @moveToBeginningOfNextParagraph()
|
||||
'editor:move-to-beginning-of-previous-paragraph': -> @moveToBeginningOfPreviousParagraph()
|
||||
'editor:move-to-beginning-of-screen-line': -> @moveToBeginningOfScreenLine()
|
||||
'editor:move-to-beginning-of-line': -> @moveToBeginningOfLine()
|
||||
'editor:move-to-end-of-screen-line': -> @moveToEndOfScreenLine()
|
||||
'editor:move-to-end-of-line': -> @moveToEndOfLine()
|
||||
'editor:move-to-first-character-of-line': -> @moveToFirstCharacterOfLine()
|
||||
'editor:move-to-beginning-of-word': -> @moveToBeginningOfWord()
|
||||
'editor:move-to-end-of-word': -> @moveToEndOfWord()
|
||||
'editor:move-to-beginning-of-next-word': -> @moveToBeginningOfNextWord()
|
||||
'editor:move-to-previous-word-boundary': -> @moveToPreviousWordBoundary()
|
||||
'editor:move-to-next-word-boundary': -> @moveToNextWordBoundary()
|
||||
'editor:move-to-previous-subword-boundary': -> @moveToPreviousSubwordBoundary()
|
||||
'editor:move-to-next-subword-boundary': -> @moveToNextSubwordBoundary()
|
||||
'editor:select-to-beginning-of-next-paragraph': -> @selectToBeginningOfNextParagraph()
|
||||
'editor:select-to-beginning-of-previous-paragraph': -> @selectToBeginningOfPreviousParagraph()
|
||||
'editor:select-to-end-of-line': -> @selectToEndOfLine()
|
||||
'editor:select-to-beginning-of-line': -> @selectToBeginningOfLine()
|
||||
'editor:select-to-end-of-word': -> @selectToEndOfWord()
|
||||
'editor:select-to-beginning-of-word': -> @selectToBeginningOfWord()
|
||||
'editor:select-to-beginning-of-next-word': -> @selectToBeginningOfNextWord()
|
||||
'editor:select-to-next-word-boundary': -> @selectToNextWordBoundary()
|
||||
'editor:select-to-previous-word-boundary': -> @selectToPreviousWordBoundary()
|
||||
'editor:select-to-next-subword-boundary': -> @selectToNextSubwordBoundary()
|
||||
'editor:select-to-previous-subword-boundary': -> @selectToPreviousSubwordBoundary()
|
||||
'editor:select-to-first-character-of-line': -> @selectToFirstCharacterOfLine()
|
||||
'editor:select-line': -> @selectLinesContainingCursors()
|
||||
commandRegistry.add(
|
||||
'atom-pane',
|
||||
{
|
||||
'pane:save-items': -> @getModel().saveItems()
|
||||
'pane:split-left': -> @getModel().splitLeft()
|
||||
'pane:split-right': -> @getModel().splitRight()
|
||||
'pane:split-up': -> @getModel().splitUp()
|
||||
'pane:split-down': -> @getModel().splitDown()
|
||||
'pane:split-left-and-copy-active-item': -> @getModel().splitLeft(copyActiveItem: true)
|
||||
'pane:split-right-and-copy-active-item': -> @getModel().splitRight(copyActiveItem: true)
|
||||
'pane:split-up-and-copy-active-item': -> @getModel().splitUp(copyActiveItem: true)
|
||||
'pane:split-down-and-copy-active-item': -> @getModel().splitDown(copyActiveItem: true)
|
||||
'pane:split-left-and-move-active-item': -> @getModel().splitLeft(moveActiveItem: true)
|
||||
'pane:split-right-and-move-active-item': -> @getModel().splitRight(moveActiveItem: true)
|
||||
'pane:split-up-and-move-active-item': -> @getModel().splitUp(moveActiveItem: true)
|
||||
'pane:split-down-and-move-active-item': -> @getModel().splitDown(moveActiveItem: true)
|
||||
'pane:close': -> @getModel().close()
|
||||
'pane:close-other-items': -> @getModel().destroyInactiveItems()
|
||||
'pane:increase-size': -> @getModel().increaseSize()
|
||||
'pane:decrease-size': -> @getModel().decreaseSize()
|
||||
},
|
||||
false
|
||||
)
|
||||
|
||||
commandRegistry.add 'atom-text-editor', stopEventPropagationAndGroupUndo(config,
|
||||
'core:backspace': -> @backspace()
|
||||
'core:delete': -> @delete()
|
||||
'core:cut': -> @cutSelectedText()
|
||||
'core:copy': -> @copySelectedText()
|
||||
'core:paste': -> @pasteText()
|
||||
'editor:delete-to-previous-word-boundary': -> @deleteToPreviousWordBoundary()
|
||||
'editor:delete-to-next-word-boundary': -> @deleteToNextWordBoundary()
|
||||
'editor:delete-to-beginning-of-word': -> @deleteToBeginningOfWord()
|
||||
'editor:delete-to-beginning-of-line': -> @deleteToBeginningOfLine()
|
||||
'editor:delete-to-end-of-line': -> @deleteToEndOfLine()
|
||||
'editor:delete-to-end-of-word': -> @deleteToEndOfWord()
|
||||
'editor:delete-to-beginning-of-subword': -> @deleteToBeginningOfSubword()
|
||||
'editor:delete-to-end-of-subword': -> @deleteToEndOfSubword()
|
||||
'editor:delete-line': -> @deleteLine()
|
||||
'editor:cut-to-end-of-line': -> @cutToEndOfLine()
|
||||
'editor:cut-to-end-of-buffer-line': -> @cutToEndOfBufferLine()
|
||||
'editor:transpose': -> @transpose()
|
||||
'editor:upper-case': -> @upperCase()
|
||||
'editor:lower-case': -> @lowerCase()
|
||||
'editor:copy-selection': -> @copyOnlySelectedText()
|
||||
commandRegistry.add(
|
||||
'atom-text-editor',
|
||||
stopEventPropagation({
|
||||
'core:undo': -> @undo()
|
||||
'core:redo': -> @redo()
|
||||
'core:move-left': -> @moveLeft()
|
||||
'core:move-right': -> @moveRight()
|
||||
'core:select-left': -> @selectLeft()
|
||||
'core:select-right': -> @selectRight()
|
||||
'core:select-up': -> @selectUp()
|
||||
'core:select-down': -> @selectDown()
|
||||
'core:select-all': -> @selectAll()
|
||||
'editor:select-word': -> @selectWordsContainingCursors()
|
||||
'editor:consolidate-selections': (event) -> event.abortKeyBinding() unless @consolidateSelections()
|
||||
'editor:move-to-beginning-of-next-paragraph': -> @moveToBeginningOfNextParagraph()
|
||||
'editor:move-to-beginning-of-previous-paragraph': -> @moveToBeginningOfPreviousParagraph()
|
||||
'editor:move-to-beginning-of-screen-line': -> @moveToBeginningOfScreenLine()
|
||||
'editor:move-to-beginning-of-line': -> @moveToBeginningOfLine()
|
||||
'editor:move-to-end-of-screen-line': -> @moveToEndOfScreenLine()
|
||||
'editor:move-to-end-of-line': -> @moveToEndOfLine()
|
||||
'editor:move-to-first-character-of-line': -> @moveToFirstCharacterOfLine()
|
||||
'editor:move-to-beginning-of-word': -> @moveToBeginningOfWord()
|
||||
'editor:move-to-end-of-word': -> @moveToEndOfWord()
|
||||
'editor:move-to-beginning-of-next-word': -> @moveToBeginningOfNextWord()
|
||||
'editor:move-to-previous-word-boundary': -> @moveToPreviousWordBoundary()
|
||||
'editor:move-to-next-word-boundary': -> @moveToNextWordBoundary()
|
||||
'editor:move-to-previous-subword-boundary': -> @moveToPreviousSubwordBoundary()
|
||||
'editor:move-to-next-subword-boundary': -> @moveToNextSubwordBoundary()
|
||||
'editor:select-to-beginning-of-next-paragraph': -> @selectToBeginningOfNextParagraph()
|
||||
'editor:select-to-beginning-of-previous-paragraph': -> @selectToBeginningOfPreviousParagraph()
|
||||
'editor:select-to-end-of-line': -> @selectToEndOfLine()
|
||||
'editor:select-to-beginning-of-line': -> @selectToBeginningOfLine()
|
||||
'editor:select-to-end-of-word': -> @selectToEndOfWord()
|
||||
'editor:select-to-beginning-of-word': -> @selectToBeginningOfWord()
|
||||
'editor:select-to-beginning-of-next-word': -> @selectToBeginningOfNextWord()
|
||||
'editor:select-to-next-word-boundary': -> @selectToNextWordBoundary()
|
||||
'editor:select-to-previous-word-boundary': -> @selectToPreviousWordBoundary()
|
||||
'editor:select-to-next-subword-boundary': -> @selectToNextSubwordBoundary()
|
||||
'editor:select-to-previous-subword-boundary': -> @selectToPreviousSubwordBoundary()
|
||||
'editor:select-to-first-character-of-line': -> @selectToFirstCharacterOfLine()
|
||||
'editor:select-line': -> @selectLinesContainingCursors()
|
||||
}),
|
||||
false
|
||||
)
|
||||
|
||||
commandRegistry.add 'atom-text-editor:not([mini])', stopEventPropagation(
|
||||
'core:move-up': -> @moveUp()
|
||||
'core:move-down': -> @moveDown()
|
||||
'core:move-to-top': -> @moveToTop()
|
||||
'core:move-to-bottom': -> @moveToBottom()
|
||||
'core:page-up': -> @pageUp()
|
||||
'core:page-down': -> @pageDown()
|
||||
'core:select-to-top': -> @selectToTop()
|
||||
'core:select-to-bottom': -> @selectToBottom()
|
||||
'core:select-page-up': -> @selectPageUp()
|
||||
'core:select-page-down': -> @selectPageDown()
|
||||
'editor:add-selection-below': -> @addSelectionBelow()
|
||||
'editor:add-selection-above': -> @addSelectionAbove()
|
||||
'editor:split-selections-into-lines': -> @splitSelectionsIntoLines()
|
||||
'editor:toggle-soft-tabs': -> @toggleSoftTabs()
|
||||
'editor:toggle-soft-wrap': -> @toggleSoftWrapped()
|
||||
'editor:fold-all': -> @foldAll()
|
||||
'editor:unfold-all': -> @unfoldAll()
|
||||
'editor:fold-current-row': -> @foldCurrentRow()
|
||||
'editor:unfold-current-row': -> @unfoldCurrentRow()
|
||||
'editor:fold-selection': -> @foldSelectedLines()
|
||||
'editor:fold-at-indent-level-1': -> @foldAllAtIndentLevel(0)
|
||||
'editor:fold-at-indent-level-2': -> @foldAllAtIndentLevel(1)
|
||||
'editor:fold-at-indent-level-3': -> @foldAllAtIndentLevel(2)
|
||||
'editor:fold-at-indent-level-4': -> @foldAllAtIndentLevel(3)
|
||||
'editor:fold-at-indent-level-5': -> @foldAllAtIndentLevel(4)
|
||||
'editor:fold-at-indent-level-6': -> @foldAllAtIndentLevel(5)
|
||||
'editor:fold-at-indent-level-7': -> @foldAllAtIndentLevel(6)
|
||||
'editor:fold-at-indent-level-8': -> @foldAllAtIndentLevel(7)
|
||||
'editor:fold-at-indent-level-9': -> @foldAllAtIndentLevel(8)
|
||||
'editor:log-cursor-scope': -> showCursorScope(@getCursorScope(), notificationManager)
|
||||
'editor:copy-path': -> copyPathToClipboard(this, project, clipboard, false)
|
||||
'editor:copy-project-path': -> copyPathToClipboard(this, project, clipboard, true)
|
||||
'editor:toggle-indent-guide': -> config.set('editor.showIndentGuide', not config.get('editor.showIndentGuide'))
|
||||
'editor:toggle-line-numbers': -> config.set('editor.showLineNumbers', not config.get('editor.showLineNumbers'))
|
||||
'editor:scroll-to-cursor': -> @scrollToCursorPosition()
|
||||
commandRegistry.add(
|
||||
'atom-text-editor',
|
||||
stopEventPropagationAndGroupUndo(
|
||||
config,
|
||||
{
|
||||
'core:backspace': -> @backspace()
|
||||
'core:delete': -> @delete()
|
||||
'core:cut': -> @cutSelectedText()
|
||||
'core:copy': -> @copySelectedText()
|
||||
'core:paste': -> @pasteText()
|
||||
'editor:delete-to-previous-word-boundary': -> @deleteToPreviousWordBoundary()
|
||||
'editor:delete-to-next-word-boundary': -> @deleteToNextWordBoundary()
|
||||
'editor:delete-to-beginning-of-word': -> @deleteToBeginningOfWord()
|
||||
'editor:delete-to-beginning-of-line': -> @deleteToBeginningOfLine()
|
||||
'editor:delete-to-end-of-line': -> @deleteToEndOfLine()
|
||||
'editor:delete-to-end-of-word': -> @deleteToEndOfWord()
|
||||
'editor:delete-to-beginning-of-subword': -> @deleteToBeginningOfSubword()
|
||||
'editor:delete-to-end-of-subword': -> @deleteToEndOfSubword()
|
||||
'editor:delete-line': -> @deleteLine()
|
||||
'editor:cut-to-end-of-line': -> @cutToEndOfLine()
|
||||
'editor:cut-to-end-of-buffer-line': -> @cutToEndOfBufferLine()
|
||||
'editor:transpose': -> @transpose()
|
||||
'editor:upper-case': -> @upperCase()
|
||||
'editor:lower-case': -> @lowerCase()
|
||||
'editor:copy-selection': -> @copyOnlySelectedText()
|
||||
}
|
||||
),
|
||||
false
|
||||
)
|
||||
|
||||
commandRegistry.add 'atom-text-editor:not([mini])', stopEventPropagationAndGroupUndo(config,
|
||||
'editor:indent': -> @indent()
|
||||
'editor:auto-indent': -> @autoIndentSelectedRows()
|
||||
'editor:indent-selected-rows': -> @indentSelectedRows()
|
||||
'editor:outdent-selected-rows': -> @outdentSelectedRows()
|
||||
'editor:newline': -> @insertNewline()
|
||||
'editor:newline-below': -> @insertNewlineBelow()
|
||||
'editor:newline-above': -> @insertNewlineAbove()
|
||||
'editor:toggle-line-comments': -> @toggleLineCommentsInSelection()
|
||||
'editor:checkout-head-revision': -> atom.workspace.checkoutHeadRevision(this)
|
||||
'editor:move-line-up': -> @moveLineUp()
|
||||
'editor:move-line-down': -> @moveLineDown()
|
||||
'editor:move-selection-left': -> @moveSelectionLeft()
|
||||
'editor:move-selection-right': -> @moveSelectionRight()
|
||||
'editor:duplicate-lines': -> @duplicateLines()
|
||||
'editor:join-lines': -> @joinLines()
|
||||
commandRegistry.add(
|
||||
'atom-text-editor:not([mini])',
|
||||
stopEventPropagation({
|
||||
'core:move-up': -> @moveUp()
|
||||
'core:move-down': -> @moveDown()
|
||||
'core:move-to-top': -> @moveToTop()
|
||||
'core:move-to-bottom': -> @moveToBottom()
|
||||
'core:page-up': -> @pageUp()
|
||||
'core:page-down': -> @pageDown()
|
||||
'core:select-to-top': -> @selectToTop()
|
||||
'core:select-to-bottom': -> @selectToBottom()
|
||||
'core:select-page-up': -> @selectPageUp()
|
||||
'core:select-page-down': -> @selectPageDown()
|
||||
'editor:add-selection-below': -> @addSelectionBelow()
|
||||
'editor:add-selection-above': -> @addSelectionAbove()
|
||||
'editor:split-selections-into-lines': -> @splitSelectionsIntoLines()
|
||||
'editor:toggle-soft-tabs': -> @toggleSoftTabs()
|
||||
'editor:toggle-soft-wrap': -> @toggleSoftWrapped()
|
||||
'editor:fold-all': -> @foldAll()
|
||||
'editor:unfold-all': -> @unfoldAll()
|
||||
'editor:fold-current-row': -> @foldCurrentRow()
|
||||
'editor:unfold-current-row': -> @unfoldCurrentRow()
|
||||
'editor:fold-selection': -> @foldSelectedLines()
|
||||
'editor:fold-at-indent-level-1': -> @foldAllAtIndentLevel(0)
|
||||
'editor:fold-at-indent-level-2': -> @foldAllAtIndentLevel(1)
|
||||
'editor:fold-at-indent-level-3': -> @foldAllAtIndentLevel(2)
|
||||
'editor:fold-at-indent-level-4': -> @foldAllAtIndentLevel(3)
|
||||
'editor:fold-at-indent-level-5': -> @foldAllAtIndentLevel(4)
|
||||
'editor:fold-at-indent-level-6': -> @foldAllAtIndentLevel(5)
|
||||
'editor:fold-at-indent-level-7': -> @foldAllAtIndentLevel(6)
|
||||
'editor:fold-at-indent-level-8': -> @foldAllAtIndentLevel(7)
|
||||
'editor:fold-at-indent-level-9': -> @foldAllAtIndentLevel(8)
|
||||
'editor:log-cursor-scope': -> showCursorScope(@getCursorScope(), notificationManager)
|
||||
'editor:copy-path': -> copyPathToClipboard(this, project, clipboard, false)
|
||||
'editor:copy-project-path': -> copyPathToClipboard(this, project, clipboard, true)
|
||||
'editor:toggle-indent-guide': -> config.set('editor.showIndentGuide', not config.get('editor.showIndentGuide'))
|
||||
'editor:toggle-line-numbers': -> config.set('editor.showLineNumbers', not config.get('editor.showLineNumbers'))
|
||||
'editor:scroll-to-cursor': -> @scrollToCursorPosition()
|
||||
}),
|
||||
false
|
||||
)
|
||||
|
||||
commandRegistry.add(
|
||||
'atom-text-editor:not([mini])',
|
||||
stopEventPropagationAndGroupUndo(
|
||||
config,
|
||||
{
|
||||
'editor:indent': -> @indent()
|
||||
'editor:auto-indent': -> @autoIndentSelectedRows()
|
||||
'editor:indent-selected-rows': -> @indentSelectedRows()
|
||||
'editor:outdent-selected-rows': -> @outdentSelectedRows()
|
||||
'editor:newline': -> @insertNewline()
|
||||
'editor:newline-below': -> @insertNewlineBelow()
|
||||
'editor:newline-above': -> @insertNewlineAbove()
|
||||
'editor:toggle-line-comments': -> @toggleLineCommentsInSelection()
|
||||
'editor:checkout-head-revision': -> atom.workspace.checkoutHeadRevision(this)
|
||||
'editor:move-line-up': -> @moveLineUp()
|
||||
'editor:move-line-down': -> @moveLineDown()
|
||||
'editor:move-selection-left': -> @moveSelectionLeft()
|
||||
'editor:move-selection-right': -> @moveSelectionRight()
|
||||
'editor:duplicate-lines': -> @duplicateLines()
|
||||
'editor:join-lines': -> @joinLines()
|
||||
}
|
||||
),
|
||||
false
|
||||
)
|
||||
|
||||
stopEventPropagation = (commandListeners) ->
|
||||
|
@ -58,7 +58,7 @@ export default class ReopenProjectMenuManager {
|
||||
// Windows users can right-click Atom taskbar and remove project from the jump list.
|
||||
// We have to honor that or the group stops working. As we only get a partial list
|
||||
// each time we remove them from history entirely.
|
||||
applyWindowsJumpListRemovals () {
|
||||
async applyWindowsJumpListRemovals () {
|
||||
if (process.platform !== 'win32') return
|
||||
if (this.app === undefined) {
|
||||
this.app = require('remote').app
|
||||
@ -68,7 +68,7 @@ export default class ReopenProjectMenuManager {
|
||||
if (removed.length === 0) return
|
||||
for (let project of this.historyManager.getProjects()) {
|
||||
if (removed.includes(ReopenProjectMenuManager.taskDescription(project.paths))) {
|
||||
this.historyManager.removeProject(project.paths)
|
||||
await this.historyManager.removeProject(project.paths)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,13 @@ path = require "path"
|
||||
async = require "async"
|
||||
{PathSearcher, PathScanner, search} = require 'scandal'
|
||||
|
||||
module.exports = (rootPaths, regexSource, options) ->
|
||||
module.exports = (rootPaths, regexSource, options, searchOptions={}) ->
|
||||
callback = @async()
|
||||
|
||||
PATHS_COUNTER_SEARCHED_CHUNK = 50
|
||||
pathsSearched = 0
|
||||
|
||||
searcher = new PathSearcher()
|
||||
searcher = new PathSearcher(searchOptions)
|
||||
|
||||
searcher.on 'file-error', ({code, path, message}) ->
|
||||
emit('scan:file-error', {code, path, message})
|
||||
|
@ -4,22 +4,31 @@ module.exports =
|
||||
class StateStore {
|
||||
constructor (databaseName, version) {
|
||||
this.connected = false
|
||||
this.dbPromise = new Promise((resolve) => {
|
||||
let dbOpenRequest = indexedDB.open(databaseName, version)
|
||||
dbOpenRequest.onupgradeneeded = (event) => {
|
||||
let db = event.target.result
|
||||
db.createObjectStore('states')
|
||||
}
|
||||
dbOpenRequest.onsuccess = () => {
|
||||
this.connected = true
|
||||
resolve(dbOpenRequest.result)
|
||||
}
|
||||
dbOpenRequest.onerror = (error) => {
|
||||
console.error('Could not connect to indexedDB', error)
|
||||
this.connected = false
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
this.databaseName = databaseName
|
||||
this.version = version
|
||||
}
|
||||
|
||||
get dbPromise () {
|
||||
if (!this._dbPromise) {
|
||||
this._dbPromise = new Promise((resolve) => {
|
||||
const dbOpenRequest = indexedDB.open(this.databaseName, this.version)
|
||||
dbOpenRequest.onupgradeneeded = (event) => {
|
||||
let db = event.target.result
|
||||
db.createObjectStore('states')
|
||||
}
|
||||
dbOpenRequest.onsuccess = () => {
|
||||
this.connected = true
|
||||
resolve(dbOpenRequest.result)
|
||||
}
|
||||
dbOpenRequest.onerror = (error) => {
|
||||
console.error('Could not connect to indexedDB', error)
|
||||
this.connected = false
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return this._dbPromise
|
||||
}
|
||||
|
||||
isConnected () {
|
||||
|
@ -13,17 +13,20 @@ const DEPRECATED_SYNTAX_SELECTORS = require('./deprecated-syntax-selectors')
|
||||
// own, but is instead subscribed to by individual `<atom-styles>` elements,
|
||||
// which clone and attach style elements in different contexts.
|
||||
module.exports = class StyleManager {
|
||||
constructor ({configDirPath}) {
|
||||
this.configDirPath = configDirPath
|
||||
if (this.configDirPath != null) {
|
||||
this.cacheDirPath = path.join(this.configDirPath, 'compile-cache', 'style-manager')
|
||||
}
|
||||
constructor () {
|
||||
this.emitter = new Emitter()
|
||||
this.styleElements = []
|
||||
this.styleElementsBySourcePath = {}
|
||||
this.deprecationsBySourcePath = {}
|
||||
}
|
||||
|
||||
initialize ({configDirPath}) {
|
||||
this.configDirPath = configDirPath
|
||||
if (this.configDirPath != null) {
|
||||
this.cacheDirPath = path.join(this.configDirPath, 'compile-cache', 'style-manager')
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Section: Event Subscription
|
||||
*/
|
||||
|
@ -70,7 +70,13 @@ class Task
|
||||
compileCachePath = require('./compile-cache').getCacheDirectory()
|
||||
taskBootstrapRequire = "require('#{require.resolve('./task-bootstrap')}');"
|
||||
bootstrap = """
|
||||
#{compileCacheRequire}.setCacheDirectory('#{compileCachePath}');
|
||||
if (typeof snapshotResult !== 'undefined') {
|
||||
snapshotResult.setGlobals(global, process, global, {}, require)
|
||||
}
|
||||
|
||||
CompileCache = #{compileCacheRequire}
|
||||
CompileCache.setCacheDirectory('#{compileCachePath}');
|
||||
CompileCache.install("#{process.resourcesPath}", require)
|
||||
#{taskBootstrapRequire}
|
||||
"""
|
||||
bootstrap = bootstrap.replace(/\\/g, "\\\\")
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @babel */
|
||||
|
||||
import {Emitter, Disposable, CompositeDisposable} from 'event-kit'
|
||||
import {Point, Range} from 'atom'
|
||||
import {Point, Range} from 'text-buffer'
|
||||
import TextEditor from './text-editor'
|
||||
import ScopeDescriptor from './scope-descriptor'
|
||||
|
||||
|
@ -192,6 +192,9 @@ class TextEditor extends Model
|
||||
|
||||
@displayLayer.setTextDecorationLayer(@tokenizedBuffer)
|
||||
@defaultMarkerLayer = @displayLayer.addMarkerLayer()
|
||||
@disposables.add(@defaultMarkerLayer.onDidDestroy =>
|
||||
@assert(false, "defaultMarkerLayer destroyed at an unexpected time")
|
||||
)
|
||||
@selectionsMarkerLayer ?= @addMarkerLayer(maintainHistory: true, persistent: true)
|
||||
@selectionsMarkerLayer.trackDestructionInOnDidCreateMarkerCallbacks = true
|
||||
|
||||
@ -353,7 +356,8 @@ class TextEditor extends Model
|
||||
cursor.setShowCursorOnSelection(value) for cursor in @getCursors()
|
||||
|
||||
else
|
||||
throw new TypeError("Invalid TextEditor parameter: '#{param}'")
|
||||
if param isnt 'ref' and param isnt 'key'
|
||||
throw new TypeError("Invalid TextEditor parameter: '#{param}'")
|
||||
|
||||
@displayLayer.reset(displayLayerParams)
|
||||
|
||||
@ -383,7 +387,7 @@ class TextEditor extends Model
|
||||
softWrapHangingIndentLength: @displayLayer.softWrapHangingIndent
|
||||
|
||||
@id, @softTabs, @softWrapped, @softWrapAtPreferredLineLength,
|
||||
@preferredLineLength, @mini, @editorWidthInChars, @width, @largeFileMode,
|
||||
@preferredLineLength, @mini, @editorWidthInChars, @width, @largeFileMode,
|
||||
@registered, @invisibles, @showInvisibles, @showIndentGuide, @autoHeight, @autoWidth
|
||||
}
|
||||
|
||||
@ -1324,12 +1328,12 @@ class TextEditor extends Model
|
||||
replaceSelectedText: (options={}, fn) ->
|
||||
{selectWordIfEmpty} = options
|
||||
@mutateSelectedText (selection) ->
|
||||
range = selection.getBufferRange()
|
||||
selection.getBufferRange()
|
||||
if selectWordIfEmpty and selection.isEmpty()
|
||||
selection.selectWord()
|
||||
text = selection.getText()
|
||||
selection.deleteSelectedText()
|
||||
selection.insertText(fn(text))
|
||||
range = selection.insertText(fn(text))
|
||||
selection.setBufferRange(range)
|
||||
|
||||
# Split multi-line selections into one selection per line.
|
||||
@ -2822,6 +2826,11 @@ class TextEditor extends Model
|
||||
# {::backwardsScanInBufferRange} to avoid tripping over your own changes.
|
||||
#
|
||||
# * `regex` A {RegExp} to search for.
|
||||
# * `options` (optional) {Object}
|
||||
# * `leadingContextLineCount` {Number} default `0`; The number of lines
|
||||
# before the matched line to include in the results object.
|
||||
# * `trailingContextLineCount` {Number} default `0`; The number of lines
|
||||
# after the matched line to include in the results object.
|
||||
# * `iterator` A {Function} that's called on each match
|
||||
# * `object` {Object}
|
||||
# * `match` The current regular expression match.
|
||||
@ -2829,7 +2838,12 @@ class TextEditor extends Model
|
||||
# * `range` The {Range} of the match.
|
||||
# * `stop` Call this {Function} to terminate the scan.
|
||||
# * `replace` Call this {Function} with a {String} to replace the match.
|
||||
scan: (regex, iterator) -> @buffer.scan(regex, iterator)
|
||||
scan: (regex, options={}, iterator) ->
|
||||
if _.isFunction(options)
|
||||
iterator = options
|
||||
options = {}
|
||||
|
||||
@buffer.scan(regex, options, iterator)
|
||||
|
||||
# Essential: Scan regular expression matches in a given range, calling the given
|
||||
# iterator function on each match.
|
||||
|
@ -9,7 +9,7 @@ fs = require 'fs-plus'
|
||||
# An instance of this class is always available as the `atom.themes` global.
|
||||
module.exports =
|
||||
class ThemeManager
|
||||
constructor: ({@packageManager, @resourcePath, @configDirPath, @safeMode, @config, @styleManager, @notificationManager, @viewRegistry}) ->
|
||||
constructor: ({@packageManager, @config, @styleManager, @notificationManager, @viewRegistry}) ->
|
||||
@emitter = new Emitter
|
||||
@styleSheetDisposablesBySourcePath = {}
|
||||
@lessCache = null
|
||||
@ -18,6 +18,8 @@ class ThemeManager
|
||||
@packageManager.onDidActivateInitialPackages =>
|
||||
@onDidChangeActiveThemes => @packageManager.reloadActivePackageStyleSheets()
|
||||
|
||||
initialize: ({@resourcePath, @configDirPath, @safeMode}) ->
|
||||
|
||||
###
|
||||
Section: Event Subscription
|
||||
###
|
||||
|
@ -8,8 +8,6 @@ ScopeDescriptor = require './scope-descriptor'
|
||||
TokenizedBufferIterator = require './tokenized-buffer-iterator'
|
||||
NullGrammar = require './null-grammar'
|
||||
|
||||
MAX_LINE_LENGTH_TO_TOKENIZE = 500
|
||||
|
||||
module.exports =
|
||||
class TokenizedBuffer extends Model
|
||||
grammar: null
|
||||
@ -253,8 +251,6 @@ class TokenizedBuffer extends Model
|
||||
|
||||
buildTokenizedLineForRowWithText: (row, text, ruleStack = @stackForRow(row - 1), openScopes = @openScopesForRow(row)) ->
|
||||
lineEnding = @buffer.lineEndingForRow(row)
|
||||
if text.length > MAX_LINE_LENGTH_TO_TOKENIZE
|
||||
text = text.slice(0, MAX_LINE_LENGTH_TO_TOKENIZE)
|
||||
{tags, ruleStack} = @grammar.tokenizeLine(text, ruleStack, row is 0, false)
|
||||
new TokenizedLine({openScopes, text, tags, ruleStack, lineEnding, @tokenIterator})
|
||||
|
||||
|
@ -54,9 +54,12 @@ class ViewRegistry
|
||||
minimumPollInterval: 200
|
||||
|
||||
constructor: (@atomEnvironment) ->
|
||||
@observer = new MutationObserver(@requestDocumentPoll)
|
||||
@polling = false
|
||||
@clear()
|
||||
|
||||
initialize: ->
|
||||
@observer = new MutationObserver(@requestDocumentPoll)
|
||||
|
||||
clear: ->
|
||||
@views = new WeakMap
|
||||
@providers = []
|
||||
@ -267,10 +270,13 @@ class ViewRegistry
|
||||
startPollingDocument: ->
|
||||
window.addEventListener('resize', @requestDocumentPoll)
|
||||
@observer.observe(document, {subtree: true, childList: true, attributes: true})
|
||||
@polling = true
|
||||
|
||||
stopPollingDocument: ->
|
||||
window.removeEventListener('resize', @requestDocumentPoll)
|
||||
@observer.disconnect()
|
||||
if @polling
|
||||
window.removeEventListener('resize', @requestDocumentPoll)
|
||||
@observer.disconnect()
|
||||
@polling = false
|
||||
|
||||
requestDocumentPoll: =>
|
||||
if @animationFrameRequest?
|
||||
|
@ -4,31 +4,13 @@ listen = require './delegated-listener'
|
||||
# Handles low-level events related to the @window.
|
||||
module.exports =
|
||||
class WindowEventHandler
|
||||
constructor: ({@atomEnvironment, @applicationDelegate, @window, @document}) ->
|
||||
constructor: ({@atomEnvironment, @applicationDelegate}) ->
|
||||
@reloadRequested = false
|
||||
@subscriptions = new CompositeDisposable
|
||||
|
||||
@addEventListener(@window, 'beforeunload', @handleWindowBeforeunload)
|
||||
@addEventListener(@window, 'focus', @handleWindowFocus)
|
||||
@addEventListener(@window, 'blur', @handleWindowBlur)
|
||||
|
||||
@addEventListener(@document, 'keyup', @handleDocumentKeyEvent)
|
||||
@addEventListener(@document, 'keydown', @handleDocumentKeyEvent)
|
||||
@addEventListener(@document, 'drop', @handleDocumentDrop)
|
||||
@addEventListener(@document, 'dragover', @handleDocumentDragover)
|
||||
@addEventListener(@document, 'contextmenu', @handleDocumentContextmenu)
|
||||
@subscriptions.add listen(@document, 'click', 'a', @handleLinkClick)
|
||||
@subscriptions.add listen(@document, 'submit', 'form', @handleFormSubmit)
|
||||
|
||||
browserWindow = @applicationDelegate.getCurrentWindow()
|
||||
browserWindow.on 'enter-full-screen', @handleEnterFullScreen
|
||||
@subscriptions.add new Disposable =>
|
||||
browserWindow.removeListener('enter-full-screen', @handleEnterFullScreen)
|
||||
|
||||
browserWindow.on 'leave-full-screen', @handleLeaveFullScreen
|
||||
@subscriptions.add new Disposable =>
|
||||
browserWindow.removeListener('leave-full-screen', @handleLeaveFullScreen)
|
||||
@handleNativeKeybindings()
|
||||
|
||||
initialize: (@window, @document) ->
|
||||
@subscriptions.add @atomEnvironment.commands.add @window,
|
||||
'window:toggle-full-screen': @handleWindowToggleFullScreen
|
||||
'window:close': @handleWindowClose
|
||||
@ -43,14 +25,31 @@ class WindowEventHandler
|
||||
'core:focus-next': @handleFocusNext
|
||||
'core:focus-previous': @handleFocusPrevious
|
||||
|
||||
@handleNativeKeybindings()
|
||||
@addEventListener(@window, 'beforeunload', @handleWindowBeforeunload)
|
||||
@addEventListener(@window, 'focus', @handleWindowFocus)
|
||||
@addEventListener(@window, 'blur', @handleWindowBlur)
|
||||
|
||||
@addEventListener(@document, 'keyup', @handleDocumentKeyEvent)
|
||||
@addEventListener(@document, 'keydown', @handleDocumentKeyEvent)
|
||||
@addEventListener(@document, 'drop', @handleDocumentDrop)
|
||||
@addEventListener(@document, 'dragover', @handleDocumentDragover)
|
||||
@addEventListener(@document, 'contextmenu', @handleDocumentContextmenu)
|
||||
@subscriptions.add listen(@document, 'click', 'a', @handleLinkClick)
|
||||
@subscriptions.add listen(@document, 'submit', 'form', @handleFormSubmit)
|
||||
|
||||
@subscriptions.add(@applicationDelegate.onDidEnterFullScreen(@handleEnterFullScreen))
|
||||
@subscriptions.add(@applicationDelegate.onDidLeaveFullScreen(@handleLeaveFullScreen))
|
||||
|
||||
# Wire commands that should be handled by Chromium for elements with the
|
||||
# `.native-key-bindings` class.
|
||||
handleNativeKeybindings: ->
|
||||
bindCommandToAction = (command, action) =>
|
||||
@subscriptions.add @atomEnvironment.commands.add '.native-key-bindings', command, (event) =>
|
||||
@applicationDelegate.getCurrentWindow().webContents[action]()
|
||||
@subscriptions.add @atomEnvironment.commands.add(
|
||||
'.native-key-bindings',
|
||||
command,
|
||||
((event) => @applicationDelegate.getCurrentWindow().webContents[action]()),
|
||||
false
|
||||
)
|
||||
|
||||
bindCommandToAction('core:copy', 'copy')
|
||||
bindCommandToAction('core:paste', 'paste')
|
||||
|
@ -1,154 +0,0 @@
|
||||
{ipcRenderer} = require 'electron'
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
{CompositeDisposable} = require 'event-kit'
|
||||
scrollbarStyle = require 'scrollbar-style'
|
||||
|
||||
module.exports =
|
||||
class WorkspaceElement extends HTMLElement
|
||||
globalTextEditorStyleSheet: null
|
||||
|
||||
attachedCallback: ->
|
||||
@focus()
|
||||
|
||||
detachedCallback: ->
|
||||
@subscriptions.dispose()
|
||||
|
||||
initializeContent: ->
|
||||
@classList.add 'workspace'
|
||||
@setAttribute 'tabindex', -1
|
||||
|
||||
@verticalAxis = document.createElement('atom-workspace-axis')
|
||||
@verticalAxis.classList.add('vertical')
|
||||
|
||||
@horizontalAxis = document.createElement('atom-workspace-axis')
|
||||
@horizontalAxis.classList.add('horizontal')
|
||||
@horizontalAxis.appendChild(@verticalAxis)
|
||||
|
||||
@appendChild(@horizontalAxis)
|
||||
|
||||
observeScrollbarStyle: ->
|
||||
@subscriptions.add scrollbarStyle.observePreferredScrollbarStyle (style) =>
|
||||
switch style
|
||||
when 'legacy'
|
||||
@classList.remove('scrollbars-visible-when-scrolling')
|
||||
@classList.add("scrollbars-visible-always")
|
||||
when 'overlay'
|
||||
@classList.remove('scrollbars-visible-always')
|
||||
@classList.add("scrollbars-visible-when-scrolling")
|
||||
|
||||
observeTextEditorFontConfig: ->
|
||||
@updateGlobalTextEditorStyleSheet()
|
||||
@subscriptions.add @config.onDidChange 'editor.fontSize', @updateGlobalTextEditorStyleSheet.bind(this)
|
||||
@subscriptions.add @config.onDidChange 'editor.fontFamily', @updateGlobalTextEditorStyleSheet.bind(this)
|
||||
@subscriptions.add @config.onDidChange 'editor.lineHeight', @updateGlobalTextEditorStyleSheet.bind(this)
|
||||
|
||||
updateGlobalTextEditorStyleSheet: ->
|
||||
fontFamily = @config.get('editor.fontFamily')
|
||||
# TODO: There is a bug in how some emojis (e.g. ❤️) are rendered on macOS.
|
||||
# This workaround should be removed once we update to Chromium 51, where the
|
||||
# problem was fixed.
|
||||
fontFamily += ', "Apple Color Emoji"' if process.platform is 'darwin'
|
||||
styleSheetSource = """
|
||||
atom-text-editor {
|
||||
font-size: #{@config.get('editor.fontSize')}px;
|
||||
font-family: #{fontFamily};
|
||||
line-height: #{@config.get('editor.lineHeight')};
|
||||
}
|
||||
"""
|
||||
@styles.addStyleSheet(styleSheetSource, sourcePath: 'global-text-editor-styles')
|
||||
@views.performDocumentPoll()
|
||||
|
||||
initialize: (@model, {@views, @workspace, @project, @config, @styles}) ->
|
||||
throw new Error("Must pass a views parameter when initializing WorskpaceElements") unless @views?
|
||||
throw new Error("Must pass a workspace parameter when initializing WorskpaceElements") unless @workspace?
|
||||
throw new Error("Must pass a project parameter when initializing WorskpaceElements") unless @project?
|
||||
throw new Error("Must pass a config parameter when initializing WorskpaceElements") unless @config?
|
||||
throw new Error("Must pass a styles parameter when initializing WorskpaceElements") unless @styles?
|
||||
|
||||
@subscriptions = new CompositeDisposable
|
||||
@initializeContent()
|
||||
@observeScrollbarStyle()
|
||||
@observeTextEditorFontConfig()
|
||||
|
||||
@paneContainer = @views.getView(@model.paneContainer)
|
||||
@verticalAxis.appendChild(@paneContainer)
|
||||
@addEventListener 'focus', @handleFocus.bind(this)
|
||||
|
||||
@addEventListener 'mousewheel', @handleMousewheel.bind(this), true
|
||||
|
||||
@panelContainers =
|
||||
top: @views.getView(@model.panelContainers.top)
|
||||
left: @views.getView(@model.panelContainers.left)
|
||||
right: @views.getView(@model.panelContainers.right)
|
||||
bottom: @views.getView(@model.panelContainers.bottom)
|
||||
header: @views.getView(@model.panelContainers.header)
|
||||
footer: @views.getView(@model.panelContainers.footer)
|
||||
modal: @views.getView(@model.panelContainers.modal)
|
||||
|
||||
@horizontalAxis.insertBefore(@panelContainers.left, @verticalAxis)
|
||||
@horizontalAxis.appendChild(@panelContainers.right)
|
||||
|
||||
@verticalAxis.insertBefore(@panelContainers.top, @paneContainer)
|
||||
@verticalAxis.appendChild(@panelContainers.bottom)
|
||||
|
||||
@insertBefore(@panelContainers.header, @horizontalAxis)
|
||||
@appendChild(@panelContainers.footer)
|
||||
|
||||
@appendChild(@panelContainers.modal)
|
||||
|
||||
this
|
||||
|
||||
getModel: -> @model
|
||||
|
||||
handleMousewheel: (event) ->
|
||||
if event.ctrlKey and @config.get('editor.zoomFontWhenCtrlScrolling') and event.target.closest('atom-text-editor')?
|
||||
if event.wheelDeltaY > 0
|
||||
@model.increaseFontSize()
|
||||
else if event.wheelDeltaY < 0
|
||||
@model.decreaseFontSize()
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
||||
handleFocus: (event) ->
|
||||
@model.getActivePane().activate()
|
||||
|
||||
focusPaneViewAbove: -> @paneContainer.focusPaneViewAbove()
|
||||
|
||||
focusPaneViewBelow: -> @paneContainer.focusPaneViewBelow()
|
||||
|
||||
focusPaneViewOnLeft: -> @paneContainer.focusPaneViewOnLeft()
|
||||
|
||||
focusPaneViewOnRight: -> @paneContainer.focusPaneViewOnRight()
|
||||
|
||||
moveActiveItemToPaneAbove: (params) -> @paneContainer.moveActiveItemToPaneAbove(params)
|
||||
|
||||
moveActiveItemToPaneBelow: (params) -> @paneContainer.moveActiveItemToPaneBelow(params)
|
||||
|
||||
moveActiveItemToPaneOnLeft: (params) -> @paneContainer.moveActiveItemToPaneOnLeft(params)
|
||||
|
||||
moveActiveItemToPaneOnRight: (params) -> @paneContainer.moveActiveItemToPaneOnRight(params)
|
||||
|
||||
runPackageSpecs: ->
|
||||
if activePath = @workspace.getActivePaneItem()?.getPath?()
|
||||
[projectPath] = @project.relativizePath(activePath)
|
||||
else
|
||||
[projectPath] = @project.getPaths()
|
||||
if projectPath
|
||||
specPath = path.join(projectPath, 'spec')
|
||||
testPath = path.join(projectPath, 'test')
|
||||
if not fs.existsSync(specPath) and fs.existsSync(testPath)
|
||||
specPath = testPath
|
||||
|
||||
ipcRenderer.send('run-package-specs', specPath)
|
||||
|
||||
runBenchmarks: ->
|
||||
if activePath = @workspace.getActivePaneItem()?.getPath?()
|
||||
[projectPath] = @project.relativizePath(activePath)
|
||||
else
|
||||
[projectPath] = @project.getPaths()
|
||||
|
||||
if projectPath
|
||||
ipcRenderer.send('run-benchmarks', path.join(projectPath, 'benchmarks'))
|
||||
|
||||
module.exports = WorkspaceElement = document.registerElement 'atom-workspace', prototype: WorkspaceElement.prototype
|
184
src/workspace-element.js
Normal file
184
src/workspace-element.js
Normal file
@ -0,0 +1,184 @@
|
||||
'use strict'
|
||||
|
||||
/* global HTMLElement */
|
||||
|
||||
const {ipcRenderer} = require('electron')
|
||||
const path = require('path')
|
||||
const fs = require('fs-plus')
|
||||
const {CompositeDisposable} = require('event-kit')
|
||||
const scrollbarStyle = require('scrollbar-style')
|
||||
|
||||
class WorkspaceElement extends HTMLElement {
|
||||
attachedCallback () {
|
||||
this.focus()
|
||||
}
|
||||
|
||||
detachedCallback () {
|
||||
this.subscriptions.dispose()
|
||||
}
|
||||
|
||||
initializeContent () {
|
||||
this.classList.add('workspace')
|
||||
this.setAttribute('tabindex', -1)
|
||||
|
||||
this.verticalAxis = document.createElement('atom-workspace-axis')
|
||||
this.verticalAxis.classList.add('vertical')
|
||||
|
||||
this.horizontalAxis = document.createElement('atom-workspace-axis')
|
||||
this.horizontalAxis.classList.add('horizontal')
|
||||
this.horizontalAxis.appendChild(this.verticalAxis)
|
||||
|
||||
this.appendChild(this.horizontalAxis)
|
||||
}
|
||||
|
||||
observeScrollbarStyle () {
|
||||
this.subscriptions.add(scrollbarStyle.observePreferredScrollbarStyle(style => {
|
||||
switch (style) {
|
||||
case 'legacy':
|
||||
this.classList.remove('scrollbars-visible-when-scrolling')
|
||||
this.classList.add('scrollbars-visible-always')
|
||||
break
|
||||
case 'overlay':
|
||||
this.classList.remove('scrollbars-visible-always')
|
||||
this.classList.add('scrollbars-visible-when-scrolling')
|
||||
break
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
observeTextEditorFontConfig () {
|
||||
this.updateGlobalTextEditorStyleSheet()
|
||||
this.subscriptions.add(this.config.onDidChange('editor.fontSize', this.updateGlobalTextEditorStyleSheet.bind(this)))
|
||||
this.subscriptions.add(this.config.onDidChange('editor.fontFamily', this.updateGlobalTextEditorStyleSheet.bind(this)))
|
||||
this.subscriptions.add(this.config.onDidChange('editor.lineHeight', this.updateGlobalTextEditorStyleSheet.bind(this)))
|
||||
}
|
||||
|
||||
updateGlobalTextEditorStyleSheet () {
|
||||
const styleSheetSource = `atom-text-editor {
|
||||
font-size: ${this.config.get('editor.fontSize')}px;
|
||||
font-family: ${this.config.get('editor.fontFamily')};
|
||||
line-height: ${this.config.get('editor.lineHeight')};
|
||||
}`
|
||||
this.styles.addStyleSheet(styleSheetSource, {sourcePath: 'global-text-editor-styles'})
|
||||
this.views.performDocumentPoll()
|
||||
}
|
||||
|
||||
initialize (model, {views, workspace, project, config, styles}) {
|
||||
this.model = model
|
||||
this.views = views
|
||||
this.workspace = workspace
|
||||
this.project = project
|
||||
this.config = config
|
||||
this.styles = styles
|
||||
if (this.views == null) { throw new Error('Must pass a views parameter when initializing WorskpaceElements') }
|
||||
if (this.workspace == null) { throw new Error('Must pass a workspace parameter when initializing WorskpaceElements') }
|
||||
if (this.project == null) { throw new Error('Must pass a project parameter when initializing WorskpaceElements') }
|
||||
if (this.config == null) { throw new Error('Must pass a config parameter when initializing WorskpaceElements') }
|
||||
if (this.styles == null) { throw new Error('Must pass a styles parameter when initializing WorskpaceElements') }
|
||||
|
||||
this.subscriptions = new CompositeDisposable()
|
||||
this.initializeContent()
|
||||
this.observeScrollbarStyle()
|
||||
this.observeTextEditorFontConfig()
|
||||
|
||||
this.paneContainer = this.views.getView(this.model.paneContainer)
|
||||
this.verticalAxis.appendChild(this.paneContainer)
|
||||
this.addEventListener('focus', this.handleFocus.bind(this))
|
||||
|
||||
this.addEventListener('mousewheel', this.handleMousewheel.bind(this), true)
|
||||
|
||||
this.panelContainers = {
|
||||
top: this.views.getView(this.model.panelContainers.top),
|
||||
left: this.views.getView(this.model.panelContainers.left),
|
||||
right: this.views.getView(this.model.panelContainers.right),
|
||||
bottom: this.views.getView(this.model.panelContainers.bottom),
|
||||
header: this.views.getView(this.model.panelContainers.header),
|
||||
footer: this.views.getView(this.model.panelContainers.footer),
|
||||
modal: this.views.getView(this.model.panelContainers.modal)
|
||||
}
|
||||
|
||||
this.horizontalAxis.insertBefore(this.panelContainers.left, this.verticalAxis)
|
||||
this.horizontalAxis.appendChild(this.panelContainers.right)
|
||||
|
||||
this.verticalAxis.insertBefore(this.panelContainers.top, this.paneContainer)
|
||||
this.verticalAxis.appendChild(this.panelContainers.bottom)
|
||||
|
||||
this.insertBefore(this.panelContainers.header, this.horizontalAxis)
|
||||
this.appendChild(this.panelContainers.footer)
|
||||
|
||||
this.appendChild(this.panelContainers.modal)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
getModel () { return this.model }
|
||||
|
||||
handleMousewheel (event) {
|
||||
if (event.ctrlKey && this.config.get('editor.zoomFontWhenCtrlScrolling') && (event.target.closest('atom-text-editor') != null)) {
|
||||
if (event.wheelDeltaY > 0) {
|
||||
this.model.increaseFontSize()
|
||||
} else if (event.wheelDeltaY < 0) {
|
||||
this.model.decreaseFontSize()
|
||||
}
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
}
|
||||
}
|
||||
|
||||
handleFocus (event) {
|
||||
this.model.getActivePane().activate()
|
||||
}
|
||||
|
||||
focusPaneViewAbove () { this.paneContainer.focusPaneViewAbove() }
|
||||
|
||||
focusPaneViewBelow () { this.paneContainer.focusPaneViewBelow() }
|
||||
|
||||
focusPaneViewOnLeft () { this.paneContainer.focusPaneViewOnLeft() }
|
||||
|
||||
focusPaneViewOnRight () { this.paneContainer.focusPaneViewOnRight() }
|
||||
|
||||
moveActiveItemToPaneAbove (params) { this.paneContainer.moveActiveItemToPaneAbove(params) }
|
||||
|
||||
moveActiveItemToPaneBelow (params) { this.paneContainer.moveActiveItemToPaneBelow(params) }
|
||||
|
||||
moveActiveItemToPaneOnLeft (params) { this.paneContainer.moveActiveItemToPaneOnLeft(params) }
|
||||
|
||||
moveActiveItemToPaneOnRight (params) { this.paneContainer.moveActiveItemToPaneOnRight(params) }
|
||||
|
||||
runPackageSpecs () {
|
||||
const activePaneItem = this.workspace.getActivePaneItem()
|
||||
const activePath = activePaneItem && typeof activePaneItem.getPath === 'function' ? activePaneItem.getPath() : null
|
||||
let projectPath
|
||||
if (activePath != null) {
|
||||
[projectPath] = this.project.relativizePath(activePath)
|
||||
} else {
|
||||
[projectPath] = this.project.getPaths()
|
||||
}
|
||||
if (projectPath) {
|
||||
let specPath = path.join(projectPath, 'spec')
|
||||
const testPath = path.join(projectPath, 'test')
|
||||
if (!fs.existsSync(specPath) && fs.existsSync(testPath)) {
|
||||
specPath = testPath
|
||||
}
|
||||
|
||||
ipcRenderer.send('run-package-specs', specPath)
|
||||
}
|
||||
}
|
||||
|
||||
runBenchmarks () {
|
||||
const activePaneItem = this.workspace.getActivePaneItem()
|
||||
const activePath = activePaneItem && typeof activePaneItem.getPath === 'function' ? activePaneItem.getPath() : null
|
||||
let projectPath
|
||||
if (activePath) {
|
||||
[projectPath] = this.project.relativizePath(activePath)
|
||||
} else {
|
||||
[projectPath] = this.project.getPaths()
|
||||
}
|
||||
|
||||
if (projectPath) {
|
||||
ipcRenderer.send('run-benchmarks', path.join(projectPath, 'benchmarks'))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = document.registerElement('atom-workspace', {prototype: WorkspaceElement.prototype})
|
1121
src/workspace.coffee
1121
src/workspace.coffee
File diff suppressed because it is too large
Load Diff
1423
src/workspace.js
Normal file
1423
src/workspace.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,16 +1,7 @@
|
||||
{
|
||||
"breakConfig": true,
|
||||
"sourceMap": "inline",
|
||||
"plugins": [
|
||||
["add-module-exports", {}],
|
||||
["transform-async-to-generator", {}],
|
||||
["transform-decorators-legacy", {}],
|
||||
["transform-class-properties", {}],
|
||||
["transform-es2015-modules-commonjs", {"strictMode": false}],
|
||||
["transform-export-extensions", {}],
|
||||
["transform-do-expressions", {}],
|
||||
["transform-function-bind", {}],
|
||||
["transform-object-rest-spread", {}],
|
||||
["transform-flow-strip-types", {}],
|
||||
["transform-react-jsx", {}]
|
||||
]
|
||||
"blacklist": ["es6.forOf", "useStrict"],
|
||||
"optional": ["asyncToGenerator"],
|
||||
"stage": 0
|
||||
}
|
||||
|
112
static/index.js
112
static/index.js
@ -1,35 +1,66 @@
|
||||
(function () {
|
||||
var path = require('path')
|
||||
var FileSystemBlobStore = require('../src/file-system-blob-store')
|
||||
var NativeCompileCache = require('../src/native-compile-cache')
|
||||
var getWindowLoadSettings = require('../src/get-window-load-settings')
|
||||
// Eagerly require cached-run-in-this-context to prevent a circular require
|
||||
// when using `NativeCompileCache` for the first time.
|
||||
require('cached-run-in-this-context')
|
||||
|
||||
var blobStore = null
|
||||
const electron = require('electron')
|
||||
const path = require('path')
|
||||
const Module = require('module')
|
||||
const getWindowLoadSettings = require('../src/get-window-load-settings')
|
||||
const entryPointDirPath = __dirname
|
||||
let blobStore = null
|
||||
let useSnapshot = false
|
||||
|
||||
window.onload = function () {
|
||||
try {
|
||||
var startTime = Date.now()
|
||||
const startTime = Date.now()
|
||||
|
||||
process.on('unhandledRejection', function (error, promise) {
|
||||
console.error('Unhandled promise rejection %o with error: %o', promise, error)
|
||||
})
|
||||
|
||||
blobStore = FileSystemBlobStore.load(
|
||||
path.join(process.env.ATOM_HOME, 'blob-store/')
|
||||
)
|
||||
NativeCompileCache.setCacheStore(blobStore)
|
||||
NativeCompileCache.setV8Version(process.versions.v8)
|
||||
NativeCompileCache.install()
|
||||
|
||||
// Normalize to make sure drive letter case is consistent on Windows
|
||||
process.resourcesPath = path.normalize(process.resourcesPath)
|
||||
|
||||
var devMode = getWindowLoadSettings().devMode || !getWindowLoadSettings().resourcePath.startsWith(process.resourcesPath + path.sep)
|
||||
setupAtomHome()
|
||||
const devMode = getWindowLoadSettings().devMode || !getWindowLoadSettings().resourcePath.startsWith(process.resourcesPath + path.sep)
|
||||
useSnapshot = !devMode && typeof snapshotResult !== 'undefined'
|
||||
|
||||
if (devMode) {
|
||||
setupDeprecatedPackages()
|
||||
const metadata = require('../package.json')
|
||||
if (!metadata._deprecatedPackages) {
|
||||
try {
|
||||
metadata._deprecatedPackages = require('../script/deprecated-packages.json')
|
||||
} catch (requireError) {
|
||||
console.error('Failed to setup deprecated packages list', requireError.stack)
|
||||
}
|
||||
}
|
||||
} else if (useSnapshot) {
|
||||
Module.prototype.require = function (module) {
|
||||
const absoluteFilePath = Module._resolveFilename(module, this, false)
|
||||
let relativeFilePath = path.relative(entryPointDirPath, absoluteFilePath)
|
||||
if (process.platform === 'win32') {
|
||||
relativeFilePath = relativeFilePath.replace(/\\/g, '/')
|
||||
}
|
||||
let cachedModule = snapshotResult.customRequire.cache[relativeFilePath] // eslint-disable-line no-undef
|
||||
if (!cachedModule) {
|
||||
cachedModule = {exports: Module._load(module, this, false)}
|
||||
snapshotResult.customRequire.cache[relativeFilePath] = cachedModule // eslint-disable-line no-undef
|
||||
}
|
||||
return cachedModule.exports
|
||||
}
|
||||
|
||||
snapshotResult.setGlobals(global, process, window, document, require) // eslint-disable-line no-undef
|
||||
}
|
||||
|
||||
const FileSystemBlobStore = useSnapshot ? snapshotResult.customRequire('../src/file-system-blob-store.js') : require('../src/file-system-blob-store') // eslint-disable-line no-undef
|
||||
blobStore = FileSystemBlobStore.load(path.join(process.env.ATOM_HOME, 'blob-store'))
|
||||
|
||||
const NativeCompileCache = useSnapshot ? snapshotResult.customRequire('../src/native-compile-cache.js') : require('../src/native-compile-cache') // eslint-disable-line no-undef
|
||||
NativeCompileCache.setCacheStore(blobStore)
|
||||
NativeCompileCache.setV8Version(process.versions.v8)
|
||||
NativeCompileCache.install()
|
||||
|
||||
if (getWindowLoadSettings().profileStartup) {
|
||||
profileStartup(Date.now() - startTime)
|
||||
} else {
|
||||
@ -48,7 +79,7 @@
|
||||
}
|
||||
|
||||
function handleSetupError (error) {
|
||||
var currentWindow = require('electron').remote.getCurrentWindow()
|
||||
const currentWindow = electron.remote.getCurrentWindow()
|
||||
currentWindow.setSize(800, 600)
|
||||
currentWindow.center()
|
||||
currentWindow.show()
|
||||
@ -57,53 +88,30 @@
|
||||
}
|
||||
|
||||
function setupWindow () {
|
||||
var CompileCache = require('../src/compile-cache')
|
||||
const CompileCache = useSnapshot ? snapshotResult.customRequire('../src/compile-cache.js') : require('../src/compile-cache') // eslint-disable-line no-undef
|
||||
CompileCache.setAtomHomeDirectory(process.env.ATOM_HOME)
|
||||
CompileCache.install(process.resourcesPath, require)
|
||||
|
||||
var ModuleCache = require('../src/module-cache')
|
||||
const ModuleCache = useSnapshot ? snapshotResult.customRequire('../src/module-cache.js') : require('../src/module-cache') // eslint-disable-line no-undef
|
||||
ModuleCache.register(getWindowLoadSettings())
|
||||
ModuleCache.add(getWindowLoadSettings().resourcePath)
|
||||
|
||||
// By explicitly passing the app version here, we could save the call
|
||||
// of "require('remote').require('app').getVersion()".
|
||||
var startCrashReporter = require('../src/crash-reporter-start')
|
||||
const startCrashReporter = useSnapshot ? snapshotResult.customRequire('../src/crash-reporter-start.js') : require('../src/crash-reporter-start') // eslint-disable-line no-undef
|
||||
startCrashReporter({_version: getWindowLoadSettings().appVersion})
|
||||
|
||||
setupVmCompatibility()
|
||||
setupCsonCache(CompileCache.getCacheDirectory())
|
||||
const CSON = useSnapshot ? snapshotResult.customRequire('../node_modules/season/lib/cson.js') : require('season') // eslint-disable-line no-undef
|
||||
CSON.setCacheDir(path.join(CompileCache.getCacheDirectory(), 'cson'))
|
||||
|
||||
var initialize = require(getWindowLoadSettings().windowInitializationScript)
|
||||
const initScriptPath = path.relative(entryPointDirPath, getWindowLoadSettings().windowInitializationScript)
|
||||
const initialize = useSnapshot ? snapshotResult.customRequire(initScriptPath) : require(initScriptPath) // eslint-disable-line no-undef
|
||||
return initialize({blobStore: blobStore}).then(function () {
|
||||
require('electron').ipcRenderer.send('window-command', 'window:loaded')
|
||||
electron.ipcRenderer.send('window-command', 'window:loaded')
|
||||
})
|
||||
}
|
||||
|
||||
function setupCsonCache (cacheDir) {
|
||||
require('season').setCacheDir(path.join(cacheDir, 'cson'))
|
||||
}
|
||||
|
||||
function setupVmCompatibility () {
|
||||
var vm = require('vm')
|
||||
if (!vm.Script.createContext) {
|
||||
vm.Script.createContext = vm.createContext
|
||||
}
|
||||
}
|
||||
|
||||
function setupDeprecatedPackages () {
|
||||
var metadata = require('../package.json')
|
||||
if (!metadata._deprecatedPackages) {
|
||||
try {
|
||||
metadata._deprecatedPackages = require('../script/deprecated-packages.json')
|
||||
} catch (requireError) {
|
||||
console.error('Failed to setup deprecated packages list', requireError.stack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function profileStartup (initialTime) {
|
||||
function profile () {
|
||||
console.profile('startup')
|
||||
var startTime = Date.now()
|
||||
const startTime = Date.now()
|
||||
setupWindow().then(function () {
|
||||
setLoadTime(Date.now() - startTime + initialTime)
|
||||
console.profileEnd('startup')
|
||||
@ -111,7 +119,7 @@
|
||||
})
|
||||
}
|
||||
|
||||
const webContents = require('electron').remote.getCurrentWindow().webContents
|
||||
const webContents = electron.remote.getCurrentWindow().webContents
|
||||
if (webContents.devToolsWebContents) {
|
||||
profile()
|
||||
} else {
|
||||
@ -120,7 +128,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
var setupAtomHome = function () {
|
||||
function setupAtomHome () {
|
||||
if (process.env.ATOM_HOME) {
|
||||
return
|
||||
}
|
||||
@ -132,6 +140,4 @@
|
||||
process.env.ATOM_HOME = getWindowLoadSettings().atomHome
|
||||
}
|
||||
}
|
||||
|
||||
setupAtomHome()
|
||||
})()
|
||||
|
@ -1,3 +1,5 @@
|
||||
@import "octicon-utf-codes.less";
|
||||
|
||||
.icon-size(@size) {
|
||||
font-size: @size;
|
||||
width: @size;
|
||||
@ -17,7 +19,6 @@
|
||||
}
|
||||
|
||||
.octicon(@name, @size: 16px) {
|
||||
@import "octicon-utf-codes.less";
|
||||
&::before {
|
||||
.icon(@size);
|
||||
content: @@name
|
||||
@ -25,7 +26,6 @@
|
||||
}
|
||||
|
||||
.mega-octicon(@name, @size: 32px) {
|
||||
@import "octicon-utf-codes.less";
|
||||
&::before {
|
||||
.icon(@size);
|
||||
content: @@name
|
||||
|
Loading…
Reference in New Issue
Block a user