Comparar commits
216 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 8fa6fdb90c | |||
| a57df59cb8 | |||
| 99d01b5d0e | |||
| c806fcf9e7 | |||
| 1bc9c2eb4b | |||
| bd08e36d2d | |||
| 76a2b8c54a | |||
| 131d2ab3ad | |||
| 0e0c508756 | |||
| 325d95ed35 | |||
| 081fc0e1ae | |||
| a6cc6afb16 | |||
| f330e58b4f | |||
| a406322748 | |||
| 8ee428f9dc | |||
| 437873411e | |||
| 00eecd4802 | |||
| 2cb13e1a66 | |||
| 8f7f1cef23 | |||
| 34d41efd9a | |||
| 82527c24f2 | |||
| ccfe787e4f | |||
| 4a5b43553b | |||
| da1ceb0e51 | |||
| 97e0ddf15d | |||
| fb3cc5554c | |||
| 184aecb4a4 | |||
| 181cecaf2f | |||
| ced66d920d | |||
| 6fe7eb086f | |||
| 462af79d21 | |||
| 771a60b1bc | |||
| 3e34e426bf | |||
| f77f48102c | |||
| 7dd67caf57 | |||
| 8081595523 | |||
| 47cd2359c8 | |||
| 13cf51f835 | |||
| 571d146ec0 | |||
| dc06173f2f | |||
| 358799285e | |||
| 8f4555b970 | |||
| e0bc7948ae | |||
| a606fc516b | |||
| 2c1f8ce733 | |||
| 62adc98b17 | |||
| 94e12ee886 | |||
| 4c74b07b22 | |||
| 8eb53696a6 | |||
| f9e28af59b | |||
| 3b5bb1501c | |||
| 8c4c15c17a | |||
| ae61ecf602 | |||
| 9a7582fd0b | |||
| f7f2f4497b | |||
| d4c4ab58b1 | |||
| a01e6e543e | |||
| d931b3ed5c | |||
| b95a7f47a8 | |||
| 06cbbe4b67 | |||
| 7d44026a92 | |||
| 11b0a80d3d | |||
| 92a8701c70 | |||
| 08e1d550c8 | |||
| c9eb84f2a4 | |||
| 74afcc58ac | |||
| 180725799a | |||
| 03468e405a | |||
| 1fd4e945ee | |||
| 0b48150b71 | |||
| bed8abea22 | |||
| 893bdda47d | |||
| 0b98093370 | |||
| 6abe05b1ab | |||
| 0f45937adf | |||
| c8726c991f | |||
| 60205aaabe | |||
| 6a16c8a59c | |||
| a055f09a6c | |||
| c19b42a49c | |||
| 2632e9aa10 | |||
| a9753d430e | |||
| 796eefd012 | |||
| 0f9eea34a5 | |||
| a84e19c9bd | |||
| 6d276d39d3 | |||
| ab203e5f81 | |||
| 61512b9e19 | |||
| c29c4652b0 | |||
| a9c0553e31 | |||
| 6d6e5baa9a | |||
| 1de76c7d73 | |||
| f6b7450dea | |||
| 71e1928f74 | |||
| 1a709065f8 | |||
| dca99cb34e | |||
| 3e79f54860 | |||
| a8b5960bc0 | |||
| 70e3484a16 | |||
| 5ac3f58cdb | |||
| 692f6947f2 | |||
| 08fad809d2 | |||
| ba63239928 | |||
| d90c8c0fb7 | |||
| 35e782f05d | |||
| 00af9a93d7 | |||
| 018e22ad8d | |||
| f73d3df233 | |||
| 25b44ceb1a | |||
| c28ecf1a7d | |||
| 478e80e585 | |||
| 08be377004 | |||
| 4db3e47377 | |||
| 76857b4486 | |||
| e743d93d6d | |||
| f443c375d4 | |||
| b9b488bee2 | |||
| e192922f0e | |||
| d1c41fbf68 | |||
| aa8b97a039 | |||
| 5276cb716a | |||
| 03f8a32f86 | |||
| eabb498af7 | |||
| a1e4c0bb05 | |||
| 6a285b695f | |||
| 7f66a2fca4 | |||
| 6565f6d608 | |||
| 493035fe4e | |||
| 6e30998ef5 | |||
| 825c4f6098 | |||
| b4756aa9b7 | |||
| 651fa1aa42 | |||
| db17fe2daa | |||
| 1e0c839257 | |||
| 18481789b0 | |||
| 304f63532e | |||
| 6e7364c7c6 | |||
| 339f331776 | |||
| 6b34a18bd9 | |||
| 32275b27a3 | |||
| 5c730415b7 | |||
| 637b2b0aba | |||
| b4246a2f07 | |||
| 31170dcfae | |||
| f784b51f12 | |||
| 3c6dab22d8 | |||
| e80f5acd50 | |||
| 90aca1c6ad | |||
| c7771ffde9 | |||
| bdfc862dac | |||
| 2c7aa170e9 | |||
| 6c8d624e73 | |||
| 57a876e677 | |||
| 20adc96e4c | |||
| d508d1eedf | |||
| 2949ebfe86 | |||
| dbaef8e593 | |||
| 3edd2f9590 | |||
| f2652bcb40 | |||
| d6c8ec83d4 | |||
| b4b492a321 | |||
| ba6a976013 | |||
| d0486cc923 | |||
| fb09f28c4c | |||
| 883c48b490 | |||
| ceefc15b15 | |||
| a0cc63273c | |||
| c328092463 | |||
| b1a3d89af3 | |||
| bd92acba7e | |||
| d90daf07f8 | |||
| 388428b074 | |||
| f439d0d996 | |||
| 4142845632 | |||
| 60c5293b5e | |||
| a1b4820c04 | |||
| 1cf8479831 | |||
| a14d57ceac | |||
| c1d5d96aca | |||
| b5632b6988 | |||
| fe02442b23 | |||
| 04ceaf36bf | |||
| 08d183dff1 | |||
| 134daa1fe2 | |||
| 360fbe2a3f | |||
| 8148446a86 | |||
| 16f56a068b | |||
| 11112cb374 | |||
| 5c7177746c | |||
| ab947ba87a | |||
| 8a4db34cb8 | |||
| 669088612c | |||
| 0a14d232d2 | |||
| 651fe5d71c | |||
| 7d49d50b34 | |||
| aab51d15ab | |||
| 1926156eee | |||
| b12a6abc90 | |||
| 46762c293f | |||
| 6b8ef25c8e | |||
| 03a769b516 | |||
| 229e7e03b2 | |||
| 45ee6df36e | |||
| 9422a8047a | |||
| 85456ad920 | |||
| 2f3d54db8a | |||
| bae903a772 | |||
| aabf4dfbab | |||
| 44327724a8 | |||
| 3c3e72e36d | |||
| e0741d2073 | |||
| d973ce9832 | |||
| 25cb56a936 | |||
| a0038b6f56 | |||
| aff1aa5112 | |||
| 3b6d55dbbb |
@@ -87,6 +87,7 @@ For more information on how to work with Atom's official packages, see
|
||||
* :white_check_mark: `:white_check_mark:` when adding tests
|
||||
* :lock: `:lock:` when dealing with security
|
||||
* :arrow_up: `:arrow_up:` when upgrading dependencies
|
||||
* :arrow_down: `:arrow_down:` when downgrading dependencies
|
||||
|
||||
## CoffeeScript Styleguide
|
||||
|
||||
|
||||
+1
-1
@@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "0.116.0"
|
||||
"atom-package-manager": "0.117.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"fs-plus": "2.x",
|
||||
"github-releases": "~0.2.0",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-atom-shell-installer": "^0.13.0",
|
||||
"grunt-atom-shell-installer": "^0.16.0",
|
||||
"grunt-cli": "~0.1.9",
|
||||
"grunt-coffeelint": "git+https://github.com/atom/grunt-coffeelint.git#cfb99aa99811d52687969532bd5a98011ed95bfe",
|
||||
"grunt-contrib-coffee": "~0.9.0",
|
||||
|
||||
@@ -71,6 +71,7 @@ module.exports = (grunt) ->
|
||||
path.join('build', 'Release', 'obj')
|
||||
path.join('build', 'Release', '.deps')
|
||||
path.join('vendor', 'apm')
|
||||
path.join('resources', 'linux')
|
||||
path.join('resources', 'mac')
|
||||
path.join('resources', 'win')
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
|
||||
@@ -101,7 +101,7 @@ getAssets = ->
|
||||
logError = (message, error, details) ->
|
||||
grunt.log.error(message)
|
||||
grunt.log.error(error.message ? error) if error?
|
||||
grunt.log.error(details) if details
|
||||
grunt.log.error(require('util').inspect(details)) if details
|
||||
|
||||
zipAssets = (buildDir, assets, callback) ->
|
||||
zip = (directory, sourcePath, assetName, callback) ->
|
||||
@@ -142,7 +142,30 @@ getAtomDraftRelease = (callback) ->
|
||||
firstDraft.assets = assets
|
||||
callback(null, firstDraft)
|
||||
else
|
||||
callback(new Error('No draft release in atom/atom repo'))
|
||||
createAtomDraftRelease(callback)
|
||||
|
||||
createAtomDraftRelease = (callback) ->
|
||||
{version} = require('../../package.json')
|
||||
options =
|
||||
uri: 'https://api.github.com/repos/atom/atom/releases'
|
||||
method: 'POST'
|
||||
headers: defaultHeaders
|
||||
json:
|
||||
tag_name: "v#{version}"
|
||||
name: version
|
||||
draft: true
|
||||
body: """
|
||||
### Notable Changes
|
||||
|
||||
* Something new
|
||||
"""
|
||||
|
||||
request options, (error, response, body='') ->
|
||||
if error? or response.statusCode isnt 201
|
||||
logError("Creating atom/atom draft release failed", error, body)
|
||||
callback(error ? new Error(response.statusCode))
|
||||
else
|
||||
callback(null, body)
|
||||
|
||||
deleteRelease = (release) ->
|
||||
options =
|
||||
|
||||
@@ -12,11 +12,18 @@ module.exports = (grunt) ->
|
||||
packageSpecQueue = null
|
||||
|
||||
logDeprecations = (label, {stderr}={}) ->
|
||||
if process.env.JANKY_SHA1 and stderr?.indexOf('Calls to deprecated functions') isnt -1
|
||||
grunt.log.error(label)
|
||||
stderr = stderr.replace(/^\[.*\] "/g, '')
|
||||
stderr = stderr.replace(/source: .*$/g, '')
|
||||
grunt.log.error(stderr)
|
||||
return unless process.env.JANKY_SHA1
|
||||
stderr ?= ''
|
||||
deprecatedStart = stderr.indexOf('Calls to deprecated functions')
|
||||
return if deprecatedStart.length is -1
|
||||
|
||||
grunt.log.error(label)
|
||||
stderr = stderr.substring(deprecatedStart)
|
||||
stderr = stderr.replace(/^\s*\[[^\]]+\]\s+/gm, '')
|
||||
stderr = stderr.replace(/source: .*$/gm, '')
|
||||
stderr = stderr.replace(/^"/gm, '')
|
||||
stderr = stderr.replace(/",\s*$/gm, '')
|
||||
grunt.log.error(stderr)
|
||||
|
||||
getAppPath = ->
|
||||
contentsDir = grunt.config.get('atom.contentsDir')
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
path = require 'path'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
grunt.registerTask 'update-octicons', 'Update octicon font and LESS variables', ->
|
||||
pathToOcticons = path.resolve('..', 'octicons')
|
||||
if grunt.file.isDir(pathToOcticons)
|
||||
# Copy font-file
|
||||
fontSrc = path.join(pathToOcticons, 'octicons', 'octicons.woff')
|
||||
fontDest = path.resolve('static', 'octicons.woff')
|
||||
grunt.file.copy(fontSrc, fontDest)
|
||||
|
||||
# Update Octicon UTF codes
|
||||
glyphsSrc = path.join(pathToOcticons, 'data', 'glyphs.yml')
|
||||
output = []
|
||||
for {css, code} in grunt.file.readYAML(glyphsSrc)
|
||||
output.push "@#{css}: \"\\#{code}\";"
|
||||
|
||||
octiconUtfDest = path.resolve('static', 'variables', 'octicon-utf-codes.less')
|
||||
grunt.file.write(octiconUtfDest, "#{output.join('\n')}\n")
|
||||
else
|
||||
grunt.log.error("octicons repo must be cloned to #{pathToOcticons}")
|
||||
false
|
||||
@@ -30,8 +30,8 @@ All requests that take parameters require `application/json`.
|
||||
Parameters:
|
||||
|
||||
- **page** (optional)
|
||||
- **sort** (optional, values: `created_at`, `updated_at`, `downloads`)
|
||||
- **direction** (optional, values: `asc`, `desc`)
|
||||
- **sort** (optional) - One of `downloads`, `created_at`, `updated_at`, `stars`. Defaults to `downloads`
|
||||
- **direction** (optional) - `asc` or `desc`. Defaults to `desc`. `stars` can only be ordered `desc`
|
||||
|
||||
Returns a list of all packages in the following format:
|
||||
```json
|
||||
@@ -61,17 +61,18 @@ Link: <https://www.atom.io/api/packages?page=1>; rel="self",
|
||||
|
||||
By default, results are sorted by download count, descending.
|
||||
|
||||
### Searching packages
|
||||
|
||||
#### GET /api/packages/search
|
||||
|
||||
Parameters:
|
||||
|
||||
- **q** String query to search
|
||||
- **sort** (optional, values: `created_at`, `updated_at`, `downloads`)
|
||||
- **direction** (optional, values: `asc`, `desc`)
|
||||
- **q** (required) - Search query
|
||||
- **page** (optional)
|
||||
- **sort** (optional) - One of `downloads`, `created_at`, `updated_at`, `stars`. Defaults to the relevance of the search query.
|
||||
- **direction** (optional) - `asc` or `desc`. Defaults to `desc`.
|
||||
|
||||
Returns a list of all packages in the same format as `/api/packages`.
|
||||
|
||||
By default, results sorted by relevance to search query.
|
||||
Returns results in the same format as [listing packages](#listing-packages).
|
||||
|
||||
### Showing package details
|
||||
|
||||
|
||||
@@ -26,13 +26,17 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
|
||||
|
||||
### Arch
|
||||
|
||||
* `sudo pacman -S base-devel git nodejs libgnome-keyring python2`
|
||||
* `sudo pacman -S gconf base-devel git nodejs libgnome-keyring python2`
|
||||
* `export PYTHON=/usr/bin/python2` before building Atom.
|
||||
|
||||
### Slackware
|
||||
|
||||
* `sbopkg -k -i node -i atom`
|
||||
|
||||
### openSUSE
|
||||
|
||||
* `sudo zypper install nodejs make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel rpmdevtools`
|
||||
|
||||
## Instructions
|
||||
|
||||
If you have problems with permissions don't forget to prefix with `sudo`
|
||||
|
||||
@@ -123,8 +123,8 @@ like you.
|
||||
|
||||
Style sheets for your package should be placed in the _stylesheets_ directory.
|
||||
Any style sheets in this directory will be loaded and attached to the DOM when
|
||||
your package is activated. Style sheets can be written as CSS or [LESS] (but
|
||||
LESS is recommended).
|
||||
your package is activated. Style sheets can be written as CSS or [LESS], but
|
||||
LESS is recommended.
|
||||
|
||||
Ideally, you won't need much in the way of styling. We've provided a standard
|
||||
set of components which define both the colors and UI elements for any package
|
||||
@@ -418,7 +418,7 @@ all the other available commands.
|
||||
[underscore]: http://underscorejs.org/
|
||||
[jasmine]: http://jasmine.github.io
|
||||
[cson]: https://github.com/atom/season
|
||||
[less]: http://lesscss.org
|
||||
[LESS]: http://lesscss.org
|
||||
[ui-variables]: https://github.com/atom/atom-dark-ui/blob/master/stylesheets/ui-variables.less
|
||||
[first-package]: your-first-package.html
|
||||
[convert-bundle]: converting-a-text-mate-bundle.html
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Creating a Theme
|
||||
|
||||
Atom's interface is rendered using HTML, and it's styled via [LESS] (a superset
|
||||
of CSS). Don't worry if you haven't heard of LESS before; it's just like CSS,
|
||||
but with a few handy extensions.
|
||||
Atom's interface is rendered using HTML, and it's styled via [LESS] which is a
|
||||
superset of CSS. Don't worry if you haven't heard of LESS before; it's just like
|
||||
CSS, but with a few handy extensions.
|
||||
|
||||
Atom supports two types of themes: _UI_ and _syntax_. UI themes style
|
||||
elements such as the tree view, the tabs, drop-down lists, and the status bar.
|
||||
@@ -131,7 +131,7 @@ _styleguide_, or use the shortcut `cmd-ctrl-shift-g`.
|
||||
![styleguide-img]
|
||||
|
||||
[atomio]: http://atom.io/packages
|
||||
[less]: http://lesscss.org/
|
||||
[LESS]: http://lesscss.org/
|
||||
[git]: http://git-scm.com/
|
||||
[atom]: https://atom.io/
|
||||
[package.json]: ./creating-a-package.html#package-json
|
||||
|
||||
@@ -105,6 +105,7 @@ You can open this file in an editor from the _Atom > Open Your Config_ menu.
|
||||
- `core`
|
||||
- `disabledPackages`: An array of package names to disable
|
||||
- `excludeVcsIgnoredPaths`: Don't search within files specified by _.gitignore_
|
||||
- `followSymlinks`: Follow symlinks when searching and scanning root directory
|
||||
- `ignoredNames`: File names to ignore across all of Atom
|
||||
- `projectHome`: The directory where projects are assumed to be located
|
||||
- `themes`: An array of theme names to load, in cascading order
|
||||
|
||||
+12
-1
@@ -3,7 +3,8 @@
|
||||
Atom provides several tools to help you understand unexpected behavior and debug problems. This guide describes some of those tools and a few approaches to help you debug and provide more helpful information when [submitting issues]:
|
||||
|
||||
* [Update to the latest version](#update-to-the-latest-version)
|
||||
* [Check Atom and package settings](#check-atom-and-package-settings)
|
||||
* [Check for linked packages](#check-for-linked-packages)
|
||||
* [Check Atom and package settings](#check-atom-and-package-settings)
|
||||
* [Check the keybindings](#check-the-keybindings)
|
||||
* [Check if the problem shows up in safe mode](#check-if-the-problem-shows-up-in-safe-mode)
|
||||
* [Check your config files](#check-your-config-files)
|
||||
@@ -24,6 +25,16 @@ $ atom --version
|
||||
|
||||
Head on over to the [list of releases][atom releases] and see if there's a more recent release. You can update to the most recent release by downloading Atom from the releases page, or with the in-app auto-updater. The in-app auto-updater checks for and downloads a new version after you restart Atom, or if you use the Atom > Check for Update menu option.
|
||||
|
||||
## Check for linked packages
|
||||
|
||||
If you develop or contribute to Atom packages, there may be left-over packages linked to your `~/.atom/packages` or `~/.atom/dev/packages` directories. You can use:
|
||||
|
||||
```shell
|
||||
$ apm links
|
||||
```
|
||||
|
||||
to list all linked development packages. You can remove the links using the `apm unlink` command. See `apm unlink --help` for details.
|
||||
|
||||
## Check Atom and package settings
|
||||
|
||||
In some cases, unexpected behavior might be caused by misconfigured or unconfigured settings in Atom or in one of the packages.
|
||||
|
||||
+16
-16
@@ -40,11 +40,11 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
Object.defineProperty module.exports, '$', get: ->
|
||||
deprecate """
|
||||
Requiring `$` from `atom` is no longer supported.
|
||||
If you are using `space-pen`, please require `$` from `space-pen`. Otherwise require `jquery` instead:
|
||||
`{$} = require 'space-pen'`
|
||||
If you are using `space-pen`, please require `$` from `atom-space-pen-views`. Otherwise require `jquery` instead:
|
||||
`{$} = require 'atom-space-pen-views'`
|
||||
or
|
||||
`$ = require 'jquery'`
|
||||
Add `"space-pen": "^4"` to your package dependencies.
|
||||
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
|
||||
Or add `"jquery": "^2"` to your package dependencies.
|
||||
"""
|
||||
$
|
||||
@@ -52,27 +52,27 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
Object.defineProperty module.exports, '$$', get: ->
|
||||
deprecate """
|
||||
Requiring `$$` from `atom` is no longer supported.
|
||||
Please require `space-pen` instead:
|
||||
`{$$} = require 'space-pen'`
|
||||
Add `"space-pen": "^4"` to your package dependencies.
|
||||
Please require `atom-space-pen-views` instead:
|
||||
`{$$} = require 'atom-space-pen-views'`
|
||||
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
|
||||
"""
|
||||
$$
|
||||
|
||||
Object.defineProperty module.exports, '$$$', get: ->
|
||||
deprecate """
|
||||
Requiring `$$$` from `atom` is no longer supported.
|
||||
Please require `space-pen` instead:
|
||||
`{$$$} = require 'space-pen'`
|
||||
Add `"space-pen": "^4"` to your package dependencies.
|
||||
Please require `atom-space-pen-views` instead:
|
||||
`{$$$} = require 'atom-space-pen-views'`
|
||||
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
|
||||
"""
|
||||
$$$
|
||||
|
||||
Object.defineProperty module.exports, 'View', get: ->
|
||||
deprecate """
|
||||
Requiring `View` from `atom` is no longer supported.
|
||||
Please require `space-pen` instead:
|
||||
`{View} = require 'space-pen'`
|
||||
Add `"space-pen": "^4"` to your package dependencies.
|
||||
Please require `atom-space-pen-views` instead:
|
||||
`{View} = require 'atom-space-pen-views'`
|
||||
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
|
||||
"""
|
||||
View
|
||||
|
||||
@@ -81,7 +81,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
Requiring `EditorView` from `atom` is no longer supported.
|
||||
Please require `TextEditorView` from `atom-space-pen-view` instead:
|
||||
`{TextEditorView} = require 'atom-space-pen-views'`
|
||||
Add `"atom-space-pen-views": "^0"` to your package dependencies.
|
||||
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
|
||||
"""
|
||||
require '../src/text-editor-view'
|
||||
|
||||
@@ -90,7 +90,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
Requiring `TextEditorView` from `atom` is no longer supported.
|
||||
Please require `TextEditorView` from `atom-space-pen-view` instead:
|
||||
`{TextEditorView} = require 'atom-space-pen-views'`
|
||||
Add `"atom-space-pen-views": "^0"` to your package dependencies.
|
||||
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
|
||||
"""
|
||||
require '../src/text-editor-view'
|
||||
|
||||
@@ -100,7 +100,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
Please require `ScrollView` from `atom-space-pen-view` instead:
|
||||
`{ScrollView} = require 'atom-space-pen-views'`
|
||||
Note that the API has changed slightly! Please read the docs at https://github.com/atom/atom-space-pen-views
|
||||
Add `"atom-space-pen-views": "^0"` to your package dependencies.
|
||||
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
|
||||
"""
|
||||
require '../src/scroll-view'
|
||||
|
||||
@@ -110,7 +110,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
Please require `SelectListView` from `atom-space-pen-view` instead:
|
||||
`{SelectListView} = require 'atom-space-pen-views'`
|
||||
Note that the API has changed slightly! Please read the docs at https://github.com/atom/atom-space-pen-views
|
||||
Add `"atom-space-pen-views": "^0"` to your package dependencies.
|
||||
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
|
||||
"""
|
||||
require '../src/select-list-view'
|
||||
|
||||
|
||||
+71
-71
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.164.0",
|
||||
"version": "0.169.0",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
@@ -17,23 +17,23 @@
|
||||
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
|
||||
}
|
||||
],
|
||||
"atomShellVersion": "0.19.4",
|
||||
"atomShellVersion": "0.20.5",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^2.3.0",
|
||||
"atom-keymap": "^2.3.3",
|
||||
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
|
||||
"clear-cut": "0.4.0",
|
||||
"coffee-script": "1.7.0",
|
||||
"coffeestack": "0.7.0",
|
||||
"delegato": "^1",
|
||||
"emissary": "^1.3.1",
|
||||
"event-kit": "0.8.1",
|
||||
"first-mate": "^2.2.0",
|
||||
"event-kit": "^1.0.1",
|
||||
"first-mate": "^2.2.3",
|
||||
"fs-plus": "^2.3.2",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "^2.1",
|
||||
"git-utils": "^2.2",
|
||||
"grim": "0.12.0",
|
||||
"grim": "1.0.0",
|
||||
"guid": "0.0.10",
|
||||
"jasmine-json": "~0.0",
|
||||
"jasmine-tagged": "^1.1.2",
|
||||
@@ -45,7 +45,7 @@
|
||||
"nslog": "^1.0.1",
|
||||
"oniguruma": "^3.0.4",
|
||||
"optimist": "0.4.0",
|
||||
"pathwatcher": "^2.3.5",
|
||||
"pathwatcher": "^2.3.7",
|
||||
"property-accessors": "^1",
|
||||
"q": "^1.0.1",
|
||||
"random-words": "0.0.1",
|
||||
@@ -53,7 +53,7 @@
|
||||
"reactionary-atom-fork": "^1.0.0",
|
||||
"runas": "1.0.1",
|
||||
"scandal": "1.0.3",
|
||||
"scoped-property-store": "^0.15.4",
|
||||
"scoped-property-store": "^0.16.2",
|
||||
"scrollbar-style": "^1.0.2",
|
||||
"season": "^1.0.2",
|
||||
"semver": "2.2.1",
|
||||
@@ -61,7 +61,7 @@
|
||||
"service-hub": "^0.1.0",
|
||||
"space-pen": "3.8.2",
|
||||
"temp": "0.7.0",
|
||||
"text-buffer": "^3.8.2",
|
||||
"text-buffer": "^3.8.4",
|
||||
"theorist": "^1.0.2",
|
||||
"underscore-plus": "^1.6.6",
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
@@ -69,83 +69,83 @@
|
||||
"packageDependencies": {
|
||||
"atom-dark-syntax": "0.23.0",
|
||||
"atom-dark-ui": "0.42.0",
|
||||
"atom-light-syntax": "0.22.0",
|
||||
"atom-light-syntax": "0.24.0",
|
||||
"atom-light-ui": "0.36.0",
|
||||
"base16-tomorrow-dark-theme": "0.22.0",
|
||||
"base16-tomorrow-light-theme": "0.5.0",
|
||||
"solarized-dark-syntax": "0.29.0",
|
||||
"solarized-light-syntax": "0.13.0",
|
||||
"archive-view": "0.40.0",
|
||||
"autocomplete": "0.34.0",
|
||||
"base16-tomorrow-dark-theme": "0.23.0",
|
||||
"base16-tomorrow-light-theme": "0.6.0",
|
||||
"solarized-dark-syntax": "0.30.0",
|
||||
"solarized-light-syntax": "0.17.0",
|
||||
"archive-view": "0.43.0",
|
||||
"autocomplete": "0.40.0",
|
||||
"autoflow": "0.20.0",
|
||||
"autosave": "0.19.0",
|
||||
"background-tips": "0.18.0",
|
||||
"bookmarks": "0.31.0",
|
||||
"bracket-matcher": "0.64.0",
|
||||
"command-palette": "0.30.0",
|
||||
"deprecation-cop": "0.20.0",
|
||||
"background-tips": "0.20.0",
|
||||
"bookmarks": "0.33.0",
|
||||
"bracket-matcher": "0.67.0",
|
||||
"command-palette": "0.32.0",
|
||||
"deprecation-cop": "0.22.0",
|
||||
"dev-live-reload": "0.36.0",
|
||||
"encoding-selector": "0.12.0",
|
||||
"encoding-selector": "0.14.0",
|
||||
"exception-reporting": "0.21.0",
|
||||
"find-and-replace": "0.152.0",
|
||||
"fuzzy-finder": "0.62.0",
|
||||
"git-diff": "0.45.0",
|
||||
"go-to-line": "0.27.0",
|
||||
"grammar-selector": "0.40.0",
|
||||
"image-view": "0.44.0",
|
||||
"incompatible-packages": "0.16.0",
|
||||
"keybinding-resolver": "0.24.0",
|
||||
"find-and-replace": "0.155.0",
|
||||
"fuzzy-finder": "0.64.0",
|
||||
"git-diff": "0.47.0",
|
||||
"go-to-line": "0.30.0",
|
||||
"grammar-selector": "0.42.0",
|
||||
"image-view": "0.46.0",
|
||||
"incompatible-packages": "0.19.0",
|
||||
"keybinding-resolver": "0.25.0",
|
||||
"link": "0.28.0",
|
||||
"markdown-preview": "0.112.0",
|
||||
"markdown-preview": "0.116.0",
|
||||
"metrics": "0.40.0",
|
||||
"notifications": "0.20.0",
|
||||
"notifications": "0.23.0",
|
||||
"open-on-github": "0.31.0",
|
||||
"package-generator": "0.34.0",
|
||||
"release-notes": "0.43.0",
|
||||
"settings-view": "0.161.0",
|
||||
"snippets": "0.60.0",
|
||||
"spell-check": "0.45.0",
|
||||
"status-bar": "0.54.0",
|
||||
"styleguide": "0.36.0",
|
||||
"symbols-view": "0.70.0",
|
||||
"tabs": "0.58.0",
|
||||
"timecop": "0.24.0",
|
||||
"tree-view": "0.139.0",
|
||||
"package-generator": "0.36.0",
|
||||
"release-notes": "0.45.0",
|
||||
"settings-view": "0.166.0",
|
||||
"snippets": "0.66.0",
|
||||
"spell-check": "0.49.0",
|
||||
"status-bar": "0.56.0",
|
||||
"styleguide": "0.39.0",
|
||||
"symbols-view": "0.77.0",
|
||||
"tabs": "0.61.0",
|
||||
"timecop": "0.26.0",
|
||||
"tree-view": "0.147.0",
|
||||
"update-package-dependencies": "0.7.0",
|
||||
"welcome": "0.21.0",
|
||||
"whitespace": "0.27.0",
|
||||
"wrap-guide": "0.27.0",
|
||||
"language-c": "0.33.0",
|
||||
"language-clojure": "0.9.0",
|
||||
"language-coffee-script": "0.38.1",
|
||||
"language-css": "0.24.0",
|
||||
"language-gfm": "0.55.0",
|
||||
"language-git": "0.9.0",
|
||||
"language-go": "0.19.1",
|
||||
"language-html": "0.27.0",
|
||||
"whitespace": "0.28.0",
|
||||
"wrap-guide": "0.29.0",
|
||||
"language-c": "0.37.0",
|
||||
"language-clojure": "0.10.0",
|
||||
"language-coffee-script": "0.39.0",
|
||||
"language-css": "0.26.0",
|
||||
"language-gfm": "0.59.0",
|
||||
"language-git": "0.10.0",
|
||||
"language-go": "0.20.0",
|
||||
"language-html": "0.28.0",
|
||||
"language-hyperlink": "0.12.2",
|
||||
"language-java": "0.13.0",
|
||||
"language-javascript": "0.51.0",
|
||||
"language-json": "0.10.0",
|
||||
"language-less": "0.21.0",
|
||||
"language-make": "0.12.0",
|
||||
"language-java": "0.14.0",
|
||||
"language-javascript": "0.53.0",
|
||||
"language-json": "0.11.0",
|
||||
"language-less": "0.24.0",
|
||||
"language-make": "0.13.0",
|
||||
"language-mustache": "0.11.0",
|
||||
"language-objective-c": "0.12.0",
|
||||
"language-perl": "0.9.0",
|
||||
"language-php": "0.18.0",
|
||||
"language-property-list": "0.7.0",
|
||||
"language-python": "0.26.0",
|
||||
"language-ruby": "0.44.0",
|
||||
"language-objective-c": "0.15.0",
|
||||
"language-perl": "0.10.0",
|
||||
"language-php": "0.20.0",
|
||||
"language-property-list": "0.8.0",
|
||||
"language-python": "0.29.0",
|
||||
"language-ruby": "0.47.0",
|
||||
"language-ruby-on-rails": "0.18.0",
|
||||
"language-sass": "0.29.0",
|
||||
"language-shellscript": "0.10.1",
|
||||
"language-source": "0.8.0",
|
||||
"language-sql": "0.11.0",
|
||||
"language-sass": "0.30.0",
|
||||
"language-shellscript": "0.12.0",
|
||||
"language-source": "0.9.0",
|
||||
"language-sql": "0.13.0",
|
||||
"language-text": "0.6.0",
|
||||
"language-todo": "0.15.0",
|
||||
"language-toml": "0.14.1",
|
||||
"language-xml": "0.25.0",
|
||||
"language-yaml": "0.21.0"
|
||||
"language-toml": "0.15.0",
|
||||
"language-xml": "0.26.0",
|
||||
"language-yaml": "0.22.0"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
Arquivo binário não exibido.
|
Antes Largura: | Altura: | Tamanho: 284 KiB Depois Largura: | Altura: | Tamanho: 628 KiB |
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
|
Antes Largura: | Altura: | Tamanho: 141 KiB Depois Largura: | Altura: | Tamanho: 182 KiB |
@@ -117,7 +117,7 @@ class AtomReporter extends View
|
||||
@div class: 'result-message fail deprecation-message', =>
|
||||
@raw marked(deprecation.message)
|
||||
|
||||
for stack in deprecation.stacks
|
||||
for stack in deprecation.getStacks()
|
||||
fullStack = stack.map ({functionName, location}) ->
|
||||
if functionName is '<unknown>'
|
||||
" at #{location}"
|
||||
|
||||
@@ -54,6 +54,7 @@ describe "the `atom` global", ->
|
||||
describe "loading default config", ->
|
||||
it 'loads the default core config', ->
|
||||
expect(atom.config.get('core.excludeVcsIgnoredPaths')).toBe true
|
||||
expect(atom.config.get('core.followSymlinks')).toBe false
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe false
|
||||
|
||||
describe "window onerror handler", ->
|
||||
|
||||
+993
-930
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "package-with-empty-keymap",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "package-with-empty-menu",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
@@ -381,6 +381,23 @@ describe "LanguageMode", ->
|
||||
expect(languageMode.isFoldableAtBufferRow(3)).toBe false
|
||||
expect(languageMode.isFoldableAtBufferRow(4)).toBe true
|
||||
|
||||
describe ".foldAllAtIndentLevel(indentLevel)", ->
|
||||
it "folds blocks of text at the given indentation level", ->
|
||||
languageMode.foldAllAtIndentLevel(0)
|
||||
expect(editor.lineTextForScreenRow(0)).toBe "var quicksort = function () {"
|
||||
expect(editor.getLastScreenRow()).toBe 0
|
||||
|
||||
languageMode.foldAllAtIndentLevel(1)
|
||||
expect(editor.lineTextForScreenRow(0)).toBe "var quicksort = function () {"
|
||||
expect(editor.lineTextForScreenRow(1)).toBe " var sort = function(items) {"
|
||||
expect(editor.getLastScreenRow()).toBe 4
|
||||
|
||||
languageMode.foldAllAtIndentLevel(2)
|
||||
expect(editor.lineTextForScreenRow(0)).toBe "var quicksort = function () {"
|
||||
expect(editor.lineTextForScreenRow(1)).toBe " var sort = function(items) {"
|
||||
expect(editor.lineTextForScreenRow(2)).toBe " if (items.length <= 1) return items;"
|
||||
expect(editor.getLastScreenRow()).toBe 9
|
||||
|
||||
describe "folding with comments", ->
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
|
||||
@@ -3,19 +3,36 @@ Package = require '../src/package'
|
||||
|
||||
describe "PackageManager", ->
|
||||
workspaceElement = null
|
||||
|
||||
beforeEach ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
|
||||
describe "::loadPackage(name)", ->
|
||||
it "continues if the package has an invalid package.json", ->
|
||||
spyOn(console, 'warn')
|
||||
beforeEach ->
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
expect(-> atom.packages.loadPackage("package-with-broken-package-json")).not.toThrow()
|
||||
|
||||
it "continues if the package has an invalid keymap", ->
|
||||
it "returns the package", ->
|
||||
pack = atom.packages.loadPackage("package-with-index")
|
||||
expect(pack instanceof Package).toBe true
|
||||
expect(pack.metadata.name).toBe "package-with-index"
|
||||
|
||||
it "returns the package if it has an invalid keymap", ->
|
||||
spyOn(console, 'warn')
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
expect(-> atom.packages.loadPackage("package-with-broken-keymap")).not.toThrow()
|
||||
pack = atom.packages.loadPackage("package-with-broken-keymap")
|
||||
expect(pack instanceof Package).toBe true
|
||||
expect(pack.metadata.name).toBe "package-with-broken-keymap"
|
||||
|
||||
it "returns null if the package has an invalid package.json", ->
|
||||
spyOn(console, 'warn')
|
||||
expect(atom.packages.loadPackage("package-with-broken-package-json")).toBeNull()
|
||||
expect(console.warn.callCount).toBe(1)
|
||||
expect(console.warn.argsForCall[0][0]).toContain("Failed to load package.json")
|
||||
|
||||
it "returns null if the package is not found in any package directory", ->
|
||||
spyOn(console, 'warn')
|
||||
expect(atom.packages.loadPackage("this-package-cannot-be-found")).toBeNull()
|
||||
expect(console.warn.callCount).toBe(1)
|
||||
expect(console.warn.argsForCall[0][0]).toContain("Could not resolve")
|
||||
|
||||
describe "::unloadPackage(name)", ->
|
||||
describe "when the package is active", ->
|
||||
@@ -197,11 +214,30 @@ describe "PackageManager", ->
|
||||
runs ->
|
||||
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
|
||||
|
||||
it "logs warning instead of throwing an exception if the package fails to load", ->
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
spyOn(console, "warn")
|
||||
expect(-> atom.packages.activatePackage("package-that-throws-an-exception")).not.toThrow()
|
||||
expect(console.warn).toHaveBeenCalled()
|
||||
describe "when the package throws an error while loading", ->
|
||||
it "logs a warning instead of throwing an exception", ->
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
spyOn(console, "warn")
|
||||
expect(-> atom.packages.activatePackage("package-that-throws-an-exception")).not.toThrow()
|
||||
expect(console.warn).toHaveBeenCalled()
|
||||
|
||||
describe "when the package is not found", ->
|
||||
it "rejects the promise", ->
|
||||
atom.config.set("core.disabledPackages", [])
|
||||
|
||||
onSuccess = jasmine.createSpy('onSuccess')
|
||||
onFailure = jasmine.createSpy('onFailure')
|
||||
spyOn(console, 'warn')
|
||||
|
||||
atom.packages.activatePackage("this-doesnt-exist").then(onSuccess, onFailure)
|
||||
|
||||
waitsFor "promise to be rejected", ->
|
||||
onFailure.callCount > 0
|
||||
|
||||
runs ->
|
||||
expect(console.warn.callCount).toBe 1
|
||||
expect(onFailure.mostRecentCall.args[0] instanceof Error).toBe true
|
||||
expect(onFailure.mostRecentCall.args[0].message).toContain "Failed to load package 'this-doesnt-exist'"
|
||||
|
||||
describe "keymap loading", ->
|
||||
describe "when the metadata does not contain a 'keymaps' manifest", ->
|
||||
@@ -237,6 +273,14 @@ describe "PackageManager", ->
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-n', target:element1[0])[0].command).toBe 'keymap-2'
|
||||
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-y', target:element3[0])).toHaveLength 0
|
||||
|
||||
describe "when the keymap file is empty", ->
|
||||
it "does not throw an error on activation", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-empty-keymap")
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.isPackageActive("package-with-empty-keymap")).toBe true
|
||||
|
||||
describe "menu loading", ->
|
||||
beforeEach ->
|
||||
atom.contextMenu.definitions = []
|
||||
@@ -275,6 +319,14 @@ describe "PackageManager", ->
|
||||
expect(atom.contextMenu.templateForElement(element)[1].label).toBe "Menu item 1"
|
||||
expect(atom.contextMenu.templateForElement(element)[2]).toBeUndefined()
|
||||
|
||||
describe "when the menu file is empty", ->
|
||||
it "does not throw an error on activation", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-empty-menu")
|
||||
|
||||
runs ->
|
||||
expect(atom.packages.isPackageActive("package-with-empty-menu")).toBe true
|
||||
|
||||
describe "stylesheet loading", ->
|
||||
describe "when the metadata contains a 'stylesheets' manifest", ->
|
||||
it "loads stylesheets from the stylesheets directory as specified by the manifest", ->
|
||||
@@ -364,7 +416,7 @@ describe "PackageManager", ->
|
||||
describe "scoped-property loading", ->
|
||||
it "loads the scoped properties", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
atom.packages.activatePackage("package-with-settings")
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get 'editor.increaseIndentPattern', scope: ['.source.omg']).toBe '^a'
|
||||
@@ -490,11 +542,11 @@ describe "PackageManager", ->
|
||||
|
||||
it "removes the package's scoped-properties", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
atom.packages.activatePackage("package-with-settings")
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get 'editor.increaseIndentPattern', scope: ['.source.omg']).toBe '^a'
|
||||
atom.packages.deactivatePackage("package-with-scoped-properties")
|
||||
atom.packages.deactivatePackage("package-with-settings")
|
||||
expect(atom.config.get 'editor.increaseIndentPattern', scope: ['.source.omg']).toBeUndefined()
|
||||
|
||||
describe "textmate packages", ->
|
||||
@@ -552,9 +604,9 @@ describe "PackageManager", ->
|
||||
themes = themeActivator.mostRecentCall.args[0]
|
||||
expect(['theme']).toContain(theme.getType()) for theme in themes
|
||||
|
||||
describe "::enablePackage() and ::disablePackage()", ->
|
||||
describe "::enablePackage(id) and ::disablePackage(id)", ->
|
||||
describe "with packages", ->
|
||||
it ".enablePackage() enables a disabled package", ->
|
||||
it "enables a disabled package", ->
|
||||
packageName = 'package-with-main'
|
||||
atom.config.pushAtKeyPath('core.disabledPackages', packageName)
|
||||
atom.packages.observeDisabledPackages()
|
||||
@@ -572,7 +624,7 @@ describe "PackageManager", ->
|
||||
expect(activatedPackages).toContain(pack)
|
||||
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
it ".disablePackage() disables an enabled package", ->
|
||||
it "disables an enabled package", ->
|
||||
packageName = 'package-with-main'
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage(packageName)
|
||||
@@ -587,6 +639,11 @@ describe "PackageManager", ->
|
||||
expect(activatedPackages).not.toContain(pack)
|
||||
expect(atom.config.get('core.disabledPackages')).toContain packageName
|
||||
|
||||
it "returns null if the package cannot be loaded", ->
|
||||
spyOn(console, 'warn')
|
||||
expect(atom.packages.enablePackage("this-doesnt-exist")).toBeNull()
|
||||
expect(console.warn.callCount).toBe 1
|
||||
|
||||
describe "with themes", ->
|
||||
reloadedHandler = null
|
||||
|
||||
@@ -597,7 +654,7 @@ describe "PackageManager", ->
|
||||
afterEach ->
|
||||
atom.themes.deactivateThemes()
|
||||
|
||||
it ".enablePackage() and .disablePackage() enables and disables a theme", ->
|
||||
it "enables and disables a theme", ->
|
||||
packageName = 'theme-with-package-file'
|
||||
|
||||
expect(atom.config.get('core.themes')).not.toContain packageName
|
||||
|
||||
@@ -4,7 +4,6 @@ Project = require '../src/project'
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
platform = require './spec-helper-platform'
|
||||
BufferedProcess = require '../src/buffered-process'
|
||||
|
||||
describe "Project", ->
|
||||
@@ -195,290 +194,6 @@ describe "Project", ->
|
||||
expect(atom.project.getPaths()[0]).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
expect(atom.project.getDirectories()[0].path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
|
||||
describe ".replace()", ->
|
||||
[filePath, commentFilePath, sampleContent, sampleCommentContent] = []
|
||||
|
||||
beforeEach ->
|
||||
atom.project.setPaths([atom.project.resolve('../')])
|
||||
|
||||
filePath = atom.project.resolve('sample.js')
|
||||
commentFilePath = atom.project.resolve('sample-with-comments.js')
|
||||
sampleContent = fs.readFileSync(filePath).toString()
|
||||
sampleCommentContent = fs.readFileSync(commentFilePath).toString()
|
||||
|
||||
afterEach ->
|
||||
fs.writeFileSync(filePath, sampleContent)
|
||||
fs.writeFileSync(commentFilePath, sampleCommentContent)
|
||||
|
||||
describe "when a file doesn't exist", ->
|
||||
it "calls back with an error", ->
|
||||
errors = []
|
||||
missingPath = path.resolve('/not-a-file.js')
|
||||
expect(fs.existsSync(missingPath)).toBeFalsy()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.replace /items/gi, 'items', [missingPath], (result, error) ->
|
||||
errors.push(error)
|
||||
|
||||
runs ->
|
||||
expect(errors).toHaveLength 1
|
||||
expect(errors[0].path).toBe missingPath
|
||||
|
||||
describe "when called with unopened files", ->
|
||||
it "replaces properly", ->
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
atom.project.replace /items/gi, 'items', [filePath], (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 1
|
||||
expect(results[0].filePath).toBe filePath
|
||||
expect(results[0].replacements).toBe 6
|
||||
|
||||
describe "when a buffer is already open", ->
|
||||
it "replaces properly and saves when not modified", ->
|
||||
editor = null
|
||||
results = []
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.open('sample.js').then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.isModified()).toBeFalsy()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.replace /items/gi, 'items', [filePath], (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 1
|
||||
expect(results[0].filePath).toBe filePath
|
||||
expect(results[0].replacements).toBe 6
|
||||
|
||||
expect(editor.isModified()).toBeFalsy()
|
||||
|
||||
it "does not replace when the path is not specified", ->
|
||||
editor = null
|
||||
results = []
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.open('sample-with-comments.js').then (o) -> editor = o
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.replace /items/gi, 'items', [commentFilePath], (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 1
|
||||
expect(results[0].filePath).toBe commentFilePath
|
||||
|
||||
it "does NOT save when modified", ->
|
||||
editor = null
|
||||
results = []
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.open('sample.js').then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
editor.buffer.setTextInRange([[0,0],[0,0]], 'omg')
|
||||
expect(editor.isModified()).toBeTruthy()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.replace /items/gi, 'okthen', [filePath], (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 1
|
||||
expect(results[0].filePath).toBe filePath
|
||||
expect(results[0].replacements).toBe 6
|
||||
|
||||
expect(editor.isModified()).toBeTruthy()
|
||||
|
||||
describe ".scan(options, callback)", ->
|
||||
describe "when called with a regex", ->
|
||||
it "calls the callback with all regex results in all files in the project", ->
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
atom.project.scan /(a)+/, (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength(3)
|
||||
expect(results[0].filePath).toBe atom.project.resolve('a')
|
||||
expect(results[0].matches).toHaveLength(3)
|
||||
expect(results[0].matches[0]).toEqual
|
||||
matchText: 'aaa'
|
||||
lineText: 'aaa bbb'
|
||||
lineTextOffset: 0
|
||||
range: [[0, 0], [0, 3]]
|
||||
|
||||
it "works with with escaped literals (like $ and ^)", ->
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
atom.project.scan /\$\w+/, (result) -> results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results.length).toBe 1
|
||||
|
||||
{filePath, matches} = results[0]
|
||||
expect(filePath).toBe atom.project.resolve('a')
|
||||
expect(matches).toHaveLength 1
|
||||
expect(matches[0]).toEqual
|
||||
matchText: '$bill'
|
||||
lineText: 'dollar$bill'
|
||||
lineTextOffset: 0
|
||||
range: [[2, 6], [2, 11]]
|
||||
|
||||
it "works on evil filenames", ->
|
||||
platform.generateEvilFiles()
|
||||
atom.project.setPaths([path.join(__dirname, 'fixtures', 'evil-files')])
|
||||
paths = []
|
||||
matches = []
|
||||
waitsForPromise ->
|
||||
atom.project.scan /evil/, (result) ->
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
|
||||
runs ->
|
||||
_.each(matches, (m) -> expect(m.matchText).toEqual 'evil')
|
||||
|
||||
if platform.isWindows()
|
||||
expect(paths.length).toBe 3
|
||||
expect(paths[0]).toMatch /a_file_with_utf8.txt$/
|
||||
expect(paths[1]).toMatch /file with spaces.txt$/
|
||||
expect(path.basename(paths[2])).toBe "utfa\u0306.md"
|
||||
else
|
||||
expect(paths.length).toBe 5
|
||||
expect(paths[0]).toMatch /a_file_with_utf8.txt$/
|
||||
expect(paths[1]).toMatch /file with spaces.txt$/
|
||||
expect(paths[2]).toMatch /goddam\nnewlines$/m
|
||||
expect(paths[3]).toMatch /quote".txt$/m
|
||||
expect(path.basename(paths[4])).toBe "utfa\u0306.md"
|
||||
|
||||
it "ignores case if the regex includes the `i` flag", ->
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
atom.project.scan /DOLLAR/i, (result) -> results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 1
|
||||
|
||||
describe "when the core.excludeVcsIgnoredPaths config is truthy", ->
|
||||
[projectPath, ignoredPath] = []
|
||||
|
||||
beforeEach ->
|
||||
sourceProjectPath = path.join(__dirname, 'fixtures', 'git', 'working-dir')
|
||||
projectPath = path.join(temp.mkdirSync("atom"))
|
||||
|
||||
writerStream = fstream.Writer(projectPath)
|
||||
fstream.Reader(sourceProjectPath).pipe(writerStream)
|
||||
|
||||
waitsFor (done) ->
|
||||
writerStream.on 'close', done
|
||||
writerStream.on 'error', done
|
||||
|
||||
runs ->
|
||||
fs.rename(path.join(projectPath, 'git.git'), path.join(projectPath, '.git'))
|
||||
ignoredPath = path.join(projectPath, 'ignored.txt')
|
||||
fs.writeFileSync(ignoredPath, 'this match should not be included')
|
||||
|
||||
afterEach ->
|
||||
fs.removeSync(projectPath) if fs.existsSync(projectPath)
|
||||
|
||||
it "excludes ignored files", ->
|
||||
atom.project.setPaths([projectPath])
|
||||
atom.config.set('core.excludeVcsIgnoredPaths', true)
|
||||
resultHandler = jasmine.createSpy("result found")
|
||||
waitsForPromise ->
|
||||
atom.project.scan /match/, (results) ->
|
||||
resultHandler()
|
||||
|
||||
runs ->
|
||||
expect(resultHandler).not.toHaveBeenCalled()
|
||||
|
||||
it "includes only files when a directory filter is specified", ->
|
||||
projectPath = path.join(path.join(__dirname, 'fixtures', 'dir'))
|
||||
atom.project.setPaths([projectPath])
|
||||
|
||||
filePath = path.join(projectPath, 'a-dir', 'oh-git')
|
||||
|
||||
paths = []
|
||||
matches = []
|
||||
waitsForPromise ->
|
||||
atom.project.scan /aaa/, paths: ["a-dir#{path.sep}"], (result) ->
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
|
||||
runs ->
|
||||
expect(paths.length).toBe 1
|
||||
expect(paths[0]).toBe filePath
|
||||
expect(matches.length).toBe 1
|
||||
|
||||
it "includes files and folders that begin with a '.'", ->
|
||||
projectPath = temp.mkdirSync()
|
||||
filePath = path.join(projectPath, '.text')
|
||||
fs.writeFileSync(filePath, 'match this')
|
||||
atom.project.setPaths([projectPath])
|
||||
paths = []
|
||||
matches = []
|
||||
waitsForPromise ->
|
||||
atom.project.scan /match this/, (result) ->
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
|
||||
runs ->
|
||||
expect(paths.length).toBe 1
|
||||
expect(paths[0]).toBe filePath
|
||||
expect(matches.length).toBe 1
|
||||
|
||||
it "excludes values in core.ignoredNames", ->
|
||||
projectPath = path.join(__dirname, 'fixtures', 'git', 'working-dir')
|
||||
ignoredNames = atom.config.get("core.ignoredNames")
|
||||
ignoredNames.push("a")
|
||||
atom.config.set("core.ignoredNames", ignoredNames)
|
||||
|
||||
resultHandler = jasmine.createSpy("result found")
|
||||
waitsForPromise ->
|
||||
atom.project.scan /dollar/, (results) ->
|
||||
resultHandler()
|
||||
|
||||
runs ->
|
||||
expect(resultHandler).not.toHaveBeenCalled()
|
||||
|
||||
it "scans buffer contents if the buffer is modified", ->
|
||||
editor = null
|
||||
results = []
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.open('a').then (o) ->
|
||||
editor = o
|
||||
editor.setText("Elephant")
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.scan /a|Elephant/, (result) -> results.push result
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 3
|
||||
resultForA = _.find results, ({filePath}) -> path.basename(filePath) == 'a'
|
||||
expect(resultForA.matches).toHaveLength 1
|
||||
expect(resultForA.matches[0].matchText).toBe 'Elephant'
|
||||
|
||||
it "ignores buffers outside the project", ->
|
||||
editor = null
|
||||
results = []
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.open(temp.openSync().path).then (o) ->
|
||||
editor = o
|
||||
editor.setText("Elephant")
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.scan /Elephant/, (result) -> results.push result
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 0
|
||||
|
||||
describe ".eachBuffer(callback)", ->
|
||||
beforeEach ->
|
||||
atom.project.bufferForPathSync('a')
|
||||
|
||||
@@ -84,6 +84,10 @@ beforeEach ->
|
||||
atom.workspaceViewParentSelector = '#jasmine-content'
|
||||
|
||||
window.resetTimeouts()
|
||||
spyOn(_._, "now").andCallFake -> window.now
|
||||
spyOn(window, "setTimeout").andCallFake window.fakeSetTimeout
|
||||
spyOn(window, "clearTimeout").andCallFake window.fakeClearTimeout
|
||||
|
||||
atom.packages.packageStates = {}
|
||||
|
||||
serializedWindowState = null
|
||||
@@ -102,9 +106,9 @@ beforeEach ->
|
||||
spyOn(atom.menu, 'sendToBrowserProcess')
|
||||
|
||||
# reset config before each spec; don't load or save from/to `config.json`
|
||||
spyOn(Config::, 'load')
|
||||
spyOn(Config::, 'save')
|
||||
config = new Config({resourcePath, configDirPath: atom.getConfigDirPath()})
|
||||
spyOn(config, 'load')
|
||||
spyOn(config, 'save')
|
||||
atom.config = config
|
||||
atom.loadConfig()
|
||||
config.set "core.destroyEmptyPanes", false
|
||||
@@ -114,6 +118,7 @@ beforeEach ->
|
||||
config.set "core.disabledPackages", ["package-that-throws-an-exception",
|
||||
"package-with-broken-package-json", "package-with-broken-keymap"]
|
||||
config.set "editor.useShadowDOM", true
|
||||
advanceClock(1000)
|
||||
config.load.reset()
|
||||
config.save.reset()
|
||||
|
||||
@@ -121,8 +126,6 @@ beforeEach ->
|
||||
TextEditorElement::setUpdatedSynchronously(true)
|
||||
|
||||
spyOn(atom, "setRepresentedFilename")
|
||||
spyOn(window, "setTimeout").andCallFake window.fakeSetTimeout
|
||||
spyOn(window, "clearTimeout").andCallFake window.fakeClearTimeout
|
||||
spyOn(pathwatcher.File.prototype, "detectResurrectionAfterDelay").andCallFake -> @detectResurrection()
|
||||
spyOn(TextEditor.prototype, "shouldPromptToSave").andReturn false
|
||||
|
||||
@@ -204,10 +207,10 @@ jasmine.attachToDOM = (element) ->
|
||||
|
||||
deprecationsSnapshot = null
|
||||
jasmine.snapshotDeprecations = ->
|
||||
deprecationsSnapshot = Grim.getDeprecations() # suppress deprecations!!
|
||||
deprecationsSnapshot = _.clone(Grim.deprecations)
|
||||
|
||||
jasmine.restoreDeprecationsSnapshot = ->
|
||||
Grim.grimDeprecations = deprecationsSnapshot
|
||||
Grim.deprecations = deprecationsSnapshot
|
||||
|
||||
addCustomMatchers = (spec) ->
|
||||
spec.addMatchers
|
||||
|
||||
@@ -25,6 +25,16 @@ describe "Windows squirrel updates", ->
|
||||
else
|
||||
originalSpawn('ls')
|
||||
|
||||
it "ignores errors spawning Squirrel", ->
|
||||
jasmine.unspy(ChildProcess, 'spawn')
|
||||
spyOn(ChildProcess, 'spawn').andCallFake -> throw new Error("EBUSY")
|
||||
|
||||
app = quit: jasmine.createSpy('quit')
|
||||
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-install')).toBe true
|
||||
|
||||
waitsFor ->
|
||||
app.quit.callCount is 1
|
||||
|
||||
it "quits the app on all squirrel events", ->
|
||||
app = quit: jasmine.createSpy('quit')
|
||||
|
||||
|
||||
@@ -53,14 +53,16 @@ describe "StyleManager", ->
|
||||
expect(addEvents[0].getAttribute('source-path')).toBe '/foo/bar'
|
||||
expect(addEvents[0].textContent).toBe "a {color: yellow;}"
|
||||
|
||||
describe "when a group parameter is specified", ->
|
||||
it "inserts the stylesheet at the end of any existing stylesheets for the same group", ->
|
||||
manager.addStyleSheet("a {color: red}", group: 'a')
|
||||
manager.addStyleSheet("a {color: blue}", group: 'b')
|
||||
manager.addStyleSheet("a {color: green}", group: 'a')
|
||||
describe "when a priority parameter is specified", ->
|
||||
it "inserts the style sheet based on the priority", ->
|
||||
manager.addStyleSheet("a {color: red}", priority: 1)
|
||||
manager.addStyleSheet("a {color: blue}", priority: 0)
|
||||
manager.addStyleSheet("a {color: green}", priority: 2)
|
||||
manager.addStyleSheet("a {color: yellow}", priority: 1)
|
||||
|
||||
expect(manager.getStyleElements().map (elt) -> elt.textContent).toEqual [
|
||||
"a {color: red}"
|
||||
"a {color: green}"
|
||||
"a {color: blue}"
|
||||
"a {color: red}"
|
||||
"a {color: yellow}"
|
||||
"a {color: green}"
|
||||
]
|
||||
|
||||
@@ -32,16 +32,18 @@ describe "StylesElement", ->
|
||||
expect(element.children[initialChildCount].textContent).toBe "a {color: blue;}"
|
||||
expect(removedStyleElements).toEqual [addedStyleElements[0]]
|
||||
|
||||
it "orders style elements by group", ->
|
||||
it "orders style elements by priority", ->
|
||||
initialChildCount = element.children.length
|
||||
|
||||
atom.styles.addStyleSheet("a {color: red}", group: 'a')
|
||||
atom.styles.addStyleSheet("a {color: blue}", group: 'b')
|
||||
atom.styles.addStyleSheet("a {color: green}", group: 'a')
|
||||
atom.styles.addStyleSheet("a {color: red}", priority: 1)
|
||||
atom.styles.addStyleSheet("a {color: blue}", priority: 0)
|
||||
atom.styles.addStyleSheet("a {color: green}", priority: 2)
|
||||
atom.styles.addStyleSheet("a {color: yellow}", priority: 1)
|
||||
|
||||
expect(element.children[initialChildCount].textContent).toBe "a {color: red}"
|
||||
expect(element.children[initialChildCount + 1].textContent).toBe "a {color: green}"
|
||||
expect(element.children[initialChildCount + 2].textContent).toBe "a {color: blue}"
|
||||
expect(element.children[initialChildCount].textContent).toBe "a {color: blue}"
|
||||
expect(element.children[initialChildCount + 1].textContent).toBe "a {color: red}"
|
||||
expect(element.children[initialChildCount + 2].textContent).toBe "a {color: yellow}"
|
||||
expect(element.children[initialChildCount + 3].textContent).toBe "a {color: green}"
|
||||
|
||||
it "updates existing style nodes when style elements are updated", ->
|
||||
initialChildCount = element.children.length
|
||||
|
||||
@@ -755,7 +755,6 @@ describe "TextEditorComponent", ->
|
||||
expect(cursorNode.offsetWidth).toBe charWidth
|
||||
|
||||
it "blinks cursors when they aren't moving", ->
|
||||
spyOn(_._, 'now').andCallFake -> window.now # Ensure _.debounce is based on our fake spec timeline
|
||||
cursorsNode = componentNode.querySelector('.cursors')
|
||||
|
||||
expect(cursorsNode.classList.contains('blink-off')).toBe false
|
||||
@@ -2048,8 +2047,6 @@ describe "TextEditorComponent", ->
|
||||
expect(component.mouseWheelScreenRow).toBe null
|
||||
|
||||
it "clears the mouseWheelScreenRow after a delay even if the event does not cause scrolling", ->
|
||||
spyOn(_._, 'now').andCallFake -> window.now # Ensure _.debounce is based on our fake spec timeline
|
||||
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
|
||||
lineNode = componentNode.querySelector('.line')
|
||||
|
||||
@@ -42,9 +42,12 @@ describe "TextEditorElement", ->
|
||||
|
||||
component = element.component
|
||||
expect(component.isMounted()).toBe true
|
||||
element.getModel().destroy()
|
||||
element.remove()
|
||||
expect(component.isMounted()).toBe false
|
||||
|
||||
jasmine.attachToDOM(element)
|
||||
expect(element.component.isMounted()).toBe true
|
||||
|
||||
describe "when the editor.useShadowDOM config option is false", ->
|
||||
it "mounts the react component and unmounts when removed from the dom", ->
|
||||
atom.config.set('editor.useShadowDOM', false)
|
||||
|
||||
@@ -62,7 +62,6 @@ describe "TextEditor", ->
|
||||
atom.workspace.open('sample.less', initialLine: 5).then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
buffer = editor.buffer
|
||||
expect(editor.getLastCursor().getBufferPosition().row).toEqual 5
|
||||
expect(editor.getLastCursor().getBufferPosition().column).toEqual 0
|
||||
|
||||
@@ -74,10 +73,37 @@ describe "TextEditor", ->
|
||||
atom.workspace.open('sample.less', initialColumn: 8).then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
buffer = editor.buffer
|
||||
expect(editor.getLastCursor().getBufferPosition().row).toEqual 0
|
||||
expect(editor.getLastCursor().getBufferPosition().column).toEqual 8
|
||||
|
||||
describe "when the editor is reopened with an initialLine option", ->
|
||||
it "positions the cursor on the specified line", ->
|
||||
editor = null
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.less', initialLine: 5).then (o) -> editor = o
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.less', initialLine: 4).then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.getLastCursor().getBufferPosition().row).toEqual 4
|
||||
expect(editor.getLastCursor().getBufferPosition().column).toEqual 0
|
||||
|
||||
describe "when the editor is reopened with an initialColumn option", ->
|
||||
it "positions the cursor on the specified column", ->
|
||||
editor = null
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.less', initialColumn: 8).then (o) -> editor = o
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.less', initialColumn: 7).then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.getLastCursor().getBufferPosition().row).toEqual 0
|
||||
expect(editor.getLastCursor().getBufferPosition().column).toEqual 7
|
||||
|
||||
describe ".copy()", ->
|
||||
it "returns a different edit session with the same initial state", ->
|
||||
editor.setSelectedBufferRange([[1, 2], [3, 4]])
|
||||
@@ -3766,8 +3792,12 @@ describe "TextEditor", ->
|
||||
it "updates the grammar based on grammar overrides", ->
|
||||
expect(editor.getGrammar().name).toBe 'JavaScript'
|
||||
atom.grammars.setGrammarOverrideForPath(editor.getPath(), 'source.coffee')
|
||||
callback = jasmine.createSpy('callback')
|
||||
editor.onDidChangeGrammar(callback)
|
||||
editor.reloadGrammar()
|
||||
expect(editor.getGrammar().name).toBe 'CoffeeScript'
|
||||
expect(callback.callCount).toBe 1
|
||||
expect(callback.argsForCall[0][0]).toBe atom.grammars.grammarForScopeName('source.coffee')
|
||||
|
||||
describe "when the editor's grammar has an injection selector", ->
|
||||
beforeEach ->
|
||||
|
||||
@@ -96,8 +96,8 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
reloadHandler.reset()
|
||||
expect($('style[group=theme]')).toHaveLength 2
|
||||
expect($('style[group=theme]:eq(0)').attr('source-path')).toMatch /atom-dark-ui/
|
||||
expect($('style[priority=1]')).toHaveLength 2
|
||||
expect($('style[priority=1]:eq(0)').attr('source-path')).toMatch /atom-dark-ui/
|
||||
atom.config.set('core.themes', ['atom-light-ui', 'atom-dark-ui'])
|
||||
|
||||
waitsFor ->
|
||||
@@ -105,9 +105,9 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
reloadHandler.reset()
|
||||
expect($('style[group=theme]')).toHaveLength 2
|
||||
expect($('style[group=theme]:eq(0)').attr('source-path')).toMatch /atom-dark-ui/
|
||||
expect($('style[group=theme]:eq(1)').attr('source-path')).toMatch /atom-light-ui/
|
||||
expect($('style[priority=1]')).toHaveLength 2
|
||||
expect($('style[priority=1]:eq(0)').attr('source-path')).toMatch /atom-dark-ui/
|
||||
expect($('style[priority=1]:eq(1)').attr('source-path')).toMatch /atom-light-ui/
|
||||
atom.config.set('core.themes', [])
|
||||
|
||||
waitsFor ->
|
||||
@@ -115,7 +115,7 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
reloadHandler.reset()
|
||||
expect($('style[group=theme]')).toHaveLength 2
|
||||
expect($('style[priority=1]')).toHaveLength 2
|
||||
# atom-dark-ui has an directory path, the syntax one doesn't
|
||||
atom.config.set('core.themes', ['theme-with-index-less', 'atom-dark-ui'])
|
||||
|
||||
@@ -123,15 +123,40 @@ describe "ThemeManager", ->
|
||||
reloadHandler.callCount == 1
|
||||
|
||||
runs ->
|
||||
expect($('style[group=theme]')).toHaveLength 2
|
||||
expect($('style[priority=1]')).toHaveLength 2
|
||||
importPaths = themeManager.getImportPaths()
|
||||
expect(importPaths.length).toBe 1
|
||||
expect(importPaths[0]).toContain 'atom-dark-ui'
|
||||
|
||||
it 'adds theme-* classes to the workspace for each active theme', ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
runs ->
|
||||
expect(workspaceElement).toHaveClass 'theme-atom-dark-ui'
|
||||
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
|
||||
|
||||
waitsFor ->
|
||||
reloadHandler.callCount > 0
|
||||
|
||||
runs ->
|
||||
# `theme-` twice as it prefixes the name with `theme-`
|
||||
expect(workspaceElement).toHaveClass 'theme-theme-with-ui-variables'
|
||||
expect(workspaceElement).toHaveClass 'theme-theme-with-syntax-variables'
|
||||
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-ui'
|
||||
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-syntax'
|
||||
|
||||
describe "when a theme fails to load", ->
|
||||
it "logs a warning", ->
|
||||
spyOn(console, 'warn')
|
||||
expect(-> atom.packages.activatePackage('a-theme-that-will-not-be-found')).toThrow()
|
||||
atom.packages.activatePackage('a-theme-that-will-not-be-found')
|
||||
expect(console.warn.callCount).toBe 1
|
||||
expect(console.warn.argsForCall[0][0]).toContain "Could not resolve 'a-theme-that-will-not-be-found'"
|
||||
|
||||
describe "::requireStylesheet(path)", ->
|
||||
beforeEach ->
|
||||
@@ -223,11 +248,9 @@ describe "ThemeManager", ->
|
||||
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
describe "base stylesheet loading", ->
|
||||
describe "base style sheet loading", ->
|
||||
workspaceElement = null
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
workspaceElement.appendChild document.createElement('atom-text-editor')
|
||||
@@ -235,9 +258,6 @@ describe "ThemeManager", ->
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
beforeEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "loads the correct values from the theme's ui-variables file", ->
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
|
||||
@@ -269,22 +289,6 @@ describe "ThemeManager", ->
|
||||
# from within the theme itself
|
||||
expect($("atom-text-editor").css("background-color")).toBe "rgb(0, 152, 255)"
|
||||
|
||||
describe "theme classes on the workspace", ->
|
||||
it 'adds theme-* classes to the workspace for each active theme', ->
|
||||
expect(workspaceElement).toHaveClass 'theme-atom-dark-ui'
|
||||
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
|
||||
|
||||
waitsFor ->
|
||||
reloadHandler.callCount > 0
|
||||
|
||||
runs ->
|
||||
# `theme-` twice as it prefixes the name with `theme-`
|
||||
expect(workspaceElement).toHaveClass 'theme-theme-with-ui-variables'
|
||||
expect(workspaceElement).toHaveClass 'theme-theme-with-syntax-variables'
|
||||
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-ui'
|
||||
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-syntax'
|
||||
|
||||
describe "when the user stylesheet changes", ->
|
||||
beforeEach ->
|
||||
|
||||
@@ -14,14 +14,14 @@ describe "ViewRegistry", ->
|
||||
expect(registry.getView(node)).toBe node
|
||||
|
||||
describe "when passed a SpacePen view", ->
|
||||
it "returns the root node of the view with a __spacePenView property pointing at the SpacePen view", ->
|
||||
it "returns the root node of the view with a .spacePenView property pointing at the SpacePen view", ->
|
||||
class TestView extends View
|
||||
@content: -> @div "Hello"
|
||||
|
||||
view = new TestView
|
||||
node = registry.getView(view)
|
||||
expect(node.textContent).toBe "Hello"
|
||||
expect(node.__spacePenView).toBe view
|
||||
expect(node.spacePenView).toBe view
|
||||
|
||||
describe "when passed a model object", ->
|
||||
describe "when a view provider is registered matching the object's constructor", ->
|
||||
@@ -62,7 +62,7 @@ describe "ViewRegistry", ->
|
||||
node = registry.getView(model)
|
||||
|
||||
expect(node.textContent).toBe "hello"
|
||||
view = node.__spacePenView
|
||||
view = node.spacePenView
|
||||
expect(view instanceof TestView).toBe true
|
||||
expect(view.model).toBe model
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@ path = require 'path'
|
||||
temp = require 'temp'
|
||||
Workspace = require '../src/workspace'
|
||||
{View} = require '../src/space-pen-extensions'
|
||||
platform = require './spec-helper-platform'
|
||||
_ = require 'underscore-plus'
|
||||
fstream = require 'fstream'
|
||||
fs = require 'fs-plus'
|
||||
|
||||
describe "Workspace", ->
|
||||
workspace = null
|
||||
@@ -553,3 +557,287 @@ describe "Workspace", ->
|
||||
|
||||
expect(atom.workspace.panelForItem(item)).toBe panel
|
||||
expect(atom.workspace.panelForItem(itemWithNoPanel)).toBe null
|
||||
|
||||
describe "::scan(regex, options, callback)", ->
|
||||
describe "when called with a regex", ->
|
||||
it "calls the callback with all regex results in all files in the project", ->
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
atom.workspace.scan /(a)+/, (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength(3)
|
||||
expect(results[0].filePath).toBe atom.project.resolve('a')
|
||||
expect(results[0].matches).toHaveLength(3)
|
||||
expect(results[0].matches[0]).toEqual
|
||||
matchText: 'aaa'
|
||||
lineText: 'aaa bbb'
|
||||
lineTextOffset: 0
|
||||
range: [[0, 0], [0, 3]]
|
||||
|
||||
it "works with with escaped literals (like $ and ^)", ->
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
atom.workspace.scan /\$\w+/, (result) -> results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results.length).toBe 1
|
||||
|
||||
{filePath, matches} = results[0]
|
||||
expect(filePath).toBe atom.project.resolve('a')
|
||||
expect(matches).toHaveLength 1
|
||||
expect(matches[0]).toEqual
|
||||
matchText: '$bill'
|
||||
lineText: 'dollar$bill'
|
||||
lineTextOffset: 0
|
||||
range: [[2, 6], [2, 11]]
|
||||
|
||||
it "works on evil filenames", ->
|
||||
platform.generateEvilFiles()
|
||||
atom.project.setPaths([path.join(__dirname, 'fixtures', 'evil-files')])
|
||||
paths = []
|
||||
matches = []
|
||||
waitsForPromise ->
|
||||
atom.workspace.scan /evil/, (result) ->
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
|
||||
runs ->
|
||||
_.each(matches, (m) -> expect(m.matchText).toEqual 'evil')
|
||||
|
||||
if platform.isWindows()
|
||||
expect(paths.length).toBe 3
|
||||
expect(paths[0]).toMatch /a_file_with_utf8.txt$/
|
||||
expect(paths[1]).toMatch /file with spaces.txt$/
|
||||
expect(path.basename(paths[2])).toBe "utfa\u0306.md"
|
||||
else
|
||||
expect(paths.length).toBe 5
|
||||
expect(paths[0]).toMatch /a_file_with_utf8.txt$/
|
||||
expect(paths[1]).toMatch /file with spaces.txt$/
|
||||
expect(paths[2]).toMatch /goddam\nnewlines$/m
|
||||
expect(paths[3]).toMatch /quote".txt$/m
|
||||
expect(path.basename(paths[4])).toBe "utfa\u0306.md"
|
||||
|
||||
it "ignores case if the regex includes the `i` flag", ->
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
atom.workspace.scan /DOLLAR/i, (result) -> results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 1
|
||||
|
||||
describe "when the core.excludeVcsIgnoredPaths config is truthy", ->
|
||||
[projectPath, ignoredPath] = []
|
||||
|
||||
beforeEach ->
|
||||
sourceProjectPath = path.join(__dirname, 'fixtures', 'git', 'working-dir')
|
||||
projectPath = path.join(temp.mkdirSync("atom"))
|
||||
|
||||
writerStream = fstream.Writer(projectPath)
|
||||
fstream.Reader(sourceProjectPath).pipe(writerStream)
|
||||
|
||||
waitsFor (done) ->
|
||||
writerStream.on 'close', done
|
||||
writerStream.on 'error', done
|
||||
|
||||
runs ->
|
||||
fs.rename(path.join(projectPath, 'git.git'), path.join(projectPath, '.git'))
|
||||
ignoredPath = path.join(projectPath, 'ignored.txt')
|
||||
fs.writeFileSync(ignoredPath, 'this match should not be included')
|
||||
|
||||
afterEach ->
|
||||
fs.removeSync(projectPath) if fs.existsSync(projectPath)
|
||||
|
||||
it "excludes ignored files", ->
|
||||
atom.project.setPaths([projectPath])
|
||||
atom.config.set('core.excludeVcsIgnoredPaths', true)
|
||||
resultHandler = jasmine.createSpy("result found")
|
||||
waitsForPromise ->
|
||||
atom.workspace.scan /match/, (results) ->
|
||||
resultHandler()
|
||||
|
||||
runs ->
|
||||
expect(resultHandler).not.toHaveBeenCalled()
|
||||
|
||||
it "includes only files when a directory filter is specified", ->
|
||||
projectPath = path.join(path.join(__dirname, 'fixtures', 'dir'))
|
||||
atom.project.setPaths([projectPath])
|
||||
|
||||
filePath = path.join(projectPath, 'a-dir', 'oh-git')
|
||||
|
||||
paths = []
|
||||
matches = []
|
||||
waitsForPromise ->
|
||||
atom.workspace.scan /aaa/, paths: ["a-dir#{path.sep}"], (result) ->
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
|
||||
runs ->
|
||||
expect(paths.length).toBe 1
|
||||
expect(paths[0]).toBe filePath
|
||||
expect(matches.length).toBe 1
|
||||
|
||||
it "includes files and folders that begin with a '.'", ->
|
||||
projectPath = temp.mkdirSync()
|
||||
filePath = path.join(projectPath, '.text')
|
||||
fs.writeFileSync(filePath, 'match this')
|
||||
atom.project.setPaths([projectPath])
|
||||
paths = []
|
||||
matches = []
|
||||
waitsForPromise ->
|
||||
atom.workspace.scan /match this/, (result) ->
|
||||
paths.push(result.filePath)
|
||||
matches = matches.concat(result.matches)
|
||||
|
||||
runs ->
|
||||
expect(paths.length).toBe 1
|
||||
expect(paths[0]).toBe filePath
|
||||
expect(matches.length).toBe 1
|
||||
|
||||
it "excludes values in core.ignoredNames", ->
|
||||
projectPath = path.join(__dirname, 'fixtures', 'git', 'working-dir')
|
||||
ignoredNames = atom.config.get("core.ignoredNames")
|
||||
ignoredNames.push("a")
|
||||
atom.config.set("core.ignoredNames", ignoredNames)
|
||||
|
||||
resultHandler = jasmine.createSpy("result found")
|
||||
waitsForPromise ->
|
||||
atom.workspace.scan /dollar/, (results) ->
|
||||
resultHandler()
|
||||
|
||||
runs ->
|
||||
expect(resultHandler).not.toHaveBeenCalled()
|
||||
|
||||
it "scans buffer contents if the buffer is modified", ->
|
||||
editor = null
|
||||
results = []
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.open('a').then (o) ->
|
||||
editor = o
|
||||
editor.setText("Elephant")
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.scan /a|Elephant/, (result) -> results.push result
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 3
|
||||
resultForA = _.find results, ({filePath}) -> path.basename(filePath) == 'a'
|
||||
expect(resultForA.matches).toHaveLength 1
|
||||
expect(resultForA.matches[0].matchText).toBe 'Elephant'
|
||||
|
||||
it "ignores buffers outside the project", ->
|
||||
editor = null
|
||||
results = []
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.open(temp.openSync().path).then (o) ->
|
||||
editor = o
|
||||
editor.setText("Elephant")
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.scan /Elephant/, (result) -> results.push result
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 0
|
||||
|
||||
describe "::replace(regex, replacementText, paths, iterator)", ->
|
||||
[filePath, commentFilePath, sampleContent, sampleCommentContent] = []
|
||||
|
||||
beforeEach ->
|
||||
atom.project.setPaths([atom.project.resolve('../')])
|
||||
|
||||
filePath = atom.project.resolve('sample.js')
|
||||
commentFilePath = atom.project.resolve('sample-with-comments.js')
|
||||
sampleContent = fs.readFileSync(filePath).toString()
|
||||
sampleCommentContent = fs.readFileSync(commentFilePath).toString()
|
||||
|
||||
afterEach ->
|
||||
fs.writeFileSync(filePath, sampleContent)
|
||||
fs.writeFileSync(commentFilePath, sampleCommentContent)
|
||||
|
||||
describe "when a file doesn't exist", ->
|
||||
it "calls back with an error", ->
|
||||
errors = []
|
||||
missingPath = path.resolve('/not-a-file.js')
|
||||
expect(fs.existsSync(missingPath)).toBeFalsy()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.replace /items/gi, 'items', [missingPath], (result, error) ->
|
||||
errors.push(error)
|
||||
|
||||
runs ->
|
||||
expect(errors).toHaveLength 1
|
||||
expect(errors[0].path).toBe missingPath
|
||||
|
||||
describe "when called with unopened files", ->
|
||||
it "replaces properly", ->
|
||||
results = []
|
||||
waitsForPromise ->
|
||||
atom.workspace.replace /items/gi, 'items', [filePath], (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 1
|
||||
expect(results[0].filePath).toBe filePath
|
||||
expect(results[0].replacements).toBe 6
|
||||
|
||||
describe "when a buffer is already open", ->
|
||||
it "replaces properly and saves when not modified", ->
|
||||
editor = null
|
||||
results = []
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.open('sample.js').then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.isModified()).toBeFalsy()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.replace /items/gi, 'items', [filePath], (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 1
|
||||
expect(results[0].filePath).toBe filePath
|
||||
expect(results[0].replacements).toBe 6
|
||||
|
||||
expect(editor.isModified()).toBeFalsy()
|
||||
|
||||
it "does not replace when the path is not specified", ->
|
||||
editor = null
|
||||
results = []
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.open('sample-with-comments.js').then (o) -> editor = o
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.replace /items/gi, 'items', [commentFilePath], (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 1
|
||||
expect(results[0].filePath).toBe commentFilePath
|
||||
|
||||
it "does NOT save when modified", ->
|
||||
editor = null
|
||||
results = []
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.open('sample.js').then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
editor.buffer.setTextInRange([[0,0],[0,0]], 'omg')
|
||||
expect(editor.isModified()).toBeTruthy()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.replace /items/gi, 'okthen', [filePath], (result) ->
|
||||
results.push(result)
|
||||
|
||||
runs ->
|
||||
expect(results).toHaveLength 1
|
||||
expect(results[0].filePath).toBe filePath
|
||||
expect(results[0].replacements).toBe 6
|
||||
|
||||
expect(editor.isModified()).toBeTruthy()
|
||||
|
||||
@@ -359,7 +359,7 @@ class AtomApplication
|
||||
|
||||
if existingWindow?
|
||||
openedWindow = existingWindow
|
||||
openedWindow.openPath(pathToOpen, initialLine)
|
||||
openedWindow.openPath(pathToOpen, initialLine, initialColumn)
|
||||
if openedWindow.isMinimized()
|
||||
openedWindow.restore()
|
||||
else
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
autoUpdater = null
|
||||
_ = require 'underscore-plus'
|
||||
{EventEmitter} = require 'events'
|
||||
path = require 'path'
|
||||
|
||||
IdleState = 'idle'
|
||||
CheckingState = 'checking'
|
||||
@@ -51,8 +52,7 @@ class AutoUpdateManager
|
||||
@emitUpdateAvailableEvent(@getWindows()...)
|
||||
|
||||
# Only released versions should check for updates.
|
||||
unless /\w{7}/.test(@version)
|
||||
@check(hidePopups: true)
|
||||
@check(hidePopups: true) unless /\w{7}/.test(@version)
|
||||
|
||||
switch process.platform
|
||||
when 'win32'
|
||||
@@ -86,12 +86,24 @@ class AutoUpdateManager
|
||||
onUpdateNotAvailable: =>
|
||||
autoUpdater.removeListener 'error', @onUpdateError
|
||||
dialog = require 'dialog'
|
||||
dialog.showMessageBox type: 'info', buttons: ['OK'], message: 'No update available.', detail: "Version #{@version} is the latest version."
|
||||
dialog.showMessageBox
|
||||
type: 'info'
|
||||
buttons: ['OK']
|
||||
icon: path.resolve(__dirname, '..', '..', 'resources', 'atom.png')
|
||||
message: 'No update available.'
|
||||
title: 'No Update Available'
|
||||
detail: "Version #{@version} is the latest version."
|
||||
|
||||
onUpdateError: (event, message) =>
|
||||
autoUpdater.removeListener 'update-not-available', @onUpdateNotAvailable
|
||||
dialog = require 'dialog'
|
||||
dialog.showMessageBox type: 'warning', buttons: ['OK'], message: 'There was an error checking for updates.', detail: message
|
||||
dialog.showMessageBox
|
||||
type: 'warning'
|
||||
buttons: ['OK']
|
||||
icon: path.resolve(__dirname, '..', '..', 'resources', 'atom.png')
|
||||
message: 'There was an error checking for updates.'
|
||||
title: 'Update Error'
|
||||
detail: message
|
||||
|
||||
getWindows: ->
|
||||
global.atomApplication.windows
|
||||
|
||||
@@ -25,9 +25,15 @@ environmentKeyPath = 'HKCU\\Environment'
|
||||
# Spawn a command and invoke the callback when it completes with an error
|
||||
# and the output from standard out.
|
||||
spawn = (command, args, callback) ->
|
||||
spawnedProcess = ChildProcess.spawn(command, args)
|
||||
|
||||
stdout = ''
|
||||
|
||||
try
|
||||
spawnedProcess = ChildProcess.spawn(command, args)
|
||||
catch error
|
||||
# Spawn can throw an error
|
||||
process.nextTick -> callback?(error, stdout)
|
||||
return
|
||||
|
||||
spawnedProcess.stdout.on 'data', (data) -> stdout += data
|
||||
|
||||
error = null
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
_ = require 'underscore-plus'
|
||||
ChildProcess = require 'child_process'
|
||||
{Emitter} = require 'event-kit'
|
||||
path = require 'path'
|
||||
|
||||
# Extended: A wrapper which provides standard error/output line buffering for
|
||||
# Node's ChildProcess.
|
||||
@@ -201,7 +202,7 @@ class BufferedProcess
|
||||
|
||||
getCmdPath: ->
|
||||
if process.env.comspec
|
||||
process.env.compec
|
||||
process.env.comspec
|
||||
else if process.env.SystemRoot
|
||||
path.join(process.env.SystemRoot, 'System32', 'cmd.exe')
|
||||
else
|
||||
|
||||
@@ -16,6 +16,11 @@ module.exports =
|
||||
type: 'boolean'
|
||||
default: true
|
||||
title: 'Exclude VCS Ignored Paths'
|
||||
followSymlinks:
|
||||
type: 'boolean'
|
||||
default: false
|
||||
title: 'Follow symlinks'
|
||||
description: 'Used when searching and when opening files with the fuzzy finder.'
|
||||
disabledPackages:
|
||||
type: 'array'
|
||||
default: []
|
||||
@@ -93,6 +98,11 @@ module.exports =
|
||||
type: ['string', 'null']
|
||||
|
||||
# These can be used as globals or scoped, thus defaults.
|
||||
completions:
|
||||
type: "array"
|
||||
items:
|
||||
type: "string"
|
||||
default: []
|
||||
fontFamily:
|
||||
type: 'string'
|
||||
default: ''
|
||||
@@ -158,9 +168,9 @@ module.exports =
|
||||
description: 'Disabling will improve editor font rendering but reduce scrolling performance.'
|
||||
useShadowDOM:
|
||||
type: 'boolean'
|
||||
default: false
|
||||
default: true
|
||||
title: 'Use Shadow DOM'
|
||||
description: 'Enable to test out themes and packages with the new shadow DOM before it ships by default.'
|
||||
description: 'Disable if you experience styling issues with packages or themes. Be sure to open an issue on the relevant package or theme, because this option is going away eventually.'
|
||||
confirmCheckoutHeadRevision:
|
||||
type: 'boolean'
|
||||
default: true
|
||||
|
||||
+117
-87
@@ -313,13 +313,13 @@ class Config
|
||||
@defaultSettings = {}
|
||||
@settings = {}
|
||||
@scopedSettingsStore = new ScopedPropertyStore
|
||||
@usersScopedSettings = new CompositeDisposable
|
||||
@configFileHasErrors = false
|
||||
@configFilePath = fs.resolve(@configDirPath, 'config', ['json', 'cson'])
|
||||
@configFilePath ?= path.join(@configDirPath, 'config.cson')
|
||||
@transactDepth = 0
|
||||
@prioritiesBySource = {}
|
||||
@prioritiesBySource[@getUserConfigPath()] = 1000
|
||||
|
||||
@debouncedSave = _.debounce(@save, 100)
|
||||
@debouncedLoad = _.debounce(@loadUserConfig, 100)
|
||||
|
||||
###
|
||||
Section: Config Subscription
|
||||
@@ -436,14 +436,14 @@ class Config
|
||||
# files.
|
||||
#
|
||||
# ```coffee
|
||||
# atom.config.get(['source.ruby'], 'editor.tabLength') # => 2
|
||||
# atom.config.get('editor.tabLength', scope: ['source.ruby']) # => 2
|
||||
# ```
|
||||
#
|
||||
# This setting in ruby files might be different than the global tabLength setting
|
||||
#
|
||||
# ```coffee
|
||||
# atom.config.get('editor.tabLength') # => 4
|
||||
# atom.config.get(['source.ruby'], 'editor.tabLength') # => 2
|
||||
# atom.config.get('editor.tabLength', scope: ['source.ruby']) # => 2
|
||||
# ```
|
||||
#
|
||||
# You can get the language scope descriptor via
|
||||
@@ -451,14 +451,14 @@ class Config
|
||||
# for the editor's language.
|
||||
#
|
||||
# ```coffee
|
||||
# atom.config.get(@editor.getRootScopeDescriptor(), 'editor.tabLength') # => 2
|
||||
# atom.config.get('editor.tabLength', scope: @editor.getRootScopeDescriptor()) # => 2
|
||||
# ```
|
||||
#
|
||||
# Additionally, you can get the setting at the specific cursor position.
|
||||
#
|
||||
# ```coffee
|
||||
# scopeDescriptor = @editor.getLastCursor().getScopeDescriptor()
|
||||
# atom.config.get(scopeDescriptor, 'editor.tabLength') # => 2
|
||||
# atom.config.get('editor.tabLength', scope: scopeDescriptor) # => 2
|
||||
# ```
|
||||
#
|
||||
# * `keyPath` The {String} name of the key to retrieve.
|
||||
@@ -468,7 +468,7 @@ class Config
|
||||
# * `excludeSources` (optional) {Array} of {String} source names. If provided,
|
||||
# values that were associated with these sources during {::set} will not
|
||||
# be used.
|
||||
# * `scopeDescriptor` (optional) {ScopeDescriptor} describing a path from
|
||||
# * `scope` (optional) {ScopeDescriptor} describing a path from
|
||||
# the root of the syntax tree to a token. Get one by calling
|
||||
# {editor.getLastCursor().getScopeDescriptor()}
|
||||
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
|
||||
@@ -496,6 +496,28 @@ class Config
|
||||
else
|
||||
@getRawValue(keyPath, options)
|
||||
|
||||
# Extended: Get all of the values for the given key-path, along with their
|
||||
# associated scope selector.
|
||||
#
|
||||
# * `keyPath` The {String} name of the key to retrieve
|
||||
# * `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
|
||||
# * `value` The value for the key-path
|
||||
getAll: (keyPath, options) ->
|
||||
{scope, sources} = options if options?
|
||||
result = []
|
||||
|
||||
if scope?
|
||||
scopeDescriptor = ScopeDescriptor.fromObject(scope)
|
||||
result = result.concat @scopedSettingsStore.getAll(scopeDescriptor.getScopeChain(), keyPath, options)
|
||||
|
||||
if globalValue = @getRawValue(keyPath, options)
|
||||
result.push(scopeSelector: '*', value: globalValue)
|
||||
|
||||
result
|
||||
|
||||
# Essential: Sets the value for a configuration setting.
|
||||
#
|
||||
# This value is stored in Atom's internal configuration file.
|
||||
@@ -513,16 +535,16 @@ class Config
|
||||
#
|
||||
# ```coffee
|
||||
# atom.config.get('editor.tabLength') # => 4
|
||||
# atom.config.get(['source.ruby'], 'editor.tabLength') # => 4
|
||||
# atom.config.get(['source.js'], 'editor.tabLength') # => 4
|
||||
# atom.config.get('editor.tabLength', scope: ['source.ruby']) # => 4
|
||||
# atom.config.get('editor.tabLength', scope: ['source.js']) # => 4
|
||||
#
|
||||
# # Set ruby to 2
|
||||
# atom.config.set('source.ruby', 'editor.tabLength', 2) # => true
|
||||
# atom.config.set('editor.tabLength', 2, scopeSelector: 'source.ruby') # => true
|
||||
#
|
||||
# # Notice it's only set to 2 in the case of ruby
|
||||
# atom.config.get('editor.tabLength') # => 4
|
||||
# atom.config.get(['source.ruby'], 'editor.tabLength') # => 2
|
||||
# atom.config.get(['source.js'], 'editor.tabLength') # => 4
|
||||
# atom.config.get('editor.tabLength', scope: ['source.ruby']) # => 2
|
||||
# atom.config.get('editor.tabLength', scope: ['source.js']) # => 4
|
||||
# ```
|
||||
#
|
||||
# * `keyPath` The {String} name of the key.
|
||||
@@ -549,6 +571,10 @@ class Config
|
||||
[keyPath, value, options] = arguments
|
||||
scopeSelector = options?.scopeSelector
|
||||
source = options?.source
|
||||
shouldSave = options?.save ? true
|
||||
|
||||
if source and not scopeSelector
|
||||
throw new Error("::set with a 'source' and no 'sourceSelector' is not yet implemented!")
|
||||
|
||||
source ?= @getUserConfigPath()
|
||||
|
||||
@@ -561,10 +587,9 @@ class Config
|
||||
if scopeSelector?
|
||||
@setRawScopedValue(source, scopeSelector, keyPath, value)
|
||||
else
|
||||
@setRawValue(source, keyPath, value)
|
||||
@setRawValue(keyPath, value)
|
||||
|
||||
@emitChangeEvent()
|
||||
@save() unless @configFileHasErrors
|
||||
@debouncedSave() if source is @getUserConfigPath() and shouldSave and not @configFileHasErrors
|
||||
true
|
||||
|
||||
# Essential: Restore the setting at `keyPath` to its default value.
|
||||
@@ -593,12 +618,20 @@ class Config
|
||||
@scopedSettingsStore.removePropertiesForSourceAndSelector(source, scopeSelector)
|
||||
_.setValueForKeyPath(settings, keyPath, undefined)
|
||||
settings = withoutEmptyObjects(settings)
|
||||
@addScopedSettings(source, scopeSelector, settings, priority: @usersScopedSettingPriority) if settings?
|
||||
@save() unless @configFileHasErrors
|
||||
@set(null, settings, {scopeSelector, source, priority: @priorityForSource(source)}) if settings?
|
||||
@debouncedSave()
|
||||
else
|
||||
@scopedSettingsStore.removePropertiesForSource(source)
|
||||
@scopedSettingsStore.removePropertiesForSourceAndSelector(source, scopeSelector)
|
||||
@emitChangeEvent()
|
||||
else
|
||||
@set(keyPath, _.valueForKeyPath(@defaultSettings, keyPath))
|
||||
@scopedSettingsStore.removePropertiesForSource(source)
|
||||
if keyPath?
|
||||
@set(keyPath, _.valueForKeyPath(@defaultSettings, keyPath))
|
||||
|
||||
# Extended: Get an {Array} of all of the `source` {String}s with which
|
||||
# settings have been added via {::set}.
|
||||
getSources: ->
|
||||
_.uniq(_.pluck(@scopedSettingsStore.propertySets, 'source')).sort()
|
||||
|
||||
# Deprecated: Restore the global setting at `keyPath` to its default value.
|
||||
#
|
||||
@@ -636,11 +669,10 @@ class Config
|
||||
Grim.deprecate("Use `not ::get(keyPath, {scope, sources: [atom.config.getUserConfigPath()]})?` instead")
|
||||
if arguments.length is 1
|
||||
[keyPath] = arguments
|
||||
scopeSelector = '*'
|
||||
else
|
||||
[scopeSelector, keyPath] = arguments
|
||||
|
||||
not @get(keyPath, {scope: [scopeSelector], sources: [@getUserConfigPath()]})?
|
||||
scope = [scopeSelector]
|
||||
not @get(keyPath, {scope, sources: [@getUserConfigPath()]})?
|
||||
|
||||
# Extended: Retrieve the schema for a specific key path. The schema will tell
|
||||
# you what type the keyPath expects, and other metadata about the config
|
||||
@@ -662,7 +694,7 @@ class Config
|
||||
# defaults. Returns the scoped settings when a `scopeSelector` is specified.
|
||||
getSettings: ->
|
||||
Grim.deprecate "Use ::get(keyPath) instead"
|
||||
_.deepExtend({}, @defaultSettings, @scopedSettingsStore.getProperties('.xxx')...)
|
||||
_.deepExtend({}, @settings, @defaultSettings)
|
||||
|
||||
# Extended: Get the {String} path to the config file being used.
|
||||
getUserConfigPath: ->
|
||||
@@ -789,7 +821,7 @@ class Config
|
||||
observeUserConfig: ->
|
||||
try
|
||||
@watchSubscription ?= pathWatcher.watch @configFilePath, (eventType) =>
|
||||
@loadUserConfig() if eventType is 'change' and @watchSubscription?
|
||||
@debouncedLoad() if eventType is 'change' and @watchSubscription?
|
||||
catch error
|
||||
@notifyFailure('Failed to watch user config', error)
|
||||
|
||||
@@ -805,41 +837,37 @@ class Config
|
||||
console.error detail
|
||||
|
||||
save: ->
|
||||
settings = @scopedSettingsStore.propertiesForSource(@getUserConfigPath())
|
||||
settings.global = settings['*']
|
||||
delete settings['*']
|
||||
CSON.writeFileSync(@configFilePath, settings)
|
||||
allSettings = {'*': @settings}
|
||||
allSettings = _.extend allSettings, @scopedSettingsStore.propertiesForSource(@getUserConfigPath())
|
||||
CSON.writeFileSync(@configFilePath, allSettings)
|
||||
|
||||
###
|
||||
Section: Private methods managing global settings
|
||||
###
|
||||
|
||||
resetUserSettings: (newSettings) ->
|
||||
@scopedSettingsStore.removePropertiesForSource(@getUserConfigPath())
|
||||
|
||||
unless isPlainObject(newSettings)
|
||||
@settings = {}
|
||||
@emitChangeEvent()
|
||||
return
|
||||
|
||||
unless newSettings.global?
|
||||
newSettings = {global: newSettings}
|
||||
if newSettings.global?
|
||||
newSettings['*'] = newSettings.global
|
||||
delete newSettings.global
|
||||
|
||||
for selector, settings of newSettings
|
||||
unless settings is undefined
|
||||
try
|
||||
settings = @makeValueConformToSchema(null, settings)
|
||||
catch e
|
||||
continue
|
||||
if newSettings['*']?
|
||||
scopedSettings = newSettings
|
||||
newSettings = newSettings['*']
|
||||
delete scopedSettings['*']
|
||||
@resetUserScopedSettings(scopedSettings)
|
||||
|
||||
if selector is 'global'
|
||||
@setRawValue(@getUserConfigPath(), null, settings)
|
||||
else
|
||||
@setRawScopedValue(@getUserConfigPath(), selector, null, settings)
|
||||
|
||||
@emitChangeEvent()
|
||||
@transact =>
|
||||
@settings = {}
|
||||
@set(key, value, save: false) for key, value of newSettings
|
||||
|
||||
getRawValue: (keyPath, options) ->
|
||||
value = @getRawScopedValue(['xxx'], keyPath, options)
|
||||
unless options?.excludeSources?.indexOf(@getUserConfigPath()) >= 0
|
||||
value = _.valueForKeyPath(@settings, keyPath)
|
||||
unless options?.sources?.length > 0
|
||||
defaultValue = _.valueForKeyPath(@defaultSettings, keyPath)
|
||||
|
||||
@@ -851,17 +879,28 @@ class Config
|
||||
|
||||
value
|
||||
|
||||
setRawValue: (source, keyPath, value) ->
|
||||
setRawValue: (keyPath, value) ->
|
||||
defaultValue = _.valueForKeyPath(@defaultSettings, keyPath)
|
||||
value = undefined if _.isEqual(defaultValue, value)
|
||||
@setRawScopedValue(source, '*', keyPath, value)
|
||||
|
||||
if keyPath?
|
||||
_.setValueForKeyPath(@settings, keyPath, value)
|
||||
else
|
||||
@settings = value
|
||||
@emitChangeEvent()
|
||||
|
||||
observeKeyPath: (keyPath, options, callback) ->
|
||||
@observeScopedKeyPath(["xxx"], keyPath, callback)
|
||||
callback(@get(keyPath))
|
||||
@onDidChangeKeyPath keyPath, (event) -> callback(event.newValue)
|
||||
|
||||
onDidChangeKeyPath: (keyPath, callback) ->
|
||||
@onDidChangeScopedKeyPath(["xxx"], keyPath, callback)
|
||||
oldValue = @get(keyPath)
|
||||
@emitter.on 'did-change', =>
|
||||
newValue = @get(keyPath)
|
||||
unless _.isEqual(oldValue, newValue)
|
||||
event = {oldValue, newValue}
|
||||
oldValue = newValue
|
||||
callback(event)
|
||||
|
||||
isSubKeyPath: (keyPath, subKeyPath) ->
|
||||
return false unless keyPath? and subKeyPath?
|
||||
@@ -883,7 +922,6 @@ class Config
|
||||
try
|
||||
defaults = @makeValueConformToSchema(keyPath, defaults)
|
||||
@setRawDefault(keyPath, defaults)
|
||||
@emitChangeEvent()
|
||||
catch e
|
||||
console.warn("'#{keyPath}' could not set the default. Attempted default: #{JSON.stringify(defaults)}; Schema: #{JSON.stringify(@getSchema(keyPath))}")
|
||||
|
||||
@@ -930,10 +968,23 @@ class Config
|
||||
Section: Private Scoped Settings
|
||||
###
|
||||
|
||||
priorityForSource: (source) ->
|
||||
if source is @getUserConfigPath()
|
||||
1000
|
||||
else
|
||||
0
|
||||
|
||||
emitChangeEvent: ->
|
||||
@emitter.emit 'did-change' unless @transactDepth > 0
|
||||
|
||||
resetUserScopedSettings: (newScopedSettings) ->
|
||||
source = @getUserConfigPath()
|
||||
@scopedSettingsStore.removePropertiesForSource(source)
|
||||
@scopedSettingsStore.addProperties(source, newScopedSettings, priority: @priorityForSource(source))
|
||||
@emitChangeEvent()
|
||||
|
||||
addScopedSettings: (source, selector, value, options) ->
|
||||
Grim.deprecate("Use ::set instead")
|
||||
settingsBySelector = {}
|
||||
settingsBySelector[selector] = value
|
||||
disposable = @scopedSettingsStore.addProperties(source, settingsBySelector, options)
|
||||
@@ -945,37 +996,35 @@ class Config
|
||||
setRawScopedValue: (source, selector, keyPath, value) ->
|
||||
if keyPath?
|
||||
newValue = {}
|
||||
setValueAtKeyPath(newValue, keyPath, value)
|
||||
_.setValueForKeyPath(newValue, keyPath, value)
|
||||
value = newValue
|
||||
|
||||
settingsBySelector = {}
|
||||
settingsBySelector[selector] = value
|
||||
@usersScopedSettings.add @scopedSettingsStore.addProperties(source, settingsBySelector, priority: @prioritiesBySource[source])
|
||||
@scopedSettingsStore.addProperties(source, settingsBySelector, priority: @priorityForSource(source))
|
||||
@emitChangeEvent()
|
||||
|
||||
getRawScopedValue: (scopeDescriptor, keyPath, options) ->
|
||||
scopeDescriptor = ScopeDescriptor.fromObject(scopeDescriptor)
|
||||
value = @scopedSettingsStore.getPropertyValue(scopeDescriptor.getScopeChain(), keyPath, options)
|
||||
value
|
||||
@scopedSettingsStore.getPropertyValue(scopeDescriptor.getScopeChain(), keyPath, options)
|
||||
|
||||
observeScopedKeyPath: (scope, keyPath, callback) ->
|
||||
callback(@get(keyPath, {scope}))
|
||||
@onDidChangeScopedKeyPath scope, keyPath, ({newValue}) ->
|
||||
callback(newValue)
|
||||
@onDidChangeScopedKeyPath scope, keyPath, (event) -> callback(event.newValue)
|
||||
|
||||
onDidChangeScopedKeyPath: (scope, keyPath, callback) ->
|
||||
oldValue = _.deepClone(@get(keyPath, {scope}))
|
||||
@emitter.on 'did-change', (event) =>
|
||||
oldValue = @get(keyPath, {scope})
|
||||
@emitter.on 'did-change', =>
|
||||
newValue = @get(keyPath, {scope})
|
||||
unless _.isEqual(newValue, oldValue)
|
||||
callback({newValue, oldValue})
|
||||
oldValue = _.deepClone(newValue)
|
||||
unless _.isEqual(oldValue, newValue)
|
||||
event = {oldValue, newValue}
|
||||
oldValue = newValue
|
||||
callback(event)
|
||||
|
||||
# TODO: figure out how to change / remove this. The return value is awkward.
|
||||
# * language mode uses it for one thing.
|
||||
# * autocomplete uses it for editor.completions
|
||||
settingsForScopeDescriptor: (scopeDescriptor, keyPath) ->
|
||||
scopeDescriptor = ScopeDescriptor.fromObject(scopeDescriptor)
|
||||
@scopedSettingsStore.getProperties(scopeDescriptor.getScopeChain(), keyPath)
|
||||
Grim.deprecate("Use Config::getAll instead")
|
||||
entries = @getAll(null, scope: scopeDescriptor)
|
||||
value for {value} in entries when _.valueForKeyPath(value, keyPath)?
|
||||
|
||||
# Base schema enforcers. These will coerce raw input into the specified type,
|
||||
# and will throw an error when the value cannot be coerced. Throwing the error
|
||||
@@ -1034,11 +1083,7 @@ Config.addSchemaEnforcers
|
||||
for prop, childSchema of schema.properties
|
||||
continue unless value.hasOwnProperty(prop)
|
||||
try
|
||||
newKeyPath = if keyPath?
|
||||
"#{keyPath}.#{prop}"
|
||||
else
|
||||
prop
|
||||
newValue[prop] = @executeSchemaEnforcers(newKeyPath, value[prop], childSchema)
|
||||
newValue[prop] = @executeSchemaEnforcers("#{keyPath}.#{prop}", value[prop], childSchema)
|
||||
catch error
|
||||
console.warn "Error setting item in object: #{error.message}"
|
||||
newValue
|
||||
@@ -1091,21 +1136,6 @@ splitKeyPath = (keyPath) ->
|
||||
keyPathArray.push keyPath.substr(startIndex, keyPath.length)
|
||||
keyPathArray
|
||||
|
||||
getValueAtKeyPath = (object, keyPath) ->
|
||||
keys = splitKeyPath(keyPath)
|
||||
for key in keys
|
||||
object = object[key]
|
||||
return unless object?
|
||||
object
|
||||
|
||||
setValueAtKeyPath = (object, keyPath, value) ->
|
||||
keys = splitKeyPath(keyPath)
|
||||
while keys.length > 1
|
||||
key = keys.shift()
|
||||
object[key] ?= {}
|
||||
object = object[key]
|
||||
object[keys.shift()] = value
|
||||
|
||||
withoutEmptyObjects = (object) ->
|
||||
resultObject = undefined
|
||||
if isPlainObject(object)
|
||||
|
||||
@@ -16,6 +16,31 @@ SpecificityCache = {}
|
||||
#
|
||||
# An instance of this class is always available as the `atom.contextMenu`
|
||||
# global.
|
||||
#
|
||||
# ## Context Menu CSON Format
|
||||
#
|
||||
# # ```coffee
|
||||
# 'atom-workspace': [{label: 'Help', command: 'application:open-documentation'}]
|
||||
# 'atom-text-editor': [{
|
||||
# label: 'History',
|
||||
# submenu: [
|
||||
# {label: 'Undo', command:'core:undo'}
|
||||
# {label: 'Redo', command:'core:redo'}
|
||||
# ]
|
||||
# }]
|
||||
# ```
|
||||
#
|
||||
# In your package's menu `.cson` file you need to specify it under a
|
||||
# `context-menu` key:
|
||||
#
|
||||
# ```coffee
|
||||
# 'context-menu':
|
||||
# 'atom-workspace': [{label: 'Help', command: 'application:open-documentation'}]
|
||||
# ...
|
||||
# ```
|
||||
#
|
||||
# The format for use in {::add} is the same minus the `context-menu` key. See
|
||||
# {::add} for more information.
|
||||
module.exports =
|
||||
class ContextMenuManager
|
||||
constructor: ({@resourcePath, @devMode}) ->
|
||||
@@ -46,8 +71,8 @@ class ContextMenuManager
|
||||
# 'atom-text-editor': [{
|
||||
# label: 'History',
|
||||
# submenu: [
|
||||
# {label: 'Undo': command:'core:undo'}
|
||||
# {label: 'Redo': command:'core:redo'}
|
||||
# {label: 'Undo', command:'core:undo'}
|
||||
# {label: 'Redo', command:'core:redo'}
|
||||
# ]
|
||||
# }]
|
||||
# }
|
||||
@@ -77,14 +102,22 @@ class ContextMenuManager
|
||||
add: (itemsBySelector) ->
|
||||
# Detect deprecated file path as first argument
|
||||
if itemsBySelector? and typeof itemsBySelector isnt 'object'
|
||||
Grim.deprecate("ContextMenuManager::add has changed to take a single object as its argument. Please consult the documentation.")
|
||||
Grim.deprecate """
|
||||
ContextMenuManager::add has changed to take a single object as its
|
||||
argument. Please see
|
||||
https://atom.io/docs/api/latest/ContextMenuManager for more info.
|
||||
"""
|
||||
itemsBySelector = arguments[1]
|
||||
devMode = arguments[2]?.devMode
|
||||
|
||||
# Detect deprecated format for items object
|
||||
for key, value of itemsBySelector
|
||||
unless _.isArray(value)
|
||||
Grim.deprecate("The format for declaring context menu items has changed. Please consult the documentation.")
|
||||
Grim.deprecate """
|
||||
ContextMenuManager::add has changed to take a single object as its
|
||||
argument. Please see
|
||||
https://atom.io/docs/api/latest/ContextMenuManager for more info.
|
||||
"""
|
||||
itemsBySelector = @convertLegacyItemsBySelector(itemsBySelector, devMode)
|
||||
|
||||
addedItemSets = []
|
||||
|
||||
+9
-3
@@ -206,10 +206,16 @@ class Cursor extends Model
|
||||
_.contains(nonWordCharacters, before) isnt _.contains(nonWordCharacters, after)
|
||||
|
||||
# Public: Returns whether this cursor is between a word's start and end.
|
||||
isInsideWord: ->
|
||||
#
|
||||
# * `options` (optional) {Object}
|
||||
# * `wordRegex` A {RegExp} indicating what constitutes a "word"
|
||||
# (default: {::wordRegExp}).
|
||||
#
|
||||
# Returns a {Boolean}
|
||||
isInsideWord: (options) ->
|
||||
{row, column} = @getBufferPosition()
|
||||
range = [[row, column], [row, Infinity]]
|
||||
@editor.getTextInBufferRange(range).search(@wordRegExp()) == 0
|
||||
@editor.getTextInBufferRange(range).search(options?.wordRegex ? @wordRegExp()) == 0
|
||||
|
||||
# Public: Returns the indentation level of the current line.
|
||||
getIndentLevel: ->
|
||||
@@ -544,7 +550,7 @@ class Cursor extends Model
|
||||
# Returns a {Range}
|
||||
getBeginningOfNextWordBufferPosition: (options = {}) ->
|
||||
currentBufferPosition = @getBufferPosition()
|
||||
start = if @isInsideWord() then @getEndOfCurrentWordBufferPosition() else currentBufferPosition
|
||||
start = if @isInsideWord(options) then @getEndOfCurrentWordBufferPosition(options) else currentBufferPosition
|
||||
scanRange = [start, @editor.getEofBufferPosition()]
|
||||
|
||||
beginningOfNextWordPosition = null
|
||||
|
||||
@@ -67,5 +67,5 @@ class GrammarRegistry extends FirstMate.GrammarRegistry
|
||||
atom.config.getRawScopedValue(scope, keyPath)
|
||||
|
||||
propertiesForScope: (scope, keyPath) ->
|
||||
deprecate 'A direct (but private) replacement is available at atom.config.scopedSettingsForScopeDescriptor().'
|
||||
deprecate 'Use atom.config.getAll instead.'
|
||||
atom.config.settingsForScopeDescriptor(scope, keyPath)
|
||||
|
||||
@@ -26,17 +26,16 @@ class LanguageMode
|
||||
#
|
||||
# startRow - The row {Number} to start at
|
||||
# endRow - The row {Number} to end at
|
||||
#
|
||||
# Returns an {Array} of the commented {Ranges}.
|
||||
toggleLineCommentsForBufferRows: (start, end) ->
|
||||
scopeDescriptor = @editor.scopeDescriptorForBufferPosition([start, 0])
|
||||
properties = atom.config.settingsForScopeDescriptor(scopeDescriptor, 'editor.commentStart')[0]
|
||||
return unless properties
|
||||
scope = @editor.scopeDescriptorForBufferPosition([start, 0])
|
||||
commentStartEntry = atom.config.getAll('editor.commentStart', {scope})[0]
|
||||
|
||||
commentStartString = _.valueForKeyPath(properties, 'editor.commentStart')
|
||||
commentEndString = _.valueForKeyPath(properties, 'editor.commentEnd')
|
||||
return unless commentStartEntry?
|
||||
|
||||
return unless commentStartString
|
||||
commentEndEntry = atom.config.getAll('editor.commentEnd', {scope}).find (entry) ->
|
||||
entry.scopeSelector is commentStartEntry.scopeSelector
|
||||
commentStartString = commentStartEntry?.value
|
||||
commentEndString = commentEndEntry?.value
|
||||
|
||||
buffer = @editor.buffer
|
||||
commentStartRegexString = _.escapeRegExp(commentStartString).replace(/(\s+)$/, '(?:$1)?')
|
||||
@@ -96,6 +95,7 @@ class LanguageMode
|
||||
buffer.insert([row, indentLength], commentStartString)
|
||||
else
|
||||
buffer.setTextInRange([[row, 0], [row, indentString.length]], indentString + commentStartString)
|
||||
return
|
||||
|
||||
# Folds all the foldable lines in the buffer.
|
||||
foldAll: ->
|
||||
@@ -113,6 +113,7 @@ class LanguageMode
|
||||
#
|
||||
# indentLevel - A {Number} indicating indentLevel; 0 based.
|
||||
foldAllAtIndentLevel: (indentLevel) ->
|
||||
@unfoldAll()
|
||||
for currentRow in [0..@buffer.getLastRow()]
|
||||
[startRow, endRow] = @rowRangeForFoldAtBufferRow(currentRow) ? []
|
||||
continue unless startRow?
|
||||
|
||||
@@ -12,6 +12,49 @@ MenuHelpers = require './menu-helpers'
|
||||
# application menu.
|
||||
#
|
||||
# An instance of this class is always available as the `atom.menu` global.
|
||||
#
|
||||
# ## Menu CSON Format
|
||||
#
|
||||
# Here is an example from the [tree-view](https://github.com/atom/tree-view/blob/master/menus/tree-view.cson):
|
||||
#
|
||||
# ```coffee
|
||||
# [
|
||||
# {
|
||||
# 'label': 'View'
|
||||
# 'submenu': [
|
||||
# { 'label': 'Toggle Tree View', 'command': 'tree-view:toggle' }
|
||||
# ]
|
||||
# }
|
||||
# {
|
||||
# 'label': 'Packages'
|
||||
# 'submenu': [
|
||||
# 'label': 'Tree View'
|
||||
# 'submenu': [
|
||||
# { 'label': 'Focus', 'command': 'tree-view:toggle-focus' }
|
||||
# { 'label': 'Toggle', 'command': 'tree-view:toggle' }
|
||||
# { 'label': 'Reveal Active File', 'command': 'tree-view:reveal-active-file' }
|
||||
# { 'label': 'Toggle Tree Side', 'command': 'tree-view:toggle-side' }
|
||||
# ]
|
||||
# ]
|
||||
# }
|
||||
# ]
|
||||
# ```
|
||||
#
|
||||
# Use in your package's menu `.cson` file requires that you place your menu
|
||||
# structure under a `menu` key.
|
||||
#
|
||||
# ```coffee
|
||||
# 'menu': [
|
||||
# {
|
||||
# 'label': 'View'
|
||||
# 'submenu': [
|
||||
# { 'label': 'Toggle Tree View', 'command': 'tree-view:toggle' }
|
||||
# ]
|
||||
# }
|
||||
# ]
|
||||
# ```
|
||||
#
|
||||
# See {::add} for more info about adding menu's directly.
|
||||
module.exports =
|
||||
class MenuManager
|
||||
constructor: ({@resourcePath}) ->
|
||||
|
||||
@@ -59,6 +59,8 @@ loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) ->
|
||||
if childMetadata?.version
|
||||
try
|
||||
mainPath = require.resolve(childPath)
|
||||
catch error
|
||||
mainPath = null
|
||||
|
||||
if mainPath
|
||||
moduleCache.dependencies.push
|
||||
|
||||
@@ -48,7 +48,7 @@ class PackageManager
|
||||
Section: Event Subscription
|
||||
###
|
||||
|
||||
# Public: Invoke the given callback when all packages have been activated.
|
||||
# Public: Invoke the given callback when all packages have been loaded.
|
||||
#
|
||||
# * `callback` {Function}
|
||||
#
|
||||
@@ -295,12 +295,12 @@ class PackageManager
|
||||
pack = new Package(packagePath, metadata)
|
||||
pack.load()
|
||||
@loadedPackages[pack.name] = pack
|
||||
pack
|
||||
return pack
|
||||
catch error
|
||||
console.warn "Failed to load package.json '#{path.basename(packagePath)}'", error.stack ? error
|
||||
|
||||
else
|
||||
throw new Error("Could not resolve '#{nameOrPath}' to a package path")
|
||||
console.warn "Could not resolve '#{nameOrPath}' to a package path"
|
||||
null
|
||||
|
||||
unloadPackages: ->
|
||||
@unloadPackage(name) for name in _.keys(@loadedPackages)
|
||||
@@ -337,11 +337,12 @@ class PackageManager
|
||||
activatePackage: (name) ->
|
||||
if pack = @getActivePackage(name)
|
||||
Q(pack)
|
||||
else
|
||||
pack = @loadPackage(name)
|
||||
else if pack = @loadPackage(name)
|
||||
pack.activate().then =>
|
||||
@activePackages[pack.name] = pack
|
||||
pack
|
||||
else
|
||||
Q.reject(new Error("Failed to load package '#{name}'"))
|
||||
|
||||
# Deactivate all packages
|
||||
deactivatePackages: ->
|
||||
|
||||
+30
-24
@@ -9,7 +9,6 @@ EmitterMixin = require('emissary').Emitter
|
||||
Q = require 'q'
|
||||
{deprecate} = require 'grim'
|
||||
|
||||
$ = null # Defer require in case this is in the window-less browser process
|
||||
ModuleCache = require './module-cache'
|
||||
ScopedProperties = require './scoped-properties'
|
||||
|
||||
@@ -52,7 +51,7 @@ class Package
|
||||
stylesheets: null
|
||||
stylesheetDisposables: null
|
||||
grammars: null
|
||||
scopedProperties: null
|
||||
settings: null
|
||||
mainModulePath: null
|
||||
resolvedMainModulePath: false
|
||||
mainModule: null
|
||||
@@ -110,7 +109,7 @@ class Package
|
||||
|
||||
getType: -> 'atom'
|
||||
|
||||
getStylesheetType: -> 'bundled'
|
||||
getStyleSheetPriority: -> 0
|
||||
|
||||
load: ->
|
||||
@measure 'loadTime', =>
|
||||
@@ -118,7 +117,7 @@ class Package
|
||||
@loadKeymaps()
|
||||
@loadMenus()
|
||||
@loadStylesheets()
|
||||
@scopedPropertiesPromise = @loadScopedProperties()
|
||||
@settingsPromise = @loadSettings()
|
||||
@requireMainModule() unless @hasActivationCommands()
|
||||
|
||||
catch error
|
||||
@@ -130,7 +129,7 @@ class Package
|
||||
@keymaps = []
|
||||
@menus = []
|
||||
@grammars = []
|
||||
@scopedProperties = []
|
||||
@settings = []
|
||||
|
||||
activate: ->
|
||||
@grammarsPromise ?= @loadGrammars()
|
||||
@@ -144,7 +143,7 @@ class Package
|
||||
else
|
||||
@activateNow()
|
||||
|
||||
Q.all([@grammarsPromise, @scopedPropertiesPromise, @activationDeferred.promise])
|
||||
Q.all([@grammarsPromise, @settingsPromise, @activationDeferred.promise])
|
||||
|
||||
activateNow: ->
|
||||
try
|
||||
@@ -176,8 +175,9 @@ class Package
|
||||
activateStylesheets: ->
|
||||
return if @stylesheetsActivated
|
||||
|
||||
group = @getStylesheetType()
|
||||
@stylesheetDisposables = new CompositeDisposable
|
||||
|
||||
priority = @getStyleSheetPriority()
|
||||
for [sourcePath, source] in @stylesheets
|
||||
if match = path.basename(sourcePath).match(/[^.]*\.([^.]*)\./)
|
||||
context = match[1]
|
||||
@@ -186,7 +186,7 @@ class Package
|
||||
else
|
||||
context = undefined
|
||||
|
||||
@stylesheetDisposables.add(atom.styles.addStyleSheet(source, {sourcePath, group, context}))
|
||||
@stylesheetDisposables.add(atom.styles.addStyleSheet(source, {sourcePath, priority, context}))
|
||||
@stylesheetsActivated = true
|
||||
|
||||
activateResources: ->
|
||||
@@ -199,20 +199,20 @@ class Package
|
||||
grammar.activate() for grammar in @grammars
|
||||
@grammarsActivated = true
|
||||
|
||||
scopedProperties.activate() for scopedProperties in @scopedProperties
|
||||
@scopedPropertiesActivated = true
|
||||
settings.activate() for settings in @settings
|
||||
@settingsActivated = true
|
||||
|
||||
loadKeymaps: ->
|
||||
if @bundledPackage and packagesCache[@name]?
|
||||
@keymaps = (["#{atom.packages.resourcePath}#{path.sep}#{keymapPath}", keymapObject] for keymapPath, keymapObject of packagesCache[@name].keymaps)
|
||||
else
|
||||
@keymaps = @getKeymapPaths().map (keymapPath) -> [keymapPath, CSON.readFileSync(keymapPath)]
|
||||
@keymaps = @getKeymapPaths().map (keymapPath) -> [keymapPath, CSON.readFileSync(keymapPath) ? {}]
|
||||
|
||||
loadMenus: ->
|
||||
if @bundledPackage and packagesCache[@name]?
|
||||
@menus = (["#{atom.packages.resourcePath}#{path.sep}#{menuPath}", menuObject] for menuPath, menuObject of packagesCache[@name].menus)
|
||||
else
|
||||
@menus = @getMenuPaths().map (menuPath) -> [menuPath, CSON.readFileSync(menuPath)]
|
||||
@menus = @getMenuPaths().map (menuPath) -> [menuPath, CSON.readFileSync(menuPath) ? {}]
|
||||
|
||||
getKeymapPaths: ->
|
||||
keymapsDirPath = path.join(@path, 'keymaps')
|
||||
@@ -283,22 +283,28 @@ class Package
|
||||
async.each grammarPaths, loadGrammar, -> deferred.resolve()
|
||||
deferred.promise
|
||||
|
||||
loadScopedProperties: ->
|
||||
@scopedProperties = []
|
||||
loadSettings: ->
|
||||
@settings = []
|
||||
|
||||
loadScopedPropertiesFile = (scopedPropertiesPath, callback) =>
|
||||
ScopedProperties.load scopedPropertiesPath, (error, scopedProperties) =>
|
||||
loadSettingsFile = (settingsPath, callback) =>
|
||||
ScopedProperties.load settingsPath, (error, settings) =>
|
||||
if error?
|
||||
console.warn("Failed to load scoped properties: #{scopedPropertiesPath}", error.stack ? error)
|
||||
console.warn("Failed to load package settings: #{settingsPath}", error.stack ? error)
|
||||
else
|
||||
@scopedProperties.push(scopedProperties)
|
||||
scopedProperties.activate() if @scopedPropertiesActivated
|
||||
@settings.push(settings)
|
||||
settings.activate() if @settingsActivated
|
||||
callback()
|
||||
|
||||
deferred = Q.defer()
|
||||
scopedPropertiesDirPath = path.join(@path, 'scoped-properties')
|
||||
fs.list scopedPropertiesDirPath, ['json', 'cson'], (error, scopedPropertiesPaths=[]) ->
|
||||
async.each scopedPropertiesPaths, loadScopedPropertiesFile, -> deferred.resolve()
|
||||
|
||||
if fs.isDirectorySync(path.join(@path, 'scoped-properties'))
|
||||
settingsDirPath = path.join(@path, 'scoped-properties')
|
||||
deprecate("Store package settings files in the `settings` directory instead of `scoped-properties`")
|
||||
else
|
||||
settingsDirPath = path.join(@path, 'settings')
|
||||
|
||||
fs.list settingsDirPath, ['json', 'cson'], (error, settingsPaths=[]) ->
|
||||
async.each settingsPaths, loadSettingsFile, -> deferred.resolve()
|
||||
deferred.promise
|
||||
|
||||
serialize: ->
|
||||
@@ -328,12 +334,12 @@ class Package
|
||||
|
||||
deactivateResources: ->
|
||||
grammar.deactivate() for grammar in @grammars
|
||||
scopedProperties.deactivate() for scopedProperties in @scopedProperties
|
||||
settings.deactivate() for settings in @settings
|
||||
@stylesheetDisposables?.dispose()
|
||||
@activationDisposables?.dispose()
|
||||
@stylesheetsActivated = false
|
||||
@grammarsActivated = false
|
||||
@scopedPropertiesActivated = false
|
||||
@settingsActivated = false
|
||||
|
||||
reloadStylesheets: ->
|
||||
oldSheets = _.clone(@stylesheets)
|
||||
|
||||
@@ -153,7 +153,9 @@ class PaneView extends View
|
||||
activeItemModifiedChanged: =>
|
||||
@trigger 'pane:active-item-modified-status-changed'
|
||||
|
||||
@::accessor 'activeView', -> atom.views.getView(@activeItem)?.__spacePenView
|
||||
@::accessor 'activeView', ->
|
||||
element = atom.views.getView(@activeItem)
|
||||
$(element).view() ? element
|
||||
|
||||
splitLeft: (items...) -> atom.views.getView(@model.splitLeft({items})).__spacePenView
|
||||
|
||||
|
||||
+29
-83
@@ -166,9 +166,33 @@ class Project extends Model
|
||||
return fullPath if fullPath?.match(/[A-Za-z0-9+-.]+:\/\//) # leave path alone if it has a scheme
|
||||
@rootDirectory?.relativize(fullPath) ? fullPath
|
||||
|
||||
# Public: Returns whether the given path is inside this project.
|
||||
# Public: Determines whether the given path (real or symbolic) is inside the
|
||||
# project's directory.
|
||||
#
|
||||
# This method does not actually check if the path exists, it just checks their
|
||||
# locations relative to each other.
|
||||
#
|
||||
# ## Examples
|
||||
#
|
||||
# Basic operation
|
||||
#
|
||||
# ```coffee
|
||||
# # Project's root directory is /foo/bar
|
||||
# project.contains('/foo/bar/baz') # => true
|
||||
# project.contains('/usr/lib/baz') # => false
|
||||
# ```
|
||||
#
|
||||
# Existence of the path is not required
|
||||
#
|
||||
# ```coffee
|
||||
# # Project's root directory is /foo/bar
|
||||
# fs.existsSync('/foo/bar/baz') # => false
|
||||
# project.contains('/foo/bar/baz') # => true
|
||||
# ```
|
||||
#
|
||||
# * `pathToCheck` {String} path
|
||||
#
|
||||
# Returns whether the path is inside the project's root directory.
|
||||
contains: (pathToCheck) ->
|
||||
@rootDirectory?.contains(pathToCheck) ? false
|
||||
|
||||
@@ -176,91 +200,13 @@ class Project extends Model
|
||||
Section: Searching and Replacing
|
||||
###
|
||||
|
||||
# Public: Performs a search across all the files in the project.
|
||||
#
|
||||
# * `regex` {RegExp} to search with.
|
||||
# * `options` (optional) {Object} (default: {})
|
||||
# * `paths` An {Array} of glob patterns to search within
|
||||
# * `iterator` {Function} callback on each file found
|
||||
scan: (regex, options={}, iterator) ->
|
||||
if _.isFunction(options)
|
||||
iterator = options
|
||||
options = {}
|
||||
Grim.deprecate("Use atom.workspace.scan instead of atom.project.scan")
|
||||
atom.workspace.scan(regex, options, iterator)
|
||||
|
||||
deferred = Q.defer()
|
||||
|
||||
searchOptions =
|
||||
ignoreCase: regex.ignoreCase
|
||||
inclusions: options.paths
|
||||
includeHidden: true
|
||||
excludeVcsIgnores: atom.config.get('core.excludeVcsIgnoredPaths')
|
||||
exclusions: atom.config.get('core.ignoredNames')
|
||||
|
||||
# TODO: need to support all paths in @getPaths()
|
||||
task = Task.once require.resolve('./scan-handler'), @getPaths()[0], regex.source, searchOptions, ->
|
||||
deferred.resolve()
|
||||
|
||||
task.on 'scan:result-found', (result) =>
|
||||
iterator(result) unless @isPathModified(result.filePath)
|
||||
|
||||
task.on 'scan:file-error', (error) ->
|
||||
iterator(null, error)
|
||||
|
||||
if _.isFunction(options.onPathsSearched)
|
||||
task.on 'scan:paths-searched', (numberOfPathsSearched) ->
|
||||
options.onPathsSearched(numberOfPathsSearched)
|
||||
|
||||
for buffer in @getBuffers() when buffer.isModified()
|
||||
filePath = buffer.getPath()
|
||||
continue unless @contains(filePath)
|
||||
matches = []
|
||||
buffer.scan regex, (match) -> matches.push match
|
||||
iterator {filePath, matches} if matches.length > 0
|
||||
|
||||
promise = deferred.promise
|
||||
promise.cancel = ->
|
||||
task.terminate()
|
||||
deferred.resolve('cancelled')
|
||||
promise
|
||||
|
||||
# Public: Performs a replace across all the specified files in the project.
|
||||
#
|
||||
# * `regex` A {RegExp} to search with.
|
||||
# * `replacementText` Text to replace all matches of regex with
|
||||
# * `filePaths` List of file path strings to run the replace on.
|
||||
# * `iterator` A {Function} callback on each file with replacements:
|
||||
# * `options` {Object} with keys `filePath` and `replacements`
|
||||
replace: (regex, replacementText, filePaths, iterator) ->
|
||||
deferred = Q.defer()
|
||||
|
||||
openPaths = (buffer.getPath() for buffer in @getBuffers())
|
||||
outOfProcessPaths = _.difference(filePaths, openPaths)
|
||||
|
||||
inProcessFinished = !openPaths.length
|
||||
outOfProcessFinished = !outOfProcessPaths.length
|
||||
checkFinished = ->
|
||||
deferred.resolve() if outOfProcessFinished and inProcessFinished
|
||||
|
||||
unless outOfProcessFinished.length
|
||||
flags = 'g'
|
||||
flags += 'i' if regex.ignoreCase
|
||||
|
||||
task = Task.once require.resolve('./replace-handler'), outOfProcessPaths, regex.source, flags, replacementText, ->
|
||||
outOfProcessFinished = true
|
||||
checkFinished()
|
||||
|
||||
task.on 'replace:path-replaced', iterator
|
||||
task.on 'replace:file-error', (error) -> iterator(null, error)
|
||||
|
||||
for buffer in @getBuffers()
|
||||
continue unless buffer.getPath() in filePaths
|
||||
replacements = buffer.replace(regex, replacementText, iterator)
|
||||
iterator({filePath: buffer.getPath(), replacements}) if replacements
|
||||
|
||||
inProcessFinished = true
|
||||
checkFinished()
|
||||
|
||||
deferred.promise
|
||||
Grim.deprecate("Use atom.workspace.replace instead of atom.project.replace")
|
||||
atom.workspace.replace(regex, replacementText, filePaths, iterator)
|
||||
|
||||
###
|
||||
Section: Private
|
||||
|
||||
@@ -11,12 +11,13 @@ class ScopedProperties
|
||||
callback(null, new ScopedProperties(scopedPropertiesPath, scopedProperties))
|
||||
|
||||
constructor: (@path, @scopedProperties) ->
|
||||
@propertyDisposable = new CompositeDisposable
|
||||
|
||||
activate: ->
|
||||
for selector, properties of @scopedProperties
|
||||
@propertyDisposable.add atom.config.addScopedSettings(@path, selector, properties)
|
||||
atom.config.set(null, properties, scopeSelector: selector, source: @path)
|
||||
return
|
||||
|
||||
deactivate: ->
|
||||
@propertyDisposable.dispose()
|
||||
for selector of @scopedProperties
|
||||
atom.config.unset(null, scopeSelector: selector, source: @path)
|
||||
return
|
||||
|
||||
@@ -536,8 +536,6 @@ class Selection extends Model
|
||||
# of a comment.
|
||||
#
|
||||
# Removes the comment if they are currently wrapped in a comment.
|
||||
#
|
||||
# Returns an Array of the commented {Range}s.
|
||||
toggleLineComments: ->
|
||||
@editor.toggleLineCommentsForBufferRows(@getBufferRowRange()...)
|
||||
|
||||
|
||||
+10
-10
@@ -92,7 +92,7 @@ class StyleManager
|
||||
addStyleSheet: (source, params) ->
|
||||
sourcePath = params?.sourcePath
|
||||
context = params?.context
|
||||
group = params?.group
|
||||
priority = params?.priority
|
||||
|
||||
if sourcePath? and styleElement = @styleElementsBySourcePath[sourcePath]
|
||||
updated = true
|
||||
@@ -106,9 +106,9 @@ class StyleManager
|
||||
styleElement.context = context
|
||||
styleElement.setAttribute('context', context)
|
||||
|
||||
if group?
|
||||
styleElement.group = group
|
||||
styleElement.setAttribute('group', group)
|
||||
if priority?
|
||||
styleElement.priority = priority
|
||||
styleElement.setAttribute('priority', priority)
|
||||
|
||||
styleElement.textContent = source
|
||||
|
||||
@@ -120,14 +120,14 @@ class StyleManager
|
||||
new Disposable => @removeStyleElement(styleElement)
|
||||
|
||||
addStyleElement: (styleElement) ->
|
||||
{sourcePath, group} = styleElement
|
||||
{sourcePath, priority} = styleElement
|
||||
|
||||
if group?
|
||||
if priority?
|
||||
for existingElement, index in @styleElements
|
||||
if existingElement.group is group
|
||||
insertIndex = index + 1
|
||||
else
|
||||
break if insertIndex?
|
||||
if existingElement.priority > priority
|
||||
insertIndex = index
|
||||
break
|
||||
|
||||
insertIndex ?= @styleElements.length
|
||||
|
||||
@styleElements.splice(insertIndex, 0, styleElement)
|
||||
|
||||
@@ -53,13 +53,14 @@ class StylesElement extends HTMLElement
|
||||
styleElementClone = styleElement.cloneNode(true)
|
||||
styleElementClone.sourcePath = styleElement.sourcePath
|
||||
styleElementClone.context = styleElement.context
|
||||
styleElementClone.priority = styleElement.priority
|
||||
@styleElementClonesByOriginalElement.set(styleElement, styleElementClone)
|
||||
|
||||
group = styleElement.getAttribute('group')
|
||||
if group?
|
||||
priority = styleElement.priority
|
||||
if priority?
|
||||
for child in @children
|
||||
if child.getAttribute('group') is group and child.nextSibling?.getAttribute('group') isnt group
|
||||
insertBefore = child.nextSibling
|
||||
if child.priority > priority
|
||||
insertBefore = child
|
||||
break
|
||||
|
||||
@insertBefore(styleElementClone, insertBefore)
|
||||
|
||||
@@ -437,7 +437,7 @@ TextEditorComponent = React.createClass
|
||||
trackSelectionClipboard: ->
|
||||
timeoutId = null
|
||||
{editor} = @props
|
||||
writeSelectedTextToSelectionClipboard = =>
|
||||
writeSelectedTextToSelectionClipboard = ->
|
||||
return if editor.isDestroyed()
|
||||
if selectedText = editor.getSelectedText()
|
||||
# This uses ipc.send instead of clipboard.writeText because
|
||||
|
||||
@@ -67,6 +67,7 @@ class TextEditorElement extends HTMLElement
|
||||
@emitter.emit("did-attach")
|
||||
|
||||
detachedCallback: ->
|
||||
@unmountComponent()
|
||||
@emitter.emit("did-detach")
|
||||
|
||||
initialize: (model) ->
|
||||
|
||||
@@ -998,8 +998,6 @@ class TextEditor extends Model
|
||||
# Extended: Toggle line comments for rows intersecting selections.
|
||||
#
|
||||
# If the current grammar doesn't support comments, does nothing.
|
||||
#
|
||||
# Returns an {Array} of the commented {Range}s.
|
||||
toggleLineCommentsInSelection: ->
|
||||
@mutateSelectedText (selection) -> selection.toggleLineComments()
|
||||
|
||||
@@ -2838,7 +2836,7 @@ class TextEditor extends Model
|
||||
@subscribeToScopedConfigSettings()
|
||||
@unfoldAll()
|
||||
@emit 'grammar-changed'
|
||||
@emitter.emit 'did-change-grammar'
|
||||
@emitter.emit 'did-change-grammar', @getGrammar()
|
||||
|
||||
handleMarkerCreated: (marker) =>
|
||||
if marker.matchesProperties(@getSelectionMarkerAttributes())
|
||||
|
||||
@@ -219,28 +219,30 @@ class ThemeManager
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to remove the
|
||||
# required stylesheet.
|
||||
requireStylesheet: (stylesheetPath, type='bundled') ->
|
||||
requireStylesheet: (stylesheetPath) ->
|
||||
if fullPath = @resolveStylesheet(stylesheetPath)
|
||||
content = @loadStylesheet(fullPath)
|
||||
@applyStylesheet(fullPath, content, type)
|
||||
@applyStylesheet(fullPath, content)
|
||||
else
|
||||
throw new Error("Could not find a file at path '#{stylesheetPath}'")
|
||||
|
||||
unwatchUserStylesheet: ->
|
||||
@userStylesheetFile?.off()
|
||||
@userStylesheetFile = null
|
||||
@removeStylesheet(@userStylesheetPath) if @userStylesheetPath?
|
||||
@userStyleSheetDisposable?.dispose()
|
||||
@userStyleSheetDisposable = null
|
||||
|
||||
loadUserStylesheet: ->
|
||||
@unwatchUserStylesheet()
|
||||
|
||||
userStylesheetPath = atom.styles.getUserStyleSheetPath()
|
||||
return unless fs.isFileSync(userStylesheetPath)
|
||||
|
||||
@userStylesheetPath = userStylesheetPath
|
||||
@userStylesheetFile = new File(userStylesheetPath)
|
||||
@userStylesheetFile.on 'contents-changed moved removed', => @loadUserStylesheet()
|
||||
userStylesheetContents = @loadStylesheet(userStylesheetPath, true)
|
||||
@applyStylesheet(userStylesheetPath, userStylesheetContents, 'userTheme')
|
||||
|
||||
@userStyleSheetDisposable = atom.styles.addStyleSheet(userStylesheetContents, sourcePath: userStylesheetPath, priority: 2)
|
||||
|
||||
loadBaseStylesheets: ->
|
||||
@requireStylesheet('../static/bootstrap')
|
||||
@@ -291,8 +293,8 @@ class ThemeManager
|
||||
removeStylesheet: (stylesheetPath) ->
|
||||
@styleSheetDisposablesBySourcePath[stylesheetPath]?.dispose()
|
||||
|
||||
applyStylesheet: (path, text, type='bundled') ->
|
||||
@styleSheetDisposablesBySourcePath[path] = atom.styles.addStyleSheet(text, sourcePath: path, group: type)
|
||||
applyStylesheet: (path, text) ->
|
||||
@styleSheetDisposablesBySourcePath[path] = atom.styles.addStyleSheet(text, sourcePath: path)
|
||||
|
||||
stringToId: (string) ->
|
||||
string.replace(/\\/g, '/')
|
||||
|
||||
@@ -5,7 +5,7 @@ module.exports =
|
||||
class ThemePackage extends Package
|
||||
getType: -> 'theme'
|
||||
|
||||
getStylesheetType: -> 'theme'
|
||||
getStyleSheetPriority: -> 1
|
||||
|
||||
enable: ->
|
||||
atom.config.unshiftAtKeyPath('core.themes', @name)
|
||||
|
||||
@@ -65,7 +65,7 @@ class ViewRegistry
|
||||
# * `modelConstructor` Constructor {Function} for your model.
|
||||
# * `viewConstructor` (Optional) Constructor {Function} for your view. It
|
||||
# should be a subclass of `HTMLElement` (that is, your view should be a
|
||||
# DOM node) and have a `::setModel()` method which will be called
|
||||
# DOM node) and have a `::setModel()` method which will be called
|
||||
# immediately after construction. If you don't supply this property, you
|
||||
# must supply the `createView` property with a function that never returns
|
||||
# `undefined`.
|
||||
@@ -97,12 +97,14 @@ class ViewRegistry
|
||||
# ## Examples
|
||||
#
|
||||
# ### Getting An Editor Element
|
||||
#
|
||||
# ```coffee
|
||||
# textEditor = atom.workspace.getActiveTextEditor()
|
||||
# textEditorElement = atom.views.getView(textEditor)
|
||||
# ```
|
||||
#
|
||||
# ### Getting A Pane Element
|
||||
#
|
||||
# ```coffee
|
||||
# pane = atom.workspace.getActivePane()
|
||||
# paneElement = atom.views.getView(pane)
|
||||
@@ -132,7 +134,6 @@ class ViewRegistry
|
||||
if object instanceof HTMLElement
|
||||
object
|
||||
else if object?.jquery
|
||||
object[0]?.__spacePenView ?= object
|
||||
object[0]
|
||||
else if provider = @findProvider(object)
|
||||
element = provider.createView?(object)
|
||||
@@ -142,7 +143,6 @@ class ViewRegistry
|
||||
element
|
||||
else if viewConstructor = object?.getViewClass?()
|
||||
view = new viewConstructor(object)
|
||||
view[0].__spacePenView ?= view
|
||||
view[0]
|
||||
else
|
||||
throw new Error("Can't create a view for #{object.constructor.name} instance. Please register a view provider.")
|
||||
|
||||
@@ -92,7 +92,7 @@ class WindowEventHandler
|
||||
|
||||
document.addEventListener 'dragover', @onDragOver
|
||||
@subscribe new Disposable =>
|
||||
document.removeEventListener('dragover', @onKeydown)
|
||||
document.removeEventListener('dragover', @onDragOver)
|
||||
|
||||
@subscribe $(document), 'click', 'a', @openLink
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ class WorkspaceView extends View
|
||||
return atom.views.getView(atom.workspace).__spacePenView
|
||||
super
|
||||
@deprecateViewEvents()
|
||||
@attachedEditorViews = new WeakSet
|
||||
|
||||
setModel: (@model) ->
|
||||
@horizontal = @find('atom-workspace-axis.horizontal')
|
||||
@@ -95,10 +96,17 @@ class WorkspaceView extends View
|
||||
# Returns a subscription object with an `.off` method that you can call to
|
||||
# unregister the callback.
|
||||
eachEditorView: (callback) ->
|
||||
callback(editorView) for editorView in @getEditorViews()
|
||||
attachedCallback = (e, editorView) ->
|
||||
callback(editorView) unless editorView.mini
|
||||
for editorView in @getEditorViews()
|
||||
@attachedEditorViews.add(editorView)
|
||||
callback(editorView)
|
||||
|
||||
attachedCallback = (e, editorView) =>
|
||||
unless @attachedEditorViews.has(editorView)
|
||||
@attachedEditorViews.add(editorView)
|
||||
callback(editorView) unless editorView.mini
|
||||
|
||||
@on('editor:attached', attachedCallback)
|
||||
|
||||
off: => @off('editor:attached', attachedCallback)
|
||||
|
||||
# Essential: Register a function to be called for every current and future
|
||||
@@ -229,7 +237,7 @@ class WorkspaceView extends View
|
||||
when 'cursor:moved'
|
||||
deprecate('Use TextEditor::onDidChangeCursorPosition instead')
|
||||
when 'editor:attached'
|
||||
deprecate('Use TextEditor::onDidAddTextEditor instead')
|
||||
deprecate('Use Workspace::onDidAddTextEditor instead')
|
||||
when 'editor:detached'
|
||||
deprecate('Use TextEditor::onDidDestroy instead')
|
||||
when 'editor:will-be-removed'
|
||||
|
||||
@@ -14,6 +14,7 @@ PanelElement = require './panel-element'
|
||||
PanelContainer = require './panel-container'
|
||||
PanelContainerElement = require './panel-container-element'
|
||||
WorkspaceElement = require './workspace-element'
|
||||
Task = require './task'
|
||||
|
||||
# Essential: Represents the state of the user interface for the entire window.
|
||||
# An instance of this class is available via the `atom.workspace` global.
|
||||
@@ -455,6 +456,8 @@ class Workspace extends Model
|
||||
@itemOpened(item)
|
||||
pane.activateItem(item)
|
||||
pane.activate() if activatePane
|
||||
if options.initialLine? or options.initialColumn?
|
||||
item.setCursorBufferPosition?([options.initialLine, options.initialColumn])
|
||||
index = pane.getActiveItemIndex()
|
||||
@emit "uri-opened"
|
||||
@emitter.emit 'did-open', {uri, pane, item, index}
|
||||
@@ -665,6 +668,16 @@ class Workspace extends Model
|
||||
|
||||
###
|
||||
Section: Panels
|
||||
|
||||
Panels are used to display UI related to an editor window. They are placed at one of the four
|
||||
edges of the window: left, right, top or bottom. If there are multiple panels on the same window
|
||||
edge they are stacked in order of priority: higher priority is closer to the center, lower
|
||||
priority towards the edge.
|
||||
|
||||
*Note:* If your panel changes its size throughout its lifetime, consider giving it a higher
|
||||
priority, allowing fixed size panels to be closer to the edge. This allows control targets to
|
||||
remain more static for easier targeting by users that employ mice or trackpads. (See
|
||||
[atom/atom#4834](https://github.com/atom/atom/issues/4834) for discussion.)
|
||||
###
|
||||
|
||||
# Essential: Get an {Array} of all the panel items at the bottom of the editor window.
|
||||
@@ -778,3 +791,98 @@ class Workspace extends Model
|
||||
addPanel: (location, options) ->
|
||||
options ?= {}
|
||||
@panelContainers[location].addPanel(new Panel(options))
|
||||
|
||||
###
|
||||
Section: Searching and Replacing
|
||||
###
|
||||
|
||||
# Public: Performs a search across all the files in the workspace.
|
||||
#
|
||||
# * `regex` {RegExp} to search with.
|
||||
# * `options` (optional) {Object} (default: {})
|
||||
# * `paths` An {Array} of glob patterns to search within
|
||||
# * `iterator` {Function} callback on each file found
|
||||
#
|
||||
# Returns a `Promise`.
|
||||
scan: (regex, options={}, iterator) ->
|
||||
if _.isFunction(options)
|
||||
iterator = options
|
||||
options = {}
|
||||
|
||||
deferred = Q.defer()
|
||||
|
||||
searchOptions =
|
||||
ignoreCase: regex.ignoreCase
|
||||
inclusions: options.paths
|
||||
includeHidden: true
|
||||
excludeVcsIgnores: atom.config.get('core.excludeVcsIgnoredPaths')
|
||||
exclusions: atom.config.get('core.ignoredNames')
|
||||
follow: atom.config.get('core.followSymlinks')
|
||||
|
||||
# TODO: need to support all paths in @getPaths()
|
||||
task = Task.once require.resolve('./scan-handler'), atom.project.getPaths()[0], regex.source, searchOptions, ->
|
||||
deferred.resolve()
|
||||
|
||||
task.on 'scan:result-found', (result) ->
|
||||
iterator(result) unless atom.project.isPathModified(result.filePath)
|
||||
|
||||
task.on 'scan:file-error', (error) ->
|
||||
iterator(null, error)
|
||||
|
||||
if _.isFunction(options.onPathsSearched)
|
||||
task.on 'scan:paths-searched', (numberOfPathsSearched) ->
|
||||
options.onPathsSearched(numberOfPathsSearched)
|
||||
|
||||
for buffer in atom.project.getBuffers() when buffer.isModified()
|
||||
filePath = buffer.getPath()
|
||||
continue unless atom.project.contains(filePath)
|
||||
matches = []
|
||||
buffer.scan regex, (match) -> matches.push match
|
||||
iterator {filePath, matches} if matches.length > 0
|
||||
|
||||
promise = deferred.promise
|
||||
promise.cancel = ->
|
||||
task.terminate()
|
||||
deferred.resolve('cancelled')
|
||||
promise
|
||||
|
||||
# Public: Performs a replace across all the specified files in the project.
|
||||
#
|
||||
# * `regex` A {RegExp} to search with.
|
||||
# * `replacementText` Text to replace all matches of regex with
|
||||
# * `filePaths` List of file path strings to run the replace on.
|
||||
# * `iterator` A {Function} callback on each file with replacements:
|
||||
# * `options` {Object} with keys `filePath` and `replacements`
|
||||
#
|
||||
# Returns a `Promise`.
|
||||
replace: (regex, replacementText, filePaths, iterator) ->
|
||||
deferred = Q.defer()
|
||||
|
||||
openPaths = (buffer.getPath() for buffer in atom.project.getBuffers())
|
||||
outOfProcessPaths = _.difference(filePaths, openPaths)
|
||||
|
||||
inProcessFinished = !openPaths.length
|
||||
outOfProcessFinished = !outOfProcessPaths.length
|
||||
checkFinished = ->
|
||||
deferred.resolve() if outOfProcessFinished and inProcessFinished
|
||||
|
||||
unless outOfProcessFinished.length
|
||||
flags = 'g'
|
||||
flags += 'i' if regex.ignoreCase
|
||||
|
||||
task = Task.once require.resolve('./replace-handler'), outOfProcessPaths, regex.source, flags, replacementText, ->
|
||||
outOfProcessFinished = true
|
||||
checkFinished()
|
||||
|
||||
task.on 'replace:path-replaced', iterator
|
||||
task.on 'replace:file-error', (error) -> iterator(null, error)
|
||||
|
||||
for buffer in atom.project.getBuffers()
|
||||
continue unless buffer.getPath() in filePaths
|
||||
replacements = buffer.replace(regex, replacementText, iterator)
|
||||
iterator({filePath: buffer.getPath(), replacements}) if replacements
|
||||
|
||||
inProcessFinished = true
|
||||
checkFinished()
|
||||
|
||||
deferred.promise
|
||||
|
||||
+8
-16
@@ -26,6 +26,7 @@
|
||||
.make-icon(beer);
|
||||
.make-icon(book);
|
||||
.make-icon(bookmark);
|
||||
.make-icon(briefcase);
|
||||
.make-icon(broadcast);
|
||||
.make-icon(browser);
|
||||
.make-icon(bug);
|
||||
@@ -37,6 +38,7 @@
|
||||
.make-icon(chevron-right);
|
||||
.make-icon(chevron-up);
|
||||
.make-icon(circle-slash);
|
||||
.make-icon(circuit-board);
|
||||
.make-icon(clippy);
|
||||
.make-icon(clock);
|
||||
.make-icon(cloud-download);
|
||||
@@ -114,6 +116,7 @@
|
||||
.make-icon(jump-up);
|
||||
.make-icon(key);
|
||||
.make-icon(keyboard);
|
||||
.make-icon(law);
|
||||
.make-icon(light-bulb);
|
||||
.make-icon(link);
|
||||
.make-icon(link-external);
|
||||
@@ -123,36 +126,26 @@
|
||||
.make-icon(lock);
|
||||
.make-icon(log-in);
|
||||
.make-icon(log-out);
|
||||
.make-icon(logo-apps);
|
||||
.make-icon(logo-atom);
|
||||
.make-icon(logo-chat);
|
||||
.make-icon(logo-gist);
|
||||
.make-icon(logo-github);
|
||||
.make-icon(logo-octicons);
|
||||
.make-icon(logo-talks);
|
||||
.make-icon(mail);
|
||||
.make-icon(mail-read);
|
||||
.make-icon(mail-reply);
|
||||
.make-icon(mark-facebook);
|
||||
.make-icon(mark-github);
|
||||
.make-icon(mark-github-detail);
|
||||
.make-icon(mark-google);
|
||||
.make-icon(mark-twitter);
|
||||
.make-icon(markdown);
|
||||
.make-icon(megaphone);
|
||||
.make-icon(mention);
|
||||
.make-icon(microscope);
|
||||
.make-icon(milestone);
|
||||
.make-icon(mirror);
|
||||
.make-icon(mirror-private);
|
||||
.make-icon(mirror-public);
|
||||
.make-icon(mortar-board);
|
||||
.make-icon(move-down);
|
||||
.make-icon(move-left);
|
||||
.make-icon(move-right);
|
||||
.make-icon(move-up);
|
||||
.make-icon(mute);
|
||||
.make-icon(mute-video);
|
||||
.make-icon(no-newline);
|
||||
.make-icon(node-js);
|
||||
.make-icon(octoface);
|
||||
.make-icon(organization);
|
||||
.make-icon(package);
|
||||
@@ -161,12 +154,12 @@
|
||||
.make-icon(person);
|
||||
.make-icon(person-add);
|
||||
.make-icon(person-follow);
|
||||
.make-icon(person-remove);
|
||||
.make-icon(pin);
|
||||
.make-icon(playback-fast-forward);
|
||||
.make-icon(playback-pause);
|
||||
.make-icon(playback-play);
|
||||
.make-icon(playback-rewind);
|
||||
.make-icon(plug);
|
||||
.make-icon(plus);
|
||||
.make-icon(podium);
|
||||
.make-icon(primitive-dot);
|
||||
@@ -187,7 +180,6 @@
|
||||
.make-icon(repo-push);
|
||||
.make-icon(repo-sync);
|
||||
.make-icon(rocket);
|
||||
.make-icon(rohan);
|
||||
.make-icon(rss);
|
||||
.make-icon(ruby);
|
||||
.make-icon(screen-full);
|
||||
@@ -196,6 +188,8 @@
|
||||
.make-icon(search-save);
|
||||
.make-icon(server);
|
||||
.make-icon(settings);
|
||||
.make-icon(sign-in);
|
||||
.make-icon(sign-out);
|
||||
.make-icon(split);
|
||||
.make-icon(squirrel);
|
||||
.make-icon(star);
|
||||
@@ -216,10 +210,8 @@
|
||||
.make-icon(triangle-left);
|
||||
.make-icon(triangle-right);
|
||||
.make-icon(triangle-up);
|
||||
.make-icon(trollface);
|
||||
.make-icon(unfold);
|
||||
.make-icon(unmute);
|
||||
.make-icon(unmute-video);
|
||||
.make-icon(versions);
|
||||
.make-icon(x);
|
||||
.make-icon(zap);
|
||||
|
||||
Arquivo normal → Arquivo executável
BIN
Arquivo binário não exibido.
@@ -13,6 +13,7 @@
|
||||
@beer: "\f069";
|
||||
@book: "\f007";
|
||||
@bookmark: "\f07b";
|
||||
@briefcase: "\f0d3";
|
||||
@broadcast: "\f048";
|
||||
@browser: "\f0c5";
|
||||
@bug: "\f091";
|
||||
@@ -24,6 +25,7 @@
|
||||
@chevron-right: "\f078";
|
||||
@chevron-up: "\f0a2";
|
||||
@circle-slash: "\f084";
|
||||
@circuit-board: "\f0d6";
|
||||
@clippy: "\f035";
|
||||
@clock: "\f046";
|
||||
@cloud-download: "\f00b";
|
||||
@@ -31,7 +33,7 @@
|
||||
@code: "\f05f";
|
||||
@color-mode: "\f065";
|
||||
@comment: "\f02b";
|
||||
@comment-add: "\f06f";
|
||||
@comment-add: "\f02b";
|
||||
@comment-discussion: "\f04f";
|
||||
@credit-card: "\f045";
|
||||
@dash: "\f0ca";
|
||||
@@ -49,13 +51,13 @@
|
||||
@diff-renamed: "\f06e";
|
||||
@ellipsis: "\f09a";
|
||||
@eye: "\f04e";
|
||||
@eye-unwatch: "\f01e";
|
||||
@eye-watch: "\f01d";
|
||||
@file-add: "\f086";
|
||||
@eye-unwatch: "\f04e";
|
||||
@eye-watch: "\f04e";
|
||||
@file-add: "\f05d";
|
||||
@file-binary: "\f094";
|
||||
@file-code: "\f010";
|
||||
@file-directory: "\f016";
|
||||
@file-directory-create: "\f095";
|
||||
@file-directory-create: "\f05d";
|
||||
@file-media: "\f012";
|
||||
@file-pdf: "\f014";
|
||||
@file-submodule: "\f017";
|
||||
@@ -68,19 +70,19 @@
|
||||
@gear: "\f02f";
|
||||
@gift: "\f042";
|
||||
@gist: "\f00e";
|
||||
@gist-fork: "\f079";
|
||||
@gist-new: "\f07a";
|
||||
@gist-private: "\f00f";
|
||||
@gist-fork: "\f002";
|
||||
@gist-new: "\f05d";
|
||||
@gist-private: "\f06a";
|
||||
@gist-secret: "\f08c";
|
||||
@git-branch: "\f020";
|
||||
@git-branch-create: "\f098";
|
||||
@git-branch-delete: "\f09b";
|
||||
@git-branch-create: "\f020";
|
||||
@git-branch-delete: "\f020";
|
||||
@git-commit: "\f01f";
|
||||
@git-compare: "\f0ac";
|
||||
@git-fork-private: "\f021";
|
||||
@git-fork-private: "\f06a";
|
||||
@git-merge: "\f023";
|
||||
@git-pull-request: "\f009";
|
||||
@git-pull-request-abandoned: "\f090";
|
||||
@git-pull-request-abandoned: "\f009";
|
||||
@globe: "\f0b6";
|
||||
@graph: "\f043";
|
||||
@heart: "\2665";
|
||||
@@ -101,6 +103,7 @@
|
||||
@jump-up: "\f073";
|
||||
@key: "\f049";
|
||||
@keyboard: "\f00d";
|
||||
@law: "\f0d8";
|
||||
@light-bulb: "\f000";
|
||||
@link: "\f05c";
|
||||
@link-external: "\f07f";
|
||||
@@ -110,50 +113,40 @@
|
||||
@lock: "\f06a";
|
||||
@log-in: "\f036";
|
||||
@log-out: "\f032";
|
||||
@logo-apps: "\f0b3";
|
||||
@logo-atom: "\f0b7";
|
||||
@logo-chat: "\f0b4";
|
||||
@logo-gist: "\f0ad";
|
||||
@logo-github: "\f092";
|
||||
@logo-octicons: "\f0ab";
|
||||
@logo-talks: "\f0b5";
|
||||
@mail: "\f03b";
|
||||
@mail-read: "\f03c";
|
||||
@mail-reply: "\f051";
|
||||
@mark-facebook: "\f0ce";
|
||||
@mark-github: "\f00a";
|
||||
@mark-github-detail: "\f093";
|
||||
@mark-google: "\f0cd";
|
||||
@mark-twitter: "\f0ae";
|
||||
@markdown: "\f0c9";
|
||||
@megaphone: "\f077";
|
||||
@mention: "\f0be";
|
||||
@microscope: "\f089";
|
||||
@milestone: "\f075";
|
||||
@mirror-private: "\f025";
|
||||
@mirror: "\f024";
|
||||
@mirror-private: "\f06a";
|
||||
@mirror-public: "\f024";
|
||||
@mortar-board: "\f0d7";
|
||||
@move-down: "\f0a8";
|
||||
@move-left: "\f074";
|
||||
@move-right: "\f0a9";
|
||||
@move-up: "\f0a7";
|
||||
@mute: "\f080";
|
||||
@mute-video: "\f0b8";
|
||||
@no-newline: "\f09c";
|
||||
@node-js: "\f0c3";
|
||||
@octoface: "\f008";
|
||||
@organization: "\f037";
|
||||
@package: "\f0c4";
|
||||
@paintcan: "\f0d1";
|
||||
@pencil: "\f058";
|
||||
@person: "\f018";
|
||||
@person-add: "\f01a";
|
||||
@person-follow: "\f01c";
|
||||
@person-remove: "\f01b";
|
||||
@person-add: "\f018";
|
||||
@person-follow: "\f018";
|
||||
@pin: "\f041";
|
||||
@playback-fast-forward: "\f0bd";
|
||||
@playback-pause: "\f0bb";
|
||||
@playback-play: "\f0bf";
|
||||
@playback-rewind: "\f0bc";
|
||||
@plug: "\f0d4";
|
||||
@plus: "\f05d";
|
||||
@podium: "\f0af";
|
||||
@primitive-dot: "\f052";
|
||||
@@ -163,37 +156,38 @@
|
||||
@question: "\f02c";
|
||||
@quote: "\f063";
|
||||
@radio-tower: "\f030";
|
||||
@remove-close: "\f050";
|
||||
@remove-close: "\f081";
|
||||
@repo: "\f001";
|
||||
@repo-clone: "\f04c";
|
||||
@repo-create: "\f003";
|
||||
@repo-delete: "\f004";
|
||||
@repo-create: "\f05d";
|
||||
@repo-delete: "\f001";
|
||||
@repo-force-push: "\f04a";
|
||||
@repo-forked: "\f002";
|
||||
@repo-pull: "\f006";
|
||||
@repo-push: "\f005";
|
||||
@repo-sync: "\f04b";
|
||||
@repo-sync: "\f087";
|
||||
@rocket: "\f033";
|
||||
@rohan: "\f022";
|
||||
@rss: "\f034";
|
||||
@ruby: "\f047";
|
||||
@screen-full: "\f066";
|
||||
@screen-normal: "\f067";
|
||||
@search: "\f02e";
|
||||
@search-save: "\f0cb";
|
||||
@search-save: "\f02e";
|
||||
@server: "\f097";
|
||||
@settings: "\f07c";
|
||||
@sign-in: "\f036";
|
||||
@sign-out: "\f032";
|
||||
@split: "\f0c6";
|
||||
@squirrel: "\f0b2";
|
||||
@star: "\f02a";
|
||||
@star-add: "\f082";
|
||||
@star-delete: "\f083";
|
||||
@star-add: "\f02a";
|
||||
@star-delete: "\f02a";
|
||||
@steps: "\f0c7";
|
||||
@stop: "\f08f";
|
||||
@sync: "\f087";
|
||||
@tag: "\f015";
|
||||
@tag-add: "\f054";
|
||||
@tag-remove: "\f055";
|
||||
@tag-add: "\f015";
|
||||
@tag-remove: "\f015";
|
||||
@telescope: "\f088";
|
||||
@terminal: "\f0c8";
|
||||
@three-bars: "\f05e";
|
||||
@@ -203,10 +197,8 @@
|
||||
@triangle-left: "\f044";
|
||||
@triangle-right: "\f05a";
|
||||
@triangle-up: "\f0aa";
|
||||
@trollface: "\f029";
|
||||
@unfold: "\f039";
|
||||
@unmute: "\f0ba";
|
||||
@unmute-video: "\f0b9";
|
||||
@versions: "\f064";
|
||||
@x: "\f081";
|
||||
@zap: "\26A1";
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário