mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-12-29 09:34:58 +03:00
Merge remote-tracking branch 'origin/master' into cj-add-flash-error
This commit is contained in:
commit
3b525302b0
@ -28,6 +28,13 @@
|
||||
* Class methods (methods starting with a `@`)
|
||||
* Instance variables
|
||||
* Instance methods
|
||||
* Be ware of platform differences
|
||||
* The home directory is `process.env.USERPROFILE` on Windows, while on OS X
|
||||
and Linux it's `process.env.HOME`
|
||||
* Path separator is `\` on Windows, and is `/` on OS X and Linux, so use
|
||||
`path.join` to concatenate filenames.
|
||||
* Temporary directory is not `/tmp` on Windows, use `os.tmpdir()` when
|
||||
possible
|
||||
|
||||
## Philosophy
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
|
||||
fm = require 'json-front-matter'
|
||||
_ = require 'underscore-plus'
|
||||
@ -9,7 +10,8 @@ packageJson = require './package.json'
|
||||
module.exports = (grunt) ->
|
||||
appName = 'Atom.app'
|
||||
[major, minor, patch] = packageJson.version.split('.')
|
||||
buildDir = grunt.option('build-dir') ? '/tmp/atom-build'
|
||||
tmpDir = if process.platform is 'win32' then os.tmpdir() else '/tmp'
|
||||
buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'atom-build')
|
||||
shellAppDir = path.join(buildDir, appName)
|
||||
contentsDir = path.join(shellAppDir, 'Contents')
|
||||
appDir = path.join(contentsDir, 'Resources', 'app')
|
||||
|
@ -35,23 +35,30 @@ a few things before starting:
|
||||
## Creating a Minimal Syntax Theme
|
||||
|
||||
1. Open the Command Palette (`cmd-p`)
|
||||
1. Search for `Package Generator: Generate Theme` and select it.
|
||||
1. Choose a name for the folder which will contain your theme.
|
||||
1. Search for `Package Generator: Generate Syntax Theme` and select it.
|
||||
1. Choose a name for your theme. A folder will be created with this name.
|
||||
1. Press enter to create your theme. After creation, your theme will be
|
||||
installed and enabled.
|
||||
1. An Atom window will open with your newly created theme.
|
||||
1. Open `package.json` and update the relevant parts.
|
||||
1. Open `stylesheets/colors.less` to change the various colors variables which
|
||||
have been already been defined.
|
||||
1. Open `stylesheets/base.less` and modify the various syntax CSS selectors
|
||||
that have been already been defined.
|
||||
1. When you're ready update the `README.md` and include an example screenshot
|
||||
1. When you're ready, update the `README.md` and include an example screenshot
|
||||
of your new theme in action.
|
||||
1. Reload Atom (`cmd-r`) and your theme should now be applied.
|
||||
1. Reload atom (`cmd-r`) to see changes you made reflected in your Atom window.
|
||||
1. Look in the theme settings, your new theme should be show in the enabled themes section
|
||||
![themesettings-img]
|
||||
1. Open a terminal to your new theme directory; it should be in `~/.atom/packages/<my-name>`.
|
||||
1. To publish, initialize a git repository, push to GitHub, and run
|
||||
`apm publish`.
|
||||
|
||||
Want to make edits and have them immediately show up without reloading? Open a
|
||||
development window (__View > Developer > Open in Dev Mode__ menu) to the
|
||||
directory of your choice — even the new theme itself. Then just edit away!
|
||||
Changes will be instantly reflected in the editor without having to reload.
|
||||
|
||||
## Interface Themes
|
||||
|
||||
There are only two differences between interface and syntax themes - what
|
||||
@ -65,7 +72,7 @@ To create a UI theme, do the following:
|
||||
1. [atom-dark-ui]
|
||||
1. [atom-light-ui]
|
||||
1. Open a terminal in the forked theme's directory
|
||||
1. Open your new theme in a Dev Mode Atom window (either run `atom -d .` in the terminal or use `cmd-shift-o` from atom)
|
||||
1. Open your new theme in a Dev Mode Atom window (run `atom -d .` in the terminal or use the __View > Developer > Open in Dev Mode__ menu)
|
||||
1. Change the name of the theme in the theme's `package.json` file
|
||||
1. Run `apm link` to tell Atom about your new theme
|
||||
1. Reload Atom (`cmd-r`)
|
||||
@ -83,7 +90,7 @@ Reloading via `cmd-r` after you make changes to your theme less than ideal. Atom
|
||||
supports [live updating][livereload] of styles on Dev Mode Atom windows.
|
||||
|
||||
1. Open your theme directory in a dev window by either using the
|
||||
__File > Open in Dev Mode__ menu or the `cmd-shift-o` shortcut
|
||||
__View > Developer > Open in Dev Mode__ menu or the `cmd-shift-o` shortcut
|
||||
1. Make a change to your theme file and save — your change should be
|
||||
immediately applied!
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
{Document, Point, Range, Site} = require 'telepath'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
#TODO Remove once all packages have been updated
|
||||
_.nextTick = setImmediate
|
||||
|
||||
module.exports =
|
||||
_: _
|
||||
BufferedNodeProcess: require '../src/buffered-node-process'
|
||||
|
@ -5,16 +5,24 @@
|
||||
'meta-shift-down': 'core:select-to-bottom'
|
||||
|
||||
'.editor':
|
||||
'meta-left': 'editor:move-to-first-character-of-line'
|
||||
'meta-right': 'editor:move-to-end-of-line'
|
||||
'meta-left': 'editor:move-to-beginning-of-line'
|
||||
'alt-left': 'editor:move-to-beginning-of-word'
|
||||
'alt-right': 'editor:move-to-end-of-word'
|
||||
'meta-shift-left': 'editor:select-to-beginning-of-line'
|
||||
'meta-shift-left': 'editor:select-to-first-character-of-line'
|
||||
'meta-shift-right': 'editor:select-to-end-of-line'
|
||||
'alt-shift-left': 'editor:select-to-beginning-of-word'
|
||||
'alt-shift-right': 'editor:select-to-end-of-word'
|
||||
|
||||
'home': 'editor:move-to-first-character-of-line'
|
||||
'end': 'editor:move-to-end-of-line'
|
||||
'shift-home': 'editor:select-to-first-character-of-line'
|
||||
'shift-end': 'editor:select-to-end-of-line'
|
||||
|
||||
'alt-left': 'editor:move-to-previous-word-boundary'
|
||||
'alt-right': 'editor:move-to-next-word-boundary'
|
||||
'alt-shift-left': 'editor:select-to-previous-word-boundary'
|
||||
'alt-shift-right': 'editor:select-to-next-word-boundary'
|
||||
|
||||
'alt-backspace': 'editor:backspace-to-beginning-of-word'
|
||||
'meta-backspace': 'editor:backspace-to-beginning-of-line'
|
||||
|
||||
'alt-delete': 'editor:delete-to-end-of-word'
|
||||
'ctrl-t': 'editor:transpose'
|
||||
'ctrl-A': 'editor:select-to-first-character-of-line'
|
||||
|
@ -30,6 +30,7 @@
|
||||
'delete': 'core:delete'
|
||||
'meta-z': 'core:undo'
|
||||
'meta-Z': 'core:redo'
|
||||
'meta-y': 'core:redo'
|
||||
'meta-x': 'core:cut'
|
||||
'meta-c': 'core:copy'
|
||||
'meta-v': 'core:paste'
|
||||
|
@ -1,5 +1,5 @@
|
||||
'.editor':
|
||||
'meta-d': 'editor:delete-line'
|
||||
'ctrl-K': 'editor:delete-line'
|
||||
'ctrl-W': 'editor:select-word'
|
||||
'meta-alt-p': 'editor:log-cursor-scope'
|
||||
'meta-u': 'editor:upper-case'
|
||||
@ -38,7 +38,7 @@
|
||||
'ctrl-meta-up': 'editor:move-line-up'
|
||||
'ctrl-meta-down': 'editor:move-line-down'
|
||||
'meta-D': 'editor:duplicate-line'
|
||||
'ctrl-J': 'editor:join-line'
|
||||
'meta-j': 'editor:join-line'
|
||||
'meta-<': 'editor:scroll-to-cursor'
|
||||
|
||||
'.editor.mini':
|
||||
|
@ -45,9 +45,96 @@
|
||||
{ label: 'Paste', command: 'core:paste' }
|
||||
{ label: 'Select All', command: 'core:select-all' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Toggle Comments', command: 'editor:toggle-line-comments' }
|
||||
{
|
||||
label: 'Lines',
|
||||
submenu: [
|
||||
{ label: 'Indent', command: 'editor:indent-selected-rows' }
|
||||
{ label: 'Outdent', command: 'editor:outdent-selected-rows' }
|
||||
{ label: 'Auto Indent', command: 'editor:auto-indent' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Move Line Up', command: 'editor:move-line-up' }
|
||||
{ label: 'Move Line Down', command: 'editor:move-line-down' }
|
||||
{ label: 'Duplicate Line', command: 'editor:duplicate-line' }
|
||||
{ label: 'Delete Line', command: 'editor:delete-line' }
|
||||
{ label: 'Join Lines', command: 'editor:join-line' }
|
||||
]
|
||||
}
|
||||
{
|
||||
label: 'Text',
|
||||
submenu: [
|
||||
{ label: 'Upper Case', command: 'editor:upper-case' }
|
||||
{ label: 'Lower Case', command: 'editor:lower-case' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Delete to End of Word', command: 'editor:delete-to-end-of-word' }
|
||||
{ label: 'Delete Line', command: 'editor:delete-line' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Transpose', command: 'editor:transpose' }
|
||||
]
|
||||
}
|
||||
{
|
||||
label: 'Folding',
|
||||
submenu: [
|
||||
{ label: 'Fold', command: 'editor:fold-current-row' }
|
||||
{ label: 'Unfold', command: 'editor:unfold-current-row' }
|
||||
{ label: 'Unfold All', command: 'editor:unfold-all' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Fold All', command: 'editor:fold-all' }
|
||||
{ label: 'Fold Level 1', command: 'editor:fold-at-indent-level-1' }
|
||||
{ label: 'Fold Level 2', command: 'editor:fold-at-indent-level-2' }
|
||||
{ label: 'Fold Level 3', command: 'editor:fold-at-indent-level-3' }
|
||||
{ label: 'Fold Level 4', command: 'editor:fold-at-indent-level-4' }
|
||||
{ label: 'Fold Level 5', command: 'editor:fold-at-indent-level-5' }
|
||||
{ label: 'Fold Level 6', command: 'editor:fold-at-indent-level-6' }
|
||||
{ label: 'Fold Level 7', command: 'editor:fold-at-indent-level-7' }
|
||||
{ label: 'Fold Level 8', command: 'editor:fold-at-indent-level-8' }
|
||||
{ label: 'Fold Level 9', command: 'editor:fold-at-indent-level-9' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
{
|
||||
label: 'Selection'
|
||||
submenu: [
|
||||
{ label: 'Add Selection Above', command: 'editor:add-selection-above' }
|
||||
{ label: 'Add Selection Below', command: 'editor:add-selection-below' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Select to Top', command: 'core:select-to-top' }
|
||||
{ label: 'Select to Bottom', command: 'core:select-to-bottom' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Select Line', command: 'editor:select-line' }
|
||||
{ label: 'Select Word', command: 'editor:select-word' }
|
||||
{ label: 'Select to Beginning of Word', command: 'editor:select-to-beginning-of-word' }
|
||||
{ label: 'Select to Beginning of Line', command: 'editor:select-to-beginning-of-line' }
|
||||
{ label: 'Select to First Character of Line', command: 'editor:select-to-first-character-of-line' }
|
||||
{ label: 'Select to End of Word', command: 'editor:select-to-end-of-word' }
|
||||
{ label: 'Select to End of Line', command: 'editor:select-to-end-of-line' }
|
||||
]
|
||||
}
|
||||
|
||||
{
|
||||
label: 'Movement'
|
||||
submenu: [
|
||||
{ label: 'Move to Top', command: 'core:move-to-top' }
|
||||
{ label: 'Move to Bottom', command: 'core:move-to-bottom' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Move to Beginning of Line', command: 'editor:move-to-beginning-of-line' }
|
||||
{ label: 'Move to First Character of Line', command: 'editor:move-to-first-character-of-line' }
|
||||
{ label: 'Move to End of Line', command: 'editor:move-to-end-of-line' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Move to Beginning of Word', command: 'editor:move-to-beginning-of-word' }
|
||||
{ label: 'Move to End of Word', command: 'editor:move-to-end-of-word' }
|
||||
{ label: 'Move to Next Word', command: 'editor:move-to-next-word-boundary' }
|
||||
{ label: 'Move to Previous Word', command: 'editor:move-to-previous-word-boundary' }
|
||||
]
|
||||
}
|
||||
|
||||
{
|
||||
label: 'Find'
|
||||
submenu: []
|
||||
}
|
||||
|
||||
{
|
||||
label: 'View'
|
||||
submenu: [
|
||||
@ -67,6 +154,16 @@
|
||||
]
|
||||
}
|
||||
|
||||
{
|
||||
label: 'Collaboration'
|
||||
submenu: []
|
||||
}
|
||||
|
||||
{
|
||||
label: 'Packages'
|
||||
submenu: []
|
||||
}
|
||||
|
||||
{
|
||||
label: 'Window'
|
||||
submenu: [
|
||||
|
163
package.json
163
package.json
@ -9,7 +9,7 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/atom/atom/issues"
|
||||
},
|
||||
"atomShellVersion": "0.6.3",
|
||||
"atomShellVersion": "0.6.4",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"bootstrap": "git://github.com/twbs/bootstrap.git#v3.0.0",
|
||||
@ -39,86 +39,7 @@
|
||||
"space-pen": "2.0.0",
|
||||
"telepath": "0.8.1",
|
||||
"temp": "0.5.0",
|
||||
"underscore-plus": "0.2.0",
|
||||
|
||||
"atom-light-ui": "0.4.0",
|
||||
"atom-light-syntax": "0.4.0",
|
||||
"atom-dark-ui": "0.4.0",
|
||||
"atom-dark-syntax": "0.4.0",
|
||||
"base16-tomorrow-dark-theme": "0.2.0",
|
||||
"solarized-dark-syntax": "0.3.0",
|
||||
|
||||
"archive-view": "0.11.0",
|
||||
"autocomplete": "0.10.0",
|
||||
"autoflow": "0.5.0",
|
||||
"bookmarks": "0.8.0",
|
||||
"bracket-matcher": "0.7.0",
|
||||
"collaboration": "0.26.0",
|
||||
"command-logger": "0.6.0",
|
||||
"command-palette": "0.5.0",
|
||||
"dev-live-reload": "0.8.0",
|
||||
"editor-stats": "0.5.0",
|
||||
"exception-reporting": "0.4.0",
|
||||
"find-and-replace": "0.29.0",
|
||||
"fuzzy-finder": "0.15.0",
|
||||
"gfm": "0.5.0",
|
||||
"git-diff": "0.11.0",
|
||||
"gists": "0.5.0",
|
||||
"github-sign-in": "0.8.0",
|
||||
"go-to-line": "0.8.0",
|
||||
"grammar-selector": "0.7.0",
|
||||
"image-view": "0.7.0",
|
||||
"link": "0.6.0",
|
||||
"markdown-preview": "0.9.0",
|
||||
"metrics": "0.8.0",
|
||||
"package-generator": "0.13.0",
|
||||
"release-notes": "0.8.0",
|
||||
"settings-view": "0.29.0",
|
||||
"snippets": "0.10.0",
|
||||
"spell-check": "0.7.0",
|
||||
"status-bar": "0.14.0",
|
||||
"styleguide": "0.9.0",
|
||||
"symbols-view": "0.12.0",
|
||||
"tabs": "0.7.0",
|
||||
"terminal": "0.13.0",
|
||||
"timecop": "0.6.0",
|
||||
"to-the-hubs": "0.8.0",
|
||||
"toml": "0.3.0",
|
||||
"tree-view": "0.19.0",
|
||||
"whitespace": "0.7.0",
|
||||
"wrap-guide": "0.4.0",
|
||||
|
||||
"c-tmbundle": "1.0.0",
|
||||
"coffee-script-tmbundle": "1.0.0",
|
||||
"css-tmbundle": "1.0.0",
|
||||
"git-tmbundle": "1.0.0",
|
||||
"go-tmbundle": "1.0.0",
|
||||
"html-tmbundle": "1.0.0",
|
||||
"hyperlink-helper-tmbundle": "1.0.0",
|
||||
"java-tmbundle": "1.0.0",
|
||||
"javascript-tmbundle": "2.0.0",
|
||||
"json-tmbundle": "1.0.0",
|
||||
"less-tmbundle": "1.0.0",
|
||||
"make-tmbundle": "1.0.0",
|
||||
"mustache-tmbundle": "1.0.0",
|
||||
"objective-c-tmbundle": "1.0.0",
|
||||
"pegjs-tmbundle": "1.0.0",
|
||||
"perl-tmbundle": "1.0.0",
|
||||
"php-tmbundle": "1.0.0",
|
||||
"property-list-tmbundle": "1.0.0",
|
||||
"puppet-textmate-tmbundle": "1.0.0",
|
||||
"python-tmbundle": "1.0.0",
|
||||
"ruby-on-rails-tmbundle": "1.0.0",
|
||||
"ruby-tmbundle": "1.0.0",
|
||||
"sass-tmbundle": "1.0.0",
|
||||
"shellscript-tmbundle": "1.0.0",
|
||||
"source-tmbundle": "1.0.0",
|
||||
"sql-tmbundle": "1.0.0",
|
||||
"text-tmbundle": "1.0.0",
|
||||
"textmate-clojure": "1.0.0",
|
||||
"todo-tmbundle": "1.0.0",
|
||||
"xml-tmbundle": "1.0.0",
|
||||
"yaml-tmbundle": "1.0.0"
|
||||
"underscore-plus": "0.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"biscotto": "0.0.17",
|
||||
@ -141,6 +62,86 @@
|
||||
"jasmine-node": "git://github.com/kevinsawicki/jasmine-node.git#short-stacks",
|
||||
"request": "~2.27.0"
|
||||
},
|
||||
"packageDependencies" : {
|
||||
"atom-light-ui": "0.5.0",
|
||||
"atom-light-syntax": "0.5.0",
|
||||
"atom-dark-ui": "0.5.0",
|
||||
"atom-dark-syntax": "0.5.0",
|
||||
"base16-tomorrow-dark-theme": "0.2.0",
|
||||
"solarized-dark-syntax": "0.3.0",
|
||||
|
||||
"archive-view": "0.11.0",
|
||||
"autocomplete": "0.11.0",
|
||||
"autoflow": "0.5.0",
|
||||
"bookmarks": "0.8.0",
|
||||
"bracket-matcher": "0.7.0",
|
||||
"collaboration": "0.28.0",
|
||||
"command-logger": "0.6.0",
|
||||
"command-palette": "0.5.0",
|
||||
"dev-live-reload": "0.11.0",
|
||||
"editor-stats": "0.5.0",
|
||||
"exception-reporting": "0.5.0",
|
||||
"find-and-replace": "0.29.0",
|
||||
"fuzzy-finder": "0.15.0",
|
||||
"gfm": "0.5.0",
|
||||
"git-diff": "0.12.0",
|
||||
"gists": "0.5.0",
|
||||
"github-sign-in": "0.8.0",
|
||||
"go-to-line": "0.8.0",
|
||||
"grammar-selector": "0.8.0",
|
||||
"image-view": "0.7.0",
|
||||
"link": "0.7.0",
|
||||
"markdown-preview": "0.12.0",
|
||||
"metrics": "0.8.0",
|
||||
"package-generator": "0.14.0",
|
||||
"release-notes": "0.8.0",
|
||||
"settings-view": "0.31.1",
|
||||
"snippets": "0.11.0",
|
||||
"spell-check": "0.8.0",
|
||||
"status-bar": "0.15.0",
|
||||
"styleguide": "0.9.0",
|
||||
"symbols-view": "0.13.0",
|
||||
"tabs": "0.7.0",
|
||||
"terminal": "0.14.0",
|
||||
"timecop": "0.7.0",
|
||||
"to-the-hubs": "0.8.0",
|
||||
"toml": "0.3.0",
|
||||
"tree-view": "0.20.0",
|
||||
"whitespace": "0.7.0",
|
||||
"wrap-guide": "0.4.0",
|
||||
|
||||
"language-c": "0.1.0",
|
||||
"language-clojure": "0.1.0",
|
||||
"language-coffee-script": "0.1.0",
|
||||
"language-css": "0.1.0",
|
||||
"language-git": "0.1.0",
|
||||
"language-go": "0.2.0",
|
||||
"language-html": "0.1.0",
|
||||
"language-hyperlink": "0.2.0",
|
||||
"language-java": "0.1.0",
|
||||
"language-javascript": "0.1.0",
|
||||
"language-json": "0.1.0",
|
||||
"language-less": "0.1.0",
|
||||
"language-make": "0.1.0",
|
||||
"language-mustache": "0.1.0",
|
||||
"language-objective-c": "0.1.0",
|
||||
"language-pegjs": "0.1.0",
|
||||
"language-perl": "0.1.0",
|
||||
"language-php": "0.1.0",
|
||||
"language-property-list": "0.2.0",
|
||||
"language-puppet": "0.1.0",
|
||||
"language-python": "0.1.0",
|
||||
"language-ruby-on-rails": "0.2.0",
|
||||
"language-ruby": "0.2.0",
|
||||
"language-sass": "0.2.0",
|
||||
"language-shellscript": "0.1.0",
|
||||
"language-source": "0.1.0",
|
||||
"language-sql": "0.1.0",
|
||||
"language-text": "0.1.0",
|
||||
"language-todo": "0.2.0",
|
||||
"language-xml": "0.1.0",
|
||||
"language-yaml": "0.1.0"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"preinstall": "true",
|
||||
|
@ -1,22 +1,31 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env node
|
||||
var safeExec = require('./utils/child-process-wrapper.js').safeExec;
|
||||
var path = require('path');
|
||||
|
||||
# exit on subprocess errors
|
||||
set -o errexit
|
||||
|
||||
exit_unless_npm_exists() {
|
||||
if ! hash npm 2> /dev/null; then
|
||||
echo "ERROR: Atom requires npm"
|
||||
exit 1
|
||||
fi
|
||||
// Executes an array of commands one by one.
|
||||
function executeCommands(commands, done, index) {
|
||||
index = (index == undefined ? 0 : index);
|
||||
if (index < commands.length)
|
||||
safeExec(commands[index], executeCommands.bind(this, commands, done, index + 1));
|
||||
else
|
||||
done(null);
|
||||
}
|
||||
|
||||
exit_unless_npm_exists
|
||||
// Join multiple commands into one line.
|
||||
function joinCommands() {
|
||||
var commandSeparator = process.platform == 'win32' ? '&' : ';';
|
||||
return Array.prototype.slice.call(arguments, 0).join(commandSeparator);
|
||||
}
|
||||
|
||||
git submodule --quiet sync
|
||||
git submodule --quiet update --recursive --init
|
||||
var echoNewLine = process.platform == 'win32' ? 'echo.' : 'echo';
|
||||
var commands = [
|
||||
'git submodule --quiet sync',
|
||||
'git submodule --quiet update --recursive --init',
|
||||
joinCommands('cd vendor/apm', 'npm install --silent .'),
|
||||
'npm install --silent vendor/apm',
|
||||
echoNewLine,
|
||||
'node vendor/apm/bin/apm install --silent',
|
||||
];
|
||||
|
||||
(cd vendor/apm && npm install --silent .)
|
||||
|
||||
npm install --silent vendor/apm
|
||||
echo ""
|
||||
./node_modules/.bin/apm install --silent
|
||||
process.chdir(path.dirname(__dirname));
|
||||
executeCommands(commands, process.exit);
|
||||
|
6
script/bootstrap.cmd
Normal file
6
script/bootstrap.cmd
Normal file
@ -0,0 +1,6 @@
|
||||
@IF EXIST "%~dp0\node.exe" (
|
||||
"%~dp0\node.exe" "%~dp0\bootstrap" %*
|
||||
) ELSE (
|
||||
node "%~dp0\bootstrap" %*
|
||||
)
|
||||
|
16
script/build
16
script/build
@ -1,8 +1,12 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env node
|
||||
var cp = require('./utils/child-process-wrapper.js');
|
||||
var path = require('path');
|
||||
|
||||
set -e
|
||||
process.chdir(path.dirname(__dirname));
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
./script/bootstrap
|
||||
./node_modules/.bin/grunt "$@"
|
||||
cp.safeExec('node script/bootstrap', function() {
|
||||
// ./node_modules/.bin/grunt "$@"
|
||||
var gruntPath = path.join('node_modules', '.bin', 'grunt');
|
||||
var args = [gruntPath].concat(process.argv.slice(2));
|
||||
cp.safeSpawn(process.execPath, args, process.exit);
|
||||
});
|
||||
|
@ -1,18 +1,40 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env node
|
||||
var cp = require('./utils/child-process-wrapper.js');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
set -e
|
||||
process.chdir(path.dirname(__dirname));
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
if (process.platform != 'darwin')
|
||||
throw new Error('cibuild can not run on ' + process.platform + ' yet!');
|
||||
|
||||
rm -rf ~/.atom
|
||||
git clean -dff
|
||||
var homeDir = process.platform == 'win32' ? process.env.USERPROFILE : process.env.HOME;
|
||||
|
||||
ATOM_CREDENTIALS_FILE=/var/lib/jenkins/config/atomcredentials
|
||||
if [ -f $ATOM_CREDENTIALS_FILE ]; then
|
||||
. $ATOM_CREDENTIALS_FILE
|
||||
export ATOM_ACCESS_TOKEN=$ATOM_ACCESS_TOKEN # make it visibile to grunt.
|
||||
fi
|
||||
function readEnvironmentVariables(callback) {
|
||||
var credenticalsPath = '/var/lib/jenkins/config/atomcredentials';
|
||||
fs.readFile(credenticalsPath, function(error, data) {
|
||||
if (!error) {
|
||||
var lines = String(data).trim().split('\n');
|
||||
for (i in lines) {
|
||||
var parts = lines[i].split('=');
|
||||
var key = parts[0].trim();
|
||||
var value = parts[1].trim().substr(1, parts[1].length - 2);
|
||||
process.env[key] = value;
|
||||
}
|
||||
}
|
||||
// Do not quit when got error.
|
||||
callback(null);
|
||||
});
|
||||
}
|
||||
|
||||
./script/bootstrap
|
||||
./node_modules/.bin/apm clean
|
||||
./node_modules/.bin/grunt ci --stack --no-color
|
||||
var async = require('async');
|
||||
async.series([
|
||||
readEnvironmentVariables,
|
||||
cp.safeExec.bind(global, 'node script/bootstrap'),
|
||||
require('rimraf').bind(global, path.join(homeDir, '.atom')),
|
||||
cp.safeExec.bind(global, 'git clean -dff'),
|
||||
cp.safeExec.bind(global, 'node node_modules/.bin/apm clean'),
|
||||
cp.safeExec.bind(global, 'node node_modules/.bin/grunt ci --stack --no-color'),
|
||||
], function(error) {
|
||||
process.exit(error ? 1 : 0);
|
||||
});
|
||||
|
13
script/test
13
script/test
@ -1,8 +1,9 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env node
|
||||
var safeExec = require('./utils/child-process-wrapper.js').safeExec;
|
||||
var path = require('path');
|
||||
|
||||
set -e
|
||||
process.chdir(path.dirname(__dirname));
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
./script/bootstrap
|
||||
./node_modules/.bin/grunt ci --stack --no-color
|
||||
safeExec('node script/bootstrap', function() {
|
||||
safeExec('node node_modules/.bin/grunt ci --stack --no-color', process.exit);
|
||||
});
|
||||
|
35
script/utils/child-process-wrapper.js
Normal file
35
script/utils/child-process-wrapper.js
Normal file
@ -0,0 +1,35 @@
|
||||
var childProcess = require('child_process');
|
||||
|
||||
// Exit the process if the command failed and only call the callback if the
|
||||
// command succeed, output of the command would also be piped.
|
||||
exports.safeExec = function(command, options, callback) {
|
||||
if (!callback) {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
var child = childProcess.exec(command, options, function(error, stdout, stderr) {
|
||||
if (error)
|
||||
process.exit(error.code);
|
||||
else
|
||||
callback(null);
|
||||
});
|
||||
child.stderr.pipe(process.stderr);
|
||||
child.stdout.pipe(process.stdout);
|
||||
}
|
||||
|
||||
// Same with safeExec but call child_process.spawn instead.
|
||||
exports.safeSpawn = function(command, args, options, callback) {
|
||||
if (!callback) {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
var child = childProcess.spawn(command, args, options);
|
||||
child.stderr.pipe(process.stderr);
|
||||
child.stdout.pipe(process.stdout);
|
||||
child.on('exit', function(code) {
|
||||
if (code != 0)
|
||||
process.exit(code);
|
||||
else
|
||||
callback(null);
|
||||
});
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
{$, $$, fs, RootView} = require 'atom'
|
||||
Exec = require('child_process').exec
|
||||
path = require 'path'
|
||||
ThemeManager = require '../src/theme-manager'
|
||||
|
||||
describe "the `atom` global", ->
|
||||
beforeEach ->
|
||||
@ -20,6 +21,7 @@ describe "the `atom` global", ->
|
||||
expect(pack.activateStylesheets).toHaveBeenCalled()
|
||||
|
||||
it "continues if the package has an invalid package.json", ->
|
||||
spyOn(console, 'warn')
|
||||
config.set("core.disabledPackages", [])
|
||||
expect(-> atom.loadPackage("package-with-broken-package-json")).not.toThrow()
|
||||
|
||||
@ -192,7 +194,6 @@ describe "the `atom` global", ->
|
||||
expect(atom.contextMenu.definitionsForElement(element)[1].label).toBe "Menu item 1"
|
||||
expect(atom.contextMenu.definitionsForElement(element)[2]).toBeUndefined()
|
||||
|
||||
|
||||
describe "stylesheet loading", ->
|
||||
describe "when the metadata contains a 'stylesheets' manifest", ->
|
||||
it "loads stylesheets from the stylesheets directory as specified by the manifest", ->
|
||||
@ -239,12 +240,12 @@ describe "the `atom` global", ->
|
||||
describe "textmate packages", ->
|
||||
it "loads the package's grammars", ->
|
||||
expect(syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
atom.activatePackage('ruby-tmbundle', sync: true)
|
||||
atom.activatePackage('language-ruby', sync: true)
|
||||
expect(syntax.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
|
||||
it "translates the package's scoped properties to Atom terms", ->
|
||||
expect(syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
|
||||
atom.activatePackage('ruby-tmbundle', sync: true)
|
||||
atom.activatePackage('language-ruby', sync: true)
|
||||
expect(syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBe '# '
|
||||
|
||||
describe "when the package has no grammars but does have preferences", ->
|
||||
@ -327,12 +328,101 @@ describe "the `atom` global", ->
|
||||
describe "textmate packages", ->
|
||||
it "removes the package's grammars", ->
|
||||
expect(syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
atom.activatePackage('ruby-tmbundle', sync: true)
|
||||
atom.activatePackage('language-ruby', sync: true)
|
||||
expect(syntax.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
atom.deactivatePackage('ruby-tmbundle')
|
||||
atom.deactivatePackage('language-ruby')
|
||||
expect(syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
it "removes the package's scoped properties", ->
|
||||
atom.activatePackage('ruby-tmbundle', sync: true)
|
||||
atom.deactivatePackage('ruby-tmbundle')
|
||||
atom.activatePackage('language-ruby', sync: true)
|
||||
atom.deactivatePackage('language-ruby')
|
||||
expect(syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
|
||||
|
||||
describe ".activate()", ->
|
||||
packageActivator = null
|
||||
themeActivator = null
|
||||
|
||||
beforeEach ->
|
||||
spyOn(console, 'warn')
|
||||
atom.packages.loadPackages()
|
||||
|
||||
loadedPackages = atom.packages.getLoadedPackages()
|
||||
expect(loadedPackages.length).toBeGreaterThan 0
|
||||
|
||||
packageActivator = spyOn(atom.packages, 'activatePackages')
|
||||
themeActivator = spyOn(atom.themes, 'activatePackages')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
Syntax = require '../src/syntax'
|
||||
atom.syntax = window.syntax = new Syntax()
|
||||
|
||||
it "activates all the packages, and none of the themes", ->
|
||||
atom.packages.activate()
|
||||
|
||||
expect(packageActivator).toHaveBeenCalled()
|
||||
expect(themeActivator).toHaveBeenCalled()
|
||||
|
||||
packages = packageActivator.mostRecentCall.args[0]
|
||||
expect(['atom', 'textmate']).toContain(pack.getType()) for pack in packages
|
||||
|
||||
themes = themeActivator.mostRecentCall.args[0]
|
||||
expect(['theme']).toContain(theme.getType()) for theme in themes
|
||||
|
||||
describe ".en/disablePackage()", ->
|
||||
describe "with packages", ->
|
||||
it ".enablePackage() enables a disabled package", ->
|
||||
packageName = 'package-with-main'
|
||||
atom.config.pushAtKeyPath('core.disabledPackages', packageName)
|
||||
atom.packages.observeDisabledPackages()
|
||||
expect(config.get('core.disabledPackages')).toContain packageName
|
||||
|
||||
pack = atom.packages.enablePackage(packageName)
|
||||
|
||||
loadedPackages = atom.packages.getLoadedPackages()
|
||||
activatedPackages = atom.packages.getActivePackages()
|
||||
expect(loadedPackages).toContain(pack)
|
||||
expect(activatedPackages).toContain(pack)
|
||||
expect(config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
it ".disablePackage() disables an enabled package", ->
|
||||
packageName = 'package-with-main'
|
||||
atom.packages.activatePackage(packageName)
|
||||
atom.packages.observeDisabledPackages()
|
||||
expect(config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
pack = atom.packages.disablePackage(packageName)
|
||||
|
||||
activatedPackages = atom.packages.getActivePackages()
|
||||
expect(activatedPackages).not.toContain(pack)
|
||||
expect(config.get('core.disabledPackages')).toContain packageName
|
||||
|
||||
describe "with themes", ->
|
||||
beforeEach ->
|
||||
atom.themes.activateThemes()
|
||||
|
||||
afterEach ->
|
||||
atom.themes.deactivateThemes()
|
||||
atom.config.unobserve('core.themes')
|
||||
|
||||
it ".enablePackage() and .disablePackage() enables and disables a theme", ->
|
||||
packageName = 'theme-with-package-file'
|
||||
|
||||
expect(config.get('core.themes')).not.toContain packageName
|
||||
expect(config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
# enabling of theme
|
||||
pack = atom.packages.enablePackage(packageName)
|
||||
activatedPackages = atom.packages.getActivePackages()
|
||||
expect(activatedPackages).toContain(pack)
|
||||
expect(config.get('core.themes')).toContain packageName
|
||||
expect(config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
||||
# disabling of theme
|
||||
pack = atom.packages.disablePackage(packageName)
|
||||
activatedPackages = atom.packages.getActivePackages()
|
||||
expect(activatedPackages).not.toContain(pack)
|
||||
expect(config.get('core.themes')).not.toContain packageName
|
||||
expect(config.get('core.themes')).not.toContain packageName
|
||||
expect(config.get('core.disabledPackages')).not.toContain packageName
|
||||
|
@ -1,10 +1,12 @@
|
||||
{fs} = require 'atom'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
installer = require '../src/command-installer'
|
||||
|
||||
describe "install(commandPath, callback)", ->
|
||||
directory = '/tmp/install-atom-command/atom'
|
||||
commandPath = "#{directory}/source"
|
||||
destinationPath = "#{directory}/bin/source"
|
||||
directory = path.join(temp.dir, 'install-atom-command', 'atom')
|
||||
commandPath = path.join(directory, 'source')
|
||||
destinationPath = path.join(directory, 'bin', 'source')
|
||||
|
||||
beforeEach ->
|
||||
spyOn(installer, 'findInstallDirectory').andCallFake (callback) ->
|
||||
|
@ -1,8 +1,11 @@
|
||||
{fs} = require 'atom'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
CSON = require 'season'
|
||||
|
||||
describe "Config", ->
|
||||
dotAtomPath = path.join(temp.dir, 'dot-atom-dir')
|
||||
|
||||
describe ".get(keyPath)", ->
|
||||
it "allows a key path's value to be read", ->
|
||||
expect(config.set("foo.bar.baz", 42)).toBe 42
|
||||
@ -29,7 +32,7 @@ describe "Config", ->
|
||||
config.set("foo.bar.baz", 42)
|
||||
|
||||
expect(config.save).toHaveBeenCalled()
|
||||
expect(observeHandler).toHaveBeenCalledWith 42
|
||||
expect(observeHandler).toHaveBeenCalledWith 42, {previous: undefined}
|
||||
|
||||
describe "when the value equals the default value", ->
|
||||
it "does not store the value", ->
|
||||
@ -51,7 +54,7 @@ describe "Config", ->
|
||||
|
||||
expect(config.pushAtKeyPath("foo.bar.baz", "b")).toBe 2
|
||||
expect(config.get("foo.bar.baz")).toEqual ["a", "b"]
|
||||
expect(observeHandler).toHaveBeenCalledWith config.get("foo.bar.baz")
|
||||
expect(observeHandler).toHaveBeenCalledWith config.get("foo.bar.baz"), {previous: ['a']}
|
||||
|
||||
describe ".removeAtKeyPath(keyPath, value)", ->
|
||||
it "removes the given value from the array at the key path and updates observers", ->
|
||||
@ -62,7 +65,7 @@ describe "Config", ->
|
||||
|
||||
expect(config.removeAtKeyPath("foo.bar.baz", "b")).toEqual ["a", "c"]
|
||||
expect(config.get("foo.bar.baz")).toEqual ["a", "c"]
|
||||
expect(observeHandler).toHaveBeenCalledWith config.get("foo.bar.baz")
|
||||
expect(observeHandler).toHaveBeenCalledWith config.get("foo.bar.baz"), {previous: ['a', 'b', 'c']}
|
||||
|
||||
describe ".getPositiveInt(keyPath, defaultValue)", ->
|
||||
it "returns the proper current or default value", ->
|
||||
@ -139,34 +142,34 @@ describe "Config", ->
|
||||
it "fires the callback every time the observed value changes", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
config.set('foo.bar.baz', "value 2")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 2")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 2", {previous: 'value 1'})
|
||||
observeHandler.reset()
|
||||
|
||||
config.set('foo.bar.baz', "value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 1", {previous: 'value 2'})
|
||||
|
||||
it "fires the callback when the observed value is deleted", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
config.set('foo.bar.baz', undefined)
|
||||
expect(observeHandler).toHaveBeenCalledWith(undefined)
|
||||
expect(observeHandler).toHaveBeenCalledWith(undefined, {previous: 'value 1'})
|
||||
|
||||
it "fires the callback when the full key path goes into and out of existence", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
config.set("foo.bar", undefined)
|
||||
|
||||
expect(observeHandler).toHaveBeenCalledWith(undefined)
|
||||
expect(observeHandler).toHaveBeenCalledWith(undefined, {previous: 'value 1'})
|
||||
observeHandler.reset()
|
||||
|
||||
config.set("foo.bar.baz", "i'm back")
|
||||
expect(observeHandler).toHaveBeenCalledWith("i'm back")
|
||||
expect(observeHandler).toHaveBeenCalledWith("i'm back", {previous: undefined})
|
||||
|
||||
describe ".initializeConfigDirectory()", ->
|
||||
beforeEach ->
|
||||
config.configDirPath = '/tmp/dot-atom-dir'
|
||||
config.configDirPath = dotAtomPath
|
||||
expect(fs.exists(config.configDirPath)).toBeFalsy()
|
||||
|
||||
afterEach ->
|
||||
fs.remove('/tmp/dot-atom-dir') if fs.exists('/tmp/dot-atom-dir')
|
||||
fs.remove(dotAtomPath) if fs.exists(dotAtomPath)
|
||||
|
||||
describe "when the configDirPath doesn't exist", ->
|
||||
it "copies the contents of dot-atom to ~/.atom", ->
|
||||
@ -185,12 +188,12 @@ describe "Config", ->
|
||||
|
||||
describe ".loadUserConfig()", ->
|
||||
beforeEach ->
|
||||
config.configDirPath = '/tmp/dot-atom-dir'
|
||||
config.configDirPath = dotAtomPath
|
||||
config.configFilePath = path.join(config.configDirPath, "config.cson")
|
||||
expect(fs.exists(config.configDirPath)).toBeFalsy()
|
||||
|
||||
afterEach ->
|
||||
fs.remove('/tmp/dot-atom-dir') if fs.exists('/tmp/dot-atom-dir')
|
||||
fs.remove(dotAtomPath) if fs.exists(dotAtomPath)
|
||||
|
||||
describe "when the config file contains valid cson", ->
|
||||
beforeEach ->
|
||||
@ -222,7 +225,7 @@ describe "Config", ->
|
||||
updatedHandler = null
|
||||
|
||||
beforeEach ->
|
||||
config.configDirPath = '/tmp/dot-atom-dir'
|
||||
config.configDirPath = dotAtomPath
|
||||
config.configFilePath = path.join(config.configDirPath, "config.cson")
|
||||
expect(fs.exists(config.configDirPath)).toBeFalsy()
|
||||
fs.writeSync(config.configFilePath, "foo: bar: 'baz'")
|
||||
@ -233,7 +236,7 @@ describe "Config", ->
|
||||
|
||||
afterEach ->
|
||||
config.unobserveUserConfig()
|
||||
fs.remove('/tmp/dot-atom-dir') if fs.exists('/tmp/dot-atom-dir')
|
||||
fs.remove(dotAtomPath) if fs.exists(dotAtomPath)
|
||||
|
||||
describe "when the config file changes to contain valid cson", ->
|
||||
it "updates the config data", ->
|
||||
|
@ -5,7 +5,7 @@ describe "DisplayBuffer", ->
|
||||
[displayBuffer, buffer, changeHandler, tabLength] = []
|
||||
beforeEach ->
|
||||
tabLength = 2
|
||||
atom.activatePackage('javascript-tmbundle', sync: true)
|
||||
atom.activatePackage('language-javascript', sync: true)
|
||||
buffer = project.bufferForPathSync('sample.js')
|
||||
displayBuffer = new DisplayBuffer({buffer, tabLength})
|
||||
changeHandler = jasmine.createSpy 'changeHandler'
|
||||
|
@ -16,7 +16,7 @@ describe "EditSession", ->
|
||||
|
||||
describe "with default options", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('javascript-tmbundle', sync: true)
|
||||
atom.activatePackage('language-javascript', sync: true)
|
||||
editSession = project.openSync('sample.js', autoIndent: false)
|
||||
buffer = editSession.buffer
|
||||
lineLengths = buffer.getLines().map (line) -> line.length
|
||||
|
@ -1,12 +1,13 @@
|
||||
{_, $, $$, fs, Editor, Range, RootView} = require 'atom'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
|
||||
describe "Editor", ->
|
||||
[buffer, editor, editSession, cachedLineHeight, cachedCharWidth] = []
|
||||
|
||||
beforeEach ->
|
||||
atom.activatePackage('text-tmbundle', sync: true)
|
||||
atom.activatePackage('javascript-tmbundle', sync: true)
|
||||
atom.activatePackage('language-text', sync: true)
|
||||
atom.activatePackage('language-javascript', sync: true)
|
||||
editSession = project.openSync('sample.js')
|
||||
buffer = editSession.buffer
|
||||
editor = new Editor(editSession)
|
||||
@ -86,7 +87,7 @@ describe "Editor", ->
|
||||
|
||||
describe "when the activeEditSession's file is modified on disk", ->
|
||||
it "triggers an alert", ->
|
||||
filePath = "/tmp/atom-changed-file.txt"
|
||||
filePath = path.join(temp.dir, 'atom-changed-file.txt')
|
||||
fs.writeSync(filePath, "")
|
||||
editSession = project.openSync(filePath)
|
||||
editor.edit(editSession)
|
||||
@ -151,7 +152,7 @@ describe "Editor", ->
|
||||
expect(editor.lineElementForScreenRow(6).text()).toMatch /^ currentgoodbye/
|
||||
|
||||
it "triggers alert if edit session's buffer goes into conflict with changes on disk", ->
|
||||
filePath = "/tmp/atom-changed-file.txt"
|
||||
filePath = path.join(temp.dir, 'atom-changed-file.txt')
|
||||
fs.writeSync(filePath, "")
|
||||
tempEditSession = project.openSync(filePath)
|
||||
editor.edit(tempEditSession)
|
||||
@ -247,7 +248,7 @@ describe "Editor", ->
|
||||
filePath = null
|
||||
|
||||
beforeEach ->
|
||||
filePath = "/tmp/something.txt"
|
||||
filePath = path.join(temp.dir, 'something.txt')
|
||||
fs.writeSync(filePath, filePath)
|
||||
|
||||
afterEach ->
|
||||
@ -274,11 +275,11 @@ describe "Editor", ->
|
||||
expect(eventHandler).toHaveBeenCalled()
|
||||
|
||||
eventHandler.reset()
|
||||
oldBuffer.saveAs("/tmp/atom-bad.txt")
|
||||
oldBuffer.saveAs(path.join(temp.dir, 'atom-bad.txt'))
|
||||
expect(eventHandler).not.toHaveBeenCalled()
|
||||
|
||||
eventHandler.reset()
|
||||
editor.getBuffer().saveAs("/tmp/atom-new.txt")
|
||||
editor.getBuffer().saveAs(path.join(temp.dir, 'atom-new.txt'))
|
||||
expect(eventHandler).toHaveBeenCalled()
|
||||
|
||||
it "loads the grammar for the new path", ->
|
||||
@ -2296,7 +2297,8 @@ describe "Editor", ->
|
||||
[filePath] = []
|
||||
|
||||
beforeEach ->
|
||||
filePath = path.join(fs.absolute("/tmp"), "grammar-change.txt")
|
||||
tmpdir = fs.absolute(temp.dir)
|
||||
filePath = path.join(tmpdir, "grammar-change.txt")
|
||||
fs.writeSync(filePath, "var i;")
|
||||
|
||||
afterEach ->
|
||||
@ -2648,10 +2650,11 @@ describe "Editor", ->
|
||||
|
||||
editor.trigger 'editor:save-debug-snapshot'
|
||||
|
||||
statePath = path.join(temp.dir, 'state')
|
||||
expect(atom.showSaveDialog).toHaveBeenCalled()
|
||||
saveDialogCallback('/tmp/state')
|
||||
saveDialogCallback(statePath)
|
||||
expect(fs.writeSync).toHaveBeenCalled()
|
||||
expect(fs.writeSync.argsForCall[0][0]).toBe '/tmp/state'
|
||||
expect(fs.writeSync.argsForCall[0][0]).toBe statePath
|
||||
expect(typeof fs.writeSync.argsForCall[0][1]).toBe 'string'
|
||||
|
||||
describe "when the escape key is pressed on the editor", ->
|
||||
|
@ -33,12 +33,15 @@ describe "fs", ->
|
||||
expect(fs.exists(null)).toBe false
|
||||
|
||||
describe ".makeTree(path)", ->
|
||||
aPath = path.join(temp.dir, 'a')
|
||||
|
||||
beforeEach ->
|
||||
fs.remove("/tmp/a") if fs.exists("/tmp/a")
|
||||
fs.remove(aPath) if fs.exists(aPath)
|
||||
|
||||
it "creates all directories in path including any missing parent directories", ->
|
||||
fs.makeTree("/tmp/a/b/c")
|
||||
expect(fs.exists("/tmp/a/b/c")).toBeTruthy()
|
||||
abcPath = path.join(aPath, 'b', 'c')
|
||||
fs.makeTree(abcPath)
|
||||
expect(fs.exists(abcPath)).toBeTruthy()
|
||||
|
||||
describe ".traverseTreeSync(path, onFile, onDirectory)", ->
|
||||
it "calls fn for every path in the tree at the given path", ->
|
||||
@ -131,6 +134,7 @@ describe "fs", ->
|
||||
|
||||
describe ".absolute(relativePath)", ->
|
||||
it "converts a leading ~ segment to the HOME directory", ->
|
||||
expect(fs.absolute('~')).toBe fs.realpathSync(process.env.HOME)
|
||||
expect(fs.absolute(path.join('~', 'does', 'not', 'exist'))).toBe path.join(process.env.HOME, 'does', 'not', 'exist')
|
||||
homeDir = atom.getHomeDirPath()
|
||||
expect(fs.absolute('~')).toBe fs.realpathSync(homeDir)
|
||||
expect(fs.absolute(path.join('~', 'does', 'not', 'exist'))).toBe path.join(homeDir, 'does', 'not', 'exist')
|
||||
expect(fs.absolute('~test')).toBe '~test'
|
||||
|
@ -8,18 +8,19 @@ describe "Git", ->
|
||||
repo = null
|
||||
|
||||
beforeEach ->
|
||||
fs.remove('/tmp/.git') if fs.isDirectorySync('/tmp/.git')
|
||||
gitPath = path.join(temp.dir, '.git')
|
||||
fs.remove(gitPath) if fs.isDirectorySync(gitPath)
|
||||
|
||||
afterEach ->
|
||||
repo.destroy() if repo?.repo?
|
||||
|
||||
describe "@open(path)", ->
|
||||
it "returns null when no repository is found", ->
|
||||
expect(Git.open('/tmp/nogit.txt')).toBeNull()
|
||||
expect(Git.open(path.join(temp.dir, 'nogit.txt'))).toBeNull()
|
||||
|
||||
describe "new Git(path)", ->
|
||||
it "throws an exception when no repository is found", ->
|
||||
expect(-> new Git('/tmp/nogit.txt')).toThrow()
|
||||
expect(-> new Git(path.join(temp.dir, 'nogit.txt'))).toThrow()
|
||||
|
||||
describe ".getPath()", ->
|
||||
it "returns the repository path for a .git directory path", ->
|
||||
|
@ -6,7 +6,7 @@ describe "LanguageMode", ->
|
||||
|
||||
describe "javascript", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('javascript-tmbundle', sync: true)
|
||||
atom.activatePackage('language-javascript', sync: true)
|
||||
editSession = project.openSync('sample.js', autoIndent: false)
|
||||
{buffer, languageMode} = editSession
|
||||
|
||||
@ -97,7 +97,7 @@ describe "LanguageMode", ->
|
||||
|
||||
describe "coffeescript", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('coffee-script-tmbundle', sync: true)
|
||||
atom.activatePackage('language-coffee-script', sync: true)
|
||||
editSession = project.openSync('coffee.coffee', autoIndent: false)
|
||||
{buffer, languageMode} = editSession
|
||||
|
||||
@ -144,7 +144,7 @@ describe "LanguageMode", ->
|
||||
|
||||
describe "css", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('css-tmbundle', sync: true)
|
||||
atom.activatePackage('language-css', sync: true)
|
||||
editSession = project.openSync('css.css', autoIndent: false)
|
||||
{buffer, languageMode} = editSession
|
||||
|
||||
@ -185,8 +185,8 @@ describe "LanguageMode", ->
|
||||
|
||||
describe "less", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('less-tmbundle', sync: true)
|
||||
atom.activatePackage('css-tmbundle', sync: true)
|
||||
atom.activatePackage('language-less', sync: true)
|
||||
atom.activatePackage('language-css', sync: true)
|
||||
editSession = project.openSync('sample.less', autoIndent: false)
|
||||
{buffer, languageMode} = editSession
|
||||
|
||||
@ -197,7 +197,7 @@ describe "LanguageMode", ->
|
||||
|
||||
describe "folding", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('javascript-tmbundle', sync: true)
|
||||
atom.activatePackage('language-javascript', sync: true)
|
||||
editSession = project.openSync('sample.js', autoIndent: false)
|
||||
{buffer, languageMode} = editSession
|
||||
|
||||
@ -287,7 +287,7 @@ describe "LanguageMode", ->
|
||||
|
||||
describe "folding with comments", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('javascript-tmbundle', sync: true)
|
||||
atom.activatePackage('language-javascript', sync: true)
|
||||
editSession = project.openSync('sample-with-comments.js', autoIndent: false)
|
||||
{buffer, languageMode} = editSession
|
||||
|
||||
@ -340,8 +340,8 @@ describe "LanguageMode", ->
|
||||
|
||||
describe "css", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('source-tmbundle', sync: true)
|
||||
atom.activatePackage('css-tmbundle', sync: true)
|
||||
atom.activatePackage('language-source', sync: true)
|
||||
atom.activatePackage('language-css', sync: true)
|
||||
editSession = project.openSync('css.css', autoIndent: true)
|
||||
|
||||
describe "suggestedIndentForBufferRow", ->
|
||||
|
@ -1,3 +1,5 @@
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
{Site} = require 'telepath'
|
||||
{View} = require 'atom'
|
||||
PaneContainer = require '../src/pane-container'
|
||||
@ -13,7 +15,7 @@ describe "PaneContainer replication", ->
|
||||
initialize: (@name) -> @text(@name)
|
||||
serialize: -> { deserializer: 'TestView', @name }
|
||||
getState: -> @serialize()
|
||||
getUri: -> "/tmp/#{@name}"
|
||||
getUri: -> path.join(temp.dir, @name)
|
||||
isEqual: (other) -> @name is other.name
|
||||
|
||||
beforeEach ->
|
||||
|
@ -1,3 +1,5 @@
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
PaneContainer = require '../src/pane-container'
|
||||
Pane = require '../src/pane'
|
||||
{_, $, View, $$} = require 'atom'
|
||||
@ -12,7 +14,7 @@ describe "PaneContainer", ->
|
||||
@content: -> @div tabindex: -1
|
||||
initialize: (@name) -> @text(@name)
|
||||
serialize: -> { deserializer: 'TestView', @name }
|
||||
getUri: -> "/tmp/#{@name}"
|
||||
getUri: -> path.join(temp.dir, @name)
|
||||
save: -> @saved = true
|
||||
isEqual: (other) -> @name is other.name
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
PaneContainer = require '../src/pane-container'
|
||||
Pane = require '../src/pane'
|
||||
{$, View} = require 'atom'
|
||||
{dirname} = require 'path'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
|
||||
describe "Pane", ->
|
||||
[container, view1, view2, editSession1, editSession2, pane] = []
|
||||
@ -372,7 +373,7 @@ describe "Pane", ->
|
||||
|
||||
pane.trigger 'core:save-as'
|
||||
|
||||
expect(atom.showSaveDialogSync).toHaveBeenCalledWith(dirname(editSession2.getPath()))
|
||||
expect(atom.showSaveDialogSync).toHaveBeenCalledWith(path.dirname(editSession2.getPath()))
|
||||
expect(editSession2.saveAs).toHaveBeenCalledWith('/selected/path')
|
||||
|
||||
describe "when the current item does not have a saveAs method", ->
|
||||
@ -679,7 +680,7 @@ describe "Pane", ->
|
||||
expect(pane.saveItem).not.toHaveBeenCalled()
|
||||
expect(pane.activeItem.save).not.toHaveBeenCalled()
|
||||
|
||||
initialActiveItemUri = '/tmp/hi'
|
||||
initialActiveItemUri = path.join(temp.dir, 'hi')
|
||||
pane.activeView.trigger 'focusout'
|
||||
expect(pane.activeItem.save).toHaveBeenCalled()
|
||||
|
||||
@ -697,7 +698,7 @@ describe "Pane", ->
|
||||
expect(initialActiveItem.save).not.toHaveBeenCalled()
|
||||
|
||||
pane.showItem(initialActiveItem)
|
||||
initialActiveItemUri = '/tmp/hi'
|
||||
initialActiveItemUri = path.join(temp.dir, 'hi')
|
||||
pane.showItem(view2)
|
||||
expect(initialActiveItem.save).toHaveBeenCalled()
|
||||
|
||||
@ -716,7 +717,7 @@ describe "Pane", ->
|
||||
pane.destroyItem(view2)
|
||||
expect(pane.saveItem).not.toHaveBeenCalled()
|
||||
|
||||
initialActiveItemUri = '/tmp/hi'
|
||||
initialActiveItemUri = path.join(temp.dir, 'hi')
|
||||
pane.destroyItem(initialActiveItem)
|
||||
expect(initialActiveItem.save).toHaveBeenCalled()
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
{$, $$, fs, RootView, View} = require 'atom'
|
||||
Q = require 'q'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
Pane = require '../src/pane'
|
||||
|
||||
describe "RootView", ->
|
||||
@ -162,7 +163,7 @@ describe "RootView", ->
|
||||
describe "when the title of the active pane item changes", ->
|
||||
it "updates the window title based on the item's new title", ->
|
||||
editSession = rootView.getActivePaneItem()
|
||||
editSession.buffer.setPath('/tmp/hi')
|
||||
editSession.buffer.setPath(path.join(temp.dir, 'hi'))
|
||||
expect(rootView.title).toBe "#{editSession.getTitle()} - #{project.getPath()}"
|
||||
|
||||
describe "when the active pane's item changes", ->
|
||||
|
@ -25,7 +25,7 @@ describe "SpacePen extensions", ->
|
||||
|
||||
config.set("foo.bar", "hello")
|
||||
|
||||
expect(observeHandler).toHaveBeenCalledWith("hello")
|
||||
expect(observeHandler).toHaveBeenCalledWith("hello", previous: undefined)
|
||||
observeHandler.reset()
|
||||
|
||||
view.unobserveConfig()
|
||||
|
@ -1,28 +1,30 @@
|
||||
{fs} = require 'atom'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
TextMateGrammar = require '../src/text-mate-grammar'
|
||||
|
||||
describe "the `syntax` global", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('text-tmbundle', sync: true)
|
||||
atom.activatePackage('javascript-tmbundle', sync: true)
|
||||
atom.activatePackage('coffee-script-tmbundle', sync: true)
|
||||
atom.activatePackage('ruby-tmbundle', sync: true)
|
||||
atom.activatePackage('language-text', sync: true)
|
||||
atom.activatePackage('language-javascript', sync: true)
|
||||
atom.activatePackage('language-coffee-script', sync: true)
|
||||
atom.activatePackage('language-ruby', sync: true)
|
||||
|
||||
describe "serialization", ->
|
||||
it "remembers grammar overrides by path", ->
|
||||
path = '/foo/bar/file.js'
|
||||
expect(syntax.selectGrammar(path).name).not.toBe 'Ruby'
|
||||
syntax.setGrammarOverrideForPath(path, 'source.ruby')
|
||||
filePath = '/foo/bar/file.js'
|
||||
expect(syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
syntax.setGrammarOverrideForPath(filePath, 'source.ruby')
|
||||
syntax2 = deserialize(syntax.serialize())
|
||||
syntax2.addGrammar(grammar) for grammar in syntax.grammars when grammar isnt syntax.nullGrammar
|
||||
expect(syntax2.selectGrammar(path).name).toBe 'Ruby'
|
||||
expect(syntax2.selectGrammar(filePath).name).toBe 'Ruby'
|
||||
|
||||
describe ".selectGrammar(filePath)", ->
|
||||
it "can use the filePath to load the correct grammar based on the grammar's filetype", ->
|
||||
atom.activatePackage('git-tmbundle', sync: true)
|
||||
atom.activatePackage('language-git', sync: true)
|
||||
|
||||
expect(syntax.selectGrammar("file.js").name).toBe "JavaScript" # based on extension (.js)
|
||||
expect(syntax.selectGrammar("/tmp/.git/config").name).toBe "Git Config" # based on end of the path (.git/config)
|
||||
expect(syntax.selectGrammar(path.join(temp.dir, '.git', 'config')).name).toBe "Git Config" # based on end of the path (.git/config)
|
||||
expect(syntax.selectGrammar("Rakefile").name).toBe "Ruby" # based on the file's basename (Rakefile)
|
||||
expect(syntax.selectGrammar("curb").name).toBe "Null Grammar"
|
||||
expect(syntax.selectGrammar("/hu.git/config").name).toBe "Null Grammar"
|
||||
@ -32,7 +34,7 @@ describe "the `syntax` global", ->
|
||||
expect(syntax.selectGrammar(filePath).name).toBe "Ruby"
|
||||
|
||||
it "uses the number of newlines in the first line regex to determine the number of lines to test against", ->
|
||||
atom.activatePackage('property-list-tmbundle', sync: true)
|
||||
atom.activatePackage('language-property-list', sync: true)
|
||||
|
||||
fileContent = "first-line\n<html>"
|
||||
expect(syntax.selectGrammar("dummy.coffee", fileContent).name).toBe "CoffeeScript"
|
||||
@ -51,12 +53,12 @@ describe "the `syntax` global", ->
|
||||
expect(fs.read).not.toHaveBeenCalled()
|
||||
|
||||
it "allows the default grammar to be overridden for a path", ->
|
||||
path = '/foo/bar/file.js'
|
||||
expect(syntax.selectGrammar(path).name).not.toBe 'Ruby'
|
||||
syntax.setGrammarOverrideForPath(path, 'source.ruby')
|
||||
expect(syntax.selectGrammar(path).name).toBe 'Ruby'
|
||||
syntax.clearGrammarOverrideForPath(path)
|
||||
expect(syntax.selectGrammar(path).name).not.toBe 'Ruby'
|
||||
filePath = '/foo/bar/file.js'
|
||||
expect(syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
syntax.setGrammarOverrideForPath(filePath, 'source.ruby')
|
||||
expect(syntax.selectGrammar(filePath).name).toBe 'Ruby'
|
||||
syntax.clearGrammarOverrideForPath(filePath)
|
||||
expect(syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
|
||||
describe "when multiple grammars have matching fileTypes", ->
|
||||
it "selects the grammar with the longest fileType match", ->
|
||||
|
@ -154,7 +154,7 @@ describe 'TextBuffer', ->
|
||||
[filePath, bufferToDelete] = []
|
||||
|
||||
beforeEach ->
|
||||
filePath = "/tmp/atom-file-to-delete.txt"
|
||||
filePath = path.join(temp.dir, 'atom-file-to-delete.txt')
|
||||
fs.writeSync(filePath, 'delete me')
|
||||
bufferToDelete = project.bufferForPathSync(filePath)
|
||||
filePath = bufferToDelete.getPath() # symlinks may have been converted
|
||||
@ -212,7 +212,7 @@ describe 'TextBuffer', ->
|
||||
|
||||
it "reports the modified status changing to true after the underlying file is deleted", ->
|
||||
buffer.release()
|
||||
filePath = "/tmp/atom-tmp-file"
|
||||
filePath = path.join(temp.dir, 'atom-tmp-file')
|
||||
fs.writeSync(filePath, 'delete me')
|
||||
buffer = project.bufferForPathSync(filePath)
|
||||
modifiedHandler = jasmine.createSpy("modifiedHandler")
|
||||
@ -224,7 +224,7 @@ describe 'TextBuffer', ->
|
||||
runs -> expect(buffer.isModified()).toBe true
|
||||
|
||||
it "reports the modified status changing to false after a modified buffer is saved", ->
|
||||
filePath = "/tmp/atom-tmp-file"
|
||||
filePath = path.join(temp.dir, 'atom-tmp-file')
|
||||
fs.writeSync(filePath, '')
|
||||
buffer.release()
|
||||
buffer = project.bufferForPathSync(filePath)
|
||||
@ -248,7 +248,7 @@ describe 'TextBuffer', ->
|
||||
expect(buffer.isModified()).toBe true
|
||||
|
||||
it "reports the modified status changing to false after a modified buffer is reloaded", ->
|
||||
filePath = "/tmp/atom-tmp-file"
|
||||
filePath = path.join(temp.dir, 'atom-tmp-file')
|
||||
fs.writeSync(filePath, '')
|
||||
buffer.release()
|
||||
buffer = project.bufferForPathSync(filePath)
|
||||
@ -271,7 +271,7 @@ describe 'TextBuffer', ->
|
||||
expect(buffer.isModified()).toBe true
|
||||
|
||||
it "reports the modified status changing to false after a buffer to a non-existent file is saved", ->
|
||||
filePath = "/tmp/atom-tmp-file"
|
||||
filePath = path.join(temp.dir, 'atom-tmp-file')
|
||||
fs.remove(filePath) if fs.exists(filePath)
|
||||
expect(fs.exists(filePath)).toBeFalsy()
|
||||
buffer.release()
|
||||
@ -464,7 +464,7 @@ describe 'TextBuffer', ->
|
||||
filePath = null
|
||||
|
||||
beforeEach ->
|
||||
filePath = '/tmp/temp.txt'
|
||||
filePath = path.join(temp.dir, 'temp.txt')
|
||||
fs.writeSync(filePath, "")
|
||||
saveBuffer = project.bufferForPathSync(filePath)
|
||||
saveBuffer.setText("blah")
|
||||
@ -521,7 +521,7 @@ describe 'TextBuffer', ->
|
||||
saveAsBuffer.release()
|
||||
|
||||
it "saves the contents of the buffer to the path", ->
|
||||
filePath = '/tmp/temp.txt'
|
||||
filePath = path.join(temp.dir, 'temp.txt')
|
||||
fs.remove filePath if fs.exists(filePath)
|
||||
|
||||
saveAsBuffer = project.bufferForPathSync(null).retain()
|
||||
@ -535,8 +535,8 @@ describe 'TextBuffer', ->
|
||||
expect(eventHandler).toHaveBeenCalledWith(saveAsBuffer)
|
||||
|
||||
it "stops listening to events on previous path and begins listening to events on new path", ->
|
||||
originalPath = "/tmp/original.txt"
|
||||
newPath = "/tmp/new.txt"
|
||||
originalPath = path.join(temp.dir, 'original.txt')
|
||||
newPath = path.join(temp.dir, 'new.txt')
|
||||
fs.writeSync(originalPath, "")
|
||||
|
||||
saveAsBuffer = project.bufferForPathSync(originalPath).retain()
|
||||
|
@ -6,13 +6,13 @@ describe "TextMateGrammar", ->
|
||||
grammar = null
|
||||
|
||||
beforeEach ->
|
||||
atom.activatePackage('text-tmbundle', sync: true)
|
||||
atom.activatePackage('javascript-tmbundle', sync: true)
|
||||
atom.activatePackage('coffee-script-tmbundle', sync: true)
|
||||
atom.activatePackage('ruby-tmbundle', sync: true)
|
||||
atom.activatePackage('html-tmbundle', sync: true)
|
||||
atom.activatePackage('php-tmbundle', sync: true)
|
||||
atom.activatePackage('python-tmbundle', sync: true)
|
||||
atom.activatePackage('language-text', sync: true)
|
||||
atom.activatePackage('language-javascript', sync: true)
|
||||
atom.activatePackage('language-coffee-script', sync: true)
|
||||
atom.activatePackage('language-ruby', sync: true)
|
||||
atom.activatePackage('language-html', sync: true)
|
||||
atom.activatePackage('language-php', sync: true)
|
||||
atom.activatePackage('language-python', sync: true)
|
||||
grammar = syntax.selectGrammar("hello.coffee")
|
||||
|
||||
describe "@loadSync(path)", ->
|
||||
@ -211,8 +211,8 @@ describe "TextMateGrammar", ->
|
||||
describe "when the pattern includes rules from another grammar", ->
|
||||
describe "when a grammar matching the desired scope is available", ->
|
||||
it "parses tokens inside the begin/end patterns based on the included grammar's rules", ->
|
||||
atom.activatePackage('html-tmbundle', sync: true)
|
||||
atom.activatePackage('ruby-on-rails-tmbundle', sync: true)
|
||||
atom.activatePackage('language-html', sync: true)
|
||||
atom.activatePackage('language-ruby-on-rails', sync: true)
|
||||
|
||||
grammar = syntax.grammarForScopeName('text.html.ruby')
|
||||
{tokens} = grammar.tokenizeLine("<div class='name'><%= User.find(2).full_name %></div>")
|
||||
@ -242,8 +242,8 @@ describe "TextMateGrammar", ->
|
||||
expect(tokens[22]).toEqual value: '>', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.end.html"]
|
||||
|
||||
it "updates the grammar if the included grammar is updated later", ->
|
||||
atom.activatePackage('html-tmbundle', sync: true)
|
||||
atom.activatePackage('ruby-on-rails-tmbundle', sync: true)
|
||||
atom.activatePackage('language-html', sync: true)
|
||||
atom.activatePackage('language-ruby-on-rails', sync: true)
|
||||
|
||||
grammar = syntax.selectGrammar('foo.html.erb')
|
||||
grammarUpdatedHandler = jasmine.createSpy("grammarUpdatedHandler")
|
||||
@ -252,7 +252,7 @@ describe "TextMateGrammar", ->
|
||||
{tokens} = grammar.tokenizeLine("<div class='name'><% <<-SQL select * from users;")
|
||||
expect(tokens[12].value).toBe " select * from users;"
|
||||
|
||||
atom.activatePackage('sql-tmbundle', sync: true)
|
||||
atom.activatePackage('language-sql', sync: true)
|
||||
expect(grammarUpdatedHandler).toHaveBeenCalled()
|
||||
{tokens} = grammar.tokenizeLine("<div class='name'><% <<-SQL select * from users;")
|
||||
expect(tokens[12].value).toBe " "
|
||||
@ -260,8 +260,8 @@ describe "TextMateGrammar", ->
|
||||
|
||||
describe "when a grammar matching the desired scope is unavailable", ->
|
||||
it "updates the grammar if a matching grammar is added later", ->
|
||||
atom.deactivatePackage('html-tmbundle')
|
||||
atom.activatePackage('ruby-on-rails-tmbundle', sync: true)
|
||||
atom.deactivatePackage('language-html')
|
||||
atom.activatePackage('language-ruby-on-rails', sync: true)
|
||||
|
||||
grammar = syntax.grammarForScopeName('text.html.ruby')
|
||||
{tokens} = grammar.tokenizeLine("<div class='name'><%= User.find(2).full_name %></div>")
|
||||
@ -270,7 +270,7 @@ describe "TextMateGrammar", ->
|
||||
expect(tokens[2]).toEqual value: ' ', scopes: ["text.html.ruby","source.ruby.rails.embedded.html"]
|
||||
expect(tokens[3]).toEqual value: 'User', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","support.class.ruby"]
|
||||
|
||||
atom.activatePackage('html-tmbundle', sync: true)
|
||||
atom.activatePackage('language-html', sync: true)
|
||||
{tokens} = grammar.tokenizeLine("<div class='name'><%= User.find(2).full_name %></div>")
|
||||
expect(tokens[0]).toEqual value: '<', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.begin.html"]
|
||||
expect(tokens[1]).toEqual value: 'div', scopes: ["text.html.ruby","meta.tag.block.any.html","entity.name.tag.block.any.html"]
|
||||
@ -314,7 +314,7 @@ describe "TextMateGrammar", ->
|
||||
|
||||
describe "when inside a C block", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('c-tmbundle', sync: true)
|
||||
atom.activatePackage('language-c', sync: true)
|
||||
|
||||
it "correctly parses a method. (regression)", ->
|
||||
grammar = syntax.selectGrammar("hello.c")
|
||||
@ -339,7 +339,7 @@ describe "TextMateGrammar", ->
|
||||
|
||||
describe "when a grammar has a pattern that has back references in the match value", ->
|
||||
it "does not special handle the back references and instead allows oniguruma to resolve them", ->
|
||||
atom.activatePackage('sass-tmbundle', sync: true)
|
||||
atom.activatePackage('language-sass', sync: true)
|
||||
grammar = syntax.selectGrammar("style.scss")
|
||||
{tokens} = grammar.tokenizeLine("@mixin x() { -moz-selector: whatever; }")
|
||||
expect(tokens[9]).toEqual value: "-moz-selector", scopes: ["source.css.scss", "meta.property-list.scss", "meta.property-name.scss"]
|
||||
@ -428,14 +428,14 @@ describe "TextMateGrammar", ->
|
||||
|
||||
describe "when the grammar's pattern name has a group number in it", ->
|
||||
it "replaces the group number with the matched captured text", ->
|
||||
atom.activatePackage('hyperlink-helper-tmbundle', sync: true)
|
||||
atom.activatePackage('language-hyperlink', sync: true)
|
||||
grammar = syntax.grammarForScopeName("text.hyperlink")
|
||||
{tokens} = grammar.tokenizeLine("https://github.com")
|
||||
expect(tokens[0].scopes).toEqual ["text.hyperlink", "markup.underline.link.https.hyperlink"]
|
||||
|
||||
describe "when the grammar has an injection selector", ->
|
||||
it "includes the grammar's patterns when the selector matches the current scope in other grammars", ->
|
||||
atom.activatePackage('hyperlink-helper-tmbundle', sync: true)
|
||||
atom.activatePackage('language-hyperlink', sync: true)
|
||||
grammar = syntax.selectGrammar("text.js")
|
||||
{tokens} = grammar.tokenizeLine("var i; // http://github.com")
|
||||
|
||||
@ -454,7 +454,7 @@ describe "TextMateGrammar", ->
|
||||
expect(tokens[1].value).toBe " http://github.com"
|
||||
expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"]
|
||||
|
||||
atom.activatePackage('hyperlink-helper-tmbundle', sync: true)
|
||||
atom.activatePackage('language-hyperlink', sync: true)
|
||||
|
||||
{tokens} = editSession.lineForScreenRow(0)
|
||||
expect(tokens[2].value).toBe "http://github.com"
|
||||
@ -481,7 +481,7 @@ describe "TextMateGrammar", ->
|
||||
expect(tokens[1].value).toBe " SELECT * FROM OCTOCATS"
|
||||
expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"]
|
||||
|
||||
atom.activatePackage('sql-tmbundle', sync: true)
|
||||
atom.activatePackage('language-sql', sync: true)
|
||||
|
||||
{tokens} = editSession.lineForScreenRow(0)
|
||||
expect(tokens[2].value).toBe "SELECT"
|
||||
@ -514,7 +514,7 @@ describe "TextMateGrammar", ->
|
||||
lines = null
|
||||
|
||||
beforeEach ->
|
||||
atom.activatePackage('todo-tmbundle', sync: true)
|
||||
atom.activatePackage('language-todo', sync: true)
|
||||
grammar = syntax.selectGrammar('main.rb')
|
||||
lines = grammar.tokenizeLines "# TODO be nicer"
|
||||
|
||||
@ -528,7 +528,7 @@ describe "TextMateGrammar", ->
|
||||
|
||||
describe "Git commit messages", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('git-tmbundle', sync: true)
|
||||
atom.activatePackage('language-git', sync: true)
|
||||
grammar = syntax.selectGrammar('COMMIT_EDITMSG')
|
||||
lines = grammar.tokenizeLines """
|
||||
longggggggggggggggggggggggggggggggggggggggggggggggg
|
||||
@ -547,7 +547,7 @@ describe "TextMateGrammar", ->
|
||||
|
||||
describe "C++", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('c-tmbundle', sync: true)
|
||||
atom.activatePackage('language-c', sync: true)
|
||||
grammar = syntax.selectGrammar('includes.cc')
|
||||
lines = grammar.tokenizeLines """
|
||||
#include "a.h"
|
||||
@ -585,8 +585,8 @@ describe "TextMateGrammar", ->
|
||||
|
||||
describe "Objective-C", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('c-tmbundle', sync: true)
|
||||
atom.activatePackage('objective-c-tmbundle', sync: true)
|
||||
atom.activatePackage('language-c', sync: true)
|
||||
atom.activatePackage('language-objective-c', sync: true)
|
||||
grammar = syntax.selectGrammar('function.mm')
|
||||
lines = grammar.tokenizeLines """
|
||||
void test() {
|
||||
@ -612,7 +612,7 @@ describe "TextMateGrammar", ->
|
||||
|
||||
describe "Java", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('java-tmbundle', sync: true)
|
||||
atom.activatePackage('language-java', sync: true)
|
||||
grammar = syntax.selectGrammar('Function.java')
|
||||
|
||||
it "correctly parses single line comments", ->
|
||||
@ -664,7 +664,7 @@ describe "TextMateGrammar", ->
|
||||
|
||||
describe "when the line contains unicode characters", ->
|
||||
it "correctly parses tokens starting after them", ->
|
||||
atom.activatePackage('json-tmbundle', sync: true)
|
||||
atom.activatePackage('language-json', sync: true)
|
||||
grammar = syntax.selectGrammar('package.json')
|
||||
{tokens} = grammar.tokenizeLine '{"\u2026": 1}'
|
||||
|
||||
|
@ -8,10 +8,25 @@ describe "ThemeManager", ->
|
||||
themeManager = null
|
||||
|
||||
beforeEach ->
|
||||
themeManager = new ThemeManager()
|
||||
themeManager = new ThemeManager(atom.packages)
|
||||
|
||||
afterEach ->
|
||||
themeManager.unload()
|
||||
themeManager.deactivateThemes()
|
||||
|
||||
describe "theme getters and setters", ->
|
||||
beforeEach ->
|
||||
atom.packages.loadPackages()
|
||||
|
||||
it 'getLoadedThemes get all the loaded themes', ->
|
||||
themes = themeManager.getLoadedThemes()
|
||||
expect(themes.length).toBeGreaterThan(2)
|
||||
|
||||
it 'getActiveThemes get all the active themes', ->
|
||||
themeManager.activateThemes()
|
||||
names = atom.config.get('core.themes')
|
||||
expect(names.length).toBeGreaterThan(0)
|
||||
themes = themeManager.getActiveThemes()
|
||||
expect(themes).toHaveLength(names.length)
|
||||
|
||||
describe "getImportPaths()", ->
|
||||
it "returns the theme directories before the themes are loaded", ->
|
||||
@ -32,7 +47,7 @@ describe "ThemeManager", ->
|
||||
it "add/removes stylesheets to reflect the new config value", ->
|
||||
themeManager.on 'reloaded', reloadHandler = jasmine.createSpy()
|
||||
spyOn(themeManager, 'getUserStylesheetPath').andCallFake -> null
|
||||
themeManager.load()
|
||||
themeManager.activateThemes()
|
||||
|
||||
config.set('core.themes', [])
|
||||
expect($('style.theme').length).toBe 0
|
||||
@ -59,21 +74,7 @@ describe "ThemeManager", ->
|
||||
describe "when a theme fails to load", ->
|
||||
it "logs a warning", ->
|
||||
spyOn(console, 'warn')
|
||||
themeManager.activateTheme('a-theme-that-will-not-be-found')
|
||||
expect(console.warn).toHaveBeenCalled()
|
||||
|
||||
describe "theme-loaded event", ->
|
||||
beforeEach ->
|
||||
spyOn(themeManager, 'getUserStylesheetPath').andCallFake -> null
|
||||
themeManager.load()
|
||||
|
||||
it "fires when a new theme has been added", ->
|
||||
themeManager.on 'theme-activated', loadHandler = jasmine.createSpy()
|
||||
|
||||
config.set('core.themes', ['atom-dark-syntax'])
|
||||
|
||||
expect(loadHandler).toHaveBeenCalled()
|
||||
expect(loadHandler.mostRecentCall.args[0]).toBeInstanceOf AtomPackage
|
||||
expect(-> atom.packages.activatePackage('a-theme-that-will-not-be-found')).toThrow()
|
||||
|
||||
describe "requireStylesheet(path)", ->
|
||||
it "synchronously loads css at the given path and installs a style tag for it in the head", ->
|
||||
@ -140,7 +141,7 @@ describe "ThemeManager", ->
|
||||
window.rootView = new RootView
|
||||
rootView.append $$ -> @div class: 'editor'
|
||||
rootView.attachToDom()
|
||||
themeManager.load()
|
||||
themeManager.activateThemes()
|
||||
|
||||
it "loads the correct values from the theme's ui-variables file", ->
|
||||
config.set('core.themes', ['theme-with-ui-variables'])
|
||||
|
@ -5,7 +5,7 @@ describe "TokenizedBuffer", ->
|
||||
[tokenizedBuffer, buffer, changeHandler] = []
|
||||
|
||||
beforeEach ->
|
||||
atom.activatePackage('javascript-tmbundle', sync: true)
|
||||
atom.activatePackage('language-javascript', sync: true)
|
||||
# enable async tokenization
|
||||
TokenizedBuffer.prototype.chunkSize = 5
|
||||
jasmine.unspy(TokenizedBuffer.prototype, 'tokenizeInBackground')
|
||||
@ -319,7 +319,7 @@ describe "TokenizedBuffer", ->
|
||||
|
||||
describe "when the buffer contains hard-tabs", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('coffee-script-tmbundle', sync: true)
|
||||
atom.activatePackage('language-coffee-script', sync: true)
|
||||
buffer = project.bufferForPathSync('sample-with-tabs.coffee')
|
||||
tokenizedBuffer = new TokenizedBuffer({buffer})
|
||||
startTokenizing(tokenizedBuffer)
|
||||
@ -349,7 +349,7 @@ describe "TokenizedBuffer", ->
|
||||
|
||||
describe "when the buffer contains surrogate pairs", ->
|
||||
beforeEach ->
|
||||
atom.activatePackage('javascript-tmbundle', sync: true)
|
||||
atom.activatePackage('language-javascript', sync: true)
|
||||
buffer = project.buildBufferSync 'sample-with-pairs.js', """
|
||||
'abc\uD835\uDF97def'
|
||||
//\uD835\uDF97xyz
|
||||
@ -386,8 +386,8 @@ describe "TokenizedBuffer", ->
|
||||
|
||||
describe "when the grammar is updated because a grammar it includes is activated", ->
|
||||
it "retokenizes the buffer", ->
|
||||
atom.activatePackage('ruby-on-rails-tmbundle', sync: true)
|
||||
atom.activatePackage('ruby-tmbundle', sync: true)
|
||||
atom.activatePackage('language-ruby-on-rails', sync: true)
|
||||
atom.activatePackage('language-ruby', sync: true)
|
||||
|
||||
buffer = project.bufferForPathSync(null, "<div class='name'><%= User.find(2).full_name %></div>")
|
||||
tokenizedBuffer = new TokenizedBuffer({buffer})
|
||||
@ -397,7 +397,7 @@ describe "TokenizedBuffer", ->
|
||||
{tokens} = tokenizedBuffer.lineForScreenRow(0)
|
||||
expect(tokens[0]).toEqual value: "<div class='name'>", scopes: ["text.html.ruby"]
|
||||
|
||||
atom.activatePackage('html-tmbundle', sync: true)
|
||||
atom.activatePackage('language-html', sync: true)
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
{tokens} = tokenizedBuffer.lineForScreenRow(0)
|
||||
expect(tokens[0]).toEqual value: '<', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.begin.html"]
|
||||
|
@ -25,20 +25,18 @@ class AtomPackage extends Package
|
||||
resolvedMainModulePath: false
|
||||
mainModule: null
|
||||
|
||||
constructor: (path, {@metadata}) ->
|
||||
super(path)
|
||||
@reset()
|
||||
|
||||
getType: -> 'atom'
|
||||
|
||||
load: ->
|
||||
@metadata = {}
|
||||
@stylesheets = []
|
||||
@keymaps = []
|
||||
@menus = []
|
||||
@grammars = []
|
||||
@scopedProperties = []
|
||||
getStylesheetType: -> 'bundled'
|
||||
|
||||
load: ->
|
||||
@measure 'loadTime', =>
|
||||
try
|
||||
@metadata = Package.loadMetadata(@path)
|
||||
return if @isTheme()
|
||||
@metadata ?= Package.loadMetadata(@path)
|
||||
|
||||
@loadKeymaps()
|
||||
@loadMenus()
|
||||
@ -55,9 +53,21 @@ class AtomPackage extends Package
|
||||
console.warn "Failed to load package named '#{@name}'", e.stack ? e
|
||||
this
|
||||
|
||||
enable: ->
|
||||
atom.config.removeAtKeyPath('core.disabledPackages', @metadata.name)
|
||||
|
||||
disable: ->
|
||||
atom.config.pushAtKeyPath('core.disabledPackages', @metadata.name)
|
||||
|
||||
reset: ->
|
||||
@stylesheets = []
|
||||
@keymaps = []
|
||||
@menus = []
|
||||
@grammars = []
|
||||
@scopedProperties = []
|
||||
|
||||
activate: ({immediate}={}) ->
|
||||
@measure 'activateTime', =>
|
||||
@loadStylesheets() if @isTheme()
|
||||
@activateResources()
|
||||
if @metadata.activationEvents? and not immediate
|
||||
@subscribeToActivationEvents()
|
||||
@ -69,7 +79,7 @@ class AtomPackage extends Package
|
||||
@activateConfig()
|
||||
@activateStylesheets()
|
||||
if @requireMainModule()
|
||||
@mainModule.activate(atom.getPackageState(@name) ? {})
|
||||
@mainModule.activate(atom.packages.getPackageState(@name) ? {})
|
||||
@mainActivated = true
|
||||
catch e
|
||||
console.warn "Failed to activate package named '#{@name}'", e.stack
|
||||
@ -86,7 +96,7 @@ class AtomPackage extends Package
|
||||
activateStylesheets: ->
|
||||
return if @stylesheetsActivated
|
||||
|
||||
type = if @metadata.theme then 'theme' else 'bundled'
|
||||
type = @getStylesheetType()
|
||||
for [stylesheetPath, content] in @stylesheets
|
||||
atom.themes.applyStylesheet(stylesheetPath, content, type)
|
||||
@stylesheetsActivated = true
|
||||
@ -183,8 +193,7 @@ class AtomPackage extends Package
|
||||
@reloadStylesheet(stylesheetPath, content) for [stylesheetPath, content] in @stylesheets
|
||||
|
||||
reloadStylesheet: (stylesheetPath, content) ->
|
||||
type = if @metadata.theme then 'theme' else 'bundled'
|
||||
atom.themes.applyStylesheet(stylesheetPath, content, type)
|
||||
atom.themes.applyStylesheet(stylesheetPath, content, @getStylesheetType())
|
||||
|
||||
requireMainModule: ->
|
||||
return @mainModule if @mainModule?
|
||||
|
@ -14,6 +14,7 @@ shell = require 'shell'
|
||||
{$$} = require 'space-pen'
|
||||
crypto = require 'crypto'
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
dialog = remote.require 'dialog'
|
||||
app = remote.require 'app'
|
||||
{Document} = require 'telepath'
|
||||
@ -55,7 +56,7 @@ class Atom
|
||||
@__defineSetter__ 'packageStates', (packageStates) => @packages.packageStates = packageStates
|
||||
|
||||
@subscribe @packages, 'loaded', => @watchThemes()
|
||||
@themes = new ThemeManager()
|
||||
@themes = new ThemeManager(@packages)
|
||||
@contextMenu = new ContextMenuManager(devMode)
|
||||
@menu = new MenuManager()
|
||||
@pasteboard = new Pasteboard()
|
||||
@ -220,6 +221,9 @@ class Atom
|
||||
inDevMode: ->
|
||||
@getLoadSettings().devMode
|
||||
|
||||
inSpecMode: ->
|
||||
@getLoadSettings().isSpec
|
||||
|
||||
toggleFullScreen: ->
|
||||
@setFullScreen(!@isFullScreen())
|
||||
|
||||
@ -230,7 +234,10 @@ class Atom
|
||||
@getCurrentWindow().isFullScreen()
|
||||
|
||||
getHomeDirPath: ->
|
||||
app.getHomeDir()
|
||||
process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME']
|
||||
|
||||
getTempDirPath: ->
|
||||
if process.platform is 'win32' then os.tmpdir() else '/tmp'
|
||||
|
||||
# Public: Get the directory path to Atom's configuration area.
|
||||
getConfigDirPath: ->
|
||||
|
@ -8,13 +8,14 @@ dialog = require 'dialog'
|
||||
fs = require 'fs'
|
||||
ipc = require 'ipc'
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
net = require 'net'
|
||||
shell = require 'shell'
|
||||
url = require 'url'
|
||||
{EventEmitter} = require 'events'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
socketPath = '/tmp/atom.sock'
|
||||
socketPath = path.join(os.tmpdir(), 'atom.sock')
|
||||
|
||||
# Private: The application's singleton class.
|
||||
#
|
||||
@ -245,7 +246,7 @@ class AtomApplication
|
||||
[basename, initialLine] = path.basename(pathToOpen).split(':')
|
||||
if initialLine
|
||||
pathToOpen = "#{path.dirname(pathToOpen)}/#{basename}"
|
||||
initialLine -= 1 if initialLine # Convert line numbers to a base of 0
|
||||
initialLine -= 1 # Convert line numbers to a base of 0
|
||||
|
||||
unless devMode
|
||||
existingWindow = @windowForPath(pathToOpen) unless pidToKillWhenClosed or newWindow
|
||||
|
@ -1,12 +1,14 @@
|
||||
crypto = require 'crypto'
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
|
||||
CoffeeScript = require 'coffee-script'
|
||||
CSON = require 'season'
|
||||
mkdir = require('mkdirp').sync
|
||||
|
||||
cacheDir = '/tmp/atom-compile-cache'
|
||||
tmpDir = if process.platform is 'win32' then os.tmpdir() else '/tmp'
|
||||
cacheDir = path.join(tmpDir, 'atom-compile-cache')
|
||||
coffeeCacheDir = path.join(cacheDir, 'coffee')
|
||||
CSON.setCacheDir(path.join(cacheDir, 'cson'))
|
||||
|
||||
|
@ -193,7 +193,7 @@ class Config
|
||||
# `callback` is fired whenever the value of the key is changed and will
|
||||
# be fired immediately unless the `callNow` option is `false`.
|
||||
#
|
||||
# keyPath - The {String} name of the key to watch
|
||||
# keyPath - The {String} name of the key to observe
|
||||
# options - An optional {Object} containing the `callNow` key.
|
||||
# callback - The {Function} that fires when the. It is given a single argument, `value`,
|
||||
# which is the new value of `keyPath`.
|
||||
@ -207,14 +207,22 @@ class Config
|
||||
updateCallback = =>
|
||||
value = @get(keyPath)
|
||||
unless _.isEqual(value, previousValue)
|
||||
previous = previousValue
|
||||
previousValue = _.clone(value)
|
||||
callback(value)
|
||||
callback(value, {previous})
|
||||
|
||||
subscription = { cancel: => @off 'updated', updateCallback }
|
||||
@on 'updated', updateCallback
|
||||
@on "updated.#{keyPath.replace(/\./, '-')}", updateCallback
|
||||
callback(value) if options.callNow ? true
|
||||
subscription
|
||||
|
||||
|
||||
# Public: Unobserve all callbacks on a given key
|
||||
#
|
||||
# keyPath - The {String} name of the key to unobserve
|
||||
unobserve: (keyPath) ->
|
||||
@off("updated.#{keyPath.replace(/\./, '-')}")
|
||||
|
||||
# Private:
|
||||
update: ->
|
||||
return if @configFileHasErrors
|
||||
|
@ -13,10 +13,12 @@ fsExtensions =
|
||||
absolute: (relativePath) ->
|
||||
return null unless relativePath?
|
||||
|
||||
homeDir = process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME']
|
||||
|
||||
if relativePath is '~'
|
||||
relativePath = process.env.HOME
|
||||
relativePath = homeDir
|
||||
else if relativePath.indexOf('~/') is 0
|
||||
relativePath = "#{process.env.HOME}#{relativePath.substring(1)}"
|
||||
relativePath = "#{homeDir}#{relativePath.substring(1)}"
|
||||
|
||||
try
|
||||
fs.realpathSync(relativePath)
|
||||
|
@ -1,12 +1,15 @@
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
LessCache = require 'less-cache'
|
||||
{Subscriber} = require 'emissary'
|
||||
|
||||
tmpDir = if process.platform is 'win32' then os.tmpdir() else '/tmp'
|
||||
|
||||
module.exports =
|
||||
class LessCompileCache
|
||||
Subscriber.includeInto(this)
|
||||
|
||||
@cacheDir: '/tmp/atom-compile-cache/less'
|
||||
@cacheDir: path.join(tmpDir, 'atom-compile-cache', 'less')
|
||||
|
||||
constructor: ->
|
||||
@cache = new LessCache
|
||||
|
@ -30,7 +30,10 @@ class MenuManager
|
||||
|
||||
# Public: Refreshes the currently visible menu.
|
||||
update: ->
|
||||
@sendToBrowserProcess(@template, atom.keymap.keystrokesByCommandForSelector('body'))
|
||||
keystrokesByCommand = atom.keymap.keystrokesByCommandForSelector('body')
|
||||
_.extend(keystrokesByCommand, atom.keymap.keystrokesByCommandForSelector('.editor'))
|
||||
_.extend(keystrokesByCommand, atom.keymap.keystrokesByCommandForSelector('.editor:not(.mini)'))
|
||||
@sendToBrowserProcess(@template, keystrokesByCommand)
|
||||
|
||||
# Private
|
||||
loadCoreItems: ->
|
||||
@ -49,6 +52,20 @@ class MenuManager
|
||||
else
|
||||
menu.push(item) unless _.find(menu, (i) -> i.label == item.label)
|
||||
|
||||
# Private: OSX can't handle displaying accelerators for multiple keystrokes.
|
||||
# If they are sent across, it will stop processing accelerators for the rest
|
||||
# of the menu items.
|
||||
filterMultipleKeystrokes: (keystrokesByCommand) ->
|
||||
filtered = {}
|
||||
for key, bindings of keystrokesByCommand
|
||||
for binding in bindings
|
||||
continue if binding.indexOf(' ') != -1
|
||||
|
||||
filtered[key] ?= []
|
||||
filtered[key].push(binding)
|
||||
filtered
|
||||
|
||||
# Private
|
||||
sendToBrowserProcess: (template, keystrokesByCommand) ->
|
||||
keystrokesByCommand = @filterMultipleKeystrokes(keystrokesByCommand)
|
||||
ipc.sendChannel 'update-application-menu', template, keystrokesByCommand
|
||||
|
@ -4,6 +4,21 @@ _ = require 'underscore-plus'
|
||||
Package = require './package'
|
||||
path = require 'path'
|
||||
|
||||
###
|
||||
Packages have a lifecycle
|
||||
|
||||
* The paths to all non-disabled packages and themes are found on disk (these are available packages)
|
||||
* Every package (except those in core.disabledPackages) is 'loaded', meaning
|
||||
`Package` objects are created, and their metadata loaded. This includes themes,
|
||||
as themes are packages
|
||||
* The ThemeManager.activateThemes() is called 'activating' all the themes, meaning
|
||||
their stylesheets are loaded into the window.
|
||||
* The PackageManager.activatePackages() function is called 'activating' non-theme
|
||||
package, meaning its resources -- keymaps, classes, etc. -- are loaded, and
|
||||
the package's activate() method is called.
|
||||
* Packages and themes can then be enabled and disabled via the public
|
||||
.enablePackage(name) and .disablePackage(name) functions.
|
||||
###
|
||||
module.exports =
|
||||
class PackageManager
|
||||
Emitter.includeInto(this)
|
||||
@ -16,6 +31,14 @@ class PackageManager
|
||||
@loadedPackages = {}
|
||||
@activePackages = {}
|
||||
@packageStates = {}
|
||||
@observingDisabledPackages = false
|
||||
|
||||
@packageActivators = []
|
||||
@registerPackageActivator(this, ['atom', 'textmate'])
|
||||
|
||||
# Public: Get the path to the apm command
|
||||
getApmPath: ->
|
||||
@apmPath ?= require.resolve('atom-package-manager/bin/apm')
|
||||
|
||||
getPackageState: (name) ->
|
||||
@packageStates[name]
|
||||
@ -23,10 +46,37 @@ class PackageManager
|
||||
setPackageState: (name, state) ->
|
||||
@packageStates[name] = state
|
||||
|
||||
activatePackages: ->
|
||||
@activatePackage(pack.name) for pack in @getLoadedPackages()
|
||||
# Public:
|
||||
enablePackage: (name) ->
|
||||
pack = @loadPackage(name)
|
||||
pack?.enable()
|
||||
pack
|
||||
|
||||
# Public:
|
||||
disablePackage: (name) ->
|
||||
pack = @loadPackage(name)
|
||||
pack?.disable()
|
||||
pack
|
||||
|
||||
# Internal-only: Activate all the packages that should be activated.
|
||||
activate: ->
|
||||
for [activator, types] in @packageActivators
|
||||
packages = @getLoadedPackagesForTypes(types)
|
||||
activator.activatePackages(packages)
|
||||
|
||||
# Public: another type of package manager can handle other package types.
|
||||
# See ThemeManager
|
||||
registerPackageActivator: (activator, types) ->
|
||||
@packageActivators.push([activator, types])
|
||||
|
||||
# Internal-only:
|
||||
activatePackages: (packages) ->
|
||||
@activatePackage(pack.name) for pack in packages
|
||||
@observeDisabledPackages()
|
||||
|
||||
# Internal-only: Activate a single package by name
|
||||
activatePackage: (name, options) ->
|
||||
return pack if pack = @getActivePackage(name)
|
||||
if pack = @loadPackage(name, options)
|
||||
@activePackages[pack.name] = pack
|
||||
pack.activate(options)
|
||||
@ -34,6 +84,7 @@ class PackageManager
|
||||
|
||||
deactivatePackages: ->
|
||||
@deactivatePackage(pack.name) for pack in @getActivePackages()
|
||||
@unobserveDisabledPackages()
|
||||
|
||||
deactivatePackage: (name) ->
|
||||
if pack = @getActivePackage(name)
|
||||
@ -43,14 +94,32 @@ class PackageManager
|
||||
else
|
||||
throw new Error("No active package for name '#{name}'")
|
||||
|
||||
getActivePackages: ->
|
||||
_.values(@activePackages)
|
||||
|
||||
getActivePackage: (name) ->
|
||||
@activePackages[name]
|
||||
|
||||
isPackageActive: (name) ->
|
||||
@getActivePackage(name)?
|
||||
|
||||
getActivePackages: ->
|
||||
_.values(@activePackages)
|
||||
unobserveDisabledPackages: ->
|
||||
return unless @observingDisabledPackages
|
||||
config.unobserve('core.disabledPackages')
|
||||
@observingDisabledPackages = false
|
||||
|
||||
observeDisabledPackages: ->
|
||||
return if @observingDisabledPackages
|
||||
|
||||
config.observe 'core.disabledPackages', callNow: false, (disabledPackages, {previous}) =>
|
||||
packagesToEnable = _.difference(previous, disabledPackages)
|
||||
packagesToDisable = _.difference(disabledPackages, previous)
|
||||
|
||||
@deactivatePackage(packageName) for packageName in packagesToDisable when @getActivePackage(packageName)
|
||||
@activatePackage(packageName) for packageName in packagesToEnable
|
||||
null
|
||||
|
||||
@observingDisabledPackages = true
|
||||
|
||||
loadPackages: ->
|
||||
# Ensure atom exports is already in the require cache so the load time
|
||||
@ -61,21 +130,19 @@ class PackageManager
|
||||
@emit 'loaded'
|
||||
|
||||
loadPackage: (name, options) ->
|
||||
if @isPackageDisabled(name)
|
||||
return console.warn("Tried to load disabled package '#{name}'")
|
||||
|
||||
if packagePath = @resolvePackagePath(name)
|
||||
return pack if pack = @getLoadedPackage(name)
|
||||
|
||||
pack = Package.load(packagePath, options)
|
||||
if pack.metadata?.theme
|
||||
atom.themes.register(pack)
|
||||
else
|
||||
@loadedPackages[pack.name] = pack
|
||||
@loadedPackages[pack.name] = pack if pack?
|
||||
pack
|
||||
else
|
||||
throw new Error("Could not resolve '#{name}' to a package path")
|
||||
|
||||
unloadPackages: ->
|
||||
@unloadPackage(name) for name in _.keys(@loadedPackages)
|
||||
null
|
||||
|
||||
unloadPackage: (name) ->
|
||||
if @isPackageActive(name)
|
||||
throw new Error("Tried to unload active package '#{name}'")
|
||||
@ -85,19 +152,6 @@ class PackageManager
|
||||
else
|
||||
throw new Error("No loaded package for name '#{name}'")
|
||||
|
||||
resolvePackagePath: (name) ->
|
||||
return name if fsUtils.isDirectorySync(name)
|
||||
|
||||
packagePath = fsUtils.resolve(@packageDirPaths..., name)
|
||||
return packagePath if fsUtils.isDirectorySync(packagePath)
|
||||
|
||||
packagePath = path.join(@resourcePath, 'node_modules', name)
|
||||
return packagePath if @isInternalPackage(packagePath)
|
||||
|
||||
isInternalPackage: (packagePath) ->
|
||||
{engines} = Package.loadMetadata(packagePath, true)
|
||||
engines?.atom?
|
||||
|
||||
getLoadedPackage: (name) ->
|
||||
@loadedPackages[name]
|
||||
|
||||
@ -107,9 +161,28 @@ class PackageManager
|
||||
getLoadedPackages: ->
|
||||
_.values(@loadedPackages)
|
||||
|
||||
# Private: Get packages for a certain package type
|
||||
#
|
||||
# * types: an {Array} of {String}s like ['atom', 'textmate']
|
||||
getLoadedPackagesForTypes: (types) ->
|
||||
pack for pack in @getLoadedPackages() when pack.getType() in types
|
||||
|
||||
resolvePackagePath: (name) ->
|
||||
return name if fsUtils.isDirectorySync(name)
|
||||
|
||||
packagePath = fsUtils.resolve(@packageDirPaths..., name)
|
||||
return packagePath if fsUtils.isDirectorySync(packagePath)
|
||||
|
||||
packagePath = path.join(@resourcePath, 'node_modules', name)
|
||||
return packagePath if @isInternalPackage(packagePath)
|
||||
|
||||
isPackageDisabled: (name) ->
|
||||
_.include(config.get('core.disabledPackages') ? [], name)
|
||||
|
||||
isInternalPackage: (packagePath) ->
|
||||
{engines} = Package.loadMetadata(packagePath, true)
|
||||
engines?.atom?
|
||||
|
||||
getAvailablePackagePaths: ->
|
||||
packagePaths = []
|
||||
|
||||
|
@ -7,15 +7,25 @@ class Package
|
||||
@build: (path) ->
|
||||
TextMatePackage = require './text-mate-package'
|
||||
AtomPackage = require './atom-package'
|
||||
ThemePackage = require './theme-package'
|
||||
|
||||
if TextMatePackage.testName(path)
|
||||
new TextMatePackage(path)
|
||||
pack = new TextMatePackage(path)
|
||||
else
|
||||
new AtomPackage(path)
|
||||
try
|
||||
metadata = @loadMetadata(path)
|
||||
if metadata.theme
|
||||
pack = new ThemePackage(path, {metadata})
|
||||
else
|
||||
pack = new AtomPackage(path, {metadata})
|
||||
catch e
|
||||
console.warn "Failed to load package.json '#{basename(path)}'", e.stack ? e
|
||||
|
||||
pack
|
||||
|
||||
@load: (path, options) ->
|
||||
pack = @build(path)
|
||||
pack.load(options)
|
||||
pack?.load(options)
|
||||
pack
|
||||
|
||||
@loadMetadata: (path, ignoreErrors=false) ->
|
||||
|
@ -10,7 +10,8 @@ async = require 'async'
|
||||
module.exports =
|
||||
class TextMatePackage extends Package
|
||||
@testName: (packageName) ->
|
||||
/(\.|_|-)tmbundle$/.test(packageName)
|
||||
packageName = path.basename(packageName)
|
||||
/(^language-.+)|((\.|_|-)tmbundle$)/.test(packageName)
|
||||
|
||||
@getLoadQueue: ->
|
||||
return @loadQueue if @loadQueue
|
||||
|
@ -8,31 +8,95 @@ _ = require 'underscore-plus'
|
||||
fsUtils = require './fs-utils'
|
||||
|
||||
# Private: Handles discovering and loading available themes.
|
||||
###
|
||||
Themes are a subset of packages
|
||||
###
|
||||
module.exports =
|
||||
class ThemeManager
|
||||
Emitter.includeInto(this)
|
||||
|
||||
constructor: ->
|
||||
@loadedThemes = []
|
||||
@activeThemes = []
|
||||
constructor: (@packageManager) ->
|
||||
@lessCache = null
|
||||
|
||||
# Internal-only:
|
||||
register: (theme) ->
|
||||
@loadedThemes.push(theme)
|
||||
theme
|
||||
@packageManager.registerPackageActivator(this, ['theme'])
|
||||
|
||||
# Internal-only:
|
||||
getAvailableNames: ->
|
||||
_.map @loadedThemes, (theme) -> theme.metadata.name
|
||||
# TODO: Maybe should change to list all the available themes out there?
|
||||
@getLoadedNames()
|
||||
|
||||
getLoadedNames: ->
|
||||
theme.name for theme in @getLoadedThemes()
|
||||
|
||||
# Internal-only:
|
||||
getActiveNames: ->
|
||||
theme.name for theme in @getActiveThemes()
|
||||
|
||||
# Internal-only:
|
||||
getActiveThemes: ->
|
||||
_.clone(@activeThemes)
|
||||
pack for pack in @packageManager.getActivePackages() when pack.isTheme()
|
||||
|
||||
# Internal-only:
|
||||
getLoadedThemes: ->
|
||||
_.clone(@loadedThemes)
|
||||
pack for pack in @packageManager.getLoadedPackages() when pack.isTheme()
|
||||
|
||||
# Internal-only: adhere to the PackageActivator interface
|
||||
activatePackages: (themePackages) -> @activateThemes()
|
||||
|
||||
# Internal-only:
|
||||
activateThemes: ->
|
||||
# atom.config.observe runs the callback once, then on subsequent changes.
|
||||
atom.config.observe 'core.themes', (themeNames) =>
|
||||
@deactivateThemes()
|
||||
themeNames = [themeNames] unless _.isArray(themeNames)
|
||||
|
||||
# Reverse so the first (top) theme is loaded after the others. We want
|
||||
# the first/top theme to override later themes in the stack.
|
||||
themeNames = _.clone(themeNames).reverse()
|
||||
|
||||
@packageManager.activatePackage(themeName) for themeName in themeNames
|
||||
@loadUserStylesheet()
|
||||
@reloadBaseStylesheets()
|
||||
@emit('reloaded')
|
||||
|
||||
# Internal-only:
|
||||
deactivateThemes: ->
|
||||
@removeStylesheet(@userStylesheetPath) if @userStylesheetPath?
|
||||
@packageManager.deactivatePackage(pack.name) for pack in @getActiveThemes()
|
||||
null
|
||||
|
||||
# Public: Set the list of enabled themes.
|
||||
#
|
||||
# * enabledThemeNames: An {Array} of {String} theme names.
|
||||
setEnabledThemes: (enabledThemeNames) ->
|
||||
atom.config.set('core.themes', enabledThemeNames)
|
||||
|
||||
# Public:
|
||||
getImportPaths: ->
|
||||
activeThemes = @getActiveThemes()
|
||||
if activeThemes.length > 0
|
||||
themePaths = (theme.getStylesheetsPath() for theme in activeThemes when theme)
|
||||
else
|
||||
themePaths = []
|
||||
for themeName in atom.config.get('core.themes') ? []
|
||||
if themePath = @packageManager.resolvePackagePath(themeName)
|
||||
themePaths.push(path.join(themePath, AtomPackage.stylesheetsDir))
|
||||
|
||||
themePath for themePath in themePaths when fsUtils.isDirectorySync(themePath)
|
||||
|
||||
# Public:
|
||||
getUserStylesheetPath: ->
|
||||
stylesheetPath = fsUtils.resolve(path.join(atom.config.configDirPath, 'user'), ['css', 'less'])
|
||||
if fsUtils.isFileSync(stylesheetPath)
|
||||
stylesheetPath
|
||||
else
|
||||
null
|
||||
|
||||
# Private:
|
||||
loadUserStylesheet: ->
|
||||
if userStylesheetPath = @getUserStylesheetPath()
|
||||
@userStylesheetPath = userStylesheetPath
|
||||
userStylesheetContents = @loadStylesheet(userStylesheetPath)
|
||||
@applyStylesheet(userStylesheetPath, userStylesheetContents, 'userTheme')
|
||||
|
||||
# Internal-only:
|
||||
loadBaseStylesheets: ->
|
||||
@ -109,91 +173,3 @@ class ThemeManager
|
||||
$("head style.#{ttype}:last").after "<style class='#{ttype}' id='#{id}'>#{text}</style>"
|
||||
else
|
||||
$("head").append "<style class='#{ttype}' id='#{id}'>#{text}</style>"
|
||||
|
||||
# Internal-only:
|
||||
unload: ->
|
||||
@removeStylesheet(@userStylesheetPath) if @userStylesheetPath?
|
||||
theme.deactivate() while theme = @activeThemes.pop()
|
||||
|
||||
# Internal-only:
|
||||
load: ->
|
||||
config.observe 'core.themes', (themeNames) =>
|
||||
@unload()
|
||||
themeNames = [themeNames] unless _.isArray(themeNames)
|
||||
|
||||
# Reverse so the first (top) theme is loaded after the others. We want
|
||||
# the first/top theme to override later themes in the stack.
|
||||
themeNames = _.clone(themeNames).reverse()
|
||||
|
||||
@activateTheme(themeName) for themeName in themeNames
|
||||
@loadUserStylesheet()
|
||||
@reloadBaseStylesheets()
|
||||
@emit('reloaded')
|
||||
|
||||
# Private:
|
||||
loadTheme: (name, options) ->
|
||||
if themePath = @resolveThemePath(name)
|
||||
return theme if theme = @getLoadedTheme(name)
|
||||
pack = Package.load(themePath, options)
|
||||
if pack.isTheme()
|
||||
@register(pack)
|
||||
else
|
||||
throw new Error("Attempted to load a non-theme package '#{name}' as a theme")
|
||||
else
|
||||
throw new Error("Could not resolve '#{name}' to a theme path")
|
||||
|
||||
# Private:
|
||||
getLoadedTheme: (name) ->
|
||||
_.find @loadedThemes, (theme) -> theme.metadata.name is name
|
||||
|
||||
# Private:
|
||||
resolveThemePath: (name) ->
|
||||
return name if fsUtils.isDirectorySync(name)
|
||||
|
||||
packagePath = fsUtils.resolve(config.packageDirPaths..., name)
|
||||
return packagePath if fsUtils.isDirectorySync(packagePath)
|
||||
|
||||
packagePath = path.join(window.resourcePath, 'node_modules', name)
|
||||
return packagePath if @isThemePath(packagePath)
|
||||
|
||||
# Private:
|
||||
isThemePath: (packagePath) ->
|
||||
{engines, theme} = Package.loadMetadata(packagePath, true)
|
||||
engines?.atom? and theme
|
||||
|
||||
# Private:
|
||||
activateTheme: (name) ->
|
||||
try
|
||||
theme = @loadTheme(name)
|
||||
theme.activate()
|
||||
@activeThemes.push(theme)
|
||||
@emit('theme-activated', theme)
|
||||
catch error
|
||||
console.warn("Failed to load theme #{name}", error.stack ? error)
|
||||
|
||||
# Public:
|
||||
getUserStylesheetPath: ->
|
||||
stylesheetPath = fsUtils.resolve(path.join(config.configDirPath, 'user'), ['css', 'less'])
|
||||
if fsUtils.isFileSync(stylesheetPath)
|
||||
stylesheetPath
|
||||
else
|
||||
null
|
||||
|
||||
# Public:
|
||||
getImportPaths: ->
|
||||
if @activeThemes.length > 0
|
||||
themePaths = (theme.getStylesheetsPath() for theme in @activeThemes when theme)
|
||||
else
|
||||
themePaths = []
|
||||
for themeName in config.get('core.themes') ? []
|
||||
if themePath = @resolveThemePath(themeName)
|
||||
themePaths.push(path.join(themePath, AtomPackage.stylesheetsDir))
|
||||
|
||||
themePath for themePath in themePaths when fsUtils.isDirectorySync(themePath)
|
||||
|
||||
# Private:
|
||||
loadUserStylesheet: ->
|
||||
if userStylesheetPath = @getUserStylesheetPath()
|
||||
@userStylesheetPath = userStylesheetPath
|
||||
userStylesheetContents = @loadStylesheet(userStylesheetPath)
|
||||
@applyStylesheet(userStylesheetPath, userStylesheetContents, 'userTheme')
|
||||
|
32
src/theme-package.coffee
Normal file
32
src/theme-package.coffee
Normal file
@ -0,0 +1,32 @@
|
||||
AtomPackage = require './atom-package'
|
||||
Package = require './package'
|
||||
|
||||
### Internal: Loads and resolves packages. ###
|
||||
|
||||
module.exports =
|
||||
class ThemePackage extends AtomPackage
|
||||
|
||||
getType: -> 'theme'
|
||||
|
||||
getStylesheetType: -> 'theme'
|
||||
|
||||
enable: ->
|
||||
themes = atom.config.get('core.themes')
|
||||
themes = [@metadata.name].concat(themes)
|
||||
atom.config.set('core.themes', themes)
|
||||
|
||||
disable: ->
|
||||
atom.config.removeAtKeyPath('core.themes', @metadata.name)
|
||||
|
||||
load: ->
|
||||
@measure 'loadTime', =>
|
||||
try
|
||||
@metadata ?= Package.loadMetadata(@path)
|
||||
catch e
|
||||
console.warn "Failed to load theme named '#{@name}'", e.stack ? e
|
||||
this
|
||||
|
||||
activate: ->
|
||||
@measure 'activateTime', =>
|
||||
@loadStylesheets()
|
||||
@activateNow()
|
@ -51,9 +51,8 @@ window.startEditorWindow = ->
|
||||
atom.keymap.loadBundledKeymaps()
|
||||
atom.themes.loadBaseStylesheets()
|
||||
atom.packages.loadPackages()
|
||||
atom.themes.load()
|
||||
deserializeEditorWindow()
|
||||
atom.packages.activatePackages()
|
||||
atom.packages.activate()
|
||||
atom.keymap.loadUserKeymaps()
|
||||
atom.requireUserInitScript()
|
||||
atom.menu.update()
|
||||
|
2
static/bootstrap.less
vendored
2
static/bootstrap.less
vendored
@ -9,6 +9,6 @@
|
||||
}
|
||||
|
||||
&.nav-pills > li.active > a {
|
||||
background-color: @background-color-info;
|
||||
background-color: @background-color-selected;
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,21 @@
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{rm} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'partial-clean', 'Delete some of the build files', ->
|
||||
tmpdir = if process.platform is 'win32' then os.tmpdir() else '/tmp'
|
||||
|
||||
rm grunt.config.get('atom.buildDir')
|
||||
rm require('../src/coffee-cache').cacheDir
|
||||
rm require('../src/less-compile-cache').cacheDir
|
||||
rm '/tmp/atom-cached-atom-shells'
|
||||
rm path.join(tmpdir, 'atom-cached-atom-shells')
|
||||
rm 'atom-shell'
|
||||
|
||||
grunt.registerTask 'clean', 'Delete all the build files', ->
|
||||
homeDir = process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME']
|
||||
|
||||
rm 'node_modules'
|
||||
rm path.join(process.env.HOME, '.atom', '.node-gyp')
|
||||
rm path.join(homeDir, '.atom', '.node-gyp')
|
||||
grunt.task.run('partial-clean')
|
||||
|
108
tasks/publish-packages.coffee
Normal file
108
tasks/publish-packages.coffee
Normal file
@ -0,0 +1,108 @@
|
||||
async = require 'async'
|
||||
request = require 'request'
|
||||
|
||||
# Configure and publish all packages in package.json to atom.io
|
||||
#
|
||||
# This task should be run whenever you want to be sure that atom.io contains
|
||||
# all the packages and versions referenced in Atom's package.json file.
|
||||
module.exports = (grunt) ->
|
||||
{spawn} = require('./task-helpers')(grunt)
|
||||
|
||||
baseUrl = "https://www.atom.io/api/packages"
|
||||
|
||||
packageExists = (packageName, token, callback) ->
|
||||
requestSettings =
|
||||
url: "#{baseUrl}/#{packageName}"
|
||||
json: true
|
||||
headers:
|
||||
authorization: token
|
||||
request.get requestSettings, (error, response, body={}) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
callback(null, response.statusCode is 404)
|
||||
|
||||
createPackage = (packageName, token, callback) ->
|
||||
requestSettings =
|
||||
url: baseUrl
|
||||
json: true
|
||||
headers:
|
||||
authorization: token
|
||||
method: 'POST'
|
||||
body:
|
||||
repository: "atom/#{packageName}"
|
||||
|
||||
request.get requestSettings, (error, response, body={}) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else if response.statusCode isnt 201
|
||||
message = body.message ? body.error ? body
|
||||
callback(new Error("Creating package failed: #{message}"))
|
||||
else
|
||||
callback()
|
||||
|
||||
createPackageVersion = (packageName, tag, token, callback) ->
|
||||
requestSettings =
|
||||
url: "#{baseUrl}/#{packageName}/versions"
|
||||
json: true
|
||||
method: 'POST'
|
||||
headers:
|
||||
authorization: token
|
||||
body:
|
||||
tag: tag
|
||||
|
||||
request.get requestSettings, (error, response, body={}) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else if response.statusCode isnt 201
|
||||
message = body.message ? body.error ? body
|
||||
if message is 'Version exists'
|
||||
callback()
|
||||
else
|
||||
callback(new Error("Creating new version failed: #{message}"))
|
||||
else
|
||||
callback()
|
||||
|
||||
getToken = (callback) ->
|
||||
if token = process.env.ATOM_ACCESS_TOKEN
|
||||
callback(null, token)
|
||||
else
|
||||
spawn {cmd: 'security', args: ['-q', 'find-generic-password', '-ws', 'GitHub API Token']}, (error, result, code) ->
|
||||
token = result.toString() unless error?
|
||||
callback(error, token)
|
||||
|
||||
grunt.registerTask 'publish-packages', 'Publish all bundled packages', ->
|
||||
done = @async()
|
||||
|
||||
getToken (error, token) ->
|
||||
unless token
|
||||
grunt.log.error('Token not found in keychain or ATOM_ACCESS_TOKEN environment variable')
|
||||
done(false)
|
||||
|
||||
{packageDependencies} = grunt.file.readJSON('package.json') ? {}
|
||||
tasks = []
|
||||
for name, version of packageDependencies
|
||||
do (name, version) ->
|
||||
tasks.push (callback) ->
|
||||
grunt.log.writeln("Publishing #{name}@#{version}")
|
||||
tag = "v#{version}"
|
||||
packageExists name, token, (error, exists) ->
|
||||
if error?
|
||||
callback(error)
|
||||
return
|
||||
|
||||
if exists
|
||||
createPackage name, token, (error) ->
|
||||
if error?
|
||||
callback(error)
|
||||
else
|
||||
createPackageVersion(name, tag, token, callback)
|
||||
else
|
||||
createPackageVersion(name, tag, token, callback)
|
||||
|
||||
async.waterfall tasks, (error) ->
|
||||
if error?
|
||||
grunt.log.error(error.message)
|
||||
done(false)
|
||||
else
|
||||
done()
|
@ -1,5 +1,6 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
|
||||
request = require 'request'
|
||||
formidable = require 'formidable'
|
||||
@ -70,7 +71,11 @@ module.exports = (grunt) ->
|
||||
else
|
||||
null
|
||||
|
||||
getCachePath = (version) -> "/tmp/atom-cached-atom-shells/#{version}"
|
||||
getTempDir = ->
|
||||
if process.platform is 'win32' then os.tmpdir() else '/tmp'
|
||||
|
||||
getCachePath = (version) ->
|
||||
path.join(getTempDir(), 'atom-cached-atom-shells', version)
|
||||
|
||||
isAtomShellVersionCached = (version) ->
|
||||
grunt.file.isFile(getCachePath(version), 'version')
|
||||
|
2
vendor/apm
vendored
2
vendor/apm
vendored
@ -1 +1 @@
|
||||
Subproject commit 6ef00ae8b1fc7c6ca96f6ce38859cd31db1f7430
|
||||
Subproject commit 0bd38255ea0aa0fec2a932177b30a388c2d16ded
|
Loading…
Reference in New Issue
Block a user