mirror of
https://github.com/atom/atom.git
synced 2026-01-23 13:58:08 -05:00
Merge branch 'master' into farnabaz-master
This commit is contained in:
15
README.md
15
README.md
@@ -1,6 +1,6 @@
|
||||

|
||||
|
||||
[](https://circleci.com/gh/atom/atom) [](https://travis-ci.org/atom/atom) [](https://ci.appveyor.com/project/Atom/atom)
|
||||
[](https://circleci.com/gh/atom/atom) [](https://travis-ci.org/atom/atom) [](https://ci.appveyor.com/project/Atom/atom)
|
||||
[](https://david-dm.org/atom/atom)
|
||||
[](http://atom-slack.herokuapp.com/)
|
||||
|
||||
@@ -33,15 +33,14 @@ Atom will automatically update when a new release is available.
|
||||
|
||||
### Windows
|
||||
|
||||
Download the latest [AtomSetup.exe installer](https://github.com/atom/atom/releases/latest).
|
||||
Download the latest [Atom installer](https://github.com/atom/atom/releases/latest). AtomSetup.exe is 32-bit, AtomSetup-x64.exe for 64-bit systems.
|
||||
|
||||
Atom will automatically update when a new release is available.
|
||||
|
||||
You can also download an `atom-windows.zip` file from the [releases page](https://github.com/atom/atom/releases/latest).
|
||||
You can also download `atom-windows.zip` (32-bit) or `atom-x64-windows.zip` (64-bit) from the [releases page](https://github.com/atom/atom/releases/latest).
|
||||
The `.zip` version will not automatically update.
|
||||
|
||||
Using [chocolatey](https://chocolatey.org/)? Run `cinst Atom` to install
|
||||
the latest version of Atom.
|
||||
Using [chocolatey](https://chocolatey.org/)? Run `cinst Atom` to install the latest version of Atom.
|
||||
|
||||
### Debian Linux (Ubuntu)
|
||||
|
||||
@@ -54,7 +53,7 @@ Atom is only available for 64-bit Linux systems.
|
||||
The Linux version does not currently automatically update so you will need to
|
||||
repeat these steps to upgrade to future releases.
|
||||
|
||||
### Red Hat Linux (Fedora 21 and under, CentOS, Red Hat)
|
||||
### Red Hat Enterprise Linux (RHEL) / CentOS
|
||||
|
||||
Atom is only available for 64-bit Linux systems.
|
||||
|
||||
@@ -65,12 +64,12 @@ Atom is only available for 64-bit Linux systems.
|
||||
The Linux version does not currently automatically update so you will need to
|
||||
repeat these steps to upgrade to future releases.
|
||||
|
||||
### Fedora 22+
|
||||
### Fedora
|
||||
|
||||
Atom is only available for 64-bit Linux systems.
|
||||
|
||||
1. Download `atom.x86_64.rpm` from the [Atom releases page](https://github.com/atom/atom/releases/latest).
|
||||
2. Run `sudo dnf install ./atom.x86_64.rpm` on the downloaded package.
|
||||
2. Run `sudo dnf install atom.x86_64.rpm` on the downloaded package.
|
||||
3. Launch Atom using the installed `atom` command.
|
||||
|
||||
The Linux version does not currently automatically update so you will need to
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "1.14.1"
|
||||
"atom-package-manager": "1.15.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,14 @@ clone_depth: 10
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
|
||||
environment:
|
||||
global:
|
||||
ATOM_DEV_RESOURCE_PATH: c:\projects\atom
|
||||
|
||||
matrix:
|
||||
- NODE_VERSION: 4.4.5
|
||||
- NODE_VERSION: 6.8.0
|
||||
|
||||
install:
|
||||
- SET PATH=C:\Program Files\Atom\resources\cli;%PATH%
|
||||
@@ -49,6 +50,4 @@ cache:
|
||||
- '%APPVEYOR_BUILD_FOLDER%\node_modules'
|
||||
- '%APPVEYOR_BUILD_FOLDER%\electron'
|
||||
- '%USERPROFILE%\.atom\.apm'
|
||||
- '%USERPROFILE%\.atom\.node-gyp\.atom'
|
||||
- '%USERPROFILE%\.atom\.npm'
|
||||
- '%USERPROFILE%\.atom\compile-cache'
|
||||
|
||||
15
atom.sh
15
atom.sh
@@ -55,11 +55,22 @@ if [ $EXPECT_OUTPUT ]; then
|
||||
fi
|
||||
|
||||
if [ $OS == 'Mac' ]; then
|
||||
if [ -L "$0" ]; then
|
||||
SCRIPT="$(readlink "$0")"
|
||||
else
|
||||
SCRIPT="$0"
|
||||
fi
|
||||
ATOM_APP="$(dirname "$(dirname "$(dirname "$(dirname "$SCRIPT")")")")"
|
||||
if [ "$ATOM_APP" == . ]; then
|
||||
unset ATOM_APP
|
||||
else
|
||||
ATOM_PATH="$(dirname "$ATOM_APP")"
|
||||
ATOM_APP_NAME="$(basename "$ATOM_APP")"
|
||||
fi
|
||||
|
||||
if [ -n "$BETA_VERSION" ]; then
|
||||
ATOM_APP_NAME="Atom Beta.app"
|
||||
ATOM_EXECUTABLE_NAME="Atom Beta"
|
||||
else
|
||||
ATOM_APP_NAME="Atom.app"
|
||||
ATOM_EXECUTABLE_NAME="Atom"
|
||||
fi
|
||||
|
||||
|
||||
@@ -2,111 +2,112 @@
|
||||
|
||||
| System | macOS | Windows | Dependencies |
|
||||
|--------|------|---------|--------------|
|
||||
| Atom | [](https://travis-ci.org/atom/atom) | [](https://ci.appveyor.com/project/Atom/atom) | [](https://david-dm.org/atom/atom) |
|
||||
| APM | [](https://travis-ci.org/atom/apm) | [](https://ci.appveyor.com/project/Atom/apm/branch/master) | [](https://david-dm.org/atom/apm) |
|
||||
| Electron | [](https://travis-ci.org/electron/electron) | [](https://ci.appveyor.com/project/Atom/electron) | [](https://david-dm.org/electron/electron)
|
||||
| [Atom](https://github.com/atom/atom) | [](https://travis-ci.org/atom/atom) | [](https://ci.appveyor.com/project/Atom/atom) | [](https://david-dm.org/atom/atom) |
|
||||
| [APM](https://github.com/atom/apm) | [](https://travis-ci.org/atom/apm) | [](https://ci.appveyor.com/project/Atom/apm/branch/master) | [](https://david-dm.org/atom/apm) |
|
||||
| [Electron](https://github.com/electron/electron) | [](https://travis-ci.org/electron/electron) | [](https://ci.appveyor.com/project/Atom/electron) | [](https://david-dm.org/electron/electron)
|
||||
|
||||
## Packages
|
||||
|
||||
| Package | macOS | Windows | Dependencies |
|
||||
|---------|------|---------|--------------|
|
||||
| About | [](https://travis-ci.org/atom/about) | [](https://ci.appveyor.com/project/atom/about/branch/master) | [](https://david-dm.org/atom/about) |
|
||||
| Archive View | [](https://travis-ci.org/atom/archive-view) | [](https://ci.appveyor.com/project/Atom/archive-view/branch/master) | [](https://david-dm.org/atom/archive-view) |
|
||||
| AutoComplete Atom API | [](https://travis-ci.org/atom/autocomplete-atom-api) | [](https://ci.appveyor.com/project/Atom/autocomplete-atom-api/branch/master) | [](https://david-dm.org/atom/autocomplete-atom-api) |
|
||||
| Atom Space Pen Views | [](https://travis-ci.org/atom/atom-space-pen-views) | [](https://ci.appveyor.com/project/Atom/atom-space-pen-views/branch/master) | [](https://david-dm.org/atom/atom-space-pen-views) |
|
||||
| AutoComplete CSS | [](https://travis-ci.org/atom/autocomplete-css) | [](https://ci.appveyor.com/project/Atom/autocomplete-css/branch/master) | [](https://david-dm.org/atom/autocomplete-css) |
|
||||
| AutoComplete HTML | [](https://travis-ci.org/atom/autocomplete-html) | [](https://ci.appveyor.com/project/Atom/autocomplete-html/branch/master) | [](https://david-dm.org/atom/autocomplete-html) |
|
||||
| AutoComplete+ | [](https://travis-ci.org/atom/autocomplete-plus) | [](https://ci.appveyor.com/project/Atom/autocomplete-plus/branch/master) | [](https://david-dm.org/atom/autocomplete-plus) |
|
||||
| AutoComplete Snippets | [](https://travis-ci.org/atom/autocomplete-snippets) | [](https://ci.appveyor.com/project/Atom/autocomplete-snippets/branch/master) | [](https://david-dm.org/atom/autocomplete-snippets) |
|
||||
| AutoFlow | [](https://travis-ci.org/atom/autoflow) | [](https://ci.appveyor.com/project/Atom/autoflow/branch/master) | [](https://david-dm.org/atom/autoflow) |
|
||||
| AutoSave | [](https://travis-ci.org/atom/autosave) | [](https://ci.appveyor.com/project/Atom/autosave/branch/master) | [](https://david-dm.org/atom/autosave) |
|
||||
| Background Tips | [](https://travis-ci.org/atom/background-tips) | [](https://ci.appveyor.com/project/Atom/background-tips/branch/master) | [](https://david-dm.org/atom/background-tips) |
|
||||
| Bookmarks | [](https://travis-ci.org/atom/bookmarks) | [](https://ci.appveyor.com/project/Atom/bookmarks/branch/master) | [](https://david-dm.org/atom/bookmarks) |
|
||||
| Bracket Matcher | [](https://travis-ci.org/atom/bracket-matcher) | [](https://ci.appveyor.com/project/Atom/bracket-matcher/branch/master) | [](https://david-dm.org/atom/bracket-matcher) |
|
||||
| Command Palette | [](https://travis-ci.org/atom/command-palette) | [](https://ci.appveyor.com/project/Atom/command-palette/branch/master) | [](https://david-dm.org/atom/command-palette) |
|
||||
| Deprecation Cop | [](https://travis-ci.org/atom/deprecation-cop) | [](https://ci.appveyor.com/project/Atom/deprecation-cop/branch/master) | [](https://david-dm.org/atom/deprecation-cop) |
|
||||
| Dev Live Reload | [](https://travis-ci.org/atom/dev-live-reload) | [](https://ci.appveyor.com/project/Atom/dev-live-reload/branch/master) | [](https://david-dm.org/atom/dev-live-reload) |
|
||||
| Encoding Selector | [](https://travis-ci.org/atom/encoding-selector) | [](https://ci.appveyor.com/project/Atom/encoding-selector/branch/master) | [](https://david-dm.org/atom/encoding-selector) |
|
||||
| Exception Reporting | [](https://travis-ci.org/atom/exception-reporting) | [](https://ci.appveyor.com/project/Atom/exception-reporting/branch/master) | [](https://david-dm.org/atom/exception-reporting) |
|
||||
| Find and Replace | [](https://travis-ci.org/atom/find-and-replace) | [](https://ci.appveyor.com/project/Atom/find-and-replace/branch/master) | [](https://david-dm.org/atom/find-and-replace) |
|
||||
| Fuzzy Finder | [](https://travis-ci.org/atom/fuzzy-finder) | [](https://ci.appveyor.com/project/Atom/fuzzy-finder/branch/master) | [](https://david-dm.org/atom/fuzzy-finder) |
|
||||
| Git Diff | [](https://travis-ci.org/atom/git-diff) | [](https://ci.appveyor.com/project/Atom/git-diff/branch/master) | [](https://david-dm.org/atom/git-diff) |
|
||||
| Go to Line | [](https://travis-ci.org/atom/go-to-line) | [](https://ci.appveyor.com/project/Atom/go-to-line/branch/master) | [](https://david-dm.org/atom/go-to-line) |
|
||||
| Grammar Selector | [](https://travis-ci.org/atom/grammar-selector) | [](https://ci.appveyor.com/project/Atom/grammar-selector/branch/master) | [](https://david-dm.org/atom/grammar-selector) |
|
||||
| Image View | [](https://travis-ci.org/atom/image-view) | [](https://ci.appveyor.com/project/Atom/image-view/branch/master) | [](https://david-dm.org/atom/image-view) |
|
||||
| Incompatible Packages | [](https://travis-ci.org/atom/incompatible-packages) | [](https://ci.appveyor.com/project/Atom/incompatible-packages/branch/master) | [](https://david-dm.org/atom/incompatible-packages) |
|
||||
| Keybinding Resolver | [](https://travis-ci.org/atom/keybinding-resolver) | [](https://ci.appveyor.com/project/Atom/keybinding-resolver/branch/master) | [](https://david-dm.org/atom/keybinding-resolver) |
|
||||
| Line Ending Selector | [](https://travis-ci.org/atom/line-ending-selector) | [](https://ci.appveyor.com/project/Atom/line-ending-selector/branch/master) | [](https://david-dm.org/atom/line-ending-selector) |
|
||||
| Link | [](https://travis-ci.org/atom/link) | [](https://ci.appveyor.com/project/Atom/link/branch/master) | [](https://david-dm.org/atom/link) |
|
||||
| Markdown Preview | [](https://travis-ci.org/atom/markdown-preview) | [](https://ci.appveyor.com/project/Atom/markdown-preview/branch/master) | [](https://david-dm.org/atom/markdown-preview) |
|
||||
| Metrics | [](https://travis-ci.org/atom/metrics) | [](https://ci.appveyor.com/project/Atom/metrics/branch/master) | [](https://david-dm.org/atom/metrics) |
|
||||
| Notifications | [](https://travis-ci.org/atom/notifications) | [](https://ci.appveyor.com/project/Atom/notifications/branch/master) | [](https://david-dm.org/atom/notifications) |
|
||||
| Open on Github | [](https://travis-ci.org/atom/open-on-github) | [](https://ci.appveyor.com/project/Atom/open-on-github/branch/master) | [](https://david-dm.org/atom/open-on-github) |
|
||||
| Package Generator | [](https://travis-ci.org/atom/package-generator)| [](https://ci.appveyor.com/project/Atom/package-generator/branch/master) | [](https://david-dm.org/atom/package-generator) |
|
||||
| Settings View | [](https://travis-ci.org/atom/settings-view) | [](https://ci.appveyor.com/project/Atom/settings-view/branch/master) | [](https://david-dm.org/atom/settings-view) |
|
||||
| Snippets | [](https://travis-ci.org/atom/snippets) | [](https://ci.appveyor.com/project/Atom/snippets/branch/master) | [](https://david-dm.org/atom/snippets) |
|
||||
| Spell Check | [](https://travis-ci.org/atom/spell-check) | [](https://ci.appveyor.com/project/Atom/spell-check/branch/master) | [](https://david-dm.org/atom/spell-check) |
|
||||
| Status Bar | [](https://travis-ci.org/atom/status-bar) | [](https://ci.appveyor.com/project/Atom/status-bar/branch/master) | [](https://david-dm.org/atom/status-bar) |
|
||||
| Styleguide | [](https://travis-ci.org/atom/styleguide) | [](https://ci.appveyor.com/project/Atom/styleguide/branch/master) | [](https://david-dm.org/atom/styleguide) |
|
||||
| Symbols View | [](https://travis-ci.org/atom/symbols-view) | [](https://ci.appveyor.com/project/Atom/symbols-view/branch/master) | [](https://david-dm.org/atom/symbols-view) |
|
||||
| Tabs | [](https://travis-ci.org/atom/tabs) | [](https://ci.appveyor.com/project/Atom/tabs/branch/master) | [](https://david-dm.org/atom/tabs) |
|
||||
| Timecop | [](https://travis-ci.org/atom/timecop) | [](https://ci.appveyor.com/project/Atom/timecop/branch/master) | [](https://david-dm.org/atom/timecop) |
|
||||
| Tree View | [](https://travis-ci.org/atom/tree-view) | [](https://ci.appveyor.com/project/Atom/tree-view/branch/master) | [](https://david-dm.org/atom/tree-view) |
|
||||
| Update Package Dependencies | [](https://travis-ci.org/atom/update-package-dependencies) | [](https://ci.appveyor.com/project/Atom/update-package-dependencies/branch/master) | [](https://david-dm.org/atom/update-package-dependencies) |
|
||||
| Welcome | [](https://travis-ci.org/atom/welcome) | [](https://ci.appveyor.com/project/Atom/welcome/branch/master) | [](https://david-dm.org/atom/welcome) |
|
||||
| Whitespace | [](https://travis-ci.org/atom/whitespace) | [](https://ci.appveyor.com/project/Atom/whitespace/branch/master) | [](https://david-dm.org/atom/whitespace) |
|
||||
| Wrap Guide | [](https://travis-ci.org/atom/wrap-guide) | [](https://ci.appveyor.com/project/Atom/wrap-guide/branch/master) | [](https://david-dm.org/atom/wrap-guide) |
|
||||
|
||||
| [About](https://github.com/atom/about) | [](https://travis-ci.org/atom/about) | [](https://ci.appveyor.com/project/atom/about/branch/master) | [](https://david-dm.org/atom/about) |
|
||||
| [Archive View](https://github.com/atom/archive-view) | [](https://travis-ci.org/atom/archive-view) | [](https://ci.appveyor.com/project/Atom/archive-view/branch/master) | [](https://david-dm.org/atom/archive-view) |
|
||||
| [AutoComplete Atom API](https://github.com/atom/autocomplete-atom-api) | [](https://travis-ci.org/atom/autocomplete-atom-api) | [](https://ci.appveyor.com/project/Atom/autocomplete-atom-api/branch/master) | [](https://david-dm.org/atom/autocomplete-atom-api) |
|
||||
| [AutoComplete CSS](https://github.com/atom/autocomplete-css) | [](https://travis-ci.org/atom/autocomplete-css) | [](https://ci.appveyor.com/project/Atom/autocomplete-css/branch/master) | [](https://david-dm.org/atom/autocomplete-css) |
|
||||
| [AutoComplete HTML](https://github.com/atom/autocomplete-html) | [](https://travis-ci.org/atom/autocomplete-html) | [](https://ci.appveyor.com/project/Atom/autocomplete-html/branch/master) | [](https://david-dm.org/atom/autocomplete-html) |
|
||||
| [AutoComplete+](https://github.com/atom/autocomplete-plus) | [](https://travis-ci.org/atom/autocomplete-plus) | [](https://ci.appveyor.com/project/Atom/autocomplete-plus/branch/master) | [](https://david-dm.org/atom/autocomplete-plus) |
|
||||
| [AutoComplete Snippets](https://github.com/atom/autocomplete-snippets) | [](https://travis-ci.org/atom/autocomplete-snippets) | [](https://ci.appveyor.com/project/Atom/autocomplete-snippets/branch/master) | [](https://david-dm.org/atom/autocomplete-snippets) |
|
||||
| [AutoFlow](https://github.com/atom/autoflow) | [](https://travis-ci.org/atom/autoflow) | [](https://ci.appveyor.com/project/Atom/autoflow/branch/master) | [](https://david-dm.org/atom/autoflow) |
|
||||
| [AutoSave](https://github.com/atom/autosave) | [](https://travis-ci.org/atom/autosave) | [](https://ci.appveyor.com/project/Atom/autosave/branch/master) | [](https://david-dm.org/atom/autosave) |
|
||||
| [Background Tips](https://github.com/atom/background-tips) | [](https://travis-ci.org/atom/background-tips) | [](https://ci.appveyor.com/project/Atom/background-tips/branch/master) | [](https://david-dm.org/atom/background-tips) |
|
||||
| [Bookmarks](https://github.com/atom/bookmarks) | [](https://travis-ci.org/atom/bookmarks) | [](https://ci.appveyor.com/project/Atom/bookmarks/branch/master) | [](https://david-dm.org/atom/bookmarks) |
|
||||
| [Bracket Matcher](https://github.com/atom/bracket-matcher) | [](https://travis-ci.org/atom/bracket-matcher) | [](https://ci.appveyor.com/project/Atom/bracket-matcher/branch/master) | [](https://david-dm.org/atom/bracket-matcher) |
|
||||
| [Command Palette](https://github.com/atom/command-palette) | [](https://travis-ci.org/atom/command-palette) | [](https://ci.appveyor.com/project/Atom/command-palette/branch/master) | [](https://david-dm.org/atom/command-palette) |
|
||||
| [Deprecation Cop](https://github.com/atom/deprecation-cop) | [](https://travis-ci.org/atom/deprecation-cop) | [](https://ci.appveyor.com/project/Atom/deprecation-cop/branch/master) | [](https://david-dm.org/atom/deprecation-cop) |
|
||||
| [Dev Live Reload](https://github.com/atom/dev-live-reload) | [](https://travis-ci.org/atom/dev-live-reload) | [](https://ci.appveyor.com/project/Atom/dev-live-reload/branch/master) | [](https://david-dm.org/atom/dev-live-reload) |
|
||||
| [Encoding Selector](https://github.com/atom/encoding-selector) | [](https://travis-ci.org/atom/encoding-selector) | [](https://ci.appveyor.com/project/Atom/encoding-selector/branch/master) | [](https://david-dm.org/atom/encoding-selector) |
|
||||
| [Exception Reporting](https://github.com/atom/exception-reporting) | [](https://travis-ci.org/atom/exception-reporting) | [](https://ci.appveyor.com/project/Atom/exception-reporting/branch/master) | [](https://david-dm.org/atom/exception-reporting) |
|
||||
| [Find and Replace](https://github.com/atom/find-and-replace) | [](https://travis-ci.org/atom/find-and-replace) | [](https://ci.appveyor.com/project/Atom/find-and-replace/branch/master) | [](https://david-dm.org/atom/find-and-replace) |
|
||||
| [Fuzzy Finder](https://github.com/atom/fuzzy-finder) | [](https://travis-ci.org/atom/fuzzy-finder) | [](https://ci.appveyor.com/project/Atom/fuzzy-finder/branch/master) | [](https://david-dm.org/atom/fuzzy-finder) |
|
||||
| [Git Diff](https://github.com/atom/git-diff) | [](https://travis-ci.org/atom/git-diff) | [](https://ci.appveyor.com/project/Atom/git-diff/branch/master) | [](https://david-dm.org/atom/git-diff) |
|
||||
| [Go to Line](https://github.com/atom/go-to-line) | [](https://travis-ci.org/atom/go-to-line) | [](https://ci.appveyor.com/project/Atom/go-to-line/branch/master) | [](https://david-dm.org/atom/go-to-line) |
|
||||
| [Grammar Selector](https://github.com/atom/grammar-selector) | [](https://travis-ci.org/atom/grammar-selector) | [](https://ci.appveyor.com/project/Atom/grammar-selector/branch/master) | [](https://david-dm.org/atom/grammar-selector) |
|
||||
| [Image View](https://github.com/atom/image-view) | [](https://travis-ci.org/atom/image-view) | [](https://ci.appveyor.com/project/Atom/image-view/branch/master) | [](https://david-dm.org/atom/image-view) |
|
||||
| [Incompatible Packages](https://github.com/atom/incompatible-packages) | [](https://travis-ci.org/atom/incompatible-packages) | [](https://ci.appveyor.com/project/Atom/incompatible-packages/branch/master) | [](https://david-dm.org/atom/incompatible-packages) |
|
||||
| [Keybinding Resolver](https://github.com/atom/keybinding-resolver) | [](https://travis-ci.org/atom/keybinding-resolver) | [](https://ci.appveyor.com/project/Atom/keybinding-resolver/branch/master) | [](https://david-dm.org/atom/keybinding-resolver) |
|
||||
| [Line Ending Selector](https://github.com/atom/line-ending-selector) | [](https://travis-ci.org/atom/line-ending-selector) | [](https://ci.appveyor.com/project/Atom/line-ending-selector/branch/master) | [](https://david-dm.org/atom/line-ending-selector) |
|
||||
| [Link](https://github.com/atom/link) | [](https://travis-ci.org/atom/link) | [](https://ci.appveyor.com/project/Atom/link/branch/master) | [](https://david-dm.org/atom/link) |
|
||||
| [Markdown Preview](https://github.com/atom/markdown-preview) | [](https://travis-ci.org/atom/markdown-preview) | [](https://ci.appveyor.com/project/Atom/markdown-preview/branch/master) | [](https://david-dm.org/atom/markdown-preview) |
|
||||
| [Metrics](https://github.com/atom/metrics) | [](https://travis-ci.org/atom/metrics) | [](https://ci.appveyor.com/project/Atom/metrics/branch/master) | [](https://david-dm.org/atom/metrics) |
|
||||
| [Notifications](https://github.com/atom/notifications) | [](https://travis-ci.org/atom/notifications) | [](https://ci.appveyor.com/project/Atom/notifications/branch/master) | [](https://david-dm.org/atom/notifications) |
|
||||
| [Open on Github](https://github.com/atom/open-on-github) | [](https://travis-ci.org/atom/open-on-github) | [](https://ci.appveyor.com/project/Atom/open-on-github/branch/master) | [](https://david-dm.org/atom/open-on-github) |
|
||||
| [Package Generator](https://github.com/atom/package-generator) | [](https://travis-ci.org/atom/package-generator)| [](https://ci.appveyor.com/project/Atom/package-generator/branch/master) | [](https://david-dm.org/atom/package-generator) |
|
||||
| [Settings View](https://github.com/atom/settings-view) | [](https://travis-ci.org/atom/settings-view) | [](https://ci.appveyor.com/project/Atom/settings-view/branch/master) | [](https://david-dm.org/atom/settings-view) |
|
||||
| [Snippets](https://github.com/atom/snippets) | [](https://travis-ci.org/atom/snippets) | [](https://ci.appveyor.com/project/Atom/snippets/branch/master) | [](https://david-dm.org/atom/snippets) |
|
||||
| [Spell Check](https://github.com/atom/spell-check) | [](https://travis-ci.org/atom/spell-check) | [](https://ci.appveyor.com/project/Atom/spell-check/branch/master) | [](https://david-dm.org/atom/spell-check) |
|
||||
| [Status Bar](https://github.com/atom/status-bar) | [](https://travis-ci.org/atom/status-bar) | [](https://ci.appveyor.com/project/Atom/status-bar/branch/master) | [](https://david-dm.org/atom/status-bar) |
|
||||
| [Styleguide](https://github.com/atom/styleguide) | [](https://travis-ci.org/atom/styleguide) | [](https://ci.appveyor.com/project/Atom/styleguide/branch/master) | [](https://david-dm.org/atom/styleguide) |
|
||||
| [Symbols View](https://github.com/atom/symbols-view) | [](https://travis-ci.org/atom/symbols-view) | [](https://ci.appveyor.com/project/Atom/symbols-view/branch/master) | [](https://david-dm.org/atom/symbols-view) |
|
||||
| [Tabs](https://github.com/atom/tabs) | [](https://travis-ci.org/atom/tabs) | [](https://ci.appveyor.com/project/Atom/tabs/branch/master) | [](https://david-dm.org/atom/tabs) |
|
||||
| [Timecop](https://github.com/atom/timecop) | [](https://travis-ci.org/atom/timecop) | [](https://ci.appveyor.com/project/Atom/timecop/branch/master) | [](https://david-dm.org/atom/timecop) |
|
||||
| [Tree View](https://github.com/atom/tree-view) | [](https://travis-ci.org/atom/tree-view) | [](https://ci.appveyor.com/project/Atom/tree-view/branch/master) | [](https://david-dm.org/atom/tree-view) |
|
||||
| [Update Package Dependencies](https://github.com/atom/update-package-dependencies) | [](https://travis-ci.org/atom/update-package-dependencies) | [](https://ci.appveyor.com/project/Atom/update-package-dependencies/branch/master) | [](https://david-dm.org/atom/update-package-dependencies) |
|
||||
| [Welcome](https://github.com/atom/welcome) | [](https://travis-ci.org/atom/welcome) | [](https://ci.appveyor.com/project/Atom/welcome/branch/master) | [](https://david-dm.org/atom/welcome) |
|
||||
| [Whitespace](https://github.com/atom/whitespace) | [](https://travis-ci.org/atom/whitespace) | [](https://ci.appveyor.com/project/Atom/whitespace/branch/master) | [](https://david-dm.org/atom/whitespace) |
|
||||
| [Wrap Guide](https://github.com/atom/wrap-guide) | [](https://travis-ci.org/atom/wrap-guide) | [](https://ci.appveyor.com/project/Atom/wrap-guide/branch/master) | [](https://david-dm.org/atom/wrap-guide) |
|
||||
|
||||
## Libraries
|
||||
|
||||
| Library | macOS | Windows | Dependencies |
|
||||
|---------|------|---------|--------------|
|
||||
| Clear Cut | [](https://travis-ci.org/atom/clear-cut) | [](https://ci.appveyor.com/project/Atom/clear-cut/branch/master) | [](https://david-dm.org/atom/clear-cut) |
|
||||
| Event Kit | [](https://travis-ci.org/atom/event-kit) | [](https://ci.appveyor.com/project/Atom/event-kit/branch/master) | [](https://david-dm.org/atom/event-kit) |
|
||||
| Fs Plus | [](https://travis-ci.org/atom/fs-plus) | [](https://ci.appveyor.com/project/Atom/fs-plus/branch/master) | [](https://david-dm.org/atom/fs-plus) |
|
||||
| Grim | [](https://travis-ci.org/atom/grim) | [](https://ci.appveyor.com/project/Atom/grim/branch/master) | [](https://david-dm.org/atom/grim) |
|
||||
| Jasmine Focused | [](https://travis-ci.org/atom/grim) | [](https://ci.appveyor.com/project/Atom/jasmine-focused/branch/master) | [](https://david-dm.org/atom/jasmine-focused) |
|
||||
| Property Accessors | [](https://travis-ci.org/atom/property-accessors) | [](https://ci.appveyor.com/project/Atom/property-accessors/branch/master) | [](https://david-dm.org/atom/property-accessors) |
|
||||
| TextBuffer | [](https://travis-ci.org/atom/text-buffer) | [](https://ci.appveyor.com/project/Atom/text-buffer/branch/master) | [](https://david-dm.org/atom/text-buffer) |
|
||||
| Underscore-Plus | [](https://travis-ci.org/atom/underscore-plus) | [](https://ci.appveyor.com/project/Atom/underscore-plus/branch/master) | [](https://david-dm.org/atom/underscore-plus) |
|
||||
|
||||
| [Clear Cut](https://github.com/atom/clear-cut) | [](https://travis-ci.org/atom/clear-cut) | [](https://ci.appveyor.com/project/Atom/clear-cut/branch/master) | [](https://david-dm.org/atom/clear-cut) |
|
||||
| [Event Kit](https://github.com/atom/event-kit) | [](https://travis-ci.org/atom/event-kit) | [](https://ci.appveyor.com/project/Atom/event-kit/branch/master) | [](https://david-dm.org/atom/event-kit) |
|
||||
| [First Mate](https://github.com/atom/first-mate) | [](https://travis-ci.org/atom/first-mate) | [](https://ci.appveyor.com/project/Atom/first-mate) | [](https://david-dm.org/atom/first-mate) |
|
||||
| [Fs Plus](https://github.com/atom/fs-plus) | [](https://travis-ci.org/atom/fs-plus) | [](https://ci.appveyor.com/project/Atom/fs-plus/branch/master) | [](https://david-dm.org/atom/fs-plus) |
|
||||
| [Grim](https://github.com/atom/grim) | [](https://travis-ci.org/atom/grim) | [](https://ci.appveyor.com/project/Atom/grim/branch/master) | [](https://david-dm.org/atom/grim) |
|
||||
| [Jasmine Focused](https://github.com/atom/jasmine-focused) | [](https://travis-ci.org/atom/grim) | [](https://ci.appveyor.com/project/Atom/jasmine-focused/branch/master) | [](https://david-dm.org/atom/jasmine-focused) |
|
||||
| [Keyboard Layout](https://github.com/atom/keyboard-layout) | [](https://travis-ci.org/atom/keyboard-layout) | [](https://ci.appveyor.com/project/Atom/keyboard-layout) | [](https://david-dm.org/atom/keyboard-layout) |
|
||||
| [Oniguruma](https://github.com/atom/node-oniguruma) | [](https://travis-ci.org/atom/node-oniguruma) | [](https://ci.appveyor.com/project/Atom/node-oniguruma/branch/master) | [](https://david-dm.org/atom/node-oniguruma) |
|
||||
| [PathWatcher](https://github.com/atom/node-pathwatcher) | [](https://travis-ci.org/atom/node-pathwatcher) | [](https://ci.appveyor.com/project/Atom/node-pathwatcher) | [](https://david-dm.org/atom/node-pathwatcher) |
|
||||
| [Property Accessors](https://github.com/atom/property-accessors) | [](https://travis-ci.org/atom/property-accessors) | [](https://ci.appveyor.com/project/Atom/property-accessors/branch/master) | [](https://david-dm.org/atom/property-accessors) |
|
||||
| [TextBuffer](https://github.com/atom/text-buffer) | [](https://travis-ci.org/atom/text-buffer) | [](https://ci.appveyor.com/project/Atom/text-buffer/branch/master) | [](https://david-dm.org/atom/text-buffer) |
|
||||
| [Underscore-Plus](https://github.com/atom/underscore-plus) | [](https://travis-ci.org/atom/underscore-plus) | [](https://ci.appveyor.com/project/Atom/underscore-plus/branch/master) | [](https://david-dm.org/atom/underscore-plus) |
|
||||
|
||||
## Tools
|
||||
| Language | macOS | Windows | Dependencies |
|
||||
|----------|------|---------|--------------|
|
||||
| AtomDoc | [](https://travis-ci.org/atom/atomdoc) | [](https://ci.appveyor.com/project/Atom/atomdoc/branch/master) | [](https://david-dm.org/atom/atomdoc)
|
||||
| [AtomDoc](https://github.com/atom/atomdoc) | [](https://travis-ci.org/atom/atomdoc) | [](https://ci.appveyor.com/project/Atom/atomdoc/branch/master) | [](https://david-dm.org/atom/atomdoc)
|
||||
|
||||
## Languages
|
||||
|
||||
| Language | macOS | Windows |
|
||||
|----------|------|---------|
|
||||
| C/C++ | [](https://travis-ci.org/atom/language-c) | [](https://ci.appveyor.com/project/Atom/language-c/branch/master) |
|
||||
| C# | [](https://travis-ci.org/atom/language-csharp) | [](https://ci.appveyor.com/project/Atom/language-csharp/branch/master) |
|
||||
| Clojure | [](https://travis-ci.org/atom/language-clojure) | [](https://ci.appveyor.com/project/Atom/language-clojure/branch/master) |
|
||||
| CoffeeScript | [](https://travis-ci.org/atom/language-coffee-script) | [](https://ci.appveyor.com/project/Atom/language-coffee-script/branch/master) |
|
||||
| CSS | [](https://travis-ci.org/atom/language-css) | [](https://ci.appveyor.com/project/Atom/language-css/branch/master) |
|
||||
| Git | [](https://travis-ci.org/atom/language-git) | [](https://ci.appveyor.com/project/Atom/language-git/branch/master) |
|
||||
| GitHub Flavored Markdown | [](https://travis-ci.org/atom/language-gfm) | [](https://ci.appveyor.com/project/Atom/language-gfm/branch/master) |
|
||||
| Go | [](https://travis-ci.org/atom/language-go) | [](https://ci.appveyor.com/project/Atom/language-go/branch/master) |
|
||||
| HTML | [](https://travis-ci.org/atom/language-html) | [](https://ci.appveyor.com/project/Atom/language-html/branch/master) |
|
||||
| Hyperlink | [](https://travis-ci.org/atom/language-hyperlink) | [](https://ci.appveyor.com/project/Atom/language-hyperlink/branch/master) |
|
||||
| Java | [](https://travis-ci.org/atom/language-java) | [](https://ci.appveyor.com/project/Atom/language-java/branch/master) |
|
||||
| JavaScript | [](https://travis-ci.org/atom/language-javascript) | [](https://ci.appveyor.com/project/Atom/language-javascript-dijf8/branch/master) |
|
||||
| JSON | [](https://travis-ci.org/atom/language-json) | [](https://ci.appveyor.com/project/Atom/language-json/branch/master) |
|
||||
| Less | [](https://travis-ci.org/atom/language-less) | [](https://ci.appveyor.com/project/Atom/language-less/branch/master) |
|
||||
| Make | [](https://travis-ci.org/atom/language-make) | [](https://ci.appveyor.com/project/Atom/language-make/branch/master) |
|
||||
| Mustache | [](https://travis-ci.org/atom/language-mustache) | [](https://ci.appveyor.com/project/Atom/language-mustache/branch/master) |
|
||||
| Objective-C | [](https://travis-ci.org/atom/language-objective-c) | [](https://ci.appveyor.com/project/Atom/language-objective-c/branch/master) |
|
||||
| Perl | [](https://travis-ci.org/atom/language-perl) | [](https://ci.appveyor.com/project/Atom/language-perl/branch/master) |
|
||||
| PHP | [](https://travis-ci.org/atom/language-php) | [](https://ci.appveyor.com/project/Atom/language-php/branch/master) |
|
||||
| Python | [](https://travis-ci.org/atom/language-python) | [](https://ci.appveyor.com/project/Atom/language-python/branch/master) |
|
||||
| Ruby | [](https://travis-ci.org/atom/language-ruby) | [](https://ci.appveyor.com/project/Atom/language-ruby/branch/master) |
|
||||
| Ruby on Rails | [](https://travis-ci.org/atom/language-ruby-on-rails) | [](https://ci.appveyor.com/project/Atom/language-ruby-on-rails/branch/master) |
|
||||
| Sass | [](https://travis-ci.org/atom/language-sass) | [](https://ci.appveyor.com/project/Atom/language-sass/branch/master) |
|
||||
| ShellScript | [](https://travis-ci.org/atom/language-shellscript) | [](https://ci.appveyor.com/project/Atom/language-shellscript/branch/master) |
|
||||
| SQL | [](https://travis-ci.org/atom/language-sql) | [](https://ci.appveyor.com/project/Atom/language-sql/branch/master) |
|
||||
| TODO | [](https://travis-ci.org/atom/language-todo) | [](https://ci.appveyor.com/project/Atom/language-todo/branch/master) |
|
||||
| TOML | [](https://travis-ci.org/atom/language-toml) | [](https://ci.appveyor.com/project/Atom/language-toml/branch/master) |
|
||||
| XML | [](https://travis-ci.org/atom/language-xml) | [](https://ci.appveyor.com/project/Atom/language-xml/branch/master) |
|
||||
| YAML | [](https://travis-ci.org/atom/language-yaml) | [](https://ci.appveyor.com/project/Atom/language-yaml/branch/master) |
|
||||
| [C/C++](https://github.com/atom/language-c) | [](https://travis-ci.org/atom/language-c) | [](https://ci.appveyor.com/project/Atom/language-c/branch/master) |
|
||||
| [C#](https://github.com/atom/language-csharp) | [](https://travis-ci.org/atom/language-csharp) | [](https://ci.appveyor.com/project/Atom/language-csharp/branch/master) |
|
||||
| [Clojure](https://github.com/atom/language-clojure) | [](https://travis-ci.org/atom/language-clojure) | [](https://ci.appveyor.com/project/Atom/language-clojure/branch/master) |
|
||||
| [CoffeeScript](https://github.com/atom/language-coffee-script) | [](https://travis-ci.org/atom/language-coffee-script) | [](https://ci.appveyor.com/project/Atom/language-coffee-script/branch/master) |
|
||||
| [CSS](https://github.com/atom/language-css) | [](https://travis-ci.org/atom/language-css) | [](https://ci.appveyor.com/project/Atom/language-css/branch/master) |
|
||||
| [Git](https://github.com/atom/language-git) | [](https://travis-ci.org/atom/language-git) | [](https://ci.appveyor.com/project/Atom/language-git/branch/master) |
|
||||
| [GitHub Flavored Markdown](https://github.com/atom/language-gfm) | [](https://travis-ci.org/atom/language-gfm) | [](https://ci.appveyor.com/project/Atom/language-gfm/branch/master) |
|
||||
| [Go](https://github.com/atom/language-go) | [](https://travis-ci.org/atom/language-go) | [](https://ci.appveyor.com/project/Atom/language-go/branch/master) |
|
||||
| [HTML](https://github.com/atom/language-html) | [](https://travis-ci.org/atom/language-html) | [](https://ci.appveyor.com/project/Atom/language-html/branch/master) |
|
||||
| [Hyperlink](https://github.com/atom/language-hyperlink) | [](https://travis-ci.org/atom/language-hyperlink) | [](https://ci.appveyor.com/project/Atom/language-hyperlink/branch/master) |
|
||||
| [Java](https://github.com/atom/language-java) | [](https://travis-ci.org/atom/language-java) | [](https://ci.appveyor.com/project/Atom/language-java/branch/master) |
|
||||
| [JavaScript](https://github.com/atom/language-javascript) | [](https://travis-ci.org/atom/language-javascript) | [](https://ci.appveyor.com/project/Atom/language-javascript-dijf8/branch/master) |
|
||||
| [JSON](https://github.com/atom/language-json) | [](https://travis-ci.org/atom/language-json) | [](https://ci.appveyor.com/project/Atom/language-json/branch/master) |
|
||||
| [Less](https://github.com/atom/language-less) | [](https://travis-ci.org/atom/language-less) | [](https://ci.appveyor.com/project/Atom/language-less/branch/master) |
|
||||
| [Make](https://github.com/atom/language-make) | [](https://travis-ci.org/atom/language-make) | [](https://ci.appveyor.com/project/Atom/language-make/branch/master) |
|
||||
| [Mustache](https://github.com/atom/language-mustache) | [](https://travis-ci.org/atom/language-mustache) | [](https://ci.appveyor.com/project/Atom/language-mustache/branch/master) |
|
||||
| [Objective-C](https://github.com/atom/language-objective-c) | [](https://travis-ci.org/atom/language-objective-c) | [](https://ci.appveyor.com/project/Atom/language-objective-c/branch/master) |
|
||||
| [Perl](https://github.com/atom/language-perl) | [](https://travis-ci.org/atom/language-perl) | [](https://ci.appveyor.com/project/Atom/language-perl/branch/master) |
|
||||
| [PHP](https://github.com/atom/language-php) | [](https://travis-ci.org/atom/language-php) | [](https://ci.appveyor.com/project/Atom/language-php/branch/master) |
|
||||
| [Python](https://github.com/atom/language-python) | [](https://travis-ci.org/atom/language-python) | [](https://ci.appveyor.com/project/Atom/language-python/branch/master) |
|
||||
| [Ruby](https://github.com/atom/language-ruby) | [](https://travis-ci.org/atom/language-ruby) | [](https://ci.appveyor.com/project/Atom/language-ruby/branch/master) |
|
||||
| [Ruby on Rails](https://github.com/atom/language-ruby-on-rails) | [](https://travis-ci.org/atom/language-ruby-on-rails) | [](https://ci.appveyor.com/project/Atom/language-ruby-on-rails/branch/master) |
|
||||
| [Sass](https://github.com/atom/language-sass) | [](https://travis-ci.org/atom/language-sass) | [](https://ci.appveyor.com/project/Atom/language-sass/branch/master) |
|
||||
| [ShellScript](https://github.com/atom/language-shellscript) | [](https://travis-ci.org/atom/language-shellscript) | [](https://ci.appveyor.com/project/Atom/language-shellscript/branch/master) |
|
||||
| [SQL](https://github.com/atom/language-sql) | [](https://travis-ci.org/atom/language-sql) | [](https://ci.appveyor.com/project/Atom/language-sql/branch/master) |
|
||||
| [TODO](https://github.com/atom/language-todo) | [](https://travis-ci.org/atom/language-todo) | [](https://ci.appveyor.com/project/Atom/language-todo/branch/master) |
|
||||
| [TOML](https://github.com/atom/language-toml) | [](https://travis-ci.org/atom/language-toml) | [](https://ci.appveyor.com/project/Atom/language-toml/branch/master) |
|
||||
| [XML](https://github.com/atom/language-xml) | [](https://travis-ci.org/atom/language-xml) | [](https://ci.appveyor.com/project/Atom/language-xml/branch/master) |
|
||||
| [YAML](https://github/atom/language-yaml) | [](https://travis-ci.org/atom/language-yaml) | [](https://ci.appveyor.com/project/Atom/language-yaml/branch/master) |
|
||||
|
||||
@@ -49,9 +49,13 @@ To also install the newly built application, use `--create-debian-package` or `-
|
||||
sudo update-alternatives --config gcc # choose gcc-5 from the list
|
||||
```
|
||||
|
||||
### Fedora / CentOS / RHEL
|
||||
### Fedora
|
||||
|
||||
* `sudo dnf --assumeyes install make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel rpmdevtools libX11-devel libxkbfile-devel`
|
||||
* `sudo dnf install make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel rpmdevtools libX11-devel libxkbfile-devel`
|
||||
|
||||
### RHEL / CentOS
|
||||
|
||||
* `sudo yum install make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel rpmdevtools libX11-devel libxkbfile-devel`
|
||||
|
||||
### Arch
|
||||
|
||||
|
||||
@@ -26,4 +26,4 @@ To also install the newly built application, use `script/build --install`.
|
||||
## Troubleshooting
|
||||
|
||||
### macOS build error reports in atom/atom
|
||||
* Use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Aos-x&type=Issues) to get a list of reports about build errors on macOS.
|
||||
* Use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Amac&type=Issues) to get a list of reports about build errors on macOS.
|
||||
|
||||
@@ -2,20 +2,21 @@
|
||||
|
||||
## Requirements
|
||||
|
||||
* Node.js 4.4.x or later
|
||||
* Node.js 4.4.x or later (the architecture of node available to the build system will determine whether you build 32-bit or 64-bit Atom)
|
||||
* Python v2.7.x
|
||||
* The python.exe must be available at `%SystemDrive%\Python27\python.exe`. If it is installed elsewhere, you can create a symbolic link to the directory containing the python.exe using: `mklink /d %SystemDrive%\Python27 D:\elsewhere\Python27`
|
||||
* The python.exe must be available at `%SystemDrive%\Python27\python.exe`. If it is installed elsewhere create a symbolic link to the directory containing the python.exe using: `mklink /d %SystemDrive%\Python27 D:\elsewhere\Python27`
|
||||
* 7zip (7z.exe available from the command line) - for unpacking Chromedriver and creating distribution zips
|
||||
* Visual Studio, either:
|
||||
* [Visual C++ Build Tools 2015](http://landinghub.visualstudio.com/visual-cpp-build-tools)
|
||||
* [Visual Studio 2013 Update 5](https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs) (Express Edition or better)
|
||||
* [Visual Studio 2015](https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs) (Community Edition or better)
|
||||
|
||||
Whichever version you use, ensure that:
|
||||
Also ensure that:
|
||||
* The default installation folder is chosen so the build tools can find it
|
||||
* If using Visual Studio make sure Visual C++ support is selected/installed
|
||||
* If using Visual C++ Build Tools make sure Windows 8 SDK is selected/installed
|
||||
* A `git` command is in your path
|
||||
* Set the `GYP_MSVS_VERSION` environment variable to the Visual Studio/Build Tools version (`2013` or `2015`) e.g. ``[Environment]::SetEnvironmentVariable("GYP_MSVS_VERSION", "2015", "User")`` in PowerShell or set it in Windows advanced system settings control panel.
|
||||
* Set the `GYP_MSVS_VERSION` environment variable to the Visual Studio/Build Tools version (`2013` or `2015`) e.g. ``[Environment]::SetEnvironmentVariable("GYP_MSVS_VERSION", "2015", "User")`` in PowerShell (or set it in Windows advanced system settings).
|
||||
|
||||
## Instructions
|
||||
|
||||
@@ -32,8 +33,8 @@ To also install the newly built application, use `script\build --create-windows-
|
||||
|
||||
### `script\build` Options
|
||||
* `--code-sign`: signs the application with the GitHub certificate specified in `$WIN_P12KEY_URL`.
|
||||
* `--compress-artifacts`: zips the generated application as `out/atom-windows.zip` (requires 7-zip).
|
||||
* `--create-windows-installer`: creates an `.msi`, an `.exe` and a `.nupkg` installer in the `out/` directory.
|
||||
* `--compress-artifacts`: zips the generated application as `out\atom-windows.zip` (requires [7-Zip](http://www.7-zip.org)).
|
||||
* `--create-windows-installer`: creates an `.msi`, an `.exe` and two `.nupkg` packages in the `out` directory.
|
||||
* `--install`: installs the application in `%LOCALAPPDATA%\Atom\app-dev\`.
|
||||
|
||||
### Running tests
|
||||
@@ -53,22 +54,18 @@ When building Atom from source, the `apm` command is not added to the system pat
|
||||
|
||||
### Common Errors
|
||||
* `node is not recognized`
|
||||
* If you just installed Node.js, you'll need to restart Command Prompt before the `node` command is available on your Path.
|
||||
* If you just installed Node.js, you'll need to restart Command Prompt before the `node` command is available on your path.
|
||||
|
||||
* `msbuild.exe failed with exit code: 1`
|
||||
* If you installed Visual Studio, ensure you have Visual C++ support installed. Go into Add/Remove Programs, select Visual Studio, press Modify, and then check the Visual C++ box.
|
||||
* If you installed Visual C++ Build Tools, ensure you have Windows 8 SDK support installed. Go into Add/Remove Programs, select Visual Studio, press Modify and then check the Windows 8 SDK box.
|
||||
* If using **Visual Studio**, ensure you have the **Visual C++** component installed. Go into Add/Remove Programs, select Visual Studio, press Modify, and then check the Visual C++ box.
|
||||
* If using **Visual C++ Build Tools**, ensure you have the **Windows 8 SDK** component installed. Go into Add/Remove Programs, select Visual C++ Build Tools, press Modify and then check the Windows 8 SDK box.
|
||||
|
||||
* `script\build` stop with no error or warning shortly after displaying the versions of node, npm and Python
|
||||
* `script\build` stops with no error or warning shortly after displaying the versions of node, npm and Python
|
||||
* Make sure that the path where you have checked out Atom does not include a space. For example, use `C:\atom` instead of `C:\my stuff\atom`.
|
||||
|
||||
* `script\build` outputs only the Node.js and Python versions before returning
|
||||
* Try moving the repository to `C:\atom`. Most likely, the path is too long.
|
||||
See [issue #2200](https://github.com/atom/atom/issues/2200).
|
||||
* Try moving the repository to `C:\atom`. Most likely, the path is too long. See [issue #2200](https://github.com/atom/atom/issues/2200).
|
||||
|
||||
* `error MSB4025: The project file could not be loaded. Invalid character in the given encoding.`
|
||||
* This can occur because your home directory (`%USERPROFILE%`) has non-ASCII
|
||||
characters in it. This is a bug in [gyp](https://code.google.com/p/gyp/)
|
||||
* This can occur because your home directory (`%USERPROFILE%`) has non-ASCII characters in it. This is a bug in [gyp](https://code.google.com/p/gyp/)
|
||||
which is used to build native Node.js modules and there is no known workaround.
|
||||
* https://github.com/TooTallNate/node-gyp/issues/297
|
||||
* https://code.google.com/p/gyp/issues/detail?id=393
|
||||
@@ -80,14 +77,14 @@ When building Atom from source, the `apm` command is not added to the system pat
|
||||
* See the next item.
|
||||
|
||||
* `error MSB8020: The build tools for Visual Studio 201? (Platform Toolset = 'v1?0') cannot be found.`
|
||||
* Try setting the `GYP_MSVS_VERSION` environment variable to 2013 or 2015 depending on what version of Visual Studio/Build Tools is installed and then `script\clean` followed by `script\build` (re-open the Command Prompt if you set the variable using the GUI).
|
||||
* Try setting the `GYP_MSVS_VERSION` environment variable to **2013** or **2015** depending on what version of Visual Studio/Build Tools is installed and then `script\clean` followed by `script\build` (re-open the Command Prompt if you set the variable using the GUI).
|
||||
|
||||
* `'node-gyp' is not recognized as an internal or external command, operable program or batch file.`
|
||||
* Try running `npm install -g node-gyp`, and run `script\build` again.
|
||||
|
||||
* Other `node-gyp` errors on first build attempt, even though the right Node.js and Python versions are installed.
|
||||
* Do try the build command one more time, as experience shows it often works on second try in many of these cases.
|
||||
* Do try the build command one more time as experience shows it often works on second try in many cases.
|
||||
|
||||
### Windows build error reports in atom/atom
|
||||
* If all fails, use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Awindows&type=Issues) to get a list of reports about build errors on Windows, and see if yours has already been reported.
|
||||
* If it hasn't, please open a new issue with your Windows version, architecture (x86 or amd64), and a screenshot of your build output, including the Node.js and Python versions.
|
||||
* If it hasn't, please open a new issue with your Windows version, architecture (x86 or x64), and a screenshot of your build output, including the Node.js and Python versions.
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
'down': 'core:move-down'
|
||||
'left': 'core:move-left'
|
||||
'right': 'core:move-right'
|
||||
'ctrl-alt-r': 'window:reload'
|
||||
'ctrl-shift-f5': 'window:reload'
|
||||
'ctrl-shift-i': 'window:toggle-dev-tools'
|
||||
'ctrl-alt-p': 'window:run-package-specs'
|
||||
'ctrl-shift-y': 'window:run-package-specs'
|
||||
'ctrl-shift-o': 'application:open-folder'
|
||||
'ctrl-alt-o': 'application:add-project-folder'
|
||||
'ctrl-shift-a': 'application:add-project-folder'
|
||||
'ctrl-shift-pageup': 'pane:move-item-left'
|
||||
'ctrl-shift-pagedown': 'pane:move-item-right'
|
||||
'f11': 'window:toggle-full-screen'
|
||||
@@ -70,12 +70,12 @@
|
||||
'ctrl-k left': 'pane:split-left-and-copy-active-item' # Atom Specific
|
||||
'ctrl-k right': 'pane:split-right-and-copy-active-item' # Atom Specific
|
||||
'ctrl-k ctrl-w': 'pane:close' # Atom Specific
|
||||
'ctrl-k alt-ctrl-w': 'pane:close-other-items' # Atom Specific
|
||||
'ctrl-k ctrl-alt-w': 'pane:close-other-items' # Atom Specific
|
||||
'ctrl-k ctrl-p': 'window:focus-previous-pane'
|
||||
'ctrl-k ctrl-n': 'window:focus-next-pane'
|
||||
'ctrl-k ctrl-up': 'window:focus-pane-above'
|
||||
'ctrl-k ctrl-down': 'window:focus-pane-below'
|
||||
'ctrl-k ctrl-left': 'window:focus-pane-on-left'
|
||||
'ctrl-k ctrl-up': 'window:focus-pane-above'
|
||||
'ctrl-k ctrl-down': 'window:focus-pane-below'
|
||||
'ctrl-k ctrl-left': 'window:focus-pane-on-left'
|
||||
'ctrl-k ctrl-right': 'window:focus-pane-on-right'
|
||||
'alt-1': 'pane:show-item-1'
|
||||
'alt-2': 'pane:show-item-2'
|
||||
@@ -108,16 +108,14 @@
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-a': 'core:select-all'
|
||||
'ctrl-alt-shift-p': 'editor:log-cursor-scope'
|
||||
'ctrl-k ctrl-u': 'editor:upper-case'
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'atom-workspace atom-text-editor:not([mini])':
|
||||
# Atom specific
|
||||
'alt-ctrl-z': 'editor:checkout-head-revision'
|
||||
'ctrl-<': 'editor:scroll-to-cursor'
|
||||
'alt-ctrl-f': 'editor:fold-selection'
|
||||
'ctrl-alt-shift-[': 'editor:fold-selection'
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-enter': 'editor:newline-below'
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
'ctrl-down': 'core:move-down'
|
||||
'left': 'core:move-left'
|
||||
'right': 'core:move-right'
|
||||
'ctrl-alt-r': 'window:reload'
|
||||
'ctrl-shift-f5': 'window:reload'
|
||||
'ctrl-shift-i': 'window:toggle-dev-tools'
|
||||
'ctrl-alt-p': 'window:run-package-specs'
|
||||
'ctrl-shift-y': 'window:run-package-specs'
|
||||
'ctrl-shift-o': 'application:open-folder'
|
||||
'ctrl-alt-o': 'application:add-project-folder'
|
||||
'ctrl-shift-a': 'application:add-project-folder'
|
||||
'ctrl-shift-left': 'pane:move-item-left'
|
||||
'ctrl-shift-right': 'pane:move-item-right'
|
||||
'f11': 'window:toggle-full-screen'
|
||||
@@ -75,12 +75,12 @@
|
||||
'ctrl-k left': 'pane:split-left-and-copy-active-item' # Atom Specific
|
||||
'ctrl-k right': 'pane:split-right-and-copy-active-item' # Atom Specific
|
||||
'ctrl-k ctrl-w': 'pane:close' # Atom Specific
|
||||
'ctrl-k alt-ctrl-w': 'pane:close-other-items' # Atom Specific
|
||||
'ctrl-k ctrl-alt-w': 'pane:close-other-items' # Atom Specific
|
||||
'ctrl-k ctrl-p': 'window:focus-previous-pane'
|
||||
'ctrl-k ctrl-n': 'window:focus-next-pane'
|
||||
'ctrl-k ctrl-up': 'window:focus-pane-above'
|
||||
'ctrl-k ctrl-down': 'window:focus-pane-below'
|
||||
'ctrl-k ctrl-left': 'window:focus-pane-on-left'
|
||||
'ctrl-k ctrl-up': 'window:focus-pane-above'
|
||||
'ctrl-k ctrl-down': 'window:focus-pane-below'
|
||||
'ctrl-k ctrl-left': 'window:focus-pane-on-left'
|
||||
'ctrl-k ctrl-right': 'window:focus-pane-on-right'
|
||||
'alt-1': 'pane:show-item-1'
|
||||
'alt-2': 'pane:show-item-2'
|
||||
@@ -113,16 +113,14 @@
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-a': 'core:select-all'
|
||||
'ctrl-alt-shift-p': 'editor:log-cursor-scope'
|
||||
'ctrl-k ctrl-u': 'editor:upper-case'
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'atom-workspace atom-text-editor:not([mini])':
|
||||
# Atom specific
|
||||
'alt-ctrl-z': 'editor:checkout-head-revision'
|
||||
'ctrl-<': 'editor:scroll-to-cursor'
|
||||
'alt-ctrl-f': 'editor:fold-selection'
|
||||
'ctrl-alt-shift-[': 'editor:fold-selection'
|
||||
|
||||
# Sublime Parity
|
||||
'ctrl-enter': 'editor:newline-below'
|
||||
|
||||
@@ -108,9 +108,9 @@
|
||||
submenu: [
|
||||
{ label: 'Fold', command: 'editor:fold-current-row' }
|
||||
{ label: 'Unfold', command: 'editor:unfold-current-row' }
|
||||
{ label: 'Fold All', command: 'editor:fold-all' }
|
||||
{ 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' }
|
||||
|
||||
@@ -81,9 +81,9 @@
|
||||
submenu: [
|
||||
{ label: '&Fold', command: 'editor:fold-current-row' }
|
||||
{ label: '&Unfold', command: 'editor:unfold-current-row' }
|
||||
{ label: 'Fol&d All', command: 'editor:fold-all' }
|
||||
{ label: 'Unfold &All', command: 'editor:unfold-all' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Fol&d 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' }
|
||||
|
||||
@@ -89,9 +89,9 @@
|
||||
submenu: [
|
||||
{ label: '&Fold', command: 'editor:fold-current-row' }
|
||||
{ label: '&Unfold', command: 'editor:unfold-current-row' }
|
||||
{ label: 'Fol&d All', command: 'editor:fold-all' }
|
||||
{ label: 'Unfold &All', command: 'editor:unfold-all' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Fol&d 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' }
|
||||
|
||||
85
package.json
85
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "1.13.0-dev",
|
||||
"version": "1.14.0-dev",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/main-process/main.js",
|
||||
"repository": {
|
||||
@@ -12,11 +12,11 @@
|
||||
"url": "https://github.com/atom/atom/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"electronVersion": "1.3.6",
|
||||
"electronVersion": "1.3.13",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "7.1.1",
|
||||
"atom-space-pen-views": "^2.0.0",
|
||||
"atom-keymap": "7.1.15",
|
||||
"atom-select-list": "0.0.6",
|
||||
"atom-ui": "0.4.1",
|
||||
"babel-core": "5.8.38",
|
||||
"cached-run-in-this-context": "0.4.1",
|
||||
@@ -33,7 +33,7 @@
|
||||
"fs-plus": "2.9.2",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "^2.1",
|
||||
"git-utils": "^4.1.2",
|
||||
"git-utils": "4.1.2",
|
||||
"glob": "^7.1.1",
|
||||
"grim": "1.5.0",
|
||||
"jasmine-json": "~0.0",
|
||||
@@ -45,17 +45,18 @@
|
||||
"marked": "^0.3.6",
|
||||
"minimatch": "^3.0.3",
|
||||
"mocha": "2.5.1",
|
||||
"mock-spawn": "^0.2.6",
|
||||
"normalize-package-data": "^2.0.0",
|
||||
"nslog": "^3",
|
||||
"oniguruma": "6.1.0",
|
||||
"pathwatcher": "~6.5",
|
||||
"pathwatcher": "^6.7.1",
|
||||
"postcss": "5.2.4",
|
||||
"postcss-selector-parser": "2.2.1",
|
||||
"property-accessors": "^1.1.3",
|
||||
"random-words": "0.0.1",
|
||||
"resolve": "^1.1.6",
|
||||
"runas": "^3.1",
|
||||
"scandal": "^2.2.1",
|
||||
"scandal": "2.2.2",
|
||||
"scoped-property-store": "^0.17.0",
|
||||
"scrollbar-style": "^3.2",
|
||||
"season": "^5.4.1",
|
||||
@@ -64,7 +65,7 @@
|
||||
"sinon": "1.17.4",
|
||||
"source-map-support": "^0.3.2",
|
||||
"temp": "0.8.1",
|
||||
"text-buffer": "9.4.1",
|
||||
"text-buffer": "9.4.3",
|
||||
"typescript-simple": "1.0.0",
|
||||
"underscore-plus": "^1.6.6",
|
||||
"winreg": "^1.2.1",
|
||||
@@ -77,88 +78,88 @@
|
||||
"atom-light-ui": "0.46.0",
|
||||
"base16-tomorrow-dark-theme": "1.4.0",
|
||||
"base16-tomorrow-light-theme": "1.4.0",
|
||||
"one-dark-ui": "1.8.2",
|
||||
"one-light-ui": "1.8.2",
|
||||
"one-dark-ui": "1.9.0",
|
||||
"one-light-ui": "1.9.0",
|
||||
"one-dark-syntax": "1.6.0",
|
||||
"one-light-syntax": "1.6.0",
|
||||
"solarized-dark-syntax": "1.1.1",
|
||||
"solarized-light-syntax": "1.1.1",
|
||||
"about": "1.7.2",
|
||||
"archive-view": "0.62.0",
|
||||
"archive-view": "0.62.2",
|
||||
"autocomplete-atom-api": "0.10.0",
|
||||
"autocomplete-css": "0.14.1",
|
||||
"autocomplete-html": "0.7.2",
|
||||
"autocomplete-plus": "2.33.1",
|
||||
"autocomplete-plus": "2.34.2",
|
||||
"autocomplete-snippets": "1.11.0",
|
||||
"autoflow": "0.27.0",
|
||||
"autoflow": "0.29.0",
|
||||
"autosave": "0.23.2",
|
||||
"background-tips": "0.26.1",
|
||||
"bookmarks": "0.43.2",
|
||||
"bracket-matcher": "0.82.2",
|
||||
"command-palette": "0.39.1",
|
||||
"bookmarks": "0.43.4",
|
||||
"bracket-matcher": "0.85.0",
|
||||
"command-palette": "0.39.2",
|
||||
"deprecation-cop": "0.55.1",
|
||||
"dev-live-reload": "0.47.0",
|
||||
"encoding-selector": "0.22.0",
|
||||
"exception-reporting": "0.40.0",
|
||||
"find-and-replace": "0.204.1",
|
||||
"fuzzy-finder": "1.4.0",
|
||||
"exception-reporting": "0.40.1",
|
||||
"find-and-replace": "0.204.7",
|
||||
"fuzzy-finder": "1.4.1",
|
||||
"git-diff": "1.2.0",
|
||||
"go-to-line": "0.31.2",
|
||||
"grammar-selector": "0.48.2",
|
||||
"image-view": "0.60.0",
|
||||
"incompatible-packages": "0.26.1",
|
||||
"keybinding-resolver": "0.35.0",
|
||||
"line-ending-selector": "0.5.0",
|
||||
"line-ending-selector": "0.5.1",
|
||||
"link": "0.31.2",
|
||||
"markdown-preview": "0.159.1",
|
||||
"metrics": "1.0.0",
|
||||
"notifications": "0.65.1",
|
||||
"metrics": "1.1.2",
|
||||
"notifications": "0.65.2",
|
||||
"open-on-github": "1.2.1",
|
||||
"package-generator": "1.0.2",
|
||||
"settings-view": "0.244.0",
|
||||
"snippets": "1.0.3",
|
||||
"spell-check": "0.68.5",
|
||||
"status-bar": "1.6.0",
|
||||
"snippets": "1.0.4",
|
||||
"spell-check": "0.69.0",
|
||||
"status-bar": "1.7.0",
|
||||
"styleguide": "0.48.0",
|
||||
"symbols-view": "0.113.1",
|
||||
"symbols-view": "0.113.2",
|
||||
"tabs": "0.103.1",
|
||||
"timecop": "0.33.2",
|
||||
"tree-view": "0.211.1",
|
||||
"update-package-dependencies": "0.10.0",
|
||||
"welcome": "0.35.1",
|
||||
"welcome": "0.35.2",
|
||||
"whitespace": "0.35.0",
|
||||
"wrap-guide": "0.39.0",
|
||||
"language-c": "0.54.0",
|
||||
"language-clojure": "0.22.1",
|
||||
"language-coffee-script": "0.48.1",
|
||||
"language-csharp": "0.12.1",
|
||||
"language-css": "0.40.1",
|
||||
"language-coffee-script": "0.48.2",
|
||||
"language-csharp": "0.13.0",
|
||||
"language-css": "0.41.0",
|
||||
"language-gfm": "0.88.0",
|
||||
"language-git": "0.15.0",
|
||||
"language-git": "0.19.0",
|
||||
"language-go": "0.43.0",
|
||||
"language-html": "0.46.1",
|
||||
"language-html": "0.47.1",
|
||||
"language-hyperlink": "0.16.1",
|
||||
"language-java": "0.24.0",
|
||||
"language-javascript": "0.122.0",
|
||||
"language-javascript": "0.124.0",
|
||||
"language-json": "0.18.3",
|
||||
"language-less": "0.29.6",
|
||||
"language-make": "0.22.2",
|
||||
"language-mustache": "0.13.0",
|
||||
"language-less": "0.30.0",
|
||||
"language-make": "0.22.3",
|
||||
"language-mustache": "0.13.1",
|
||||
"language-objective-c": "0.15.1",
|
||||
"language-perl": "0.37.0",
|
||||
"language-php": "0.37.3",
|
||||
"language-property-list": "0.8.0",
|
||||
"language-property-list": "0.9.0",
|
||||
"language-python": "0.45.1",
|
||||
"language-ruby": "0.70.2",
|
||||
"language-ruby": "0.70.3",
|
||||
"language-ruby-on-rails": "0.25.1",
|
||||
"language-sass": "0.57.0",
|
||||
"language-shellscript": "0.23.0",
|
||||
"language-sass": "0.57.1",
|
||||
"language-shellscript": "0.24.0",
|
||||
"language-source": "0.9.0",
|
||||
"language-sql": "0.25.0",
|
||||
"language-sql": "0.25.1",
|
||||
"language-text": "0.7.1",
|
||||
"language-todo": "0.29.1",
|
||||
"language-toml": "0.18.1",
|
||||
"language-xml": "0.34.12",
|
||||
"language-xml": "0.34.13",
|
||||
"language-yaml": "0.27.1"
|
||||
},
|
||||
"private": true,
|
||||
|
||||
@@ -8,6 +8,11 @@ AutoReqProv: no # Avoid libchromiumcontent.so missing dependency
|
||||
Prefix: <%= installDir %>
|
||||
|
||||
Requires: lsb-core-noarch
|
||||
%if 0%{?fedora} || 0%{?rhel}
|
||||
Requires: libXScrnSaver
|
||||
%else
|
||||
Requires: libXss1
|
||||
%endif
|
||||
|
||||
%description
|
||||
<%= description %>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
@echo off
|
||||
|
||||
"%~dp0\..\app\apm\bin\node.exe" "%~dp0\..\app\apm\lib\cli.js" %*
|
||||
"%~dp0\..\app\apm\bin\apm.cmd" %*
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
directory=$(dirname "$0")
|
||||
"$directory/../app/apm/bin/node.exe" "$directory/../app/apm/lib/cli.js" "$@"
|
||||
"$(dirname "$0")/../app/apm/apm.sh" "$@"
|
||||
|
||||
@@ -866,6 +866,10 @@
|
||||
"hasDeprecations": true,
|
||||
"latestHasDeprecations": true
|
||||
},
|
||||
"language-nlf": {
|
||||
"hasAlternative": true,
|
||||
"alternative": "language-nsis"
|
||||
},
|
||||
"language-rspec": {
|
||||
"version": "<=0.2.1",
|
||||
"hasDeprecations": true,
|
||||
|
||||
@@ -7,23 +7,7 @@ const spawnSync = require('./spawn-sync')
|
||||
const CONFIG = require('../config')
|
||||
|
||||
module.exports = function (packagedAppPath) {
|
||||
let appArchiveName
|
||||
if (process.platform === 'darwin') {
|
||||
appArchiveName = 'atom-mac.zip'
|
||||
} else if (process.platform === 'win32') {
|
||||
appArchiveName = 'atom-windows.zip'
|
||||
} else {
|
||||
let arch
|
||||
if (process.arch === 'ia32') {
|
||||
arch = 'i386'
|
||||
} else if (process.arch === 'x64') {
|
||||
arch = 'amd64'
|
||||
} else {
|
||||
arch = process.arch
|
||||
}
|
||||
appArchiveName = `atom-${arch}.tar.gz`
|
||||
}
|
||||
const appArchivePath = path.join(CONFIG.buildOutputPath, appArchiveName)
|
||||
const appArchivePath = path.join(CONFIG.buildOutputPath, getArchiveName())
|
||||
compress(packagedAppPath, appArchivePath)
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
@@ -32,6 +16,22 @@ module.exports = function (packagedAppPath) {
|
||||
}
|
||||
}
|
||||
|
||||
function getArchiveName () {
|
||||
switch (process.platform) {
|
||||
case 'darwin': return 'atom-mac.zip'
|
||||
case 'win32': return `atom-windows.zip`
|
||||
default: return `atom-${getLinuxArchiveArch()}.tar.gz`
|
||||
}
|
||||
}
|
||||
|
||||
function getLinuxArchiveArch () {
|
||||
switch (process.arch) {
|
||||
case 'ia32': return 'i386'
|
||||
case 'x64' : return 'amd64'
|
||||
default: return process.arch
|
||||
}
|
||||
}
|
||||
|
||||
function compress (inputDirPath, outputArchivePath) {
|
||||
if (fs.existsSync(outputArchivePath)) {
|
||||
console.log(`Deleting "${outputArchivePath}"`)
|
||||
|
||||
@@ -11,30 +11,36 @@ const spawnSync = require('./spawn-sync')
|
||||
const CONFIG = require('../config')
|
||||
|
||||
module.exports = function (packagedAppPath, codeSign) {
|
||||
const archSuffix = process.arch === 'ia32' ? '' : '-' + process.arch
|
||||
const options = {
|
||||
appDirectory: packagedAppPath,
|
||||
authors: 'GitHub Inc.',
|
||||
iconUrl: `https://raw.githubusercontent.com/atom/atom/master/resources/app-icons/${CONFIG.channel}/atom.ico`,
|
||||
loadingGif: path.join(CONFIG.repositoryRootPath, 'resources', 'win', 'loading.gif'),
|
||||
outputDirectory: CONFIG.buildOutputPath,
|
||||
remoteReleases: `https://atom.io/api/updates?version=${CONFIG.appMetadata.version}`,
|
||||
remoteReleases: `https://atom.io/api/updates${archSuffix}`,
|
||||
setupIcon: path.join(CONFIG.repositoryRootPath, 'resources', 'app-icons', CONFIG.channel, 'atom.ico')
|
||||
}
|
||||
|
||||
// Remove this once an x64 version is published or atom.io is returning blank instead of 404 for RELEASES-X64
|
||||
if (process.arch === 'x64') {
|
||||
options.remoteReleases = null
|
||||
}
|
||||
|
||||
const certPath = path.join(os.tmpdir(), 'win.p12')
|
||||
const signing = codeSign && process.env.WIN_P12KEY_URL
|
||||
const signing = codeSign && process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL
|
||||
|
||||
if (signing) {
|
||||
downloadFileFromGithub(process.env.WIN_P12KEY_URL, certPath)
|
||||
downloadFileFromGithub(process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL, certPath)
|
||||
var signParams = []
|
||||
signParams.push(`/f ${certPath}`) // Signing cert file
|
||||
signParams.push(`/p ${process.env.WIN_P12KEY_PASSWORD}`) // Signing cert password
|
||||
signParams.push(`/p ${process.env.ATOM_WIN_CODE_SIGNING_CERT_PASSWORD}`) // Signing cert password
|
||||
signParams.push('/fd sha256') // File digest algorithm
|
||||
signParams.push('/tr http://timestamp.digicert.com') // Time stamp server
|
||||
signParams.push('/td sha256') // Times stamp algorithm
|
||||
options.signWithParams = signParams.join(' ')
|
||||
} else {
|
||||
console.log('Skipping code-signing. Specify the --code-sign option and provide a WIN_P12KEY_URL environment variable to perform code-signing'.gray)
|
||||
console.log('Skipping code-signing. Specify the --code-sign option and provide a ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL environment variable to perform code-signing'.gray)
|
||||
}
|
||||
|
||||
const cleanUp = function () {
|
||||
|
||||
@@ -22,7 +22,7 @@ module.exports = {
|
||||
// Include the electron minor version in the fingerprint since that changing requires a re-install
|
||||
const electronVersion = CONFIG.appMetadata.electronVersion.replace(/\.\d+$/, '')
|
||||
const apmVersion = CONFIG.apmMetadata.dependencies['atom-package-manager']
|
||||
const body = electronVersion + apmVersion + process.platform + process.version
|
||||
const body = electronVersion + apmVersion + process.platform + process.version + process.arch
|
||||
return crypto.createHash('sha1').update(body).digest('hex')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,26 +11,23 @@ const syncRequest = require('sync-request')
|
||||
const CONFIG = require('../config')
|
||||
|
||||
module.exports = function () {
|
||||
if (process.platform === 'darwin') {
|
||||
// Chromedriver is only distributed with the first patch release for any given
|
||||
// major and minor version of electron.
|
||||
const electronVersion = semver.parse(CONFIG.appMetadata.electronVersion)
|
||||
const electronVersionWithChromedriver = `${electronVersion.major}.${electronVersion.minor}.0`
|
||||
const electronAssets = getElectronAssetsForVersion(electronVersionWithChromedriver)
|
||||
const chromedriverAssets = electronAssets.filter(e => /chromedriver.*darwin-x64/.test(e.name))
|
||||
assert(chromedriverAssets.length === 1, 'Found more than one chrome driver asset to download!')
|
||||
const chromedriverAsset = chromedriverAssets[0]
|
||||
// Chromedriver is only distributed with the first patch release for any given
|
||||
// major and minor version of electron.
|
||||
const electronVersion = semver.parse(CONFIG.appMetadata.electronVersion)
|
||||
const electronVersionWithChromedriver = `${electronVersion.major}.${electronVersion.minor}.0`
|
||||
const electronAssets = getElectronAssetsForVersion(electronVersionWithChromedriver)
|
||||
const chromeDriverMatch = new RegExp(`^chromedriver-v.*-${process.platform}-${process.arch}`)
|
||||
const chromedriverAssets = electronAssets.filter(e => chromeDriverMatch.test(e.name))
|
||||
assert(chromedriverAssets.length === 1, 'Found more than one chrome driver asset to download!')
|
||||
const chromedriverAsset = chromedriverAssets[0]
|
||||
|
||||
const chromedriverZipPath = path.join(CONFIG.electronDownloadPath, `electron-${electronVersionWithChromedriver}-${chromedriverAsset.name}`)
|
||||
if (!fs.existsSync(chromedriverZipPath)) {
|
||||
downloadFileFromGithub(chromedriverAsset.url, chromedriverZipPath)
|
||||
}
|
||||
|
||||
const chromedriverDirPath = path.join(CONFIG.electronDownloadPath, 'chromedriver')
|
||||
unzipPath(chromedriverZipPath, chromedriverDirPath)
|
||||
} else {
|
||||
console.log('Skipping Chromedriver download because it is used only on macOS'.gray)
|
||||
const chromedriverZipPath = path.join(CONFIG.electronDownloadPath, `electron-${electronVersionWithChromedriver}-${chromedriverAsset.name}`)
|
||||
if (!fs.existsSync(chromedriverZipPath)) {
|
||||
downloadFileFromGithub(chromedriverAsset.url, chromedriverZipPath)
|
||||
}
|
||||
|
||||
const chromedriverDirPath = path.join(CONFIG.electronDownloadPath, 'chromedriver')
|
||||
unzipPath(chromedriverZipPath, chromedriverDirPath)
|
||||
}
|
||||
|
||||
function getElectronAssetsForVersion (version) {
|
||||
@@ -52,5 +49,16 @@ function unzipPath (inputPath, outputPath) {
|
||||
}
|
||||
|
||||
console.log(`Unzipping "${inputPath}" to "${outputPath}"`)
|
||||
spawnSync('unzip', [inputPath, '-d', outputPath])
|
||||
try {
|
||||
spawnSync('unzip', [inputPath, '-d', outputPath])
|
||||
}
|
||||
catch(err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
// Unzip might not be available on Windows even though it comes with git so fall back to 7zip
|
||||
spawnSync('7z', ['x', inputPath, `-o${outputPath}`])
|
||||
}
|
||||
else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,6 @@ module.exports = function () {
|
||||
// Set our target (Electron) version so that node-pre-gyp can download the
|
||||
// proper binaries.
|
||||
installEnv.npm_config_target = CONFIG.appMetadata.electronVersion;
|
||||
// Force 32-bit modules on Windows. (Ref.: https://github.com/atom/atom/issues/10450)
|
||||
if (process.platform === 'win32') {
|
||||
installEnv.npm_config_target_arch = 'ia32'
|
||||
}
|
||||
childProcess.execFileSync(
|
||||
CONFIG.getApmBinPath(),
|
||||
['--loglevel=error', 'install'],
|
||||
|
||||
@@ -18,12 +18,7 @@ module.exports = function () {
|
||||
'app-bundle-id': 'com.github.atom',
|
||||
'app-copyright': `Copyright © 2014-${(new Date()).getFullYear()} GitHub, Inc. All rights reserved.`,
|
||||
'app-version': CONFIG.appMetadata.version,
|
||||
'arch': (() => {
|
||||
if (process.platform === 'linux') {
|
||||
return process.arch
|
||||
} else {
|
||||
return process.platform === 'win32' ? 'ia32' : 'x64'
|
||||
}})(),
|
||||
'arch': process.platform === 'darwin' ? 'x64' : process.arch, // OS X is 64-bit only
|
||||
'asar': {unpack: buildAsarUnpackGlobExpression()},
|
||||
'build-version': CONFIG.appMetadata.version,
|
||||
'download': {cache: CONFIG.electronDownloadPath},
|
||||
@@ -174,6 +169,9 @@ function renamePackagedAppDir (packageOutputDirPath) {
|
||||
} else {
|
||||
const appName = CONFIG.channel === 'beta' ? 'Atom Beta' : 'Atom'
|
||||
packagedAppPath = path.join(CONFIG.buildOutputPath, appName)
|
||||
if (process.platform === 'win32' && process.arch !== 'ia32') {
|
||||
packagedAppPath += ` ${process.arch}`
|
||||
}
|
||||
if (fs.existsSync(packagedAppPath)) fs.removeSync(packagedAppPath)
|
||||
fs.renameSync(packageOutputDirPath, packagedAppPath)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"csslint": "1.0.2",
|
||||
"donna": "1.0.13",
|
||||
"electron-packager": "7.3.0",
|
||||
"electron-winstaller": "2.3.4",
|
||||
"electron-winstaller": "2.5.0",
|
||||
"fs-extra": "0.30.0",
|
||||
"glob": "7.0.3",
|
||||
"joanna": "0.0.6",
|
||||
|
||||
14
script/test
14
script/test
@@ -93,11 +93,15 @@ function runBenchmarkTests (callback) {
|
||||
cp.on('close', exitCode => { callback(null, exitCode) })
|
||||
}
|
||||
|
||||
let testSuitesToRun
|
||||
if (process.platform === 'darwin') {
|
||||
testSuitesToRun = [runCoreMainProcessTests, runCoreRenderProcessTests, runBenchmarkTests].concat(packageTestSuites)
|
||||
} else {
|
||||
testSuitesToRun = [runCoreMainProcessTests]
|
||||
let testSuitesToRun = testSuitesForPlatform(process.platform)
|
||||
|
||||
function testSuitesForPlatform(platform) {
|
||||
switch(platform) {
|
||||
case 'darwin': return [runCoreMainProcessTests, runCoreRenderProcessTests, runBenchmarkTests].concat(packageTestSuites)
|
||||
case 'win32': return (process.arch === 'x64') ? [runCoreMainProcessTests, runCoreRenderProcessTests] : [runCoreMainProcessTests]
|
||||
case 'linux': return [runCoreMainProcessTests]
|
||||
default: return []
|
||||
}
|
||||
}
|
||||
|
||||
async.series(testSuitesToRun, function (err, exitCodes) {
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
_ = require 'underscore-plus'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
AtomEnvironment = require '../src/atom-environment'
|
||||
StorageFolder = require '../src/storage-folder'
|
||||
|
||||
describe "AtomEnvironment", ->
|
||||
afterEach ->
|
||||
temp.cleanupSync()
|
||||
|
||||
describe 'window sizing methods', ->
|
||||
describe '::getPosition and ::setPosition', ->
|
||||
originalPosition = null
|
||||
@@ -324,7 +327,7 @@ describe "AtomEnvironment", ->
|
||||
|
||||
describe "::unloadEditorWindow()", ->
|
||||
it "saves the BlobStore so it can be loaded after reload", ->
|
||||
configDirPath = temp.mkdirSync()
|
||||
configDirPath = temp.mkdirSync('atom-spec-environment')
|
||||
fakeBlobStore = jasmine.createSpyObj("blob store", ["save"])
|
||||
atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, enablePersistence: true, configDirPath, blobStore: fakeBlobStore, window, document})
|
||||
|
||||
@@ -336,7 +339,7 @@ describe "AtomEnvironment", ->
|
||||
|
||||
describe "::destroy()", ->
|
||||
it "does not throw exceptions when unsubscribing from ipc events (regression)", ->
|
||||
configDirPath = temp.mkdirSync()
|
||||
configDirPath = temp.mkdirSync('atom-spec-environment')
|
||||
fakeDocument = {
|
||||
addEventListener: ->
|
||||
removeEventListener: ->
|
||||
@@ -401,6 +404,8 @@ describe "AtomEnvironment", ->
|
||||
subscription?.dispose()
|
||||
|
||||
it "invokes onUpdateAvailable listeners", ->
|
||||
return unless process.platform is 'darwin' # Test tied to electron autoUpdater, we use something else on Linux and Win32
|
||||
|
||||
atom.listenForUpdates()
|
||||
|
||||
updateAvailableHandler = jasmine.createSpy("update-available-handler")
|
||||
|
||||
119
spec/atom-paths-spec.js
Normal file
119
spec/atom-paths-spec.js
Normal file
@@ -0,0 +1,119 @@
|
||||
/** @babel */
|
||||
|
||||
import {it, fit, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers'
|
||||
import {app} from 'remote'
|
||||
import atomPaths from '../src/atom-paths'
|
||||
import fs from 'fs-plus'
|
||||
import path from 'path'
|
||||
const temp = require('temp').track()
|
||||
|
||||
describe("AtomPaths", () => {
|
||||
const portableAtomHomePath = path.join(atomPaths.getAppDirectory(), '.atom')
|
||||
console.log(portableAtomHomePath)
|
||||
|
||||
afterEach(() => {
|
||||
atomPaths.setAtomHome(app.getPath('home'))
|
||||
})
|
||||
|
||||
describe('SetAtomHomePath', () => {
|
||||
describe('when a portable .atom folder exists', () => {
|
||||
beforeEach(() => {
|
||||
delete process.env.ATOM_HOME
|
||||
if (!fs.existsSync(portableAtomHomePath))
|
||||
fs.mkdirSync(portableAtomHomePath)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
delete process.env.ATOM_HOME
|
||||
fs.removeSync(portableAtomHomePath)
|
||||
})
|
||||
|
||||
it('sets ATOM_HOME to the portable .atom folder if it has permission', () => {
|
||||
atomPaths.setAtomHome(app.getPath('home'))
|
||||
expect(process.env.ATOM_HOME).toEqual(portableAtomHomePath)
|
||||
})
|
||||
|
||||
it('uses ATOM_HOME if no write access to portable .atom folder', () => {
|
||||
if (process.platform === 'win32') return
|
||||
|
||||
const readOnlyPath = temp.mkdirSync('atom-path-spec-no-write-access')
|
||||
process.env.ATOM_HOME = readOnlyPath
|
||||
fs.chmodSync(portableAtomHomePath, 444)
|
||||
atomPaths.setAtomHome(app.getPath('home'))
|
||||
expect(process.env.ATOM_HOME).toEqual(readOnlyPath)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when a portable folder does not exist', () => {
|
||||
beforeEach(() => {
|
||||
delete process.env.ATOM_HOME
|
||||
fs.removeSync(portableAtomHomePath)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
delete process.env.ATOM_HOME
|
||||
})
|
||||
|
||||
it('leaves ATOM_HOME unmodified if it was already set', () => {
|
||||
const temporaryHome = temp.mkdirSync('atom-spec-setatomhomepath')
|
||||
process.env.ATOM_HOME = temporaryHome
|
||||
atomPaths.setAtomHome(app.getPath('home'))
|
||||
expect(process.env.ATOM_HOME).toEqual(temporaryHome)
|
||||
})
|
||||
|
||||
it('sets ATOM_HOME to a default location if not yet set', () => {
|
||||
const expectedPath = path.join(app.getPath('home'), '.atom')
|
||||
atomPaths.setAtomHome(app.getPath('home'))
|
||||
expect(process.env.ATOM_HOME).toEqual(expectedPath)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('setUserData', () => {
|
||||
let tempAtomHomePath = null
|
||||
let electronUserDataPath = null
|
||||
let defaultElectronUserDataPath = null
|
||||
|
||||
beforeEach(() => {
|
||||
defaultElectronUserDataPath = app.getPath('userData')
|
||||
delete process.env.ATOM_HOME
|
||||
tempAtomHomePath = temp.mkdirSync('atom-paths-specs-userdata-home')
|
||||
tempAtomConfigPath = path.join(tempAtomHomePath, '.atom')
|
||||
fs.mkdirSync(tempAtomConfigPath)
|
||||
electronUserDataPath = path.join(tempAtomConfigPath, 'electronUserData')
|
||||
atomPaths.setAtomHome(tempAtomHomePath)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
delete process.env.ATOM_HOME
|
||||
fs.removeSync(electronUserDataPath)
|
||||
temp.cleanupSync()
|
||||
app.setPath('userData', defaultElectronUserDataPath)
|
||||
})
|
||||
|
||||
describe('when an electronUserData folder exists', () => {
|
||||
it('sets userData path to the folder if it has permission', () => {
|
||||
fs.mkdirSync(electronUserDataPath)
|
||||
atomPaths.setUserData(app)
|
||||
expect(app.getPath('userData')).toEqual(electronUserDataPath)
|
||||
})
|
||||
|
||||
it('leaves userData unchanged if no write access to electronUserData folder', () => {
|
||||
if (process.platform === 'win32') return
|
||||
|
||||
fs.mkdirSync(electronUserDataPath)
|
||||
fs.chmodSync(electronUserDataPath, 444)
|
||||
atomPaths.setUserData(app)
|
||||
fs.chmodSync(electronUserDataPath, 666)
|
||||
expect(app.getPath('userData')).toEqual(defaultElectronUserDataPath)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when an electronUserDataPath folder does not exist', () => {
|
||||
it('leaves userData app path unchanged', () => {
|
||||
atomPaths.setUserData(app)
|
||||
expect(app.getPath('userData')).toEqual(defaultElectronUserDataPath)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,67 +0,0 @@
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
AtomPortable = require '../src/main-process/atom-portable'
|
||||
|
||||
portableModeCommonPlatformBehavior = (platform) ->
|
||||
describe "with ATOM_HOME environment variable", ->
|
||||
it "returns false", ->
|
||||
expect(AtomPortable.isPortableInstall(platform, "C:\\some\\path")).toBe false
|
||||
|
||||
describe "without ATOM_HOME environment variable", ->
|
||||
environmentAtomHome = undefined
|
||||
portableAtomHomePath = path.join(path.dirname(process.execPath), "..", ".atom")
|
||||
portableAtomHomeNaturallyExists = fs.existsSync(portableAtomHomePath)
|
||||
portableAtomHomeBackupPath = "#{portableAtomHomePath}.temp"
|
||||
|
||||
beforeEach ->
|
||||
fs.renameSync(portableAtomHomePath, portableAtomHomeBackupPath) if fs.existsSync(portableAtomHomePath)
|
||||
|
||||
afterEach ->
|
||||
if portableAtomHomeNaturallyExists
|
||||
fs.renameSync(portableAtomHomeBackupPath, portableAtomHomePath) if not fs.existsSync(portableAtomHomePath)
|
||||
else
|
||||
fs.removeSync(portableAtomHomePath) if fs.existsSync(portableAtomHomePath)
|
||||
fs.removeSync(portableAtomHomeBackupPath) if fs.existsSync(portableAtomHomeBackupPath)
|
||||
|
||||
describe "with .atom directory sibling to exec", ->
|
||||
beforeEach ->
|
||||
fs.mkdirSync(portableAtomHomePath) if not fs.existsSync(portableAtomHomePath)
|
||||
|
||||
describe "without .atom directory sibling to exec", ->
|
||||
beforeEach ->
|
||||
fs.removeSync(portableAtomHomePath) if fs.existsSync(portableAtomHomePath)
|
||||
|
||||
it "returns false", ->
|
||||
expect(AtomPortable.isPortableInstall(platform, environmentAtomHome)).toBe false
|
||||
|
||||
describe "Set Portable Mode on #win32", ->
|
||||
portableAtomHomePath = path.join(path.dirname(process.execPath), "..", ".atom")
|
||||
portableAtomHomeNaturallyExists = fs.existsSync(portableAtomHomePath)
|
||||
portableAtomHomeBackupPath = "#{portableAtomHomePath}.temp"
|
||||
|
||||
beforeEach ->
|
||||
fs.renameSync(portableAtomHomePath, portableAtomHomeBackupPath) if fs.existsSync(portableAtomHomePath)
|
||||
|
||||
afterEach ->
|
||||
if portableAtomHomeNaturallyExists
|
||||
fs.renameSync(portableAtomHomeBackupPath, portableAtomHomePath) if not fs.existsSync(portableAtomHomePath)
|
||||
else
|
||||
fs.removeSync(portableAtomHomePath) if fs.existsSync(portableAtomHomePath)
|
||||
fs.removeSync(portableAtomHomeBackupPath) if fs.existsSync(portableAtomHomeBackupPath)
|
||||
|
||||
it "creates a portable home directory", ->
|
||||
expect(fs.existsSync(portableAtomHomePath)).toBe false
|
||||
|
||||
AtomPortable.setPortable(process.env.ATOM_HOME)
|
||||
expect(fs.existsSync(portableAtomHomePath)).toBe true
|
||||
|
||||
describe "Check for Portable Mode", ->
|
||||
describe "Windows", ->
|
||||
portableModeCommonPlatformBehavior "win32"
|
||||
|
||||
describe "Mac", ->
|
||||
it "returns false", ->
|
||||
expect(AtomPortable.isPortableInstall("darwin", "darwin")).toBe false
|
||||
|
||||
describe "Linux", ->
|
||||
portableModeCommonPlatformBehavior "linux"
|
||||
@@ -5,6 +5,9 @@ import {remote} from 'electron'
|
||||
const electronAutoUpdater = remote.require('electron').autoUpdater
|
||||
|
||||
describe('AutoUpdateManager (renderer)', () => {
|
||||
|
||||
if (process.platform !== 'darwin') return // Tests are tied to electron autoUpdater, we use something else on Linux and Win32
|
||||
|
||||
let autoUpdateManager
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -19,6 +19,7 @@ describe "Babel transpiler support", ->
|
||||
|
||||
afterEach ->
|
||||
CompileCache.setCacheDirectory(originalCacheDir)
|
||||
temp.cleanupSync()
|
||||
|
||||
describe 'when a .js file starts with /** @babel */;', ->
|
||||
it "transpiles it using babel", ->
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
CommandInstaller = require '../src/command-installer'
|
||||
|
||||
describe "CommandInstaller on #darwin", ->
|
||||
@@ -20,6 +20,9 @@ describe "CommandInstaller on #darwin", ->
|
||||
spyOn(CommandInstaller::, 'getResourcesDirectory').andReturn(resourcesPath)
|
||||
spyOn(CommandInstaller::, 'getInstallDirectory').andReturn(installationPath)
|
||||
|
||||
afterEach ->
|
||||
temp.cleanupSync()
|
||||
|
||||
it "shows an error dialog when installing commands interactively fails", ->
|
||||
appDelegate = jasmine.createSpyObj("appDelegate", ["confirm"])
|
||||
installer = new CommandInstaller("2.0.2", appDelegate)
|
||||
|
||||
@@ -21,8 +21,9 @@ describe 'CompileCache', ->
|
||||
spyOn(TypeScriptSimple::, 'compile').andReturn 'the-typescript-code'
|
||||
|
||||
afterEach ->
|
||||
CSON.setCacheDir(CompileCache.getCacheDirectory())
|
||||
CompileCache.setAtomHomeDirectory(process.env.ATOM_HOME)
|
||||
CSON.setCacheDir(CompileCache.getCacheDirectory())
|
||||
temp.cleanupSync()
|
||||
|
||||
describe 'addPathToCache(filePath, atomHome)', ->
|
||||
describe 'when the given file is plain javascript', ->
|
||||
@@ -77,6 +78,8 @@ describe 'CompileCache', ->
|
||||
|
||||
describe 'overriding Error.prepareStackTrace', ->
|
||||
it 'removes the override on the next tick, and always assigns the raw stack', ->
|
||||
return if process.platform is 'win32' # Flakey Error.stack contents on Win32
|
||||
|
||||
Error.prepareStackTrace = -> 'a-stack-trace'
|
||||
|
||||
error = new Error("Oops")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
CSON = require 'season'
|
||||
fs = require 'fs-plus'
|
||||
|
||||
@@ -9,13 +9,14 @@ describe "Config", ->
|
||||
beforeEach ->
|
||||
spyOn(atom.config, "load")
|
||||
spyOn(atom.config, "save")
|
||||
dotAtomPath = temp.path('dot-atom-dir')
|
||||
dotAtomPath = temp.path('atom-spec-config')
|
||||
atom.config.configDirPath = dotAtomPath
|
||||
atom.config.enablePersistence = true
|
||||
atom.config.configFilePath = path.join(atom.config.configDirPath, "atom.config.cson")
|
||||
|
||||
afterEach ->
|
||||
atom.config.enablePersistence = false
|
||||
fs.removeSync(dotAtomPath)
|
||||
|
||||
describe ".get(keyPath, {scope, sources, excludeSources})", ->
|
||||
it "allows a key path's value to be read", ->
|
||||
@@ -486,8 +487,8 @@ describe "Config", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
atom.config.set('foo.bar.baz', "value 2")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 2")
|
||||
observeHandler.reset()
|
||||
|
||||
observeHandler.reset()
|
||||
atom.config.set('foo.bar.baz', "value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 1")
|
||||
advanceClock(100) # complete pending save that was requested in ::set
|
||||
@@ -1079,6 +1080,7 @@ describe "Config", ->
|
||||
|
||||
describe "when the configDirPath doesn't exist", ->
|
||||
it "copies the contents of dot-atom to ~/.atom", ->
|
||||
return if process.platform is 'win32' # Flakey test on Win32
|
||||
initializationDone = false
|
||||
jasmine.unspy(window, "setTimeout")
|
||||
atom.config.initializeConfigDirectory ->
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
DefaultDirectoryProvider = require '../src/default-directory-provider'
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
|
||||
describe "DefaultDirectoryProvider", ->
|
||||
tmp = null
|
||||
|
||||
beforeEach ->
|
||||
tmp = temp.mkdirSync('atom-spec-default-dir-provider')
|
||||
|
||||
afterEach ->
|
||||
temp.cleanupSync()
|
||||
|
||||
describe ".directoryForURISync(uri)", ->
|
||||
it "returns a Directory with a path that matches the uri", ->
|
||||
provider = new DefaultDirectoryProvider()
|
||||
tmp = temp.mkdirSync()
|
||||
|
||||
directory = provider.directoryForURISync(tmp)
|
||||
expect(directory.getPath()).toEqual tmp
|
||||
|
||||
it "normalizes its input before creating a Directory for it", ->
|
||||
provider = new DefaultDirectoryProvider()
|
||||
tmp = temp.mkdirSync()
|
||||
nonNormalizedPath = tmp + path.sep + ".." + path.sep + path.basename(tmp)
|
||||
expect(tmp.includes("..")).toBe false
|
||||
expect(nonNormalizedPath.includes("..")).toBe true
|
||||
@@ -24,7 +30,6 @@ describe "DefaultDirectoryProvider", ->
|
||||
|
||||
it "creates a Directory for its parent dir when passed a file", ->
|
||||
provider = new DefaultDirectoryProvider()
|
||||
tmp = temp.mkdirSync()
|
||||
file = path.join(tmp, "example.txt")
|
||||
fs.writeFileSync(file, "data")
|
||||
|
||||
@@ -40,7 +45,6 @@ describe "DefaultDirectoryProvider", ->
|
||||
describe ".directoryForURI(uri)", ->
|
||||
it "returns a Promise that resolves to a Directory with a path that matches the uri", ->
|
||||
provider = new DefaultDirectoryProvider()
|
||||
tmp = temp.mkdirSync()
|
||||
|
||||
waitsForPromise ->
|
||||
provider.directoryForURI(tmp).then (directory) ->
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
FileSystemBlobStore = require '../src/file-system-blob-store'
|
||||
@@ -7,9 +7,12 @@ describe "FileSystemBlobStore", ->
|
||||
[storageDirectory, blobStore] = []
|
||||
|
||||
beforeEach ->
|
||||
storageDirectory = temp.path()
|
||||
storageDirectory = temp.path('atom-spec-filesystemblobstore')
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
|
||||
afterEach ->
|
||||
fs.removeSync(storageDirectory)
|
||||
|
||||
it "is empty when the file doesn't exist", ->
|
||||
expect(blobStore.get("foo", "invalidation-key-1")).toBeUndefined()
|
||||
expect(blobStore.get("bar", "invalidation-key-2")).toBeUndefined()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
module.exports = {
|
||||
initialize() {},
|
||||
activate () {},
|
||||
|
||||
deserializeMethod1 (state) {
|
||||
|
||||
2
spec/fixtures/sample.txt
vendored
2
spec/fixtures/sample.txt
vendored
@@ -1 +1 @@
|
||||
Some text.
|
||||
Some textSome text.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
{Directory} = require 'pathwatcher'
|
||||
GitRepository = require '../src/git-repository'
|
||||
GitRepositoryProvider = require '../src/git-repository-provider'
|
||||
@@ -11,6 +11,9 @@ describe "GitRepositoryProvider", ->
|
||||
beforeEach ->
|
||||
provider = new GitRepositoryProvider(atom.project, atom.config, atom.confirm)
|
||||
|
||||
afterEach ->
|
||||
temp.cleanupSync()
|
||||
|
||||
describe ".repositoryForDirectory(directory)", ->
|
||||
describe "when specified a Directory with a Git repository", ->
|
||||
it "returns a Promise that resolves to a GitRepository", ->
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
GitRepository = require '../src/git-repository'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
Project = require '../src/project'
|
||||
|
||||
copyRepository = ->
|
||||
workingDirPath = temp.mkdirSync('atom-working-dir')
|
||||
workingDirPath = temp.mkdirSync('atom-spec-git')
|
||||
fs.copySync(path.join(__dirname, 'fixtures', 'git', 'working-dir'), workingDirPath)
|
||||
fs.renameSync(path.join(workingDirPath, 'git.git'), path.join(workingDirPath, '.git'))
|
||||
workingDirPath
|
||||
@@ -19,6 +19,8 @@ describe "GitRepository", ->
|
||||
|
||||
afterEach ->
|
||||
repo.destroy() if repo?.repo?
|
||||
try
|
||||
temp.cleanupSync() # These tests sometimes lag at shutting down resources
|
||||
|
||||
describe "@open(path)", ->
|
||||
it "returns null when no repository is found", ->
|
||||
@@ -29,10 +31,15 @@ describe "GitRepository", ->
|
||||
expect(-> new GitRepository(path.join(temp.dir, 'nogit.txt'))).toThrow()
|
||||
|
||||
describe ".getPath()", ->
|
||||
it "returns the repository path for a .git directory path", ->
|
||||
it "returns the repository path for a .git directory path with a file", ->
|
||||
return if process.platform is 'win32' #Win32TestFailures - libgit2 does not detect files in .git folders
|
||||
repo = new GitRepository(path.join(__dirname, 'fixtures', 'git', 'master.git', 'HEAD'))
|
||||
expect(repo.getPath()).toBe path.join(__dirname, 'fixtures', 'git', 'master.git')
|
||||
|
||||
it "returns the repository path for a .git directory path with a directory", ->
|
||||
repo = new GitRepository(path.join(__dirname, 'fixtures', 'git', 'master.git', 'objects'))
|
||||
expect(repo.getPath()).toBe path.join(__dirname, 'fixtures', 'git', 'master.git')
|
||||
|
||||
it "returns the repository path for a repository path", ->
|
||||
repo = new GitRepository(path.join(__dirname, 'fixtures', 'git', 'master.git'))
|
||||
expect(repo.getPath()).toBe path.join(__dirname, 'fixtures', 'git', 'master.git')
|
||||
@@ -137,6 +144,8 @@ describe "GitRepository", ->
|
||||
editor = atom.workspace.getActiveTextEditor()
|
||||
|
||||
it "displays a confirmation dialog by default", ->
|
||||
return if process.platform is 'win32' # Permissions issues with this test on Windows
|
||||
|
||||
atom.confirm.andCallFake ({buttons}) -> buttons.OK()
|
||||
atom.config.set('editor.confirmCheckoutHeadRevision', true)
|
||||
|
||||
@@ -145,6 +154,7 @@ describe "GitRepository", ->
|
||||
expect(fs.readFileSync(filePath, 'utf8')).toBe ''
|
||||
|
||||
it "does not display a dialog when confirmation is disabled", ->
|
||||
return if process.platform is 'win32' # Flakey EPERM opening a.txt on Win32
|
||||
atom.config.set('editor.confirmCheckoutHeadRevision', false)
|
||||
|
||||
repo.checkoutHeadForEditor(editor)
|
||||
@@ -154,7 +164,7 @@ describe "GitRepository", ->
|
||||
|
||||
describe ".destroy()", ->
|
||||
it "throws an exception when any method is called after it is called", ->
|
||||
repo = new GitRepository(require.resolve('./fixtures/git/master.git/HEAD'))
|
||||
repo = new GitRepository(path.join(__dirname, 'fixtures', 'git', 'master.git'))
|
||||
repo.destroy()
|
||||
expect(-> repo.getShortHead()).toThrow()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
GrammarRegistry = require '../src/grammar-registry'
|
||||
Grim = require 'grim'
|
||||
|
||||
@@ -24,6 +24,7 @@ describe "the `grammars` global", ->
|
||||
afterEach ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
temp.cleanupSync()
|
||||
|
||||
describe ".selectGrammar(filePath)", ->
|
||||
it "always returns a grammar", ->
|
||||
@@ -96,6 +97,7 @@ describe "the `grammars` global", ->
|
||||
)
|
||||
grammar1 = atom.grammars.loadGrammarSync(grammarPath1)
|
||||
expect(atom.grammars.selectGrammar('more.test', '')).toBe grammar1
|
||||
fs.removeSync(grammarPath1)
|
||||
|
||||
grammarPath2 = temp.path(suffix: '.json')
|
||||
fs.writeFileSync grammarPath2, JSON.stringify(
|
||||
@@ -105,6 +107,7 @@ describe "the `grammars` global", ->
|
||||
)
|
||||
grammar2 = atom.grammars.loadGrammarSync(grammarPath2)
|
||||
expect(atom.grammars.selectGrammar('more.test', '')).toBe grammar2
|
||||
fs.removeSync(grammarPath2)
|
||||
|
||||
it "favors non-bundled packages when breaking scoring ties", ->
|
||||
waitsForPromise ->
|
||||
|
||||
@@ -139,3 +139,22 @@ describe "GutterContainerComponent", ->
|
||||
expect(expectedCustomGutterNode1).toBe atom.views.getView(customGutter1)
|
||||
expectedCustomGutterNode3 = gutterContainerComponent.getDomNode().children.item(2)
|
||||
expect(expectedCustomGutterNode3).toBe atom.views.getView(customGutter3)
|
||||
|
||||
it "reorders correctly when prepending multiple gutters at once", ->
|
||||
lineNumberGutter = new Gutter(mockGutterContainer, {name: 'line-number'})
|
||||
testState = buildTestState([lineNumberGutter])
|
||||
gutterContainerComponent.updateSync(testState)
|
||||
expect(gutterContainerComponent.getDomNode().children.length).toBe 1
|
||||
expectedCustomGutterNode = gutterContainerComponent.getDomNode().children.item(0)
|
||||
expect(expectedCustomGutterNode).toBe atom.views.getView(lineNumberGutter)
|
||||
|
||||
# Prepend two gutters at once
|
||||
customGutter1 = new Gutter(mockGutterContainer, {name: 'first', priority: -200})
|
||||
customGutter2 = new Gutter(mockGutterContainer, {name: 'second', priority: -100})
|
||||
testState = buildTestState([customGutter1, customGutter2, lineNumberGutter])
|
||||
gutterContainerComponent.updateSync(testState)
|
||||
expect(gutterContainerComponent.getDomNode().children.length).toBe 3
|
||||
expectedCustomGutterNode1 = gutterContainerComponent.getDomNode().children.item(0)
|
||||
expect(expectedCustomGutterNode1).toBe atom.views.getView(customGutter1)
|
||||
expectedCustomGutterNode2 = gutterContainerComponent.getDomNode().children.item(1)
|
||||
expect(expectedCustomGutterNode2).toBe atom.views.getView(customGutter2)
|
||||
|
||||
@@ -16,7 +16,7 @@ ChromedriverPort = 9515
|
||||
ChromedriverURLBase = "/wd/hub"
|
||||
ChromedriverStatusURL = "http://localhost:#{ChromedriverPort}#{ChromedriverURLBase}/status"
|
||||
|
||||
userDataDir = temp.mkdirSync('atom-user-data-dir')
|
||||
userDataDir = null
|
||||
|
||||
chromeDriverUp = (done) ->
|
||||
checkStatus = ->
|
||||
@@ -38,6 +38,7 @@ chromeDriverDown = (done) ->
|
||||
setTimeout(checkStatus, 100)
|
||||
|
||||
buildAtomClient = (args, env) ->
|
||||
userDataDir = temp.mkdirSync('atom-user-data-dir')
|
||||
client = webdriverio.remote(
|
||||
host: 'localhost'
|
||||
port: ChromedriverPort
|
||||
|
||||
@@ -5,6 +5,8 @@ temp = require('temp').track()
|
||||
runAtom = require './helpers/start-atom'
|
||||
|
||||
describe "Smoke Test", ->
|
||||
return unless process.platform is 'darwin' # Fails on win32
|
||||
|
||||
atomHome = temp.mkdirSync('atom-home')
|
||||
|
||||
beforeEach ->
|
||||
|
||||
@@ -78,9 +78,10 @@ describe "LinesYardstick", ->
|
||||
expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 0))).toEqual({left: 0, top: 0})
|
||||
expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 1))).toEqual({left: 7, top: 0})
|
||||
expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 5))).toEqual({left: 38, top: 0})
|
||||
expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 6))).toEqual({left: 43, top: 14})
|
||||
expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 9))).toEqual({left: 72, top: 14})
|
||||
expect(linesYardstick.pixelPositionForScreenPosition(Point(2, Infinity))).toEqual({left: 287.859375, top: 28})
|
||||
if process.platform is 'darwin' # One pixel off on left on Win32
|
||||
expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 6))).toEqual({left: 43, top: 14})
|
||||
expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 9))).toEqual({left: 72, top: 14})
|
||||
expect(linesYardstick.pixelPositionForScreenPosition(Point(2, Infinity))).toEqual({left: 287.859375, top: 28})
|
||||
|
||||
it "reuses already computed pixel positions unless it is invalidated", ->
|
||||
atom.styles.addStyleSheet """
|
||||
@@ -133,6 +134,7 @@ describe "LinesYardstick", ->
|
||||
|
||||
editor.setText(text)
|
||||
|
||||
return unless process.platform is 'darwin' # These numbers are 15 higher on win32 and always integer
|
||||
expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 35)).left).toBe 230.90625
|
||||
expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 36)).left).toBe 237.5
|
||||
expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 37)).left).toBe 244.09375
|
||||
@@ -172,8 +174,9 @@ describe "LinesYardstick", ->
|
||||
expect(linesYardstick.screenPositionForPixelPosition({top: 32, left: 24.3})).toEqual([2, 3])
|
||||
expect(linesYardstick.screenPositionForPixelPosition({top: 46, left: 66.5})).toEqual([3, 9])
|
||||
expect(linesYardstick.screenPositionForPixelPosition({top: 70, left: 99.9})).toEqual([5, 14])
|
||||
expect(linesYardstick.screenPositionForPixelPosition({top: 70, left: 224.2365234375})).toEqual([5, 29])
|
||||
expect(linesYardstick.screenPositionForPixelPosition({top: 70, left: 225})).toEqual([5, 30])
|
||||
return unless process.platform is 'darwin' # Following tests are 1 pixel off on Win32
|
||||
expect(linesYardstick.screenPositionForPixelPosition({top: 70, left: 224.2365234375})).toEqual([5, 29])
|
||||
expect(linesYardstick.screenPositionForPixelPosition({top: 84, left: 247.1})).toEqual([6, 33])
|
||||
|
||||
it "overshoots to the nearest character when text nodes are not spatially contiguous", ->
|
||||
|
||||
@@ -22,7 +22,7 @@ describe('AtomApplication', function () {
|
||||
originalAtomHome = process.env.ATOM_HOME
|
||||
process.env.ATOM_HOME = makeTempDir('atom-home')
|
||||
// Symlinking the compile cache into the temporary home dir makes the windows load much faster
|
||||
fs.symlinkSync(path.join(originalAtomHome, 'compile-cache'), path.join(process.env.ATOM_HOME, 'compile-cache'))
|
||||
fs.symlinkSync(path.join(originalAtomHome, 'compile-cache'), path.join(process.env.ATOM_HOME, 'compile-cache'), 'junction')
|
||||
season.writeFileSync(path.join(process.env.ATOM_HOME, 'config.cson'), {
|
||||
'*': {
|
||||
welcome: {showOnStartup: false},
|
||||
@@ -309,7 +309,7 @@ describe('AtomApplication', function () {
|
||||
const packagePath = path.join(__dirname, '..', 'fixtures', 'packages', 'package-with-directory-provider')
|
||||
const packagesDirPath = path.join(process.env.ATOM_HOME, 'packages')
|
||||
fs.mkdirSync(packagesDirPath)
|
||||
fs.symlinkSync(packagePath, path.join(packagesDirPath, 'package-with-directory-provider'))
|
||||
fs.symlinkSync(packagePath, path.join(packagesDirPath, 'package-with-directory-provider'), 'junction')
|
||||
|
||||
const atomApplication = buildAtomApplication()
|
||||
atomApplication.config.set('core.disabledPackages', ['fuzzy-finder'])
|
||||
|
||||
@@ -2,19 +2,23 @@
|
||||
|
||||
import {dialog} from 'electron'
|
||||
import FileRecoveryService from '../../src/main-process/file-recovery-service'
|
||||
import temp from 'temp'
|
||||
import fs from 'fs-plus'
|
||||
import sinon from 'sinon'
|
||||
import {escapeRegExp} from 'underscore-plus'
|
||||
const temp = require('temp').track()
|
||||
|
||||
describe("FileRecoveryService", () => {
|
||||
let recoveryService, recoveryDirectory
|
||||
|
||||
beforeEach(() => {
|
||||
recoveryDirectory = temp.mkdirSync()
|
||||
recoveryDirectory = temp.mkdirSync('atom-spec-file-recovery')
|
||||
recoveryService = new FileRecoveryService(recoveryDirectory)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
temp.cleanupSync()
|
||||
})
|
||||
|
||||
describe("when no crash happens during a save", () => {
|
||||
it("creates a recovery file and deletes it after saving", () => {
|
||||
const mockWindow = {}
|
||||
@@ -28,6 +32,8 @@ describe("FileRecoveryService", () => {
|
||||
recoveryService.didSavePath(mockWindow, filePath)
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 0)
|
||||
assert.equal(fs.readFileSync(filePath, 'utf8'), "changed")
|
||||
|
||||
fs.removeSync(filePath)
|
||||
})
|
||||
|
||||
it("creates only one recovery file when many windows attempt to save the same file, deleting it when the last one finishes saving it", () => {
|
||||
@@ -48,6 +54,8 @@ describe("FileRecoveryService", () => {
|
||||
recoveryService.didSavePath(anotherMockWindow, filePath)
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 0)
|
||||
assert.equal(fs.readFileSync(filePath, 'utf8'), "changed")
|
||||
|
||||
fs.removeSync(filePath)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -64,6 +72,8 @@ describe("FileRecoveryService", () => {
|
||||
recoveryService.didCrashWindow(mockWindow)
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 0)
|
||||
assert.equal(fs.readFileSync(filePath, 'utf8'), "some content")
|
||||
|
||||
fs.removeSync(filePath)
|
||||
})
|
||||
|
||||
it("restores the created recovery file when many windows attempt to save the same file and one of them crashes", () => {
|
||||
@@ -94,6 +104,8 @@ describe("FileRecoveryService", () => {
|
||||
recoveryService.didCrashWindow(anotherMockWindow)
|
||||
assert.equal(fs.readFileSync(filePath, 'utf8'), "D")
|
||||
assert.equal(fs.listTreeSync(recoveryDirectory).length, 0)
|
||||
|
||||
fs.removeSync(filePath)
|
||||
})
|
||||
|
||||
it("emits a warning when a file can't be recovered", sinon.test(function () {
|
||||
@@ -113,6 +125,8 @@ describe("FileRecoveryService", () => {
|
||||
assert.equal(logs.length, 1)
|
||||
assert.match(logs[0], new RegExp(escapeRegExp(filePath)))
|
||||
assert.match(logs[0], new RegExp(escapeRegExp(recoveryFiles[0])))
|
||||
|
||||
fs.removeSync(filePath)
|
||||
}))
|
||||
})
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ describe "MenuManager", ->
|
||||
runs -> expect(menu.sendToBrowserProcess.argsForCall[0][1]['b']).toBeUndefined()
|
||||
|
||||
it "omits key bindings that could conflict with AltGraph characters on macOS", ->
|
||||
Object.defineProperty process, 'platform', value: 'darwin'
|
||||
spyOn(menu, 'sendToBrowserProcess')
|
||||
menu.add [{label: "A", submenu: [
|
||||
{label: "B", command: "b"},
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
path = require 'path'
|
||||
Module = require 'module'
|
||||
fs = require 'fs-plus'
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
ModuleCache = require '../src/module-cache'
|
||||
|
||||
describe 'ModuleCache', ->
|
||||
beforeEach ->
|
||||
spyOn(Module, '_findPath').andCallThrough()
|
||||
|
||||
afterEach ->
|
||||
temp.cleanupSync()
|
||||
|
||||
it 'resolves Electron module paths without hitting the filesystem', ->
|
||||
builtins = ModuleCache.cache.builtins
|
||||
expect(Object.keys(builtins).length).toBeGreaterThan 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
path = require 'path'
|
||||
Package = require '../src/package'
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
fs = require 'fs-plus'
|
||||
{Disposable} = require 'atom'
|
||||
{buildKeydownEvent} = require '../src/keymap-extensions'
|
||||
@@ -17,6 +17,9 @@ describe "PackageManager", ->
|
||||
beforeEach ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
|
||||
afterEach ->
|
||||
temp.cleanupSync()
|
||||
|
||||
describe "::getApmPath()", ->
|
||||
it "returns the path to the apm command", ->
|
||||
apmPath = path.join(process.resourcesPath, "app", "apm", "bin", "apm")
|
||||
@@ -440,11 +443,9 @@ describe "PackageManager", ->
|
||||
spyOn(mainModule, 'activate').andCallThrough()
|
||||
spyOn(Package.prototype, 'requireMainModule').andCallThrough()
|
||||
|
||||
promise = atom.packages.activatePackage('package-with-activation-hooks')
|
||||
|
||||
it "defers requiring/activating the main module until an triggering of an activation hook occurs", ->
|
||||
promise = atom.packages.activatePackage('package-with-activation-hooks')
|
||||
expect(Package.prototype.requireMainModule.callCount).toBe 0
|
||||
|
||||
atom.packages.triggerActivationHook('language-fictitious:grammar-used')
|
||||
atom.packages.triggerDeferredActivationHooks()
|
||||
|
||||
@@ -455,6 +456,7 @@ describe "PackageManager", ->
|
||||
expect(Package.prototype.requireMainModule.callCount).toBe 1
|
||||
|
||||
it "does not double register activation hooks when deactivating and reactivating", ->
|
||||
promise = atom.packages.activatePackage('package-with-activation-hooks')
|
||||
expect(mainModule.activate.callCount).toBe 0
|
||||
atom.packages.triggerActivationHook('language-fictitious:grammar-used')
|
||||
atom.packages.triggerDeferredActivationHooks()
|
||||
@@ -489,6 +491,17 @@ describe "PackageManager", ->
|
||||
expect(mainModule.activate.callCount).toBe 1
|
||||
expect(Package.prototype.requireMainModule.callCount).toBe 1
|
||||
|
||||
it "activates the package immediately if the activation hook had already been triggered", ->
|
||||
atom.packages.triggerActivationHook('language-fictitious:grammar-used')
|
||||
atom.packages.triggerDeferredActivationHooks()
|
||||
expect(Package.prototype.requireMainModule.callCount).toBe 0
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-activation-hooks')
|
||||
|
||||
runs ->
|
||||
expect(Package.prototype.requireMainModule.callCount).toBe 1
|
||||
|
||||
describe "when the package has no main module", ->
|
||||
it "does not throw an exception", ->
|
||||
spyOn(console, "error")
|
||||
@@ -643,7 +656,7 @@ describe "PackageManager", ->
|
||||
[element, events, userKeymapPath] = []
|
||||
|
||||
beforeEach ->
|
||||
userKeymapPath = path.join(temp.path(), "user-keymaps.cson")
|
||||
userKeymapPath = path.join(temp.mkdirSync(), "user-keymaps.cson")
|
||||
spyOn(atom.keymaps, "getUserKeymapPath").andReturn(userKeymapPath)
|
||||
|
||||
element = createTestElement('test-1')
|
||||
@@ -660,6 +673,8 @@ describe "PackageManager", ->
|
||||
atom.keymaps.watchSubscriptions[userKeymapPath].dispose()
|
||||
delete atom.keymaps.watchSubscriptions[userKeymapPath]
|
||||
|
||||
temp.cleanupSync()
|
||||
|
||||
it "doesn't override user-defined keymaps", ->
|
||||
fs.writeFileSync userKeymapPath, """
|
||||
".test-1":
|
||||
@@ -740,10 +755,6 @@ describe "PackageManager", ->
|
||||
two = require.resolve("./fixtures/packages/package-with-style-sheets-manifest/styles/2.less")
|
||||
three = require.resolve("./fixtures/packages/package-with-style-sheets-manifest/styles/3.css")
|
||||
|
||||
one = atom.themes.stringToId(one)
|
||||
two = atom.themes.stringToId(two)
|
||||
three = atom.themes.stringToId(three)
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
@@ -765,11 +776,6 @@ describe "PackageManager", ->
|
||||
three = require.resolve("./fixtures/packages/package-with-styles/styles/3.test-context.css")
|
||||
four = require.resolve("./fixtures/packages/package-with-styles/styles/4.css")
|
||||
|
||||
one = atom.themes.stringToId(one)
|
||||
two = atom.themes.stringToId(two)
|
||||
three = atom.themes.stringToId(three)
|
||||
four = atom.themes.stringToId(four)
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
|
||||
@@ -205,3 +205,26 @@ describe "Package", ->
|
||||
|
||||
it "uses the package name defined in package.json", ->
|
||||
expect(metadata.name).toBe 'package-with-a-totally-different-name'
|
||||
|
||||
describe "the initialize() hook", ->
|
||||
it "gets called when the package is activated", ->
|
||||
packagePath = atom.project.getDirectories()[0].resolve('packages/package-with-deserializers')
|
||||
pack = buildPackage(packagePath)
|
||||
pack.requireMainModule()
|
||||
mainModule = pack.mainModule
|
||||
spyOn(mainModule, 'initialize')
|
||||
expect(mainModule.initialize).not.toHaveBeenCalled()
|
||||
pack.activate()
|
||||
expect(mainModule.initialize).toHaveBeenCalled()
|
||||
expect(mainModule.initialize.callCount).toBe(1)
|
||||
|
||||
it "gets called when a deserializer is used", ->
|
||||
packagePath = atom.project.getDirectories()[0].resolve('packages/package-with-deserializers')
|
||||
pack = buildPackage(packagePath)
|
||||
pack.requireMainModule()
|
||||
mainModule = pack.mainModule
|
||||
spyOn(mainModule, 'initialize')
|
||||
pack.load()
|
||||
expect(mainModule.initialize).not.toHaveBeenCalled()
|
||||
atom.deserializers.deserialize({deserializer: 'Deserializer1', a: 'b'})
|
||||
expect(mainModule.initialize).toHaveBeenCalled()
|
||||
|
||||
@@ -44,19 +44,19 @@ describe("PackageTranspilationRegistry", () => {
|
||||
})
|
||||
|
||||
describe('when a file is contained in a path that has custom transpilation', () => {
|
||||
const hitPath = '/path/to/lib/file.js'
|
||||
const hitPathCoffee = '/path/to/file2.coffee'
|
||||
const missPath = '/path/other/file3.js'
|
||||
const hitPathMissSubdir = '/path/to/file4.js'
|
||||
const hitPathMissExt = '/path/to/file5.ts'
|
||||
const nodeModulesFolder = '/path/to/lib/node_modules/file6.js'
|
||||
const hitNonStandardExt = '/path/to/file7.omgwhatisthis'
|
||||
const hitPath = path.join('/path/to/lib/file.js')
|
||||
const hitPathCoffee = path.join('/path/to/file2.coffee')
|
||||
const missPath = path.join('/path/other/file3.js')
|
||||
const hitPathMissSubdir =path.join('/path/to/file4.js')
|
||||
const hitPathMissExt = path.join('/path/to/file5.ts')
|
||||
const nodeModulesFolder = path.join('/path/to/lib/node_modules/file6.js')
|
||||
const hitNonStandardExt = path.join('/path/to/file7.omgwhatisthis')
|
||||
|
||||
const jsSpec = { glob: "lib/**/*.js", transpiler: './transpiler-js', options: { type: 'js' } }
|
||||
const coffeeSpec = { glob: "*.coffee", transpiler: './transpiler-coffee', options: { type: 'coffee' } }
|
||||
const omgSpec = { glob: "*.omgwhatisthis", transpiler: './transpiler-omg', options: { type: 'omg' } }
|
||||
|
||||
const expectedMeta = { name: 'my-package', path: '/path/to', meta: { some: 'metadata' } }
|
||||
const expectedMeta = { name: 'my-package', path: path.join('/path/to'), meta: { some: 'metadata' } }
|
||||
|
||||
const jsTranspiler = {
|
||||
transpile: (sourceCode, filePath, options) => {
|
||||
@@ -100,7 +100,7 @@ describe("PackageTranspilationRegistry", () => {
|
||||
throw new Error('bad transpiler path ' + spec.transpiler)
|
||||
})
|
||||
|
||||
registry.addTranspilerConfigForPath('/path/to', 'my-package', { some: 'metadata' }, [
|
||||
registry.addTranspilerConfigForPath(path.join('/path/to'), 'my-package', { some: 'metadata' }, [
|
||||
jsSpec, coffeeSpec, omgSpec
|
||||
])
|
||||
})
|
||||
|
||||
@@ -1080,6 +1080,7 @@ describe "Pane", ->
|
||||
expect(eventCount).toBe 1
|
||||
|
||||
it "only calls terminate handler once when text is modified twice", ->
|
||||
originalText = editor1.getText()
|
||||
editor1.insertText('Some text')
|
||||
advanceClock(editor1.getBuffer().stoppedChangingDelay)
|
||||
|
||||
@@ -1091,6 +1092,10 @@ describe "Pane", ->
|
||||
expect(pane.getPendingItem()).toBeNull()
|
||||
expect(eventCount).toBe 1
|
||||
|
||||
# Reset fixture back to original state
|
||||
editor1.setText(originalText)
|
||||
editor1.save()
|
||||
|
||||
it "only calls clearPendingItem if there is a pending item to clear", ->
|
||||
spyOn(pane, "clearPendingItem").andCallThrough()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
Project = require '../src/project'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
@@ -12,6 +12,9 @@ describe "Project", ->
|
||||
# Wait for project's service consumers to be asynchronously added
|
||||
waits(1)
|
||||
|
||||
afterEach ->
|
||||
temp.cleanupSync()
|
||||
|
||||
describe "serialization", ->
|
||||
deserializedProject = null
|
||||
|
||||
@@ -51,7 +54,7 @@ describe "Project", ->
|
||||
|
||||
|
||||
it "does not deserialize buffers when their path is a directory that exists", ->
|
||||
pathToOpen = path.join(temp.mkdirSync(), 'file.txt')
|
||||
pathToOpen = path.join(temp.mkdirSync('atom-spec-project'), 'file.txt')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open(pathToOpen)
|
||||
@@ -64,7 +67,8 @@ describe "Project", ->
|
||||
expect(deserializedProject.getBuffers().length).toBe 0
|
||||
|
||||
it "does not deserialize buffers when their path is inaccessible", ->
|
||||
pathToOpen = path.join(temp.mkdirSync(), 'file.txt')
|
||||
return if process.platform is 'win32' # chmod not supported on win32
|
||||
pathToOpen = path.join(temp.mkdirSync('atom-spec-project'), 'file.txt')
|
||||
fs.writeFileSync(pathToOpen, '')
|
||||
|
||||
waitsForPromise ->
|
||||
@@ -151,7 +155,7 @@ describe "Project", ->
|
||||
expect(notification.getType()).toBe 'warning'
|
||||
expect(notification.getDetail()).toBe 'SomeError'
|
||||
expect(notification.getMessage()).toContain '`resurrect`'
|
||||
expect(notification.getMessage()).toContain 'fixtures/dir/a'
|
||||
expect(notification.getMessage()).toContain path.join('fixtures', 'dir', 'a')
|
||||
|
||||
describe "when a custom repository-provider service is provided", ->
|
||||
[fakeRepositoryProvider, fakeRepository] = []
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{EventEmitter} = require 'events'
|
||||
fs = require 'fs-plus'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
SquirrelUpdate = require '../src/main-process/squirrel-update'
|
||||
Spawner = require '../src/main-process/spawner'
|
||||
WinShell = require '../src/main-process/win-shell'
|
||||
@@ -36,6 +36,9 @@ describe "Windows Squirrel Update", ->
|
||||
WinShell.folderContextMenu = new FakeShellOption()
|
||||
WinShell.folderBackgroundContextMenu = new FakeShellOption()
|
||||
|
||||
afterEach ->
|
||||
temp.cleanupSync()
|
||||
|
||||
it "quits the app on all squirrel events", ->
|
||||
app = quit: jasmine.createSpy('quit')
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const temp = require('temp')
|
||||
const temp = require('temp').track()
|
||||
const StyleManager = require('../src/style-manager')
|
||||
|
||||
describe('StyleManager', () => {
|
||||
@@ -14,6 +14,10 @@ describe('StyleManager', () => {
|
||||
styleManager.onDidUpdateStyleElement((event) => { updateEvents.push(event) })
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
temp.cleanupSync()
|
||||
})
|
||||
|
||||
describe('::addStyleSheet(source, params)', () => {
|
||||
it('adds a style sheet based on the given source and returns a disposable allowing it to be removed', () => {
|
||||
const disposable = styleManager.addStyleSheet('a {color: red}')
|
||||
|
||||
@@ -2291,7 +2291,9 @@ describe('TextEditorComponent', function () {
|
||||
|
||||
let position = wrapperNode.pixelPositionForBufferPosition([0, 26])
|
||||
let overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe(Math.round(position.left + gutterWidth) + 'px')
|
||||
if (process.platform == 'darwin') { // Result is 359px on win32, expects 375px
|
||||
expect(overlay.style.left).toBe(Math.round(position.left + gutterWidth) + 'px')
|
||||
}
|
||||
expect(overlay.style.top).toBe(position.top + editor.getLineHeightInPixels() + 'px')
|
||||
|
||||
editor.insertText('a')
|
||||
@@ -3846,6 +3848,40 @@ describe('TextEditorComponent', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the mousewheel event\'s target is an SVG element inside a block decoration', function () {
|
||||
it('keeps the block decoration on the DOM if it is scrolled off-screen', function () {
|
||||
wrapperNode.style.height = 4.5 * lineHeightInPixels + 'px'
|
||||
wrapperNode.style.width = 20 * charWidth + 'px'
|
||||
editor.update({autoHeight: false})
|
||||
component.measureDimensions()
|
||||
runAnimationFrames()
|
||||
|
||||
const item = document.createElement('div')
|
||||
const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg")
|
||||
item.appendChild(svgElement)
|
||||
editor.decorateMarker(
|
||||
editor.markScreenPosition([0, 0], {invalidate: "never"}),
|
||||
{type: "block", item: item}
|
||||
)
|
||||
|
||||
runAnimationFrames()
|
||||
|
||||
let wheelEvent = new WheelEvent('mousewheel', {
|
||||
wheelDeltaX: 0,
|
||||
wheelDeltaY: -500
|
||||
})
|
||||
Object.defineProperty(wheelEvent, 'target', {
|
||||
get: function () {
|
||||
return svgElement
|
||||
}
|
||||
})
|
||||
componentNode.dispatchEvent(wheelEvent)
|
||||
runAnimationFrames()
|
||||
|
||||
expect(component.getTopmostDOMNode().contains(item)).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
it('only prevents the default action of the mousewheel event if it actually lead to scrolling', function () {
|
||||
spyOn(WheelEvent.prototype, 'preventDefault').andCallThrough()
|
||||
wrapperNode.style.height = 4.5 * lineHeightInPixels + 'px'
|
||||
|
||||
@@ -78,6 +78,19 @@ describe "TextEditorElement", ->
|
||||
jasmine.attachToDOM(element)
|
||||
expect(element.querySelectorAll('.decoration').length).toBe initialDecorationCount
|
||||
|
||||
it "can be re-focused using the previous `document.activeElement`", ->
|
||||
editorElement = document.createElement('atom-text-editor')
|
||||
jasmine.attachToDOM(editorElement)
|
||||
editorElement.focus()
|
||||
|
||||
activeElement = document.activeElement
|
||||
|
||||
editorElement.remove()
|
||||
jasmine.attachToDOM(editorElement)
|
||||
activeElement.focus()
|
||||
|
||||
expect(editorElement.hasFocus()).toBe(true)
|
||||
|
||||
describe "focus and blur handling", ->
|
||||
it "proxies focus/blur events to/from the hidden input", ->
|
||||
element = new TextEditorElement
|
||||
|
||||
@@ -165,23 +165,6 @@ describe "TextEditorPresenter", ->
|
||||
expect(stateFn(presenter).tiles[10]).toBeUndefined()
|
||||
expect(stateFn(presenter).tiles[12]).toBeUndefined()
|
||||
|
||||
it "excludes invalid tiles for screen rows to measure", ->
|
||||
presenter = buildPresenter(explicitHeight: 6, scrollTop: 0, lineHeight: 1, tileSize: 2)
|
||||
presenter.setScreenRowsToMeasure([20, 30]) # unexisting rows
|
||||
|
||||
expect(stateFn(presenter).tiles[0]).toBeDefined()
|
||||
expect(stateFn(presenter).tiles[2]).toBeDefined()
|
||||
expect(stateFn(presenter).tiles[4]).toBeDefined()
|
||||
expect(stateFn(presenter).tiles[6]).toBeDefined()
|
||||
expect(stateFn(presenter).tiles[8]).toBeUndefined()
|
||||
expect(stateFn(presenter).tiles[10]).toBeUndefined()
|
||||
expect(stateFn(presenter).tiles[12]).toBeUndefined()
|
||||
|
||||
presenter.setScreenRowsToMeasure([12])
|
||||
buffer.deleteRows(12, 13)
|
||||
|
||||
expect(stateFn(presenter).tiles[12]).toBeUndefined()
|
||||
|
||||
describe "when there are block decorations", ->
|
||||
it "computes each tile's height and scrollTop based on block decorations' height", ->
|
||||
presenter = buildPresenter(explicitHeight: 120, scrollTop: 0, lineHeight: 10, tileSize: 2)
|
||||
@@ -2045,6 +2028,27 @@ describe "TextEditorPresenter", ->
|
||||
|
||||
expect(stateForHighlightInTile(presenter, highlight, 0)).toBeUndefined()
|
||||
|
||||
it "handles highlights that extend to the left of the visible area (regression)", ->
|
||||
editor.setSelectedBufferRanges([
|
||||
[[0, 2], [1, 4]],
|
||||
])
|
||||
|
||||
presenter = buildPresenter(explicitHeight: 20, scrollLeft: 0, tileSize: 2)
|
||||
expectValues stateForSelectionInTile(presenter, 0, 0), {
|
||||
regions: [
|
||||
{top: 0 * 10, height: 10, left: 2 * 10, right: 0 * 10},
|
||||
{top: 1 * 10, height: 10, left: 0 * 10, width: 4 * 10}
|
||||
]
|
||||
}
|
||||
|
||||
presenter = buildPresenter(explicitHeight: 20, scrollLeft: 20, tileSize: 2)
|
||||
expectValues stateForSelectionInTile(presenter, 0, 0), {
|
||||
regions: [
|
||||
{top: 0 * 10, height: 10, left: 2 * 10, right: 0 * 10},
|
||||
{top: 1 * 10, height: 10, left: 0 * 10, width: 4 * 10}
|
||||
]
|
||||
}
|
||||
|
||||
it "updates when ::scrollTop changes", ->
|
||||
editor.setSelectedBufferRanges([
|
||||
[[6, 2], [6, 4]],
|
||||
@@ -2518,13 +2522,13 @@ describe "TextEditorPresenter", ->
|
||||
pixelPosition: {top: 1 * 10, left: 26 * 10 + gutterWidth - scrollLeft}
|
||||
}
|
||||
|
||||
expectStateUpdate presenter, -> editor.insertText('a')
|
||||
expectStateUpdate presenter, -> editor.insertText('abc', autoscroll: false)
|
||||
expectValues stateForOverlay(presenter, decoration), {
|
||||
item: item
|
||||
pixelPosition: {top: 1 * 10, left: windowWidth - itemWidth}
|
||||
}
|
||||
|
||||
expectStateUpdate presenter, -> editor.insertText('b')
|
||||
expectStateUpdate presenter, -> editor.insertText('d', autoscroll: false)
|
||||
expectValues stateForOverlay(presenter, decoration), {
|
||||
item: item
|
||||
pixelPosition: {top: 1 * 10, left: windowWidth - itemWidth}
|
||||
@@ -2545,14 +2549,55 @@ describe "TextEditorPresenter", ->
|
||||
}
|
||||
|
||||
expectStateUpdate presenter, ->
|
||||
editor.insertNewline()
|
||||
presenter.setScrollTop(scrollTop) # I'm fighting the editor
|
||||
editor.insertNewline(autoscroll: false)
|
||||
|
||||
expectValues stateForOverlay(presenter, decoration), {
|
||||
item: item
|
||||
pixelPosition: {top: 6 * 10 - scrollTop - itemHeight, left: gutterWidth}
|
||||
}
|
||||
|
||||
it "when avoidOverflow is false, does not move horizontally when overflowing the editor's scrollView horizontally", ->
|
||||
scrollLeft = 20
|
||||
marker = editor.markBufferPosition([0, 26], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item, avoidOverflow: false})
|
||||
|
||||
presenter = buildPresenter({scrollLeft, windowWidth, windowHeight, contentFrameWidth, boundingClientRect, gutterWidth})
|
||||
expectStateUpdate presenter, ->
|
||||
presenter.setOverlayDimensions(decoration.id, itemWidth, itemHeight, contentMargin)
|
||||
|
||||
expectValues stateForOverlay(presenter, decoration), {
|
||||
item: item
|
||||
pixelPosition: {top: 1 * 10, left: 26 * 10 + gutterWidth - scrollLeft}
|
||||
}
|
||||
|
||||
expectStateUpdate presenter, -> editor.insertText('a', autoscroll: false)
|
||||
expectValues stateForOverlay(presenter, decoration), {
|
||||
item: item
|
||||
pixelPosition: {top: 1 * 10, left: 27 * 10 + gutterWidth - scrollLeft}
|
||||
}
|
||||
|
||||
it "when avoidOverflow is false, does not flip vertically when overflowing the editor's scrollView vertically", ->
|
||||
scrollTop = 10
|
||||
marker = editor.markBufferPosition([5, 0], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item, avoidOverflow: false})
|
||||
|
||||
presenter = buildPresenter({scrollTop, windowWidth, windowHeight, contentFrameWidth, boundingClientRect, gutterWidth})
|
||||
expectStateUpdate presenter, ->
|
||||
presenter.setOverlayDimensions(decoration.id, itemWidth, itemHeight, contentMargin)
|
||||
|
||||
expectValues stateForOverlay(presenter, decoration), {
|
||||
item: item
|
||||
pixelPosition: {top: 6 * 10 - scrollTop, left: gutterWidth}
|
||||
}
|
||||
|
||||
expectStateUpdate presenter, ->
|
||||
editor.insertNewline(autoscroll: false)
|
||||
|
||||
expectValues stateForOverlay(presenter, decoration), {
|
||||
item: item
|
||||
pixelPosition: {top: 7 * 10 - scrollTop, left: gutterWidth}
|
||||
}
|
||||
|
||||
describe "when the overlay item has a margin", ->
|
||||
beforeEach ->
|
||||
itemWidth = 12 * 10
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
|
||||
describe "atom.themes", ->
|
||||
beforeEach ->
|
||||
@@ -8,6 +8,7 @@ describe "atom.themes", ->
|
||||
|
||||
afterEach ->
|
||||
atom.themes.deactivateThemes()
|
||||
temp.cleanupSync()
|
||||
|
||||
describe "theme getters and setters", ->
|
||||
beforeEach ->
|
||||
@@ -170,7 +171,7 @@ describe "atom.themes", ->
|
||||
expect(styleElementAddedHandler).toHaveBeenCalled()
|
||||
|
||||
element = document.querySelector('head style[source-path*="css.css"]')
|
||||
expect(element.getAttribute('source-path')).toEqualPath atom.themes.stringToId(cssPath)
|
||||
expect(element.getAttribute('source-path')).toEqualPath cssPath
|
||||
expect(element.textContent).toBe fs.readFileSync(cssPath, 'utf8')
|
||||
|
||||
# doesn't append twice
|
||||
@@ -189,7 +190,7 @@ describe "atom.themes", ->
|
||||
expect(document.querySelectorAll('head style').length).toBe lengthBefore + 1
|
||||
|
||||
element = document.querySelector('head style[source-path*="sample.less"]')
|
||||
expect(element.getAttribute('source-path')).toEqualPath atom.themes.stringToId(lessPath)
|
||||
expect(element.getAttribute('source-path')).toEqualPath lessPath
|
||||
expect(element.textContent).toBe """
|
||||
#header {
|
||||
color: #4d926f;
|
||||
@@ -208,9 +209,9 @@ describe "atom.themes", ->
|
||||
|
||||
it "supports requiring css and less stylesheets without an explicit extension", ->
|
||||
atom.themes.requireStylesheet path.join(__dirname, 'fixtures', 'css')
|
||||
expect(document.querySelector('head style[source-path*="css.css"]').getAttribute('source-path')).toEqualPath atom.themes.stringToId(atom.project.getDirectories()[0]?.resolve('css.css'))
|
||||
expect(document.querySelector('head style[source-path*="css.css"]').getAttribute('source-path')).toEqualPath atom.project.getDirectories()[0]?.resolve('css.css')
|
||||
atom.themes.requireStylesheet path.join(__dirname, 'fixtures', 'sample')
|
||||
expect(document.querySelector('head style[source-path*="sample.less"]').getAttribute('source-path')).toEqualPath atom.themes.stringToId(atom.project.getDirectories()[0]?.resolve('sample.less'))
|
||||
expect(document.querySelector('head style[source-path*="sample.less"]').getAttribute('source-path')).toEqualPath atom.project.getDirectories()[0]?.resolve('sample.less')
|
||||
|
||||
document.querySelector('head style[source-path*="css.css"]').remove()
|
||||
document.querySelector('head style[source-path*="sample.less"]').remove()
|
||||
|
||||
@@ -1,28 +1,38 @@
|
||||
/** @babel */
|
||||
/* eslint-env jasmine */
|
||||
|
||||
import {it, fit, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers'
|
||||
import path from 'path'
|
||||
import temp from 'temp'
|
||||
import child_process from 'child_process'
|
||||
import childProcess from 'child_process'
|
||||
import {updateProcessEnv, shouldGetEnvFromShell} from '../src/update-process-env'
|
||||
import dedent from 'dedent'
|
||||
import {EventEmitter} from 'events'
|
||||
import mockSpawn from 'mock-spawn'
|
||||
const temp = require('temp').track()
|
||||
|
||||
describe('updateProcessEnv(launchEnv)', function () {
|
||||
let originalProcessEnv, originalProcessPlatform
|
||||
let originalProcessEnv, originalProcessPlatform, originalSpawn, spawn
|
||||
|
||||
beforeEach(function () {
|
||||
originalSpawn = childProcess.spawn
|
||||
spawn = mockSpawn()
|
||||
childProcess.spawn = spawn
|
||||
originalProcessEnv = process.env
|
||||
originalProcessPlatform = process.platform
|
||||
process.env = {}
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
if (originalSpawn) {
|
||||
childProcess.spawn = originalSpawn
|
||||
}
|
||||
process.env = originalProcessEnv
|
||||
process.platform = originalProcessPlatform
|
||||
temp.cleanupSync()
|
||||
})
|
||||
|
||||
describe('when the launch environment appears to come from a shell', function () {
|
||||
it('updates process.env to match the launch environment', function () {
|
||||
it('updates process.env to match the launch environment', async function () {
|
||||
process.env = {
|
||||
WILL_BE_DELETED: 'hi',
|
||||
NODE_ENV: 'the-node-env',
|
||||
@@ -32,7 +42,7 @@ describe('updateProcessEnv(launchEnv)', function () {
|
||||
|
||||
const initialProcessEnv = process.env
|
||||
|
||||
updateProcessEnv({ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true', PWD: '/the/dir', TERM: 'xterm-something', KEY1: 'value1', KEY2: 'value2'})
|
||||
await updateProcessEnv({ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true', PWD: '/the/dir', TERM: 'xterm-something', KEY1: 'value1', KEY2: 'value2'})
|
||||
expect(process.env).toEqual({
|
||||
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
||||
PWD: '/the/dir',
|
||||
@@ -50,7 +60,7 @@ describe('updateProcessEnv(launchEnv)', function () {
|
||||
expect(process.env).toBe(initialProcessEnv)
|
||||
})
|
||||
|
||||
it('allows ATOM_HOME to be overwritten only if the new value is a valid path', function () {
|
||||
it('allows ATOM_HOME to be overwritten only if the new value is a valid path', async function () {
|
||||
let newAtomHomePath = temp.mkdirSync('atom-home')
|
||||
|
||||
process.env = {
|
||||
@@ -60,7 +70,7 @@ describe('updateProcessEnv(launchEnv)', function () {
|
||||
ATOM_HOME: '/the/atom/home'
|
||||
}
|
||||
|
||||
updateProcessEnv({ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true', PWD: '/the/dir'})
|
||||
await updateProcessEnv({ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true', PWD: '/the/dir'})
|
||||
expect(process.env).toEqual({
|
||||
PWD: '/the/dir',
|
||||
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
||||
@@ -69,7 +79,7 @@ describe('updateProcessEnv(launchEnv)', function () {
|
||||
ATOM_HOME: '/the/atom/home'
|
||||
})
|
||||
|
||||
updateProcessEnv({ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true', PWD: '/the/dir', ATOM_HOME: path.join(newAtomHomePath, 'non-existent')})
|
||||
await updateProcessEnv({ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true', PWD: '/the/dir', ATOM_HOME: path.join(newAtomHomePath, 'non-existent')})
|
||||
expect(process.env).toEqual({
|
||||
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
||||
PWD: '/the/dir',
|
||||
@@ -78,7 +88,7 @@ describe('updateProcessEnv(launchEnv)', function () {
|
||||
ATOM_HOME: '/the/atom/home'
|
||||
})
|
||||
|
||||
updateProcessEnv({ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true', PWD: '/the/dir', ATOM_HOME: newAtomHomePath})
|
||||
await updateProcessEnv({ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true', PWD: '/the/dir', ATOM_HOME: newAtomHomePath})
|
||||
expect(process.env).toEqual({
|
||||
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
||||
PWD: '/the/dir',
|
||||
@@ -88,7 +98,7 @@ describe('updateProcessEnv(launchEnv)', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('allows ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT to be preserved if set', function () {
|
||||
it('allows ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT to be preserved if set', async function () {
|
||||
process.env = {
|
||||
WILL_BE_DELETED: 'hi',
|
||||
NODE_ENV: 'the-node-env',
|
||||
@@ -96,7 +106,7 @@ describe('updateProcessEnv(launchEnv)', function () {
|
||||
ATOM_HOME: '/the/atom/home'
|
||||
}
|
||||
|
||||
updateProcessEnv({ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true', PWD: '/the/dir', NODE_ENV: 'the-node-env', NODE_PATH: '/the/node/path', ATOM_HOME: '/the/atom/home'})
|
||||
await updateProcessEnv({ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true', PWD: '/the/dir', NODE_ENV: 'the-node-env', NODE_PATH: '/the/node/path', ATOM_HOME: '/the/atom/home'})
|
||||
expect(process.env).toEqual({
|
||||
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
||||
PWD: '/the/dir',
|
||||
@@ -105,7 +115,7 @@ describe('updateProcessEnv(launchEnv)', function () {
|
||||
ATOM_HOME: '/the/atom/home'
|
||||
})
|
||||
|
||||
updateProcessEnv({PWD: '/the/dir', NODE_ENV: 'the-node-env', NODE_PATH: '/the/node/path', ATOM_HOME: '/the/atom/home'})
|
||||
await updateProcessEnv({PWD: '/the/dir', NODE_ENV: 'the-node-env', NODE_PATH: '/the/node/path', ATOM_HOME: '/the/atom/home'})
|
||||
expect(process.env).toEqual({
|
||||
ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT: 'true',
|
||||
PWD: '/the/dir',
|
||||
@@ -115,7 +125,7 @@ describe('updateProcessEnv(launchEnv)', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('allows an existing env variable to be updated', function () {
|
||||
it('allows an existing env variable to be updated', async function () {
|
||||
process.env = {
|
||||
WILL_BE_UPDATED: 'old-value',
|
||||
NODE_ENV: 'the-node-env',
|
||||
@@ -123,7 +133,7 @@ describe('updateProcessEnv(launchEnv)', function () {
|
||||
ATOM_HOME: '/the/atom/home'
|
||||
}
|
||||
|
||||
updateProcessEnv(process.env)
|
||||
await updateProcessEnv(process.env)
|
||||
expect(process.env).toEqual(process.env)
|
||||
|
||||
let updatedEnv = {
|
||||
@@ -135,27 +145,27 @@ describe('updateProcessEnv(launchEnv)', function () {
|
||||
PWD: '/the/dir'
|
||||
}
|
||||
|
||||
updateProcessEnv(updatedEnv)
|
||||
await updateProcessEnv(updatedEnv)
|
||||
expect(process.env).toEqual(updatedEnv)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the launch environment does not come from a shell', function () {
|
||||
describe('on osx', function () {
|
||||
it('updates process.env to match the environment in the user\'s login shell', function () {
|
||||
describe('on macOS', function () {
|
||||
it('updates process.env to match the environment in the user\'s login shell', async function () {
|
||||
if (process.platform === 'win32') return // TestsThatFailOnWin32
|
||||
|
||||
process.platform = 'darwin'
|
||||
process.env.SHELL = '/my/custom/bash'
|
||||
|
||||
spyOn(child_process, 'spawnSync').andReturn({
|
||||
stdout: dedent`
|
||||
FOO=BAR=BAZ=QUUX
|
||||
TERM=xterm-something
|
||||
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path
|
||||
`
|
||||
})
|
||||
|
||||
updateProcessEnv(process.env)
|
||||
expect(child_process.spawnSync.mostRecentCall.args[0]).toBe('/my/custom/bash')
|
||||
spawn.setDefault(spawn.simple(0, dedent`
|
||||
FOO=BAR=BAZ=QUUX
|
||||
TERM=xterm-something
|
||||
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path
|
||||
`))
|
||||
await updateProcessEnv(process.env)
|
||||
expect(spawn.calls.length).toBe(1)
|
||||
expect(spawn.calls[0].command).toBe('/my/custom/bash')
|
||||
expect(spawn.calls[0].args).toEqual(['-ilc', 'command env'])
|
||||
expect(process.env).toEqual({
|
||||
FOO: 'BAR=BAZ=QUUX',
|
||||
TERM: 'xterm-something',
|
||||
@@ -163,25 +173,25 @@ describe('updateProcessEnv(launchEnv)', function () {
|
||||
})
|
||||
|
||||
// Doesn't error
|
||||
updateProcessEnv(null)
|
||||
await updateProcessEnv(null)
|
||||
})
|
||||
})
|
||||
|
||||
describe('on linux', function () {
|
||||
it('updates process.env to match the environment in the user\'s login shell', function () {
|
||||
it('updates process.env to match the environment in the user\'s login shell', async function () {
|
||||
if (process.platform === 'win32') return // TestsThatFailOnWin32
|
||||
|
||||
process.platform = 'linux'
|
||||
process.env.SHELL = '/my/custom/bash'
|
||||
|
||||
spyOn(child_process, 'spawnSync').andReturn({
|
||||
stdout: dedent`
|
||||
FOO=BAR=BAZ=QUUX
|
||||
TERM=xterm-something
|
||||
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path
|
||||
`
|
||||
})
|
||||
|
||||
updateProcessEnv(process.env)
|
||||
expect(child_process.spawnSync.mostRecentCall.args[0]).toBe('/my/custom/bash')
|
||||
spawn.setDefault(spawn.simple(0, dedent`
|
||||
FOO=BAR=BAZ=QUUX
|
||||
TERM=xterm-something
|
||||
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/crazy/path
|
||||
`))
|
||||
await updateProcessEnv(process.env)
|
||||
expect(spawn.calls.length).toBe(1)
|
||||
expect(spawn.calls[0].command).toBe('/my/custom/bash')
|
||||
expect(spawn.calls[0].args).toEqual(['-ilc', 'command env'])
|
||||
expect(process.env).toEqual({
|
||||
FOO: 'BAR=BAZ=QUUX',
|
||||
TERM: 'xterm-something',
|
||||
@@ -189,24 +199,26 @@ describe('updateProcessEnv(launchEnv)', function () {
|
||||
})
|
||||
|
||||
// Doesn't error
|
||||
updateProcessEnv(null)
|
||||
await updateProcessEnv(null)
|
||||
})
|
||||
})
|
||||
|
||||
describe('on windows', function () {
|
||||
it('does not update process.env', function () {
|
||||
it('does not update process.env', async function () {
|
||||
process.platform = 'win32'
|
||||
spyOn(child_process, 'spawnSync')
|
||||
spyOn(childProcess, 'spawn')
|
||||
process.env = {FOO: 'bar'}
|
||||
|
||||
updateProcessEnv(process.env)
|
||||
expect(child_process.spawnSync).not.toHaveBeenCalled()
|
||||
await updateProcessEnv(process.env)
|
||||
expect(childProcess.spawn).not.toHaveBeenCalled()
|
||||
expect(process.env).toEqual({FOO: 'bar'})
|
||||
})
|
||||
})
|
||||
|
||||
describe('shouldGetEnvFromShell()', function () {
|
||||
it('indicates when the environment should be fetched from the shell', function () {
|
||||
if (process.platform === 'win32') return // TestsThatFailOnWin32
|
||||
|
||||
process.platform = 'darwin'
|
||||
expect(shouldGetEnvFromShell({SHELL: '/bin/sh'})).toBe(true)
|
||||
expect(shouldGetEnvFromShell({SHELL: '/usr/local/bin/sh'})).toBe(true)
|
||||
|
||||
@@ -23,6 +23,7 @@ describe "WindowEventHandler", ->
|
||||
|
||||
describe "when the window is loaded", ->
|
||||
it "doesn't have .is-blurred on the body tag", ->
|
||||
return if process.platform is 'win32' #Win32TestFailures - can not steal focus
|
||||
expect(document.body.className).not.toMatch("is-blurred")
|
||||
|
||||
describe "when the window is blurred", ->
|
||||
|
||||
@@ -4,6 +4,9 @@ temp = require('temp').track()
|
||||
{Disposable} = require 'event-kit'
|
||||
|
||||
describe "WorkspaceElement", ->
|
||||
afterEach ->
|
||||
temp.cleanupSync()
|
||||
|
||||
describe "when the workspace element is focused", ->
|
||||
it "transfers focus to the active pane", ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
temp = require('temp').track()
|
||||
TextEditor = require '../src/text-editor'
|
||||
Workspace = require '../src/workspace'
|
||||
Project = require '../src/project'
|
||||
@@ -19,6 +19,9 @@ describe "Workspace", ->
|
||||
atom.project.setPaths([atom.project.getDirectories()[0]?.resolve('dir')])
|
||||
waits(1)
|
||||
|
||||
afterEach ->
|
||||
temp.cleanupSync()
|
||||
|
||||
describe "serialization", ->
|
||||
simulateReload = ->
|
||||
workspaceState = atom.workspace.serialize()
|
||||
@@ -489,6 +492,7 @@ describe "Workspace", ->
|
||||
expect(item).toEqual {bar: "bar://baz"}
|
||||
|
||||
it "adds the file to the application's recent documents list", ->
|
||||
return unless process.platform is 'darwin' # Feature only supported on macOS
|
||||
spyOn(atom.applicationDelegate, 'addRecentDocument')
|
||||
|
||||
waitsForPromise ->
|
||||
@@ -1139,6 +1143,7 @@ describe "Workspace", ->
|
||||
range: [[2, 6], [2, 11]]
|
||||
|
||||
it "works on evil filenames", ->
|
||||
atom.config.set('core.excludeVcsIgnoredPaths', false)
|
||||
platform.generateEvilFiles()
|
||||
atom.project.setPaths([path.join(__dirname, 'fixtures', 'evil-files')])
|
||||
paths = []
|
||||
@@ -1224,7 +1229,7 @@ describe "Workspace", ->
|
||||
expect(matches.length).toBe 1
|
||||
|
||||
it "includes files and folders that begin with a '.'", ->
|
||||
projectPath = temp.mkdirSync()
|
||||
projectPath = temp.mkdirSync('atom-spec-workspace')
|
||||
filePath = path.join(projectPath, '.text')
|
||||
fs.writeFileSync(filePath, 'match this')
|
||||
atom.project.setPaths([projectPath])
|
||||
|
||||
@@ -13,6 +13,7 @@ StateStore = require './state-store'
|
||||
StorageFolder = require './storage-folder'
|
||||
{getWindowLoadSettings} = require './window-load-settings-helpers'
|
||||
registerDefaultCommands = require './register-default-commands'
|
||||
{updateProcessEnv} = require './update-process-env'
|
||||
|
||||
DeserializerManager = require './deserializer-manager'
|
||||
ViewRegistry = require './view-registry'
|
||||
@@ -239,16 +240,6 @@ class AtomEnvironment extends Model
|
||||
|
||||
new ReopenProjectMenuManager({@menu, @commands, @history, @config, open: (paths) => @open(pathsToOpen: paths)})
|
||||
|
||||
checkPortableHomeWritable = =>
|
||||
responseChannel = "check-portable-home-writable-response"
|
||||
ipcRenderer.on responseChannel, (event, response) ->
|
||||
ipcRenderer.removeAllListeners(responseChannel)
|
||||
@notifications.addWarning("#{response.message.replace(/([\\\.+\\-_#!])/g, '\\$1')}") if not response.writable
|
||||
@disposables.add new Disposable -> ipcRenderer.removeAllListeners(responseChannel)
|
||||
ipcRenderer.send('check-portable-home-writable', responseChannel)
|
||||
|
||||
checkPortableHomeWritable()
|
||||
|
||||
attachSaveStateListeners: ->
|
||||
saveState = _.debounce((=>
|
||||
window.requestIdleCallback => @saveState({isUnloading: false}) unless @unloaded
|
||||
@@ -675,7 +666,11 @@ class AtomEnvironment extends Model
|
||||
# Call this method when establishing a real application window.
|
||||
startEditorWindow: ->
|
||||
@unloaded = false
|
||||
@loadState().then (state) =>
|
||||
updateProcessEnvPromise = updateProcessEnv(@getLoadSettings().env)
|
||||
updateProcessEnvPromise.then =>
|
||||
@packages.triggerActivationHook('core:loaded-shell-environment')
|
||||
|
||||
loadStatePromise = @loadState().then (state) =>
|
||||
@windowDimensions = state?.windowDimensions
|
||||
@displayWindow().then =>
|
||||
@commandInstaller.installAtomCommand false, (error) ->
|
||||
@@ -716,6 +711,8 @@ class AtomEnvironment extends Model
|
||||
|
||||
@openInitialEmptyEditorIfNecessary()
|
||||
|
||||
Promise.all([loadStatePromise, updateProcessEnvPromise])
|
||||
|
||||
serialize: (options) ->
|
||||
version: @constructor.version
|
||||
project: @project.serialize(options)
|
||||
|
||||
62
src/atom-paths.js
Normal file
62
src/atom-paths.js
Normal file
@@ -0,0 +1,62 @@
|
||||
/** @babel */
|
||||
|
||||
const fs = require('fs-plus')
|
||||
const path = require('path')
|
||||
|
||||
const hasWriteAccess = (dir) => {
|
||||
const testFilePath = path.join(dir, 'write.test')
|
||||
try {
|
||||
fs.writeFileSync(testFilePath, new Date().toISOString(), { flag: 'w+' })
|
||||
fs.unlinkSync(testFilePath)
|
||||
return true
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const getAppDirectory = () => {
|
||||
switch (process.platform) {
|
||||
case 'darwin':
|
||||
return path.join(process.execPath.substring(0, process.execPath.indexOf('.app')), '..')
|
||||
case 'linux':
|
||||
case 'win32':
|
||||
return path.join(process.execPath, '..')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
setAtomHome: (homePath) => {
|
||||
// When a read-writeable .atom folder exists above app use that
|
||||
const portableHomePath = path.join(getAppDirectory(), '.atom')
|
||||
if (fs.existsSync(portableHomePath)) {
|
||||
if (hasWriteAccess(portableHomePath)) {
|
||||
process.env.ATOM_HOME = portableHomePath
|
||||
} else {
|
||||
// A path exists so it was intended to be used but we didn't have rights, so warn.
|
||||
console.log(`Insufficient permission to portable Atom home "${portableHomePath}".`)
|
||||
}
|
||||
}
|
||||
|
||||
// Check ATOM_HOME environment variable next
|
||||
if (process.env.ATOM_HOME !== undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
// Fall back to default .atom folder in users home folder
|
||||
process.env.ATOM_HOME = path.join(homePath, '.atom')
|
||||
},
|
||||
|
||||
setUserData: (app) => {
|
||||
const electronUserDataPath = path.join(process.env.ATOM_HOME, 'electronUserData')
|
||||
if (fs.existsSync(electronUserDataPath)) {
|
||||
if (hasWriteAccess(electronUserDataPath)) {
|
||||
app.setPath('userData', electronUserDataPath)
|
||||
} else {
|
||||
// A path exists so it was intended to be used but we didn't have rights, so warn.
|
||||
console.log(`Insufficient permission to Electron user data "${electronUserDataPath}".`)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getAppDirectory: getAppDirectory
|
||||
}
|
||||
@@ -50,33 +50,8 @@ export default class BufferedProcess {
|
||||
this.emitter = new Emitter()
|
||||
this.command = command
|
||||
// Related to joyent/node#2318
|
||||
if (process.platform === 'win32' && !options.shell) {
|
||||
let cmdArgs = []
|
||||
|
||||
// Quote all arguments and escapes inner quotes
|
||||
if (args) {
|
||||
cmdArgs = args.filter((arg) => arg != null)
|
||||
.map((arg) => {
|
||||
if (this.isExplorerCommand(command) && /^\/[a-zA-Z]+,.*$/.test(arg)) {
|
||||
// Don't wrap /root,C:\folder style arguments to explorer calls in
|
||||
// quotes since they will not be interpreted correctly if they are
|
||||
return arg
|
||||
} else {
|
||||
return `\"${arg.toString().replace(/"/g, '\\"')}\"`
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (/\s/.test(command)) {
|
||||
cmdArgs.unshift(`\"${command}\"`)
|
||||
} else {
|
||||
cmdArgs.unshift(command)
|
||||
}
|
||||
|
||||
cmdArgs = ['/s', '/d', '/c', `\"${cmdArgs.join(' ')}\"`]
|
||||
const cmdOptions = _.clone(options)
|
||||
cmdOptions.windowsVerbatimArguments = true
|
||||
this.spawn(this.getCmdPath(), cmdArgs, cmdOptions)
|
||||
if (process.platform === 'win32' && options.shell === undefined) {
|
||||
this.spawnWithEscapedWindowsArgs(command, args, options)
|
||||
} else {
|
||||
this.spawn(command, args, options)
|
||||
}
|
||||
@@ -85,6 +60,33 @@ export default class BufferedProcess {
|
||||
this.handleEvents(stdout, stderr, exit)
|
||||
}
|
||||
|
||||
// Windows has a bunch of special rules that node still doesn't take care of for you
|
||||
spawnWithEscapedWindowsArgs (command, args, options) {
|
||||
let cmdArgs = []
|
||||
// Quote all arguments and escapes inner quotes
|
||||
if (args) {
|
||||
cmdArgs = args.filter((arg) => arg != null)
|
||||
.map((arg) => {
|
||||
if (this.isExplorerCommand(command) && /^\/[a-zA-Z]+,.*$/.test(arg)) {
|
||||
// Don't wrap /root,C:\folder style arguments to explorer calls in
|
||||
// quotes since they will not be interpreted correctly if they are
|
||||
return arg
|
||||
} else {
|
||||
// Escape double quotes by putting a backslash in front of them
|
||||
return `\"${arg.toString().replace(/"/g, '\\"')}\"`
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// The command itself is quoted if it contains spaces, &, ^ or | chars
|
||||
cmdArgs.unshift(/\s|&|\^|\|/.test(command) ? `\"${command}\"` : command)
|
||||
|
||||
const cmdOptions = _.clone(options)
|
||||
cmdOptions.windowsVerbatimArguments = true
|
||||
|
||||
this.spawn(this.getCmdPath(), ['/s', '/d', '/c', `\"${cmdArgs.join(' ')}\"`], cmdOptions)
|
||||
}
|
||||
|
||||
/*
|
||||
Section: Event Subscription
|
||||
*/
|
||||
|
||||
@@ -12,7 +12,7 @@ const configSchema = {
|
||||
properties: {
|
||||
ignoredNames: {
|
||||
type: 'array',
|
||||
default: ['.git', '.hg', '.svn', '.DS_Store', '._*', 'Thumbs.db'],
|
||||
default: ['.git', '.hg', '.svn', '.DS_Store', '._*', 'Thumbs.db', 'desktop.ini'],
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
@@ -85,6 +85,8 @@ const configSchema = {
|
||||
default: 'utf8',
|
||||
enum: [
|
||||
'cp437',
|
||||
'cp850',
|
||||
'cp866',
|
||||
'eucjp',
|
||||
'euckr',
|
||||
'gbk',
|
||||
@@ -117,12 +119,16 @@ const configSchema = {
|
||||
'windows1255',
|
||||
'windows1256',
|
||||
'windows1257',
|
||||
'windows1258',
|
||||
'windows866'
|
||||
'windows1258'
|
||||
]
|
||||
},
|
||||
openEmptyEditorOnStart: {
|
||||
description: 'Automatically open an empty editor on startup.',
|
||||
description: 'When checked opens an untitled editor when loading a blank environment (such as with _File > New Window_ or when "Restore Previous Windows On Start" is unchecked); otherwise no editor is opened when loading a blank environment. This setting has no effect when restoring a previous state.',
|
||||
type: 'boolean',
|
||||
default: true
|
||||
},
|
||||
restorePreviousWindowsOnStart: {
|
||||
description: 'When checked restores the last state of all Atom windows when started from the icon or `atom` by itself from the command line; otherwise a blank environment is loaded.',
|
||||
type: 'boolean',
|
||||
default: true
|
||||
},
|
||||
|
||||
@@ -238,6 +238,7 @@ class GitRepository
|
||||
|
||||
# Public: Returns the git configuration value specified by the key.
|
||||
#
|
||||
# * `key` The {String} key for the configuration to lookup.
|
||||
# * `path` An optional {String} path in the repository to get this information
|
||||
# for, only needed if the repository has submodules.
|
||||
getConfigValue: (key, path) -> @getRepo(path).getConfigValue(key)
|
||||
|
||||
@@ -103,6 +103,7 @@ class GutterContainerComponent
|
||||
@domNode.appendChild(gutterComponent.getDomNode())
|
||||
else
|
||||
@domNode.insertBefore(gutterComponent.getDomNode(), @domNode.children[indexInOldGutters])
|
||||
indexInOldGutters += 1
|
||||
|
||||
# Remove any gutters that were not present in the new gutters state.
|
||||
for gutterComponentDescription in @gutterComponents
|
||||
|
||||
@@ -47,6 +47,8 @@ export class HistoryManager {
|
||||
}
|
||||
|
||||
addProject (paths, lastOpened) {
|
||||
if (paths.length === 0) return
|
||||
|
||||
let project = this.getProject(paths)
|
||||
if (!project) {
|
||||
project = new HistoryProject(paths)
|
||||
@@ -60,9 +62,8 @@ export class HistoryManager {
|
||||
}
|
||||
|
||||
getProject (paths) {
|
||||
const pathsString = paths.toString()
|
||||
for (var i = 0; i < this.projects.length; i++) {
|
||||
if (this.projects[i].paths.toString() === pathsString) {
|
||||
if (arrayEquivalent(paths, this.projects[i].paths)) {
|
||||
return this.projects[i]
|
||||
}
|
||||
}
|
||||
@@ -98,6 +99,14 @@ export class HistoryManager {
|
||||
}
|
||||
}
|
||||
|
||||
function arrayEquivalent (a, b) {
|
||||
if (a.length !== b.length) return false
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
if (a[i] !== b[i]) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export class HistoryProject {
|
||||
constructor (paths, lastOpened) {
|
||||
this.paths = paths
|
||||
|
||||
@@ -8,8 +8,6 @@ module.exports = ({blobStore}) ->
|
||||
{resourcePath, devMode, env} = getWindowLoadSettings()
|
||||
require './electron-shims'
|
||||
|
||||
updateProcessEnv(env)
|
||||
|
||||
# Add application-specific exports to module search path.
|
||||
exportsPath = path.join(resourcePath, 'exports')
|
||||
require('module').globalPaths.push(exportsPath)
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
module.exports =
|
||||
class InputComponent
|
||||
constructor: ->
|
||||
@domNode = document.createElement('input')
|
||||
@domNode.classList.add('hidden-input')
|
||||
@domNode.setAttribute('tabindex', -1)
|
||||
@domNode.setAttribute('data-react-skip-selection-restoration', true)
|
||||
@domNode.style['-webkit-transform'] = 'translateZ(0)'
|
||||
@domNode.addEventListener 'paste', (event) -> event.preventDefault()
|
||||
|
||||
getDomNode: ->
|
||||
@domNode
|
||||
constructor: (@domNode) ->
|
||||
|
||||
updateSync: (state) ->
|
||||
@oldState ?= {}
|
||||
|
||||
@@ -34,7 +34,7 @@ class AtomApplication
|
||||
unless options.socketPath?
|
||||
if process.platform is 'win32'
|
||||
userNameSafe = new Buffer(process.env.USERNAME).toString('base64')
|
||||
options.socketPath = "\\\\.\\pipe\\atom-#{options.version}-#{userNameSafe}-sock"
|
||||
options.socketPath = "\\\\.\\pipe\\atom-#{options.version}-#{userNameSafe}-#{process.arch}-sock"
|
||||
else
|
||||
options.socketPath = path.join(os.tmpdir(), "atom-#{options.version}-#{process.env.USER}.sock")
|
||||
|
||||
@@ -63,7 +63,7 @@ class AtomApplication
|
||||
exit: (status) -> app.exit(status)
|
||||
|
||||
constructor: (options) ->
|
||||
{@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, @logFile, @setPortable, @userDataDir} = options
|
||||
{@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, @logFile, @userDataDir} = options
|
||||
@socketPath = null if options.test or options.benchmark or options.benchmarkTest
|
||||
@pidsToOpenWindows = {}
|
||||
@windows = []
|
||||
@@ -509,7 +509,7 @@ class AtomApplication
|
||||
openPaths: ({initialPaths, pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearWindowState, addToLastWindow, env}={}) ->
|
||||
if not pathsToOpen? or pathsToOpen.length is 0
|
||||
return
|
||||
|
||||
env = process.env unless env?
|
||||
devMode = Boolean(devMode)
|
||||
safeMode = Boolean(safeMode)
|
||||
clearWindowState = Boolean(clearWindowState)
|
||||
@@ -796,7 +796,6 @@ class AtomApplication
|
||||
restart: ->
|
||||
args = []
|
||||
args.push("--safe") if @safeMode
|
||||
args.push("--portable") if @setPortable
|
||||
args.push("--log-file=#{@logFile}") if @logFile?
|
||||
args.push("--socket-path=#{@socketPath}") if @socketPath?
|
||||
args.push("--user-data-dir=#{@userDataDir}") if @userDataDir?
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
const fs = require('fs-plus')
|
||||
const path = require('path')
|
||||
const {ipcMain} = require('electron')
|
||||
|
||||
module.exports = class AtomPortable {
|
||||
static getPortableAtomHomePath () {
|
||||
const execDirectoryPath = path.dirname(process.execPath)
|
||||
return path.join(execDirectoryPath, '..', '.atom')
|
||||
}
|
||||
|
||||
static setPortable (existingAtomHome) {
|
||||
fs.copySync(existingAtomHome, this.getPortableAtomHomePath())
|
||||
}
|
||||
|
||||
static isPortableInstall (platform, environmentAtomHome, defaultHome) {
|
||||
if (!['linux', 'win32'].includes(platform)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (environmentAtomHome) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!fs.existsSync(this.getPortableAtomHomePath())) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Currently checking only that the directory exists and is writable,
|
||||
// probably want to do some integrity checks on contents in future.
|
||||
return this.isPortableAtomHomePathWritable(defaultHome)
|
||||
}
|
||||
|
||||
static isPortableAtomHomePathWritable (defaultHome) {
|
||||
let writable = false
|
||||
let message = ''
|
||||
try {
|
||||
const writePermissionTestFile = path.join(this.getPortableAtomHomePath(), 'write.test')
|
||||
|
||||
if (!fs.existsSync(writePermissionTestFile)) {
|
||||
fs.writeFileSync(writePermissionTestFile, 'test')
|
||||
}
|
||||
|
||||
fs.removeSync(writePermissionTestFile)
|
||||
writable = true
|
||||
} catch (error) {
|
||||
message = `Failed to use portable Atom home directory (${this.getPortableAtomHomePath()}). Using the default instead (${defaultHome}). ${error.message}.`
|
||||
}
|
||||
|
||||
ipcMain.on('check-portable-home-writable', function (event) {
|
||||
event.sender.send('check-portable-home-writable-response', {
|
||||
writable: writable,
|
||||
message: message
|
||||
})
|
||||
})
|
||||
|
||||
return writable
|
||||
}
|
||||
}
|
||||
@@ -17,13 +17,15 @@ class AutoUpdateManager
|
||||
constructor: (@version, @testMode, resourcePath, @config) ->
|
||||
@state = IdleState
|
||||
@iconPath = path.resolve(__dirname, '..', '..', 'resources', 'atom.png')
|
||||
@feedUrl = "https://atom.io/api/updates?version=#{@version}"
|
||||
process.nextTick => @setupAutoUpdater()
|
||||
|
||||
setupAutoUpdater: ->
|
||||
if process.platform is 'win32'
|
||||
archSuffix = if process.arch is 'ia32' then '' else '-' + process.arch
|
||||
@feedUrl = "https://atom.io/api/updates#{archSuffix}"
|
||||
autoUpdater = require './auto-updater-win32'
|
||||
else
|
||||
@feedUrl = "https://atom.io/api/updates?version=#{@version}"
|
||||
{autoUpdater} = require 'electron'
|
||||
|
||||
autoUpdater.on 'error', (event, message) =>
|
||||
|
||||
@@ -41,10 +41,6 @@ module.exports = function parseCommandLine (processArgs) {
|
||||
'safe',
|
||||
'Do not load packages from ~/.atom/packages or ~/.atom/dev/packages.'
|
||||
)
|
||||
options.boolean('portable').describe(
|
||||
'portable',
|
||||
'Set portable mode. Copies the ~/.atom folder to be a sibling of the installed Atom location if a .atom folder is not already there.'
|
||||
)
|
||||
options.boolean('benchmark').describe('benchmark', 'Open a new window that runs the specified benchmarks.')
|
||||
options.boolean('benchmark-test').describe('benchmark--test', 'Run a faster version of the benchmarks in headless mode.')
|
||||
options.alias('t', 'test').boolean('t').describe('t', 'Run the specified specs and exit with error code on failures.')
|
||||
@@ -104,7 +100,6 @@ module.exports = function parseCommandLine (processArgs) {
|
||||
const profileStartup = args['profile-startup']
|
||||
const clearWindowState = args['clear-window-state']
|
||||
const urlsToOpen = []
|
||||
const setPortable = args.portable
|
||||
let devMode = args['dev']
|
||||
let devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH || path.join(app.getPath('home'), 'github', 'atom')
|
||||
let resourcePath = null
|
||||
@@ -152,7 +147,6 @@ module.exports = function parseCommandLine (processArgs) {
|
||||
userDataDir,
|
||||
profileStartup,
|
||||
timeout,
|
||||
setPortable,
|
||||
clearWindowState,
|
||||
addToLastWindow,
|
||||
mainProcess,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
const {app} = require('electron')
|
||||
const fs = require('fs-plus')
|
||||
const nslog = require('nslog')
|
||||
const path = require('path')
|
||||
const temp = require('temp')
|
||||
const parseCommandLine = require('./parse-command-line')
|
||||
const startCrashReporter = require('../crash-reporter-start')
|
||||
const atomPaths = require('../atom-paths')
|
||||
|
||||
module.exports = function start (resourcePath, startTime) {
|
||||
global.shellStartTime = startTime
|
||||
@@ -23,7 +23,8 @@ module.exports = function start (resourcePath, startTime) {
|
||||
console.log = nslog
|
||||
|
||||
const args = parseCommandLine(process.argv.slice(1))
|
||||
setupAtomHome(args)
|
||||
atomPaths.setAtomHome(app.getPath('home'))
|
||||
atomPaths.setUserData()
|
||||
setupCompileCache()
|
||||
|
||||
if (handleStartupEventWithSquirrel()) {
|
||||
@@ -39,7 +40,7 @@ module.exports = function start (resourcePath, startTime) {
|
||||
}
|
||||
|
||||
// NB: This prevents Win10 from showing dupe items in the taskbar
|
||||
app.setAppUserModelId('com.squirrel.atom.atom')
|
||||
app.setAppUserModelId('com.squirrel.atom.' + process.arch)
|
||||
|
||||
function addPathToOpen (event, pathToOpen) {
|
||||
event.preventDefault()
|
||||
@@ -79,36 +80,6 @@ function handleStartupEventWithSquirrel () {
|
||||
return SquirrelUpdate.handleStartupEvent(app, squirrelCommand)
|
||||
}
|
||||
|
||||
function setupAtomHome ({setPortable}) {
|
||||
if (process.env.ATOM_HOME) {
|
||||
return
|
||||
}
|
||||
|
||||
let atomHome = path.join(app.getPath('home'), '.atom')
|
||||
const AtomPortable = require('./atom-portable')
|
||||
|
||||
if (setPortable && !AtomPortable.isPortableInstall(process.platform, process.env.ATOM_HOME, atomHome)) {
|
||||
try {
|
||||
AtomPortable.setPortable(atomHome)
|
||||
} catch (error) {
|
||||
console.log(`Failed copying portable directory '${atomHome}' to '${AtomPortable.getPortableAtomHomePath()}'`)
|
||||
console.log(`${error.message} ${error.stack}`)
|
||||
}
|
||||
}
|
||||
|
||||
if (AtomPortable.isPortableInstall(process.platform, process.env.ATOM_HOME, atomHome)) {
|
||||
atomHome = AtomPortable.getPortableAtomHomePath()
|
||||
}
|
||||
|
||||
try {
|
||||
atomHome = fs.realpathSync(atomHome)
|
||||
} catch (e) {
|
||||
// Don't throw an error if atomHome doesn't exist.
|
||||
}
|
||||
|
||||
process.env.ATOM_HOME = atomHome
|
||||
}
|
||||
|
||||
function setupCompileCache () {
|
||||
const CompileCache = require('../compile-cache')
|
||||
CompileCache.setAtomHomeDirectory(process.env.ATOM_HOME)
|
||||
|
||||
@@ -39,6 +39,7 @@ class PackageManager
|
||||
@activationHookEmitter = new Emitter
|
||||
@packageDirPaths = []
|
||||
@deferredActivationHooks = []
|
||||
@triggeredActivationHooks = new Set()
|
||||
if configDirPath? and not safeMode
|
||||
if @devMode
|
||||
@packageDirPaths.push(path.join(configDirPath, "dev", "packages"))
|
||||
@@ -67,6 +68,7 @@ class PackageManager
|
||||
@deactivatePackages()
|
||||
@loadedPackages = {}
|
||||
@packageStates = {}
|
||||
@triggeredActivationHooks.clear()
|
||||
|
||||
###
|
||||
Section: Event Subscription
|
||||
@@ -460,12 +462,17 @@ class PackageManager
|
||||
Promise.resolve(pack)
|
||||
else if pack = @loadPackage(name)
|
||||
@activatingPackages[pack.name] = pack
|
||||
pack.activate().then =>
|
||||
activationPromise = pack.activate().then =>
|
||||
if @activatingPackages[pack.name]?
|
||||
delete @activatingPackages[pack.name]
|
||||
@activePackages[pack.name] = pack
|
||||
@emitter.emit 'did-activate-package', pack
|
||||
pack
|
||||
|
||||
unless @deferredActivationHooks?
|
||||
@triggeredActivationHooks.forEach((hook) => @activationHookEmitter.emit(hook))
|
||||
|
||||
activationPromise
|
||||
else
|
||||
Promise.reject(new Error("Failed to load package '#{name}'"))
|
||||
|
||||
@@ -476,6 +483,7 @@ class PackageManager
|
||||
|
||||
triggerActivationHook: (hook) ->
|
||||
return new Error("Cannot trigger an empty activation hook") unless hook? and _.isString(hook) and hook.length > 0
|
||||
@triggeredActivationHooks.add(hook)
|
||||
if @deferredActivationHooks?
|
||||
@deferredActivationHooks.push hook
|
||||
else
|
||||
|
||||
@@ -96,7 +96,7 @@ class PackageTranspilationRegistry {
|
||||
}
|
||||
|
||||
lastPath = thisPath
|
||||
thisPath = path.resolve(thisPath, '..')
|
||||
thisPath = path.join(thisPath, '..')
|
||||
}
|
||||
|
||||
this.specByFilePath[filePath] = null
|
||||
|
||||
@@ -24,6 +24,7 @@ class Package
|
||||
mainModulePath: null
|
||||
resolvedMainModulePath: false
|
||||
mainModule: null
|
||||
mainInitialized: false
|
||||
mainActivated: false
|
||||
|
||||
###
|
||||
@@ -114,8 +115,24 @@ class Package
|
||||
@menus = []
|
||||
@grammars = []
|
||||
@settings = []
|
||||
@mainInitialized = false
|
||||
@mainActivated = false
|
||||
|
||||
initializeIfNeeded: ->
|
||||
return if @mainInitialized
|
||||
@measure 'initializeTime', =>
|
||||
try
|
||||
# The main module's `initialize()` method is guaranteed to be called
|
||||
# before its `activate()`. This gives you a chance to handle the
|
||||
# serialized package state before the package's derserializers and view
|
||||
# providers are used.
|
||||
@requireMainModule() unless @mainModule?
|
||||
@mainModule.initialize?(@packageManager.getPackageState(@name) ? {})
|
||||
@mainInitialized = true
|
||||
catch error
|
||||
@handleError("Failed to initialize the #{@name} package", error)
|
||||
return
|
||||
|
||||
activate: ->
|
||||
@grammarsPromise ?= @loadGrammars()
|
||||
@activationPromise ?=
|
||||
@@ -140,10 +157,13 @@ class Package
|
||||
@registerViewProviders()
|
||||
@activateStylesheets()
|
||||
if @mainModule? and not @mainActivated
|
||||
@initializeIfNeeded()
|
||||
@mainModule.activateConfig?()
|
||||
@mainModule.activate?(@packageManager.getPackageState(@name) ? {})
|
||||
@mainActivated = true
|
||||
@activateServices()
|
||||
@activationCommandSubscriptions?.dispose()
|
||||
@activationHookSubscriptions?.dispose()
|
||||
catch error
|
||||
@handleError("Failed to activate the #{@name} package", error)
|
||||
|
||||
@@ -301,6 +321,7 @@ class Package
|
||||
deserialize: (state, atomEnvironment) =>
|
||||
@registerViewProviders()
|
||||
@requireMainModule()
|
||||
@initializeIfNeeded()
|
||||
@mainModule[methodName](state, atomEnvironment)
|
||||
return
|
||||
|
||||
@@ -318,6 +339,7 @@ class Package
|
||||
@requireMainModule()
|
||||
@metadata.viewProviders.forEach (methodName) =>
|
||||
@viewRegistry.addViewProvider (model) =>
|
||||
@initializeIfNeeded()
|
||||
@mainModule[methodName](model)
|
||||
@registeredViewProviders = true
|
||||
|
||||
@@ -420,6 +442,7 @@ class Package
|
||||
@mainModule?.deactivate?()
|
||||
@mainModule?.deactivateConfig?()
|
||||
@mainActivated = false
|
||||
@mainInitialized = false
|
||||
catch e
|
||||
console.error "Error deactivating package '#{@name}'", e.stack
|
||||
@emitter.emit 'did-deactivate'
|
||||
|
||||
@@ -234,6 +234,39 @@ class Pane extends Model
|
||||
onDidChangeActiveItem: (callback) ->
|
||||
@emitter.on 'did-change-active-item', callback
|
||||
|
||||
# Public: Invoke the given callback when {::activateNextRecentlyUsedItem}
|
||||
# has been called, either initiating or continuing a forward MRU traversal of
|
||||
# pane items.
|
||||
#
|
||||
# * `callback` {Function} to be called with when the active item changes.
|
||||
# * `nextRecentlyUsedItem` The next MRU item, now being set active
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
|
||||
onChooseNextMRUItem: (callback) ->
|
||||
@emitter.on 'choose-next-mru-item', callback
|
||||
|
||||
# Public: Invoke the given callback when {::activatePreviousRecentlyUsedItem}
|
||||
# has been called, either initiating or continuing a reverse MRU traversal of
|
||||
# pane items.
|
||||
#
|
||||
# * `callback` {Function} to be called with when the active item changes.
|
||||
# * `previousRecentlyUsedItem` The previous MRU item, now being set active
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
|
||||
onChooseLastMRUItem: (callback) ->
|
||||
@emitter.on 'choose-last-mru-item', callback
|
||||
|
||||
# Public: Invoke the given callback when {::moveActiveItemToTopOfStack}
|
||||
# has been called, terminating an MRU traversal of pane items and moving the
|
||||
# current active item to the top of the stack. Typically bound to a modifier
|
||||
# (e.g. CTRL) key up event.
|
||||
#
|
||||
# * `callback` {Function} to be called with when the MRU traversal is done.
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
|
||||
onDoneChoosingMRUItem: (callback) ->
|
||||
@emitter.on 'done-choosing-mru-item', callback
|
||||
|
||||
# Public: Invoke the given callback with the current and future values of
|
||||
# {::getActiveItem}.
|
||||
#
|
||||
@@ -334,6 +367,7 @@ class Pane extends Model
|
||||
@itemStackIndex = @itemStack.length if @itemStackIndex is 0
|
||||
@itemStackIndex = @itemStackIndex - 1
|
||||
nextRecentlyUsedItem = @itemStack[@itemStackIndex]
|
||||
@emitter.emit 'choose-next-mru-item', nextRecentlyUsedItem
|
||||
@setActiveItem(nextRecentlyUsedItem, modifyStack: false)
|
||||
|
||||
# Makes the previous item in the itemStack active.
|
||||
@@ -343,12 +377,15 @@ class Pane extends Model
|
||||
@itemStackIndex = -1
|
||||
@itemStackIndex = @itemStackIndex + 1
|
||||
previousRecentlyUsedItem = @itemStack[@itemStackIndex]
|
||||
@emitter.emit 'choose-last-mru-item', previousRecentlyUsedItem
|
||||
@setActiveItem(previousRecentlyUsedItem, modifyStack: false)
|
||||
|
||||
# Moves the active item to the end of the itemStack once the ctrl key is lifted
|
||||
moveActiveItemToTopOfStack: ->
|
||||
delete @itemStackIndex
|
||||
@addItemToStack(@activeItem)
|
||||
@emitter.emit 'done-choosing-mru-item'
|
||||
|
||||
|
||||
# Public: Makes the next item active.
|
||||
activateNextItem: ->
|
||||
|
||||
@@ -1,59 +1,71 @@
|
||||
/** @babel */
|
||||
|
||||
import { SelectListView } from 'atom-space-pen-views'
|
||||
import SelectListView from 'atom-select-list'
|
||||
|
||||
export default class ReopenProjectListView extends SelectListView {
|
||||
initialize (callback) {
|
||||
export default class ReopenProjectListView {
|
||||
constructor (callback) {
|
||||
this.callback = callback
|
||||
super.initialize()
|
||||
this.addClass('reopen-project')
|
||||
this.list.addClass('mark-active')
|
||||
this.selectListView = new SelectListView({
|
||||
emptyMessage: 'No projects in history.',
|
||||
itemsClassList: ['mark-active'],
|
||||
items: [],
|
||||
filterKeyForItem: (project) => project.name,
|
||||
elementForItem: (project) => {
|
||||
let element = document.createElement('li')
|
||||
if (project.name === this.currentProjectName) {
|
||||
element.classList.add('active')
|
||||
}
|
||||
element.textContent = project.name
|
||||
return element
|
||||
},
|
||||
didConfirmSelection: (project) => {
|
||||
this.cancel()
|
||||
this.callback(project.value)
|
||||
},
|
||||
didCancelSelection: () => {
|
||||
this.cancel()
|
||||
}
|
||||
})
|
||||
this.selectListView.element.classList.add('reopen-project')
|
||||
}
|
||||
|
||||
getFilterKey () {
|
||||
return 'name'
|
||||
get element () {
|
||||
return this.selectListView.element
|
||||
}
|
||||
|
||||
destroy () {
|
||||
dispose () {
|
||||
this.cancel()
|
||||
return this.selectListView.destroy()
|
||||
}
|
||||
|
||||
viewForItem (project) {
|
||||
let element = document.createElement('li')
|
||||
if (project.name === this.currentProjectName) {
|
||||
element.classList.add('active')
|
||||
}
|
||||
element.textContent = project.name
|
||||
return element
|
||||
}
|
||||
|
||||
cancelled () {
|
||||
cancel () {
|
||||
if (this.panel != null) {
|
||||
this.panel.destroy()
|
||||
}
|
||||
this.panel = null
|
||||
this.currentProjectName = null
|
||||
}
|
||||
|
||||
confirmed (project) {
|
||||
this.cancel()
|
||||
this.callback(project.value)
|
||||
if (this.previouslyFocusedElement) {
|
||||
this.previouslyFocusedElement.focus()
|
||||
this.previouslyFocusedElement = null
|
||||
}
|
||||
}
|
||||
|
||||
attach () {
|
||||
this.storeFocusedElement()
|
||||
this.previouslyFocusedElement = document.activeElement
|
||||
if (this.panel == null) {
|
||||
this.panel = atom.workspace.addModalPanel({item: this})
|
||||
}
|
||||
this.focusFilterEditor()
|
||||
this.selectListView.focus()
|
||||
this.selectListView.reset()
|
||||
}
|
||||
|
||||
toggle () {
|
||||
async toggle () {
|
||||
if (this.panel != null) {
|
||||
this.cancel()
|
||||
} else {
|
||||
this.currentProjectName = atom.project != null ? this.makeName(atom.project.getPaths()) : null
|
||||
this.setItems(atom.history.getProjects().map(p => ({ name: this.makeName(p.paths), value: p.paths })))
|
||||
const projects = atom.history.getProjects().map(p => ({ name: this.makeName(p.paths), value: p.paths }))
|
||||
await this.selectListView.update({items: projects})
|
||||
this.attach()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,32 @@ export default class ReopenProjectMenuManager {
|
||||
this.projects = this.historyManager.getProjects().slice(0, this.config.get('core.reopenProjectMenuCount'))
|
||||
const newMenu = ReopenProjectMenuManager.createProjectsMenu(this.projects)
|
||||
this.lastProjectMenu = this.menuManager.add([newMenu])
|
||||
this.updateWindowsJumpList()
|
||||
}
|
||||
|
||||
updateWindowsJumpList () {
|
||||
if (process.platform !== 'win32') return
|
||||
|
||||
if (this.app === undefined) {
|
||||
this.app = require('remote').app
|
||||
}
|
||||
|
||||
this.app.setJumpList([
|
||||
{
|
||||
type: 'custom',
|
||||
name: 'Recent Projects',
|
||||
items: this.projects.map(project => ({
|
||||
type: 'task',
|
||||
title: project.paths.map(ReopenProjectMenuManager.betterBaseName).join(', '),
|
||||
description: project.paths.map(path => `${ReopenProjectMenuManager.betterBaseName(path)} (${path})`).join(' '),
|
||||
program: process.execPath,
|
||||
args: project.paths.map(path => `"${path}"`).join(' ') }))
|
||||
},
|
||||
{ type: 'recent' },
|
||||
{ items: [
|
||||
{type: 'task', title: 'New Window', program: process.execPath, args: '--new-window', description: 'Opens a new Atom window'}
|
||||
]}
|
||||
])
|
||||
}
|
||||
|
||||
dispose () {
|
||||
|
||||
@@ -366,7 +366,7 @@ class Selection extends Model
|
||||
insertText: (text, options={}) ->
|
||||
oldBufferRange = @getBufferRange()
|
||||
wasReversed = @isReversed()
|
||||
@clear()
|
||||
@clear(options)
|
||||
|
||||
autoIndentFirstLine = false
|
||||
precedingText = @editor.getTextInRange([[oldBufferRange.start.row, 0], oldBufferRange.start])
|
||||
@@ -403,7 +403,7 @@ class Selection extends Model
|
||||
else if options.autoDecreaseIndent and NonWhitespaceRegExp.test(text)
|
||||
@editor.autoDecreaseIndentForBufferRow(newBufferRange.start.row)
|
||||
|
||||
@autoscroll() if @isLastSelection()
|
||||
@autoscroll() if options.autoscroll ? @isLastSelection()
|
||||
|
||||
newBufferRange
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class TextEditorComponent
|
||||
@assert domNode?, "TextEditorComponent::domNode was set to null."
|
||||
@domNodeValue = domNode
|
||||
|
||||
constructor: ({@editor, @hostElement, tileSize, @views, @themes, @styles, @assert}) ->
|
||||
constructor: ({@editor, @hostElement, tileSize, @views, @themes, @styles, @assert, hiddenInputElement}) ->
|
||||
@tileSize = tileSize if tileSize?
|
||||
@disposables = new CompositeDisposable
|
||||
|
||||
@@ -70,8 +70,12 @@ class TextEditorComponent
|
||||
@scrollViewNode.classList.add('scroll-view')
|
||||
@domNode.appendChild(@scrollViewNode)
|
||||
|
||||
@hiddenInputComponent = new InputComponent
|
||||
@scrollViewNode.appendChild(@hiddenInputComponent.getDomNode())
|
||||
@hiddenInputComponent = new InputComponent(hiddenInputElement)
|
||||
@scrollViewNode.appendChild(hiddenInputElement)
|
||||
# Add a getModel method to the hidden input component to make it easy to
|
||||
# access the editor in response to DOM events or when using
|
||||
# document.activeElement.
|
||||
hiddenInputElement.getModel = => @editor
|
||||
|
||||
@linesComponent = new LinesComponent({@presenter, @domElementPool, @assert, @grammars, @views})
|
||||
@scrollViewNode.appendChild(@linesComponent.getDomNode())
|
||||
@@ -342,7 +346,6 @@ class TextEditorComponent
|
||||
focused: ->
|
||||
if @mounted
|
||||
@presenter.setFocused(true)
|
||||
@hiddenInputComponent.getDomNode().focus()
|
||||
|
||||
blurred: ->
|
||||
if @mounted
|
||||
@@ -416,7 +419,6 @@ class TextEditorComponent
|
||||
|
||||
onScrollViewScroll: =>
|
||||
if @mounted
|
||||
console.warn "TextEditorScrollView scrolled when it shouldn't have."
|
||||
@scrollViewNode.scrollTop = 0
|
||||
@scrollViewNode.scrollLeft = 0
|
||||
|
||||
@@ -905,7 +907,7 @@ class TextEditorComponent
|
||||
|
||||
screenRowForNode: (node) ->
|
||||
while node?
|
||||
if screenRow = node.dataset.screenRow
|
||||
if screenRow = node.dataset?.screenRow
|
||||
return parseInt(screenRow)
|
||||
node = node.parentElement
|
||||
null
|
||||
|
||||
@@ -25,8 +25,17 @@ class TextEditorElement extends HTMLElement
|
||||
@emitter = new Emitter
|
||||
@subscriptions = new CompositeDisposable
|
||||
|
||||
@hiddenInputElement = document.createElement('input')
|
||||
@hiddenInputElement.classList.add('hidden-input')
|
||||
@hiddenInputElement.setAttribute('tabindex', -1)
|
||||
@hiddenInputElement.setAttribute('data-react-skip-selection-restoration', true)
|
||||
@hiddenInputElement.style['-webkit-transform'] = 'translateZ(0)'
|
||||
@hiddenInputElement.addEventListener 'paste', (event) -> event.preventDefault()
|
||||
|
||||
@addEventListener 'focus', @focused.bind(this)
|
||||
@addEventListener 'blur', @blurred.bind(this)
|
||||
@hiddenInputElement.addEventListener 'focus', @focused.bind(this)
|
||||
@hiddenInputElement.addEventListener 'blur', @inputNodeBlurred.bind(this)
|
||||
|
||||
@classList.add('editor')
|
||||
@setAttribute('tabindex', -1)
|
||||
@@ -117,12 +126,10 @@ class TextEditorElement extends HTMLElement
|
||||
themes: @themes
|
||||
styles: @styles
|
||||
workspace: @workspace
|
||||
assert: @assert
|
||||
assert: @assert,
|
||||
hiddenInputElement: @hiddenInputElement
|
||||
)
|
||||
@rootElement.appendChild(@component.getDomNode())
|
||||
inputNode = @component.hiddenInputComponent.getDomNode()
|
||||
inputNode.addEventListener 'focus', @focused.bind(this)
|
||||
inputNode.addEventListener 'blur', @inputNodeBlurred.bind(this)
|
||||
|
||||
unmountComponent: ->
|
||||
if @component?
|
||||
@@ -132,16 +139,17 @@ class TextEditorElement extends HTMLElement
|
||||
|
||||
focused: (event) ->
|
||||
@component?.focused()
|
||||
@hiddenInputElement.focus()
|
||||
|
||||
blurred: (event) ->
|
||||
if event.relatedTarget is @component?.hiddenInputComponent.getDomNode()
|
||||
if event.relatedTarget is @hiddenInputElement
|
||||
event.stopImmediatePropagation()
|
||||
return
|
||||
@component?.blurred()
|
||||
|
||||
inputNodeBlurred: (event) ->
|
||||
if event.relatedTarget isnt this
|
||||
@dispatchEvent(new FocusEvent('blur', bubbles: false))
|
||||
@dispatchEvent(new FocusEvent('blur', relatedTarget: event.relatedTarget, bubbles: false))
|
||||
|
||||
addGrammarScopeAttribute: ->
|
||||
@dataset.grammar = @model.getGrammar()?.scopeName?.replace(/\./g, ' ')
|
||||
|
||||
@@ -306,9 +306,6 @@ class TextEditorPresenter
|
||||
getEndTileRow: ->
|
||||
@tileForRow(@endRow ? 0)
|
||||
|
||||
isValidScreenRow: (screenRow) ->
|
||||
screenRow >= 0 and screenRow < @model.getApproximateScreenLineCount()
|
||||
|
||||
getScreenRowsToRender: ->
|
||||
startRow = @getStartTileRow()
|
||||
endRow = @getEndTileRow() + @tileSize
|
||||
@@ -320,7 +317,7 @@ class TextEditorPresenter
|
||||
if @screenRowsToMeasure?
|
||||
screenRows.push(@screenRowsToMeasure...)
|
||||
|
||||
screenRows = screenRows.filter @isValidScreenRow.bind(this)
|
||||
screenRows = screenRows.filter (row) -> row >= 0
|
||||
screenRows.sort (a, b) -> a - b
|
||||
_.uniq(screenRows, true)
|
||||
|
||||
@@ -395,19 +392,17 @@ class TextEditorPresenter
|
||||
visibleTiles[tileStartRow] = true
|
||||
zIndex++
|
||||
|
||||
if @mouseWheelScreenRow? and 0 <= @mouseWheelScreenRow < @model.getApproximateScreenLineCount()
|
||||
mouseWheelTile = @tileForRow(@mouseWheelScreenRow)
|
||||
|
||||
unless visibleTiles[mouseWheelTile]?
|
||||
@lineNumberGutter.tiles[mouseWheelTile].display = "none"
|
||||
@state.content.tiles[mouseWheelTile].display = "none"
|
||||
visibleTiles[mouseWheelTile] = true
|
||||
mouseWheelTileId = @tileForRow(@mouseWheelScreenRow) if @mouseWheelScreenRow?
|
||||
|
||||
for id, tile of @state.content.tiles
|
||||
continue if visibleTiles.hasOwnProperty(id)
|
||||
|
||||
delete @state.content.tiles[id]
|
||||
delete @lineNumberGutter.tiles[id]
|
||||
if Number(id) is mouseWheelTileId
|
||||
@state.content.tiles[id].display = "none"
|
||||
@lineNumberGutter.tiles[id].display = "none"
|
||||
else
|
||||
delete @state.content.tiles[id]
|
||||
delete @lineNumberGutter.tiles[id]
|
||||
|
||||
updateLinesState: (tileState, screenRows) ->
|
||||
tileState.lines ?= {}
|
||||
@@ -456,7 +451,7 @@ class TextEditorPresenter
|
||||
for decoration in @model.getOverlayDecorations()
|
||||
continue unless decoration.getMarker().isValid()
|
||||
|
||||
{item, position, class: klass} = decoration.getProperties()
|
||||
{item, position, class: klass, avoidOverflow} = decoration.getProperties()
|
||||
if position is 'tail'
|
||||
screenPosition = decoration.getMarker().getTailScreenPosition()
|
||||
else
|
||||
@@ -471,15 +466,16 @@ class TextEditorPresenter
|
||||
if overlayDimensions = @overlayDimensions[decoration.id]
|
||||
{itemWidth, itemHeight, contentMargin} = overlayDimensions
|
||||
|
||||
rightDiff = left + itemWidth + contentMargin - @windowWidth
|
||||
left -= rightDiff if rightDiff > 0
|
||||
if avoidOverflow isnt false
|
||||
rightDiff = left + itemWidth + contentMargin - @windowWidth
|
||||
left -= rightDiff if rightDiff > 0
|
||||
|
||||
leftDiff = left + contentMargin
|
||||
left -= leftDiff if leftDiff < 0
|
||||
leftDiff = left + contentMargin
|
||||
left -= leftDiff if leftDiff < 0
|
||||
|
||||
if top + itemHeight > @windowHeight and
|
||||
top - (itemHeight + @lineHeight) >= 0
|
||||
top -= itemHeight + @lineHeight
|
||||
if top + itemHeight > @windowHeight and
|
||||
top - (itemHeight + @lineHeight) >= 0
|
||||
top -= itemHeight + @lineHeight
|
||||
|
||||
pixelPosition.top = top
|
||||
pixelPosition.left = left
|
||||
@@ -1006,8 +1002,7 @@ class TextEditorPresenter
|
||||
@lineHeight? and @baseCharacterWidth?
|
||||
|
||||
pixelPositionForScreenPosition: (screenPosition) ->
|
||||
position =
|
||||
@linesYardstick.pixelPositionForScreenPosition(screenPosition)
|
||||
position = @linesYardstick.pixelPositionForScreenPosition(screenPosition)
|
||||
position.top -= @getScrollTop()
|
||||
position.left -= @getScrollLeft()
|
||||
|
||||
@@ -1230,13 +1225,14 @@ class TextEditorPresenter
|
||||
screenRange.end.column = 0
|
||||
|
||||
repositionRegionWithinTile: (region, tileStartRow) ->
|
||||
region.top += @scrollTop - @lineTopIndex.pixelPositionBeforeBlocksForRow(tileStartRow)
|
||||
region.left += @scrollLeft
|
||||
region.top += @scrollTop - @lineTopIndex.pixelPositionBeforeBlocksForRow(tileStartRow)
|
||||
|
||||
buildHighlightRegions: (screenRange) ->
|
||||
lineHeightInPixels = @lineHeight
|
||||
startPixelPosition = @pixelPositionForScreenPosition(screenRange.start)
|
||||
endPixelPosition = @pixelPositionForScreenPosition(screenRange.end)
|
||||
startPixelPosition.left += @scrollLeft
|
||||
endPixelPosition.left += @scrollLeft
|
||||
spannedRows = screenRange.end.row - screenRange.start.row + 1
|
||||
|
||||
regions = []
|
||||
|
||||
@@ -222,6 +222,7 @@ class TextEditor extends Model
|
||||
@backgroundWorkHandle = null
|
||||
|
||||
update: (params) ->
|
||||
currentSoftWrapColumn = @getSoftWrapColumn()
|
||||
displayLayerParams = {}
|
||||
|
||||
for param in Object.keys(params)
|
||||
@@ -272,12 +273,16 @@ class TextEditor extends Model
|
||||
when 'softWrapAtPreferredLineLength'
|
||||
if value isnt @softWrapAtPreferredLineLength
|
||||
@softWrapAtPreferredLineLength = value
|
||||
displayLayerParams.softWrapColumn = @getSoftWrapColumn() if @isSoftWrapped()
|
||||
softWrapColumn = @getSoftWrapColumn()
|
||||
if softWrapColumn isnt currentSoftWrapColumn
|
||||
displayLayerParams.softWrapColumn = softWrapColumn
|
||||
|
||||
when 'preferredLineLength'
|
||||
if value isnt @preferredLineLength
|
||||
@preferredLineLength = value
|
||||
displayLayerParams.softWrapColumn = @getSoftWrapColumn() if @isSoftWrapped()
|
||||
softWrapColumn = @getSoftWrapColumn()
|
||||
if softWrapColumn isnt currentSoftWrapColumn
|
||||
displayLayerParams.softWrapColumn = softWrapColumn
|
||||
|
||||
when 'mini'
|
||||
if value isnt @mini
|
||||
@@ -322,12 +327,16 @@ class TextEditor extends Model
|
||||
when 'editorWidthInChars'
|
||||
if value > 0 and value isnt @editorWidthInChars
|
||||
@editorWidthInChars = value
|
||||
displayLayerParams.softWrapColumn = @getSoftWrapColumn() if @isSoftWrapped()
|
||||
softWrapColumn = @getSoftWrapColumn()
|
||||
if softWrapColumn isnt currentSoftWrapColumn
|
||||
displayLayerParams.softWrapColumn = softWrapColumn
|
||||
|
||||
when 'width'
|
||||
if value isnt @width
|
||||
@width = value
|
||||
displayLayerParams.softWrapColumn = @getSoftWrapColumn() if @isSoftWrapped()
|
||||
softWrapColumn = @getSoftWrapColumn()
|
||||
if softWrapColumn isnt currentSoftWrapColumn
|
||||
displayLayerParams.softWrapColumn = softWrapColumn
|
||||
|
||||
when 'scrollPastEnd'
|
||||
if value isnt @scrollPastEnd
|
||||
@@ -1076,8 +1085,8 @@ class TextEditor extends Model
|
||||
)
|
||||
|
||||
# Essential: For each selection, replace the selected text with a newline.
|
||||
insertNewline: ->
|
||||
@insertText('\n')
|
||||
insertNewline: (options) ->
|
||||
@insertText('\n', options)
|
||||
|
||||
# Essential: For each selection, if the selection is empty, delete the character
|
||||
# following the cursor. Otherwise delete the selected text.
|
||||
@@ -1740,10 +1749,14 @@ class TextEditor extends Model
|
||||
# * `onlyNonEmpty` (optional) If `true`, the decoration will only be applied
|
||||
# if the associated `DisplayMarker` is non-empty. Only applicable to the
|
||||
# `gutter`, `line`, and `line-number` types.
|
||||
# * `position` (optional) Only applicable to decorations of type `overlay` and `block`,
|
||||
# controls where the view is positioned relative to the `TextEditorMarker`.
|
||||
# * `position` (optional) Only applicable to decorations of type `overlay` and `block`.
|
||||
# Controls where the view is positioned relative to the `TextEditorMarker`.
|
||||
# Values can be `'head'` (the default) or `'tail'` for overlay decorations, and
|
||||
# `'before'` (the default) or `'after'` for block decorations.
|
||||
# * `avoidOverflow` (optional) Only applicable to decorations of type
|
||||
# `overlay`. Determines whether the decoration adjusts its horizontal or
|
||||
# vertical position to remain fully visible when it would otherwise
|
||||
# overflow the editor. Defaults to `true`.
|
||||
#
|
||||
# Returns a {Decoration} object
|
||||
decorateMarker: (marker, decorationParams) ->
|
||||
|
||||
@@ -178,7 +178,8 @@ class ThemeManager
|
||||
@requireStylesheet(nativeStylesheetPath)
|
||||
|
||||
stylesheetElementForId: (id) ->
|
||||
document.head.querySelector("atom-styles style[source-path=\"#{id}\"]")
|
||||
escapedId = id.replace(/\\/g, '\\\\')
|
||||
document.head.querySelector("atom-styles style[source-path=\"#{escapedId}\"]")
|
||||
|
||||
resolveStylesheet: (stylesheetPath) ->
|
||||
if path.extname(stylesheetPath).length > 0
|
||||
@@ -231,9 +232,6 @@ class ThemeManager
|
||||
applyStylesheet: (path, text) ->
|
||||
@styleSheetDisposablesBySourcePath[path] = @styleManager.addStyleSheet(text, sourcePath: path)
|
||||
|
||||
stringToId: (string) ->
|
||||
string.replace(/\\/g, '/')
|
||||
|
||||
activateThemes: ->
|
||||
new Promise (resolve) =>
|
||||
# @config.observe runs the callback once, then on subsequent changes.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** @babel */
|
||||
|
||||
import fs from 'fs'
|
||||
import {spawnSync} from 'child_process'
|
||||
import childProcess from 'child_process'
|
||||
|
||||
const ENVIRONMENT_VARIABLES_TO_PRESERVE = new Set([
|
||||
'NODE_ENV',
|
||||
@@ -15,12 +15,14 @@ const PLATFORMS_KNOWN_TO_WORK = new Set([
|
||||
'linux'
|
||||
])
|
||||
|
||||
function updateProcessEnv (launchEnv) {
|
||||
async function updateProcessEnv (launchEnv) {
|
||||
let envToAssign
|
||||
if (launchEnv && shouldGetEnvFromShell(launchEnv)) {
|
||||
envToAssign = getEnvFromShell(launchEnv)
|
||||
} else if (launchEnv && launchEnv.PWD) {
|
||||
envToAssign = launchEnv
|
||||
if (launchEnv) {
|
||||
if (shouldGetEnvFromShell(launchEnv)) {
|
||||
envToAssign = await getEnvFromShell(launchEnv)
|
||||
} else if (launchEnv.PWD) {
|
||||
envToAssign = launchEnv
|
||||
}
|
||||
}
|
||||
|
||||
if (envToAssign) {
|
||||
@@ -58,24 +60,64 @@ function shouldGetEnvFromShell (env) {
|
||||
return true
|
||||
}
|
||||
|
||||
function getEnvFromShell (env) {
|
||||
if (!shouldGetEnvFromShell(env)) {
|
||||
return
|
||||
}
|
||||
|
||||
let {stdout} = spawnSync(env.SHELL, ['-ilc', 'command env'], {encoding: 'utf8'})
|
||||
if (stdout) {
|
||||
let result = {}
|
||||
for (let line of stdout.split('\n')) {
|
||||
if (line.includes('=')) {
|
||||
let components = line.split('=')
|
||||
let key = components.shift()
|
||||
let value = components.join('=')
|
||||
result[key] = value
|
||||
async function getEnvFromShell (env) {
|
||||
let {stdout, error} = await new Promise((resolve) => {
|
||||
let child
|
||||
let error
|
||||
let stdout = ''
|
||||
let done = false
|
||||
const cleanup = () => {
|
||||
if (!done && child) {
|
||||
child.kill()
|
||||
done = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
process.once('exit', cleanup)
|
||||
setTimeout(() => {
|
||||
cleanup()
|
||||
}, 5000)
|
||||
child = childProcess.spawn(env.SHELL, ['-ilc', 'command env'], {encoding: 'utf8', detached: true, stdio: ['ignore', 'pipe', process.stderr]})
|
||||
const buffers = []
|
||||
child.on('error', (e) => {
|
||||
done = true
|
||||
error = e
|
||||
})
|
||||
child.stdout.on('data', (data) => {
|
||||
buffers.push(data)
|
||||
})
|
||||
child.on('close', (code, signal) => {
|
||||
done = true
|
||||
process.removeListener('exit', cleanup)
|
||||
if (buffers.length) {
|
||||
stdout = Buffer.concat(buffers).toString('utf8')
|
||||
}
|
||||
|
||||
resolve({stdout, error})
|
||||
})
|
||||
})
|
||||
|
||||
if (error) {
|
||||
if (error.handle) {
|
||||
error.handle()
|
||||
}
|
||||
console.log('warning: ' + env.SHELL + ' -ilc "command env" failed with signal (' + error.signal + ')')
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
if (!stdout || stdout.trim() === '') {
|
||||
return null
|
||||
}
|
||||
|
||||
let result = {}
|
||||
for (let line of stdout.split('\n')) {
|
||||
if (line.includes('=')) {
|
||||
let components = line.split('=')
|
||||
let key = components.shift()
|
||||
let value = components.join('=')
|
||||
result[key] = value
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export default { updateProcessEnv, shouldGetEnvFromShell }
|
||||
|
||||
@@ -441,7 +441,7 @@ class Workspace extends Model
|
||||
|
||||
# Avoid adding URLs as recent documents to work-around this Spotlight crash:
|
||||
# https://github.com/atom/atom/issues/10071
|
||||
if uri? and not url.parse(uri).protocol?
|
||||
if uri? and (not url.parse(uri).protocol? or process.platform is 'win32')
|
||||
@applicationDelegate.addRecentDocument(uri)
|
||||
|
||||
pane = @paneContainer.paneForURI(uri) if searchAllPanes
|
||||
|
||||
@@ -116,14 +116,12 @@
|
||||
})
|
||||
}
|
||||
|
||||
var currentWindow = require('electron').remote.getCurrentWindow()
|
||||
if (currentWindow.devToolsWebContents) {
|
||||
const webContents = require('electron').remote.getCurrentWindow().webContents
|
||||
if (webContents.devToolsWebContents) {
|
||||
profile()
|
||||
} else {
|
||||
currentWindow.openDevTools()
|
||||
currentWindow.once('devtools-opened', function () {
|
||||
setTimeout(profile, 1000)
|
||||
})
|
||||
webContents.once('devtools-opened', () => { setTimeout(profile, 1000) })
|
||||
webContents.openDevTools()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user