Merge branch 'master' into as-public-ci

This commit is contained in:
Antonio Scandurra 2015-04-08 08:30:58 +02:00
commit 8720af76a4
31 changed files with 296 additions and 168 deletions

View File

@ -4,13 +4,14 @@
The following is a set of guidelines for contributing to Atom and its packages,
which are hosted in the [Atom Organization](https://github.com/atom) on GitHub.
If you're unsure which package is causing your problem or if you're having an
issue with Atom core, please open an issue on the [main atom repository](https://github.com/atom/atom/issues).
These are just guidelines, not rules, use your best judgment and feel free to
propose changes to this document in a pull request.
## Submitting Issues
* You can create an issue [here](https://github.com/atom/atom/issues/new), but
before doing that please read the notes below on debugging and submitting issues,
and include as many details as possible with your report.
* Check the [debugging guide](https://atom.io/docs/latest/hacking-atom-debugging) for tips
on debugging. You might be able to find the cause of the problem and fix
things yourself.
@ -24,7 +25,8 @@ propose changes to this document in a pull request.
will be logged. If you can reproduce the error, use this approach to get the
full stack trace and include it in the issue.
* On Mac, check Console.app for stack traces to include if reporting a crash.
* Perform a cursory search to see if a similar issue has already been submitted.
* Perform a [cursory search](https://github.com/issues?q=+is%3Aissue+user%3Aatom)
to see if a similar issue has already been submitted.
* Please setup a [profile picture](https://help.github.com/articles/how-do-i-set-up-my-profile-picture)
to make yourself recognizable and so we can all get to know each other better.
@ -38,6 +40,10 @@ many packages and themes that are stored in other repos under the
[language-javascript](https://github.com/atom/language-javascript), and
[atom-light-ui](https://github.com/atom/atom-light-ui).
If your issue is related to a specific package, open an issue on that package's
issue tracker. If you're unsure which package is causing your problem or if
you're having an issue with Atom core, open an issue on this repository.
For more information on how to work with Atom's official packages, see
[Contributing to Atom Packages](https://github.com/atom/atom/blob/master/docs/contributing-to-packages.md)

View File

@ -7,7 +7,7 @@
},
"dependencies": {
"async": "~0.2.9",
"donna": "1.0.9",
"donna": "1.0.10",
"formidable": "~1.0.14",
"fs-plus": "2.x",
"github-releases": "~0.2.0",

View File

@ -1,7 +0,0 @@
'editor':
'fontSize': 16
'core':
'themes': [
'one-dark-ui'
'one-dark-syntax'
]

View File

@ -18,7 +18,6 @@
'ctrl-d': 'core:delete'
# Atom Specific
'cmd-O': 'application:open-dev'
'cmd-alt-ctrl-s': 'application:run-all-specs'
'enter': 'core:confirm'
'escape': 'core:cancel'
@ -37,6 +36,7 @@
'cmd-N': 'application:new-window'
'cmd-W': 'window:close'
'cmd-o': 'application:open'
'cmd-O': 'application:add-project-folder'
'cmd-T': 'pane:reopen-closed-item'
'cmd-n': 'application:new-file'
'cmd-s': 'core:save'

View File

@ -10,8 +10,8 @@
'ctrl-shift-i': 'window:toggle-dev-tools'
'ctrl-alt-p': 'window:run-package-specs'
'ctrl-alt-s': 'application:run-all-specs'
'ctrl-alt-o': 'application:open-dev'
'ctrl-shift-o': 'application:open-folder'
'ctrl-alt-o': 'application:add-project-folder'
'ctrl-shift-pageup': 'pane:move-item-left'
'ctrl-shift-pagedown': 'pane:move-item-right'
'F11': 'window:toggle-full-screen'

View File

@ -14,8 +14,8 @@
'ctrl-alt-i': 'window:toggle-dev-tools'
'ctrl-alt-p': 'window:run-package-specs'
'ctrl-alt-s': 'application:run-all-specs'
'ctrl-alt-o': 'application:open-dev'
'ctrl-shift-o': 'application:open-folder'
'ctrl-alt-o': 'application:add-project-folder'
'ctrl-shift-left': 'pane:move-item-left'
'ctrl-shift-right': 'pane:move-item-right'
'F11': 'window:toggle-full-screen'

View File

@ -34,6 +34,7 @@
{ label: 'New Window', command: 'application:new-window' }
{ label: 'New File', command: 'application:new-file' }
{ label: 'Open...', command: 'application:open' }
{ label: 'Add Project Folder...', command: 'application:add-project-folder' }
{ label: 'Reopen Last Item', command: 'pane:reopen-closed-item' }
{ type: 'separator' }
{ label: 'Save', command: 'core:save' }

View File

@ -6,6 +6,7 @@
{ label: '&New File', command: 'application:new-file' }
{ label: '&Open File...', command: 'application:open-file' }
{ label: 'Open Folder...', command: 'application:open-folder' }
{ label: 'Add Project Folder...', command: 'application:add-project-folder' }
{ label: 'Reopen Last &Item', command: 'pane:reopen-closed-item' }
{ type: 'separator' }
{ label: '&Save', command: 'core:save' }
@ -95,6 +96,25 @@
{ label: '&Reload', command: 'window:reload' }
{ label: 'Toggle &Full Screen', command: 'window:toggle-full-screen' }
{ label: 'Toggle Menu Bar', command: 'window:toggle-menu-bar' }
{
label: 'Panes'
submenu: [
{ label: 'Split Up', command: 'pane:split-up' }
{ label: 'Split Down', command: 'pane:split-down' }
{ label: 'Split Left', command: 'pane:split-left' }
{ label: 'Split Right', command: 'pane:split-right' }
{ type: 'separator' }
{ label: 'Focus Next Pane', command: 'window:focus-next-pane' }
{ label: 'Focus Previous Pane', command: 'window:focus-previous-pane' }
{ type: 'separator' }
{ label: 'Focus Pane Above', command: 'window:focus-pane-above' }
{ label: 'Focus Pane Below', command: 'window:focus-pane-below' }
{ label: 'Focus Pane On Left', command: 'window:focus-pane-on-left' }
{ label: 'Focus Pane On Right', command: 'window:focus-pane-on-right' }
{ type: 'separator' }
{ label: 'Close Pane', command: 'pane:close' }
]
}
{
label: 'Developer'
submenu: [

View File

@ -6,6 +6,7 @@
{ label: '&New File', command: 'application:new-file' }
{ label: '&Open File...', command: 'application:open-file' }
{ label: 'Open Folder...', command: 'application:open-folder' }
{ label: 'Add Project Folder...', command: 'application:add-project-folder' }
{ label: 'Reopen Last &Item', command: 'pane:reopen-closed-item' }
{ type: 'separator' }
{ label: 'Se&ttings', command: 'application:show-settings' }

View File

@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "0.190.0",
"version": "0.191.0",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/browser/main.js",
"repository": {
@ -76,26 +76,26 @@
"atom-light-ui": "0.41.0",
"base16-tomorrow-dark-theme": "0.25.0",
"base16-tomorrow-light-theme": "0.8.0",
"one-dark-ui": "0.5.0",
"one-dark-ui": "0.6.2",
"one-dark-syntax": "0.3.0",
"one-light-syntax": "0.4.0",
"one-light-ui": "0.4.0",
"one-light-ui": "0.5.2",
"solarized-dark-syntax": "0.32.0",
"solarized-light-syntax": "0.19.0",
"archive-view": "0.55.0",
"autocomplete": "0.44.0",
"autoflow": "0.22.0",
"autosave": "0.20.0",
"background-tips": "0.23.0",
"background-tips": "0.24.0",
"bookmarks": "0.35.0",
"bracket-matcher": "0.73.0",
"command-palette": "0.35.0",
"deprecation-cop": "0.39.0",
"deprecation-cop": "0.40.0",
"dev-live-reload": "0.45.0",
"encoding-selector": "0.19.0",
"exception-reporting": "0.24.0",
"feedback": "0.38.0",
"find-and-replace": "0.159.0",
"find-and-replace": "0.160.0",
"fuzzy-finder": "0.72.0",
"git-diff": "0.54.0",
"go-to-line": "0.30.0",
@ -104,37 +104,37 @@
"incompatible-packages": "0.24.0",
"keybinding-resolver": "0.30.0",
"link": "0.30.0",
"markdown-preview": "0.147.0",
"markdown-preview": "0.148.0",
"metrics": "0.45.0",
"notifications": "0.35.0",
"notifications": "0.36.0",
"open-on-github": "0.36.0",
"package-generator": "0.38.0",
"release-notes": "0.52.0",
"settings-view": "0.187.0",
"snippets": "0.87.0",
"snippets": "0.88.0",
"spell-check": "0.55.0",
"status-bar": "0.66.0",
"status-bar": "0.67.0",
"styleguide": "0.44.0",
"symbols-view": "0.93.0",
"tabs": "0.67.0",
"timecop": "0.31.0",
"tree-view": "0.168.0",
"tree-view": "0.170.0",
"update-package-dependencies": "0.9.0",
"welcome": "0.26.0",
"whitespace": "0.29.0",
"wrap-guide": "0.32.0",
"language-c": "0.43.0",
"language-clojure": "0.13.0",
"language-c": "0.44.0",
"language-clojure": "0.14.0",
"language-coffee-script": "0.39.0",
"language-csharp": "0.5.0",
"language-css": "0.28.0",
"language-gfm": "0.67.0",
"language-git": "0.10.0",
"language-go": "0.22.0",
"language-go": "0.23.0",
"language-html": "0.31.0",
"language-hyperlink": "0.12.2",
"language-java": "0.14.0",
"language-javascript": "0.67.0",
"language-javascript": "0.70.0",
"language-json": "0.14.0",
"language-less": "0.25.0",
"language-make": "0.14.0",
@ -144,7 +144,7 @@
"language-php": "0.22.0",
"language-property-list": "0.8.0",
"language-python": "0.33.0",
"language-ruby": "0.50.0",
"language-ruby": "0.51.0",
"language-ruby-on-rails": "0.21.0",
"language-sass": "0.36.0",
"language-shellscript": "0.13.0",

View File

@ -180,3 +180,19 @@ describe "the `atom` global", ->
it "does not open an empty buffer", ->
atom.openInitialEmptyEditorIfNecessary()
expect(atom.workspace.open).not.toHaveBeenCalled()
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", ->
initialPaths = atom.project.getPaths()
tempDirectory = temp.mkdirSync("a-new-directory")
spyOn(atom, "pickFolder").andCallFake (callback) -> callback(null)
atom.addProjectFolder()
expect(atom.project.getPaths()).toEqual(initialPaths)

View File

@ -987,7 +987,6 @@ describe "Config", ->
expect(fs.existsSync(atom.config.configDirPath)).toBeTruthy()
expect(fs.existsSync(path.join(atom.config.configDirPath, 'packages'))).toBeTruthy()
expect(fs.isFileSync(path.join(atom.config.configDirPath, 'snippets.cson'))).toBeTruthy()
expect(fs.isFileSync(path.join(atom.config.configDirPath, 'config.cson'))).toBeTruthy()
expect(fs.isFileSync(path.join(atom.config.configDirPath, 'init.coffee'))).toBeTruthy()
expect(fs.isFileSync(path.join(atom.config.configDirPath, 'styles.less'))).toBeTruthy()

View File

@ -221,7 +221,7 @@ describe "Project", ->
beforeEach ->
absolutePath = require.resolve('./fixtures/dir/a')
newBufferHandler = jasmine.createSpy('newBufferHandler')
atom.project.on 'buffer-created', newBufferHandler
atom.project.onDidAddBuffer(newBufferHandler)
describe "when given an absolute path that isn't currently open", ->
it "returns a new edit session for the given path and emits 'buffer-created'", ->
@ -502,8 +502,12 @@ describe "Project", ->
describe ".eachBuffer(callback)", ->
beforeEach ->
jasmine.snapshotDeprecations()
atom.project.bufferForPathSync('a')
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "invokes the callback for existing buffer", ->
count = 0
count = 0

View File

@ -72,7 +72,6 @@ if specDirectory
isCoreSpec = specDirectory == fs.realpathSync(__dirname)
beforeEach ->
Grim.clearDeprecations() if isCoreSpec
$.fx.off = true
documentTitle = null
projectPath = specProjectPath ? path.join(@specDirectory, 'fixtures')

View File

@ -728,7 +728,7 @@ describe "TextEditorComponent", ->
expect(cursorNodes[0].style['-webkit-transform']).toBe "translate(#{10 * charWidth}px, #{4 * lineHeightInPixels}px)"
expect(cursorNodes[1].style['-webkit-transform']).toBe "translate(#{11 * charWidth}px, #{8 * lineHeightInPixels}px)"
wrapperView.on 'cursor:moved', cursorMovedListener = jasmine.createSpy('cursorMovedListener')
editor.onDidChangeCursorPosition cursorMovedListener = jasmine.createSpy('cursorMovedListener')
cursor3.setScreenPosition([4, 11], autoscroll: false)
nextAnimationFrame()
expect(cursorNodes[0].style['-webkit-transform']).toBe "translate(#{11 * charWidth}px, #{4 * lineHeightInPixels}px)"

View File

@ -3370,6 +3370,20 @@ describe "TextEditor", ->
expect(buffer.lineForRow(0)).toBe(line2)
expect(buffer.getLineCount()).toBe(count - 2)
it "deletes a line only once when multiple selections are on the same line", ->
line1 = buffer.lineForRow(1)
count = buffer.getLineCount()
editor.setSelectedBufferRanges([
[[0, 1], [0, 2]],
[[0, 4], [0, 5]]
])
expect(buffer.lineForRow(0)).not.toBe(line1)
editor.deleteLine()
expect(buffer.lineForRow(0)).toBe(line1)
expect(buffer.getLineCount()).toBe(count - 1)
it "only deletes first line if only newline is selected on second line", ->
editor.setSelectedBufferRange([[0, 2], [1, 0]])
line1 = buffer.lineForRow(1)

View File

@ -412,10 +412,11 @@ class Atom extends Model
open: (options) ->
ipc.send('open', options)
# Extended: Show the native dialog to prompt the user to select a folder.
# Extended: Prompt the user to select one or more folders.
#
# * `callback` A {Function} to call once the user has selected a folder.
# * `path` {String} the path to the folder the user selected.
# * `callback` A {Function} to call once the user has confirmed the selection.
# * `paths` An {Array} of {String} paths that the user selected, or `null`
# if the user dismissed the dialog.
pickFolder: (callback) ->
responseChannel = "atom-pick-folder-response"
ipc.on responseChannel, (path) ->
@ -728,7 +729,10 @@ class Atom extends Model
@workspace = Workspace.deserialize(@state.workspace) ? new Workspace
workspaceElement = @views.getView(@workspace)
@__workspaceView = workspaceElement.__spacePenView
if includeDeprecatedAPIs
@__workspaceView = workspaceElement.__spacePenView
@deserializeTimings.workspace = Date.now() - startTime
@keymaps.defaultTarget = workspaceElement
@ -773,6 +777,10 @@ class Atom extends Model
setRepresentedFilename: (filename) ->
ipc.send('call-window-method', 'setRepresentedFilename', filename)
addProjectFolder: ->
@pickFolder (selectedPaths = []) =>
@project.addPath(selectedPath) for selectedPath in selectedPaths
showSaveDialog: (callback) ->
callback(showSaveDialogSync())

View File

@ -169,7 +169,7 @@ class AtomApplication
@on 'application:open-roadmap', -> require('shell').openExternal('https://atom.io/roadmap?app')
@on 'application:open-faq', -> require('shell').openExternal('https://atom.io/faq')
@on 'application:open-terms-of-use', -> require('shell').openExternal('https://atom.io/terms')
@on 'application:report-issue', -> require('shell').openExternal('https://github.com/atom/atom/issues/new')
@on 'application:report-issue', -> require('shell').openExternal('https://github.com/atom/atom/blob/master/CONTRIBUTING.md#submitting-issues')
@on 'application:search-issues', -> require('shell').openExternal('https://github.com/issues?q=+is%3Aissue+user%3Aatom')
@on 'application:install-update', -> @autoUpdateManager.install()

View File

@ -1,6 +1,12 @@
clipboard = require 'clipboard'
crypto = require 'crypto'
# Using clipboard in renderer process is not safe on Linux.
clipboard =
if process.platform is 'linux'
require('remote').require 'clipboard'
else
require 'clipboard'
# Extended: Represents the clipboard used for copying and pasting in Atom.
#
# An instance of this class is always available as the `atom.clipboard` global.

View File

@ -1,6 +1,5 @@
_ = require 'underscore-plus'
fs = require 'fs-plus'
EmitterMixin = require('emissary').Emitter
{CompositeDisposable, Disposable, Emitter} = require 'event-kit'
CSON = require 'season'
path = require 'path'
@ -290,7 +289,6 @@ ScopeDescriptor = require './scope-descriptor'
#
module.exports =
class Config
EmitterMixin.includeInto(this)
@schemaEnforcers = {}
@addSchemaEnforcer: (typeName, enforcerFunction) ->
@ -1147,6 +1145,9 @@ withoutEmptyObjects = (object) ->
resultObject
if Grim.includeDeprecatedAPIs
EmitterMixin = require('emissary').Emitter
EmitterMixin.includeInto(Config)
Config::restoreDefault = (scopeSelector, keyPath) ->
Grim.deprecate("Use ::unset instead.")
@unset(scopeSelector, keyPath)

View File

@ -1,11 +1,11 @@
_ = require 'underscore-plus'
Serializable = require 'serializable'
{Model} = require 'theorist'
{CompositeDisposable, Emitter} = require 'event-kit'
{Point, Range} = require 'text-buffer'
TokenizedBuffer = require './tokenized-buffer'
RowMap = require './row-map'
Fold = require './fold'
Model = require './model'
Token = require './token'
Decoration = require './decoration'
Marker = require './marker'
@ -20,19 +20,6 @@ module.exports =
class DisplayBuffer extends Model
Serializable.includeInto(this)
@properties
softWrapped: null
editorWidthInChars: null
lineHeightInPixels: null
defaultCharWidth: null
height: null
width: null
scrollTop: 0
scrollLeft: 0
scrollWidth: 0
verticalScrollbarWidth: 15
horizontalScrollbarHeight: 15
verticalScrollMargin: 2
horizontalScrollMargin: 6
scopedCharacterWidthsChangeCount: 0
@ -135,6 +122,20 @@ class DisplayBuffer extends Model
onDidChangeCharacterWidths: (callback) ->
@emitter.on 'did-change-character-widths', callback
onDidChangeScrollTop: (callback) ->
@emitter.on 'did-change-scroll-top', callback
onDidChangeScrollLeft: (callback) ->
@emitter.on 'did-change-scroll-left', callback
observeScrollTop: (callback) ->
callback(@scrollTop)
@onDidChangeScrollTop(callback)
observeScrollLeft: (callback) ->
callback(@scrollLeft)
@onDidChangeScrollLeft(callback)
observeDecorations: (callback) ->
callback(decoration) for decoration in @getDecorations()
@onDidAddDecoration(callback)
@ -250,7 +251,11 @@ class DisplayBuffer extends Model
getScrollTop: -> @scrollTop
setScrollTop: (scrollTop) ->
@scrollTop = Math.round(Math.max(0, Math.min(@getMaxScrollTop(), scrollTop)))
scrollTop = Math.round(Math.max(0, Math.min(@getMaxScrollTop(), scrollTop)))
unless scrollTop is @scrollTop
@scrollTop = scrollTop
@emitter.emit 'did-change-scroll-top', @scrollTop
@scrollTop
getMaxScrollTop: ->
@getScrollHeight() - @getClientHeight()
@ -262,7 +267,11 @@ class DisplayBuffer extends Model
getScrollLeft: -> @scrollLeft
setScrollLeft: (scrollLeft) ->
@scrollLeft = Math.round(Math.max(0, Math.min(@getScrollWidth() - @getClientWidth(), scrollLeft)))
scrollLeft = Math.round(Math.max(0, Math.min(@getScrollWidth() - @getClientWidth(), scrollLeft)))
unless scrollLeft is @scrollLeft
@scrollLeft = scrollLeft
@emitter.emit 'did-change-scroll-left', @scrollLeft
@scrollLeft
getMaxScrollLeft: ->
@getScrollWidth() - @getClientWidth()
@ -1228,6 +1237,19 @@ class DisplayBuffer extends Model
@foldsByMarkerId[marker.id]
if Grim.includeDeprecatedAPIs
DisplayBuffer.properties
softWrapped: null
editorWidthInChars: null
lineHeightInPixels: null
defaultCharWidth: null
height: null
width: null
scrollTop: 0
scrollLeft: 0
scrollWidth: 0
verticalScrollbarWidth: 15
horizontalScrollbarHeight: 15
EmitterMixin = require('emissary').Emitter
DisplayBuffer::on = (eventName) ->
@ -1256,3 +1278,15 @@ if Grim.includeDeprecatedAPIs
Grim.deprecate("DisplayBuffer::on is deprecated. Use event subscription methods instead.")
EmitterMixin::on.apply(this, arguments)
else
DisplayBuffer::softWrapped = null
DisplayBuffer::editorWidthInChars = null
DisplayBuffer::lineHeightInPixels = null
DisplayBuffer::defaultCharWidth = null
DisplayBuffer::height = null
DisplayBuffer::width = null
DisplayBuffer::scrollTop = 0
DisplayBuffer::scrollLeft = 0
DisplayBuffer::scrollWidth = 0
DisplayBuffer::verticalScrollbarWidth = 15
DisplayBuffer::horizontalScrollbarHeight = 15

View File

@ -1,14 +1,10 @@
{Range} = require 'text-buffer'
_ = require 'underscore-plus'
{OnigRegExp} = require 'oniguruma'
{Emitter, Subscriber} = require 'emissary'
ScopeDescriptor = require './scope-descriptor'
module.exports =
class LanguageMode
Emitter.includeInto(this)
Subscriber.includeInto(this)
# Sets up a `LanguageMode` for the given {TextEditor}.
#
# editor - The {TextEditor} to associate with
@ -16,7 +12,6 @@ class LanguageMode
{@buffer} = @editor
destroy: ->
@unsubscribe()
toggleLineCommentForBufferRow: (row) ->
@toggleLineCommentsForBufferRows(row, row)

View File

@ -276,8 +276,7 @@ class PackageManager
getPackageDependencies: ->
unless @packageDependencies?
try
metadataPath = path.join(@resourcePath, 'package.json')
{@packageDependencies} = JSON.parse(fs.readFileSync(metadataPath)) ? {}
@packageDependencies = require('../package.json')?.packageDependencies
@packageDependencies ?= {}
@packageDependencies

View File

@ -1,7 +1,7 @@
{Model} = require 'theorist'
{Emitter, CompositeDisposable} = require 'event-kit'
{flatten} = require 'underscore-plus'
Serializable = require 'serializable'
Model = require './model'
module.exports =
class PaneAxis extends Model

View File

@ -1,7 +1,8 @@
{find, flatten} = require 'underscore-plus'
{Model} = require 'theorist'
Grim = require 'grim'
{Emitter, CompositeDisposable} = require 'event-kit'
Serializable = require 'serializable'
Model = require './model'
Pane = require './pane'
PaneElement = require './pane-element'
PaneContainerElement = require './pane-container-element'
@ -18,19 +19,14 @@ class PaneContainer extends Model
@version: 1
@properties
activePane: null
root: null
@behavior 'activePaneItem', ->
@$activePane
.switch((activePane) -> activePane?.$activeItem)
.distinctUntilChanged()
constructor: (params) ->
super
unless Grim.includeDeprecatedAPIs
@activePane = params?.activePane
@emitter = new Emitter
@subscriptions = new CompositeDisposable
@ -236,3 +232,12 @@ class PaneContainer extends Model
removedPaneItem: (item) ->
@itemRegistry.removeItem(item)
if Grim.includeDeprecatedAPIs
PaneContainer.properties
activePane: null
PaneContainer.behavior 'activePaneItem', ->
@$activePane
.switch((activePane) -> activePane?.$activeItem)
.distinctUntilChanged()

View File

@ -1,8 +1,8 @@
{find, compact, extend, last} = require 'underscore-plus'
{Model} = require 'theorist'
{Emitter} = require 'event-kit'
Serializable = require 'serializable'
Grim = require 'grim'
Model = require './model'
PaneAxis = require './pane-axis'
TextEditor = require './text-editor'
@ -15,23 +15,13 @@ class Pane extends Model
atom.deserializers.add(this)
Serializable.includeInto(this)
@properties
container: undefined
activeItem: undefined
focused: false
# Public: Only one pane is considered *active* at a time. A pane is activated
# when it is focused, and when focus returns to the pane container after
# moving to another element such as a panel, it returns to the active pane.
@behavior 'active', ->
@$container
.switch((container) -> container?.$activePane)
.map((activePane) => activePane is this)
.distinctUntilChanged()
constructor: (params) ->
super
unless Grim.includeDeprecatedAPIs
@container = params?.container
@activeItem = params?.activeItem
@emitter = new Emitter
@itemSubscriptions = new WeakMap
@items = []
@ -41,9 +31,9 @@ class Pane extends Model
# Called by the Serializable mixin during serialization.
serializeParams: ->
if Grim.includeDeprecatedAPIs and typeof @activeItem?.getURI is 'function'
if typeof @activeItem?.getURI is 'function'
activeItemURI = @activeItem.getURI()
else if typeof @activeItem?.getUri is 'function'
else if Grim.includeDeprecatedAPIs and typeof @activeItem?.getUri is 'function'
activeItemURI = @activeItem.getUri()
id: @id
@ -59,7 +49,7 @@ class Pane extends Model
params.activeItem = find params.items, (item) ->
if typeof item.getURI is 'function'
itemURI = item.getURI()
else if typeof item.getUri is 'function'
else if Grim.includeDeprecatedAPIs and typeof item.getUri is 'function'
itemURI = item.getUri()
itemURI is activeItemURI
@ -313,7 +303,7 @@ class Pane extends Model
if typeof item.onDidDestroy is 'function'
@itemSubscriptions.set item, item.onDidDestroy => @removeItem(item, true)
else if typeof item.on is 'function'
else if Grim.includeDeprecatedAPIs and typeof item.on is 'function'
@subscribe item, 'destroyed', => @removeItem(item, true)
@items.splice(index, 0, item)
@ -340,7 +330,7 @@ class Pane extends Model
index = @items.indexOf(item)
return if index is -1
if typeof item.on is 'function'
if Grim.includeDeprecatedAPIs and typeof item.on is 'function'
@unsubscribe item
@unsubscribeFromItem(item)
@ -661,6 +651,17 @@ class Pane extends Model
throw error
if Grim.includeDeprecatedAPIs
Pane.properties
container: undefined
activeItem: undefined
focused: false
Pane.behavior 'active', ->
@$container
.switch((container) -> container?.$activePane)
.map((activePane) => activePane is this)
.distinctUntilChanged()
Pane::on = (eventName) ->
switch eventName
when 'activated'
@ -701,3 +702,7 @@ if Grim.includeDeprecatedAPIs
Pane::activateItemForUri = (uri) ->
Grim.deprecate("Use `::activateItemForURI` instead.")
@activateItemForURI(uri)
else
Pane::container = undefined
Pane::activeItem = undefined
Pane::focused = undefined

View File

@ -5,7 +5,6 @@ _ = require 'underscore-plus'
fs = require 'fs-plus'
Q = require 'q'
{includeDeprecatedAPIs, deprecate} = require 'grim'
{Subscriber} = require 'emissary'
{Emitter} = require 'event-kit'
Serializable = require 'serializable'
TextBuffer = require 'text-buffer'
@ -171,7 +170,9 @@ class Project extends Model
#
# * `projectPaths` {Array} of {String} paths.
setPaths: (projectPaths) ->
rootDirectory.off() for rootDirectory in @rootDirectories
if includeDeprecatedAPIs
rootDirectory.off() for rootDirectory in @rootDirectories
repository?.destroy() for repository in @repositories
@rootDirectories = []
@repositories = []
@ -225,7 +226,7 @@ class Project extends Model
if indexToRemove?
[removedDirectory] = @rootDirectories.splice(indexToRemove, 1)
[removedRepository] = @repositories.splice(indexToRemove, 1)
removedDirectory.off()
removedDirectory.off() if includeDeprecatedAPIs
removedRepository?.destroy() unless removedRepository in @repositories
@emit "path-changed" if includeDeprecatedAPIs
@emitter.emit "did-change-paths", @getPaths()

View File

@ -3,13 +3,12 @@ path = require 'path'
Serializable = require 'serializable'
Delegator = require 'delegato'
{includeDeprecatedAPIs, deprecate} = require 'grim'
{Model} = require 'theorist'
EmitterMixin = require('emissary').Emitter
{CompositeDisposable, Emitter} = require 'event-kit'
{Point, Range} = TextBuffer = require 'text-buffer'
LanguageMode = require './language-mode'
DisplayBuffer = require './display-buffer'
Cursor = require './cursor'
Model = require './model'
Selection = require './selection'
TextMateScopeSelector = require('first-mate').ScopeSelector
{Directory} = require "pathwatcher"
@ -74,14 +73,11 @@ class TextEditor extends Model
'autoDecreaseIndentForBufferRow', 'toggleLineCommentForBufferRow', 'toggleLineCommentsForBufferRows',
toProperty: 'languageMode'
@delegatesProperties '$lineHeightInPixels', '$defaultCharWidth', '$height', '$width',
'$verticalScrollbarWidth', '$horizontalScrollbarHeight', '$scrollTop', '$scrollLeft',
toProperty: 'displayBuffer'
constructor: ({@softTabs, initialLine, initialColumn, tabLength, softWrapped, @displayBuffer, buffer, registerEditor, suppressCursorCreation, @mini, @placeholderText, @gutterVisible}) ->
super
@emitter = new Emitter
@disposables = new CompositeDisposable
@cursors = []
@selections = []
@ -108,10 +104,11 @@ class TextEditor extends Model
@setEncoding(atom.config.get('core.fileEncoding', scope: @getRootScopeDescriptor()))
@subscribe @$scrollTop, (scrollTop) =>
@disposables.add @displayBuffer.onDidChangeScrollTop (scrollTop) =>
@emit 'scroll-top-changed', scrollTop if includeDeprecatedAPIs
@emitter.emit 'did-change-scroll-top', scrollTop
@subscribe @$scrollLeft, (scrollLeft) =>
@disposables.add @displayBuffer.onDidChangeScrollLeft (scrollLeft) =>
@emit 'scroll-left-changed', scrollLeft if includeDeprecatedAPIs
@emitter.emit 'did-change-scroll-left', scrollLeft
@ -131,16 +128,16 @@ class TextEditor extends Model
subscribeToBuffer: ->
@buffer.retain()
@subscribe @buffer.onDidChangePath =>
@disposables.add @buffer.onDidChangePath =>
unless atom.project.getPaths().length > 0
atom.project.setPaths([path.dirname(@getPath())])
@emit "title-changed" if includeDeprecatedAPIs
@emitter.emit 'did-change-title', @getTitle()
@emit "path-changed" if includeDeprecatedAPIs
@emitter.emit 'did-change-path', @getPath()
@subscribe @buffer.onDidChangeEncoding =>
@disposables.add @buffer.onDidChangeEncoding =>
@emitter.emit 'did-change-encoding', @getEncoding()
@subscribe @buffer.onDidDestroy => @destroy()
@disposables.add @buffer.onDidDestroy => @destroy()
# TODO: remove these when we remove the deprecations. They are old events.
if includeDeprecatedAPIs
@ -151,18 +148,19 @@ class TextEditor extends Model
@preserveCursorPositionOnBufferReload()
subscribeToDisplayBuffer: ->
@subscribe @displayBuffer.onDidCreateMarker @handleMarkerCreated
@subscribe @displayBuffer.onDidUpdateMarkers => @mergeIntersectingSelections()
@subscribe @displayBuffer.onDidChangeGrammar => @handleGrammarChange()
@subscribe @displayBuffer.onDidTokenize => @handleTokenization()
@subscribe @displayBuffer.onDidChange (e) =>
@emit 'screen-lines-changed', e
@disposables.add @displayBuffer.onDidCreateMarker @handleMarkerCreated
@disposables.add @displayBuffer.onDidUpdateMarkers => @mergeIntersectingSelections()
@disposables.add @displayBuffer.onDidChangeGrammar => @handleGrammarChange()
@disposables.add @displayBuffer.onDidTokenize => @handleTokenization()
@disposables.add @displayBuffer.onDidChange (e) =>
@emit 'screen-lines-changed', e if includeDeprecatedAPIs
@emitter.emit 'did-change', e
# TODO: remove these when we remove the deprecations. Though, no one is likely using them
@subscribe @displayBuffer.onDidChangeSoftWrapped (softWrapped) => @emit 'soft-wrap-changed', softWrapped
@subscribe @displayBuffer.onDidAddDecoration (decoration) => @emit 'decoration-added', decoration
@subscribe @displayBuffer.onDidRemoveDecoration (decoration) => @emit 'decoration-removed', decoration
if includeDeprecatedAPIs
@subscribe @displayBuffer.onDidChangeSoftWrapped (softWrapped) => @emit 'soft-wrap-changed', softWrapped
@subscribe @displayBuffer.onDidAddDecoration (decoration) => @emit 'decoration-added', decoration
@subscribe @displayBuffer.onDidRemoveDecoration (decoration) => @emit 'decoration-removed', decoration
@subscribeToScopedConfigSettings()
@ -176,7 +174,8 @@ class TextEditor extends Model
subscriptions.add atom.config.onDidChange 'editor.invisibles', scope: scopeDescriptor, => @updateInvisibles()
destroyed: ->
@unsubscribe()
@unsubscribe() if includeDeprecatedAPIs
@disposables.dispose()
@scopedConfigSubscriptions.dispose()
selection.destroy() for selection in @getSelections()
@buffer.release()
@ -459,7 +458,7 @@ class TextEditor extends Model
onDidChangeIcon: (callback) ->
@emitter.on 'did-change-icon', callback
# Retrieves the current {TextBuffer}.
# Public: Retrieves the current {TextBuffer}.
getBuffer: -> @buffer
# Retrieves the current buffer's URI.
@ -720,7 +719,7 @@ class TextEditor extends Model
willInsert = true
cancel = -> willInsert = false
willInsertEvent = {cancel, text}
@emit('will-insert-text', willInsertEvent)
@emit('will-insert-text', willInsertEvent) if includeDeprecatedAPIs
@emitter.emit 'will-insert-text', willInsertEvent
if willInsert
@ -729,7 +728,7 @@ class TextEditor extends Model
@mutateSelectedText (selection) =>
range = selection.insertText(text, options)
didInsertEvent = {text, range}
@emit('did-insert-text', didInsertEvent)
@emit('did-insert-text', didInsertEvent) if includeDeprecatedAPIs
@emitter.emit 'did-insert-text', didInsertEvent
range
else
@ -1026,6 +1025,7 @@ class TextEditor extends Model
# Extended: Delete all lines intersecting selections.
deleteLine: ->
@mergeSelectionsOnSameRows()
@mutateSelectedText (selection) -> selection.deleteLine()
###
@ -1662,9 +1662,9 @@ class TextEditor extends Model
preserveCursorPositionOnBufferReload: ->
cursorPosition = null
@subscribe @buffer.onWillReload =>
@disposables.add @buffer.onWillReload =>
cursorPosition = @getCursorBufferPosition()
@subscribe @buffer.onDidReload =>
@disposables.add @buffer.onDidReload =>
@setCursorBufferPosition(cursorPosition) if cursorPosition
cursorPosition = null
@ -2048,6 +2048,19 @@ class TextEditor extends Model
# the function with merging suppressed, then merges intersecting selections
# afterward.
mergeIntersectingSelections: (args...) ->
@mergeSelections args..., (previousSelection, currentSelection) ->
exclusive = not currentSelection.isEmpty() and not previousSelection.isEmpty()
previousSelection.intersectsWith(currentSelection, exclusive)
mergeSelectionsOnSameRows: (args...) ->
@mergeSelections args..., (previousSelection, currentSelection) ->
screenRange = currentSelection.getScreenRange()
previousSelection.intersectsScreenRowRange(screenRange.start.row, screenRange.end.row)
mergeSelections: (args...) ->
mergePredicate = args.pop()
fn = args.pop() if _.isFunction(_.last(args))
options = args.pop() ? {}
@ -2060,10 +2073,7 @@ class TextEditor extends Model
reducer = (disjointSelections, selection) ->
adjacentSelection = _.last(disjointSelections)
exclusive = not selection.isEmpty() and not adjacentSelection.isEmpty()
intersects = adjacentSelection.intersectsWith(selection, exclusive)
if intersects
if mergePredicate(adjacentSelection, selection)
adjacentSelection.merge(selection, options)
disjointSelections
else
@ -2837,6 +2847,10 @@ class TextEditor extends Model
logScreenLines: (start, end) -> @displayBuffer.logLines(start, end)
if includeDeprecatedAPIs
TextEditor.delegatesProperties '$lineHeightInPixels', '$defaultCharWidth', '$height', '$width',
'$verticalScrollbarWidth', '$horizontalScrollbarHeight', '$scrollTop', '$scrollLeft',
toProperty: 'displayBuffer'
TextEditor::getViewClass = ->
require './text-editor-view'
@ -3000,6 +3014,7 @@ if includeDeprecatedAPIs
deprecate("Use TextEditor::isSoftWrapped instead")
@displayBuffer.isSoftWrapped()
EmitterMixin = require('emissary').Emitter
TextEditor::on = (eventName) ->
switch eventName
when 'title-changed'

View File

@ -1,8 +1,8 @@
_ = require 'underscore-plus'
{Model} = require 'theorist'
{CompositeDisposable, Emitter} = require 'event-kit'
{Point, Range} = require 'text-buffer'
Serializable = require 'serializable'
Model = require './model'
TokenizedLine = require './tokenized-line'
Token = require './token'
ScopeDescriptor = require './scope-descriptor'
@ -12,11 +12,10 @@ module.exports =
class TokenizedBuffer extends Model
Serializable.includeInto(this)
@property 'tabLength'
grammar: null
currentGrammarScore: null
buffer: null
tabLength: null
tokenizedLines: null
chunkSize: 50
invalidRows: null

View File

@ -138,6 +138,7 @@ atom.commands.add 'atom-workspace',
'application:open-safe': -> ipc.send('command', 'application:open-safe')
'application:open-api-preview': -> ipc.send('command', 'application:open-api-preview')
'application:open-dev-api-preview': -> ipc.send('command', 'application:open-dev-api-preview')
'application:add-project-folder': -> atom.addProjectFolder()
'application:minimize': -> ipc.send('command', 'application:minimize')
'application:zoom': -> ipc.send('command', 'application:zoom')
'application:bring-all-windows-to-front': -> ipc.send('command', 'application:bring-all-windows-to-front')
@ -155,9 +156,9 @@ atom.commands.add 'atom-workspace',
'window:focus-pane-on-left': -> @focusPaneViewOnLeft()
'window:focus-pane-on-right': -> @focusPaneViewOnRight()
'window:save-all': -> @getModel().saveAll()
'window:toggle-invisibles': -> atom.config.toggle("editor.showInvisibles")
'window:toggle-invisibles': -> atom.config.set("editor.showInvisibles", !atom.config.get("editor.showInvisibles"))
'window:log-deprecation-warnings': -> Grim.logDeprecations()
'window:toggle-auto-indent': -> atom.config.toggle("editor.autoIndent")
'window:toggle-auto-indent': -> atom.config.set("editor.autoIndent", !atom.config.get("editor.autoIndent"))
'pane:reopen-closed-item': -> @getModel().reopenItem()
'core:close': -> @getModel().destroyActivePaneItemOrEmptyPane()
'core:save': -> @getModel().saveActivePaneItem()

View File

@ -2,13 +2,12 @@
_ = require 'underscore-plus'
path = require 'path'
{join} = path
{Model} = require 'theorist'
Q = require 'q'
Serializable = require 'serializable'
{Emitter, Disposable, CompositeDisposable} = require 'event-kit'
Grim = require 'grim'
fs = require 'fs-plus'
StackTraceParser = require 'stacktrace-parser'
Model = require './model'
TextEditor = require './text-editor'
PaneContainer = require './pane-container'
Pane = require './pane'
@ -33,14 +32,14 @@ class Workspace extends Model
atom.deserializers.add(this)
Serializable.includeInto(this)
@properties
paneContainer: null
fullScreen: false
destroyedItemURIs: -> []
constructor: (params) ->
super
unless Grim.includeDeprecatedAPIs
@paneContainer = params?.paneContainer
@fullScreen = params?.fullScreen ? false
@destroyedItemURIs = params?.destroyedItemURIs ? []
@emitter = new Emitter
@openers = []
@ -495,34 +494,6 @@ class Workspace extends Model
getOpeners: ->
@openers
getCallingPackageName: ->
error = new Error
Error.captureStackTrace(error)
stack = StackTraceParser.parse(error.stack)
packagePaths = @getPackagePathsByPackageName()
for i in [0...stack.length]
stackFramePath = stack[i].file
# Empty when it was run from the dev console
return unless stackFramePath
for packageName, packagePath of packagePaths
continue if stackFramePath is 'node.js'
relativePath = path.relative(packagePath, stackFramePath)
return packageName unless /^\.\./.test(relativePath)
return
getPackagePathsByPackageName: ->
packagePathsByPackageName = {}
for pack in atom.packages.getLoadedPackages()
packagePath = pack.path
if packagePath.indexOf('.atom/dev/packages') > -1 or packagePath.indexOf('.atom/packages') > -1
packagePath = fs.realpathSync(packagePath)
packagePathsByPackageName[pack.name] = packagePath
packagePathsByPackageName
###
Section: Pane Items
###
@ -892,6 +863,11 @@ class Workspace extends Model
deferred.promise
if includeDeprecatedAPIs
Workspace.properties
paneContainer: null
fullScreen: false
destroyedItemURIs: -> []
Object.defineProperty Workspace::, 'activePaneItem',
get: ->
Grim.deprecate "Use ::getActivePaneItem() instead of the ::activePaneItem property"
@ -902,6 +878,36 @@ if includeDeprecatedAPIs
Grim.deprecate "Use ::getActivePane() instead of the ::activePane property"
@getActivePane()
StackTraceParser = require 'stacktrace-parser'
Workspace::getCallingPackageName = ->
error = new Error
Error.captureStackTrace(error)
stack = StackTraceParser.parse(error.stack)
packagePaths = @getPackagePathsByPackageName()
for i in [0...stack.length]
stackFramePath = stack[i].file
# Empty when it was run from the dev console
return unless stackFramePath
for packageName, packagePath of packagePaths
continue if stackFramePath is 'node.js'
relativePath = path.relative(packagePath, stackFramePath)
return packageName unless /^\.\./.test(relativePath)
return
Workspace::getPackagePathsByPackageName = ->
packagePathsByPackageName = {}
for pack in atom.packages.getLoadedPackages()
packagePath = pack.path
if packagePath.indexOf('.atom/dev/packages') > -1 or packagePath.indexOf('.atom/packages') > -1
packagePath = fs.realpathSync(packagePath)
packagePathsByPackageName[pack.name] = packagePath
packagePathsByPackageName
Workspace::eachEditor = (callback) ->
deprecate("Use Workspace::observeTextEditors instead")