Comparar commits
235 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 9105348c8c | |||
| 30419027a8 | |||
| 5de95759cd | |||
| f7502d8508 | |||
| c9f13afb72 | |||
| e51c8f3407 | |||
| 63ee46023d | |||
| 68e5839b14 | |||
| 477801ba52 | |||
| 3850550345 | |||
| 728a8049d9 | |||
| 77741b6f3f | |||
| 4597dd5594 | |||
| 04d015a7e0 | |||
| 4bd07be7d8 | |||
| 40de6a7114 | |||
| 9100d20dc4 | |||
| 4361b67214 | |||
| 83c8d904cf | |||
| 3257d17fc0 | |||
| fd1d872840 | |||
| c5b6b90c88 | |||
| 9618ec45cf | |||
| 6e3d41f433 | |||
| 6f438ca7da | |||
| c629eb73b2 | |||
| cbe5eff04c | |||
| 01bf346d0f | |||
| c3bd501b84 | |||
| 556bb5b65e | |||
| de1c6d1a5d | |||
| a985942b16 | |||
| 9ba106192d | |||
| 83568a1d85 | |||
| 71333bbc93 | |||
| 4e10ea0b10 | |||
| 888d6dfab5 | |||
| 622b396111 | |||
| 0f2943989f | |||
| 63e618cf74 | |||
| 76f37277d9 | |||
| 745e9c8284 | |||
| 456e511031 | |||
| 390be558e2 | |||
| 4acd5951f5 | |||
| 8cd7d7dc0c | |||
| a127240f4f | |||
| c0ab2c4ac8 | |||
| 4c534606c2 | |||
| f330e207b4 | |||
| d05a3f370e | |||
| 08edcf23c9 | |||
| dc4640eee0 | |||
| 33073ea270 | |||
| 449acc7ced | |||
| dde253160c | |||
| c547039f1d | |||
| afb795d8cc | |||
| ef8a493b9a | |||
| c738145dc7 | |||
| 86991bbec2 | |||
| 973d7ebf13 | |||
| 93c67b670a | |||
| c7315e2be6 | |||
| a4976c32ae | |||
| 37a85bcdd0 | |||
| 47bd093d68 | |||
| a788a7e9b7 | |||
| 9101da11ce | |||
| f7159181ac | |||
| 1784a7f726 | |||
| a28a8447a7 | |||
| 197e74f18d | |||
| 5cae6f20c4 | |||
| 6ad704c1e4 | |||
| 2b0cb11df3 | |||
| 9aee7d4b38 | |||
| b6c86ea217 | |||
| 0d169f0516 | |||
| 740e6de5f3 | |||
| 5dea6e7d12 | |||
| 312e4e0e8a | |||
| 853ad9cee3 | |||
| a5ccfa6299 | |||
| 800ca5a37a | |||
| 23b8b15261 | |||
| 959aa08d62 | |||
| 6eed4e461f | |||
| 00b79e69f1 | |||
| 3739995ddb | |||
| f942bafe54 | |||
| 5fa230e71a | |||
| 9858916c31 | |||
| 18ed76f111 | |||
| feb35e710c | |||
| 2e989b502a | |||
| 434c9e60a8 | |||
| 84453d5441 | |||
| 9e11914b8b | |||
| f9f7cf6d34 | |||
| c7b206f5ca | |||
| 3b8b569d0c | |||
| 8365ccb064 | |||
| fee8e4a75a | |||
| edd8714bbf | |||
| 56adf8cc32 | |||
| d3956da8e5 | |||
| b24b338b2c | |||
| 14969c0522 | |||
| 65f2ffa55e | |||
| 5638c7fb6a | |||
| cb8b254502 | |||
| 027ebc78c4 | |||
| d9fb54ad6f | |||
| 2e72790e72 | |||
| 8fcd71f207 | |||
| 776eedd473 | |||
| 62c515e4e7 | |||
| 223334181b | |||
| a7e18b05d3 | |||
| b92e6f5a2d | |||
| 2170e917bd | |||
| 7add4af585 | |||
| 5076e2c8b3 | |||
| b56d73cd74 | |||
| 6c5a0e3670 | |||
| 791f89216b | |||
| f6067cb629 | |||
| 22158031bf | |||
| 8ac3fada4e | |||
| a03d5bc288 | |||
| cc489e5663 | |||
| cd3f7f73a0 | |||
| 9cb67a6def | |||
| 786e8c558a | |||
| bfeeddea4d | |||
| 1589b8b192 | |||
| b02d0e3df3 | |||
| d3f29c4580 | |||
| 7263ca8faa | |||
| cd812e7a65 | |||
| 4e6e636b8b | |||
| 083bafdb33 | |||
| adbe151c5d | |||
| 26b450fe49 | |||
| 5d273d0ee6 | |||
| b9b2b4bca2 | |||
| 79094ee889 | |||
| 52f2c0ec69 | |||
| d2f485a1ab | |||
| c12002a0ba | |||
| fed2bd6ab8 | |||
| d29b5b20cd | |||
| a0bb9d88e0 | |||
| 32b3c4076f | |||
| acd1d31480 | |||
| 242fce3d79 | |||
| e0bac77fa5 | |||
| c4c13375e4 | |||
| 83f0104c46 | |||
| a0a3c93b1d | |||
| 98a874808e | |||
| e7b790c5b9 | |||
| 4988293400 | |||
| 0d51c3b871 | |||
| 8316183fa0 | |||
| 8e617ff4e2 | |||
| 3ca5495690 | |||
| 5c47ae0cbc | |||
| 6a86a00c66 | |||
| 1abe64e73e | |||
| bb9150340d | |||
| c3f5c43694 | |||
| 1678016ae4 | |||
| f50e402de3 | |||
| e6363150dd | |||
| 5f024bfd69 | |||
| 76adb58fea | |||
| 53d5e61b23 | |||
| 499c09fc25 | |||
| 7891595fed | |||
| 604f2a951f | |||
| c1b6b716b1 | |||
| 4d861a68d1 | |||
| a831688ce1 | |||
| 1cbac24cee | |||
| afa5f73094 | |||
| a142e23f49 | |||
| f1b7536d06 | |||
| 397e61a0d8 | |||
| af22e45f70 | |||
| e6a12530a1 | |||
| 896c98b7a0 | |||
| 3201a05672 | |||
| 93181d8a54 | |||
| 661f1f822a | |||
| 678306317d | |||
| 8dd5f17609 | |||
| 13e069b45d | |||
| e61cc5eb13 | |||
| 9e92952ad0 | |||
| a8d778781c | |||
| da17679ec7 | |||
| 1cf663714e | |||
| 05963c4e57 | |||
| 965a18f7e2 | |||
| 58c45f87e6 | |||
| 21e609ffac | |||
| 93befc986f | |||
| 3321d77264 | |||
| 84761563f0 | |||
| 014cf19723 | |||
| 2a42ed4aaa | |||
| 34b1615782 | |||
| 87db2760b8 | |||
| b4dd0f4f73 | |||
| 9d655fd642 | |||
| 4700edf439 | |||
| 87c2f4496f | |||
| 2741445d95 | |||
| ed90c5e6c2 | |||
| 0bf2a3f480 | |||
| a743e8d058 | |||
| ddc607c760 | |||
| cbc8ad1467 | |||
| 1a1eb4380a | |||
| 535b49f60c | |||
| b5e60f7aa0 | |||
| ce29060d2d | |||
| 7d1c23b561 | |||
| 9e2799db27 | |||
| 040f6deb1e | |||
| 33d2debf5f | |||
| 6de40e21c7 | |||
| 3b13e4f502 |
@@ -36,7 +36,7 @@ many packages and themes that are stored in other repos under the
|
||||
[tabs](https://github.com/atom/tabs),
|
||||
[find-and-replace](https://github.com/atom/find-and-replace),
|
||||
[language-javascript](https://github.com/atom/language-javascript), and
|
||||
[atom-light-ui](http://github.com/atom/atom-light-ui).
|
||||
[atom-light-ui](https://github.com/atom/atom-light-ui).
|
||||
|
||||
For more information on how to work with Atom's official packages, see
|
||||
[Contributing to Atom Packages](https://atom.io/docs/latest/contributing-to-packages.html)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||

|
||||
|
||||
Atom is a hackable text editor for the 21st century, built on [atom-shell](http://github.com/atom/atom-shell), and based on everything we love about our favorite editors. We designed it to be deeply customizable, but still approachable using the default configuration.
|
||||
Atom is a hackable text editor for the 21st century, built on [atom-shell](https://github.com/atom/atom-shell), and based on everything we love about our favorite editors. We designed it to be deeply customizable, but still approachable using the default configuration.
|
||||
|
||||
Visit [atom.io](https://atom.io) to learn more or visit the [Atom forum](https://discuss.atom.io).
|
||||
|
||||
@@ -9,7 +9,7 @@ about the Atom 1.0 roadmap.
|
||||
|
||||
## Installing
|
||||
|
||||
### Mac OS X
|
||||
### OS X
|
||||
|
||||
Download the latest [Atom release](https://github.com/atom/atom/releases/latest).
|
||||
|
||||
@@ -24,18 +24,8 @@ Atom will automatically update when a new release is available.
|
||||
You can also download an `atom-windows.zip` file from the [releases page](https://github.com/atom/atom/releases/latest).
|
||||
The `.zip` version will not automatically update.
|
||||
|
||||
#### Uninstalling Chocolatey Version
|
||||
|
||||
The recommended installation of Atom on Windows used to be using [Chocolatey](https://chocolatey.org/packages/Atom/).
|
||||
This is no longer recommended now that the Atom Windows installer & auto-updater
|
||||
exists.
|
||||
|
||||
To switch from Chocolatey to the new installer:
|
||||
* Upgrade to Atom 0.155 or above by running `cup Atom`
|
||||
* Run `cuninst Atom` to uninstall the Chocolatey version of Atom
|
||||
* This will not delete any of your installed packages or Atom config files.
|
||||
* Download the latest [AtomSetup.exe installer](https://github.com/atom/atom/releases/latest).
|
||||
* Double-click the downloaded file to install Atom
|
||||
Using [chocolatey](https://chocolatey.org/)? Run `cinst Atom` to install
|
||||
the latest version of Atom.
|
||||
|
||||
### Debian Linux (Ubuntu)
|
||||
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "0.128"
|
||||
"atom-package-manager": "0.135.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,18 +45,24 @@ if [ $REDIRECT_STDERR ]; then
|
||||
fi
|
||||
|
||||
if [ $OS == 'Mac' ]; then
|
||||
ATOM_PATH="${ATOM_PATH:-/Applications}" # Set ATOM_PATH unless it is already set
|
||||
ATOM_APP_NAME=Atom.app
|
||||
|
||||
# If ATOM_PATH isn't a executable file, use spotlight to search for Atom
|
||||
if [ ! -x "$ATOM_PATH/$ATOM_APP_NAME" ]; then
|
||||
ATOM_PATH="$(mdfind "kMDItemCFBundleIdentifier == 'com.github.atom'" | grep -v ShipIt | head -1 | xargs -0 dirname)"
|
||||
fi
|
||||
if [ -z "${ATOM_PATH}" ]; then
|
||||
# If ATOM_PATH isnt set, check /Applications and then ~/Applications for Atom.app
|
||||
if [ -x "/Applications/$ATOM_APP_NAME" ]; then
|
||||
ATOM_PATH="/Applications"
|
||||
elif [ -x "$HOME/Applications/$ATOM_APP_NAME" ]; then
|
||||
ATOM_PATH="$HOME/Applications"
|
||||
else
|
||||
# We havent found an Atom.app, use spotlight to search for Atom
|
||||
ATOM_PATH="$(mdfind "kMDItemCFBundleIdentifier == 'com.github.atom'" | grep -v ShipIt | head -1 | xargs -0 dirname)"
|
||||
|
||||
# Exit if Atom can't be found
|
||||
if [ -z "$ATOM_PATH" ]; then
|
||||
echo "Cannot locate Atom.app, it is usually located in /Applications. Set the ATOM_PATH environment variable to the directory containing Atom.app."
|
||||
exit 1
|
||||
# Exit if Atom can't be found
|
||||
if [ ! -x "$ATOM_PATH/$ATOM_APP_NAME" ]; then
|
||||
echo "Cannot locate Atom.app, it is usually located in /Applications. Set the ATOM_PATH environment variable to the directory containing Atom.app."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $EXPECT_OUTPUT ]; then
|
||||
@@ -69,9 +75,9 @@ elif [ $OS == 'Linux' ]; then
|
||||
SCRIPT=$(readlink -f "$0")
|
||||
USR_DIRECTORY=$(readlink -f $(dirname $SCRIPT)/..)
|
||||
ATOM_PATH="$USR_DIRECTORY/share/atom/atom"
|
||||
DOT_ATOM_DIR="$HOME/.atom"
|
||||
ATOM_HOME="${ATOM_HOME:-$HOME/.atom}"
|
||||
|
||||
mkdir -p "$DOT_ATOM_DIR"
|
||||
mkdir -p "$ATOM_HOME"
|
||||
|
||||
: ${TMPDIR:=/tmp}
|
||||
|
||||
@@ -82,9 +88,9 @@ elif [ $OS == 'Linux' ]; then
|
||||
exit $?
|
||||
else
|
||||
(
|
||||
nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > "$DOT_ATOM_DIR/nohup.out" 2>&1
|
||||
nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > "$ATOM_HOME/nohup.out" 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
cat "$DOT_ATOM_DIR/nohup.out"
|
||||
cat "$ATOM_HOME/nohup.out"
|
||||
exit $?
|
||||
fi
|
||||
) &
|
||||
|
||||
@@ -207,6 +207,7 @@ module.exports = (grunt) ->
|
||||
loadingGif: path.resolve(__dirname, '..', 'resources', 'win', 'loading.gif')
|
||||
iconUrl: 'https://raw.githubusercontent.com/atom/atom/master/resources/win/atom.ico'
|
||||
setupIcon: path.resolve(__dirname, '..', 'resources', 'win', 'atom.ico')
|
||||
remoteReleases: 'https://atom.io/api/updates'
|
||||
|
||||
shell:
|
||||
'kill-atom':
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# VERSION: 0.1
|
||||
# DESCRIPTION: Create the atom editor in a container
|
||||
# DESCRIPTION: Create the atom editor in a container
|
||||
# AUTHOR: Jessica Frazelle <jessie@docker.com>
|
||||
# COMMENTS:
|
||||
# This file describes how to build the atom editor
|
||||
# This file describes how to build the atom editor
|
||||
# in a container with all dependencies installed.
|
||||
# Tested on Debian Jessie.
|
||||
# USAGE:
|
||||
# # Download atom Dockerfile
|
||||
# wget http://raw.githubusercontent.com/atom/atom/master/Dockerfile
|
||||
# wget https://raw.githubusercontent.com/atom/atom/master/Dockerfile
|
||||
#
|
||||
# # Build atom image
|
||||
# docker build -t atom .
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"fs-plus": "2.x",
|
||||
"github-releases": "~0.2.0",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-atom-shell-installer": "^0.20.0",
|
||||
"grunt-atom-shell-installer": "^0.21.0",
|
||||
"grunt-cli": "~0.1.9",
|
||||
"grunt-coffeelint": "git+https://github.com/atom/grunt-coffeelint.git#cfb99aa99811d52687969532bd5a98011ed95bfe",
|
||||
"grunt-contrib-coffee": "~0.12.0",
|
||||
|
||||
@@ -47,9 +47,9 @@ module.exports = (grunt) ->
|
||||
|
||||
{description} = grunt.file.readJSON('package.json')
|
||||
iconName = path.join(shareDir, 'resources', 'app', 'resources', 'atom.png')
|
||||
installDir = path.join(installDir, '.') # To prevent "Exec=/usr/local//share/atom/atom"
|
||||
executable = path.join(shareDir, 'atom')
|
||||
template = _.template(String(fs.readFileSync(desktopFile)))
|
||||
filled = template({description, installDir, iconName})
|
||||
filled = template({description, iconName, executable})
|
||||
|
||||
grunt.file.write(desktopInstallFile, filled)
|
||||
|
||||
|
||||
@@ -79,3 +79,6 @@ module.exports =
|
||||
|
||||
LGPL
|
||||
"""
|
||||
'core-js@0.4.10':
|
||||
license: 'MIT'
|
||||
source: 'http://rock.mit-license.org linked in source files and bower.json says MIT'
|
||||
|
||||
@@ -36,8 +36,9 @@ module.exports = (grunt) ->
|
||||
maintainer = 'GitHub <atom@github.com>'
|
||||
installDir = '/usr'
|
||||
iconName = 'atom'
|
||||
executable = path.join(installDir, 'share', 'atom', 'atom')
|
||||
getInstalledSize buildDir, (error, installedSize) ->
|
||||
data = {name, version, description, section, arch, maintainer, installDir, iconName, installedSize}
|
||||
data = {name, version, description, section, arch, maintainer, installDir, iconName, installedSize, executable}
|
||||
controlFilePath = fillTemplate(path.join('resources', 'linux', 'debian', 'control'), data)
|
||||
desktopFilePath = fillTemplate(path.join('resources', 'linux', 'atom.desktop'), data)
|
||||
icon = path.join('resources', 'atom.png')
|
||||
|
||||
@@ -33,8 +33,9 @@ module.exports = (grunt) ->
|
||||
installDir = grunt.config.get('atom.installDir')
|
||||
shareDir = path.join(installDir, 'share', 'atom')
|
||||
iconName = path.join(shareDir, 'resources', 'app', 'resources', 'atom.png')
|
||||
executable = 'atom'
|
||||
|
||||
data = {name, version, description, installDir, iconName}
|
||||
data = {name, version, description, installDir, iconName, executable}
|
||||
specFilePath = fillTemplate(path.join('resources', 'linux', 'redhat', 'atom.spec'), data)
|
||||
desktopFilePath = fillTemplate(path.join('resources', 'linux', 'atom.desktop'), data)
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ module.exports = (grunt) ->
|
||||
fullPath = path.join(relativePath, fileName)
|
||||
else
|
||||
fullPath = fileName
|
||||
longPaths.push(fullPath) if fullPath.length >= 200
|
||||
longPaths.push(fullPath) if fullPath.length >= 175
|
||||
|
||||
longPaths.sort (longPath1, longPath2) -> longPath2.length - longPath1.length
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ getAssets = ->
|
||||
]
|
||||
when 'win32'
|
||||
assets = [{assetName: 'atom-windows.zip', sourcePath: 'Atom'}]
|
||||
for squirrelAsset in ['AtomSetup.exe', 'RELEASES', "atom-#{version}-full.nupkg"]
|
||||
for squirrelAsset in ['AtomSetup.exe', 'RELEASES', "atom-#{version}-full.nupkg", "atom-#{version}-delta.nupkg"]
|
||||
cp path.join(buildDir, 'installer', squirrelAsset), path.join(buildDir, squirrelAsset)
|
||||
assets.push({assetName: squirrelAsset, sourcePath: assetName})
|
||||
assets
|
||||
|
||||
@@ -49,19 +49,17 @@ can be expressed as keystroke patterns separated by spaces.
|
||||
Commands are custom DOM events that are triggered when a keystroke matches a
|
||||
binding. This allows user interface code to listen for named commands without
|
||||
specifying the specific keybinding that triggers it. For example, the following
|
||||
code sets up {EditorView} to listen for commands to move the cursor to the first
|
||||
character of the current line:
|
||||
code creates a command to insert the current date in an editor:
|
||||
|
||||
```coffee
|
||||
class EditorView
|
||||
listenForEvents: ->
|
||||
@command 'editor:move-to-first-character-of-line', =>
|
||||
@editor.moveToFirstCharacterOfLine()
|
||||
atom.commands.add 'atom-text-editor',
|
||||
'user:insert-date': (event) ->
|
||||
editor = @getModel()
|
||||
editor.insertText(new Date().toLocaleString())
|
||||
```
|
||||
|
||||
The `::command` method is basically an enhanced version of jQuery's `::on`
|
||||
method that listens for a custom DOM event and adds some metadata to the DOM,
|
||||
which is read by the command palette.
|
||||
`atom.commands` refers to the global {CommandRegistry} instance where all commands
|
||||
are set and consequently picked up by the command palette.
|
||||
|
||||
When you are looking to bind new keys, it is often useful to use the command
|
||||
palette (`ctrl-shift-p`) to discover what commands are being listened for in a
|
||||
@@ -69,6 +67,30 @@ given focus context. Commands are "humanized" following a simple algorithm, so a
|
||||
command like `editor:fold-current-row` would appear as "Editor: Fold Current
|
||||
Row".
|
||||
|
||||
### "Composed" Commands
|
||||
|
||||
A common question is, "How do I make a single keybinding execute two or more
|
||||
commands?" There isn't any direct support for this in Atom, but it can be
|
||||
achieved by creating a custom command that performs the multiple actions
|
||||
you desire and then creating a keybinding for that command. For example, let's
|
||||
say I want to create a "composed" command that performs a Select Line followed
|
||||
by Cut. You could add the following to your `init.coffee`:
|
||||
|
||||
```coffee
|
||||
atom.commands.add 'atom-text-editor', 'custom:cut-line', ->
|
||||
editor = atom.workspace.getActiveTextEditor()
|
||||
editor.selectLinesContainingCursors()
|
||||
editor.cutSelectedText()
|
||||
```
|
||||
|
||||
Then let's say we want to map this custom command to `alt-ctrl-z`, you could
|
||||
add the following to your keymap:
|
||||
|
||||
```coffee
|
||||
'atom-text-editor':
|
||||
'alt-ctrl-z': 'custom:cut-line'
|
||||
```
|
||||
|
||||
### Specificity and Cascade Order
|
||||
|
||||
As is the case with CSS applying styles, when multiple bindings match for a
|
||||
|
||||
@@ -8,7 +8,7 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
|
||||
* C++ toolchain
|
||||
* [Git](http://git-scm.com/)
|
||||
* [Node.js](http://nodejs.org/download/) v0.10.x
|
||||
* [npm](http://www.npmjs.org/) v1.4.x (bundled with Node.js)
|
||||
* [npm](https://www.npmjs.com/) v1.4.x (bundled with Node.js)
|
||||
* `npm -v` to check the version.
|
||||
* `npm config set python /usr/bin/python2 -g` to ensure that gyp uses python2.
|
||||
* You might need to run this command as `sudo`, depending on how you have set up [npm](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* For 64-bit builds of node and native modules you **must** have the
|
||||
[Windows 7 64-bit SDK](http://www.microsoft.com/en-us/download/details.aspx?id=8279).
|
||||
You may also need the [compiler update for the Windows SDK 7.1](http://www.microsoft.com/en-us/download/details.aspx?id=4422)
|
||||
* [Python](http://www.python.org/download/) v2.7.
|
||||
* [Python](https://www.python.org/downloads/) v2.7.
|
||||
* The python.exe must be available at `%SystemDrive%\Python27\python.exe`.
|
||||
If it is installed elsewhere, you can create a symbolic link to the
|
||||
directory containing the python.exe using:
|
||||
@@ -19,7 +19,7 @@
|
||||
### On Windows 8
|
||||
* [Visual Studio Express 2013 for Windows Desktop](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs#DownloadFamilies_2)
|
||||
* [node.js](http://nodejs.org/download/) v0.10.x
|
||||
* [Python](http://www.python.org/download/) v2.7.x (required by [node-gyp](https://github.com/TooTallNate/node-gyp))
|
||||
* [Python](https://www.python.org/downloads/) v2.7.x (required by [node-gyp](https://github.com/TooTallNate/node-gyp))
|
||||
* [GitHub for Windows](http://windows.github.com/)
|
||||
|
||||
## Instructions
|
||||
|
||||
@@ -44,9 +44,9 @@ the editor to see it in action!
|
||||
on publishing the package you just created to [atom.io][atomio].
|
||||
|
||||
[atomio]: https://atom.io
|
||||
[CSS]: http://en.wikipedia.org/wiki/Cascading_Style_Sheets
|
||||
[CSS]: https://en.wikipedia.org/wiki/Cascading_Style_Sheets
|
||||
[Less]: http://lesscss.org
|
||||
[plist]: http://en.wikipedia.org/wiki/Property_list
|
||||
[R]: http://en.wikipedia.org/wiki/R_(programming_language)
|
||||
[plist]: https://en.wikipedia.org/wiki/Property_list
|
||||
[R]: https://en.wikipedia.org/wiki/R_(programming_language)
|
||||
[TextMate]: http://macromates.com
|
||||
[TextMateOrg]: https://github.com/textmate
|
||||
|
||||
@@ -61,8 +61,8 @@ __Syntax Theme__ dropdown menu to enable your new theme.
|
||||
on publishing the theme you just created to [atom.io][atomio].
|
||||
|
||||
[atomio]: https://atom.io
|
||||
[CSS]: http://en.wikipedia.org/wiki/Cascading_Style_Sheets
|
||||
[CSS]: https://en.wikipedia.org/wiki/Cascading_Style_Sheets
|
||||
[Less]: http://lesscss.org
|
||||
[plist]: http://en.wikipedia.org/wiki/Property_list
|
||||
[plist]: https://en.wikipedia.org/wiki/Property_list
|
||||
[TextMate]: http://macromates.com
|
||||
[TextMateThemes]: http://wiki.macromates.com/Themes/UserSubmittedThemes
|
||||
|
||||
@@ -51,9 +51,24 @@ in the _menus_ directory are added alphabetically.
|
||||
- `snippets` (**Optional**): an Array of Strings identifying the order of the
|
||||
snippets your package needs to load. If not specified, snippets in the
|
||||
_snippets_ directory are added alphabetically.
|
||||
- `activationEvents` (**Optional**): an Array of Strings identifying events that
|
||||
- `activationCommands` (**Optional**): an Array of Strings identifying commands that
|
||||
trigger your package's activation. You can delay the loading of your package
|
||||
until one of these events is triggered.
|
||||
- `providedServices` (**Optional**): an Object describing the services that your
|
||||
package provides, which can be used by other packages. The keys of this object
|
||||
are the names of the services, and the values are Objects with the following
|
||||
keys:
|
||||
- `description` (**Optional**) a String describing the service
|
||||
- `versions` (**Required**) an Object whose keys are Semver version strings,
|
||||
and whose values are names of methods in your package's top-level module
|
||||
that return a value implementing the service.
|
||||
- `consumedServices` (**Optional**): an Object describing the services that your
|
||||
package uses, which can be provided by other packages. The keys of this object
|
||||
are the names of the services, and the values are Objects with the following
|
||||
keys:
|
||||
- `versions` (**Required**) an Object whose keys are Semver version ranges
|
||||
and whose values are names of methods in your package's top-level module
|
||||
that are called with values implementing the service.
|
||||
|
||||
## Source Code
|
||||
|
||||
@@ -83,9 +98,9 @@ module's `activate` method so you can restore your view to where the user left
|
||||
off.
|
||||
|
||||
- `deactivate()`: This **optional** method is called when the window is shutting
|
||||
down. If your package is watching any files or holding external resources in any
|
||||
other way, release them here. If you're just subscribing to things on window,
|
||||
you don't need to worry because that's getting torn down anyway.
|
||||
down, or when your package is being updated or disabled. If your package is
|
||||
watching any files, holding external resources, providing commands or subscribing
|
||||
to events, release them here.
|
||||
|
||||
### Simple Package Code
|
||||
|
||||
@@ -112,12 +127,11 @@ module.exports =
|
||||
serialize: -> # ...
|
||||
```
|
||||
|
||||
Beyond this simple contract, your package has access to Atom's API. Be aware
|
||||
that since we are early in development, APIs are subject to change and we have
|
||||
not yet established clear boundaries between what is public and what is private.
|
||||
Also, please collaborate with us if you need an API that doesn't exist. Our goal
|
||||
is to build out Atom's API organically based on the needs of package authors
|
||||
like you.
|
||||
Beyond this simple contract, your package has access to [Atom's API][api]. Be aware
|
||||
that the Atom 1.0 API is mostly frozen. Refer to the API documentation for what
|
||||
is public. That said, please collaborate with us if you need an API that doesn't
|
||||
exist. Our goal is to build out Atom's API organically based on the needs of
|
||||
package authors like you.
|
||||
|
||||
## Style Sheets
|
||||
|
||||
@@ -352,6 +366,79 @@ to indicate the type your value should be, its default, etc.
|
||||
See the [Config API Docs](https://atom.io/docs/api/latest/Config) for more
|
||||
details specifying your configuration.
|
||||
|
||||
## Interacting With Other Packages Via Services
|
||||
|
||||
Atom packages can interact with each other through versioned APIs called
|
||||
*services*. To provide a service, in your `package.json`, specify one or more
|
||||
version numbers, each paired with the name of a method on your package's main module:
|
||||
|
||||
```json
|
||||
{
|
||||
"providedServices": {
|
||||
"my-service": {
|
||||
"description": "Does a useful thing",
|
||||
"versions": {
|
||||
"1.2.3": "provideMyServiceV1",
|
||||
"2.3.4": "provideMyServiceV2",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In your package's main module, implement the methods named above. These methods
|
||||
will be called any time a package is activated that consumes their corresponding
|
||||
service. They should return a value that implements the service's API.
|
||||
|
||||
|
||||
```coffeescript
|
||||
module.exports =
|
||||
activate: -> # ...
|
||||
|
||||
provideMyServiceV1: ->
|
||||
adaptToLegacyAPI(myService)
|
||||
|
||||
provideMyServiceV2: ->
|
||||
myService
|
||||
```
|
||||
|
||||
Similarly, to consume a service, specify one or more [version *ranges*][version-ranges],
|
||||
each paired with the name of a method on the package's main module:
|
||||
|
||||
```json
|
||||
{
|
||||
"consumedServices": {
|
||||
"another-service": {
|
||||
"versions": {
|
||||
"^1.2.3": "consumeAnotherServiceV1",
|
||||
">=2.3.4 <2.5": "consumeAnotherServiceV2",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
These methods will be called any time a package is activated that *provides* their
|
||||
corresponding service. They will receive the service object as an argument. You
|
||||
will usually need to perform some kind of cleanup in the event that the package
|
||||
providing the service is deactivated. To do this, return a `Disposable` from
|
||||
your service-consuming method:
|
||||
|
||||
```coffeescript
|
||||
{Disposable} = require 'atom'
|
||||
|
||||
module.exports =
|
||||
activate: -> # ...
|
||||
|
||||
consumeAnotherServiceV1: (service) ->
|
||||
useService(adaptServiceFromLegacyAPI(service))
|
||||
new Disposable -> stopUsingService(service)
|
||||
|
||||
consumeAnotherServiceV2: (service) ->
|
||||
useService(service)
|
||||
new Disposable -> stopUsingService(service)
|
||||
```
|
||||
|
||||
## Bundle External Resources
|
||||
|
||||
It's common to ship external resources like images and fonts in the package, to
|
||||
@@ -402,11 +489,12 @@ registry.
|
||||
Run `apm help publish` to see all the available options and `apm help` to see
|
||||
all the other available commands.
|
||||
|
||||
[api]: https://atom.io/docs/api/latest
|
||||
[file-tree]: https://github.com/atom/tree-view
|
||||
[status-bar]: https://github.com/atom/status-bar
|
||||
[cs-syntax]: https://github.com/atom/language-coffee-script
|
||||
[npm]: http://en.wikipedia.org/wiki/Npm_(software)
|
||||
[npm-keys]: https://npmjs.org/doc/json.html
|
||||
[npm]: https://en.wikipedia.org/wiki/Npm_(software)
|
||||
[npm-keys]: https://docs.npmjs.com/files/package.json
|
||||
[git-tag]: http://git-scm.com/book/en/Git-Basics-Tagging
|
||||
[wrap-guide]: https://github.com/atom/wrap-guide/
|
||||
[keymaps]: advanced/keymaps.md
|
||||
@@ -424,3 +512,4 @@ all the other available commands.
|
||||
[convert-bundle]: converting-a-text-mate-bundle.html
|
||||
[convert-theme]: converting-a-text-mate-theme.html
|
||||
[json-schema]: http://json-schema.org/
|
||||
[version-ranges]: https://docs.npmjs.com/misc/semver#ranges
|
||||
|
||||
@@ -9,8 +9,8 @@ elements such as the tree view, the tabs, drop-down lists, and the status bar.
|
||||
Syntax themes style the code inside the editor.
|
||||
|
||||
Themes can be installed and changed from the settings view which you can open
|
||||
by selecting the _Atom > Preferences..._ menu and navigating to the _Themes_
|
||||
section on the left hand side.
|
||||
by selecting the _Atom > Preferences..._ menu and navigating to the _Install_
|
||||
section and the _Themes_ section on the left hand side.
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -24,7 +24,8 @@ a few things before starting:
|
||||
is used to help distribute your theme to Atom users.
|
||||
* Your theme's _package.json_ must contain a `"theme"` key with a value
|
||||
of `"ui"` or `"syntax"` for Atom to recognize and load it as a theme.
|
||||
* You can find existing themes to install or fork on [atom.io](atomio).
|
||||
* You can find existing themes to install or fork on
|
||||
[atom.io][atomio-themes].
|
||||
|
||||
## Creating a Syntax Theme
|
||||
|
||||
@@ -130,13 +131,13 @@ _styleguide_, or use the shortcut `cmd-ctrl-shift-g`.
|
||||
|
||||
![styleguide-img]
|
||||
|
||||
[atomio]: http://atom.io/packages
|
||||
[atomio-themes]: https://atom.io/themes
|
||||
[Less]: http://lesscss.org/
|
||||
[git]: http://git-scm.com/
|
||||
[atom]: https://atom.io/
|
||||
[package.json]: ./creating-a-package.html#package-json
|
||||
[less-tutorial]: https://speakerdeck.com/danmatthews/less-css
|
||||
[devtools-tutorial]: https://developers.google.com/chrome-developer-tools/docs/elements
|
||||
[devtools-tutorial]: https://developer.chrome.com/devtools/docs/dom-and-styles
|
||||
[ui-variables]: ./theme-variables.html
|
||||
[livereload]: https://github.com/atom/dev-live-reload
|
||||
[styleguide]: https://github.com/atom/styleguide
|
||||
|
||||
@@ -100,6 +100,14 @@ namespaces: `core` and `editor`.
|
||||
|
||||
You can open this file in an editor from the _Atom > Open Your Config_ menu.
|
||||
|
||||
### Custom Configuration Location
|
||||
|
||||
You can override the location that Atom stores configuration files and folders
|
||||
in by setting the `ATOM_HOME` environment variable. The `ATOM_HOME` path will be
|
||||
used instead of `~/.atom` when it is set.
|
||||
|
||||
This option can be useful when you want to make Atom portable across machines.
|
||||
|
||||
### Configuration Key Reference
|
||||
|
||||
- `core`
|
||||
@@ -169,7 +177,7 @@ For example, to change the color of the cursor, you could add the following
|
||||
rule to your _~/.atom/styles.less_ file:
|
||||
|
||||
```less
|
||||
atom-text-editor.is-focused .cursor {
|
||||
atom-text-editor::shadow .cursor {
|
||||
border-color: pink;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
* [Contributing](contributing.md)
|
||||
* [Contributing to Core Packages](contributing-to-packages.md)
|
||||
* [Debugging](debugging.md)
|
||||
* [Your First Package](your-first-package.md)
|
||||
|
||||
### Advanced Topics
|
||||
|
||||
@@ -19,6 +20,8 @@
|
||||
* [Keymaps](advanced/keymaps.md)
|
||||
* [Serialization](advanced/serialization.md)
|
||||
* [Scopes and Scope Descriptors](advanced/scopes-and-scope-descriptors.md)
|
||||
* [Theme Variables](theme-variables.md)
|
||||
* [apm REST API](apm-rest-api.md)
|
||||
|
||||
### Upgrading to 1.0 APIs
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ If not, there are a few things you should check before publishing:
|
||||
|
||||
Before you publish a package it is a good idea to check ahead of time if
|
||||
a package with the same name has already been published to atom.io. You can do
|
||||
that by visiting `http://atom.io/packages/my-package` to see if the package
|
||||
that by visiting `https://atom.io/packages/my-package` to see if the package
|
||||
already exists. If it does, update your package's name to something that is
|
||||
available before proceeding.
|
||||
|
||||
@@ -73,7 +73,7 @@ and you only need to enter this information the first time you publish. The
|
||||
credentials are stored securely in your [keychain][keychain] once you login.
|
||||
|
||||
:tada: Your package is now published and available on atom.io. Head on over to
|
||||
`http://atom.io/packages/my-package` to see your package's page.
|
||||
`https://atom.io/packages/my-package` to see your package's page.
|
||||
|
||||
With `apm publish`, you can bump the version and publish by using
|
||||
```sh
|
||||
@@ -107,7 +107,7 @@ Use `patch` when you make a small change like a bug fix that does not add or rem
|
||||
[atomio]: https://atom.io
|
||||
[github]: https://github.com
|
||||
[git-tag]: http://git-scm.com/book/en/Git-Basics-Tagging
|
||||
[keychain]: http://en.wikipedia.org/wiki/Keychain_(Apple)
|
||||
[keychain]: https://en.wikipedia.org/wiki/Keychain_(Apple)
|
||||
[repo-guide]: http://guides.github.com/overviews/desktop
|
||||
[semver]: http://semver.org
|
||||
[your-first-package]: your-first-package.html
|
||||
|
||||
@@ -24,7 +24,7 @@ Here's an example `.less` file that a package can define using theme variables:
|
||||
```css
|
||||
@import "ui-variables";
|
||||
|
||||
.my-selector{
|
||||
.my-selector {
|
||||
background-color: @base-background-color;
|
||||
padding: @component-padding;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ When you are deprecation free and all done converting, upgrade the `engines` fie
|
||||
```json
|
||||
{
|
||||
"engines": {
|
||||
"atom": ">=0.174.0, <2.0.0"
|
||||
"atom": ">=0.174.0 <2.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Writing specs
|
||||
|
||||
Atom uses [Jasmine](http://jasmine.github.io/2.0/introduction.html) as its spec framework. Any new functionality should have specs to guard against regressions.
|
||||
Atom uses [Jasmine](http://jasmine.github.io/1.3/introduction.html) as its spec framework. Any new functionality should have specs to guard against regressions.
|
||||
|
||||
## Create a new spec
|
||||
|
||||
@@ -12,7 +12,7 @@ Atom uses [Jasmine](http://jasmine.github.io/2.0/introduction.html) as its spec
|
||||
|
||||
0. Add one or more `describe` methods
|
||||
|
||||
The `describe` method takes two arguments, a description and a function. If the description explains a behavior it typically begins with `when` if it is more like a unit test it begins with the method name.
|
||||
The `describe` method takes two arguments, a description and a function. If the description explains a behavior it typically begins with `when`; if it is more like a unit test it begins with the method name.
|
||||
|
||||
```coffee
|
||||
describe "when a test is written", ->
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Create Your First Package
|
||||
|
||||
This tutorial will guide you though creating a simple command that replaces the
|
||||
selected text with [ascii art](http://en.wikipedia.org/wiki/ASCII_art). When you
|
||||
selected text with [ascii art](https://en.wikipedia.org/wiki/ASCII_art). When you
|
||||
run our new command with the word "cool" selected, it will be replaced with:
|
||||
|
||||
```
|
||||
@@ -72,12 +72,12 @@ command palette or by pressing `ctrl-alt-cmd-l`.
|
||||
|
||||
Now open the command panel and search for the `ascii-art:convert` command. But
|
||||
it's not there! To fix this, open _package.json_ and find the property called
|
||||
`activationEvents`. Activation Events speed up load time by allowing Atom to
|
||||
`activationCommands`. Activation Events speed up load time by allowing Atom to
|
||||
delay a package's activation until it's needed. So remove the existing command
|
||||
and add `ascii-art:convert` to the `activationEvents` array:
|
||||
and add `ascii-art:convert` to the `activationCommands` array:
|
||||
|
||||
```json
|
||||
"activationEvents": ["ascii-art:convert"],
|
||||
"activationCommands": ["ascii-art:convert"],
|
||||
```
|
||||
|
||||
First, reload the window by running the command `window:reload`. Now when you
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.176.0",
|
||||
"version": "0.178.0",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
@@ -17,10 +17,11 @@
|
||||
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
|
||||
}
|
||||
],
|
||||
"atomShellVersion": "0.20.7",
|
||||
"atomShellVersion": "0.21.0",
|
||||
"dependencies": {
|
||||
"6to5-core": "^3.0.14",
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^2.5.2",
|
||||
"atom-keymap": "^3.1.0",
|
||||
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
|
||||
"clear-cut": "0.4.0",
|
||||
"coffee-script": "1.8.0",
|
||||
@@ -28,42 +29,42 @@
|
||||
"color": "^0.7.3",
|
||||
"delegato": "^1",
|
||||
"emissary": "^1.3.1",
|
||||
"event-kit": "^1.0.1",
|
||||
"first-mate": "^2.2.4",
|
||||
"fs-plus": "^2.3.2",
|
||||
"event-kit": "^1.0.2",
|
||||
"first-mate": "^3.0.0",
|
||||
"fs-plus": "^2.5",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "^2.1",
|
||||
"git-utils": "^2.2",
|
||||
"git-utils": "^3.0.0",
|
||||
"grim": "1.1.0",
|
||||
"guid": "0.0.10",
|
||||
"jasmine-json": "~0.0",
|
||||
"jasmine-tagged": "^1.1.2",
|
||||
"jquery": "^2.1.1",
|
||||
"less-cache": "0.20.0",
|
||||
"less-cache": "0.21",
|
||||
"marked": "^0.3",
|
||||
"mixto": "^1",
|
||||
"mkdirp": "0.3.5",
|
||||
"nslog": "^1.0.1",
|
||||
"oniguruma": "^3.0.6",
|
||||
"nslog": "^2.0.0",
|
||||
"oniguruma": "^4.0.0",
|
||||
"optimist": "0.4.0",
|
||||
"pathwatcher": "^2.6.1",
|
||||
"pathwatcher": "^3.1.0",
|
||||
"property-accessors": "^1",
|
||||
"q": "^1.0.1",
|
||||
"random-words": "0.0.1",
|
||||
"react-atom-fork": "^0.11.4",
|
||||
"react-atom-fork": "^0.11.5",
|
||||
"reactionary-atom-fork": "^1.0.0",
|
||||
"runas": "1.0.1",
|
||||
"scandal": "1.0.3",
|
||||
"runas": "2.0.0",
|
||||
"scandal": "2.0.0",
|
||||
"scoped-property-store": "^0.16.2",
|
||||
"scrollbar-style": "^1.0.2",
|
||||
"season": "^5.1.1",
|
||||
"scrollbar-style": "^2.0.0",
|
||||
"season": "^5.1.2",
|
||||
"semver": "2.2.1",
|
||||
"serializable": "^1",
|
||||
"service-hub": "^0.2.0",
|
||||
"space-pen": "3.8.2",
|
||||
"stacktrace-parser": "0.1.1",
|
||||
"temp": "0.7.0",
|
||||
"text-buffer": "^3.10.1",
|
||||
"text-buffer": "^4.0.0",
|
||||
"theorist": "^1.0.2",
|
||||
"underscore-plus": "^1.6.6",
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
@@ -75,64 +76,65 @@
|
||||
"atom-light-ui": "0.40.0",
|
||||
"base16-tomorrow-dark-theme": "0.25.0",
|
||||
"base16-tomorrow-light-theme": "0.8.0",
|
||||
"one-dark-ui": "0.2.0",
|
||||
"one-dark-syntax": "0.2.0",
|
||||
"one-light-syntax": "0.2.0",
|
||||
"one-light-ui": "0.1.0",
|
||||
"one-dark-ui": "0.3.0",
|
||||
"one-dark-syntax": "0.3.0",
|
||||
"one-light-syntax": "0.3.0",
|
||||
"one-light-ui": "0.2.0",
|
||||
"solarized-dark-syntax": "0.32.0",
|
||||
"solarized-light-syntax": "0.19.0",
|
||||
"archive-view": "0.44.0",
|
||||
"autocomplete": "0.43.0",
|
||||
"archive-view": "0.46.0",
|
||||
"autocomplete": "0.44.0",
|
||||
"autoflow": "0.21.0",
|
||||
"autosave": "0.20.0",
|
||||
"background-tips": "0.21.0",
|
||||
"background-tips": "0.22.0",
|
||||
"bookmarks": "0.35.0",
|
||||
"bracket-matcher": "0.69.0",
|
||||
"bracket-matcher": "0.71.0",
|
||||
"command-palette": "0.34.0",
|
||||
"deprecation-cop": "0.33.0",
|
||||
"dev-live-reload": "0.39.0",
|
||||
"deprecation-cop": "0.34.0",
|
||||
"dev-live-reload": "0.41.0",
|
||||
"encoding-selector": "0.17.0",
|
||||
"exception-reporting": "0.21.0",
|
||||
"find-and-replace": "0.156.0",
|
||||
"fuzzy-finder": "0.65.0",
|
||||
"git-diff": "0.49.0",
|
||||
"git-diff": "0.50.0",
|
||||
"go-to-line": "0.30.0",
|
||||
"grammar-selector": "0.44.0",
|
||||
"image-view": "0.47.0",
|
||||
"image-view": "0.48.0",
|
||||
"incompatible-packages": "0.21.0",
|
||||
"keybinding-resolver": "0.27.0",
|
||||
"link": "0.29.0",
|
||||
"markdown-preview": "0.126.0",
|
||||
"metrics": "0.41.0",
|
||||
"link": "0.30.0",
|
||||
"markdown-preview": "0.134.0",
|
||||
"metrics": "0.42.0",
|
||||
"notifications": "0.26.0",
|
||||
"open-on-github": "0.32.0",
|
||||
"package-generator": "0.37.0",
|
||||
"release-notes": "0.47.0",
|
||||
"settings-view": "0.174.0",
|
||||
"snippets": "0.70.0",
|
||||
"spell-check": "0.51.0",
|
||||
"snippets": "0.72.0",
|
||||
"spell-check": "0.54.0",
|
||||
"status-bar": "0.57.0",
|
||||
"styleguide": "0.42.0",
|
||||
"symbols-view": "0.79.0",
|
||||
"styleguide": "0.43.0",
|
||||
"symbols-view": "0.81.0",
|
||||
"tabs": "0.64.0",
|
||||
"timecop": "0.28.0",
|
||||
"tree-view": "0.148.0",
|
||||
"update-package-dependencies": "0.7.0",
|
||||
"timecop": "0.29.0",
|
||||
"tree-view": "0.154.0",
|
||||
"update-package-dependencies": "0.8.0",
|
||||
"welcome": "0.21.0",
|
||||
"whitespace": "0.28.0",
|
||||
"wrap-guide": "0.31.0",
|
||||
"language-c": "0.37.0",
|
||||
"language-c": "0.38.0",
|
||||
"language-clojure": "0.10.0",
|
||||
"language-coffee-script": "0.39.0",
|
||||
"language-css": "0.26.0",
|
||||
"language-csharp": "0.5.0",
|
||||
"language-css": "0.27.0",
|
||||
"language-gfm": "0.63.0",
|
||||
"language-git": "0.10.0",
|
||||
"language-go": "0.21.0",
|
||||
"language-html": "0.28.0",
|
||||
"language-hyperlink": "0.12.2",
|
||||
"language-java": "0.14.0",
|
||||
"language-javascript": "0.55.0",
|
||||
"language-json": "0.11.0",
|
||||
"language-javascript": "0.56.0",
|
||||
"language-json": "0.12.0",
|
||||
"language-less": "0.24.0",
|
||||
"language-make": "0.13.0",
|
||||
"language-mustache": "0.11.0",
|
||||
@@ -148,9 +150,9 @@
|
||||
"language-source": "0.9.0",
|
||||
"language-sql": "0.14.0",
|
||||
"language-text": "0.6.0",
|
||||
"language-todo": "0.15.0",
|
||||
"language-todo": "0.16.0",
|
||||
"language-toml": "0.15.0",
|
||||
"language-xml": "0.27.0",
|
||||
"language-xml": "0.28.0",
|
||||
"language-yaml": "0.22.0"
|
||||
},
|
||||
"private": true,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Name=Atom
|
||||
Comment=<%= description %>
|
||||
GenericName=Text Editor
|
||||
Exec=<%= installDir %>/share/atom/atom %U
|
||||
Exec=<%= executable %> %U
|
||||
Icon=<%= iconName %>
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
|
||||
|
Depois Largura: | Altura: | Tamanho: 628 KiB |
|
Depois Largura: | Altura: | Tamanho: 20 KiB |
|
Depois Largura: | Altura: | Tamanho: 944 B |
|
Depois Largura: | Altura: | Tamanho: 1.6 KiB |
|
Depois Largura: | Altura: | Tamanho: 61 KiB |
|
Depois Largura: | Altura: | Tamanho: 2.4 KiB |
|
Depois Largura: | Altura: | Tamanho: 4.5 KiB |
|
Depois Largura: | Altura: | Tamanho: 192 KiB |
|
Depois Largura: | Altura: | Tamanho: 7.0 KiB |
@@ -1,26 +1,27 @@
|
||||
Name: <%= name %>
|
||||
Version: <%= version %>
|
||||
Release: 0.1%{?dist}
|
||||
Summary: Atom is a hackable text editor for the 21st century
|
||||
Summary: <%= description %>
|
||||
License: MIT
|
||||
URL: https://atom.io/
|
||||
AutoReqProv: no # Avoid libchromiumcontent.so missing dependency
|
||||
Prefix: <%= installDir %>
|
||||
|
||||
%description
|
||||
<%= description %>
|
||||
|
||||
%install
|
||||
mkdir -p %{buildroot}/usr/local/share/atom
|
||||
cp -r /tmp/atom-build/Atom/* %{buildroot}/usr/local/share/atom
|
||||
mkdir -p %{buildroot}/usr/local/bin/
|
||||
ln -sf /usr/local/share/atom/resources/app/apm/node_modules/.bin/apm %{buildroot}/usr/local/bin/apm
|
||||
cp atom.sh %{buildroot}/usr/local/bin/atom
|
||||
chmod 755 atom.sh
|
||||
mkdir -p %{buildroot}/usr/local/share/applications/
|
||||
mv atom.desktop %{buildroot}/usr/local/share/applications/
|
||||
mkdir -p %{buildroot}/<%= installDir %>/share/atom/
|
||||
cp -r Atom/* %{buildroot}/<%= installDir %>/share/atom/
|
||||
mkdir -p %{buildroot}/<%= installDir %>/bin/
|
||||
ln -sf ../share/atom/resources/app/apm/node_modules/.bin/apm %{buildroot}/<%= installDir %>/bin/apm
|
||||
cp atom.sh %{buildroot}/<%= installDir %>/bin/atom
|
||||
chmod 755 %{buildroot}/<%= installDir %>/bin/atom
|
||||
mkdir -p %{buildroot}/<%= installDir %>/share/applications/
|
||||
cp atom.desktop %{buildroot}/<%= installDir %>/share/applications/
|
||||
|
||||
%files
|
||||
/usr/local/bin/atom
|
||||
/usr/local/bin/apm
|
||||
/usr/local/share/atom/
|
||||
/usr/local/share/applications/atom.desktop
|
||||
<%= installDir %>/bin/atom
|
||||
<%= installDir %>/bin/apm
|
||||
<%= installDir %>/share/atom/
|
||||
<%= installDir %>/share/applications/atom.desktop
|
||||
|
||||
@@ -11,7 +11,7 @@ ARCH=`uname -m`
|
||||
|
||||
rpmdev-setuptree
|
||||
|
||||
cp -r $BUILD_DIRECTORY/Atom/* $RPM_BUILD_ROOT/BUILD
|
||||
cp -r $BUILD_DIRECTORY/Atom $RPM_BUILD_ROOT/BUILD
|
||||
cp $SPEC_FILE $RPM_BUILD_ROOT/SPECS
|
||||
cp ./atom.sh $RPM_BUILD_ROOT/BUILD
|
||||
cp $DESKTOP_FILE $RPM_BUILD_ROOT/BUILD
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
set -e
|
||||
|
||||
script/build
|
||||
script/grunt mkrpm publish-build --stack
|
||||
script/grunt mkrpm publish-build --stack --install-dir /usr
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
to5 = require '../src/6to5'
|
||||
crypto = require 'crypto'
|
||||
|
||||
describe "6to5 transpiler support", ->
|
||||
describe "::create6to5VersionAndOptionsDigest", ->
|
||||
it "returns a digest for the library version and specified options", ->
|
||||
defaultOptions =
|
||||
blacklist: [
|
||||
'useStrict'
|
||||
]
|
||||
experimental: true
|
||||
optional: [
|
||||
'asyncToGenerator'
|
||||
]
|
||||
reactCompat: true
|
||||
sourceMap: 'inline'
|
||||
version = '3.0.14'
|
||||
shasum = crypto.createHash('sha1')
|
||||
shasum.update('6to5-core', 'utf8')
|
||||
shasum.update('\0', 'utf8')
|
||||
shasum.update(version, 'utf8')
|
||||
shasum.update('\0', 'utf8')
|
||||
shasum.update('{"blacklist": ["useStrict",],"experimental": true,"optional": ["asyncToGenerator",],"reactCompat": true,"sourceMap": "inline",}')
|
||||
expectedDigest = shasum.digest('hex')
|
||||
|
||||
observedDigest = to5.create6to5VersionAndOptionsDigest(version, defaultOptions)
|
||||
expect(observedDigest).toEqual expectedDigest
|
||||
|
||||
describe "when a .js file starts with 'use 6to5';", ->
|
||||
it "transpiles it using 6to5", ->
|
||||
transpiled = require('./fixtures/6to5/single-quotes.js')
|
||||
expect(transpiled(3)).toBe 4
|
||||
|
||||
describe 'when a .js file starts with "use 6to5";', ->
|
||||
it "transpiles it using 6to5", ->
|
||||
transpiled = require('./fixtures/6to5/double-quotes.js')
|
||||
expect(transpiled(3)).toBe 4
|
||||
|
||||
describe "when a .js file does not start with 'use 6to6';", ->
|
||||
it "does not transpile it using 6to5", ->
|
||||
expect(-> require('./fixtures/6to5/invalid.js')).toThrow()
|
||||
@@ -47,9 +47,8 @@ describe "the `atom` global", ->
|
||||
updateAvailableHandler.callCount > 0
|
||||
|
||||
runs ->
|
||||
{releaseVersion, releaseNotes} = updateAvailableHandler.mostRecentCall.args[0]
|
||||
{releaseVersion} = updateAvailableHandler.mostRecentCall.args[0]
|
||||
expect(releaseVersion).toBe 'version'
|
||||
expect(releaseNotes).toBe 'notes'
|
||||
|
||||
describe "loading default config", ->
|
||||
it 'loads the default core config', ->
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
path = require 'path'
|
||||
BufferedNodeProcess = require '../src/buffered-node-process'
|
||||
|
||||
describe "BufferedNodeProcess", ->
|
||||
it "executes the script in a new process", ->
|
||||
exit = jasmine.createSpy('exitCallback')
|
||||
output = ''
|
||||
stdout = (lines) -> output += lines
|
||||
error = ''
|
||||
stderr = (lines) -> error += lines
|
||||
args = ['hi']
|
||||
command = path.join(__dirname, 'fixtures', 'script.js')
|
||||
|
||||
new BufferedNodeProcess({command, args, stdout, stderr, exit})
|
||||
|
||||
waitsFor ->
|
||||
exit.callCount is 1
|
||||
|
||||
runs ->
|
||||
expect(output).toBe 'hi'
|
||||
expect(error).toBe ''
|
||||
expect(args).toEqual ['hi']
|
||||
|
||||
it "suppresses deprecations in the new process", ->
|
||||
exit = jasmine.createSpy('exitCallback')
|
||||
output = ''
|
||||
stdout = (lines) -> output += lines
|
||||
error = ''
|
||||
stderr = (lines) -> error += lines
|
||||
command = path.join(__dirname, 'fixtures', 'script-with-deprecations.js')
|
||||
|
||||
new BufferedNodeProcess({command, stdout, stderr, exit})
|
||||
|
||||
waitsFor ->
|
||||
exit.callCount is 1
|
||||
|
||||
runs ->
|
||||
expect(output).toBe 'hi'
|
||||
expect(error).toBe ''
|
||||
@@ -666,6 +666,23 @@ describe "Config", ->
|
||||
foo:
|
||||
bar: 'coffee'
|
||||
|
||||
describe "when an error is thrown writing the file to disk", ->
|
||||
addErrorHandler = null
|
||||
beforeEach ->
|
||||
atom.notifications.onDidAddNotification addErrorHandler = jasmine.createSpy()
|
||||
|
||||
it "creates a notification", ->
|
||||
jasmine.unspy CSON, 'writeFileSync'
|
||||
spyOn(CSON, 'writeFileSync').andCallFake ->
|
||||
error = new Error()
|
||||
error.code = 'EPERM'
|
||||
error.path = atom.config.getUserConfigPath()
|
||||
throw error
|
||||
|
||||
save = -> atom.config.save()
|
||||
expect(save).not.toThrow()
|
||||
expect(addErrorHandler.callCount).toBe 1
|
||||
|
||||
describe ".loadUserConfig()", ->
|
||||
beforeEach ->
|
||||
expect(fs.existsSync(atom.config.configDirPath)).toBeFalsy()
|
||||
@@ -699,6 +716,26 @@ describe "Config", ->
|
||||
expect(atom.config.get("foo.bar")).toBe 'baz'
|
||||
expect(atom.config.get("foo.bar", scope: ['.source.ruby'])).toBe 'more-specific'
|
||||
|
||||
describe "when the config file does not conform to the schema", ->
|
||||
beforeEach ->
|
||||
fs.writeFileSync atom.config.configFilePath, """
|
||||
'*':
|
||||
foo:
|
||||
bar: 'omg'
|
||||
int: 'baz'
|
||||
'.source.ruby':
|
||||
foo:
|
||||
bar: 'scoped'
|
||||
int: 'nope'
|
||||
"""
|
||||
|
||||
it "validates and does not load the incorrect values", ->
|
||||
atom.config.loadUserConfig()
|
||||
expect(atom.config.get("foo.int")).toBe 12
|
||||
expect(atom.config.get("foo.bar")).toBe 'omg'
|
||||
expect(atom.config.get("foo.int", scope: ['.source.ruby'])).toBe 12
|
||||
expect(atom.config.get("foo.bar", scope: ['.source.ruby'])).toBe 'scoped'
|
||||
|
||||
describe "when the config file contains valid cson", ->
|
||||
beforeEach ->
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: bar: 'baz'")
|
||||
@@ -1106,6 +1143,62 @@ describe "Config", ->
|
||||
expect(atom.config.get('foo.bar.str', scope: ['.source.js'])).toBe 'omg'
|
||||
expect(atom.config.get('foo.bar.str', scope: ['.source.coffee'])).toBe 'ok'
|
||||
|
||||
describe 'when a schema is added after config values have been set', ->
|
||||
schema = null
|
||||
beforeEach ->
|
||||
schema =
|
||||
type: 'object'
|
||||
properties:
|
||||
int:
|
||||
type: 'integer'
|
||||
default: 2
|
||||
str:
|
||||
type: 'string'
|
||||
default: 'def'
|
||||
|
||||
it "respects the new schema when values are set", ->
|
||||
expect(atom.config.set('foo.bar.str', 'global')).toBe true
|
||||
expect(atom.config.set('foo.bar.str', 'scoped', scopeSelector: '.source.js')).toBe true
|
||||
expect(atom.config.get('foo.bar.str')).toBe 'global'
|
||||
expect(atom.config.get('foo.bar.str', scope: ['.source.js'])).toBe 'scoped'
|
||||
|
||||
expect(atom.config.set('foo.bar.noschema', 'nsGlobal')).toBe true
|
||||
expect(atom.config.set('foo.bar.noschema', 'nsScoped', scopeSelector: '.source.js')).toBe true
|
||||
expect(atom.config.get('foo.bar.noschema')).toBe 'nsGlobal'
|
||||
expect(atom.config.get('foo.bar.noschema', scope: ['.source.js'])).toBe 'nsScoped'
|
||||
|
||||
expect(atom.config.set('foo.bar.int', 'nope')).toBe true
|
||||
expect(atom.config.set('foo.bar.int', 'notanint', scopeSelector: '.source.js')).toBe true
|
||||
expect(atom.config.set('foo.bar.int', 23, scopeSelector: '.source.coffee')).toBe true
|
||||
expect(atom.config.get('foo.bar.int')).toBe 'nope'
|
||||
expect(atom.config.get('foo.bar.int', scope: ['.source.js'])).toBe 'notanint'
|
||||
expect(atom.config.get('foo.bar.int', scope: ['.source.coffee'])).toBe 23
|
||||
|
||||
atom.config.setSchema('foo.bar', schema)
|
||||
|
||||
expect(atom.config.get('foo.bar.str')).toBe 'global'
|
||||
expect(atom.config.get('foo.bar.str', scope: ['.source.js'])).toBe 'scoped'
|
||||
expect(atom.config.get('foo.bar.noschema')).toBe 'nsGlobal'
|
||||
expect(atom.config.get('foo.bar.noschema', scope: ['.source.js'])).toBe 'nsScoped'
|
||||
|
||||
expect(atom.config.get('foo.bar.int')).toBe 2
|
||||
expect(atom.config.get('foo.bar.int', scope: ['.source.js'])).toBe 2
|
||||
expect(atom.config.get('foo.bar.int', scope: ['.source.coffee'])).toBe 23
|
||||
|
||||
it "sets all values that adhere to the schema", ->
|
||||
expect(atom.config.set('foo.bar.int', 10)).toBe true
|
||||
expect(atom.config.set('foo.bar.int', 15, scopeSelector: '.source.js')).toBe true
|
||||
expect(atom.config.set('foo.bar.int', 23, scopeSelector: '.source.coffee')).toBe true
|
||||
expect(atom.config.get('foo.bar.int')).toBe 10
|
||||
expect(atom.config.get('foo.bar.int', scope: ['.source.js'])).toBe 15
|
||||
expect(atom.config.get('foo.bar.int', scope: ['.source.coffee'])).toBe 23
|
||||
|
||||
atom.config.setSchema('foo.bar', schema)
|
||||
|
||||
expect(atom.config.get('foo.bar.int')).toBe 10
|
||||
expect(atom.config.get('foo.bar.int', scope: ['.source.js'])).toBe 15
|
||||
expect(atom.config.get('foo.bar.int', scope: ['.source.coffee'])).toBe 23
|
||||
|
||||
describe 'when the value has an "integer" type', ->
|
||||
beforeEach ->
|
||||
schema =
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
"use 6to5";
|
||||
|
||||
module.exports = v => v + 1
|
||||
@@ -0,0 +1,3 @@
|
||||
'use 6to6';
|
||||
|
||||
module.exports = v => v + 1
|
||||
@@ -0,0 +1,3 @@
|
||||
'use 6to5';
|
||||
|
||||
module.exports = v => v + 1
|
||||
@@ -0,0 +1,10 @@
|
||||
module.exports =
|
||||
activate: ->
|
||||
|
||||
deactivate: ->
|
||||
|
||||
consumeFirstServiceV3: ->
|
||||
|
||||
consumeFirstServiceV4: ->
|
||||
|
||||
consumeSecondService: ->
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "package-with-consumed-services",
|
||||
|
||||
"consumedServices": {
|
||||
"service-1": {
|
||||
"versions": {
|
||||
">=0.2 <=0.3.6": "consumeFirstServiceV3",
|
||||
"^0.4.1": "consumeFirstServiceV4"
|
||||
}
|
||||
},
|
||||
"service-2": {
|
||||
"versions": {
|
||||
"0.2.1 || 0.2.2": "consumeSecondService"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "package-with-invalid-styles",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{
|
||||
@@ -0,0 +1,13 @@
|
||||
module.exports =
|
||||
activate: ->
|
||||
|
||||
deactivate: ->
|
||||
|
||||
provideFirstServiceV3: ->
|
||||
'first-service-v3'
|
||||
|
||||
provideFirstServiceV4: ->
|
||||
'first-service-v4'
|
||||
|
||||
provideSecondService: ->
|
||||
'second-service'
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "package-with-provided-services",
|
||||
|
||||
"providedServices": {
|
||||
"service-1": {
|
||||
"description": "The first service",
|
||||
"versions": {
|
||||
"0.3.1": "provideFirstServiceV3",
|
||||
"0.4.1": "provideFirstServiceV4"
|
||||
}
|
||||
},
|
||||
"service-2": {
|
||||
"description": "The second service",
|
||||
"versions": {
|
||||
"0.2.1": "provideSecondService"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
require('fs').existsSync('hi');
|
||||
process.stdout.write('hi');
|
||||
@@ -0,0 +1 @@
|
||||
process.stdout.write(process.argv[2]);
|
||||
@@ -1,5 +1,6 @@
|
||||
{$, $$} = require '../src/space-pen-extensions'
|
||||
Package = require '../src/package'
|
||||
{Disposable} = require 'atom'
|
||||
|
||||
describe "PackageManager", ->
|
||||
workspaceElement = null
|
||||
@@ -22,6 +23,12 @@ describe "PackageManager", ->
|
||||
expect(pack instanceof Package).toBe true
|
||||
expect(pack.metadata.name).toBe "package-with-broken-keymap"
|
||||
|
||||
it "returns the package if it has an invalid stylesheet", ->
|
||||
pack = atom.packages.loadPackage("package-with-invalid-styles")
|
||||
expect(pack instanceof Package).toBe true
|
||||
expect(pack.metadata.name).toBe "package-with-invalid-styles"
|
||||
expect(pack.stylesheets.length).toBe 0
|
||||
|
||||
it "returns null if the package has an invalid package.json", ->
|
||||
spyOn(console, 'warn')
|
||||
expect(atom.packages.loadPackage("package-with-broken-package-json")).toBeNull()
|
||||
@@ -445,6 +452,47 @@ describe "PackageManager", ->
|
||||
runs ->
|
||||
expect(atom.config.get 'editor.increaseIndentPattern', scope: ['.source.omg']).toBe '^a'
|
||||
|
||||
describe "service registration", ->
|
||||
it "registers the package's provided and consumed services", ->
|
||||
consumerModule = require "./fixtures/packages/package-with-consumed-services"
|
||||
firstServiceV3Disposed = false
|
||||
firstServiceV4Disposed = false
|
||||
secondServiceDisposed = false
|
||||
spyOn(consumerModule, 'consumeFirstServiceV3').andReturn(new Disposable -> firstServiceV3Disposed = true)
|
||||
spyOn(consumerModule, 'consumeFirstServiceV4').andReturn(new Disposable -> firstServiceV4Disposed = true)
|
||||
spyOn(consumerModule, 'consumeSecondService').andReturn(new Disposable -> secondServiceDisposed = true)
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-consumed-services")
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-provided-services")
|
||||
|
||||
runs ->
|
||||
expect(consumerModule.consumeFirstServiceV3).toHaveBeenCalledWith('first-service-v3')
|
||||
expect(consumerModule.consumeFirstServiceV4).toHaveBeenCalledWith('first-service-v4')
|
||||
expect(consumerModule.consumeSecondService).toHaveBeenCalledWith('second-service')
|
||||
|
||||
consumerModule.consumeFirstServiceV3.reset()
|
||||
consumerModule.consumeFirstServiceV4.reset()
|
||||
consumerModule.consumeSecondService.reset()
|
||||
|
||||
atom.packages.deactivatePackage("package-with-provided-services")
|
||||
|
||||
expect(firstServiceV3Disposed).toBe true
|
||||
expect(firstServiceV4Disposed).toBe true
|
||||
expect(secondServiceDisposed).toBe true
|
||||
|
||||
atom.packages.deactivatePackage("package-with-consumed-services")
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-provided-services")
|
||||
|
||||
runs ->
|
||||
expect(consumerModule.consumeFirstServiceV3).not.toHaveBeenCalled()
|
||||
expect(consumerModule.consumeFirstServiceV4).not.toHaveBeenCalled()
|
||||
expect(consumerModule.consumeSecondService).not.toHaveBeenCalled()
|
||||
|
||||
describe "::deactivatePackage(id)", ->
|
||||
afterEach ->
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
@@ -383,6 +383,25 @@ describe "Pane", ->
|
||||
pane.saveActiveItem()
|
||||
expect(atom.showSaveDialogSync).not.toHaveBeenCalled()
|
||||
|
||||
describe "when the item's saveAs method throws a well-known IO error", ->
|
||||
notificationSpy = null
|
||||
beforeEach ->
|
||||
atom.notifications.onDidAddNotification notificationSpy = jasmine.createSpy()
|
||||
|
||||
it "creates a notification", ->
|
||||
pane.getActiveItem().saveAs = ->
|
||||
error = new Error("EACCES, permission denied '/foo'")
|
||||
error.path = '/foo'
|
||||
error.code = 'EACCES'
|
||||
throw error
|
||||
|
||||
pane.saveActiveItem()
|
||||
expect(notificationSpy).toHaveBeenCalled()
|
||||
notification = notificationSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'warning'
|
||||
expect(notification.getMessage()).toContain 'Permission denied'
|
||||
expect(notification.getMessage()).toContain '/foo'
|
||||
|
||||
describe "::saveActiveItemAs()", ->
|
||||
pane = null
|
||||
|
||||
@@ -404,6 +423,25 @@ describe "Pane", ->
|
||||
pane.saveActiveItemAs()
|
||||
expect(atom.showSaveDialogSync).not.toHaveBeenCalled()
|
||||
|
||||
describe "when the item's saveAs method throws a well-known IO error", ->
|
||||
notificationSpy = null
|
||||
beforeEach ->
|
||||
atom.notifications.onDidAddNotification notificationSpy = jasmine.createSpy()
|
||||
|
||||
it "creates a notification", ->
|
||||
pane.getActiveItem().saveAs = ->
|
||||
error = new Error("EACCES, permission denied '/foo'")
|
||||
error.path = '/foo'
|
||||
error.code = 'EACCES'
|
||||
throw error
|
||||
|
||||
pane.saveActiveItemAs()
|
||||
expect(notificationSpy).toHaveBeenCalled()
|
||||
notification = notificationSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'warning'
|
||||
expect(notification.getMessage()).toContain 'Permission denied'
|
||||
expect(notification.getMessage()).toContain '/foo'
|
||||
|
||||
describe "::itemForURI(uri)", ->
|
||||
it "returns the item for which a call to .getURI() returns the given uri", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D")])
|
||||
|
||||
@@ -17,6 +17,7 @@ Config = require '../src/config'
|
||||
{Point} = require 'text-buffer'
|
||||
Project = require '../src/project'
|
||||
Workspace = require '../src/workspace'
|
||||
ServiceHub = require 'service-hub'
|
||||
TextEditor = require '../src/text-editor'
|
||||
TextEditorView = require '../src/text-editor-view'
|
||||
TextEditorElement = require '../src/text-editor-element'
|
||||
@@ -77,6 +78,7 @@ beforeEach ->
|
||||
projectPath = specProjectPath ? path.join(@specDirectory, 'fixtures')
|
||||
atom.project = new Project(paths: [projectPath])
|
||||
atom.workspace = new Workspace()
|
||||
atom.packages.serviceHub = new ServiceHub
|
||||
atom.keymaps.keyBindings = _.clone(keyBindingsToRestore)
|
||||
atom.commands.restoreSnapshot(commandsToRestore)
|
||||
atom.styles.restoreSnapshot(styleElementsToRestore)
|
||||
|
||||
@@ -374,6 +374,22 @@ describe "TextEditorComponent", ->
|
||||
expect(line2LeafNodes[2].textContent).toBe ' '
|
||||
expect(line2LeafNodes[2].classList.contains('indent-guide')).toBe true
|
||||
|
||||
it "renders indent guides correctly on lines containing only whitespace when invisibles are enabled", ->
|
||||
atom.config.set 'editor.showInvisibles', true
|
||||
atom.config.set 'editor.invisibles', space: '-', eol: 'x'
|
||||
editor.getBuffer().insert([1, Infinity], '\n ')
|
||||
nextAnimationFrame()
|
||||
|
||||
line2LeafNodes = getLeafNodes(component.lineNodeForScreenRow(2))
|
||||
expect(line2LeafNodes.length).toBe 4
|
||||
expect(line2LeafNodes[0].textContent).toBe '--'
|
||||
expect(line2LeafNodes[0].classList.contains('indent-guide')).toBe true
|
||||
expect(line2LeafNodes[1].textContent).toBe '--'
|
||||
expect(line2LeafNodes[1].classList.contains('indent-guide')).toBe true
|
||||
expect(line2LeafNodes[2].textContent).toBe '--'
|
||||
expect(line2LeafNodes[2].classList.contains('indent-guide')).toBe true
|
||||
expect(line2LeafNodes[3].textContent).toBe 'x'
|
||||
|
||||
it "does not render indent guides in trailing whitespace for lines containing non whitespace characters", ->
|
||||
editor.getBuffer().setText " hi "
|
||||
nextAnimationFrame()
|
||||
|
||||
@@ -364,12 +364,13 @@ describe "ThemeManager", ->
|
||||
throw new Error('EACCES permission denied "styles.less"')
|
||||
atom.notifications.onDidAddNotification addErrorHandler = jasmine.createSpy()
|
||||
|
||||
it "creates an error notification", ->
|
||||
it "creates an error notification and does not add the stylesheet", ->
|
||||
themeManager.loadUserStylesheet()
|
||||
expect(addErrorHandler).toHaveBeenCalled()
|
||||
note = addErrorHandler.mostRecentCall.args[0]
|
||||
expect(note.getType()).toBe 'error'
|
||||
expect(note.getMessage()).toContain 'Error loading'
|
||||
expect(atom.styles.styleElementsBySourcePath[atom.styles.getUserStyleSheetPath()]).toBeUndefined()
|
||||
|
||||
describe "when there is an error watching the user stylesheet", ->
|
||||
addErrorHandler = null
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{$, $$} = require '../src/space-pen-extensions'
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
temp = require 'temp'
|
||||
TextEditor = require '../src/text-editor'
|
||||
WindowEventHandler = require '../src/window-event-handler'
|
||||
|
||||
@@ -54,7 +56,7 @@ describe "Window", ->
|
||||
jasmine.unspy(TextEditor.prototype, "shouldPromptToSave")
|
||||
beforeUnloadEvent = $.Event(new Event('beforeunload'))
|
||||
|
||||
describe "when pane items are are modified", ->
|
||||
describe "when pane items are modified", ->
|
||||
it "prompts user to save and calls atom.workspace.confirmClose", ->
|
||||
editor = null
|
||||
spyOn(atom.workspace, 'confirmClose').andCallThrough()
|
||||
@@ -92,6 +94,25 @@ describe "Window", ->
|
||||
$(window).trigger(beforeUnloadEvent)
|
||||
expect(atom.confirm).toHaveBeenCalled()
|
||||
|
||||
describe "when the same path is modified in multiple panes", ->
|
||||
it "prompts to save the item", ->
|
||||
editor = null
|
||||
filePath = path.join(temp.mkdirSync('atom-file'), 'file.txt')
|
||||
fs.writeFileSync(filePath, 'hello')
|
||||
spyOn(atom.workspace, 'confirmClose').andCallThrough()
|
||||
spyOn(atom, 'confirm').andReturn(0)
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open(filePath).then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
atom.workspace.getActivePane().splitRight(copyActiveItem: true)
|
||||
editor.setText('world')
|
||||
$(window).trigger(beforeUnloadEvent)
|
||||
expect(atom.workspace.confirmClose).toHaveBeenCalled()
|
||||
expect(atom.confirm.callCount).toBe 1
|
||||
expect(fs.readFileSync(filePath, 'utf8')).toBe 'world'
|
||||
|
||||
describe ".unloadEditorWindow()", ->
|
||||
it "saves the serialized state of the window so it can be deserialized after reload", ->
|
||||
workspaceState = atom.workspace.serialize()
|
||||
|
||||
@@ -955,9 +955,14 @@ describe "Workspace", ->
|
||||
expect(editor.isModified()).toBeTruthy()
|
||||
|
||||
describe "::saveActivePaneItem()", ->
|
||||
editor = null
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.js').then (o) -> editor = o
|
||||
|
||||
describe "when there is an error", ->
|
||||
it "emits a warning notification when the file cannot be saved", ->
|
||||
spyOn(Pane::, 'saveActiveItem').andCallFake ->
|
||||
spyOn(editor, 'save').andCallFake ->
|
||||
throw new Error("'/some/file' is a directory")
|
||||
|
||||
atom.notifications.onDidAddNotification addedSpy = jasmine.createSpy()
|
||||
@@ -966,7 +971,7 @@ describe "Workspace", ->
|
||||
expect(addedSpy.mostRecentCall.args[0].getType()).toBe 'warning'
|
||||
|
||||
it "emits a warning notification when the directory cannot be written to", ->
|
||||
spyOn(Pane::, 'saveActiveItem').andCallFake ->
|
||||
spyOn(editor, 'save').andCallFake ->
|
||||
throw new Error("ENOTDIR, not a directory '/Some/dir/and-a-file.js'")
|
||||
|
||||
atom.notifications.onDidAddNotification addedSpy = jasmine.createSpy()
|
||||
@@ -975,7 +980,7 @@ describe "Workspace", ->
|
||||
expect(addedSpy.mostRecentCall.args[0].getType()).toBe 'warning'
|
||||
|
||||
it "emits a warning notification when the user does not have permission", ->
|
||||
spyOn(Pane::, 'saveActiveItem').andCallFake ->
|
||||
spyOn(editor, 'save').andCallFake ->
|
||||
error = new Error("EACCES, permission denied '/Some/dir/and-a-file.js'")
|
||||
error.code = 'EACCES'
|
||||
error.path = '/Some/dir/and-a-file.js'
|
||||
@@ -987,14 +992,14 @@ describe "Workspace", ->
|
||||
expect(addedSpy.mostRecentCall.args[0].getType()).toBe 'warning'
|
||||
|
||||
it "emits a warning notification when the operation is not permitted", ->
|
||||
spyOn(Pane::, 'saveActiveItem').andCallFake ->
|
||||
spyOn(editor, 'save').andCallFake ->
|
||||
error = new Error("EPERM, operation not permitted '/Some/dir/and-a-file.js'")
|
||||
error.code = 'EPERM'
|
||||
error.path = '/Some/dir/and-a-file.js'
|
||||
throw error
|
||||
|
||||
it "emits a warning notification when the file is already open by another app", ->
|
||||
spyOn(Pane::, 'saveActiveItem').andCallFake ->
|
||||
spyOn(editor, 'save').andCallFake ->
|
||||
error = new Error("EBUSY, resource busy or locked '/Some/dir/and-a-file.js'")
|
||||
error.code = 'EBUSY'
|
||||
error.path = '/Some/dir/and-a-file.js'
|
||||
@@ -1009,7 +1014,7 @@ describe "Workspace", ->
|
||||
expect(notificaiton.getMessage()).toContain 'Unable to save'
|
||||
|
||||
it "emits a warning notification when the file system is read-only", ->
|
||||
spyOn(Pane::, 'saveActiveItem').andCallFake ->
|
||||
spyOn(editor, 'save').andCallFake ->
|
||||
error = new Error("EROFS, read-only file system '/Some/dir/and-a-file.js'")
|
||||
error.code = 'EROFS'
|
||||
error.path = '/Some/dir/and-a-file.js'
|
||||
@@ -1024,7 +1029,7 @@ describe "Workspace", ->
|
||||
expect(notification.getMessage()).toContain 'Unable to save'
|
||||
|
||||
it "emits a warning notification when the file cannot be saved", ->
|
||||
spyOn(Pane::, 'saveActiveItem').andCallFake ->
|
||||
spyOn(editor, 'save').andCallFake ->
|
||||
throw new Error("no one knows")
|
||||
|
||||
save = -> atom.workspace.saveActivePaneItem()
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
###
|
||||
Cache for source code transpiled by 6to5.
|
||||
|
||||
Inspired by https://github.com/atom/atom/blob/6b963a562f8d495fbebe6abdbafbc7caf705f2c3/src/coffee-cache.coffee.
|
||||
###
|
||||
|
||||
crypto = require 'crypto'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
to5 = null # Defer until used
|
||||
|
||||
stats =
|
||||
hits: 0
|
||||
misses: 0
|
||||
|
||||
defaultOptions =
|
||||
# The Chrome dev tools will show the original version of the file
|
||||
# when the source map is inlined.
|
||||
sourceMap: 'inline'
|
||||
|
||||
# Because Atom is currently packaged with a fork of React v0.11,
|
||||
# it makes sense to use the --react-compat option so the React
|
||||
# JSX transformer produces pre-v0.12 code.
|
||||
reactCompat: true
|
||||
|
||||
# Blacklisted features do not get transpiled. Features that are
|
||||
# natively supported in the target environment should be listed
|
||||
# here. Because Atom uses a bleeding edge version of Node/io.js,
|
||||
# I think this can include es6.arrowFunctions, es6.classes, and
|
||||
# possibly others, but I want to be conservative.
|
||||
blacklist: [
|
||||
'useStrict'
|
||||
]
|
||||
|
||||
# Includes support for es7 features listed at:
|
||||
# http://6to5.org/docs/usage/transformers/#es7-experimental-.
|
||||
experimental: true
|
||||
|
||||
optional: [
|
||||
# Target a version of the regenerator runtime that
|
||||
# supports yield so the transpiled code is cleaner/smaller.
|
||||
'asyncToGenerator'
|
||||
]
|
||||
|
||||
###
|
||||
shasum - Hash with an update() method.
|
||||
value - Must be a value that could be returned by JSON.parse().
|
||||
###
|
||||
updateDigestForJsonValue = (shasum, value) ->
|
||||
# Implmentation is similar to that of pretty-printing a JSON object, except:
|
||||
# * Strings are not escaped.
|
||||
# * No effort is made to avoid trailing commas.
|
||||
# These shortcuts should not affect the correctness of this function.
|
||||
type = typeof value
|
||||
if type is 'string'
|
||||
shasum.update('"', 'utf8')
|
||||
shasum.update(value, 'utf8')
|
||||
shasum.update('"', 'utf8')
|
||||
else if type in ['boolean', 'number']
|
||||
shasum.update(value.toString(), 'utf8')
|
||||
else if value is null
|
||||
shasum.update('null', 'utf8')
|
||||
else if Array.isArray value
|
||||
shasum.update('[', 'utf8')
|
||||
for item in value
|
||||
updateDigestForJsonValue(shasum, item)
|
||||
shasum.update(',', 'utf8')
|
||||
shasum.update(']', 'utf8')
|
||||
else
|
||||
# value must be an object: be sure to sort the keys.
|
||||
keys = Object.keys value
|
||||
keys.sort()
|
||||
|
||||
shasum.update('{', 'utf8')
|
||||
for key in keys
|
||||
updateDigestForJsonValue(shasum, key)
|
||||
shasum.update(': ', 'utf8')
|
||||
updateDigestForJsonValue(shasum, value[key])
|
||||
shasum.update(',', 'utf8')
|
||||
shasum.update('}', 'utf8')
|
||||
|
||||
create6to5VersionAndOptionsDigest = (version, options) ->
|
||||
shasum = crypto.createHash('sha1')
|
||||
# Include the version of 6to5 in the hash.
|
||||
shasum.update('6to5-core', 'utf8')
|
||||
shasum.update('\0', 'utf8')
|
||||
shasum.update(version, 'utf8')
|
||||
shasum.update('\0', 'utf8')
|
||||
updateDigestForJsonValue(shasum, options)
|
||||
shasum.digest('hex')
|
||||
|
||||
jsCacheDir = null
|
||||
|
||||
getCachePath = (sourceCode) ->
|
||||
digest = crypto.createHash('sha1').update(sourceCode, 'utf8').digest('hex')
|
||||
|
||||
unless jsCacheDir?
|
||||
to5Version = require('6to5-core/package.json').version
|
||||
cacheDir = path.join(process.env.ATOM_HOME, 'compile-cache')
|
||||
jsCacheDir = path.join(cacheDir, 'js', '6to5', create6to5VersionAndOptionsDigest(to5Version, defaultOptions))
|
||||
|
||||
path.join(jsCacheDir, "#{digest}.js")
|
||||
|
||||
getCachedJavaScript = (cachePath) ->
|
||||
if fs.isFileSync(cachePath)
|
||||
try
|
||||
cachedJavaScript = fs.readFileSync(cachePath, 'utf8')
|
||||
stats.hits++
|
||||
return cachedJavaScript
|
||||
null
|
||||
|
||||
# Returns the 6to5 options that should be used to transpile filePath.
|
||||
createOptions = (filePath) ->
|
||||
options = filename: filePath
|
||||
for key, value of defaultOptions
|
||||
options[key] = value
|
||||
options
|
||||
|
||||
transpile = (sourceCode, filePath, cachePath) ->
|
||||
options = createOptions(filePath)
|
||||
to5 ?= require '6to5-core'
|
||||
js = to5.transform(sourceCode, options).code
|
||||
stats.misses++
|
||||
|
||||
try
|
||||
fs.writeFileSync(cachePath, js)
|
||||
|
||||
js
|
||||
|
||||
# Function that obeys the contract of an entry in the require.extensions map.
|
||||
# Returns the transpiled version of the JavaScript code at filePath, which is
|
||||
# either generated on the fly or pulled from cache.
|
||||
loadFile = (module, filePath) ->
|
||||
sourceCode = fs.readFileSync(filePath, 'utf8')
|
||||
unless sourceCode.startsWith('"use 6to5"') or sourceCode.startsWith("'use 6to5'")
|
||||
return module._compile(sourceCode, filePath)
|
||||
|
||||
cachePath = getCachePath(sourceCode)
|
||||
js = getCachedJavaScript(cachePath) ? transpile(sourceCode, filePath, cachePath)
|
||||
module._compile(js, filePath)
|
||||
|
||||
register = ->
|
||||
Object.defineProperty(require.extensions, '.js', {
|
||||
writable: false
|
||||
value: loadFile
|
||||
})
|
||||
|
||||
module.exports =
|
||||
register: register
|
||||
getCacheMisses: -> stats.misses
|
||||
getCacheHits: -> stats.hits
|
||||
|
||||
# Visible for testing.
|
||||
create6to5VersionAndOptionsDigest: create6to5VersionAndOptionsDigest
|
||||
|
||||
addPathToCache: (filePath) ->
|
||||
return if path.extname(filePath) isnt '.js'
|
||||
|
||||
sourceCode = fs.readFileSync(filePath, 'utf8')
|
||||
cachePath = getCachePath(sourceCode)
|
||||
transpile(sourceCode, filePath, cachePath)
|
||||
@@ -42,6 +42,12 @@ class Atom extends Model
|
||||
which returns an HTMLElement.
|
||||
"""
|
||||
|
||||
serviceHubDeprecationMessage = """
|
||||
atom.services is no longer available. To register service providers and
|
||||
consumers, use the `providedServices` and `consumedServices` fields in
|
||||
your package's package.json.
|
||||
"""
|
||||
|
||||
Object.defineProperty atom, 'workspaceView',
|
||||
get: ->
|
||||
deprecate(workspaceViewDeprecationMessage)
|
||||
@@ -50,6 +56,14 @@ class Atom extends Model
|
||||
deprecate(workspaceViewDeprecationMessage)
|
||||
atom.__workspaceView = newValue
|
||||
|
||||
Object.defineProperty atom, 'services',
|
||||
get: ->
|
||||
deprecate(serviceHubDeprecationMessage)
|
||||
atom.packages.serviceHub
|
||||
set: (newValue) ->
|
||||
deprecate(serviceHubDeprecationMessage)
|
||||
atom.packages.serviceHub = newValue
|
||||
|
||||
atom
|
||||
|
||||
# Deserializes the Atom environment from a state object
|
||||
@@ -95,7 +109,7 @@ class Atom extends Model
|
||||
#
|
||||
# Returns the absolute path to ~/.atom
|
||||
@getConfigDirPath: ->
|
||||
@configDirPath ?= fs.absolute('~/.atom')
|
||||
@configDirPath ?= process.env.ATOM_HOME
|
||||
|
||||
# Get the path to Atom's storage directory.
|
||||
#
|
||||
@@ -133,9 +147,6 @@ class Atom extends Model
|
||||
# Public: A {Clipboard} instance
|
||||
clipboard: null
|
||||
|
||||
# A {ServiceHub} instance
|
||||
services: null
|
||||
|
||||
# Public: A {ContextMenuManager} instance
|
||||
contextMenu: null
|
||||
|
||||
@@ -235,7 +246,6 @@ class Atom extends Model
|
||||
NotificationManager = require './notification-manager'
|
||||
PackageManager = require './package-manager'
|
||||
Clipboard = require './clipboard'
|
||||
ServiceHub = require './service-hub'
|
||||
GrammarRegistry = require './grammar-registry'
|
||||
ThemeManager = require './theme-manager'
|
||||
StyleManager = require './style-manager'
|
||||
@@ -253,9 +263,6 @@ class Atom extends Model
|
||||
# Make react.js faster
|
||||
process.env.NODE_ENV ?= 'production' unless devMode
|
||||
|
||||
# Set Atom's home so packages don't have to guess it
|
||||
process.env.ATOM_HOME = configDirPath
|
||||
|
||||
@config = new Config({configDirPath, resourcePath})
|
||||
@keymaps = new KeymapManager({configDirPath, resourcePath})
|
||||
@keymap = @keymaps # Deprecated
|
||||
@@ -271,7 +278,6 @@ class Atom extends Model
|
||||
@contextMenu = new ContextMenuManager({resourcePath, devMode})
|
||||
@menu = new MenuManager({resourcePath})
|
||||
@clipboard = new Clipboard()
|
||||
@services = new ServiceHub
|
||||
|
||||
@grammars = @deserializers.deserialize(@state.grammars ? @state.syntax) ? new GrammarRegistry()
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ AutoUpdateManager = require './auto-update-manager'
|
||||
BrowserWindow = require 'browser-window'
|
||||
Menu = require 'menu'
|
||||
app = require 'app'
|
||||
fs = require 'fs'
|
||||
fs = require 'fs-plus'
|
||||
ipc = require 'ipc'
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
@@ -216,6 +216,8 @@ class AtomApplication
|
||||
ipc.on 'open', (event, options) =>
|
||||
window = @windowForEvent(event)
|
||||
if options?
|
||||
if typeof options.pathsToOpen is 'string'
|
||||
options.pathsToOpen = [options.pathsToOpen]
|
||||
if options.pathsToOpen?.length > 0
|
||||
options.window = window
|
||||
@openPaths(options)
|
||||
@@ -340,6 +342,7 @@ class AtomApplication
|
||||
# :window - {AtomWindow} to open file paths in.
|
||||
openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, window}={}) ->
|
||||
{pathToOpen, initialLine, initialColumn} = @locationForPathToOpen(pathToOpen)
|
||||
pathToOpen = fs.normalize(pathToOpen)
|
||||
|
||||
unless pidToKillWhenClosed or newWindow
|
||||
pathToOpenStat = fs.statSyncNoException(pathToOpen)
|
||||
@@ -412,9 +415,8 @@ class AtomApplication
|
||||
openUrl: ({urlToOpen, devMode, safeMode}) ->
|
||||
unless @packages?
|
||||
PackageManager = require '../package-manager'
|
||||
fs = require 'fs-plus'
|
||||
@packages = new PackageManager
|
||||
configDirPath: fs.absolute('~/.atom')
|
||||
configDirPath: process.env.ATOM_HOME
|
||||
devMode: devMode
|
||||
resourcePath: @resourcePath
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ module.exports =
|
||||
class AtomWindow
|
||||
_.extend @prototype, EventEmitter.prototype
|
||||
|
||||
@iconPath: path.resolve(__dirname, '..', '..', 'resources', 'atom.png')
|
||||
@includeShellLoadTime: true
|
||||
|
||||
browserWindow: null
|
||||
@@ -22,12 +23,18 @@ class AtomWindow
|
||||
# Normalize to make sure drive letter case is consistent on Windows
|
||||
@resourcePath = path.normalize(@resourcePath) if @resourcePath
|
||||
|
||||
@browserWindow = new BrowserWindow
|
||||
options =
|
||||
show: false
|
||||
title: 'Atom'
|
||||
'web-preferences':
|
||||
'direct-write': false
|
||||
'direct-write': true
|
||||
'subpixel-font-scaling': false
|
||||
# Don't set icon on Windows so the exe's ico will be used as window and
|
||||
# taskbar's icon. See https://github.com/atom/atom/issues/4811 for more.
|
||||
if process.platform is 'linux'
|
||||
options.icon = @constructor.iconPath
|
||||
|
||||
@browserWindow = new BrowserWindow options
|
||||
global.atomApplication.addWindow(this)
|
||||
|
||||
@handleEvents()
|
||||
|
||||
@@ -47,7 +47,7 @@ class AutoUpdateManager
|
||||
@setState(ErrorState)
|
||||
console.error "Error Downloading Update: #{message}"
|
||||
|
||||
autoUpdater.on 'update-downloaded', (event, @releaseNotes, @releaseVersion) =>
|
||||
autoUpdater.on 'update-downloaded', (event, releaseNotes, @releaseVersion) =>
|
||||
@setState(UpdateAvailableState)
|
||||
@emitUpdateAvailableEvent(@getWindows()...)
|
||||
|
||||
@@ -61,9 +61,9 @@ class AutoUpdateManager
|
||||
@setState(UnsupportedState)
|
||||
|
||||
emitUpdateAvailableEvent: (windows...) ->
|
||||
return unless @releaseVersion? and @releaseNotes
|
||||
return unless @releaseVersion?
|
||||
for atomWindow in windows
|
||||
atomWindow.sendMessage('update-available', {@releaseVersion, @releaseNotes})
|
||||
atomWindow.sendMessage('update-available', {@releaseVersion})
|
||||
|
||||
setState: (state) ->
|
||||
return if @state is state
|
||||
|
||||
@@ -2,7 +2,7 @@ global.shellStartTime = Date.now()
|
||||
|
||||
crashReporter = require 'crash-reporter'
|
||||
app = require 'app'
|
||||
fs = require 'fs'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
optimist = require 'optimist'
|
||||
nslog = require 'nslog'
|
||||
@@ -14,6 +14,7 @@ process.on 'uncaughtException', (error={}) ->
|
||||
nslog(error.stack) if error.stack?
|
||||
|
||||
start = ->
|
||||
setupAtomHome()
|
||||
if process.platform is 'win32'
|
||||
SquirrelUpdate = require './squirrel-update'
|
||||
squirrelCommand = process.argv[1]
|
||||
@@ -42,10 +43,11 @@ start = ->
|
||||
|
||||
cwd = args.executedFrom?.toString() or process.cwd()
|
||||
args.pathsToOpen = args.pathsToOpen.map (pathToOpen) ->
|
||||
pathToOpen = fs.normalize(pathToOpen)
|
||||
if cwd
|
||||
path.resolve(cwd, pathToOpen.toString())
|
||||
path.resolve(cwd, pathToOpen)
|
||||
else
|
||||
path.resolve(pathToOpen.toString())
|
||||
path.resolve(pathToOpen)
|
||||
|
||||
setupCoffeeScript()
|
||||
if args.devMode
|
||||
@@ -73,6 +75,14 @@ setupCoffeeScript = ->
|
||||
js = CoffeeScript.compile(coffee, filename: filePath)
|
||||
module._compile(js, filePath)
|
||||
|
||||
setupAtomHome = ->
|
||||
return if process.env.ATOM_HOME
|
||||
|
||||
atomHome = path.join(app.getHomeDir(), '.atom')
|
||||
try
|
||||
atomHome = fs.realpathSync(atomHome)
|
||||
process.env.ATOM_HOME = atomHome
|
||||
|
||||
parseCommandLine = ->
|
||||
version = app.getVersion()
|
||||
options = optimist(process.argv[1..])
|
||||
@@ -89,8 +99,12 @@ parseCommandLine = ->
|
||||
opened or a new window if it hasn't.
|
||||
|
||||
Environment Variables:
|
||||
ATOM_DEV_RESOURCE_PATH The path from which Atom loads source code in dev mode.
|
||||
Defaults to `~/github/atom`.
|
||||
|
||||
ATOM_DEV_RESOURCE_PATH The path from which Atom loads source code in dev mode.
|
||||
Defaults to `~/github/atom`.
|
||||
|
||||
ATOM_HOME The root path for all configuration files and folders.
|
||||
Defaults to `~/.atom`.
|
||||
"""
|
||||
options.alias('d', 'dev').boolean('d').describe('d', 'Run in development mode.')
|
||||
options.alias('f', 'foreground').boolean('f').describe('f', 'Keep the browser process in the foreground.')
|
||||
|
||||
@@ -48,5 +48,8 @@ class BufferedNodeProcess extends BufferedProcess
|
||||
options.env ?= Object.create(process.env)
|
||||
options.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = 1
|
||||
|
||||
args = args?.slice() ? []
|
||||
args.unshift(command)
|
||||
args.unshift('--no-deprecation')
|
||||
|
||||
super({command: node, args, options, stdout, stderr, exit})
|
||||
|
||||
@@ -5,7 +5,7 @@ CoffeeScript = require 'coffee-script'
|
||||
CSON = require 'season'
|
||||
fs = require 'fs-plus'
|
||||
|
||||
cacheDir = path.join(fs.absolute('~/.atom'), 'compile-cache')
|
||||
cacheDir = path.join(process.env.ATOM_HOME, 'compile-cache')
|
||||
|
||||
stats =
|
||||
hits: 0
|
||||
@@ -61,13 +61,15 @@ module.exports =
|
||||
})
|
||||
|
||||
addPathToCache: (filePath) ->
|
||||
extension = path.extname(filePath)
|
||||
if extension is '.coffee'
|
||||
content = fs.readFileSync(filePath, 'utf8')
|
||||
cachePath = getCachePath(coffee)
|
||||
compileCoffeeScript(coffee, filePath, cachePath)
|
||||
else if extension is '.cson'
|
||||
CSON.readFileSync(filePath)
|
||||
switch path.extname(filePath)
|
||||
when '.coffee'
|
||||
content = fs.readFileSync(filePath, 'utf8')
|
||||
cachePath = getCachePath(coffee)
|
||||
compileCoffeeScript(coffee, filePath, cachePath)
|
||||
when '.cson'
|
||||
CSON.readFileSync(filePath)
|
||||
when '.js'
|
||||
require('./6to5').addPathToCache(filePath)
|
||||
|
||||
getCacheMisses: -> stats.misses
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ ScopeDescriptor = require './scope-descriptor'
|
||||
#
|
||||
# ## Config Schemas
|
||||
#
|
||||
# We use [json schema](json-schema.org) which allows you to define your value's
|
||||
# We use [json schema](http://json-schema.org) which allows you to define your value's
|
||||
# default, the type it should be, etc. A simple example:
|
||||
#
|
||||
# ```coffee
|
||||
@@ -519,7 +519,7 @@ class Config
|
||||
# * `options` (optional) {Object} see the `options` argument to {::get}
|
||||
#
|
||||
# Returns an {Array} of {Object}s with the following keys:
|
||||
# * `scopeSelector` The scope-selector {String} with which the value is associated
|
||||
# * `scopeDescriptor` The {ScopeDescriptor} with which the value is associated
|
||||
# * `value` The value for the key-path
|
||||
getAll: (keyPath, options) ->
|
||||
{scope, sources} = options if options?
|
||||
@@ -602,7 +602,7 @@ class Config
|
||||
return false
|
||||
|
||||
if scopeSelector?
|
||||
@setRawScopedValue(source, scopeSelector, keyPath, value)
|
||||
@setRawScopedValue(keyPath, value, source, scopeSelector)
|
||||
else
|
||||
@setRawValue(keyPath, value)
|
||||
|
||||
@@ -797,6 +797,7 @@ class Config
|
||||
_.extend rootSchema, schema
|
||||
@setDefaults(keyPath, @extractDefaultsFromSchema(schema))
|
||||
@setScopedDefaultsFromSchema(keyPath, schema)
|
||||
@resetSettingsForSchemaChange()
|
||||
|
||||
load: ->
|
||||
@initializeConfigDirectory()
|
||||
@@ -867,7 +868,12 @@ class Config
|
||||
save: ->
|
||||
allSettings = {'*': @settings}
|
||||
allSettings = _.extend allSettings, @scopedSettingsStore.propertiesForSource(@getUserConfigPath())
|
||||
CSON.writeFileSync(@configFilePath, allSettings)
|
||||
try
|
||||
CSON.writeFileSync(@configFilePath, allSettings)
|
||||
catch error
|
||||
message = "Failed to save `#{path.basename(@configFilePath)}`"
|
||||
detail = error.message
|
||||
@notifyFailure(message, detail)
|
||||
|
||||
###
|
||||
Section: Private methods managing global settings
|
||||
@@ -998,9 +1004,28 @@ class Config
|
||||
defaults[key] = @extractDefaultsFromSchema(value) for key, value of properties
|
||||
defaults
|
||||
|
||||
makeValueConformToSchema: (keyPath, value) ->
|
||||
value = @constructor.executeSchemaEnforcers(keyPath, value, schema) if schema = @getSchema(keyPath)
|
||||
value
|
||||
makeValueConformToSchema: (keyPath, value, options) ->
|
||||
if options?.suppressException
|
||||
try
|
||||
@makeValueConformToSchema(keyPath, value)
|
||||
catch e
|
||||
undefined
|
||||
else
|
||||
value = @constructor.executeSchemaEnforcers(keyPath, value, schema) if schema = @getSchema(keyPath)
|
||||
value
|
||||
|
||||
# When the schema is changed / added, there may be values set in the config
|
||||
# that do not conform to the schema. This will reset make them conform.
|
||||
resetSettingsForSchemaChange: (source=@getUserConfigPath()) ->
|
||||
@transact =>
|
||||
@settings = @makeValueConformToSchema(null, @settings, suppressException: true)
|
||||
priority = @priorityForSource(source)
|
||||
selectorsAndSettings = @scopedSettingsStore.propertiesForSource(source)
|
||||
@scopedSettingsStore.removePropertiesForSource(source)
|
||||
for scopeSelector, settings of selectorsAndSettings
|
||||
settings = @makeValueConformToSchema(null, settings, suppressException: true)
|
||||
@setRawScopedValue(null, settings, source, scopeSelector)
|
||||
return
|
||||
|
||||
###
|
||||
Section: Private Scoped Settings
|
||||
@@ -1017,8 +1042,15 @@ class Config
|
||||
|
||||
resetUserScopedSettings: (newScopedSettings) ->
|
||||
source = @getUserConfigPath()
|
||||
priority = @priorityForSource(source)
|
||||
@scopedSettingsStore.removePropertiesForSource(source)
|
||||
@scopedSettingsStore.addProperties(source, newScopedSettings, priority: @priorityForSource(source))
|
||||
|
||||
for scopeSelector, settings of newScopedSettings
|
||||
settings = @makeValueConformToSchema(null, settings, suppressException: true)
|
||||
validatedSettings = {}
|
||||
validatedSettings[scopeSelector] = withoutEmptyObjects(settings)
|
||||
@scopedSettingsStore.addProperties(source, validatedSettings, {priority}) if validatedSettings[scopeSelector]?
|
||||
|
||||
@emitChangeEvent()
|
||||
|
||||
addScopedSettings: (source, selector, value, options) ->
|
||||
@@ -1031,7 +1063,7 @@ class Config
|
||||
disposable.dispose()
|
||||
@emitChangeEvent()
|
||||
|
||||
setRawScopedValue: (source, selector, keyPath, value) ->
|
||||
setRawScopedValue: (keyPath, value, source, selector, options) ->
|
||||
if keyPath?
|
||||
newValue = {}
|
||||
_.setValueForKeyPath(newValue, keyPath, value)
|
||||
@@ -1118,12 +1150,17 @@ Config.addSchemaEnforcers
|
||||
return value unless schema.properties?
|
||||
|
||||
newValue = {}
|
||||
for prop, childSchema of schema.properties
|
||||
continue unless value.hasOwnProperty(prop)
|
||||
try
|
||||
newValue[prop] = @executeSchemaEnforcers("#{keyPath}.#{prop}", value[prop], childSchema)
|
||||
catch error
|
||||
console.warn "Error setting item in object: #{error.message}"
|
||||
for prop, propValue of value
|
||||
childSchema = schema.properties[prop]
|
||||
if childSchema?
|
||||
try
|
||||
newValue[prop] = @executeSchemaEnforcers("#{keyPath}.#{prop}", propValue, childSchema)
|
||||
catch error
|
||||
console.warn "Error setting item in object: #{error.message}"
|
||||
else
|
||||
# Just pass through un-schema'd values
|
||||
newValue[prop] = propValue
|
||||
|
||||
newValue
|
||||
|
||||
'array':
|
||||
|
||||
@@ -32,7 +32,7 @@ class LanguageMode
|
||||
|
||||
return unless commentStartEntry?
|
||||
|
||||
commentEndEntry = atom.config.getAll('editor.commentEnd', {scope}).find (entry) ->
|
||||
commentEndEntry = _.find atom.config.getAll('editor.commentEnd', {scope}), (entry) ->
|
||||
entry.scopeSelector is commentStartEntry.scopeSelector
|
||||
commentStartString = commentStartEntry?.value
|
||||
commentEndString = commentEndEntry?.value
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
LessCache = require 'less-cache'
|
||||
{Subscriber} = require 'emissary'
|
||||
|
||||
# {LessCache} wrapper used by {ThemeManager} to read stylesheets.
|
||||
module.exports =
|
||||
class LessCompileCache
|
||||
Subscriber.includeInto(this)
|
||||
|
||||
@cacheDir: path.join(require('./coffee-cache').cacheDir, 'less')
|
||||
@cacheDir: path.join(process.env.ATOM_HOME, 'compile-cache', 'less')
|
||||
|
||||
constructor: ({resourcePath, importPaths}) ->
|
||||
@lessSearchPaths = [
|
||||
@@ -35,5 +31,3 @@ class LessCompileCache
|
||||
|
||||
cssForFile: (stylesheetPath, lessContent) ->
|
||||
@cache.cssForFile(stylesheetPath, lessContent)
|
||||
|
||||
destroy: -> @unsubscribe()
|
||||
|
||||
@@ -213,8 +213,7 @@ LinesComponent = React.createClass
|
||||
innerHTML = ""
|
||||
|
||||
scopeStack = []
|
||||
firstTrailingWhitespacePosition = text.search(/\s*$/)
|
||||
lineIsWhitespaceOnly = firstTrailingWhitespacePosition is 0
|
||||
lineIsWhitespaceOnly = line.isOnlyWhitespace()
|
||||
for token in tokens
|
||||
innerHTML += @updateScopeStack(scopeStack, token.scopes)
|
||||
hasIndentGuide = not editor.isMini() and showIndentGuide and (token.hasLeadingWhitespace() or (token.hasTrailingWhitespace() and lineIsWhitespaceOnly))
|
||||
|
||||
@@ -176,7 +176,7 @@ class MenuManager
|
||||
element?.classList.toString().split(' ') ? []
|
||||
|
||||
sortPackagesMenu: ->
|
||||
packagesMenu = @template.find ({label}) -> MenuHelpers.normalizeLabel(label) is 'Packages'
|
||||
packagesMenu = _.find @template, ({label}) -> MenuHelpers.normalizeLabel(label) is 'Packages'
|
||||
return unless packagesMenu?.submenu?
|
||||
|
||||
packagesMenu.submenu.sort (item1, item2) ->
|
||||
|
||||
@@ -7,6 +7,7 @@ fs = require 'fs-plus'
|
||||
Q = require 'q'
|
||||
Grim = require 'grim'
|
||||
|
||||
ServiceHub = require 'service-hub'
|
||||
Package = require './package'
|
||||
ThemePackage = require './theme-package'
|
||||
|
||||
@@ -40,6 +41,7 @@ class PackageManager
|
||||
@loadedPackages = {}
|
||||
@activePackages = {}
|
||||
@packageStates = {}
|
||||
@serviceHub = new ServiceHub
|
||||
|
||||
@packageActivators = []
|
||||
@registerPackageActivator(this, ['atom', 'textmate'])
|
||||
|
||||
@@ -159,6 +159,7 @@ class Package
|
||||
if @requireMainModule()
|
||||
@mainModule.activate(atom.packages.getPackageState(@name) ? {})
|
||||
@mainActivated = true
|
||||
@activateServices()
|
||||
catch e
|
||||
console.warn "Failed to activate package named '#{@name}'", e.stack
|
||||
|
||||
@@ -209,6 +210,15 @@ class Package
|
||||
settings.activate() for settings in @settings
|
||||
@settingsActivated = true
|
||||
|
||||
activateServices: ->
|
||||
for name, {versions} of @metadata.providedServices
|
||||
for version, methodName of versions
|
||||
@activationDisposables.add atom.packages.serviceHub.provide(name, version, @mainModule[methodName]())
|
||||
|
||||
for name, {versions} of @metadata.consumedServices
|
||||
for version, methodName of versions
|
||||
@activationDisposables.add atom.packages.serviceHub.consume(name, version, @mainModule[methodName].bind(@mainModule))
|
||||
|
||||
loadKeymaps: ->
|
||||
if @bundledPackage and packagesCache[@name]?
|
||||
@keymaps = (["#{atom.packages.resourcePath}#{path.sep}#{keymapPath}", keymapObject] for keymapPath, keymapObject of packagesCache[@name].keymaps)
|
||||
|
||||
@@ -48,7 +48,7 @@ class PaneContainer extends Model
|
||||
deserializeParams: (params) ->
|
||||
params.root = atom.deserializers.deserialize(params.root, container: this)
|
||||
params.destroyEmptyPanes = atom.config.get('core.destroyEmptyPanes')
|
||||
params.activePane = params.root.getPanes().find (pane) -> pane.id is params.activePaneId
|
||||
params.activePane = find params.root.getPanes(), (pane) -> pane.id is params.activePaneId
|
||||
params
|
||||
|
||||
serializeParams: (params) ->
|
||||
@@ -147,17 +147,17 @@ class PaneContainer extends Model
|
||||
find @getPanes(), (pane) -> pane.itemForURI(uri)?
|
||||
|
||||
paneForItem: (item) ->
|
||||
@getPanes().find (pane) -> item in pane.getItems()
|
||||
find @getPanes(), (pane) -> item in pane.getItems()
|
||||
|
||||
saveAll: ->
|
||||
pane.saveItems() for pane in @getPanes()
|
||||
|
||||
confirmClose: ->
|
||||
confirmClose: (options) ->
|
||||
allSaved = true
|
||||
|
||||
for pane in @getPanes()
|
||||
for item in pane.getItems()
|
||||
unless pane.promptToSaveItem(item)
|
||||
unless pane.promptToSaveItem(item, options)
|
||||
allSaved = false
|
||||
break
|
||||
|
||||
|
||||
@@ -437,8 +437,8 @@ class Pane extends Model
|
||||
destroyInactiveItems: ->
|
||||
@destroyItem(item) for item in @getItems() when item isnt @activeItem
|
||||
|
||||
promptToSaveItem: (item) ->
|
||||
return true unless item.shouldPromptToSave?()
|
||||
promptToSaveItem: (item, options={}) ->
|
||||
return true unless item.shouldPromptToSave?(options)
|
||||
|
||||
if typeof item.getURI is 'function'
|
||||
uri = item.getURI()
|
||||
@@ -481,7 +481,10 @@ class Pane extends Model
|
||||
itemURI = item.getUri()
|
||||
|
||||
if itemURI?
|
||||
item.save?()
|
||||
try
|
||||
item.save?()
|
||||
catch error
|
||||
@handleSaveError(error)
|
||||
nextAction?()
|
||||
else
|
||||
@saveItemAs(item, nextAction)
|
||||
@@ -498,7 +501,10 @@ class Pane extends Model
|
||||
itemPath = item.getPath?()
|
||||
newItemPath = atom.showSaveDialogSync(itemPath)
|
||||
if newItemPath
|
||||
item.saveAs(newItemPath)
|
||||
try
|
||||
item.saveAs(newItemPath)
|
||||
catch error
|
||||
@handleSaveError(error)
|
||||
nextAction?()
|
||||
|
||||
# Public: Save all items.
|
||||
@@ -667,3 +673,18 @@ class Pane extends Model
|
||||
for item in @getItems()
|
||||
return false unless @promptToSaveItem(item)
|
||||
true
|
||||
|
||||
handleSaveError: (error) ->
|
||||
if error.message.endsWith('is a directory')
|
||||
atom.notifications.addWarning("Unable to save file: #{error.message}")
|
||||
else if error.code is 'EACCES' and error.path?
|
||||
atom.notifications.addWarning("Unable to save file: Permission denied '#{error.path}'")
|
||||
else if error.code in ['EPERM', 'EBUSY', 'UNKNOWN'] and error.path?
|
||||
atom.notifications.addWarning("Unable to save file '#{error.path}'", detail: error.message)
|
||||
else if error.code is 'EROFS' and error.path?
|
||||
atom.notifications.addWarning("Unable to save file: Read-only file system '#{error.path}'")
|
||||
else if errorMatch = /ENOTDIR, not a directory '([^']+)'/.exec(error.message)
|
||||
fileName = errorMatch[1]
|
||||
atom.notifications.addWarning("Unable to save file: A directory in the path '#{fileName}' could not be written to")
|
||||
else
|
||||
throw error
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
_ServiceHub = require('service-hub')
|
||||
|
||||
# Experimental: This class facilitates communication between Atom packages
|
||||
# through semantically-versioned services. If you want your package to provide
|
||||
# an API for other packages to interact with, provide or consume a service via
|
||||
# the global instance of this class available as `atom.services`.
|
||||
#
|
||||
# If you're providing an API for other packages, the most straightforward is to
|
||||
# `provide` a module namespaced under your package's name as follows.
|
||||
#
|
||||
# ```coffee
|
||||
# atom.services.provide "status-bar", "1.0.0",
|
||||
# addRightItem: (item) -> # ...
|
||||
# addLeftItem: (item) -> # ...
|
||||
# ```
|
||||
#
|
||||
# Then other packages can interact with your package by consuming the provided
|
||||
# service. Note that a service consumer can provide an npm-style version range
|
||||
# string to express the required API version of the consumed service. The
|
||||
# callback will be invoked with the service immediately or when the service
|
||||
# becomes available. If multiple services match the provided key-path and
|
||||
# version range, the callback will be invoked multiple times.
|
||||
#
|
||||
# ```coffee
|
||||
# atom.services.consume "status-bar", "^1.0.0", (statusBar) ->
|
||||
# statusBar.addLeftItem(new GrammarChanger)
|
||||
# ```
|
||||
#
|
||||
# You can also provide multiple services end-points under the same namespace by
|
||||
# passing a dot-separated key path. In this example, we also provide a global
|
||||
# reference to the status bar's DOM element so other packages can modify it
|
||||
# directly. Doing this via `atom.services` is superior to querying from the DOM
|
||||
# manually because you can use semantic versioning to indicate when the DOM
|
||||
# structure changes in a breaking way.
|
||||
#
|
||||
# ```coffee
|
||||
# atom.services.provide "status-bar.view", "1.0.0", statusBarElement
|
||||
# ```
|
||||
#
|
||||
# By convention, every package owns its package name in the services namespace.
|
||||
# Your package can provide a service under another package's namespace, but you
|
||||
# should always conform to that package's API. If you want to make additions to
|
||||
# the API, add them under your own namespace.
|
||||
#
|
||||
# When upgrading your package's API, consider retaining previous versions with
|
||||
# shims if at all possible to minimize breakage and to give the ecosystem time
|
||||
# to catch up with your changes.
|
||||
#
|
||||
# You can also apply an inverted pattern, where your package consumes services
|
||||
# under its own namespace. In this pattern, you would define a contract for
|
||||
# services that other packages provide and your package consumes. For example,
|
||||
# say we were adding the ability to add custom completion providers to
|
||||
# autocomplete:
|
||||
#
|
||||
# ```coffee
|
||||
# atom.services.consume "autocomplete", "1.0.0", (provider) ->
|
||||
# addCompletionProvider(provider)
|
||||
# ```
|
||||
#
|
||||
# In this use case, you would want to consume a specific version number rather
|
||||
# than a range. You could consume multiple version numbers to provide backward
|
||||
# compatibility.
|
||||
module.exports =
|
||||
class ServiceHub extends _ServiceHub
|
||||
# Experimental: Provide a service by invoking the callback of all current and
|
||||
# future consumers matching the given key path and version range.
|
||||
#
|
||||
# * `keyPath` A {String} of `.` separated keys indicating the services's
|
||||
# location in the namespace of all services.
|
||||
# * `version` A {String} containing a [semantic version](http://semver.org/)
|
||||
# for the service's API.
|
||||
# * `service` An object exposing the service API.
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to remove the
|
||||
# provided service.
|
||||
provide: (keyPath, version, service) ->
|
||||
super
|
||||
|
||||
# Experimental: Consume a service by invoking the given callback for all
|
||||
# current and future provided services matching the given key path and version
|
||||
# range.
|
||||
#
|
||||
# * `keyPath` A {String} of `.` separated keys indicating the services's
|
||||
# location in the namespace of all services.
|
||||
# * `versionRange` A {String} containing a [semantic version range](https://www.npmjs.org/doc/misc/semver.html)
|
||||
# that any provided services for the given key path must satisfy.
|
||||
# * `callback` A {Function} to be called with current and future matching
|
||||
# service objects.
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to remove the
|
||||
# consumer.
|
||||
consume: (keyPath, versionRange, callback) ->
|
||||
super
|
||||
@@ -641,7 +641,11 @@ class TextEditor extends Model
|
||||
|
||||
# Determine whether the user should be prompted to save before closing
|
||||
# this editor.
|
||||
shouldPromptToSave: -> @isModified() and not @buffer.hasMultipleEditors()
|
||||
shouldPromptToSave: ({windowCloseRequested}={}) ->
|
||||
if windowCloseRequested
|
||||
@isModified()
|
||||
else
|
||||
@isModified() and not @buffer.hasMultipleEditors()
|
||||
|
||||
###
|
||||
Section: Reading Text
|
||||
|
||||
@@ -266,7 +266,11 @@ class ThemeManager
|
||||
"""
|
||||
atom.notifications.addError(message, dismissable: true)
|
||||
|
||||
userStylesheetContents = @loadStylesheet(userStylesheetPath, true)
|
||||
try
|
||||
userStylesheetContents = @loadStylesheet(userStylesheetPath, true)
|
||||
catch
|
||||
return
|
||||
|
||||
@userStyleSheetDisposable = atom.styles.addStyleSheet(userStylesheetContents, sourcePath: userStylesheetPath, priority: 2)
|
||||
|
||||
loadBaseStylesheets: ->
|
||||
@@ -320,6 +324,7 @@ class ThemeManager
|
||||
detail = error.message
|
||||
|
||||
atom.notifications.addError(message, {detail, dismissable: true})
|
||||
throw error
|
||||
|
||||
removeStylesheet: (stylesheetPath) ->
|
||||
@styleSheetDisposablesBySourcePath[stylesheetPath]?.dispose()
|
||||
|
||||
@@ -9,6 +9,7 @@ idCounter = 1
|
||||
module.exports =
|
||||
class TokenizedLine
|
||||
endOfLineInvisibles: null
|
||||
lineIsWhitespaceOnly: false
|
||||
|
||||
constructor: ({tokens, @lineEnding, @ruleStack, @startBufferColumn, @fold, @tabLength, @indentLevel, @invisibles}) ->
|
||||
@startBufferColumn ?= 0
|
||||
@@ -146,7 +147,7 @@ class TokenizedLine
|
||||
markLeadingAndTrailingWhitespaceTokens: ->
|
||||
firstNonWhitespaceIndex = @text.search(NonWhitespaceRegex)
|
||||
firstTrailingWhitespaceIndex = @text.search(TrailingWhitespaceRegex)
|
||||
lineIsWhitespaceOnly = firstTrailingWhitespaceIndex is 0
|
||||
@lineIsWhitespaceOnly = firstTrailingWhitespaceIndex is 0
|
||||
index = 0
|
||||
for token in @tokens
|
||||
if index < firstNonWhitespaceIndex
|
||||
@@ -202,12 +203,7 @@ class TokenizedLine
|
||||
false
|
||||
|
||||
isOnlyWhitespace: ->
|
||||
if @text == ''
|
||||
true
|
||||
else
|
||||
for token in @tokens
|
||||
return false unless token.isOnlyWhitespace()
|
||||
true
|
||||
@lineIsWhitespaceOnly
|
||||
|
||||
tokenAtIndex: (index) ->
|
||||
@tokens[index]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{find} = require 'underscore-plus'
|
||||
Grim = require 'grim'
|
||||
{Disposable} = require 'event-kit'
|
||||
|
||||
@@ -148,4 +149,4 @@ class ViewRegistry
|
||||
throw new Error("Can't create a view for #{object.constructor.name} instance. Please register a view provider.")
|
||||
|
||||
findProvider: (object) ->
|
||||
@providers.find ({modelConstructor}) -> object instanceof modelConstructor
|
||||
find @providers, ({modelConstructor}) -> object instanceof modelConstructor
|
||||
|
||||
@@ -31,8 +31,8 @@ class WindowEventHandler
|
||||
atom.updateAvailable(detail)
|
||||
|
||||
# FIXME: Remove this when deprecations are removed
|
||||
{releaseVersion, releaseNotes} = detail
|
||||
detail = [releaseVersion, releaseNotes]
|
||||
{releaseVersion} = detail
|
||||
detail = [releaseVersion]
|
||||
if workspaceElement = atom.views.getView(atom.workspace)
|
||||
atom.commands.dispatch workspaceElement, "window:update-available", detail
|
||||
|
||||
@@ -52,7 +52,7 @@ class WindowEventHandler
|
||||
@subscribe $(window), 'blur', -> document.body.classList.add('is-blurred')
|
||||
|
||||
@subscribe $(window), 'beforeunload', =>
|
||||
confirmed = atom.workspace?.confirmClose()
|
||||
confirmed = atom.workspace?.confirmClose(windowCloseRequested: true)
|
||||
atom.hide() if confirmed and not @reloadRequested and atom.getCurrentWindow().isWebViewFocused()
|
||||
@reloadRequested = false
|
||||
|
||||
|
||||
@@ -599,8 +599,8 @@ class Workspace extends Model
|
||||
saveAll: ->
|
||||
@paneContainer.saveAll()
|
||||
|
||||
confirmClose: ->
|
||||
@paneContainer.confirmClose()
|
||||
confirmClose: (options) ->
|
||||
@paneContainer.confirmClose(options)
|
||||
|
||||
# Save the active pane item.
|
||||
#
|
||||
@@ -609,7 +609,7 @@ class Workspace extends Model
|
||||
# {::saveActivePaneItemAs} # will be called instead. This method does nothing
|
||||
# if the active item does not implement a `.save` method.
|
||||
saveActivePaneItem: ->
|
||||
@saveActivePaneItemAndReportErrors('saveActiveItem')
|
||||
@getActivePane().saveActiveItem()
|
||||
|
||||
# Prompt the user for a path and save the active pane item to it.
|
||||
#
|
||||
@@ -617,27 +617,7 @@ class Workspace extends Model
|
||||
# `.saveAs` on the item with the selected path. This method does nothing if
|
||||
# the active item does not implement a `.saveAs` method.
|
||||
saveActivePaneItemAs: ->
|
||||
@saveActivePaneItemAndReportErrors('saveActiveItemAs')
|
||||
|
||||
saveActivePaneItemAndReportErrors: (method) ->
|
||||
try
|
||||
@getActivePane()[method]()
|
||||
catch error
|
||||
if error.message.endsWith('is a directory')
|
||||
atom.notifications.addWarning("Unable to save file: #{error.message}")
|
||||
else if error.code is 'EACCES' and error.path?
|
||||
atom.notifications.addWarning("Unable to save file: Permission denied '#{error.path}'")
|
||||
else if error.code is 'EPERM' and error.path?
|
||||
atom.notifications.addWarning("Unable to save file '#{error.path}'", detail: error.message)
|
||||
else if error.code is 'EBUSY' and error.path?
|
||||
atom.notifications.addWarning("Unable to save file '#{error.path}'", detail: error.message)
|
||||
else if error.code is 'EROFS' and error.path?
|
||||
atom.notifications.addWarning("Unable to save file: Read-only file system '#{error.path}'")
|
||||
else if errorMatch = /ENOTDIR, not a directory '([^']+)'/.exec(error.message)
|
||||
fileName = errorMatch[1]
|
||||
atom.notifications.addWarning("Unable to save file: A directory in the path '#{fileName}' could not be written to")
|
||||
else
|
||||
throw error
|
||||
@getActivePane().saveActiveItemAs()
|
||||
|
||||
# Destroy (close) the active pane item.
|
||||
#
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
function registerRuntimeTranspilers() {
|
||||
// This sets require.extensions['.coffee'].
|
||||
require('coffee-script').register();
|
||||
|
||||
// This redefines require.extensions['.js'].
|
||||
require('../src/6to5').register();
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
try {
|
||||
var startTime = Date.now();
|
||||
@@ -5,6 +13,23 @@ window.onload = function() {
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
// Ensure ATOM_HOME is always set before anything else is required
|
||||
if (!process.env.ATOM_HOME) {
|
||||
var home;
|
||||
if (process.platform === 'win32') {
|
||||
home = process.env.USERPROFILE;
|
||||
} else {
|
||||
home = process.env.HOME;
|
||||
}
|
||||
var atomHome = path.join(home, '.atom');
|
||||
try {
|
||||
atomHome = fs.realpathSync(atomHome);
|
||||
} catch (error) {
|
||||
// Ignore since the path might just not exist yet.
|
||||
}
|
||||
process.env.ATOM_HOME = atomHome;
|
||||
}
|
||||
|
||||
// Skip "?loadSettings=".
|
||||
var rawLoadSettings = decodeURIComponent(location.search.substr(14));
|
||||
var loadSettings;
|
||||
@@ -22,7 +47,7 @@ window.onload = function() {
|
||||
|
||||
// Require before the module cache in dev mode
|
||||
if (devMode) {
|
||||
require('coffee-script').register();
|
||||
registerRuntimeTranspilers();
|
||||
}
|
||||
|
||||
ModuleCache = require('../src/module-cache');
|
||||
@@ -41,7 +66,7 @@ window.onload = function() {
|
||||
require('vm-compatibility-layer');
|
||||
|
||||
if (!devMode) {
|
||||
require('coffee-script').register();
|
||||
registerRuntimeTranspilers();
|
||||
}
|
||||
|
||||
require('../src/coffee-cache').register();
|
||||
|
||||