mirror of
https://github.com/atom/atom.git
synced 2026-01-24 14:28:14 -05:00
Merge branch 'master' of github.com:atom/atom into fb-pw-decaffeinate-config
This commit is contained in:
@@ -1,13 +1,12 @@
|
||||
/** @babel */
|
||||
|
||||
import TextBuffer, {Point, Range} from 'text-buffer'
|
||||
import {File, Directory} from 'pathwatcher'
|
||||
import {Emitter, Disposable, CompositeDisposable} from 'event-kit'
|
||||
import BufferedNodeProcess from '../src/buffered-node-process'
|
||||
import BufferedProcess from '../src/buffered-process'
|
||||
import GitRepository from '../src/git-repository'
|
||||
import Notification from '../src/notification'
|
||||
import {watchPath} from '../src/path-watcher'
|
||||
const TextBuffer = require('text-buffer')
|
||||
const {Point, Range} = TextBuffer
|
||||
const {File, Directory} = require('pathwatcher')
|
||||
const {Emitter, Disposable, CompositeDisposable} = require('event-kit')
|
||||
const BufferedNodeProcess = require('../src/buffered-node-process')
|
||||
const BufferedProcess = require('../src/buffered-process')
|
||||
const GitRepository = require('../src/git-repository')
|
||||
const Notification = require('../src/notification')
|
||||
const {watchPath} = require('../src/path-watcher')
|
||||
|
||||
const atomExport = {
|
||||
BufferedNodeProcess,
|
||||
@@ -42,4 +41,4 @@ if (process.type === 'renderer') {
|
||||
atomExport.TextEditor = require('../src/text-editor')
|
||||
}
|
||||
|
||||
export default atomExport
|
||||
module.exports = atomExport
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
"autosave": "0.24.6",
|
||||
"background-tips": "0.27.1",
|
||||
"bookmarks": "0.45.1",
|
||||
"bracket-matcher": "0.89.0",
|
||||
"bracket-matcher": "0.89.1",
|
||||
"command-palette": "0.43.0",
|
||||
"dalek": "0.2.1",
|
||||
"deprecation-cop": "0.56.9",
|
||||
|
||||
@@ -16,9 +16,6 @@ module.exports = function () {
|
||||
|
||||
function getPathsToTranspile () {
|
||||
let paths = []
|
||||
paths = paths.concat(glob.sync(path.join(CONFIG.intermediateAppPath, 'benchmarks', '**', '*.js'), {nodir: true}))
|
||||
paths = paths.concat(glob.sync(path.join(CONFIG.intermediateAppPath, 'exports', '**', '*.js'), {nodir: true}))
|
||||
paths = paths.concat(glob.sync(path.join(CONFIG.intermediateAppPath, 'src', '**', '*.js'), {nodir: true}))
|
||||
for (let packageName of Object.keys(CONFIG.appMetadata.packageDependencies)) {
|
||||
paths = paths.concat(glob.sync(
|
||||
path.join(CONFIG.intermediateAppPath, 'node_modules', packageName, '**', '*.js'),
|
||||
|
||||
@@ -4,7 +4,6 @@ const fs = require('fs')
|
||||
const path = require('path')
|
||||
const temp = require('temp').track()
|
||||
const AtomEnvironment = require('../src/atom-environment')
|
||||
const StorageFolder = require('../src/storage-folder')
|
||||
|
||||
describe('AtomEnvironment', () => {
|
||||
afterEach(() => {
|
||||
|
||||
@@ -49,7 +49,7 @@ describe('AtomApplication', function () {
|
||||
fs.writeFileSync(filePath, '1\n2\n3\n4\n')
|
||||
const atomApplication = buildAtomApplication()
|
||||
|
||||
const window = atomApplication.launch(parseCommandLine([filePath + ':3']))
|
||||
const [window] = await atomApplication.launch(parseCommandLine([filePath + ':3']))
|
||||
await focusWindow(window)
|
||||
|
||||
const cursorRow = await evalInWebContents(window.browserWindow.webContents, sendBackToMainProcess => {
|
||||
@@ -66,7 +66,7 @@ describe('AtomApplication', function () {
|
||||
fs.writeFileSync(filePath, '1\n2\n3\n4\n')
|
||||
const atomApplication = buildAtomApplication()
|
||||
|
||||
const window = atomApplication.launch(parseCommandLine([filePath + ':2:2']))
|
||||
const [window] = await atomApplication.launch(parseCommandLine([filePath + ':2:2']))
|
||||
await focusWindow(window)
|
||||
|
||||
const cursorPosition = await evalInWebContents(window.browserWindow.webContents, sendBackToMainProcess => {
|
||||
@@ -83,7 +83,7 @@ describe('AtomApplication', function () {
|
||||
fs.writeFileSync(filePath, '1\n2\n3\n4\n')
|
||||
const atomApplication = buildAtomApplication()
|
||||
|
||||
const window = atomApplication.launch(parseCommandLine([filePath + ':: ']))
|
||||
const [window] = await atomApplication.launch(parseCommandLine([filePath + ':: ']))
|
||||
await focusWindow(window)
|
||||
|
||||
const openedPath = await evalInWebContents(window.browserWindow.webContents, sendBackToMainProcess => {
|
||||
@@ -99,11 +99,11 @@ describe('AtomApplication', function () {
|
||||
it('positions new windows at an offset distance from the previous window', async () => {
|
||||
const atomApplication = buildAtomApplication()
|
||||
|
||||
const window1 = atomApplication.launch(parseCommandLine([makeTempDir()]))
|
||||
const [window1] = await atomApplication.launch(parseCommandLine([makeTempDir()]))
|
||||
await focusWindow(window1)
|
||||
window1.browserWindow.setBounds({width: 400, height: 400, x: 0, y: 0})
|
||||
|
||||
const window2 = atomApplication.launch(parseCommandLine([makeTempDir()]))
|
||||
const [window2] = await atomApplication.launch(parseCommandLine([makeTempDir()]))
|
||||
await focusWindow(window2)
|
||||
|
||||
assert.notEqual(window1, window2)
|
||||
@@ -122,7 +122,7 @@ describe('AtomApplication', function () {
|
||||
fs.writeFileSync(existingDirCFilePath, 'this is an existing file')
|
||||
|
||||
const atomApplication = buildAtomApplication()
|
||||
const window1 = atomApplication.launch(parseCommandLine([path.join(dirAPath, 'new-file')]))
|
||||
const [window1] = await atomApplication.launch(parseCommandLine([path.join(dirAPath, 'new-file')]))
|
||||
await emitterEventPromise(window1, 'window:locations-opened')
|
||||
await focusWindow(window1)
|
||||
|
||||
@@ -135,7 +135,7 @@ describe('AtomApplication', function () {
|
||||
|
||||
// Reuses the window when opening *files*, even if they're in a different directory
|
||||
// Does not change the project paths when doing so.
|
||||
const reusedWindow = atomApplication.launch(parseCommandLine([existingDirCFilePath]))
|
||||
const [reusedWindow] = await atomApplication.launch(parseCommandLine([existingDirCFilePath]))
|
||||
assert.equal(reusedWindow, window1)
|
||||
assert.deepEqual(atomApplication.getAllWindows(), [window1])
|
||||
activeEditorPath = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
|
||||
@@ -148,7 +148,7 @@ describe('AtomApplication', function () {
|
||||
assert.deepEqual(await getTreeViewRootDirectories(window1), [dirAPath])
|
||||
|
||||
// Opens new windows when opening directories
|
||||
const window2 = atomApplication.launch(parseCommandLine([dirCPath]))
|
||||
const [window2] = await atomApplication.launch(parseCommandLine([dirCPath]))
|
||||
await emitterEventPromise(window2, 'window:locations-opened')
|
||||
assert.notEqual(window2, window1)
|
||||
await focusWindow(window2)
|
||||
@@ -163,7 +163,7 @@ describe('AtomApplication', function () {
|
||||
fs.writeFileSync(existingDirCFilePath, 'this is an existing file')
|
||||
|
||||
const atomApplication = buildAtomApplication()
|
||||
const window1 = atomApplication.launch(parseCommandLine([path.join(dirAPath, 'new-file')]))
|
||||
const [window1] = await atomApplication.launch(parseCommandLine([path.join(dirAPath, 'new-file')]))
|
||||
await focusWindow(window1)
|
||||
|
||||
let activeEditorPath = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
|
||||
@@ -175,7 +175,7 @@ describe('AtomApplication', function () {
|
||||
|
||||
// When opening *files* with --add, reuses an existing window and adds
|
||||
// parent directory to the project
|
||||
let reusedWindow = atomApplication.launch(parseCommandLine([existingDirCFilePath, '--add']))
|
||||
let [reusedWindow] = await atomApplication.launch(parseCommandLine([existingDirCFilePath, '--add']))
|
||||
assert.equal(reusedWindow, window1)
|
||||
assert.deepEqual(atomApplication.getAllWindows(), [window1])
|
||||
activeEditorPath = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
|
||||
@@ -189,7 +189,7 @@ describe('AtomApplication', function () {
|
||||
|
||||
// When opening *directories* with add reuses an existing window and adds
|
||||
// the directory to the project
|
||||
reusedWindow = atomApplication.launch(parseCommandLine([dirBPath, '-a']))
|
||||
reusedWindow = (await atomApplication.launch(parseCommandLine([dirBPath, '-a'])))[0]
|
||||
assert.equal(reusedWindow, window1)
|
||||
assert.deepEqual(atomApplication.getAllWindows(), [window1])
|
||||
|
||||
@@ -202,7 +202,7 @@ describe('AtomApplication', function () {
|
||||
const atomApplication = buildAtomApplication()
|
||||
const nonExistentFilePath = path.join(tempDirPath, 'new-file')
|
||||
|
||||
const window1 = atomApplication.launch(parseCommandLine([nonExistentFilePath]))
|
||||
const [window1] = await atomApplication.launch(parseCommandLine([nonExistentFilePath]))
|
||||
await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
|
||||
atom.workspace.observeTextEditors(textEditor => {
|
||||
textEditor.insertText('Hello World!')
|
||||
@@ -214,7 +214,7 @@ describe('AtomApplication', function () {
|
||||
await window1.closedPromise
|
||||
|
||||
// Restore unsaved state when opening the directory itself
|
||||
const window2 = atomApplication.launch(parseCommandLine([tempDirPath]))
|
||||
const [window2] = await atomApplication.launch(parseCommandLine([tempDirPath]))
|
||||
await window2.loadedPromise
|
||||
const window2Text = await evalInWebContents(window2.browserWindow.webContents, sendBackToMainProcess => {
|
||||
const textEditor = atom.workspace.getActiveTextEditor()
|
||||
@@ -228,7 +228,7 @@ describe('AtomApplication', function () {
|
||||
await window2.closedPromise
|
||||
|
||||
// Restore unsaved state when opening a path to a non-existent file in the directory
|
||||
const window3 = atomApplication.launch(parseCommandLine([path.join(tempDirPath, 'another-non-existent-file')]))
|
||||
const [window3] = await atomApplication.launch(parseCommandLine([path.join(tempDirPath, 'another-non-existent-file')]))
|
||||
await window3.loadedPromise
|
||||
const window3Texts = await evalInWebContents(window3.browserWindow.webContents, (sendBackToMainProcess, nonExistentFilePath) => {
|
||||
sendBackToMainProcess(atom.workspace.getTextEditors().map(editor => editor.getText()))
|
||||
@@ -243,7 +243,7 @@ describe('AtomApplication', function () {
|
||||
fs.mkdirSync(dirBSubdirPath)
|
||||
|
||||
const atomApplication = buildAtomApplication()
|
||||
const window1 = atomApplication.launch(parseCommandLine([dirAPath, dirBPath]))
|
||||
const [window1] = await atomApplication.launch(parseCommandLine([dirAPath, dirBPath]))
|
||||
await focusWindow(window1)
|
||||
|
||||
assert.deepEqual(await getTreeViewRootDirectories(window1), [dirAPath, dirBPath])
|
||||
@@ -252,17 +252,17 @@ describe('AtomApplication', function () {
|
||||
it('reuses windows with no project paths to open directories', async () => {
|
||||
const tempDirPath = makeTempDir()
|
||||
const atomApplication = buildAtomApplication()
|
||||
const window1 = atomApplication.launch(parseCommandLine([]))
|
||||
const [window1] = await atomApplication.launch(parseCommandLine([]))
|
||||
await focusWindow(window1)
|
||||
|
||||
const reusedWindow = atomApplication.launch(parseCommandLine([tempDirPath]))
|
||||
const [reusedWindow] = await atomApplication.launch(parseCommandLine([tempDirPath]))
|
||||
assert.equal(reusedWindow, window1)
|
||||
await conditionPromise(async () => (await getTreeViewRootDirectories(reusedWindow)).length > 0)
|
||||
})
|
||||
|
||||
it('opens a new window with a single untitled buffer when launched with no path, even if windows already exist', async () => {
|
||||
const atomApplication = buildAtomApplication()
|
||||
const window1 = atomApplication.launch(parseCommandLine([]))
|
||||
const [window1] = await atomApplication.launch(parseCommandLine([]))
|
||||
await focusWindow(window1)
|
||||
const window1EditorTitle = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
|
||||
sendBackToMainProcess(atom.workspace.getActiveTextEditor().getTitle())
|
||||
@@ -287,7 +287,7 @@ describe('AtomApplication', function () {
|
||||
season.writeFileSync(configPath, config)
|
||||
|
||||
const atomApplication = buildAtomApplication()
|
||||
const window1 = atomApplication.launch(parseCommandLine([]))
|
||||
const [window1] = await atomApplication.launch(parseCommandLine([]))
|
||||
await focusWindow(window1)
|
||||
|
||||
// wait a bit just to make sure we don't pass due to querying the render process before it loads
|
||||
@@ -302,7 +302,7 @@ describe('AtomApplication', function () {
|
||||
it('opens an empty text editor and loads its parent directory in the tree-view when launched with a new file path', async () => {
|
||||
const atomApplication = buildAtomApplication()
|
||||
const newFilePath = path.join(makeTempDir(), 'new-file')
|
||||
const window = atomApplication.launch(parseCommandLine([newFilePath]))
|
||||
const [window] = await atomApplication.launch(parseCommandLine([newFilePath]))
|
||||
await focusWindow(window)
|
||||
const {editorTitle, editorText} = await evalInWebContents(window.browserWindow.webContents, sendBackToMainProcess => {
|
||||
atom.workspace.observeTextEditors(editor => {
|
||||
@@ -324,7 +324,7 @@ describe('AtomApplication', function () {
|
||||
atomApplication.config.set('core.disabledPackages', ['fuzzy-finder'])
|
||||
|
||||
const remotePath = 'remote://server:3437/some/directory/path'
|
||||
let window = atomApplication.launch(parseCommandLine([remotePath]))
|
||||
let [window] = await atomApplication.launch(parseCommandLine([remotePath]))
|
||||
|
||||
await focusWindow(window)
|
||||
await conditionPromise(async () => (await getProjectDirectories()).length > 0)
|
||||
@@ -350,9 +350,9 @@ describe('AtomApplication', function () {
|
||||
const tempDirPath2 = makeTempDir()
|
||||
|
||||
const atomApplication1 = buildAtomApplication()
|
||||
const app1Window1 = atomApplication1.launch(parseCommandLine([tempDirPath1]))
|
||||
const [app1Window1] = await atomApplication1.launch(parseCommandLine([tempDirPath1]))
|
||||
await emitterEventPromise(app1Window1, 'window:locations-opened')
|
||||
const app1Window2 = atomApplication1.launch(parseCommandLine([tempDirPath2]))
|
||||
const [app1Window2] = await atomApplication1.launch(parseCommandLine([tempDirPath2]))
|
||||
await emitterEventPromise(app1Window2, 'window:locations-opened')
|
||||
|
||||
await Promise.all([
|
||||
@@ -361,7 +361,7 @@ describe('AtomApplication', function () {
|
||||
])
|
||||
|
||||
const atomApplication2 = buildAtomApplication()
|
||||
const [app2Window1, app2Window2] = atomApplication2.launch(parseCommandLine([]))
|
||||
const [app2Window1, app2Window2] = await atomApplication2.launch(parseCommandLine([]))
|
||||
await Promise.all([
|
||||
emitterEventPromise(app2Window1, 'window:locations-opened'),
|
||||
emitterEventPromise(app2Window2, 'window:locations-opened')
|
||||
@@ -373,9 +373,9 @@ describe('AtomApplication', function () {
|
||||
|
||||
it('does not reopen any previously opened windows when launched with no path and `core.restorePreviousWindowsOnStart` is no', async () => {
|
||||
const atomApplication1 = buildAtomApplication()
|
||||
const app1Window1 = atomApplication1.launch(parseCommandLine([makeTempDir()]))
|
||||
const [app1Window1] = await atomApplication1.launch(parseCommandLine([makeTempDir()]))
|
||||
await focusWindow(app1Window1)
|
||||
const app1Window2 = atomApplication1.launch(parseCommandLine([makeTempDir()]))
|
||||
const [app1Window2] = await atomApplication1.launch(parseCommandLine([makeTempDir()]))
|
||||
await focusWindow(app1Window2)
|
||||
|
||||
const configPath = path.join(process.env.ATOM_HOME, 'config.cson')
|
||||
@@ -385,7 +385,7 @@ describe('AtomApplication', function () {
|
||||
season.writeFileSync(configPath, config)
|
||||
|
||||
const atomApplication2 = buildAtomApplication()
|
||||
const app2Window = atomApplication2.launch(parseCommandLine([]))
|
||||
const [app2Window] = await atomApplication2.launch(parseCommandLine([]))
|
||||
await focusWindow(app2Window)
|
||||
assert.deepEqual(app2Window.representedDirectoryPaths, [])
|
||||
})
|
||||
@@ -405,10 +405,10 @@ describe('AtomApplication', function () {
|
||||
})
|
||||
|
||||
it('kills the specified pid after a newly-opened window is closed', async () => {
|
||||
const window1 = atomApplication.launch(parseCommandLine(['--wait', '--pid', '101']))
|
||||
const [window1] = await atomApplication.launch(parseCommandLine(['--wait', '--pid', '101']))
|
||||
await focusWindow(window1)
|
||||
|
||||
const [window2] = atomApplication.launch(parseCommandLine(['--new-window', '--wait', '--pid', '102']))
|
||||
const [window2] = await atomApplication.launch(parseCommandLine(['--new-window', '--wait', '--pid', '102']))
|
||||
await focusWindow(window2)
|
||||
assert.deepEqual(killedPids, [])
|
||||
|
||||
@@ -424,7 +424,7 @@ describe('AtomApplication', function () {
|
||||
})
|
||||
|
||||
it('kills the specified pid after a newly-opened file in an existing window is closed', async () => {
|
||||
const window = atomApplication.launch(parseCommandLine(['--wait', '--pid', '101']))
|
||||
const [window] = await atomApplication.launch(parseCommandLine(['--wait', '--pid', '101']))
|
||||
await focusWindow(window)
|
||||
|
||||
const filePath1 = temp.openSync('test').path
|
||||
@@ -432,7 +432,7 @@ describe('AtomApplication', function () {
|
||||
fs.writeFileSync(filePath1, 'File 1')
|
||||
fs.writeFileSync(filePath2, 'File 2')
|
||||
|
||||
const reusedWindow = atomApplication.launch(parseCommandLine(['--wait', '--pid', '102', filePath1, filePath2]))
|
||||
const [reusedWindow] = await atomApplication.launch(parseCommandLine(['--wait', '--pid', '102', filePath1, filePath2]))
|
||||
assert.equal(reusedWindow, window)
|
||||
|
||||
const activeEditorPath = await evalInWebContents(window.browserWindow.webContents, send => {
|
||||
@@ -467,11 +467,11 @@ describe('AtomApplication', function () {
|
||||
})
|
||||
|
||||
it('kills the specified pid after a newly-opened directory in an existing window is closed', async () => {
|
||||
const window = atomApplication.launch(parseCommandLine([]))
|
||||
const [window] = await atomApplication.launch(parseCommandLine([]))
|
||||
await focusWindow(window)
|
||||
|
||||
const dirPath1 = makeTempDir()
|
||||
const reusedWindow = atomApplication.launch(parseCommandLine(['--wait', '--pid', '101', dirPath1]))
|
||||
const [reusedWindow] = await atomApplication.launch(parseCommandLine(['--wait', '--pid', '101', dirPath1]))
|
||||
assert.equal(reusedWindow, window)
|
||||
assert.deepEqual(await getTreeViewRootDirectories(window), [dirPath1])
|
||||
assert.deepEqual(killedPids, [])
|
||||
@@ -498,7 +498,7 @@ describe('AtomApplication', function () {
|
||||
if (process.platform === 'linux' || process.platform === 'win32') {
|
||||
it('quits the application', async () => {
|
||||
const atomApplication = buildAtomApplication()
|
||||
const window = atomApplication.launch(parseCommandLine([path.join(makeTempDir("a"), 'file-a')]))
|
||||
const [window] = await atomApplication.launch(parseCommandLine([path.join(makeTempDir("a"), 'file-a')]))
|
||||
await focusWindow(window)
|
||||
window.close()
|
||||
await window.closedPromise
|
||||
@@ -508,7 +508,7 @@ describe('AtomApplication', function () {
|
||||
} else if (process.platform === 'darwin') {
|
||||
it('leaves the application open', async () => {
|
||||
const atomApplication = buildAtomApplication()
|
||||
const window = atomApplication.launch(parseCommandLine([path.join(makeTempDir("a"), 'file-a')]))
|
||||
const [window] = await atomApplication.launch(parseCommandLine([path.join(makeTempDir("a"), 'file-a')]))
|
||||
await focusWindow(window)
|
||||
window.close()
|
||||
await window.closedPromise
|
||||
@@ -524,7 +524,7 @@ describe('AtomApplication', function () {
|
||||
const dirB = makeTempDir()
|
||||
|
||||
const atomApplication = buildAtomApplication()
|
||||
const window = atomApplication.launch(parseCommandLine([dirA, dirB]))
|
||||
const [window] = await atomApplication.launch(parseCommandLine([dirA, dirB]))
|
||||
await emitterEventPromise(window, 'window:locations-opened')
|
||||
await focusWindow(window)
|
||||
assert.deepEqual(await getTreeViewRootDirectories(window), [dirA, dirB])
|
||||
@@ -539,7 +539,7 @@ describe('AtomApplication', function () {
|
||||
|
||||
// Window state should be saved when the project folder is removed
|
||||
const atomApplication2 = buildAtomApplication()
|
||||
const [window2] = atomApplication2.launch(parseCommandLine([]))
|
||||
const [window2] = await atomApplication2.launch(parseCommandLine([]))
|
||||
await emitterEventPromise(window2, 'window:locations-opened')
|
||||
await focusWindow(window2)
|
||||
assert.deepEqual(await getTreeViewRootDirectories(window2), [dirB])
|
||||
@@ -556,7 +556,7 @@ describe('AtomApplication', function () {
|
||||
const atomApplication = buildAtomApplication()
|
||||
const launchOptions = parseCommandLine([])
|
||||
launchOptions.urlsToOpen = ['atom://package-with-url-main/test']
|
||||
let windows = atomApplication.launch(launchOptions)
|
||||
let [windows] = await atomApplication.launch(launchOptions)
|
||||
await windows[0].loadedPromise
|
||||
|
||||
let reached = await evalInWebContents(windows[0].browserWindow.webContents, sendBackToMainProcess => {
|
||||
@@ -571,9 +571,9 @@ describe('AtomApplication', function () {
|
||||
const dirBPath = makeTempDir('b')
|
||||
|
||||
const atomApplication = buildAtomApplication()
|
||||
const window1 = atomApplication.launch(parseCommandLine([path.join(dirAPath)]))
|
||||
const [window1] = await atomApplication.launch(parseCommandLine([path.join(dirAPath)]))
|
||||
await focusWindow(window1)
|
||||
const window2 = atomApplication.launch(parseCommandLine([path.join(dirBPath)]))
|
||||
const [window2] = await atomApplication.launch(parseCommandLine([path.join(dirBPath)]))
|
||||
await focusWindow(window2)
|
||||
|
||||
const fileA = path.join(dirAPath, 'file-a')
|
||||
@@ -597,9 +597,9 @@ describe('AtomApplication', function () {
|
||||
const dirAPath = makeTempDir("a")
|
||||
const dirBPath = makeTempDir("b")
|
||||
const atomApplication = buildAtomApplication()
|
||||
const window1 = atomApplication.launch(parseCommandLine([path.join(dirAPath, 'file-a')]))
|
||||
const [window1] = await atomApplication.launch(parseCommandLine([path.join(dirAPath, 'file-a')]))
|
||||
await focusWindow(window1)
|
||||
const window2 = atomApplication.launch(parseCommandLine([path.join(dirBPath, 'file-b')]))
|
||||
const [window2] = await atomApplication.launch(parseCommandLine([path.join(dirBPath, 'file-b')]))
|
||||
await focusWindow(window2)
|
||||
electron.app.quit()
|
||||
await new Promise(process.nextTick)
|
||||
@@ -612,8 +612,8 @@ describe('AtomApplication', function () {
|
||||
|
||||
it('prevents quitting if user cancels when prompted to save an item', async () => {
|
||||
const atomApplication = buildAtomApplication()
|
||||
const window1 = atomApplication.launch(parseCommandLine([]))
|
||||
const window2 = atomApplication.launch(parseCommandLine([]))
|
||||
const [window1] = await atomApplication.launch(parseCommandLine([]))
|
||||
const [window2] = await atomApplication.launch(parseCommandLine([]))
|
||||
await Promise.all([window1.loadedPromise, window2.loadedPromise])
|
||||
await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
|
||||
atom.workspace.getActiveTextEditor().insertText('unsaved text')
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
/** @babel */
|
||||
|
||||
import {dialog} from 'electron'
|
||||
import FileRecoveryService from '../../src/main-process/file-recovery-service'
|
||||
import fs from 'fs-plus'
|
||||
import sinon from 'sinon'
|
||||
import {escapeRegExp} from 'underscore-plus'
|
||||
const {dialog} = require('electron')
|
||||
const FileRecoveryService = require('../../src/main-process/file-recovery-service')
|
||||
const fs = require('fs-plus')
|
||||
const sinon = require('sinon')
|
||||
const {escapeRegExp} = require('underscore-plus')
|
||||
const temp = require('temp').track()
|
||||
|
||||
describe("FileRecoveryService", () => {
|
||||
let recoveryService, recoveryDirectory
|
||||
let recoveryService, recoveryDirectory, spies
|
||||
|
||||
beforeEach(() => {
|
||||
recoveryDirectory = temp.mkdirSync('atom-spec-file-recovery')
|
||||
recoveryService = new FileRecoveryService(recoveryDirectory)
|
||||
spies = sinon.sandbox.create()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
spies.restore()
|
||||
try {
|
||||
temp.cleanupSync()
|
||||
} catch (e) {
|
||||
@@ -24,38 +24,38 @@ describe("FileRecoveryService", () => {
|
||||
})
|
||||
|
||||
describe("when no crash happens during a save", () => {
|
||||
it("creates a recovery file and deletes it after saving", () => {
|
||||
it("creates a recovery file and deletes it after saving", async () => {
|
||||
const mockWindow = {}
|
||||
const filePath = temp.path()
|
||||
|
||||
fs.writeFileSync(filePath, "some content")
|
||||
recoveryService.willSavePath(mockWindow, filePath)
|
||||
await recoveryService.willSavePath(mockWindow, filePath)
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 1)
|
||||
|
||||
fs.writeFileSync(filePath, "changed")
|
||||
recoveryService.didSavePath(mockWindow, filePath)
|
||||
await recoveryService.didSavePath(mockWindow, filePath)
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 0)
|
||||
assert.equal(fs.readFileSync(filePath, 'utf8'), "changed")
|
||||
|
||||
fs.removeSync(filePath)
|
||||
})
|
||||
|
||||
it("creates only one recovery file when many windows attempt to save the same file, deleting it when the last one finishes saving it", () => {
|
||||
it("creates only one recovery file when many windows attempt to save the same file, deleting it when the last one finishes saving it", async () => {
|
||||
const mockWindow = {}
|
||||
const anotherMockWindow = {}
|
||||
const filePath = temp.path()
|
||||
|
||||
fs.writeFileSync(filePath, "some content")
|
||||
recoveryService.willSavePath(mockWindow, filePath)
|
||||
recoveryService.willSavePath(anotherMockWindow, filePath)
|
||||
await recoveryService.willSavePath(mockWindow, filePath)
|
||||
await recoveryService.willSavePath(anotherMockWindow, filePath)
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 1)
|
||||
|
||||
fs.writeFileSync(filePath, "changed")
|
||||
recoveryService.didSavePath(mockWindow, filePath)
|
||||
await recoveryService.didSavePath(mockWindow, filePath)
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 1)
|
||||
assert.equal(fs.readFileSync(filePath, 'utf8'), "changed")
|
||||
|
||||
recoveryService.didSavePath(anotherMockWindow, filePath)
|
||||
await recoveryService.didSavePath(anotherMockWindow, filePath)
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 0)
|
||||
assert.equal(fs.readFileSync(filePath, 'utf8'), "changed")
|
||||
|
||||
@@ -64,66 +64,66 @@ describe("FileRecoveryService", () => {
|
||||
})
|
||||
|
||||
describe("when a crash happens during a save", () => {
|
||||
it("restores the created recovery file and deletes it", () => {
|
||||
it("restores the created recovery file and deletes it", async () => {
|
||||
const mockWindow = {}
|
||||
const filePath = temp.path()
|
||||
|
||||
fs.writeFileSync(filePath, "some content")
|
||||
recoveryService.willSavePath(mockWindow, filePath)
|
||||
await recoveryService.willSavePath(mockWindow, filePath)
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 1)
|
||||
|
||||
fs.writeFileSync(filePath, "changed")
|
||||
recoveryService.didCrashWindow(mockWindow)
|
||||
await recoveryService.didCrashWindow(mockWindow)
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 0)
|
||||
assert.equal(fs.readFileSync(filePath, 'utf8'), "some content")
|
||||
|
||||
fs.removeSync(filePath)
|
||||
})
|
||||
|
||||
it("restores the created recovery file when many windows attempt to save the same file and one of them crashes", () => {
|
||||
it("restores the created recovery file when many windows attempt to save the same file and one of them crashes", async () => {
|
||||
const mockWindow = {}
|
||||
const anotherMockWindow = {}
|
||||
const filePath = temp.path()
|
||||
|
||||
fs.writeFileSync(filePath, "A")
|
||||
recoveryService.willSavePath(mockWindow, filePath)
|
||||
await recoveryService.willSavePath(mockWindow, filePath)
|
||||
fs.writeFileSync(filePath, "B")
|
||||
recoveryService.willSavePath(anotherMockWindow, filePath)
|
||||
await recoveryService.willSavePath(anotherMockWindow, filePath)
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 1)
|
||||
|
||||
fs.writeFileSync(filePath, "C")
|
||||
|
||||
recoveryService.didCrashWindow(mockWindow)
|
||||
await recoveryService.didCrashWindow(mockWindow)
|
||||
assert.equal(fs.readFileSync(filePath, 'utf8'), "A")
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 0)
|
||||
|
||||
fs.writeFileSync(filePath, "D")
|
||||
recoveryService.willSavePath(mockWindow, filePath)
|
||||
await recoveryService.willSavePath(mockWindow, filePath)
|
||||
fs.writeFileSync(filePath, "E")
|
||||
recoveryService.willSavePath(anotherMockWindow, filePath)
|
||||
await recoveryService.willSavePath(anotherMockWindow, filePath)
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 1)
|
||||
|
||||
fs.writeFileSync(filePath, "F")
|
||||
|
||||
recoveryService.didCrashWindow(anotherMockWindow)
|
||||
await recoveryService.didCrashWindow(anotherMockWindow)
|
||||
assert.equal(fs.readFileSync(filePath, 'utf8'), "D")
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 0)
|
||||
|
||||
fs.removeSync(filePath)
|
||||
})
|
||||
|
||||
it("emits a warning when a file can't be recovered", sinon.test(function () {
|
||||
it("emits a warning when a file can't be recovered", async () => {
|
||||
const mockWindow = {}
|
||||
const filePath = temp.path()
|
||||
fs.writeFileSync(filePath, "content")
|
||||
fs.chmodSync(filePath, 0444)
|
||||
|
||||
let logs = []
|
||||
this.stub(console, 'log', (message) => logs.push(message))
|
||||
this.stub(dialog, 'showMessageBox')
|
||||
spies.stub(console, 'log', (message) => logs.push(message))
|
||||
spies.stub(dialog, 'showMessageBox')
|
||||
|
||||
recoveryService.willSavePath(mockWindow, filePath)
|
||||
recoveryService.didCrashWindow(mockWindow)
|
||||
await recoveryService.willSavePath(mockWindow, filePath)
|
||||
await recoveryService.didCrashWindow(mockWindow)
|
||||
let recoveryFiles = fs.listTreeSync(recoveryDirectory)
|
||||
assert.equal(recoveryFiles.length, 1)
|
||||
assert.equal(logs.length, 1)
|
||||
@@ -131,16 +131,16 @@ describe("FileRecoveryService", () => {
|
||||
assert.match(logs[0], new RegExp(escapeRegExp(recoveryFiles[0])))
|
||||
|
||||
fs.removeSync(filePath)
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
it("doesn't create a recovery file when the file that's being saved doesn't exist yet", () => {
|
||||
it("doesn't create a recovery file when the file that's being saved doesn't exist yet", async () => {
|
||||
const mockWindow = {}
|
||||
|
||||
recoveryService.willSavePath(mockWindow, "a-file-that-doesnt-exist")
|
||||
await recoveryService.willSavePath(mockWindow, "a-file-that-doesnt-exist")
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 0)
|
||||
|
||||
recoveryService.didSavePath(mockWindow, "a-file-that-doesnt-exist")
|
||||
await recoveryService.didSavePath(mockWindow, "a-file-that-doesnt-exist")
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 0)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -104,7 +104,7 @@ describe('TextEditorComponent', () => {
|
||||
|
||||
{
|
||||
expect(editor.getApproximateLongestScreenRow()).toBe(3)
|
||||
const expectedWidth = Math.round(
|
||||
const expectedWidth = Math.ceil(
|
||||
component.pixelPositionForScreenPosition(Point(3, Infinity)).left +
|
||||
component.getBaseCharacterWidth()
|
||||
)
|
||||
@@ -121,7 +121,7 @@ describe('TextEditorComponent', () => {
|
||||
// Capture the width of the lines before requesting the width of
|
||||
// longest line, because making that request forces a DOM update
|
||||
const actualWidth = element.querySelector('.lines').style.width
|
||||
const expectedWidth = Math.round(
|
||||
const expectedWidth = Math.ceil(
|
||||
component.pixelPositionForScreenPosition(Point(6, Infinity)).left +
|
||||
component.getBaseCharacterWidth()
|
||||
)
|
||||
@@ -3980,7 +3980,7 @@ describe('TextEditorComponent', () => {
|
||||
// Capture the width of the lines before requesting the width of
|
||||
// longest line, because making that request forces a DOM update
|
||||
const actualWidth = element.querySelector('.lines').style.width
|
||||
const expectedWidth = Math.round(
|
||||
const expectedWidth = Math.ceil(
|
||||
component.pixelPositionForScreenPosition(Point(3, Infinity)).left +
|
||||
component.getBaseCharacterWidth()
|
||||
)
|
||||
|
||||
@@ -354,11 +354,11 @@ class ApplicationDelegate {
|
||||
}
|
||||
|
||||
emitWillSavePath (path) {
|
||||
return ipcRenderer.sendSync('will-save-path', path)
|
||||
return ipcHelpers.call('will-save-path', path)
|
||||
}
|
||||
|
||||
emitDidSavePath (path) {
|
||||
return ipcRenderer.sendSync('did-save-path', path)
|
||||
return ipcHelpers.call('did-save-path', path)
|
||||
}
|
||||
|
||||
resolveProxy (requestId, url) {
|
||||
|
||||
@@ -9,7 +9,6 @@ const fs = require('fs-plus')
|
||||
const {mapSourcePosition} = require('@atom/source-map-support')
|
||||
const WindowEventHandler = require('./window-event-handler')
|
||||
const StateStore = require('./state-store')
|
||||
const StorageFolder = require('./storage-folder')
|
||||
const registerDefaultCommands = require('./register-default-commands')
|
||||
const {updateProcessEnv} = require('./update-process-env')
|
||||
const ConfigSchema = require('./config-schema')
|
||||
@@ -208,12 +207,7 @@ class AtomEnvironment {
|
||||
this.blobStore = params.blobStore
|
||||
this.configDirPath = params.configDirPath
|
||||
|
||||
const {devMode, safeMode, resourcePath, clearWindowState} = this.getLoadSettings()
|
||||
|
||||
if (clearWindowState) {
|
||||
this.getStorageFolder().clear()
|
||||
this.stateStore.clear()
|
||||
}
|
||||
const {devMode, safeMode, resourcePath} = this.getLoadSettings()
|
||||
|
||||
ConfigSchema.projectHome = {
|
||||
type: 'string',
|
||||
@@ -764,7 +758,11 @@ class AtomEnvironment {
|
||||
}
|
||||
|
||||
// Call this method when establishing a real application window.
|
||||
startEditorWindow () {
|
||||
async startEditorWindow () {
|
||||
if (this.getLoadSettings().clearWindowState) {
|
||||
await this.stateStore.clear()
|
||||
}
|
||||
|
||||
this.unloaded = false
|
||||
|
||||
const updateProcessEnvPromise = this.updateProcessEnvAndTriggerHooks()
|
||||
@@ -1264,11 +1262,6 @@ or use Pane::saveItemAs for programmatic saving.`)
|
||||
}
|
||||
}
|
||||
|
||||
getStorageFolder () {
|
||||
if (!this.storageFolder) this.storageFolder = new StorageFolder(this.getConfigDirPath())
|
||||
return this.storageFolder
|
||||
}
|
||||
|
||||
getConfigDirPath () {
|
||||
if (!this.configDirPath) this.configDirPath = process.env.ATOM_HOME
|
||||
return this.configDirPath
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/** @babel */
|
||||
|
||||
const fs = require('fs-plus')
|
||||
const path = require('path')
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
'use babel'
|
||||
const {Emitter, CompositeDisposable} = require('event-kit')
|
||||
|
||||
import {Emitter, CompositeDisposable} from 'event-kit'
|
||||
|
||||
export default class AutoUpdateManager {
|
||||
module.exports =
|
||||
class AutoUpdateManager {
|
||||
constructor ({applicationDelegate}) {
|
||||
this.applicationDelegate = applicationDelegate
|
||||
this.subscriptions = new CompositeDisposable()
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
/** @babel */
|
||||
|
||||
import BufferedProcess from './buffered-process'
|
||||
const BufferedProcess = require('./buffered-process')
|
||||
|
||||
// Extended: Like {BufferedProcess}, but accepts a Node script as the command
|
||||
// to run.
|
||||
@@ -12,7 +10,8 @@ import BufferedProcess from './buffered-process'
|
||||
// ```js
|
||||
// const {BufferedNodeProcess} = require('atom')
|
||||
// ```
|
||||
export default class BufferedNodeProcess extends BufferedProcess {
|
||||
module.exports =
|
||||
class BufferedNodeProcess extends BufferedProcess {
|
||||
|
||||
// Public: Runs the given Node script by spawning a new child process.
|
||||
//
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
/** @babel */
|
||||
|
||||
import _ from 'underscore-plus'
|
||||
import ChildProcess from 'child_process'
|
||||
import {Emitter} from 'event-kit'
|
||||
import path from 'path'
|
||||
const _ = require('underscore-plus')
|
||||
const ChildProcess = require('child_process')
|
||||
const {Emitter} = require('event-kit')
|
||||
const path = require('path')
|
||||
|
||||
// Extended: A wrapper which provides standard error/output line buffering for
|
||||
// Node's ChildProcess.
|
||||
@@ -19,7 +17,8 @@ import path from 'path'
|
||||
// const exit = (code) => console.log("ps -ef exited with #{code}")
|
||||
// const process = new BufferedProcess({command, args, stdout, exit})
|
||||
// ```
|
||||
export default class BufferedProcess {
|
||||
module.exports =
|
||||
class BufferedProcess {
|
||||
/*
|
||||
Section: Construction
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/** @babel */
|
||||
|
||||
import crypto from 'crypto'
|
||||
import clipboard from './safe-clipboard'
|
||||
const crypto = require('crypto')
|
||||
const clipboard = require('./safe-clipboard')
|
||||
|
||||
// Extended: Represents the clipboard used for copying and pasting in Atom.
|
||||
//
|
||||
@@ -14,7 +12,8 @@ import clipboard from './safe-clipboard'
|
||||
//
|
||||
// console.log(atom.clipboard.read()) # 'hello'
|
||||
// ```
|
||||
export default class Clipboard {
|
||||
module.exports =
|
||||
class Clipboard {
|
||||
constructor () {
|
||||
this.reset()
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/** @babel */
|
||||
|
||||
let ParsedColor = null
|
||||
|
||||
// Essential: A simple color class returned from {Config::get} when the value
|
||||
// at the key path is of type 'color'.
|
||||
export default class Color {
|
||||
module.exports =
|
||||
class Color {
|
||||
// Essential: Parse a {String} or {Object} into a {Color}.
|
||||
//
|
||||
// * `value` A {String} such as `'white'`, `#ff00ff`, or
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
/** @babel */
|
||||
|
||||
import {Disposable} from 'event-kit'
|
||||
const {Disposable} = require('event-kit')
|
||||
|
||||
// Extended: Manages the deserializers used for serialized state
|
||||
//
|
||||
@@ -21,7 +19,8 @@ import {Disposable} from 'event-kit'
|
||||
// serialize: ->
|
||||
// @state
|
||||
// ```
|
||||
export default class DeserializerManager {
|
||||
module.exports =
|
||||
class DeserializerManager {
|
||||
constructor (atomEnvironment) {
|
||||
this.atomEnvironment = atomEnvironment
|
||||
this.deserializers = {}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/** @babel */
|
||||
|
||||
import {Emitter, CompositeDisposable} from 'event-kit'
|
||||
const {Emitter, CompositeDisposable} = require('event-kit')
|
||||
|
||||
// Extended: History manager for remembering which projects have been opened.
|
||||
//
|
||||
// An instance of this class is always available as the `atom.history` global.
|
||||
//
|
||||
// The project history is used to enable the 'Reopen Project' menu.
|
||||
export class HistoryManager {
|
||||
class HistoryManager {
|
||||
constructor ({project, commands, stateStore}) {
|
||||
this.stateStore = stateStore
|
||||
this.emitter = new Emitter()
|
||||
@@ -116,7 +114,7 @@ function arrayEquivalent (a, b) {
|
||||
return true
|
||||
}
|
||||
|
||||
export class HistoryProject {
|
||||
class HistoryProject {
|
||||
constructor (paths, lastOpened) {
|
||||
this.paths = paths
|
||||
this.lastOpened = lastOpened || new Date()
|
||||
@@ -128,3 +126,5 @@ export class HistoryProject {
|
||||
set lastOpened (lastOpened) { this._lastOpened = lastOpened }
|
||||
get lastOpened () { return this._lastOpened }
|
||||
}
|
||||
|
||||
module.exports = {HistoryManager, HistoryProject}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/** @babel */
|
||||
const {remote} = require('electron')
|
||||
const path = require('path')
|
||||
const ipcHelpers = require('./ipc-helpers')
|
||||
const util = require('util')
|
||||
|
||||
import {remote} from 'electron'
|
||||
import path from 'path'
|
||||
import ipcHelpers from './ipc-helpers'
|
||||
import util from 'util'
|
||||
|
||||
export default async function () {
|
||||
module.exports = async function () {
|
||||
const getWindowLoadSettings = require('./get-window-load-settings')
|
||||
const {test, headless, resourcePath, benchmarkPaths} = getWindowLoadSettings()
|
||||
try {
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
'use strict'
|
||||
|
||||
const Disposable = require('event-kit').Disposable
|
||||
let ipcRenderer = null
|
||||
let ipcMain = null
|
||||
let BrowserWindow = null
|
||||
|
||||
let nextResponseChannelId = 0
|
||||
|
||||
exports.on = function (emitter, eventName, callback) {
|
||||
emitter.on(eventName, callback)
|
||||
return new Disposable(function () {
|
||||
emitter.removeListener(eventName, callback)
|
||||
})
|
||||
return new Disposable(() => emitter.removeListener(eventName, callback))
|
||||
}
|
||||
|
||||
exports.call = function (channel, ...args) {
|
||||
@@ -18,34 +16,28 @@ exports.call = function (channel, ...args) {
|
||||
ipcRenderer.setMaxListeners(20)
|
||||
}
|
||||
|
||||
var responseChannel = getResponseChannel(channel)
|
||||
const responseChannel = `ipc-helpers-response-${nextResponseChannelId++}`
|
||||
|
||||
return new Promise(function (resolve) {
|
||||
ipcRenderer.on(responseChannel, function (event, result) {
|
||||
return new Promise(resolve => {
|
||||
ipcRenderer.on(responseChannel, (event, result) => {
|
||||
ipcRenderer.removeAllListeners(responseChannel)
|
||||
resolve(result)
|
||||
})
|
||||
|
||||
ipcRenderer.send(channel, ...args)
|
||||
ipcRenderer.send(channel, responseChannel, ...args)
|
||||
})
|
||||
}
|
||||
|
||||
exports.respondTo = function (channel, callback) {
|
||||
if (!ipcMain) {
|
||||
var electron = require('electron')
|
||||
const electron = require('electron')
|
||||
ipcMain = electron.ipcMain
|
||||
BrowserWindow = electron.BrowserWindow
|
||||
}
|
||||
|
||||
var responseChannel = getResponseChannel(channel)
|
||||
|
||||
return exports.on(ipcMain, channel, function (event, ...args) {
|
||||
var browserWindow = BrowserWindow.fromWebContents(event.sender)
|
||||
var result = callback(browserWindow, ...args)
|
||||
return exports.on(ipcMain, channel, async (event, responseChannel, ...args) => {
|
||||
const browserWindow = BrowserWindow.fromWebContents(event.sender)
|
||||
const result = await callback(browserWindow, ...args)
|
||||
event.sender.send(responseChannel, result)
|
||||
})
|
||||
}
|
||||
|
||||
function getResponseChannel (channel) {
|
||||
return 'ipc-helpers-' + channel + '-response'
|
||||
}
|
||||
|
||||
@@ -169,18 +169,32 @@ class AtomApplication extends EventEmitter {
|
||||
this.disposable.dispose()
|
||||
}
|
||||
|
||||
launch (options) {
|
||||
async launch (options) {
|
||||
const optionsForWindowsToOpen = []
|
||||
|
||||
let shouldReopenPreviousWindows = false
|
||||
|
||||
if (options.test || options.benchmark || options.benchmarkTest) {
|
||||
return this.openWithOptions(options)
|
||||
optionsForWindowsToOpen.push(options)
|
||||
} else if ((options.pathsToOpen && options.pathsToOpen.length > 0) ||
|
||||
(options.urlsToOpen && options.urlsToOpen.length > 0)) {
|
||||
if (this.config.get('core.restorePreviousWindowsOnStart') === 'always') {
|
||||
this.loadState(_.deepClone(options))
|
||||
}
|
||||
return this.openWithOptions(options)
|
||||
optionsForWindowsToOpen.push(options)
|
||||
shouldReopenPreviousWindows = this.config.get('core.restorePreviousWindowsOnStart') === 'always'
|
||||
} else {
|
||||
return this.loadState(options) || this.openPath(options)
|
||||
shouldReopenPreviousWindows = this.config.get('core.restorePreviousWindowsOnStart') !== 'no'
|
||||
}
|
||||
|
||||
if (shouldReopenPreviousWindows) {
|
||||
for (const previousOptions of await this.loadPreviousWindowOptions()) {
|
||||
optionsForWindowsToOpen.push(Object.assign({}, options, previousOptions))
|
||||
}
|
||||
}
|
||||
|
||||
if (optionsForWindowsToOpen.length === 0) {
|
||||
optionsForWindowsToOpen.push(options)
|
||||
}
|
||||
|
||||
return optionsForWindowsToOpen.map(options => this.openWithOptions(options))
|
||||
}
|
||||
|
||||
openWithOptions (options) {
|
||||
@@ -271,7 +285,7 @@ class AtomApplication extends EventEmitter {
|
||||
return
|
||||
}
|
||||
}
|
||||
if (!window.isSpec) this.saveState(true)
|
||||
if (!window.isSpec) this.saveCurrentWindowOptions(true)
|
||||
}
|
||||
|
||||
// Public: Adds the {AtomWindow} to the global window list.
|
||||
@@ -285,7 +299,7 @@ class AtomApplication extends EventEmitter {
|
||||
|
||||
if (!window.isSpec) {
|
||||
const focusHandler = () => this.windowStack.touch(window)
|
||||
const blurHandler = () => this.saveState(false)
|
||||
const blurHandler = () => this.saveCurrentWindowOptions(false)
|
||||
window.browserWindow.on('focus', focusHandler)
|
||||
window.browserWindow.on('blur', blurHandler)
|
||||
window.browserWindow.once('closed', () => {
|
||||
@@ -569,18 +583,16 @@ class AtomApplication extends EventEmitter {
|
||||
event.returnValue = this.autoUpdateManager.getErrorMessage()
|
||||
}))
|
||||
|
||||
this.disposable.add(ipcHelpers.on(ipcMain, 'will-save-path', (event, path) => {
|
||||
this.fileRecoveryService.willSavePath(this.atomWindowForEvent(event), path)
|
||||
event.returnValue = true
|
||||
}))
|
||||
this.disposable.add(ipcHelpers.respondTo('will-save-path', (window, path) =>
|
||||
this.fileRecoveryService.willSavePath(window, path)
|
||||
))
|
||||
|
||||
this.disposable.add(ipcHelpers.on(ipcMain, 'did-save-path', (event, path) => {
|
||||
this.fileRecoveryService.didSavePath(this.atomWindowForEvent(event), path)
|
||||
event.returnValue = true
|
||||
}))
|
||||
this.disposable.add(ipcHelpers.respondTo('did-save-path', (window, path) =>
|
||||
this.fileRecoveryService.didSavePath(window, path)
|
||||
))
|
||||
|
||||
this.disposable.add(ipcHelpers.on(ipcMain, 'did-change-paths', () =>
|
||||
this.saveState(false)
|
||||
this.saveCurrentWindowOptions(false)
|
||||
))
|
||||
|
||||
this.disposable.add(this.disableZoomOnDisplayChange())
|
||||
@@ -911,7 +923,7 @@ class AtomApplication extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
saveState (allowEmpty = false) {
|
||||
async saveCurrentWindowOptions (allowEmpty = false) {
|
||||
if (this.quitting) return
|
||||
|
||||
const states = []
|
||||
@@ -921,28 +933,23 @@ class AtomApplication extends EventEmitter {
|
||||
states.reverse()
|
||||
|
||||
if (states.length > 0 || allowEmpty) {
|
||||
this.storageFolder.storeSync('application.json', states)
|
||||
await this.storageFolder.store('application.json', states)
|
||||
this.emit('application:did-save-state')
|
||||
}
|
||||
}
|
||||
|
||||
loadState (options) {
|
||||
const states = this.storageFolder.load('application.json')
|
||||
if (
|
||||
['yes', 'always'].includes(this.config.get('core.restorePreviousWindowsOnStart')) &&
|
||||
states && states.length > 0
|
||||
) {
|
||||
return states.map(state =>
|
||||
this.openWithOptions(Object.assign(options, {
|
||||
initialPaths: state.initialPaths,
|
||||
pathsToOpen: state.initialPaths.filter(p => fs.isDirectorySync(p)),
|
||||
urlsToOpen: [],
|
||||
devMode: this.devMode,
|
||||
safeMode: this.safeMode
|
||||
}))
|
||||
)
|
||||
async loadPreviousWindowOptions () {
|
||||
const states = await this.storageFolder.load('application.json')
|
||||
if (states) {
|
||||
return states.map(state => ({
|
||||
initialPaths: state.initialPaths,
|
||||
pathsToOpen: state.initialPaths.filter(p => fs.isDirectorySync(p)),
|
||||
urlsToOpen: [],
|
||||
devMode: this.devMode,
|
||||
safeMode: this.safeMode
|
||||
}))
|
||||
} else {
|
||||
return null
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1293,17 +1300,16 @@ class AtomApplication extends EventEmitter {
|
||||
|
||||
// File dialog defaults to project directory of currently active editor
|
||||
if (path) openOptions.defaultPath = path
|
||||
return dialog.showOpenDialog(parentWindow, openOptions, callback)
|
||||
dialog.showOpenDialog(parentWindow, openOptions, callback)
|
||||
}
|
||||
|
||||
promptForRestart () {
|
||||
const chosen = dialog.showMessageBox(BrowserWindow.getFocusedWindow(), {
|
||||
dialog.showMessageBox(BrowserWindow.getFocusedWindow(), {
|
||||
type: 'warning',
|
||||
title: 'Restart required',
|
||||
message: 'You will need to restart Atom for this change to take effect.',
|
||||
buttons: ['Restart Atom', 'Cancel']
|
||||
})
|
||||
if (chosen === 0) return this.restart()
|
||||
}, response => { if (response === 0) this.restart() })
|
||||
}
|
||||
|
||||
restart () {
|
||||
|
||||
@@ -163,7 +163,7 @@ class AtomWindow extends EventEmitter {
|
||||
if (!this.atomApplication.quitting && !this.unloading) {
|
||||
event.preventDefault()
|
||||
this.unloading = true
|
||||
this.atomApplication.saveState(false)
|
||||
this.atomApplication.saveCurrentWindowOptions(false)
|
||||
if (await this.prepareToUnload()) this.close()
|
||||
}
|
||||
})
|
||||
@@ -176,34 +176,34 @@ class AtomWindow extends EventEmitter {
|
||||
|
||||
this.browserWindow.on('unresponsive', () => {
|
||||
if (this.isSpec) return
|
||||
const chosen = dialog.showMessageBox(this.browserWindow, {
|
||||
dialog.showMessageBox(this.browserWindow, {
|
||||
type: 'warning',
|
||||
buttons: ['Force Close', 'Keep Waiting'],
|
||||
message: 'Editor is not responding',
|
||||
detail:
|
||||
'The editor is not responding. Would you like to force close it or just keep waiting?'
|
||||
})
|
||||
if (chosen === 0) this.browserWindow.destroy()
|
||||
}, response => { if (response === 0) this.browserWindow.destroy() })
|
||||
})
|
||||
|
||||
this.browserWindow.webContents.on('crashed', () => {
|
||||
this.browserWindow.webContents.on('crashed', async () => {
|
||||
if (this.headless) {
|
||||
console.log('Renderer process crashed, exiting')
|
||||
this.atomApplication.exit(100)
|
||||
return
|
||||
}
|
||||
|
||||
this.fileRecoveryService.didCrashWindow(this)
|
||||
const chosen = dialog.showMessageBox(this.browserWindow, {
|
||||
await this.fileRecoveryService.didCrashWindow(this)
|
||||
dialog.showMessageBox(this.browserWindow, {
|
||||
type: 'warning',
|
||||
buttons: ['Close Window', 'Reload', 'Keep It Open'],
|
||||
message: 'The editor has crashed',
|
||||
detail: 'Please report this issue to https://github.com/atom/atom'
|
||||
}, response => {
|
||||
switch (response) {
|
||||
case 0: return this.browserWindow.destroy()
|
||||
case 1: return this.browserWindow.reload()
|
||||
}
|
||||
})
|
||||
switch (chosen) {
|
||||
case 0: return this.browserWindow.destroy()
|
||||
case 1: return this.browserWindow.reload()
|
||||
}
|
||||
})
|
||||
|
||||
this.browserWindow.webContents.on('will-navigate', (event, url) => {
|
||||
@@ -415,7 +415,7 @@ class AtomWindow extends EventEmitter {
|
||||
this.representedDirectoryPaths.sort()
|
||||
this.loadSettings.initialPaths = this.representedDirectoryPaths
|
||||
this.browserWindow.loadSettingsJSON = JSON.stringify(this.loadSettings)
|
||||
return this.atomApplication.saveState()
|
||||
return this.atomApplication.saveCurrentWindowOptions()
|
||||
}
|
||||
|
||||
didClosePathWithWaitSession (path) {
|
||||
|
||||
@@ -118,24 +118,26 @@ class AutoUpdateManager
|
||||
onUpdateNotAvailable: =>
|
||||
autoUpdater.removeListener 'error', @onUpdateError
|
||||
{dialog} = require 'electron'
|
||||
dialog.showMessageBox
|
||||
dialog.showMessageBox {
|
||||
type: 'info'
|
||||
buttons: ['OK']
|
||||
icon: @iconPath
|
||||
message: 'No update available.'
|
||||
title: 'No Update Available'
|
||||
detail: "Version #{@version} is the latest version."
|
||||
}, -> # noop callback to get async behavior
|
||||
|
||||
onUpdateError: (event, message) =>
|
||||
autoUpdater.removeListener 'update-not-available', @onUpdateNotAvailable
|
||||
{dialog} = require 'electron'
|
||||
dialog.showMessageBox
|
||||
dialog.showMessageBox {
|
||||
type: 'warning'
|
||||
buttons: ['OK']
|
||||
icon: @iconPath
|
||||
message: 'There was an error checking for updates.'
|
||||
title: 'Update Error'
|
||||
detail: message
|
||||
}, -> # noop callback to get async behavior
|
||||
|
||||
getWindows: ->
|
||||
global.atomApplication.getAllWindows()
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
'use babel'
|
||||
const {dialog} = require('electron')
|
||||
const crypto = require('crypto')
|
||||
const Path = require('path')
|
||||
const fs = require('fs-plus')
|
||||
|
||||
import {dialog} from 'electron'
|
||||
import crypto from 'crypto'
|
||||
import Path from 'path'
|
||||
import fs from 'fs-plus'
|
||||
|
||||
export default class FileRecoveryService {
|
||||
module.exports =
|
||||
class FileRecoveryService {
|
||||
constructor (recoveryDirectory) {
|
||||
this.recoveryDirectory = recoveryDirectory
|
||||
this.recoveryFilesByFilePath = new Map()
|
||||
@@ -13,15 +12,16 @@ export default class FileRecoveryService {
|
||||
this.windowsByRecoveryFile = new Map()
|
||||
}
|
||||
|
||||
willSavePath (window, path) {
|
||||
if (!fs.existsSync(path)) return
|
||||
async willSavePath (window, path) {
|
||||
const stats = await tryStatFile(path)
|
||||
if (!stats) return
|
||||
|
||||
const recoveryPath = Path.join(this.recoveryDirectory, RecoveryFile.fileNameForPath(path))
|
||||
const recoveryFile =
|
||||
this.recoveryFilesByFilePath.get(path) || new RecoveryFile(path, recoveryPath)
|
||||
this.recoveryFilesByFilePath.get(path) || new RecoveryFile(path, stats.mode, recoveryPath)
|
||||
|
||||
try {
|
||||
recoveryFile.retain()
|
||||
await recoveryFile.retain()
|
||||
} catch (err) {
|
||||
console.log(`Couldn't retain ${recoveryFile.recoveryPath}. Code: ${err.code}. Message: ${err.message}`)
|
||||
return
|
||||
@@ -39,11 +39,11 @@ export default class FileRecoveryService {
|
||||
this.recoveryFilesByFilePath.set(path, recoveryFile)
|
||||
}
|
||||
|
||||
didSavePath (window, path) {
|
||||
async didSavePath (window, path) {
|
||||
const recoveryFile = this.recoveryFilesByFilePath.get(path)
|
||||
if (recoveryFile != null) {
|
||||
try {
|
||||
recoveryFile.release()
|
||||
await recoveryFile.release()
|
||||
} catch (err) {
|
||||
console.log(`Couldn't release ${recoveryFile.recoveryPath}. Code: ${err.code}. Message: ${err.message}`)
|
||||
}
|
||||
@@ -53,27 +53,31 @@ export default class FileRecoveryService {
|
||||
}
|
||||
}
|
||||
|
||||
didCrashWindow (window) {
|
||||
async didCrashWindow (window) {
|
||||
if (!this.recoveryFilesByWindow.has(window)) return
|
||||
|
||||
const promises = []
|
||||
for (const recoveryFile of this.recoveryFilesByWindow.get(window)) {
|
||||
try {
|
||||
recoveryFile.recoverSync()
|
||||
} catch (error) {
|
||||
const message = 'A file that Atom was saving could be corrupted'
|
||||
const detail =
|
||||
`Error ${error.code}. There was a crash while saving "${recoveryFile.originalPath}", so this file might be blank or corrupted.\n` +
|
||||
`Atom couldn't recover it automatically, but a recovery file has been saved at: "${recoveryFile.recoveryPath}".`
|
||||
console.log(detail)
|
||||
dialog.showMessageBox(window.browserWindow, {type: 'info', buttons: ['OK'], message, detail})
|
||||
} finally {
|
||||
for (let window of this.windowsByRecoveryFile.get(recoveryFile)) {
|
||||
this.recoveryFilesByWindow.get(window).delete(recoveryFile)
|
||||
}
|
||||
this.windowsByRecoveryFile.delete(recoveryFile)
|
||||
this.recoveryFilesByFilePath.delete(recoveryFile.originalPath)
|
||||
}
|
||||
promises.push(recoveryFile.recover()
|
||||
.catch(error => {
|
||||
const message = 'A file that Atom was saving could be corrupted'
|
||||
const detail =
|
||||
`Error ${error.code}. There was a crash while saving "${recoveryFile.originalPath}", so this file might be blank or corrupted.\n` +
|
||||
`Atom couldn't recover it automatically, but a recovery file has been saved at: "${recoveryFile.recoveryPath}".`
|
||||
console.log(detail)
|
||||
dialog.showMessageBox(window, {type: 'info', buttons: ['OK'], message, detail}, () => { /* noop callback to get async behavior */ })
|
||||
})
|
||||
.then(() => {
|
||||
for (let window of this.windowsByRecoveryFile.get(recoveryFile)) {
|
||||
this.recoveryFilesByWindow.get(window).delete(recoveryFile)
|
||||
}
|
||||
this.windowsByRecoveryFile.delete(recoveryFile)
|
||||
this.recoveryFilesByFilePath.delete(recoveryFile.originalPath)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
await Promise.all(promises)
|
||||
}
|
||||
|
||||
didCloseWindow (window) {
|
||||
@@ -94,36 +98,64 @@ class RecoveryFile {
|
||||
return `${basename}-${randomSuffix}${extension}`
|
||||
}
|
||||
|
||||
constructor (originalPath, recoveryPath) {
|
||||
constructor (originalPath, fileMode, recoveryPath) {
|
||||
this.originalPath = originalPath
|
||||
this.fileMode = fileMode
|
||||
this.recoveryPath = recoveryPath
|
||||
this.refCount = 0
|
||||
}
|
||||
|
||||
storeSync () {
|
||||
fs.copyFileSync(this.originalPath, this.recoveryPath)
|
||||
async store () {
|
||||
await copyFile(this.originalPath, this.recoveryPath, this.fileMode)
|
||||
}
|
||||
|
||||
recoverSync () {
|
||||
fs.copyFileSync(this.recoveryPath, this.originalPath)
|
||||
this.removeSync()
|
||||
async recover () {
|
||||
await copyFile(this.recoveryPath, this.originalPath, this.fileMode)
|
||||
await this.remove()
|
||||
}
|
||||
|
||||
removeSync () {
|
||||
fs.unlinkSync(this.recoveryPath)
|
||||
async remove () {
|
||||
return new Promise((resolve, reject) =>
|
||||
fs.unlink(this.recoveryPath, error =>
|
||||
error && error.code !== 'ENOENT' ? reject(error) : resolve()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
retain () {
|
||||
if (this.isReleased()) this.storeSync()
|
||||
async retain () {
|
||||
if (this.isReleased()) await this.store()
|
||||
this.refCount++
|
||||
}
|
||||
|
||||
release () {
|
||||
async release () {
|
||||
this.refCount--
|
||||
if (this.isReleased()) this.removeSync()
|
||||
if (this.isReleased()) await this.remove()
|
||||
}
|
||||
|
||||
isReleased () {
|
||||
return this.refCount === 0
|
||||
}
|
||||
}
|
||||
|
||||
async function tryStatFile (path) {
|
||||
return new Promise((resolve, reject) =>
|
||||
fs.stat(path, (error, result) =>
|
||||
resolve(error == null && result)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
async function copyFile (source, destination, mode) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const readStream = fs.createReadStream(source)
|
||||
readStream
|
||||
.on('error', reject)
|
||||
.once('open', () => {
|
||||
const writeStream = fs.createWriteStream(destination, {mode})
|
||||
writeStream
|
||||
.on('error', reject)
|
||||
.on('open', () => readStream.pipe(writeStream))
|
||||
.once('close', () => resolve())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
'use babel'
|
||||
|
||||
import Registry from 'winreg'
|
||||
import Path from 'path'
|
||||
const Registry = require('winreg')
|
||||
const Path = require('path')
|
||||
|
||||
let exeName = Path.basename(process.execPath)
|
||||
let appPath = `\"${process.execPath}\"`
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/** @babel */
|
||||
|
||||
const path = require('path')
|
||||
|
||||
// Private: re-join the segments split from an absolute path to form another absolute path.
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/** @babel */
|
||||
const {Disposable} = require('event-kit')
|
||||
|
||||
import {Disposable} from 'event-kit'
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
name: 'Null Grammar',
|
||||
scopeName: 'text.plain.null-grammar',
|
||||
scopeForId (id) {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/** @babel */
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
|
||||
@@ -695,7 +695,7 @@ class Project extends Model {
|
||||
}
|
||||
|
||||
subscribeToBuffer (buffer) {
|
||||
buffer.onWillSave(({path}) => this.applicationDelegate.emitWillSavePath(path))
|
||||
buffer.onWillSave(async ({path}) => this.applicationDelegate.emitWillSavePath(path))
|
||||
buffer.onDidSave(({path}) => this.applicationDelegate.emitDidSavePath(path))
|
||||
buffer.onDidDestroy(() => this.removeBuffer(buffer))
|
||||
buffer.onDidChangePath(() => {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/** @babel */
|
||||
const SelectListView = require('atom-select-list')
|
||||
|
||||
import SelectListView from 'atom-select-list'
|
||||
|
||||
export default class ReopenProjectListView {
|
||||
module.exports =
|
||||
class ReopenProjectListView {
|
||||
constructor (callback) {
|
||||
this.callback = callback
|
||||
this.selectListView = new SelectListView({
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/** @babel */
|
||||
const {CompositeDisposable} = require('event-kit')
|
||||
const path = require('path')
|
||||
|
||||
import {CompositeDisposable} from 'event-kit'
|
||||
import path from 'path'
|
||||
|
||||
export default class ReopenProjectMenuManager {
|
||||
module.exports =
|
||||
class ReopenProjectMenuManager {
|
||||
constructor ({menu, commands, history, config, open}) {
|
||||
this.menuManager = menu
|
||||
this.historyManager = history
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
path = require "path"
|
||||
fs = require "fs-plus"
|
||||
|
||||
module.exports =
|
||||
class StorageFolder
|
||||
constructor: (containingPath) ->
|
||||
@path = path.join(containingPath, "storage") if containingPath?
|
||||
|
||||
clear: ->
|
||||
return unless @path?
|
||||
|
||||
try
|
||||
fs.removeSync(@path)
|
||||
catch error
|
||||
console.warn "Error deleting #{@path}", error.stack, error
|
||||
|
||||
storeSync: (name, object) ->
|
||||
return unless @path?
|
||||
|
||||
fs.writeFileSync(@pathForKey(name), JSON.stringify(object), 'utf8')
|
||||
|
||||
load: (name) ->
|
||||
return unless @path?
|
||||
|
||||
statePath = @pathForKey(name)
|
||||
try
|
||||
stateString = fs.readFileSync(statePath, 'utf8')
|
||||
catch error
|
||||
unless error.code is 'ENOENT'
|
||||
console.warn "Error reading state file: #{statePath}", error.stack, error
|
||||
return undefined
|
||||
|
||||
try
|
||||
JSON.parse(stateString)
|
||||
catch error
|
||||
console.warn "Error parsing state file: #{statePath}", error.stack, error
|
||||
|
||||
pathForKey: (name) -> path.join(@getPath(), name)
|
||||
getPath: -> @path
|
||||
49
src/storage-folder.js
Normal file
49
src/storage-folder.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const path = require('path')
|
||||
const fs = require('fs-plus')
|
||||
|
||||
module.exports =
|
||||
class StorageFolder {
|
||||
constructor (containingPath) {
|
||||
if (containingPath) {
|
||||
this.path = path.join(containingPath, 'storage')
|
||||
}
|
||||
}
|
||||
|
||||
store (name, object) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.path) return resolve()
|
||||
fs.writeFile(this.pathForKey(name), JSON.stringify(object), 'utf8', error =>
|
||||
error ? reject(error) : resolve()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
load (name) {
|
||||
return new Promise(resolve => {
|
||||
if (!this.path) return resolve(null)
|
||||
const statePath = this.pathForKey(name)
|
||||
fs.readFile(statePath, 'utf8', (error, stateString) => {
|
||||
if (error && error.code !== 'ENOENT') {
|
||||
console.warn(`Error reading state file: ${statePath}`, error.stack, error)
|
||||
}
|
||||
|
||||
if (!stateString) return resolve(null)
|
||||
|
||||
try {
|
||||
resolve(JSON.parse(stateString))
|
||||
} catch (error) {
|
||||
console.warn(`Error parsing state file: ${statePath}`, error.stack, error)
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pathForKey (name) {
|
||||
return path.join(this.getPath(), name)
|
||||
}
|
||||
|
||||
getPath () {
|
||||
return this.path
|
||||
}
|
||||
}
|
||||
@@ -2694,7 +2694,7 @@ class TextEditorComponent {
|
||||
}
|
||||
|
||||
getContentWidth () {
|
||||
return Math.round(this.getLongestLineWidth() + this.getBaseCharacterWidth())
|
||||
return Math.ceil(this.getLongestLineWidth() + this.getBaseCharacterWidth())
|
||||
}
|
||||
|
||||
getScrollContainerClientWidthInBaseCharacters () {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/** @babel */
|
||||
|
||||
import fs from 'fs'
|
||||
import childProcess from 'child_process'
|
||||
const fs = require('fs')
|
||||
const childProcess = require('child_process')
|
||||
|
||||
const ENVIRONMENT_VARIABLES_TO_PRESERVE = new Set([
|
||||
'NODE_ENV',
|
||||
@@ -120,4 +118,4 @@ async function getEnvFromShell (env) {
|
||||
return result
|
||||
}
|
||||
|
||||
export default { updateProcessEnv, shouldGetEnvFromShell }
|
||||
module.exports = {updateProcessEnv, shouldGetEnvFromShell}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
'use babel'
|
||||
|
||||
const _ = require('underscore-plus')
|
||||
const url = require('url')
|
||||
const path = require('path')
|
||||
|
||||
Reference in New Issue
Block a user