Merge remote-tracking branch 'origin/master' into atom-links

This commit is contained in:
David Wilson
2018-09-05 09:43:06 -07:00
235 changed files with 36222 additions and 3116 deletions

View File

@@ -0,0 +1,41 @@
---
name: Feature request
about: Suggest an idea for this project
---
<!--
Have you read Atom's Code of Conduct? By filing an Issue, you are expected to comply with it, including treating everyone with respect: https://github.com/atom/atom/blob/master/CODE_OF_CONDUCT.md
Do you want to ask a question? Are you looking for support? The Atom message board is the best place for getting support: https://discuss.atom.io
---
Keep in mind that Atom is highly customizable in a number of ways and we strongly prefer that you consider these options before filing this issue:
* https://flight-manual.atom.io/using-atom/sections/basic-customization/: tweak Atom's configuration, styles, and keybindings.
* https://flight-manual.atom.io/using-atom/sections/atom-packages/: install a community package.
* https://flight-manual.atom.io/hacking-atom/: use the Atom API in your init script, to create a package, or to enhance an existing package.
If you're convinced that none of these options are appropriate for the feature you want, please explain why that's the case by completely filling out the issue template below.
Also note that the Atom team has finite resources so it's unlikely that we'll work on feature requests. If we're interested in a particular feature however, we'll follow up and ask you to submit an RFC to talk about it in more detail.
-->
## Summary
One paragraph explanation of the feature.
## Motivation
Why are we doing this? What use cases does it support? What is the expected outcome?
## Describe alternatives you've considered
A clear and concise description of the alternative solutions you've considered. Be sure to explain why Atom's existing customizability isn't suitable for this feature.
## Additional context
Add any other context or screenshots about the feature request here.

46
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,46 @@
---
name: Bug report
about: Create a report to help us improve
---
<!--
Have you read Atom's Code of Conduct? By filing an Issue, you are expected to comply with it, including treating everyone with respect: https://github.com/atom/atom/blob/master/CODE_OF_CONDUCT.md
Do you want to ask a question? Are you looking for support? The Atom message board is the best place for getting support: https://discuss.atom.io
-->
### Prerequisites
* [ ] Put an X between the brackets on this line if you have done all of the following:
* Reproduced the problem in Safe Mode: https://flight-manual.atom.io/hacking-atom/sections/debugging/#using-safe-mode
* Followed all applicable steps in the debugging guide: https://flight-manual.atom.io/hacking-atom/sections/debugging/
* Checked the FAQs on the message board for common solutions: https://discuss.atom.io/c/faq
* Checked that your issue isn't already filed: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aatom
* Checked that there is not already an Atom package that provides the described functionality: https://atom.io/packages
### Description
[Description of the issue]
### Steps to Reproduce
1. [First Step]
2. [Second Step]
3. [and so on...]
**Expected behavior:** [What you expect to happen]
**Actual behavior:** [What actually happens]
**Reproduces how often:** [What percentage of the time does it reproduce?]
### Versions
You can get this information from copy and pasting the output of `atom --version` and `apm --version` from the command line. Also, please include the OS and what version of the OS you're running.
### Additional Information
Any additional information, configuration or data that might be necessary to reproduce the issue.

17
.github/lock.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
# Configuration for lock-threads - https://github.com/dessant/lock-threads
# Number of days of inactivity before a closed issue or pull request is locked
daysUntilLock: 180
# Comment to post before locking. Set to `false` to disable
lockComment: >
This issue has been automatically locked since there has not been
any recent activity after it was closed. If you can still reproduce this issue in
[Safe Mode](https://flight-manual.atom.io/hacking-atom/sections/debugging/#using-safe-mode)
then please open a new issue and fill out
[the entire issue template](https://github.com/atom/atom/blob/master/ISSUE_TEMPLATE.md)
to ensure that we have enough information to address your issue. Thanks!
# Issues or pull requests with these labels will not be locked
exemptLabels:
- help-wanted
# Limit to only `issues` or `pulls`
only: issues

0
.github/move.yml vendored Normal file
View File

View File

@@ -15,7 +15,7 @@ matrix:
include:
- os: linux
dist: trusty
env: NODE_VERSION=6.9.4 DISPLAY=:99.0 CC=clang CXX=clang++ npm_config_clang=1
env: NODE_VERSION=8.9.3 DISPLAY=:99.0 CC=clang CXX=clang++ npm_config_clang=1
sudo: required
@@ -27,7 +27,7 @@ install:
- source /tmp/.nvm/nvm.sh
- nvm install $NODE_VERSION
- nvm use --delete-prefix $NODE_VERSION
- npm install -g npm@5.3.0
- npm install --global npm@6.2.0
- script/build --create-debian-package --create-rpm-package --compress-artifacts
script:

View File

@@ -1,6 +1,6 @@
![Atom](https://cloud.githubusercontent.com/assets/72919/2874231/3af1db48-d3dd-11e3-98dc-6066f8bc766f.png)
[![macOS Build Status](https://circleci.com/gh/atom/atom/tree/master.svg?style=shield)](https://circleci.com/gh/atom/atom) [![Linux Build Status](https://travis-ci.org/atom/atom.svg?branch=master)](https://travis-ci.org/atom/atom) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/1tkktwh654w07eim?svg=true)](https://ci.appveyor.com/project/Atom/atom)
[![Build status](https://github.visualstudio.com/Atom/_apis/build/status/Atom%20Production%20Branches?branch=master)](https://github.visualstudio.com/Atom/_build/latest?definitionId=32&branch=master) [![Linux Build Status](https://travis-ci.org/atom/atom.svg?branch=master)](https://travis-ci.org/atom/atom) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/1tkktwh654w07eim?svg=true)](https://ci.appveyor.com/project/Atom/atom)
[![Dependency Status](https://david-dm.org/atom/atom.svg)](https://david-dm.org/atom/atom)
[![Join the Atom Community on Slack](https://atom-slack.herokuapp.com/badge.svg)](https://atom-slack.herokuapp.com)
@@ -65,7 +65,6 @@ repeat these steps to upgrade to future releases.
## Building
* [FreeBSD](./docs/build-instructions/freebsd.md)
* [Linux](https://flight-manual.atom.io/hacking-atom/sections/hacking-on-atom-core/#platform-linux)
* [macOS](https://flight-manual.atom.io/hacking-atom/sections/hacking-on-atom-core/#platform-mac)
* [Windows](https://flight-manual.atom.io/hacking-atom/sections/hacking-on-atom-core/#platform-windows)

4522
apm/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -6,6 +6,6 @@
"url": "https://github.com/atom/atom.git"
},
"dependencies": {
"atom-package-manager": "1.19.0"
"atom-package-manager": "2.1.1"
}
}

View File

@@ -10,6 +10,7 @@ branches:
only:
- master
- /^[0-9.]+-releases$/
- /^electron-[0-9.]+$/
platform:
- x64
@@ -19,7 +20,7 @@ environment:
global:
ATOM_DEV_RESOURCE_PATH: c:\projects\atom
TEST_JUNIT_XML_ROOT: c:\projects\junit-test-results
NODE_VERSION: 6.9.4
NODE_VERSION: 8.9.3
matrix:
- TASK: test
@@ -35,19 +36,22 @@ install:
- IF NOT EXIST %TEST_JUNIT_XML_ROOT% MKDIR %TEST_JUNIT_XML_ROOT%
- SET PATH=C:\Program Files\Atom\resources\cli;%PATH%
- ps: Install-Product node $env:NODE_VERSION $env:PLATFORM
- npm install -g npm@5.3.0
- npm install --global npm@6.2.0
build_script:
- CD %APPVEYOR_BUILD_FOLDER%
- IF NOT EXIST C:\tmp MKDIR C:\tmp
- SET SQUIRREL_TEMP=C:\tmp
- IF [%APPVEYOR_REPO_BRANCH:~-9%]==[-releases] SET IS_RELEASE_BRANCH=true
- IF [%APPVEYOR_REPO_BRANCH%]==[master] IF NOT DEFINED APPVEYOR_PULL_REQUEST_NUMBER SET IS_SIGNED_ZIP_BRANCH=true
- IF [%APPVEYOR_REPO_BRANCH:~0,9%]==[electron-] SET IS_SIGNED_ZIP_BRANCH=true
- IF [%TASK%]==[installer] (
IF [%APPVEYOR_REPO_BRANCH:~-9%]==[-releases] (
IF [%IS_RELEASE_BRANCH%]==[true] (
ECHO Building on release branch - Creating production artifacts &&
script\build.cmd --code-sign --compress-artifacts --create-windows-installer
) ELSE (
IF [%APPVEYOR_REPO_BRANCH%]==[master] IF NOT DEFINED APPVEYOR_PULL_REQUEST_NUMBER (
ECHO Building on master branch - Creating signed zips &&
IF [%IS_SIGNED_ZIP_BRANCH%]==[true] (
ECHO Building on %APPVEYOR_REPO_BRANCH% branch - Creating signed zips &&
script\build.cmd --code-sign --compress-artifacts
) ELSE (
ECHO Skipping installer build for non-release/non-master branch
@@ -74,6 +78,12 @@ artifacts:
name: atom-windows.zip
- path: out\RELEASES
name: RELEASES
- path: out\AtomSetup-x64.exe
name: AtomSetup-x64.exe
- path: out\atom-x64-windows.zip
name: atom-x64-windows.zip
- path: out\RELEASES-x64
name: RELEASES-x64
- path: out\atom-*-delta.nupkg
name: atom-delta.nupkg
- path: out\atom-*-full.nupkg

42
atom.sh
View File

@@ -13,6 +13,9 @@ case $(basename $0) in
atom-beta)
CHANNEL=beta
;;
atom-nightly)
CHANNEL=nightly
;;
atom-dev)
CHANNEL=dev
;;
@@ -59,6 +62,9 @@ if [ $REDIRECT_STDERR ]; then
exec 2> /dev/null
fi
ATOM_HOME="${ATOM_HOME:-$HOME/.atom}"
mkdir -p "$ATOM_HOME"
if [ $OS == 'Mac' ]; then
if [ -L "$0" ]; then
SCRIPT="$(readlink "$0")"
@@ -73,10 +79,20 @@ if [ $OS == 'Mac' ]; then
ATOM_APP_NAME="$(basename "$ATOM_APP")"
fi
if [ "$CHANNEL" == 'beta' ]; then
ATOM_EXECUTABLE_NAME="Atom Beta"
if [ ! -z "${ATOM_APP_NAME}" ]; then
# If ATOM_APP_NAME is known, use it as the executable name
ATOM_EXECUTABLE_NAME="${ATOM_APP_NAME%.*}"
else
ATOM_EXECUTABLE_NAME="Atom"
# Else choose it from the inferred channel name
if [ "$CHANNEL" == 'beta' ]; then
ATOM_EXECUTABLE_NAME="Atom Beta"
elif [ "$CHANNEL" == 'nightly' ]; then
ATOM_EXECUTABLE_NAME="Atom Nightly"
elif [ "$CHANNEL" == 'dev' ]; then
ATOM_EXECUTABLE_NAME="Atom Dev"
else
ATOM_EXECUTABLE_NAME="Atom"
fi
fi
if [ -z "${ATOM_PATH}" ]; then
@@ -111,6 +127,9 @@ elif [ $OS == 'Linux' ]; then
beta)
ATOM_PATH="$USR_DIRECTORY/share/atom-beta/atom"
;;
nightly)
ATOM_PATH="$USR_DIRECTORY/share/atom-nightly/atom"
;;
dev)
ATOM_PATH="$USR_DIRECTORY/share/atom-dev/atom"
;;
@@ -119,9 +138,6 @@ elif [ $OS == 'Linux' ]; then
;;
esac
ATOM_HOME="${ATOM_HOME:-$HOME/.atom}"
mkdir -p "$ATOM_HOME"
: ${TMPDIR:=/tmp}
[ -x "$ATOM_PATH" ] || ATOM_PATH="$TMPDIR/atom-build/Atom/atom"
@@ -146,8 +162,20 @@ on_die() {
}
trap 'on_die' SIGQUIT SIGTERM
# If the wait flag is set, don't exit this process until Atom tells it to.
# If the wait flag is set, don't exit this process until Atom kills it.
if [ $WAIT ]; then
WAIT_FIFO="$ATOM_HOME/.wait_fifo"
if [ ! -p "$WAIT_FIFO" ]; then
rm -f "$WAIT_FIFO"
mkfifo "$WAIT_FIFO"
fi
# Block endlessly by reading from a named pipe.
exec 2>/dev/null
read < "$WAIT_FIFO"
# If the read completes for some reason, fall back to sleeping in a loop.
while true; do
sleep 1
done

View File

@@ -1,45 +0,0 @@
machine:
environment:
XCODE_SCHEME: test
XCODE_WORKSPACE: test
XCODE_PROJECT: test
TEST_JUNIT_XML_ROOT: ${CIRCLE_TEST_REPORTS}
xcode:
version: 7.3
general:
artifacts:
- out/atom-mac.zip
- out/atom-mac-symbols.zip
- docs/output/atom-api.json
dependencies:
pre:
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.3/install.sh | bash
- nvm install 6.9.4
- nvm use 6.9.4
- npm install -g npm@5.3.0
override:
- script/build --code-sign --compress-artifacts
cache_directories:
- electron
- apm/node_modules
- script/node_modules
- node_modules
- ~/.atom/compile-cache
- ~/.atom/snapshot-cache
test:
override:
- script/lint
- osascript -e 'tell application "System Events" to keystroke "x"' # clear screen saver
- caffeinate -s script/test # Run with caffeinate to prevent screen saver
experimental:
notify:
branches:
only:
- master

View File

@@ -8,7 +8,6 @@ Most of the Atom user and developer documentation is contained in the [Atom Flig
Instructions for building Atom on various platforms from source.
* [FreeBSD](./build-instructions/freebsd.md)
* Moved to [the Flight Manual](https://flight-manual.atom.io/hacking-atom/sections/hacking-on-atom-core/)
* Linux
* macOS

View File

@@ -1,8 +1,8 @@
# Atom build status
| System | Travis | AppVeyor/Win | Circle/Mac | Dependencies |
| System | Travis | AppVeyor/Win | VSTS | Dependencies |
|--------|--------|--------------|------------|--------------|
| [Atom](https://github.com/atom/atom) | [![Travis Build Status](https://travis-ci.org/atom/atom.svg?branch=master)](https://travis-ci.org/atom/atom) | [![AppVeyor/Wi Build Status](https://ci.appveyor.com/api/projects/status/1tkktwh654w07eim?svg=true)](https://ci.appveyor.com/project/Atom/atom) | [![Circle/Mac Build Status](https://circleci.com/gh/atom/atom.svg?style=shield)](https://circleci.com/gh/atom/atom) | [![Dependency Status](https://david-dm.org/atom/atom.svg)](https://david-dm.org/atom/atom) |
| [Atom](https://github.com/atom/atom) | [![Travis Build Status](https://travis-ci.org/atom/atom.svg?branch=master)](https://travis-ci.org/atom/atom) | [![AppVeyor/Wi Build Status](https://ci.appveyor.com/api/projects/status/1tkktwh654w07eim?svg=true)](https://ci.appveyor.com/project/Atom/atom) | [![Build status](https://github.visualstudio.com/Atom/_apis/build/status/Atom%20Production%20Branches?branch=master)](https://github.visualstudio.com/Atom/_build/latest?definitionId=32&branch=master) | [![Dependency Status](https://david-dm.org/atom/atom.svg)](https://david-dm.org/atom/atom) |
| [APM](https://github.com/atom/apm) | [![Travis Build Status](https://travis-ci.org/atom/apm.svg?branch=master)](https://travis-ci.org/atom/apm) | [![AppVeyor/Wi Build Status](https://ci.appveyor.com/api/projects/status/j6ixw374a397ugkb/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/apm/branch/master) | | [![Dependency Status](https://david-dm.org/atom/apm.svg)](https://david-dm.org/atom/apm) |
| [Electron](https://github.com/electron/electron) | [![Travis Build Status](https://travis-ci.org/electron/electron.svg?branch=master)](https://travis-ci.org/electron/electron) | [![AppVeyor/Wi Build Status](https://ci.appveyor.com/api/projects/status/kvxe4byi7jcxbe26/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/electron) | | [![Dependency Status](https://david-dm.org/electron/electron/dev-status.svg)](https://david-dm.org/electron/electron)

View File

@@ -1,19 +0,0 @@
# FreeBSD
FreeBSD -RELEASE 64-bit is the recommended platform.
## Requirements
* FreeBSD
* `pkg install node`
* `pkg install npm`
* `pkg install libgnome-keyring`
* `npm config set python /usr/local/bin/python2 -g` to ensure that gyp uses Python 2
## Instructions
```sh
git clone https://github.com/atom/atom
cd atom
script/build
```

View File

@@ -1,55 +0,0 @@
## Highlights from the past week
- Atom IDE
- Started conversion of atom-languageclient to TypeScript [atom/atom-languageclient#175](https://github.com/atom/atom-languageclient/pull/175)
- @atom/watcher
- Report events related to [symlinks](https://github.com/atom/watcher/pull/111) and [test for symlink-related edge cases.](https://github.com/atom/watcher/pull/114)
- Produce filesystem events with a [consistent parent path](https://github.com/atom/watcher/pull/113) to the one used to create a watcher, even if the watcher was created with a a path containing symlinks.
- Verified correct behavior with regard to [filesystem case sensitivity.](https://github.com/atom/watcher/pull/116)
- Corrected buggy [utf8 to utf16 conversion](https://github.com/atom/watcher/pull/115) on Windows.
- Ran through the MacOS cases in the [testing matrix.](https://github.com/atom/atom/pull/16124)
- Set up a Samba share on @ungb's testing server to exercise Samba network drives.
- Published version 1.0.0 on [npm.](https://www.npmjs.com/package/@atom/watcher)
- GitHub Package
- Introduce a package configuration option to [disable the in-editor merge conflict resolution.](https://github.com/atom/github/pull/1305)
- Published a new release v0.10.0
- Investigated and spiked on a fix for amending bug in single-commit repos, which was surfaced by failing cache invalidation tests that were blocking release
- Deferred fixing underlying bug - [atom/github#1303](https://github.com/atom/github/issues/1303)
- Fixed failing tests - [atom/github#1302](https://github.com/atom/github/pull/1302)
- Teletype
- Released [Teletype 0.7.0](https://github.com/atom/teletype/releases/tag/v0.7.0) with improved diagnostics for errors that occur during package initialization ([atom/teletype#266](https://github.com/atom/teletype/issues/266), [atom/teletype#297](https://github.com/atom/teletype/issues/297))
- Opened [atom/teletype#323](https://github.com/atom/teletype/pull/323), [atom/teletype-client#52](https://github.com/atom/teletype-client/pull/52), and [atom/fuzzy-finder#335](https://github.com/atom/fuzzy-finder/pull/335) to pave the way for guests to use the fuzzy-finder to open any remote editor shared by the host ([atom/teletype#268](https://github.com/atom/teletype/issues/268))
## Focus for week ahead
- Atom IDE
- Finish conversion of atom-languageclient to TypeScript [atom/atom-languageclient#175](https://github.com/atom/atom-languageclient/pull/175)
- Contribute TypeScript type definitions for Atom IDE to [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)
- Contribute missing TypeScript type defintions for Atom to [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/atom)
- @atom/watcher
- Complete [the testing matrix](https://github.com/atom/atom/pull/16124) on Linux and Windows.
- :shipit: Merge [@atom/watcher support]((https://github.com/atom/atom/pull/16124)) into Atom _(as a non-default `PathWatcher` backend)_. :shipit:
- GitHub Package
- Quarterly planning. Which might change all of these :wink:
- Finish tracking down our [freezing CI builds.](https://github.com/atom/github/pull/1289)
- Resurrect the [gargantuan credential helper and GPG pinentry refactoring PR](https://github.com/atom/github/pull/846) and see how much work is needed to get it over the finish line.
- Fix issue with diff view popping up unexpectedly - [atom/github#1287](https://github.com/atom/github/issues/1287)
- Teletype
- Complete initial implementation and merge pull requests ([atom/teletype#323](https://github.com/atom/teletype/pull/323), [atom/teletype-client#52](https://github.com/atom/teletype-client/pull/52), and [atom/fuzzy-finder#335](https://github.com/atom/fuzzy-finder/pull/335)) allowing guests to use the fuzzy-finder to open any remote editor shared by the host ([atom/teletype#268](https://github.com/atom/teletype/issues/268))
- Use fuzzy-finder support internally in our day-to-day workflows to assess usability
- Tree-sitter
- Finish and merge [tree-sitter/tree-sitter#128](https://github.com/tree-sitter/tree-sitter/pull/128), which fixes a fundamental performance problem when editing large files.
- Fix syntax highlighting bugs [#16643](https://github.com/atom/atom/issues/16643) and [#16642](https://github.com/atom/atom/issues/16642).
- Fix [#16621](https://github.com/atom/atom/issues/16621) - snippets not working when using Tree-sitter.
- Xray
* @nathansobo (and @as-cii part time) will be focusing the next 12 weeks on a prototype for [a new Electron-based text editor](https://github.com/atom/xray). The goal is to explore the viability of radical performance improvements that could be possible if we make breaking changes to Atom's APIs. At the end of the 12 weeks, we will reassess our plans based on what we have managed to learn and accomplish.
* Week 1 of 12
* Clarify and document goals for the next 12 weeks.
* Ensure that the guide matches our current plans.
* Refine WebGL based text rendering.
* Make sure ASCII text renders correctly without being clipped
* Render text correctly on high DPI displays
* Use correct API for texture atlas updates
* Add mouse-wheel scrolling support
* Non-ASCII rendering, using the HarfBuzz text shaping library to detect combining characters
* Stretch goal: Switch document encoding to UTF-8 for memory compactness and support multi-byte-aware character indexing.

View File

@@ -1,51 +0,0 @@
## Highlights from the past week
- Atom IDE
- Converted atom-languageclient to TypeScript
- ide-typescript updated to use TypeScript 2.7.2
- Published updates to ide-typescript, ide-json, and ide-csharp to improve language server stability
- @atom/watcher
- Gracefully handle the situation where a network share with a watch root is disconnected ([#119](https://github.com/atom/watcher/pull/119))
- Merged into Atom master behind a feature flag ([#16124](https://github.com/atom/atom/pull/16124)) just after the 1.24.0 / 1.25.0-beta0 release
- Fixed a crash when messages are sent to the worker thread before it's properly initialized ([atom/watcher#121](https://github.com/atom/watcher/pull/121))
- GitHub Package
- Investigate intermittently freezing tests on Travis in [atom/github#1289](https://github.com/atom/github/pull/1289). Not much luck so far
- Fixed issue with diff views popping up unexpectedly [atom/github#1311](https://github.com/atom/github/pull/1311). Just waiting on review
- Teletype
- Fixed an unanticipated bug that would cause non-existent selections to appear in the editor of other participants ([atom/teletype#326](https://github.com/atom/teletype/pull/326)).
- Published [version 0.8.0](https://github.com/atom/teletype/releases/tag/v0.8.0).
- Refactored teletype-client and simplified how added/removed editors are broadcasted to participants ([atom/teletype-client#52](https://github.com/atom/teletype-client/pull/52)).
- Polished the design of fuzzy-finder ([atom/fuzzy-finder#335](https://github.com/atom/fuzzy-finder/pull/335))
- Pushed [atom/teletype#323](https://github.com/atom/teletype/pull/323) over the finish line.
- Xray
- We made a slight change of plans and decided to spend more time clarifying the overall vision for the project.
- We have a [branch](https://github.com/atom/xray/tree/roadmap) with a new README that matches our current thinking, but the Q1 roadmap is still in progress.
- We did manage to get text rendering with retina displays and non-clipped characters, but there's still work to do. We are also experimenting populating our glyph atlas with up to 4 variants of each glyph at different subpixel positions to more closely match text rendered purely on the CPU.
- Tree-sitter
- Took some time to fix unrelated regressions from the bug-bash month
- Fixed a bug where atom --wait did not work correctly on Windows (#16740)
- Fixed a bug that prevented Atom from reusing an existing window when the same path was opened twice (#16764)
- Fixed regressions in the behavior of the atom.textEditors.getGrammarOverride and atom.grammars.loadGrammar methods (#16733, #16747)
- Fixed several syntax highlighting bugs (#16642, #16643)
## Focus for week ahead
- Atom IDE
- Investigate new Atom IDE UI features for rename operations and workspace symbol search
- Publish TypeScript definitions for atom-ide/atom-languageclient to DefinitelyTyped
- Wire up atom-ide-ui console to LSP server logging
- @atom/watcher
- Diagnose and correct crashes and lock-ups as people report them
- GitHub Package
- Establish high-level goals and scope bounds for the GitHub side of the integration
- Document a protocol for the evolution of major features: ensure they contribute to a cohesive experience with the rest of the package, make sure that @simurai is looped in to the conversation, make sure the community has visibility to our goals
- Show recent commits in Git panel
- Teletype
- Merge and use [atom/fuzzy-finder#335](https://github.com/atom/fuzzy-finder/pull/335), [atom/teletype-client#52](https://github.com/atom/teletype-client/pull/52) and [atom/teletype#323](https://github.com/atom/teletype/pull/323).
- Publish Teletype v0.9.0 containing the new fuzzy-finder support.
- Tree-sitter
- Fix an issue where snippets are not available when using tree-sitter (#16621)
- Start work on optimizing editing in the presence of large parse errors (#16590)
- Start work on allowing parsing to take place on a background thread
- Xray
- We will continue clarifying the overall vision with a focus on real time collaboration. This may extend beyond the scope of Xray, but is important to get clarity on before comitting to a roadmap.
- We hope to iron out the remaining issues with subpixel-positioning of glyphs to more faithfully reproduce Chrome's behavior when rendering text via the normal DOM-based code path.

View File

@@ -1,43 +0,0 @@
## Highlights from the past week
- Atom IDE
- TypeScript conversion fully cleaned up, types ready for definitely typed
- Started work on AutoComplete rewrites to address poor filtering and over-eager pop-up
- Review of code actions integration (currently on ide-java)
- @atom/watcher
- GitHub Package
- Loads of [planning and process](https://github.com/atom/github/blob/master/docs/how-we-work.md)
- Recent commit history [RFC](https://github.com/atom/github/pull/1318) and [implementation](https://github.com/atom/github/pull/1322)
- Port another few components from Etch to React in preparation for :point_up:
- Wrestle with a few [flaky](https://github.com/atom/github/pull/1289) [tests](https://github.com/atom/github/pull/1320) to get our [build](https://github.com/atom/github/pull/1317) under control.
- Teletype
- Tree-sitter
- Finally wrote some documentation about Tree-sitter and how to develop parsers, now that members of the Atom community are starting to contribute to parsers.
- Xray
- We finished off some up-front planning around Xray's support for real time collaboration.
- We're now comfortably scrolling a dev-build of React at 60 frames per second. Frames are rendered in about 1.2ms per frame on our hardware, and rendering is looking identical to Chrome's CPU backend for basic ASCII text, modulo ligatures and kerning. We still have a lot of features to add, but we don't any of them will dramatically impact frame computation time.
- Reactor Duty
- Discovered root cause of Windows test failures in [atom/tree-view#1203](https://github.com/atom/tree-view/issues/1203), discussed in-progress fix with @50wliu
## Focus for week ahead
- Atom IDE
- Complete work on AutoComplete improvements
- Stop cancellations for autocomplete and outline throwing errors in the logs
- Investigate workspace symbol user interface
- @atom/watcher
- Diagnose crashes and lockups on Atom launch
- GitHub Package
- Recent commit implementation: land a [read-only view of the most recent commits](https://github.com/atom/github/pull/1322).
- Port [CommitViewController and CommitView to React](https://github.com/atom/github/pull/1325).
- Write up `docs/vision` from meeting notes.
- Begin on ["remember me"](https://github.com/atom/github/issues/861) for the git credential helper.
- Teletype
- Tree-sitter
- Optimizing syntax tree updates in the presence of syntax errors. This will improve performance across the board but also make Tree-sitter usable in edge cases where the wrong language is being used to parse a document.
- Xray
- @as-cii will be focused on more sophisticated text-shaping to extend our support beyond basic ASCII. We're working on a [glyph-renderer](https://github.com/atom/xray/tree/glyph-renderer) module that handles text layout and glyph rasterization. To support a standalone web-based component, we're starting with a WebAssembly module based on HarfBuzz and FreeType, but we can always explore using platform-specific frameworks for the Electron use case.
- @nathansobo will be focused on implementing selections. We're introducing a new "anchor" abstraction that creates a stable reference to a buffer location, along with methods for converting anchors to offsets or points. Each editor will store selections as a sorted array of anchor ranges. To move a selection, we'll convert its anchors to concrete points, adjust their rows/columns, then convert the points back to anchors. We're curious how long it will take us to do this for thousands of selections. Hopefully it's fast. Then we'll focus on inserting text inside the selections.
- Reactor Duty
- Investigate dock pane dragging regression [atom/atom#16769](https://github.com/atom/atom/issues/16769)
- Merge PR [atom/node-keytar#67](https://github.com/atom/node-keytar/pull/67)

View File

@@ -1,55 +0,0 @@
## Highlights from the past week
- Atom IDE
- Console logging started
- IDE-Java/PHP/TypeScript updates and fixes
- GitHub Package
- Recent commits view, read-only mode :tm: (@kuychaco, @smashwilson, @simurai) [#1322](https://github.com/atom/github/pull/1322)
- Recent commits view: show co-authors (@kuychaco, @simurai)
- Commit interactions research spike: undo most recent, amend (@kuychaco) [#1328](https://github.com/atom/github/pull/1328)
- Port CommitView and CommitController to React. (@smashwilson) [#1325](https://github.com/atom/github/pull/1325)
- Begin "Remember me" within the credential dialog [#1327](https://github.com/atom/github/pull/1327)
- Tree-sitter
- Shifted focus to address some open-source contributions to parsers:
- Wrote documentation about how to create parsers: http://tree-sitter.github.io/tree-sitter
- Fixed issues with the Bash parser
- Fixed a bug found during constant fuzzing by the security team: https://github.com/tree-sitter/tree-sitter/issues/133
- Xray
- Decided not to run all text through HarfBuzz for performance reasons, and came up with a plan for addressing mandatory text shaping issues in the future.
- Implemented anchors, selections, and basic selection movement.
- Partially implemented selection rendering.
- For more details, see the [detailed update](https://github.com/atom/xray/blob/master/docs/updates/2018_03_05.md) in the Xray repository.
- Engineering Improvements
- Automated Linux package repository publishing as part of Atom release process
- Reactor Duty
- Shipped node-keytar update, primary feature being prebuilt node modules ([atom/node-keytar#67](https://github.com/atom/node-keytar/pull/67))
- Merged community pull requests to atom/atom-select-list, atom/command-palette, and atom/tree-view
## Focus for week ahead
- Atom IDE
- Console logging completion
- Investigate language server process hanging on deactivation in ide-typescript
- Investigate using the new native LSP support in omnisharp-roslyn in ide-csharp
- @atom/watcher
- Diagnose crashes and lockups on Atom launch (@smashwilson)
- GitHub Package
- Finish "Remember me" within the credential dialog (@smashwilson) [#1327](https://github.com/atom/github/pull/1327)
- Write up `docs/vision` from meeting notes (@smashwilson)
- Kick-start our GPG pinentry handling (@smashwilson) [#846](https://github.com/atom/github/pull/846)
- Build UI for adding co-authors, much like Desktop's UI/UX - desktop.github.com/features/co-authors/
- Teletype
- Open pull request for the avatar UX enhancements described in ([atom/teletype#268](https://github.com/atom/teletype/issues/268))
- Tree-sitter
- Carrying over goals from previous weeks:
- Optimize syntax tree updates in the presence of syntax errors. This will improve performance across the board but also make Tree-sitter usable in edge cases where the wrong language is being used to parse a document.
- Start work on allowing parsing to take place on a background thread
- Xray
- Finish selection rendering
- Wire up enough of the key bindings / commands system to move cursors/selections
- Start on editing
- For more details, see [the detailed update](https://github.com/atom/xray/blob/master/docs/updates/2018_03_05.md)
- Engineering Improvements
- Finish new Atom release publishing automation
- Reactor Duty

View File

@@ -2,154 +2,27 @@
Want to know what the Atom team is working on and what has our focus over the next few months? You've come to the right place. 🎯
In this directory, you'll find **weekly progress and planning updates** from the core Atom team at GitHub (e.g., [`2018-02-12.md`](2018-02-12.md)), and the sections below represent our **near-term roadmap**:
* [Atom IDE](#atom-ide)
* [GitHub package](#github-package)
* [Teletype](#teletype)
* [Tree-sitter](#tree-sitter)
* [Xray](#xray)
This roadmap is a [living document](https://en.wikipedia.org/wiki/Living_document): it represents our current plans, but we expect these plans to change from time to time. Follow [this link](https://github.com/atom/atom/blob/4fbad81a7cd2f2e3925d7e920086bc1ebf2fe210/docs/focus/README.md) to see the previous major version of this roadmap.
This roadmap is a [living document](https://en.wikipedia.org/wiki/Living_document): it represents our current plans, but we expect these plans to change from time to time.
You can find our bi-weekly iteration plans by searching for issues with the [`iteration-plan`](https://github.com/atom/atom/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aiteration-plan) label.
---
# Atom IDE
### Core package development is streamlined
Everything in Atom is a package. While this adds to its hackability, it is not always the best path forward. Consolidating packages as well as thinking about other ways to decrease friction for contributors will help pay down some of our tech debt in this area. More information regarding planning was provided in [this RFC](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate-core-packages.md)
## Roadmap
- [ ] Merge at least 22 packages in to atom/atom
TODO
## Looking farther ahead
### Improve Communication and Process
TODO
- [ ] Refine process for triaging issues and PRs across Atom org repositories
- [ ] Publish a document that outlines merge requirements for community PRs
- [ ] Reactive tickets are incorporated in to 80% of all sprints
- [ ] Automate some aspects of Atom issue and PR triage with Probot, especially around ensuring PRs follow our contribution guidelines
---
### Establish and Measure
# GitHub package
Main repository: [atom/github](http://github.com/atom/github) (Atom package)
## Roadmap
Watch our progress on the [short-term roadmap project](https://github.com/atom/github/projects/8).
##### Recent commit history
_Near-term goal:_ An informational view that displays the most recent 1-3 commits beneath the mini commit message editor. Design and discussion in: [#554](https://github.com/atom/github/issues/554), [#86](https://github.com/atom/github/issues/86).
_Longer-term goals:_ Introduce interactivity to the commits shown in the recent history list. Right-click on the top click to amend it, or on prior commits to reset. Overhaul the "amend button" functionality and implementation.
##### Commit co-authoring
_Near-term goal:_ Allow users to specify co-authors when committing. Draw inspiration from [Desktop's implementation](https://github.com/desktop/desktop/pull/3879) for UI. Tracking issue: [#1309](https://github.com/atom/github/issues/1309).
_Longer-term goals:_ Expose an API so that packages like teletype can add portal participants to commits automatically. Tangentially related to [#1089](https://github.com/atom/github/issues/1089).
##### Pull request workflow - Create Pull Request
_Near-term goal:_ Add buttons in the GitHub panel to allow users to push any unpushed changes and open new pull requests. The "Open new pull request" button will link to the github.com compare view in browser. Open pull request: [#1138](https://github.com/atom/github/pull/1138).
_Longer-term goals:_ Offer a complete in-editor experience. Compose pull request titles and descriptions in the GitHub dock item. However, we wish to avoid needing replicating the full .com experience, so to specify labels, projects, or milestones, we will preserve the "navigate browser to compare view" functionality, and focus on text composition.
This will require building out UI in the GitHub panel and adding GraphQL API support to create pull requests.
UI/UX considerations include:
* Offer a pop-out editor to craft PR descriptions in a full pane, similar to the commit editor pop out.
* Allow the user to specify the merge target.
* Show a preview of the list of commits that would be introduced by PR.
##### Build stability
_Near-term goal:_ Fix that damn Travis hang documented in [#1119](https://github.com/atom/github/issues/1119). Resume the diagnosis work in [#1289](https://github.com/atom/github/pull/1289) and find a way to bring our build success rate back under control.
##### GPG and credential handler overhaul
_Near-term goals:_ Passphrase prompting from git credential helpers and GPG has been a significant pain point since public release; unsurprisingly, because those are the areas where we need to leverage binaries and configuration from the users' system if present.
* Implement a "remember me" checkbox backed by keytar. This is probably our top feature request. [#861](https://github.com/atom/github/issues/861)
_Longer-term goals:_ Finish the credential handler refactor begun in [#846](https://github.com/atom/github/pull/846) to handle GPG 1.x through 2.3 and include diagnostic logging and testing.
* Improve our handling of 2FA credentials. Ideally we could detect when a user has 2FA enabled and prompt for a one-time code. [#844](https://github.com/atom/github/issues/844)
## Looking farther ahead
In no particular order:
- Git Virtual File System support.
- Improved branch management. [#556](https://github.com/atom/github/issues/556)
- Introduce an overview dock item that summarizes and navigates to other functionality. [#1018](https://github.com/atom/github/issues/1018)
- Code review. [#269](https://github.com/atom/github/issues/269), [#268](https://github.com/atom/github/issues/268)
- `git log` pane.
- Merge or close pull requests.
- Browse and check out pull requests.
---
# Teletype
Main repository: [atom/teletype](http://github.com/atom/teletype) (Atom package)
## Roadmap
##### 1. Deliver a multi-file collaboration experience that meets 80% of the needs with 20% of the effort
- Ship RFC-001 (https://github.com/atom/teletype/issues/268)
##### 2. Streamline collaboration set-up
Near-term goal: Encourage more collaboration by reducing barriers to entry.
Longer-term goal: Provide the world's fastest transition from "I want to collaborate" to "I am collaborating." 🚀
- Publish RFC (including a request for review from GitHub's Community and Safety team)
- Host can share a URL for the portal, and guests can follow the URL to instantly join the portal (https://github.com/atom/teletype/issues/109)
- Quickly collaborate with coworkers and friends (https://github.com/atom/teletype/issues/213, https://github.com/atom/teletype/issues/284)
- You can view a list of past collaborators (i.e., a ["buddy list"](https://github.com/atom/teletype/issues/22) of sorts).
- You can choose any online person in the buddy list and invite them to join your portal. They get a notification (or similar) informing them of the invitation, and they can choose to join the portal or not.
- To prevent abuse/harassment, each time you join a portal via a URL or portal ID, Teletype adds the collaborators to your buddy list. You can directly invite anyone in your buddy list to join your portal, and anyone in your buddy list can invite you to a portal. You can remove anyone from your buddy list, at which point they can no longer _directly_ invite you to a portal.
##### 3. Nice bang-for-the-buck refinements
- Add a colored border around avatars that matches the cursor when that participant's tether is not retracted (https://github.com/atom/teletype/issues/338)
##### 4. Prioritized bugs
- Uncaught TypeError: Cannot match against 'undefined' or 'null' (https://github.com/atom/teletype/issues/233)
## Looking farther ahead
In no particular order:
- 🐛 Resolve or reduce impact of package initialization errors (https://github.com/atom/teletype/issues/266)
- 🐛 Surface uncaught errors in promises (https://github.com/atom/teletype/issues/298#issuecomment-355369327)
- ✨ Ensure remote buffers are updated when host renames files (https://github.com/atom/teletype/issues/147)
- 💖 In the buddy list, you can see which people are currently online (i.e., presence)
- 💖 Screen-sharing -- (We should prioritize screen-sharing above audio. We can keep using Slack/Skype/Zoom/Whatever for audio and use Atom for screen-sharing, whereas the opposite is not true; disabling audio on a Slack call would feel unintuitive.)
- 💖 Audio
---
# Tree-sitter
## Roadmap
TODO
## Looking farther ahead
TODO
---
# Xray
## Roadmap
TODO
## Looking farther ahead
TODO
- [ ] Implement Atom metrics dashboard that can be used to drive future decisions
- [ ] Determine what may be helpful to measure in the future building upon work [already in progress](http://blog.atom.io/2018/06/20/atom-metrics.html)

37
docs/rfcs/000-template.md Normal file
View File

@@ -0,0 +1,37 @@
# Feature title
## Status
Proposed
## Summary
One paragraph explanation of the feature.
## Motivation
Why are we doing this? What use cases does it support? What is the expected outcome?
## Explanation
Explain the proposal as if it was already implemented and you were describing it to an Atom user. That generally means:
- Introducing new named concepts.
- Explaining the feature largely in terms of examples.
- Explaining any changes to existing workflows.
## Drawbacks
Why should we *not* do this?
## Rationale and alternatives
- Why is this approach the best in the space of possible approaches?
- What other approaches have been considered and what is the rationale for not choosing them?
- What is the impact of not doing this?
## Unresolved questions
- What unresolved questions do you expect to resolve through the RFC process before this gets merged?
- What unresolved questions do you expect to resolve through the implementation of this feature before it is released in a new version of Atom?
- What related issues do you consider out of scope for this RFC that could be addressed in the future independently of the solution that comes out of this RFC?

View File

@@ -0,0 +1,105 @@
# Updatable Bundled Packages
## Status
Proposed
## Summary
This feature will enable an opt-in subset of bundled Atom packages to be updated with `apm` outside of the Atom release cycle. This will enable users to receive new functionality and bug fixes for some bundled packages as regularly as needed without waiting for them to be included in a new Atom release. This is especially important for packages like [GitHub](https://github.com/atom/github/) and [Teletype](https://github.com/atom/teletype/) which provide essential Atom functionality and could be improved independently of Atom.
## Motivation
Atom currently uses a monthly release cycle with staged Stable and Beta releases so that major issues get caught early in Beta before reaching the Stable release. Because Atom releases updates monthly, this means that a new feature merged into `master` right after a new Atom release could take one month to reach the next Beta and then another month to reach Stable.
Since a large part of Atom's built-in functionality is provided by bundled packages, it makes sense to allow some of those packages to be updated independently of Atom's monthly release cycle so that users can receive new features and fixes whenever they become available.
Bundled packages are treated differently than community packages that you can install using `apm`:
- You are not prompted to update them when new versions are released on `apm`
- `apm` will warn you at the command line when you try to install or update a bundled package
- If a user intentionally installs a bundled package from `apm` the [dalek package](https://github.com/atom/dalek/) will show a warning in the "deprecations" view asking the user to remove the offending package
Despite all this, if the user *does* manually install an update to a bundled package using `apm`, it will be loaded into the editor and updated dutifully as new releases occur. The only new functionality needed is to enable `apm` to check bundled packages for updates when those packages haven't yet been installed in the user's `~/.atom/packages` folder.
The primary use case for this improvement is enabling the GitHub package to ship improvements more frequently than Atom's release cycle since many of its improvements can be done without changes to Atom itself. If this approach is proven to work well for the GitHub package, we might also consider using it to ship Teletype as a bundled Atom package.
## Explanation
Any bundled Atom package can opt in to new updates released via `apm` by adding `"coreUpdatable": true` to its `package.json` file. This causes `apm` to consider it as part of the list of packages it checks for updates. If a community (non-bundled) package sets this field to `true` or `false` it will be ignored as it's only relevant to bundled packages.
Atom shows update notifications for Updatable bundled packages whenever they are available so long as those updates support the engine version of the current Atom build. Bundled package updates can also be found and installed in the Settings view's *Updates* tab.
The `dalek` package is aware of the new "Updatable" metadata and excludes updated bundled packages from its deprecation warnings.
### User Experience Examples
1. The user downloads and installs Atom 1.28.0 which includes GitHub package version 0.15.0. Two weeks later, GitHub package 0.16.0 is released with a few new features. The user is prompted to update to the new version and gets the new features even though Atom 1.29.0 hasn't been released yet.
2. The user downloads and installs Atom 1.28.0, including GitHub package 0.15.0, which was released two weeks prior. Since that release the GitHub package has been updated to version 0.15.1 on `apm`. When the user starts Atom for the first time they are prompted to update the GitHub package.
3. In the future, a user has an old install of Atom 1.28.0 and waits a long time between installing Atom updates. The GitHub package releases version 0.25.0 but the user is not prompted to install it because the GitHub package has set `engines` in `package.json` to restrict to Atom 1.32.0 and above.
### Rules for Updatable Bundled Packages
Any package that opts into this behavior must adhere to these rules:
1. **Each release must ensure that its `engines` field in `package.json` reflects the necessary Atom version for the Atom, Electron, and Node.js APIs used in the package**. This field defines the range of Atom versions in which the package is expected to work. The field should always be set to the lowest possible Atom version that the package supports.
2. **Any new update to a bundled package *must* support current Stable *and* Beta releases**. This enables the user to upgrade the package and continue to use it in side-by-side Stable and Beta installs on their machine. If a package wants to use API features of a newer version of Atom while still supporting older Atom versions, it must do so in a way that is aware of the user's version and adjust itself accordingly.
3. **Atom's `package.json` *must* stay up to date with the latest supported version of the package** in the `master` and Beta release branches. This ensures that the user always gets the latest version of the package in a new release and also benefits from its inclusion in Atom's snapshot.
For rule #3, it will be important to have automation to ensure that current Beta release and `master` are kept up to date with the latest compatible version of any updatable bundled package as it will be difficult for maintainers to do that manually. This could be accomplished by a nightly CI run which is focused explicitly on bumping package dependencies in this manner.
## Drawbacks
### Possible API incompatibility
The primary drawback of this approach is that Updatable bundled packages might exhibit problems on older Atom versions due to missing or changed APIs in Atom, Electron, or Node.js. The solution for these packages is to keep their `engines` field updated appropriately, but there's still a chance that some updates will slip through without the necessary engine version changes. If this does occur and users are affected by it, the solution is to publish a new update which rolls back the package to the functionality of its previous release and then publish another new update with the new functionality restored and the proper `engines` version in place.
### Increased Atom startup time
Another major drawback is that the snapshotted code for the bundled package will no longer be used since a newer version has been installed. This updated version of the package cannot be easily added back into Atom's snapshot so it could cause a noticable drag on Atom's startup time. Some quick measurements with Timecop show a 10x increase in GitHub package load time for bundled (snapshot) vs updated (non-snapshot) package code:
| GitHub Package Code | Load Time |
|----------------------------------|-----------|
| **Bundled** | 52 ms |
| **Updated (first load)** | 5026 ms |
| **Updated (subsequent loads)** | 591 ms |
There was no measurable effect on shell or window startup time, only package load time. It seems that the transpilation phase of the first load of the package incurs a 100x increase in load time. Pre-transpilation of the package code (either when shipped or when installed using `apm`) will be useful in mitigating this cost. Further investigation into snapshotting package code will be needed to understand if the load time increase can be mitigated.
There is a possibility that the GitHub package could load parts of its codebase on demand to mitigate the increased startup time when not loaded as part of Atom's snapshot. This approach is discussed in more detail at [atom/github#1522](https://github.com/atom/github/issues/1522).
### Incompatibility across Atom release channels
One other possible drawback is that an updated version of a bundled package might not be compatible across two different Atom channels. For example, if the user installs a new update to a bundled package that only supports the current Atom Beta release or higher, the user will no longer have access to that package if they open Atom Stable. However, this drawback is no different than what the user would face today installing a community package under the same circumstances, so this could be considered a general problem in the Atom package ecosystem.
Finally, one risk of this approach is that the Atom team forgets to update a bundled package to its latest appropriate version on `apm` just before a new release. If this happens, the user will install a new Atom update and then be prompted to update a package that should have been snapshotted and shipped in-box. To avoid this problem we could add some build automation that checks for the latest version of a bundled package to see if the current Atom build would be supported by it.
## Rationale and alternatives
This is the best approach for updating bundled packages because it allows those packages to take control of their own release cycle so long as they manage their Atom engine version correctly. It also does so in a way that allows us to decide which packages can be updated independently, reducing the likelihood of problems for users.
The primary alternative to this approach is to speed up the Atom release cycle so that bundled Atom package updates will reach users more frequently. This approach will be investigated independently of this RFC as it may still be valuable even with Updatable bundled packages.
## Unresolved questions
> - What unresolved questions do you expect to resolve through the RFC process before this gets merged?
Is it enough to just depend on the `engines` field of `package.json` to protect users from installing a package update that doesn't work with their version of Atom?
> - What unresolved questions do you expect to resolve through the implementation of this feature before it is released in a new version of Atom?
Is there any optimization we can use to reduce the performance hit of loading updated bundled packages?
> - What related issues do you consider out of scope for this RFC that could be addressed in the future independently of the solution that comes out of this RFC?
One issue that's out of scope for this RFC is how we ship new features and fixes to the core components of Atom (not its bundled packages) more frequently. There are two options we can investigate to accomplish this:
- **Ship Atom updates more frequently, possibly every two weeks**
- **Introduce a channel for nightly builds which surface the latest changes every day**
Both of these possibilities will be covered in future RFCs as they could be implemented independently of the feature described in this RFC.

View File

@@ -0,0 +1,57 @@
# Atom Nightly Releases
## Status
Implemented in PR [#17538](https://github.com/atom/atom/pull/17538)
## Summary
This RFC proposes that Atom add a third official release channel which delivers new builds of Atom nightly from the `master` branch. Nightly releases will allow new improvements to reach users long before a new Stable or Beta release is shipped. This effort will also give us the opportunity to experiment with new release automation strategies that could eventually be used to speed up the Stable and Beta release cadence.
## Motivation
Atom currently uses a monthly release cycle with staged Stable and Beta releases so that major issues get caught early in Beta before reaching the Stable release. Because Atom releases updates monthly, this means that a new feature merged into `master` right after a new Atom release could take one month to reach the next Beta and then another month to reach Stable.
This release process works well for delivering stable improvements to users on a regular basis but it results in friction for users who want to try out the latest Atom improvements and provide feedback. If we deliver a nightly release channel, it will be possible to deliver new features and bug fixes on a regular basis and get valuable feedback to guide our work.
Today, a bleeding-edge user must manually pull Atom's `master` branch and compile their own build. There is a source of `dev` builds from `master` across our CI services but those aren't made available to users as an official distribution.
## Explanation
A user who wants to use the latest improvements to Atom each day can go to atom.io, download the Atom Nightly release, and install it on their machine. This release can be installed alongside Atom Stable and Atom Beta.
Each night when there are new commits to Atom's `master` branch, a scheduled CI build creates a new Atom Nightly release with packages for Windows, macOS, and Linux. These packages are automatically uploaded to a new GitHub release on the `atom/atom-nightly-releases` repository using a monotonically-increasing nightly version based off of the version in `master` (e.g. `v1.29.0-nightly1`).
Every 4 hours, an Atom Nightly release installed on Windows or macOS checks for a new update by consulting Electron's [update.electronjs.org](update-electron) service. If a new update is available, it is downloaded in the background and the user is notified to restart Atom once it's complete. This update flow is the same as what users experience in Atom Stable or Beta releases but updates occur more frequently.
Linux users must manually download nightly releases for now as there isn't an easy way to automatically install new updates across the various Linux distributions. We may consider providing updatable [AppImage](http://appimage.org/) packages in the future; this will be proposed in a separate RFC.
## Drawbacks
There isn't a major downside to this effort since it would run in parallel to the existing Atom release process without affecting it.
## Rationale and alternatives
This is a useful approach because it allows us to achieve a much more rapid feedback loop with highly engaged users to ensure that Atom is improving regularly. It's the best approach because it allows us to get rapid feedback without sacrificing the stability of the Stable and Beta releases.
Another option is to speed up Atom's release cadence to ship Stable and Beta every two weeks (or more regularly). This approach could shorten our feedback loop but at the expense of greater instability since new improvements would not have as much time to be polished before release.
The impact of not taking this approach is that we continue to have to wait 1-2 months to get feedback from users about new features or bugs in Stable and Beta releases.
## Unresolved questions
- **What should we call this release channel?**
Some ideas:
- Atom Nightly
- Atom Reactor
- Atom Dev - Currently the name of dev builds but it might make sense to leave that for "normal" builds from `master`
According to a [Twitter poll](https://twitter.com/daviwil/status/1006545552987701248) with about 1,600 responses, 50% of the voters chose "Atom Nightly". The final name will be determined before launch.
- **Will Electron's new autoUpdate service work for all Atom releases?**
One outcome of this effort is to use the new [update.electronjs.org](update-electron) service for Atom's update checks so that we can deprecate on our own custom update service. Building the Nightly channel on this service will allow us to evaluate it to see if it meets the needs of the Stable and Beta channels.
[update-electron]: https://github.com/electron/update.electronjs.org

View File

@@ -0,0 +1,345 @@
# Consolidate Core Atom Packages
## Status
Accepted
## Summary
Atom's official distribution is comprised of 92 core packages which provide its built-in functionality. These packages currently live in their own independent repositories in the Atom organization, all with their own separate issues, PRs, releases, and CI configurations. This RFC proposes that by consolidating most, if not all, of these core packages back into the `atom/atom` repo, we will see the following benefits:
- Less confusion for new contributors
- Simpler core package contribution experience
- Greatly reduced burden for maintainers
## Motivation
Let's cover each of the bullet points mentioned above:
### Less confusion for contributors
Imagine that a new contributor wants to add a small new feature to the `tree-view` package. The first place they are likely to look is the `atom/atom` repository. Scanning through the folders will lead to a dead end as nothing that looks like `tree-view` code can be found. They might take one of the following steps next:
- By reading README.md, maybe they will decide to click the link to the Atom Flight Manual and _maybe_ find the [Contributing to Official Atom Packages](https://flight-manual.atom.io/hacking-atom/sections/contributing-to-official-atom-packages/) page there
- They could read the CONTRIBUTING.md file which [has a section](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#atom-and-packages) that explains where to find the repos for core packages and how to contribute, but we don't really have a clear pointer to that in our README.md
- If they don't happen to find that page, they might use Google to search for "atom tree view" and find the atom/tree-view repo and _maybe_ read the CONTRIBUTING.md file which sends them to Atom's overall contribution documentation
- They might go to the Atom Forum or Slack community to ask how to contribute to a particular part of Atom and *hopefully* get a helpful response that points them in the right direction
Having all of the core Atom packages represented in a top-level `packages` folder, even if they all don't actually live in the repo, will go a long way to making the core package code more discoverable.
### Simpler core package contribution experience
Separating core Atom features out into individual repositories and delivering them to Atom builds via `apm` is a great idea in theory because it validates the Atom package ecosystem and gives developers many examples of how to develop an Atom package. It also gives Atom developers real-world experience working with Atom's APIs so that we ensure community package authors have the same hackability that Atom developers enjoy.
On the other hand, having these packages live in separate repositories and released "independently" introduces a great deal of overhead when adding new features. Here is a comparison of the current package development workflow contrasted to what we could achieve with consolidated packages:
#### Current Package Development Workflow
For example, to add a single feature to the `tree-view` package, one must:
1. Fork and clone the `tree-view` repository to their computer (making sure to pull the commit relevant to the version of Atom they are working with)
1. Run `apm install` and `apm link` inside of the repo folder
1. Make their desired changes to the code
1. Open a PR to the `tree-view` repo and wait for CI to pass and a maintainer to review it
1. Work with maintainers to get the PR approved and merged
After this is finished, an Atom maintainer must take the following steps:
1. Clone the `tree-view` repo
2. Run `apm publish` to publish a new release of the package
3. Edit `package.json` in the Atom repo to reflect the new version of `tree-view`
4. Commit and push the changes to the relevant branch where the change belongs (`master` or `1.nn-releases`)
#### Simplified Package Development
If we were to move `tree-view` (or any other core Atom package) back into `atom/atom`, the development workflow would look more like this:
1. Fork and clone `atom/atom` and switch to a release branch if necessary
1. Build Atom and launch it in dev mode
1. Make desired changes to the code in `packages/tree-view`
1. Open a PR on `atom/atom` and wait for CI to pass and a maintainer to review it
1. Work with maintainers to get the PR approved and merged
At this point, the change is merged into Atom and ready for inclusion in the next release.
### Greatly reduced burden for maintainers
Since packages all have their own repositories, this means that we have to watch 91 different repos for issues and pull requests. This also means that we have to redirect issues filed on `atom/atom` to the appropriate repository when a user doesn't know where it belongs. Even more importantly, there's not an easy way to prioritize and track issues across the Atom organization without using GitHub Projects.
Also, as mentioned above, there's the added duty of doing the package "version dance" when we merge any new PRs to a package repository: publish the package update, update `package.json` in Atom. It's very easy to forget to do this and not have community contributions included in the next Atom release!
The more core packages live in `atom/atom`, the less work Atom maintainers have to do overall.
## Explanation
Many of Atom's core packages now live in the core `atom/atom` repository. To the Atom user, this change will be imperceptible as these packages still show up in the list of Core Packages in the Settings View. Users can still optionally disable these packages.
For maintainers and contributors, there will be less juggling of repositories and no more publishing of updates to these packages with `apm`:
Contributors now clone and build `atom/atom` to work on improvements to core packages. They will no longer have to use `apm link` in dev mode to test changes they make to packages in the repo's `packages` folder. Core packages that aren't consolidated still have folders under `packages` with README.md files that point to the home repository for that package.
When a contributor sends a PR to `atom/atom` that only affects files in a folder under `packages`, only the specs for the relevant package folders will be executed using Atom's CI scripts. This means that a full Atom build will not be required when no Atom Core code is changed in a PR. Package specs are also now run against all 3 OSes on Atom `master` and release builds.
Atom maintainers no longer have to publish new versions to consolidated core packages and then edit `package.json` to bump the package version in a particular Atom release branch (Stable, Beta, or `master`). When a PR against a consolidated core package in `atom/atom` is merged, no version number change is required and the changes will immediately be a part of the next release from that branch.
## Drawbacks
One possible drawback of this approach is that there might be some initial confusion where core Atom packages live, especially if some are consolidated into `atom/atom` and others still live in their own repositories. We will manage this confusion by doing the following:
- Include a `README.md` file in the `packages` folder which lists core packages that are not consolidated in the Atom repo. This will enable users to find the home repositories of those packages.
- Archive the repositories for consolidated core packages, but only after migrating existing issues, merging or closing existing PRs, and updating the README.md to point to the new home of the package code.
Also, contributors will now have to fork, clone, and build `atom/atom` to contribute to core packages where they would previously just need to clone the package repository. This might put added burden on them such as installing necessary build dependencies on their machine that they wouldn't otherwise need. It is very likely we could simplify this process for them, though.
One final drawback is that it will now be harder to have single-package maintainers. We currently have 7 core packages where there is a maintainer who isn't a part of the core Atom maintainers team. These maintainers generally are able to merge community PRs and make commits to those packages with their own judgement. If we get rid of individual package repositories, do we now make those maintainers full Atom maintainers?
## Rationale and alternatives
The Motivation section explains most of the rationale, so this section will focus on the process of consolidating packages back into `atom/atom`. The set of packages we've chosen to consolidate were evaluated based on a few factors:
- Number of open issues and PRs (exclude any with > 10 open PRs)
- Time since last update (longer duration since last update is prioritized)
- Number of package-only maintainers on the repo (exclude any with package maintainers for now)
Using this criteria, all 91 packages have been evaluated and categorized to determine whether they are good candidates for consolidation:
#### Initial Consolidation Candidates
| Package | Open Issues | Open PRs | Outside Maintainers | Last Updated |
|---------|-------------|----------|---------------------| -------------|
| **[about]** | 2 | 0 | 0 | 7/11/18 |
| **[archive-view]** | 10 | 0 | 0 | 6/3/18 |
| **[atom-dark-syntax]** | 5 | 0 | 0 | 12/6/17 |
| **[atom-dark-ui]** | 1 | 2 | 0 | 2/13/18 |
| **[atom-light-syntax]** | 1 | 0 | 0 | 10/17/16 |
| **[atom-light-ui]** | 1 | 0 | 0 | 2/13/18 |
| **[autoflow]** | 17 | 4 | 0 | 4/17/18 |
| **[autosave]** | 13 | 0 | 0 | 9/16/17 |
| **[background-tips]** | 3 | 2 | 0 | 2/17/18 |
| **[base16-tomorrow-dark-theme]** | 5 | 0 | 0 | 1/10/17 |
| **[base16-tomorrow-light-theme]** | 1 | 0 | 0 | 1/10/17 |
| **[bookmarks]** | 19 | 4 | 0 | 12/10/17 |
| **[bracket-matcher]** | 74 | 8 | 0 | 3/20/18 |
| **[command-palette]** | 18 | 6 | 0 | 2/27/18 |
| **[dalek]** | 2 | 0 | 0 | 2/28/18 |
| **[deprecation-cop]** | 5 | 0 | 0 | 9/7/17 |
| **[dev-live-reload]** | 4 | 0 | 0 | 11/14/17 |
| **[encoding-selector]** | 11 | 2 | 0 | 4/19/18 |
| **[exception-reporting]** | 5 | 0 | 0 | 2/6/18 |
| **[git-diff]** | 38 | 1 | 0 | 1/18/18 |
| **[go-to-line]** | 5 | 2 | 0 | 1/25/18 |
| **[grammar-selector]** | 3 | 1 | 0 | 4/12/18 |
| **[image-view]** | 4 | 4 | 0 | 7/9/18 |
| **[incompatible-packages]** | 1 | 0 | 0 | 4/25/17 |
| **[keybinding-resolver]** | 11 | 3 | 0 | 7/6/18 |
| **[language-clojure]** | 13 | 3 | 0 | 1/26/18 |
| **[language-coffee-script]** | 9 | 2 | 0 | 11/1/17 |
| **[language-csharp]** | 1 | 1 | 0 | 4/27/18 |
| **[language-css]** | 6 | 7 | 0 | 6/11/18 |
| **[language-gfm]** | 52 | 9 | 0 | 6/15/18 |
| **[language-git]** | 4 | 2 | 0 | 4/18/17 |
| **[language-html]** | 11 | 4 | 0 | 7/5/18 |
| **[language-hyperlink]** | 2 | 3 | 0 | 10/25/17 |
| **[language-json]** | 1 | 0 | 0 | 5/11/18 |
| **[language-less]** | 5 | 1 | 0 | 6/11/18 |
| **[language-make]** | 7 | 3 | 0 | 11/26/16 |
| **[language-mustache]** | 0 | 0 | 0 | 2/5/18 |
| **[language-objective-c]** | 2 | 0 | 0 | 12/1/15 |
| **[language-php]** | 25 | 7 | 0 | 6/11/18 |
| **[language-property-list]** | 1 | 0 | 0 | 3/11/17 |
| **[language-python]** | 33 | 4 | 0 | 6/18/18 |
| **[language-ruby]** | 38 | 10 | 0 | 10/25/17 |
| **[language-ruby-on-rails]** | 9 | 6 | 0 | 12/7/17 |
| **[language-sass]** | 12 | 5 | 0 | 5/2/18 |
| **[language-shellscript]** | 12 | 3 | 0 | 6/18/18 |
| **[language-source]** | 0 | 0 | 0 | 1/6/15 |
| **[language-sql]** | 6 | 4 | 0 | 1/26/18 |
| **[language-text]** | 1 | 0 | 0 | 3/9/18 |
| **[language-todo]** | 10 | 6 | 0 | 1/26/18 |
| **[language-toml]** | 1 | 0 | 0 | 1/6/18 |
| **[language-typescript]** | 6 | 0 | 0 | 6/18/18 |
| **[language-xml]** | 2 | 1 | 0 | 6/12/17 |
| **[language-yaml]** | 8 | 2 | 0 | 3/9/18 |
| **[line-ending-selector]** | 10 | 0 | 0 | 5/18/18 |
| **[link]** | 0 | 1 | 0 | 11/14/17 |
| **[metrics]** | 1 | 2 | 0 | 7/5/18 |
| **[notifications]** | 29 | 8 | 0 | 3/22/18 |
| **[one-dark-syntax]** | 4 | 0 | 0 | 5/27/18 |
| **[one-dark-ui]** | 13 | 1 | 0 | 5/1/18 |
| **[one-light-syntax]** | 2 | 1 | 0 | 5/27/18 |
| **[one-light-ui]** | 2 | 0 | 0 | 5/1/18 |
| **[open-on-github]** | 8 | 3 | 0 | 11/21/17 |
| **[package-generator]** | 10 | 2 | 0 | 11/16/17 |
| **[status-bar]** | 25 | 3 | 0 | 11/6/17 |
| **[styleguide]** | 12 | 2 | 0 | 4/12/18 |
| **[tabs]** | 66 | 7 | 0 | 5/13/18 |
| **[timecop]** | 5 | 0 | 0 | 11/4/17 |
| **[update-package-dependencies]** | 0 | 0 | 0 | 12/10/17 |
| **[welcome]** | 0 | 0 | 0 | 11/21/17 |
| **[whitespace]** | 31 | 6 | 0 | 5/30/18 |
| **[wrap-guide]** | 3 | 4 | 0 | 11/27/17 |
#### Packages to be Consolidated Later
The following packages will not be consolidated until the stated reasons can be resolved or we decide on a consolidation strategy for them:
| Package | Open Issues | Open PRs | Outside Maintainers | Last Updated | Reason |
|---------|-------------|----------|---------------------|--------------|-------|
| **[find-and-replace]** | 219 | 17 | 0 | 6/4/18 | Too many open PRs |
| **[fuzzy-finder]** | 89 | 22 | 0 | 5/17/18 | Too many open PRs |
| **[github]** | | | | | Independent project |
| **[language-c]** | 53 | 15 | 0 | 7/10/18 | Too many open PRs |
| **[language-go]** | 12 | 2 | **1** | 6/18/18 | Package maintainer, possibly inactive? |
| **[language-java]** | 8 | 2 | **1** | 6/11/18 | Package maintainer |
| **[language-javascript]** | 66 | 12 | 0 | 7/6/18 | Too many open PRs |
| **[language-perl]** | 17 | 1 | **1** | 10/30/17 | Package maintainer, possibly inactive? |
| **[markdown-preview]** | 139 | 12 | 0 | 1/8/18 | Too many open PRs |
| **[settings-view]** | 137 | 18 | 0 | 5/17/18 | Too many open PRs |
| **[snippets]** | 57 | 4 | **1** | 4/17/18 | Package maintainer |
| **[solarized-dark-syntax]** | 8 | 3 | **1** | 5/27/18 | Package maintainer |
| **[solarized-light-syntax]** | 2 | 3 | **1** | 5/27/18 | Package maintainer |
| **[spell-check]** | 68 | 14 | **1** | 5/25/18 | Too many open PRs, package maintainer |
| **[symbols-view]** | 86 | 13 | 0 | 12/10/17 | Too many open PRs |
| **[tree-view]** | 210 | 36 | 0 | 3/21/18 | Too many open PRs |
#### Packages to Never Consolidate
These packages will not be consolidated because they would inhibit contributions from our friends in the Nuclide team at Facebook:
- **[autocomplete-atom-api]**
- **[autocomplete-css]**
- **[autocomplete-html]**
- **[autocomplete-plus]**
- **[autocomplete-snippets]**
### Consolidation Process
To consolidate a single core package repository back into `atom/atom`, the following steps will be taken:
1. All open pull requests on the package's repository must either be closed or merged before consolidation can proceed
1. The package repository's code in `master` will be copied over to Atom's `packages` folder in a subfolder bearing that package's name.
1. Atom's `package.json` file will be updated to change the package's `packageDependencies` entry to reference its local path with the following syntax: `"tree-view": "file:./packages/tree-view"`
1. A test build will be created locally to manually verify that the package loads and works correctly at first glance
1. The package specs for the newly-consolidated package will be run against the local Atom build
1. A PR will be sent to `atom/atom` to verify that CI passes with the introduction of the consolidated package
1. Once CI is clean and the PR is approved, the PR will be merged
1. The package's original repository will have all of its existing issues moved over to `atom/atom` using a bulk issue mover tool, assigning a label to those issues relative to the package name, like `packages/tree-view`
1. The package's original repository will have its README.md updated to point contributors to the code's new home in `atom/atom`
1. The package's original repository will now be archived on GitHub
### Alternative Approaches
One alternative approach would be to break this core Atom functionality out of packages and put it directly in the Atom codebase without treating them as packages. This would simplify the development process even further but with the following drawbacks:
- The Atom team would have less regular exposure to Atom package development
- Users would no longer be able to disable core packages to replace their behavior with other packages (different tree views, etc)
## Unresolved questions
- Is there a good reason to not move the `language-*` packages into `atom/atom`?
One concern here is that there exist projects which depend directly on these repositories for the TextMate syntax grammars they contain. Moving the code into `atom/atom` would require that we notify the consumers of the grammars so that they can redirect their requests to the `atom/atom` repo.
- Should we use `git subtree` to migrate the entire commit history of these packages over or just depend on the history from a package's original repository?
For now, we won't use `git subtree` due to the possibility that bringing over thousands of commits could cause unknown problems in the Atom repo. We may try this for newly consolidated packages in the future if we decide that not having the package commit history is a sufficient impediment to problem investigations.
- What are the criteria we might use to eventually decide to move larger packages like `tree-view`, `settings-view`, and `find-and-replace` back into `atom/atom`?
- Will we be losing any useful data about these packages if we don't have standalone repositories anymore?
- Should we use this as an opportunity to remove any unnecessary packages from the core Atom distribution?
[about]: https://github.com/atom/about
[archive-view]: https://github.com/atom/archive-view
[atom-dark-syntax]: https://github.com/atom/atom-dark-syntax
[atom-dark-ui]: https://github.com/atom/atom-dark-ui
[atom-light-syntax]: https://github.com/atom/atom-light-syntax
[atom-light-ui]: https://github.com/atom/atom-light-ui
[autocomplete-atom-api]: https://github.com/atom/autocomplete-atom-api
[autocomplete-css]: https://github.com/atom/autocomplete-css
[autocomplete-html]: https://github.com/atom/autocomplete-html
[autocomplete-plus]: https://github.com/atom/autocomplete-plus
[autocomplete-snippets]: https://github.com/atom/autocomplete-snippets
[autoflow]: https://github.com/atom/autoflow
[autosave]: https://github.com/atom/autosave
[background-tips]: https://github.com/atom/background-tips
[base16-tomorrow-dark-theme]: https://github.com/atom/base16-tomorrow-dark-theme
[base16-tomorrow-light-theme]: https://github.com/atom/base16-tomorrow-light-theme
[bookmarks]: https://github.com/atom/bookmarks
[bracket-matcher]: https://github.com/atom/bracket-matcher
[command-palette]: https://github.com/atom/command-palette
[dalek]: https://github.com/atom/dalek
[deprecation-cop]: https://github.com/atom/deprecation-cop
[dev-live-reload]: https://github.com/atom/dev-live-reload
[encoding-selector]: https://github.com/atom/encoding-selector
[exception-reporting]: https://github.com/atom/exception-reporting
[find-and-replace]: https://github.com/atom/find-and-replace
[fuzzy-finder]: https://github.com/atom/fuzzy-finder
[git-diff]: https://github.com/atom/git-diff
[github]: https://github.com/atom/github
[go-to-line]: https://github.com/atom/go-to-line
[grammar-selector]: https://github.com/atom/grammar-selector
[image-view]: https://github.com/atom/image-view
[incompatible-packages]: https://github.com/atom/incompatible-packages
[keybinding-resolver]: https://github.com/atom/keybinding-resolver
[language-c]: https://github.com/atom/language-c
[language-clojure]: https://github.com/atom/language-clojure
[language-coffee-script]: https://github.com/atom/language-coffee-script
[language-csharp]: https://github.com/atom/language-csharp
[language-css]: https://github.com/atom/language-css
[language-gfm]: https://github.com/atom/language-gfm
[language-git]: https://github.com/atom/language-git
[language-go]: https://github.com/atom/language-go
[language-html]: https://github.com/atom/language-html
[language-hyperlink]: https://github.com/atom/language-hyperlink
[language-java]: https://github.com/atom/language-java
[language-javascript]: https://github.com/atom/language-javascript
[language-json]: https://github.com/atom/language-json
[language-less]: https://github.com/atom/language-less
[language-make]: https://github.com/atom/language-make
[language-mustache]: https://github.com/atom/language-mustache
[language-objective-c]: https://github.com/atom/language-objective-c
[language-perl]: https://github.com/atom/language-perl
[language-php]: https://github.com/atom/language-php
[language-property-list]: https://github.com/atom/language-property-list
[language-python]: https://github.com/atom/language-python
[language-ruby]: https://github.com/atom/language-ruby
[language-ruby-on-rails]: https://github.com/atom/language-ruby-on-rails
[language-sass]: https://github.com/atom/language-sass
[language-shellscript]: https://github.com/atom/language-shellscript
[language-source]: https://github.com/atom/language-source
[language-sql]: https://github.com/atom/language-sql
[language-text]: https://github.com/atom/language-text
[language-todo]: https://github.com/atom/language-todo
[language-toml]: https://github.com/atom/language-toml
[language-typescript]: https://github.com/atom/language-typescript
[language-xml]: https://github.com/atom/language-xml
[language-yaml]: https://github.com/atom/language-yaml
[line-ending-selector]: https://github.com/atom/line-ending-selector
[link]: https://github.com/atom/link
[markdown-preview]: https://github.com/atom/markdown-preview
[metrics]: https://github.com/atom/metrics
[notifications]: https://github.com/atom/notifications
[one-dark-syntax]: https://github.com/atom/one-dark-syntax
[one-dark-ui]: https://github.com/atom/one-dark-ui
[one-light-syntax]: https://github.com/atom/one-light-syntax
[one-light-ui]: https://github.com/atom/one-light-ui
[open-on-github]: https://github.com/atom/open-on-github
[package-generator]: https://github.com/atom/package-generator
[settings-view]: https://github.com/atom/settings-view
[snippets]: https://github.com/atom/snippets
[solarized-dark-syntax]: https://github.com/atom/solarized-dark-syntax
[solarized-light-syntax]: https://github.com/atom/solarized-light-syntax
[spell-check]: https://github.com/atom/spell-check
[status-bar]: https://github.com/atom/status-bar
[styleguide]: https://github.com/atom/styleguide
[symbols-view]: https://github.com/atom/symbols-view
[tabs]: https://github.com/atom/tabs
[timecop]: https://github.com/atom/timecop
[tree-view]: https://github.com/atom/tree-view
[update-package-dependencies]: https://github.com/atom/update-package-dependencies
[welcome]: https://github.com/atom/welcome
[whitespace]: https://github.com/atom/whitespace
[wrap-guide]: https://github.com/atom/wrap-guide

View File

@@ -79,8 +79,8 @@
'ctrl-shift-tab ^ctrl': 'pane:move-active-item-to-top-of-stack'
'cmd-=': 'window:increase-font-size'
'cmd-+': 'window:increase-font-size'
'cmd--': 'window:decrease-font-size'
'cmd-_': 'window:decrease-font-size'
'cmd--': 'window:decrease-font-size'
'cmd-0': 'window:reset-font-size'
'cmd-k up': 'pane:split-up-and-copy-active-item' # Atom Specific

5996
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "1.26.0-dev",
"version": "1.32.0-dev",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/main-process/main.js",
"repository": {
@@ -12,51 +12,128 @@
"url": "https://github.com/atom/atom/issues"
},
"license": "MIT",
"electronVersion": "1.7.11",
"electronVersion": "2.0.7",
"dependencies": {
"@atom/nsfw": "^1.0.18",
"@atom/watcher": "1.0.3",
"@atom/source-map-support": "^0.3.4",
"@atom/watcher": "1.0.8",
"about": "file:packages/about",
"archive-view": "https://www.atom.io/api/packages/archive-view/versions/0.65.1/tarball",
"async": "0.2.6",
"atom-dark-syntax": "https://www.atom.io/api/packages/atom-dark-syntax/versions/0.29.1/tarball",
"atom-dark-ui": "https://www.atom.io/api/packages/atom-dark-ui/versions/0.53.3/tarball",
"atom-keymap": "8.2.10",
"atom-select-list": "^0.7.0",
"atom-light-syntax": "https://www.atom.io/api/packages/atom-light-syntax/versions/0.29.1/tarball",
"atom-light-ui": "https://www.atom.io/api/packages/atom-light-ui/versions/0.46.3/tarball",
"atom-select-list": "^0.7.2",
"atom-ui": "0.4.1",
"autocomplete-atom-api": "https://www.atom.io/api/packages/autocomplete-atom-api/versions/0.10.7/tarball",
"autocomplete-css": "https://www.atom.io/api/packages/autocomplete-css/versions/0.17.5/tarball",
"autocomplete-html": "https://www.atom.io/api/packages/autocomplete-html/versions/0.8.5/tarball",
"autocomplete-plus": "https://www.atom.io/api/packages/autocomplete-plus/versions/2.41.0/tarball",
"autocomplete-snippets": "https://www.atom.io/api/packages/autocomplete-snippets/versions/1.12.0/tarball",
"autoflow": "https://www.atom.io/api/packages/autoflow/versions/0.29.4/tarball",
"autosave": "https://www.atom.io/api/packages/autosave/versions/0.24.6/tarball",
"babel-core": "5.8.38",
"background-tips": "https://www.atom.io/api/packages/background-tips/versions/0.28.0/tarball",
"base16-tomorrow-dark-theme": "https://www.atom.io/api/packages/base16-tomorrow-dark-theme/versions/1.6.0/tarball",
"base16-tomorrow-light-theme": "https://www.atom.io/api/packages/base16-tomorrow-light-theme/versions/1.6.0/tarball",
"bookmarks": "https://www.atom.io/api/packages/bookmarks/versions/0.45.1/tarball",
"bracket-matcher": "https://www.atom.io/api/packages/bracket-matcher/versions/0.89.2/tarball",
"cached-run-in-this-context": "0.4.1",
"chai": "3.5.0",
"chart.js": "^2.3.0",
"clear-cut": "^2.0.2",
"coffee-script": "1.12.7",
"color": "^0.7.3",
"command-palette": "https://www.atom.io/api/packages/command-palette/versions/0.43.5/tarball",
"dalek": "https://www.atom.io/api/packages/dalek/versions/0.2.2/tarball",
"dedent": "^0.7.0",
"deprecation-cop": "https://www.atom.io/api/packages/deprecation-cop/versions/0.56.9/tarball",
"dev-live-reload": "https://www.atom.io/api/packages/dev-live-reload/versions/0.48.1/tarball",
"devtron": "1.3.0",
"encoding-selector": "https://www.atom.io/api/packages/encoding-selector/versions/0.23.9/tarball",
"etch": "^0.12.6",
"event-kit": "^2.4.0",
"event-kit": "^2.5.0",
"exception-reporting": "https://www.atom.io/api/packages/exception-reporting/versions/0.43.1/tarball",
"find-and-replace": "https://www.atom.io/api/packages/find-and-replace/versions/0.215.12/tarball",
"find-parent-dir": "^0.3.0",
"first-mate": "7.1.0",
"focus-trap": "^2.3.0",
"first-mate": "7.1.1",
"focus-trap": "2.4.5",
"fs-admin": "^0.1.6",
"fs-plus": "^3.0.1",
"fstream": "0.1.24",
"fuzzaldrin": "^2.1",
"git-utils": "5.3.1",
"fuzzy-finder": "https://www.atom.io/api/packages/fuzzy-finder/versions/1.8.2/tarball",
"git-diff": "https://www.atom.io/api/packages/git-diff/versions/1.3.9/tarball",
"git-utils": "5.2.1",
"github": "https://www.atom.io/api/packages/github/versions/0.19.0/tarball",
"glob": "^7.1.1",
"go-to-line": "https://www.atom.io/api/packages/go-to-line/versions/0.33.0/tarball",
"grammar-selector": "https://www.atom.io/api/packages/grammar-selector/versions/0.50.1/tarball",
"grim": "1.5.0",
"image-view": "https://www.atom.io/api/packages/image-view/versions/0.63.1/tarball",
"incompatible-packages": "https://www.atom.io/api/packages/incompatible-packages/versions/0.27.3/tarball",
"jasmine-json": "~0.0",
"jasmine-reporters": "1.1.0",
"jasmine-tagged": "^1.1.4",
"key-path-helpers": "^0.4.0",
"keybinding-resolver": "https://www.atom.io/api/packages/keybinding-resolver/versions/0.38.2/tarball",
"language-c": "https://www.atom.io/api/packages/language-c/versions/0.60.4/tarball",
"language-clojure": "https://www.atom.io/api/packages/language-clojure/versions/0.22.7/tarball",
"language-coffee-script": "https://www.atom.io/api/packages/language-coffee-script/versions/0.49.3/tarball",
"language-csharp": "https://www.atom.io/api/packages/language-csharp/versions/1.1.0/tarball",
"language-css": "https://www.atom.io/api/packages/language-css/versions/0.42.11/tarball",
"language-gfm": "https://www.atom.io/api/packages/language-gfm/versions/0.90.5/tarball",
"language-git": "https://www.atom.io/api/packages/language-git/versions/0.19.1/tarball",
"language-go": "https://www.atom.io/api/packages/language-go/versions/0.46.2/tarball",
"language-html": "https://www.atom.io/api/packages/language-html/versions/0.51.5/tarball",
"language-hyperlink": "https://www.atom.io/api/packages/language-hyperlink/versions/0.16.3/tarball",
"language-java": "https://www.atom.io/api/packages/language-java/versions/0.30.0/tarball",
"language-javascript": "https://www.atom.io/api/packages/language-javascript/versions/0.129.9/tarball",
"language-json": "https://www.atom.io/api/packages/language-json/versions/0.19.2/tarball",
"language-less": "https://www.atom.io/api/packages/language-less/versions/0.34.2/tarball",
"language-make": "https://www.atom.io/api/packages/language-make/versions/0.22.3/tarball",
"language-mustache": "https://www.atom.io/api/packages/language-mustache/versions/0.14.5/tarball",
"language-objective-c": "https://www.atom.io/api/packages/language-objective-c/versions/0.15.1/tarball",
"language-perl": "https://www.atom.io/api/packages/language-perl/versions/0.38.1/tarball",
"language-php": "https://www.atom.io/api/packages/language-php/versions/0.44.0/tarball",
"language-property-list": "https://www.atom.io/api/packages/language-property-list/versions/0.9.1/tarball",
"language-python": "https://www.atom.io/api/packages/language-python/versions/0.51.4/tarball",
"language-ruby": "https://www.atom.io/api/packages/language-ruby/versions/0.72.7/tarball",
"language-ruby-on-rails": "https://www.atom.io/api/packages/language-ruby-on-rails/versions/0.25.3/tarball",
"language-sass": "https://www.atom.io/api/packages/language-sass/versions/0.62.0/tarball",
"language-shellscript": "https://www.atom.io/api/packages/language-shellscript/versions/0.27.4/tarball",
"language-source": "https://www.atom.io/api/packages/language-source/versions/0.9.0/tarball",
"language-sql": "https://www.atom.io/api/packages/language-sql/versions/0.25.10/tarball",
"language-text": "https://www.atom.io/api/packages/language-text/versions/0.7.4/tarball",
"language-todo": "https://www.atom.io/api/packages/language-todo/versions/0.29.4/tarball",
"language-toml": "https://www.atom.io/api/packages/language-toml/versions/0.18.2/tarball",
"language-typescript": "https://www.atom.io/api/packages/language-typescript/versions/0.4.6/tarball",
"language-xml": "https://www.atom.io/api/packages/language-xml/versions/0.35.2/tarball",
"language-yaml": "https://www.atom.io/api/packages/language-yaml/versions/0.32.0/tarball",
"less-cache": "1.1.0",
"line-ending-selector": "https://www.atom.io/api/packages/line-ending-selector/versions/0.7.7/tarball",
"line-top-index": "0.3.1",
"link": "https://www.atom.io/api/packages/link/versions/0.31.4/tarball",
"markdown-preview": "https://www.atom.io/api/packages/markdown-preview/versions/0.159.23/tarball",
"marked": "^0.3.12",
"metrics": "https://www.atom.io/api/packages/metrics/versions/1.6.2/tarball",
"minimatch": "^3.0.3",
"mocha": "2.5.1",
"mocha-junit-reporter": "^1.13.0",
"mocha-multi-reporters": "^1.1.4",
"mock-spawn": "^0.2.6",
"normalize-package-data": "^2.0.0",
"notifications": "https://www.atom.io/api/packages/notifications/versions/0.70.5/tarball",
"nslog": "^3",
"one-dark-syntax": "https://www.atom.io/api/packages/one-dark-syntax/versions/1.8.4/tarball",
"one-dark-ui": "https://www.atom.io/api/packages/one-dark-ui/versions/1.12.5/tarball",
"one-light-syntax": "https://www.atom.io/api/packages/one-light-syntax/versions/1.8.4/tarball",
"one-light-ui": "file:packages/one-light-ui",
"oniguruma": "6.2.1",
"open-on-github": "https://www.atom.io/api/packages/open-on-github/versions/1.3.1/tarball",
"package-generator": "https://www.atom.io/api/packages/package-generator/versions/1.3.0/tarball",
"pathwatcher": "8.0.1",
"postcss": "5.2.4",
"postcss-selector-parser": "2.2.1",
@@ -69,106 +146,121 @@
"season": "^6.0.2",
"semver": "^4.3.3",
"service-hub": "^0.7.4",
"settings-view": "https://www.atom.io/api/packages/settings-view/versions/0.256.0/tarball",
"sinon": "1.17.4",
"snippets": "https://www.atom.io/api/packages/snippets/versions/1.3.5/tarball",
"solarized-dark-syntax": "https://www.atom.io/api/packages/solarized-dark-syntax/versions/1.2.0/tarball",
"solarized-light-syntax": "https://www.atom.io/api/packages/solarized-light-syntax/versions/1.2.0/tarball",
"spell-check": "https://www.atom.io/api/packages/spell-check/versions/0.74.1/tarball",
"status-bar": "https://www.atom.io/api/packages/status-bar/versions/1.8.15/tarball",
"styleguide": "https://www.atom.io/api/packages/styleguide/versions/0.49.12/tarball",
"symbols-view": "https://www.atom.io/api/packages/symbols-view/versions/0.118.2/tarball",
"tabs": "https://www.atom.io/api/packages/tabs/versions/0.109.2/tarball",
"temp": "^0.8.3",
"text-buffer": "13.11.8",
"tree-sitter": "^0.9.2",
"text-buffer": "13.14.8",
"timecop": "https://www.atom.io/api/packages/timecop/versions/0.36.2/tarball",
"tree-sitter": "0.13.9",
"tree-view": "https://www.atom.io/api/packages/tree-view/versions/0.224.2/tarball",
"typescript-simple": "1.0.0",
"underscore-plus": "^1.6.6",
"underscore-plus": "^1.6.8",
"update-package-dependencies": "https://www.atom.io/api/packages/update-package-dependencies/versions/0.13.1/tarball",
"welcome": "https://www.atom.io/api/packages/welcome/versions/0.36.7/tarball",
"whitespace": "https://www.atom.io/api/packages/whitespace/versions/0.37.6/tarball",
"winreg": "^1.2.1",
"wrap-guide": "https://www.atom.io/api/packages/wrap-guide/versions/0.40.3/tarball",
"yargs": "^3.23.0"
},
"packageDependencies": {
"atom-dark-syntax": "0.29.0",
"atom-dark-ui": "0.53.2",
"atom-light-syntax": "0.29.0",
"atom-light-ui": "0.46.2",
"base16-tomorrow-dark-theme": "1.5.0",
"base16-tomorrow-light-theme": "1.5.0",
"one-dark-ui": "1.11.0",
"one-light-ui": "1.11.0",
"one-dark-syntax": "1.8.2",
"one-light-syntax": "1.8.2",
"solarized-dark-syntax": "1.1.4",
"solarized-light-syntax": "1.1.4",
"about": "1.8.0",
"archive-view": "0.64.3",
"atom-dark-syntax": "0.29.1",
"atom-dark-ui": "0.53.3",
"atom-light-syntax": "0.29.1",
"atom-light-ui": "0.46.3",
"base16-tomorrow-dark-theme": "1.6.0",
"base16-tomorrow-light-theme": "1.6.0",
"one-dark-ui": "1.12.5",
"one-light-ui": "file:./packages/one-light-ui",
"one-dark-syntax": "1.8.4",
"one-light-syntax": "1.8.4",
"solarized-dark-syntax": "1.2.0",
"solarized-light-syntax": "1.2.0",
"about": "file:./packages/about",
"archive-view": "0.65.1",
"autocomplete-atom-api": "0.10.7",
"autocomplete-css": "0.17.5",
"autocomplete-html": "0.8.4",
"autocomplete-plus": "2.40.5",
"autocomplete-html": "0.8.5",
"autocomplete-plus": "2.41.0",
"autocomplete-snippets": "1.12.0",
"autoflow": "0.29.3",
"autoflow": "0.29.4",
"autosave": "0.24.6",
"background-tips": "0.28.0",
"bookmarks": "0.45.1",
"bracket-matcher": "0.89.1",
"bracket-matcher": "0.89.2",
"command-palette": "0.43.5",
"dalek": "0.2.2",
"deprecation-cop": "0.56.9",
"dev-live-reload": "0.48.1",
"encoding-selector": "0.23.8",
"encoding-selector": "0.23.9",
"exception-reporting": "0.43.1",
"find-and-replace": "0.215.5",
"fuzzy-finder": "1.8.0",
"github": "0.12.0",
"find-and-replace": "0.215.12",
"fuzzy-finder": "1.8.2",
"github": "0.19.0",
"git-diff": "1.3.9",
"go-to-line": "0.33.0",
"grammar-selector": "0.50.0",
"image-view": "0.62.4",
"grammar-selector": "0.50.1",
"image-view": "0.63.1",
"incompatible-packages": "0.27.3",
"keybinding-resolver": "0.38.1",
"line-ending-selector": "0.7.5",
"keybinding-resolver": "0.38.2",
"line-ending-selector": "0.7.7",
"link": "0.31.4",
"markdown-preview": "0.159.20",
"metrics": "1.2.6",
"notifications": "0.70.2",
"markdown-preview": "0.159.23",
"metrics": "1.6.2",
"notifications": "0.70.5",
"open-on-github": "1.3.1",
"package-generator": "1.3.0",
"settings-view": "0.254.2",
"snippets": "1.3.1",
"spell-check": "0.73.1",
"settings-view": "0.256.0",
"snippets": "1.3.5",
"spell-check": "0.74.1",
"status-bar": "1.8.15",
"styleguide": "0.49.10",
"styleguide": "0.49.12",
"symbols-view": "0.118.2",
"tabs": "0.109.1",
"tabs": "0.109.2",
"timecop": "0.36.2",
"tree-view": "0.221.3",
"tree-view": "0.224.2",
"update-package-dependencies": "0.13.1",
"welcome": "0.36.6",
"whitespace": "0.37.5",
"welcome": "0.36.7",
"whitespace": "0.37.6",
"wrap-guide": "0.40.3",
"language-c": "0.59.2",
"language-c": "0.60.4",
"language-clojure": "0.22.7",
"language-coffee-script": "0.49.3",
"language-csharp": "1.0.1",
"language-css": "0.42.10",
"language-gfm": "0.90.3",
"language-csharp": "1.1.0",
"language-css": "0.42.11",
"language-gfm": "0.90.5",
"language-git": "0.19.1",
"language-go": "0.45.2",
"language-html": "0.49.0",
"language-go": "0.46.2",
"language-html": "0.51.5",
"language-hyperlink": "0.16.3",
"language-java": "0.29.0",
"language-javascript": "0.128.4",
"language-json": "0.19.1",
"language-java": "0.30.0",
"language-javascript": "0.129.9",
"language-json": "0.19.2",
"language-less": "0.34.2",
"language-make": "0.22.3",
"language-mustache": "0.14.5",
"language-objective-c": "0.15.1",
"language-perl": "0.38.1",
"language-php": "0.43.2",
"language-php": "0.44.0",
"language-property-list": "0.9.1",
"language-python": "0.49.2",
"language-ruby": "0.71.4",
"language-python": "0.51.4",
"language-ruby": "0.72.7",
"language-ruby-on-rails": "0.25.3",
"language-sass": "0.61.4",
"language-shellscript": "0.26.2",
"language-sass": "0.62.0",
"language-shellscript": "0.27.4",
"language-source": "0.9.0",
"language-sql": "0.25.10",
"language-text": "0.7.4",
"language-todo": "0.29.4",
"language-toml": "0.18.2",
"language-typescript": "0.3.2",
"language-typescript": "0.4.6",
"language-xml": "0.35.2",
"language-yaml": "0.32.0"
},

194
packages/README.md Normal file
View File

@@ -0,0 +1,194 @@
# Atom Core Packages
This folder contains core packages that are bundled with Atom releases. Not all Atom core packages are kept here; please
see the table below for the location of every core Atom package.
> **NOTE:** There is an ongoing effort to migrate more Atom packages from their individual repositories to this folder.
See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate-core-packages.md) for more details.
| Package | Where to find it | Migration issue |
|---------|------------------|-----------------|
| **about** | [`./packages/about`](./about) | [#17832](https://github.com/atom/atom/issues/17832) |
| **atom-dark-syntax** | [`atom/atom-dark-syntax`][atom-dark-syntax] | [#17849](https://github.com/atom/atom/issues/17849) |
| **atom-dark-ui** | [`atom/atom-dark-ui`][atom-dark-ui] | [#17850](https://github.com/atom/atom/issues/17850) |
| **atom-light-syntax** | [`atom/atom-light-syntax`][atom-light-syntax] | [#17851](https://github.com/atom/atom/issues/17851) |
| **atom-light-ui** | [`atom/atom-light-ui`][atom-light-ui] | [#17852](https://github.com/atom/atom/issues/17852) |
| **autocomplete-atom-api** | [`atom/autocomplete-atom-api`][autocomplete-atom-api] | |
| **autocomplete-css** | [`atom/autocomplete-css`][autocomplete-css] | |
| **autocomplete-html** | [`atom/autocomplete-html`][autocomplete-html] | |
| **autocomplete-plus** | [`atom/autocomplete-plus`][autocomplete-plus] | |
| **autocomplete-snippets** | [`atom/autocomplete-snippets`][autocomplete-snippets] | |
| **autoflow** | [`atom/autoflow`][autoflow] | [#17833](https://github.com/atom/atom/issues/17833) |
| **autosave** | [`atom/autosave`][autosave] | [#17834](https://github.com/atom/atom/issues/17834) |
| **background-tips** | [`atom/background-tips`][background-tips] | [#17835](https://github.com/atom/atom/issues/17835) |
| **base16-tomorrow-dark-theme** | [`atom/base16-tomorrow-dark-theme`][base16-tomorrow-dark-theme] | [#17836](https://github.com/atom/atom/issues/17836) |
| **base16-tomorrow-light-theme** | [`atom/base16-tomorrow-light-theme`][base16-tomorrow-light-theme] | [#17837](https://github.com/atom/atom/issues/17837) |
| **bookmarks** | [`atom/bookmarks`][bookmarks] | |
| **bracket-matcher** | [`atom/bracket-matcher`][bracket-matcher] | |
| **command-palette** | [`atom/command-palette`][command-palette] | |
| **dalek** | [`atom/dalek`][dalek] | [#17838](https://github.com/atom/atom/issues/17838) |
| **deprecation-cop** | [`atom/deprecation-cop`][deprecation-cop] | [#17839](https://github.com/atom/atom/issues/17839) |
| **dev-live-reload** | [`atom/dev-live-reload`][dev-live-reload] | [#17840](https://github.com/atom/atom/issues/17840) |
| **encoding-selector** | [`atom/encoding-selector`][encoding-selector] | [#17841](https://github.com/atom/atom/issues/17841) |
| **exception-reporting** | [`atom/exception-reporting`][exception-reporting] | [#17842](https://github.com/atom/atom/issues/17842) |
| **find-and-replace** | [`atom/find-and-replace`][find-and-replace] | |
| **fuzzy-finder** | [`atom/fuzzy-finder`][fuzzy-finder] | |
| **github** | [`atom/github`][github] | |
| **git-diff** | [`atom/git-diff`][git-diff] | [#17843](https://github.com/atom/atom/issues/17843) |
| **go-to-line** | [`atom/go-to-line`][go-to-line] | [#17844](https://github.com/atom/atom/issues/17844) |
| **grammar-selector** | [`atom/grammar-selector`][grammar-selector] | [#17845](https://github.com/atom/atom/issues/17845) |
| **image-view** | [`atom/image-view`][image-view] | |
| **incompatible-packages** | [`atom/incompatible-packages`][incompatible-packages] | [#17846](https://github.com/atom/atom/issues/17846) |
| **keybinding-resolver** | [`atom/keybinding-resolver`][keybinding-resolver] | |
| **language-c** | [`atom/language-c`][language-c] | |
| **language-clojure** | [`atom/language-clojure`][language-clojure] | |
| **language-coffee-script** | [`atom/language-coffee-script`][language-coffee-script] | |
| **language-csharp** | [`atom/language-csharp`][language-csharp] | |
| **language-css** | [`atom/language-css`][language-css] | |
| **language-gfm** | [`atom/language-gfm`][language-gfm] | |
| **language-git** | [`atom/language-git`][language-git] | |
| **language-go** | [`atom/language-go`][language-go] | |
| **language-html** | [`atom/language-html`][language-html] | |
| **language-hyperlink** | [`atom/language-hyperlink`][language-hyperlink] | |
| **language-java** | [`atom/language-java`][language-java] | |
| **language-javascript** | [`atom/language-javascript`][language-javascript] | |
| **language-json** | [`atom/language-json`][language-json] | |
| **language-less** | [`atom/language-less`][language-less] | |
| **language-make** | [`atom/language-make`][language-make] | |
| **language-mustache** | [`atom/language-mustache`][language-mustache] | |
| **language-objective-c** | [`atom/language-objective-c`][language-objective-c] | |
| **language-perl** | [`atom/language-perl`][language-perl] | |
| **language-php** | [`atom/language-php`][language-php] | |
| **language-property-list** | [`atom/language-property-list`][language-property-list] | |
| **language-python** | [`atom/language-python`][language-python] | |
| **language-ruby** | [`atom/language-ruby`][language-ruby] | |
| **language-ruby-on-rails** | [`atom/language-ruby-on-rails`][language-ruby-on-rails] | |
| **language-sass** | [`atom/language-sass`][language-sass] | |
| **language-shellscript** | [`atom/language-shellscript`][language-shellscript] | |
| **language-source** | [`atom/language-source`][language-source] | |
| **language-sql** | [`atom/language-sql`][language-sql] | |
| **language-text** | [`atom/language-text`][language-text] | |
| **language-todo** | [`atom/language-todo`][language-todo] | |
| **language-toml** | [`atom/language-toml`][language-toml] | |
| **language-typescript** | [`atom/language-typescript`][language-typescript] | |
| **language-xml** | [`atom/language-xml`][language-xml] | |
| **language-yaml** | [`atom/language-yaml`][language-yaml] | |
| **line-ending-selector** | [`atom/line-ending-selector`][line-ending-selector] | [#17847](https://github.com/atom/atom/issues/17847) |
| **link** | [`atom/link`][link] | [#17848](https://github.com/atom/atom/issues/17848) |
| **markdown-preview** | [`atom/markdown-preview`][markdown-preview] | |
| **metrics** | [`atom/metrics`][metrics] | |
| **notifications** | [`atom/notifications`][notifications] | |
| **one-dark-syntax** | [`atom/one-dark-syntax`][one-dark-syntax] | [#17853](https://github.com/atom/atom/issues/17853) |
| **one-dark-ui** | [`atom/one-dark-ui`][one-dark-ui] | [#17854](https://github.com/atom/atom/issues/17854) |
| **one-light-syntax** | [`atom/one-light-syntax`][one-light-syntax] | [#17855](https://github.com/atom/atom/issues/17855) |
| **one-light-ui** | [`./packages/one-light-ui`](./one-light-ui) | [#17856](https://github.com/atom/atom/issues/17856) |
| **open-on-github** | [`atom/open-on-github`][open-on-github] | |
| **package-generator** | [`atom/package-generator`][package-generator] | |
| **settings-view** | [`atom/settings-view`][settings-view] | |
| **snippets** | [`atom/snippets`][snippets] | |
| **solarized-dark-syntax** | [`atom/solarized-dark-syntax`][solarized-dark-syntax] | |
| **solarized-light-syntax** | [`atom/solarized-light-syntax`][solarized-light-syntax] | |
| **spell-check** | [`atom/spell-check`][spell-check] | |
| **status-bar** | [`atom/status-bar`][status-bar] | |
| **styleguide** | [`atom/styleguide`][styleguide] | |
| **symbols-view** | [`atom/symbols-view`][symbols-view] | |
| **tabs** | [`atom/tabs`][tabs] | |
| **timecop** | [`atom/timecop`][timecop] | |
| **tree-view** | [`atom/tree-view`][tree-view] | |
| **update-package-dependencies** | [`atom/update-package-dependencies`][update-package-dependencies] | |
| **welcome** | [`atom/welcome`][welcome] | |
| **whitespace** | [`atom/whitespace`][whitespace] | |
| **wrap-guide** | [`atom/wrap-guide`][wrap-guide] | |
[about]: https://github.com/atom/about
[archive-view]: https://github.com/atom/archive-view
[atom-dark-syntax]: https://github.com/atom/atom-dark-syntax
[atom-dark-ui]: https://github.com/atom/atom-dark-ui
[atom-light-syntax]: https://github.com/atom/atom-light-syntax
[atom-light-ui]: https://github.com/atom/atom-light-ui
[autocomplete-atom-api]: https://github.com/atom/autocomplete-atom-api
[autocomplete-css]: https://github.com/atom/autocomplete-css
[autocomplete-html]: https://github.com/atom/autocomplete-html
[autocomplete-plus]: https://github.com/atom/autocomplete-plus
[autocomplete-snippets]: https://github.com/atom/autocomplete-snippets
[autoflow]: https://github.com/atom/autoflow
[autosave]: https://github.com/atom/autosave
[background-tips]: https://github.com/atom/background-tips
[base16-tomorrow-dark-theme]: https://github.com/atom/base16-tomorrow-dark-theme
[base16-tomorrow-light-theme]: https://github.com/atom/base16-tomorrow-light-theme
[bookmarks]: https://github.com/atom/bookmarks
[bracket-matcher]: https://github.com/atom/bracket-matcher
[command-palette]: https://github.com/atom/command-palette
[dalek]: https://github.com/atom/dalek
[deprecation-cop]: https://github.com/atom/deprecation-cop
[dev-live-reload]: https://github.com/atom/dev-live-reload
[encoding-selector]: https://github.com/atom/encoding-selector
[exception-reporting]: https://github.com/atom/exception-reporting
[find-and-replace]: https://github.com/atom/find-and-replace
[fuzzy-finder]: https://github.com/atom/fuzzy-finder
[git-diff]: https://github.com/atom/git-diff
[github]: https://github.com/atom/github
[go-to-line]: https://github.com/atom/go-to-line
[grammar-selector]: https://github.com/atom/grammar-selector
[image-view]: https://github.com/atom/image-view
[incompatible-packages]: https://github.com/atom/incompatible-packages
[keybinding-resolver]: https://github.com/atom/keybinding-resolver
[language-c]: https://github.com/atom/language-c
[language-clojure]: https://github.com/atom/language-clojure
[language-coffee-script]: https://github.com/atom/language-coffee-script
[language-csharp]: https://github.com/atom/language-csharp
[language-css]: https://github.com/atom/language-css
[language-gfm]: https://github.com/atom/language-gfm
[language-git]: https://github.com/atom/language-git
[language-go]: https://github.com/atom/language-go
[language-html]: https://github.com/atom/language-html
[language-hyperlink]: https://github.com/atom/language-hyperlink
[language-java]: https://github.com/atom/language-java
[language-javascript]: https://github.com/atom/language-javascript
[language-json]: https://github.com/atom/language-json
[language-less]: https://github.com/atom/language-less
[language-make]: https://github.com/atom/language-make
[language-mustache]: https://github.com/atom/language-mustache
[language-objective-c]: https://github.com/atom/language-objective-c
[language-perl]: https://github.com/atom/language-perl
[language-php]: https://github.com/atom/language-php
[language-property-list]: https://github.com/atom/language-property-list
[language-python]: https://github.com/atom/language-python
[language-ruby]: https://github.com/atom/language-ruby
[language-ruby-on-rails]: https://github.com/atom/language-ruby-on-rails
[language-sass]: https://github.com/atom/language-sass
[language-shellscript]: https://github.com/atom/language-shellscript
[language-source]: https://github.com/atom/language-source
[language-sql]: https://github.com/atom/language-sql
[language-text]: https://github.com/atom/language-text
[language-todo]: https://github.com/atom/language-todo
[language-toml]: https://github.com/atom/language-toml
[language-typescript]: https://github.com/atom/language-typescript
[language-xml]: https://github.com/atom/language-xml
[language-yaml]: https://github.com/atom/language-yaml
[line-ending-selector]: https://github.com/atom/line-ending-selector
[link]: https://github.com/atom/link
[markdown-preview]: https://github.com/atom/markdown-preview
[metrics]: https://github.com/atom/metrics
[notifications]: https://github.com/atom/notifications
[one-dark-syntax]: https://github.com/atom/one-dark-syntax
[one-dark-ui]: https://github.com/atom/one-dark-ui
[one-light-syntax]: https://github.com/atom/one-light-syntax
[one-light-ui]: https://github.com/atom/one-light-ui
[open-on-github]: https://github.com/atom/open-on-github
[package-generator]: https://github.com/atom/package-generator
[settings-view]: https://github.com/atom/settings-view
[snippets]: https://github.com/atom/snippets
[solarized-dark-syntax]: https://github.com/atom/solarized-dark-syntax
[solarized-light-syntax]: https://github.com/atom/solarized-light-syntax
[spell-check]: https://github.com/atom/spell-check
[status-bar]: https://github.com/atom/status-bar
[styleguide]: https://github.com/atom/styleguide
[symbols-view]: https://github.com/atom/symbols-view
[tabs]: https://github.com/atom/tabs
[timecop]: https://github.com/atom/timecop
[tree-view]: https://github.com/atom/tree-view
[update-package-dependencies]: https://github.com/atom/update-package-dependencies
[welcome]: https://github.com/atom/welcome
[whitespace]: https://github.com/atom/whitespace
[wrap-guide]: https://github.com/atom/wrap-guide

3
packages/about/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
.DS_Store
npm-debug.log
node_modules

20
packages/about/LICENSE.md Normal file
View File

@@ -0,0 +1,20 @@
Copyright (c) 2015 Machisté N. Quintana
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

21
packages/about/README.md Normal file
View File

@@ -0,0 +1,21 @@
# About package
View useful information about your Atom installation.
![About Atom](https://cloud.githubusercontent.com/assets/16760489/19395499/69bbb780-922d-11e6-9779-2b8327027ea5.png)
This is a package for [Atom](https://atom.io), a hackable text editor for the 21st Century.
## Usage
This package provides a cross-platform "About Atom" view that displays information about your Atom installation, which currently includes the current version, the license, and the Terms of Use.
## Contributing
Always feel free to help out! Whether it's filing bugs and feature requests
or working on some of the open issues, Atom's [contributing guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md)
will help get you started while the [guide for contributing to packages](https://github.com/atom/atom/blob/master/docs/contributing-to-packages.md)
has some extra information.
## License
[MIT License](https://opensource.org/licenses/MIT) - see the [LICENSE](https://github.com/atom/about/blob/master/LICENSE.md) for more details.

View File

@@ -0,0 +1,93 @@
const {CompositeDisposable, Emitter} = require('atom')
const AboutView = require('./components/about-view')
// Deferred requires
let shell
module.exports = class About {
constructor (initialState) {
this.subscriptions = new CompositeDisposable()
this.emitter = new Emitter()
this.state = initialState
this.views = {
aboutView: null
}
this.subscriptions.add(atom.workspace.addOpener((uriToOpen) => {
if (uriToOpen === this.state.uri) {
return this.deserialize()
}
}))
this.subscriptions.add(atom.commands.add('atom-workspace', 'about:view-release-notes', () => {
shell = shell || require('electron').shell
shell.openExternal(this.state.updateManager.getReleaseNotesURLForCurrentVersion())
}))
}
destroy () {
if (this.views.aboutView) this.views.aboutView.destroy()
this.views.aboutView = null
if (this.state.updateManager) this.state.updateManager.dispose()
this.setState({updateManager: null})
this.subscriptions.dispose()
}
setState (newState) {
if (newState && typeof newState === 'object') {
let {state} = this
this.state = Object.assign({}, state, newState)
this.didChange()
}
}
didChange () {
this.emitter.emit('did-change')
}
onDidChange (callback) {
this.emitter.on('did-change', callback)
}
deserialize (state) {
if (!this.views.aboutView) {
this.setState(state)
this.views.aboutView = new AboutView({
uri: this.state.uri,
updateManager: this.state.updateManager,
currentAtomVersion: this.state.currentAtomVersion,
currentElectronVersion: this.state.currentElectronVersion,
currentChromeVersion: this.state.currentChromeVersion,
currentNodeVersion: this.state.currentNodeVersion,
availableVersion: this.state.updateManager.getAvailableVersion()
})
this.handleStateChanges()
}
return this.views.aboutView
}
handleStateChanges () {
this.onDidChange(() => {
if (this.views.aboutView) {
this.views.aboutView.update({
updateManager: this.state.updateManager,
currentAtomVersion: this.state.currentAtomVersion,
currentElectronVersion: this.state.currentElectronVersion,
currentChromeVersion: this.state.currentChromeVersion,
currentNodeVersion: this.state.currentNodeVersion,
availableVersion: this.state.updateManager.getAvailableVersion()
})
}
})
this.state.updateManager.onDidChange(() => {
this.didChange()
})
}
}

View File

@@ -0,0 +1,30 @@
const {CompositeDisposable} = require('atom')
const etch = require('etch')
const EtchComponent = require('../etch-component')
const $ = etch.dom
module.exports =
class AboutStatusBar extends EtchComponent {
constructor () {
super()
this.subscriptions = new CompositeDisposable()
this.subscriptions.add(atom.tooltips.add(this.element, {title: 'An update will be installed the next time Atom is relaunched.<br/><br/>Click the squirrel icon for more information.'}))
}
handleClick () {
atom.workspace.open('atom://about')
}
render () {
return $.div({className: 'about-release-notes inline-block', onclick: this.handleClick.bind(this)},
$.span({type: 'button', className: 'icon icon-squirrel'})
)
}
destroy () {
super.destroy()
this.subscriptions.dispose()
}
}

View File

@@ -0,0 +1,159 @@
const {Disposable} = require('atom')
const etch = require('etch')
const shell = require('shell')
const AtomLogo = require('./atom-logo')
const EtchComponent = require('../etch-component')
const UpdateView = require('./update-view')
const $ = etch.dom
module.exports =
class AboutView extends EtchComponent {
handleAtomVersionClick (e) {
e.preventDefault()
atom.clipboard.write(this.props.currentAtomVersion)
}
handleElectronVersionClick (e) {
e.preventDefault()
atom.clipboard.write(this.props.currentElectronVersion)
}
handleChromeVersionClick (e) {
e.preventDefault()
atom.clipboard.write(this.props.currentChromeVersion)
}
handleNodeVersionClick (e) {
e.preventDefault()
atom.clipboard.write(this.props.currentNodeVersion)
}
handleReleaseNotesClick (e) {
e.preventDefault()
shell.openExternal(this.props.updateManager.getReleaseNotesURLForAvailableVersion())
}
handleLicenseClick (e) {
e.preventDefault()
atom.commands.dispatch(atom.views.getView(atom.workspace), 'application:open-license')
}
handleTermsOfUseClick (e) {
e.preventDefault()
shell.openExternal('https://atom.io/terms')
}
handleHowToUpdateClick (e) {
e.preventDefault()
shell.openExternal('https://flight-manual.atom.io/getting-started/sections/installing-atom/')
}
handleShowMoreClick (e) {
e.preventDefault()
var showMoreDiv = document.querySelector('.show-more')
var showMoreText = document.querySelector('.about-more-expand')
switch (showMoreText.textContent) {
case 'Show more':
showMoreDiv.classList.toggle('hidden')
showMoreText.textContent = 'Hide'
break
case 'Hide':
showMoreDiv.classList.toggle('hidden')
showMoreText.textContent = 'Show more'
break
}
}
render () {
return $.div({className: 'pane-item native-key-bindings about'},
$.div({className: 'about-container'},
$.header({className: 'about-header'},
$.a({className: 'about-atom-io', href: 'https://atom.io'},
$(AtomLogo)
),
$.div({className: 'about-header-info'},
$.span({className: 'about-version-container inline-block atom', onclick: this.handleAtomVersionClick.bind(this)},
$.span({className: 'about-version'}, `${this.props.currentAtomVersion} ${process.arch}`),
$.span({className: 'icon icon-clippy about-copy-version'})
),
$.a({className: 'about-header-release-notes', onclick: this.handleReleaseNotesClick.bind(this)}, 'Release Notes')
),
$.span({className: 'about-version-container inline-block show-more-expand', onclick: this.handleShowMoreClick.bind(this)},
$.span({className: 'about-more-expand'}, 'Show more')
),
$.div({className: 'show-more hidden about-more-info'},
$.div({className: 'about-more-info'},
$.span({className: 'about-version-container inline-block electron', onclick: this.handleElectronVersionClick.bind(this)},
$.span({className: 'about-more-version'}, `Electron: ${this.props.currentElectronVersion} `),
$.span({className: 'icon icon-clippy about-copy-version'})
)
),
$.div({className: 'about-more-info'},
$.span({className: 'about-version-container inline-block chrome', onclick: this.handleChromeVersionClick.bind(this)},
$.span({className: 'about-more-version'}, `Chrome: ${this.props.currentChromeVersion} `),
$.span({className: 'icon icon-clippy about-copy-version'})
)
),
$.div({className: 'about-more-info'},
$.span({className: 'about-version-container inline-block node', onclick: this.handleNodeVersionClick.bind(this)},
$.span({className: 'about-more-version'}, `Node: ${this.props.currentNodeVersion} `),
$.span({className: 'icon icon-clippy about-copy-version'})
)
)
)
)
),
$(UpdateView, {
updateManager: this.props.updateManager,
availableVersion: this.props.availableVersion,
viewUpdateReleaseNotes: this.handleReleaseNotesClick.bind(this),
viewUpdateInstructions: this.handleHowToUpdateClick.bind(this)
}),
$.div({className: 'about-actions group-item'},
$.div({className: 'btn-group'},
$.button({className: 'btn view-license', onclick: this.handleLicenseClick.bind(this)}, 'License'),
$.button({className: 'btn terms-of-use', onclick: this.handleTermsOfUseClick.bind(this)}, 'Terms of Use')
)
),
$.div({className: 'about-love group-start'},
$.span({className: 'icon icon-code'}),
$.span({className: 'inline'}, ' with '),
$.span({className: 'icon icon-heart'}),
$.span({className: 'inline'}, ' by '),
$.a({className: 'icon icon-logo-github', href: 'https://github.com'})
),
$.div({className: 'about-credits group-item'},
$.span({className: 'inline'}, 'And the awesome '),
$.a({href: 'https://github.com/atom/atom/contributors'}, 'Atom Community')
)
)
}
serialize () {
return {
deserializer: this.constructor.name,
uri: this.props.uri
}
}
onDidChangeTitle () {
return new Disposable()
}
onDidChangeModified () {
return new Disposable()
}
getTitle () {
return 'About'
}
getIconName () {
return 'info'
}
}

View File

@@ -0,0 +1,28 @@
const etch = require('etch')
const EtchComponent = require('../etch-component')
const $ = etch.dom
module.exports =
class AtomLogo extends EtchComponent {
render () {
return $.svg({className: 'about-logo', width: '330px', height: '68px', viewBox: '0 0 330 68'},
$.g({stroke: 'none', 'stroke-width': '1', fill: 'none', 'fill-rule': 'evenodd'},
$.g({transform: 'translate(2.000000, 1.000000)'},
$.g({transform: 'translate(96.000000, 8.000000)', fill: 'currentColor'},
$.path({d: 'M185.498,3.399 C185.498,2.417 186.34,1.573 187.324,1.573 L187.674,1.573 C188.447,1.573 189.01,1.995 189.5,2.628 L208.676,30.862 L227.852,2.628 C228.272,1.995 228.905,1.573 229.676,1.573 L230.028,1.573 C231.01,1.573 231.854,2.417 231.854,3.399 L231.854,49.403 C231.854,50.387 231.01,51.231 230.028,51.231 C229.044,51.231 228.202,50.387 228.202,49.403 L228.202,8.246 L210.151,34.515 C209.729,35.148 209.237,35.428 208.606,35.428 C207.973,35.428 207.481,35.148 207.061,34.515 L189.01,8.246 L189.01,49.475 C189.01,50.457 188.237,51.231 187.254,51.231 C186.27,51.231 185.498,50.458 185.498,49.475 L185.498,3.399 L185.498,3.399 Z'}),
$.path({d: 'M113.086,26.507 L113.086,26.367 C113.086,12.952 122.99,0.941 137.881,0.941 C152.77,0.941 162.533,12.811 162.533,26.225 L162.533,26.367 C162.533,39.782 152.629,51.792 137.74,51.792 C122.85,51.792 113.086,39.923 113.086,26.507 M158.74,26.507 L158.74,26.367 C158.74,14.216 149.89,4.242 137.74,4.242 C125.588,4.242 116.879,14.075 116.879,26.225 L116.879,26.367 C116.879,38.518 125.729,48.491 137.881,48.491 C150.031,48.491 158.74,38.658 158.74,26.507'}),
$.path({d: 'M76.705,5.155 L60.972,5.155 C60.06,5.155 59.287,4.384 59.287,3.469 C59.287,2.556 60.059,1.783 60.972,1.783 L96.092,1.783 C97.004,1.783 97.778,2.555 97.778,3.469 C97.778,4.383 97.005,5.155 96.092,5.155 L80.358,5.155 L80.358,49.405 C80.358,50.387 79.516,51.231 78.532,51.231 C77.55,51.231 76.706,50.387 76.706,49.405 L76.706,5.155 L76.705,5.155 Z'}),
$.path({d: 'M0.291,48.562 L21.291,3.05 C21.783,1.995 22.485,1.292 23.75,1.292 L23.891,1.292 C25.155,1.292 25.858,1.995 26.348,3.05 L47.279,48.421 C47.49,48.843 47.56,49.194 47.56,49.546 C47.56,50.458 46.788,51.231 45.803,51.231 C44.961,51.231 44.329,50.599 43.978,49.826 L38.219,37.183 L9.21,37.183 L3.45,49.897 C3.099,50.739 2.538,51.231 1.694,51.231 C0.781,51.231 0.008,50.529 0.008,49.685 C0.009,49.404 0.08,48.983 0.291,48.562 L0.291,48.562 Z M36.673,33.882 L23.749,5.437 L10.755,33.882 L36.673,33.882 L36.673,33.882 Z'})
),
$.g({},
$.path({d: 'M40.363,32.075 C40.874,34.44 39.371,36.77 37.006,37.282 C34.641,37.793 32.311,36.29 31.799,33.925 C31.289,31.56 32.791,29.23 35.156,28.718 C37.521,28.207 39.851,29.71 40.363,32.075', fill: 'currentColor'}),
$.path({d: 'M48.578,28.615 C56.851,45.587 58.558,61.581 52.288,64.778 C45.822,68.076 33.326,56.521 24.375,38.969 C15.424,21.418 13.409,4.518 19.874,1.221 C22.689,-0.216 26.648,1.166 30.959,4.629', stroke: 'currentColor', 'stroke-width': '3.08', 'stroke-linecap': 'round'}),
$.path({d: 'M7.64,39.45 C2.806,36.94 -0.009,33.915 0.154,30.79 C0.531,23.542 16.787,18.497 36.462,19.52 C56.137,20.544 71.781,27.249 71.404,34.497 C71.241,37.622 68.127,40.338 63.06,42.333', stroke: 'currentColor', 'stroke-width': '3.08', 'stroke-linecap': 'round'}),
$.path({d: 'M28.828,59.354 C23.545,63.168 18.843,64.561 15.902,62.653 C9.814,58.702 13.572,42.102 24.296,25.575 C35.02,9.048 48.649,-1.149 54.736,2.803 C57.566,4.639 58.269,9.208 57.133,15.232', stroke: 'currentColor', 'stroke-width': '3.08', 'stroke-linecap': 'round'})
)
)
)
)
}
}

View File

@@ -0,0 +1,121 @@
const etch = require('etch')
const EtchComponent = require('../etch-component')
const UpdateManager = require('../update-manager')
const $ = etch.dom
module.exports =
class UpdateView extends EtchComponent {
constructor (props) {
super(props)
if (this.props.updateManager.getAutoUpdatesEnabled() && this.props.updateManager.getState() === UpdateManager.State.Idle) {
this.props.updateManager.checkForUpdate()
}
}
handleAutoUpdateCheckbox (e) {
atom.config.set('core.automaticallyUpdate', e.target.checked)
}
shouldUpdateActionButtonBeDisabled () {
let {state} = this.props.updateManager
return state === UpdateManager.State.CheckingForUpdate || state === UpdateManager.State.DownloadingUpdate
}
executeUpdateAction () {
if (this.props.updateManager.state === UpdateManager.State.UpdateAvailableToInstall) {
this.props.updateManager.restartAndInstallUpdate()
} else {
this.props.updateManager.checkForUpdate()
}
}
renderUpdateStatus () {
let updateStatus = ''
switch (this.props.updateManager.state) {
case UpdateManager.State.Idle:
updateStatus = $.div({className: 'about-updates-item is-shown about-default-update-message'},
this.props.updateManager.getAutoUpdatesEnabled() ? 'Atom will check for updates automatically' : 'Automatic updates are disabled please check manually'
)
break
case UpdateManager.State.CheckingForUpdate:
updateStatus = $.div({className: 'about-updates-item app-checking-for-updates'},
$.span({className: 'about-updates-label icon icon-search'}, 'Checking for updates...')
)
break
case UpdateManager.State.DownloadingUpdate:
updateStatus = $.div({className: 'about-updates-item app-downloading-update'},
$.span({className: 'loading loading-spinner-tiny inline-block'}),
$.span({className: 'about-updates-label'}, 'Downloading update')
)
break
case UpdateManager.State.UpdateAvailableToInstall:
updateStatus = $.div({className: 'about-updates-item app-update-available-to-install'},
$.span({className: 'about-updates-label icon icon-squirrel'}, 'New update'),
$.span({className: 'about-updates-version'}, this.props.availableVersion),
$.a({className: 'about-updates-release-notes', onclick: this.props.viewUpdateReleaseNotes}, 'Release Notes')
)
break
case UpdateManager.State.UpToDate:
updateStatus = $.div({className: 'about-updates-item app-up-to-date'},
$.span({className: 'icon icon-check'}),
$.span({className: 'about-updates-label is-strong'}, 'Atom is up to date!')
)
break
case UpdateManager.State.Unsupported:
updateStatus = $.div({className: 'about-updates-item app-unsupported'},
$.span({className: 'about-updates-label is-strong'}, 'Your system does not support automatic updates'),
$.a({className: 'about-updates-instructions', onclick: this.props.viewUpdateInstructions}, 'How to update')
)
break
case UpdateManager.State.Error:
updateStatus = $.div({className: 'about-updates-item app-update-error'},
$.span({className: 'icon icon-x'}),
$.span({className: 'about-updates-label app-error-message is-strong'}, this.props.updateManager.getErrorMessage())
)
break
}
return updateStatus
}
render () {
return $.div({className: 'about-updates group-start'},
$.div({className: 'about-updates-box'},
$.div({className: 'about-updates-status'}, this.renderUpdateStatus()),
$.button(
{
className: 'btn about-update-action-button',
disabled: this.shouldUpdateActionButtonBeDisabled(),
onclick: this.executeUpdateAction.bind(this),
style: {
display: this.props.updateManager.state === UpdateManager.State.Unsupported ? 'none' : 'block'
}
},
this.props.updateManager.state === 'update-available' ? 'Restart and install' : 'Check now'
)
),
$.div(
{
className: 'about-auto-updates',
style: {
display: this.props.updateManager.state === UpdateManager.State.Unsupported ? 'none' : 'block'
}
},
$.label({},
$.input(
{
className: 'input-checkbox',
type: 'checkbox',
checked: this.props.updateManager.getAutoUpdatesEnabled(),
onchange: this.handleAutoUpdateCheckbox.bind(this)
}
),
$.span({}, 'Automatically download updates')
)
)
)
}
}

View File

@@ -0,0 +1,57 @@
const etch = require('etch')
/*
Public: Abstract class for handling the initialization
boilerplate of an Etch component.
*/
module.exports =
class EtchComponent {
constructor (props) {
this.props = props
etch.initialize(this)
EtchComponent.setScheduler(atom.views)
}
/*
Public: Gets the scheduler Etch uses for coordinating DOM updates.
Returns a {Scheduler}
*/
static getScheduler () {
return etch.getScheduler()
}
/*
Public: Sets the scheduler Etch uses for coordinating DOM updates.
* `scheduler` {Scheduler}
*/
static setScheduler (scheduler) {
etch.setScheduler(scheduler)
}
/*
Public: Updates the component's properties and re-renders it. Only the
properties you specify in this object will update any other properties
the component stores will be unaffected.
* `props` an {Object} representing the properties you want to update
*/
update (props) {
let oldProps = this.props
this.props = Object.assign({}, oldProps, props)
return etch.update(this)
}
/*
Public: Destroys the component, removing it from the DOM.
*/
destroy () {
etch.destroy(this)
}
render () {
throw new Error('Etch components must implement a `render` method')
}
}

View File

@@ -0,0 +1,96 @@
const {CompositeDisposable} = require('atom')
const semver = require('semver')
const UpdateManager = require('./update-manager')
const About = require('./about')
const StatusBarView = require('./components/about-status-bar')
let updateManager
// The local storage key for the available update version.
const AvailableUpdateVersion = 'about:version-available'
const AboutURI = 'atom://about'
module.exports = {
activate () {
this.subscriptions = new CompositeDisposable()
this.createModel()
let availableVersion = window.localStorage.getItem(AvailableUpdateVersion)
if (atom.getReleaseChannel() === 'dev' || (availableVersion && semver.lte(availableVersion, atom.getVersion()))) {
this.clearUpdateState()
}
this.subscriptions.add(updateManager.onDidChange(() => {
if (updateManager.getState() === UpdateManager.State.UpdateAvailableToInstall) {
window.localStorage.setItem(AvailableUpdateVersion, updateManager.getAvailableVersion())
this.showStatusBarIfNeeded()
}
}))
this.subscriptions.add(atom.commands.add('atom-workspace', 'about:clear-update-state', () => {
this.clearUpdateState()
}))
},
deactivate () {
this.model.destroy()
if (this.statusBarTile) this.statusBarTile.destroy()
if (updateManager) {
updateManager.dispose()
updateManager = undefined
}
},
clearUpdateState () {
window.localStorage.removeItem(AvailableUpdateVersion)
},
consumeStatusBar (statusBar) {
this.statusBar = statusBar
this.showStatusBarIfNeeded()
},
deserializeAboutView (state) {
if (!this.model) {
this.createModel()
}
return this.model.deserialize(state)
},
createModel () {
updateManager = updateManager || new UpdateManager()
this.model = new About({
uri: AboutURI,
currentAtomVersion: atom.getVersion(),
currentElectronVersion: process.versions.electron,
currentChromeVersion: process.versions.chrome,
currentNodeVersion: process.version,
updateManager: updateManager
})
},
isUpdateAvailable () {
let availableVersion = window.localStorage.getItem(AvailableUpdateVersion)
return availableVersion && semver.gt(availableVersion, atom.getVersion())
},
showStatusBarIfNeeded () {
if (this.isUpdateAvailable() && this.statusBar) {
let statusBarView = new StatusBarView()
if (this.statusBarTile) {
this.statusBarTile.destroy()
}
this.statusBarTile = this.statusBar.addRightTile({
item: statusBarView,
priority: -100
})
return this.statusBarTile
}
}
}

View File

@@ -0,0 +1,146 @@
const {Emitter, CompositeDisposable} = require('atom')
const Unsupported = 'unsupported'
const Idle = 'idle'
const CheckingForUpdate = 'checking'
const DownloadingUpdate = 'downloading'
const UpdateAvailableToInstall = 'update-available'
const UpToDate = 'no-update-available'
const ErrorState = 'error'
let UpdateManager = class UpdateManager {
constructor () {
this.emitter = new Emitter()
this.currentVersion = atom.getVersion()
this.availableVersion = atom.getVersion()
this.resetState()
this.listenForAtomEvents()
}
listenForAtomEvents () {
this.subscriptions = new CompositeDisposable()
this.subscriptions.add(
atom.autoUpdater.onDidBeginCheckingForUpdate(() => {
this.setState(CheckingForUpdate)
}),
atom.autoUpdater.onDidBeginDownloadingUpdate(() => {
this.setState(DownloadingUpdate)
}),
atom.autoUpdater.onDidCompleteDownloadingUpdate(({releaseVersion}) => {
this.setAvailableVersion(releaseVersion)
}),
atom.autoUpdater.onUpdateNotAvailable(() => {
this.setState(UpToDate)
}),
atom.autoUpdater.onUpdateError(() => {
this.setState(ErrorState)
}),
atom.config.observe('core.automaticallyUpdate', (value) => {
this.autoUpdatesEnabled = value
this.emitDidChange()
})
)
// TODO: When https://github.com/atom/electron/issues/4587 is closed we can add this support.
// atom.autoUpdater.onUpdateAvailable =>
// @find('.about-updates-item').removeClass('is-shown')
// @updateAvailable.addClass('is-shown')
}
dispose () {
this.subscriptions.dispose()
}
onDidChange (callback) {
return this.emitter.on('did-change', callback)
}
emitDidChange () {
this.emitter.emit('did-change')
}
getAutoUpdatesEnabled () {
return this.autoUpdatesEnabled && this.state !== UpdateManager.State.Unsupported
}
setAutoUpdatesEnabled (enabled) {
return atom.config.set('core.automaticallyUpdate', enabled)
}
getErrorMessage () {
return atom.autoUpdater.getErrorMessage()
}
getState () {
return this.state
}
setState (state) {
this.state = state
this.emitDidChange()
}
resetState () {
this.state = atom.autoUpdater.platformSupportsUpdates() ? atom.autoUpdater.getState() : Unsupported
this.emitDidChange()
}
getAvailableVersion () {
return this.availableVersion
}
setAvailableVersion (version) {
this.availableVersion = version
if (this.availableVersion !== this.currentVersion) {
this.state = UpdateAvailableToInstall
} else {
this.state = UpToDate
}
this.emitDidChange()
}
checkForUpdate () {
atom.autoUpdater.checkForUpdate()
}
restartAndInstallUpdate () {
atom.autoUpdater.restartAndInstallUpdate()
}
getReleaseNotesURLForCurrentVersion () {
return this.getReleaseNotesURLForVersion(this.currentVersion)
}
getReleaseNotesURLForAvailableVersion () {
return this.getReleaseNotesURLForVersion(this.availableVersion)
}
getReleaseNotesURLForVersion (appVersion) {
// Dev versions will not have a releases page
if (appVersion.indexOf('dev') > -1) {
return 'https://atom.io/releases'
}
if (!appVersion.startsWith('v')) {
appVersion = `v${appVersion}`
}
const releaseRepo = appVersion.indexOf('nightly') > -1 ? 'atom-nightly-releases' : 'atom'
return `https://github.com/atom/${releaseRepo}/releases/tag/${appVersion}`
}
}
UpdateManager.State = {
Unsupported: Unsupported,
Idle: Idle,
CheckingForUpdate: CheckingForUpdate,
DownloadingUpdate: DownloadingUpdate,
UpdateAvailableToInstall: UpdateAvailableToInstall,
UpToDate: UpToDate,
Error: ErrorState
}
module.exports = UpdateManager

1806
packages/about/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,44 @@
{
"name": "about",
"author": "Machisté N. Quintana <mnquintana@users.noreply.github.com>",
"main": "./lib/main",
"version": "1.9.1",
"description": "View useful information about your Atom installation.",
"keywords": [],
"repository": "https://github.com/atom/about",
"license": "MIT",
"scripts": {
"lint": "standard"
},
"engines": {
"atom": ">=1.7 <2.0.0"
},
"dependencies": {
"etch": "0.9.0",
"semver": "^5.5.0"
},
"devDependencies": {
"standard": "^11.0.0"
},
"consumedServices": {
"status-bar": {
"versions": {
"^1.0.0": "consumeStatusBar"
}
}
},
"deserializers": {
"AboutView": "deserializeAboutView"
},
"standard": {
"env": [
"browser",
"node",
"atomtest",
"jasmine"
],
"globals": [
"atom"
]
}
}

View File

@@ -0,0 +1,101 @@
const {it, fit, ffit, fffit, beforeEach, afterEach} = require('./helpers/async-spec-helpers') // eslint-disable-line no-unused-vars
describe('About', () => {
let workspaceElement
beforeEach(async () => {
let storage = {}
spyOn(window.localStorage, 'setItem').andCallFake((key, value) => {
storage[key] = value
})
spyOn(window.localStorage, 'getItem').andCallFake((key) => {
return storage[key]
})
workspaceElement = atom.views.getView(atom.workspace)
await atom.packages.activatePackage('about')
})
it('deserializes correctly', () => {
let deserializedAboutView = atom.deserializers.deserialize({
deserializer: 'AboutView',
uri: 'atom://about'
})
expect(deserializedAboutView).toBeTruthy()
})
describe('when the about:about-atom command is triggered', () => {
it('shows the About Atom view', async () => {
// Attaching the workspaceElement to the DOM is required to allow the
// `toBeVisible()` matchers to work. Anything testing visibility or focus
// requires that the workspaceElement is on the DOM. Tests that attach the
// workspaceElement to the DOM are generally slower than those off DOM.
jasmine.attachToDOM(workspaceElement)
expect(workspaceElement.querySelector('.about')).not.toExist()
await atom.workspace.open('atom://about')
let aboutElement = workspaceElement.querySelector('.about')
expect(aboutElement).toBeVisible()
})
})
describe('when the Atom version number is clicked', () => {
it('copies the version number to the clipboard', async () => {
await atom.workspace.open('atom://about')
let aboutElement = workspaceElement.querySelector('.about')
let versionContainer = aboutElement.querySelector('.atom')
versionContainer.click()
expect(atom.clipboard.read()).toBe(atom.getVersion())
})
})
describe('when the show more link is clicked', () => {
it('expands to show additional version numbers', async () => {
await atom.workspace.open('atom://about')
jasmine.attachToDOM(workspaceElement)
let aboutElement = workspaceElement.querySelector('.about')
let showMoreElement = aboutElement.querySelector('.show-more-expand')
let moreInfoElement = workspaceElement.querySelector('.show-more')
showMoreElement.click()
expect(moreInfoElement).toBeVisible()
})
})
describe('when the Electron version number is clicked', () => {
it('copies the version number to the clipboard', async () => {
await atom.workspace.open('atom://about')
let aboutElement = workspaceElement.querySelector('.about')
let versionContainer = aboutElement.querySelector('.electron')
versionContainer.click()
expect(atom.clipboard.read()).toBe(process.versions.electron)
})
})
describe('when the Chrome version number is clicked', () => {
it('copies the version number to the clipboard', async () => {
await atom.workspace.open('atom://about')
let aboutElement = workspaceElement.querySelector('.about')
let versionContainer = aboutElement.querySelector('.chrome')
versionContainer.click()
expect(atom.clipboard.read()).toBe(process.versions.chrome)
})
})
describe('when the Node version number is clicked', () => {
it('copies the version number to the clipboard', async () => {
await atom.workspace.open('atom://about')
let aboutElement = workspaceElement.querySelector('.about')
let versionContainer = aboutElement.querySelector('.node')
versionContainer.click()
expect(atom.clipboard.read()).toBe(process.version)
})
})
})

View File

@@ -0,0 +1,179 @@
const {it, fit, ffit, fffit, beforeEach, afterEach, conditionPromise} = require('./helpers/async-spec-helpers') // eslint-disable-line no-unused-vars
const MockUpdater = require('./mocks/updater')
describe('the status bar', () => {
let atomVersion
let workspaceElement
beforeEach(async () => {
let storage = {}
spyOn(window.localStorage, 'setItem').andCallFake((key, value) => {
storage[key] = value
})
spyOn(window.localStorage, 'getItem').andCallFake((key) => {
return storage[key]
})
spyOn(atom, 'getVersion').andCallFake(() => {
return atomVersion
})
workspaceElement = atom.views.getView(atom.workspace)
await atom.packages.activatePackage('status-bar')
await atom.workspace.open('sample.js')
})
afterEach(async () => {
await atom.packages.deactivatePackage('about')
await atom.packages.deactivatePackage('status-bar')
})
describe('on a stable version', function () {
beforeEach(async () => {
atomVersion = '1.2.3'
await atom.packages.activatePackage('about')
})
describe('with no update', () => {
it('does not show the view', () => {
expect(workspaceElement).not.toContain('.about-release-notes')
})
})
describe('with an update', () => {
it('shows the view when the update finishes downloading', () => {
MockUpdater.finishDownloadingUpdate('42.0.0')
expect(workspaceElement).toContain('.about-release-notes')
})
describe('clicking on the status', () => {
it('opens the about page', async () => {
MockUpdater.finishDownloadingUpdate('42.0.0')
workspaceElement.querySelector('.about-release-notes').click()
await conditionPromise(() => workspaceElement.querySelector('.about'))
expect(workspaceElement.querySelector('.about')).toExist()
})
})
it('continues to show the squirrel until Atom is updated to the new version', async () => {
MockUpdater.finishDownloadingUpdate('42.0.0')
expect(workspaceElement).toContain('.about-release-notes')
await atom.packages.deactivatePackage('about')
expect(workspaceElement).not.toContain('.about-release-notes')
await atom.packages.activatePackage('about')
await Promise.resolve() // Service consumption hooks are deferred until the next tick
expect(workspaceElement).toContain('.about-release-notes')
await atom.packages.deactivatePackage('about')
expect(workspaceElement).not.toContain('.about-release-notes')
atomVersion = '42.0.0'
await atom.packages.activatePackage('about')
await Promise.resolve() // Service consumption hooks are deferred until the next tick
expect(workspaceElement).not.toContain('.about-release-notes')
})
it('does not show the view if Atom is updated to a newer version than notified', async () => {
MockUpdater.finishDownloadingUpdate('42.0.0')
await atom.packages.deactivatePackage('about')
atomVersion = '43.0.0'
await atom.packages.activatePackage('about')
await Promise.resolve() // Service consumption hooks are deferred until the next tick
expect(workspaceElement).not.toContain('.about-release-notes')
})
})
})
describe('on a beta version', function () {
beforeEach(async () => {
atomVersion = '1.2.3-beta4'
await atom.packages.activatePackage('about')
})
describe('with no update', () => {
it('does not show the view', () => {
expect(workspaceElement).not.toContain('.about-release-notes')
})
})
describe('with an update', () => {
it('shows the view when the update finishes downloading', () => {
MockUpdater.finishDownloadingUpdate('42.0.0')
expect(workspaceElement).toContain('.about-release-notes')
})
describe('clicking on the status', () => {
it('opens the about page', async () => {
MockUpdater.finishDownloadingUpdate('42.0.0')
workspaceElement.querySelector('.about-release-notes').click()
await conditionPromise(() => workspaceElement.querySelector('.about'))
expect(workspaceElement.querySelector('.about')).toExist()
})
})
it('continues to show the squirrel until Atom is updated to the new version', async () => {
MockUpdater.finishDownloadingUpdate('42.0.0')
expect(workspaceElement).toContain('.about-release-notes')
await atom.packages.deactivatePackage('about')
expect(workspaceElement).not.toContain('.about-release-notes')
await atom.packages.activatePackage('about')
await Promise.resolve() // Service consumption hooks are deferred until the next tick
expect(workspaceElement).toContain('.about-release-notes')
await atom.packages.deactivatePackage('about')
expect(workspaceElement).not.toContain('.about-release-notes')
atomVersion = '42.0.0'
await atom.packages.activatePackage('about')
await Promise.resolve() // Service consumption hooks are deferred until the next tick
expect(workspaceElement).not.toContain('.about-release-notes')
})
it('does not show the view if Atom is updated to a newer version than notified', async () => {
MockUpdater.finishDownloadingUpdate('42.0.0')
await atom.packages.deactivatePackage('about')
atomVersion = '43.0.0'
await atom.packages.activatePackage('about')
await Promise.resolve() // Service consumption hooks are deferred until the next tick
expect(workspaceElement).not.toContain('.about-release-notes')
})
})
})
describe('on a development version', function () {
beforeEach(async () => {
atomVersion = '1.2.3-dev-0123abcd'
await atom.packages.activatePackage('about')
})
describe('with no update', () => {
it('does not show the view', () => {
expect(workspaceElement).not.toContain('.about-release-notes')
})
})
describe('with a previously downloaded update', () => {
it('does not show the view', () => {
window.localStorage.setItem('about:version-available', '42.0.0')
expect(workspaceElement).not.toContain('.about-release-notes')
})
})
})
})

View File

@@ -0,0 +1,65 @@
/** @babel */
const {now} = Date
const {setTimeout} = global
export function beforeEach (fn) {
global.beforeEach(function () {
const result = fn()
if (result instanceof Promise) {
waitsForPromise(() => result)
}
})
}
export function afterEach (fn) {
global.afterEach(function () {
const result = fn()
if (result instanceof Promise) {
waitsForPromise(() => result)
}
})
}
['it', 'fit', 'ffit', 'fffit'].forEach(function (name) {
module.exports[name] = function (description, fn) {
global[name](description, function () {
const result = fn()
if (result instanceof Promise) {
waitsForPromise(() => result)
}
})
}
})
export async function conditionPromise (condition) {
const startTime = now()
while (true) {
await timeoutPromise(100)
if (await condition()) {
return
}
if (now() - startTime > 5000) {
throw new Error('Timed out waiting on condition')
}
}
}
export function timeoutPromise (timeout) {
return new Promise(function (resolve) {
setTimeout(resolve, timeout)
})
}
function waitsForPromise (fn) {
const promise = fn()
global.waitsFor('spec promise to resolve', function (done) {
promise.then(done, function (error) {
jasmine.getEnv().currentSpec.fail(error)
done()
})
})
}

View File

@@ -0,0 +1,21 @@
module.exports = {
updateError () {
atom.autoUpdater.emitter.emit('update-error')
},
checkForUpdate () {
atom.autoUpdater.emitter.emit('did-begin-checking-for-update')
},
updateNotAvailable () {
atom.autoUpdater.emitter.emit('update-not-available')
},
downloadUpdate () {
atom.autoUpdater.emitter.emit('did-begin-downloading-update')
},
finishDownloadingUpdate (releaseVersion) {
atom.autoUpdater.emitter.emit('did-complete-downloading-update', {releaseVersion})
}
}

View File

@@ -0,0 +1,22 @@
const UpdateManager = require('../lib/update-manager')
describe('UpdateManager', () => {
let updateManager
beforeEach(() => {
updateManager = new UpdateManager()
})
describe('::getReleaseNotesURLForVersion', () => {
it('returns atom.io releases when dev version', () => {
expect(updateManager.getReleaseNotesURLForVersion('1.7.0-dev-e44b57d')).toContain('atom.io/releases')
})
it('returns the page for the release when not a dev version', () => {
expect(updateManager.getReleaseNotesURLForVersion('1.7.0')).toContain('atom/atom/releases/tag/v1.7.0')
expect(updateManager.getReleaseNotesURLForVersion('v1.7.0')).toContain('atom/atom/releases/tag/v1.7.0')
expect(updateManager.getReleaseNotesURLForVersion('1.7.0-beta10')).toContain('atom/atom/releases/tag/v1.7.0-beta10')
expect(updateManager.getReleaseNotesURLForVersion('1.7.0-nightly10')).toContain('atom/atom-nightly-releases/releases/tag/v1.7.0-nightly10')
})
})
})

View File

@@ -0,0 +1,280 @@
const {shell} = require('electron')
const {it, fit, ffit, fffit, beforeEach, afterEach} = require('./helpers/async-spec-helpers') // eslint-disable-line no-unused-vars
const main = require('../lib/main')
const AboutView = require('../lib/components/about-view')
const UpdateView = require('../lib/components/update-view')
const MockUpdater = require('./mocks/updater')
describe('UpdateView', () => {
let aboutElement
let updateManager
let workspaceElement
let scheduler
beforeEach(async () => {
let storage = {}
spyOn(window.localStorage, 'setItem').andCallFake((key, value) => {
storage[key] = value
})
spyOn(window.localStorage, 'getItem').andCallFake((key) => {
return storage[key]
})
workspaceElement = atom.views.getView(atom.workspace)
await atom.packages.activatePackage('about')
spyOn(atom.autoUpdater, 'getState').andReturn('idle')
spyOn(atom.autoUpdater, 'checkForUpdate')
spyOn(atom.autoUpdater, 'platformSupportsUpdates').andReturn(true)
})
describe('when the About page is open', () => {
beforeEach(async () => {
jasmine.attachToDOM(workspaceElement)
await atom.workspace.open('atom://about')
aboutElement = workspaceElement.querySelector('.about')
updateManager = main.model.state.updateManager
scheduler = AboutView.getScheduler()
})
describe('when the updates are not supported by the platform', () => {
beforeEach(async () => {
atom.autoUpdater.platformSupportsUpdates.andReturn(false)
updateManager.resetState()
await scheduler.getNextUpdatePromise()
})
it('hides the auto update UI and shows the update instructions link', async () => {
expect(aboutElement.querySelector('.about-update-action-button')).not.toBeVisible()
expect(aboutElement.querySelector('.about-auto-updates')).not.toBeVisible()
})
it('opens the update instructions page when the instructions link is clicked', async () => {
spyOn(shell, 'openExternal')
let link = aboutElement.querySelector('.app-unsupported .about-updates-instructions')
link.click()
let args = shell.openExternal.mostRecentCall.args
expect(shell.openExternal).toHaveBeenCalled()
expect(args[0]).toContain('installing-atom')
})
})
describe('when updates are supported by the platform', () => {
beforeEach(async () => {
atom.autoUpdater.platformSupportsUpdates.andReturn(true)
updateManager.resetState()
await scheduler.getNextUpdatePromise()
})
it('shows the auto update UI', () => {
expect(aboutElement.querySelector('.about-updates')).toBeVisible()
})
it('shows the correct panels when the app checks for updates and there is no update available', async () => {
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
MockUpdater.checkForUpdate()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-up-to-date')).not.toBeVisible()
expect(aboutElement.querySelector('.app-checking-for-updates')).toBeVisible()
MockUpdater.updateNotAvailable()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-up-to-date')).toBeVisible()
expect(aboutElement.querySelector('.app-checking-for-updates')).not.toBeVisible()
})
it('shows the correct panels when the app checks for updates and encounters an error', async () => {
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
MockUpdater.checkForUpdate()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-up-to-date')).not.toBeVisible()
expect(aboutElement.querySelector('.app-checking-for-updates')).toBeVisible()
spyOn(atom.autoUpdater, 'getErrorMessage').andReturn('an error message')
MockUpdater.updateError()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-update-error')).toBeVisible()
expect(aboutElement.querySelector('.app-error-message').textContent).toBe('an error message')
expect(aboutElement.querySelector('.app-checking-for-updates')).not.toBeVisible()
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(false)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Check now')
})
it('shows the correct panels and button states when the app checks for updates and an update is downloaded', async () => {
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(false)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Check now')
MockUpdater.checkForUpdate()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-up-to-date')).not.toBeVisible()
expect(aboutElement.querySelector('.app-checking-for-updates')).toBeVisible()
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(true)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Check now')
MockUpdater.downloadUpdate()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-checking-for-updates')).not.toBeVisible()
expect(aboutElement.querySelector('.app-downloading-update')).toBeVisible()
// TODO: at some point it would be nice to be able to cancel an update download, and then this would be a cancel button
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(true)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Check now')
MockUpdater.finishDownloadingUpdate('42.0.0')
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-downloading-update')).not.toBeVisible()
expect(aboutElement.querySelector('.app-update-available-to-install')).toBeVisible()
expect(aboutElement.querySelector('.app-update-available-to-install .about-updates-version').textContent).toBe('42.0.0')
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(false)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Restart and install')
})
it('opens the release notes for the downloaded release when the release notes link are clicked', async () => {
MockUpdater.finishDownloadingUpdate('1.2.3')
await scheduler.getNextUpdatePromise()
spyOn(shell, 'openExternal')
let link = aboutElement.querySelector('.app-update-available-to-install .about-updates-release-notes')
link.click()
let args = shell.openExternal.mostRecentCall.args
expect(shell.openExternal).toHaveBeenCalled()
expect(args[0]).toContain('/v1.2.3')
})
it('executes checkForUpdate() when the check for update button is clicked', () => {
let button = aboutElement.querySelector('.about-update-action-button')
button.click()
expect(atom.autoUpdater.checkForUpdate).toHaveBeenCalled()
})
it('executes restartAndInstallUpdate() when the restart and install button is clicked', async () => {
spyOn(atom.autoUpdater, 'restartAndInstallUpdate')
MockUpdater.finishDownloadingUpdate('42.0.0')
await scheduler.getNextUpdatePromise()
let button = aboutElement.querySelector('.about-update-action-button')
button.click()
expect(atom.autoUpdater.restartAndInstallUpdate).toHaveBeenCalled()
})
it("starts in the same state as atom's AutoUpdateManager", async () => {
atom.autoUpdater.getState.andReturn('downloading')
updateManager.resetState()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-checking-for-updates')).not.toBeVisible()
expect(aboutElement.querySelector('.app-downloading-update')).toBeVisible()
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(true)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Check now')
})
describe('when core.automaticallyUpdate is toggled', () => {
beforeEach(async () => {
expect(atom.config.get('core.automaticallyUpdate')).toBe(true)
atom.autoUpdater.checkForUpdate.reset()
})
it('shows the auto update UI', async () => {
expect(aboutElement.querySelector('.about-auto-updates input').checked).toBe(true)
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
expect(aboutElement.querySelector('.about-default-update-message').textContent).toBe('Atom will check for updates automatically')
atom.config.set('core.automaticallyUpdate', false)
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.about-auto-updates input').checked).toBe(false)
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
expect(aboutElement.querySelector('.about-default-update-message').textContent).toBe('Automatic updates are disabled please check manually')
})
it('updates config and the UI when the checkbox is used to toggle', async () => {
expect(aboutElement.querySelector('.about-auto-updates input').checked).toBe(true)
aboutElement.querySelector('.about-auto-updates input').click()
await scheduler.getNextUpdatePromise()
expect(atom.config.get('core.automaticallyUpdate')).toBe(false)
expect(aboutElement.querySelector('.about-auto-updates input').checked).toBe(false)
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
expect(aboutElement.querySelector('.about-default-update-message').textContent).toBe('Automatic updates are disabled please check manually')
aboutElement.querySelector('.about-auto-updates input').click()
await scheduler.getNextUpdatePromise()
expect(atom.config.get('core.automaticallyUpdate')).toBe(true)
expect(aboutElement.querySelector('.about-auto-updates input').checked).toBe(true)
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
expect(aboutElement.querySelector('.about-default-update-message').textContent).toBe('Atom will check for updates automatically')
})
describe('checking for updates', function () {
afterEach(() => {
this.updateView = null
})
it('checks for update when the about page is shown', () => {
expect(atom.autoUpdater.checkForUpdate).not.toHaveBeenCalled()
this.updateView = new UpdateView({
updateManager: updateManager,
availableVersion: '9999.0.0',
viewUpdateReleaseNotes: () => {}
})
expect(atom.autoUpdater.checkForUpdate).toHaveBeenCalled()
})
it('does not check for update when the about page is shown and the update manager is not in the idle state', () => {
atom.autoUpdater.getState.andReturn('downloading')
updateManager.resetState()
expect(atom.autoUpdater.checkForUpdate).not.toHaveBeenCalled()
this.updateView = new UpdateView({
updateManager: updateManager,
availableVersion: '9999.0.0',
viewUpdateReleaseNotes: () => {}
})
expect(atom.autoUpdater.checkForUpdate).not.toHaveBeenCalled()
})
it('does not check for update when the about page is shown and auto updates are turned off', () => {
atom.config.set('core.automaticallyUpdate', false)
expect(atom.autoUpdater.checkForUpdate).not.toHaveBeenCalled()
this.updateView = new UpdateView({
updateManager: updateManager,
availableVersion: '9999.0.0',
viewUpdateReleaseNotes: () => {}
})
expect(atom.autoUpdater.checkForUpdate).not.toHaveBeenCalled()
})
})
})
})
})
describe('when the About page is not open and an update is downloaded', () => {
it('should display the new version when it is opened', async () => {
MockUpdater.finishDownloadingUpdate('42.0.0')
jasmine.attachToDOM(workspaceElement)
await atom.workspace.open('atom://about')
aboutElement = workspaceElement.querySelector('.about')
updateManager = main.model.state.updateManager
scheduler = AboutView.getScheduler()
expect(aboutElement.querySelector('.app-update-available-to-install')).toBeVisible()
expect(aboutElement.querySelector('.app-update-available-to-install .about-updates-version').textContent).toBe('42.0.0')
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(false)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Restart and install')
})
})
})

View File

@@ -0,0 +1,175 @@
@import "ui-variables";
@import "variables";
.about {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
-webkit-user-select: none;
cursor: default;
overflow: auto;
text-align: center;
font-size: 1.25em;
line-height: 1.4;
padding: 4em;
color: @text-color;
background-color: @base-background-color;
button {
cursor: default;
}
a:focus {
// Don't use Bootstrap default here
color: inherit;
}
img, a {
-webkit-user-drag: none;
}
.input-checkbox {
margin-top: -.2em;
}
// used to group different elements
.group-start {
margin-top: 4em;
}
.group-item {
margin-top: 1.5em;
}
}
.about-container {
width: 100%;
max-width: 500px;
}
// Header --------------------------------
.about-atom-io:hover {
.about-logo {
color: @atom-green;
}
}
.about-logo {
display: block;
width: 100%;
max-width: 280px;
margin: 0 auto 1em auto;
color: @text-color-highlight;
transition: color 0.2s;
}
.about-version-container {
&:hover {
color: lighten(@text-color, 15%);
}
&:active {
color: lighten(@text-color, 30%);
}
}
.about-version {
margin-right: .5em;
font-size: 1.25em;
vertical-align: middle;
}
.about-more-version {
color: @text-color-subtle;
font-size: .9em;
}
.about-header-release-notes {
vertical-align: middle;
margin-left: 1em;
}
// Updates --------------------------------
.about-updates {
width: 100%;
max-width: 500px;
}
.about-updates-box {
display: flex;
align-items: center;
padding: @component-padding;
border: 1px solid @base-border-color;
border-radius: @component-border-radius * 2;
background-color: @background-color-highlight;
}
.about-updates-status {
flex: 1;
margin-left: .5em;
text-align: left;
}
.about-updates-item,
.about-default-update-message .about-updates-label {
display: block;
}
.about-updates-label {
color: @text-color-subtle;
&.is-strong {
color: @text-color;
}
}
.about-updates-version {
margin: 0 .4em;
}
.about-updates-release-notes,
.about-updates-instructions {
margin: 0 1em 0 1.5em;
}
.about-auto-updates {
margin-top: 1em;
input {
margin-right: .5em;
}
}
// Love --------------------------------
.about-love {
.icon::before {
// Make these octicons look good inlined with text
position: relative;
width: auto;
height: auto;
margin-right: 0;
font-size: 1.5em;
vertical-align: text-top;
}
.icon-logo-github::before {
font-size: 3.6em;
height: .36em;
}
}
.about-credits {
color: @text-color-subtle;
}
// the blue squirrel --------------------------------
.about-release-notes {
color: @background-color-info;
&:hover {
color: lighten(@background-color-info, 15%);
}
}

View File

@@ -0,0 +1 @@
@atom-green: #40a977;

View File

@@ -0,0 +1 @@
spec/fixtures

1
packages/one-light-ui/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
node_modules

View File

@@ -0,0 +1,20 @@
Copyright (c) 2014 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,42 @@
## One Light UI theme
A light UI theme that adapts to most syntax themes.
![One light UI](https://cloud.githubusercontent.com/assets/378023/26246819/0826f04e-3cd6-11e7-98eb-cd94bc48b090.png)
> The font used in the screenshot is [Fira Mono](https://github.com/mozilla/Fira).
### Install
This theme comes bundled with Atom and can be activated by going to the __Settings > Themes__ section and selecting "One Light" from the __UI Themes__ drop-down menu.
### Settings
In the theme settings you can:
- Change the __Font Size__ to scale the whole UI up or down.
- Choose between 3 __Tab Sizing__ modes.
- Hide the __dock buttons__.
To make changes, go to `Settings > Themes > One Light UI > Settings` or the cog icon next to the theme picker.
### Customize
It's also possible to resize only certain areas by adding the following to your `styles.less` (Use DevTools to find the right selectors):
```css
.theme-one-light-ui {
.tab-bar { font-size: 18px; }
.tree-view { font-size: 14px; }
.status-bar { font-size: 12px; }
}
```
### FAQ
__Why do the colors change when I switch Syntax themes.__
This UI theme uses the same background color as the chosen syntax theme. If that syntax theme has a dark background color, it only uses its hue, but otherwise stays light. This lets you use light-dark combos.

View File

@@ -0,0 +1,37 @@
{
"max_line_length": {
"level": "ignore"
},
"no_empty_param_list": {
"level": "error"
},
"arrow_spacing": {
"level": "error"
},
"no_interpolation_in_single_quotes": {
"level": "error"
},
"no_debugger": {
"level": "error"
},
"prefer_english_operator": {
"level": "error"
},
"colon_assignment_spacing": {
"spacing": {
"left": 0,
"right": 1
},
"level": "error"
},
"braces_spacing": {
"spaces": 0,
"level": "error"
},
"spacing_after_comma": {
"level": "error"
},
"no_stand_alone_at": {
"level": "error"
}
}

View File

@@ -0,0 +1,35 @@
// Atom UI Theme: One
@import "styles/ui-variables.less";
@import "styles/ui-mixins.less";
@import "octicon-mixins.less"; // https://github.com/atom/atom/blob/master/static/variables/octicon-mixins.less
@import "styles/atom.less";
@import "styles/badges.less";
@import "styles/buttons.less";
@import "styles/docks.less";
@import "styles/editor.less";
@import "styles/git.less";
@import "styles/inputs.less";
@import "styles/lists.less";
@import "styles/messages.less";
@import "styles/nav.less";
@import "styles/notifications.less";
@import "styles/modal.less";
@import "styles/panels.less";
@import "styles/panes.less";
@import "styles/progress.less";
@import "styles/tabs.less";
@import "styles/text.less";
@import "styles/title-bar.less";
@import "styles/tooltips.less";
@import "styles/tree-view.less";
@import "styles/status-bar.less";
@import "styles/key-binding.less";
@import "styles/sites.less";
@import "styles/settings.less";
@import "styles/packages.less";
@import "styles/core.less";
@import "styles/config.less";

View File

@@ -0,0 +1,86 @@
root = document.documentElement
themeName = 'one-light-ui'
module.exports =
activate: (state) ->
atom.config.observe "#{themeName}.fontSize", (value) ->
setFontSize(value)
atom.config.observe "#{themeName}.tabSizing", (value) ->
setTabSizing(value)
atom.config.observe "#{themeName}.tabCloseButton", (value) ->
setTabCloseButton(value)
atom.config.observe "#{themeName}.hideDockButtons", (value) ->
setHideDockButtons(value)
atom.config.observe "#{themeName}.stickyHeaders", (value) ->
setStickyHeaders(value)
# DEPRECATED: This can be removed at some point (added in Atom 1.17/1.18ish)
# It removes `layoutMode`
if atom.config.get("#{themeName}.layoutMode")
atom.config.unset("#{themeName}.layoutMode")
deactivate: ->
unsetFontSize()
unsetTabSizing()
unsetTabCloseButton()
unsetHideDockButtons()
unsetStickyHeaders()
# Font Size -----------------------
setFontSize = (currentFontSize) ->
root.style.fontSize = "#{currentFontSize}px"
unsetFontSize = ->
root.style.fontSize = ''
# Tab Sizing -----------------------
setTabSizing = (tabSizing) ->
root.setAttribute("theme-#{themeName}-tabsizing", tabSizing.toLowerCase())
unsetTabSizing = ->
root.removeAttribute("theme-#{themeName}-tabsizing")
# Tab Close Button -----------------------
setTabCloseButton = (tabCloseButton) ->
if tabCloseButton is 'Left'
root.setAttribute("theme-#{themeName}-tab-close-button", 'left')
else
unsetTabCloseButton()
unsetTabCloseButton = ->
root.removeAttribute("theme-#{themeName}-tab-close-button")
# Dock Buttons -----------------------
setHideDockButtons = (hideDockButtons) ->
if hideDockButtons
root.setAttribute("theme-#{themeName}-dock-buttons", 'hidden')
else
unsetHideDockButtons()
unsetHideDockButtons = ->
root.removeAttribute("theme-#{themeName}-dock-buttons")
# Sticky Headers -----------------------
setStickyHeaders = (stickyHeaders) ->
if stickyHeaders
root.setAttribute("theme-#{themeName}-sticky-headers", 'sticky')
else
unsetStickyHeaders()
unsetStickyHeaders = ->
root.removeAttribute("theme-#{themeName}-sticky-headers")

View File

@@ -0,0 +1,78 @@
{
"name": "one-light-ui",
"theme": "ui",
"version": "1.12.5",
"description": "Atom One light UI theme",
"keywords": [
"light",
"adaptive",
"ui"
],
"license": "MIT",
"repository": "https://github.com/atom/one-light-ui",
"main": "lib/main",
"engines": {
"atom": ">0.40.0"
},
"devDependencies": {
"coffeelint": "^1.9.7"
},
"configSchema": {
"fontSize": {
"title": "Font Size",
"description": "Change the font size for the UI.",
"type": "integer",
"default": 12,
"enum": [
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20
],
"order": 1
},
"tabSizing": {
"title": "Tab Sizing",
"description": "In Even mode all tabs will be the same size. Great for quickly closing many tabs. In Maximum mode the tabs will expand to take up the full width. In Minimum mode the tabs will only take as little space as needed and also show longer file names.",
"type": "string",
"default": "Even",
"enum": [
"Even",
"Maximum",
"Minimum"
],
"order": 2
},
"tabCloseButton": {
"title": "Tab Close Button",
"description": "Choose the position of the close button shown in tabs.",
"type": "string",
"default": "Right",
"enum": [
"Left",
"Right"
],
"order": 3
},
"hideDockButtons": {
"title": "Hide dock toggle buttons",
"description": "Note: When hiding the toggle buttons, opening a dock needs to be done by using the keyboard or other alternatives.",
"type": "boolean",
"default": "false",
"order": 4
},
"stickyHeaders": {
"title": "Make tree-view project headers sticky",
"type": "boolean",
"default": "false",
"order": 5
}
}
}

View File

@@ -0,0 +1,36 @@
themeName = 'one-light-ui'
describe "#{themeName} theme", ->
beforeEach ->
waitsForPromise ->
atom.packages.activatePackage(themeName)
it "allows the font size to be set via config", ->
expect(document.documentElement.style.fontSize).toBe '12px'
atom.config.set("#{themeName}.fontSize", '10')
expect(document.documentElement.style.fontSize).toBe '10px'
it "allows the tab sizing to be set via config", ->
atom.config.set("#{themeName}.tabSizing", 'Maximum')
expect(document.documentElement.getAttribute("theme-#{themeName}-tabsizing")).toBe 'maximum'
it "allows the tab sizing to be set via config", ->
atom.config.set("#{themeName}.tabSizing", 'Minimum')
expect(document.documentElement.getAttribute("theme-#{themeName}-tabsizing")).toBe 'minimum'
it "allows the tab close button to be shown on the left via config", ->
atom.config.set("#{themeName}.tabCloseButton", 'Left')
expect(document.documentElement.getAttribute("theme-#{themeName}-tab-close-button")).toBe 'left'
it "allows the dock toggle buttons to be hidden via config", ->
atom.config.set("#{themeName}.hideDockButtons", true)
expect(document.documentElement.getAttribute("theme-#{themeName}-dock-buttons")).toBe 'hidden'
it "allows the tree-view headers to be sticky via config", ->
atom.config.set("#{themeName}.stickyHeaders", true)
expect(document.documentElement.getAttribute("theme-#{themeName}-sticky-headers")).toBe 'sticky'
it "allows the tree-view headers to not be sticky via config", ->
atom.config.set("#{themeName}.stickyHeaders", false)
expect(document.documentElement.getAttribute("theme-#{themeName}-sticky-headers")).toBe null

View File

@@ -0,0 +1,67 @@
* {
box-sizing: border-box;
}
html {
font-size: @font-size;
}
atom-workspace {
background-color: @app-background-color;
}
// Scrollbars ------------------------------------
.scrollbars-visible-always {
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
background: @scrollbar-background-color;
}
::-webkit-scrollbar-thumb {
border-radius: 5px;
border: 3px solid @scrollbar-background-color;
background: @scrollbar-color;
background-clip: content-box;
}
::-webkit-scrollbar-corner {
background: @scrollbar-background-color;
}
::-webkit-scrollbar-thumb:vertical:active {
border-radius: 0;
border-left-width: 0;
border-right-width: 0;
}
::-webkit-scrollbar-thumb:horizontal:active {
border-radius: 0;
border-top-width: 0;
border-bottom-width: 0;
}
atom-text-editor {
::-webkit-scrollbar-track {
background: @scrollbar-background-color-editor;
}
::-webkit-scrollbar-corner {
background: @scrollbar-background-color-editor;
}
::-webkit-scrollbar-thumb {
border-color: @scrollbar-background-color-editor;
background: @scrollbar-color-editor;
}
}
}
// TODO: Move to a better place, not sure where it gets used
.caret {
border-top: 5px solid #fff;
margin-top: -1px;
}

View File

@@ -0,0 +1,14 @@
.badge {
padding: @ui-padding/4 @ui-padding/2.5;
min-width: @ui-padding*1.25;
.text(highlight);
border-radius: @ui-size*2;
background-color: @badge-background-color;
// Icon ----------------------
&.icon {
font-size: @ui-size;
padding: @ui-padding-icon @ui-padding-icon*1.5;
}
}

View File

@@ -0,0 +1,186 @@
@btn-border: 1px solid @button-border-color;
@btn-padding: 0 @ui-size/1.25;
// Mixins -----------------------
.btn-default (@color, @hover-color, @selected-color, @text-color) {
color: @text-color;
text-shadow: none;
border: @btn-border;
background-color: @color;
background-image: linear-gradient(lighten(@color, 2%), @color);
&:hover {
color: @text-color-highlight;
background-image: linear-gradient(lighten(@hover-color, 2%), @hover-color);
}
&:active {
background: darken(@color, 4%);
box-shadow: none;
}
&.selected {
background: @selected-color;
}
&.selected:focus,
&.selected:hover {
background: lighten(@selected-color, 2%);
}
&:focus {
.focus(); // unfortunately :focus styles stay even after releasing mouse.
}
}
.btn-variant (@color) {
@_text-color: contrast(@color, white, hsl(0,0%,20%), 33% );
.btn-default(
@color,
lighten(@color, 3%),
saturate(darken(@color, 12%), 20%),
@text-color-highlight
);
color: @_text-color;
& when (@ui-lightness > 50%) {
border-color: transparent; // hide border on light backgrounds
}
&:hover,
&:focus {
color: @_text-color;
}
&:focus {
border-color: transparent;
background-clip: padding-box;
box-shadow: inset 0 0 0 1px fade(@base-border-color, 50%), 0 0 0 1px @color;
}
&.icon:before {
color: @_text-color;
}
}
// Buttons -----------------------
.btn {
height: initial;
padding: @btn-padding;
font-size: @ui-size;
line-height: @ui-line-height;
}
.btn,
.btn.btn-default {
.btn-default(@button-background-color, @button-background-color-hover, @button-background-color-selected, @text-color);
}
.btn.btn-primary {
.btn-variant(@accent-bg-color);
}
.btn.btn-info {
.btn-variant(@background-color-info);
}
.btn.btn-success {
.btn-variant(@background-color-success);
}
.btn.btn-warning {
.btn-variant(@background-color-warning);
}
.btn.btn-error {
.btn-variant(@background-color-error);
}
// Button Sizes -----------------------
.btn.btn-xs,
.btn-group-xs > .btn {
font-size: @ui-size*.8;
line-height: @ui-line-height;
padding: @btn-padding;
}
.btn.btn-sm,
.btn-group-sm > .btn {
font-size: @ui-size*.9;
line-height: @ui-line-height;
padding: @btn-padding;
}
.btn.btn-lg,
.btn-group-lg > .btn {
font-size: @ui-size * 1.5;
line-height: @ui-line-height;
padding: @btn-padding;
}
// Button Group -----------------------
.btn-group > .btn {
z-index: 0;
&:hover {
z-index: 0;
}
&.btn:focus {
z-index: 1;
.focus();
}
&:first-child {
border-left: @btn-border;
}
&:last-child,
&.selected:last-child {
border-right: @btn-border;
}
// hide border on light backgrounds
& when (@ui-lightness > 50%) {
&.btn-primary:first-child,
&.btn-info:first-child,
&.btn-success:first-child,
&.btn-warning:first-child,
&.btn-error:first-child {
border-left-color: transparent;
}
&.btn-primary:last-child,
&.btn-info:last-child,
&.btn-success:last-child,
&.btn-warning:last-child,
&.btn-error:last-child {
border-right-color: transparent;
}
}
&.selected,
&.selected:first-child,
&.selected:last-child {
color: @button-text-color-selected;
border-color: @button-border-color-selected;
}
& when (@ui-lightness > 50%) {
&.selected + .btn {
border-left-color: @button-border-color-selected;
}
&.selected + .selected {
border-left-color: mix(@button-border-color, @button-border-color-selected);
}
}
&.selected:focus {
border-color: @button-background-color-selected;
box-shadow: inset 0 0 0 1px fade(@base-border-color, 50%), 0 0 0 1px @button-background-color-selected;
}
}
// Button Icons -----------------------
.btn.icon:before {
width: auto;
height: auto;
font-size: 1.333333em;
vertical-align: -.1em;
}

View File

@@ -0,0 +1,156 @@
// Theme config
// This gets changed from the theme settings
@theme-tabsizing: ~'theme-@{ui-theme-name}-tabsizing';
@theme-dockButtons: ~'theme-@{ui-theme-name}-dock-buttons';
@theme-stickyHeaders: ~'theme-@{ui-theme-name}-sticky-headers';
@theme-closeButton: ~'theme-@{ui-theme-name}-tab-close-button';
// Tabs ----------------------------------------------
@tab-min-width: 7em; // ~ icon + 6 characters
// Even (default)
.tab-bar {
.tab,
.tab.active {
flex: 1 1 0;
max-width: 22em;
min-width: @tab-min-width;
}
atom-dock & {
.tab,
.tab.active {
max-width: none;
}
}
// TODO: Turn this into a config
// Truncates the beginning instead
// .title.title.title {
// direction: rtl; // change direction
// }
}
// Maximum (full width)
[@{theme-tabsizing}="maximum"] .tab-bar {
.tab,
.tab.active {
max-width: none;
}
}
// Minimum (show long paths)
[@{theme-tabsizing}="minimum"] .tab-bar {
.tab,
.tab.active {
flex: 0 0 auto;
min-width: 2.75em;
max-width: @tab-min-width * 3.3;
}
atom-dock {
.tab,
.tab.active {
max-width: @tab-min-width * 2;
}
}
}
// Tabs: close button position ------------------------------
[@{theme-closeButton}="left"] {
.tab-bar .tab {
.close-icon {
right: auto;
left: @icon-padding-right;
}
}
}
// Hide docks toggle buttons ------------------------------
[@{theme-dockButtons}="hidden"] {
// Hide docks when not open
.atom-dock-inner:not(.atom-dock-open) {
display: none;
}
// Hide toggle buttons
.atom-dock-toggle-button {
display: none;
}
}
// Sticky Projects ------------------------------
[@{theme-stickyHeaders}="sticky"] {
.tree-view {
.project-root-header {
position: sticky;
top: 0;
z-index: 3;
padding-left: 5px;
padding-right: 10px;
border-bottom: 1px solid @base-border-color;
background-color: @tree-view-background-color;
}
.project-root.project-root {
margin-left: -5px;
margin-right: -10px;
// Disable selection
&::before {
display: none;
}
// Add selection back
&.selected .project-root-header {
background-color: @background-color-selected;
}
}
&:focus .selected .project-root-header.project-root-header {
background: @button-background-color-selected;
}
// Fix sticky header from covering auto-revealed files
.entry.file.selected {
padding-top: @ui-tab-height;
margin-top: -@ui-tab-height;
}
// Fix sticky header from covering auto-revealed directories when using up/down keys
// for directories, scroll test moves to .header, see https://github.com/atom/tree-view/blob/d2857ad4d7eeb7dad5cf94b33257a8740211480e/lib/tree-view.coffee#L839
.entry.directory.selected:not(.project-root) {
& > .header {
padding-top: @ui-tab-height;
margin-top: -@ui-tab-height;
}
&::before {
margin-top: @ui-tab-height;
}
}
// Fix above directory is not being clickable
.entry.directory:not(.project-root) > .header {
z-index: 2;
}
.entry.directory.selected:not(.project-root) > .header {
z-index: 1;
}
}
}

View File

@@ -0,0 +1,25 @@
// Misc
.preview-pane .results-view .path-match-number {
// show number also on selected item
color: inherit;
opacity: .6;
}
.tool-panel.incompatible-packages {
// incompatible-packages isn't really a tool-panel and more a whole pane
.text(normal);
background-color: @level-2-color;
}
// Styleguide ----------------------------------------------
.styleguide {
// Modal
atom-panel.modal:after {
position: absolute; // prevent overlay backdrop from leaking outside
left: -@ui-padding;
right: -@ui-padding;
bottom: -@ui-padding;
}
}

View File

@@ -0,0 +1,43 @@
// Docks ------------------------------
// Make handles not take up any space when dock is open
.atom-dock-resize-handle {
position: absolute;
z-index: 11; // same as toggle buttons
&.left {
top: 0;
right: 0;
bottom: 0;
}
&.right {
top: 0;
left: 0;
bottom: 0;
}
&.bottom {
top: 0;
left: 0;
right: 0;
}
}
// Add borders
.atom-dock-inner.atom-dock-open.left {
border-right: 1px solid @base-border-color;
}
.atom-dock-inner.atom-dock-open.right {
border-left: 1px solid @base-border-color;
}
// Make toggle buttons cover ^ border
.atom-dock-toggle-button.left {
margin-left: -2px;
}
.atom-dock-toggle-button.right {
margin-right: -2px;
}
.atom-dock-inner:not(.atom-dock-open) .atom-dock-toggle-button.bottom {
margin-bottom: -1px;
}

View File

@@ -0,0 +1,15 @@
.dropdown-menu {
background-color: @overlay-background-color;
border-radius: @component-border-radius;
border: 1px solid @base-border-color;
padding: 0;
> li > a {
.text(normal);
}
> li > a:hover {
.text(highlight);
background-color: @background-color-highlight;
}
}

View File

@@ -0,0 +1,44 @@
// Editor in a panel
// TODO: Find a better selector, maybe a new class like atom-text-editor[medium]
atom-panel-container atom-text-editor.is-focused {
.focus();
}
// Mini
// Usually just single line inputs
atom-text-editor[mini] {
overflow: auto;
font-size: @ui-input-size;
line-height: @ui-line-height;
max-height: @ui-line-height * 5; // rows
padding-left: @ui-padding/3;
border-radius: @component-border-radius;
color: @text-color-highlight;
border: 1px solid @input-border-color;
background-color: @input-background-color;
.placeholder-text {
color: @text-color-subtle;
}
.selection .region {
background-color: @input-selection-color;
}
.cursor {
border-color: @accent-color;
border-width: 2px;
}
&.is-focused {
.focus();
background-color: @input-background-color-focus;
.selection .region {
background-color: @input-selection-color-focus;
}
}
}

View File

@@ -0,0 +1,6 @@
.status { .text(normal); }
.status-added { .text(success); } // green
.status-ignored { .text(subtle); } // faded
.status-modified { .text(warning); } // orange
.status-removed { .text(error); } // red
.status-renamed { .text(info); } // blue

View File

@@ -0,0 +1,87 @@
//
// Checkbox
// -------------------------
.input-checkbox {
&:active {
background-color: @accent-color;
}
&:before,
&:after {
background-color: @accent-text-color;
}
&:checked {
background-color: @accent-color;
}
&:indeterminate {
background-color: @accent-color;
}
}
//
// Radio
// -------------------------
.input-radio {
&:before {
background-color: @accent-text-color;
}
&:active {
background-color: @accent-color;
}
&:checked {
background-color: @accent-color;
}
}
//
// Range (Slider)
// -------------------------
.input-range {
&::-webkit-slider-thumb {
background-color: @accent-color;
}
}
//
// Toggle
// -------------------------
.input-toggle {
&:checked {
background-color: @accent-color;
}
&:before {
background-color: @accent-text-color;
}
}
// States -------------------------
.input-text,
.input-search,
.input-number,
.input-textarea,
.input-select,
.input-color {
&:focus {
.focus();
}
}
.input-text,
.input-search,
.input-number,
.input-textarea {
&:invalid {
.invalid();
}
}

View File

@@ -0,0 +1,12 @@
.key-binding {
display: inline-block;
margin-left: @ui-padding-icon;
padding: 0 @ui-padding/4;
line-height: 2;
font-family: inherit;
font-size: max(1em, @ui-size*.85);
letter-spacing: @ui-size/10;
border-radius: @component-border-radius;
color: @accent-bg-text-color;
background-color: @accent-bg-color;
}

View File

@@ -0,0 +1,150 @@
.list-group,
.list-tree {
li:not(.list-nested-item),
li.list-nested-item > .list-item {
.text(normal);
}
.generate-list-item-text-color(@class) {
li:not(.list-nested-item).text-@{class},
li.list-nested-item.text-@{class} > .list-item {
.text(@class);
}
}
.generate-list-item-text-color(subtle);
.generate-list-item-text-color(info);
.generate-list-item-text-color(success);
.generate-list-item-text-color(warning);
.generate-list-item-text-color(error);
.generate-list-item-text-color(selected);
.generate-list-item-status-color(@color, @status) {
li:not(.list-nested-item).status-@{status},
li.list-nested-item.status-@{status} > .list-item {
color: @color;
}
li:not(.list-nested-item).selected.status-@{status},
li.list-nested-item.selected.status-@{status} > .list-item {
color: @color;
}
}
.generate-list-item-status-color(@text-color-added, added);
.generate-list-item-status-color(@text-color-ignored, ignored);
.generate-list-item-status-color(@text-color-modified, modified);
.generate-list-item-status-color(@text-color-removed, removed);
.generate-list-item-status-color(@text-color-renamed, renamed);
li:not(.list-nested-item).selected,
li.list-nested-item.selected > .list-item {
.text(selected);
}
.no-icon {
padding-left: calc(@ui-padding-icon ~"+" @component-icon-size);
}
}
.list-tree.has-collapsable-children .list-nested-item > .list-item::before {
text-align: center;
}
.select-list ol.list-group,
&.select-list ol.list-group {
li.two-lines {
.secondary-line {
color: @text-color-subtle;
}
&.selected .secondary-line {
color: fade(@text-color-highlight, 50%);
text-shadow: none;
}
}
// Reset icon to allow nesting
.icon {
display: initial;
height: initial;
}
// We want to highlight the background of the list items because we dont
// know their size.
li.selected {
background-color: @background-color-selected;
&:before{ display: none; }
}
&.mark-active {
@active-icon-size: 14px;
// pad in front of the text where the icon would be We'll pad the non-
// active items with a 'fake' icon so other classes can pad the item
// without worrying about the icon padding.
li:before {
content: '';
background-color: transparent;
position: static;
display: inline-block;
left: auto; right: auto;
height: @active-icon-size;
width: @active-icon-size;
font-size: @active-icon-size;
}
> li:not(.active):before {
margin-right: @ui-padding-icon;
}
li.active {
.octicon(check, @active-icon-size);
&:before {
margin-right: @ui-padding-icon;
color: @text-color-success;
}
}
}
}
.select-list.popover-list {
@popover-list-padding: @ui-padding/4;
background-color: @overlay-background-color;
box-shadow: 0 2px 8px 1px rgba(0, 0, 0, 0.3);
padding: @popover-list-padding;
border-radius: @component-border-radius;
atom-text-editor[mini] {
margin-bottom: @popover-list-padding;
}
ol.list-group {
margin-top: @popover-list-padding;
}
.list-group li {
padding-left: @popover-list-padding;
}
}
.ui-sortable {
li {
line-height: 2.5;
}
// For sortable lists in the settings view
li.ui-sortable-placeholder {
visibility: visible !important;
background-color: darken(@pane-item-background-color, 10%);
}
}
li.ui-draggable-dragging,
li.ui-sortable-helper {
line-height: @ui-line-height;
height: @ui-line-height;
border: 0;
border-radius: 0;
list-style: none;
padding: 0 @ui-padding;
background: @background-color-highlight;
box-shadow: 0 0 1px @base-border-color;
}

View File

@@ -0,0 +1,16 @@
background-tips ul.background-message {
font-weight: 500;
font-size: 2em;
color: @text-color-faded;
.message {
padding: 0 @component-padding * 10;
.keystroke {
white-space: nowrap;
vertical-align: middle;
line-height: 1;
padding: .1em .4em;
}
}
}

View File

@@ -0,0 +1,125 @@
@modal-padding: @ui-padding/2 @ui-padding/1.5;
@modal-width: @ui-size * 50;
atom-panel-container.modal {
position: absolute;
top: 0; left: 0; right: 0;
}
atom-panel.modal {
position: relative;
width: 100%;
max-width: @modal-width;
margin: 0 auto;
left: initial;
color: @text-color;
background-color: transparent;
padding: @ui-padding/2;
&.from-top {
top: @component-padding * 5;
}
atom-text-editor[mini] {
margin-bottom: @ui-padding/2;
}
.select-list ol.list-group,
&.select-list ol.list-group {
border: 1px solid @overlay-border-color;
background-color: lighten(@overlay-background-color, 2%);
&:empty {
border: none;
margin-top: 0;
}
li {
padding: @modal-padding;
line-height: @ui-line-height;
border-bottom: 1px solid @overlay-border-color;
&:last-of-type {
border-bottom: none;
}
.icon::before {
margin-left: 1px;
}
.icon.status {
float: right;
margin-left: @ui-padding-icon;
&:before {
margin-left: 0;
margin-right: 0;
}
}
&.selected {
.status.icon {
color: @text-color-selected;
}
}
}
}
.select-list .key-binding {
margin-top: -1px;
margin-left: @ui-padding/2;
margin-right: calc( -@ui-padding/3 ~"+" 1px);
}
.select-list .primary-line {
display: block;
}
& > * {
position: relative; // fixes stacking order
}
.command-palette {
padding: 1px; // prevents the box-shadow of the input from being cut off
background-color: @overlay-background-color;
}
// Container
&:before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 0;
background-color: @overlay-background-color;
border-radius: @component-border-radius*2;
box-shadow: 0 6px 12px -2px hsla(0,0%,0%,.4);
}
// Backdrop
// TODO: Add extra wrapper to translate individually or easier positioning
&:after {
content: "";
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
background: @overlay-backdrop-color;
opacity: @overlay-backdrop-opacity;
backface-visibility: hidden; // fixes scrollbar on retina screens
-webkit-animation: overlay-fade .24s cubic-bezier(0.215, 0.61, 0.355, 1);
}
@-webkit-keyframes overlay-fade {
0% { opacity: 0; }
100% { opacity: @overlay-backdrop-opacity; }
}
}

View File

@@ -0,0 +1,25 @@
.nav-tabs {
border-bottom: 1px solid @base-border-color;
li {
a,
&.active a {
border: none;
margin-right: 0px;
margin-bottom: 1px;
}
a:hover,
&.active a,
&.active a:hover {
background-color: @background-color-highlight;
border: none;
color: @text-color-selected;
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
}
&.active a {
background-color: @tab-background-color-active;
}
}
}

View File

@@ -0,0 +1,45 @@
atom-notifications {
font-size: @ui-size * 1.2;
atom-notification {
width: 32em;
&.has-detail {
width: 32em;
}
&:first-child.has-close .message {
padding-right: 9em;
}
&:only-child.has-close .message,
&.has-close .message {
padding-right: 2.5em;
}
.item {
padding: @ui-padding/2;
}
.detail,
.description {
font-size: .85em;
}
&.icon:before {
padding-top: .85em;
}
.close {
width: 2.5em;
height: 3em;
line-height: 3em;
font-size: inherit;
}
.close-all.btn {
top: .5em;
right: 2.5em;
}
.btn-copy-report {
line-height: 2em;
margin-left: .5em;
}
}
}

View File

@@ -0,0 +1,231 @@
// Overrides packages
// find-and-replace + project-find ---------------------------
.find-and-replace,
.project-find {
padding: @ui-padding/4;
.input-block-item {
padding: @ui-padding/4;
}
}
// find-and-replace
.find-and-replace {
.header,
.input-block {
min-width: @ui-size*22;
}
.input-block-item {
flex: 1 1 @ui-size*22;
}
.input-block-item--flex {
flex: 100 1 @ui-size*22;
}
.btn,
.btn-group-options .btn {
font-size: @ui-size*1.1;
padding: 0;
}
.btn-group-options .btn,
.btn-group-options .btn.option-selection,
.btn-group-options .btn.option-whole-word {
padding: 0;
font-size: @ui-input-size; // keep same as text input
}
.find-container atom-text-editor {
padding-right: @ui-size*5; // leave some room for the results count
}
.find-meta-container {
top: 0;
font-size: @ui-size;
line-height: @ui-size*2.5;
}
}
// project-find
.project-find {
.header,
.input-block {
min-width: @ui-size*15;
}
.input-block-item {
flex: 1 1 @ui-size*14;
}
.input-block-item--flex {
flex: 100 1 @ui-size*20;
}
.btn {
font-size: @ui-size*1.1;
padding: 0;
}
.btn-group-options .btn {
padding: 0;
font-size: @ui-input-size; // keep same as text input
}
}
// Colorize find-and-replace based on results
& when (@ui-hue >= 190) and (@ui-hue <= 340) {
.find-and-replace {
&.has-no-results .find-container atom-text-editor[mini].is-focused {
.invalid();
.selection .region {
background-color: mix(@text-color-error, @input-background-color, 50%);
}
.cursor {
border-color: @text-color-error;
}
}
&.has-results .find-container atom-text-editor[mini].is-focused {
.valid();
.selection .region {
background-color: mix(@text-color-success, @input-background-color, 50%);
}
.cursor {
border-color: @text-color-success;
}
}
&.has-results .find-container .result-counter { color: @text-color-success; }
&.has-no-results .find-container .result-counter { color: @text-color-error; }
}
}
// Timecop ---------------------------
.timecop {
.timecop-panel {
padding: @component-padding/2;
background-color: @level-2-color;
}
.tool-panel {
padding: @component-padding/2;
background-color: @level-2-color;
}
.inset-panel {
border: 1px solid @base-border-color;
}
.panel-heading {
.text(highlight);
border-color: @base-border-color;
background-color: @level-1-color;
}
.list-item .inline-block {
line-height: 1.5;
}
}
// Command Palette + Fuzzy Finder ---------------------------
.command-palette .list-group .character-match,
.fuzzy-finder .list-group .character-match {
color: @accent-only-text-color;
}
// Deprecation Cop ---------------------------
.deprecation-cop {
.deprecation-overview {
background-color: @level-2-color;
border-bottom: 1px solid @base-border-color;
}
}
// Tool Bar ---------------------------
.tool-bar {
// Make it look the same as other panels
background-color: @level-3-color;
border: none;
// just a single border + more spacing
&.tool-bar-horizontal .tool-bar-spacer {
border-left: 0 none;
margin-left: .5em;
margin-right: .5em;
}
&.tool-bar-vertical .tool-bar-spacer {
border-bottom: 0 none;
margin-top: .5em;
margin-bottom: .5em;
}
// only show button styles on hover
button.tool-bar-btn {
background-color: @level-3-color;
background-image: none;
border-color: @level-3-color;
}
}
// GitHub package ---------------------------------------------------
.github {
// Fix focus styles
// Since it's not possible to add a padding to <atom-text-editor>
// a pseudo element is used to add the border when focused.
&-CommitView-editor atom-text-editor.is-focused {
box-shadow: none;
&:before {
content: "";
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
border: 2px solid;
border-color: inherit;
border-radius: @component-border-radius;
}
}
// Add focus styles since :focus doesn't work
&-CommitView-coAuthorEditor {
&.is-focused {
.focus();
}
&.is-open {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.Select-option {
&.is-focused {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
color: @accent-text-color;
background-color: @accent-color;
}
}
.Select-menu-outer {
left: -2px;
right: -2px;
bottom: 100%;
border: 2px solid @accent-color;
background-color: @overlay-background-color;
}
}
}

View File

@@ -0,0 +1,64 @@
// Panels
atom-panel {
.text(normal);
position: relative;
border-bottom: 1px solid @base-border-color;
&.top {
border-right: 1px solid @base-border-color;
}
&.left {
border-right: 1px solid @base-border-color;
}
&.right {
border-left: 1px solid @base-border-color;
}
&.bottom {
border-right: 1px solid @base-border-color;
}
&.footer:last-child {
border-bottom: none;
}
&.tool-panel:empty {
border: none;
}
}
.panel {
&.bordered {
border: 1px solid @base-border-color;
border-radius: @component-border-radius;
}
}
.inset-panel {
position: relative;
background-color: @inset-panel-background-color;
border-radius: @component-border-radius;
&.bordered {
border: 1px solid @base-border-color;
border-radius: @component-border-radius;
}
& .panel-heading {
border-color: @inset-panel-border-color;
}
}
.panel-heading {
.text(normal);
border-bottom: 1px solid @panel-heading-border-color;
background-color: @panel-heading-background-color;
.btn {
padding-left: 8px;
padding-right: 8px;
.btn-default(
lighten(@button-background-color, 10%),
lighten(@button-background-color-hover, 10%),
lighten(@button-background-color-selected, 10%),
lighten(@text-color, 10%)
);
}
}

View File

@@ -0,0 +1,22 @@
atom-pane-container {
atom-pane {
position: relative;
border-right: 1px solid @base-border-color;
border-bottom: 1px solid @base-border-color;
.item-views {
// prevent atom-text-editor from leaking ouside might improve performance
overflow: hidden;
}
}
}
// Hide right-most border
atom-pane:only-child,
atom-pane-axis.pane-row > atom-pane:last-child,
atom-pane-axis.pane-column:last-child > atom-pane {
border-right: none;
}

View File

@@ -0,0 +1,94 @@
// Spinner ----------------------
@spinner-duration: 1.2s;
.loading-spinner(@size) {
position: relative;
display: block;
width: 1em;
height: 1em;
font-size: @size;
background: radial-gradient(@accent-color .1em, transparent .11em);
&::before,
&::after {
content: "";
position: absolute;
z-index: 10; // prevent sibling elements from getting their own layers
top: 0;
left: 0;
border-radius: 1em;
width: inherit;
height: inherit;
border-radius: 1em;
border: 2px solid;
-webkit-animation: spinner-animation @spinner-duration infinite;
-webkit-animation-fill-mode: backwards;
}
&::before {
border-color: @accent-color transparent transparent transparent;
}
&::after {
border-color: transparent lighten(@accent-color, 15%) transparent transparent;
-webkit-animation-delay: @spinner-duration/2;
}
&.inline-block {
display: inline-block;
}
}
@-webkit-keyframes spinner-animation {
0% { transform: rotateZ( 0deg); -webkit-animation-timing-function: cubic-bezier(0, 0, .8, .2); }
50% { transform: rotateZ(180deg); -webkit-animation-timing-function: cubic-bezier(.2, .8, 1, 1); }
100% { transform: rotateZ(360deg); }
}
// Spinner sizes
.loading-spinner-tiny { .loading-spinner(16px); &::before, &::after { border-width: 1px; } }
.loading-spinner-small { .loading-spinner(32px); }
.loading-spinner-medium { .loading-spinner(48px); }
.loading-spinner-large { .loading-spinner(64px); }
// Progress Bar ----------------------
@progress-height: 8px;
@progress-buffer-color: fade(@progress-background-color, 20%);
progress {
-webkit-appearance: none;
height: @progress-height;
border-radius: @component-border-radius;
background-color: @input-background-color;
box-shadow: inset 0 0 0 1px @input-border-color;
&::-webkit-progress-bar {
background-color: transparent;
}
&::-webkit-progress-value {
border-radius: @component-border-radius;
background-color: @progress-background-color;
}
// Is buffering (when no value is set)
&:indeterminate {
background-image:
linear-gradient(-45deg, transparent 33%, @progress-buffer-color 33%,
@progress-buffer-color 66%, transparent 66%);
background-size: 25px @progress-height, 100% 100%, 100% 100%;
// Plays animation for 1min (12runs) at normal speed,
// then slows down frame-rate for 9mins (108runs) to limit CPU usage
-webkit-animation: progress-buffering 5s linear 12,
progress-buffering 5s 60s steps(10) 108;
}
}
@-webkit-keyframes progress-buffering {
100% { background-position: -100px 0px; }
}

View File

@@ -0,0 +1,140 @@
// Settings
// Modular Scale (1.125): http://www.modularscale.com/?1&em&1.125&web&table
@ms-6: @ui-size * 2.027;
@ms-5: @ui-size * 1.802;
@ms-4: @ui-size * 1.602;
@ms-3: @ui-size * 1.424;
@ms-2: @ui-size * 1.266;
@ms-1: @ui-size * 1.125;
@ms-0: @ui-size * 1;
@ms_1: @ui-size * 0.889;
@ms_2: @ui-size * 0.790;
.settings-view {
// Menu ------------------------------
.config-menu {
position: relative;
min-width: @ui-size * 15;
max-width: @ui-size * 20;
border-width: 0 1px 0 0;
border-image: linear-gradient(@level-2-color 10px, @base-border-color 200px) 0 1 0 0 stretch;
background: @level-2-color;
.btn {
white-space: initial;
font-size: @ms_1;
line-height: 1;
padding: @ui-padding/3 @ui-padding/2;
&::before {
vertical-align: middle;
}
}
}
.nav {
& > li > a {
padding: @ui-padding/2 @ui-padding;
line-height: @ui-line-height;
}
}
// Sections ------------------------------
& > .panels {
background-color: @level-2-color;
}
.section-container {
max-width: @ui-size*60;
}
.sub-section {
margin: @ui-padding*3 0;
}
.section,
.section:first-child,
.section:last-child {
padding: @ui-padding*3;
}
.themes-panel .control-group {
margin-top: @ui-padding*2;
}
// Titles ------------------------------
.section .section-heading {
margin-bottom: @ui-padding/1.5;
}
.sub-section-heading.icon:before,
.section-heading.icon:before {
margin-right: @ui-padding-icon;
}
// Cards ------------------------------
.package-card {
padding: @ui-padding;
.meta-controls .status-indicator {
width: @ui-padding/4;
&:before {
content: "\00a0"; // fixes 0 height
}
}
}
// Components ------------------------------
.icon::before {
color: @text-color-subtle;
}
.editor-container {
margin: @ui-padding 0;
}
.form-control {
font-size: @ui-size*1.25;
height: @ui-line-height;
padding-top: 0;
padding-bottom: 0;
}
.update-all-button {
font-size: .75em;
}
.install-button {
.btn-variant(@accent-bg-color);
}
input[type="checkbox"] {
background-color: @background-color-selected;
&:active,
&:checked {
background-color: @accent-color;
}
&:before,
&:after {
background-color: @accent-text-color;
}
}
.search-container .btn {
font-size: @ui-input-size;
}
}

View File

@@ -0,0 +1,13 @@
// Site Colors
.ui-site(@num, @color) {
.ui-site-@{num} {
background-color: @color;
}
}
.ui-site(1, @ui-site-color-1);
.ui-site(2, @ui-site-color-2);
.ui-site(3, @ui-site-color-3);
.ui-site(4, @ui-site-color-4);
.ui-site(5, @ui-site-color-5);

View File

@@ -0,0 +1,97 @@
@status-bar-height: @ui-tab-height; // same as tabs
@status-bar-padding: @ui-padding;
.status-bar {
font-size: @ui-size;
height: @status-bar-height;
line-height: @status-bar-height;
background-color: @level-3-color;
.flexbox-repaint-hack {
padding: 0; // override default
}
// underlines should only be used for external links
a:hover,
a:focus {
text-decoration: none;
cursor: default;
}
.inline-block {
margin: 0; // override default
padding: 0 @status-bar-padding/2;
vertical-align: top;
&:hover {
text-decoration: none;
background-color: @level-3-color-hover;
}
&:active {
background-color: @level-3-color-active;
}
// reset on child inline-block
.inline-block {
margin: 0;
padding: 0;
}
}
.status-bar-right {
.inline-block {
margin-left: 0; // override default
}
}
.icon {
vertical-align: middle;
}
.icon::before {
font-size: 1.33333em; // should be 16px with a default of 12px
width: auto; // use natural width
line-height: 1;
height: 1em; // same as line-height
margin-right: .25em;
top: auto;
}
}
// Package overrides -------------------------------
.status-bar.status-bar {
// Read-only -> Remove hover effect
.is-read-only, // <- use this class in packages
status-bar-launch-mode,
busy-signal {
&:hover,
&:active,
.inline-block:hover,
.inline-block:active {
background-color: transparent;
}
}
// Remove underline
.package-updates-status-view,
.github-ChangedFilesCount {
&:hover,
&:focus {
text-decoration: none;
cursor: default;
}
}
// Remove margin for icon without text
status-bar-launch-mode::before, // Launch mode
.about-release-notes::before, // New release squirrel
.PortalStatusBarIndicator .icon::before, // Teletype
.icon.is-icon-only::before {
margin-right: 0;
}
.github-PushPull-label.is-push:empty { // GitHub package when nothing to push
margin-right: -.25em;
}
}

View File

@@ -0,0 +1,250 @@
// Tabs
@tab-border: 1px solid @tab-border-color;
@title-padding: .66em;
@icon-padding-top: .5em; // 2.5 (total) - 1.5 (text) / 2
@icon-padding-right: .5em;
.tab-bar {
position: relative;
height: @ui-tab-height;
box-shadow: inset 0 -1px 0 @tab-border-color;
background: @tab-bar-background-color;
overflow-x: auto;
overflow-y: hidden;
border-radius: 0;
&::-webkit-scrollbar {
display: none;
}
&:empty {
display: none;
}
// Tab ----------------------
.tab {
position: relative;
top: 0;
padding: 0;
margin: 0;
height: inherit;
font-size: inherit;
line-height: @ui-tab-height;
color: @tab-text-color;
background-color: @tab-background-color;
box-shadow: inherit;
border-left: @tab-border;
&.active {
color: @tab-text-color-active;
background-color: @tab-background-color-active;
box-shadow: none;
}
&:first-of-type {
border-left-color: transparent;
}
&:last-of-type {
// use box-shadow to not take up any space
box-shadow: inset 0 -1px 0 @tab-border-color, 1px 0 0 @base-border-color;
}
&.active:last-of-type {
box-shadow: 1px 0 0 @base-border-color;
}
// Title ----------------------
.title {
text-align: center;
margin: 0 @title-padding;
}
// VCS coloring ----------------------
&:not(.active) .status-added { color: @tab-inactive-status-added; }
&:not(.active) .status-modified { color: @tab-inactive-status-modified; }
// Icons ----------------------
.title.title:before {
margin-right: .3em;
width: auto;
height: auto;
line-height: 1;
font-size: 1.125em;
vertical-align: -.0625em; // Adjust center for the 0.1em font-size increase
}
// Close icon ----------------------
.close-icon {
top: @icon-padding-top;
right: @icon-padding-right;
z-index: 2;
font-size: 1em;
width: 1.5em;
height: 1.5em;
line-height: 1.5;
text-align: center;
border-radius: @component-border-radius;
background-color: inherit;
overflow: hidden;
transform: scale(0);
transition: transform .08s;
&:hover {
color: @accent-text-color;
background-color: @accent-color;
}
&:active {
background-color: fade(@accent-color, 50%);
}
&::before {
z-index: 1;
font-size: 1.1em;
vertical-align: -.05em; // Adjust center for the 0.1em font-size increase
width: auto;
height: auto;
pointer-events: none;
}
}
&:hover .close-icon {
transform: scale(1);
transition-duration: .16s;
}
}
// Modified icon ----------------------
.tab.modified {
&:hover .close-icon {
color: @accent-color;
&:hover {
color: @accent-bg-text-color;
}
}
&:not(:hover) .close-icon {
top: @icon-padding-top;
right: @icon-padding-right;
width: 1.5em;
height: 1.5em;
line-height: 1.5;
color: @accent-color;
border-radius: @component-border-radius;
border: none;
transform: scale(1);
&::before {
content: "\f052";
display: inline-block;
}
}
}
// Tabs in the docks ----------------------
atom-dock & {
.tab.active {
background-color: @tool-panel-background-color;
}
}
// Dragging ----------------------
.tab.is-dragging {
opacity: .5;
.close-icon,
&:before {
visibility: hidden;
}
}
.placeholder {
position: relative;
pointer-events: none;
// bar
&:before {
z-index: 1;
margin: 0;
width: 2px;
height: @ui-tab-height;
background-color: @accent-color;
}
// arrow
&:after {
z-index: 0;
top: @ui-tab-height/2;
margin: -4px 0 0 -3px;
border-radius: 0;
border: 4px solid @accent-color;
transform: rotate(45deg);
background: transparent;
}
&:last-child {
&:before {
margin-left: -2px;
}
&:after {
transform: none;
margin-left: -10px;
border-color: transparent @accent-color transparent transparent;
}
}
}
// Overrides ----------------------
// keep tabs same size when active
.tab,
.tab.active {
padding-right: 0;
.title {
padding: 0;
}
}
}
// Active pane marker --------------
atom-pane-axis > atom-pane.active,
atom-pane-container > atom-pane.pane {
.tab.active:before {
content: "";
position: absolute;
pointer-events: none;
z-index: 2;
top: 0;
left: -1px; // cover left border
bottom: 0;
width: 2px;
background: @accent-color;
}
}
// hide marker in docks
atom-dock .tab-bar .tab::before {
display: none;
}
// Custom tabs --------------
.tab-bar .tab.active {
&[data-type$="Editor"],
&[data-type$="AboutView"],
&[data-type$="TimecopView"],
&[data-type$="StyleguideView"],
&[data-type="MarkdownPreviewView"] {
color: @tab-text-color-editor;
background-color: @tab-background-color-editor; // Match syntax background color
}
}

View File

@@ -0,0 +1,84 @@
h1,
h2,
h3 {
line-height: 1em;
margin-bottom: 15px
}
h1 { font-size: 2em; }
h2 { font-size: 1.5em; }
h3 { font-size: 1.2em; }
p {
line-height: 1.6;
margin-bottom: 15px;
}
label {
font-weight: normal;
}
pre {
box-shadow: none;
color: @text-color;
background: @inset-panel-background-color;
border-radius: @component-border-radius;
border: none;
margin: 0;
}
code {
.text(highlight);
background: @background-color-highlight;
border-radius: @component-border-radius;
}
.selected { .text(highlight); }
.text-smaller { font-size: 0.9em; }
.text-subtle { .text(subtle); }
.text-highlight { .text(highlight); }
.text-error { .text(error); }
.text-info {
.text(info);
&:hover { color: @text-color-info; }
}
.text-warning {
.text(warning);
&:hover { color: @text-color-warning; }
}
.text-success {
.text(success);
&:hover { color: @text-color-success; }
}
.highlight-mixin {
padding: 1px 4px;
border-radius: 2px;
}
.highlight {
.highlight-mixin();
font-weight: 700;
color: @text-color-highlight;
background-color: @background-color-highlight;
}
.highlight-color(@name, @background-color) {
.highlight-@{name} {
.highlight-mixin();
font-weight: 500;
color: white;
text-shadow: 0 1px 0px hsla(0,0%,0%,.2);
background-color: @background-color;
}
}
.highlight-color( info, @background-color-info);
.highlight-color(warning, @background-color-warning);
.highlight-color( error, @background-color-error);
.highlight-color(success, @background-color-success);
.results-view .path-details.list-item {
color: darken(@text-color-highlight, 18%);
}

View File

@@ -0,0 +1,4 @@
.title-bar {
height: 22px; // remove 1px since there is no border
border-bottom: none;
}

View File

@@ -0,0 +1,53 @@
.tooltip {
white-space: nowrap;
font-size: @ui-size*1.15;
&.in {
opacity: 1;
transition: opacity .12s ease-out;
}
.tooltip-inner {
line-height: 1;
padding: @ui-padding*.5 @ui-padding*.65;
border-radius: @component-border-radius;
background-color: @tooltip-background-color;
color: @tooltip-text-color;
white-space: nowrap;
max-width: none;
}
.keystroke {
font-size: max(1em, @ui-size*.85);
padding: .1em .4em;
margin: 0 @ui-padding*-.35 0 @ui-padding*.25;
border-radius: max(2px, @component-border-radius / 2);
color: @tooltip-text-key-color;
background: @tooltip-background-key-color;
}
&.top .tooltip-arrow {
border-top-color: @tooltip-background-color;
}
&.top-left .tooltip-arrow {
border-top-color: @tooltip-background-color;
}
&.top-right .tooltip-arrow {
border-top-color: @tooltip-background-color;
}
&.right .tooltip-arrow {
border-right-color: @tooltip-background-color;
}
&.left .tooltip-arrow {
border-left-color: @tooltip-background-color;
}
&.bottom .tooltip-arrow {
border-bottom-color: @tooltip-background-color;
}
&.bottom-left .tooltip-arrow {
border-bottom-color: @tooltip-background-color;
}
&.bottom-right .tooltip-arrow {
border-bottom-color: @tooltip-background-color;
}
}

View File

@@ -0,0 +1,85 @@
@tree-view-height: @ui-line-height;
.tree-view {
font-size: @ui-size;
background: @tree-view-background-color;
.project-root.project-root {
&:before {
height: @ui-tab-height;
background-clip: padding-box;
}
& > .header .name {
line-height: @ui-tab-height;
}
}
// Selected state
.selected:before {
background: @background-color-selected;
}
// Focus + selected state
&:focus {
.selected.list-item > .name, // files
.selected.list-nested-item > .list-item > .name, // folders
.selected.list-nested-item > .header:before { // arrow icon
color: contrast(@button-background-color-selected);
}
.selected:before {
background: @button-background-color-selected;
}
}
}
.theme-one-dark-ui .tree-view .project-root.project-root::before {
border-top: 1px solid transparent;
background-clip: padding-box;
}
.tree-view-resizer {
.tree-view-resize-handle {
width: 8px;
}
}
// Variable height, based on ems
.list-group li:not(.list-nested-item),
.list-tree li:not(.list-nested-item),
.list-group li.list-nested-item > .list-item,
.list-tree li.list-nested-item > .list-item {
line-height: @tree-view-height;
}
.list-group .selected::before,
.list-tree .selected::before {
height: @tree-view-height;
}
// icon
.list-group .icon,
.list-tree .icon {
display: inline-block;
height: inherit;
&::before {
top: initial;
line-height: inherit;
height: inherit;
vertical-align: top;
}
}
// Arrow icon
.list-group,
.list-tree {
.header.header.header.header::before {
top: initial;
line-height: inherit;
height: inherit;
vertical-align: top;
font-size: inherit;
}
}
.tree-view .project-root-header.project-root-header.project-root-header.project-root-header::before {
line-height: @ui-tab-height;
}

View File

@@ -0,0 +1,49 @@
// Pattern matching; ish is cray.
// http://lesscss.org/#-pattern-matching-and-guard-expressions
.text(normal) {
font-weight: normal;
color: @text-color;
}
.text(subtle) {
font-weight: normal;
color: @text-color-subtle;
}
.text(highlight) {
font-weight: normal;
color: @text-color-highlight;
}
.text(selected) {
.text(highlight)
}
.text(info) {
color: @text-color-info;
}
.text(success) {
color: @text-color-success;
}
.text(warning) {
color: @text-color-warning;
}
.text(error) {
color: @text-color-error;
}
.focus() {
outline: none;
border-color: @accent-color;
box-shadow: 0 0 0 1px @accent-color;
}
.valid() {
border-color: @text-color-success;
box-shadow: 0 0 0 1px @text-color-success;
background-color: mix(@text-color-success, @input-background-color, 10%);
}
.invalid() {
border-color: @text-color-error;
box-shadow: 0 0 0 1px @text-color-error;
background-color: mix(@text-color-error, @input-background-color, 10%);
}

View File

@@ -0,0 +1,132 @@
// ONE light UI variables
// ----------------------------------------------
@import "syntax-variables";
.ui-syntax-color() { @syntax-background-color: hsl(220,1%,98%); } .ui-syntax-color(); // fallback color
@ui-syntax-color: @syntax-background-color;
// Color guards -----------------
@ui-s-h: hue(@ui-syntax-color);
.ui-hue() when (@ui-s-h = 0) { @ui-hue: 220; } // Use blue hue when no saturation
.ui-hue() when (@ui-s-h > 0) { @ui-hue: @ui-s-h; }
.ui-hue();
@ui-saturation: min( saturation(@ui-syntax-color), 24%); // max saturation
@ui-lightness: max( lightness(@ui-syntax-color), 92%); // min lightness
// Main colors -----------------
@ui-fg: hsl(@ui-hue, @ui-saturation, @ui-lightness - 72%);
@ui-bg: hsl(@ui-hue, @ui-saturation, @ui-lightness); // normalized @syntax-background-color
@ui-border: darken(@level-3-color, 6%);
// Custom variables
// These variables are only used in this theme
// ----------------------------------------------
@ui-theme-name: one-light-ui;
// Text (Custom) -----------------
@text-color-faded: fade(@text-color, 30%);
@text-color-added: @text-color-success; // green
@text-color-ignored: @text-color-subtle; // faded
@text-color-modified: @text-color-warning; // orange
@text-color-removed: @text-color-error; // red
@text-color-renamed: @text-color-info; // blue
// Background (Custom) -----------------
@level-1-color: lighten(@base-background-color, 4%);
@level-2-color: @base-background-color;
@level-3-color: darken(@base-background-color, 6%);
@level-3-color-hover: darken(@level-3-color, 6%);
@level-3-color-active: darken(@level-3-color, 3%);
// Accent (Custom) -----------------
@accent-luma: luma( hsl(@ui-hue, 50%, 50%) ); // get lightness of current hue
// used for marker, inputs (smaller things)
@accent-color: mix( hsv( @ui-hue, 60%, 60%), hsl( @ui-hue, 100%, 68%), @accent-luma * 2 ); // mix hsv + hsl (favor hsl for dark, hsv for light colors)
@accent-text-color: contrast(@accent-color, hsl(@ui-hue,100%,16%), #fff, 40% );
// used for button, tooltip (larger things)
@accent-bg-color: mix( hsv( @ui-hue, 40%, 72%), hsl( @ui-hue, 100%, 66%), @accent-luma * 2 ); // mix hsv + hsl (favor hsl for dark, hsv for light colors)
@accent-bg-text-color: contrast(@accent-bg-color, hsl(@ui-hue,100%,10%), #fff, 40% );
// used for text only
@accent-only-text-color: mix( hsv( @ui-hue, 70%, 50%), hsl( @ui-hue, 100%, 60%), @accent-luma * 2 ); // mix hsv + hsl (favor hsl for dark, hsv for light colors)
// Components (Custom) -----------------
@badge-background-color: @background-color-selected;
@button-text-color-selected: @accent-bg-text-color;
@button-border-color-selected: @accent-color;
@checkbox-background-color: fade(@accent-bg-color, 33%);
@input-background-color-focus: hsl(@ui-hue, 100%, 96%);
@input-selection-color: mix( hsv( @ui-hue, 33%, 95%), hsl( @ui-hue, 100%, 98%), @accent-luma * 2 ); // mix hsv + hsl (favor hsl for dark, hsv for light colors)
@input-selection-color-focus: mix( hsv( @ui-hue, 44%, 90%), hsl( @ui-hue, 100%, 94%), @accent-luma * 2 ); // mix hsv + hsl (favor hsl for dark, hsv for light colors)
@overlay-backdrop-color: hsl(@ui-hue, @ui-saturation*0.4, @ui-lightness*0.8);
@overlay-backdrop-opacity: .66;
@progress-background-color: @accent-color;
@scrollbar-color: darken(@level-3-color, 14%);
@scrollbar-background-color: @level-3-color; // replaced `transparent` with a solid color to test https://github.com/atom/one-light-ui/issues/4
@scrollbar-color-editor: contrast(@ui-syntax-color, darken(@ui-syntax-color, 14%), lighten(@ui-syntax-color, 9%) );
@scrollbar-background-color-editor: @ui-syntax-color;
@tab-text-color: @text-color-subtle;
@tab-text-color-active: @text-color-highlight;
@tab-text-color-editor: contrast(@ui-syntax-color, lighten(@ui-syntax-color, 70%), @text-color-highlight );
@tab-background-color-editor: @ui-syntax-color;
@tab-inactive-status-added: fade(@text-color-success, 77%);
@tab-inactive-status-modified: fade(@text-color-warning, 77%);
@tooltip-background-color: @accent-bg-color;
@tooltip-text-color: @accent-bg-text-color;
@tooltip-text-key-color: @tooltip-background-color;
@tooltip-background-key-color: @tooltip-text-color;
// Sizes (Custom) -----------------
@ui-size: 1em;
@ui-input-size: @ui-size*1.15;
@ui-padding: @ui-size*1.5;
@ui-padding-pane: @ui-size*.5;
@ui-padding-icon: @ui-padding/3.3;
@ui-line-height: @ui-size*2;
@ui-tab-height: @ui-size*2.5;
// Packages variables
// These variables are used to override packages
// ----------------------------------------------
@settings-list-background-color: darken(@level-2-color, 3%);
@theme-config-box-shadow: inset 0 1px 2px hsla(0, 0%, 0%, .2), 0 1px 0 hsla(0, 0%, 100%, .3);
@theme-config-box-shadow-selected: inset 0 1px 3px hsla(0, 0%, 0%, .2);
@theme-config-border-selected: hsla(0, 0%, 0%, .5);
// Debug
// Output variables to the top of the UI
// -------------------------------------
// html:before {
// content: "@{variable}";
// }

View File

@@ -0,0 +1,97 @@
@import "ui-variables-custom.less"; // import colors and custom variables
// ONE light UI variables
// ----------------------------------------------
// Official variables
// These variables must be defined in every theme
// Source: https://github.com/atom/atom/blob/master/static/variables/ui-variables.less
// ----------------------------------------------
// Text -----------------
@text-color: @ui-fg;
@text-color-subtle: lighten(@text-color, 30%);
@text-color-highlight: darken(@text-color, 12%);
@text-color-selected: darken(@text-color-highlight, 12%);
@text-color-info: hsl(208, 100%, 54%);
@text-color-success: hsl(132, 60%, 44%);
@text-color-warning: hsl( 37, 90%, 44%);
@text-color-error: hsl( 0, 90%, 56%);
// Background -----------------
@background-color-info: hsl(208, 100%, 56%);
@background-color-success: hsl(132, 52%, 48%);
@background-color-warning: hsl( 40, 60%, 48%);
@background-color-error: hsl( 5, 72%, 56%);
@background-color-highlight: darken(@level-3-color, 2%);
@background-color-selected: darken(@level-3-color, 6%);
@app-background-color: @level-3-color;
// Base -----------------
@base-background-color: @ui-bg;
@base-border-color: @ui-border;
// Components -----------------
@pane-item-background-color: @base-background-color;
@pane-item-border-color: @base-border-color;
@input-background-color: @level-1-color;
@input-border-color: @base-border-color;
@tool-panel-background-color: @level-3-color;
@tool-panel-border-color: @base-border-color;
@inset-panel-background-color: lighten(@level-2-color, 4%);
@inset-panel-border-color: fadeout(@base-border-color, 15%);
@panel-heading-background-color: @level-2-color;
@panel-heading-border-color: @base-border-color;
@overlay-background-color: mix(@level-2-color, @level-3-color);
@overlay-border-color: @base-border-color;
@button-background-color: @level-1-color;
@button-background-color-hover: darken(@button-background-color, 4%);
@button-background-color-selected: @accent-bg-color;
@button-border-color: @base-border-color;
@tab-bar-background-color: @level-3-color;
@tab-bar-border-color: @base-border-color;
@tab-background-color: @level-3-color;
@tab-background-color-active: @level-2-color;
@tab-border-color: @base-border-color;
@tree-view-background-color: @level-3-color;
@tree-view-border-color: @base-border-color;
@ui-site-color-1: hsl(208, 100%, 56%); // blue
@ui-site-color-2: hsl(132, 48%, 48%); // green
@ui-site-color-3: hsl( 40, 60%, 52%); // orange
@ui-site-color-4: #D831B0; // pink
@ui-site-color-5: #EBDD5B; // yellow
// Sizes -----------------
@font-size: 12px;
@input-font-size: 14px;
@disclosure-arrow-size: 12px;
@component-padding: 10px;
@component-icon-padding: 5px;
@component-icon-size: 16px; // needs to stay 16px to look sharpest
@component-line-height: 25px;
@component-border-radius: 3px;
@tab-height: 30px;
// Font -----------------
@font-family: system-ui;

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -1,6 +1,6 @@
Package: <%= appFileName %>
Version: <%= version %>
Depends: git, gconf2, gconf-service, libgtk2.0-0, libudev0 | libudev1, libgcrypt11 | libgcrypt20, libnotify4, libxtst6, libnss3 (>= 2:3.22), python, gvfs-bin, xdg-utils, libcap2, libx11-xcb1, libxss1, libasound2 (>= 1.0.16), libxkbfile1
Depends: git, gconf2, gconf-service, libgtk-3-0 (>= 3.9.10), libudev0 | libudev1, libgcrypt11 | libgcrypt20, libnotify4, libxtst6, libnss3 (>= 2:3.22), python, gvfs-bin, xdg-utils, libcap2, libx11-xcb1, libxss1, libasound2 (>= 1.0.16), libxkbfile1
Recommends: lsb-release
Suggests: libsecret-1-0, gir1.2-gnomekeyring-1.0
Section: devel

Some files were not shown because too many files have changed in this diff Show More