mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-11 19:17:09 +03:00
Merge pull request #424 from pulsar-edit/bundle-time
Additional Bundling of Core Packages
This commit is contained in:
commit
80f3fc6b05
18
package.json
18
package.json
@ -39,7 +39,7 @@
|
||||
"autocomplete-plus": "file:./packages/autocomplete-plus",
|
||||
"autocomplete-snippets": "file:packages/autocomplete-snippets",
|
||||
"autoflow": "file:packages/autoflow",
|
||||
"autosave": "https://codeload.github.com/atom/autosave/legacy.tar.gz/refs/tags/v0.24.6",
|
||||
"autosave": "file:./packages/autosave",
|
||||
"babel-preset-atomic": "^5.0.0",
|
||||
"background-tips": "file:packages/background-tips",
|
||||
"base16-tomorrow-dark-theme": "file:packages/base16-tomorrow-dark-theme",
|
||||
@ -81,7 +81,7 @@
|
||||
"jasmine-reporters": "1.1.0",
|
||||
"jasmine-tagged": "^1.1.4",
|
||||
"key-path-helpers": "^0.4.0",
|
||||
"keybinding-resolver": "https://codeload.github.com/atom/keybinding-resolver/legacy.tar.gz/refs/tags/v0.39.1",
|
||||
"keybinding-resolver": "file:./packages/keybinding-resolver",
|
||||
"language-c": "file:packages/language-c",
|
||||
"language-clojure": "file:packages/language-clojure",
|
||||
"language-coffee-script": "file:packages/language-coffee-script",
|
||||
@ -160,7 +160,7 @@
|
||||
"tabs": "file:packages/tabs",
|
||||
"temp": "0.9.4",
|
||||
"text-buffer": "^13.18.6",
|
||||
"timecop": "https://codeload.github.com/atom/timecop/legacy.tar.gz/refs/tags/v0.36.2",
|
||||
"timecop": "file:./packages/timecop",
|
||||
"tree-sitter": "0.20.0",
|
||||
"tree-view": "https://codeload.github.com/atom/tree-view/legacy.tar.gz/refs/tags/v0.229.1",
|
||||
"typescript-simple": "8.0.6",
|
||||
@ -168,7 +168,7 @@
|
||||
"update-package-dependencies": "file:./packages/update-package-dependencies",
|
||||
"vscode-ripgrep": "1.9.0",
|
||||
"welcome": "file:packages/welcome",
|
||||
"whitespace": "https://codeload.github.com/atom/whitespace/legacy.tar.gz/refs/tags/v0.37.8",
|
||||
"whitespace": "file:./packages/whitespace",
|
||||
"winreg": "^1.2.1",
|
||||
"wrap-guide": "file:./packages/wrap-guide",
|
||||
"yargs": "17.6.2"
|
||||
@ -194,10 +194,10 @@
|
||||
"autocomplete-plus": "file:./packages/autocomplete-plus",
|
||||
"autocomplete-snippets": "file:./packages/autocomplete-snippets",
|
||||
"autoflow": "file:./packages/autoflow",
|
||||
"autosave": "0.24.6",
|
||||
"autosave": "file:./packages/autosave",
|
||||
"background-tips": "file:./packages/background-tips",
|
||||
"bookmarks": "file:./packages/bookmarks",
|
||||
"bracket-matcher": "0.92.0",
|
||||
"bracket-matcher": "file:./packages/bracket-matcher",
|
||||
"command-palette": "file:./packages/command-palette",
|
||||
"dalek": "file:./packages/dalek",
|
||||
"deprecation-cop": "file:./packages/deprecation-cop",
|
||||
@ -212,7 +212,7 @@
|
||||
"grammar-selector": "file:./packages/grammar-selector",
|
||||
"image-view": "file:./packages/image-view",
|
||||
"incompatible-packages": "file:./packages/incompatible-packages",
|
||||
"keybinding-resolver": "0.39.1",
|
||||
"keybinding-resolver": "file:./packages/keybinding-resolver",
|
||||
"line-ending-selector": "file:./packages/line-ending-selector",
|
||||
"link": "file:./packages/link",
|
||||
"markdown-preview": "file:./packages/markdown-preview",
|
||||
@ -226,11 +226,11 @@
|
||||
"styleguide": "file:./packages/styleguide",
|
||||
"symbols-view": "0.118.4",
|
||||
"tabs": "file:./packages/tabs",
|
||||
"timecop": "0.36.2",
|
||||
"timecop": "file:./packages/timecop",
|
||||
"tree-view": "0.229.1",
|
||||
"update-package-dependencies": "file:./packages/update-package-dependencies",
|
||||
"welcome": "file:./packages/welcome",
|
||||
"whitespace": "0.37.8",
|
||||
"whitespace": "file:./packages/whitespace",
|
||||
"wrap-guide": "file:./packages/wrap-guide",
|
||||
"language-c": "file:./packages/language-c",
|
||||
"language-clojure": "file:./packages/language-clojure",
|
||||
|
@ -19,12 +19,12 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate
|
||||
| **autocomplete-plus** | [`./autocomplete-plus`](./autocomplete-plus) | |
|
||||
| **autocomplete-snippets** | [`./autocomplete-snippets`](./autocomplete-snippets) | |
|
||||
| **autoflow** | [`./autoflow`](./autoflow) | |
|
||||
| **autosave** | [`pulsar-edit/autosave`][autosave] | [#17834](https://github.com/atom/atom/issues/17834) |
|
||||
| **autosave** | [`./autosave`](./autosave) | |
|
||||
| **background-tips** | [`./background-tips`](./background-tips) | |
|
||||
| **base16-tomorrow-dark-theme** | [`./base16-tomorrow-dark-theme`](./base16-tomorrow-dark-theme) | |
|
||||
| **base16-tomorrow-light-theme** | [`./base16-tomorrow-light-theme`](./base16-tomorrow-light-theme) | |
|
||||
| **bookmarks** | [`./bookmarks`](./bookmarks) | |
|
||||
| **bracket-matcher** | [`atom/bracket-matcher`][bracket-matcher] | |
|
||||
| **bracket-matcher** | [`./bracket-matcher`](./bracket-matcher) | |
|
||||
| **command-palette** | [`./command-palette`](./command-palette) | |
|
||||
| **dalek** | [`./dalek`](./dalek) | |
|
||||
| **deprecation-cop** | [`./deprecation-cop`](./deprecation-cop) | |
|
||||
@ -39,7 +39,7 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate
|
||||
| **grammar-selector** | [`./grammar-selector`](./grammar-selector) | |
|
||||
| **image-view** | [`./image-view`](./image-view) | |
|
||||
| **incompatible-packages** | [`./incompatible-packages`](./incompatible-packages) | |
|
||||
| **keybinding-resolver** | [`atom/keybinding-resolver`][keybinding-resolver] | [#18275](https://github.com/atom/atom/issues/18275) |
|
||||
| **keybinding-resolver** | [`./keybinding-resolver`](./keybinding-resolver) | |
|
||||
| **language-c** | [`./language-c`](./language-c) | |
|
||||
| **language-clojure** | [`./language-clojure`](./language-clojure) | |
|
||||
| **language-coffee-script** | [`./language-coffee-script`](./language-coffee-script) | |
|
||||
@ -93,7 +93,7 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate
|
||||
| **styleguide** | [`./styleguide`](./styleguide) | |
|
||||
| **symbols-view** | [`pulsar-edit/symbols-view`][symbols-view] | |
|
||||
| **tabs** | [`./tabs`](./tabs) | |
|
||||
| **timecop** | [`pulsar-edit/timecop`][timecop] | [#18272](https://github.com/atom/atom/issues/18272) |
|
||||
| **timecop** | [`./timecop`](./timecop) | |
|
||||
| **tree-view** | [`pulsar-edit/tree-view`][tree-view] | |
|
||||
| **update-package-dependencies** | [`./update-package-dependencies`](./update-package-dependencies) | |
|
||||
| **welcome** | [`./welcome`](./welcome) | |
|
||||
@ -101,8 +101,6 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate
|
||||
| **wrap-guide** | [`./wrap-guide`](./wrap-guide) | |
|
||||
|
||||
[autocomplete-atom-api]: https://github.com/pulsar-edit/autocomplete-atom-api
|
||||
[autosave]: https://github.com/pulsar-edit/autosave
|
||||
[bracket-matcher]: https://github.com/pulsar-edit/bracket-matcher
|
||||
[find-and-replace]: https://github.com/pulsar-edit/find-and-replace
|
||||
[fuzzy-finder]: https://github.com/pulsar-edit/fuzzy-finder
|
||||
[github]: https://github.com/pulsar-edit/github
|
||||
@ -111,5 +109,4 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate
|
||||
[snippets]: https://github.com/pulsar-edit/snippets
|
||||
[spell-check]: https://github.com/pulsar-edit/spell-check
|
||||
[symbols-view]: https://github.com/pulsar-edit/symbols-view
|
||||
[timecop]: https://github.com/pulsar-edit/timecop
|
||||
[tree-view]: https://github.com/pulsar-edit/tree-view
|
||||
|
1
packages/autosave/.gitignore
vendored
Normal file
1
packages/autosave/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
node_modules/
|
20
packages/autosave/LICENSE.md
Normal file
20
packages/autosave/LICENSE.md
Normal 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.
|
32
packages/autosave/README.md
Normal file
32
packages/autosave/README.md
Normal file
@ -0,0 +1,32 @@
|
||||
# Autosave package
|
||||
|
||||
Autosaves editor when they lose focus, are destroyed, or when the window is closed.
|
||||
|
||||
This package is disabled by default and can be enabled via the `autosave.enabled` config
|
||||
setting or by checking *Enabled* in the settings for the *autosave* package in the
|
||||
Settings view.
|
||||
|
||||
## Service API
|
||||
The service exposes an object with a function `dontSaveIf`, which accepts a callback.
|
||||
Callbacks will be invoked with each pane item eligible for an autosave and if the callback
|
||||
returns true, the item will be skipped.
|
||||
|
||||
### Usage
|
||||
|
||||
#### package.json
|
||||
``` json
|
||||
"consumedServices": {
|
||||
"autosave": {
|
||||
"versions": {
|
||||
"1.0.0": "consumeAutosave"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### package initialize
|
||||
``` javascript
|
||||
consumeAutosave({dontSaveIf}) {
|
||||
dontSaveIf(paneItem -> paneItem.getPath() === '/dont/autosave/me.coffee')
|
||||
}
|
||||
```
|
66
packages/autosave/lib/autosave.js
Normal file
66
packages/autosave/lib/autosave.js
Normal file
@ -0,0 +1,66 @@
|
||||
const fs = require('fs')
|
||||
const {CompositeDisposable, Disposable} = require('atom')
|
||||
const {dontSaveIf, shouldSave} = require('./controls')
|
||||
|
||||
module.exports = {
|
||||
subscriptions: null,
|
||||
|
||||
provideService () {
|
||||
return {dontSaveIf}
|
||||
},
|
||||
|
||||
activate () {
|
||||
this.subscriptions = new CompositeDisposable()
|
||||
|
||||
const handleBlur = event => {
|
||||
if (event.target === window) {
|
||||
this.autosaveAllPaneItems()
|
||||
} else if (event.target.matches('atom-text-editor:not(mini)')) {
|
||||
return this.autosavePaneItem(event.target.getModel())
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('blur', handleBlur, true)
|
||||
this.subscriptions.add(new Disposable(() => window.removeEventListener('blur', handleBlur, true)))
|
||||
|
||||
this.subscriptions.add(atom.workspace.onDidAddPaneItem(({item}) => this.autosavePaneItem(item, true)))
|
||||
this.subscriptions.add(atom.workspace.onWillDestroyPaneItem(({item}) => this.autosavePaneItem(item)))
|
||||
},
|
||||
|
||||
deactivate () {
|
||||
this.subscriptions.dispose()
|
||||
return this.autosaveAllPaneItems()
|
||||
},
|
||||
|
||||
autosavePaneItem (paneItem, create = false) {
|
||||
if (!atom.config.get('autosave.enabled')) return
|
||||
if (!paneItem) return
|
||||
if (typeof paneItem.getURI !== 'function' || !paneItem.getURI()) return
|
||||
if (typeof paneItem.isModified !== 'function' || !paneItem.isModified()) return
|
||||
if (typeof paneItem.getPath !== 'function' || !paneItem.getPath()) return
|
||||
if (!shouldSave(paneItem)) return
|
||||
|
||||
try {
|
||||
const stats = fs.statSync(paneItem.getPath())
|
||||
if (!stats.isFile()) return
|
||||
} catch (e) {
|
||||
if (e.code !== 'ENOENT') return
|
||||
if (!create) return
|
||||
}
|
||||
|
||||
const pane = atom.workspace.paneForItem(paneItem)
|
||||
let promise = Promise.resolve()
|
||||
if (pane) {
|
||||
promise = pane.saveItem(paneItem)
|
||||
} else if (typeof paneItem.save === 'function') {
|
||||
promise = paneItem.save()
|
||||
}
|
||||
return promise
|
||||
},
|
||||
|
||||
autosaveAllPaneItems () {
|
||||
return Promise.all(
|
||||
atom.workspace.getPaneItems().map((paneItem) => this.autosavePaneItem(paneItem))
|
||||
)
|
||||
}
|
||||
}
|
21
packages/autosave/lib/controls.js
vendored
Normal file
21
packages/autosave/lib/controls.js
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
const tests = []
|
||||
|
||||
module.exports = {
|
||||
// Public: Add a predicate to set of tests
|
||||
//
|
||||
// * `predicate` A {Function} determining if a {PaneItem} should autosave.
|
||||
//
|
||||
// Returns `undefined`.
|
||||
dontSaveIf (predicate) {
|
||||
tests.push(predicate)
|
||||
},
|
||||
|
||||
// Public: Test whether a paneItem should be autosaved.
|
||||
//
|
||||
// * `paneItem` A pane item {Object}.
|
||||
//
|
||||
// Returns `Boolean`.
|
||||
shouldSave (paneItem) {
|
||||
return !tests.some(test => test(paneItem))
|
||||
}
|
||||
}
|
166
packages/autosave/package-lock.json
generated
Normal file
166
packages/autosave/package-lock.json
generated
Normal file
@ -0,0 +1,166 @@
|
||||
{
|
||||
"name": "autosave",
|
||||
"version": "0.24.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "autosave",
|
||||
"version": "0.24.6",
|
||||
"dependencies": {
|
||||
"fs-plus": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"atom": ">0.27.0"
|
||||
}
|
||||
},
|
||||
"node_modules/async": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
|
||||
"integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w=="
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"node_modules/fs-plus": {
|
||||
"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==",
|
||||
"dependencies": {
|
||||
"async": "^1.5.2",
|
||||
"mkdirp": "^0.5.1",
|
||||
"rimraf": "^2.5.2",
|
||||
"underscore-plus": "1.x"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
|
||||
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
|
||||
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.6"
|
||||
},
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/underscore": {
|
||||
"version": "1.13.6",
|
||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
|
||||
"integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A=="
|
||||
},
|
||||
"node_modules/underscore-plus": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz",
|
||||
"integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==",
|
||||
"dependencies": {
|
||||
"underscore": "^1.9.1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
}
|
||||
}
|
||||
}
|
25
packages/autosave/package.json
Normal file
25
packages/autosave/package.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "autosave",
|
||||
"main": "./lib/autosave",
|
||||
"version": "0.24.6",
|
||||
"private": true,
|
||||
"description": "Save editors when they lose focus or are closed",
|
||||
"repository": "https://github.com/pulsar-edit/pulsar",
|
||||
"engines": {
|
||||
"atom": ">0.27.0"
|
||||
},
|
||||
"providedServices": {
|
||||
"autosave": {
|
||||
"description": "A configuration object to control what is autosaved",
|
||||
"versions": {
|
||||
"1.0.0": "provideService"
|
||||
}
|
||||
}
|
||||
},
|
||||
"configSchema": {
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
43
packages/autosave/spec/async-spec-helpers.js
Normal file
43
packages/autosave/spec/async-spec-helpers.js
Normal file
@ -0,0 +1,43 @@
|
||||
exports.beforeEach = function beforeEach (fn) {
|
||||
global.beforeEach(function () {
|
||||
const result = fn()
|
||||
if (result instanceof Promise) {
|
||||
waitsForPromise(() => result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
exports.afterEach = function afterEach (fn) {
|
||||
global.afterEach(function () {
|
||||
const result = fn()
|
||||
if (result instanceof Promise) {
|
||||
waitsForPromise(() => result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
;['it', 'fit', 'ffit', 'fffit'].forEach(function (name) {
|
||||
exports[name] = function (description, fn) {
|
||||
if (fn === undefined) {
|
||||
global[name](description)
|
||||
return
|
||||
}
|
||||
|
||||
global[name](description, function () {
|
||||
const result = fn()
|
||||
if (result instanceof Promise) {
|
||||
waitsForPromise(() => result)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
function waitsForPromise (fn) {
|
||||
const promise = fn()
|
||||
global.waitsFor('spec promise to resolve', function (done) {
|
||||
promise.then(done, function (error) {
|
||||
jasmine.getEnv().currentSpec.fail(error)
|
||||
done()
|
||||
})
|
||||
})
|
||||
}
|
267
packages/autosave/spec/autosave-spec.js
Normal file
267
packages/autosave/spec/autosave-spec.js
Normal file
@ -0,0 +1,267 @@
|
||||
const fs = require('fs')
|
||||
const {it, fit, ffit, beforeEach} = require('./async-spec-helpers') // eslint-disable-line
|
||||
|
||||
describe('Autosave', () => {
|
||||
let workspaceElement, initialActiveItem, otherItem1, otherItem2
|
||||
|
||||
beforeEach(async () => {
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
|
||||
await atom.packages.activatePackage('autosave')
|
||||
|
||||
await atom.workspace.open('sample.js')
|
||||
|
||||
initialActiveItem = atom.workspace.getActiveTextEditor()
|
||||
|
||||
if (atom.workspace.createItemForURI != null) {
|
||||
otherItem1 = await atom.workspace.createItemForURI('sample.coffee')
|
||||
} else {
|
||||
otherItem1 = await atom.workspace.open('sample.coffee', {activateItem: false})
|
||||
}
|
||||
|
||||
otherItem2 = otherItem1.copy()
|
||||
|
||||
spyOn(initialActiveItem, 'save').andCallFake(() => Promise.resolve())
|
||||
spyOn(otherItem1, 'save').andCallFake(() => Promise.resolve())
|
||||
spyOn(otherItem2, 'save').andCallFake(() => Promise.resolve())
|
||||
})
|
||||
|
||||
describe('when the item is not modified', () => {
|
||||
it('does not autosave the item', () => {
|
||||
atom.config.set('autosave.enabled', true)
|
||||
atom.workspace.getActivePane().splitRight({items: [otherItem1]})
|
||||
expect(initialActiveItem.save).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the buffer is modified', () => {
|
||||
beforeEach(() => initialActiveItem.setText('i am modified'))
|
||||
|
||||
it('autosaves newly added items', async () => {
|
||||
const newItem = await atom.workspace.createItemForURI('notyet.js')
|
||||
spyOn(newItem, 'isModified').andReturn(true)
|
||||
|
||||
atom.config.set('autosave.enabled', true)
|
||||
spyOn(atom.workspace.getActivePane(), 'saveItem').andCallFake(() => Promise.resolve())
|
||||
atom.workspace.getActivePane().addItem(newItem)
|
||||
|
||||
expect(atom.workspace.getActivePane().saveItem).toHaveBeenCalledWith(newItem)
|
||||
})
|
||||
|
||||
describe('when a pane loses focus', () => {
|
||||
it('saves the item if autosave is enabled and the item has a uri', () => {
|
||||
document.body.focus()
|
||||
expect(initialActiveItem.save).not.toHaveBeenCalled()
|
||||
|
||||
workspaceElement.focus()
|
||||
atom.config.set('autosave.enabled', true)
|
||||
document.body.focus()
|
||||
expect(initialActiveItem.save).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('suppresses autosave if the file does not exist', () => {
|
||||
document.body.focus()
|
||||
expect(initialActiveItem.save).not.toHaveBeenCalled()
|
||||
|
||||
workspaceElement.focus()
|
||||
atom.config.set('autosave.enabled', true)
|
||||
|
||||
const originalPath = atom.workspace.getActiveTextEditor().getPath()
|
||||
const tmpPath = `${originalPath}~`
|
||||
fs.renameSync(originalPath, tmpPath)
|
||||
|
||||
document.body.focus()
|
||||
expect(initialActiveItem.save).not.toHaveBeenCalled()
|
||||
|
||||
fs.renameSync(tmpPath, originalPath)
|
||||
})
|
||||
|
||||
it('suppresses autosave if the focused element is contained by the editor, such as occurs when opening the autocomplete menu', () => {
|
||||
atom.config.set('autosave.enabled', true)
|
||||
const focusStealer = document.createElement('div')
|
||||
focusStealer.setAttribute('tabindex', -1)
|
||||
|
||||
const textEditorElement = atom.views.getView(atom.workspace.getActiveTextEditor())
|
||||
textEditorElement.appendChild(focusStealer)
|
||||
focusStealer.focus()
|
||||
expect(initialActiveItem.save).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('when a new pane is created', () => {
|
||||
it('saves the item if autosave is enabled and the item has a uri', () => {
|
||||
const leftPane = atom.workspace.getActivePane()
|
||||
const rightPane = leftPane.splitRight()
|
||||
expect(initialActiveItem.save).not.toHaveBeenCalled()
|
||||
|
||||
rightPane.destroy()
|
||||
leftPane.activate()
|
||||
|
||||
atom.config.set('autosave.enabled', true)
|
||||
leftPane.splitRight()
|
||||
expect(initialActiveItem.save).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('when an item is destroyed', () => {
|
||||
describe('when the item is the active item', () => {
|
||||
it('does not save the item if autosave is enabled and the item has a uri', async () => {
|
||||
let leftPane = atom.workspace.getActivePane()
|
||||
const rightPane = leftPane.splitRight({items: [otherItem1]})
|
||||
leftPane.activate()
|
||||
expect(initialActiveItem).toBe(atom.workspace.getActivePaneItem())
|
||||
leftPane.destroyItem(initialActiveItem)
|
||||
expect(initialActiveItem.save).not.toHaveBeenCalled()
|
||||
|
||||
otherItem2.setText('I am also modified')
|
||||
atom.config.set('autosave.enabled', true)
|
||||
leftPane = rightPane.splitLeft({items: [otherItem2]})
|
||||
expect(otherItem2).toBe(atom.workspace.getActivePaneItem())
|
||||
await leftPane.destroyItem(otherItem2)
|
||||
expect(otherItem2.save).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the item is NOT the active item', () => {
|
||||
it('does not save the item if autosave is enabled and the item has a uri', () => {
|
||||
let leftPane = atom.workspace.getActivePane()
|
||||
const rightPane = leftPane.splitRight({items: [otherItem1]})
|
||||
expect(initialActiveItem).not.toBe(atom.workspace.getActivePaneItem())
|
||||
leftPane.destroyItem(initialActiveItem)
|
||||
expect(initialActiveItem.save).not.toHaveBeenCalled()
|
||||
|
||||
otherItem2.setText('I am also modified')
|
||||
atom.config.set('autosave.enabled', true)
|
||||
leftPane = rightPane.splitLeft({items: [otherItem2]})
|
||||
rightPane.focus()
|
||||
expect(otherItem2).not.toBe(atom.workspace.getActivePaneItem())
|
||||
leftPane.destroyItem(otherItem2)
|
||||
expect(otherItem2.save).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the item does not have a URI', () => {
|
||||
it('does not save the item', async () => {
|
||||
await atom.workspace.open()
|
||||
|
||||
const pathLessItem = atom.workspace.getActiveTextEditor()
|
||||
spyOn(pathLessItem, 'save').andCallThrough()
|
||||
pathLessItem.setText('text!')
|
||||
expect(pathLessItem.getURI()).toBeFalsy()
|
||||
|
||||
atom.config.set('autosave.enabled', true)
|
||||
atom.workspace.getActivePane().destroyItem(pathLessItem)
|
||||
expect(pathLessItem.save).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the window is blurred', () => {
|
||||
it('saves all items', () => {
|
||||
atom.config.set('autosave.enabled', true)
|
||||
|
||||
const leftPane = atom.workspace.getActivePane()
|
||||
leftPane.splitRight({items: [otherItem1]})
|
||||
|
||||
initialActiveItem.insertText('a')
|
||||
otherItem1.insertText('b')
|
||||
|
||||
window.dispatchEvent(new FocusEvent('blur'))
|
||||
|
||||
expect(initialActiveItem.save).toHaveBeenCalled()
|
||||
expect(otherItem1.save).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the package is deactivated', () => {
|
||||
it('saves all items and waits for saves to complete', () => {
|
||||
atom.config.set('autosave.enabled', true)
|
||||
|
||||
const leftPane = atom.workspace.getActivePane()
|
||||
leftPane.splitRight({items: [otherItem1]})
|
||||
|
||||
initialActiveItem.insertText('a')
|
||||
otherItem1.insertText('b')
|
||||
|
||||
let deactivated = false
|
||||
let asyncDeactivateSupported = true
|
||||
let resolveInitial = () => {}
|
||||
let resolveOther = () => {}
|
||||
initialActiveItem.save.andCallFake(() => {
|
||||
return new Promise(resolve => {
|
||||
resolveInitial = resolve
|
||||
})
|
||||
})
|
||||
otherItem1.save.andCallFake(() => {
|
||||
return new Promise(resolve => {
|
||||
resolveOther = resolve
|
||||
})
|
||||
})
|
||||
|
||||
let deactivatePromise = atom.packages.deactivatePackage('autosave')
|
||||
if (!deactivatePromise || !deactivatePromise.then || typeof deactivatePromise.then !== 'function') {
|
||||
// Atom does not support asynchronous package deactivation.
|
||||
// This keeps us from failing on 1.20
|
||||
asyncDeactivateSupported = false
|
||||
deactivatePromise = Promise.resolve()
|
||||
}
|
||||
deactivatePromise.then((result) => {
|
||||
if (result === undefined) {
|
||||
// This keeps us from failing on 1.21-beta1
|
||||
asyncDeactivateSupported = false
|
||||
}
|
||||
deactivated = true
|
||||
})
|
||||
|
||||
waitsForPromise(() => Promise.resolve())
|
||||
|
||||
runs(() => {
|
||||
if (asyncDeactivateSupported) {
|
||||
expect(deactivated).toBe(false)
|
||||
}
|
||||
|
||||
resolveInitial()
|
||||
resolveOther()
|
||||
})
|
||||
|
||||
waitsFor(() => !asyncDeactivateSupported || deactivated)
|
||||
})
|
||||
})
|
||||
|
||||
it("saves via the item's Pane so that write errors are handled via notifications", async () => {
|
||||
const saveError = new Error('Save failed')
|
||||
saveError.code = 'EACCES'
|
||||
saveError.path = initialActiveItem.getPath()
|
||||
initialActiveItem.save.andThrow(saveError)
|
||||
|
||||
const errorCallback = jasmine.createSpy('errorCallback').andCallFake(({preventDefault}) => preventDefault())
|
||||
atom.onWillThrowError(errorCallback)
|
||||
spyOn(atom.notifications, 'addWarning')
|
||||
|
||||
initialActiveItem.insertText('a')
|
||||
atom.config.set('autosave.enabled', true)
|
||||
|
||||
await atom.workspace.destroyActivePaneItem()
|
||||
expect(initialActiveItem.save).toHaveBeenCalled()
|
||||
expect(atom.notifications.addWarning.callCount > 0 || errorCallback.callCount > 0).toBe(true)
|
||||
})
|
||||
|
||||
describe('dontSaveIf service', () => {
|
||||
it("doesn't save a paneItem if a predicate function registered via the dontSaveIf service returns true", async () => {
|
||||
atom.workspace.getActivePane().addItem(otherItem1)
|
||||
atom.config.set('autosave.enabled', true)
|
||||
const service = atom.packages.getActivePackage('autosave').mainModule.provideService()
|
||||
service.dontSaveIf(paneItem => paneItem === initialActiveItem)
|
||||
|
||||
initialActiveItem.setText('foo')
|
||||
otherItem1.setText('bar')
|
||||
|
||||
window.dispatchEvent(new FocusEvent('blur'))
|
||||
|
||||
expect(initialActiveItem.save).not.toHaveBeenCalled()
|
||||
expect(otherItem1.save).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
})
|
23
packages/autosave/spec/fixtures/sample.coffee
vendored
Normal file
23
packages/autosave/spec/fixtures/sample.coffee
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
class Quicksort
|
||||
sort: (items) ->
|
||||
return items if items.length <= 1
|
||||
|
||||
pivot = items.shift()
|
||||
left = []
|
||||
right = []
|
||||
|
||||
# Comment in the middle (and add the word 'items' again)
|
||||
|
||||
while items.length > 0
|
||||
current = items.shift()
|
||||
if current < pivot
|
||||
left.push(current)
|
||||
else
|
||||
right.push(current)
|
||||
|
||||
sort(left).concat(pivot).concat(sort(right))
|
||||
|
||||
noop: ->
|
||||
# just a noop
|
||||
|
||||
exports.modules = quicksort
|
13
packages/autosave/spec/fixtures/sample.js
vendored
Normal file
13
packages/autosave/spec/fixtures/sample.js
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
var quicksort = function () {
|
||||
var sort = function(items) {
|
||||
if (items.length <= 1) return items;
|
||||
var pivot = items.shift(), current, left = [], right = [];
|
||||
while(items.length > 0) {
|
||||
current = items.shift();
|
||||
current < pivot ? left.push(current) : right.push(current);
|
||||
}
|
||||
return sort(left).concat(pivot).concat(sort(right));
|
||||
};
|
||||
|
||||
return sort(Array.apply(this, arguments));
|
||||
};
|
1
packages/bracket-matcher/.gitignore
vendored
Normal file
1
packages/bracket-matcher/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
node_modules
|
441
packages/bracket-matcher/package-lock.json
generated
Normal file
441
packages/bracket-matcher/package-lock.json
generated
Normal file
@ -0,0 +1,441 @@
|
||||
{
|
||||
"name": "bracket-matcher",
|
||||
"version": "0.92.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"async": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
|
||||
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
|
||||
"integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
|
||||
},
|
||||
"cliui": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
|
||||
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
|
||||
"requires": {
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1",
|
||||
"wrap-ansi": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
|
||||
},
|
||||
"coffee-script": {
|
||||
"version": "1.12.7",
|
||||
"resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz",
|
||||
"integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw=="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"cson-parser": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz",
|
||||
"integrity": "sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ=",
|
||||
"requires": {
|
||||
"coffee-script": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"d": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz",
|
||||
"integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=",
|
||||
"requires": {
|
||||
"es5-ext": "~0.10.2"
|
||||
}
|
||||
},
|
||||
"decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
|
||||
},
|
||||
"emissary": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/emissary/-/emissary-1.3.3.tgz",
|
||||
"integrity": "sha1-phjZLWgrIy0xER3DYlpd9mF5lgY=",
|
||||
"requires": {
|
||||
"es6-weak-map": "^0.1.2",
|
||||
"mixto": "1.x",
|
||||
"property-accessors": "^1.1",
|
||||
"underscore-plus": "1.x"
|
||||
}
|
||||
},
|
||||
"es5-ext": {
|
||||
"version": "0.10.52",
|
||||
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.52.tgz",
|
||||
"integrity": "sha512-bWCbE9fbpYQY4CU6hJbJ1vSz70EClMlDgJ7BmwI+zEJhxrwjesZRPglGJlsZhu0334U3hI+gaspwksH9IGD6ag==",
|
||||
"requires": {
|
||||
"es6-iterator": "~2.0.3",
|
||||
"es6-symbol": "~3.1.2",
|
||||
"next-tick": "~1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"d": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
|
||||
"integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
|
||||
"requires": {
|
||||
"es5-ext": "^0.10.50",
|
||||
"type": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"es6-iterator": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
|
||||
"integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
|
||||
"requires": {
|
||||
"d": "1",
|
||||
"es5-ext": "^0.10.35",
|
||||
"es6-symbol": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"es6-symbol": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
|
||||
"integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
|
||||
"requires": {
|
||||
"d": "^1.0.1",
|
||||
"ext": "^1.1.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"es6-iterator": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-0.1.3.tgz",
|
||||
"integrity": "sha1-1vWLjE/EE8JJtLqhl2j45NfIlE4=",
|
||||
"requires": {
|
||||
"d": "~0.1.1",
|
||||
"es5-ext": "~0.10.5",
|
||||
"es6-symbol": "~2.0.1"
|
||||
}
|
||||
},
|
||||
"es6-symbol": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-2.0.1.tgz",
|
||||
"integrity": "sha1-dhtcZ8/U8dGK+yNPaR1nhoLLO/M=",
|
||||
"requires": {
|
||||
"d": "~0.1.1",
|
||||
"es5-ext": "~0.10.5"
|
||||
}
|
||||
},
|
||||
"es6-weak-map": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-0.1.4.tgz",
|
||||
"integrity": "sha1-cGzvnpmqI2undmwjnIueKG6n0ig=",
|
||||
"requires": {
|
||||
"d": "~0.1.1",
|
||||
"es5-ext": "~0.10.6",
|
||||
"es6-iterator": "~0.1.3",
|
||||
"es6-symbol": "~2.0.1"
|
||||
}
|
||||
},
|
||||
"event-kit": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/event-kit/-/event-kit-2.5.3.tgz",
|
||||
"integrity": "sha512-b7Qi1JNzY4BfAYfnIRanLk0DOD1gdkWHT4GISIn8Q2tAf3LpU8SP2CMwWaq40imYoKWbtN4ZhbSRxvsnikooZQ=="
|
||||
},
|
||||
"ext": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.2.0.tgz",
|
||||
"integrity": "sha512-0ccUQK/9e3NreLFg6K6np8aPyRgwycx+oFGtfx1dSp7Wj00Ozw9r05FgBRlzjf2XBM7LAzwgLyDscRrtSU91hA==",
|
||||
"requires": {
|
||||
"type": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"type": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz",
|
||||
"integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"first-mate": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/first-mate/-/first-mate-7.4.1.tgz",
|
||||
"integrity": "sha512-SEG5W0aajCvK/Ngoo3he3Ib4DsT+CRPhBAgSju5hksBLvvUfRWP7Jf3+HQ+CNTD4GZZqbDNOEJNOxbf35EblrQ==",
|
||||
"requires": {
|
||||
"emissary": "^1",
|
||||
"event-kit": "^2.2.0",
|
||||
"fs-plus": "^3.0.0",
|
||||
"grim": "^2.0.1",
|
||||
"oniguruma": "7.2.1",
|
||||
"season": "^6.0.2",
|
||||
"underscore-plus": "^1"
|
||||
}
|
||||
},
|
||||
"fs-plus": {
|
||||
"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",
|
||||
"rimraf": "^2.5.2",
|
||||
"underscore-plus": "1.x"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"grim": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/grim/-/grim-2.0.2.tgz",
|
||||
"integrity": "sha512-Qj7hTJRfd87E/gUgfvM0YIH/g2UA2SV6niv6BYXk1o6w4mhgv+QyYM1EjOJQljvzgEj4SqSsRWldXIeKHz3e3Q==",
|
||||
"requires": {
|
||||
"event-kit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"invert-kv": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
|
||||
"integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"lcid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
|
||||
"integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
|
||||
"requires": {
|
||||
"invert-kv": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
},
|
||||
"mixto": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mixto/-/mixto-1.0.0.tgz",
|
||||
"integrity": "sha1-wyDvYbUvKJj1IuF9i7xtUG2EJbY="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
|
||||
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
|
||||
},
|
||||
"next-tick": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
|
||||
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"oniguruma": {
|
||||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmjs.org/oniguruma/-/oniguruma-7.2.1.tgz",
|
||||
"integrity": "sha512-WPS/e1uzhswPtJSe+Zls/kAj27+lEqZjCmRSjnYk/Z4L2Mu+lJC2JWtkZhPJe4kZeTQfz7ClcLyXlI4J68MG2w==",
|
||||
"requires": {
|
||||
"nan": "^2.14.0"
|
||||
}
|
||||
},
|
||||
"os-locale": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
|
||||
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
|
||||
"requires": {
|
||||
"lcid": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
},
|
||||
"property-accessors": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/property-accessors/-/property-accessors-1.1.3.tgz",
|
||||
"integrity": "sha1-Hd6EAkYxhlkJ7zBwM2VoDF+SixU=",
|
||||
"requires": {
|
||||
"es6-weak-map": "^0.1.2",
|
||||
"mixto": "1.x"
|
||||
}
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
},
|
||||
"season": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/season/-/season-6.0.2.tgz",
|
||||
"integrity": "sha1-naWPsd3SSCTXYhstxjpxI7UCF7Y=",
|
||||
"requires": {
|
||||
"cson-parser": "^1.3.0",
|
||||
"fs-plus": "^3.0.0",
|
||||
"yargs": "^3.23.0"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
"strip-ansi": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
|
||||
"integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
|
||||
},
|
||||
"underscore": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
|
||||
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
|
||||
},
|
||||
"underscore-plus": {
|
||||
"version": "1.6.8",
|
||||
"resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.6.8.tgz",
|
||||
"integrity": "sha512-88PrCeMKeAAC1L4xjSiiZ3Fg6kZOYrLpLGVPPeqKq/662DfQe/KTSKdSR/Q/tucKNnfW2MNAUGSCkDf8HmXC5Q==",
|
||||
"requires": {
|
||||
"underscore": "~1.8.3"
|
||||
}
|
||||
},
|
||||
"window-size": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
|
||||
"integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY="
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
|
||||
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
|
||||
"requires": {
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
|
||||
"integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "3.32.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
|
||||
"integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
|
||||
"requires": {
|
||||
"camelcase": "^2.0.1",
|
||||
"cliui": "^3.0.3",
|
||||
"decamelize": "^1.1.1",
|
||||
"os-locale": "^1.4.0",
|
||||
"string-width": "^1.0.1",
|
||||
"window-size": "^0.1.4",
|
||||
"y18n": "^3.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,67 +1,67 @@
|
||||
{
|
||||
"name": "bracket-matcher",
|
||||
"version": "0.92.0",
|
||||
"main": "./lib/main",
|
||||
"description": "Highlight the matching bracket for the `(){}[]` character under the cursor. Move the cursor to the matching bracket with `ctrl-m`.",
|
||||
"repository": "https://github.com/pulsar-edit/bracket-matcher",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"atom": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"underscore-plus": "1.x"
|
||||
},
|
||||
"configSchema": {
|
||||
"autocompleteCharacters": {
|
||||
"description": "Autocompleted characters treated as matching pairs, such as `()`, and `{}`.",
|
||||
"type": "array",
|
||||
"default": [
|
||||
"()",
|
||||
"[]",
|
||||
"{}",
|
||||
"\"\"",
|
||||
"''",
|
||||
"``",
|
||||
"“”",
|
||||
"‘’",
|
||||
"«»",
|
||||
"‹›"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"pairsWithExtraNewline": {
|
||||
"description": "Automatically add a newline between the pair when enter is pressed.",
|
||||
"type": "array",
|
||||
"default": [
|
||||
"()",
|
||||
"[]",
|
||||
"{}"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"autocompleteBrackets": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Autocomplete bracket and quote characters, such as `(` and `)`, and `\"`."
|
||||
},
|
||||
"wrapSelectionsInBrackets": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Wrap selected text in brackets or quotes when the editor contains selections and the opening bracket or quote is typed."
|
||||
},
|
||||
"highlightMatchingLineNumber": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Highlight the line number of the matching bracket."
|
||||
},
|
||||
"alwaysSkipClosingPairs": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Always skip closing pairs in front of the cursor."
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"name": "bracket-matcher",
|
||||
"version": "0.92.0",
|
||||
"main": "./lib/main",
|
||||
"description": "Highlight the matching bracket for the `(){}[]` character under the cursor. Move the cursor to the matching bracket with `ctrl-m`.",
|
||||
"repository": "https://github.com/pulsar-edit/pulsar",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"atom": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"underscore-plus": "1.x"
|
||||
},
|
||||
"configSchema": {
|
||||
"autocompleteCharacters": {
|
||||
"description": "Autocompleted characters treated as matching pairs, such as `()`, and `{}`.",
|
||||
"type": "array",
|
||||
"default": [
|
||||
"()",
|
||||
"[]",
|
||||
"{}",
|
||||
"\"\"",
|
||||
"''",
|
||||
"``",
|
||||
"“”",
|
||||
"‘’",
|
||||
"«»",
|
||||
"‹›"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"pairsWithExtraNewline": {
|
||||
"description": "Automatically add a newline between the pair when enter is pressed.",
|
||||
"type": "array",
|
||||
"default": [
|
||||
"()",
|
||||
"[]",
|
||||
"{}"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"autocompleteBrackets": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Autocomplete bracket and quote characters, such as `(` and `)`, and `\"`."
|
||||
},
|
||||
"wrapSelectionsInBrackets": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Wrap selected text in brackets or quotes when the editor contains selections and the opening bracket or quote is typed."
|
||||
},
|
||||
"highlightMatchingLineNumber": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Highlight the line number of the matching bracket."
|
||||
},
|
||||
"alwaysSkipClosingPairs": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Always skip closing pairs in front of the cursor."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
packages/keybinding-resolver/.gitignore
vendored
Normal file
15
packages/keybinding-resolver/.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
lib-cov
|
||||
*.seed
|
||||
*.log
|
||||
*.csv
|
||||
*.dat
|
||||
*.out
|
||||
*.pid
|
||||
*.gz
|
||||
|
||||
pids
|
||||
logs
|
||||
results
|
||||
|
||||
npm-debug.log
|
||||
node_modules
|
10
packages/keybinding-resolver/README.md
Normal file
10
packages/keybinding-resolver/README.md
Normal file
@ -0,0 +1,10 @@
|
||||
# Keybinding Resolver package
|
||||
|
||||
Shows what commands a keybinding resolves to.
|
||||
|
||||
You can open and close the resolver using <kbd>Cmd+.</kbd> (macOS) or <kbd>Ctrl+.</kbd> (Linux and Windows).
|
||||
|
||||
Please note the clipboard icon which can be selected to copy the given keybinding
|
||||
directive so that you can easily paste it into your keymap files.
|
||||
|
||||
![](https://user-images.githubusercontent.com/4137660/44482876-8de73a80-a617-11e8-8bd5-24023c96b39e.png)
|
@ -0,0 +1,8 @@
|
||||
'.platform-darwin':
|
||||
'cmd-.': 'key-binding-resolver:toggle'
|
||||
|
||||
'.platform-win32':
|
||||
'ctrl-.': 'key-binding-resolver:toggle'
|
||||
|
||||
'.platform-linux':
|
||||
'ctrl-.': 'key-binding-resolver:toggle'
|
266
packages/keybinding-resolver/lib/keybinding-resolver-view.js
Normal file
266
packages/keybinding-resolver/lib/keybinding-resolver-view.js
Normal file
@ -0,0 +1,266 @@
|
||||
/** @babel */
|
||||
/** @jsx etch.dom */
|
||||
|
||||
import fs from 'fs-plus'
|
||||
import etch from 'etch'
|
||||
import {CompositeDisposable} from 'atom'
|
||||
import path from 'path'
|
||||
|
||||
export default class KeyBindingResolverView {
|
||||
constructor () {
|
||||
this.keystrokes = null
|
||||
this.usedKeyBinding = null
|
||||
this.unusedKeyBindings = []
|
||||
this.unmatchedKeyBindings = []
|
||||
this.partiallyMatchedBindings = []
|
||||
this.attached = false
|
||||
this.disposables = new CompositeDisposable()
|
||||
this.keybindingDisposables = new CompositeDisposable()
|
||||
|
||||
this.disposables.add(atom.workspace.getBottomDock().observeActivePaneItem(item => {
|
||||
if (item === this) {
|
||||
this.attach()
|
||||
} else {
|
||||
this.detach()
|
||||
}
|
||||
}))
|
||||
|
||||
this.disposables.add(atom.workspace.getBottomDock().observeVisible(visible => {
|
||||
if (visible) {
|
||||
if (atom.workspace.getBottomDock().getActivePaneItem() === this) this.attach()
|
||||
} else {
|
||||
this.detach()
|
||||
}
|
||||
}))
|
||||
|
||||
etch.initialize(this)
|
||||
}
|
||||
|
||||
getTitle () {
|
||||
return 'Key Binding Resolver'
|
||||
}
|
||||
|
||||
getIconName () {
|
||||
return 'keyboard'
|
||||
}
|
||||
|
||||
getDefaultLocation () {
|
||||
return 'bottom'
|
||||
}
|
||||
|
||||
getAllowedLocations () {
|
||||
// TODO: Support left and right possibly
|
||||
return ['bottom']
|
||||
}
|
||||
|
||||
getURI () {
|
||||
return 'atom://keybinding-resolver'
|
||||
}
|
||||
|
||||
serialize () {
|
||||
return {
|
||||
deserializer: 'keybinding-resolver/KeyBindingResolverView'
|
||||
}
|
||||
}
|
||||
|
||||
destroy () {
|
||||
this.disposables.dispose()
|
||||
this.detach()
|
||||
return etch.destroy(this)
|
||||
}
|
||||
|
||||
attach () {
|
||||
if (this.attached) return
|
||||
|
||||
this.attached = true
|
||||
this.keybindingDisposables = new CompositeDisposable()
|
||||
this.keybindingDisposables.add(atom.keymaps.onDidMatchBinding(({keystrokes, binding, keyboardEventTarget, eventType}) => {
|
||||
if (eventType === 'keyup' && binding == null) {
|
||||
return
|
||||
}
|
||||
|
||||
const unusedKeyBindings = atom.keymaps
|
||||
.findKeyBindings({keystrokes, target: keyboardEventTarget})
|
||||
.filter((b) => b !== binding)
|
||||
|
||||
const unmatchedKeyBindings = atom.keymaps
|
||||
.findKeyBindings({keystrokes})
|
||||
.filter((b) => b !== binding && !unusedKeyBindings.includes(b))
|
||||
|
||||
this.update({usedKeyBinding: binding, unusedKeyBindings, unmatchedKeyBindings, keystrokes})
|
||||
}))
|
||||
|
||||
this.keybindingDisposables.add(atom.keymaps.onDidPartiallyMatchBindings(({keystrokes, partiallyMatchedBindings}) => {
|
||||
this.update({keystrokes, partiallyMatchedBindings})
|
||||
}))
|
||||
|
||||
this.keybindingDisposables.add(atom.keymaps.onDidFailToMatchBinding(({keystrokes, keyboardEventTarget, eventType}) => {
|
||||
if (eventType === 'keyup') {
|
||||
return
|
||||
}
|
||||
|
||||
const unusedKeyBindings = atom.keymaps.findKeyBindings({keystrokes, target: keyboardEventTarget})
|
||||
const unmatchedKeyBindings = atom.keymaps
|
||||
.findKeyBindings({keystrokes})
|
||||
.filter((b) => !unusedKeyBindings.includes(b))
|
||||
|
||||
this.update({unusedKeyBindings, unmatchedKeyBindings, keystrokes})
|
||||
}))
|
||||
}
|
||||
|
||||
detach () {
|
||||
if (!this.attached) return
|
||||
|
||||
this.attached = false
|
||||
this.keybindingDisposables.dispose()
|
||||
this.keybindingDisposables = null
|
||||
}
|
||||
|
||||
update (props) {
|
||||
this.keystrokes = props.keystrokes
|
||||
this.usedKeyBinding = props.usedKeyBinding
|
||||
this.unusedKeyBindings = props.unusedKeyBindings || []
|
||||
this.unmatchedKeyBindings = props.unmatchedKeyBindings || []
|
||||
this.partiallyMatchedBindings = props.partiallyMatchedBindings || []
|
||||
return etch.update(this)
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className='key-binding-resolver'>
|
||||
<div className='panel-heading'>{this.renderKeystrokes()}</div>
|
||||
<div className='panel-body'>{this.renderKeyBindings()}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderKeystrokes () {
|
||||
if (this.keystrokes) {
|
||||
if (this.partiallyMatchedBindings.length > 0) {
|
||||
return <span className='keystroke highlight-info'>{this.keystrokes} (partial)</span>
|
||||
} else {
|
||||
return <span className='keystroke highlight-info'>{this.keystrokes}</span>
|
||||
}
|
||||
} else {
|
||||
return <span>Press any key</span>
|
||||
}
|
||||
}
|
||||
|
||||
renderKeyBindings () {
|
||||
if (this.partiallyMatchedBindings.length > 0) {
|
||||
return (
|
||||
<table className='table-condensed'>
|
||||
<tbody>
|
||||
{this.partiallyMatchedBindings.map((binding) => (
|
||||
<tr className='unused'>
|
||||
<td className='copy' onclick={() => this.copyKeybinding(binding)}><span className='icon icon-clippy' /></td>
|
||||
<td className='command'>{binding.command}</td>
|
||||
<td className='keystrokes'>{binding.keystrokes}</td>
|
||||
<td className='selector'>{binding.selector}</td>
|
||||
<td className='source' onclick={() => this.openKeybindingFile(binding.source)}>{binding.source}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
} else {
|
||||
let usedKeyBinding = ''
|
||||
if (this.usedKeyBinding) {
|
||||
usedKeyBinding = (
|
||||
<tr className='used'>
|
||||
<td className='copy' onclick={() => this.copyKeybinding(this.usedKeyBinding)}><span className='icon icon-clippy' /></td>
|
||||
<td className='command'>{this.usedKeyBinding.command}</td>
|
||||
<td className='selector'>{this.usedKeyBinding.selector}</td>
|
||||
<td className='source' onclick={() => this.openKeybindingFile(this.usedKeyBinding.source)}>{this.usedKeyBinding.source}</td>
|
||||
</tr>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<table className='table-condensed'>
|
||||
<tbody>
|
||||
{usedKeyBinding}
|
||||
{this.unusedKeyBindings.map((binding) => (
|
||||
<tr className='unused'>
|
||||
<td className='copy' onclick={() => this.copyKeybinding(binding)}><span className='icon icon-clippy' /></td>
|
||||
<td className='command'>{binding.command}</td>
|
||||
<td className='selector'>{binding.selector}</td>
|
||||
<td className='source' onclick={() => this.openKeybindingFile(binding.source)}>{binding.source}</td>
|
||||
</tr>
|
||||
))}
|
||||
{this.unmatchedKeyBindings.map((binding) => (
|
||||
<tr className='unmatched'>
|
||||
<td className='copy' onclick={() => this.copyKeybinding(binding)}><span className='icon icon-clippy' /></td>
|
||||
<td className='command'>{binding.command}</td>
|
||||
<td className='selector'>{binding.selector}</td>
|
||||
<td className='source' onclick={() => this.openKeybindingFile(binding.source)}>{binding.source}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
isInAsarArchive (pathToCheck) {
|
||||
const {resourcePath} = atom.getLoadSettings()
|
||||
return pathToCheck.startsWith(`${resourcePath}${path.sep}`) && path.extname(resourcePath) === '.asar'
|
||||
}
|
||||
|
||||
extractBundledKeymap (bundledKeymapPath) {
|
||||
const metadata = require(path.join(atom.getLoadSettings().resourcePath, 'package.json'))
|
||||
const bundledKeymaps = metadata ? metadata._atomKeymaps : {}
|
||||
const keymapName = path.basename(bundledKeymapPath)
|
||||
const extractedKeymapPath = path.join(require('temp').mkdirSync('atom-bundled-keymap-'), keymapName)
|
||||
fs.writeFileSync(
|
||||
extractedKeymapPath,
|
||||
JSON.stringify(bundledKeymaps[keymapName] || {}, null, 2)
|
||||
)
|
||||
return extractedKeymapPath
|
||||
}
|
||||
|
||||
extractBundledPackageKeymap (keymapRelativePath) {
|
||||
const packageName = keymapRelativePath.split(path.sep)[1]
|
||||
const keymapName = path.basename(keymapRelativePath)
|
||||
const metadata = atom.packages.packagesCache[packageName] || {}
|
||||
const keymaps = metadata.keymaps || {}
|
||||
const extractedKeymapPath = path.join(require('temp').mkdirSync('atom-bundled-keymap-'), keymapName)
|
||||
fs.writeFileSync(
|
||||
extractedKeymapPath,
|
||||
JSON.stringify(keymaps[keymapRelativePath] || {}, null, 2)
|
||||
)
|
||||
return extractedKeymapPath
|
||||
}
|
||||
|
||||
openKeybindingFile (keymapPath) {
|
||||
if (this.isInAsarArchive(keymapPath)) {
|
||||
keymapPath = this.extractBundledKeymap(keymapPath)
|
||||
} else if (keymapPath.startsWith('core:node_modules')) {
|
||||
keymapPath = this.extractBundledPackageKeymap(keymapPath.replace('core:', ''))
|
||||
} else if (keymapPath.startsWith('core:')) {
|
||||
keymapPath = this.extractBundledKeymap(keymapPath.replace('core:', ''))
|
||||
}
|
||||
|
||||
atom.workspace.open(keymapPath)
|
||||
}
|
||||
|
||||
copyKeybinding (binding) {
|
||||
let content
|
||||
const keymapExtension = path.extname(atom.keymaps.getUserKeymapPath())
|
||||
let escapedKeystrokes = binding.keystrokes.replace(/\\/g, '\\\\') // Escape backslashes
|
||||
if (keymapExtension === '.cson') {
|
||||
content = `\
|
||||
'${binding.selector}':
|
||||
'${escapedKeystrokes}': '${binding.command}'
|
||||
`
|
||||
} else {
|
||||
content = `\
|
||||
"${binding.selector}": {
|
||||
"${escapedKeystrokes}": "${binding.command}"
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
atom.notifications.addInfo('Keybinding Copied')
|
||||
return atom.clipboard.write(content)
|
||||
}
|
||||
}
|
33
packages/keybinding-resolver/lib/main.js
Normal file
33
packages/keybinding-resolver/lib/main.js
Normal file
@ -0,0 +1,33 @@
|
||||
const {CompositeDisposable} = require('atom')
|
||||
|
||||
const KeyBindingResolverView = require('./keybinding-resolver-view')
|
||||
|
||||
const KEYBINDING_RESOLVER_URI = 'atom://keybinding-resolver'
|
||||
|
||||
module.exports = {
|
||||
activate () {
|
||||
this.subscriptions = new CompositeDisposable()
|
||||
|
||||
this.subscriptions.add(atom.workspace.addOpener(uri => {
|
||||
if (uri === KEYBINDING_RESOLVER_URI) {
|
||||
return new KeyBindingResolverView()
|
||||
}
|
||||
}))
|
||||
|
||||
this.subscriptions.add(atom.commands.add('atom-workspace', {
|
||||
'key-binding-resolver:toggle': () => this.toggle()
|
||||
}))
|
||||
},
|
||||
|
||||
deactivate () {
|
||||
this.subscriptions.dispose()
|
||||
},
|
||||
|
||||
toggle () {
|
||||
atom.workspace.toggle(KEYBINDING_RESOLVER_URI)
|
||||
},
|
||||
|
||||
deserializeKeyBindingResolverView (serialized) {
|
||||
return new KeyBindingResolverView()
|
||||
}
|
||||
}
|
11
packages/keybinding-resolver/menus/keybinding-resolver.cson
Normal file
11
packages/keybinding-resolver/menus/keybinding-resolver.cson
Normal file
@ -0,0 +1,11 @@
|
||||
'menu': [
|
||||
{
|
||||
'label': 'Packages'
|
||||
'submenu': [
|
||||
'label': 'Keybinding Resolver'
|
||||
'submenu': [
|
||||
{ 'label': 'Toggle', 'command': 'key-binding-resolver:toggle' }
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
232
packages/keybinding-resolver/package-lock.json
generated
Normal file
232
packages/keybinding-resolver/package-lock.json
generated
Normal file
@ -0,0 +1,232 @@
|
||||
{
|
||||
"name": "keybinding-resolver",
|
||||
"version": "0.39.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "keybinding-resolver",
|
||||
"version": "0.39.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"etch": "0.9.0",
|
||||
"fs-plus": "^3.0.0",
|
||||
"temp": "^0.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"atom": ">=1.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/async": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
|
||||
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
|
||||
"integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz",
|
||||
"integrity": "sha1-cZfX6qm4fmSDkOph/GbIRCdCDfk=",
|
||||
"dependencies": {
|
||||
"balanced-match": "^0.4.1",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"node_modules/etch": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/etch/-/etch-0.9.0.tgz",
|
||||
"integrity": "sha1-CSJpiPLO4GkL3yCMyyXkFNXfrV8="
|
||||
},
|
||||
"node_modules/fs-plus": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.0.2.tgz",
|
||||
"integrity": "sha1-a19Sp3EolMTd6f2PgfqMYN8EHz0=",
|
||||
"dependencies": {
|
||||
"async": "^1.5.2",
|
||||
"mkdirp": "^0.5.1",
|
||||
"rimraf": "^2.5.2",
|
||||
"underscore-plus": "1.x"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-plus/node_modules/rimraf": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
|
||||
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
|
||||
"dependencies": {
|
||||
"glob": "^7.0.5"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
|
||||
"integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.2",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
|
||||
"integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
|
||||
"dependencies": {
|
||||
"minimist": "0.0.8"
|
||||
},
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp/node_modules/minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/temp": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/temp/-/temp-0.9.0.tgz",
|
||||
"integrity": "sha512-YfUhPQCJoNQE5N+FJQcdPz63O3x3sdT4Xju69Gj4iZe0lBKOtnAMi0SLj9xKhGkcGhsxThvTJ/usxtFPo438zQ==",
|
||||
"engines": [
|
||||
"node >=4.0.0"
|
||||
],
|
||||
"dependencies": {
|
||||
"rimraf": "~2.6.2"
|
||||
}
|
||||
},
|
||||
"node_modules/temp/node_modules/balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||
},
|
||||
"node_modules/temp/node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/temp/node_modules/glob": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
||||
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/temp/node_modules/minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/temp/node_modules/rimraf": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
|
||||
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/underscore": {
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
|
||||
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
|
||||
},
|
||||
"node_modules/underscore-plus": {
|
||||
"version": "1.6.8",
|
||||
"resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.6.8.tgz",
|
||||
"integrity": "sha512-88PrCeMKeAAC1L4xjSiiZ3Fg6kZOYrLpLGVPPeqKq/662DfQe/KTSKdSR/Q/tucKNnfW2MNAUGSCkDf8HmXC5Q==",
|
||||
"dependencies": {
|
||||
"underscore": "~1.8.3"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
}
|
||||
}
|
||||
}
|
19
packages/keybinding-resolver/package.json
Normal file
19
packages/keybinding-resolver/package.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "keybinding-resolver",
|
||||
"main": "./lib/main",
|
||||
"version": "0.39.1",
|
||||
"description": "Show what commands a keybinding resolves to",
|
||||
"license": "MIT",
|
||||
"repository": "https://github.com/pulsar-edit/pulsar",
|
||||
"engines": {
|
||||
"atom": ">=1.17.0"
|
||||
},
|
||||
"deserializers": {
|
||||
"keybinding-resolver/KeyBindingResolverView": "deserializeKeyBindingResolverView"
|
||||
},
|
||||
"dependencies": {
|
||||
"etch": "0.9.0",
|
||||
"fs-plus": "^3.0.0",
|
||||
"temp": "^0.9.0"
|
||||
}
|
||||
}
|
40
packages/keybinding-resolver/spec/async-spec-helpers.js
Normal file
40
packages/keybinding-resolver/spec/async-spec-helpers.js
Normal file
@ -0,0 +1,40 @@
|
||||
/** @babel */
|
||||
|
||||
export function beforeEach (fn) {
|
||||
global.beforeEach(function () {
|
||||
const result = fn()
|
||||
if (result instanceof Promise) {
|
||||
waitsForPromise(() => result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function afterEach (fn) {
|
||||
global.afterEach(function () {
|
||||
const result = fn()
|
||||
if (result instanceof Promise) {
|
||||
waitsForPromise(() => result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
['it', 'fit', 'ffit', 'fffit'].forEach(function (name) {
|
||||
module.exports[name] = function (description, fn) {
|
||||
global[name](description, function () {
|
||||
const result = fn()
|
||||
if (result instanceof Promise) {
|
||||
waitsForPromise(() => result)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
function waitsForPromise (fn) {
|
||||
const promise = fn()
|
||||
global.waitsFor('spec promise to resolve', function (done) {
|
||||
promise.then(done, function (error) {
|
||||
jasmine.getEnv().currentSpec.fail(error)
|
||||
done()
|
||||
})
|
||||
})
|
||||
}
|
@ -0,0 +1,180 @@
|
||||
const {it, fit, ffit, beforeEach} = require('./async-spec-helpers') // eslint-disable-line no-unused-vars
|
||||
const etch = require('etch')
|
||||
|
||||
describe('KeyBindingResolverView', () => {
|
||||
let workspaceElement, bottomDockElement
|
||||
|
||||
beforeEach(async () => {
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
bottomDockElement = atom.views.getView(atom.workspace.getBottomDock())
|
||||
await atom.packages.activatePackage('keybinding-resolver')
|
||||
jasmine.attachToDOM(workspaceElement);
|
||||
})
|
||||
|
||||
describe('when the key-binding-resolver:toggle event is triggered', () => {
|
||||
it('toggles the view', async () => {
|
||||
expect(atom.workspace.getBottomDock().isVisible()).toBe(false)
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver')).not.toExist()
|
||||
|
||||
await atom.commands.dispatch(workspaceElement, 'key-binding-resolver:toggle')
|
||||
expect(atom.workspace.getBottomDock().isVisible()).toBe(true)
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver')).toExist()
|
||||
|
||||
await atom.commands.dispatch(workspaceElement, 'key-binding-resolver:toggle')
|
||||
expect(atom.workspace.getBottomDock().isVisible()).toBe(false)
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver')).toExist()
|
||||
|
||||
await atom.commands.dispatch(workspaceElement, 'key-binding-resolver:toggle')
|
||||
expect(atom.workspace.getBottomDock().isVisible()).toBe(true)
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver')).toExist()
|
||||
})
|
||||
|
||||
it('focuses the view if it is not visible instead of destroying it', async () => {
|
||||
expect(atom.workspace.getBottomDock().isVisible()).toBe(false)
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver')).not.toExist()
|
||||
|
||||
await atom.commands.dispatch(workspaceElement, 'key-binding-resolver:toggle')
|
||||
expect(atom.workspace.getBottomDock().isVisible()).toBe(true)
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver')).toExist()
|
||||
|
||||
atom.workspace.getBottomDock().hide()
|
||||
await atom.commands.dispatch(workspaceElement, 'key-binding-resolver:toggle')
|
||||
|
||||
expect(atom.workspace.getBottomDock().isVisible()).toBe(true)
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver')).toExist()
|
||||
})
|
||||
})
|
||||
|
||||
describe('capturing keybinding events', () => {
|
||||
it('captures events when the keybinding resolver is visible', async () => {
|
||||
await atom.commands.dispatch(workspaceElement, 'key-binding-resolver:toggle')
|
||||
const keybindingResolverView = atom.workspace.getBottomDock().getActivePaneItem()
|
||||
expect(keybindingResolverView.keybindingDisposables).not.toBe(null)
|
||||
|
||||
document.dispatchEvent(atom.keymaps.constructor.buildKeydownEvent('x', {target: bottomDockElement}))
|
||||
await etch.getScheduler().getNextUpdatePromise()
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver .keystroke').textContent).toBe('x')
|
||||
})
|
||||
|
||||
it('does not capture events when the keybinding resolver is not the active pane item', async () => {
|
||||
await atom.commands.dispatch(workspaceElement, 'key-binding-resolver:toggle')
|
||||
const keybindingResolverView = atom.workspace.getBottomDock().getActivePaneItem()
|
||||
expect(keybindingResolverView.keybindingDisposables).not.toBe(null)
|
||||
|
||||
atom.workspace.getBottomDock().getActivePane().splitRight()
|
||||
expect(keybindingResolverView.keybindingDisposables).toBe(null)
|
||||
|
||||
atom.workspace.getBottomDock().getActivePane().destroy()
|
||||
document.dispatchEvent(atom.keymaps.constructor.buildKeydownEvent('x', {target: bottomDockElement}))
|
||||
await etch.getScheduler().getNextUpdatePromise()
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver .keystroke').textContent).toBe('x')
|
||||
})
|
||||
|
||||
it('does not capture events when the dock the keybinding resolver is in is not visible', async () => {
|
||||
await atom.commands.dispatch(workspaceElement, 'key-binding-resolver:toggle')
|
||||
const keybindingResolverView = atom.workspace.getBottomDock().getActivePaneItem()
|
||||
expect(keybindingResolverView.keybindingDisposables).not.toBe(null)
|
||||
|
||||
atom.workspace.getBottomDock().hide()
|
||||
expect(keybindingResolverView.keybindingDisposables).toBe(null)
|
||||
|
||||
atom.workspace.getBottomDock().show()
|
||||
document.dispatchEvent(atom.keymaps.constructor.buildKeydownEvent('x', {target: bottomDockElement}))
|
||||
await etch.getScheduler().getNextUpdatePromise()
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver .keystroke').textContent).toBe('x')
|
||||
})
|
||||
})
|
||||
|
||||
describe('when a keydown event occurs', () => {
|
||||
it('displays all commands for the keydown event but does not clear for the keyup when there is no keyup binding', async () => {
|
||||
atom.keymaps.add('name', {
|
||||
'.workspace': {
|
||||
'x': 'match-1'
|
||||
}
|
||||
})
|
||||
atom.keymaps.add('name', {
|
||||
'.workspace': {
|
||||
'x': 'match-2'
|
||||
}
|
||||
})
|
||||
atom.keymaps.add('name', {
|
||||
'.never-again': {
|
||||
'x': 'unmatch-2'
|
||||
}
|
||||
})
|
||||
|
||||
await atom.commands.dispatch(workspaceElement, 'key-binding-resolver:toggle')
|
||||
|
||||
document.dispatchEvent(atom.keymaps.constructor.buildKeydownEvent('x', {target: bottomDockElement}))
|
||||
await etch.getScheduler().getNextUpdatePromise()
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver .keystroke').textContent).toBe('x')
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .used')).toHaveLength(1)
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .unused')).toHaveLength(1)
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .unmatched')).toHaveLength(1)
|
||||
|
||||
// It should not render the keyup event data because there is no match
|
||||
spyOn(etch.getScheduler(), 'updateDocument').andCallThrough()
|
||||
document.dispatchEvent(atom.keymaps.constructor.buildKeyupEvent('x', {target: bottomDockElement}))
|
||||
expect(etch.getScheduler().updateDocument).not.toHaveBeenCalled()
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver .keystroke').textContent).toBe('x')
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .used')).toHaveLength(1)
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .unused')).toHaveLength(1)
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .unmatched')).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('displays all commands for the keydown event but does not clear for the keyup when there is no keyup binding', async () => {
|
||||
atom.keymaps.add('name', {
|
||||
'.workspace': {
|
||||
'x': 'match-1'
|
||||
}
|
||||
})
|
||||
atom.keymaps.add('name', {
|
||||
'.workspace': {
|
||||
'x ^x': 'match-2'
|
||||
}
|
||||
})
|
||||
atom.keymaps.add('name', {
|
||||
'.workspace': {
|
||||
'a ^a': 'match-3'
|
||||
}
|
||||
})
|
||||
atom.keymaps.add('name', {
|
||||
'.never-again': {
|
||||
'x': 'unmatch-2'
|
||||
}
|
||||
})
|
||||
|
||||
await atom.commands.dispatch(workspaceElement, 'key-binding-resolver:toggle')
|
||||
|
||||
// Not partial because it dispatches the command for `x` immediately due to only having keyup events in remainder of partial match
|
||||
document.dispatchEvent(atom.keymaps.constructor.buildKeydownEvent('x', {target: bottomDockElement}))
|
||||
await etch.getScheduler().getNextUpdatePromise()
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver .keystroke').textContent).toBe('x')
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .used')).toHaveLength(1)
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .unused')).toHaveLength(0)
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .unmatched')).toHaveLength(1)
|
||||
|
||||
// It should not render the keyup event data because there is no match
|
||||
document.dispatchEvent(atom.keymaps.constructor.buildKeyupEvent('x', {target: bottomDockElement}))
|
||||
await etch.getScheduler().getNextUpdatePromise()
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver .keystroke').textContent).toBe('x ^x')
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .used')).toHaveLength(1)
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .unused')).toHaveLength(0)
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .unmatched')).toHaveLength(0)
|
||||
|
||||
document.dispatchEvent(atom.keymaps.constructor.buildKeydownEvent('a', {target: bottomDockElement}))
|
||||
await etch.getScheduler().getNextUpdatePromise()
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver .keystroke').textContent).toBe('a (partial)')
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .used')).toHaveLength(0)
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .unused')).toHaveLength(1)
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .unmatched')).toHaveLength(0)
|
||||
|
||||
document.dispatchEvent(atom.keymaps.constructor.buildKeyupEvent('a', {target: bottomDockElement}))
|
||||
await etch.getScheduler().getNextUpdatePromise()
|
||||
expect(bottomDockElement.querySelector('.key-binding-resolver .keystroke').textContent).toBe('a ^a')
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .used')).toHaveLength(1)
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .unused')).toHaveLength(0)
|
||||
expect(bottomDockElement.querySelectorAll('.key-binding-resolver .unmatched')).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
})
|
64
packages/keybinding-resolver/styles/keybinding-resolver.less
Normal file
64
packages/keybinding-resolver/styles/keybinding-resolver.less
Normal file
@ -0,0 +1,64 @@
|
||||
@import "ui-variables";
|
||||
@import "octicon-mixins";
|
||||
|
||||
.key-binding-resolver {
|
||||
overflow: auto;
|
||||
|
||||
.panel-heading {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
padding: 0 @component-padding;
|
||||
}
|
||||
|
||||
table {
|
||||
|
||||
tr:not(:last-child) {
|
||||
border-bottom: 1px solid @base-border-color;
|
||||
}
|
||||
|
||||
.used {
|
||||
color: @text-color-success;
|
||||
}
|
||||
|
||||
.unused {
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.unmatched {
|
||||
color: @text-color-subtle;
|
||||
}
|
||||
|
||||
// move icon so text is aligned when wrapped
|
||||
.command {
|
||||
padding-left: @component-icon-size;
|
||||
&:before {
|
||||
position: absolute;
|
||||
margin-left: -@component-icon-size;
|
||||
}
|
||||
}
|
||||
|
||||
.used .command,
|
||||
.unused .command {
|
||||
.octicon(check);
|
||||
}
|
||||
|
||||
.unmatched .command {
|
||||
.octicon(x);
|
||||
}
|
||||
|
||||
.command,
|
||||
.selector,
|
||||
.source {
|
||||
min-width: 10em;
|
||||
word-break: break-word; // wrap long path names
|
||||
}
|
||||
|
||||
.source {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
1
packages/timecop/.gitignore
vendored
Normal file
1
packages/timecop/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
node_modules
|
14
packages/timecop/README.md
Normal file
14
packages/timecop/README.md
Normal file
@ -0,0 +1,14 @@
|
||||
# Timecop package
|
||||
|
||||
Displays information about where time is spent while Pulsar loads.
|
||||
|
||||
* Startup time
|
||||
* Compile cache
|
||||
* Package loading time
|
||||
* Package activation time
|
||||
* Theme loading time
|
||||
* Theme activation time
|
||||
|
||||
![](https://cloud.githubusercontent.com/assets/378023/20422582/9e5907f8-adae-11e6-8267-faa3514de896.png)
|
||||
|
||||
Inspired by [Timecop](http://www.imdb.com/title/tt0111438/) the movie. :watch: :rotating_light:
|
100
packages/timecop/lib/cache-panel-view.js
Normal file
100
packages/timecop/lib/cache-panel-view.js
Normal file
@ -0,0 +1,100 @@
|
||||
/** @babel */
|
||||
/** @jsx etch.dom */
|
||||
|
||||
import path from 'path'
|
||||
import etch from 'etch'
|
||||
|
||||
export default class CachePanelView {
|
||||
constructor () {
|
||||
etch.initialize(this)
|
||||
}
|
||||
|
||||
update () {}
|
||||
|
||||
destroy () {
|
||||
return etch.destroy(this)
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className='tool-panel padded package-panel'>
|
||||
<div className='inset-panel'>
|
||||
<div className='panel-heading'>Compile Cache</div>
|
||||
<div className='panel-body padded'>
|
||||
<div className='timing'>
|
||||
<span className='inline-block'>CoffeeScript files compiled</span>
|
||||
<span className='inline-block' ref='coffeeCompileCount'>Loading…</span>
|
||||
</div>
|
||||
|
||||
<div className='timing'>
|
||||
<span className='inline-block'>Babel files compiled</span>
|
||||
<span className='inline-block' ref='babelCompileCount'>Loading…</span>
|
||||
</div>
|
||||
|
||||
<div className='timing'>
|
||||
<span className='inline-block'>Typescript files compiled</span>
|
||||
<span className='inline-block' ref='typescriptCompileCount'>Loading…</span>
|
||||
</div>
|
||||
|
||||
<div className='timing'>
|
||||
<span className='inline-block'>CSON files compiled</span>
|
||||
<span className='inline-block' ref='csonCompileCount'>Loading…</span>
|
||||
</div>
|
||||
|
||||
<div className='timing'>
|
||||
<span className='inline-block'>Less files compiled</span>
|
||||
<span className='inline-block' ref='lessCompileCount'>Loading…</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
populate () {
|
||||
const compileCacheStats = this.getCompileCacheStats()
|
||||
if (compileCacheStats) {
|
||||
this.refs.coffeeCompileCount.classList.add('highlight-info')
|
||||
this.refs.coffeeCompileCount.textContent = compileCacheStats['.coffee'].misses
|
||||
this.refs.babelCompileCount.classList.add('highlight-info')
|
||||
this.refs.babelCompileCount.textContent = compileCacheStats['.js'].misses
|
||||
this.refs.typescriptCompileCount.classList.add('highlight-info')
|
||||
this.refs.typescriptCompileCount.textContent = compileCacheStats['.ts'].misses
|
||||
}
|
||||
|
||||
this.refs.csonCompileCount.classList.add('highlight-info')
|
||||
this.refs.csonCompileCount.textContent = this.getCsonCompiles()
|
||||
this.refs.lessCompileCount.classList.add('highlight-info')
|
||||
this.refs.lessCompileCount.textContent = this.getLessCompiles()
|
||||
}
|
||||
|
||||
getCompileCacheStats () {
|
||||
try {
|
||||
return require(path.join(atom.getLoadSettings().resourcePath, 'src', 'compile-cache')).getCacheStats()
|
||||
} catch (error) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
getCsonCompiles () {
|
||||
try {
|
||||
const CSON = require(path.join(atom.getLoadSettings().resourcePath, 'node_modules', 'season'))
|
||||
if (CSON.getCacheMisses) {
|
||||
return CSON.getCacheMisses() || 0
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
} catch (error) {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
getLessCompiles () {
|
||||
const lessCache = atom.themes.lessCache
|
||||
if (lessCache && lessCache.cache && lessCache.cache.stats && lessCache.cache.stats.misses) {
|
||||
return lessCache.cache.stats.misses || 0
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
24
packages/timecop/lib/main.js
Normal file
24
packages/timecop/lib/main.js
Normal file
@ -0,0 +1,24 @@
|
||||
const {CompositeDisposable} = require('atom')
|
||||
|
||||
let TimecopView = null
|
||||
const ViewURI = 'atom://timecop'
|
||||
|
||||
module.exports = {
|
||||
activate () {
|
||||
this.subscriptions = new CompositeDisposable()
|
||||
this.subscriptions.add(atom.workspace.addOpener(filePath => {
|
||||
if (filePath === ViewURI) return this.createTimecopView({uri: ViewURI})
|
||||
}))
|
||||
|
||||
this.subscriptions.add(atom.commands.add('atom-workspace', 'timecop:view', () => atom.workspace.open(ViewURI)))
|
||||
},
|
||||
|
||||
deactivate () {
|
||||
this.subscriptions.dispose()
|
||||
},
|
||||
|
||||
createTimecopView (state) {
|
||||
if (TimecopView == null) TimecopView = require('./timecop-view')
|
||||
return new TimecopView(state)
|
||||
}
|
||||
}
|
70
packages/timecop/lib/package-panel-view.js
Normal file
70
packages/timecop/lib/package-panel-view.js
Normal file
@ -0,0 +1,70 @@
|
||||
/** @babel */
|
||||
/** @jsx etch.dom */
|
||||
|
||||
import {Disposable} from 'atom'
|
||||
import etch from 'etch'
|
||||
|
||||
export default class PackagePanelView {
|
||||
constructor ({title}) {
|
||||
this.title = title
|
||||
etch.initialize(this)
|
||||
|
||||
const clickHandler = (event) => {
|
||||
const target = event.target.closest('a.package')
|
||||
if (target) {
|
||||
atom.workspace.open(`atom://config/packages/${target.dataset.package}`)
|
||||
}
|
||||
}
|
||||
this.element.addEventListener('click', clickHandler)
|
||||
this.disposable = new Disposable(() => { this.element.removeEventListener('click', clickHandler) })
|
||||
}
|
||||
|
||||
update () {}
|
||||
|
||||
destroy () {
|
||||
this.disposable.dispose()
|
||||
return etch.destroy(this)
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className='tool-panel padded package-panel'>
|
||||
<div className='inset-panel'>
|
||||
<div className='panel-heading'>{this.title}</div>
|
||||
<div className='panel-body padded'>
|
||||
<div className='text-info' ref='summary'>Loading…</div>
|
||||
<ul className='list-group' ref='list' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
addPackages (packages, timeKey) {
|
||||
for (const pack of packages) {
|
||||
this.addPackage(pack, timeKey)
|
||||
}
|
||||
}
|
||||
|
||||
addPackage (pack, timeKey) {
|
||||
const li = document.createElement('div')
|
||||
li.classList.add('list-item')
|
||||
|
||||
const a = document.createElement('a')
|
||||
a.classList.add('inline-block', 'package')
|
||||
a.dataset.package = pack.name
|
||||
a.textContent = pack.name
|
||||
li.appendChild(a)
|
||||
|
||||
const line = document.createElement('span')
|
||||
line.classList.add('timecop-line')
|
||||
li.appendChild(line)
|
||||
|
||||
const timeSpan = document.createElement('span')
|
||||
timeSpan.classList.add('inline-block', pack[timeKey] > 25 ? 'highlight-error' : 'highlight-warning')
|
||||
timeSpan.textContent = `${pack[timeKey]}ms`
|
||||
li.appendChild(timeSpan)
|
||||
|
||||
this.refs.list.appendChild(li)
|
||||
}
|
||||
}
|
137
packages/timecop/lib/timecop-view.js
Normal file
137
packages/timecop/lib/timecop-view.js
Normal file
@ -0,0 +1,137 @@
|
||||
/** @babel */
|
||||
/** @jsx etch.dom */
|
||||
|
||||
import _ from 'underscore-plus'
|
||||
import dedent from 'dedent'
|
||||
import etch from 'etch'
|
||||
import CachePanelView from './cache-panel-view'
|
||||
import PackagePanelView from './package-panel-view'
|
||||
import WindowPanelView from './window-panel-view'
|
||||
|
||||
export default class TimecopView {
|
||||
constructor ({uri}) {
|
||||
this.uri = uri
|
||||
etch.initialize(this)
|
||||
this.refs.cacheLoadingPanel.populate()
|
||||
if (atom.packages.hasLoadedInitialPackages()) {
|
||||
this.populateLoadingViews()
|
||||
} else {
|
||||
atom.packages.onDidLoadInitialPackages(() => this.populateLoadingViews())
|
||||
}
|
||||
|
||||
if (atom.packages.hasActivatedInitialPackages()) {
|
||||
this.populateActivationViews()
|
||||
} else {
|
||||
atom.packages.onDidActivateInitialPackages(() => this.populateActivationViews())
|
||||
}
|
||||
}
|
||||
|
||||
update () {}
|
||||
|
||||
destroy () {
|
||||
return etch.destroy(this)
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className='timecop pane-item native-key-bindings' tabIndex='-1'>
|
||||
<div className='timecop-panel'>
|
||||
<div className='panels'>
|
||||
<WindowPanelView ref='windowLoadingPanel' />
|
||||
<CachePanelView ref='cacheLoadingPanel' />
|
||||
</div>
|
||||
<div className='panels'>
|
||||
<PackagePanelView ref='packageLoadingPanel' title='Package Loading' />
|
||||
<PackagePanelView ref='packageActivationPanel' title='Package Activation' />
|
||||
<PackagePanelView ref='themeLoadingPanel' title='Theme Loading' />
|
||||
<PackagePanelView ref='themeActivationPanel' title='Theme Activation' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
populateLoadingViews () {
|
||||
this.showLoadedPackages()
|
||||
this.showLoadedThemes()
|
||||
}
|
||||
|
||||
populateActivationViews () {
|
||||
this.refs.windowLoadingPanel.populate()
|
||||
this.showActivePackages()
|
||||
this.showActiveThemes()
|
||||
}
|
||||
|
||||
showLoadedPackages () {
|
||||
const {time, count, packages} = this.getSlowPackages(
|
||||
atom.packages.getLoadedPackages().filter(pack => pack.getType() !== 'theme'),
|
||||
'loadTime'
|
||||
)
|
||||
this.refs.packageLoadingPanel.addPackages(packages, 'loadTime')
|
||||
this.refs.packageLoadingPanel.refs.summary.textContent = dedent`
|
||||
Loaded ${count} packages in ${time}ms.
|
||||
${_.pluralize(packages.length, 'package')} took longer than 5ms to load.
|
||||
`
|
||||
}
|
||||
|
||||
showActivePackages () {
|
||||
const {time, count, packages} = this.getSlowPackages(
|
||||
atom.packages.getActivePackages().filter(pack => pack.getType() !== 'theme'),
|
||||
'activateTime'
|
||||
)
|
||||
this.refs.packageActivationPanel.addPackages(packages, 'activateTime')
|
||||
this.refs.packageActivationPanel.refs.summary.textContent = dedent`
|
||||
Activated ${count} packages in ${time}ms.
|
||||
${_.pluralize(packages.length, 'package')} took longer than 5ms to activate.\
|
||||
`
|
||||
}
|
||||
|
||||
showLoadedThemes () {
|
||||
const {time, count, packages} = this.getSlowPackages(atom.themes.getLoadedThemes(), 'loadTime')
|
||||
this.refs.themeLoadingPanel.addPackages(packages, 'loadTime')
|
||||
this.refs.themeLoadingPanel.refs.summary.textContent = dedent`
|
||||
Loaded ${count} themes in ${time}ms.
|
||||
${_.pluralize(packages.length, 'theme')} took longer than 5ms to load.\
|
||||
`
|
||||
}
|
||||
|
||||
showActiveThemes () {
|
||||
const {time, count, packages} = this.getSlowPackages(atom.themes.getActiveThemes(), 'activateTime')
|
||||
this.refs.themeActivationPanel.addPackages(packages, 'activateTime')
|
||||
this.refs.themeActivationPanel.refs.summary.textContent = dedent`
|
||||
Activated ${count} themes in ${time}ms.
|
||||
${_.pluralize(packages.length, 'theme')} took longer than 5ms to activate.\
|
||||
`
|
||||
}
|
||||
|
||||
getSlowPackages (packages, timeKey) {
|
||||
let time = 0
|
||||
let count = 0
|
||||
packages = packages.filter(function (pack) {
|
||||
time += pack[timeKey]
|
||||
count++
|
||||
return pack[timeKey] > 5
|
||||
})
|
||||
packages.sort((pack1, pack2) => pack2[timeKey] - pack1[timeKey])
|
||||
return {time, count, packages}
|
||||
}
|
||||
|
||||
serialize () {
|
||||
return {
|
||||
deserializer: this.constructor.name,
|
||||
uri: this.getURI()
|
||||
}
|
||||
}
|
||||
|
||||
getURI () {
|
||||
return this.uri
|
||||
}
|
||||
|
||||
getTitle () {
|
||||
return 'Timecop'
|
||||
}
|
||||
|
||||
getIconName () {
|
||||
return 'dashboard'
|
||||
}
|
||||
}
|
91
packages/timecop/lib/window-panel-view.js
Normal file
91
packages/timecop/lib/window-panel-view.js
Normal file
@ -0,0 +1,91 @@
|
||||
/** @babel */
|
||||
/** @jsx etch.dom */
|
||||
|
||||
import {CompositeDisposable} from 'atom'
|
||||
import etch from 'etch'
|
||||
|
||||
export default class WindowPanelView {
|
||||
constructor () {
|
||||
etch.initialize(this)
|
||||
|
||||
this.disposables = new CompositeDisposable()
|
||||
this.disposables.add(atom.tooltips.add(this.refs.shellTiming, {title: 'The time taken to launch the app'}))
|
||||
this.disposables.add(atom.tooltips.add(this.refs.windowTiming, {title: 'The time taken to load this window'}))
|
||||
this.disposables.add(atom.tooltips.add(this.refs.projectTiming, {title: 'The time taken to rebuild the previously opened buffers'}))
|
||||
this.disposables.add(atom.tooltips.add(this.refs.workspaceTiming, {title: 'The time taken to rebuild the previously opened editors'}))
|
||||
}
|
||||
|
||||
update () {}
|
||||
|
||||
destroy () {
|
||||
this.disposables.dispose()
|
||||
return etch.destroy(this)
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className='tool-panel padded package-panel'>
|
||||
<div className='inset-panel'>
|
||||
<div className='panel-heading'>Startup Time</div>
|
||||
<div className='panel-body padded'>
|
||||
<div className='timing' ref='shellTiming'>
|
||||
<span className='inline-block'>Shell load time</span>
|
||||
<span className='inline-block' ref='shellLoadTime'>Loading…</span>
|
||||
</div>
|
||||
|
||||
<div className='timing' ref='windowTiming'>
|
||||
<span className='inline-block'>Window load time</span>
|
||||
<span className='inline-block' ref='windowLoadTime'>Loading…</span>
|
||||
</div>
|
||||
|
||||
<div ref='deserializeTimings'>
|
||||
<div className='timing' ref='projectTiming'>
|
||||
<span className='inline-block'>Project load time</span>
|
||||
<span className='inline-block' ref='projectLoadTime'>Loading…</span>
|
||||
</div>
|
||||
|
||||
<div className='timing' ref='workspaceTiming'>
|
||||
<span className='inline-block'>Workspace load time</span>
|
||||
<span className='inline-block' ref='workspaceLoadTime'>Loading…</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
populate () {
|
||||
const time = atom.getWindowLoadTime()
|
||||
this.refs.windowLoadTime.classList.add(this.getHighlightClass(time))
|
||||
this.refs.windowLoadTime.textContent = `${time}ms`
|
||||
|
||||
const {shellLoadTime} = atom.getLoadSettings()
|
||||
if (shellLoadTime != null) {
|
||||
this.refs.shellLoadTime.classList.add(this.getHighlightClass(shellLoadTime))
|
||||
this.refs.shellLoadTime.textContent = `${shellLoadTime}ms`
|
||||
} else {
|
||||
this.refs.shellTiming.style.display = 'none'
|
||||
}
|
||||
|
||||
if (atom.deserializeTimings.project != null) {
|
||||
// Project and workspace timings only exist if the current project was previously opened
|
||||
this.refs.projectLoadTime.classList.add(this.getHighlightClass(atom.deserializeTimings.project))
|
||||
this.refs.projectLoadTime.textContent = `${atom.deserializeTimings.project}ms`
|
||||
this.refs.workspaceLoadTime.classList.add(this.getHighlightClass(atom.deserializeTimings.workspace))
|
||||
this.refs.workspaceLoadTime.textContent = `${atom.deserializeTimings.workspace}ms`
|
||||
} else {
|
||||
this.refs.deserializeTimings.style.display = 'none'
|
||||
}
|
||||
}
|
||||
|
||||
getHighlightClass (time) {
|
||||
if (time > 1000) {
|
||||
return 'highlight-error'
|
||||
} else if (time > 800) {
|
||||
return 'highlight-warning'
|
||||
} else {
|
||||
return 'highlight-info'
|
||||
}
|
||||
}
|
||||
}
|
10
packages/timecop/menus/timecop.cson
Normal file
10
packages/timecop/menus/timecop.cson
Normal file
@ -0,0 +1,10 @@
|
||||
'menu': [
|
||||
'label': 'Packages'
|
||||
'submenu': [
|
||||
'label': 'Timecop'
|
||||
'submenu': [
|
||||
'label': 'Show'
|
||||
'command': 'timecop:view'
|
||||
]
|
||||
]
|
||||
]
|
44
packages/timecop/package-lock.json
generated
Normal file
44
packages/timecop/package-lock.json
generated
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "timecop",
|
||||
"version": "0.36.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "timecop",
|
||||
"version": "0.36.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dedent": "^0.7.0",
|
||||
"etch": "^0.12.6",
|
||||
"underscore-plus": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"atom": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/dedent": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
|
||||
"integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA=="
|
||||
},
|
||||
"node_modules/etch": {
|
||||
"version": "0.12.8",
|
||||
"resolved": "https://registry.npmjs.org/etch/-/etch-0.12.8.tgz",
|
||||
"integrity": "sha512-dFLRe4wLroVtwzyy1vGlE3BSDZHiL0kZME5XgNGzZIULcYTvVno8vbiIleAesoKJmwWaxDTzG+4eppg2zk14JQ=="
|
||||
},
|
||||
"node_modules/underscore": {
|
||||
"version": "1.13.6",
|
||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
|
||||
"integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A=="
|
||||
},
|
||||
"node_modules/underscore-plus": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz",
|
||||
"integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==",
|
||||
"dependencies": {
|
||||
"underscore": "^1.9.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
19
packages/timecop/package.json
Normal file
19
packages/timecop/package.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "timecop",
|
||||
"version": "0.36.2",
|
||||
"description": "Displays information about where time is spent while Pulsar loads.",
|
||||
"main": "./lib/main",
|
||||
"repository": "https://github.com/pulsar-edit/pulsar",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"atom": "*"
|
||||
},
|
||||
"deserializers": {
|
||||
"TimecopView": "createTimecopView"
|
||||
},
|
||||
"dependencies": {
|
||||
"dedent": "^0.7.0",
|
||||
"etch": "^0.12.6",
|
||||
"underscore-plus": "^1.0.0"
|
||||
}
|
||||
}
|
103
packages/timecop/spec/async-spec-helpers.js
Normal file
103
packages/timecop/spec/async-spec-helpers.js
Normal file
@ -0,0 +1,103 @@
|
||||
/** @babel */
|
||||
|
||||
export function beforeEach (fn) {
|
||||
global.beforeEach(function () {
|
||||
const result = fn()
|
||||
if (result instanceof Promise) {
|
||||
waitsForPromise(() => result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function afterEach (fn) {
|
||||
global.afterEach(function () {
|
||||
const result = fn()
|
||||
if (result instanceof Promise) {
|
||||
waitsForPromise(() => result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
['it', 'fit', 'ffit', 'fffit'].forEach(function (name) {
|
||||
module.exports[name] = function (description, fn) {
|
||||
if (fn === undefined) {
|
||||
global[name](description)
|
||||
return
|
||||
}
|
||||
|
||||
global[name](description, function () {
|
||||
const result = fn()
|
||||
if (result instanceof Promise) {
|
||||
waitsForPromise(() => result)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
export async function conditionPromise (condition, description = 'anonymous condition') {
|
||||
const startTime = Date.now()
|
||||
|
||||
while (true) {
|
||||
await timeoutPromise(100)
|
||||
|
||||
if (await condition()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (Date.now() - startTime > 5000) {
|
||||
throw new Error('Timed out waiting on ' + description)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function timeoutPromise (timeout) {
|
||||
return new Promise(function (resolve) {
|
||||
global.setTimeout(resolve, timeout)
|
||||
})
|
||||
}
|
||||
|
||||
function waitsForPromise (fn) {
|
||||
const promise = fn()
|
||||
global.waitsFor('spec promise to resolve', function (done) {
|
||||
promise.then(done, function (error) {
|
||||
jasmine.getEnv().currentSpec.fail(error)
|
||||
done()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function emitterEventPromise (emitter, event, timeout = 15000) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const timeoutHandle = setTimeout(() => {
|
||||
reject(new Error(`Timed out waiting for '${event}' event`))
|
||||
}, timeout)
|
||||
emitter.once(event, () => {
|
||||
clearTimeout(timeoutHandle)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function promisify (original) {
|
||||
return function (...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
args.push((err, ...results) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(...results)
|
||||
}
|
||||
})
|
||||
|
||||
return original(...args)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function promisifySome (obj, fnNames) {
|
||||
const result = {}
|
||||
for (const fnName of fnNames) {
|
||||
result[fnName] = promisify(obj[fnName])
|
||||
}
|
||||
return result
|
||||
}
|
98
packages/timecop/spec/timecop-spec.js
Normal file
98
packages/timecop/spec/timecop-spec.js
Normal file
@ -0,0 +1,98 @@
|
||||
const path = require('path')
|
||||
const CompileCache = require(path.join(atom.getLoadSettings().resourcePath, 'src', 'compile-cache'))
|
||||
const CSON = require(path.join(atom.getLoadSettings().resourcePath, 'node_modules', 'season'))
|
||||
|
||||
const {it, fit, ffit, beforeEach, afterEach} = require('./async-spec-helpers') // eslint-disable-line no-unused-vars
|
||||
|
||||
describe('Timecop', () => {
|
||||
beforeEach(async () => {
|
||||
spyOn(CompileCache, 'getCacheStats').andReturn({
|
||||
'.js': {hits: 3, misses: 4},
|
||||
'.ts': {hits: 5, misses: 6},
|
||||
'.coffee': {hits: 7, misses: 8}
|
||||
})
|
||||
|
||||
spyOn(CSON, 'getCacheMisses').andReturn(10)
|
||||
|
||||
atom.themes.lessCache.cache.stats.misses = 12
|
||||
|
||||
await atom.packages.activatePackage('timecop')
|
||||
})
|
||||
|
||||
describe('the Timecop view', () => {
|
||||
let timecopView = null
|
||||
|
||||
beforeEach(async () => {
|
||||
const packages = [
|
||||
new FakePackage({
|
||||
name: 'slow-activating-package-1',
|
||||
activateTime: 500,
|
||||
loadTime: 5
|
||||
}),
|
||||
new FakePackage({
|
||||
name: 'slow-activating-package-2',
|
||||
activateTime: 500,
|
||||
loadTime: 5
|
||||
}),
|
||||
new FakePackage({
|
||||
name: 'slow-loading-package',
|
||||
activateTime: 5,
|
||||
loadTime: 500
|
||||
}),
|
||||
new FakePackage({
|
||||
name: 'fast-package',
|
||||
activateTime: 2,
|
||||
loadTime: 3
|
||||
})
|
||||
]
|
||||
|
||||
spyOn(atom.packages, 'getLoadedPackages').andReturn(packages)
|
||||
spyOn(atom.packages, 'getActivePackages').andReturn(packages)
|
||||
spyOn(atom.packages, 'hasLoadedInitialPackages').andReturn(true)
|
||||
spyOn(atom.packages, 'hasActivatedInitialPackages').andReturn(true)
|
||||
|
||||
timecopView = await atom.workspace.open('atom://timecop')
|
||||
})
|
||||
|
||||
afterEach(() => jasmine.unspy(atom.packages, 'getLoadedPackages'))
|
||||
|
||||
it('shows the packages that loaded slowly', () => {
|
||||
const loadingPanel = timecopView.refs.packageLoadingPanel
|
||||
expect(loadingPanel.element.textContent).toMatch(/1 package took longer than 5ms to load/)
|
||||
expect(loadingPanel.element.textContent).toMatch(/slow-loading-package/)
|
||||
|
||||
expect(loadingPanel.element.textContent).not.toMatch(/slow-activating-package/)
|
||||
expect(loadingPanel.element.textContent).not.toMatch(/fast-package/)
|
||||
})
|
||||
|
||||
it('shows the packages that activated slowly', () => {
|
||||
const activationPanel = timecopView.refs.packageActivationPanel
|
||||
expect(activationPanel.element.textContent).toMatch(/2 packages took longer than 5ms to activate/)
|
||||
expect(activationPanel.element.textContent).toMatch(/slow-activating-package-1/)
|
||||
expect(activationPanel.element.textContent).toMatch(/slow-activating-package-2/)
|
||||
|
||||
expect(activationPanel.element.textContent).not.toMatch(/slow-loading-package/)
|
||||
expect(activationPanel.element.textContent).not.toMatch(/fast-package/)
|
||||
})
|
||||
|
||||
it('shows how many files were transpiled from each language', () => {
|
||||
const cachePanel = timecopView.refs.cacheLoadingPanel
|
||||
|
||||
expect(cachePanel.element.textContent).toMatch(/CoffeeScript files compiled\s*8/)
|
||||
expect(cachePanel.element.textContent).toMatch(/Babel files compiled\s*4/)
|
||||
expect(cachePanel.element.textContent).toMatch(/Typescript files compiled\s*6/)
|
||||
expect(cachePanel.element.textContent).toMatch(/CSON files compiled\s*10/)
|
||||
expect(cachePanel.element.textContent).toMatch(/Less files compiled\s*12/)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
class FakePackage {
|
||||
constructor ({name, activateTime, loadTime}) {
|
||||
this.name = name
|
||||
this.activateTime = activateTime
|
||||
this.loadTime = loadTime
|
||||
}
|
||||
getType () { return 'package' }
|
||||
isTheme () { return false }
|
||||
}
|
69
packages/timecop/styles/timecop.less
Normal file
69
packages/timecop/styles/timecop.less
Normal file
@ -0,0 +1,69 @@
|
||||
@import "ui-variables";
|
||||
|
||||
.timecop {
|
||||
.timecop-panel {
|
||||
background-color: @tool-panel-background-color;
|
||||
}
|
||||
|
||||
overflow: auto;
|
||||
|
||||
.panels {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.package-panel {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex: 1;
|
||||
|
||||
.list-group {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.inset-panel {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.text-info {
|
||||
margin-bottom: @component-padding;
|
||||
}
|
||||
|
||||
.timing,
|
||||
.list-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.inline-block:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.timing {
|
||||
margin-bottom: @component-padding;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
margin-top: @component-padding / 2;;
|
||||
margin-bottom: @component-padding / 2;
|
||||
}
|
||||
|
||||
.package {
|
||||
color: @text-color;
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
color: @text-color-selected;
|
||||
}
|
||||
}
|
||||
.timecop-line {
|
||||
flex: 1 1 0;
|
||||
margin-right: @component-padding;
|
||||
margin-top: .80em;
|
||||
border-top: 1px dashed fade(@text-color, 20%);
|
||||
}
|
||||
|
||||
.package:hover + .timecop-line {
|
||||
border-color: fade(@text-color, 60%);
|
||||
}
|
||||
|
||||
}
|
14
yarn.lock
14
yarn.lock
@ -2379,11 +2379,8 @@ atom-slick@^2, atom-slick@^2.0.0:
|
||||
dependencies:
|
||||
underscore-plus "^1.7.0"
|
||||
|
||||
"autosave@https://codeload.github.com/atom/autosave/legacy.tar.gz/refs/tags/v0.24.6":
|
||||
"autosave@file:./packages/autosave":
|
||||
version "0.24.6"
|
||||
resolved "https://codeload.github.com/atom/autosave/legacy.tar.gz/refs/tags/v0.24.6#bbd25c3364cfa5b3c73f9d4d08da93aaac339020"
|
||||
dependencies:
|
||||
fs-plus "^3.0.0"
|
||||
|
||||
available-typed-arrays@^1.0.5:
|
||||
version "1.0.5"
|
||||
@ -6125,9 +6122,8 @@ key-path-helpers@^0.4.0:
|
||||
resolved "https://registry.yarnpkg.com/key-path-helpers/-/key-path-helpers-0.4.0.tgz#e87f6a159144adf2692e46f2a4641ce269c09119"
|
||||
integrity sha512-WGl1FG6zjyXCU6YrOVrvanyN3iiLFPLr/UmZ/jGiEOd7CXQV83/Ng5aLGK/Erehtr1nxU8dOwnRjseQDGElMQw==
|
||||
|
||||
"keybinding-resolver@https://codeload.github.com/atom/keybinding-resolver/legacy.tar.gz/refs/tags/v0.39.1":
|
||||
"keybinding-resolver@file:./packages/keybinding-resolver":
|
||||
version "0.39.1"
|
||||
resolved "https://codeload.github.com/atom/keybinding-resolver/legacy.tar.gz/refs/tags/v0.39.1#a1c08beb144cfca145bf19fe0830b2e82514d4cb"
|
||||
dependencies:
|
||||
etch "0.9.0"
|
||||
fs-plus "^3.0.0"
|
||||
@ -9293,9 +9289,8 @@ through@2, through@2.3.x, through@^2.3.8, through@~2.3, through@~2.3.1:
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
|
||||
|
||||
"timecop@https://codeload.github.com/atom/timecop/legacy.tar.gz/refs/tags/v0.36.2":
|
||||
"timecop@file:./packages/timecop":
|
||||
version "0.36.2"
|
||||
resolved "https://codeload.github.com/atom/timecop/legacy.tar.gz/refs/tags/v0.36.2#8965f20444701af3b6f86dfa9f144a46e1aaa9d0"
|
||||
dependencies:
|
||||
dedent "^0.7.0"
|
||||
etch "^0.12.6"
|
||||
@ -10001,9 +9996,8 @@ which@^2.0.1, which@^2.0.2:
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
"whitespace@https://codeload.github.com/atom/whitespace/legacy.tar.gz/refs/tags/v0.37.8":
|
||||
"whitespace@file:./packages/whitespace":
|
||||
version "0.37.8"
|
||||
resolved "https://codeload.github.com/atom/whitespace/legacy.tar.gz/refs/tags/v0.37.8#0c0510f8ead296d63a16105024700ec34b2b5d1b"
|
||||
|
||||
wide-align@1.1.3:
|
||||
version "1.1.3"
|
||||
|
Loading…
Reference in New Issue
Block a user