mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-20 07:28:08 +03:00
Merge pull request #13963 from atom/ku-mkt-restore-atom-env-when-adding-folder-to-fresh-window
Restore atom environment when adding project folders to a fresh window
This commit is contained in:
commit
1ff5c9e684
@ -65,6 +65,7 @@
|
|||||||
"sinon": "1.17.4",
|
"sinon": "1.17.4",
|
||||||
"source-map-support": "^0.3.2",
|
"source-map-support": "^0.3.2",
|
||||||
"temp": "0.8.1",
|
"temp": "0.8.1",
|
||||||
|
"test-until": "^1.1.1",
|
||||||
"text-buffer": "11.4.0",
|
"text-buffer": "11.4.0",
|
||||||
"typescript-simple": "1.0.0",
|
"typescript-simple": "1.0.0",
|
||||||
"underscore-plus": "^1.6.6",
|
"underscore-plus": "^1.6.6",
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
/** @babel */
|
/** @babel */
|
||||||
|
|
||||||
|
import until from 'test-until'
|
||||||
|
|
||||||
export function beforeEach (fn) {
|
export function beforeEach (fn) {
|
||||||
global.beforeEach(function () {
|
global.beforeEach(function () {
|
||||||
const result = fn()
|
const result = fn()
|
||||||
@ -60,3 +62,9 @@ function waitsForPromise (fn) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function emitterEventPromise (emitter, event, timeout = 5000) {
|
||||||
|
let emitted = false
|
||||||
|
emitter.once(event, () => { emitted = true })
|
||||||
|
return until(`${event} is emitted`, () => emitted, timeout)
|
||||||
|
}
|
||||||
|
@ -321,14 +321,6 @@ describe "AtomEnvironment", ->
|
|||||||
expect(atom.workspace.open).not.toHaveBeenCalled()
|
expect(atom.workspace.open).not.toHaveBeenCalled()
|
||||||
|
|
||||||
describe "adding a project folder", ->
|
describe "adding a project folder", ->
|
||||||
it "adds a second path to the project", ->
|
|
||||||
initialPaths = atom.project.getPaths()
|
|
||||||
tempDirectory = temp.mkdirSync("a-new-directory")
|
|
||||||
spyOn(atom, "pickFolder").andCallFake (callback) ->
|
|
||||||
callback([tempDirectory])
|
|
||||||
atom.addProjectFolder()
|
|
||||||
expect(atom.project.getPaths()).toEqual(initialPaths.concat([tempDirectory]))
|
|
||||||
|
|
||||||
it "does nothing if the user dismisses the file picker", ->
|
it "does nothing if the user dismisses the file picker", ->
|
||||||
initialPaths = atom.project.getPaths()
|
initialPaths = atom.project.getPaths()
|
||||||
tempDirectory = temp.mkdirSync("a-new-directory")
|
tempDirectory = temp.mkdirSync("a-new-directory")
|
||||||
@ -336,6 +328,106 @@ describe "AtomEnvironment", ->
|
|||||||
atom.addProjectFolder()
|
atom.addProjectFolder()
|
||||||
expect(atom.project.getPaths()).toEqual(initialPaths)
|
expect(atom.project.getPaths()).toEqual(initialPaths)
|
||||||
|
|
||||||
|
describe "when there is no saved state for the added folders", ->
|
||||||
|
beforeEach ->
|
||||||
|
spyOn(atom, 'loadState').andReturn(Promise.resolve(null))
|
||||||
|
spyOn(atom, 'attemptRestoreProjectStateForPaths')
|
||||||
|
|
||||||
|
it "adds the selected folder to the project", ->
|
||||||
|
initialPaths = atom.project.setPaths([])
|
||||||
|
tempDirectory = temp.mkdirSync("a-new-directory")
|
||||||
|
spyOn(atom, "pickFolder").andCallFake (callback) ->
|
||||||
|
callback([tempDirectory])
|
||||||
|
waitsForPromise ->
|
||||||
|
atom.addProjectFolder()
|
||||||
|
runs ->
|
||||||
|
expect(atom.project.getPaths()).toEqual([tempDirectory])
|
||||||
|
expect(atom.attemptRestoreProjectStateForPaths).not.toHaveBeenCalled()
|
||||||
|
|
||||||
|
describe "when there is saved state for the relevant directories", ->
|
||||||
|
state = Symbol('savedState')
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
spyOn(atom, "getStateKey").andCallFake (dirs) -> dirs.join(':')
|
||||||
|
spyOn(atom, "loadState").andCallFake (key) ->
|
||||||
|
if key is __dirname then Promise.resolve(state) else Promise.resolve(null)
|
||||||
|
spyOn(atom, "attemptRestoreProjectStateForPaths")
|
||||||
|
spyOn(atom, "pickFolder").andCallFake (callback) ->
|
||||||
|
callback([__dirname])
|
||||||
|
atom.project.setPaths([])
|
||||||
|
|
||||||
|
describe "when there are no project folders", ->
|
||||||
|
it "attempts to restore the project state", ->
|
||||||
|
waitsForPromise ->
|
||||||
|
atom.addProjectFolder()
|
||||||
|
runs ->
|
||||||
|
expect(atom.attemptRestoreProjectStateForPaths).toHaveBeenCalledWith(state, [__dirname])
|
||||||
|
expect(atom.project.getPaths()).toEqual([])
|
||||||
|
|
||||||
|
describe "when there are already project folders", ->
|
||||||
|
openedPath = path.join(__dirname, 'fixtures')
|
||||||
|
beforeEach ->
|
||||||
|
atom.project.setPaths([openedPath])
|
||||||
|
|
||||||
|
it "does not attempt to restore the project state, instead adding the project paths", ->
|
||||||
|
waitsForPromise ->
|
||||||
|
atom.addProjectFolder()
|
||||||
|
runs ->
|
||||||
|
expect(atom.attemptRestoreProjectStateForPaths).not.toHaveBeenCalled()
|
||||||
|
expect(atom.project.getPaths()).toEqual([openedPath, __dirname])
|
||||||
|
|
||||||
|
describe "attemptRestoreProjectStateForPaths(state, projectPaths, filesToOpen)", ->
|
||||||
|
describe "when the window is clean (empty or has only unnamed, unmodified buffers)", ->
|
||||||
|
beforeEach ->
|
||||||
|
# Unnamed, unmodified buffer doesn't count toward "clean"-ness
|
||||||
|
waitsForPromise -> atom.workspace.open()
|
||||||
|
|
||||||
|
it "automatically restores the saved state into the current environment", ->
|
||||||
|
state = Symbol()
|
||||||
|
spyOn(atom.workspace, 'open')
|
||||||
|
spyOn(atom, 'restoreStateIntoThisEnvironment')
|
||||||
|
|
||||||
|
atom.attemptRestoreProjectStateForPaths(state, [__dirname], [__filename])
|
||||||
|
expect(atom.restoreStateIntoThisEnvironment).toHaveBeenCalledWith(state)
|
||||||
|
expect(atom.workspace.open.callCount).toBe(1)
|
||||||
|
expect(atom.workspace.open).toHaveBeenCalledWith(__filename)
|
||||||
|
|
||||||
|
describe "when the window is dirty", ->
|
||||||
|
editor = null
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
waitsForPromise -> atom.workspace.open().then (e) ->
|
||||||
|
editor = e
|
||||||
|
editor.setText('new editor')
|
||||||
|
|
||||||
|
it "prompts the user to restore the state in a new window, discarding it and adding folder to current window", ->
|
||||||
|
spyOn(atom, "confirm").andReturn(1)
|
||||||
|
spyOn(atom.project, 'addPath')
|
||||||
|
spyOn(atom.workspace, 'open')
|
||||||
|
state = Symbol()
|
||||||
|
|
||||||
|
atom.attemptRestoreProjectStateForPaths(state, [__dirname], [__filename])
|
||||||
|
expect(atom.confirm).toHaveBeenCalled()
|
||||||
|
expect(atom.project.addPath.callCount).toBe(1)
|
||||||
|
expect(atom.project.addPath).toHaveBeenCalledWith(__dirname)
|
||||||
|
expect(atom.workspace.open.callCount).toBe(1)
|
||||||
|
expect(atom.workspace.open).toHaveBeenCalledWith(__filename)
|
||||||
|
|
||||||
|
it "prompts the user to restore the state in a new window, opening a new window", ->
|
||||||
|
spyOn(atom, "confirm").andReturn(0)
|
||||||
|
spyOn(atom, "open")
|
||||||
|
state = Symbol()
|
||||||
|
|
||||||
|
atom.attemptRestoreProjectStateForPaths(state, [__dirname], [__filename])
|
||||||
|
expect(atom.confirm).toHaveBeenCalled()
|
||||||
|
expect(atom.open).toHaveBeenCalledWith
|
||||||
|
pathsToOpen: [__dirname, __filename]
|
||||||
|
newWindow: true
|
||||||
|
devMode: atom.inDevMode()
|
||||||
|
safeMode: atom.inSafeMode()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
describe "::unloadEditorWindow()", ->
|
describe "::unloadEditorWindow()", ->
|
||||||
it "saves the BlobStore so it can be loaded after reload", ->
|
it "saves the BlobStore so it can be loaded after reload", ->
|
||||||
configDirPath = temp.mkdirSync('atom-spec-environment')
|
configDirPath = temp.mkdirSync('atom-spec-environment')
|
||||||
@ -371,44 +463,91 @@ describe "AtomEnvironment", ->
|
|||||||
spyOn(atom.workspace, 'open')
|
spyOn(atom.workspace, 'open')
|
||||||
atom.project.setPaths([])
|
atom.project.setPaths([])
|
||||||
|
|
||||||
|
describe "when there is no saved state", ->
|
||||||
|
beforeEach ->
|
||||||
|
spyOn(atom, "loadState").andReturn(Promise.resolve(null))
|
||||||
|
|
||||||
describe "when the opened path exists", ->
|
describe "when the opened path exists", ->
|
||||||
it "adds it to the project's paths", ->
|
it "adds it to the project's paths", ->
|
||||||
pathToOpen = __filename
|
pathToOpen = __filename
|
||||||
atom.openLocations([{pathToOpen}])
|
waitsForPromise -> atom.openLocations([{pathToOpen}])
|
||||||
expect(atom.project.getPaths()[0]).toBe __dirname
|
runs -> expect(atom.project.getPaths()[0]).toBe __dirname
|
||||||
|
|
||||||
describe "then a second path is opened with forceAddToWindow", ->
|
describe "then a second path is opened with forceAddToWindow", ->
|
||||||
it "adds the second path to the project's paths", ->
|
it "adds the second path to the project's paths", ->
|
||||||
firstPathToOpen = __dirname
|
firstPathToOpen = __dirname
|
||||||
secondPathToOpen = path.resolve(__dirname, './fixtures')
|
secondPathToOpen = path.resolve(__dirname, './fixtures')
|
||||||
atom.openLocations([{pathToOpen: firstPathToOpen}])
|
waitsForPromise -> atom.openLocations([{pathToOpen: firstPathToOpen}])
|
||||||
atom.openLocations([{pathToOpen: secondPathToOpen, forceAddToWindow: true}])
|
waitsForPromise -> atom.openLocations([{pathToOpen: secondPathToOpen, forceAddToWindow: true}])
|
||||||
expect(atom.project.getPaths()).toEqual([firstPathToOpen, secondPathToOpen])
|
runs -> expect(atom.project.getPaths()).toEqual([firstPathToOpen, secondPathToOpen])
|
||||||
|
|
||||||
describe "when the opened path does not exist but its parent directory does", ->
|
describe "when the opened path does not exist but its parent directory does", ->
|
||||||
it "adds the parent directory to the project paths", ->
|
it "adds the parent directory to the project paths", ->
|
||||||
pathToOpen = path.join(__dirname, 'this-path-does-not-exist.txt')
|
pathToOpen = path.join(__dirname, 'this-path-does-not-exist.txt')
|
||||||
atom.openLocations([{pathToOpen}])
|
waitsForPromise -> atom.openLocations([{pathToOpen}])
|
||||||
expect(atom.project.getPaths()[0]).toBe __dirname
|
runs -> expect(atom.project.getPaths()[0]).toBe __dirname
|
||||||
|
|
||||||
describe "when the opened path is a file", ->
|
describe "when the opened path is a file", ->
|
||||||
it "opens it in the workspace", ->
|
it "opens it in the workspace", ->
|
||||||
pathToOpen = __filename
|
pathToOpen = __filename
|
||||||
atom.openLocations([{pathToOpen}])
|
waitsForPromise -> atom.openLocations([{pathToOpen}])
|
||||||
expect(atom.workspace.open.mostRecentCall.args[0]).toBe __filename
|
runs -> expect(atom.workspace.open.mostRecentCall.args[0]).toBe __filename
|
||||||
|
|
||||||
describe "when the opened path is a directory", ->
|
describe "when the opened path is a directory", ->
|
||||||
it "does not open it in the workspace", ->
|
it "does not open it in the workspace", ->
|
||||||
pathToOpen = __dirname
|
pathToOpen = __dirname
|
||||||
atom.openLocations([{pathToOpen}])
|
waitsForPromise -> atom.openLocations([{pathToOpen}])
|
||||||
expect(atom.workspace.open.callCount).toBe 0
|
runs -> expect(atom.workspace.open.callCount).toBe 0
|
||||||
|
|
||||||
describe "when the opened path is a uri", ->
|
describe "when the opened path is a uri", ->
|
||||||
it "adds it to the project's paths as is", ->
|
it "adds it to the project's paths as is", ->
|
||||||
pathToOpen = 'remote://server:7644/some/dir/path'
|
pathToOpen = 'remote://server:7644/some/dir/path'
|
||||||
spyOn(atom.project, 'addPath')
|
spyOn(atom.project, 'addPath')
|
||||||
atom.openLocations([{pathToOpen}])
|
waitsForPromise -> atom.openLocations([{pathToOpen}])
|
||||||
expect(atom.project.addPath).toHaveBeenCalledWith(pathToOpen)
|
runs -> expect(atom.project.addPath).toHaveBeenCalledWith(pathToOpen)
|
||||||
|
|
||||||
|
describe "when there is saved state for the relevant directories", ->
|
||||||
|
state = Symbol('savedState')
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
spyOn(atom, "getStateKey").andCallFake (dirs) -> dirs.join(':')
|
||||||
|
spyOn(atom, "loadState").andCallFake (key) ->
|
||||||
|
if key is __dirname then Promise.resolve(state) else Promise.resolve(null)
|
||||||
|
spyOn(atom, "attemptRestoreProjectStateForPaths")
|
||||||
|
|
||||||
|
describe "when there are no project folders", ->
|
||||||
|
it "attempts to restore the project state", ->
|
||||||
|
pathToOpen = __dirname
|
||||||
|
waitsForPromise -> atom.openLocations([{pathToOpen}])
|
||||||
|
runs ->
|
||||||
|
expect(atom.attemptRestoreProjectStateForPaths).toHaveBeenCalledWith(state, [pathToOpen], [])
|
||||||
|
expect(atom.project.getPaths()).toEqual([])
|
||||||
|
|
||||||
|
it "opens the specified files", ->
|
||||||
|
waitsForPromise -> atom.openLocations([{pathToOpen: __dirname}, {pathToOpen: __filename}])
|
||||||
|
runs ->
|
||||||
|
expect(atom.attemptRestoreProjectStateForPaths).toHaveBeenCalledWith(state, [__dirname], [__filename])
|
||||||
|
expect(atom.project.getPaths()).toEqual([])
|
||||||
|
|
||||||
|
|
||||||
|
describe "when there are already project folders", ->
|
||||||
|
beforeEach ->
|
||||||
|
atom.project.setPaths([__dirname])
|
||||||
|
|
||||||
|
it "does not attempt to restore the project state, instead adding the project paths", ->
|
||||||
|
pathToOpen = path.join(__dirname, 'fixtures')
|
||||||
|
waitsForPromise -> atom.openLocations([{pathToOpen, forceAddToWindow: true}])
|
||||||
|
runs ->
|
||||||
|
expect(atom.attemptRestoreProjectStateForPaths).not.toHaveBeenCalled()
|
||||||
|
expect(atom.project.getPaths()).toEqual([__dirname, pathToOpen])
|
||||||
|
|
||||||
|
it "opens the specified files", ->
|
||||||
|
pathToOpen = path.join(__dirname, 'fixtures')
|
||||||
|
fileToOpen = path.join(pathToOpen, 'michelle-is-awesome.txt')
|
||||||
|
waitsForPromise -> atom.openLocations([{pathToOpen}, {pathToOpen: fileToOpen}])
|
||||||
|
runs ->
|
||||||
|
expect(atom.attemptRestoreProjectStateForPaths).not.toHaveBeenCalledWith(state, [pathToOpen], [fileToOpen])
|
||||||
|
expect(atom.project.getPaths()).toEqual([__dirname])
|
||||||
|
|
||||||
describe "::updateAvailable(info) (called via IPC from browser process)", ->
|
describe "::updateAvailable(info) (called via IPC from browser process)", ->
|
||||||
subscription = null
|
subscription = null
|
||||||
|
@ -7,7 +7,7 @@ import fs from 'fs-plus'
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import AtomApplication from '../../src/main-process/atom-application'
|
import AtomApplication from '../../src/main-process/atom-application'
|
||||||
import parseCommandLine from '../../src/main-process/parse-command-line'
|
import parseCommandLine from '../../src/main-process/parse-command-line'
|
||||||
import {timeoutPromise, conditionPromise} from '../async-spec-helpers'
|
import {timeoutPromise, conditionPromise, emitterEventPromise} from '../async-spec-helpers'
|
||||||
|
|
||||||
const ATOM_RESOURCE_PATH = path.resolve(__dirname, '..', '..')
|
const ATOM_RESOURCE_PATH = path.resolve(__dirname, '..', '..')
|
||||||
|
|
||||||
@ -121,6 +121,7 @@ describe('AtomApplication', function () {
|
|||||||
|
|
||||||
const atomApplication = buildAtomApplication()
|
const atomApplication = buildAtomApplication()
|
||||||
const window1 = atomApplication.launch(parseCommandLine([path.join(dirAPath, 'new-file')]))
|
const window1 = atomApplication.launch(parseCommandLine([path.join(dirAPath, 'new-file')]))
|
||||||
|
await emitterEventPromise(window1, 'window:locations-opened')
|
||||||
await focusWindow(window1)
|
await focusWindow(window1)
|
||||||
|
|
||||||
let activeEditorPath
|
let activeEditorPath
|
||||||
@ -146,6 +147,7 @@ describe('AtomApplication', function () {
|
|||||||
|
|
||||||
// Opens new windows when opening directories
|
// Opens new windows when opening directories
|
||||||
const window2 = atomApplication.launch(parseCommandLine([dirCPath]))
|
const window2 = atomApplication.launch(parseCommandLine([dirCPath]))
|
||||||
|
await emitterEventPromise(window2, 'window:locations-opened')
|
||||||
assert.notEqual(window2, window1)
|
assert.notEqual(window2, window1)
|
||||||
await focusWindow(window2)
|
await focusWindow(window2)
|
||||||
assert.deepEqual(await getTreeViewRootDirectories(window2), [dirCPath])
|
assert.deepEqual(await getTreeViewRootDirectories(window2), [dirCPath])
|
||||||
@ -365,6 +367,9 @@ describe('AtomApplication', function () {
|
|||||||
|
|
||||||
const atomApplication2 = buildAtomApplication()
|
const atomApplication2 = buildAtomApplication()
|
||||||
const [app2Window1, app2Window2] = atomApplication2.launch(parseCommandLine([]))
|
const [app2Window1, app2Window2] = atomApplication2.launch(parseCommandLine([]))
|
||||||
|
const p1 = emitterEventPromise(app2Window1, 'window:locations-opened', 15000)
|
||||||
|
const p2 = emitterEventPromise(app2Window2, 'window:locations-opened', 15000)
|
||||||
|
await Promise.all([p1, p2])
|
||||||
await app2Window1.loadedPromise
|
await app2Window1.loadedPromise
|
||||||
await app2Window2.loadedPromise
|
await app2Window2.loadedPromise
|
||||||
|
|
||||||
@ -420,6 +425,7 @@ describe('AtomApplication', function () {
|
|||||||
|
|
||||||
const atomApplication = buildAtomApplication()
|
const atomApplication = buildAtomApplication()
|
||||||
const window = atomApplication.launch(parseCommandLine([dirA, dirB]))
|
const window = atomApplication.launch(parseCommandLine([dirA, dirB]))
|
||||||
|
await emitterEventPromise(window, 'window:locations-opened', 15000)
|
||||||
await focusWindow(window)
|
await focusWindow(window)
|
||||||
assert.deepEqual(await getTreeViewRootDirectories(window), [dirA, dirB])
|
assert.deepEqual(await getTreeViewRootDirectories(window), [dirA, dirB])
|
||||||
|
|
||||||
|
@ -894,7 +894,51 @@ class AtomEnvironment extends Model
|
|||||||
|
|
||||||
addProjectFolder: ->
|
addProjectFolder: ->
|
||||||
@pickFolder (selectedPaths = []) =>
|
@pickFolder (selectedPaths = []) =>
|
||||||
@project.addPath(selectedPath) for selectedPath in selectedPaths
|
@addToProject(selectedPaths)
|
||||||
|
|
||||||
|
addToProject: (projectPaths) ->
|
||||||
|
@loadState(@getStateKey(projectPaths)).then (state) =>
|
||||||
|
if state and @project.getPaths().length is 0
|
||||||
|
@attemptRestoreProjectStateForPaths(state, projectPaths)
|
||||||
|
else
|
||||||
|
@project.addPath(folder) for folder in projectPaths
|
||||||
|
|
||||||
|
attemptRestoreProjectStateForPaths: (state, projectPaths, filesToOpen = []) ->
|
||||||
|
paneItemIsEmptyUnnamedTextEditor = (item) ->
|
||||||
|
return false unless item instanceof TextEditor
|
||||||
|
return false if item.getPath() or item.isModified()
|
||||||
|
true
|
||||||
|
|
||||||
|
windowIsUnused = @workspace.getPaneItems().every(paneItemIsEmptyUnnamedTextEditor)
|
||||||
|
if windowIsUnused
|
||||||
|
@restoreStateIntoThisEnvironment(state)
|
||||||
|
Promise.all (@workspace.open(file) for file in filesToOpen)
|
||||||
|
else
|
||||||
|
nouns = if projectPaths.length is 1 then 'folder' else 'folders'
|
||||||
|
btn = @confirm
|
||||||
|
message: 'Previous automatically-saved project state detected'
|
||||||
|
detailedMessage: "There is previously saved state for the selected #{nouns}. " +
|
||||||
|
"Would you like to add the #{nouns} to this window, permanently discarding the saved state, " +
|
||||||
|
"or open the #{nouns} in a new window, restoring the saved state?"
|
||||||
|
buttons: [
|
||||||
|
'Open in new window and recover state'
|
||||||
|
'Add to this window and discard state'
|
||||||
|
]
|
||||||
|
if btn is 0
|
||||||
|
@open
|
||||||
|
pathsToOpen: projectPaths.concat(filesToOpen)
|
||||||
|
newWindow: true
|
||||||
|
devMode: @inDevMode()
|
||||||
|
safeMode: @inSafeMode()
|
||||||
|
Promise.resolve(null)
|
||||||
|
else if btn is 1
|
||||||
|
@project.addPath(selectedPath) for selectedPath in projectPaths
|
||||||
|
Promise.all (@workspace.open(file) for file in filesToOpen)
|
||||||
|
|
||||||
|
restoreStateIntoThisEnvironment: (state) ->
|
||||||
|
state.fullScreen = @isFullScreen()
|
||||||
|
pane.destroy() for pane in @workspace.getPanes()
|
||||||
|
@deserialize(state)
|
||||||
|
|
||||||
showSaveDialog: (callback) ->
|
showSaveDialog: (callback) ->
|
||||||
callback(@showSaveDialogSync())
|
callback(@showSaveDialogSync())
|
||||||
@ -902,12 +946,12 @@ class AtomEnvironment extends Model
|
|||||||
showSaveDialogSync: (options={}) ->
|
showSaveDialogSync: (options={}) ->
|
||||||
@applicationDelegate.showSaveDialog(options)
|
@applicationDelegate.showSaveDialog(options)
|
||||||
|
|
||||||
saveState: (options) ->
|
saveState: (options, storageKey) ->
|
||||||
new Promise (resolve, reject) =>
|
new Promise (resolve, reject) =>
|
||||||
if @enablePersistence and @project
|
if @enablePersistence and @project
|
||||||
state = @serialize(options)
|
state = @serialize(options)
|
||||||
savePromise =
|
savePromise =
|
||||||
if storageKey = @getStateKey(@project?.getPaths())
|
if storageKey ?= @getStateKey(@project?.getPaths())
|
||||||
@stateStore.save(storageKey, state)
|
@stateStore.save(storageKey, state)
|
||||||
else
|
else
|
||||||
@applicationDelegate.setTemporaryWindowState(state)
|
@applicationDelegate.setTemporaryWindowState(state)
|
||||||
@ -915,9 +959,9 @@ class AtomEnvironment extends Model
|
|||||||
else
|
else
|
||||||
resolve()
|
resolve()
|
||||||
|
|
||||||
loadState: ->
|
loadState: (stateKey) ->
|
||||||
if @enablePersistence
|
if @enablePersistence
|
||||||
if stateKey = @getStateKey(@getLoadSettings().initialPaths)
|
if stateKey ?= @getStateKey(@getLoadSettings().initialPaths)
|
||||||
@stateStore.load(stateKey).then (state) =>
|
@stateStore.load(stateKey).then (state) =>
|
||||||
if state
|
if state
|
||||||
state
|
state
|
||||||
@ -1004,19 +1048,45 @@ class AtomEnvironment extends Model
|
|||||||
openLocations: (locations) ->
|
openLocations: (locations) ->
|
||||||
needsProjectPaths = @project?.getPaths().length is 0
|
needsProjectPaths = @project?.getPaths().length is 0
|
||||||
|
|
||||||
|
foldersToAddToProject = []
|
||||||
|
fileLocationsToOpen = []
|
||||||
|
|
||||||
|
pushFolderToOpen = (folder) ->
|
||||||
|
if folder not in foldersToAddToProject
|
||||||
|
foldersToAddToProject.push(folder)
|
||||||
|
|
||||||
for {pathToOpen, initialLine, initialColumn, forceAddToWindow} in locations
|
for {pathToOpen, initialLine, initialColumn, forceAddToWindow} in locations
|
||||||
if pathToOpen? and (needsProjectPaths or forceAddToWindow)
|
if pathToOpen? and (needsProjectPaths or forceAddToWindow)
|
||||||
if fs.existsSync(pathToOpen)
|
if fs.existsSync(pathToOpen)
|
||||||
@project.addPath(pathToOpen)
|
pushFolderToOpen @project.getDirectoryForProjectPath(pathToOpen).getPath()
|
||||||
else if fs.existsSync(path.dirname(pathToOpen))
|
else if fs.existsSync(path.dirname(pathToOpen))
|
||||||
@project.addPath(path.dirname(pathToOpen))
|
pushFolderToOpen @project.getDirectoryForProjectPath(path.dirname(pathToOpen)).getPath()
|
||||||
else
|
else
|
||||||
@project.addPath(pathToOpen)
|
pushFolderToOpen @project.getDirectoryForProjectPath(pathToOpen).getPath()
|
||||||
|
|
||||||
unless fs.isDirectorySync(pathToOpen)
|
unless fs.isDirectorySync(pathToOpen)
|
||||||
@workspace?.open(pathToOpen, {initialLine, initialColumn})
|
fileLocationsToOpen.push({pathToOpen, initialLine, initialColumn})
|
||||||
|
|
||||||
return
|
promise = Promise.resolve(null)
|
||||||
|
if foldersToAddToProject.length > 0
|
||||||
|
promise = @loadState(@getStateKey(foldersToAddToProject)).then (state) =>
|
||||||
|
if state and needsProjectPaths # only load state if this is the first path added to the project
|
||||||
|
files = (location.pathToOpen for location in fileLocationsToOpen)
|
||||||
|
@attemptRestoreProjectStateForPaths(state, foldersToAddToProject, files)
|
||||||
|
else
|
||||||
|
promises = []
|
||||||
|
@project.addPath(folder) for folder in foldersToAddToProject
|
||||||
|
for {pathToOpen, initialLine, initialColumn} in fileLocationsToOpen
|
||||||
|
promises.push @workspace?.open(pathToOpen, {initialLine, initialColumn})
|
||||||
|
Promise.all(promises)
|
||||||
|
else
|
||||||
|
promises = []
|
||||||
|
for {pathToOpen, initialLine, initialColumn} in fileLocationsToOpen
|
||||||
|
promises.push @workspace?.open(pathToOpen, {initialLine, initialColumn})
|
||||||
|
promise = Promise.all(promises)
|
||||||
|
|
||||||
|
promise.then ->
|
||||||
|
ipcRenderer.send 'window-command', 'window:locations-opened'
|
||||||
|
|
||||||
resolveProxy: (url) ->
|
resolveProxy: (url) ->
|
||||||
return new Promise (resolve, reject) =>
|
return new Promise (resolve, reject) =>
|
||||||
|
@ -89,6 +89,9 @@ class AtomWindow
|
|||||||
@emit 'window:loaded'
|
@emit 'window:loaded'
|
||||||
@resolveLoadedPromise()
|
@resolveLoadedPromise()
|
||||||
|
|
||||||
|
@browserWindow.on 'window:locations-opened', =>
|
||||||
|
@emit 'window:locations-opened'
|
||||||
|
|
||||||
@browserWindow.on 'enter-full-screen', =>
|
@browserWindow.on 'enter-full-screen', =>
|
||||||
@browserWindow.webContents.send('did-enter-full-screen')
|
@browserWindow.webContents.send('did-enter-full-screen')
|
||||||
|
|
||||||
|
@ -184,11 +184,7 @@ class Project extends Model
|
|||||||
#
|
#
|
||||||
# * `projectPath` {String} The path to the directory to add.
|
# * `projectPath` {String} The path to the directory to add.
|
||||||
addPath: (projectPath, options) ->
|
addPath: (projectPath, options) ->
|
||||||
directory = null
|
directory = @getDirectoryForProjectPath(projectPath)
|
||||||
for provider in @directoryProviders
|
|
||||||
break if directory = provider.directoryForURISync?(projectPath)
|
|
||||||
directory ?= @defaultDirectoryProvider.directoryForURISync(projectPath)
|
|
||||||
|
|
||||||
return unless directory.existsSync()
|
return unless directory.existsSync()
|
||||||
for existingDirectory in @getDirectories()
|
for existingDirectory in @getDirectories()
|
||||||
return if existingDirectory.getPath() is directory.getPath()
|
return if existingDirectory.getPath() is directory.getPath()
|
||||||
@ -203,6 +199,13 @@ class Project extends Model
|
|||||||
unless options?.emitEvent is false
|
unless options?.emitEvent is false
|
||||||
@emitter.emit 'did-change-paths', @getPaths()
|
@emitter.emit 'did-change-paths', @getPaths()
|
||||||
|
|
||||||
|
getDirectoryForProjectPath: (projectPath) ->
|
||||||
|
directory = null
|
||||||
|
for provider in @directoryProviders
|
||||||
|
break if directory = provider.directoryForURISync?(projectPath)
|
||||||
|
directory ?= @defaultDirectoryProvider.directoryForURISync(projectPath)
|
||||||
|
directory
|
||||||
|
|
||||||
# Public: remove a path from the project's list of root paths.
|
# Public: remove a path from the project's list of root paths.
|
||||||
#
|
#
|
||||||
# * `projectPath` {String} The path to remove.
|
# * `projectPath` {String} The path to remove.
|
||||||
|
Loading…
Reference in New Issue
Block a user