mirror of
https://github.com/atom/atom.git
synced 2026-01-22 21:38:10 -05:00
213 lines
6.5 KiB
CoffeeScript
213 lines
6.5 KiB
CoffeeScript
{remove, last} = require 'underscore-plus'
|
|
{join} = require 'path'
|
|
{Model} = require 'theorist'
|
|
Q = require 'q'
|
|
Serializable = require 'serializable'
|
|
Delegator = require 'delegato'
|
|
PaneContainer = require './pane-container'
|
|
Pane = require './pane'
|
|
|
|
# Public: Represents the view state of the entire window, including the panes at
|
|
# the center and panels around the periphery.
|
|
#
|
|
# An instance of this class is always available as the `atom.workspace` global.
|
|
module.exports =
|
|
class Workspace extends Model
|
|
atom.deserializers.add(this)
|
|
Serializable.includeInto(this)
|
|
|
|
@delegatesProperty 'activePane', 'activePaneItem', toProperty: 'paneContainer'
|
|
@delegatesMethod 'getPanes', 'saveAll', 'activateNextPane', 'activatePreviousPane',
|
|
toProperty: 'paneContainer'
|
|
|
|
@properties
|
|
paneContainer: -> new PaneContainer
|
|
fullScreen: false
|
|
destroyedItemUris: -> []
|
|
|
|
constructor: ->
|
|
super
|
|
@subscribe @paneContainer, 'item-destroyed', @onPaneItemDestroyed
|
|
@registerOpener (filePath) =>
|
|
switch filePath
|
|
when 'atom://.atom/stylesheet'
|
|
@open(atom.themes.getUserStylesheetPath())
|
|
when 'atom://.atom/keymap'
|
|
@open(atom.keymap.getUserKeymapPath())
|
|
when 'atom://.atom/config'
|
|
@open(atom.config.getUserConfigPath())
|
|
when 'atom://.atom/init-script'
|
|
@open(atom.getUserInitScriptPath())
|
|
|
|
# Called by the Serializable mixin during deserialization
|
|
deserializeParams: (params) ->
|
|
params.paneContainer = PaneContainer.deserialize(params.paneContainer)
|
|
params
|
|
|
|
# Called by the Serializable mixin during serialization.
|
|
serializeParams: ->
|
|
paneContainer: @paneContainer.serialize()
|
|
fullScreen: atom.isFullScreen()
|
|
|
|
# Public: Calls callback for every existing {Editor} and for all new {Editor}s.
|
|
# that are created.
|
|
#
|
|
# callback - A {Function} with an {Editor} as its only argument
|
|
eachEditor: (callback) ->
|
|
atom.project.eachEditor(callback)
|
|
|
|
# Public: Returns an {Array} of all open {Editor}s.
|
|
getEditors: ->
|
|
atom.project.getEditors()
|
|
|
|
# Public: Asynchronously opens a given a filepath in Atom.
|
|
#
|
|
# uri - A {String} uri.
|
|
# options - An options {Object} (default: {}).
|
|
# :initialLine - A {Number} indicating which line number to open to.
|
|
# :split - A {String} ('left' or 'right') that opens the filePath in a new
|
|
# pane or an existing one if it exists.
|
|
# :changeFocus - A {Boolean} that allows the filePath to be opened without
|
|
# changing focus.
|
|
# :searchAllPanes - A {Boolean} that will open existing editors from any pane
|
|
# if the uri is already open (default: false)
|
|
#
|
|
# Returns a promise that resolves to the {Editor} for the file URI.
|
|
open: (uri, options={}) ->
|
|
searchAllPanes = options.searchAllPanes
|
|
split = options.split
|
|
uri = atom.project.resolve(uri)
|
|
|
|
pane = @paneContainer.paneForUri(uri) if searchAllPanes
|
|
pane ?= switch split
|
|
when 'left'
|
|
@activePane.findLeftmostSibling()
|
|
when 'right'
|
|
@activePane.findOrCreateRightmostSibling()
|
|
else
|
|
@activePane
|
|
|
|
@openUriInPane(uri, pane, options)
|
|
|
|
openLicense: ->
|
|
@open(join(atom.getLoadSettings().resourcePath, 'LICENSE'))
|
|
|
|
# Only used in specs
|
|
openSync: (uri='', options={}) ->
|
|
{initialLine} = options
|
|
# TODO: Remove deprecated changeFocus option
|
|
activatePane = options.activatePane ? options.changeFocus ? true
|
|
uri = atom.project.resolve(uri)
|
|
|
|
item = @activePane.itemForUri(uri)
|
|
if uri
|
|
item ?= opener(uri, options) for opener in @getOpeners() when !item
|
|
item ?= atom.project.openSync(uri, {initialLine})
|
|
|
|
@activePane.activateItem(item)
|
|
@itemOpened(item)
|
|
@activePane.activate() if activatePane
|
|
item
|
|
|
|
openUriInPane: (uri, pane, options={}) ->
|
|
changeFocus = options.changeFocus ? true
|
|
|
|
if uri?
|
|
item = pane.itemForUri(uri)
|
|
item ?= opener(atom.project.resolve(uri), options) for opener in @getOpeners() when !item
|
|
item ?= atom.project.open(uri, options)
|
|
|
|
Q(item)
|
|
.then (item) =>
|
|
if not pane
|
|
pane = new Pane(items: [item])
|
|
@paneContainer.root = pane
|
|
@itemOpened(item)
|
|
pane.activateItem(item)
|
|
pane.activate() if changeFocus
|
|
@emit "uri-opened"
|
|
item
|
|
.catch (error) ->
|
|
console.error(error.stack ? error)
|
|
|
|
# Public: Reopens the last-closed item uri if it hasn't already been reopened.
|
|
reopenItemSync: ->
|
|
if uri = @destroyedItemUris.pop()
|
|
@openSync(uri)
|
|
|
|
# Public: Register an opener for a uri.
|
|
#
|
|
# An {Editor} will be used if no openers return a value.
|
|
#
|
|
# ## Example
|
|
# ```coffeescript
|
|
# atom.project.registerOpener (uri) ->
|
|
# if path.extname(uri) is '.toml'
|
|
# return new TomlEditor(uri)
|
|
# ```
|
|
#
|
|
# opener - A {Function} to be called when a path is being opened.
|
|
registerOpener: (opener) ->
|
|
atom.project.registerOpener(opener)
|
|
|
|
# Public: Remove a registered opener.
|
|
unregisterOpener: (opener) ->
|
|
atom.project.unregisterOpener(opener)
|
|
|
|
getOpeners: ->
|
|
atom.project.openers
|
|
|
|
# Public: Returns the active {Pane}.
|
|
getActivePane: ->
|
|
@paneContainer.activePane
|
|
|
|
# Public: Returns the first pane {Pane} with an item for the given uri or
|
|
# undefined if none exists.
|
|
paneForUri: (uri) ->
|
|
@paneContainer.paneForUri(uri)
|
|
|
|
# Public: save the active item.
|
|
saveActivePaneItem: ->
|
|
@activePane?.saveActiveItem()
|
|
|
|
# Public: save the active item as.
|
|
saveActivePaneItemAs: ->
|
|
@activePane?.saveActiveItemAs()
|
|
|
|
# Public: destroy/close the active item.
|
|
destroyActivePaneItem: ->
|
|
@activePane?.destroyActiveItem()
|
|
|
|
# Public: destroy/close the active pane.
|
|
destroyActivePane: ->
|
|
@activePane?.destroy()
|
|
|
|
# Public: Returns an {Editor} if the active pane item is an {Editor},
|
|
# or null otherwise.
|
|
getActiveEditor: ->
|
|
@activePane?.getActiveEditor()
|
|
|
|
increaseFontSize: ->
|
|
atom.config.set("editor.fontSize", atom.config.get("editor.fontSize") + 1)
|
|
|
|
decreaseFontSize: ->
|
|
fontSize = atom.config.get("editor.fontSize")
|
|
atom.config.set("editor.fontSize", fontSize - 1) if fontSize > 1
|
|
|
|
resetFontSize: ->
|
|
atom.config.restoreDefault("editor.fontSize")
|
|
|
|
# Removes the item's uri from the list of potential items to reopen.
|
|
itemOpened: (item) ->
|
|
if uri = item.getUri?()
|
|
remove(@destroyedItemUris, uri)
|
|
|
|
# Adds the destroyed item's uri to the list of items to reopen.
|
|
onPaneItemDestroyed: (item) =>
|
|
if uri = item.getUri?()
|
|
@destroyedItemUris.push(uri)
|
|
|
|
# Called by Model superclass when destroyed
|
|
destroyed: ->
|
|
@paneContainer.destroy()
|