Merge branch 'master' of github.com:atom/atom into content-regex

This commit is contained in:
Aerijo
2019-02-04 20:58:19 +10:00
137 changed files with 7408 additions and 867 deletions

View File

@@ -1,10 +1,14 @@
![Atom](https://cloud.githubusercontent.com/assets/72919/2874231/3af1db48-d3dd-11e3-98dc-6066f8bc766f.png)
# Atom
[![Build status](https://dev.azure.com/github/Atom/_apis/build/status/Atom%20Production%20Branches?branchName=master)](https://dev.azure.com/github/Atom/_build/latest?definitionId=32&branchName=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)
Atom is a hackable text editor for the 21st century, built on [Electron](https://github.com/atom/electron), and based on everything we love about our favorite editors. We designed it to be deeply customizable, but still approachable using the default configuration.
Atom is a hackable text editor for the 21st century, built on [Electron](https://github.com/electron/electron), and based on everything we love about our favorite editors. We designed it to be deeply customizable, but still approachable using the default configuration.
![Atom](https://user-images.githubusercontent.com/378023/49132477-f4b77680-f31f-11e8-8357-ac6491761c6c.png)
![Atom Screenshot](https://user-images.githubusercontent.com/378023/49132478-f4b77680-f31f-11e8-9e10-e8454d8d9b7e.png)
Visit [atom.io](https://atom.io) to learn more or visit the [Atom forum](https://discuss.atom.io).

5
apm/package-lock.json generated
View File

@@ -21,7 +21,6 @@
"node-gyp": "3.4.0",
"npm": "6.2.0",
"open": "0.0.5",
"plist": "git+https://github.com/nathansobo/node-plist.git#bd3a93387f1d4b2cff819b200870d35465796e77",
"q": "~0.9.7",
"read": "~1.0.5",
"request": "^2.87.0",
@@ -3974,7 +3973,7 @@
},
"plist": {
"version": "git+https://github.com/nathansobo/node-plist.git#bd3a93387f1d4b2cff819b200870d35465796e77",
"from": "git+https://github.com/nathansobo/node-plist.git",
"from": "git+https://github.com/nathansobo/node-plist.git#bd3a93387f1d4b2cff819b200870d35465796e77",
"requires": {
"xmlbuilder": "0.4.x",
"xmldom": "0.1.x"
@@ -4500,7 +4499,7 @@
},
"xmlbuilder": {
"version": "0.4.3",
"resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-0.4.3.tgz",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-0.4.3.tgz",
"integrity": "sha1-xGFLp04K0ZbmCcknLNnh3bKKilg="
},
"xmldom": {

View File

@@ -0,0 +1,44 @@
# Decoration ordering
## Status
Accepted
## Summary
Order block decoration items in the DOM in a deterministic and controllable way.
## Motivation
When multiple block decorations are created at the same screen line, they are inserted into the DOM in an order determined by the sequence of their creation; from oldest to newest when `position` is set to `"before"`, from newest to oldest when `position` is set to `"after"`. While this is deterministic, it is limited: it isn't possible to insert decorations within a sequence of existing ones, and it's difficult to control the order of decorations when creating and destroying and moving markers around an editor.
We hit the need for this in [atom/github#1913](https://github.com/atom/github/pull/1913) when we have a block decoration for multiple consecutive collapsed file patches.
## Explanation
[TextEditor::decorateMarker()](https://atom.io/docs/api/v1.34.0/TextEditor#instance-decorateMarker) accepts an additional `order` parameter in its `decorationParams` argument when `type` is "block". When multiple block or overlay decorations occur at the same screen line, they are ordered within the DOM in increasing "order" value.
Block decorations with the same `order` property are rendered in the order they were created, oldest to newest. Block decorations with no `order` property are rendered after those with one, in the order in which they were created, oldest to newest.
## Drawbacks
This is a breaking change for co-located block decorations created with an "after" position - they'll now appear in the reverse order.
When multiple packages create block decorations at the same screen line, they'll need to coordinate their `order` values to have expected behavior. There may not even be a clear, universal answer about how block decorations from distinct packages _should_ be ordered.
This adds another situational parameter to `TextEditor::decorationMarker()`, which already has complicated arguments.
## Rationale and alternatives
Originally I wanted to address the package coordination problem with a similar approach to [the way context menu items are ordered](https://github.com/atom/atom/pull/16661), by allowing individual decorations to specify constraints: "before this block," "after this block," "next to this block" and so forth. I ultimately chose to write up the simpler proposal because:
* Block decoration collisions among packages seem much less likely than context menu collisions.
* Constraint satisfaction problems are complex. There would be a relatively high chance of introducing bugs and performance regressions.
* The order number approach is similar to the APIs already offered to order status bar tiles and custom gutters.
The alternative to having an explicit API for this is at all is to create and destroy decorations to achieve the desired order. That's possible, but requires a great deal of bookkeeping on the package's side to accomplish, especially as decorations are added and removed and text is edited.
## Unresolved questions
- Should overlay decorations respect an `order` parameter in a similar fashion?
- Should screen column effect decoration ordering at all?

442
package-lock.json generated
View File

@@ -1,19 +1,19 @@
{
"name": "atom",
"version": "1.34.0-dev",
"version": "1.36.0-dev",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@atom/nsfw": {
"version": "1.0.18",
"resolved": "https://registry.npmjs.org/@atom/nsfw/-/nsfw-1.0.18.tgz",
"integrity": "sha512-YceKV9a3X62mh4Q78Nyi8aTRaoVGdpeJBHogL8gxU17iBhEpYvxGgMfTe02j1hH2taFT4barkZ5RdZkGKIsJ/w==",
"version": "1.0.20",
"resolved": "https://registry.npmjs.org/@atom/nsfw/-/nsfw-1.0.20.tgz",
"integrity": "sha512-g/7g0xeqoqhnpb28GZr0I6h8q6sKzS83ic+e+40cD5GoEx8Gpo2MzlvrHvrkONGxckxnSmtcIGlon7YoT/UV3Q==",
"requires": {
"fs-extra": "^0.26.5",
"fs-extra": "^7.0.0",
"lodash.isinteger": "^4.0.4",
"lodash.isundefined": "^3.0.1",
"nan": "^2.0.0",
"promisify-node": "^0.3.0"
"nan": "^2.10.0",
"promisify-node": "^0.5.0"
}
},
"@atom/source-map-support": {
@@ -283,7 +283,7 @@
},
"json5": {
"version": "0.5.1",
"resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE="
},
"lodash": {
@@ -314,9 +314,9 @@
}
},
"atom-keymap": {
"version": "8.2.11",
"resolved": "https://registry.npmjs.org/atom-keymap/-/atom-keymap-8.2.11.tgz",
"integrity": "sha512-dpTpDNENJMjT9tc+F5xUOzMKkf9rje+VZcy/Iz1+U2xvtfyhTDiHJgglXFfIqJ/0s1sCYBUfQESjJFmwBXRe1Q==",
"version": "8.2.12",
"resolved": "https://registry.npmjs.org/atom-keymap/-/atom-keymap-8.2.12.tgz",
"integrity": "sha512-qAXylPa/uysvYhZC1zJR7yG7QFs2RqU+2646JYGeiqgm0nMxLpdJpJ9ABIXbDNxzjhlRXNmZkr5V6N22RWjh4Q==",
"requires": {
"clear-cut": "^2",
"emissary": "^1.1.0",
@@ -364,11 +364,6 @@
"resolved": "https://registry.npmjs.org/atom-slick/-/atom-slick-2.0.0.tgz",
"integrity": "sha1-/w2+Fb4sTtomi50w124lF+C308o="
},
"atom-ui": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/atom-ui/-/atom-ui-0.4.1.tgz",
"integrity": "sha1-cNl3ZsukcW15jpSWKq0HkghB6lw="
},
"autocomplete-atom-api": {
"version": "https://www.atom.io/api/packages/autocomplete-atom-api/versions/0.10.7/tarball",
"integrity": "sha512-027xza+IwcoAut6ryUQYJGXkIOJkFVAA2mRzmOX5DdADSrifXDn3BZtPjfRpMMvqstC8H+xuxNs0dOdUYhssqw=="
@@ -555,7 +550,7 @@
},
"jsesc": {
"version": "1.3.0",
"resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
"integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s="
},
"lodash": {
@@ -710,22 +705,22 @@
},
"babel-plugin-syntax-class-properties": {
"version": "6.13.0",
"resolved": "http://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
"integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94="
},
"babel-plugin-syntax-flow": {
"version": "6.18.0",
"resolved": "http://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz",
"integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0="
},
"babel-plugin-syntax-jsx": {
"version": "6.18.0",
"resolved": "http://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
"integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY="
},
"babel-plugin-syntax-object-rest-spread": {
"version": "6.13.0",
"resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U="
},
"babel-plugin-transform-class-properties": {
@@ -893,9 +888,9 @@
"integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
},
"core-js": {
"version": "2.5.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz",
"integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw=="
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz",
"integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg=="
},
"home-or-tmp": {
"version": "2.0.0",
@@ -908,7 +903,7 @@
},
"json5": {
"version": "0.5.1",
"resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE="
},
"lodash": {
@@ -941,9 +936,9 @@
},
"dependencies": {
"core-js": {
"version": "2.5.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz",
"integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw=="
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz",
"integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg=="
}
}
},
@@ -1087,8 +1082,8 @@
"integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE="
},
"bookmarks": {
"version": "https://www.atom.io/api/packages/bookmarks/versions/0.45.1/tarball",
"integrity": "sha512-BcKY7ujoJoQ6x0C0CPeV4e9cw0cqwjlKvCVh3T6XeDwZQ1Na8KMrjPHWp8dO7B1cnGFN1LCWWQGWqGH624Ymkw==",
"version": "https://www.atom.io/api/packages/bookmarks/versions/0.46.0/tarball",
"integrity": "sha512-ZgYwD3Diq6nkagxuorWuKXyUBMJUZjjK1ePEYUUEzh155QcD/H1k66RZ/SfO5HrWZ4fPN+j6ux/qoXcnD77Ntg==",
"requires": {
"atom-select-list": "^0.7.0"
}
@@ -1111,8 +1106,8 @@
}
},
"bracket-matcher": {
"version": "https://www.atom.io/api/packages/bracket-matcher/versions/0.90.2/tarball",
"integrity": "sha512-ANAi0fOKm5Air6jgv682ye3UFYQpYy3s3Dk89Ap7bcNnZgsdmojA7Lq1EmeD+yobjYUqemSp/qelkktttAOgzg==",
"version": "https://www.atom.io/api/packages/bracket-matcher/versions/0.90.4/tarball",
"integrity": "sha512-vOeFxfxQGwBoNkuK7srzVUN65q7jL8UKN/IuReilfqp7eg46z39NSchQvw87dpgEOAQEkV3N99h/vBcMmIDTuw==",
"requires": {
"first-mate": "^7.0.1",
"underscore-plus": "1.x"
@@ -1162,14 +1157,6 @@
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
},
"cached-run-in-this-context": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cached-run-in-this-context/-/cached-run-in-this-context-0.5.0.tgz",
"integrity": "sha512-FdtDP0u8WjetQ95nLz9vI06efJTFrmtmk5ZT6FECpyTKi9aakNLMHyMH21WRbGYyWlbmB/QlRoB/g1lcEpyjMw==",
"requires": {
"nan": "^2.10.0"
}
},
"camelcase": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
@@ -1288,11 +1275,6 @@
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
"integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE="
},
"circular-json": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.7.tgz",
"integrity": "sha512-/pXoV1JA847qRKPrHbBK6YIBGFF8GOP4wzSgUOA7q0ew0vAv0iJswP+2/nZQ9uzA3Azi7eTrg9L2yzXc/7ZMIA=="
},
"classnames": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
@@ -1593,9 +1575,9 @@
}
},
"date-format": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz",
"integrity": "sha1-YV6CjiM90aubua4JUODOzPpuytg="
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-2.0.0.tgz",
"integrity": "sha512-M6UqVvZVgFYqZL1SfHsRGIQSz3ZL+qgbsV5Lp1Vj61LZVYuEwcMXYay7DRDtYs2HQQBK5hQtQ0fD9aEJ89V0LA=="
},
"debug": {
"version": "2.6.9",
@@ -1840,16 +1822,45 @@
}
},
"dugite": {
"version": "1.79.0",
"resolved": "https://registry.npmjs.org/dugite/-/dugite-1.79.0.tgz",
"integrity": "sha512-1iohG+Yj+7wwVNUv+HCWaK5ZeAbqNyxHZf96B65KojBVcvMT29i8Tnh/Ta/KHI7LcI0dQqSqsKJdZozpWjXWKw==",
"version": "1.81.0",
"resolved": "https://registry.npmjs.org/dugite/-/dugite-1.81.0.tgz",
"integrity": "sha512-aH1cVzbEXOHqpiub9PWJUN+R2p7H+tvN+VqyAYHR9Tj/axLDccWJk5aKDN1/US82DkaIYWUZz8x0lAbjfqrq4Q==",
"requires": {
"checksum": "^0.1.1",
"mkdirp": "^0.5.1",
"progress": "^2.0.0",
"progress": "^2.0.3",
"request": "^2.88.0",
"rimraf": "^2.5.4",
"tar": "^4.4.6"
"tar": "^4.4.7"
},
"dependencies": {
"chownr": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
"integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g=="
},
"minizlib": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz",
"integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==",
"requires": {
"minipass": "^2.2.1"
}
},
"tar": {
"version": "4.4.8",
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz",
"integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==",
"requires": {
"chownr": "^1.1.1",
"fs-minipass": "^1.2.5",
"minipass": "^2.3.4",
"minizlib": "^1.1.1",
"mkdirp": "^0.5.0",
"safe-buffer": "^5.1.2",
"yallist": "^3.0.2"
}
}
}
},
"duplexer": {
@@ -1867,11 +1878,11 @@
}
},
"element-resize-detector": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/element-resize-detector/-/element-resize-detector-1.1.14.tgz",
"integrity": "sha1-rwZKCmGKggrVcKlcXuxbd74BKME=",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/element-resize-detector/-/element-resize-detector-1.2.0.tgz",
"integrity": "sha512-UmhNB8sIJVZeg56gEjgmMd6p37sCg8j8trVW0LZM7Wzv+kxQ5CnRHcgRKBTB/kFUSn3e7UP59kl2V2U8Du1hmg==",
"requires": {
"batch-processor": "^1.0.0"
"batch-processor": "1.0.0"
}
},
"emissary": {
@@ -2145,8 +2156,8 @@
}
},
"find-and-replace": {
"version": "https://www.atom.io/api/packages/find-and-replace/versions/0.215.14/tarball",
"integrity": "sha512-6TGLE6HQPWeD7jCrtIh5lxoXSoFcSQplbcaFX/HPUmjcUko3/QfuLEuTFmosidwQSWSAcPwUpcQ0Ih3e2KiryA==",
"version": "https://www.atom.io/api/packages/find-and-replace/versions/0.218.0/tarball",
"integrity": "sha512-c77OpEcgce8cfPgjPQStEvK016AVmNMUfKIuCYgzYbjTik2lCSU+QAEG3q6MitIzqoFiSW6WW3FL502HFyZwKg==",
"requires": {
"binary-search": "^1.3.3",
"element-resize-detector": "^1.1.10",
@@ -2192,6 +2203,11 @@
}
}
},
"flatted": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz",
"integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg=="
},
"flatten": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
@@ -2306,25 +2322,13 @@
"integrity": "sha1-a+Dem+mYzhavivwkSXue6bfM2a0="
},
"fs-extra": {
"version": "0.26.7",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz",
"integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.0.tgz",
"integrity": "sha512-EglNDLRpmaTWiD/qraZn6HREAEAHJcJOmxNEYwq6xeMKnVMAy3GUcFB+wXt2C6k4CNvB/mP1y/U3dzvKKj5OtQ==",
"requires": {
"graceful-fs": "^4.1.2",
"jsonfile": "^2.1.0",
"klaw": "^1.0.0",
"path-is-absolute": "^1.0.0",
"rimraf": "^2.2.8"
},
"dependencies": {
"jsonfile": {
"version": "2.4.0",
"resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
"integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
"requires": {
"graceful-fs": "^4.1.6"
}
}
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"fs-minipass": {
@@ -2336,9 +2340,9 @@
}
},
"fs-plus": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.0.2.tgz",
"integrity": "sha1-a19Sp3EolMTd6f2PgfqMYN8EHz0=",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.1.1.tgz",
"integrity": "sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==",
"requires": {
"async": "^1.5.2",
"mkdirp": "^0.5.1",
@@ -2348,7 +2352,7 @@
"dependencies": {
"async": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
}
}
@@ -2397,8 +2401,8 @@
"integrity": "sha1-gy9kifvodnaUWVmckUpnDsIpR+4="
},
"fuzzy-finder": {
"version": "https://www.atom.io/api/packages/fuzzy-finder/versions/1.8.2/tarball",
"integrity": "sha512-wg3uX5fPtVItOByflO+vsQKHAqn3aSgutYM+xO3lEKQov9DuMdtMzMgbf/Tlam0YwjV+Qz/JV10LluJuliP03A==",
"version": "https://www.atom.io/api/packages/fuzzy-finder/versions/1.9.0/tarball",
"integrity": "sha512-YJTPPMZLQmDiUa6eoONhHF7sOvAPQqrXNFLfPGAUItDUoJxvJBwkPcxh+ryCHLlO8MuoJdDvAKHsU0mGzb/JeQ==",
"requires": {
"async": "0.2.6",
"atom-select-list": "^0.7.0",
@@ -2483,8 +2487,8 @@
}
},
"github": {
"version": "https://www.atom.io/api/packages/github/versions/0.23.0/tarball",
"integrity": "sha512-VWpKCWY5jsQpEF3XmWCwdlFU5n2S0PQ2PLOD/9WnvuC9U7vtKyrEdd5bqWxS76KNOwpjw6CRoyPmK7WYsKtz6g==",
"version": "https://www.atom.io/api/packages/github/versions/0.24.0/tarball",
"integrity": "sha512-STupVetbztFBB+eGnzUyuX1jbeRL9z9vkkf3t1zbi0+8zr82NDWhSRlyojYyJ0vsT0BbqYxDeKWYl4kQySOfdg==",
"requires": {
"atom-babel6-transpiler": "1.2.0",
"babel-generator": "6.26.1",
@@ -2498,7 +2502,7 @@
"classnames": "2.2.6",
"compare-sets": "1.0.1",
"dugite": "^1.79.0",
"event-kit": "2.5.2",
"event-kit": "2.5.3",
"fs-extra": "4.0.3",
"graphql": "0.13.2",
"keytar": "4.2.1",
@@ -2512,20 +2516,15 @@
"react-select": "1.2.1",
"react-tabs": "^2.3.0",
"relay-runtime": "1.6.0",
"temp": "0.8.3",
"temp": "0.9.0",
"tinycolor2": "1.4.1",
"tree-kill": "1.2.0",
"tree-kill": "1.2.1",
"underscore-plus": "1.6.8",
"what-the-diff": "0.4.0",
"what-the-diff": "0.5.0",
"what-the-status": "1.0.3",
"yubikiri": "1.0.0"
},
"dependencies": {
"event-kit": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/event-kit/-/event-kit-2.5.2.tgz",
"integrity": "sha512-1w3eEk45CstP8gzQtJdxhNl6kmvT+3dsGMK31VX7Wmt1/hlwS+s2yJY7SeVRhyhhx2W8neomdBfSZ9ACJ9eNeg=="
},
"fs-extra": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
@@ -2535,6 +2534,14 @@
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"temp": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/temp/-/temp-0.9.0.tgz",
"integrity": "sha512-YfUhPQCJoNQE5N+FJQcdPz63O3x3sdT4Xju69Gj4iZe0lBKOtnAMi0SLj9xKhGkcGhsxThvTJ/usxtFPo438zQ==",
"requires": {
"rimraf": "~2.6.2"
}
}
}
},
@@ -2756,20 +2763,14 @@
"optional": true
},
"image-view": {
"version": "https://www.atom.io/api/packages/image-view/versions/0.63.1/tarball",
"integrity": "sha512-KMtreZG1QLdCiCmkoHPKnP54oe2mEXDyoliM0wYTsVvaTOIfXW6Gi1rbQgGClqi+iHHWOBFKuJdmVGj/phbK9Q==",
"version": "https://www.atom.io/api/packages/image-view/versions/0.64.0/tarball",
"integrity": "sha512-MQLv/IFAvBvycg7ZrcyIHpcQ/dxKNNRmlMyB0rlY1Owc01bNJDDjkhmSDKSNwl0T9slWwE4emlzGQvqoNWUDbw==",
"requires": {
"bytes": "^2.4.0",
"bytes": "^3.0.0",
"etch": "0.9.0",
"fs-plus": "^3.0.0",
"underscore-plus": "^1.0.0"
"fs-plus": "^3.0.0"
},
"dependencies": {
"bytes": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-2.5.0.tgz",
"integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo="
},
"etch": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/etch/-/etch-0.9.0.tgz",
@@ -3109,7 +3110,7 @@
},
"keytar": {
"version": "4.2.1",
"resolved": "http://registry.npmjs.org/keytar/-/keytar-4.2.1.tgz",
"resolved": "https://registry.npmjs.org/keytar/-/keytar-4.2.1.tgz",
"integrity": "sha1-igamV3/fY3PgqmsRInfmPex3/RI=",
"requires": {
"nan": "2.8.0",
@@ -3131,14 +3132,6 @@
"is-buffer": "^1.1.5"
}
},
"klaw": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
"integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
"requires": {
"graceful-fs": "^4.1.9"
}
},
"language-c": {
"version": "https://www.atom.io/api/packages/language-c/versions/0.60.14/tarball",
"integrity": "sha512-jGFMc9vNutvBflFdoUXWJqxBFdMFG7n13PxS8z+SB8H0taZStq55JixDaQ0i/qu7ay4K5BCJ7y/PHdL13vjouQ==",
@@ -3152,8 +3145,8 @@
"integrity": "sha512-HJfBRKbzOYGlEVQNnnRtx0BgiZ9pHlUioHUtG9pFV65EgO4jm4Q5cPHLDvBj+zEy0cm28eYgEYFjfacyBaZElg=="
},
"language-coffee-script": {
"version": "https://www.atom.io/api/packages/language-coffee-script/versions/0.49.3/tarball",
"integrity": "sha512-2xXcSiiRySd0qE4lhsOTqMwcKlBVKc/0ru9HHGJSeTdp/On9iNrkcM1+asDYa/QmvppgAILC2/0xUS6+B/cnqQ=="
"version": "https://www.atom.io/api/packages/language-coffee-script/versions/0.50.0/tarball",
"integrity": "sha512-Sp3b1i8wsd+AELphP2f52mli4C3YjicGC8ps21g48V3SrTZoM7tLE7lkcEdKddYlTqo0fBixTKN2R/iL6GcEVw=="
},
"language-csharp": {
"version": "https://www.atom.io/api/packages/language-csharp/versions/1.1.0/tarball",
@@ -3182,8 +3175,8 @@
}
},
"language-html": {
"version": "https://www.atom.io/api/packages/language-html/versions/0.51.5/tarball",
"integrity": "sha512-ZzYdXsmbcKpRHvkq2SyWVByVmzsVAx6UquYOFlN5R51Wn21WeAIHhvf0sz54WntkTXOCGoaII/4sLxrkeqNEKw==",
"version": "https://www.atom.io/api/packages/language-html/versions/0.52.0/tarball",
"integrity": "sha512-fmj0XFE6x8LsiJwcTtXDqDlajcPYDf+ZFHE13K4N1fQrWa7/lICN5k0qOWTvWZJPeEL+p32okzN+SdWmiYKdpw==",
"requires": {
"atom-grammar-test": "^0.6.3",
"tree-sitter-embedded-template": "^0.13.0",
@@ -3199,10 +3192,10 @@
"integrity": "sha512-kdTsc2efREnuj72WsAfcx28h0RqrVUIGF7BQcS5zy+ZibqbvnaB5DiVunRFYLhefGoaKVkAyTdRkZWMKH/yIWg=="
},
"language-javascript": {
"version": "https://www.atom.io/api/packages/language-javascript/versions/0.129.18/tarball",
"integrity": "sha512-ZCcMHpz7tiBzKCeaDzNGfDcthz504qcleo9hsPFcPkGL0uwOBe4AWpX1xNUz+Uhljf9jHzu7aS3d2G0lvGAMKQ==",
"version": "https://www.atom.io/api/packages/language-javascript/versions/0.129.19/tarball",
"integrity": "sha512-ClPU0dc41WqagaPd+qy5DQ5ahDCVcfFxC1nwppyQSsSXzrzsiE2+FuYzG33OMaSGDA6/zZ6gBkHXnXXPFzWcNA==",
"requires": {
"tree-sitter-javascript": "^0.13.8",
"tree-sitter-javascript": "^0.13.10",
"tree-sitter-jsdoc": "^0.13.4",
"tree-sitter-regex": "^0.13.1"
}
@@ -3248,10 +3241,10 @@
}
},
"language-ruby": {
"version": "https://www.atom.io/api/packages/language-ruby/versions/0.72.14/tarball",
"integrity": "sha512-acTLw8OPSpsCLiwTwMR8kekEJ50FUL4ZFWrriUTjJXg9ePdYCglKsZr5Zaw36a/3AIceCwbwTSWG+hW/O3kYRQ==",
"version": "https://www.atom.io/api/packages/language-ruby/versions/0.72.15/tarball",
"integrity": "sha512-S+VSHL5wUjXvCGswOYTtB/O6D1irmwyU+pkqktyv8o7BKUfvhOygFGAtFTfjglzGdezw4gHnWgb92fMHcymkwQ==",
"requires": {
"tree-sitter-ruby": "^0.13.10"
"tree-sitter-ruby": "^0.13.12"
}
},
"language-ruby-on-rails": {
@@ -3583,21 +3576,21 @@
"integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE="
},
"log4js": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.5.tgz",
"integrity": "sha512-IX5c3G/7fuTtdr0JjOT2OIR12aTESVhsH6cEsijloYwKgcPRlO6DgOU72v0UFhWcoV1HN6+M3dwT89qVPLXm0w==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/log4js/-/log4js-4.0.0.tgz",
"integrity": "sha512-XlxZfcFAvQjnjCJBIV/EpsPmrVC12n+TxNUKgrmQh6eeA+9X+6UqvaRNV8t6dpMtXszl1LAQimB4pqyp2Gsgfw==",
"requires": {
"circular-json": "^0.5.5",
"date-format": "^1.2.0",
"date-format": "^2.0.0",
"debug": "^3.1.0",
"flatted": "^2.0.0",
"rfdc": "^1.1.2",
"streamroller": "0.7.0"
"streamroller": "^1.0.1"
},
"dependencies": {
"debug": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz",
"integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==",
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
"requires": {
"ms": "^2.1.1"
}
@@ -4086,8 +4079,8 @@
}
},
"notifications": {
"version": "https://www.atom.io/api/packages/notifications/versions/0.70.5/tarball",
"integrity": "sha512-Eye5knLSgDXOr4qQNv/mnSp+rfmckK+J3Gok6j+tQuaiIYwCPPmJ2rRjy5t6gaJo81yZRuheBf0ur3TpKTXuUw==",
"version": "https://www.atom.io/api/packages/notifications/versions/0.70.6/tarball",
"integrity": "sha512-Gen7TAvNIBwSE9LDl1ejr8Sp2ipGP0je4F2mVqQkED0ScjEr+uHFMqamCYSCh0k6YqQ12Hu0b4clagTPrtMOKQ==",
"requires": {
"dompurify": "^1.0.3",
"fs-plus": "^3.0.0",
@@ -4249,9 +4242,9 @@
"integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME="
},
"pathwatcher": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/pathwatcher/-/pathwatcher-8.0.1.tgz",
"integrity": "sha1-UaLOKgHbbDLYZ/ZYXvKEvmvQo64=",
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/pathwatcher/-/pathwatcher-8.0.2.tgz",
"integrity": "sha512-zuP+fLmB2IB6z89ikcehA+vG/ITx3Cmhaj3DJrBgnbdss6dwPolSq7cDBjgZ78Vl+SXmG7CHGIOM5mqdT9h7BQ==",
"requires": {
"async": "~0.2.10",
"emissary": "^1.3.2",
@@ -4259,19 +4252,19 @@
"fs-plus": "^3.0.0",
"grim": "^2.0.1",
"iconv-lite": "~0.4.4",
"nan": "2.x",
"nan": "^2.10.0",
"underscore-plus": "~1.x"
},
"dependencies": {
"async": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
"resolved": "http://registry.npmjs.org/async/-/async-0.2.10.tgz",
"integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E="
},
"grim": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/grim/-/grim-2.0.2.tgz",
"integrity": "sha1-52CinKe4NDsMH/r2ziDyGkbuiu0=",
"integrity": "sha512-Qj7hTJRfd87E/gUgfvM0YIH/g2UA2SV6niv6BYXk1o6w4mhgv+QyYM1EjOJQljvzgEj4SqSsRWldXIeKHz3e3Q==",
"requires": {
"event-kit": "^2.0.0"
}
@@ -4361,7 +4354,7 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
}
}
@@ -4377,9 +4370,9 @@
"integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o="
},
"progress": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz",
"integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg=="
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
},
"promise": {
"version": "7.3.1",
@@ -4390,11 +4383,12 @@
}
},
"promisify-node": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/promisify-node/-/promisify-node-0.3.0.tgz",
"integrity": "sha1-tLVaz5D6p9K4uQyjlomQhsAwYM8=",
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/promisify-node/-/promisify-node-0.5.0.tgz",
"integrity": "sha512-GR2E4qgCoKFTprhULqP2OP3bl8kHo16XtnqtkHH6be7tPW1yL6rXd15nl3oV2sLTFv1+j6tqoF69VVpFtJ/j+A==",
"requires": {
"nodegit-promise": "~4.0.0"
"nodegit-promise": "^4.0.0",
"object-assign": "^4.1.1"
}
},
"prop-types": {
@@ -4934,8 +4928,8 @@
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
},
"settings-view": {
"version": "https://www.atom.io/api/packages/settings-view/versions/0.257.2/tarball",
"integrity": "sha512-wAqucDcKKHKiCGw9a29/s6dWLfAB9tBdawQ3dKBxqLwh/eERdQjO4qAxlbsMDlWDf9iOsgSSYpfk8r1/OqbMbQ==",
"version": "https://www.atom.io/api/packages/settings-view/versions/0.258.0/tarball",
"integrity": "sha512-X2avkVC51tM8yGxyQDXF9DZUbxTOhuJPZbgZJaXkebo+Yj/aq4AUkc+AQFOHzWs+PWctyIzCem4PyRq8XIoQ+A==",
"requires": {
"async": "~0.2.9",
"dompurify": "^1.0.2",
@@ -5069,12 +5063,10 @@
}
},
"solarized-dark-syntax": {
"version": "https://www.atom.io/api/packages/solarized-dark-syntax/versions/1.3.0/tarball",
"integrity": "sha512-2X4Df16sQqna8dmpWnpk2FoL346cXW34Vk2JKJY23fYYCH3t16mGl9G9URB7+S2x+/WmeCjdwIQSMsGvBf/95g=="
"version": "file:packages/solarized-dark-syntax"
},
"solarized-light-syntax": {
"version": "https://www.atom.io/api/packages/solarized-light-syntax/versions/1.3.0/tarball",
"integrity": "sha512-DVl8aJnecUKy5s1WY5mDyN1/3McqyZWfE3cjBVY8U7X4w9Xkp8SPVndVGufSpSWIxh9vY/iSU4kfBxWqUdiW5w=="
"version": "file:packages/solarized-light-syntax"
},
"source-map": {
"version": "0.1.32",
@@ -5121,22 +5113,22 @@
"integrity": "sha1-enzShHDMbToc/m1miG9rxDDTrIc="
},
"spell-check": {
"version": "https://www.atom.io/api/packages/spell-check/versions/0.74.2/tarball",
"integrity": "sha512-WhwhDF4nznhQuwnRemZbXODI6aqax2HlHudfLEjbhzkRGjEbfssRK82lRRvCK9LmQh3fAqCqbmELU40NEODJ8Q==",
"version": "https://www.atom.io/api/packages/spell-check/versions/0.74.3/tarball",
"integrity": "sha512-QYy0xpSKp8OSZjlvq7fOjrf/NdG4BncHvn9AmO/vcuJvWAoiwEWhqqB+BSA6uSrxOxJeJhbDJSxOrvm4YXs1xQ==",
"requires": {
"atom-pathspec": "^0.0.0",
"atom-select-list": "^0.7.0",
"multi-integer-range": "^2.0.0",
"natural": "^0.4.0",
"spellchecker": "^3.4.4",
"spellchecker": "^3.5.1",
"spelling-manager": "^1.1.0",
"underscore-plus": "^1"
}
},
"spellchecker": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/spellchecker/-/spellchecker-3.5.0.tgz",
"integrity": "sha512-Xa7XnRulYhh5N/XENeL2O8/875XhLBjos7Bemv0rfcgV6ojNYMSrXscUZUGJwniX2t67eY+lNUJeptD1bMauHQ==",
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/spellchecker/-/spellchecker-3.5.1.tgz",
"integrity": "sha512-R1qUBsDZzio+7MFZN6/AtPUe5NGvnc0wywckuXAlp9akASaYSFqKuI5O8p3rSiA+yKP31qC7Iijjoygmzkh6xw==",
"requires": {
"any-promise": "^1.3.0",
"nan": "^2.10.0"
@@ -5208,8 +5200,8 @@
"integrity": "sha1-ATl5IuX2Ls8whFUiyVxP4dJefU4="
},
"status-bar": {
"version": "https://www.atom.io/api/packages/status-bar/versions/1.8.15/tarball",
"integrity": "sha512-zQa+fdr6pAnix4Lw3tKiU6Uq8Hx1dLsb+w2SaxIDbJaZatO25rN9FTZqNrw0ZchJpCEiSkuLolqUutPB4iNydQ==",
"version": "https://www.atom.io/api/packages/status-bar/versions/1.8.17/tarball",
"integrity": "sha512-QqUIcKw3QuFtstyl841kJ67oBGewWJGe12q+aEkyv6c6jvWBThfLHrGbnvJxgWqtYWbYQtXuqQdj3Wd//EZk6g==",
"requires": {
"fs-plus": "^3.0.1",
"grim": "^2.0.1",
@@ -5219,7 +5211,7 @@
"grim": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/grim/-/grim-2.0.2.tgz",
"integrity": "sha1-52CinKe4NDsMH/r2ziDyGkbuiu0=",
"integrity": "sha512-Qj7hTJRfd87E/gUgfvM0YIH/g2UA2SV6niv6BYXk1o6w4mhgv+QyYM1EjOJQljvzgEj4SqSsRWldXIeKHz3e3Q==",
"requires": {
"event-kit": "^2.0.0"
}
@@ -5235,24 +5227,38 @@
}
},
"streamroller": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz",
"integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/streamroller/-/streamroller-1.0.1.tgz",
"integrity": "sha512-FKL2mEB0A+XTIWSOlBHm2DvdsER5cGraqrUufO0lFMfsVY+Gpb3TC29Z+6/l0Urbb7vtm6m9zJOQBVl6fEkZBA==",
"requires": {
"date-format": "^1.2.0",
"async": "^2.6.1",
"date-format": "^2.0.0",
"debug": "^3.1.0",
"mkdirp": "^0.5.1",
"readable-stream": "^2.3.0"
"fs-extra": "^7.0.0",
"lodash": "^4.17.10"
},
"dependencies": {
"async": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
"integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
"requires": {
"lodash": "^4.17.10"
}
},
"debug": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz",
"integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==",
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
"requires": {
"ms": "^2.1.1"
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
@@ -5324,9 +5330,9 @@
}
},
"superstring": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/superstring/-/superstring-2.3.4.tgz",
"integrity": "sha512-DcNkTCdB9F3FMZRdURSALsHi+7DWqFCI0cH+Eg8mwBg+kxQs6GeB3LrGUvCI5bEB6Dtlu2ox8UYN0onPN4JeZQ==",
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/superstring/-/superstring-2.3.6.tgz",
"integrity": "sha512-kDTXCXArhHL1lRk2zBW7ByRJByqVwoLK3E3jlf8+LcwQLZgSMs9dwrDHDpBdoOm89kstSBSrGcW8OJqNkxjWrQ==",
"requires": {
"nan": "^2.10.0"
}
@@ -5361,8 +5367,8 @@
"integrity": "sha1-Dk7jdvNjHkLXl3oHTb0rOCeEMIE="
},
"tabs": {
"version": "https://www.atom.io/api/packages/tabs/versions/0.109.2/tarball",
"integrity": "sha512-IdKT8s9Wm4++Sm5wLzrI+nLCB57DMUtTMYnLGlA9Y/C/IRlfMp3PQC2aM/dHGuIzf9JsXsI2wfPsJcU4YXKFoQ==",
"version": "https://www.atom.io/api/packages/tabs/versions/0.110.0/tarball",
"integrity": "sha512-O8Tj9zfpcNavbFuHcNVUnv09Bbya4gFSJgd79IRFHy+d/blViK2Ai8X0Y32vJjxgywzrCIpthOHxw0l9qaqylA==",
"requires": {
"fs-plus": "^3.0.0",
"temp": "~0.8.1",
@@ -5460,21 +5466,21 @@
}
},
"text-buffer": {
"version": "13.15.0",
"resolved": "https://registry.npmjs.org/text-buffer/-/text-buffer-13.15.0.tgz",
"integrity": "sha512-8X2rSI/W+w+nzSLQ8vm1xLFKZbgcLndDEOsMzN3lNKCy3Zuzru40fl2KHEko6MqHXAGKgA78+kvEDW/gryCP1g==",
"version": "13.15.3",
"resolved": "https://registry.npmjs.org/text-buffer/-/text-buffer-13.15.3.tgz",
"integrity": "sha512-H2fz/N15g0fBP7R33FUFLnIyND+Lji/xmuvHg9rKgmfCh7NAVxiFIvnZTabuBhL9InqPrtV5t4hkUy+r3dNXMg==",
"requires": {
"delegato": "^1.0.0",
"diff": "^2.2.1",
"emissary": "^1.0.0",
"event-kit": "^2.4.0",
"fs-admin": "^0.1.4",
"fs-admin": "^0.1.7",
"fs-plus": "^3.0.0",
"grim": "^2.0.2",
"mkdirp": "^0.5.1",
"pathwatcher": "8.0.1",
"pathwatcher": "8.0.2",
"serializable": "^1.0.3",
"superstring": "2.3.4",
"superstring": "2.3.6",
"underscore-plus": "^1.0.0"
},
"dependencies": {
@@ -5537,9 +5543,9 @@
}
},
"tree-kill": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz",
"integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg=="
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz",
"integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q=="
},
"tree-sitter": {
"version": "0.13.23",
@@ -5667,17 +5673,17 @@
}
},
"tree-sitter-html": {
"version": "0.13.4",
"resolved": "https://registry.npmjs.org/tree-sitter-html/-/tree-sitter-html-0.13.4.tgz",
"integrity": "sha512-l52UJ27BmGdwUgEC3d7UJKTtAJDIQ9GL+du8qQoDt2oJg/iSRxckZeevwJ+YyCfYjBlqFH7nXDLtVJxEzhdM/g==",
"version": "0.13.5",
"resolved": "https://registry.npmjs.org/tree-sitter-html/-/tree-sitter-html-0.13.5.tgz",
"integrity": "sha512-lawojfDlj/9ujEYvLoW4+WTTh2ocrYCYP2Dw5LmwxuvvE2lHr/D4RWA8W1N4jpR58tVef0SSqnnQwJkl1pNIeA==",
"requires": {
"nan": "^2.10.0"
}
},
"tree-sitter-javascript": {
"version": "0.13.8",
"resolved": "https://registry.npmjs.org/tree-sitter-javascript/-/tree-sitter-javascript-0.13.8.tgz",
"integrity": "sha512-p7u6ZXEX1sIjgGNAiuSNnK6PSl5FiUsQzEV2QOAYVH5GN13cUnUsoa/BiaDMWQ3uddoNXwTdxhB8UwNAolizQQ==",
"version": "0.13.10",
"resolved": "https://registry.npmjs.org/tree-sitter-javascript/-/tree-sitter-javascript-0.13.10.tgz",
"integrity": "sha512-ku/841Nu7k/VXwI2ifm7xxv2cUiiYztLlIeYTYZXpjaIHMfFer5XZRgmZldJHVthTQ9uRMEr7UQ0qeqnWKzOlg==",
"requires": {
"nan": "^2.4.0"
}
@@ -5691,9 +5697,9 @@
},
"dependencies": {
"nan": {
"version": "2.11.1",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz",
"integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA=="
"version": "2.12.1",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz",
"integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw=="
}
}
},
@@ -5714,26 +5720,31 @@
}
},
"tree-sitter-ruby": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/tree-sitter-ruby/-/tree-sitter-ruby-0.13.11.tgz",
"integrity": "sha512-EBmBBZ20yaoRqDRgQof9Yir29/3lv5cY/y8UDUC1GzRf5pYd4CsYU0WAjIJ7dyAv+3n7p3y/LOuXkyJLiIN1wA==",
"version": "0.13.12",
"resolved": "https://registry.npmjs.org/tree-sitter-ruby/-/tree-sitter-ruby-0.13.12.tgz",
"integrity": "sha512-QAf7qtOuOSgYtLnJKOapUw389mwSFQdg9LdSXOO1aO5OZ0yFewFChOSxjG4sH7skaXQenkQdT9ASD79WbjRuZw==",
"requires": {
"nan": "^2.10.0",
"prebuild-install": "^5.0.0"
},
"dependencies": {
"expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
},
"prebuild-install": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.2.1.tgz",
"integrity": "sha512-9DAccsInWHB48TBQi2eJkLPE049JuAI6FjIH0oIrij4bpDVEbX6JvlWRAcAAlUqBHhjgq0jNqA3m3bBXWm9v6w==",
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.2.2.tgz",
"integrity": "sha512-4e8VJnP3zJdZv/uP0eNWmr2r9urp4NECw7Mt1OSAi3rcLrbBRxGiAkfUFtre2MhQ5wfREAjRV+K1gubvs/GPsA==",
"requires": {
"detect-libc": "^1.0.3",
"expand-template": "^1.0.2",
"expand-template": "^2.0.3",
"github-from-package": "0.0.0",
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
@@ -5769,8 +5780,8 @@
}
},
"tree-view": {
"version": "https://www.atom.io/api/packages/tree-view/versions/0.224.4/tarball",
"integrity": "sha512-C1TZTezOu8y5qv4xsYM3G7JePyF4o7TqFj2jYo09YiXtW3m/RX+uTT7WfL8ozGsq082uVzuPlu8/kQAotv95qQ==",
"version": "https://www.atom.io/api/packages/tree-view/versions/0.224.5/tarball",
"integrity": "sha512-cIHL5pewQlD8v5Y30cquYTc74TeJ6+6wXKA6+Hsjh0Z28+lEB3Gqac8AKYPFUaGsSEm5MH6us3FJ/4y1Yqkr2Q==",
"requires": {
"@atom/temp": "~0.8.4",
"fs-plus": "^3.0.0",
@@ -5926,9 +5937,9 @@
}
},
"what-the-diff": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/what-the-diff/-/what-the-diff-0.4.0.tgz",
"integrity": "sha512-Aw5OoYs5pY4RcZhD9UrS/brg/YRFm/SRRwJEI3f12PTWYadXzkvmf2eGDggSwcZuH2OH8J5HmtUK6LH+jRc2aA=="
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/what-the-diff/-/what-the-diff-0.5.0.tgz",
"integrity": "sha512-+ZX92uzic8Ufbyvl128Rsi8Hf67lYMKA4MJBOUtDnA3PD+rQY0493G25KAKzb9qQ8NN5TcD6VyV/BqBFq1Ktuw=="
},
"what-the-status": {
"version": "1.0.3",
@@ -5985,21 +5996,8 @@
}
},
"wrap-guide": {
"version": "https://www.atom.io/api/packages/wrap-guide/versions/0.40.3/tarball",
"integrity": "sha512-TQdO+E8t8sS3c4UUym2Orrf4s6/AYGrfu32lUHLMgnSYcBov/t8J3jYJfPImNkCq7kgYgfycQZM5UryW54J4KA==",
"requires": {
"grim": "^2.0.1"
},
"dependencies": {
"grim": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/grim/-/grim-2.0.2.tgz",
"integrity": "sha1-52CinKe4NDsMH/r2ziDyGkbuiu0=",
"requires": {
"event-kit": "^2.0.0"
}
}
}
"version": "https://www.atom.io/api/packages/wrap-guide/versions/0.41.0/tarball",
"integrity": "sha512-1XF9yc6pjp3f9smEBrnrNuk0pA6fKd+xet5OMD05ehZs4wA9/lnXrxTd9hCPJpP4krqHdcNFB5/h4VRJWlrlmQ=="
},
"wrappy": {
"version": "1.0.2",

View File

@@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "1.35.0-dev",
"version": "1.36.0-dev",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/main-process/main.js",
"repository": {
@@ -12,9 +12,9 @@
"url": "https://github.com/atom/atom/issues"
},
"license": "MIT",
"electronVersion": "2.0.14",
"electronVersion": "3.0.14",
"dependencies": {
"@atom/nsfw": "1.0.18",
"@atom/nsfw": "^1.0.20",
"@atom/source-map-support": "^0.3.4",
"@atom/watcher": "1.0.8",
"about": "file:packages/about",
@@ -22,11 +22,10 @@
"async": "0.2.6",
"atom-dark-syntax": "file:packages/atom-dark-syntax",
"atom-dark-ui": "file:packages/atom-dark-ui",
"atom-keymap": "8.2.11",
"atom-keymap": "8.2.12",
"atom-light-syntax": "file:packages/atom-light-syntax",
"atom-light-ui": "file:packages/atom-light-ui",
"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.8/tarball",
@@ -38,9 +37,8 @@
"background-tips": "https://www.atom.io/api/packages/background-tips/versions/0.28.0/tarball",
"base16-tomorrow-dark-theme": "file:packages/base16-tomorrow-dark-theme",
"base16-tomorrow-light-theme": "file:packages/base16-tomorrow-light-theme",
"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.90.2/tarball",
"cached-run-in-this-context": "0.5.0",
"bookmarks": "https://www.atom.io/api/packages/bookmarks/versions/0.46.0/tarball",
"bracket-matcher": "https://www.atom.io/api/packages/bracket-matcher/versions/0.90.4/tarball",
"chai": "3.5.0",
"chart.js": "^2.3.0",
"clear-cut": "^2.0.2",
@@ -56,23 +54,23 @@
"etch": "^0.12.6",
"event-kit": "^2.5.3",
"exception-reporting": "file:packages/exception-reporting",
"find-and-replace": "https://www.atom.io/api/packages/find-and-replace/versions/0.215.14/tarball",
"find-and-replace": "https://www.atom.io/api/packages/find-and-replace/versions/0.218.0/tarball",
"find-parent-dir": "^0.3.0",
"first-mate": "7.1.3",
"focus-trap": "2.4.5",
"fs-admin": "^0.1.7",
"fs-plus": "^3.0.1",
"fs-plus": "^3.1.1",
"fstream": "0.1.24",
"fuzzaldrin": "^2.1",
"fuzzy-finder": "https://www.atom.io/api/packages/fuzzy-finder/versions/1.8.2/tarball",
"fuzzy-finder": "https://www.atom.io/api/packages/fuzzy-finder/versions/1.9.0/tarball",
"git-diff": "file:packages/git-diff",
"git-utils": "5.2.1",
"github": "https://www.atom.io/api/packages/github/versions/0.23.0/tarball",
"github": "https://www.atom.io/api/packages/github/versions/0.24.0/tarball",
"glob": "^7.1.1",
"go-to-line": "file:packages/go-to-line",
"grammar-selector": "file:packages/grammar-selector",
"grim": "1.5.0",
"image-view": "https://www.atom.io/api/packages/image-view/versions/0.63.1/tarball",
"image-view": "https://www.atom.io/api/packages/image-view/versions/0.64.0/tarball",
"incompatible-packages": "file:packages/incompatible-packages",
"jasmine-json": "~0.0",
"jasmine-reporters": "1.1.0",
@@ -81,16 +79,16 @@
"keybinding-resolver": "https://www.atom.io/api/packages/keybinding-resolver/versions/0.38.4/tarball",
"language-c": "https://www.atom.io/api/packages/language-c/versions/0.60.14/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-coffee-script": "https://www.atom.io/api/packages/language-coffee-script/versions/0.50.0/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.43.0/tarball",
"language-gfm": "https://www.atom.io/api/packages/language-gfm/versions/0.90.6/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.6/tarball",
"language-html": "https://www.atom.io/api/packages/language-html/versions/0.51.5/tarball",
"language-html": "https://www.atom.io/api/packages/language-html/versions/0.52.0/tarball",
"language-hyperlink": "https://www.atom.io/api/packages/language-hyperlink/versions/0.17.0/tarball",
"language-java": "https://www.atom.io/api/packages/language-java/versions/0.31.1/tarball",
"language-javascript": "https://www.atom.io/api/packages/language-javascript/versions/0.129.18/tarball",
"language-javascript": "https://www.atom.io/api/packages/language-javascript/versions/0.129.19/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.3/tarball",
"language-make": "https://www.atom.io/api/packages/language-make/versions/0.23.0/tarball",
@@ -100,7 +98,7 @@
"language-php": "https://www.atom.io/api/packages/language-php/versions/0.44.1/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.8/tarball",
"language-ruby": "https://www.atom.io/api/packages/language-ruby/versions/0.72.14/tarball",
"language-ruby": "https://www.atom.io/api/packages/language-ruby/versions/0.72.15/tarball",
"language-ruby-on-rails": "https://www.atom.io/api/packages/language-ruby-on-rails/versions/0.25.3/tarball",
"language-rust-bundled": "file:packages/language-rust-bundled",
"language-sass": "https://www.atom.io/api/packages/language-sass/versions/0.62.0/tarball",
@@ -126,7 +124,7 @@
"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",
"notifications": "https://www.atom.io/api/packages/notifications/versions/0.70.6/tarball",
"nslog": "^3",
"one-dark-syntax": "file:packages/one-dark-syntax",
"one-dark-ui": "file:packages/one-dark-ui",
@@ -134,7 +132,7 @@
"one-light-ui": "file:packages/one-light-ui",
"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",
"pathwatcher": "8.0.2",
"postcss": "5.2.4",
"postcss-selector-parser": "2.2.1",
"property-accessors": "^1.1.3",
@@ -146,29 +144,29 @@
"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.257.2/tarball",
"settings-view": "https://www.atom.io/api/packages/settings-view/versions/0.258.0/tarball",
"sinon": "1.17.4",
"snippets": "https://www.atom.io/api/packages/snippets/versions/1.4.0/tarball",
"solarized-dark-syntax": "https://www.atom.io/api/packages/solarized-dark-syntax/versions/1.3.0/tarball",
"solarized-light-syntax": "https://www.atom.io/api/packages/solarized-light-syntax/versions/1.3.0/tarball",
"spell-check": "https://www.atom.io/api/packages/spell-check/versions/0.74.2/tarball",
"status-bar": "https://www.atom.io/api/packages/status-bar/versions/1.8.15/tarball",
"solarized-dark-syntax": "file:packages/solarized-dark-syntax",
"solarized-light-syntax": "file:packages/solarized-light-syntax",
"spell-check": "https://www.atom.io/api/packages/spell-check/versions/0.74.3/tarball",
"status-bar": "https://www.atom.io/api/packages/status-bar/versions/1.8.17/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",
"tabs": "https://www.atom.io/api/packages/tabs/versions/0.110.0/tarball",
"temp": "^0.8.3",
"text-buffer": "13.15.0",
"text-buffer": "13.15.3",
"timecop": "https://www.atom.io/api/packages/timecop/versions/0.36.2/tarball",
"tree-sitter": "0.13.23",
"tree-sitter-css": "^0.13.7",
"tree-view": "https://www.atom.io/api/packages/tree-view/versions/0.224.4/tarball",
"tree-view": "https://www.atom.io/api/packages/tree-view/versions/0.224.5/tarball",
"typescript-simple": "1.0.0",
"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.7/tarball",
"winreg": "^1.2.1",
"wrap-guide": "https://www.atom.io/api/packages/wrap-guide/versions/0.40.3/tarball",
"wrap-guide": "https://www.atom.io/api/packages/wrap-guide/versions/0.41.0/tarball",
"yargs": "^3.23.0"
},
"packageDependencies": {
@@ -182,8 +180,8 @@
"one-light-ui": "file:./packages/one-light-ui",
"one-dark-syntax": "file:./packages/one-dark-syntax",
"one-light-syntax": "file:./packages/one-light-syntax",
"solarized-dark-syntax": "1.3.0",
"solarized-light-syntax": "1.3.0",
"solarized-dark-syntax": "file:./packages/solarized-dark-syntax",
"solarized-light-syntax": "file:./packages/solarized-light-syntax",
"about": "file:./packages/about",
"archive-view": "0.65.1",
"autocomplete-atom-api": "0.10.7",
@@ -194,55 +192,55 @@
"autoflow": "file:./packages/autoflow",
"autosave": "0.24.6",
"background-tips": "0.28.0",
"bookmarks": "0.45.1",
"bracket-matcher": "0.90.2",
"bookmarks": "0.46.0",
"bracket-matcher": "0.90.4",
"command-palette": "0.43.5",
"dalek": "file:./packages/dalek",
"deprecation-cop": "file:./packages/deprecation-cop",
"dev-live-reload": "file:./packages/dev-live-reload",
"encoding-selector": "0.23.9",
"exception-reporting": "file:./packages/exception-reporting",
"find-and-replace": "0.215.14",
"fuzzy-finder": "1.8.2",
"github": "0.23.0",
"find-and-replace": "0.218.0",
"fuzzy-finder": "1.9.0",
"github": "0.24.0",
"git-diff": "file:./packages/git-diff",
"go-to-line": "file:./packages/go-to-line",
"grammar-selector": "file:./packages/grammar-selector",
"image-view": "0.63.1",
"image-view": "0.64.0",
"incompatible-packages": "file:./packages/incompatible-packages",
"keybinding-resolver": "0.38.4",
"line-ending-selector": "file:./packages/line-ending-selector",
"link": "file:./packages/link",
"markdown-preview": "0.159.25",
"metrics": "1.6.2",
"notifications": "0.70.5",
"notifications": "0.70.6",
"open-on-github": "1.3.1",
"package-generator": "1.3.0",
"settings-view": "0.257.2",
"settings-view": "0.258.0",
"snippets": "1.4.0",
"spell-check": "0.74.2",
"status-bar": "1.8.15",
"spell-check": "0.74.3",
"status-bar": "1.8.17",
"styleguide": "0.49.12",
"symbols-view": "0.118.2",
"tabs": "0.109.2",
"tabs": "0.110.0",
"timecop": "0.36.2",
"tree-view": "0.224.4",
"tree-view": "0.224.5",
"update-package-dependencies": "0.13.1",
"welcome": "0.36.7",
"whitespace": "0.37.7",
"wrap-guide": "0.40.3",
"wrap-guide": "0.41.0",
"language-c": "0.60.14",
"language-clojure": "0.22.7",
"language-coffee-script": "0.49.3",
"language-coffee-script": "0.50.0",
"language-csharp": "1.1.0",
"language-css": "0.43.0",
"language-gfm": "0.90.6",
"language-git": "0.19.1",
"language-go": "0.46.6",
"language-html": "0.51.5",
"language-html": "0.52.0",
"language-hyperlink": "0.17.0",
"language-java": "0.31.1",
"language-javascript": "0.129.18",
"language-javascript": "0.129.19",
"language-json": "0.19.2",
"language-less": "0.34.3",
"language-make": "0.23.0",
@@ -252,7 +250,7 @@
"language-php": "0.44.1",
"language-property-list": "0.9.1",
"language-python": "0.51.8",
"language-ruby": "0.72.14",
"language-ruby": "0.72.15",
"language-ruby-on-rails": "0.25.3",
"language-rust-bundled": "file:./packages/language-rust-bundled",
"language-sass": "0.62.0",
@@ -271,6 +269,7 @@
"preinstall": "node -e 'process.exit(0)'",
"test": "node script/test"
},
"standard-engine": "./script/node_modules/standard",
"standard": {
"env": {
"atomtest": true,

View File

@@ -87,8 +87,8 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate
| **package-generator** | [`atom/package-generator`][package-generator] | [#18279](https://github.com/atom/atom/issues/18279) |
| **settings-view** | [`atom/settings-view`][settings-view] | |
| **snippets** | [`atom/snippets`][snippets] | |
| **solarized-dark-syntax** | [`atom/solarized-dark-syntax`][solarized-dark-syntax] | [#18280](https://github.com/atom/atom/issues/18280) |
| **solarized-light-syntax** | [`atom/solarized-light-syntax`][solarized-light-syntax] | [#18281](https://github.com/atom/atom/issues/18281) |
| **solarized-dark-syntax** | [`./solarized-dark-syntax`](./solarized-dark-syntax) | [#18280](https://github.com/atom/atom/issues/18280) |
| **solarized-light-syntax** | [`./solarized-light-syntax`](./solarized-light-syntax) | [#18281](https://github.com/atom/atom/issues/18281) |
| **spell-check** | [`atom/spell-check`][spell-check] | |
| **status-bar** | [`atom/status-bar`][status-bar] | [#18282](https://github.com/atom/atom/issues/18282) |
| **styleguide** | [`atom/styleguide`][styleguide] | [#18283](https://github.com/atom/atom/issues/18283) |
@@ -158,8 +158,6 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate
[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

View File

@@ -51,14 +51,30 @@ module.exports =
tabLengthInSpaces = ''
for block in paragraphBlocks
blockLines = block.split('\n')
# For LaTeX tags surrounding the text, we simply ignore them, and
# reproduce them verbatim in the wrapped text.
beginningLinesToIgnore = []
endingLinesToIgnore = []
latexTagRegex = /^\s*\\\w+(\[.*\])?\{\w+\}(\[.*\])?\s*$/g # e.g. \begin{verbatim}
latexTagStartRegex = /^\s*\\\w+\s*\{\s*$/g # e.g. \item{
latexTagEndRegex = /^\s*\}\s*$/g # e.g. }
while blockLines[0].match(latexTagRegex) or
blockLines[0].match(latexTagStartRegex)
beginningLinesToIgnore.push(blockLines[0])
blockLines.shift()
while blockLines[blockLines.length - 1].match(latexTagRegex) or
blockLines[blockLines.length - 1].match(latexTagEndRegex)
endingLinesToIgnore.unshift(blockLines[blockLines.length - 1])
blockLines.pop()
# TODO: this could be more language specific. Use the actual comment char.
# Remember that `-` has to be the last character in the character class.
linePrefix = block.match(/^\s*(\/\/|\/\*|;;|#'|\|\|\||--|[#%*>-])?\s*/g)[0]
linePrefix = blockLines[0].match(/^\s*(\/\/|\/\*|;;|#'|\|\|\||--|[#%*>-])?\s*/g)[0]
linePrefixTabExpanded = linePrefix
if tabLengthInSpaces
linePrefixTabExpanded = linePrefix.replace(/\t/g, tabLengthInSpaces)
blockLines = block.split('\n')
if linePrefix
escapedLinePrefix = _.escapeRegExp(linePrefix)
@@ -93,7 +109,8 @@ module.exports =
currentLineLength += segment.length
lines.push(linePrefix + currentLine.join(''))
paragraphs.push(lines.join('\n').replace(/\s+\n/g, '\n'))
wrappedLines = beginningLinesToIgnore.concat(lines.concat(endingLinesToIgnore))
paragraphs.push(wrappedLines.join('\n').replace(/\s+\n/g, '\n'))
leadingVerticalSpace + paragraphs.join('\n\n') + trailingVerticalSpace

View File

@@ -560,3 +560,71 @@ describe "Autoflow package", ->
'''
expect(autoflow.reflow(test, wrapColumn: 80)).toEqual res
it 'properly reflows text around LaTeX tags', ->
text =
'''
\\begin{verbatim}
Lorem ipsum dolor sit amet, nisl odio amet, et tempor netus neque at at blandit, vel vestibulum libero dolor, semper lobortis ligula praesent. Eget condimentum integer, porta sagittis nam, fusce vitae a vitae augue. Nec semper quis sed ut, est porttitor praesent. Nisl velit quam dolore velit quam, elementum neque pellentesque pulvinar et vestibulum.
\\end{verbatim}
'''
res =
'''
\\begin{verbatim}
Lorem ipsum dolor sit amet, nisl odio amet, et tempor netus neque at at
blandit, vel vestibulum libero dolor, semper lobortis ligula praesent. Eget
condimentum integer, porta sagittis nam, fusce vitae a vitae augue. Nec
semper quis sed ut, est porttitor praesent. Nisl velit quam dolore velit
quam, elementum neque pellentesque pulvinar et vestibulum.
\\end{verbatim}
'''
expect(autoflow.reflow(text, wrapColumn: 80)).toEqual res
it 'properly reflows text inside LaTeX tags', ->
text =
'''
\\item{
Lorem ipsum dolor sit amet, nisl odio amet, et tempor netus neque at at blandit, vel vestibulum libero dolor, semper lobortis ligula praesent. Eget condimentum integer, porta sagittis nam, fusce vitae a vitae augue. Nec semper quis sed ut, est porttitor praesent. Nisl velit quam dolore velit quam, elementum neque pellentesque pulvinar et vestibulum.
}
'''
res =
'''
\\item{
Lorem ipsum dolor sit amet, nisl odio amet, et tempor netus neque at at
blandit, vel vestibulum libero dolor, semper lobortis ligula praesent. Eget
condimentum integer, porta sagittis nam, fusce vitae a vitae augue. Nec
semper quis sed ut, est porttitor praesent. Nisl velit quam dolore velit
quam, elementum neque pellentesque pulvinar et vestibulum.
}
'''
expect(autoflow.reflow(text, wrapColumn: 80)).toEqual res
it 'properly reflows text inside nested LaTeX tags', ->
text =
'''
\\begin{enumerate}[label=(\\alph*)]
\\item{
Lorem ipsum dolor sit amet, nisl odio amet, et tempor netus neque at at blandit, vel vestibulum libero dolor, semper lobortis ligula praesent. Eget condimentum integer, porta sagittis nam, fusce vitae a vitae augue. Nec semper quis sed ut, est porttitor praesent. Nisl velit quam dolore velit quam, elementum neque pellentesque pulvinar et vestibulum.
}
\\end{enumerate}
'''
res =
'''
\\begin{enumerate}[label=(\\alph*)]
\\item{
Lorem ipsum dolor sit amet, nisl odio amet, et tempor netus neque at at
blandit, vel vestibulum libero dolor, semper lobortis ligula praesent.
Eget condimentum integer, porta sagittis nam, fusce vitae a vitae augue.
Nec semper quis sed ut, est porttitor praesent. Nisl velit quam dolore
velit quam, elementum neque pellentesque pulvinar et vestibulum.
}
\\end{enumerate}
'''
expect(autoflow.reflow(text, wrapColumn: 80)).toEqual res

View File

@@ -79,6 +79,7 @@ scopes:
'''
use_wildcard > identifier:nth-child(0),
use_wildcard > scoped_identifier > identifier:nth-child(2),
scoped_type_identifier > identifier:nth-child(0),
scoped_type_identifier > scoped_identifier:nth-child(0) > identifier,
scoped_identifier > identifier:nth-child(0),

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,9 @@
# Solarized Dark Syntax theme
Atom theme using the ever popular dark [solarized](http://ethanschoonover.com/solarized) colors.
<img alt="screenshot" src="https://cloud.githubusercontent.com/assets/378023/12602908/9c252b08-c4f0-11e5-8833-6aad91b8fa34.png" srcset="https://cloud.githubusercontent.com/assets/378023/12602909/9c25b366-c4f0-11e5-9f5d-aa6a517f7d7e.png 2x">
This theme is installed by default with Atom and can be activated by going to
the _Themes_ section in the Settings view (`cmd-,`) and selecting it from the
_Syntax Themes_ dropdown menu.

View File

@@ -0,0 +1,22 @@
// Solarized Syntax Theme
@import "styles/syntax-variables.less";
// Editor
@import "styles/editor.less";
// Languages
@import "styles/syntax/_base.less";
@import "styles/syntax/c.less";
@import "styles/syntax/coffee.less";
@import "styles/syntax/css.less";
@import "styles/syntax/go.less";
@import "styles/syntax/java.less";
@import "styles/syntax/javascript.less";
@import "styles/syntax/markdown.less";
@import "styles/syntax/markup.less";
@import "styles/syntax/php.less";
@import "styles/syntax/python.less";
@import "styles/syntax/ruby.less";
@import "styles/syntax/scala.less";
@import "styles/syntax/typescript.less";

View File

@@ -0,0 +1,11 @@
{
"name": "solarized-dark-syntax",
"theme": "syntax",
"version": "1.3.0",
"description": "A dark syntax theme using the solarized colors",
"repository": "https://github.com/atom/atom",
"license": "MIT",
"engines": {
"atom": ">0.50.0"
}
}

View File

@@ -0,0 +1,27 @@
// Solarized color scheme
// http://ethanschoonover.com/solarized#the-values
// Background/Foreground Tones
@base03: #002b36;
@base02: #073642;
// Content Tones
@base01: #586e75;
@base00: #657b83;
@base0: #839496;
@base1: #93a1a1;
// Background/Foreground Tones
@base2: #eee8d5;
@base3: #fdf6e3;
// Accent Colors
@yellow: #b58900;
@orange: #cb4b16;
@red: #dc322f;
@magenta: #d33682;
@violet: #6c71c4;
@blue: #268bd2;
@cyan: #2aa198;
@green: #859900;

View File

@@ -0,0 +1,44 @@
atom-text-editor {
color: @syntax-text-color;
background-color: @syntax-background-color;
.gutter {
color: @syntax-gutter-text-color;
background-color: @syntax-gutter-background-color;
.line-number {
&.cursor-line {
background-color: @syntax-gutter-background-color-selected;
}
}
}
.invisible-character {
color: @syntax-invisible-character-color;
}
.indent-guide {
color: @syntax-indent-guide-color;
}
.cursor {
border-color: @syntax-cursor-color;
}
.cursor-line {
background-color: @syntax-cursor-line;
}
.selection .region {
background-color: @syntax-selection-color;
}
.fold-marker:after,
.gutter .line-number.folded {
color: @magenta;
}
.bracket-matcher .region {
border-color: @magenta;
}
}

View File

@@ -0,0 +1,55 @@
@import "colors.less";
// This defines all syntax variables that syntax themes must implement when they
// include a syntax-variables.less file.
// General colors
@syntax-text-color: @base0;
@syntax-cursor-color: @base3;
@syntax-selection-color: lighten(@base02, 1%);
@syntax-selection-flash-color: @base1;
@syntax-background-color: @base03;
// Guide colors
@syntax-wrap-guide-color: lighten(@base02, 6%);
@syntax-indent-guide-color: lighten(@base02, 6%);
@syntax-invisible-character-color: lighten(@base02, 6%);
// For find and replace markers
@syntax-result-marker-color: @cyan;
@syntax-result-marker-color-selected: @base3;
// Gutter colors
@syntax-gutter-text-color: @base0;
@syntax-gutter-text-color-selected: @base2;
@syntax-gutter-background-color: @base02;
@syntax-gutter-background-color-selected: lighten(@base02, 6%);
// For git diff info. i.e. in the gutter
@syntax-color-added: @green;
@syntax-color-renamed: @blue;
@syntax-color-modified: @yellow;
@syntax-color-removed: @red;
// For language entity colors
@syntax-color-variable: @blue;
@syntax-color-constant: @yellow;
@syntax-color-property: @yellow;
@syntax-color-value: @cyan;
@syntax-color-function: @blue;
@syntax-color-method: @blue;
@syntax-color-class: @blue;
@syntax-color-keyword: @green;
@syntax-color-tag: @blue;
@syntax-color-attribute: @syntax-comment-color;
@syntax-color-import: @red;
@syntax-color-snippet: @syntax-color-keyword;
// Custom variables
// Warning: Don't use in packages
@syntax-comment-color: @base01;
@syntax-subtle-color: @base00;
@syntax-emphasized-color: @base1;
@syntax-cursor-line: fade(lighten(@syntax-background-color, 30%), 8%); // needs to be semi-transparent

View File

@@ -0,0 +1,100 @@
.syntax--comment {
color: @syntax-comment-color;
font-style: italic;
.syntax--markup.syntax--link {
color: @syntax-comment-color;
}
}
.syntax--string {
color: @cyan;
&.syntax--regexp {
color: @red;
}
}
.syntax--constant {
&.syntax--numeric {
color: @magenta;
}
&.syntax--language {
color: @yellow;
}
&.syntax--character,
&.syntax--other,
&.syntax--support {
color: @orange;
}
}
.syntax--variable {
color: @blue;
}
.syntax--keyword {
color: @green;
}
.syntax--storage {
color: @green;
}
.syntax--meta.syntax--class {
color: @blue;
}
.syntax--entity {
&.syntax--name {
&.syntax--class,
&.syntax--function,
&.syntax--section,
&.syntax--type {
color: @blue;
}
}
&.syntax--other.syntax--attribute-name {
color: @syntax-subtle-color;
}
}
.syntax--support {
&.syntax--function {
color: @blue;
&.syntax--builtin {
color: @green;
}
}
&.syntax--type,
&.syntax--class {
color: @green;
}
}
.syntax--tag {
&.syntax--entity.syntax--name {
color: @blue;
}
&.syntax--punctuation.syntax--definition {
&.syntax--html,
&.syntax--begin,
&.syntax--end {
color: @syntax-comment-color;
}
}
}
.syntax--invalid {
&.syntax--deprecated {
color: @yellow;
text-decoration: underline;
}
&.syntax--illegal {
color: @red;
text-decoration: underline;
}
}
.syntax--none {
color: @syntax-text-color;
}

View File

@@ -0,0 +1,44 @@
.syntax--source.syntax--c,
.syntax--source.syntax--cpp {
.syntax--meta.syntax--preprocessor {
color: @red;
}
.syntax--keyword.syntax--control.syntax--directive {
color: @orange;
}
.syntax--punctuation.syntax--string {
color: @cyan;
}
.syntax--constant {
color: @orange;
&.syntax--numeric, &.syntax--language.syntax--c {
color: @cyan;
}
}
.syntax--storage {
color: @yellow;
}
.syntax--entity {
color: @syntax-text-color;
&.syntax--name.syntax--function.syntax--preprocessor {
color: @red;
}
}
.syntax--support.syntax--type {
color: @yellow;
&.syntax--posix-reserved {
color: @syntax-text-color;
}
}
.syntax--variable {
&.syntax--other.syntax--dot-access {
color: @syntax-text-color;
}
&.syntax--parameter.syntax--preprocessor {
color: @red;
}
}
}

View File

@@ -0,0 +1,58 @@
.syntax--source.syntax--coffee {
.syntax--support.syntax--class {
color: @green;
}
.syntax--variable,
.syntax--entity.syntax--name.syntax--function,
.syntax--entity.syntax--name.syntax--class {
color: @blue;
}
.syntax--variable.syntax--parameter.syntax--function {
color: @syntax-text-color;
}
.syntax--variable.syntax--other.syntax--readwrite {
color: @green;
}
.syntax--storage.syntax--type.syntax--function {
color: @green;
}
.syntax--entity.syntax--name {
color: @syntax-text-color;
}
.syntax--meta.syntax--brace {
&.syntax--round,
&.syntax--square {
color: @syntax-text-color;
}
}
.syntax--meta.syntax--delimiter {
color: @syntax-text-color;
}
.syntax--storage.syntax--type.syntax--class {
color: @green;
}
.syntax--punctuation.syntax--terminator {
color: @syntax-text-color;
}
.syntax--punctuation.syntax--section.syntax--embedded {
color: @red;
}
.syntax--embedded.syntax--source {
color: @syntax-text-color;
}
.syntax--constant.syntax--numeric {
color: @magenta;
}
.syntax--constant.syntax--language.syntax--boolean {
color: @yellow;
}
}

View File

@@ -0,0 +1,63 @@
.syntax--source.syntax--css {
.syntax--punctuation {
&.syntax--separator,
&.syntax--terminator {
color: @syntax-text-color;
}
&.syntax--property-list.syntax--begin,
&.syntax--property-list.syntax--end {
color: @red;
}
&.syntax--section.syntax--function {
color: @cyan;
}
}
.syntax--entity.syntax--name {
color: @green;
}
.syntax--attribute-name.syntax--class,
.syntax--id {
color: @blue;
}
.syntax--pseudo-element,
.syntax--pseudo-class {
color: @orange;
}
.syntax--property-value {
color: @cyan;
}
.syntax--constant.syntax--numeric {
color: @cyan;
.syntax--unit {
color: @cyan;
}
}
.syntax--rgb-value {
color: @cyan;
}
.syntax--support.syntax--constant {
color: @cyan;
&.syntax--media {
color: @red;
}
}
.syntax--keyword.syntax--important {
color: @red;
}
}
// Less/Sass should have their own files,
// but for just a single override, here should be fine too
.syntax--source.syntax--less,
.syntax--source.syntax--scss {
.syntax--keyword.syntax--unit {
color: @cyan;
}
}

View File

@@ -0,0 +1,10 @@
.syntax--source.syntax--go {
.syntax--operator {
color: @syntax-text-color;
&.syntax--assignment {
color: @green;
}
}
}

View File

@@ -0,0 +1,47 @@
.syntax--source.syntax--java {
.syntax--keyword.syntax--operator{
color:@green;
}
.syntax--keyword.syntax--import{
color: @orange;
}
.syntax--storage.syntax--modifier.syntax--import{
color: @syntax-comment-color;
}
.syntax--meta.syntax--class{
.syntax--storage.syntax--modifier{
color: @yellow;
}
.syntax--meta.syntax--class.syntax--identifier{
.syntax--entity.syntax--name.syntax--type.syntax--class{
color: @blue;
}
}
}
.syntax--storage.syntax--type.syntax--primitive.syntax--array{
color:@green;
}
.syntax--constant.syntax--numeric{
color:@magenta;
}
.syntax--constant.syntax--other{
color:@orange;
}
.syntax--storage.syntax--type{
color:@green;
}
.syntax--meta.syntax--method-call{
//@ibocon: method parameter's color
color:@red;
//@ibocon: method and variable use different hightlight
.syntax--meta.syntax--method{
color:@violet;
}
.syntax--punctuation.syntax--definition.syntax--seperator.syntax--parameter{
color:@green;
}
}
.syntax--punctuation.syntax--definition.syntax--method-parameters{
color: @syntax-emphasized-color;
}
}

View File

@@ -0,0 +1,128 @@
.syntax--source.syntax--js {
.syntax--comma {
color: @syntax-text-color;
}
.syntax--support.syntax--class {
color: @green;
}
.syntax--entity {
&.syntax--name.syntax--type {
color: @yellow;
}
&.syntax--name {
color: @syntax-text-color;
&.syntax--function {
color: @blue;
}
}
&.syntax--name.syntax--tag {
color: @blue;
}
&.syntax--other.syntax--attribute-name {
color: @yellow;
}
}
.syntax--meta.syntax--brace {
color: @syntax-text-color;
}
.syntax--keyword {
color: @syntax-text-color;
}
.syntax--keyword.syntax--operator.syntax--new {
color: @green;
}
.syntax--keyword.syntax--control {
color: @orange;
}
.syntax--keyword.syntax--control.syntax--regexp {
color: @cyan;
}
.syntax--variable {
color: @syntax-text-color;
}
.syntax--variable.syntax--dom {
color: @green;
}
.syntax--delimiter + .syntax--dom {
color: @syntax-text-color;
}
.syntax--name {
color: @syntax-text-color;
}
.syntax--variable.syntax--language {
color: @blue;
}
.syntax--variable.syntax--parameter {
color: @syntax-text-color;
}
.syntax--regexp {
color: @cyan;
}
.syntax--support.syntax--function {
color: @syntax-text-color;
}
.syntax--support.syntax--constant {
color: @syntax-text-color;
}
.syntax--storage.syntax--modifier {
color: @yellow;
}
.syntax--punctuation.syntax--terminator.syntax--statement {
color: @syntax-text-color;
}
.syntax--meta.syntax--delimiter.syntax--method.syntax--period {
color: @syntax-text-color;
}
.syntax--meta.syntax--brace.syntax--square {
color: @blue;
}
.syntax--meta.syntax--brace.syntax--curly {
color: @blue;
}
.syntax--string.syntax--quoted.syntax--template {
.syntax--embedded.syntax--source {
color: @syntax-text-color;
& > .syntax--embedded.syntax--punctuation {
color: @red;
}
}
}
&.syntax--embedded .syntax--entity.syntax--name.syntax--tag {
color: @blue;
}
.syntax--import {
.syntax--control {
color: @orange;
}
}
}
// JavaScript (Rails) language-ruby-on-rails
.syntax--source.syntax--js.syntax--rails {
.syntax--instance {
color: @blue;
}
.syntax--class {
color: @yellow;
}
}

View File

@@ -0,0 +1,26 @@
.syntax--md,
.syntax--gfm {
.syntax--link .syntax--entity {
color: @violet;
}
.syntax--list {
&.syntax--ordered {
color: @green;
}
&.syntax--unordered {
color: @yellow;
}
}
.syntax--raw {
font-style: italic;
}
&.syntax--support {
color:@syntax-comment-color;
&.syntax--quote {
color: @violet;
}
}
}

View File

@@ -0,0 +1,30 @@
.syntax--markup {
&.syntax--bold {
font-weight: bold;
}
&.syntax--italic {
font-style: italic;
}
&.syntax--heading {
color: @blue;
}
&.syntax--link {
color: @cyan;
}
&.syntax--deleted {
color: @red;
}
&.syntax--changed {
color: @yellow;
}
&.syntax--inserted {
color: @cyan;
}
}

View File

@@ -0,0 +1,67 @@
.syntax--source.syntax--php {
.syntax--storage {
&.syntax--type {
&.syntax--class {
color: @yellow;
}
&.syntax--function {
color: @orange;
}
}
&.syntax--modifier {
color: @yellow;
}
}
.syntax--entity {
&.syntax--name {
&.syntax--type.syntax--class {
color: @syntax-text-color;
}
&.syntax--function {
color: @syntax-text-color;
}
}
&.syntax--other {
color: @syntax-text-color;
}
}
.syntax--variable {
color: @blue;
}
.syntax--punctuation.syntax--definition {
color: @syntax-text-color;
&.syntax--comment {
color: @syntax-comment-color;
}
&.syntax--array {
color: @red;
}
&.syntax--string {
color: @syntax-text-color;
}
&.syntax--variable {
color: @green;
}
}
.syntax--support.syntax--function {
&.syntax--construct {
color: @yellow;
}
&.syntax--array {
color: @green;
}
}
.syntax--keyword {
&.syntax--operator {
&.syntax--class {
color: @yellow;
}
&.syntax--assignment {
color: @green;
}
}
&.syntax--other {
color: @red;
}
}
}

View File

@@ -0,0 +1,100 @@
.syntax--source.syntax--python {
.syntax--entity {
color: @syntax-text-color;
&.syntax--name {
color: @blue;
}
&.syntax--other {
color: @blue;
}
}
.syntax--function {
color: @blue;
&.syntax--magic {
color: @blue;
}
}
.syntax--punctuation.syntax--string {
color: @cyan;
}
.syntax--keyword {
&.syntax--operator {
color: @syntax-text-color;
&.syntax--quantifier {
color: @cyan;
}
&.syntax--logical {
color: @green;
}
}
&.syntax--control.syntax--import {
color: @orange;
}
&.syntax--other {
color: @green;
}
}
.syntax--constant {
&.syntax--language {
color: @blue;
}
&.syntax--character {
color: @cyan;
}
&.syntax--other {
color: @red;
}
}
.syntax--entity.syntax--name.syntax--type.syntax--class {
color: @blue;
}
.syntax--variable {
color: @syntax-text-color;
}
.syntax--support {
&.syntax--function.syntax--builtin {
color: @blue;
}
&.syntax--type {
&.syntax--exception.syntax--python {
color: @yellow;
}
&.syntax--python {
color: @blue;
}
}
}
.syntax--storage.syntax--type.syntax--string {
color: @cyan;
}
.syntax--storage.syntax--type.syntax--class {
color: @green;
&.syntax--todo {
color: @magenta;
}
}
.syntax--storage.syntax--type.syntax--function {
color: @green;
}
.syntax--punctuation.syntax--definition.syntax--parameters {
color: @syntax-text-color;
}
.syntax--punctuation.syntax--section.syntax--function.syntax--begin {
color: @syntax-text-color;
}
.syntax--punctuation.syntax--separator.syntax--parameters {
color: @syntax-text-color;
}
}

View File

@@ -0,0 +1,129 @@
.syntax--source.syntax--ruby {
.syntax--meta.syntax--embedded {
.syntax--punctuation.syntax--section {
color: @red;
}
}
.syntax--punctuation.syntax--definition {
color: @syntax-text-color;
&.syntax--string {
color: @red;
}
}
.syntax--punctuation.syntax--definition.syntax--comment {
color: @syntax-comment-color;
}
.syntax--entity.syntax--inherited-class {
color: @yellow;
}
.syntax--variable {
&.syntax--parameter {
color: @syntax-text-color;
}
}
.syntax--variable.syntax--constant {
color: @yellow;
}
.syntax--constant.syntax--boolean {
color: @cyan;
}
.syntax--instance {
.syntax--punctuation.syntax--definition {
color: @blue;
}
}
.syntax--class {
color: @yellow;
&.syntax--control {
color: @syntax-text-color;
}
}
.syntax--module {
color: @yellow;
}
.syntax--require {
.syntax--keyword.syntax--other.syntax--special-method {
color: @orange;
}
}
.syntax--keyword.syntax--other.syntax--special-method {
color: @orange;
}
.syntax--keyword.syntax--other {
color: @green;
}
.syntax--keyword.syntax--control {
color: @green;
}
.syntax--keyword.syntax--operator {
color: @syntax-text-color;
}
.syntax--special-method {
color: @blue;
}
.syntax--symbol {
color: @cyan;
.syntax--punctuation.syntax--definition {
color: @cyan;
}
}
.syntax--hashkey {
color: @red;
.syntax--punctuation.syntax--definition {
color: @red;
}
}
.syntax--string.syntax--regexp {
color: @red;
}
.syntax--todo {
color: @magenta;
}
.syntax--variable.syntax--ruby.syntax--global {
color: @blue;
.syntax--punctuation {
color: @blue;
}
}
.syntax--variable.syntax--block {
color: @blue;
}
.syntax--variable.syntax--self {
color: @cyan;
}
.syntax--punctuation.syntax--separator {
color: @syntax-text-color;
}
.syntax--numeric {
color: @cyan;
}
.syntax--punctuation.syntax--section.syntax--regexp {
color: @red;
}
.syntax--string.syntax--interpolated {
color: @cyan;
}
.syntax--string.syntax--interpolated {
.syntax--embedded.syntax--line.syntax--ruby {
.syntax--punctuation {
.syntax--source.syntax--ruby {
color: @red;
}
}
.syntax--source.syntax--ruby {
.syntax--punctuation.syntax--array,
.syntax--punctuation.syntax--function {
color: @syntax-text-color;
}
color: @syntax-text-color;
}
}
}
.syntax--support.syntax--function {
color: @syntax-text-color;
}
.syntax--support.syntax--function.syntax--kernel {
color: @green;
}
}

View File

@@ -0,0 +1,79 @@
.syntax--source.syntax--scala {
.syntax--variable {
color: @syntax-emphasized-color;
}
.syntax--declaration {
color: @syntax-emphasized-color;
font-weight: bold;
}
.syntax--comparison {
color: @syntax-emphasized-color;
}
.syntax--class, .syntax--type {
color: @yellow;
}
.syntax--val {
font-weight: normal;
}
.syntax--variable {
font-weight: bold;
}
.syntax--variable.syntax--parameter {
color: @violet;
font-weight: normal;
}
.syntax--control.syntax--flow {
color: @syntax-emphasized-color;
font-weight: bold;
}
.syntax--constant.syntax--language {
color: @syntax-emphasized-color;
font-weight: bold;
}
.syntax--function.syntax--declaration {
color: @violet;
}
.syntax--modifier.syntax--other {
font-weight: bold;
}
.syntax--package {
color: @syntax-emphasized-color;
}
.syntax--variable.syntax--import {
font-weight: normal;
}
.syntax--type {
.syntax--bounds, .syntax--class {
color: @violet;
}
}
.syntax--documentation {
:not(.syntax--embedded) {
// out of scope ?
// https://github.syntax--com/atom/link
&.syntax--link.syntax--entity {
color: @blue;
text-decoration: underline;
}
.syntax--class, .syntax--parameter {
color: @syntax-emphasized-color;
}
.syntax--description {
color: @syntax-comment-color;
}
}
}
.syntax--embedded {
color: darken(@syntax-emphasized-color, 15%);
// so we dont confused it with normal expressions
font-style: italic;
.syntax--margin, .syntax--delimiters {
font-style: normal;
}
}
}

View File

@@ -0,0 +1,22 @@
.syntax--source.syntax--ts,
.syntax--source.syntax--tsx {
.syntax--import {
.syntax--control {
color: @orange;
}
}
.syntax--entity {
&.syntax--name.syntax--type {
color: @yellow;
}
&.syntax--inherited-class {
color: @yellow;
}
}
.syntax--support.syntax--type {
color: @yellow;
}
}

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,9 @@
# Solarized Light Syntax theme
Atom theme using the ever popular light [solarized](http://ethanschoonover.com/solarized) colors.
<img alt="screenshot" src="https://cloud.githubusercontent.com/assets/378023/12602186/87edab3e-c4ea-11e5-8f4a-4b7defda283b.png" srcset="https://cloud.githubusercontent.com/assets/378023/12602177/78d568da-c4ea-11e5-836d-e922ca5c850a.png 2x">
This theme is installed by default with Atom and can be activated by going to
the _Themes_ section in the Settings view (`cmd-,`) and selecting it from the
_Syntax Themes_ dropdown menu.

View File

@@ -0,0 +1,22 @@
// Solarized Syntax Theme
@import "styles/syntax-variables.less";
// Editor
@import "styles/editor.less";
// Languages
@import "styles/syntax/_base.less";
@import "styles/syntax/c.less";
@import "styles/syntax/coffee.less";
@import "styles/syntax/css.less";
@import "styles/syntax/go.less";
@import "styles/syntax/java.less";
@import "styles/syntax/javascript.less";
@import "styles/syntax/markdown.less";
@import "styles/syntax/markup.less";
@import "styles/syntax/php.less";
@import "styles/syntax/python.less";
@import "styles/syntax/ruby.less";
@import "styles/syntax/scala.less";
@import "styles/syntax/typescript.less";

View File

@@ -0,0 +1,11 @@
{
"name": "solarized-light-syntax",
"theme": "syntax",
"version": "1.3.0",
"description": "A light syntax theme using the solarized colors",
"repository": "https://github.com/atom/atom",
"license": "MIT",
"engines": {
"atom": ">0.50.0"
}
}

View File

@@ -0,0 +1,27 @@
// Solarized color scheme
// http://ethanschoonover.com/solarized#the-values
// Background/Foreground Tones
@base03: #002b36;
@base02: #073642;
// Content Tones
@base01: #586e75;
@base00: #657b83;
@base0: #839496;
@base1: #93a1a1;
// Background/Foreground Tones
@base2: #eee8d5;
@base3: #fdf6e3;
// Accent Colors
@yellow: #b58900;
@orange: #cb4b16;
@red: #dc322f;
@magenta: #d33682;
@violet: #6c71c4;
@blue: #268bd2;
@cyan: #2aa198;
@green: #859900;

View File

@@ -0,0 +1,44 @@
atom-text-editor {
color: @syntax-text-color;
background-color: @syntax-background-color;
.gutter {
color: @syntax-gutter-text-color;
background-color: @syntax-gutter-background-color;
.line-number {
&.cursor-line {
background-color: @syntax-gutter-background-color-selected;
}
}
}
.invisible-character {
color: @syntax-invisible-character-color;
}
.indent-guide {
color: @syntax-indent-guide-color;
}
.cursor {
border-color: @syntax-cursor-color;
}
.cursor-line {
background-color: @syntax-cursor-line;
}
.selection .region {
background-color: @syntax-selection-color;
}
.fold-marker:after,
.gutter .line-number.folded {
color: @magenta;
}
.bracket-matcher .region {
border-color: @magenta;
}
}

View File

@@ -0,0 +1,55 @@
@import "colors.less";
// This defines all syntax variables that syntax themes must implement when they
// include a syntax-variables.less file.
// General colors
@syntax-text-color: @base00;
@syntax-cursor-color: @base03;
@syntax-selection-color: @base2;
@syntax-selection-flash-color: @base0;
@syntax-background-color: @base3;
// Guide colors
@syntax-wrap-guide-color: darken(@base2, 12%);
@syntax-indent-guide-color: darken(@base2, 12%);
@syntax-invisible-character-color: darken(@base2, 12%);
// For find and replace markers
@syntax-result-marker-color: @base1;
@syntax-result-marker-color-selected: @base03;
// Gutter colors
@syntax-gutter-text-color: @base00;
@syntax-gutter-text-color-selected: @base03;
@syntax-gutter-background-color: @base2;
@syntax-gutter-background-color-selected: darken(@syntax-gutter-background-color, 10%);
// For git diff info. i.e. in the gutter
@syntax-color-added: @green;
@syntax-color-renamed: @blue;
@syntax-color-modified: @yellow;
@syntax-color-removed: @red;
// For language entity colors
@syntax-color-variable: @blue;
@syntax-color-constant: @yellow;
@syntax-color-property: @yellow;
@syntax-color-value: @cyan;
@syntax-color-function: @blue;
@syntax-color-method: @blue;
@syntax-color-class: @blue;
@syntax-color-keyword: @green;
@syntax-color-tag: @blue;
@syntax-color-attribute: @syntax-comment-color;
@syntax-color-import: @red;
@syntax-color-snippet: @syntax-color-keyword;
// Custom variables
// Warning: Don't use in packages
@syntax-comment-color: @base1;
@syntax-subtle-color: @base00;
@syntax-emphasized-color: @base01;
@syntax-cursor-line: fade(darken(@syntax-background-color, 30%), 15%); // needs to be semi-transparent

View File

@@ -0,0 +1,100 @@
.syntax--comment {
color: @syntax-comment-color;
font-style: italic;
.syntax--markup.syntax--link {
color: @syntax-comment-color;
}
}
.syntax--string {
color: @cyan;
&.syntax--regexp {
color: @red;
}
}
.syntax--constant {
&.syntax--numeric {
color: @magenta;
}
&.syntax--language {
color: @yellow;
}
&.syntax--character,
&.syntax--other,
&.syntax--support {
color: @orange;
}
}
.syntax--variable {
color: @blue;
}
.syntax--keyword {
color: @green;
}
.syntax--storage {
color: @green;
}
.syntax--meta.syntax--class {
color: @blue;
}
.syntax--entity {
&.syntax--name {
&.syntax--class,
&.syntax--function,
&.syntax--section,
&.syntax--type {
color: @blue;
}
}
&.syntax--other.syntax--attribute-name {
color: @syntax-subtle-color;
}
}
.syntax--support {
&.syntax--function {
color: @blue;
&.syntax--builtin {
color: @green;
}
}
&.syntax--type,
&.syntax--class {
color: @green;
}
}
.syntax--tag {
&.syntax--entity.syntax--name {
color: @blue;
}
&.syntax--punctuation.syntax--definition {
&.syntax--html,
&.syntax--begin,
&.syntax--end {
color: @syntax-comment-color;
}
}
}
.syntax--invalid {
&.syntax--deprecated {
color: @yellow;
text-decoration: underline;
}
&.syntax--illegal {
color: @red;
text-decoration: underline;
}
}
.syntax--none {
color: @syntax-text-color;
}

View File

@@ -0,0 +1,44 @@
.syntax--source.syntax--c,
.syntax--source.syntax--cpp {
.syntax--meta.syntax--preprocessor {
color: @red;
}
.syntax--keyword.syntax--control.syntax--directive {
color: @orange;
}
.syntax--punctuation.syntax--string {
color: @cyan;
}
.syntax--constant {
color: @orange;
&.syntax--numeric, &.syntax--language.syntax--c {
color: @cyan;
}
}
.syntax--storage {
color: @yellow;
}
.syntax--entity {
color: @syntax-text-color;
&.syntax--name.syntax--function.syntax--preprocessor {
color: @red;
}
}
.syntax--support.syntax--type {
color: @yellow;
&.syntax--posix-reserved {
color: @syntax-text-color;
}
}
.syntax--variable {
&.syntax--other.syntax--dot-access {
color: @syntax-text-color;
}
&.syntax--parameter.syntax--preprocessor {
color: @red;
}
}
}

View File

@@ -0,0 +1,58 @@
.syntax--source.syntax--coffee {
.syntax--support.syntax--class {
color: @green;
}
.syntax--variable,
.syntax--entity.syntax--name.syntax--function,
.syntax--entity.syntax--name.syntax--class {
color: @blue;
}
.syntax--variable.syntax--parameter.syntax--function {
color: @syntax-text-color;
}
.syntax--variable.syntax--other.syntax--readwrite {
color: @green;
}
.syntax--storage.syntax--type.syntax--function {
color: @green;
}
.syntax--entity.syntax--name {
color: @syntax-text-color;
}
.syntax--meta.syntax--brace {
&.syntax--round,
&.syntax--square {
color: @syntax-text-color;
}
}
.syntax--meta.syntax--delimiter {
color: @syntax-text-color;
}
.syntax--storage.syntax--type.syntax--class {
color: @green;
}
.syntax--punctuation.syntax--terminator {
color: @syntax-text-color;
}
.syntax--punctuation.syntax--section.syntax--embedded {
color: @red;
}
.syntax--embedded.syntax--source {
color: @syntax-text-color;
}
.syntax--constant.syntax--numeric {
color: @magenta;
}
.syntax--constant.syntax--language.syntax--boolean {
color: @yellow;
}
}

View File

@@ -0,0 +1,63 @@
.syntax--source.syntax--css {
.syntax--punctuation {
&.syntax--separator,
&.syntax--terminator {
color: @syntax-text-color;
}
&.syntax--property-list.syntax--begin,
&.syntax--property-list.syntax--end {
color: @red;
}
&.syntax--section.syntax--function {
color: @cyan;
}
}
.syntax--entity.syntax--name {
color: @green;
}
.syntax--attribute-name.syntax--class,
.syntax--id {
color: @blue;
}
.syntax--pseudo-element,
.syntax--pseudo-class {
color: @orange;
}
.syntax--property-value {
color: @cyan;
}
.syntax--constant.syntax--numeric {
color: @cyan;
.syntax--unit {
color: @cyan;
}
}
.syntax--rgb-value {
color: @cyan;
}
.syntax--support.syntax--constant {
color: @cyan;
&.syntax--media {
color: @red;
}
}
.syntax--keyword.syntax--important {
color: @red;
}
}
// Less/Sass should have their own files,
// but for just a single override, here should be fine too
.syntax--source.syntax--less,
.syntax--source.syntax--scss {
.syntax--keyword.syntax--unit {
color: @cyan;
}
}

View File

@@ -0,0 +1,10 @@
.syntax--source.syntax--go {
.syntax--operator {
color: @syntax-text-color;
&.syntax--assignment {
color: @green;
}
}
}

View File

@@ -0,0 +1,47 @@
.syntax--source.syntax--java {
.syntax--keyword.syntax--operator{
color:@green;
}
.syntax--keyword.syntax--import{
color: @orange;
}
.syntax--storage.syntax--modifier.syntax--import{
color: @syntax-comment-color;
}
.syntax--meta.syntax--class{
.syntax--storage.syntax--modifier{
color: @yellow;
}
.syntax--meta.syntax--class.syntax--identifier{
.syntax--entity.syntax--name.syntax--type.syntax--class{
color: @blue;
}
}
}
.syntax--storage.syntax--type.syntax--primitive.syntax--array{
color:@green;
}
.syntax--constant.syntax--numeric{
color:@magenta;
}
.syntax--constant.syntax--other{
color:@orange;
}
.syntax--storage.syntax--type{
color:@green;
}
.syntax--meta.syntax--method-call{
//@ibocon: method parameter's color
color:@red;
//@ibocon: method and variable use different hightlight
.syntax--meta.syntax--method{
color:@violet;
}
.syntax--punctuation.syntax--definition.syntax--seperator.syntax--parameter{
color:@green;
}
}
.syntax--punctuation.syntax--definition.syntax--method-parameters{
color: @syntax-emphasized-color;
}
}

View File

@@ -0,0 +1,128 @@
.syntax--source.syntax--js {
.syntax--comma {
color: @syntax-text-color;
}
.syntax--support.syntax--class {
color: @green;
}
.syntax--entity {
&.syntax--name.syntax--type {
color: @yellow;
}
&.syntax--name {
color: @syntax-text-color;
&.syntax--function {
color: @blue;
}
}
&.syntax--name.syntax--tag {
color: @blue;
}
&.syntax--other.syntax--attribute-name {
color: @yellow;
}
}
.syntax--meta.syntax--brace {
color: @syntax-text-color;
}
.syntax--keyword {
color: @syntax-text-color;
}
.syntax--keyword.syntax--operator.syntax--new {
color: @green;
}
.syntax--keyword.syntax--control {
color: @orange;
}
.syntax--keyword.syntax--control.syntax--regexp {
color: @cyan;
}
.syntax--variable {
color: @syntax-text-color;
}
.syntax--variable.syntax--dom {
color: @green;
}
.syntax--delimiter + .syntax--dom {
color: @syntax-text-color;
}
.syntax--name {
color: @syntax-text-color;
}
.syntax--variable.syntax--language {
color: @blue;
}
.syntax--variable.syntax--parameter {
color: @syntax-text-color;
}
.syntax--regexp {
color: @cyan;
}
.syntax--support.syntax--function {
color: @syntax-text-color;
}
.syntax--support.syntax--constant {
color: @syntax-text-color;
}
.syntax--storage.syntax--modifier {
color: @yellow;
}
.syntax--punctuation.syntax--terminator.syntax--statement {
color: @syntax-text-color;
}
.syntax--meta.syntax--delimiter.syntax--method.syntax--period {
color: @syntax-text-color;
}
.syntax--meta.syntax--brace.syntax--square {
color: @blue;
}
.syntax--meta.syntax--brace.syntax--curly {
color: @blue;
}
.syntax--string.syntax--quoted.syntax--template {
.syntax--embedded.syntax--source {
color: @syntax-text-color;
& > .syntax--embedded.syntax--punctuation {
color: @red;
}
}
}
&.syntax--embedded .syntax--entity.syntax--name.syntax--tag {
color: @blue;
}
.syntax--import {
.syntax--control {
color: @orange;
}
}
}
// JavaScript (Rails) language-ruby-on-rails
.syntax--source.syntax--js.syntax--rails {
.syntax--instance {
color: @blue;
}
.syntax--class {
color: @yellow;
}
}

View File

@@ -0,0 +1,26 @@
.syntax--md,
.syntax--gfm {
.syntax--link .syntax--entity {
color: @violet;
}
.syntax--list {
&.syntax--ordered {
color: @green;
}
&.syntax--unordered {
color: @yellow;
}
}
.syntax--raw {
font-style: italic;
}
&.syntax--support {
color:@syntax-comment-color;
&.syntax--quote {
color: @violet;
}
}
}

View File

@@ -0,0 +1,30 @@
.syntax--markup {
&.syntax--bold {
font-weight: bold;
}
&.syntax--italic {
font-style: italic;
}
&.syntax--heading {
color: @blue;
}
&.syntax--link {
color: @cyan;
}
&.syntax--deleted {
color: @red;
}
&.syntax--changed {
color: @yellow;
}
&.syntax--inserted {
color: @cyan;
}
}

View File

@@ -0,0 +1,67 @@
.syntax--source.syntax--php {
.syntax--storage {
&.syntax--type {
&.syntax--class {
color: @yellow;
}
&.syntax--function {
color: @orange;
}
}
&.syntax--modifier {
color: @yellow;
}
}
.syntax--entity {
&.syntax--name {
&.syntax--type.syntax--class {
color: @syntax-text-color;
}
&.syntax--function {
color: @syntax-text-color;
}
}
&.syntax--other {
color: @syntax-text-color;
}
}
.syntax--variable {
color: @blue;
}
.syntax--punctuation.syntax--definition {
color: @syntax-text-color;
&.syntax--comment {
color: @syntax-comment-color;
}
&.syntax--array {
color: @red;
}
&.syntax--string {
color: @syntax-text-color;
}
&.syntax--variable {
color: @green;
}
}
.syntax--support.syntax--function {
&.syntax--construct {
color: @yellow;
}
&.syntax--array {
color: @green;
}
}
.syntax--keyword {
&.syntax--operator {
&.syntax--class {
color: @yellow;
}
&.syntax--assignment {
color: @green;
}
}
&.syntax--other {
color: @red;
}
}
}

View File

@@ -0,0 +1,100 @@
.syntax--source.syntax--python {
.syntax--entity {
color: @syntax-text-color;
&.syntax--name {
color: @blue;
}
&.syntax--other {
color: @blue;
}
}
.syntax--function {
color: @blue;
&.syntax--magic {
color: @blue;
}
}
.syntax--punctuation.syntax--string {
color: @cyan;
}
.syntax--keyword {
&.syntax--operator {
color: @syntax-text-color;
&.syntax--quantifier {
color: @cyan;
}
&.syntax--logical {
color: @green;
}
}
&.syntax--control.syntax--import {
color: @orange;
}
&.syntax--other {
color: @green;
}
}
.syntax--constant {
&.syntax--language {
color: @blue;
}
&.syntax--character {
color: @cyan;
}
&.syntax--other {
color: @red;
}
}
.syntax--entity.syntax--name.syntax--type.syntax--class {
color: @blue;
}
.syntax--variable {
color: @syntax-text-color;
}
.syntax--support {
&.syntax--function.syntax--builtin {
color: @blue;
}
&.syntax--type {
&.syntax--exception.syntax--python {
color: @yellow;
}
&.syntax--python {
color: @blue;
}
}
}
.syntax--storage.syntax--type.syntax--string {
color: @cyan;
}
.syntax--storage.syntax--type.syntax--class {
color: @green;
&.syntax--todo {
color: @magenta;
}
}
.syntax--storage.syntax--type.syntax--function {
color: @green;
}
.syntax--punctuation.syntax--definition.syntax--parameters {
color: @syntax-text-color;
}
.syntax--punctuation.syntax--section.syntax--function.syntax--begin {
color: @syntax-text-color;
}
.syntax--punctuation.syntax--separator.syntax--parameters {
color: @syntax-text-color;
}
}

View File

@@ -0,0 +1,129 @@
.syntax--source.syntax--ruby {
.syntax--meta.syntax--embedded {
.syntax--punctuation.syntax--section {
color: @red;
}
}
.syntax--punctuation.syntax--definition {
color: @syntax-text-color;
&.syntax--string {
color: @red;
}
}
.syntax--punctuation.syntax--definition.syntax--comment {
color: @syntax-comment-color;
}
.syntax--entity.syntax--inherited-class {
color: @yellow;
}
.syntax--variable {
&.syntax--parameter {
color: @syntax-text-color;
}
}
.syntax--variable.syntax--constant {
color: @yellow;
}
.syntax--constant.syntax--boolean {
color: @cyan;
}
.syntax--instance {
.syntax--punctuation.syntax--definition {
color: @blue;
}
}
.syntax--class {
color: @yellow;
&.syntax--control {
color: @syntax-text-color;
}
}
.syntax--module {
color: @yellow;
}
.syntax--require {
.syntax--keyword.syntax--other.syntax--special-method {
color: @orange;
}
}
.syntax--keyword.syntax--other.syntax--special-method {
color: @orange;
}
.syntax--keyword.syntax--other {
color: @green;
}
.syntax--keyword.syntax--control {
color: @green;
}
.syntax--keyword.syntax--operator {
color: @syntax-text-color;
}
.syntax--special-method {
color: @blue;
}
.syntax--symbol {
color: @cyan;
.syntax--punctuation.syntax--definition {
color: @cyan;
}
}
.syntax--hashkey {
color: @red;
.syntax--punctuation.syntax--definition {
color: @red;
}
}
.syntax--string.syntax--regexp {
color: @red;
}
.syntax--todo {
color: @magenta;
}
.syntax--variable.syntax--ruby.syntax--global {
color: @blue;
.syntax--punctuation {
color: @blue;
}
}
.syntax--variable.syntax--block {
color: @blue;
}
.syntax--variable.syntax--self {
color: @cyan;
}
.syntax--punctuation.syntax--separator {
color: @syntax-text-color;
}
.syntax--numeric {
color: @cyan;
}
.syntax--punctuation.syntax--section.syntax--regexp {
color: @red;
}
.syntax--string.syntax--interpolated {
color: @cyan;
}
.syntax--string.syntax--interpolated {
.syntax--embedded.syntax--line.syntax--ruby {
.syntax--punctuation {
.syntax--source.syntax--ruby {
color: @red;
}
}
.syntax--source.syntax--ruby {
.syntax--punctuation.syntax--array,
.syntax--punctuation.syntax--function {
color: @syntax-text-color;
}
color: @syntax-text-color;
}
}
}
.syntax--support.syntax--function {
color: @syntax-text-color;
}
.syntax--support.syntax--function.syntax--kernel {
color: @green;
}
}

View File

@@ -0,0 +1,79 @@
.syntax--source.syntax--scala {
.syntax--variable {
color: @syntax-emphasized-color;
}
.syntax--declaration {
color: @syntax-emphasized-color;
font-weight: bold;
}
.syntax--comparison {
color: @syntax-emphasized-color;
}
.syntax--class, .syntax--type {
color: @yellow;
}
.syntax--val {
font-weight: normal;
}
.syntax--variable {
font-weight: bold;
}
.syntax--variable.syntax--parameter {
color: @violet;
font-weight: normal;
}
.syntax--control.syntax--flow {
color: @syntax-emphasized-color;
font-weight: bold;
}
.syntax--constant.syntax--language {
color: @syntax-emphasized-color;
font-weight: bold;
}
.syntax--function.syntax--declaration {
color: @violet;
}
.syntax--modifier.syntax--other {
font-weight: bold;
}
.syntax--package {
color: @syntax-emphasized-color;
}
.syntax--variable.syntax--import {
font-weight: normal;
}
.syntax--type {
.syntax--bounds, .syntax--class {
color: @violet;
}
}
.syntax--documentation {
:not(.syntax--embedded) {
// out of scope ?
// https://github.syntax--com/atom/link
&.syntax--link.syntax--entity {
color: @blue;
text-decoration: underline;
}
.syntax--class, .syntax--parameter {
color: @syntax-emphasized-color;
}
.syntax--description {
color: @syntax-comment-color;
}
}
}
.syntax--embedded {
color: darken(@syntax-emphasized-color, 15%);
// so we dont confused it with normal expressions
font-style: italic;
.syntax--margin, .syntax--delimiters {
font-style: normal;
}
}
}

View File

@@ -0,0 +1,22 @@
.syntax--source.syntax--ts,
.syntax--source.syntax--tsx {
.syntax--import {
.syntax--control {
color: @orange;
}
}
.syntax--entity {
&.syntax--name.syntax--type {
color: @yellow;
}
&.syntax--inherited-class {
color: @yellow;
}
}
.syntax--support.syntax--type {
color: @yellow;
}
}

View File

@@ -34,6 +34,8 @@
<string>AtomApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>NSRequiresAquaSystemAppearance</key>
<string>NO</string>
<key>SUScheduledCheckInterval</key>
<string>3600</string>
<key>CFBundleURLTypes</key>

View File

@@ -3,10 +3,12 @@ const path = require('path')
const CONFIG = require('../config')
module.exports = function () {
// We can't require fs-extra if `script/bootstrap` has never been run, because
// it's a third party module. This is okay because cleaning dependencies only
// makes sense if dependencies have been installed at least once.
// We can't require fs-extra or glob if `script/bootstrap` has never been run,
// because they are third party modules. This is okay because cleaning
// dependencies only makes sense if dependencies have been installed at least
// once.
const fs = require('fs-extra')
const glob = require('glob')
const apmDependenciesPath = path.join(CONFIG.apmRootPath, 'node_modules')
console.log(`Cleaning ${apmDependenciesPath}`)
@@ -19,4 +21,9 @@ module.exports = function () {
const scriptDependenciesPath = path.join(CONFIG.scriptRootPath, 'node_modules')
console.log(`Cleaning ${scriptDependenciesPath}`)
fs.removeSync(scriptDependenciesPath)
const bundledPackageDependenciesPaths = path.join(CONFIG.repositoryRootPath, 'packages', '**', 'node_modules')
for (const bundledPackageDependencyPath of glob.sync(bundledPackageDependenciesPaths)) {
fs.removeSync(bundledPackageDependencyPath)
}
}

View File

@@ -15,7 +15,6 @@ module.exports = function () {
path.join(CONFIG.repositoryRootPath, 'benchmarks', 'benchmark-runner.js'),
path.join(CONFIG.repositoryRootPath, 'dot-atom'),
path.join(CONFIG.repositoryRootPath, 'exports'),
path.join(CONFIG.repositoryRootPath, 'node_modules'),
path.join(CONFIG.repositoryRootPath, 'package.json'),
path.join(CONFIG.repositoryRootPath, 'static'),
path.join(CONFIG.repositoryRootPath, 'src'),
@@ -23,9 +22,22 @@ module.exports = function () {
]
srcPaths = srcPaths.concat(glob.sync(path.join(CONFIG.repositoryRootPath, 'spec', '*.*'), {ignore: path.join('**', '*-spec.*')}))
for (let srcPath of srcPaths) {
fs.copySync(srcPath, computeDestinationPath(srcPath), {filter: includePathInPackagedApp, dereference: true})
fs.copySync(srcPath, computeDestinationPath(srcPath), {filter: includePathInPackagedApp})
}
// Run a copy pass to dereference symlinked directories under node_modules.
// We do this to ensure that symlinked repo-local bundled packages get
// copied to the output folder correctly. We dereference only the top-level
// symlinks and not nested symlinks to avoid issues where symlinked binaries
// are duplicated in Atom's installation packages (see atom/atom#18490).
const nodeModulesPath = path.join(CONFIG.repositoryRootPath, 'node_modules')
glob.sync(path.join(nodeModulesPath, '*'))
.map(p => fs.lstatSync(p).isSymbolicLink() ? path.resolve(nodeModulesPath, fs.readlinkSync(p)) : p)
.forEach(modulePath => {
const destPath = path.join(CONFIG.intermediateAppPath, 'node_modules', path.basename(modulePath))
fs.copySync(modulePath, destPath, { filter: includePathInPackagedApp })
})
fs.copySync(
path.join(CONFIG.repositoryRootPath, 'resources', 'app-icons', CONFIG.channel, 'png', '1024.png'),
path.join(CONFIG.intermediateAppPath, 'resources', 'atom.png')

View File

@@ -37,11 +37,11 @@ module.exports = function (packagedAppPath) {
requiredModuleRelativePath.endsWith(path.join('node_modules', 'minimatch', 'minimatch.js')) ||
requiredModuleRelativePath.endsWith(path.join('node_modules', 'request', 'index.js')) ||
requiredModuleRelativePath.endsWith(path.join('node_modules', 'request', 'request.js')) ||
requiredModuleRelativePath.endsWith(path.join('node_modules', 'temp', 'lib', 'temp.js')) ||
requiredModuleRelativePath === path.join('..', 'exports', 'atom.js') ||
requiredModuleRelativePath === path.join('..', 'src', 'electron-shims.js') ||
requiredModuleRelativePath === path.join('..', 'node_modules', 'atom-keymap', 'lib', 'command-event.js') ||
requiredModuleRelativePath === path.join('..', 'node_modules', 'babel-core', 'index.js') ||
requiredModuleRelativePath === path.join('..', 'node_modules', 'cached-run-in-this-context', 'lib', 'main.js') ||
requiredModuleRelativePath === path.join('..', 'node_modules', 'debug', 'node.js') ||
requiredModuleRelativePath === path.join('..', 'node_modules', 'git-utils', 'src', 'git.js') ||
requiredModuleRelativePath === path.join('..', 'node_modules', 'glob', 'glob.js') ||
@@ -60,7 +60,6 @@ module.exports = function (packagedAppPath) {
requiredModuleRelativePath === path.join('..', 'node_modules', 'spelling-manager', 'node_modules', 'natural', 'lib', 'natural', 'index.js') ||
requiredModuleRelativePath === path.join('..', 'node_modules', 'tar', 'tar.js') ||
requiredModuleRelativePath === path.join('..', 'node_modules', 'ls-archive', 'node_modules', 'tar', 'tar.js') ||
requiredModuleRelativePath === path.join('..', 'node_modules', 'temp', 'lib', 'temp.js') ||
requiredModuleRelativePath === path.join('..', 'node_modules', 'tmp', 'lib', 'tmp.js') ||
requiredModuleRelativePath === path.join('..', 'node_modules', 'tree-sitter', 'index.js') ||
requiredModuleRelativePath === path.join('..', 'node_modules', 'yauzl', 'index.js') ||
@@ -97,22 +96,36 @@ module.exports = function (packagedAppPath) {
{env: Object.assign({}, process.env, {ELECTRON_RUN_AS_NODE: 1})}
)
const generatedStartupBlobPath = path.join(CONFIG.buildOutputPath, 'snapshot_blob.bin')
console.log(`Generating startup blob at "${generatedStartupBlobPath}"`)
childProcess.execFileSync(
path.join(CONFIG.repositoryRootPath, 'script', 'node_modules', 'electron-mksnapshot', 'bin', 'mksnapshot'),
['--no-use_ic', snapshotScriptPath, '--startup_blob', generatedStartupBlobPath]
console.log('Generating startup blob with mksnapshot')
childProcess.spawnSync(
process.execPath, [
path.join(CONFIG.repositoryRootPath, 'script', 'node_modules', 'electron-mksnapshot', 'mksnapshot.js'),
snapshotScriptPath,
'--output_dir',
CONFIG.buildOutputPath
]
)
let startupBlobDestinationPath
if (process.platform === 'darwin') {
startupBlobDestinationPath = `${packagedAppPath}/Contents/Frameworks/Electron Framework.framework/Resources/snapshot_blob.bin`
startupBlobDestinationPath = `${packagedAppPath}/Contents/Frameworks/Electron Framework.framework/Resources`
} else {
startupBlobDestinationPath = path.join(packagedAppPath, 'snapshot_blob.bin')
startupBlobDestinationPath = packagedAppPath
}
console.log(`Moving generated startup blob into "${startupBlobDestinationPath}"`)
fs.unlinkSync(startupBlobDestinationPath)
fs.renameSync(generatedStartupBlobPath, startupBlobDestinationPath)
const snapshotBinaries = ['v8_context_snapshot.bin', 'snapshot_blob.bin']
for (let snapshotBinary of snapshotBinaries) {
const destinationPath = path.join(startupBlobDestinationPath, snapshotBinary)
console.log(`Moving generated startup blob into "${destinationPath}"`)
try {
fs.unlinkSync(destinationPath)
} catch (err) {
// Doesn't matter if the file doesn't exist already
if (!err.code || err.code !== 'ENOENT') {
throw err
}
}
fs.renameSync(path.join(CONFIG.buildOutputPath, snapshotBinary), destinationPath)
}
})
}

View File

@@ -29,6 +29,7 @@ module.exports = function () {
'name': appName,
'out': CONFIG.buildOutputPath,
'overwrite': true,
'deref-symlinks': false,
'platform': process.platform,
'version': CONFIG.appMetadata.electronVersion,
'version-string': {

121
script/package-lock.json generated
View File

@@ -649,9 +649,9 @@
}
},
"bindings": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz",
"integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw=="
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz",
"integrity": "sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew=="
},
"bl": {
"version": "1.2.2",
@@ -921,9 +921,9 @@
"integrity": "sha512-7I/xceXfKyUJmSAn/jw8ve/9DyOP7XxufNYLI9Px7CmsKgEUaZLUTax6nZxGQtaoiZCjpu6cHPj20xC/vqRReQ=="
},
"chownr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
"integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE="
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
"integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g=="
},
"chromium-pickle-js": {
"version": "0.1.0",
@@ -1691,54 +1691,76 @@
"integrity": "sha1-YMf4e9YrzGqJT6jM1q+3gjok90I="
},
"electron-chromedriver": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/electron-chromedriver/-/electron-chromedriver-2.0.0.tgz",
"integrity": "sha512-kERk/Wzhc9RzW9jUKXA5kJc4m8BlL6c9p5QH+CrIlst0saeqZL1Up7vzD4ZOnuBDpAVBBYJ4jhkAKIssf8ZlXg==",
"version": "3.0.0-beta.1",
"resolved": "https://registry.npmjs.org/electron-chromedriver/-/electron-chromedriver-3.0.0-beta.1.tgz",
"integrity": "sha512-S8KuOWqTISSfeVccrh1XjqR5tARdkAbF93azz8TvuNJTKoIw7V54mLKoyhi2Hj5UvKuPLcrHmfa4B9Uh45A5lA==",
"requires": {
"electron-download": "^4.1.0",
"extract-zip": "^1.6.5"
}
},
"electron-download": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/electron-download/-/electron-download-4.1.0.tgz",
"integrity": "sha1-v5MsdG8vh//MCdHdRy8v9rkYeEU=",
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/electron-download/-/electron-download-4.1.1.tgz",
"integrity": "sha512-FjEWG9Jb/ppK/2zToP+U5dds114fM1ZOJqMAR4aXXL5CvyPE9fiqBK/9YcwC9poIFQTEJk/EM/zyRwziziRZrg==",
"requires": {
"debug": "^2.2.0",
"debug": "^3.0.0",
"env-paths": "^1.0.0",
"fs-extra": "^2.0.0",
"fs-extra": "^4.0.1",
"minimist": "^1.2.0",
"nugget": "^2.0.0",
"nugget": "^2.0.1",
"path-exists": "^3.0.0",
"rc": "^1.1.2",
"semver": "^5.3.0",
"sumchecker": "^2.0.1"
"rc": "^1.2.1",
"semver": "^5.4.1",
"sumchecker": "^2.0.2"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
},
"fs-extra": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz",
"integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=",
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
"integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
"requires": {
"graceful-fs": "^4.1.2",
"jsonfile": "^2.1.0"
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"requires": {
"graceful-fs": "^4.1.6"
}
},
"path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
},
"semver": {
"version": "5.5.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz",
"integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw=="
}
}
},
"electron-link": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/electron-link/-/electron-link-0.2.2.tgz",
"integrity": "sha1-uWvx/MrowwyAuiaTBq+UVOYtP2U=",
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/electron-link/-/electron-link-0.3.2.tgz",
"integrity": "sha512-V7QmtujzWgvrW5BI2CKmIRF+q+pkrFO5Lecd8TpibbBz+FfW5WQ4kCN0sZjNaUOMtGGroCib721OqIDEynjwgA==",
"requires": {
"ast-util": "^0.6.0",
"encoding-down": "~5.0.0",
"indent-string": "^2.1.0",
"indent-string": "^3.2.0",
"leveldown": "~4.0.0",
"levelup": "~3.0.0",
"recast": "^0.12.6",
@@ -1752,15 +1774,20 @@
"integrity": "sha512-UY7+9DPzlJ9VM8eY0b2TUZcZvF+1pO0hzMtAyjBYKhOmnvRlqYNYnWdtsMj0V16CGaMlpL0G1jnLbLo4AyotuQ=="
},
"core-js": {
"version": "2.5.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz",
"integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw=="
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz",
"integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg=="
},
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"indent-string": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
"integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok="
},
"recast": {
"version": "0.12.9",
"resolved": "https://registry.npmjs.org/recast/-/recast-0.12.9.tgz",
@@ -1783,12 +1810,13 @@
}
},
"electron-mksnapshot": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/electron-mksnapshot/-/electron-mksnapshot-2.0.0.tgz",
"integrity": "sha512-OoZwZJNKgHP+DwhCGVTJEuDSeb478hOzAbHeg7dKGCHDbKKmUWmjGc+pEjxGutpqQ3Mn8hCdLzdx2c/lAJcTLA==",
"version": "3.0.10",
"resolved": "https://registry.npmjs.org/electron-mksnapshot/-/electron-mksnapshot-3.0.10.tgz",
"integrity": "sha512-Toy6sAC3t9tgvq1kUYsx+4TRNPDj7Bzoo+1gx5FD8Q0YCS+tq+ter62Ot6dBXCKG9SwoaGBz84b++MgO0VobYw==",
"requires": {
"electron-download": "^4.1.0",
"extract-zip": "^1.6.5"
"extract-zip": "^1.6.5",
"temp": "^0.8.3"
}
},
"electron-osx-sign": {
@@ -4718,17 +4746,17 @@
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
},
"node-abi": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.4.3.tgz",
"integrity": "sha512-b656V5C0628gOOA2kwcpNA/bxdlqYF9FvxJ+qqVX0ctdXNVZpS8J6xEUYir3WAKc7U0BH/NRlSpNbGsy+azjeg==",
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.5.1.tgz",
"integrity": "sha512-oDbFc7vCFx0RWWCweTer3hFm1u+e60N5FtGnmRV6QqvgATGFH/XRR6vqWIeBVosCYCqt6YdIr2L0exLZuEdVcQ==",
"requires": {
"semver": "^5.4.1"
},
"dependencies": {
"semver": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
}
}
},
@@ -9874,16 +9902,16 @@
}
},
"tar-stream": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz",
"integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==",
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
"integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
"requires": {
"bl": "^1.0.0",
"buffer-alloc": "^1.1.0",
"buffer-alloc": "^1.2.0",
"end-of-stream": "^1.0.0",
"fs-constants": "^1.0.0",
"readable-stream": "^2.3.0",
"to-buffer": "^1.1.0",
"to-buffer": "^1.1.1",
"xtend": "^4.0.0"
},
"dependencies": {
@@ -10304,6 +10332,11 @@
"unist-util-is": "^2.1.1"
}
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
},
"unset-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",

View File

@@ -9,9 +9,9 @@
"coffeelint": "1.15.7",
"colors": "1.1.2",
"donna": "1.0.16",
"electron-chromedriver": "~2.0",
"electron-link": "0.2.2",
"electron-mksnapshot": "~2.0",
"electron-chromedriver": "~3.0.0-beta.1",
"electron-link": "0.3.2",
"electron-mksnapshot": "~3.0.10",
"electron-packager": "7.3.0",
"electron-winstaller": "2.6.4",
"fs-admin": "^0.1.5",

View File

@@ -3,7 +3,36 @@
'use strict'
require('colors')
const argv = require('yargs').argv
const argv = require('yargs')
.option('core-main', {
describe: 'Run core main process tests',
boolean: true,
default: false
})
.option('skip-main', {
describe: 'Skip main process tests if they would otherwise run on your platform',
boolean: true,
default: false,
conflicts: 'core-main'
})
.option('core-renderer', {
describe: 'Run core renderer process tests',
boolean: true,
default: false
})
.option('core-benchmark', {
describe: 'Run core benchmarks',
boolean: true,
default: false
})
.option('package', {
describe: 'Run bundled package specs',
boolean: true,
default: false
})
.help()
.argv
const assert = require('assert')
const async = require('async')
const childProcess = require('child_process')
@@ -148,10 +177,27 @@ function runBenchmarkTests (callback) {
cp.on('close', exitCode => { callback(null, exitCode) })
}
let testSuitesToRun = testSuitesForPlatform(process.platform)
let testSuitesToRun = requestedTestSuites() || testSuitesForPlatform(process.platform)
function requestedTestSuites () {
const suites = []
if (argv.coreMain) {
suites.push(runCoreMainProcessTests)
}
if (argv.coreRenderer) {
suites.push(runCoreRenderProcessTests)
}
if (argv.coreBenchmark) {
suites.push(runBenchmarkTests)
}
if (argv.package) {
suites.push(...packageTestSuites)
}
return suites.length > 0 ? suites : null
}
function testSuitesForPlatform (platform) {
let suites = [];
let suites = []
switch (platform) {
case 'darwin':
suites = [runCoreMainProcessTests, runCoreRenderProcessTests, runBenchmarkTests].concat(packageTestSuites)
@@ -167,10 +213,10 @@ function testSuitesForPlatform (platform) {
}
if (argv.skipMainProcessTests) {
suites = suites.filter(suite => suite !== runCoreMainProcessTests);
suites = suites.filter(suite => suite !== runCoreMainProcessTests)
}
return suites;
return suites
}
async.series(testSuitesToRun, function (err, exitCodes) {

View File

@@ -639,7 +639,6 @@ describe('AtomEnvironment', () => {
describe('::openLocations(locations) (called via IPC from browser process)', () => {
beforeEach(() => {
spyOn(atom.workspace, 'open')
atom.project.setPaths([])
})
@@ -649,48 +648,72 @@ describe('AtomEnvironment', () => {
})
describe('when the opened path exists', () => {
it("adds it to the project's paths", async () => {
it('opens a file', async () => {
const pathToOpen = __filename
await atom.openLocations([{pathToOpen}])
expect(atom.project.getPaths()[0]).toBe(__dirname)
expect(atom.project.getPaths()).toEqual([])
})
describe('then a second path is opened with forceAddToWindow', () => {
it("adds the second path to the project's paths", async () => {
const firstPathToOpen = __dirname
const secondPathToOpen = path.resolve(__dirname, './fixtures')
await atom.openLocations([{pathToOpen: firstPathToOpen}])
await atom.openLocations([{pathToOpen: secondPathToOpen, forceAddToWindow: true}])
expect(atom.project.getPaths()).toEqual([firstPathToOpen, secondPathToOpen])
})
})
})
describe('when the opened path does not exist but its parent directory does', () => {
it('adds the parent directory to the project paths', async () => {
const pathToOpen = path.join(__dirname, 'this-path-does-not-exist.txt')
await atom.openLocations([{pathToOpen}])
expect(atom.project.getPaths()[0]).toBe(__dirname)
})
})
describe('when the opened path is a file', () => {
it('opens it in the workspace', async () => {
const pathToOpen = __filename
await atom.openLocations([{pathToOpen}])
expect(atom.workspace.open.mostRecentCall.args[0]).toBe(__filename)
})
})
describe('when the opened path is a directory', () => {
it('does not open it in the workspace', async () => {
it('opens a directory as a project folder', async () => {
const pathToOpen = __dirname
await atom.openLocations([{pathToOpen}])
expect(atom.workspace.open.callCount).toBe(0)
expect(atom.workspace.getTextEditors().map(e => e.getPath())).toEqual([])
expect(atom.project.getPaths()).toEqual([pathToOpen])
})
})
describe('when the opened path is a uri', () => {
describe('when the opened path does not exist', () => {
it('opens it as a new file', async () => {
const pathToOpen = path.join(__dirname, 'this-path-does-not-exist.txt')
await atom.openLocations([{pathToOpen}])
expect(atom.workspace.getTextEditors().map(e => e.getPath())).toEqual([pathToOpen])
expect(atom.project.getPaths()).toEqual([])
})
it('may be required to be an existing directory', async () => {
spyOn(atom.notifications, 'addWarning')
const nonExistent = path.join(__dirname, 'no')
const existingFile = __filename
const existingDir = path.join(__dirname, 'fixtures')
await atom.openLocations([
{pathToOpen: nonExistent, mustBeDirectory: true},
{pathToOpen: existingFile, mustBeDirectory: true},
{pathToOpen: existingDir, mustBeDirectory: true}
])
expect(atom.workspace.getTextEditors()).toEqual([])
expect(atom.project.getPaths()).toEqual([existingDir])
expect(atom.notifications.addWarning).toHaveBeenCalledWith(
'Unable to open project folders',
{description: `The directories \`${nonExistent}\` and \`${existingFile}\` do not exist.`}
)
})
})
describe('when the opened path is handled by a registered directory provider', () => {
let serviceDisposable
beforeEach(() => {
serviceDisposable = atom.packages.serviceHub.provide('atom.directory-provider', '0.1.0', {
directoryForURISync (uri) {
if (uri.startsWith('remote://')) {
return { getPath() { return uri } }
} else {
return null
}
}
})
waitsFor(() => atom.project.directoryProviders.length > 0)
})
afterEach(() => {
serviceDisposable.dispose()
})
it("adds it to the project's paths as is", async () => {
const pathToOpen = 'remote://server:7644/some/dir/path'
spyOn(atom.project, 'addPath')
@@ -719,6 +742,27 @@ describe('AtomEnvironment', () => {
expect(atom.project.getPaths()).toEqual([])
})
it('includes missing mandatory project folders in computation of initial state key', async () => {
const existingDir = path.join(__dirname, 'fixtures')
const missingDir = path.join(__dirname, 'no')
atom.loadState.andCallFake(function (key) {
if (key === `${existingDir}:${missingDir}`) {
return Promise.resolve(state)
} else {
return Promise.resolve(null)
}
})
await atom.openLocations([
{pathToOpen: existingDir},
{pathToOpen: missingDir, mustBeDirectory: true}
])
expect(atom.attemptRestoreProjectStateForPaths).toHaveBeenCalledWith(state, [existingDir], [])
expect(atom.project.getPaths(), [existingDir])
})
it('opens the specified files', async () => {
await atom.openLocations([{pathToOpen: __dirname}, {pathToOpen: __filename}])
expect(atom.attemptRestoreProjectStateForPaths).toHaveBeenCalledWith(state, [__dirname], [__filename])
@@ -741,7 +785,7 @@ describe('AtomEnvironment', () => {
const fileToOpen = path.join(pathToOpen, 'michelle-is-awesome.txt')
await atom.openLocations([{pathToOpen}, {pathToOpen: fileToOpen}])
expect(atom.attemptRestoreProjectStateForPaths).not.toHaveBeenCalledWith(state, [pathToOpen], [fileToOpen])
expect(atom.project.getPaths()).toEqual([__dirname])
expect(atom.project.getPaths()).toEqual([__dirname, pathToOpen])
})
})
})

View File

@@ -1,6 +1,7 @@
DecorationManager = require '../src/decoration-manager'
TextEditor = require '../src/text-editor'
# Tests crash the renderer process on Electron 3.0, disabling for now.
describe "DecorationManager", ->
[decorationManager, buffer, editor, markerLayer1, markerLayer2] = []
@@ -64,7 +65,9 @@ describe "DecorationManager", ->
{oldProperties, newProperties} = updatedSpy.mostRecentCall.args[0]
expect(oldProperties).toEqual decorationProperties
expect(newProperties).toEqual {type: 'line-number', gutterName: 'line-number', class: 'two'}
expect(newProperties.type).toBe 'line-number'
expect(newProperties.gutterName).toBe 'line-number'
expect(newProperties.class).toBe 'two'
describe "::getDecorations(properties)", ->
it "returns decorations matching the given optional properties", ->

View File

@@ -1,3 +1,3 @@
'use 6to6';
module.exports = async function* hello() {}
export default 42;

View File

@@ -23,10 +23,14 @@ describe "Smoke Test", ->
it "can open a file in Atom and perform basic operations on it", ->
tempDirPath = temp.mkdirSync("empty-dir")
runAtom [path.join(tempDirPath, "new-file")], {ATOM_HOME: atomHome}, (client) ->
filePath = path.join(tempDirPath, "new-file")
fs.writeFileSync filePath, "", {encoding: "utf8"}
runAtom [filePath], {ATOM_HOME: atomHome}, (client) ->
client
.treeViewRootDirectories()
.then ({value}) -> expect(value).toEqual([tempDirPath])
.then ({value}) -> expect(value).toEqual([])
.waitForExist("atom-text-editor", 5000)
.then (exists) -> expect(exists).toBe true
.waitForPaneItemCount(1, 1000)

View File

@@ -1,3 +1,5 @@
/* globals assert */
const temp = require('temp').track()
const season = require('season')
const dedent = require('dedent')
@@ -44,55 +46,226 @@ describe('AtomApplication', function () {
})
describe('launch', () => {
it('can open to a specific line number of a file', async () => {
const filePath = path.join(makeTempDir(), 'new-file')
fs.writeFileSync(filePath, '1\n2\n3\n4\n')
const atomApplication = buildAtomApplication()
describe('with no paths', () => {
it('reopens any previously opened windows', async () => {
if (process.platform === 'win32') return // Test is too flakey on Windows
const [window] = await atomApplication.launch(parseCommandLine([filePath + ':3']))
await focusWindow(window)
const tempDirPath1 = makeTempDir()
const tempDirPath2 = makeTempDir()
const cursorRow = await evalInWebContents(window.browserWindow.webContents, sendBackToMainProcess => {
atom.workspace.observeTextEditors(textEditor => {
sendBackToMainProcess(textEditor.getCursorBufferPosition().row)
})
const atomApplication1 = buildAtomApplication()
const [app1Window1] = await atomApplication1.launch(parseCommandLine([tempDirPath1]))
await emitterEventPromise(app1Window1, 'window:locations-opened')
const [app1Window2] = await atomApplication1.launch(parseCommandLine([tempDirPath2]))
await emitterEventPromise(app1Window2, 'window:locations-opened')
await Promise.all([
app1Window1.prepareToUnload(),
app1Window2.prepareToUnload()
])
const atomApplication2 = buildAtomApplication()
const [app2Window1, app2Window2] = await atomApplication2.launch(parseCommandLine([]))
await Promise.all([
emitterEventPromise(app2Window1, 'window:locations-opened'),
emitterEventPromise(app2Window2, 'window:locations-opened')
])
assert.deepEqual(await getTreeViewRootDirectories(app2Window1), [tempDirPath1])
assert.deepEqual(await getTreeViewRootDirectories(app2Window2), [tempDirPath2])
})
assert.equal(cursorRow, 2)
it('when windows already exist, opens a new window with a single untitled buffer', async () => {
const atomApplication = buildAtomApplication()
const [window1] = await atomApplication.launch(parseCommandLine([]))
await focusWindow(window1)
const window1EditorTitle = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
sendBackToMainProcess(atom.workspace.getActiveTextEditor().getTitle())
})
assert.equal(window1EditorTitle, 'untitled')
const window2 = atomApplication.openWithOptions(parseCommandLine([]))
await window2.loadedPromise
const window2EditorTitle = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
sendBackToMainProcess(atom.workspace.getActiveTextEditor().getTitle())
})
assert.equal(window2EditorTitle, 'untitled')
assert.deepEqual(atomApplication.getAllWindows(), [window2, window1])
})
it('when no windows are open but --new-window is passed, opens a new window with a single untitled buffer', async () => {
// Populate some saved state
const tempDirPath1 = makeTempDir()
const tempDirPath2 = makeTempDir()
const atomApplication1 = buildAtomApplication()
const [app1Window1] = await atomApplication1.launch(parseCommandLine([tempDirPath1]))
await emitterEventPromise(app1Window1, 'window:locations-opened')
const [app1Window2] = await atomApplication1.launch(parseCommandLine([tempDirPath2]))
await emitterEventPromise(app1Window2, 'window:locations-opened')
await Promise.all([
app1Window1.prepareToUnload(),
app1Window2.prepareToUnload()
])
// Launch with --new-window
const atomApplication2 = buildAtomApplication()
const appWindows2 = await atomApplication2.launch(parseCommandLine(['--new-window']))
assert.lengthOf(appWindows2, 1)
const [appWindow2] = appWindows2
await appWindow2.loadedPromise
const window2EditorTitle = await evalInWebContents(appWindow2.browserWindow.webContents, sendBackToMainProcess => {
sendBackToMainProcess(atom.workspace.getActiveTextEditor().getTitle())
})
assert.equal(window2EditorTitle, 'untitled')
})
it('does not open an empty editor if core.openEmptyEditorOnStart is false', async () => {
const configPath = path.join(process.env.ATOM_HOME, 'config.cson')
const config = season.readFileSync(configPath)
if (!config['*'].core) config['*'].core = {}
config['*'].core.openEmptyEditorOnStart = false
season.writeFileSync(configPath, config)
const atomApplication = buildAtomApplication()
const [window1] = await atomApplication.launch(parseCommandLine([]))
await focusWindow(window1)
// wait a bit just to make sure we don't pass due to querying the render process before it loads
await timeoutPromise(1000)
const itemCount = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
sendBackToMainProcess(atom.workspace.getActivePane().getItems().length)
})
assert.equal(itemCount, 0)
})
})
it('can open to a specific line and column of a file', async () => {
const filePath = path.join(makeTempDir(), 'new-file')
fs.writeFileSync(filePath, '1\n2\n3\n4\n')
const atomApplication = buildAtomApplication()
describe('with file or folder paths', () => {
it('shows all directories in the tree view when multiple directory paths are passed to Atom', async () => {
const dirAPath = makeTempDir('a')
const dirBPath = makeTempDir('b')
const dirBSubdirPath = path.join(dirBPath, 'c')
fs.mkdirSync(dirBSubdirPath)
const [window] = await atomApplication.launch(parseCommandLine([filePath + ':2:2']))
await focusWindow(window)
const atomApplication = buildAtomApplication()
const [window1] = await atomApplication.launch(parseCommandLine([dirAPath, dirBPath]))
await focusWindow(window1)
const cursorPosition = await evalInWebContents(window.browserWindow.webContents, sendBackToMainProcess => {
atom.workspace.observeTextEditors(textEditor => {
sendBackToMainProcess(textEditor.getCursorBufferPosition())
})
await conditionPromise(async () => (await getTreeViewRootDirectories(window1)).length === 2)
assert.deepEqual(await getTreeViewRootDirectories(window1), [dirAPath, dirBPath])
})
assert.deepEqual(cursorPosition, {row: 1, column: 1})
it('can open to a specific line number of a file', async () => {
const filePath = path.join(makeTempDir(), 'new-file')
fs.writeFileSync(filePath, '1\n2\n3\n4\n')
const atomApplication = buildAtomApplication()
const [window] = await atomApplication.launch(parseCommandLine([filePath + ':3']))
await focusWindow(window)
const cursorRow = await evalInWebContents(window.browserWindow.webContents, sendBackToMainProcess => {
atom.workspace.observeTextEditors(textEditor => {
sendBackToMainProcess(textEditor.getCursorBufferPosition().row)
})
})
assert.equal(cursorRow, 2)
})
it('can open to a specific line and column of a file', async () => {
const filePath = path.join(makeTempDir(), 'new-file')
fs.writeFileSync(filePath, '1\n2\n3\n4\n')
const atomApplication = buildAtomApplication()
const [window] = await atomApplication.launch(parseCommandLine([filePath + ':2:2']))
await focusWindow(window)
const cursorPosition = await evalInWebContents(window.browserWindow.webContents, sendBackToMainProcess => {
atom.workspace.observeTextEditors(textEditor => {
sendBackToMainProcess(textEditor.getCursorBufferPosition())
})
})
assert.deepEqual(cursorPosition, {row: 1, column: 1})
})
it('removes all trailing whitespace and colons from the specified path', async () => {
let filePath = path.join(makeTempDir(), 'new-file')
fs.writeFileSync(filePath, '1\n2\n3\n4\n')
const atomApplication = buildAtomApplication()
const [window] = await atomApplication.launch(parseCommandLine([filePath + ':: ']))
await focusWindow(window)
const openedPath = await evalInWebContents(window.browserWindow.webContents, sendBackToMainProcess => {
atom.workspace.observeTextEditors(textEditor => {
sendBackToMainProcess(textEditor.getPath())
})
})
assert.equal(openedPath, filePath)
})
it('opens an empty text editor when launched with a new file path', async () => {
// Choosing "Don't save"
mockElectronShowMessageBox({response: 2})
const atomApplication = buildAtomApplication()
const newFilePath = path.join(makeTempDir(), 'new-file')
const [window] = await atomApplication.launch(parseCommandLine([newFilePath]))
await focusWindow(window)
const {editorTitle, editorText} = await evalInWebContents(window.browserWindow.webContents, sendBackToMainProcess => {
atom.workspace.observeTextEditors(editor => {
sendBackToMainProcess({editorTitle: editor.getTitle(), editorText: editor.getText()})
})
})
assert.equal(editorTitle, path.basename(newFilePath))
assert.equal(editorText, '')
assert.deepEqual(await getTreeViewRootDirectories(window), [])
})
})
it('removes all trailing whitespace and colons from the specified path', async () => {
let filePath = path.join(makeTempDir(), 'new-file')
fs.writeFileSync(filePath, '1\n2\n3\n4\n')
const atomApplication = buildAtomApplication()
describe('when the --add option is specified', () => {
it('adds folders to existing windows when the --add option is used', async () => {
const dirAPath = makeTempDir('a')
const dirBPath = makeTempDir('b')
const dirCPath = makeTempDir('c')
const existingDirCFilePath = path.join(dirCPath, 'existing-file')
fs.writeFileSync(existingDirCFilePath, 'this is an existing file')
const [window] = await atomApplication.launch(parseCommandLine([filePath + ':: ']))
await focusWindow(window)
const atomApplication = buildAtomApplication()
const [window1] = await atomApplication.launch(parseCommandLine([dirAPath]))
await focusWindow(window1)
const openedPath = await evalInWebContents(window.browserWindow.webContents, sendBackToMainProcess => {
atom.workspace.observeTextEditors(textEditor => {
sendBackToMainProcess(textEditor.getPath())
await conditionPromise(async () => (await getTreeViewRootDirectories(window1)).length === 1)
assert.deepEqual(await getTreeViewRootDirectories(window1), [dirAPath])
// When opening *files* with --add, reuses an existing window
let [reusedWindow] = await atomApplication.launch(parseCommandLine([existingDirCFilePath, '--add']))
assert.equal(reusedWindow, window1)
assert.deepEqual(atomApplication.getAllWindows(), [window1])
let activeEditorPath = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
const subscription = atom.workspace.onDidChangeActivePaneItem(textEditor => {
sendBackToMainProcess(textEditor.getPath())
subscription.dispose()
})
})
})
assert.equal(activeEditorPath, existingDirCFilePath)
assert.deepEqual(await getTreeViewRootDirectories(window1), [dirAPath])
assert.equal(openedPath, filePath)
// When opening *directories* with --add, reuses an existing window and adds the directory to the project
reusedWindow = (await atomApplication.launch(parseCommandLine([dirBPath, '-a'])))[0]
assert.equal(reusedWindow, window1)
assert.deepEqual(atomApplication.getAllWindows(), [window1])
await conditionPromise(async () => (await getTreeViewRootDirectories(reusedWindow)).length === 2)
assert.deepEqual(await getTreeViewRootDirectories(window1), [dirAPath, dirBPath])
})
})
if (process.platform === 'darwin' || process.platform === 'win32') {
@@ -114,95 +287,15 @@ describe('AtomApplication', function () {
})
}
it('reuses existing windows when opening paths, but not directories', async () => {
const dirAPath = makeTempDir("a")
const dirBPath = makeTempDir("b")
const dirCPath = makeTempDir("c")
const existingDirCFilePath = path.join(dirCPath, 'existing-file')
fs.writeFileSync(existingDirCFilePath, 'this is an existing file')
const atomApplication = buildAtomApplication()
const [window1] = await atomApplication.launch(parseCommandLine([path.join(dirAPath, 'new-file')]))
await emitterEventPromise(window1, 'window:locations-opened')
await focusWindow(window1)
let activeEditorPath = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
atom.workspace.observeTextEditors(textEditor => {
sendBackToMainProcess(textEditor.getPath())
})
})
assert.equal(activeEditorPath, path.join(dirAPath, 'new-file'))
// Reuses the window when opening *files*, even if they're in a different directory
// Does not change the project paths when doing so.
const [reusedWindow] = await atomApplication.launch(parseCommandLine([existingDirCFilePath]))
assert.equal(reusedWindow, window1)
assert.deepEqual(atomApplication.getAllWindows(), [window1])
activeEditorPath = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
const subscription = atom.workspace.onDidChangeActivePaneItem(textEditor => {
sendBackToMainProcess(textEditor.getPath())
subscription.dispose()
})
})
assert.equal(activeEditorPath, existingDirCFilePath)
assert.deepEqual(await getTreeViewRootDirectories(window1), [dirAPath])
// Opens new windows when opening directories
const [window2] = await atomApplication.launch(parseCommandLine([dirCPath]))
await emitterEventPromise(window2, 'window:locations-opened')
assert.notEqual(window2, window1)
await focusWindow(window2)
assert.deepEqual(await getTreeViewRootDirectories(window2), [dirCPath])
})
it('adds folders to existing windows when the --add option is used', async () => {
const dirAPath = makeTempDir("a")
const dirBPath = makeTempDir("b")
const dirCPath = makeTempDir("c")
const existingDirCFilePath = path.join(dirCPath, 'existing-file')
fs.writeFileSync(existingDirCFilePath, 'this is an existing file')
const atomApplication = buildAtomApplication()
const [window1] = await atomApplication.launch(parseCommandLine([path.join(dirAPath, 'new-file')]))
await focusWindow(window1)
let activeEditorPath = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
atom.workspace.observeTextEditors(textEditor => {
sendBackToMainProcess(textEditor.getPath())
})
})
assert.equal(activeEditorPath, path.join(dirAPath, 'new-file'))
// When opening *files* with --add, reuses an existing window and adds
// parent directory to the project
let [reusedWindow] = await atomApplication.launch(parseCommandLine([existingDirCFilePath, '--add']))
assert.equal(reusedWindow, window1)
assert.deepEqual(atomApplication.getAllWindows(), [window1])
activeEditorPath = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
const subscription = atom.workspace.onDidChangeActivePaneItem(textEditor => {
sendBackToMainProcess(textEditor.getPath())
subscription.dispose()
})
})
assert.equal(activeEditorPath, existingDirCFilePath)
assert.deepEqual(await getTreeViewRootDirectories(window1), [dirAPath, dirCPath])
// When opening *directories* with add reuses an existing window and adds
// the directory to the project
reusedWindow = (await atomApplication.launch(parseCommandLine([dirBPath, '-a'])))[0]
assert.equal(reusedWindow, window1)
assert.deepEqual(atomApplication.getAllWindows(), [window1])
await conditionPromise(async () => (await getTreeViewRootDirectories(reusedWindow)).length === 3)
assert.deepEqual(await getTreeViewRootDirectories(window1), [dirAPath, dirCPath, dirBPath])
})
it('persists window state based on the project directories', async () => {
// Choosing "Don't save"
mockElectronShowMessageBox({response: 2})
const tempDirPath = makeTempDir()
const atomApplication = buildAtomApplication()
const nonExistentFilePath = path.join(tempDirPath, 'new-file')
const [window1] = await atomApplication.launch(parseCommandLine([nonExistentFilePath]))
const [window1] = await atomApplication.launch(parseCommandLine([tempDirPath, nonExistentFilePath]))
await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
atom.workspace.observeTextEditors(textEditor => {
textEditor.insertText('Hello World!')
@@ -213,7 +306,7 @@ describe('AtomApplication', function () {
window1.close()
await window1.closedPromise
// Restore unsaved state when opening the directory itself
// Restore unsaved state when opening the same project directory
const [window2] = await atomApplication.launch(parseCommandLine([tempDirPath]))
await window2.loadedPromise
const window2Text = await evalInWebContents(window2.browserWindow.webContents, sendBackToMainProcess => {
@@ -223,95 +316,6 @@ describe('AtomApplication', function () {
sendBackToMainProcess(textEditor.getText())
})
assert.equal(window2Text, 'Hello World! How are you?')
await window2.prepareToUnload()
window2.close()
await window2.closedPromise
// Restore unsaved state when opening a path to a non-existent file in the directory
const [window3] = await atomApplication.launch(parseCommandLine([path.join(tempDirPath, 'another-non-existent-file')]))
await window3.loadedPromise
const window3Texts = await evalInWebContents(window3.browserWindow.webContents, (sendBackToMainProcess, nonExistentFilePath) => {
sendBackToMainProcess(atom.workspace.getTextEditors().map(editor => editor.getText()))
})
assert.include(window3Texts, 'Hello World! How are you?')
})
it('shows all directories in the tree view when multiple directory paths are passed to Atom', async () => {
const dirAPath = makeTempDir("a")
const dirBPath = makeTempDir("b")
const dirBSubdirPath = path.join(dirBPath, 'c')
fs.mkdirSync(dirBSubdirPath)
const atomApplication = buildAtomApplication()
const [window1] = await atomApplication.launch(parseCommandLine([dirAPath, dirBPath]))
await focusWindow(window1)
assert.deepEqual(await getTreeViewRootDirectories(window1), [dirAPath, dirBPath])
})
it('reuses windows with no project paths to open directories', async () => {
const tempDirPath = makeTempDir()
const atomApplication = buildAtomApplication()
const [window1] = await atomApplication.launch(parseCommandLine([]))
await focusWindow(window1)
const [reusedWindow] = await atomApplication.launch(parseCommandLine([tempDirPath]))
assert.equal(reusedWindow, window1)
await conditionPromise(async () => (await getTreeViewRootDirectories(reusedWindow)).length > 0)
})
it('opens a new window with a single untitled buffer when launched with no path, even if windows already exist', async () => {
const atomApplication = buildAtomApplication()
const [window1] = await atomApplication.launch(parseCommandLine([]))
await focusWindow(window1)
const window1EditorTitle = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
sendBackToMainProcess(atom.workspace.getActiveTextEditor().getTitle())
})
assert.equal(window1EditorTitle, 'untitled')
const window2 = atomApplication.openWithOptions(parseCommandLine([]))
await focusWindow(window2)
const window2EditorTitle = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
sendBackToMainProcess(atom.workspace.getActiveTextEditor().getTitle())
})
assert.equal(window2EditorTitle, 'untitled')
assert.deepEqual(atomApplication.getAllWindows(), [window2, window1])
})
it('does not open an empty editor when opened with no path if the core.openEmptyEditorOnStart config setting is false', async () => {
const configPath = path.join(process.env.ATOM_HOME, 'config.cson')
const config = season.readFileSync(configPath)
if (!config['*'].core) config['*'].core = {}
config['*'].core.openEmptyEditorOnStart = false
season.writeFileSync(configPath, config)
const atomApplication = buildAtomApplication()
const [window1] = await atomApplication.launch(parseCommandLine([]))
await focusWindow(window1)
// wait a bit just to make sure we don't pass due to querying the render process before it loads
await timeoutPromise(1000)
const itemCount = await evalInWebContents(window1.browserWindow.webContents, sendBackToMainProcess => {
sendBackToMainProcess(atom.workspace.getActivePane().getItems().length)
})
assert.equal(itemCount, 0)
})
it('opens an empty text editor and loads its parent directory in the tree-view when launched with a new file path', async () => {
const atomApplication = buildAtomApplication()
const newFilePath = path.join(makeTempDir(), 'new-file')
const [window] = await atomApplication.launch(parseCommandLine([newFilePath]))
await focusWindow(window)
const {editorTitle, editorText} = await evalInWebContents(window.browserWindow.webContents, sendBackToMainProcess => {
atom.workspace.observeTextEditors(editor => {
sendBackToMainProcess({editorTitle: editor.getTitle(), editorText: editor.getText()})
})
})
assert.equal(editorTitle, path.basename(newFilePath))
assert.equal(editorText, '')
assert.deepEqual(await getTreeViewRootDirectories(window), [path.dirname(newFilePath)])
})
it('adds a remote directory to the project when launched with a remote directory', async () => {
@@ -343,38 +347,11 @@ describe('AtomApplication', function () {
}
})
it('reopens any previously opened windows when launched with no path', async () => {
if (process.platform === 'win32') return; // Test is too flakey on Windows
const tempDirPath1 = makeTempDir()
const tempDirPath2 = makeTempDir()
const atomApplication1 = buildAtomApplication()
const [app1Window1] = await atomApplication1.launch(parseCommandLine([tempDirPath1]))
await emitterEventPromise(app1Window1, 'window:locations-opened')
const [app1Window2] = await atomApplication1.launch(parseCommandLine([tempDirPath2]))
await emitterEventPromise(app1Window2, 'window:locations-opened')
await Promise.all([
app1Window1.prepareToUnload(),
app1Window2.prepareToUnload()
])
const atomApplication2 = buildAtomApplication()
const [app2Window1, app2Window2] = await atomApplication2.launch(parseCommandLine([]))
await Promise.all([
emitterEventPromise(app2Window1, 'window:locations-opened'),
emitterEventPromise(app2Window2, 'window:locations-opened')
])
assert.deepEqual(await getTreeViewRootDirectories(app2Window1), [tempDirPath1])
assert.deepEqual(await getTreeViewRootDirectories(app2Window2), [tempDirPath2])
})
it('does not reopen any previously opened windows when launched with no path and `core.restorePreviousWindowsOnStart` is no', async () => {
const atomApplication1 = buildAtomApplication()
const [app1Window1] = await atomApplication1.launch(parseCommandLine([makeTempDir()]))
await focusWindow(app1Window1)
const [app1Window2] = await atomApplication1.launch(parseCommandLine([makeTempDir()]))
await focusWindow(app1Window2)
@@ -424,15 +401,16 @@ describe('AtomApplication', function () {
})
it('kills the specified pid after a newly-opened file in an existing window is closed', async () => {
const [window] = await atomApplication.launch(parseCommandLine(['--wait', '--pid', '101']))
await focusWindow(window)
const filePath1 = temp.openSync('test').path
const filePath2 = temp.openSync('test').path
const projectDir = makeTempDir('existing')
const filePath1 = path.join(projectDir, 'file-1')
const filePath2 = path.join(projectDir, 'file-2')
fs.writeFileSync(filePath1, 'File 1')
fs.writeFileSync(filePath2, 'File 2')
const [reusedWindow] = await atomApplication.launch(parseCommandLine(['--wait', '--pid', '102', filePath1, filePath2]))
const [window] = await atomApplication.launch(parseCommandLine(['--wait', '--pid', '101', projectDir]))
await focusWindow(window)
const [reusedWindow] = await atomApplication.launch(parseCommandLine(['--add', '--wait', '--pid', '102', filePath1, filePath2]))
assert.equal(reusedWindow, window)
const activeEditorPath = await evalInWebContents(window.browserWindow.webContents, send => {
@@ -471,8 +449,9 @@ describe('AtomApplication', function () {
await focusWindow(window)
const dirPath1 = makeTempDir()
const [reusedWindow] = await atomApplication.launch(parseCommandLine(['--wait', '--pid', '101', dirPath1]))
const [reusedWindow] = await atomApplication.launch(parseCommandLine(['--add', '--wait', '--pid', '101', dirPath1]))
assert.equal(reusedWindow, window)
await conditionPromise(async () => (await getTreeViewRootDirectories(window)).length === 1)
assert.deepEqual(await getTreeViewRootDirectories(window), [dirPath1])
assert.deepEqual(killedPids, [])
@@ -498,7 +477,7 @@ describe('AtomApplication', function () {
if (process.platform === 'linux' || process.platform === 'win32') {
it('quits the application', async () => {
const atomApplication = buildAtomApplication()
const [window] = await atomApplication.launch(parseCommandLine([path.join(makeTempDir("a"), 'file-a')]))
const [window] = await atomApplication.launch(parseCommandLine([path.join(makeTempDir('a'), 'file-a')]))
await focusWindow(window)
window.close()
await window.closedPromise
@@ -508,7 +487,7 @@ describe('AtomApplication', function () {
} else if (process.platform === 'darwin') {
it('leaves the application open', async () => {
const atomApplication = buildAtomApplication()
const [window] = await atomApplication.launch(parseCommandLine([path.join(makeTempDir("a"), 'file-a')]))
const [window] = await atomApplication.launch(parseCommandLine([path.join(makeTempDir('a'), 'file-a')]))
await focusWindow(window)
window.close()
await window.closedPromise
@@ -524,24 +503,24 @@ describe('AtomApplication', function () {
const dirB = makeTempDir()
const atomApplication = buildAtomApplication()
const [window] = await atomApplication.launch(parseCommandLine([dirA, dirB]))
await emitterEventPromise(window, 'window:locations-opened')
await focusWindow(window)
assert.deepEqual(await getTreeViewRootDirectories(window), [dirA, dirB])
const [window0] = await atomApplication.launch(parseCommandLine([dirA, dirB]))
await focusWindow(window0)
await conditionPromise(async () => (await getTreeViewRootDirectories(window0)).length === 2)
assert.deepEqual(await getTreeViewRootDirectories(window0), [dirA, dirB])
const saveStatePromise = emitterEventPromise(atomApplication, 'application:did-save-state')
await evalInWebContents(window.browserWindow.webContents, (sendBackToMainProcess) => {
await evalInWebContents(window0.browserWindow.webContents, (sendBackToMainProcess) => {
atom.project.removePath(atom.project.getPaths()[0])
sendBackToMainProcess(null)
})
assert.deepEqual(await getTreeViewRootDirectories(window), [dirB])
assert.deepEqual(await getTreeViewRootDirectories(window0), [dirB])
await saveStatePromise
// Window state should be saved when the project folder is removed
const atomApplication2 = buildAtomApplication()
const [window2] = await atomApplication2.launch(parseCommandLine([]))
await emitterEventPromise(window2, 'window:locations-opened')
await focusWindow(window2)
await conditionPromise(async () => (await getTreeViewRootDirectories(window2)).length === 1)
assert.deepEqual(await getTreeViewRootDirectories(window2), [dirB])
})
})
@@ -562,11 +541,11 @@ describe('AtomApplication', function () {
let reached = await evalInWebContents(windows[0].browserWindow.webContents, sendBackToMainProcess => {
sendBackToMainProcess(global.reachedUrlMain)
})
assert.equal(reached, true);
windows[0].close();
assert.isTrue(reached)
windows[0].close()
})
it('triggers /core/open/file in the correct window', async function() {
it('triggers /core/open/file in the correct window', async function () {
const dirAPath = makeTempDir('a')
const dirBPath = makeTempDir('b')
@@ -594,12 +573,12 @@ describe('AtomApplication', function () {
})
it('waits until all the windows have saved their state before quitting', async () => {
const dirAPath = makeTempDir("a")
const dirBPath = makeTempDir("b")
const dirAPath = makeTempDir('a')
const dirBPath = makeTempDir('b')
const atomApplication = buildAtomApplication()
const [window1] = await atomApplication.launch(parseCommandLine([path.join(dirAPath, 'file-a')]))
const [window1] = await atomApplication.launch(parseCommandLine([dirAPath]))
await focusWindow(window1)
const [window2] = await atomApplication.launch(parseCommandLine([path.join(dirBPath, 'file-b')]))
const [window2] = await atomApplication.launch(parseCommandLine([dirBPath]))
await focusWindow(window2)
electron.app.quit()
await new Promise(process.nextTick)
@@ -662,7 +641,7 @@ describe('AtomApplication', function () {
function buildAtomApplication (params = {}) {
const atomApplication = new AtomApplication(Object.assign({
resourcePath: ATOM_RESOURCE_PATH,
atomHomeDirPath: process.env.ATOM_HOME,
atomHomeDirPath: process.env.ATOM_HOME
}, params))
atomApplicationsToDestroy.push(atomApplication)
return atomApplication
@@ -680,7 +659,7 @@ describe('AtomApplication', function () {
electron.app.quit = function () {
this.quit.callCount++
let defaultPrevented = false
this.emit('before-quit', {preventDefault() { defaultPrevented = true }})
this.emit('before-quit', {preventDefault () { defaultPrevented = true }})
if (!defaultPrevented) didQuit = true
}
@@ -710,12 +689,15 @@ describe('AtomApplication', function () {
resolve(result)
}
webContents.executeJavaScript(dedent`
const js = dedent`
function sendBackToMainProcess (result) {
require('electron').ipcRenderer.send('${channelId}', result)
}
(${source})(sendBackToMainProcess, ${args.map(JSON.stringify).join(', ')})
`)
`
// console.log(`about to execute:\n${js}`)
webContents.executeJavaScript(js)
})
}
@@ -728,6 +710,8 @@ describe('AtomApplication', function () {
.from(treeView.element.querySelectorAll('.project-root > .header .name'))
.map(element => element.dataset.path)
)
} else {
sendBackToMainProcess([])
}
})
})

View File

@@ -1,5 +1,6 @@
const TextEditor = require('../src/text-editor')
// Tests crash the renderer process on Electron 3.0, disabling for now.
describe('Selection', () => {
let buffer, editor, selection

View File

@@ -47,7 +47,6 @@ describe('StyleManager', () => {
atom-text-editor::shadow .class-1, atom-text-editor::shadow .class-2 { color: red }
atom-text-editor::shadow > .class-3 { color: yellow }
atom-text-editor .class-4 { color: blue }
another-element::shadow .class-5 { color: white }
atom-text-editor[data-grammar*=\"js\"]::shadow .class-6 { color: green; }
atom-text-editor[mini].is-focused::shadow .class-7 { color: green; }
`)
@@ -55,7 +54,6 @@ describe('StyleManager', () => {
'atom-text-editor.editor .class-1, atom-text-editor.editor .class-2',
'atom-text-editor.editor > .class-3',
'atom-text-editor .class-4',
'another-element::shadow .class-5',
'atom-text-editor[data-grammar*=\"js\"].editor .class-6',
'atom-text-editor[mini].is-focused.editor .class-7'
])
@@ -102,13 +100,6 @@ describe('StyleManager', () => {
])
})
it('does not transform CSS rules with invalid syntax', () => {
styleManager.addStyleSheet("atom-text-editor::shadow .class-1 { font-family: inval'id }")
expect(Array.from(styleManager.getStyleElements()[0].sheet.cssRules).map((r) => r.selectorText)).toEqual([
'atom-text-editor::shadow .class-1'
])
})
it('does not throw exceptions on rules with no selectors', () => {
styleManager.addStyleSheet('@media screen {font-size: 10px}', {context: 'atom-text-editor'})
})

View File

@@ -2638,7 +2638,71 @@ describe('TextEditorComponent', () => {
expect(editor.getCursorScreenPosition()).toEqual([0, 0])
})
function createBlockDecorationAtScreenRow(editor, screenRow, {height, margin, marginTop, marginBottom, position, invalidate}) {
it('uses the order property to control the order of block decorations at the same screen row', async () => {
const editor = buildEditor({autoHeight: false})
const {component, element} = buildComponent({editor})
element.style.height = 10 * component.getLineHeight() + horizontalScrollbarHeight + 'px'
await component.getNextUpdatePromise()
// Order parameters that differ from creation order; that collide; and that are not provided.
const [beforeItems, beforeDecorations] = [30, 20, undefined, 20, 10, undefined].map(order => {
return createBlockDecorationAtScreenRow(editor, 2, {height: 10, position: 'before', order})
}).reduce((lists, result) => {
lists[0].push(result.item)
lists[1].push(result.decoration)
return lists
}, [[], []])
const [afterItems, afterDecorations] = [undefined, 1, 6, undefined, 6, 2].map(order => {
return createBlockDecorationAtScreenRow(editor, 2, {height: 10, position: 'after', order})
}).reduce((lists, result) => {
lists[0].push(result.item)
lists[1].push(result.decoration)
return lists
}, [[], []])
await component.getNextUpdatePromise()
expect(beforeItems[4].previousSibling).toBe(lineNodeForScreenRow(component, 1))
expect(beforeItems[4].nextSibling).toBe(beforeItems[1])
expect(beforeItems[1].nextSibling).toBe(beforeItems[3])
expect(beforeItems[3].nextSibling).toBe(beforeItems[0])
expect(beforeItems[0].nextSibling).toBe(beforeItems[2])
expect(beforeItems[2].nextSibling).toBe(beforeItems[5])
expect(beforeItems[5].nextSibling).toBe(lineNodeForScreenRow(component, 2))
expect(afterItems[1].previousSibling).toBe(lineNodeForScreenRow(component, 2))
expect(afterItems[1].nextSibling).toBe(afterItems[5])
expect(afterItems[5].nextSibling).toBe(afterItems[2])
expect(afterItems[2].nextSibling).toBe(afterItems[4])
expect(afterItems[4].nextSibling).toBe(afterItems[0])
expect(afterItems[0].nextSibling).toBe(afterItems[3])
// Create a decoration somewhere else and move it to the same screen row as the existing decorations
const {item: later, decoration} = createBlockDecorationAtScreenRow(editor, 4, {height: 20, position: 'after', order: 3})
await component.getNextUpdatePromise()
expect(later.previousSibling).toBe(lineNodeForScreenRow(component, 4))
expect(later.nextSibling).toBe(lineNodeForScreenRow(component, 5))
decoration.getMarker().setHeadScreenPosition([2, 0])
await component.getNextUpdatePromise()
expect(later.previousSibling).toBe(afterItems[5])
expect(later.nextSibling).toBe(afterItems[2])
// Move a decoration away from its screen row and ensure the rest maintain their order
beforeDecorations[3].getMarker().setHeadScreenPosition([5, 0])
await component.getNextUpdatePromise()
expect(beforeItems[3].previousSibling).toBe(lineNodeForScreenRow(component, 4))
expect(beforeItems[3].nextSibling).toBe(lineNodeForScreenRow(component, 5))
expect(beforeItems[4].previousSibling).toBe(lineNodeForScreenRow(component, 1))
expect(beforeItems[4].nextSibling).toBe(beforeItems[1])
expect(beforeItems[1].nextSibling).toBe(beforeItems[0])
expect(beforeItems[0].nextSibling).toBe(beforeItems[2])
expect(beforeItems[2].nextSibling).toBe(beforeItems[5])
expect(beforeItems[5].nextSibling).toBe(lineNodeForScreenRow(component, 2))
});
function createBlockDecorationAtScreenRow(editor, screenRow, {height, margin, marginTop, marginBottom, position, order, invalidate}) {
const marker = editor.markScreenPosition([screenRow, 0], {invalidate: invalidate || 'never'})
const item = document.createElement('div')
item.style.height = height + 'px'
@@ -2646,7 +2710,7 @@ describe('TextEditorComponent', () => {
if (marginTop != null) item.style.marginTop = marginTop + 'px'
if (marginBottom != null) item.style.marginBottom = marginBottom + 'px'
item.style.width = 30 + 'px'
const decoration = editor.decorateMarker(marker, {type: 'block', item, position})
const decoration = editor.decorateMarker(marker, {type: 'block', item, position, order})
return {item, decoration, marker}
}

View File

@@ -6861,7 +6861,7 @@ describe('TextEditor', () => {
const marker = editor.markBufferRange([[2, 4], [6, 8]])
const decoration = editor.decorateMarker(marker, {type: 'highlight', class: 'foo'})
expect(editor.decorationsStateForScreenRowRange(0, 5)[decoration.id]).toEqual({
properties: {type: 'highlight', class: 'foo'},
properties: {id: decoration.id, order: Infinity, type: 'highlight', class: 'foo'},
screenRange: marker.getScreenRange(),
bufferRange: marker.getBufferRange(),
rangeIsReversed: false

View File

@@ -6,6 +6,7 @@ const _ = require('underscore-plus')
const dedent = require('dedent')
const {it, fit, ffit, fffit, beforeEach, afterEach} = require('./async-spec-helpers')
// Tests crash the renderer process on Electron 3.0, disabling for now.
describe('TextMateLanguageMode', () => {
let languageMode, buffer, config

View File

@@ -251,9 +251,9 @@ h2 {
it('returns a disposable allowing styles applied by the given path to be removed', function () {
const cssPath = require.resolve('./fixtures/css.css')
expect(getComputedStyle(document.body).fontWeight).not.toBe('bold')
expect(getComputedStyle(document.body).fontWeight).not.toBe('700')
const disposable = atom.themes.requireStylesheet(cssPath)
expect(getComputedStyle(document.body).fontWeight).toBe('bold')
expect(getComputedStyle(document.body).fontWeight).toBe('700')
let styleElementRemovedHandler
atom.styles.onDidRemoveStyleElement(styleElementRemovedHandler = jasmine.createSpy('styleElementRemovedHandler'))

View File

@@ -407,7 +407,7 @@ describe('TreeSitterLanguageMode', () => {
scopes: {
'identifier': 'variable',
'call_expression > identifier': 'function',
'new_expression > call_expression > identifier': 'constructor'
'new_expression > identifier': 'constructor'
}
})
@@ -1307,6 +1307,42 @@ describe('TreeSitterLanguageMode', () => {
`)
})
it('updates fold locations when the buffer changes', () => {
const grammar = new TreeSitterGrammar(atom.grammars, jsGrammarPath, {
parser: 'tree-sitter-javascript',
folds: [
{
start: {type: '{', index: 0},
end: {type: '}', index: -1}
}
]
})
buffer.setText(dedent `
class A {
// a
constructor (b) {
this.b = b
}
}
`)
const languageMode = new TreeSitterLanguageMode({buffer, grammar})
buffer.setLanguageMode(languageMode)
expect(languageMode.isFoldableAtRow(0)).toBe(true)
expect(languageMode.isFoldableAtRow(1)).toBe(false)
expect(languageMode.isFoldableAtRow(2)).toBe(true)
expect(languageMode.isFoldableAtRow(3)).toBe(false)
expect(languageMode.isFoldableAtRow(4)).toBe(false)
buffer.insert([0, 0], '\n')
expect(languageMode.isFoldableAtRow(0)).toBe(false)
expect(languageMode.isFoldableAtRow(1)).toBe(true)
expect(languageMode.isFoldableAtRow(2)).toBe(false)
expect(languageMode.isFoldableAtRow(3)).toBe(true)
expect(languageMode.isFoldableAtRow(4)).toBe(false)
})
describe('when folding a node that ends with a line break', () => {
it('ends the fold at the end of the previous line', async () => {
const grammar = new TreeSitterGrammar(atom.grammars, pythonGrammarPath, {

View File

@@ -2086,7 +2086,7 @@ describe('Workspace', () => {
})
runs(() => {
fs.rename(path.join(projectPath, 'git.git'), path.join(projectPath, '.git'))
fs.renameSync(path.join(projectPath, 'git.git'), path.join(projectPath, '.git'))
ignoredPath = path.join(projectPath, 'ignored.txt')
fs.writeFileSync(ignoredPath, 'this match should not be included')
})

View File

@@ -1,5 +1,6 @@
const crypto = require('crypto')
const path = require('path')
const util = require('util')
const {ipcRenderer} = require('electron')
const _ = require('underscore-plus')
@@ -44,6 +45,8 @@ const TextBuffer = require('text-buffer')
const TextEditorRegistry = require('./text-editor-registry')
const AutoUpdateManager = require('./auto-update-manager')
const stat = util.promisify(fs.stat)
let nextId = 0
// Essential: Atom global for dealing with packages, themes, menus, and the window.
@@ -1010,6 +1013,7 @@ class AtomEnvironment {
// window.alert('bummer')
// }
// })
// ```
//
// ```js
// // Legacy sync version
@@ -1358,42 +1362,71 @@ or use Pane::saveItemAs for programmatic saving.`)
async openLocations (locations) {
const needsProjectPaths = this.project && this.project.getPaths().length === 0
const foldersToAddToProject = []
const foldersToAddToProject = new Set()
const fileLocationsToOpen = []
const missingFolders = []
function pushFolderToOpen (folder) {
if (!foldersToAddToProject.includes(folder)) {
foldersToAddToProject.push(folder)
}
}
// Asynchronously fetch stat information about each requested path to open.
const locationStats = await Promise.all(
locations.map(async location => {
const stats = location.pathToOpen ? await stat(location.pathToOpen).catch(() => null) : null
return {location, stats}
}),
)
for (const location of locations) {
for (const {location, stats} of locationStats) {
const {pathToOpen} = location
if (pathToOpen && (needsProjectPaths || location.forceAddToWindow)) {
if (fs.existsSync(pathToOpen)) {
pushFolderToOpen(this.project.getDirectoryForProjectPath(pathToOpen).getPath())
} else if (fs.existsSync(path.dirname(pathToOpen))) {
pushFolderToOpen(this.project.getDirectoryForProjectPath(path.dirname(pathToOpen)).getPath())
} else {
pushFolderToOpen(this.project.getDirectoryForProjectPath(pathToOpen).getPath())
}
if (!pathToOpen) {
// Untitled buffer
fileLocationsToOpen.push(location)
continue
}
if (!fs.isDirectorySync(pathToOpen)) {
fileLocationsToOpen.push(location)
if (stats !== null) {
// Path exists
if (stats.isDirectory()) {
// Directory: add as a project folder
foldersToAddToProject.add(this.project.getDirectoryForProjectPath(pathToOpen).getPath())
} else if (stats.isFile()) {
if (location.mustBeDirectory) {
// File: no longer a directory
missingFolders.push(location)
} else {
// File: add as a file location
fileLocationsToOpen.push(location)
}
}
} else {
// Path does not exist
// Attempt to interpret as a URI from a non-default directory provider
const directory = this.project.getProvidedDirectoryForProjectPath(pathToOpen)
if (directory) {
// Found: add as a project folder
foldersToAddToProject.add(directory.getPath())
} else if (location.mustBeDirectory) {
// Not found and must be a directory: add to missing list and use to derive state key
missingFolders.push(location)
} else {
// Not found: open as a new file
fileLocationsToOpen.push(location)
}
}
if (location.hasWaitSession) this.pathsWithWaitSessions.add(pathToOpen)
}
let restoredState = false
if (foldersToAddToProject.length > 0) {
const state = await this.loadState(this.getStateKey(foldersToAddToProject))
if (foldersToAddToProject.size > 0 || missingFolders.length > 0) {
// Include missing folders in the state key so that sessions restored with no-longer-present project root folders
// don't lose data.
const foldersForStateKey = Array.from(foldersToAddToProject)
.concat(missingFolders.map(location => location.pathToOpen))
const state = await this.loadState(this.getStateKey(Array.from(foldersForStateKey)))
// only restore state if this is the first path added to the project
if (state && needsProjectPaths) {
const files = fileLocationsToOpen.map((location) => location.pathToOpen)
await this.attemptRestoreProjectStateForPaths(state, foldersToAddToProject, files)
await this.attemptRestoreProjectStateForPaths(state, Array.from(foldersToAddToProject), files)
restoredState = true
} else {
for (let folder of foldersToAddToProject) {
@@ -1410,6 +1443,33 @@ or use Pane::saveItemAs for programmatic saving.`)
await Promise.all(fileOpenPromises)
}
if (missingFolders.length > 0) {
let message = 'Unable to open project folder'
if (missingFolders.length > 1) {
message += 's'
}
let description = 'The '
if (missingFolders.length === 1) {
description += 'directory `'
description += missingFolders[0].pathToOpen
description += '` does not exist.'
} else if (missingFolders.length === 2) {
description += `directories \`${missingFolders[0].pathToOpen}\` `
description += `and \`${missingFolders[1].pathToOpen}\` do not exist.`
} else {
description += 'directories '
description += (missingFolders
.slice(0, -1)
.map(location => location.pathToOpen)
.map(pathToOpen => '`' + pathToOpen + '`, ')
.join(''))
description += 'and `' + missingFolders[missingFolders.length - 1].pathToOpen + '` do not exist.'
}
this.notifications.addWarning(message, {description})
}
ipcRenderer.send('window-command', 'window:locations-opened')
}

View File

@@ -177,7 +177,7 @@ exports.install = function (resourcesPath, nodeRequire) {
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1)
try {
var sourceMap = JSON.parse(new Buffer(rawData, 'base64'))
var sourceMap = JSON.parse(Buffer.from(rawData, 'base64'))
} catch (error) {
console.warn('Error parsing source map', error.stack)
return null

View File

@@ -3,12 +3,17 @@ const {Emitter} = require('event-kit')
let idCounter = 0
const nextId = () => idCounter++
// Applies changes to a decorationsParam {Object} to make it possible to
// differentiate decorations on custom gutters versus the line-number gutter.
const translateDecorationParamsOldToNew = function (decorationParams) {
if (decorationParams.type === 'line-number') {
const normalizeDecorationProperties = function (decoration, decorationParams) {
decorationParams.id = decoration.id
if (decorationParams.type === 'line-number' && decorationParams.gutterName == null) {
decorationParams.gutterName = 'line-number'
}
if (decorationParams.order == null) {
decorationParams.order = Infinity
}
return decorationParams
}
@@ -164,7 +169,7 @@ class Decoration {
setProperties (newProperties) {
if (this.destroyed) { return }
const oldProperties = this.properties
this.properties = translateDecorationParamsOldToNew(newProperties)
this.properties = normalizeDecorationProperties(this, newProperties)
if (newProperties.type != null) {
this.decorationManager.decorationDidChangeType(this)
}

View File

@@ -20,7 +20,7 @@ class FileSystemBlobStore {
reset () {
this.inMemoryBlobs = new Map()
this.storedBlob = new Buffer(0)
this.storedBlob = Buffer.alloc(0)
this.storedBlobMap = {}
this.usedKeys = new Set()
}

View File

@@ -187,6 +187,8 @@ class AtomApplication extends EventEmitter {
(options.urlsToOpen && options.urlsToOpen.length > 0)) {
optionsForWindowsToOpen.push(options)
shouldReopenPreviousWindows = this.config.get('core.restorePreviousWindowsOnStart') === 'always'
} else if (options.newWindow) {
shouldReopenPreviousWindows = false
} else {
shouldReopenPreviousWindows = this.config.get('core.restorePreviousWindowsOnStart') !== 'no'
}
@@ -206,9 +208,9 @@ class AtomApplication extends EventEmitter {
openWithOptions (options) {
const {
initialPaths,
pathsToOpen,
executedFrom,
foldersToOpen,
urlsToOpen,
benchmark,
benchmarkTest,
@@ -216,7 +218,6 @@ class AtomApplication extends EventEmitter {
pidToKillWhenClosed,
devMode,
safeMode,
newWindow,
logFile,
profileStartup,
timeout,
@@ -248,13 +249,12 @@ class AtomApplication extends EventEmitter {
timeout,
env
})
} else if (pathsToOpen.length > 0) {
} else if ((pathsToOpen && pathsToOpen.length > 0) || (foldersToOpen && foldersToOpen.length > 0)) {
return this.openPaths({
initialPaths,
pathsToOpen,
foldersToOpen,
executedFrom,
pidToKillWhenClosed,
newWindow,
devMode,
safeMode,
profileStartup,
@@ -267,9 +267,7 @@ class AtomApplication extends EventEmitter {
} else {
// Always open a editor window if this is the first instance of Atom.
return this.openPath({
initialPaths,
pidToKillWhenClosed,
newWindow,
devMode,
safeMode,
profileStartup,
@@ -576,7 +574,7 @@ class AtomApplication extends EventEmitter {
this.disposable.add(ipcHelpers.respondTo('set-user-settings', (window, settings, filePath) => {
if (!this.quitting) {
ConfigFile.at(filePath || this.configFilePath).update(JSON.parse(settings))
return ConfigFile.at(filePath || this.configFilePath).update(JSON.parse(settings))
}
}))
@@ -777,17 +775,14 @@ class AtomApplication extends EventEmitter {
// options -
// :pathToOpen - The file path to open
// :pidToKillWhenClosed - The integer of the pid to kill
// :newWindow - Boolean of whether this should be opened in a new window.
// :devMode - Boolean to control the opened window's dev mode.
// :safeMode - Boolean to control the opened window's safe mode.
// :profileStartup - Boolean to control creating a profile of the startup time.
// :window - {AtomWindow} to open file paths in.
// :addToLastWindow - Boolean of whether this should be opened in last focused window.
openPath ({
initialPaths,
pathToOpen,
pidToKillWhenClosed,
newWindow,
devMode,
safeMode,
profileStartup,
@@ -797,10 +792,8 @@ class AtomApplication extends EventEmitter {
env
} = {}) {
return this.openPaths({
initialPaths,
pathsToOpen: [pathToOpen],
pidToKillWhenClosed,
newWindow,
devMode,
safeMode,
profileStartup,
@@ -815,19 +808,18 @@ class AtomApplication extends EventEmitter {
//
// options -
// :pathsToOpen - The array of file paths to open
// :foldersToOpen - An array of additional paths to open that must be existing directories
// :pidToKillWhenClosed - The integer of the pid to kill
// :newWindow - Boolean of whether this should be opened in a new window.
// :devMode - Boolean to control the opened window's dev mode.
// :safeMode - Boolean to control the opened window's safe mode.
// :windowDimensions - Object with height and width keys.
// :window - {AtomWindow} to open file paths in.
// :addToLastWindow - Boolean of whether this should be opened in last focused window.
openPaths ({
initialPaths,
pathsToOpen,
foldersToOpen,
executedFrom,
pidToKillWhenClosed,
newWindow,
devMode,
safeMode,
windowDimensions,
@@ -837,32 +829,45 @@ class AtomApplication extends EventEmitter {
addToLastWindow,
env
} = {}) {
if (!pathsToOpen || pathsToOpen.length === 0) return
if (!env) env = process.env
if (!pathsToOpen) pathsToOpen = []
if (!foldersToOpen) foldersToOpen = []
devMode = Boolean(devMode)
safeMode = Boolean(safeMode)
clearWindowState = Boolean(clearWindowState)
const locationsToOpen = []
for (let i = 0; i < pathsToOpen.length; i++) {
const location = this.parsePathToOpen(pathsToOpen[i], executedFrom, addToLastWindow)
location.forceAddToWindow = addToLastWindow
location.hasWaitSession = pidToKillWhenClosed != null
locationsToOpen.push(location)
pathsToOpen[i] = location.pathToOpen
const locationsToOpen = pathsToOpen.map(pathToOpen => {
return this.parsePathToOpen(pathToOpen, executedFrom, {
forceAddToWindow: addToLastWindow,
hasWaitSession: pidToKillWhenClosed != null
})
})
for (const folderToOpen of foldersToOpen) {
locationsToOpen.push({
pathToOpen: folderToOpen,
initialLine: null,
initialColumn: null,
mustBeDirectory: true,
forceAddToWindow: addToLastWindow,
hasWaitSession: pidToKillWhenClosed != null
})
}
if (locationsToOpen.length === 0) {
return
}
const normalizedPathsToOpen = locationsToOpen.map(location => location.pathToOpen).filter(Boolean)
let existingWindow
if (!newWindow) {
existingWindow = this.windowForPaths(pathsToOpen, devMode)
if (addToLastWindow && normalizedPathsToOpen.length > 0) {
existingWindow = this.windowForPaths(normalizedPathsToOpen, devMode)
if (!existingWindow) {
let lastWindow = window || this.getLastFocusedWindow()
if (lastWindow && lastWindow.devMode === devMode) {
if (addToLastWindow || (
locationsToOpen.every(({stat}) => stat && stat.isFile()) ||
(locationsToOpen.some(({stat}) => stat && stat.isDirectory()) && !lastWindow.hasProjectPath()))) {
existingWindow = lastWindow
}
existingWindow = lastWindow
}
}
}
@@ -895,7 +900,6 @@ class AtomApplication extends EventEmitter {
if (!windowDimensions) windowDimensions = this.getDimensionsForNewWindow()
openedWindow = new AtomWindow(this, this.fileRecoveryService, {
initialPaths,
locationsToOpen,
windowInitializationScript,
resourcePath,
@@ -916,7 +920,7 @@ class AtomApplication extends EventEmitter {
}
this.waitSessionsByWindow.get(openedWindow).push({
pid: pidToKillWhenClosed,
remainingPaths: new Set(pathsToOpen)
remainingPaths: new Set(normalizedPathsToOpen)
})
}
@@ -984,8 +988,7 @@ class AtomApplication extends EventEmitter {
const states = await this.storageFolder.load('application.json')
if (states) {
return states.map(state => ({
initialPaths: state.initialPaths,
pathsToOpen: state.initialPaths.filter(p => fs.isDirectorySync(p)),
foldersToOpen: state.initialPaths,
urlsToOpen: [],
devMode: this.devMode,
safeMode: this.safeMode
@@ -1264,7 +1267,7 @@ class AtomApplication extends EventEmitter {
}
}
parsePathToOpen (pathToOpen, executedFrom = '') {
parsePathToOpen (pathToOpen, executedFrom, extra) {
let initialColumn, initialLine
if (!pathToOpen) {
return {pathToOpen}
@@ -1286,10 +1289,9 @@ class AtomApplication extends EventEmitter {
}
const normalizedPath = path.normalize(path.resolve(executedFrom, fs.normalize(pathToOpen)))
const stat = fs.statSyncNoException(normalizedPath)
if (stat || !url.parse(pathToOpen).protocol) pathToOpen = normalizedPath
if (!url.parse(pathToOpen).protocol) pathToOpen = normalizedPath
return {pathToOpen, stat, initialLine, initialColumn}
return Object.assign({pathToOpen, initialLine, initialColumn}, extra)
}
// Opens a native dialog to prompt the user for a path.

View File

@@ -23,9 +23,7 @@ class AtomWindow extends EventEmitter {
this.devMode = settings.devMode
this.resourcePath = settings.resourcePath
let {pathToOpen, locationsToOpen} = settings
if (!locationsToOpen && pathToOpen) locationsToOpen = [{pathToOpen}]
if (!locationsToOpen) locationsToOpen = []
const locationsToOpen = settings.locationsToOpen || []
this.loadedPromise = new Promise(resolve => { this.resolveLoadedPromise = resolve })
this.closedPromise = new Promise(resolve => { this.resolveClosedPromise = resolve })
@@ -73,23 +71,7 @@ class AtomWindow extends EventEmitter {
if (this.loadSettings.safeMode == null) this.loadSettings.safeMode = false
if (this.loadSettings.clearWindowState == null) this.loadSettings.clearWindowState = false
if (!this.loadSettings.initialPaths) {
this.loadSettings.initialPaths = []
for (const {pathToOpen, stat} of locationsToOpen) {
if (!pathToOpen) continue
if (stat && stat.isDirectory()) {
this.loadSettings.initialPaths.push(pathToOpen)
} else {
const parentDirectory = path.dirname(pathToOpen)
if (stat && stat.isFile() || fs.existsSync(parentDirectory)) {
this.loadSettings.initialPaths.push(parentDirectory)
} else {
this.loadSettings.initialPaths.push(pathToOpen)
}
}
}
}
this.loadSettings.initialPaths = locationsToOpen.map(location => location.pathToOpen).filter(Boolean)
this.loadSettings.initialPaths.sort()
// Only send to the first non-spec window created

View File

@@ -39,7 +39,7 @@ class AutoUpdater extends EventEmitter {
}
supportsUpdates () {
SquirrelUpdate.existsSync()
return SquirrelUpdate.existsSync()
}
checkForUpdates () {

View File

@@ -11,16 +11,20 @@ module.exports = function parseCommandLine (processArgs) {
dedent`Atom Editor v${version}
Usage:
atom
atom [options] [path ...]
atom file[:line[:column]]
One or more paths to files or folders may be specified. If there is an
existing Atom window that contains all of the given folders, the paths
will be opened in that window. Otherwise, they will be opened in a new
window.
If no arguments are given and no Atom windows are already open, restore all windows
from the previous editing session. Use "atom --new-window" to open a single empty
Atom window instead.
A file may be opened at the desired line (and optionally column) by
appending the numbers right after the file name, e.g. \`atom file:5:8\`.
If no arguments are given and at least one Atom window is open, open a new, empty
Atom window.
One or more paths to files or folders may be specified. All paths will be opened
in a new Atom window. Each file may be opened at the desired line (and optionally
column) by appending the numbers after the file name, e.g. \`atom file:5:8\`.
Paths that start with \`atom://\` will be interpreted as URLs.
@@ -39,7 +43,7 @@ module.exports = function parseCommandLine (processArgs) {
options.alias('f', 'foreground').boolean('f').describe('f', 'Keep the main process in the foreground.')
options.alias('h', 'help').boolean('h').describe('h', 'Print this usage message.')
options.alias('l', 'log-file').string('l').describe('l', 'Log all output to file.')
options.alias('n', 'new-window').boolean('n').describe('n', 'Open a new window.')
options.alias('n', 'new-window').boolean('n').describe('n', 'Launch an empty Atom window instead of restoring previous session.')
options.boolean('profile-startup').describe('profile-startup', 'Create a profile of the startup execution time.')
options.alias('r', 'resource-path').string('r').describe('r', 'Set the path to the Atom source directory and enable dev-mode.')
options.boolean('safe').describe(

View File

@@ -1,7 +1,7 @@
const Module = require('module')
const path = require('path')
const cachedVm = require('cached-run-in-this-context')
const crypto = require('crypto')
const vm = require('vm')
function computeHash (contents) {
return crypto.createHash('sha1').update(contents, 'utf8').digest('hex')
@@ -34,6 +34,24 @@ class NativeCompileCache {
this.previousModuleCompile = Module.prototype._compile
}
runInThisContext (code, filename) {
// produceCachedData is deprecated after Node 10.6, will need to update
// this for Electron 4.0 to use script.createCachedData()
const script = new vm.Script(code, {filename, produceCachedData: true})
return {
result: script.runInThisContext(),
cacheBuffer: script.cachedData
}
}
runInThisContextCached (code, filename, cachedData) {
const script = new vm.Script(code, {filename, cachedData})
return {
result: script.runInThisContext(),
wasRejected: script.cachedDataRejected
}
}
overrideModuleCompile () {
let self = this
// Here we override Node's module.js
@@ -64,7 +82,7 @@ class NativeCompileCache {
let compiledWrapper = null
if (self.cacheStore.has(cacheKey)) {
let buffer = self.cacheStore.get(cacheKey)
let compilationResult = cachedVm.runInThisContextCached(wrapper, filename, buffer)
let compilationResult = self.runInThisContextCached(wrapper, filename, buffer)
compiledWrapper = compilationResult.result
if (compilationResult.wasRejected) {
self.cacheStore.delete(cacheKey)
@@ -72,12 +90,12 @@ class NativeCompileCache {
} else {
let compilationResult
try {
compilationResult = cachedVm.runInThisContext(wrapper, filename)
compilationResult = self.runInThisContext(wrapper, filename)
} catch (err) {
console.error(`Error running script ${filename}`)
throw err
}
if (compilationResult.cacheBuffer) {
if (compilationResult.cacheBuffer !== null) {
self.cacheStore.set(cacheKey, compilationResult.cacheBuffer)
}
compiledWrapper = compilationResult.result

View File

@@ -282,7 +282,7 @@ class PaneContainer {
this.cancelStoppedChangingActivePaneItemTimeout()
// `setTimeout()` isn't available during the snapshotting phase, but that's okay.
if (typeof setTimeout === 'function') {
if (!global.isGeneratingSnapshot) {
this.stoppedChangingActivePaneItemTimeout = setTimeout(() => {
this.stoppedChangingActivePaneItemTimeout = null
this.emitter.emit('did-stop-changing-active-pane-item', activeItem)

View File

@@ -204,11 +204,11 @@ class Project extends Model {
// // absolute path to the filesystem entry that was touched
// console.log(`Event path: ${event.path}`)
//
// if (event.type === 'renamed') {
// if (event.action === 'renamed') {
// console.log(`.. renamed from: ${event.oldPath}`)
// }
// }
// }
// })
//
// disposable.dispose()
// ```
@@ -441,14 +441,20 @@ class Project extends Model {
}
}
getDirectoryForProjectPath (projectPath) {
let directory = null
getProvidedDirectoryForProjectPath (projectPath) {
for (let provider of this.directoryProviders) {
if (typeof provider.directoryForURISync === 'function') {
directory = provider.directoryForURISync(projectPath)
if (directory) break
const directory = provider.directoryForURISync(projectPath)
if (directory) {
return directory
}
}
}
return null
}
getDirectoryForProjectPath (projectPath) {
let directory = this.getProvidedDirectoryForProjectPath(projectPath)
if (directory == null) {
directory = this.defaultDirectoryProvider.directoryForURISync(projectPath)
}

View File

@@ -84,17 +84,17 @@ class Task
# Routes messages from the child to the appropriate event.
handleEvents: ->
@childProcess.removeAllListeners()
@childProcess.removeAllListeners('message')
@childProcess.on 'message', ({event, args}) =>
@emitter.emit(event, args) if @childProcess?
# Catch the errors that happened before task-bootstrap.
if @childProcess.stdout?
@childProcess.stdout.removeAllListeners()
@childProcess.stdout.removeAllListeners('data')
@childProcess.stdout.on 'data', (data) -> console.log data.toString()
if @childProcess.stderr?
@childProcess.stderr.removeAllListeners()
@childProcess.stderr.removeAllListeners('data')
@childProcess.stderr.on 'data', (data) -> console.error data.toString()
# Public: Starts the task.
@@ -147,9 +147,9 @@ class Task
terminate: ->
return false unless @childProcess?
@childProcess.removeAllListeners()
@childProcess.stdout?.removeAllListeners()
@childProcess.stderr?.removeAllListeners()
@childProcess.removeAllListeners('message')
@childProcess.stdout?.removeAllListeners('data')
@childProcess.stderr?.removeAllListeners('data')
@childProcess.kill()
@childProcess = null

View File

@@ -1191,6 +1191,10 @@ class TextEditorComponent {
decorationsByScreenLine.set(screenLine.id, decorations)
}
decorations.push(decoration)
// Order block decorations by increasing values of their "order" property. Break ties with "id", which mirrors
// their creation sequence.
decorations.sort((a, b) => a.order !== b.order ? a.order - b.order : a.id - b.id)
}
addTextDecorationToRender (decoration, screenRange, marker) {
@@ -3862,15 +3866,24 @@ class LinesTileComponent {
if (blockDecorations) {
blockDecorations.forEach((newDecorations, screenLineId) => {
var oldDecorations = oldProps.blockDecorations ? oldProps.blockDecorations.get(screenLineId) : null
for (var i = 0; i < newDecorations.length; i++) {
var newDecoration = newDecorations[i]
if (oldDecorations && oldDecorations.includes(newDecoration)) continue
const oldDecorations = oldProps.blockDecorations ? oldProps.blockDecorations.get(screenLineId) : null
const lineNode = lineComponentsByScreenLineId.get(screenLineId).element
let lastAfter = lineNode
for (let i = 0; i < newDecorations.length; i++) {
const newDecoration = newDecorations[i]
const element = TextEditor.viewForItem(newDecoration.item)
if (oldDecorations && oldDecorations.includes(newDecoration)) {
if (newDecoration.position === 'after') {
lastAfter = element
}
continue
}
var element = TextEditor.viewForItem(newDecoration.item)
var lineNode = lineComponentsByScreenLineId.get(screenLineId).element
if (newDecoration.position === 'after') {
this.element.insertBefore(element, lineNode.nextSibling)
this.element.insertBefore(element, lastAfter.nextSibling)
lastAfter = element
} else {
this.element.insertBefore(element, lineNode)
}
@@ -4433,7 +4446,7 @@ class NodePool {
if (element) {
element.className = className || ''
element.styleMap.forEach((value, key) => {
element.attributeStyleMap.forEach((value, key) => {
if (!style || style[key] == null) element.style[key] = ''
})
if (style) Object.assign(element.style, style)

View File

@@ -959,9 +959,6 @@ class TextEditor {
return this.decorationManager.onDidUpdateDecorations(callback)
}
// Essential: Retrieves the current {TextBuffer}.
getBuffer () { return this.buffer }
// Retrieves the current buffer's URI.
getURI () { return this.buffer.getUri() }
@@ -1076,6 +1073,15 @@ class TextEditor {
}
}
/*
Section: Buffer
*/
// Essential: Retrieves the current {TextBuffer}.
getBuffer () {
return this.buffer
}
/*
Section: File Details
*/
@@ -2215,14 +2221,17 @@ class TextEditor {
//
// The following are the supported decorations types:
//
// * __line__: Adds your CSS `class` to the line nodes within the range
// marked by the marker
// * __line-number__: Adds your CSS `class` to the line number nodes within the
// range marked by the marker
// * __highlight__: Adds a new highlight div to the editor surrounding the
// range marked by the marker. When the user selects text, the selection is
// visualized with a highlight decoration internally. The structure of this
// highlight will be
// * __line__: Adds the given CSS `class` to the lines overlapping the rows
// spanned by the marker.
// * __line-number__: Adds the given CSS `class` to the line numbers overlapping
// the rows spanned by the marker
// * __text__: Injects spans into all text overlapping the marked range, then adds
// the given `class` or `style` to these spans. Use this to manipulate the foreground
// color or styling of text in a range.
// * __highlight__: Creates an absolutely-positioned `.highlight` div to the editor
// containing nested divs that cover the marked region. For example, when the user
// selects text, the selection is implemented with a highlight decoration. The structure
// of this highlight will be:
// ```html
// <div class="highlight <your-class>">
// <!-- Will be one region for each row in the range. Spans 2 lines? There will be 2 regions. -->
@@ -2230,45 +2239,25 @@ class TextEditor {
// </div>
// ```
// * __overlay__: Positions the view associated with the given item at the head
// or tail of the given `DisplayMarker`.
// * __gutter__: A decoration that tracks a {DisplayMarker} in a {Gutter}. Gutter
// decorations are created by calling {Gutter::decorateMarker} on the
// desired `Gutter` instance.
// or tail of the given `DisplayMarker`, depending on the `position` property.
// * __gutter__: Tracks a {DisplayMarker} in a {Gutter}. Gutter decorations are created
// by calling {Gutter::decorateMarker} on the desired `Gutter` instance.
// * __block__: Positions the view associated with the given item before or
// after the row of the given `TextEditorMarker`.
// after the row of the given {DisplayMarker}, depending on the `position` property.
// Block decorations at the same screen row are ordered by their `order` property.
// * __cursor__: Render a cursor at the head of the {DisplayMarker}. If multiple cursor decorations
// are created for the same marker, their class strings and style objects are combined
// into a single cursor. This decoration type may be used to style existing cursors
// by passing in their markers or to render artificial cursors that don't actaully
// exist in the model by passing a marker that isn't associated with a real cursor.
//
// ## Arguments
//
// * `marker` A {DisplayMarker} you want this decoration to follow.
// * `decorationParams` An {Object} representing the decoration e.g.
// `{type: 'line-number', class: 'linter-error'}`
// * `type` There are several supported decoration types. The behavior of the
// types are as follows:
// * `line` Adds the given `class` to the lines overlapping the rows
// spanned by the `DisplayMarker`.
// * `line-number` Adds the given `class` to the line numbers overlapping
// the rows spanned by the `DisplayMarker`.
// * `text` Injects spans into all text overlapping the marked range,
// then adds the given `class` or `style` properties to these spans.
// Use this to manipulate the foreground color or styling of text in
// a given range.
// * `highlight` Creates an absolutely-positioned `.highlight` div
// containing nested divs to cover the marked region. For example, this
// is used to implement selections.
// * `overlay` Positions the view associated with the given item at the
// head or tail of the given `DisplayMarker`, depending on the `position`
// property.
// * `gutter` Tracks a {DisplayMarker} in a {Gutter}. Created by calling
// {Gutter::decorateMarker} on the desired `Gutter` instance.
// * `block` Positions the view associated with the given item before or
// after the row of the given `TextEditorMarker`, depending on the `position`
// property.
// * `cursor` Renders a cursor at the head of the given marker. If multiple
// decorations are created for the same marker, their class strings and
// style objects are combined into a single cursor. You can use this
// decoration type to style existing cursors by passing in their markers
// or render artificial cursors that don't actually exist in the model
// by passing a marker that isn't actually associated with a cursor.
// * `type` Determines the behavior and appearance of this {Decoration}. Supported decoration types
// and their uses are listed above.
// * `class` This CSS class will be applied to the decorated line number,
// line, text spans, highlight regions, cursors, or overlay.
// * `style` An {Object} containing CSS style properties to apply to the
@@ -2294,12 +2283,15 @@ class TextEditor {
// Controls where the view is positioned relative to the `TextEditorMarker`.
// Values can be `'head'` (the default) or `'tail'` for overlay decorations, and
// `'before'` (the default) or `'after'` for block decorations.
// * `order` (optional) Only applicable to decorations of type `block`. Controls
// where the view is positioned relative to other block decorations at the
// same screen row. If unspecified, block decorations render oldest to newest.
// * `avoidOverflow` (optional) Only applicable to decorations of type
// `overlay`. Determines whether the decoration adjusts its horizontal or
// vertical position to remain fully visible when it would otherwise
// overflow the editor. Defaults to `true`.
//
// Returns a {Decoration} object
// Returns the created {Decoration} object.
decorateMarker (marker, decorationParams) {
return this.decorationManager.decorateMarker(marker, decorationParams)
}

View File

@@ -10,7 +10,7 @@ let Tooltip = null
//
// The essence of displaying a tooltip
//
// ```javascript
// ```js
// // display it
// const disposable = atom.tooltips.add(div, {title: 'This is a tooltip'})
//
@@ -21,7 +21,7 @@ let Tooltip = null
// In practice there are usually multiple tooltips. So we add them to a
// CompositeDisposable
//
// ```javascript
// ```js
// const {CompositeDisposable} = require('atom')
// const subscriptions = new CompositeDisposable()
//
@@ -37,7 +37,7 @@ let Tooltip = null
// You can display a key binding in the tooltip as well with the
// `keyBindingCommand` option.
//
// ```javascript
// ```js
// disposable = atom.tooltips.add(this.caseOptionButton, {
// title: 'Match Case',
// keyBindingCommand: 'find-and-replace:toggle-case-option',

View File

@@ -94,7 +94,7 @@ class TreeSitterLanguageMode {
}
}
bufferDidFinishTransaction (changes) {
bufferDidFinishTransaction ({changes}) {
for (let i = 0, {length} = changes; i < length; i++) {
const {oldRange, newRange} = changes[i]
spliceArray(

13
static/atom-ui/README.md Normal file
View File

@@ -0,0 +1,13 @@
# :sparkles: Atom UI :sparkles:
This is Atom's UI library. Originally forked from Bootstrap `3.3.6`, then merged with some core styles and now tweaked to Atom's needy needs.
## Components
Here a list of [all components](atom-ui.less). Open the [Styleguide](https://github.com/atom/styleguide) package (`cmd-ctrl-shift-g`) to see them in action and how to use them.
![Styleguide](https://cloud.githubusercontent.com/assets/378023/15767543/ccecf9bc-2983-11e6-9c5e-d228d39f52b0.png)
## Feature requests
If you need something, feel free to open an issue and it might can be added. :v:

View File

@@ -0,0 +1,35 @@
// Atom UI
// Private! Don't use these in packages.
// If you need something, feel free to open an issue and it might can be made public
@import "styles/private/scaffolding.less";
@import "styles/private/alerts.less";
@import "styles/private/close.less";
@import "styles/private/code.less";
@import "styles/private/forms.less";
@import "styles/private/links.less";
@import "styles/private/navs.less";
@import "styles/private/sections.less";
@import "styles/private/tables.less";
@import "styles/private/utilities.less";
// Public components
// Open the Styleguide to see them in action
@import "styles/badges.less";
@import "styles/button-groups.less";
@import "styles/buttons.less";
@import "styles/git-status.less";
@import "styles/icons.less";
@import "styles/inputs.less";
@import "styles/layout.less";
@import "styles/lists.less";
@import "styles/loading.less";
@import "styles/messages.less";
@import "styles/modals.less";
@import "styles/panels.less";
@import "styles/select-list.less";
@import "styles/site-colors.less";
@import "styles/text.less";
@import "styles/tooltip.less";

View File

@@ -0,0 +1,64 @@
@import "ui-variables";
.badge {
display: inline-block;
line-height: 1;
vertical-align: middle;
font-weight: normal;
text-align: center;
white-space: nowrap;
border-radius: 1em;
&:empty {
display: none; // Hide when un-used
}
// Color ----------------------
.badge-color( @fg: @text-color-selected; @bg: @background-color-selected; ) {
color: @fg;
background-color: @bg;
}
.badge-color();
&.badge-info { .badge-color(white, @background-color-info); }
&.badge-success { .badge-color(white, @background-color-success); }
&.badge-warning { .badge-color(white, @background-color-warning); }
&.badge-error { .badge-color(white, @background-color-error); }
// Size ----------------------
.badge-size( @size: @font-size; ) {
@padding: round(@size/4);
font-size: @size;
min-width: @size + @padding*2;
padding: @padding round(@padding*1.5);
}
.badge-size(); // default
// Fixed size
&.badge-large { .badge-size(18px); }
&.badge-medium { .badge-size(14px); }
&.badge-small { .badge-size(10px); }
// Flexible size
// The size changes depending on the parent element
// Best used for larger sizes, since em's can cause rounding errors
&.badge-flexible {
@size: .8em;
@padding: @size/2;
font-size: @size;
min-width: @size + @padding*2;
padding: @padding @padding*1.5;
}
// Icon ----------------------
&.icon {
font-size: round(@component-icon-size*0.8);
padding: @component-icon-padding @component-icon-padding*2;
}
}

View File

@@ -0,0 +1,187 @@
@import "variables/variables";
@import "ui-variables";
@import "mixins/mixins";
//
// Button groups
// --------------------------------------------------
// Make the div behave like a button
.btn-group,
.btn-group-vertical {
position: relative;
display: inline-block;
vertical-align: middle; // match .btn alignment given font-size hack above
> .btn {
position: relative;
float: left;
// Bring the "active" button to the front
&:hover,
&:focus,
&:active,
&.active {
z-index: 2;
}
}
}
// Borders
// ---------------------------------------------------------
.btn-group > .btn {
border-left: 1px solid @button-border-color;
border-right: 1px solid @button-border-color;
}
.btn-group > .btn:first-child {
border-left: none;
border-top-left-radius: @component-border-radius;
border-bottom-left-radius: @component-border-radius;
}
.btn-group > .btn:last-child,
.btn-group > .btn.selected:last-child,
.btn-group > .dropdown-toggle {
border-right: none;
border-top-right-radius: @component-border-radius;
border-bottom-right-radius: @component-border-radius;
}
// Prevent double borders when buttons are next to each other
.btn-group {
.btn + .btn,
.btn + .btn-group,
.btn-group + .btn,
.btn-group + .btn-group {
margin-left: -1px;
}
}
// Optional: Group multiple button groups together for a toolbar
.btn-toolbar {
margin-left: -5px; // Offset the first child's margin
&:extend(.clearfix all);
.btn,
.btn-group,
.input-group {
float: left;
}
> .btn,
> .btn-group,
> .input-group {
margin-left: 5px;
}
}
.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
border-radius: 0;
}
// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match
.btn-group > .btn:first-child {
margin-left: 0;
&:not(:last-child):not(.dropdown-toggle) {
.border-right-radius(0);
}
}
// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it
.btn-group > .btn:last-child:not(:first-child),
.btn-group > .dropdown-toggle:not(:first-child) {
.border-left-radius(0);
}
// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)
.btn-group > .btn-group {
float: left;
}
.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
border-radius: 0;
}
.btn-group > .btn-group:first-child:not(:last-child) {
> .btn:last-child,
> .dropdown-toggle {
.border-right-radius(0);
}
}
.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
.border-left-radius(0);
}
// On active and open, don't show outline
.btn-group .dropdown-toggle:active,
.btn-group.open .dropdown-toggle {
outline: 0;
}
// Sizing
//
// Remix the default button sizing classes into new ones for easier manipulation.
.btn-group-xs > .btn { &:extend(.btn-xs); }
.btn-group-sm > .btn { &:extend(.btn-sm); }
.btn-group-lg > .btn { &:extend(.btn-lg); }
// Split button dropdowns
// ----------------------
// Give the line between buttons some depth
.btn-group > .btn + .dropdown-toggle {
padding-left: 8px;
padding-right: 8px;
}
.btn-group > .btn-lg + .dropdown-toggle {
padding-left: 12px;
padding-right: 12px;
}
// The clickable button for toggling the menu
// Remove the gradient and set the same inset shadow as the :active state
.btn-group.open .dropdown-toggle {
box-shadow: inset 0 3px 5px rgba(0,0,0,.125);
// Show no shadow for `.btn-link` since it has no other button styles.
&.btn-link {
box-shadow: none;
}
}
// Reposition the caret
.btn .caret {
margin-left: 0;
}
// Carets in other button sizes
.btn-lg .caret {
border-width: @caret-width-large @caret-width-large 0;
border-bottom-width: 0;
}
// Upside down carets for .dropup
.dropup .btn-lg .caret {
border-width: 0 @caret-width-large @caret-width-large;
}
// Justified button groups
// ----------------------
.btn-group-justified {
display: table;
width: 100%;
table-layout: fixed;
border-collapse: separate;
> .btn,
> .btn-group {
float: none;
display: table-cell;
width: 1%;
}
> .btn-group .btn {
width: 100%;
}
> .btn-group .dropdown-menu {
left: auto;
}
}

View File

@@ -0,0 +1,274 @@
@import "variables/variables";
@import "ui-variables";
@import "mixins/mixins";
//
// Buttons
// --------------------------------------------------
// Base styles
// --------------------------------------------------
.btn {
display: inline-block;
margin-bottom: 0; // For input.btn
height: @component-line-height + 2px;
padding: 0 @component-padding;
font-size: @font-size;
font-weight: normal;
line-height: @component-line-height;
text-align: center;
vertical-align: middle;
border: none;
border-radius: @component-border-radius;
background-color: @btn-default-bg;
white-space: nowrap;
cursor: pointer;
z-index: 0;
-webkit-user-select: none;
&,
&:active,
&.active {
&:focus,
&.focus {
.tab-focus();
}
}
&:hover,
&:focus,
&.focus {
color: @btn-default-color;
text-decoration: none;
background-color: @button-background-color-hover;
}
&:active,
&.active {
outline: 0;
background-image: none;
box-shadow: inset 0 3px 5px rgba(0,0,0,.125);
}
&.selected,
&.selected:hover {
// we want the selected button to behave like the :hover button; it's on top of the other buttons.
z-index: 1;
color: @text-color-selected;
background-color: @button-background-color-selected;
}
&.disabled,
&[disabled],
fieldset[disabled] & {
cursor: @cursor-disabled;
opacity: .65;
box-shadow: none;
}
a& {
&.disabled,
fieldset[disabled] & {
pointer-events: none; // Future-proof disabling of clicks on `<a>` elements
}
}
}
// Button variants
// --------------------------------------------------
.button-variant(@color; @background;) {
color: @color;
background-color: @background;
&:focus,
&.focus {
color: @color;
background-color: darken(@background, 10%);
}
&:hover {
color: @color;
background-color: darken(@background, 10%);
}
&:active,
&.active {
color: @color;
background-color: darken(@background, 10%);
&:hover,
&:focus,
&.focus {
color: @color;
background-color: darken(@background, 17%);
}
}
&.selected,
&.selected:hover {
// we want the selected button to behave like the :hover button; it's on top of the other buttons.
z-index: 1;
background-color: darken(@background, 10%);
}
&.disabled,
&[disabled],
fieldset[disabled] & {
&:hover,
&:focus,
&.focus {
background-color: @background;
}
}
.badge {
color: @background;
background-color: @color;
}
}
.btn-primary {
.button-variant(@btn-primary-color; @btn-primary-bg;);
}
// Success appears as green
.btn-success {
.button-variant(@btn-success-color; @btn-success-bg;);
}
// Info appears as blue-green
.btn-info {
.button-variant(@btn-info-color; @btn-info-bg;);
}
// Warning appears as orange
.btn-warning {
.button-variant(@btn-warning-color; @btn-warning-bg;);
}
// Danger and error appear as red
.btn-error {
.button-variant(@btn-error-color; @btn-error-bg;);
}
// Button Sizes
// --------------------------------------------------
.btn-xs,
.btn-group-xs > .btn {
padding: @component-padding/4 @component-padding/2;
font-size: @font-size - 2px;
height: auto;
line-height: 1.3em;
&.icon:before {
font-size: @font-size - 2px;
}
}
.btn-sm,
.btn-group-sm > .btn {
padding: @component-padding/4 @component-padding/2;
height: auto;
line-height: 1.3em;
&.icon:before {
font-size: @font-size + 1px;
}
}
.btn-lg,
.btn-group-lg > .btn {
font-size: @font-size + 2px;
padding: @component-padding - 2px @component-padding + 2px;
height: auto;
line-height: 1.3em;
&.icon:before {
font-size: @font-size + 6px;
}
}
// Link button
// -------------------------
// Make a button look and behave like a link
.btn-link {
color: @link-color;
font-weight: normal;
border-radius: 0;
&,
&:active,
&.active,
&[disabled],
fieldset[disabled] & {
background-color: transparent;
box-shadow: none;
}
&:hover,
&:focus {
color: @link-hover-color;
text-decoration: @link-hover-decoration;
background-color: transparent;
}
&[disabled],
fieldset[disabled] & {
&:hover,
&:focus {
color: @btn-link-disabled-color;
text-decoration: none;
}
}
}
// Block button
// --------------------------------------------------
.btn-block {
display: block;
width: 100%;
}
// Vertically space out multiple block buttons
.btn-block + .btn-block {
margin-top: 5px;
}
// Specificity overrides
input[type="submit"],
input[type="reset"],
input[type="button"] {
&.btn-block {
width: 100%;
}
}
// Icon buttons
// --------------------------------------------------
.btn.icon {
&:before {
width: initial;
height: initial;
margin-right: .3125em;
}
&:empty:before {
margin-right: 0;
}
}
// Button Toolbar
// --------------------------------------------------
.btn-toolbar {
> .btn-group + .btn-group,
> .btn-group + .btn,
> .btn + .btn {
float: none;
display: inline-block;
margin-left: 0;
}
> * {
margin-right: @component-padding / 2;
}
> *:last-child {
margin-right: 0;
}
}

View File

@@ -0,0 +1,13 @@
@import "ui-variables";
//
// Git Status
// --------------------------------------------------
.status {
&-ignored { color: @text-color-subtle; }
&-added { color: @text-color-success; }
&-modified { color: @text-color-warning; }
&-removed { color: @text-color-error; }
&-renamed { color: @text-color-info; }
}

View File

@@ -0,0 +1,13 @@
@import "ui-variables";
.icon::before {
margin-right: @component-icon-padding;
}
a.icon {
text-decoration: none;
color: @text-color;
&:hover{
color: @text-color-highlight;
}
}

View File

@@ -0,0 +1,383 @@
@import "./variables/ui-variables"; // Fallback for @use-custom-controls
@import "ui-variables";
@component-size: @component-icon-size; // use for text-less controls like radio, checkboxes etc.
@component-margin-side: .3em;
@text-component-height: 2em;
@component-background-color: mix(@text-color, @base-background-color, 20%);
//
// Overrides
// -------------------------
input.input-radio,
input.input-checkbox,
input.input-toggle {
margin-top: 0; // Override Bootstrap's 4px
}
.input-label {
margin-bottom: 0;
}
//
// Mixins
// -------------------------
.input-field-mixin() {
padding: .25em .4em;
line-height: 1.5; // line-height + padding = @text-component-height
border-radius: @component-border-radius;
border: 1px solid @input-border-color;
background-color: @input-background-color;
&::-webkit-input-placeholder {
color: @text-color-subtle;
}
&:invalid {
color: @text-color-error;
border-color: @background-color-error;
}
}
.input-block-mixin() {
display: block;
width: 100%;
}
//
// Checkbox
// -------------------------
.input-checkbox {
vertical-align: middle;
& when (@use-custom-controls) {
-webkit-appearance: none;
display: inline-block;
position: relative;
width: @component-size;
height: @component-size;
font-size: inherit;
border-radius: @component-border-radius;
background-color: @component-background-color;
transition: background-color .16s cubic-bezier(0.5, 0.15, 0.2, 1);
&&:focus {
outline: 0; // TODO: Add it back
}
&:active {
background-color: @background-color-info;
}
&:before,
&:after {
content: "";
position: absolute;
top: @component-size * .75;
left: @component-size * .4;
height: 2px;
border-radius: 1px;
background-color: @base-background-color;
transform-origin: 0 0;
opacity: 0;
transition: transform .1s cubic-bezier(0.5, 0.15, 0.2, 1), opacity .1s cubic-bezier(0.5, 0.15, 0.2, 1);
}
&:before {
width: @component-size * .33;
transform: translate3d(0,0,0) rotate(225deg) scale(0);
}
&:after {
width: @component-size * .66;
margin: -1px;
transform: translate3d(0,0,0) rotate(-45deg) scale(0);
transition-delay: .05s;
}
&:checked {
background-color: @background-color-info;
&:active {
background-color: @component-background-color;
}
&:before {
opacity: 1;
transform: translate3d(0,0,0) rotate(225deg) scale(1);
transition-delay: .05s;
}
&:after {
opacity: 1;
transform: translate3d(0, 0, 0) rotate(-45deg) scale(1);
transition-delay: 0;
}
}
&:indeterminate {
background-color: @background-color-info;
&:active {
background-color: @component-background-color;
}
&:after {
opacity: 1;
transform: translate3d(@component-size * -.14, @component-size * -.25, 0) rotate(0deg) scale(1);
transition-delay: 0;
}
}
}
}
//
// Color
// -------------------------
.input-color {
vertical-align: middle;
& when (@use-custom-controls) {
-webkit-appearance: none;
padding: 0;
width: @component-size * 2.5;
height: @component-size * 2.5;
border-radius: 50%;
border: 2px solid @input-border-color;
background-color: @input-background-color;
&::-webkit-color-swatch-wrapper { padding: 0; }
&::-webkit-color-swatch {
border: 1px solid hsla(0,0%,0%,.1);
border-radius: 50%;
transition: transform .16s cubic-bezier(0.5, 0.15, 0.2, 1);
&:active {
transition-duration: 0s;
transform: scale(.9);
}
}
}
}
//
// Label
// -------------------------
.input-label {
.input-radio,
.input-checkbox,
.input-toggle {
margin-top: -.25em; // Vertical center (visually) - since most labels are upper case.
margin-right: @component-margin-side;
}
}
//
// Number
// -------------------------
.input-number {
vertical-align: middle;
& when (@use-custom-controls) {
.input-field-mixin();
position: relative;
width: auto;
.platform-darwin & {
padding-right: 1.2em; // space for the spin button
&::-webkit-inner-spin-button {
-webkit-appearance: menulist-button;
position: absolute;
top: 1px;
bottom: 1px;
right: 1px;
width: calc(.6em ~'+' 9px); // magic numbers, OMG!
outline: 1px solid @input-background-color;
outline-offset: -1px; // reduces border radius (that can't be changed)
border-right: .2em solid @background-color-highlight; // a bit more padding
background-color: @background-color-highlight;
transition: transform .16s cubic-bezier(0.5, 0.15, 0.2, 1);
&:active {
transform: scale(.9);
transition-duration: 0s;
}
}
}
}
}
//
// Radio
// -------------------------
.input-radio {
vertical-align: middle;
& when (@use-custom-controls) {
-webkit-appearance: none;
display: inline-block;
position: relative;
width: @component-size;
height: @component-size;
font-size: inherit;
border-radius: 50%;
background-color: @component-background-color;
transition: background-color .16s cubic-bezier(0.5, 0.15, 0.2, 1);
&:before {
content: "";
position: absolute;
width: inherit;
height: inherit;
border-radius: inherit;
border: @component-size/3 solid transparent;
background-clip: content-box;
background-color: @base-background-color;
transform: scale(0);
transition: transform .1s cubic-bezier(0.5, 0.15, 0.2, 1);
}
&&:focus {
outline: none;
}
&:active {
background-color: @background-color-info;
}
&:checked {
background-color: @background-color-info;
&:before {
transform: scale(1);
}
}
}
}
//
// Range (Slider)
// -------------------------
.input-range {
& when (@use-custom-controls) {
-webkit-appearance: none;
margin: @component-padding 0;
height: 4px;
border-radius: @component-border-radius;
background-color: @component-background-color;
&::-webkit-slider-thumb {
-webkit-appearance: none;
width: @component-size;
height: @component-size;
border-radius: 50%;
background-color: @background-color-info;
transition: transform .16s;
&:active {
transition-duration: 0s;
transform: scale(.9);
}
}
}
}
//
// Search
// -------------------------
.input-search {
.input-block-mixin();
&&::-webkit-search-cancel-button {
-webkit-appearance: searchfield-cancel-button;
}
& when (@use-custom-controls) {
.input-field-mixin();
}
}
//
// Select
// -------------------------
.input-select {
vertical-align: middle;
& when (@use-custom-controls) {
height: calc(@text-component-height ~'+' 2px); // + 2px? Magic!
border-radius: @component-border-radius;
border: 1px solid @button-border-color;
background-color: @button-background-color;
}
}
//
// Text
// -------------------------
.input-text {
.input-block-mixin();
& when (@use-custom-controls) {
.input-field-mixin();
}
}
//
// Text Area
// -------------------------
.input-textarea {
.input-block-mixin();
& when (@use-custom-controls) {
.input-field-mixin();
}
}
//
// Toggle
// -------------------------
.input-toggle {
& when (@use-custom-controls) {
-webkit-appearance: none;
display: inline-block;
position: relative;
font-size: inherit;
width: @component-size * 2;
height: @component-size;
vertical-align: middle;
border-radius: 2em;
background-color: @component-background-color;
transition: background-color .2s cubic-bezier(0.5, 0.15, 0.2, 1);
&&:focus {
outline: 0;
}
&:checked {
background-color: @background-color-info;
}
// Thumb
&:before {
content: "";
position: absolute;
width: @component-size;
height: @component-size;
border-radius: inherit;
border: @component-size/4 solid transparent;
background-clip: content-box;
background-color: @base-background-color;
transition: transform .2s cubic-bezier(0.5, 0.15, 0.2, 1);
}
&:active:before {
opacity: .5;
}
&:checked:before {
transform: translate3d(100%, 0, 0);
}
}
}

View File

@@ -0,0 +1,85 @@
@import "ui-variables";
@import "mixins/mixins";
.padded {
padding: @component-padding;
}
// Blocks
.center-block {
display: block;
margin-left: auto;
margin-right: auto;
}
// Must be div.block so as not to affect syntax highlighting.
ul.block,
div.block {
margin-bottom: @component-padding;
}
div > ul.block:last-child,
div > div.block:last-child {
margin-bottom: 0;
}
// Inline Blocks
.inline-block,
.inline-block-tight {
display: inline-block;
vertical-align: middle;
}
.inline-block {
margin-right: @component-padding;
}
.inline-block-tight {
margin-right: @component-padding/2;
}
div > .inline-block:last-child,
div > .inline-block-tight:last-child {
margin-right: 0;
}
.inline-block .inline-block {
vertical-align: top;
}
// Centering
// -------------------------
.pull-center {
margin-left: auto;
margin-right: auto;
}
// Floats
// -------------------------
// Use left margin when it's in a float: right element.
// Sets the margin correctly when inline blocks are hidden and shown.
.pull-right {
float: right !important;
.inline-block {
margin-right: 0;
margin-left: @component-padding;
}
.inline-block-tight {
margin-right: 0;
margin-left: @component-padding/2;
}
> .inline-block:first-child,
> .inline-block-tight:first-child {
margin-left: 0;
}
}
.pull-left {
float: left !important;
}
.clearfix {
.clearfix();
}

View File

@@ -0,0 +1,291 @@
@import "variables/variables";
@import "ui-variables";
@import "mixins/mixins";
@import "octicon-mixins";
//
// List options
// --------------------------------------------------
// Unstyled keeps list items block level, just removes default browser padding and list-style
.list-unstyled {
padding-left: 0;
list-style: none;
}
// Inline turns list items into inline-block
.list-inline {
.list-unstyled();
margin-left: -5px;
> li {
display: inline-block;
padding-left: 5px;
padding-right: 5px;
}
}
//
// List groups
// --------------------------------------------------
// Mixins
.list-group-item-variant(@state; @background; @color) {
.list-group-item-@{state} {
color: @color;
background-color: @background;
a&,
button& {
color: @color;
.list-group-item-heading {
color: inherit;
}
&:hover,
&:focus {
color: @color;
background-color: darken(@background, 5%);
}
&.active,
&.active:hover,
&.active:focus {
color: #fff;
background-color: @color;
border-color: @color;
}
}
}
}
// Individual list items
//
// Use on `li`s or `div`s within the `.list-group` parent.
.list-group-item {
position: relative;
display: block;
padding: 10px 15px;
// Place the border on the list items and negative margin up for better styling
margin-bottom: -1px;
background-color: @list-group-bg;
border: 1px solid @list-group-border;
// Round the first and last items
&:first-child {
.border-top-radius(@list-group-border-radius);
}
&:last-child {
margin-bottom: 0;
.border-bottom-radius(@list-group-border-radius);
}
}
// Interactive list items
//
// Use anchor or button elements instead of `li`s or `div`s to create interactive items.
// Includes an extra `.active` modifier class for showing selected items.
a.list-group-item,
button.list-group-item {
color: @list-group-link-color;
.list-group-item-heading {
color: @list-group-link-heading-color;
}
// Hover state
&:hover,
&:focus {
text-decoration: none;
color: @list-group-link-hover-color;
background-color: @list-group-hover-bg;
}
}
button.list-group-item {
width: 100%;
text-align: left;
}
.list-group-item {
// Disabled state
&.disabled,
&.disabled:hover,
&.disabled:focus {
background-color: @list-group-disabled-bg;
color: @list-group-disabled-color;
cursor: @cursor-disabled;
// Force color to inherit for custom content
.list-group-item-heading {
color: inherit;
}
.list-group-item-text {
color: @list-group-disabled-text-color;
}
}
// Active class on item itself, not parent
&.active,
&.active:hover,
&.active:focus {
z-index: 2; // Place active items above their siblings for proper border styling
color: @list-group-active-color;
background-color: @list-group-active-bg;
border-color: @list-group-active-border;
// Force color to inherit for custom content
.list-group-item-heading,
.list-group-item-heading > small,
.list-group-item-heading > .small {
color: inherit;
}
.list-group-item-text {
color: @list-group-active-text-color;
}
}
}
// Contextual variants
//
// Add modifier classes to change text and background color on individual items.
// Organizationally, this must come after the `:hover` states.
.list-group-item-variant(success; @state-success-bg; @state-success-text);
.list-group-item-variant(info; @state-info-bg; @state-info-text);
.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);
.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);
// Custom content options
//
// Extra classes for creating well-formatted content within `.list-group-item`s.
.list-group-item-heading {
margin-top: 0;
margin-bottom: 5px;
}
.list-group-item-text {
margin-bottom: 0;
line-height: 1.3;
}
// This is a bootstrap override
// ---------------------------------------------
.list-group,
.list-group .list-group-item {
background-color: transparent;
border: none;
padding: 0;
margin: 0;
position: static;
}
.list-group,
.list-tree {
margin: 0;
padding: 0;
list-style: none;
cursor: default;
li:not(.list-nested-item),
li.list-nested-item > .list-item {
line-height: @component-line-height;
text-wrap: none;
white-space: nowrap;
}
// The background highlight uses ::before rather than the item background so
// it can span the entire width of the parent container rather than the size
// of the list item.
.selected::before {
content: '';
background-color: @background-color-selected;
position: absolute;
left: 0;
right: 0;
height: @component-line-height;
}
// Make sure the background highlight is below the content.
.selected > * {
position: relative;
}
.icon::before {
margin-right: @component-icon-padding;
position: relative;
top: 1px;
}
.no-icon {
padding-left: @component-icon-padding + @component-icon-size;
}
}
//
// List Tree
// --------------------------------------------------
// Handle indentation of the tree. Assume disclosure arrows.
.list-tree {
.list-nested-item > .list-tree > li,
.list-nested-item > .list-group > li {
padding-left: @component-icon-size + @component-icon-padding;
}
&.has-collapsable-children {
@disclosure-arrow-padding: @disclosure-arrow-size + @component-icon-padding;
li.list-item {
margin-left: @disclosure-arrow-padding;
}
.list-nested-item.collapsed > .list-group,
.list-nested-item.collapsed > .list-tree {
display: none;
}
// Nested items always get disclosure arrows
.list-nested-item > .list-item {
.octicon(chevron-down, @disclosure-arrow-size);
&::before{
position: relative;
top: -1px;
margin-right: @component-icon-padding;
}
}
.list-nested-item.collapsed > .list-item {
.octicon(chevron-right, @disclosure-arrow-size);
&::before{
left: 1px;
}
}
.list-nested-item > .list-tree > li,
.list-nested-item > .list-group > li {
padding-left: @disclosure-arrow-padding;
}
// You want a subtree to be flat -- no collapsable children
.has-flat-children,
&.has-flat-children {
li.list-item {
margin-left: 0;
}
}
}
}

View File

@@ -0,0 +1,21 @@
//
// Loading
// --------------------------------------------------
.loading-spinner(@size) {
display: block;
width: @size;
height: @size;
background-image: url(images/octocat-spinner-128.gif);
background-repeat: no-repeat;
background-size: cover;
&.inline-block {
display: inline-block;
}
}
.loading-spinner-tiny { .loading-spinner(16px); }
.loading-spinner-small { .loading-spinner(32px); }
.loading-spinner-medium { .loading-spinner(48px); }
.loading-spinner-large { .loading-spinner(64px); }

View File

@@ -0,0 +1,41 @@
@import "ui-variables";
.info-messages,
.error-messages {
margin: 0;
padding: 0;
list-style: none;
}
.error-messages {
color: @text-color-error;
}
ul.background-message {
font-size: @font-size * 3;
margin: 0;
padding: 0;
li {
margin: 0;
padding: 0;
list-style: none;
}
&.centered {
display: flex;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
align-items: center;
text-align: center;
li {
width: 100%;
}
}
}

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