diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..3639ff8
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,12 @@
+{
+ "env": {
+ "jasmine": true
+ },
+ "globals": {
+ "waitsForPromise": true,
+ "atom": true
+ },
+ "rules": {
+ "no-template-curly-in-string": "off"
+ }
+}
diff --git a/.coffeelintignore b/.prettierignore
similarity index 100%
rename from .coffeelintignore
rename to .prettierignore
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..544138b
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,3 @@
+{
+ "singleQuote": true
+}
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
index b60bb86..bd8b5f5 100644
--- a/ISSUE_TEMPLATE.md
+++ b/ISSUE_TEMPLATE.md
@@ -8,12 +8,12 @@ Do you want to ask a question? Are you looking for support? The Atom message boa
### Prerequisites
-* [ ] Put an X between the brackets on this line if you have done all of the following:
- * Reproduced the problem in Safe Mode: http://flight-manual.atom.io/hacking-atom/sections/debugging/#using-safe-mode
- * Followed all applicable steps in the debugging guide: http://flight-manual.atom.io/hacking-atom/sections/debugging/
- * Checked the FAQs on the message board for common solutions: https://discuss.atom.io/c/faq
- * Checked that your issue isn't already filed: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aatom
- * Checked that there is not already an Atom package that provides the described functionality: https://atom.io/packages
+- [ ] Put an X between the brackets on this line if you have done all of the following:
+ - Reproduced the problem in Safe Mode: http://flight-manual.atom.io/hacking-atom/sections/debugging/#using-safe-mode
+ - Followed all applicable steps in the debugging guide: http://flight-manual.atom.io/hacking-atom/sections/debugging/
+ - Checked the FAQs on the message board for common solutions: https://discuss.atom.io/c/faq
+ - Checked that your issue isn't already filed: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aatom
+ - Checked that there is not already an Atom package that provides the described functionality: https://atom.io/packages
### Description
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
index cdaa94a..b4a55e7 100644
--- a/PULL_REQUEST_TEMPLATE.md
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -1,7 +1,7 @@
### Requirements
-* Filling out the template is required. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion.
-* All new code requires tests to ensure against regressions
+- Filling out the template is required. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion.
+- All new code requires tests to ensure against regressions
### Description of the Change
diff --git a/README.md b/README.md
index 267f42c..1526d2f 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,5 @@
# Snippets package
+
[![macOS Build Status](https://travis-ci.org/atom/snippets.svg?branch=master)](https://travis-ci.org/atom/snippets) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/8hlc0onofkgbxw53/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/snippets/branch/master) [![Dependency Status](https://david-dm.org/atom/snippets.svg)](https://david-dm.org/atom/snippets)
Expand snippets matching the current prefix with tab in Atom.
@@ -27,23 +28,25 @@ Under each snippet name is a `prefix` that should trigger the snippet and a `bod
The above example adds a `log` snippet to JavaScript files that would expand to.
```js
-console.log("crash");
+console.log('crash')
```
The string `"crash"` would be initially selected and pressing tab again would place the cursor after the `;`
### Optional parameters
+
These parameters are meant to provide extra information about your snippet to [autocomplete-plus](https://github.com/atom/autocomplete-plus/wiki/Provider-API).
-* `leftLabel` will add text to the left part of the autocomplete results box.
-* `leftLabelHTML` will overwrite what's in `leftLabel` and allow you to use a bit of CSS such as `color`.
-* `rightLabelHTML`. By default, in the right part of the results box you will see the name of the snippet. When using `rightLabelHTML` the name of the snippet will no longer be displayed, and you will be able to use a bit of CSS.
-* `description` will add text to a description box under the autocomplete results list.
-* `descriptionMoreURL` URL to the documentation of the snippet.
+- `leftLabel` will add text to the left part of the autocomplete results box.
+- `leftLabelHTML` will overwrite what's in `leftLabel` and allow you to use a bit of CSS such as `color`.
+- `rightLabelHTML`. By default, in the right part of the results box you will see the name of the snippet. When using `rightLabelHTML` the name of the snippet will no longer be displayed, and you will be able to use a bit of CSS.
+- `description` will add text to a description box under the autocomplete results list.
+- `descriptionMoreURL` URL to the documentation of the snippet.
![autocomplete-description](http://i.imgur.com/cvI2lOq.png)
Example:
+
```coffee
'.source.js':
'console.log':
@@ -55,7 +58,7 @@ Example:
### Determining the correct scope for a snippet
-The outmost key of a snippet is the "scope" that you want the descendent snippets to be available in. The key should be prefixed with a period (`text.html.basic` => `.text.html.basic`). You can find out the correct scope by opening the Settings (cmd-, on macOS) and selecting the corresponding *Language [xxx]* package, e.g. for *Language Html*:
+The outmost key of a snippet is the "scope" that you want the descendent snippets to be available in. The key should be prefixed with a period (`text.html.basic` => `.text.html.basic`). You can find out the correct scope by opening the Settings (cmd-, on macOS) and selecting the corresponding _Language [xxx]_ package, e.g. for _Language Html_:
![Screenshot of Language Html settings](https://cloud.githubusercontent.com/assets/1038121/5137632/126beb66-70f2-11e4-839b-bc7e84103f67.png)
@@ -68,9 +71,9 @@ This package supports a subset of the features of TextMate snippets, [documented
The following features are not yet supported:
-* Variables
-* Interpolated shell code
-* Conditional insertions in transformations
+- Variables
+- Interpolated shell code
+- Conditional insertions in transformations
### Multi-line Snippet Body
diff --git a/appveyor.yml b/appveyor.yml
index 2b0fde4..49981c8 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,10 +1,10 @@
-version: "{build}"
+version: '{build}'
platform: x64
branches:
- only:
- - master
+ only:
+ - master
clone_depth: 10
@@ -14,8 +14,8 @@ environment:
APM_TEST_PACKAGES:
matrix:
- - ATOM_CHANNEL: stable
- - ATOM_CHANNEL: beta
+ - ATOM_CHANNEL: stable
+ - ATOM_CHANNEL: beta
install:
- ps: Install-Product node 4
diff --git a/coffeelint.json b/coffeelint.json
deleted file mode 100644
index a5dd715..0000000
--- a/coffeelint.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "max_line_length": {
- "level": "ignore"
- },
- "no_empty_param_list": {
- "level": "error"
- },
- "arrow_spacing": {
- "level": "error"
- },
- "no_interpolation_in_single_quotes": {
- "level": "error"
- },
- "no_debugger": {
- "level": "error"
- },
- "prefer_english_operator": {
- "level": "error"
- },
- "colon_assignment_spacing": {
- "spacing": {
- "left": 0,
- "right": 1
- },
- "level": "error"
- },
- "braces_spacing": {
- "spaces": 0,
- "level": "error"
- },
- "spacing_after_comma": {
- "level": "error"
- },
- "no_stand_alone_at": {
- "level": "error"
- }
-}
diff --git a/lib/editor-store.js b/lib/editor-store.js
index c57cb7a..631b220 100644
--- a/lib/editor-store.js
+++ b/lib/editor-store.js
@@ -31,23 +31,32 @@ class EditorStore {
this.existingHistoryProvider = this.buffer.historyProvider
}
- const newProvider = SnippetHistoryProvider(this.existingHistoryProvider, delegates)
+ const newProvider = SnippetHistoryProvider(
+ this.existingHistoryProvider,
+ delegates
+ )
this.buffer.setHistoryProvider(newProvider)
}
stopObservingHistory (editor) {
- if (this.existingHistoryProvider == null) { return }
+ if (this.existingHistoryProvider == null) {
+ return
+ }
this.buffer.setHistoryProvider(this.existingHistoryProvider)
this.existingHistoryProvider = null
}
observe (callback) {
- if (this.observer != null) { this.observer.dispose() }
+ if (this.observer != null) {
+ this.observer.dispose()
+ }
this.observer = this.buffer.onDidChangeText(callback)
}
stopObserving () {
- if (this.observer == null) { return false }
+ if (this.observer == null) {
+ return false
+ }
this.observer.dispose()
this.observer = null
return true
diff --git a/lib/helpers.js b/lib/helpers.js
index 0814a3d..461e774 100644
--- a/lib/helpers.js
+++ b/lib/helpers.js
@@ -2,8 +2,8 @@
import path from 'path'
-export function getPackageRoot() {
- const {resourcePath} = atom.getLoadSettings()
+export function getPackageRoot () {
+ const { resourcePath } = atom.getLoadSettings()
const currentFileWasRequiredFromSnapshot = !path.isAbsolute(__dirname)
if (currentFileWasRequiredFromSnapshot) {
return path.join(resourcePath, 'node_modules', 'snippets')
diff --git a/lib/insertion.js b/lib/insertion.js
index 96065d1..02442d2 100644
--- a/lib/insertion.js
+++ b/lib/insertion.js
@@ -1,21 +1,21 @@
const ESCAPES = {
- u: (flags) => {
+ u: flags => {
flags.lowercaseNext = false
flags.uppercaseNext = true
},
- l: (flags) => {
+ l: flags => {
flags.uppercaseNext = false
flags.lowercaseNext = true
},
- U: (flags) => {
+ U: flags => {
flags.lowercaseAll = false
flags.uppercaseAll = true
},
- L: (flags) => {
+ L: flags => {
flags.uppercaseAll = false
flags.lowercaseAll = true
},
- E: (flags) => {
+ E: flags => {
flags.uppercaseAll = false
flags.lowercaseAll = false
},
@@ -62,21 +62,21 @@ class Insertion {
makeReplacer (replace) {
return function replacer (...match) {
- let flags = {
+ const flags = {
uppercaseAll: false,
lowercaseAll: false,
uppercaseNext: false,
lowercaseNext: false
}
replace = [...replace]
- let result = []
+ const result = []
replace.forEach(token => {
if (typeof token === 'string') {
result.push(transformText(token, flags))
} else if (token.escape) {
ESCAPES[token.escape](flags, result)
} else if (token.backreference) {
- let transformed = transformText(match[token.backreference], flags)
+ const transformed = transformText(match[token.backreference], flags)
result.push(transformed)
}
})
@@ -85,8 +85,10 @@ class Insertion {
}
transform (input) {
- let { substitution } = this
- if (!substitution) { return input }
+ const { substitution } = this
+ if (!substitution) {
+ return input
+ }
return input.replace(substitution.find, this.replacer)
}
}
diff --git a/lib/snippet-body-parser.js b/lib/snippet-body-parser.js
index d4293ec..a0deb53 100644
--- a/lib/snippet-body-parser.js
+++ b/lib/snippet-body-parser.js
@@ -2,13 +2,16 @@ let parser
try {
parser = require('./snippet-body')
} catch (error) {
- const {allowUnsafeEval} = require('loophole')
+ const { allowUnsafeEval } = require('loophole')
const fs = require('fs-plus')
const PEG = require('pegjs')
- const grammarSrc = fs.readFileSync(require.resolve('./snippet-body.pegjs'), 'utf8')
+ const grammarSrc = fs.readFileSync(
+ require.resolve('./snippet-body.pegjs'),
+ 'utf8'
+ )
parser = null
- allowUnsafeEval(() => parser = PEG.buildParser(grammarSrc))
+ allowUnsafeEval(() => (parser = PEG.buildParser(grammarSrc)))
}
module.exports = parser
diff --git a/lib/snippet-expansion.js b/lib/snippet-expansion.js
index 54a525b..3463cea 100644
--- a/lib/snippet-expansion.js
+++ b/lib/snippet-expansion.js
@@ -1,7 +1,7 @@
-const {CompositeDisposable, Range, Point} = require('atom')
+const { CompositeDisposable, Range, Point } = require('atom')
module.exports = class SnippetExpansion {
- constructor(snippet, editor, cursor, snippets) {
+ constructor (snippet, editor, cursor, snippets) {
this.settingTabStop = false
this.isIgnoringBufferChanges = false
this.onUndoOrRedo = this.onUndoOrRedo.bind(this)
@@ -9,15 +9,17 @@ module.exports = class SnippetExpansion {
this.editor = editor
this.cursor = cursor
this.snippets = snippets
- this.subscriptions = new CompositeDisposable
+ this.subscriptions = new CompositeDisposable()
this.tabStopMarkers = []
this.selections = [this.cursor.selection]
const startPosition = this.cursor.selection.getBufferRange().start
- let {body, tabStopList} = this.snippet
+ let { body, tabStopList } = this.snippet
let tabStops = tabStopList.toArray()
- let indent = this.editor.lineTextForBufferRow(startPosition.row).match(/^\s*/)[0]
+ const indent = this.editor
+ .lineTextForBufferRow(startPosition.row)
+ .match(/^\s*/)[0]
if (this.snippet.lineCount > 1 && indent) {
// Add proper leading indentation to the snippet
body = body.replace(/\n/g, `\n${indent}`)
@@ -28,10 +30,16 @@ module.exports = class SnippetExpansion {
this.editor.transact(() => {
this.ignoringBufferChanges(() => {
this.editor.transact(() => {
- const newRange = this.cursor.selection.insertText(body, {autoIndent: false})
+ const newRange = this.cursor.selection.insertText(body, {
+ autoIndent: false
+ })
if (this.snippet.tabStopList.length > 0) {
- this.subscriptions.add(this.cursor.onDidChangePosition(event => this.cursorMoved(event)))
- this.subscriptions.add(this.cursor.onDidDestroy(() => this.cursorDestroyed()))
+ this.subscriptions.add(
+ this.cursor.onDidChangePosition(event => this.cursorMoved(event))
+ )
+ this.subscriptions.add(
+ this.cursor.onDidDestroy(() => this.cursorDestroyed())
+ )
this.placeTabStopMarkers(startPosition, tabStops)
this.snippets.addExpansion(this.editor, this)
this.editor.normalizeTabsInBufferRange(newRange)
@@ -47,19 +55,31 @@ module.exports = class SnippetExpansion {
this.isUndoingOrRedoing = true
}
- cursorMoved ({oldBufferPosition, newBufferPosition, textChanged}) {
- if (this.settingTabStop || textChanged) { return }
- const itemWithCursor = this.tabStopMarkers[this.tabStopIndex].find(item => item.marker.getBufferRange().containsPoint(newBufferPosition))
+ cursorMoved ({ oldBufferPosition, newBufferPosition, textChanged }) {
+ if (this.settingTabStop || textChanged) {
+ return
+ }
+ const itemWithCursor = this.tabStopMarkers[this.tabStopIndex].find(item =>
+ item.marker.getBufferRange().containsPoint(newBufferPosition)
+ )
- if (itemWithCursor && !itemWithCursor.insertion.isTransformation()) { return }
+ if (itemWithCursor && !itemWithCursor.insertion.isTransformation()) {
+ return
+ }
this.destroy()
}
- cursorDestroyed () { if (!this.settingTabStop) { this.destroy() } }
+ cursorDestroyed () {
+ if (!this.settingTabStop) {
+ this.destroy()
+ }
+ }
textChanged (event) {
- if (this.isIgnoringBufferChanges) { return }
+ if (this.isIgnoringBufferChanges) {
+ return
+ }
// Don't try to alter the buffer if all we're doing is restoring a
// snapshot from history.
@@ -81,13 +101,16 @@ module.exports = class SnippetExpansion {
applyAllTransformations () {
this.editor.transact(() => {
this.tabStopMarkers.forEach((item, index) =>
- this.applyTransformations(index, true))
+ this.applyTransformations(index, true)
+ )
})
}
applyTransformations (tabStop, initial = false) {
const items = [...this.tabStopMarkers[tabStop]]
- if (items.length === 0) { return }
+ if (items.length === 0) {
+ return
+ }
const primary = items.shift()
const primaryRange = primary.marker.getBufferRange()
@@ -95,15 +118,19 @@ module.exports = class SnippetExpansion {
this.ignoringBufferChanges(() => {
for (const item of items) {
- const {marker, insertion} = item
+ const { marker, insertion } = item
var range = marker.getBufferRange()
// Don't transform mirrored tab stops. They have their own cursors, so
// mirroring happens automatically.
- if (!insertion.isTransformation()) { continue }
+ if (!insertion.isTransformation()) {
+ continue
+ }
var outputText = insertion.transform(inputText)
- this.editor.transact(() => this.editor.setTextInBufferRange(range, outputText))
+ this.editor.transact(() =>
+ this.editor.setTextInBufferRange(range, outputText)
+ )
const newRange = new Range(
range.start,
range.start.traverse(new Point(0, outputText.length))
@@ -115,14 +142,16 @@ module.exports = class SnippetExpansion {
placeTabStopMarkers (startPosition, tabStops) {
for (const tabStop of tabStops) {
- const {insertions} = tabStop
+ const { insertions } = tabStop
const markers = []
- if (!tabStop.isValid()) { continue }
+ if (!tabStop.isValid()) {
+ continue
+ }
for (const insertion of insertions) {
- const {range} = insertion
- const {start, end} = range
+ const { range } = insertion
+ const { start, end } = range
const marker = this.getMarkerLayer(this.editor).markBufferRange([
startPosition.traverse(start),
startPosition.traverse(end)
@@ -164,7 +193,9 @@ module.exports = class SnippetExpansion {
}
goToPreviousTabStop () {
- if (this.tabStopIndex > 0) { this.setTabStopIndex(this.tabStopIndex - 1) }
+ if (this.tabStopIndex > 0) {
+ this.setTabStopIndex(this.tabStopIndex - 1)
+ }
}
setTabStopIndex (tabStopIndex) {
@@ -173,14 +204,20 @@ module.exports = class SnippetExpansion {
let markerSelected = false
const items = this.tabStopMarkers[this.tabStopIndex]
- if (items.length === 0) { return false }
+ if (items.length === 0) {
+ return false
+ }
const ranges = []
this.hasTransforms = false
for (const item of items) {
- const {marker, insertion} = item
- if (marker.isDestroyed()) { continue }
- if (!marker.isValid()) { continue }
+ const { marker, insertion } = item
+ if (marker.isDestroyed()) {
+ continue
+ }
+ if (!marker.isValid()) {
+ continue
+ }
if (insertion.isTransformation()) {
this.hasTransforms = true
continue
@@ -189,7 +226,9 @@ module.exports = class SnippetExpansion {
}
if (ranges.length > 0) {
- for (const selection of this.selections.slice(ranges.length)) { selection.destroy() }
+ for (const selection of this.selections.slice(ranges.length)) {
+ selection.destroy()
+ }
this.selections = this.selections.slice(0, ranges.length)
for (let i = 0; i < ranges.length; i++) {
const range = ranges[i]
@@ -197,8 +236,14 @@ module.exports = class SnippetExpansion {
this.selections[i].setBufferRange(range)
} else {
const newSelection = this.editor.addSelectionForBufferRange(range)
- this.subscriptions.add(newSelection.cursor.onDidChangePosition(event => this.cursorMoved(event)))
- this.subscriptions.add(newSelection.cursor.onDidDestroy(() => this.cursorDestroyed()))
+ this.subscriptions.add(
+ newSelection.cursor.onDidChangePosition(event =>
+ this.cursorMoved(event)
+ )
+ )
+ this.subscriptions.add(
+ newSelection.cursor.onDidDestroy(() => this.cursorDestroyed())
+ )
this.selections.push(newSelection)
}
}
@@ -208,16 +253,22 @@ module.exports = class SnippetExpansion {
this.settingTabStop = false
// If this snippet has at least one transform, we need to observe changes
// made to the editor so that we can update the transformed tab stops.
- if (this.hasTransforms) { this.snippets.observeEditor(this.editor) }
+ if (this.hasTransforms) {
+ this.snippets.observeEditor(this.editor)
+ }
return markerSelected
}
goToEndOfLastTabStop () {
- if (this.tabStopMarkers.length === 0) { return }
+ if (this.tabStopMarkers.length === 0) {
+ return
+ }
const items = this.tabStopMarkers[this.tabStopMarkers.length - 1]
- if (items.length === 0) { return }
- const {marker: lastMarker} = items[items.length - 1]
+ if (items.length === 0) {
+ return
+ }
+ const { marker: lastMarker } = items[items.length - 1]
if (lastMarker.isDestroyed()) {
return false
} else {
diff --git a/lib/snippet-history-provider.js b/lib/snippet-history-provider.js
index b1b3e57..0c78f3f 100644
--- a/lib/snippet-history-provider.js
+++ b/lib/snippet-history-provider.js
@@ -1,5 +1,5 @@
function wrap (manager, callbacks) {
- let klass = new SnippetHistoryProvider(manager)
+ const klass = new SnippetHistoryProvider(manager)
return new Proxy(manager, {
get (target, name) {
if (name in callbacks) {
diff --git a/lib/snippet.js b/lib/snippet.js
index fcdfed9..e22a283 100644
--- a/lib/snippet.js
+++ b/lib/snippet.js
@@ -1,8 +1,18 @@
-const {Range} = require('atom')
+const { Range } = require('atom')
const TabStopList = require('./tab-stop-list')
module.exports = class Snippet {
- constructor({name, prefix, bodyText, description, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML, bodyTree}) {
+ constructor ({
+ name,
+ prefix,
+ bodyText,
+ description,
+ descriptionMoreURL,
+ rightLabelHTML,
+ leftLabel,
+ leftLabelHTML,
+ bodyTree
+ }) {
this.name = name
this.prefix = prefix
this.bodyText = bodyText
@@ -21,11 +31,13 @@ module.exports = class Snippet {
let column = 0
// recursive helper function; mutates vars above
- let extractTabStops = bodyTree => {
+ const extractTabStops = bodyTree => {
for (const segment of bodyTree) {
if (segment.index != null) {
- let {index, content, substitution} = segment
- if (index === 0) { index = Infinity; }
+ let { index, content, substitution } = segment
+ if (index === 0) {
+ index = Infinity
+ }
const start = [row, column]
extractTabStops(content)
const range = new Range(start, [row, column])
diff --git a/lib/snippets-available.js b/lib/snippets-available.js
index d244cb1..db53687 100644
--- a/lib/snippets-available.js
+++ b/lib/snippets-available.js
@@ -9,8 +9,8 @@ export default class SnippetsAvailable {
this.snippets = snippets
this.selectListView = new SelectListView({
items: [],
- filterKeyForItem: (snippet) => snippet.searchText,
- elementForItem: (snippet) => {
+ filterKeyForItem: snippet => snippet.searchText,
+ elementForItem: snippet => {
const li = document.createElement('li')
li.classList.add('two-lines')
@@ -26,7 +26,7 @@ export default class SnippetsAvailable {
return li
},
- didConfirmSelection: (snippet) => {
+ didConfirmSelection: snippet => {
for (const cursor of this.editor.getCursors()) {
this.snippets.insert(snippet.bodyText, this.editor, cursor)
}
@@ -70,15 +70,15 @@ export default class SnippetsAvailable {
populate () {
const snippets = Object.values(this.snippets.getSnippets(this.editor))
- for (let snippet of snippets) {
+ for (const snippet of snippets) {
snippet.searchText = _.compact([snippet.prefix, snippet.name]).join(' ')
}
- return this.selectListView.update({items: snippets})
+ return this.selectListView.update({ items: snippets })
}
attach () {
this.previouslyFocusedElement = document.activeElement
- this.panel = atom.workspace.addModalPanel({item: this})
+ this.panel = atom.workspace.addModalPanel({ item: this })
this.selectListView.focus()
}
}
diff --git a/lib/snippets.js b/lib/snippets.js
index 8e67ec0..81419d1 100644
--- a/lib/snippets.js
+++ b/lib/snippets.js
@@ -1,5 +1,5 @@
const path = require('path')
-const {Emitter, Disposable, CompositeDisposable, File} = require('atom')
+const { Emitter, Disposable, CompositeDisposable, File } = require('atom')
const _ = require('underscore-plus')
const async = require('async')
const CSON = require('season')
@@ -9,72 +9,87 @@ const ScopedPropertyStore = require('scoped-property-store')
const Snippet = require('./snippet')
const SnippetExpansion = require('./snippet-expansion')
const EditorStore = require('./editor-store')
-const {getPackageRoot} = require('./helpers')
+const { getPackageRoot } = require('./helpers')
module.exports = {
activate () {
this.loaded = false
this.userSnippetsPath = null
this.snippetIdCounter = 0
- this.snippetsByPackage = new Map
- this.parsedSnippetsById = new Map
- this.editorMarkerLayers = new WeakMap
+ this.snippetsByPackage = new Map()
+ this.parsedSnippetsById = new Map()
+ this.editorMarkerLayers = new WeakMap()
- this.scopedPropertyStore = new ScopedPropertyStore
+ this.scopedPropertyStore = new ScopedPropertyStore()
// The above ScopedPropertyStore will store the main registry of snippets.
// But we need a separate ScopedPropertyStore for the snippets that come
// from disabled packages. They're isolated so that they're not considered
// as candidates when the user expands a prefix, but we still need the data
// around so that the snippets provided by those packages can be shown in
// the settings view.
- this.disabledSnippetsScopedPropertyStore = new ScopedPropertyStore
+ this.disabledSnippetsScopedPropertyStore = new ScopedPropertyStore()
- this.subscriptions = new CompositeDisposable
- this.subscriptions.add(atom.workspace.addOpener(uri => {
- if (uri === 'atom://.atom/snippets') {
- return atom.workspace.openTextFile(this.getUserSnippetsPath())
- }
- }))
+ this.subscriptions = new CompositeDisposable()
+ this.subscriptions.add(
+ atom.workspace.addOpener(uri => {
+ if (uri === 'atom://.atom/snippets') {
+ return atom.workspace.openTextFile(this.getUserSnippetsPath())
+ }
+ })
+ )
this.loadAll()
this.watchUserSnippets(watchDisposable => {
this.subscriptions.add(watchDisposable)
})
- this.subscriptions.add(atom.config.onDidChange('core.packagesWithSnippetsDisabled', ({newValue, oldValue}) => {
- this.handleDisabledPackagesDidChange(newValue, oldValue)
- }))
+ this.subscriptions.add(
+ atom.config.onDidChange(
+ 'core.packagesWithSnippetsDisabled',
+ ({ newValue, oldValue }) => {
+ this.handleDisabledPackagesDidChange(newValue, oldValue)
+ }
+ )
+ )
const snippets = this
- this.subscriptions.add(atom.commands.add('atom-text-editor', {
- 'snippets:expand'(event) {
- const editor = this.getModel()
- if (snippets.snippetToExpandUnderCursor(editor)) {
- snippets.clearExpansions(editor)
- snippets.expandSnippetsUnderCursors(editor)
- } else {
- event.abortKeyBinding()
+ this.subscriptions.add(
+ atom.commands.add('atom-text-editor', {
+ 'snippets:expand' (event) {
+ const editor = this.getModel()
+ if (snippets.snippetToExpandUnderCursor(editor)) {
+ snippets.clearExpansions(editor)
+ snippets.expandSnippetsUnderCursors(editor)
+ } else {
+ event.abortKeyBinding()
+ }
+ },
+
+ 'snippets:next-tab-stop' (event) {
+ const editor = this.getModel()
+ if (!snippets.goToNextTabStop(editor)) {
+ event.abortKeyBinding()
+ }
+ },
+
+ 'snippets:previous-tab-stop' (event) {
+ const editor = this.getModel()
+ if (!snippets.goToPreviousTabStop(editor)) {
+ event.abortKeyBinding()
+ }
+ },
+
+ 'snippets:available' (event) {
+ const editor = this.getModel()
+ const SnippetsAvailable = require('./snippets-available')
+ if (snippets.availableSnippetsView == null) {
+ snippets.availableSnippetsView = new SnippetsAvailable(snippets)
+ }
+ snippets.availableSnippetsView.toggle(editor)
}
- },
-
- 'snippets:next-tab-stop'(event) {
- const editor = this.getModel()
- if (!snippets.goToNextTabStop(editor)) { event.abortKeyBinding() }
- },
-
- 'snippets:previous-tab-stop'(event) {
- const editor = this.getModel()
- if (!snippets.goToPreviousTabStop(editor)) { event.abortKeyBinding() }
- },
-
- 'snippets:available'(event) {
- const editor = this.getModel()
- const SnippetsAvailable = require('./snippets-available')
- if (snippets.availableSnippetsView == null) { snippets.availableSnippetsView = new SnippetsAvailable(snippets) }
- snippets.availableSnippetsView.toggle(editor)
- }
- }))
+ })
+ )
},
deactivate () {
@@ -87,19 +102,32 @@ module.exports = {
},
getUserSnippetsPath () {
- if (this.userSnippetsPath != null) { return this.userSnippetsPath }
+ if (this.userSnippetsPath != null) {
+ return this.userSnippetsPath
+ }
- this.userSnippetsPath = CSON.resolve(path.join(atom.getConfigDirPath(), 'snippets'))
- if (this.userSnippetsPath == null) { this.userSnippetsPath = path.join(atom.getConfigDirPath(), 'snippets.cson') }
+ this.userSnippetsPath = CSON.resolve(
+ path.join(atom.getConfigDirPath(), 'snippets')
+ )
+ if (this.userSnippetsPath == null) {
+ this.userSnippetsPath = path.join(
+ atom.getConfigDirPath(),
+ 'snippets.cson'
+ )
+ }
return this.userSnippetsPath
},
loadAll () {
this.loadBundledSnippets(bundledSnippets => {
this.loadPackageSnippets(packageSnippets => {
- this.loadUserSnippets(userSnippets => {
+ this.loadUserSnippets((userSnippets = {}) => {
atom.config.transact(() => {
- for (const snippetSet of [bundledSnippets, packageSnippets, userSnippets]) {
+ for (const snippetSet of [
+ bundledSnippets,
+ packageSnippets,
+ userSnippets
+ ]) {
for (const filepath in snippetSet) {
const snippetsBySelector = snippetSet[filepath]
this.add(filepath, snippetsBySelector)
@@ -113,8 +141,10 @@ module.exports = {
},
loadBundledSnippets (callback) {
- const bundledSnippetsPath = CSON.resolve(path.join(getPackageRoot(), 'lib', 'snippets'))
- this.loadSnippetsFile(bundledSnippetsPath, snippets => {
+ const bundledSnippetsPath = CSON.resolve(
+ path.join(getPackageRoot(), 'lib', 'snippets')
+ )
+ this.loadSnippetsFile(bundledSnippetsPath, (snippets = {}) => {
const snippetsByPath = {}
snippetsByPath[bundledSnippetsPath] = snippets
callback(snippetsByPath)
@@ -124,14 +154,14 @@ module.exports = {
loadUserSnippets (callback) {
const userSnippetsPath = this.getUserSnippetsPath()
fs.stat(userSnippetsPath, (error, stat) => {
- if (stat != null && stat.isFile()) {
- this.loadSnippetsFile(userSnippetsPath, snippets => {
+ if (!error && stat.isFile()) {
+ this.loadSnippetsFile(userSnippetsPath, (snippets = {}) => {
const result = {}
result[userSnippetsPath] = snippets
callback(result)
})
} else {
- callback({})
+ callback()
}
})
},
@@ -139,13 +169,25 @@ module.exports = {
watchUserSnippets (callback) {
const userSnippetsPath = this.getUserSnippetsPath()
fs.stat(userSnippetsPath, (error, stat) => {
- if (stat != null && stat.isFile()) {
+ if (!error && stat.isFile()) {
const userSnippetsFileDisposable = new CompositeDisposable()
const userSnippetsFile = new File(userSnippetsPath)
try {
- userSnippetsFileDisposable.add(userSnippetsFile.onDidChange(() => this.handleUserSnippetsDidChange()))
- userSnippetsFileDisposable.add(userSnippetsFile.onDidDelete(() => this.handleUserSnippetsDidChange()))
- userSnippetsFileDisposable.add(userSnippetsFile.onDidRename(() => this.handleUserSnippetsDidChange()))
+ userSnippetsFileDisposable.add(
+ userSnippetsFile.onDidChange(() =>
+ this.handleUserSnippetsDidChange()
+ )
+ )
+ userSnippetsFileDisposable.add(
+ userSnippetsFile.onDidDelete(() =>
+ this.handleUserSnippetsDidChange()
+ )
+ )
+ userSnippetsFileDisposable.add(
+ userSnippetsFile.onDidRename(() =>
+ this.handleUserSnippetsDidChange()
+ )
+ )
} catch (e) {
const message = `\
Unable to watch path: \`snippets.cson\`. Make sure you have permissions
@@ -155,7 +197,7 @@ module.exports = {
[this document][watches] for more info.
[watches]:https://github.com/atom/atom/blob/master/docs/build-instructions/linux.md#typeerror-unable-to-watch-path\
`
- atom.notifications.addError(message, {dismissable: true})
+ atom.notifications.addError(message, { dismissable: true })
}
callback(userSnippetsFileDisposable)
@@ -171,7 +213,7 @@ module.exports = {
const userSnippetsPath = this.getUserSnippetsPath()
atom.config.transact(() => {
this.clearSnippetsForPath(userSnippetsPath)
- this.loadSnippetsFile(userSnippetsPath, result => {
+ this.loadSnippetsFile(userSnippetsPath, (result = {}) => {
this.add(userSnippetsPath, result)
})
})
@@ -179,20 +221,31 @@ module.exports = {
// Called when the "Enable" checkbox is checked/unchecked in the Snippets
// section of a package's settings view.
- handleDisabledPackagesDidChange (newDisabledPackages = [], oldDisabledPackages = []) {
+ handleDisabledPackagesDidChange (
+ newDisabledPackages = [],
+ oldDisabledPackages = []
+ ) {
const packagesToAdd = []
const packagesToRemove = []
for (const p of oldDisabledPackages) {
- if (!newDisabledPackages.includes(p)) { packagesToAdd.push(p) }
+ if (!newDisabledPackages.includes(p)) {
+ packagesToAdd.push(p)
+ }
}
for (const p of newDisabledPackages) {
- if (!oldDisabledPackages.includes(p)) { packagesToRemove.push(p) }
+ if (!oldDisabledPackages.includes(p)) {
+ packagesToRemove.push(p)
+ }
}
atom.config.transact(() => {
- for (const p of packagesToRemove) { this.removeSnippetsForPackage(p) }
- for (const p of packagesToAdd) { this.addSnippetsForPackage(p) }
+ for (const p of packagesToRemove) {
+ this.removeSnippetsForPackage(p)
+ }
+ for (const p of packagesToAdd) {
+ this.addSnippetsForPackage(p)
+ }
})
},
@@ -216,7 +269,8 @@ module.exports = {
},
loadPackageSnippets (callback) {
- const disabledPackageNames = atom.config.get('core.packagesWithSnippetsDisabled') || []
+ const disabledPackageNames =
+ atom.config.get('core.packagesWithSnippetsDisabled') || []
const packages = atom.packages.getLoadedPackages().sort((pack, _) => {
return /\/node_modules\//.test(pack.path) ? -1 : 1
})
@@ -226,34 +280,43 @@ module.exports = {
snippetsDirPaths.push(path.join(pack.path, 'snippets'))
}
- async.map(snippetsDirPaths, this.loadSnippetsDirectory.bind(this), (error, results) => {
- const zipped = []
- for (const key in results) {
- zipped.push({result: results[key], pack: packages[key]})
- }
+ async.map(
+ snippetsDirPaths,
+ this.loadSnippetsDirectory.bind(this),
+ (error, results) => {
+ if (error) {
+ callback()
+ }
+ const zipped = []
+ for (const key in results) {
+ zipped.push({ result: results[key], pack: packages[key] })
+ }
- const enabledPackages = []
- for (const o of zipped) {
- // Skip packages that contain no snippets.
- if (Object.keys(o.result).length === 0) { continue }
- // Keep track of which snippets come from which packages so we can
- // unload them selectively later. All packages get put into this map,
- // even disabled packages, because we need to know which snippets to add
- // if those packages are enabled again.
- this.snippetsByPackage.set(o.pack.name, o.result)
- if (disabledPackageNames.includes(o.pack.name)) {
- // Since disabled packages' snippets won't get added to the main
- // ScopedPropertyStore, we'll keep track of them in a separate
- // ScopedPropertyStore so that they can still be represented in the
- // settings view.
- this.addSnippetsInDisabledPackage(o.result)
- } else {
- enabledPackages.push(o.result)
+ const enabledPackages = []
+ for (const o of zipped) {
+ // Skip packages that contain no snippets.
+ if (Object.keys(o.result).length === 0) {
+ continue
+ }
+ // Keep track of which snippets come from which packages so we can
+ // unload them selectively later. All packages get put into this map,
+ // even disabled packages, because we need to know which snippets to add
+ // if those packages are enabled again.
+ this.snippetsByPackage.set(o.pack.name, o.result)
+ if (disabledPackageNames.includes(o.pack.name)) {
+ // Since disabled packages' snippets won't get added to the main
+ // ScopedPropertyStore, we'll keep track of them in a separate
+ // ScopedPropertyStore so that they can still be represented in the
+ // settings view.
+ this.addSnippetsInDisabledPackage(o.result)
+ } else {
+ enabledPackages.push(o.result)
+ }
}
- }
- callback(_.extend({}, ...enabledPackages))
- })
+ callback(_.extend({}, ...enabledPackages))
+ }
+ )
},
doneLoading () {
@@ -267,18 +330,23 @@ module.exports = {
getEmitter () {
if (this.emitter == null) {
- this.emitter = new Emitter
+ this.emitter = new Emitter()
}
return this.emitter
},
loadSnippetsDirectory (snippetsDirPath, callback) {
fs.isDirectory(snippetsDirPath, isDirectory => {
- if (!isDirectory) { return callback(null, {}) }
+ if (!isDirectory) {
+ return callback(null, {})
+ }
fs.readdir(snippetsDirPath, (error, entries) => {
if (error) {
- console.warn(`Error reading snippets directory ${snippetsDirPath}`, error)
+ console.warn(
+ `Error reading snippets directory ${snippetsDirPath}`,
+ error
+ )
return callback(null, {})
}
@@ -286,28 +354,44 @@ module.exports = {
entries,
(entry, done) => {
const filePath = path.join(snippetsDirPath, entry)
- this.loadSnippetsFile(filePath, snippets => done(null, {filePath, snippets}))
+ this.loadSnippetsFile(filePath, (snippets = {}) =>
+ done(null, { filePath, snippets })
+ )
},
(error, results) => {
const snippetsByPath = {}
- for (const {filePath, snippets} of results) {
+ for (const { filePath, snippets } of results) {
snippetsByPath[filePath] = snippets
}
- callback(null, snippetsByPath)
- })
+ callback(error, snippetsByPath)
+ }
+ )
})
})
},
loadSnippetsFile (filePath, callback) {
- if (!CSON.isObjectPath(filePath)) { return callback({}) }
- CSON.readFile(filePath, {allowDuplicateKeys: false}, (error, object = {}) => {
- if (error != null) {
- console.warn(`Error reading snippets file '${filePath}': ${error.stack != null ? error.stack : error}`)
- atom.notifications.addError(`Failed to load snippets from '${filePath}'`, {detail: error.message, dismissable: true})
+ if (!CSON.isObjectPath(filePath)) {
+ return callback()
+ }
+ CSON.readFile(
+ filePath,
+ { allowDuplicateKeys: false },
+ (error, object = {}) => {
+ if (error != null) {
+ console.warn(
+ `Error reading snippets file '${filePath}': ${
+ error.stack != null ? error.stack : error
+ }`
+ )
+ atom.notifications.addError(
+ `Failed to load snippets from '${filePath}'`,
+ { detail: error.message, dismissable: true }
+ )
+ }
+ callback(object)
}
- callback(object)
- })
+ )
},
add (filePath, snippetsBySelector, isDisabled = false) {
@@ -316,7 +400,7 @@ module.exports = {
const unparsedSnippetsByPrefix = {}
for (const name in snippetsByName) {
const attributes = snippetsByName[name]
- const {prefix, body} = attributes
+ const { prefix, body } = attributes
attributes.name = name
attributes.id = this.snippetIdCounter++
if (typeof body === 'string') {
@@ -326,7 +410,12 @@ module.exports = {
}
}
- this.storeUnparsedSnippets(unparsedSnippetsByPrefix, filePath, selector, isDisabled)
+ this.storeUnparsedSnippets(
+ unparsedSnippetsByPrefix,
+ filePath,
+ selector,
+ isDisabled
+ )
}
},
@@ -344,7 +433,7 @@ module.exports = {
}
return scopesArray
- .map(scope => scope[0] === '.' ? scope : `.${scope}`)
+ .map(scope => (scope[0] === '.' ? scope : `.${scope}`))
.join(' ')
},
@@ -355,20 +444,32 @@ module.exports = {
// prefix for expansion, but both stores have their contents exported when
// the settings view asks for all available snippets.
const unparsedSnippets = {}
- unparsedSnippets[selector] = {"snippets": value}
- const store = isDisabled ? this.disabledSnippetsScopedPropertyStore : this.scopedPropertyStore
- store.addProperties(path, unparsedSnippets, {priority: this.priorityForSource(path)})
+ unparsedSnippets[selector] = { snippets: value }
+ const store = isDisabled
+ ? this.disabledSnippetsScopedPropertyStore
+ : this.scopedPropertyStore
+ store.addProperties(path, unparsedSnippets, {
+ priority: this.priorityForSource(path)
+ })
},
clearSnippetsForPath (path) {
- for (const scopeSelector in this.scopedPropertyStore.propertiesForSource(path)) {
- const object = this.scopedPropertyStore.propertiesForSourceAndSelector(path, scopeSelector)
+ for (const scopeSelector in this.scopedPropertyStore.propertiesForSource(
+ path
+ )) {
+ const object = this.scopedPropertyStore.propertiesForSourceAndSelector(
+ path,
+ scopeSelector
+ )
for (const prefix in object) {
const attributes = object[prefix]
this.parsedSnippetsById.delete(attributes.id)
}
- this.scopedPropertyStore.removePropertiesForSourceAndSelector(path, scopeSelector)
+ this.scopedPropertyStore.removePropertiesForSourceAndSelector(
+ path,
+ scopeSelector
+ )
}
},
@@ -377,17 +478,20 @@ module.exports = {
const unparsedSnippetsByPrefix = this.scopedPropertyStore.getPropertyValue(
this.getScopeChain(scopeDescriptor),
- "snippets"
+ 'snippets'
)
- const legacyScopeDescriptor = atom.config.getLegacyScopeDescriptorForNewScopeDescriptor
- ? atom.config.getLegacyScopeDescriptorForNewScopeDescriptor(scopeDescriptor)
+ const legacyScopeDescriptor = atom.config
+ .getLegacyScopeDescriptorForNewScopeDescriptor
+ ? atom.config.getLegacyScopeDescriptorForNewScopeDescriptor(
+ scopeDescriptor
+ )
: undefined
if (legacyScopeDescriptor) {
unparsedLegacySnippetsByPrefix = this.scopedPropertyStore.getPropertyValue(
this.getScopeChain(legacyScopeDescriptor),
- "snippets"
+ 'snippets'
)
}
@@ -396,7 +500,11 @@ module.exports = {
if (unparsedSnippetsByPrefix) {
for (const prefix in unparsedSnippetsByPrefix) {
const attributes = unparsedSnippetsByPrefix[prefix]
- if (typeof (attributes != null ? attributes.body : undefined) !== 'string') { continue }
+ if (
+ typeof (attributes != null ? attributes.body : undefined) !== 'string'
+ ) {
+ continue
+ }
snippets[prefix] = this.getParsedSnippet(attributes)
}
}
@@ -404,8 +512,14 @@ module.exports = {
if (unparsedLegacySnippetsByPrefix) {
for (const prefix in unparsedLegacySnippetsByPrefix) {
const attributes = unparsedLegacySnippetsByPrefix[prefix]
- if (snippets[prefix]) { continue }
- if (typeof (attributes != null ? attributes.body : undefined) !== 'string') { continue }
+ if (snippets[prefix]) {
+ continue
+ }
+ if (
+ typeof (attributes != null ? attributes.body : undefined) !== 'string'
+ ) {
+ continue
+ }
snippets[prefix] = this.getParsedSnippet(attributes)
}
}
@@ -416,9 +530,33 @@ module.exports = {
getParsedSnippet (attributes) {
let snippet = this.parsedSnippetsById.get(attributes.id)
if (snippet == null) {
- let {id, prefix, name, body, bodyTree, description, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML} = attributes
- if (bodyTree == null) { bodyTree = this.getBodyParser().parse(body) }
- snippet = new Snippet({id, name, prefix, bodyTree, description, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML, bodyText: body})
+ let {
+ id,
+ prefix,
+ name,
+ body,
+ bodyTree,
+ description,
+ descriptionMoreURL,
+ rightLabelHTML,
+ leftLabel,
+ leftLabelHTML
+ } = attributes
+ if (bodyTree == null) {
+ bodyTree = this.getBodyParser().parse(body)
+ }
+ snippet = new Snippet({
+ id,
+ name,
+ prefix,
+ bodyTree,
+ description,
+ descriptionMoreURL,
+ rightLabelHTML,
+ leftLabel,
+ leftLabelHTML,
+ bodyText: body
+ })
this.parsedSnippetsById.set(attributes.id, snippet)
}
return snippet
@@ -453,18 +591,24 @@ module.exports = {
for (const cursor of editor.getCursors()) {
const position = cursor.getBufferPosition()
- const prefixStart = cursor.getBeginningOfCurrentWordBufferPosition({wordRegex})
+ const prefixStart = cursor.getBeginningOfCurrentWordBufferPosition({
+ wordRegex
+ })
const cursorSnippetPrefix = editor.getTextInRange([prefixStart, position])
- if ((snippetPrefix != null) && (cursorSnippetPrefix !== snippetPrefix)) { return null }
+ if (snippetPrefix != null && cursorSnippetPrefix !== snippetPrefix) {
+ return null
+ }
snippetPrefix = cursorSnippetPrefix
const wordStart = cursor.getBeginningOfCurrentWordBufferPosition()
const cursorWordPrefix = editor.getTextInRange([wordStart, position])
- if ((wordPrefix != null) && (cursorWordPrefix !== wordPrefix)) { return null }
+ if (wordPrefix != null && cursorWordPrefix !== wordPrefix) {
+ return null
+ }
wordPrefix = cursorWordPrefix
}
- return {snippetPrefix, wordPrefix}
+ return { snippetPrefix, wordPrefix }
},
// Get a RegExp of all the characters used in the snippet prefixes
@@ -472,7 +616,9 @@ module.exports = {
const prefixes = {}
for (const prefix in snippets) {
- for (const character of prefix) { prefixes[character] = true }
+ for (const character of prefix) {
+ prefixes[character] = true
+ }
}
const prefixCharacters = Object.keys(prefixes).join('')
@@ -486,8 +632,14 @@ module.exports = {
for (const snippetPrefix in snippets) {
const snippet = snippets[snippetPrefix]
- if (prefix.endsWith(snippetPrefix) && (wordPrefix.length <= snippetPrefix.length)) {
- if ((longestPrefixMatch == null) || (snippetPrefix.length > longestPrefixMatch.prefix.length)) {
+ if (
+ prefix.endsWith(snippetPrefix) &&
+ wordPrefix.length <= snippetPrefix.length
+ ) {
+ if (
+ longestPrefixMatch == null ||
+ snippetPrefix.length > longestPrefixMatch.prefix.length
+ ) {
longestPrefixMatch = snippet
}
}
@@ -497,27 +649,43 @@ module.exports = {
},
getSnippets (editor) {
- return this.parsedSnippetsForScopes(editor.getLastCursor().getScopeDescriptor())
+ return this.parsedSnippetsForScopes(
+ editor.getLastCursor().getScopeDescriptor()
+ )
},
snippetToExpandUnderCursor (editor) {
- if (!editor.getLastSelection().isEmpty()) { return false }
+ if (!editor.getLastSelection().isEmpty()) {
+ return false
+ }
const snippets = this.getSnippets(editor)
- if (_.isEmpty(snippets)) { return false }
+ if (_.isEmpty(snippets)) {
+ return false
+ }
const prefixData = this.getPrefixText(snippets, editor)
if (prefixData) {
- return this.snippetForPrefix(snippets, prefixData.snippetPrefix, prefixData.wordPrefix)
+ return this.snippetForPrefix(
+ snippets,
+ prefixData.snippetPrefix,
+ prefixData.wordPrefix
+ )
}
},
expandSnippetsUnderCursors (editor) {
const snippet = this.snippetToExpandUnderCursor(editor)
- if (!snippet) { return false }
+ if (!snippet) {
+ return false
+ }
this.getStore(editor).observeHistory({
- undo: event => { this.onUndoOrRedo(editor, event, true) },
- redo: event => { this.onUndoOrRedo(editor, event, false) }
+ undo: event => {
+ this.onUndoOrRedo(editor, event, true)
+ },
+ redo: event => {
+ this.onUndoOrRedo(editor, event, false)
+ }
})
this.findOrCreateMarkerLayer(editor)
@@ -525,7 +693,10 @@ module.exports = {
const cursors = editor.getCursors()
for (const cursor of cursors) {
const cursorPosition = cursor.getBufferPosition()
- const startPoint = cursorPosition.translate([0, -snippet.prefix.length], [0, 0])
+ const startPoint = cursorPosition.translate(
+ [0, -snippet.prefix.length],
+ [0, 0]
+ )
cursor.selection.setBufferRange([startPoint, cursorPosition])
this.insert(snippet, editor, cursor)
}
@@ -560,7 +731,7 @@ module.exports = {
findOrCreateMarkerLayer (editor) {
let layer = this.editorMarkerLayers.get(editor)
if (layer === undefined) {
- layer = editor.addMarkerLayer({maintainHistory: true})
+ layer = editor.addMarkerLayer({ maintainHistory: true })
this.editorMarkerLayers.set(editor, layer)
}
return layer
@@ -587,11 +758,17 @@ module.exports = {
const store = this.getStore(editor)
const activeExpansions = store.getExpansions()
- if ((activeExpansions.length === 0) || activeExpansions[0].isIgnoringBufferChanges) { return }
+ if (
+ activeExpansions.length === 0 ||
+ activeExpansions[0].isIgnoringBufferChanges
+ ) {
+ return
+ }
this.ignoringTextChangesForEditor(editor, () =>
editor.transact(() =>
- activeExpansions.map(expansion => expansion.textChanged(event)))
+ activeExpansions.map(expansion => expansion.textChanged(event))
+ )
)
// Create a checkpoint here to consolidate all the changes we just made into
@@ -620,11 +797,20 @@ module.exports = {
},
insert (snippet, editor, cursor) {
- if (editor == null) { editor = atom.workspace.getActiveTextEditor() }
- if (cursor == null) { cursor = editor.getLastCursor() }
+ if (editor == null) {
+ editor = atom.workspace.getActiveTextEditor()
+ }
+ if (cursor == null) {
+ cursor = editor.getLastCursor()
+ }
if (typeof snippet === 'string') {
const bodyTree = this.getBodyParser().parse(snippet)
- snippet = new Snippet({name: '__anonymous', prefix: '', bodyTree, bodyText: snippet})
+ snippet = new Snippet({
+ name: '__anonymous',
+ prefix: '',
+ bodyTree,
+ bodyText: snippet
+ })
}
return new SnippetExpansion(snippet, editor, cursor, this)
},
diff --git a/lib/tab-stop-list.js b/lib/tab-stop-list.js
index 0d3bd01..7391b24 100644
--- a/lib/tab-stop-list.js
+++ b/lib/tab-stop-list.js
@@ -22,12 +22,12 @@ class TabStopList {
}
forEachIndex (iterator) {
- let indices = Object.keys(this.list).sort((a1, a2) => a1 - a2)
+ const indices = Object.keys(this.list).sort((a1, a2) => a1 - a2)
indices.forEach(iterator)
}
getInsertions () {
- let results = []
+ const results = []
this.forEachIndex(index => {
results.push(...this.list[index].insertions)
})
@@ -35,9 +35,9 @@ class TabStopList {
}
toArray () {
- let results = []
+ const results = []
this.forEachIndex(index => {
- let tabStop = this.list[index]
+ const tabStop = this.list[index]
if (!tabStop.isValid()) return
results.push(tabStop)
})
diff --git a/lib/tab-stop.js b/lib/tab-stop.js
index 61a423e..e6af340 100644
--- a/lib/tab-stop.js
+++ b/lib/tab-stop.js
@@ -1,4 +1,4 @@
-const {Range} = require('atom')
+const { Range } = require('atom')
const Insertion = require('./insertion')
// A tab stop:
@@ -12,22 +12,22 @@ class TabStop {
}
isValid () {
- let any = this.insertions.some(insertion => insertion.isTransformation())
+ const any = this.insertions.some(insertion => insertion.isTransformation())
if (!any) return true
- let all = this.insertions.every(insertion => insertion.isTransformation())
+ const all = this.insertions.every(insertion => insertion.isTransformation())
// If there are any transforming insertions, there must be at least one
// non-transforming insertion to act as the primary.
return !all
}
addInsertion ({ range, substitution }) {
- let insertion = new Insertion({ range, substitution })
+ const insertion = new Insertion({ range, substitution })
let insertions = this.insertions
insertions.push(insertion)
insertions = insertions.sort((i1, i2) => {
return i1.range.start.compare(i2.range.start)
})
- let initial = insertions.find(insertion => !insertion.isTransformation())
+ const initial = insertions.find(insertion => !insertion.isTransformation())
if (initial) {
insertions.splice(insertions.indexOf(initial), 1)
insertions.unshift(initial)
@@ -36,10 +36,10 @@ class TabStop {
}
copyWithIndent (indent) {
- let { snippet, index, insertions } = this
- let newInsertions = insertions.map(insertion => {
- let { range, substitution } = insertion
- let newRange = Range.fromObject(range, true)
+ const { snippet, index, insertions } = this
+ const newInsertions = insertions.map(insertion => {
+ const { range, substitution } = insertion
+ const newRange = Range.fromObject(range, true)
if (newRange.start.row) {
newRange.start.column += indent.length
newRange.end.column += indent.length
diff --git a/package-lock.json b/package-lock.json
index c085050..7ecbbef 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,15 +4,321 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "@angular/compiler": {
+ "version": "8.2.14",
+ "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-8.2.14.tgz",
+ "integrity": "sha512-ABZO4E7eeFA1QyJ2trDezxeQM5ZFa1dXw1Mpl/+1vuXDKNjJgNyWYwKp/NwRkLmrsuV0yv4UDCDe4kJOGbPKnw==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "@babel/code-frame": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+ "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.10.4"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+ "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
+ "dev": true
+ },
+ "@babel/highlight": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+ "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.9.4",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz",
+ "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==",
+ "dev": true
+ },
+ "@babel/runtime": {
+ "version": "7.11.2",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz",
+ "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==",
+ "dev": true,
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "@glimmer/interfaces": {
+ "version": "0.41.4",
+ "resolved": "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.41.4.tgz",
+ "integrity": "sha512-MzXwMyod3MlwSZezHSaVBsCEIW/giYYfTDYARR46QnYsaFVatMVbydjsI7jkAuBCbnLCyNOIc1TrYIj71i/rpg==",
+ "dev": true
+ },
+ "@glimmer/syntax": {
+ "version": "0.41.4",
+ "resolved": "https://registry.npmjs.org/@glimmer/syntax/-/syntax-0.41.4.tgz",
+ "integrity": "sha512-NLPNirZDbNmpZ8T/ccle22zt2rhUq5il7ST6IJk62T58QZeJsdr3m3RS4kaGSBsQhXoKELrgX048yYEX5sC+fw==",
+ "dev": true,
+ "requires": {
+ "@glimmer/interfaces": "^0.41.4",
+ "@glimmer/util": "^0.41.4",
+ "handlebars": "^4.0.13",
+ "simple-html-tokenizer": "^0.5.7"
+ }
+ },
+ "@glimmer/util": {
+ "version": "0.41.4",
+ "resolved": "https://registry.npmjs.org/@glimmer/util/-/util-0.41.4.tgz",
+ "integrity": "sha512-DwS94K+M0vtG+cymxH0rslJr09qpdjyOLdCjmpKcG/nNiZQfMA1ybAaFEmwk9UaVlUG9STENFeQwyrLevJB+7g==",
+ "dev": true
+ },
+ "@iarna/toml": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.3.tgz",
+ "integrity": "sha512-FmuxfCuolpLl0AnQ2NHSzoUKWEJDFl63qXjzdoWBVyFCXzMGm1spBzk7LeHNoVCiWCF7mRVms9e6jEV9+MoPbg==",
+ "dev": true
+ },
+ "@nodelib/fs.scandir": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
+ "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "2.0.3",
+ "run-parallel": "^1.1.9"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
+ "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
+ "dev": true
+ },
+ "@nodelib/fs.walk": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
+ "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.scandir": "2.1.3",
+ "fastq": "^1.6.0"
+ }
+ },
+ "@samverschueren/stream-to-observable": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz",
+ "integrity": "sha512-c/qwwcHyafOQuVQJj0IlBjf5yYgBI7YPJ77k4fOJYesb41jio65eaJODRUmfYKhTOFBrIZ66kgvGPlNbjuoRdQ==",
+ "dev": true,
+ "requires": {
+ "any-observable": "^0.3.0"
+ }
+ },
+ "@types/color-name": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
+ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
+ "dev": true
+ },
+ "@types/glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
+ "dev": true,
+ "requires": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+ "dev": true
+ },
+ "@types/node": {
+ "version": "14.11.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.2.tgz",
+ "integrity": "sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA==",
+ "dev": true
+ },
+ "@types/unist": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
+ "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==",
+ "dev": true
+ },
+ "@typescript-eslint/typescript-estree": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.6.1.tgz",
+ "integrity": "sha512-+sTnssW6bcbDZKE8Ce7VV6LdzkQz2Bxk7jzk1J8H1rovoTxnm6iXvYIyncvNsaB/kBCOM63j/LNJfm27bNdUoA==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "glob": "^7.1.4",
+ "is-glob": "^4.0.1",
+ "lodash.unescape": "4.0.1",
+ "semver": "^6.3.0",
+ "tsutils": "^3.17.1"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "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"
+ }
+ }
+ }
+ },
+ "acorn": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
+ "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
+ "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
+ "dev": true
+ },
+ "aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "dev": true,
+ "requires": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ }
+ },
+ "ajv": {
+ "version": "6.12.5",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz",
+ "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "angular-estree-parser": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/angular-estree-parser/-/angular-estree-parser-1.3.1.tgz",
+ "integrity": "sha512-jvlnNk4aoEmA6EKK12OnsOkCSdsWleBsYB+aWyH8kpfTB6Li1kxWVbHKVldH9zDCwVVi1hXfqPi/gbSv49tkbQ==",
+ "dev": true,
+ "requires": {
+ "lines-and-columns": "^1.1.6",
+ "tslib": "^1.9.3"
+ }
+ },
+ "angular-html-parser": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/angular-html-parser/-/angular-html-parser-1.4.0.tgz",
+ "integrity": "sha512-5KyzzYOeZV9g9ahXw4rbi8IIbMjUdXoarXJ0CfbWue5U1YsvMnjMZJ3oadpU8ZtnIx1zR/dsyt+FLJx2U65d2Q==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.3"
+ }
+ },
+ "ansi-escapes": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
+ "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.11.0"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+ "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+ "dev": true
+ }
+ }
+ },
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "any-observable": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz",
+ "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==",
+ "dev": true
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "array-differ": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-2.1.0.tgz",
+ "integrity": "sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==",
+ "dev": true
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "^1.0.1"
+ }
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true
+ },
+ "arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+ "dev": true
+ },
+ "astral-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+ "dev": true
+ },
"async": {
- "version": "0.2.10",
- "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
- "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E="
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
+ "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw=="
},
"atom-select-list": {
"version": "0.7.2",
@@ -28,6 +334,12 @@
"resolved": "https://registry.npmjs.org/atom-slick/-/atom-slick-2.0.0.tgz",
"integrity": "sha1-/w2+Fb4sTtomi50w124lF+C308o="
},
+ "bail": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz",
+ "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==",
+ "dev": true
+ },
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@@ -42,11 +354,153 @@
"concat-map": "0.0.1"
}
},
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "caller-callsite": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+ "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
+ "dev": true,
+ "requires": {
+ "callsites": "^2.0.0"
+ },
+ "dependencies": {
+ "callsites": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+ "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
+ "dev": true
+ }
+ }
+ },
+ "caller-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+ "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
+ "dev": true,
+ "requires": {
+ "caller-callsite": "^2.0.0"
+ }
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"camelcase": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
"integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
},
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "character-entities": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
+ "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
+ "dev": true
+ },
+ "character-entities-legacy": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
+ "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
+ "dev": true
+ },
+ "character-reference-invalid": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
+ "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
+ "dev": true
+ },
+ "chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "dev": true
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "cjk-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/cjk-regex/-/cjk-regex-2.0.0.tgz",
+ "integrity": "sha512-E4gFi2f3jC0zFVHpaAcupW+gv9OejZ2aV3DP/LlSO0dDcZJAXw7W0ivn+vN17edN/PhU4HCgs1bfx7lPK7FpdA==",
+ "dev": true,
+ "requires": {
+ "regexp-util": "^1.2.1",
+ "unicode-regex": "^2.0.0"
+ },
+ "dependencies": {
+ "unicode-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-regex/-/unicode-regex-2.0.0.tgz",
+ "integrity": "sha512-5nbEG2YU7loyTvPABaKb+8B0u8L7vWCsVmCSsiaO249ZdMKlvrXlxR2ex4TUVAdzv/Cne/TdoXSSaJArGXaleQ==",
+ "dev": true,
+ "requires": {
+ "regexp-util": "^1.2.0"
+ }
+ }
+ }
+ },
+ "clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^3.1.0"
+ }
+ },
+ "cli-truncate": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz",
+ "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=",
+ "dev": true,
+ "requires": {
+ "slice-ansi": "0.0.4",
+ "string-width": "^1.0.1"
+ },
+ "dependencies": {
+ "slice-ansi": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
+ "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
+ "dev": true
+ }
+ }
+ },
+ "cli-width": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
+ "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
+ "dev": true
+ },
"cliui": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
@@ -67,42 +521,88 @@
"resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz",
"integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw=="
},
- "coffeelint": {
- "version": "1.16.0",
- "resolved": "https://registry.npmjs.org/coffeelint/-/coffeelint-1.16.0.tgz",
- "integrity": "sha1-g9jtHa/eOmd95E57ihi+YHdh5tg=",
+ "collapse-white-space": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz",
+ "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
- "coffee-script": "~1.11.0",
- "glob": "^7.0.6",
- "ignore": "^3.0.9",
- "optimist": "^0.6.1",
- "resolve": "^0.6.3",
- "strip-json-comments": "^1.0.2"
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "cosmiconfig": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+ "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+ "dev": true,
+ "requires": {
+ "import-fresh": "^2.0.0",
+ "is-directory": "^0.3.1",
+ "js-yaml": "^3.13.1",
+ "parse-json": "^4.0.0"
},
"dependencies": {
- "coffee-script": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.11.1.tgz",
- "integrity": "sha1-vxxHrWREOg2V0S3ysUfMCk2q1uk=",
- "dev": true
- },
- "optimist": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
- "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+ "import-fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+ "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
"dev": true,
"requires": {
- "minimist": "~0.0.1",
- "wordwrap": "~0.0.2"
+ "caller-path": "^2.0.0",
+ "resolve-from": "^3.0.0"
}
+ },
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+ "dev": true
}
}
},
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ }
+ }
},
"cson-parser": {
"version": "1.3.5",
@@ -120,56 +620,246 @@
"es5-ext": "~0.10.2"
}
},
+ "dashify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dashify/-/dashify-2.0.0.tgz",
+ "integrity": "sha512-hpA5C/YrPjucXypHPPc0oJ1l9Hf6wWbiOL7Ik42cxnsUOhWiCB/fylKbKqqJalW9FgkNQCw16YO8uW9Hs0Iy1A==",
+ "dev": true
+ },
+ "date-fns": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
+ "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
+ "dev": true
+ },
+ "debug": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
+ "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.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"
- }
+ "dedent": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
+ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
+ "dev": true
},
- "es5-ext": {
- "version": "0.10.30",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz",
- "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=",
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "del": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz",
+ "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==",
+ "dev": true,
"requires": {
- "es6-iterator": "2",
- "es6-symbol": "~3.1"
+ "globby": "^10.0.1",
+ "graceful-fs": "^4.2.2",
+ "is-glob": "^4.0.1",
+ "is-path-cwd": "^2.2.0",
+ "is-path-inside": "^3.0.1",
+ "p-map": "^3.0.0",
+ "rimraf": "^3.0.0",
+ "slash": "^3.0.0"
},
"dependencies": {
- "d": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
- "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+ "array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
"requires": {
- "es5-ext": "^0.10.9"
+ "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"
}
},
- "es6-iterator": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
- "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=",
+ "globby": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
+ "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
+ "dev": true,
"requires": {
- "d": "1",
- "es5-ext": "^0.10.14",
- "es6-symbol": "^3.1"
+ "@types/glob": "^7.1.1",
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.0.3",
+ "glob": "^7.1.3",
+ "ignore": "^5.1.1",
+ "merge2": "^1.2.3",
+ "slash": "^3.0.0"
}
},
- "es6-symbol": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
- "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+ "ignore": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true
+ },
+ "diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true
+ },
+ "dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "requires": {
+ "path-type": "^4.0.0"
+ }
+ },
+ "doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "editorconfig": {
+ "version": "0.15.3",
+ "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
+ "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==",
+ "dev": true,
+ "requires": {
+ "commander": "^2.19.0",
+ "lru-cache": "^4.1.5",
+ "semver": "^5.6.0",
+ "sigmund": "^1.0.1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ }
+ }
+ },
+ "editorconfig-to-prettier": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/editorconfig-to-prettier/-/editorconfig-to-prettier-0.1.1.tgz",
+ "integrity": "sha512-MMadSSVRDb4uKdxV6bCXXN4cTsxIsXYtV4XdPu6FOCSAw6zsCIDA+QEktEU+u6h+c/mTrul5NR+pwFpPxwetiQ==",
+ "dev": true
+ },
+ "elegant-spinner": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz",
+ "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.53",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+ "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+ "requires": {
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "~3.1.3",
+ "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.14"
+ "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"
}
}
}
@@ -204,6 +894,168 @@
"es6-symbol": "~2.0.1"
}
},
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "eslint": {
+ "version": "6.8.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
+ "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "ajv": "^6.10.0",
+ "chalk": "^2.1.0",
+ "cross-spawn": "^6.0.5",
+ "debug": "^4.0.1",
+ "doctrine": "^3.0.0",
+ "eslint-scope": "^5.0.0",
+ "eslint-utils": "^1.4.3",
+ "eslint-visitor-keys": "^1.1.0",
+ "espree": "^6.1.2",
+ "esquery": "^1.0.1",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^5.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "glob-parent": "^5.0.0",
+ "globals": "^12.1.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^7.0.0",
+ "is-glob": "^4.0.0",
+ "js-yaml": "^3.13.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.3.0",
+ "lodash": "^4.17.14",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.3",
+ "progress": "^2.0.0",
+ "regexpp": "^2.0.1",
+ "semver": "^6.1.2",
+ "strip-ansi": "^5.2.0",
+ "strip-json-comments": "^3.0.1",
+ "table": "^5.2.3",
+ "text-table": "^0.2.0",
+ "v8-compile-cache": "^2.0.3"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-utils": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
+ "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "dev": true
+ },
+ "espree": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz",
+ "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.1.1",
+ "acorn-jsx": "^5.2.0",
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
+ "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.1.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true
+ }
+ }
+ },
+ "esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.2.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true
+ }
+ }
+ },
+ "estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true
+ },
"etch": {
"version": "0.12.8",
"resolved": "https://registry.npmjs.org/etch/-/etch-0.12.8.tgz",
@@ -217,10 +1069,246 @@
"grim": "^1.2.1"
}
},
+ "execa": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz",
+ "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^3.0.0",
+ "onetime": "^5.1.0",
+ "p-finally": "^2.0.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "ext": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
+ "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
+ "requires": {
+ "type": "^2.0.0"
+ },
+ "dependencies": {
+ "type": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz",
+ "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA=="
+ }
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "dev": true
+ },
+ "external-editor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+ "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+ "dev": true,
+ "requires": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ }
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "fast-glob": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
+ "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.0",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.2",
+ "picomatch": "^2.2.1"
+ }
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "fastq": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz",
+ "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==",
+ "dev": true,
+ "requires": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "figures": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+ "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "file-entry-cache": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+ "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^2.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "find-parent-dir": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz",
+ "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=",
+ "dev": true
+ },
+ "find-project-root": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/find-project-root/-/find-project-root-1.1.1.tgz",
+ "integrity": "sha1-0kJyei2QRyXfVxTyPf3N7doLbvg=",
+ "dev": true
+ },
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "flat-cache": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+ "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+ "dev": true,
+ "requires": {
+ "flatted": "^2.0.0",
+ "rimraf": "2.6.3",
+ "write": "1.0.3"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "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"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "flatted": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
+ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
+ "dev": true
+ },
+ "flatten": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz",
+ "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==",
+ "dev": true
+ },
+ "flow-parser": {
+ "version": "0.111.3",
+ "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.111.3.tgz",
+ "integrity": "sha512-iEjGZ94OBMcESxnLorXNjJmtd/JtQYXUVrQpfwvtAKkuyawRmv+2LM6nqyOsOJkISEYbyY6ziudRE0u4VyPSVA==",
+ "dev": true
+ },
"fs-plus": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.0.1.tgz",
- "integrity": "sha1-VMFpxA4ohKZtNSeA0Y3TH5HToQ0=",
+ "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",
@@ -240,15 +1328,43 @@
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
"fuzzaldrin": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz",
"integrity": "sha1-kCBMPi/appQbso0WZF1BgGOpDps="
},
+ "get-own-enumerable-property-symbols": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
+ "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz",
+ "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
"glob": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
"integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=",
+ "dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -258,27 +1374,164 @@
"path-is-absolute": "^1.0.0"
}
},
- "grim": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/grim/-/grim-1.5.0.tgz",
- "integrity": "sha1-sysI71Z88YUvgXWe2caLDXE5ajI=",
+ "glob-parent": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+ "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+ "dev": true,
"requires": {
- "emissary": "^1.2.0"
+ "is-glob": "^4.0.1"
}
},
- "ignore": {
- "version": "3.3.5",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz",
- "integrity": "sha1-xOcVRV9gc6jX5drnLS/J1xZj26Y=",
+ "globals": {
+ "version": "12.4.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
+ "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.8.1"
+ }
+ },
+ "globby": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+ "dev": true,
+ "requires": {
+ "array-union": "^1.0.1",
+ "glob": "^7.0.3",
+ "object-assign": "^4.0.1",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
"dev": true
},
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "graphql": {
+ "version": "14.6.0",
+ "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.6.0.tgz",
+ "integrity": "sha512-VKzfvHEKybTKjQVpTFrA5yUq2S9ihcZvfJAtsDBBCuV6wauPu1xl/f9ehgVf0FcEJJs4vz6ysb/ZMkGigQZseg==",
+ "dev": true,
"requires": {
- "once": "^1.3.0",
- "wrappy": "1"
+ "iterall": "^1.2.2"
+ }
+ },
+ "grim": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/grim/-/grim-1.5.0.tgz",
+ "integrity": "sha1-sysI71Z88YUvgXWe2caLDXE5ajI=",
+ "requires": {
+ "emissary": "^1.2.0"
+ }
+ },
+ "handlebars": {
+ "version": "4.7.6",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz",
+ "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.0",
+ "source-map": "^0.6.1",
+ "uglify-js": "^3.1.4",
+ "wordwrap": "^1.0.0"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ }
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "html-element-attributes": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/html-element-attributes/-/html-element-attributes-2.2.1.tgz",
+ "integrity": "sha512-gGTgCeQu+g1OFExZKWQ1LwbFXxLJ6cGdCGj64ByEaxatr/EPVc23D6Gxngb37ao+SNInP/sGu8FXxRsSxMm7aQ==",
+ "dev": true
+ },
+ "html-styles": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/html-styles/-/html-styles-1.0.0.tgz",
+ "integrity": "sha1-oYBh/WUfmca3XEXI4FSaO8PgGnU=",
+ "dev": true
+ },
+ "html-tag-names": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/html-tag-names/-/html-tag-names-1.1.5.tgz",
+ "integrity": "sha512-aI5tKwNTBzOZApHIynaAwecLBv8TlZTEy/P4Sj2SzzAhBrGuI8yGZ0UIXVPQzOHGS+to2mjb04iy6VWt/8+d8A==",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "ignore": {
+ "version": "3.3.10",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
+ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
+ "dev": true
+ },
+ "import-fresh": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
+ "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true
+ },
+ "indexes-of": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
+ "dev": true
+ },
+ "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": {
@@ -286,11 +1539,171 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
+ "inquirer": {
+ "version": "7.3.3",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
+ "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.1.0",
+ "cli-cursor": "^3.1.0",
+ "cli-width": "^3.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^3.0.0",
+ "lodash": "^4.17.19",
+ "mute-stream": "0.0.8",
+ "run-async": "^2.4.0",
+ "rxjs": "^6.6.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "through": "^2.3.6"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+ "dev": true,
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
"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-alphabetical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
+ "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
+ "dev": true
+ },
+ "is-alphanumerical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
+ "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
+ "dev": true,
+ "requires": {
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0"
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "is-buffer": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
+ "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "is-decimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
+ "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
+ "dev": true
+ },
+ "is-directory": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
"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",
@@ -299,6 +1712,166 @@
"number-is-nan": "^1.0.0"
}
},
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-hexadecimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
+ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "is-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+ "dev": true
+ },
+ "is-observable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz",
+ "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==",
+ "dev": true,
+ "requires": {
+ "symbol-observable": "^1.1.0"
+ }
+ },
+ "is-path-cwd": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
+ "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
+ "dev": true
+ },
+ "is-path-inside": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
+ "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
+ "dev": true
+ },
+ "is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "dev": true
+ },
+ "is-promise": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
+ "dev": true
+ },
+ "is-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
+ "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+ "dev": true
+ },
+ "is-whitespace-character": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz",
+ "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==",
+ "dev": true
+ },
+ "is-word-character": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz",
+ "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "iterall": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz",
+ "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==",
+ "dev": true
+ },
+ "jest-docblock": {
+ "version": "25.3.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz",
+ "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==",
+ "dev": true,
+ "requires": {
+ "detect-newline": "^3.0.0"
+ }
+ },
+ "js-base64": {
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
+ "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==",
+ "dev": true
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
+ "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "json-stable-stringify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+ "dev": true,
+ "requires": {
+ "jsonify": "~0.0.0"
+ }
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+ "dev": true
+ },
"key-path-helpers": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/key-path-helpers/-/key-path-helpers-0.1.0.tgz",
@@ -312,96 +1885,1272 @@
"invert-kv": "^1.0.0"
}
},
- "loophole": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/loophole/-/loophole-1.1.0.tgz",
- "integrity": "sha1-N5Sf6kU7YlasxyXDIM4MWn9wor0="
+ "leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true
},
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
"requires": {
- "brace-expansion": "^1.1.7"
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
}
},
- "minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ "lines-and-columns": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
+ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+ "dev": true
},
- "mixto": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/mixto/-/mixto-1.0.0.tgz",
- "integrity": "sha1-wyDvYbUvKJj1IuF9i7xtUG2EJbY="
+ "linguist-languages": {
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/linguist-languages/-/linguist-languages-7.6.0.tgz",
+ "integrity": "sha512-DBZPIWjrQmb/52UlSEN8MTiwwugrAh4NBX9/DyIG8IuO8rDLYDRM+KVPbuiPVKd3ResxYtZB5AiSuc8dTzOSog==",
+ "dev": true
},
- "mkdirp": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "lint-staged": {
+ "version": "9.4.3",
+ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.4.3.tgz",
+ "integrity": "sha512-PejnI+rwOAmKAIO+5UuAZU9gxdej/ovSEOAY34yMfC3OS4Ac82vCBPzAWLReR9zCPOMqeVwQRaZ3bUBpAsaL2Q==",
+ "dev": true,
"requires": {
- "minimist": "0.0.8"
+ "chalk": "^2.4.2",
+ "commander": "^2.20.0",
+ "cosmiconfig": "^5.2.1",
+ "debug": "^4.1.1",
+ "dedent": "^0.7.0",
+ "del": "^5.0.0",
+ "execa": "^2.0.3",
+ "listr": "^0.14.3",
+ "log-symbols": "^3.0.0",
+ "micromatch": "^4.0.2",
+ "normalize-path": "^3.0.0",
+ "please-upgrade-node": "^3.1.1",
+ "string-argv": "^0.3.0",
+ "stringify-object": "^3.3.0"
}
},
- "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="
+ "listr": {
+ "version": "0.14.3",
+ "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz",
+ "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==",
+ "dev": true,
+ "requires": {
+ "@samverschueren/stream-to-observable": "^0.3.0",
+ "is-observable": "^1.1.0",
+ "is-promise": "^2.1.0",
+ "is-stream": "^1.1.0",
+ "listr-silent-renderer": "^1.1.1",
+ "listr-update-renderer": "^0.5.0",
+ "listr-verbose-renderer": "^0.5.0",
+ "p-map": "^2.0.0",
+ "rxjs": "^6.3.3"
+ },
+ "dependencies": {
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "p-map": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+ "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
+ "dev": true
+ }
+ }
},
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "listr-silent-renderer": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz",
+ "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=",
+ "dev": true
+ },
+ "listr-update-renderer": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz",
+ "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "cli-truncate": "^0.2.1",
+ "elegant-spinner": "^1.0.1",
+ "figures": "^1.7.0",
+ "indent-string": "^3.0.0",
+ "log-symbols": "^1.0.2",
+ "log-update": "^2.3.0",
+ "strip-ansi": "^3.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "figures": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5",
+ "object-assign": "^4.1.0"
+ }
+ },
+ "indent-string": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
+ "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
+ "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "listr-verbose-renderer": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz",
+ "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "cli-cursor": "^2.1.0",
+ "date-fns": "^1.27.2",
+ "figures": "^2.0.0"
+ },
+ "dependencies": {
+ "cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^2.0.0"
+ }
+ },
+ "figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+ "dev": true
+ },
+ "onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^1.0.0"
+ }
+ },
+ "restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "dev": true,
+ "requires": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
+ }
+ }
+ }
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+ "dev": true
+ },
+ "lodash.unescape": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz",
+ "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=",
+ "dev": true
+ },
+ "lodash.uniqby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz",
+ "integrity": "sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+ "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2"
+ }
+ },
+ "log-update": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz",
+ "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^3.0.0",
+ "cli-cursor": "^2.0.0",
+ "wrap-ansi": "^3.0.1"
+ },
+ "dependencies": {
+ "ansi-escapes": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+ "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^2.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+ "dev": true
+ },
+ "onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^1.0.0"
+ }
+ },
+ "restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "dev": true,
+ "requires": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz",
+ "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=",
+ "dev": true,
+ "requires": {
+ "string-width": "^2.1.1",
+ "strip-ansi": "^4.0.0"
+ }
+ }
+ }
+ },
+ "loophole": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/loophole/-/loophole-1.1.0.tgz",
+ "integrity": "sha1-N5Sf6kU7YlasxyXDIM4MWn9wor0="
+ },
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "map-age-cleaner": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
+ "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
+ "dev": true,
+ "requires": {
+ "p-defer": "^1.0.0"
+ }
+ },
+ "markdown-escapes": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz",
+ "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==",
+ "dev": true
+ },
+ "mem": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/mem/-/mem-5.1.1.tgz",
+ "integrity": "sha512-qvwipnozMohxLXG1pOqoLiZKNkC4r4qqRucSoDwXowsNGDSULiqFTRUF05vcZWnwJSG22qTsynQhxbaMtnX9gw==",
+ "dev": true,
+ "requires": {
+ "map-age-cleaner": "^0.1.3",
+ "mimic-fn": "^2.1.0",
+ "p-is-promise": "^2.1.0"
+ }
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+ "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.0.5"
+ }
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "mri": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz",
+ "integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "multimatch": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-3.0.0.tgz",
+ "integrity": "sha512-22foS/gqQfANZ3o+W7ST2x25ueHDVNWl/b9OlGcLpy/iKxjCpvcNCM51YCenUi7Mt/jAjjqv8JwZRs8YP5sRjA==",
+ "dev": true,
+ "requires": {
+ "array-differ": "^2.0.3",
+ "array-union": "^1.0.2",
+ "arrify": "^1.0.1",
+ "minimatch": "^3.0.4"
+ }
+ },
+ "mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+ "dev": true
+ },
+ "n-readlines": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/n-readlines/-/n-readlines-1.0.0.tgz",
+ "integrity": "sha512-ISDqGcspVu6U3VKqtJZG1uR55SmNNF9uK0EMq1IvNVVZOui6MW6VR0+pIZhqz85ORAGp+4zW+5fJ/SE7bwEibA==",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true
+ },
+ "next-tick": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "npm-run-path": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz",
+ "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ },
+ "dependencies": {
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ }
+ }
+ },
+ "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="
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "dev": true,
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ }
+ },
+ "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"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "p-defer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
+ "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
+ "dev": true
+ },
+ "p-finally": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
+ "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==",
+ "dev": true
+ },
+ "p-is-promise": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
+ "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "p-map": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
+ "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
+ "dev": true,
+ "requires": {
+ "aggregate-error": "^3.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0"
+ }
+ },
+ "parse-entities": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz",
+ "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==",
+ "dev": true,
+ "requires": {
+ "character-entities": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "character-reference-invalid": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "parse-srcset": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
+ "integrity": "sha1-8r0iH2zJcKk42IVWq8WJyqqiveE=",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
+ "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="
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "dev": true
+ },
+ "path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true
+ },
+ "pegjs": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.8.0.tgz",
+ "integrity": "sha1-l28GfaE+XFsVAcAXklZoolOBFWE="
+ },
+ "picomatch": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+ "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+ "dev": true
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "requires": {
+ "pinkie": "^2.0.0"
+ }
+ },
+ "please-upgrade-node": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
+ "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
+ "dev": true,
+ "requires": {
+ "semver-compare": "^1.0.0"
+ }
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "js-base64": "^2.1.9",
+ "source-map": "^0.5.6",
+ "supports-color": "^3.2.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "dev": true,
+ "requires": {
+ "has-flag": "^1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-less": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-2.0.0.tgz",
+ "integrity": "sha512-pPNsVnpCB13nBMOcl5GVh8JGmB0JGFjqkLUDzKdVpptFFKEe9wFdEzvh2j4lD2AD+7qcrUfw9Ta+oi5+Fw7jjQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.2.16"
+ }
+ },
+ "postcss-media-query-parser": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
+ "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=",
+ "dev": true
+ },
+ "postcss-scss": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.0.0.tgz",
+ "integrity": "sha512-um9zdGKaDZirMm+kZFKKVsnKPF7zF7qBAtIfTSnZXD1jZ0JNZIxdB6TxQOjCnlSzLRInVl2v3YdBh/M881C4ug==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ },
+ "dependencies": {
+ "postcss": {
+ "version": "7.0.34",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.34.tgz",
+ "integrity": "sha512-H/7V2VeNScX9KE83GDrDZNiGT1m2H+UTnlinIzhjlLX9hfMUn1mHNnGeX81a1c8JSBdBvqk7c2ZOG6ZPn5itGw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2",
+ "source-map": "^0.6.1",
+ "supports-color": "^6.1.0"
+ }
+ },
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "postcss-selector-parser": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz",
+ "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=",
+ "dev": true,
+ "requires": {
+ "flatten": "^1.0.2",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ },
+ "postcss-values-parser": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-1.5.0.tgz",
+ "integrity": "sha512-3M3p+2gMp0AH3da530TlX8kiO1nxdTnc3C6vr8dMxRLIlh8UYkz0/wcwptSXjhtx2Fr0TySI7a+BHDQ8NL7LaQ==",
+ "dev": true,
+ "requires": {
+ "flatten": "^1.0.2",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "prettier-standard": {
+ "version": "16.4.1",
+ "resolved": "https://registry.npmjs.org/prettier-standard/-/prettier-standard-16.4.1.tgz",
+ "integrity": "sha512-IW3Sct4GOdqc1s4+1HZjH2HegzLZQ6mDMl2xz6i6KHCac7kCM+obLbvm2e0zp8PytKkLQCdOpj0cWWa48Ruetw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2",
+ "diff": "^4.0.2",
+ "eslint": "^6.8.0",
+ "execa": "^2.0.4",
+ "find-up": "^4.1.0",
+ "get-stdin": "^7.0.0",
+ "globby": "^6.1.0",
+ "ignore": "^3.3.7",
+ "lint-staged": "9.4.3",
+ "mri": "^1.1.5",
+ "multimatch": "^3.0.0",
+ "prettierx": "0.11.3"
+ }
+ },
+ "prettierx": {
+ "version": "0.11.3",
+ "resolved": "https://registry.npmjs.org/prettierx/-/prettierx-0.11.3.tgz",
+ "integrity": "sha512-Xf04LEfD3ITo26i5U/zR++hwqKPG3feR06rrjB0t2o+QFv8ZidFp4o7nPqPGLfE4UwHJgd0qwnZKwm0MsUQHUA==",
+ "dev": true,
+ "requires": {
+ "@angular/compiler": "8.2.14",
+ "@babel/code-frame": "7.8.3",
+ "@babel/parser": "7.9.4",
+ "@glimmer/syntax": "0.41.4",
+ "@iarna/toml": "2.2.3",
+ "@typescript-eslint/typescript-estree": "2.6.1",
+ "angular-estree-parser": "1.3.1",
+ "angular-html-parser": "1.4.0",
+ "camelcase": "5.3.1",
+ "chalk": "3.0.0",
+ "cjk-regex": "2.0.0",
+ "cosmiconfig": "5.2.1",
+ "dashify": "2.0.0",
+ "dedent": "0.7.0",
+ "diff": "4.0.2",
+ "editorconfig": "0.15.3",
+ "editorconfig-to-prettier": "0.1.1",
+ "escape-string-regexp": "2.0.0",
+ "esutils": "2.0.3",
+ "find-parent-dir": "0.3.0",
+ "find-project-root": "1.1.1",
+ "flow-parser": "0.111.3",
+ "get-stream": "4.1.0",
+ "globby": "6.1.0",
+ "graphql": "14.6.0",
+ "html-element-attributes": "2.2.1",
+ "html-styles": "1.0.0",
+ "html-tag-names": "1.1.5",
+ "ignore": "4.0.6",
+ "is-ci": "2.0.0",
+ "jest-docblock": "25.3.0",
+ "json-stable-stringify": "1.0.1",
+ "leven": "3.1.0",
+ "lines-and-columns": "1.1.6",
+ "linguist-languages": "7.6.0",
+ "lodash.uniqby": "4.7.0",
+ "mem": "5.1.1",
+ "minimatch": "3.0.4",
+ "minimist": "1.2.5",
+ "n-readlines": "1.0.0",
+ "normalize-path": "3.0.0",
+ "parse-srcset": "1.0.2",
+ "postcss-less": "2.0.0",
+ "postcss-media-query-parser": "0.2.3",
+ "postcss-scss": "2.0.0",
+ "postcss-selector-parser": "2.2.3",
+ "postcss-values-parser": "1.5.0",
+ "regexp-util": "1.2.2",
+ "remark-math": "1.0.6",
+ "remark-parse": "5.0.0",
+ "resolve": "1.15.1",
+ "semver": "6.3.0",
+ "string-width": "4.2.0",
+ "unicode-regex": "3.0.0",
+ "unified": "8.4.2",
+ "vnopts": "1.0.2",
+ "yaml": "1.8.3",
+ "yaml-unist-parser": "1.1.1"
+ },
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
+ "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.8.3"
+ }
+ },
+ "ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+ "dev": true,
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+ "dev": true
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "regenerator-runtime": {
+ "version": "0.13.7",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
+ "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
+ "dev": true
+ },
+ "regexp-util": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/regexp-util/-/regexp-util-1.2.2.tgz",
+ "integrity": "sha512-5/rl2UD18oAlLQEIuKBeiSIOp1hb5wCXcakl5yvHxlY1wyWI4D5cUKKzCibBeu741PA9JKvZhMqbkDQqPusX3w==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "regexpp": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+ "dev": true
+ },
+ "remark-math": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-1.0.6.tgz",
+ "integrity": "sha512-I43wU/QOQpXvVFXKjA4FHp5xptK65+5F6yolm8+69/JV0EqSOB64wURUZ3JK50JtnTL8FvwLiH2PZ+fvsBxviA==",
+ "dev": true,
"requires": {
- "wrappy": "1"
+ "trim-trailing-lines": "^1.1.0"
}
},
- "os-locale": {
- "version": "1.4.0",
- "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
- "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "remark-parse": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz",
+ "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==",
+ "dev": true,
"requires": {
- "lcid": "^1.0.0"
+ "collapse-white-space": "^1.0.2",
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-whitespace-character": "^1.0.0",
+ "is-word-character": "^1.0.0",
+ "markdown-escapes": "^1.0.0",
+ "parse-entities": "^1.1.0",
+ "repeat-string": "^1.5.4",
+ "state-toggle": "^1.0.0",
+ "trim": "0.0.1",
+ "trim-trailing-lines": "^1.0.0",
+ "unherit": "^1.0.4",
+ "unist-util-remove-position": "^1.0.0",
+ "vfile-location": "^2.0.0",
+ "xtend": "^4.0.1"
}
},
- "os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true
},
- "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="
+ "replace-ext": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
+ "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
+ "dev": true
},
- "pegjs": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.8.0.tgz",
- "integrity": "sha1-l28GfaE+XFsVAcAXklZoolOBFWE="
+ "resolve": {
+ "version": "1.15.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
+ "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
},
- "property-accessors": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/property-accessors/-/property-accessors-1.1.3.tgz",
- "integrity": "sha1-Hd6EAkYxhlkJ7zBwM2VoDF+SixU=",
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
"requires": {
- "es6-weak-map": "^0.1.2",
- "mixto": "1.x"
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
}
},
- "resolve": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-0.6.3.tgz",
- "integrity": "sha1-3ZV5gufnNt699TtYpN2RdUV13UY=",
+ "reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
"dev": true
},
"rimraf": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
- "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=",
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "requires": {
+ "glob": "^7.1.3"
+ },
+ "dependencies": {
+ "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"
+ }
+ }
+ }
+ },
+ "run-async": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+ "dev": true
+ },
+ "run-parallel": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
+ "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
+ "dev": true
+ },
+ "rxjs": {
+ "version": "6.6.3",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz",
+ "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==",
+ "dev": true,
"requires": {
- "glob": "^7.0.5"
+ "tslib": "^1.9.0"
}
},
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
"scoped-property-store": {
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/scoped-property-store/-/scoped-property-store-0.17.0.tgz",
@@ -424,6 +3173,100 @@
"yargs": "^3.23.0"
}
},
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "semver-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+ "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+ "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+ "dev": true
+ },
+ "simple-html-tokenizer": {
+ "version": "0.5.9",
+ "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.9.tgz",
+ "integrity": "sha512-w/3FEDN94r4JQ9WoYrIr8RqDIPZdyNkdpbK9glFady1CAEyD97XWCv8HFetQO21w81e7h7Nh59iYTyG1mUJftg==",
+ "dev": true
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+ "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "astral-regex": "^1.0.0",
+ "is-fullwidth-code-point": "^2.0.0"
+ },
+ "dependencies": {
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ }
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "state-toggle": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz",
+ "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==",
+ "dev": true
+ },
+ "string-argv": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
+ "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
+ "dev": true
+ },
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
@@ -434,6 +3277,17 @@
"strip-ansi": "^3.0.0"
}
},
+ "stringify-object": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
+ "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==",
+ "dev": true,
+ "requires": {
+ "get-own-enumerable-property-symbols": "^3.0.0",
+ "is-obj": "^1.0.1",
+ "is-regexp": "^1.0.0"
+ }
+ },
"strip-ansi": {
"version": "3.0.1",
"resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
@@ -442,39 +3296,372 @@
"ansi-regex": "^2.0.0"
}
},
+ "strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true
+ },
"strip-json-comments": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
- "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "symbol-observable": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==",
"dev": true
},
+ "table": {
+ "version": "5.4.6",
+ "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
+ "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.10.2",
+ "lodash": "^4.17.14",
+ "slice-ansi": "^2.1.0",
+ "string-width": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
"temp": {
- "version": "0.8.3",
- "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
- "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=",
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.1.tgz",
+ "integrity": "sha512-WMuOgiua1xb5R56lE0eH6ivpVmg/lq2OHm4+LtT/xtEtPQ+sz6N3bBM6WZ5FvO1lO4IKIOb43qnhoc4qxP5OeA==",
+ "dev": true,
"requires": {
- "os-tmpdir": "^1.0.0",
- "rimraf": "~2.2.6"
+ "rimraf": "~2.6.2"
},
"dependencies": {
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "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"
+ }
+ },
"rimraf": {
- "version": "2.2.8",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
- "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI="
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
}
}
},
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "~1.0.2"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "trim": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
+ "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=",
+ "dev": true
+ },
+ "trim-trailing-lines": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz",
+ "integrity": "sha512-4ku0mmjXifQcTVfYDfR5lpgV7zVqPg6zV9rdZmwOPqq0+Zq19xDqEgagqVbc4pOOShbncuAOIs59R3+3gcF3ZA==",
+ "dev": true
+ },
+ "trough": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz",
+ "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==",
+ "dev": true
+ },
+ "tslib": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
+ "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
+ "dev": true
+ },
+ "tsutils": {
+ "version": "3.17.1",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
+ "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.8.1"
+ }
+ },
+ "type": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true
+ },
+ "uglify-js": {
+ "version": "3.10.4",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.4.tgz",
+ "integrity": "sha512-kBFT3U4Dcj4/pJ52vfjCSfyLyvG9VYYuGYPmrPvAxRw/i7xHiT4VvCev+uiEMcEEiu6UNB6KgWmGtSUYIWScbw==",
+ "dev": true,
+ "optional": true
+ },
"underscore": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz",
- "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag="
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.11.0.tgz",
+ "integrity": "sha512-xY96SsN3NA461qIRKZ/+qox37YXPtSBswMGfiNptr+wrt6ds4HaMw23TP612fEyGekRE6LNRiLYr/aqbHXNedw=="
},
"underscore-plus": {
- "version": "1.6.6",
- "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.6.6.tgz",
- "integrity": "sha1-ZezeG9xEGjXYnmUP1w3PE65Dmn0=",
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz",
+ "integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==",
+ "requires": {
+ "underscore": "^1.9.1"
+ }
+ },
+ "unherit": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz",
+ "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "unicode-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-regex/-/unicode-regex-3.0.0.tgz",
+ "integrity": "sha512-WiDJdORsqgxkZrjC8WsIP573130HNn7KsB0IDnUccW2BG2b19QQNloNhVe6DKk3Aef0UcoIHhNVj7IkkcYWrNw==",
+ "dev": true,
+ "requires": {
+ "regexp-util": "^1.2.0"
+ }
+ },
+ "unified": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-8.4.2.tgz",
+ "integrity": "sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA==",
+ "dev": true,
+ "requires": {
+ "bail": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-plain-obj": "^2.0.0",
+ "trough": "^1.0.0",
+ "vfile": "^4.0.0"
+ }
+ },
+ "uniq": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
+ "dev": true
+ },
+ "unist-util-is": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz",
+ "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==",
+ "dev": true
+ },
+ "unist-util-remove-position": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz",
+ "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==",
+ "dev": true,
+ "requires": {
+ "unist-util-visit": "^1.1.0"
+ }
+ },
+ "unist-util-stringify-position": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
+ "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.2"
+ }
+ },
+ "unist-util-visit": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
+ "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
+ "dev": true,
+ "requires": {
+ "unist-util-visit-parents": "^2.0.0"
+ }
+ },
+ "unist-util-visit-parents": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
+ "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
+ "dev": true,
+ "requires": {
+ "unist-util-is": "^3.0.0"
+ }
+ },
+ "uri-js": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
+ "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "v8-compile-cache": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
+ "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==",
+ "dev": true
+ },
+ "vfile": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.0.tgz",
+ "integrity": "sha512-a/alcwCvtuc8OX92rqqo7PflxiCgXRFjdyoGVuYV+qbgCb0GgZJRvIgCD4+U/Kl1yhaRsaTwksF88xbPyGsgpw==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "is-buffer": "^2.0.0",
+ "replace-ext": "1.0.0",
+ "unist-util-stringify-position": "^2.0.0",
+ "vfile-message": "^2.0.0"
+ }
+ },
+ "vfile-location": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz",
+ "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==",
+ "dev": true
+ },
+ "vfile-message": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
+ "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
+ "dev": true,
"requires": {
- "underscore": "~1.6.0"
+ "@types/unist": "^2.0.0",
+ "unist-util-stringify-position": "^2.0.0"
+ }
+ },
+ "vnopts": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/vnopts/-/vnopts-1.0.2.tgz",
+ "integrity": "sha512-d2rr2EFhAGHnTlURu49G7GWmiJV80HbAnkYdD9IFAtfhmxC+kSWEaZ6ZF064DJFTv9lQZQV1vuLTntyQpoanGQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "leven": "^2.1.0",
+ "tslib": "^1.9.3"
+ },
+ "dependencies": {
+ "leven": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
+ "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=",
+ "dev": true
+ }
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
}
},
"window-size": {
@@ -482,15 +3669,21 @@
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
"integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY="
},
+ "word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true
+ },
"wordwrap": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
- "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
"dev": true
},
"wrap-ansi": {
"version": "2.1.0",
- "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"requires": {
"string-width": "^1.0.1",
@@ -502,14 +3695,55 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
+ "write": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+ "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
+ },
+ "xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true
+ },
"y18n": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
},
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
+ },
+ "yaml": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.8.3.tgz",
+ "integrity": "sha512-X/v7VDnK+sxbQ2Imq4Jt2PRUsRsP7UcpSl3Llg6+NRRqWLIvxkMFYtH1FmvwNGYRKKPa+EPA4qDBlI9WVG1UKw==",
+ "dev": true,
+ "requires": {
+ "@babel/runtime": "^7.8.7"
+ }
+ },
+ "yaml-unist-parser": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/yaml-unist-parser/-/yaml-unist-parser-1.1.1.tgz",
+ "integrity": "sha512-cGtqhHBlcft+rTKiPsVcSyi43Eqm5a1buYokW9VkztroKMErBSdR9ANHx+/XxNppHZTu2KMEn4yY8MdhuGoFuA==",
+ "dev": true,
+ "requires": {
+ "lines-and-columns": "^1.1.6",
+ "tslib": "^1.10.0",
+ "yaml": "^1.7.1"
+ }
+ },
"yargs": {
"version": "3.32.0",
- "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
"integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
"requires": {
"camelcase": "^2.0.1",
diff --git a/package.json b/package.json
index 7ced027..cfed826 100644
--- a/package.json
+++ b/package.json
@@ -1,23 +1,30 @@
{
"name": "snippets",
"version": "1.6.0",
- "main": "./lib/snippets",
"description": "Expand snippets matching the current prefix with `tab`.",
"repository": "https://github.com/atom/snippets",
"license": "MIT",
- "engines": {
- "atom": "*"
+ "main": "./lib/snippets",
+ "scripts": {
+ "lint": "prettier-standard --lint",
+ "test": "npm run lint && atom --test spec"
},
"dependencies": {
- "async": "~0.2.6",
- "atom-select-list": "^0.7.0",
- "fs-plus": "^3.0.0",
+ "async": "^3.2.0",
+ "atom-select-list": "^0.7.2",
+ "fs-plus": "^3.1.1",
"loophole": "^1",
"pegjs": "~0.8.0",
"scoped-property-store": "^0.17.0",
"season": "^6.0.2",
- "temp": "~0.8.0",
- "underscore-plus": "^1.0.0"
+ "underscore-plus": "^1.7.0"
+ },
+ "devDependencies": {
+ "prettier-standard": "^16.4.1",
+ "temp": "^0.9.1"
+ },
+ "engines": {
+ "atom": "*"
},
"providedServices": {
"snippets": {
@@ -26,8 +33,5 @@
"0.1.0": "provideSnippets"
}
}
- },
- "devDependencies": {
- "coffeelint": "^1.9.7"
}
}
diff --git a/spec/body-parser-spec.js b/spec/body-parser-spec.js
index 35492de..3e62e6c 100644
--- a/spec/body-parser-spec.js
+++ b/spec/body-parser-spec.js
@@ -1,227 +1,205 @@
-const BodyParser = require('../lib/snippet-body-parser');
+const BodyParser = require('../lib/snippet-body-parser')
-describe("Snippet Body Parser", () => {
- it("breaks a snippet body into lines, with each line containing tab stops at the appropriate position", () => {
+describe('Snippet Body Parser', () => {
+ it('breaks a snippet body into lines, with each line containing tab stops at the appropriate position', () => {
const bodyTree = BodyParser.parse(`\
the quick brown $1fox \${2:jumped \${3:over}
}the \${4:lazy} dog\
-`
- );
+`)
expect(bodyTree).toEqual([
- "the quick brown ",
- {index: 1, content: []},
- "fox ",
+ 'the quick brown ',
+ { index: 1, content: [] },
+ 'fox ',
{
index: 2,
- content: [
- "jumped ",
- {index: 3, content: ["over"]},
- "\n"
- ],
+ content: ['jumped ', { index: 3, content: ['over'] }, '\n']
},
- "the ",
- {index: 4, content: ["lazy"]},
- " dog"
- ]);
- });
+ 'the ',
+ { index: 4, content: ['lazy'] },
+ ' dog'
+ ])
+ })
it("removes interpolated variables in placeholder text (we don't currently support it)", () => {
- const bodyTree = BodyParser.parse("module ${1:ActiveRecord::${TM_FILENAME/(?:\\A|_)([A-Za-z0-9]+)(?:\\.rb)?/(?2::\\u$1)/g}}");
+ const bodyTree = BodyParser.parse(
+ 'module ${1:ActiveRecord::${TM_FILENAME/(?:\\A|_)([A-Za-z0-9]+)(?:\\.rb)?/(?2::\\u$1)/g}}'
+ )
expect(bodyTree).toEqual([
- "module ",
+ 'module ',
{
- "index": 1,
- "content": ["ActiveRecord::", ""]
+ index: 1,
+ content: ['ActiveRecord::', '']
}
- ]);
- });
+ ])
+ })
- it("skips escaped tabstops", () => {
- const bodyTree = BodyParser.parse("snippet $1 escaped \\$2 \\\\$3");
+ it('skips escaped tabstops', () => {
+ const bodyTree = BodyParser.parse('snippet $1 escaped \\$2 \\\\$3')
expect(bodyTree).toEqual([
- "snippet ",
+ 'snippet ',
{
index: 1,
content: []
},
- " escaped $2 \\",
+ ' escaped $2 \\',
{
index: 3,
content: []
}
- ]);
- });
+ ])
+ })
- it("includes escaped right-braces", () => {
- const bodyTree = BodyParser.parse("snippet ${1:{\\}}");
+ it('includes escaped right-braces', () => {
+ const bodyTree = BodyParser.parse(`snippet \${1:{\\}}`)
expect(bodyTree).toEqual([
- "snippet ",
+ 'snippet ',
{
index: 1,
- content: ["{}"]
+ content: ['{}']
}
- ]);
- });
+ ])
+ })
- it("parses a snippet with transformations", () => {
- const bodyTree = BodyParser.parse("<${1:p}>$0${1/f/F/}>");
+ it('parses a snippet with transformations', () => {
+ const bodyTree = BodyParser.parse('<${1:p}>$0${1/f/F/}>')
expect(bodyTree).toEqual([
'<',
- {index: 1, content: ['p']},
+ { index: 1, content: ['p'] },
'>',
- {index: 0, content: []},
+ { index: 0, content: [] },
'',
- {index: 1, content: [], substitution: {find: /f/g, replace: ['F']}},
+ { index: 1, content: [], substitution: { find: /f/g, replace: ['F'] } },
'>'
- ]);
- });
+ ])
+ })
- it("parses a snippet with multiple tab stops with transformations", () => {
- const bodyTree = BodyParser.parse("${1:placeholder} ${1/(.)/\\u$1/} $1 ${2:ANOTHER} ${2/^(.*)$/\\L$1/} $2");
+ it('parses a snippet with multiple tab stops with transformations', () => {
+ const bodyTree = BodyParser.parse(
+ '${1:placeholder} ${1/(.)/\\u$1/} $1 ${2:ANOTHER} ${2/^(.*)$/\\L$1/} $2'
+ )
expect(bodyTree).toEqual([
- {index: 1, content: ['placeholder']},
+ { index: 1, content: ['placeholder'] },
' ',
{
index: 1,
content: [],
substitution: {
find: /(.)/g,
- replace: [
- {escape: 'u'},
- {backreference: 1}
- ]
+ replace: [{ escape: 'u' }, { backreference: 1 }]
}
},
' ',
- {index: 1, content: []},
+ { index: 1, content: [] },
' ',
- {index: 2, content: ['ANOTHER']},
+ { index: 2, content: ['ANOTHER'] },
' ',
{
index: 2,
content: [],
substitution: {
find: /^(.*)$/g,
- replace: [
- {escape: 'L'},
- {backreference: 1}
- ]
+ replace: [{ escape: 'L' }, { backreference: 1 }]
}
},
' ',
- {index: 2, content: []},
- ]);
- });
-
+ { index: 2, content: [] }
+ ])
+ })
- it("parses a snippet with transformations and mirrors", () => {
- const bodyTree = BodyParser.parse("${1:placeholder}\n${1/(.)/\\u$1/}\n$1");
+ it('parses a snippet with transformations and mirrors', () => {
+ const bodyTree = BodyParser.parse('${1:placeholder}\n${1/(.)/\\u$1/}\n$1')
expect(bodyTree).toEqual([
- {index: 1, content: ['placeholder']},
+ { index: 1, content: ['placeholder'] },
'\n',
{
index: 1,
content: [],
substitution: {
find: /(.)/g,
- replace: [
- {escape: 'u'},
- {backreference: 1}
- ]
+ replace: [{ escape: 'u' }, { backreference: 1 }]
}
},
'\n',
- {index: 1, content: []}
- ]);
- });
+ { index: 1, content: [] }
+ ])
+ })
- it("parses a snippet with a format string and case-control flags", () => {
- const bodyTree = BodyParser.parse("<${1:p}>$0${1/(.)(.*)/\\u$1$2/}>");
+ it('parses a snippet with a format string and case-control flags', () => {
+ const bodyTree = BodyParser.parse('<${1:p}>$0${1/(.)(.*)/\\u$1$2/}>')
expect(bodyTree).toEqual([
'<',
- {index: 1, content: ['p']},
+ { index: 1, content: ['p'] },
'>',
- {index: 0, content: []},
+ { index: 0, content: [] },
'',
{
index: 1,
content: [],
substitution: {
find: /(.)(.*)/g,
- replace: [
- {escape: 'u'},
- {backreference: 1},
- {backreference: 2}
- ]
+ replace: [{ escape: 'u' }, { backreference: 1 }, { backreference: 2 }]
}
},
'>'
- ]);
- });
+ ])
+ })
- it("parses a snippet with an escaped forward slash in a transform", () => {
+ it('parses a snippet with an escaped forward slash in a transform', () => {
// Annoyingly, a forward slash needs to be double-backslashed just like the
// other escapes.
- const bodyTree = BodyParser.parse("<${1:p}>$0${1/(.)\\/(.*)/\\u$1$2/}>");
+ const bodyTree = BodyParser.parse('<${1:p}>$0${1/(.)\\/(.*)/\\u$1$2/}>')
expect(bodyTree).toEqual([
'<',
- {index: 1, content: ['p']},
+ { index: 1, content: ['p'] },
'>',
- {index: 0, content: []},
+ { index: 0, content: [] },
'',
{
index: 1,
content: [],
substitution: {
find: /(.)\/(.*)/g,
- replace: [
- {escape: 'u'},
- {backreference: 1},
- {backreference: 2}
- ]
+ replace: [{ escape: 'u' }, { backreference: 1 }, { backreference: 2 }]
}
},
'>'
- ]);
- });
+ ])
+ })
it("parses a snippet with a placeholder that mirrors another tab stop's content", () => {
- const bodyTree = BodyParser.parse("$4console.${3:log}('${2:$1}', $1);$0");
+ const bodyTree = BodyParser.parse("$4console.${3:log}('${2:$1}', $1);$0")
expect(bodyTree).toEqual([
- {index: 4, content: []},
+ { index: 4, content: [] },
'console.',
- {index: 3, content: ['log']},
- '(\'',
+ { index: 3, content: ['log'] },
+ "('",
{
- index: 2, content: [
- {index: 1, content: []}
- ]
+ index: 2,
+ content: [{ index: 1, content: [] }]
},
- '\', ',
- {index: 1, content: []},
+ "', ",
+ { index: 1, content: [] },
');',
- {index: 0, content: []}
- ]);
- });
+ { index: 0, content: [] }
+ ])
+ })
- it("parses a snippet with a placeholder that mixes text and tab stop references", () => {
- const bodyTree = BodyParser.parse("$4console.${3:log}('${2:uh $1}', $1);$0");
+ it('parses a snippet with a placeholder that mixes text and tab stop references', () => {
+ const bodyTree = BodyParser.parse("$4console.${3:log}('${2:uh $1}', $1);$0")
expect(bodyTree).toEqual([
- {index: 4, content: []},
+ { index: 4, content: [] },
'console.',
- {index: 3, content: ['log']},
- '(\'',
+ { index: 3, content: ['log'] },
+ "('",
{
- index: 2, content: [
- 'uh ',
- {index: 1, content: []}
- ]
+ index: 2,
+ content: ['uh ', { index: 1, content: [] }]
},
- '\', ',
- {index: 1, content: []},
+ "', ",
+ { index: 1, content: [] },
');',
- {index: 0, content: []}
- ]);
- });
-});
+ { index: 0, content: [] }
+ ])
+ })
+})
diff --git a/spec/insertion-spec.js b/spec/insertion-spec.js
index 83fac92..949870d 100644
--- a/spec/insertion-spec.js
+++ b/spec/insertion-spec.js
@@ -5,30 +5,30 @@ const range = new Range(0, 0)
describe('Insertion', () => {
it('returns what it was given when it has no substitution', () => {
- let insertion = new Insertion({
+ const insertion = new Insertion({
range,
substitution: undefined
})
- let transformed = insertion.transform('foo!')
+ const transformed = insertion.transform('foo!')
expect(transformed).toEqual('foo!')
})
it('transforms what it was given when it has a regex transformation', () => {
- let insertion = new Insertion({
+ const insertion = new Insertion({
range,
substitution: {
find: /foo/g,
replace: ['bar']
}
})
- let transformed = insertion.transform('foo!')
+ const transformed = insertion.transform('foo!')
expect(transformed).toEqual('bar!')
})
it('transforms the case of the next character when encountering a \\u or \\l flag', () => {
- let uInsertion = new Insertion({
+ const uInsertion = new Insertion({
range,
substitution: {
find: /(.)(.)(.*)/g,
@@ -45,7 +45,7 @@ describe('Insertion', () => {
expect(uInsertion.transform('fOo!')).toEqual('fOo!')
expect(uInsertion.transform('FOO!')).toEqual('FOO!')
- let lInsertion = new Insertion({
+ const lInsertion = new Insertion({
range,
substitution: {
find: /(.{2})(.)(.*)/g,
@@ -65,15 +65,11 @@ describe('Insertion', () => {
})
it('transforms the case of all remaining characters when encountering a \\U or \\L flag, up until it sees a \\E flag', () => {
- let uInsertion = new Insertion({
+ const uInsertion = new Insertion({
range,
substitution: {
find: /(.)(.*)/,
- replace: [
- { backreference: 1 },
- { escape: 'U' },
- { backreference: 2 }
- ]
+ replace: [{ backreference: 1 }, { escape: 'U' }, { backreference: 2 }]
}
})
@@ -81,7 +77,7 @@ describe('Insertion', () => {
expect(uInsertion.transform('lOREM IPSUM!')).toEqual('lOREM IPSUM!')
expect(uInsertion.transform('LOREM IPSUM!')).toEqual('LOREM IPSUM!')
- let ueInsertion = new Insertion({
+ const ueInsertion = new Insertion({
range,
substitution: {
find: /(.)(.{3})(.*)/,
@@ -99,7 +95,7 @@ describe('Insertion', () => {
expect(ueInsertion.transform('lOREm ipsum!')).toEqual('lOREm ipsum!')
expect(ueInsertion.transform('LOREM IPSUM!')).toEqual('LOREM IPSUM!')
- let lInsertion = new Insertion({
+ const lInsertion = new Insertion({
range,
substitution: {
find: /(.{4})(.)(.*)/,
@@ -114,7 +110,7 @@ describe('Insertion', () => {
expect(lInsertion.transform('LOREM IPSUM!')).toEqual('LOREmwhat')
- let leInsertion = new Insertion({
+ const leInsertion = new Insertion({
range,
substitution: {
find: /^([A-Fa-f])(.*)(.)$/,
diff --git a/spec/snippet-loading-spec.js b/spec/snippet-loading-spec.js
index d6c5dd1..a9b280d 100644
--- a/spec/snippet-loading-spec.js
+++ b/spec/snippet-loading-spec.js
@@ -1,132 +1,164 @@
-const path = require('path');
-const fs = require('fs-plus');
-const temp = require('temp').track();
+const path = require('path')
+const fs = require('fs-plus')
+const temp = require('temp').track()
-describe("Snippet Loading", () => {
- let configDirPath, snippetsService;
+describe('Snippet Loading', () => {
+ let configDirPath, snippetsService
beforeEach(() => {
- configDirPath = temp.mkdirSync('atom-config-dir-');
- spyOn(atom, 'getConfigDirPath').andReturn(configDirPath);
+ configDirPath = temp.mkdirSync('atom-config-dir-')
+ spyOn(atom, 'getConfigDirPath').andReturn(configDirPath)
- spyOn(console, 'warn');
- if (atom.notifications != null) { spyOn(atom.notifications, 'addError'); }
+ spyOn(console, 'warn')
+ if (atom.notifications != null) {
+ spyOn(atom.notifications, 'addError')
+ }
spyOn(atom.packages, 'getLoadedPackages').andReturn([
- atom.packages.loadPackage(path.join(__dirname, 'fixtures', 'package-with-snippets')),
- atom.packages.loadPackage(path.join(__dirname, 'fixtures', 'package-with-broken-snippets')),
- ]);
- });
+ atom.packages.loadPackage(
+ path.join(__dirname, 'fixtures', 'package-with-snippets')
+ ),
+ atom.packages.loadPackage(
+ path.join(__dirname, 'fixtures', 'package-with-broken-snippets')
+ )
+ ])
+ })
afterEach(() => {
- waitsForPromise(() => Promise.resolve(atom.packages.deactivatePackages('snippets')));
+ waitsForPromise(() =>
+ Promise.resolve(atom.packages.deactivatePackages('snippets'))
+ )
runs(() => {
- jasmine.unspy(atom.packages, 'getLoadedPackages');
- });
- });
+ jasmine.unspy(atom.packages, 'getLoadedPackages')
+ })
+ })
const activateSnippetsPackage = () => {
- waitsForPromise(() => atom.packages.activatePackage("snippets").then(({mainModule}) => {
- snippetsService = mainModule.provideSnippets();
- mainModule.loaded = false;
- }));
-
- waitsFor("all snippets to load", 3000, () => snippetsService.bundledSnippetsLoaded());
- };
+ waitsForPromise(() =>
+ atom.packages.activatePackage('snippets').then(({ mainModule }) => {
+ snippetsService = mainModule.provideSnippets()
+ mainModule.loaded = false
+ })
+ )
+
+ waitsFor('all snippets to load', 3000, () =>
+ snippetsService.bundledSnippetsLoaded()
+ )
+ }
- it("loads the bundled snippet template snippets", () => {
- activateSnippetsPackage();
+ it('loads the bundled snippet template snippets', () => {
+ activateSnippetsPackage()
runs(() => {
- const jsonSnippet = snippetsService.snippetsForScopes(['.source.json'])['snip'];
- expect(jsonSnippet.name).toBe('Atom Snippet');
- expect(jsonSnippet.prefix).toBe('snip');
- expect(jsonSnippet.body).toContain('"prefix":');
- expect(jsonSnippet.body).toContain('"body":');
- expect(jsonSnippet.tabStopList.length).toBeGreaterThan(0);
-
- const csonSnippet = snippetsService.snippetsForScopes(['.source.coffee'])['snip'];
- expect(csonSnippet.name).toBe('Atom Snippet');
- expect(csonSnippet.prefix).toBe('snip');
- expect(csonSnippet.body).toContain("'prefix':");
- expect(csonSnippet.body).toContain("'body':");
- expect(csonSnippet.tabStopList.length).toBeGreaterThan(0);
- });
- });
-
- it("loads non-hidden snippet files from atom packages with snippets directories", () => {
- activateSnippetsPackage();
+ const jsonSnippet = snippetsService.snippetsForScopes(['.source.json'])
+ .snip
+ expect(jsonSnippet.name).toBe('Atom Snippet')
+ expect(jsonSnippet.prefix).toBe('snip')
+ expect(jsonSnippet.body).toContain('"prefix":')
+ expect(jsonSnippet.body).toContain('"body":')
+ expect(jsonSnippet.tabStopList.length).toBeGreaterThan(0)
+
+ const csonSnippet = snippetsService.snippetsForScopes(['.source.coffee'])
+ .snip
+ expect(csonSnippet.name).toBe('Atom Snippet')
+ expect(csonSnippet.prefix).toBe('snip')
+ expect(csonSnippet.body).toContain("'prefix':")
+ expect(csonSnippet.body).toContain("'body':")
+ expect(csonSnippet.tabStopList.length).toBeGreaterThan(0)
+ })
+ })
+
+ it('loads non-hidden snippet files from atom packages with snippets directories', () => {
+ activateSnippetsPackage()
runs(() => {
- let snippet = snippetsService.snippetsForScopes(['.test'])['test'];
- expect(snippet.prefix).toBe('test');
- expect(snippet.body).toBe('testing 123');
-
- snippet = snippetsService.snippetsForScopes(['.test'])['testd'];
- expect(snippet.prefix).toBe('testd');
- expect(snippet.body).toBe('testing 456');
- expect(snippet.description).toBe('a description');
- expect(snippet.descriptionMoreURL).toBe('http://google.com');
-
- snippet = snippetsService.snippetsForScopes(['.test'])['testlabelleft'];
- expect(snippet.prefix).toBe('testlabelleft');
- expect(snippet.body).toBe('testing 456');
- expect(snippet.leftLabel).toBe('a label');
-
- snippet = snippetsService.snippetsForScopes(['.test'])['testhtmllabels'];
- expect(snippet.prefix).toBe('testhtmllabels');
- expect(snippet.body).toBe('testing 456');
- expect(snippet.leftLabelHTML).toBe('Label');
- expect(snippet.rightLabelHTML).toBe('Label');
- });
- });
-
- it("logs a warning if package snippets files cannot be parsed", () => {
- activateSnippetsPackage();
+ let snippet = snippetsService.snippetsForScopes(['.test']).test
+ expect(snippet.prefix).toBe('test')
+ expect(snippet.body).toBe('testing 123')
+
+ snippet = snippetsService.snippetsForScopes(['.test']).testd
+ expect(snippet.prefix).toBe('testd')
+ expect(snippet.body).toBe('testing 456')
+ expect(snippet.description).toBe('a description')
+ expect(snippet.descriptionMoreURL).toBe('http://google.com')
+
+ snippet = snippetsService.snippetsForScopes(['.test']).testlabelleft
+ expect(snippet.prefix).toBe('testlabelleft')
+ expect(snippet.body).toBe('testing 456')
+ expect(snippet.leftLabel).toBe('a label')
+
+ snippet = snippetsService.snippetsForScopes(['.test']).testhtmllabels
+ expect(snippet.prefix).toBe('testhtmllabels')
+ expect(snippet.body).toBe('testing 456')
+ expect(snippet.leftLabelHTML).toBe('Label')
+ expect(snippet.rightLabelHTML).toBe(
+ 'Label'
+ )
+ })
+ })
+
+ it('logs a warning if package snippets files cannot be parsed', () => {
+ activateSnippetsPackage()
runs(() => {
// Warn about invalid-file, but don't even try to parse a hidden file
- expect(console.warn.calls.length).toBeGreaterThan(0);
- expect(console.warn.mostRecentCall.args[0]).toMatch(/Error reading.*package-with-broken-snippets/);
- });
- });
-
- describe("::loadPackageSnippets(callback)", () => {
- beforeEach(() => { // simulate a list of packages where the javascript core package is returned at the end
- atom.packages.getLoadedPackages.andReturn([
- atom.packages.loadPackage(path.join(__dirname, 'fixtures', 'package-with-snippets')),
+ expect(console.warn.calls.length).toBeGreaterThan(0)
+ expect(console.warn.mostRecentCall.args[0]).toMatch(
+ /Error reading.*package-with-broken-snippets/
+ )
+ })
+ })
+
+ describe('::loadPackageSnippets(callback)', () => {
+ beforeEach(() => {
+ // simulate a list of packages where the javascript core package is returned at the end
+ atom.packages.getLoadedPackages.andReturn([
+ atom.packages.loadPackage(
+ path.join(__dirname, 'fixtures', 'package-with-snippets')
+ ),
atom.packages.loadPackage('language-javascript')
])
- });
+ })
it("allows other packages to override core packages' snippets", () => {
- waitsForPromise(() => atom.packages.activatePackage("language-javascript"));
+ waitsForPromise(() =>
+ atom.packages.activatePackage('language-javascript')
+ )
- activateSnippetsPackage();
+ activateSnippetsPackage()
runs(() => {
- const snippet = snippetsService.snippetsForScopes(['.source.js'])['log'];
- expect(snippet.body).toBe("from-a-community-package");
- });
- });
- });
-
- describe("::onDidLoadSnippets(callback)", () => {
- it("invokes listeners when all snippets are loaded", () => {
- let loadedCallback = null;
-
- waitsFor("package to activate", done => atom.packages.activatePackage("snippets").then(({mainModule}) => {
- mainModule.onDidLoadSnippets(loadedCallback = jasmine.createSpy('onDidLoadSnippets callback'));
- done();
- }));
-
- waitsFor("onDidLoad callback to be called", () => loadedCallback.callCount > 0);
- });
- });
-
- describe("when ~/.atom/snippets.json exists", () => {
+ const snippet = snippetsService.snippetsForScopes(['.source.js']).log
+ expect(snippet.body).toBe('from-a-community-package')
+ })
+ })
+ })
+
+ describe('::onDidLoadSnippets(callback)', () => {
+ it('invokes listeners when all snippets are loaded', () => {
+ let loadedCallback = null
+
+ waitsFor('package to activate', done =>
+ atom.packages.activatePackage('snippets').then(({ mainModule }) => {
+ mainModule.onDidLoadSnippets(
+ (loadedCallback = jasmine.createSpy('onDidLoadSnippets callback'))
+ )
+ done()
+ })
+ )
+
+ waitsFor(
+ 'onDidLoad callback to be called',
+ () => loadedCallback.callCount > 0
+ )
+ })
+ })
+
+ describe('when ~/.atom/snippets.json exists', () => {
beforeEach(() => {
- fs.writeFileSync(path.join(configDirPath, 'snippets.json'), `\
+ fs.writeFileSync(
+ path.join(configDirPath, 'snippets.json'),
+ `\
{
".foo": {
"foo snippet": {
@@ -136,25 +168,29 @@ describe("Snippet Loading", () => {
}
}\
`
- );
- activateSnippetsPackage();
- });
+ )
+ activateSnippetsPackage()
+ })
- it("loads the snippets from that file", () => {
- let snippet = null;
+ it('loads the snippets from that file', () => {
+ let snippet = null
- waitsFor(() => snippet = snippetsService.snippetsForScopes(['.foo'])['foo']);
+ waitsFor(
+ () => (snippet = snippetsService.snippetsForScopes(['.foo']).foo)
+ )
runs(() => {
- expect(snippet.name).toBe('foo snippet');
- expect(snippet.prefix).toBe("foo");
- expect(snippet.body).toBe("bar1");
- });
- });
-
- describe("when that file changes", () => {
- it("reloads the snippets", () => {
- fs.writeFileSync(path.join(configDirPath, 'snippets.json'), `\
+ expect(snippet.name).toBe('foo snippet')
+ expect(snippet.prefix).toBe('foo')
+ expect(snippet.body).toBe('bar1')
+ })
+ })
+
+ describe('when that file changes', () => {
+ it('reloads the snippets', () => {
+ fs.writeFileSync(
+ path.join(configDirPath, 'snippets.json'),
+ `\
{
".foo": {
"foo snippet": {
@@ -164,146 +200,181 @@ describe("Snippet Loading", () => {
}
}\
`
- );
+ )
- waitsFor("snippets to be changed", () => {
- const snippet = snippetsService.snippetsForScopes(['.foo'])['foo'];
- return snippet && snippet.body === 'bar2';
- });
+ waitsFor('snippets to be changed', () => {
+ const snippet = snippetsService.snippetsForScopes(['.foo']).foo
+ return snippet && snippet.body === 'bar2'
+ })
runs(() => {
- fs.writeFileSync(path.join(configDirPath, 'snippets.json'), "");
- });
-
- waitsFor("snippets to be removed", () => !snippetsService.snippetsForScopes(['.foo'])['foo']);
- });
- });
- });
-
- describe("when ~/.atom/snippets.cson exists", () => {
+ fs.writeFileSync(path.join(configDirPath, 'snippets.json'), '')
+ })
+
+ waitsFor(
+ 'snippets to be removed',
+ () => !snippetsService.snippetsForScopes(['.foo']).foo
+ )
+ })
+ })
+ })
+
+ describe('when ~/.atom/snippets.cson exists', () => {
beforeEach(() => {
- fs.writeFileSync(path.join(configDirPath, 'snippets.cson'), `\
+ fs.writeFileSync(
+ path.join(configDirPath, 'snippets.cson'),
+ `\
".foo":
"foo snippet":
"prefix": "foo"
"body": "bar1"\
`
- );
- activateSnippetsPackage();
- });
+ )
+ activateSnippetsPackage()
+ })
- it("loads the snippets from that file", () => {
- let snippet = null;
+ it('loads the snippets from that file', () => {
+ let snippet = null
- waitsFor(() => snippet = snippetsService.snippetsForScopes(['.foo'])['foo']);
+ waitsFor(
+ () => (snippet = snippetsService.snippetsForScopes(['.foo']).foo)
+ )
runs(() => {
- expect(snippet.name).toBe('foo snippet');
- expect(snippet.prefix).toBe("foo");
- expect(snippet.body).toBe("bar1");
- });
- });
-
- describe("when that file changes", () => {
- it("reloads the snippets", () => {
- fs.writeFileSync(path.join(configDirPath, 'snippets.cson'), `\
+ expect(snippet.name).toBe('foo snippet')
+ expect(snippet.prefix).toBe('foo')
+ expect(snippet.body).toBe('bar1')
+ })
+ })
+
+ describe('when that file changes', () => {
+ it('reloads the snippets', () => {
+ fs.writeFileSync(
+ path.join(configDirPath, 'snippets.cson'),
+ `\
".foo":
"foo snippet":
"prefix": "foo"
"body": "bar2"\
`
- );
+ )
- waitsFor("snippets to be changed", () => {
- const snippet = snippetsService.snippetsForScopes(['.foo'])['foo'];
- return snippet && snippet.body === 'bar2';
- });
+ waitsFor('snippets to be changed', () => {
+ const snippet = snippetsService.snippetsForScopes(['.foo']).foo
+ return snippet && snippet.body === 'bar2'
+ })
runs(() => {
- fs.writeFileSync(path.join(configDirPath, 'snippets.cson'), "");
- });
+ fs.writeFileSync(path.join(configDirPath, 'snippets.cson'), '')
+ })
- waitsFor("snippets to be removed", () => {
- const snippet = snippetsService.snippetsForScopes(['.foo'])['foo'];
- return snippet == null;
- });
- });
- });
- });
+ waitsFor('snippets to be removed', () => {
+ const snippet = snippetsService.snippetsForScopes(['.foo']).foo
+ return snippet == null
+ })
+ })
+ })
+ })
- it("notifies the user when the user snippets file cannot be loaded", () => {
- fs.writeFileSync(path.join(configDirPath, 'snippets.cson'), '".junk":::');
+ it('notifies the user when the user snippets file cannot be loaded', () => {
+ fs.writeFileSync(path.join(configDirPath, 'snippets.cson'), '".junk":::')
- activateSnippetsPackage();
+ activateSnippetsPackage()
runs(() => {
- expect(console.warn).toHaveBeenCalled();
+ expect(console.warn).toHaveBeenCalled()
if (atom.notifications != null) {
- expect(atom.notifications.addError).toHaveBeenCalled();
+ expect(atom.notifications.addError).toHaveBeenCalled()
}
- });
- });
+ })
+ })
- describe("packages-with-snippets-disabled feature", () => {
- it("disables no snippets if the config option is empty", () => {
- const originalConfig = atom.config.get('core.packagesWithSnippetsDisabled');
- atom.config.set('core.packagesWithSnippetsDisabled', []);
+ describe('packages-with-snippets-disabled feature', () => {
+ it('disables no snippets if the config option is empty', () => {
+ const originalConfig = atom.config.get(
+ 'core.packagesWithSnippetsDisabled'
+ )
+ atom.config.set('core.packagesWithSnippetsDisabled', [])
- activateSnippetsPackage();
+ activateSnippetsPackage()
runs(() => {
- const snippets = snippetsService.snippetsForScopes(['.package-with-snippets-unique-scope']);
- expect(Object.keys(snippets).length).toBe(1);
- atom.config.set('core.packagesWithSnippetsDisabled', originalConfig);
- });
- });
+ const snippets = snippetsService.snippetsForScopes([
+ '.package-with-snippets-unique-scope'
+ ])
+ expect(Object.keys(snippets).length).toBe(1)
+ atom.config.set('core.packagesWithSnippetsDisabled', originalConfig)
+ })
+ })
it("still includes a disabled package's snippets in the list of unparsed snippets", () => {
- let originalConfig = atom.config.get('core.packagesWithSnippetsDisabled');
- atom.config.set('core.packagesWithSnippetsDisabled', []);
+ const originalConfig = atom.config.get(
+ 'core.packagesWithSnippetsDisabled'
+ )
+ atom.config.set('core.packagesWithSnippetsDisabled', [])
- activateSnippetsPackage();
+ activateSnippetsPackage()
runs(() => {
- atom.config.set('core.packagesWithSnippetsDisabled', ['package-with-snippets']);
- const allSnippets = snippetsService.getUnparsedSnippets();
- const scopedSnippet = allSnippets.find(s => s.selectorString === '.package-with-snippets-unique-scope');
- expect(scopedSnippet).not.toBe(undefined);
- atom.config.set('core.packagesWithSnippetsDisabled', originalConfig);
- });
- });
+ atom.config.set('core.packagesWithSnippetsDisabled', [
+ 'package-with-snippets'
+ ])
+ const allSnippets = snippetsService.getUnparsedSnippets()
+ const scopedSnippet = allSnippets.find(
+ s => s.selectorString === '.package-with-snippets-unique-scope'
+ )
+ expect(scopedSnippet).not.toBe(undefined)
+ atom.config.set('core.packagesWithSnippetsDisabled', originalConfig)
+ })
+ })
it("never loads a package's snippets when that package is disabled in config", () => {
- const originalConfig = atom.config.get('core.packagesWithSnippetsDisabled');
- atom.config.set('core.packagesWithSnippetsDisabled', ['package-with-snippets']);
+ const originalConfig = atom.config.get(
+ 'core.packagesWithSnippetsDisabled'
+ )
+ atom.config.set('core.packagesWithSnippetsDisabled', [
+ 'package-with-snippets'
+ ])
- activateSnippetsPackage();
+ activateSnippetsPackage()
runs(() => {
- const snippets = snippetsService.snippetsForScopes(['.package-with-snippets-unique-scope']);
- expect(Object.keys(snippets).length).toBe(0);
- atom.config.set('core.packagesWithSnippetsDisabled', originalConfig);
- });
- });
-
- it("unloads and/or reloads snippets from a package if the config option is changed after activation", () => {
- const originalConfig = atom.config.get('core.packagesWithSnippetsDisabled');
- atom.config.set('core.packagesWithSnippetsDisabled', []);
-
- activateSnippetsPackage();
+ const snippets = snippetsService.snippetsForScopes([
+ '.package-with-snippets-unique-scope'
+ ])
+ expect(Object.keys(snippets).length).toBe(0)
+ atom.config.set('core.packagesWithSnippetsDisabled', originalConfig)
+ })
+ })
+
+ it('unloads and/or reloads snippets from a package if the config option is changed after activation', () => {
+ const originalConfig = atom.config.get(
+ 'core.packagesWithSnippetsDisabled'
+ )
+ atom.config.set('core.packagesWithSnippetsDisabled', [])
+
+ activateSnippetsPackage()
runs(() => {
- let snippets = snippetsService.snippetsForScopes(['.package-with-snippets-unique-scope']);
- expect(Object.keys(snippets).length).toBe(1);
+ let snippets = snippetsService.snippetsForScopes([
+ '.package-with-snippets-unique-scope'
+ ])
+ expect(Object.keys(snippets).length).toBe(1)
// Disable it.
- atom.config.set('core.packagesWithSnippetsDisabled', ['package-with-snippets']);
- snippets = snippetsService.snippetsForScopes(['.package-with-snippets-unique-scope']);
- expect(Object.keys(snippets).length).toBe(0);
+ atom.config.set('core.packagesWithSnippetsDisabled', [
+ 'package-with-snippets'
+ ])
+ snippets = snippetsService.snippetsForScopes([
+ '.package-with-snippets-unique-scope'
+ ])
+ expect(Object.keys(snippets).length).toBe(0)
// Re-enable it.
- atom.config.set('core.packagesWithSnippetsDisabled', []);
- snippets = snippetsService.snippetsForScopes(['.package-with-snippets-unique-scope']);
- expect(Object.keys(snippets).length).toBe(1);
-
- atom.config.set('core.packagesWithSnippetsDisabled', originalConfig);
- });
- });
- });
-});
+ atom.config.set('core.packagesWithSnippetsDisabled', [])
+ snippets = snippetsService.snippetsForScopes([
+ '.package-with-snippets-unique-scope'
+ ])
+ expect(Object.keys(snippets).length).toBe(1)
+
+ atom.config.set('core.packagesWithSnippetsDisabled', originalConfig)
+ })
+ })
+ })
+})
diff --git a/spec/snippets-spec.js b/spec/snippets-spec.js
index 6899447..07267ba 100644
--- a/spec/snippets-spec.js
+++ b/spec/snippets-spec.js
@@ -1,152 +1,166 @@
-const path = require('path');
-const temp = require('temp').track();
-const Snippets = require('../lib/snippets');
-const {TextEditor} = require('atom');
+const path = require('path')
+const temp = require('temp').track()
+const Snippets = require('../lib/snippets')
+const { TextEditor } = require('atom')
-describe("Snippets extension", () => {
- let editorElement, editor;
+describe('Snippets extension', () => {
+ let editorElement, editor
- const simulateTabKeyEvent = (param) => {
+ const simulateTabKeyEvent = param => {
if (param == null) {
- param = {};
+ param = {}
}
- const {shift} = param;
- const event = atom.keymaps.constructor.buildKeydownEvent('tab', {shift, target: editorElement});
- atom.keymaps.handleKeyboardEvent(event);
- };
+ const { shift } = param
+ const event = atom.keymaps.constructor.buildKeydownEvent('tab', {
+ shift,
+ target: editorElement
+ })
+ atom.keymaps.handleKeyboardEvent(event)
+ }
beforeEach(() => {
- spyOn(Snippets, 'loadAll');
- spyOn(Snippets, 'getUserSnippetsPath').andReturn('');
+ spyOn(Snippets, 'loadAll')
+ spyOn(Snippets, 'getUserSnippetsPath').andReturn('')
- waitsForPromise(() => atom.workspace.open('sample.js'));
- waitsForPromise(() => atom.packages.activatePackage('language-javascript'));
- waitsForPromise(() => atom.packages.activatePackage('snippets'));
+ waitsForPromise(() => atom.workspace.open('sample.js'))
+ waitsForPromise(() => atom.packages.activatePackage('language-javascript'))
+ waitsForPromise(() => atom.packages.activatePackage('snippets'))
runs(() => {
- editor = atom.workspace.getActiveTextEditor();
- editorElement = atom.views.getView(editor);
- });
- });
+ editor = atom.workspace.getActiveTextEditor()
+ editorElement = atom.views.getView(editor)
+ })
+ })
afterEach(() => {
- waitsForPromise(() => atom.packages.deactivatePackage('snippets'));
- });
+ waitsForPromise(() => atom.packages.deactivatePackage('snippets'))
+ })
- describe("provideSnippets interface", () => {
- let snippetsInterface = null;
+ describe('provideSnippets interface', () => {
+ let snippetsInterface = null
beforeEach(() => {
- snippetsInterface = Snippets.provideSnippets();
- });
+ snippetsInterface = Snippets.provideSnippets()
+ })
- describe("bundledSnippetsLoaded", () => {
- it("indicates the loaded state of the bundled snippets", () => {
- expect(snippetsInterface.bundledSnippetsLoaded()).toBe(false);
- Snippets.doneLoading();
- expect(snippetsInterface.bundledSnippetsLoaded()).toBe(true);
- });
+ describe('bundledSnippetsLoaded', () => {
+ it('indicates the loaded state of the bundled snippets', () => {
+ expect(snippetsInterface.bundledSnippetsLoaded()).toBe(false)
+ Snippets.doneLoading()
+ expect(snippetsInterface.bundledSnippetsLoaded()).toBe(true)
+ })
- it("resets the loaded state after snippets is deactivated", () => {
- expect(snippetsInterface.bundledSnippetsLoaded()).toBe(false);
- Snippets.doneLoading();
- expect(snippetsInterface.bundledSnippetsLoaded()).toBe(true);
+ it('resets the loaded state after snippets is deactivated', () => {
+ expect(snippetsInterface.bundledSnippetsLoaded()).toBe(false)
+ Snippets.doneLoading()
+ expect(snippetsInterface.bundledSnippetsLoaded()).toBe(true)
- waitsForPromise(() => atom.packages.deactivatePackage('snippets'));
- waitsForPromise(() => atom.packages.activatePackage('snippets'));
+ waitsForPromise(() => atom.packages.deactivatePackage('snippets'))
+ waitsForPromise(() => atom.packages.activatePackage('snippets'))
runs(() => {
- expect(snippetsInterface.bundledSnippetsLoaded()).toBe(false);
- Snippets.doneLoading();
- expect(snippetsInterface.bundledSnippetsLoaded()).toBe(true);
- });
- });
- });
-
- describe("insertSnippet", () => {
- it("can insert a snippet", () => {
- editor.setSelectedBufferRange([[0, 4], [0, 13]]);
- snippetsInterface.insertSnippet("hello ${1:world}", editor);
- expect(editor.lineTextForBufferRow(0)).toBe("var hello world = function () {");
- });
- });
- });
-
- it("returns false for snippetToExpandUnderCursor if getSnippets returns {}", () => {
- const snippets = atom.packages.getActivePackage('snippets').mainModule;
- expect(snippets.snippetToExpandUnderCursor(editor)).toEqual(false);
- });
-
- it("ignores invalid snippets in the config", () => {
- const snippets = atom.packages.getActivePackage('snippets').mainModule;
-
- let invalidSnippets = null;
- spyOn(snippets.scopedPropertyStore, 'getPropertyValue').andCallFake(() => invalidSnippets);
- expect(snippets.getSnippets(editor)).toEqual({});
-
- invalidSnippets = 'test';
- expect(snippets.getSnippets(editor)).toEqual({});
-
- invalidSnippets = [];
- expect(snippets.getSnippets(editor)).toEqual({});
-
- invalidSnippets = 3;
- expect(snippets.getSnippets(editor)).toEqual({});
-
- invalidSnippets = {a: null};
- expect(snippets.getSnippets(editor)).toEqual({});
- });
-
- describe("when null snippets are present", () => {
- beforeEach(() => Snippets.add(__filename, {
- ".source.js": {
- "some snippet": {
- prefix: "t1",
- body: "this is a test"
- }
- },
+ expect(snippetsInterface.bundledSnippetsLoaded()).toBe(false)
+ Snippets.doneLoading()
+ expect(snippetsInterface.bundledSnippetsLoaded()).toBe(true)
+ })
+ })
+ })
+
+ describe('insertSnippet', () => {
+ it('can insert a snippet', () => {
+ editor.setSelectedBufferRange([
+ [0, 4],
+ [0, 13]
+ ])
+ snippetsInterface.insertSnippet('hello ${1:world}', editor)
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'var hello world = function () {'
+ )
+ })
+ })
+ })
+
+ it('returns false for snippetToExpandUnderCursor if getSnippets returns {}', () => {
+ const snippets = atom.packages.getActivePackage('snippets').mainModule
+ expect(snippets.snippetToExpandUnderCursor(editor)).toEqual(false)
+ })
+
+ it('ignores invalid snippets in the config', () => {
+ const snippets = atom.packages.getActivePackage('snippets').mainModule
+
+ let invalidSnippets = null
+ spyOn(snippets.scopedPropertyStore, 'getPropertyValue').andCallFake(
+ () => invalidSnippets
+ )
+ expect(snippets.getSnippets(editor)).toEqual({})
+
+ invalidSnippets = 'test'
+ expect(snippets.getSnippets(editor)).toEqual({})
+
+ invalidSnippets = []
+ expect(snippets.getSnippets(editor)).toEqual({})
+
+ invalidSnippets = 3
+ expect(snippets.getSnippets(editor)).toEqual({})
+
+ invalidSnippets = { a: null }
+ expect(snippets.getSnippets(editor)).toEqual({})
+ })
+
+ describe('when null snippets are present', () => {
+ beforeEach(() =>
+ Snippets.add(__filename, {
+ '.source.js': {
+ 'some snippet': {
+ prefix: 't1',
+ body: 'this is a test'
+ }
+ },
- ".source.js .nope": {
- "some snippet": {
- prefix: "t1",
- body: null
+ '.source.js .nope': {
+ 'some snippet': {
+ prefix: 't1',
+ body: null
+ }
}
- }
- }));
-
- it("overrides the less-specific defined snippet", () => {
- const snippets = Snippets.provideSnippets();
- expect(snippets.snippetsForScopes(['.source.js'])['t1']).toBeTruthy();
- expect(snippets.snippetsForScopes(['.source.js .nope.not-today'])['t1']).toBeFalsy();
- });
- });
+ })
+ )
+
+ it('overrides the less-specific defined snippet', () => {
+ const snippets = Snippets.provideSnippets()
+ expect(snippets.snippetsForScopes(['.source.js']).t1).toBeTruthy()
+ expect(
+ snippets.snippetsForScopes(['.source.js .nope.not-today']).t1
+ ).toBeFalsy()
+ })
+ })
describe("when 'tab' is triggered on the editor", () => {
beforeEach(() => {
Snippets.add(__filename, {
- ".source.js": {
- "without tab stops": {
- prefix: "t1",
- body: "this is a test"
+ '.source.js': {
+ 'without tab stops': {
+ prefix: 't1',
+ body: 'this is a test'
},
- "with only an end tab stop": {
- prefix: "t1a",
- body: "something $0 strange"
+ 'with only an end tab stop': {
+ prefix: 't1a',
+ body: 'something $0 strange'
},
- "overlapping prefix": {
- prefix: "tt1",
- body: "this is another test"
+ 'overlapping prefix': {
+ prefix: 'tt1',
+ body: 'this is another test'
},
- "special chars": {
- prefix: "@unique",
- body: "@unique see"
+ 'special chars': {
+ prefix: '@unique',
+ body: '@unique see'
},
- "tab stops": {
- prefix: "t2",
+ 'tab stops': {
+ prefix: 't2',
body: `\
go here next:($2) and finally go here:($0)
go here first:($1)
@@ -154,8 +168,8 @@ go here first:($1)
`
},
- "indented second line": {
- prefix: "t3",
+ 'indented second line': {
+ prefix: 't3',
body: `\
line 1
\tline 2$1
@@ -163,16 +177,16 @@ $2\
`
},
- "multiline with indented placeholder tabstop": {
- prefix: "t4",
+ 'multiline with indented placeholder tabstop': {
+ prefix: 't4',
body: `\
line \${1:1}
\${2:body...}\
`
},
- "multiline starting with tabstop": {
- prefix: "t4b",
+ 'multiline starting with tabstop': {
+ prefix: 't4b',
body: `\
$1 = line 1 {
line 2
@@ -180,31 +194,31 @@ $1 = line 1 {
`
},
- "nested tab stops": {
- prefix: "t5",
+ 'nested tab stops': {
+ prefix: 't5',
body: '${1:"${2:key}"}: ${3:value}'
},
- "caused problems with undo": {
- prefix: "t6",
+ 'caused problems with undo': {
+ prefix: 't6',
body: `\
first line$1
\${2:placeholder ending second line}\
`
},
- "tab stops at beginning and then end of snippet": {
- prefix: "t6b",
- body: "$1expanded$0"
+ 'tab stops at beginning and then end of snippet': {
+ prefix: 't6b',
+ body: '$1expanded$0'
},
- "tab stops at end and then beginning of snippet": {
- prefix: "t6c",
- body: "$0expanded$1"
+ 'tab stops at end and then beginning of snippet': {
+ prefix: 't6c',
+ body: '$0expanded$1'
},
- "contains empty lines": {
- prefix: "t7",
+ 'contains empty lines': {
+ prefix: 't7',
body: `\
first line $1
@@ -212,24 +226,24 @@ first line $1
fourth line after blanks $2\
`
},
- "with/without placeholder": {
- prefix: "t8",
+ 'with/without placeholder': {
+ prefix: 't8',
body: `\
with placeholder \${1:test}
without placeholder \${2}\
`
},
- "multi-caret": {
- prefix: "t9",
+ 'multi-caret': {
+ prefix: 't9',
body: `\
with placeholder \${1:test}
without placeholder $1\
`
},
- "multi-caret-multi-tabstop": {
- prefix: "t9b",
+ 'multi-caret-multi-tabstop': {
+ prefix: 't9b',
body: `\
with placeholder \${1:test}
without placeholder $1
@@ -238,974 +252,1167 @@ third tabstop $3\
`
},
- "large indices": {
- prefix: "t10",
- body: "hello${10} ${11:large} indices${1}"
+ 'large indices': {
+ prefix: 't10',
+ body: 'hello${10} ${11:large} indices${1}'
},
- "no body": {
- prefix: "bad1"
+ 'no body': {
+ prefix: 'bad1'
},
- "number body": {
- prefix: "bad2",
+ 'number body': {
+ prefix: 'bad2',
body: 100
},
- "many tabstops": {
- prefix: "t11",
- body: "$0one${1} ${2:two} three${3}"
+ 'many tabstops': {
+ prefix: 't11',
+ body: '$0one${1} ${2:two} three${3}'
},
- "simple transform": {
- prefix: "t12",
- body: "[${1:b}][/${1/[ ]+.*$//}]"
+ 'simple transform': {
+ prefix: 't12',
+ body: '[${1:b}][/${1/[ ]+.*$//}]'
},
- "transform with non-transforming mirrors": {
- prefix: "t13",
- body: "${1:placeholder}\n${1/(.)/\\u$1/}\n$1"
+ 'transform with non-transforming mirrors': {
+ prefix: 't13',
+ body: '${1:placeholder}\n${1/(.)/\\u$1/}\n$1'
},
- "multiple tab stops, some with transforms and some without": {
- prefix: "t14",
- body: "${1:placeholder} ${1/(.)/\\u$1/} $1 ${2:ANOTHER} ${2/^(.*)$/\\L$1/} $2"
+ 'multiple tab stops, some with transforms and some without': {
+ prefix: 't14',
+ body:
+ '${1:placeholder} ${1/(.)/\\u$1/} $1 ${2:ANOTHER} ${2/^(.*)$/\\L$1/} $2'
},
- "has a transformed tab stop without a corresponding ordinary tab stop": {
+ 'has a transformed tab stop without a corresponding ordinary tab stop': {
prefix: 't15',
- body: "${1/(.)/\\u$1/} & $2"
+ body: '${1/(.)/\\u$1/} & $2'
},
- "has a transformed tab stop that occurs before the corresponding ordinary tab stop": {
+ 'has a transformed tab stop that occurs before the corresponding ordinary tab stop': {
prefix: 't16',
- body: "& ${1/(.)/\\u$1/} & ${1:q}"
+ body: '& ${1/(.)/\\u$1/} & ${1:q}'
},
"has a placeholder that mirrors another tab stop's content": {
prefix: 't17',
body: "$4console.${3:log}('${2:uh $1}', $1);$0"
},
- "has a transformed tab stop such that it is possible to move the cursor between the ordinary tab stop and its transformed version without an intermediate step": {
+ 'has a transformed tab stop such that it is possible to move the cursor between the ordinary tab stop and its transformed version without an intermediate step': {
prefix: 't18',
body: '// $1\n// ${1/./=/}'
}
}
- });
- });
+ })
+ })
- it("parses snippets once, reusing cached ones on subsequent queries", () => {
- spyOn(Snippets, "getBodyParser").andCallThrough();
+ it('parses snippets once, reusing cached ones on subsequent queries', () => {
+ spyOn(Snippets, 'getBodyParser').andCallThrough()
- editor.insertText("t1");
- simulateTabKeyEvent();
+ editor.insertText('t1')
+ simulateTabKeyEvent()
- expect(Snippets.getBodyParser).toHaveBeenCalled();
- expect(editor.lineTextForBufferRow(0)).toBe("this is a testvar quicksort = function () {");
- expect(editor.getCursorScreenPosition()).toEqual([0, 14]);
+ expect(Snippets.getBodyParser).toHaveBeenCalled()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'this is a testvar quicksort = function () {'
+ )
+ expect(editor.getCursorScreenPosition()).toEqual([0, 14])
- Snippets.getBodyParser.reset();
+ Snippets.getBodyParser.reset()
- editor.setText("");
- editor.insertText("t1");
- simulateTabKeyEvent();
+ editor.setText('')
+ editor.insertText('t1')
+ simulateTabKeyEvent()
- expect(Snippets.getBodyParser).not.toHaveBeenCalled();
- expect(editor.lineTextForBufferRow(0)).toBe("this is a test");
- expect(editor.getCursorScreenPosition()).toEqual([0, 14]);
+ expect(Snippets.getBodyParser).not.toHaveBeenCalled()
+ expect(editor.lineTextForBufferRow(0)).toBe('this is a test')
+ expect(editor.getCursorScreenPosition()).toEqual([0, 14])
- Snippets.getBodyParser.reset();
+ Snippets.getBodyParser.reset()
Snippets.add(__filename, {
- ".source.js": {
- "invalidate previous snippet": {
- prefix: "t1",
- body: "new snippet"
+ '.source.js': {
+ 'invalidate previous snippet': {
+ prefix: 't1',
+ body: 'new snippet'
}
}
- });
-
- editor.setText("");
- editor.insertText("t1");
- simulateTabKeyEvent();
-
- expect(Snippets.getBodyParser).toHaveBeenCalled();
- expect(editor.lineTextForBufferRow(0)).toBe("new snippet");
- expect(editor.getCursorScreenPosition()).toEqual([0, 11]);
- });
-
- describe("when the snippet body is invalid or missing", () => {
- it("does not register the snippet", () => {
- editor.setText('');
- editor.insertText('bad1');
- atom.commands.dispatch(editorElement, 'snippets:expand');
- expect(editor.getText()).toBe('bad1');
-
- editor.setText('');
- editor.setText('bad2');
- atom.commands.dispatch(editorElement, 'snippets:expand');
- expect(editor.getText()).toBe('bad2');
- });
- });
-
- describe("when the letters preceding the cursor trigger a snippet", () => {
- describe("when the snippet contains no tab stops", () => {
- it("replaces the prefix with the snippet text and places the cursor at its end", () => {
- editor.insertText("t1");
- expect(editor.getCursorScreenPosition()).toEqual([0, 2]);
-
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("this is a testvar quicksort = function () {");
- expect(editor.getCursorScreenPosition()).toEqual([0, 14]);
- });
-
- it("inserts a real tab the next time a tab is pressed after the snippet is expanded", () => {
- editor.insertText("t1");
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("this is a testvar quicksort = function () {");
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("this is a test var quicksort = function () {");
- });
- });
-
- describe("when the snippet contains tab stops", () => {
+ })
+
+ editor.setText('')
+ editor.insertText('t1')
+ simulateTabKeyEvent()
+
+ expect(Snippets.getBodyParser).toHaveBeenCalled()
+ expect(editor.lineTextForBufferRow(0)).toBe('new snippet')
+ expect(editor.getCursorScreenPosition()).toEqual([0, 11])
+ })
+
+ describe('when the snippet body is invalid or missing', () => {
+ it('does not register the snippet', () => {
+ editor.setText('')
+ editor.insertText('bad1')
+ atom.commands.dispatch(editorElement, 'snippets:expand')
+ expect(editor.getText()).toBe('bad1')
+
+ editor.setText('')
+ editor.setText('bad2')
+ atom.commands.dispatch(editorElement, 'snippets:expand')
+ expect(editor.getText()).toBe('bad2')
+ })
+ })
+
+ describe('when the letters preceding the cursor trigger a snippet', () => {
+ describe('when the snippet contains no tab stops', () => {
+ it('replaces the prefix with the snippet text and places the cursor at its end', () => {
+ editor.insertText('t1')
+ expect(editor.getCursorScreenPosition()).toEqual([0, 2])
+
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'this is a testvar quicksort = function () {'
+ )
+ expect(editor.getCursorScreenPosition()).toEqual([0, 14])
+ })
+
+ it('inserts a real tab the next time a tab is pressed after the snippet is expanded', () => {
+ editor.insertText('t1')
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'this is a testvar quicksort = function () {'
+ )
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'this is a test var quicksort = function () {'
+ )
+ })
+ })
+
+ describe('when the snippet contains tab stops', () => {
it("places the cursor at the first tab-stop, and moves the cursor in response to 'next-tab-stop' events", () => {
- const markerCountBefore = editor.getMarkerCount();
- editor.setCursorScreenPosition([2, 0]);
- editor.insertText('t2');
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(2)).toBe("go here next:() and finally go here:()");
- expect(editor.lineTextForBufferRow(3)).toBe("go here first:()");
- expect(editor.lineTextForBufferRow(4)).toBe(" if (items.length <= 1) return items;");
- expect(editor.getSelectedBufferRange()).toEqual([[3, 15], [3, 15]]);
-
- simulateTabKeyEvent();
- expect(editor.getSelectedBufferRange()).toEqual([[2, 14], [2, 14]]);
- editor.insertText('abc');
-
- simulateTabKeyEvent();
- expect(editor.getSelectedBufferRange()).toEqual([[2, 40], [2, 40]]);
+ const markerCountBefore = editor.getMarkerCount()
+ editor.setCursorScreenPosition([2, 0])
+ editor.insertText('t2')
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(2)).toBe(
+ 'go here next:() and finally go here:()'
+ )
+ expect(editor.lineTextForBufferRow(3)).toBe('go here first:()')
+ expect(editor.lineTextForBufferRow(4)).toBe(
+ ' if (items.length <= 1) return items;'
+ )
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [3, 15],
+ [3, 15]
+ ])
+
+ simulateTabKeyEvent()
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [2, 14],
+ [2, 14]
+ ])
+ editor.insertText('abc')
+
+ simulateTabKeyEvent()
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [2, 40],
+ [2, 40]
+ ])
// tab backwards
- simulateTabKeyEvent({shift: true});
- expect(editor.getSelectedBufferRange()).toEqual([[2, 14], [2, 17]]); // should highlight text typed at tab stop
-
- simulateTabKeyEvent({shift: true});
- expect(editor.getSelectedBufferRange()).toEqual([[3, 15], [3, 15]]);
+ simulateTabKeyEvent({ shift: true })
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [2, 14],
+ [2, 17]
+ ]) // should highlight text typed at tab stop
+
+ simulateTabKeyEvent({ shift: true })
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [3, 15],
+ [3, 15]
+ ])
// shift-tab on first tab-stop does nothing
- simulateTabKeyEvent({shift: true});
- expect(editor.getCursorScreenPosition()).toEqual([3, 15]);
+ simulateTabKeyEvent({ shift: true })
+ expect(editor.getCursorScreenPosition()).toEqual([3, 15])
// tab through all tab stops, then tab on last stop to terminate snippet
- simulateTabKeyEvent();
- simulateTabKeyEvent();
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(2)).toBe("go here next:(abc) and finally go here:( )");
- expect(editor.getMarkerCount()).toBe(markerCountBefore);
- });
-
- describe("when tab stops are nested", () => {
- it("destroys the inner tab stop if the outer tab stop is modified", () => {
- editor.setText('');
- editor.insertText('t5');
- atom.commands.dispatch(editorElement, 'snippets:expand');
- expect(editor.lineTextForBufferRow(0)).toBe('"key": value');
- expect(editor.getSelectedBufferRange()).toEqual([[0, 0], [0, 5]]);
- editor.insertText("foo");
- simulateTabKeyEvent();
- expect(editor.getSelectedBufferRange()).toEqual([[0, 5], [0, 10]]);
- });
- });
-
- describe("when the only tab stop is an end stop", () => {
- it("terminates the snippet immediately after moving the cursor to the end stop", () => {
- editor.setText('');
- editor.insertText('t1a');
- simulateTabKeyEvent();
-
- expect(editor.lineTextForBufferRow(0)).toBe("something strange");
- expect(editor.getCursorBufferPosition()).toEqual([0, 10]);
-
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("something strange");
- expect(editor.getCursorBufferPosition()).toEqual([0, 12]);
- });
- });
-
- describe("when tab stops are separated by blank lines", () => {
- it("correctly places the tab stops (regression)", () => {
- editor.setText('');
- editor.insertText('t7');
- atom.commands.dispatch(editorElement, 'snippets:expand');
- atom.commands.dispatch(editorElement, 'snippets:next-tab-stop');
- expect(editor.getCursorBufferPosition()).toEqual([3, 25]);
- });
- });
-
- describe("when the cursor is moved beyond the bounds of the current tab stop", () => {
- it("terminates the snippet", () => {
- editor.setCursorScreenPosition([2, 0]);
- editor.insertText('t2');
- simulateTabKeyEvent();
-
- editor.moveUp();
- editor.moveLeft();
- simulateTabKeyEvent();
-
- expect(editor.lineTextForBufferRow(2)).toBe("go here next:( ) and finally go here:()");
- expect(editor.getCursorBufferPosition()).toEqual([2, 16]);
+ simulateTabKeyEvent()
+ simulateTabKeyEvent()
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(2)).toBe(
+ 'go here next:(abc) and finally go here:( )'
+ )
+ expect(editor.getMarkerCount()).toBe(markerCountBefore)
+ })
+
+ describe('when tab stops are nested', () => {
+ it('destroys the inner tab stop if the outer tab stop is modified', () => {
+ editor.setText('')
+ editor.insertText('t5')
+ atom.commands.dispatch(editorElement, 'snippets:expand')
+ expect(editor.lineTextForBufferRow(0)).toBe('"key": value')
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [0, 0],
+ [0, 5]
+ ])
+ editor.insertText('foo')
+ simulateTabKeyEvent()
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [0, 5],
+ [0, 10]
+ ])
+ })
+ })
+
+ describe('when the only tab stop is an end stop', () => {
+ it('terminates the snippet immediately after moving the cursor to the end stop', () => {
+ editor.setText('')
+ editor.insertText('t1a')
+ simulateTabKeyEvent()
+
+ expect(editor.lineTextForBufferRow(0)).toBe('something strange')
+ expect(editor.getCursorBufferPosition()).toEqual([0, 10])
+
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe('something strange')
+ expect(editor.getCursorBufferPosition()).toEqual([0, 12])
+ })
+ })
+
+ describe('when tab stops are separated by blank lines', () => {
+ it('correctly places the tab stops (regression)', () => {
+ editor.setText('')
+ editor.insertText('t7')
+ atom.commands.dispatch(editorElement, 'snippets:expand')
+ atom.commands.dispatch(editorElement, 'snippets:next-tab-stop')
+ expect(editor.getCursorBufferPosition()).toEqual([3, 25])
+ })
+ })
+
+ describe('when the cursor is moved beyond the bounds of the current tab stop', () => {
+ it('terminates the snippet', () => {
+ editor.setCursorScreenPosition([2, 0])
+ editor.insertText('t2')
+ simulateTabKeyEvent()
+
+ editor.moveUp()
+ editor.moveLeft()
+ simulateTabKeyEvent()
+
+ expect(editor.lineTextForBufferRow(2)).toBe(
+ 'go here next:( ) and finally go here:()'
+ )
+ expect(editor.getCursorBufferPosition()).toEqual([2, 16])
// test we can terminate with shift-tab
- editor.setCursorScreenPosition([4, 0]);
- editor.insertText('t2');
- simulateTabKeyEvent();
- simulateTabKeyEvent();
-
- editor.moveRight();
- simulateTabKeyEvent({shift: true});
- expect(editor.getCursorBufferPosition()).toEqual([4, 15]);
- });
- });
-
- describe("when the cursor is moved within the bounds of the current tab stop", () => {
- it("should not terminate the snippet", () => {
- editor.setCursorScreenPosition([0, 0]);
- editor.insertText('t8');
- simulateTabKeyEvent();
-
- expect(editor.lineTextForBufferRow(0)).toBe("with placeholder test");
- editor.moveRight();
- editor.moveLeft();
- editor.insertText("foo");
- expect(editor.lineTextForBufferRow(0)).toBe("with placeholder tesfoot");
-
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(1)).toBe("without placeholder var quicksort = function () {");
- editor.insertText("test");
- expect(editor.lineTextForBufferRow(1)).toBe("without placeholder testvar quicksort = function () {");
- editor.moveLeft();
- editor.insertText("foo");
- expect(editor.lineTextForBufferRow(1)).toBe("without placeholder tesfootvar quicksort = function () {");
- });
- });
-
- describe("when the backspace is press within the bounds of the current tab stop", () => {
- it("should not terminate the snippet", () => {
- editor.setCursorScreenPosition([0, 0]);
- editor.insertText('t8');
- simulateTabKeyEvent();
-
- expect(editor.lineTextForBufferRow(0)).toBe("with placeholder test");
- editor.moveRight();
- editor.backspace();
- editor.insertText("foo");
- expect(editor.lineTextForBufferRow(0)).toBe("with placeholder tesfoo");
-
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(1)).toBe("without placeholder var quicksort = function () {");
- editor.insertText("test");
- expect(editor.lineTextForBufferRow(1)).toBe("without placeholder testvar quicksort = function () {");
- editor.backspace();
- editor.insertText("foo");
- expect(editor.lineTextForBufferRow(1)).toBe("without placeholder tesfoovar quicksort = function () {");
- });
- });
- });
-
- describe("when the snippet contains hard tabs", () => {
- describe("when the edit session is in soft-tabs mode", () => {
- it("translates hard tabs in the snippet to the appropriate number of spaces", () => {
- expect(editor.getSoftTabs()).toBeTruthy();
- editor.insertText("t3");
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(1)).toBe(" line 2");
- expect(editor.getCursorBufferPosition()).toEqual([1, 8]);
- });
- });
-
- describe("when the edit session is in hard-tabs mode", () => {
- it("inserts hard tabs in the snippet directly", () => {
- editor.setSoftTabs(false);
- editor.insertText("t3");
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(1)).toBe("\tline 2");
- expect(editor.getCursorBufferPosition()).toEqual([1, 7]);
- });
- });
- });
-
- describe("when the snippet prefix is indented", () => {
- describe("when the snippet spans a single line", () => {
- it("does not indent the next line", () => {
- editor.setCursorScreenPosition([2, Infinity]);
- editor.insertText(' t1');
- atom.commands.dispatch(editorElement, 'snippets:expand');
- expect(editor.lineTextForBufferRow(3)).toBe(" var pivot = items.shift(), current, left = [], right = [];");
- });
- });
-
- describe("when the snippet spans multiple lines", () => {
- it("indents the subsequent lines of the snippet to be even with the start of the first line", () => {
- expect(editor.getSoftTabs()).toBeTruthy();
- editor.setCursorScreenPosition([2, Infinity]);
- editor.insertText(' t3');
- atom.commands.dispatch(editorElement, 'snippets:expand');
- expect(editor.lineTextForBufferRow(2)).toBe(" if (items.length <= 1) return items; line 1");
- expect(editor.lineTextForBufferRow(3)).toBe(" line 2");
- expect(editor.getCursorBufferPosition()).toEqual([3, 12]);
- });
- });
- });
-
- describe("when the snippet spans multiple lines", () => {
+ editor.setCursorScreenPosition([4, 0])
+ editor.insertText('t2')
+ simulateTabKeyEvent()
+ simulateTabKeyEvent()
+
+ editor.moveRight()
+ simulateTabKeyEvent({ shift: true })
+ expect(editor.getCursorBufferPosition()).toEqual([4, 15])
+ })
+ })
+
+ describe('when the cursor is moved within the bounds of the current tab stop', () => {
+ it('should not terminate the snippet', () => {
+ editor.setCursorScreenPosition([0, 0])
+ editor.insertText('t8')
+ simulateTabKeyEvent()
+
+ expect(editor.lineTextForBufferRow(0)).toBe('with placeholder test')
+ editor.moveRight()
+ editor.moveLeft()
+ editor.insertText('foo')
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'with placeholder tesfoot'
+ )
+
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'without placeholder var quicksort = function () {'
+ )
+ editor.insertText('test')
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'without placeholder testvar quicksort = function () {'
+ )
+ editor.moveLeft()
+ editor.insertText('foo')
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'without placeholder tesfootvar quicksort = function () {'
+ )
+ })
+ })
+
+ describe('when the backspace is press within the bounds of the current tab stop', () => {
+ it('should not terminate the snippet', () => {
+ editor.setCursorScreenPosition([0, 0])
+ editor.insertText('t8')
+ simulateTabKeyEvent()
+
+ expect(editor.lineTextForBufferRow(0)).toBe('with placeholder test')
+ editor.moveRight()
+ editor.backspace()
+ editor.insertText('foo')
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'with placeholder tesfoo'
+ )
+
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'without placeholder var quicksort = function () {'
+ )
+ editor.insertText('test')
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'without placeholder testvar quicksort = function () {'
+ )
+ editor.backspace()
+ editor.insertText('foo')
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'without placeholder tesfoovar quicksort = function () {'
+ )
+ })
+ })
+ })
+
+ describe('when the snippet contains hard tabs', () => {
+ describe('when the edit session is in soft-tabs mode', () => {
+ it('translates hard tabs in the snippet to the appropriate number of spaces', () => {
+ expect(editor.getSoftTabs()).toBeTruthy()
+ editor.insertText('t3')
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(1)).toBe(' line 2')
+ expect(editor.getCursorBufferPosition()).toEqual([1, 8])
+ })
+ })
+
+ describe('when the edit session is in hard-tabs mode', () => {
+ it('inserts hard tabs in the snippet directly', () => {
+ editor.setSoftTabs(false)
+ editor.insertText('t3')
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(1)).toBe('\tline 2')
+ expect(editor.getCursorBufferPosition()).toEqual([1, 7])
+ })
+ })
+ })
+
+ describe('when the snippet prefix is indented', () => {
+ describe('when the snippet spans a single line', () => {
+ it('does not indent the next line', () => {
+ editor.setCursorScreenPosition([2, Infinity])
+ editor.insertText(' t1')
+ atom.commands.dispatch(editorElement, 'snippets:expand')
+ expect(editor.lineTextForBufferRow(3)).toBe(
+ ' var pivot = items.shift(), current, left = [], right = [];'
+ )
+ })
+ })
+
+ describe('when the snippet spans multiple lines', () => {
+ it('indents the subsequent lines of the snippet to be even with the start of the first line', () => {
+ expect(editor.getSoftTabs()).toBeTruthy()
+ editor.setCursorScreenPosition([2, Infinity])
+ editor.insertText(' t3')
+ atom.commands.dispatch(editorElement, 'snippets:expand')
+ expect(editor.lineTextForBufferRow(2)).toBe(
+ ' if (items.length <= 1) return items; line 1'
+ )
+ expect(editor.lineTextForBufferRow(3)).toBe(' line 2')
+ expect(editor.getCursorBufferPosition()).toEqual([3, 12])
+ })
+ })
+ })
+
+ describe('when the snippet spans multiple lines', () => {
beforeEach(() => {
- editor.update({autoIndent: true});
+ editor.update({ autoIndent: true })
// editor.update() returns a Promise that never gets resolved, so we
// need to return undefined to avoid a timeout in the spec.
// TODO: Figure out why `editor.update({autoIndent: true})` never gets resolved.
- });
-
- it("places tab stops correctly", () => {
- expect(editor.getSoftTabs()).toBeTruthy();
- editor.setCursorScreenPosition([2, Infinity]);
- editor.insertText(' t3');
- atom.commands.dispatch(editorElement, 'snippets:expand');
- expect(editor.getCursorBufferPosition()).toEqual([3, 12]);
- atom.commands.dispatch(editorElement, 'snippets:next-tab-stop');
- expect(editor.getCursorBufferPosition()).toEqual([4, 4]);
- });
-
- it("indents the subsequent lines of the snippet based on the indent level before the snippet is inserted", () => {
- editor.setCursorScreenPosition([2, Infinity]);
- editor.insertNewline();
- editor.insertText('t4b');
- atom.commands.dispatch(editorElement, 'snippets:expand');
-
- expect(editor.lineTextForBufferRow(3)).toBe(" = line 1 {"); // 4 + 1 spaces (because the tab stop is invisible)
- expect(editor.lineTextForBufferRow(4)).toBe(" line 2");
- expect(editor.lineTextForBufferRow(5)).toBe(" }");
- expect(editor.getCursorBufferPosition()).toEqual([3, 4]);
- });
-
- it("does not change the relative positioning of the tab stops when inserted multiple times", () => {
- editor.setCursorScreenPosition([2, Infinity]);
- editor.insertNewline();
- editor.insertText('t4');
- atom.commands.dispatch(editorElement, 'snippets:expand');
-
- expect(editor.getSelectedBufferRange()).toEqual([[3, 9], [3, 10]]);
- atom.commands.dispatch(editorElement, 'snippets:next-tab-stop');
- expect(editor.getSelectedBufferRange()).toEqual([[4, 6], [4, 13]]);
-
- editor.insertText('t4');
- atom.commands.dispatch(editorElement, 'snippets:expand');
-
- expect(editor.getSelectedBufferRange()).toEqual([[4, 11], [4, 12]]);
- atom.commands.dispatch(editorElement, 'snippets:next-tab-stop');
- expect(editor.getSelectedBufferRange()).toEqual([[5, 8], [5, 15]]);
-
- editor.setText(''); // Clear editor
- editor.insertText('t4');
- atom.commands.dispatch(editorElement, 'snippets:expand');
-
- expect(editor.getSelectedBufferRange()).toEqual([[0, 5], [0, 6]]);
- atom.commands.dispatch(editorElement, 'snippets:next-tab-stop');
- expect(editor.getSelectedBufferRange()).toEqual([[1, 2], [1, 9]]);
- });
- });
-
- describe("when multiple snippets match the prefix", () => {
- it("expands the snippet that is the longest match for the prefix", () => {
- editor.insertText('t113');
- expect(editor.getCursorScreenPosition()).toEqual([0, 4]);
-
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("t113 var quicksort = function () {");
- expect(editor.getCursorScreenPosition()).toEqual([0, 6]);
-
- editor.undo();
- editor.undo();
-
- editor.insertText("tt1");
- expect(editor.getCursorScreenPosition()).toEqual([0, 3]);
-
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("this is another testvar quicksort = function () {");
- expect(editor.getCursorScreenPosition()).toEqual([0, 20]);
-
- editor.undo();
- editor.undo();
-
- editor.insertText("@t1");
- expect(editor.getCursorScreenPosition()).toEqual([0, 3]);
-
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("@this is a testvar quicksort = function () {");
- expect(editor.getCursorScreenPosition()).toEqual([0, 15]);
- });
- });
- });
-
- describe("when the word preceding the cursor ends with a snippet prefix", () => {
- it("inserts a tab as normal", () => {
- editor.insertText("t1t1t1");
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("t1t1t1 var quicksort = function () {");
- });
- });
+ })
+
+ it('places tab stops correctly', () => {
+ expect(editor.getSoftTabs()).toBeTruthy()
+ editor.setCursorScreenPosition([2, Infinity])
+ editor.insertText(' t3')
+ atom.commands.dispatch(editorElement, 'snippets:expand')
+ expect(editor.getCursorBufferPosition()).toEqual([3, 12])
+ atom.commands.dispatch(editorElement, 'snippets:next-tab-stop')
+ expect(editor.getCursorBufferPosition()).toEqual([4, 4])
+ })
+
+ it('indents the subsequent lines of the snippet based on the indent level before the snippet is inserted', () => {
+ editor.setCursorScreenPosition([2, Infinity])
+ editor.insertNewline()
+ editor.insertText('t4b')
+ atom.commands.dispatch(editorElement, 'snippets:expand')
+
+ expect(editor.lineTextForBufferRow(3)).toBe(' = line 1 {') // 4 + 1 spaces (because the tab stop is invisible)
+ expect(editor.lineTextForBufferRow(4)).toBe(' line 2')
+ expect(editor.lineTextForBufferRow(5)).toBe(' }')
+ expect(editor.getCursorBufferPosition()).toEqual([3, 4])
+ })
+
+ it('does not change the relative positioning of the tab stops when inserted multiple times', () => {
+ editor.setCursorScreenPosition([2, Infinity])
+ editor.insertNewline()
+ editor.insertText('t4')
+ atom.commands.dispatch(editorElement, 'snippets:expand')
+
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [3, 9],
+ [3, 10]
+ ])
+ atom.commands.dispatch(editorElement, 'snippets:next-tab-stop')
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [4, 6],
+ [4, 13]
+ ])
+
+ editor.insertText('t4')
+ atom.commands.dispatch(editorElement, 'snippets:expand')
+
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [4, 11],
+ [4, 12]
+ ])
+ atom.commands.dispatch(editorElement, 'snippets:next-tab-stop')
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [5, 8],
+ [5, 15]
+ ])
+
+ editor.setText('') // Clear editor
+ editor.insertText('t4')
+ atom.commands.dispatch(editorElement, 'snippets:expand')
+
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [0, 5],
+ [0, 6]
+ ])
+ atom.commands.dispatch(editorElement, 'snippets:next-tab-stop')
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [1, 2],
+ [1, 9]
+ ])
+ })
+ })
+
+ describe('when multiple snippets match the prefix', () => {
+ it('expands the snippet that is the longest match for the prefix', () => {
+ editor.insertText('t113')
+ expect(editor.getCursorScreenPosition()).toEqual([0, 4])
+
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 't113 var quicksort = function () {'
+ )
+ expect(editor.getCursorScreenPosition()).toEqual([0, 6])
+
+ editor.undo()
+ editor.undo()
+
+ editor.insertText('tt1')
+ expect(editor.getCursorScreenPosition()).toEqual([0, 3])
+
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'this is another testvar quicksort = function () {'
+ )
+ expect(editor.getCursorScreenPosition()).toEqual([0, 20])
+
+ editor.undo()
+ editor.undo()
+
+ editor.insertText('@t1')
+ expect(editor.getCursorScreenPosition()).toEqual([0, 3])
+
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ '@this is a testvar quicksort = function () {'
+ )
+ expect(editor.getCursorScreenPosition()).toEqual([0, 15])
+ })
+ })
+ })
+
+ describe('when the word preceding the cursor ends with a snippet prefix', () => {
+ it('inserts a tab as normal', () => {
+ editor.insertText('t1t1t1')
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 't1t1t1 var quicksort = function () {'
+ )
+ })
+ })
describe("when the letters preceding the cursor don't match a snippet", () => {
- it("inserts a tab as normal", () => {
- editor.insertText("xxte");
- expect(editor.getCursorScreenPosition()).toEqual([0, 4]);
-
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("xxte var quicksort = function () {");
- expect(editor.getCursorScreenPosition()).toEqual([0, 6]);
- });
- });
-
- describe("when text is selected", () => {
- it("inserts a tab as normal", () => {
- editor.insertText("t1");
- editor.setSelectedBufferRange([[0, 0], [0, 2]]);
-
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe(" t1var quicksort = function () {");
- expect(editor.getSelectedBufferRange()).toEqual([[0, 0], [0, 4]]);
- });
- });
-
- describe("when a previous snippet expansion has just been undone", () => {
- describe("when the tab stops appear in the middle of the snippet", () => {
+ it('inserts a tab as normal', () => {
+ editor.insertText('xxte')
+ expect(editor.getCursorScreenPosition()).toEqual([0, 4])
+
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'xxte var quicksort = function () {'
+ )
+ expect(editor.getCursorScreenPosition()).toEqual([0, 6])
+ })
+ })
+
+ describe('when text is selected', () => {
+ it('inserts a tab as normal', () => {
+ editor.insertText('t1')
+ editor.setSelectedBufferRange([
+ [0, 0],
+ [0, 2]
+ ])
+
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ ' t1var quicksort = function () {'
+ )
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [0, 0],
+ [0, 4]
+ ])
+ })
+ })
+
+ describe('when a previous snippet expansion has just been undone', () => {
+ describe('when the tab stops appear in the middle of the snippet', () => {
it("expands the snippet based on the current prefix rather than jumping to the old snippet's tab stop", () => {
- editor.insertText('t6\n');
- editor.setCursorBufferPosition([0, 2]);
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("first line");
- editor.undo();
- expect(editor.lineTextForBufferRow(0)).toBe("t6");
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("first line");
- });
- });
-
- describe("when the tab stops appear at the beginning and then the end of snippet", () => {
+ editor.insertText('t6\n')
+ editor.setCursorBufferPosition([0, 2])
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe('first line')
+ editor.undo()
+ expect(editor.lineTextForBufferRow(0)).toBe('t6')
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe('first line')
+ })
+ })
+
+ describe('when the tab stops appear at the beginning and then the end of snippet', () => {
it("expands the snippet based on the current prefix rather than jumping to the old snippet's tab stop", () => {
- editor.insertText('t6b\n');
- editor.setCursorBufferPosition([0, 3]);
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("expanded");
- editor.undo();
- expect(editor.lineTextForBufferRow(0)).toBe("t6b");
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("expanded");
- expect(editor.getCursorBufferPosition()).toEqual([0, 0]);
- });
- });
-
- describe("when the tab stops appear at the end and then the beginning of snippet", () => {
+ editor.insertText('t6b\n')
+ editor.setCursorBufferPosition([0, 3])
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe('expanded')
+ editor.undo()
+ expect(editor.lineTextForBufferRow(0)).toBe('t6b')
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe('expanded')
+ expect(editor.getCursorBufferPosition()).toEqual([0, 0])
+ })
+ })
+
+ describe('when the tab stops appear at the end and then the beginning of snippet', () => {
it("expands the snippet based on the current prefix rather than jumping to the old snippet's tab stop", () => {
- editor.insertText('t6c\n');
- editor.setCursorBufferPosition([0, 3]);
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("expanded");
- editor.undo();
- expect(editor.lineTextForBufferRow(0)).toBe("t6c");
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("expanded");
- expect(editor.getCursorBufferPosition()).toEqual([0, 8]);
- });
- });
- });
-
- describe("when the prefix contains non-word characters", () => {
- it("selects the non-word characters as part of the prefix", () => {
- editor.insertText("@unique");
- expect(editor.getCursorScreenPosition()).toEqual([0, 7]);
-
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("@unique seevar quicksort = function () {");
- expect(editor.getCursorScreenPosition()).toEqual([0, 11]);
-
- editor.setCursorBufferPosition([10, 0]);
- editor.insertText("'@unique");
-
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(10)).toBe("'@unique see");
- expect(editor.getCursorScreenPosition()).toEqual([10, 12]);
- });
-
- it("does not select the whitespace before the prefix", () => {
- editor.insertText("a; @unique");
- expect(editor.getCursorScreenPosition()).toEqual([0, 10]);
-
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("a; @unique seevar quicksort = function () {");
- expect(editor.getCursorScreenPosition()).toEqual([0, 14]);
- });
- });
-
- describe("when snippet contains tabstops with or without placeholder", () => {
- it("should create two markers", () => {
- editor.setCursorScreenPosition([0, 0]);
- editor.insertText('t8');
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("with placeholder test");
- expect(editor.lineTextForBufferRow(1)).toBe("without placeholder var quicksort = function () {");
-
- expect(editor.getSelectedBufferRange()).toEqual([[0, 17], [0, 21]]);
-
- simulateTabKeyEvent();
- expect(editor.getSelectedBufferRange()).toEqual([[1, 20], [1, 20]]);
- });
- });
-
- describe("when snippet contains multi-caret tabstops with or without placeholder", () => {
- it("should create two markers", () => {
- editor.setCursorScreenPosition([0, 0]);
- editor.insertText('t9');
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("with placeholder test");
- expect(editor.lineTextForBufferRow(1)).toBe("without placeholder var quicksort = function () {");
- editor.insertText('hello');
- expect(editor.lineTextForBufferRow(0)).toBe("with placeholder hello");
- expect(editor.lineTextForBufferRow(1)).toBe("without placeholder hellovar quicksort = function () {");
- });
-
- it("terminates the snippet when cursors are destroyed", () => {
- editor.setCursorScreenPosition([0, 0]);
- editor.insertText('t9b');
- simulateTabKeyEvent();
- editor.getCursors()[0].destroy();
- editor.getCursorBufferPosition();
- simulateTabKeyEvent();
-
- expect(editor.lineTextForBufferRow(1)).toEqual("without placeholder ");
- });
-
- it("terminates the snippet expansion if a new cursor moves outside the bounds of the tab stops", () => {
- editor.setCursorScreenPosition([0, 0]);
- editor.insertText('t9b');
- simulateTabKeyEvent();
- editor.insertText('test');
-
- editor.getCursors()[0].destroy();
- editor.moveDown(); // this should destroy the previous expansion
- editor.moveToBeginningOfLine();
+ editor.insertText('t6c\n')
+ editor.setCursorBufferPosition([0, 3])
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe('expanded')
+ editor.undo()
+ expect(editor.lineTextForBufferRow(0)).toBe('t6c')
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe('expanded')
+ expect(editor.getCursorBufferPosition()).toEqual([0, 8])
+ })
+ })
+ })
+
+ describe('when the prefix contains non-word characters', () => {
+ it('selects the non-word characters as part of the prefix', () => {
+ editor.insertText('@unique')
+ expect(editor.getCursorScreenPosition()).toEqual([0, 7])
+
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ '@unique seevar quicksort = function () {'
+ )
+ expect(editor.getCursorScreenPosition()).toEqual([0, 11])
+
+ editor.setCursorBufferPosition([10, 0])
+ editor.insertText("'@unique")
+
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(10)).toBe("'@unique see")
+ expect(editor.getCursorScreenPosition()).toEqual([10, 12])
+ })
+
+ it('does not select the whitespace before the prefix', () => {
+ editor.insertText('a; @unique')
+ expect(editor.getCursorScreenPosition()).toEqual([0, 10])
+
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'a; @unique seevar quicksort = function () {'
+ )
+ expect(editor.getCursorScreenPosition()).toEqual([0, 14])
+ })
+ })
+
+ describe('when snippet contains tabstops with or without placeholder', () => {
+ it('should create two markers', () => {
+ editor.setCursorScreenPosition([0, 0])
+ editor.insertText('t8')
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe('with placeholder test')
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'without placeholder var quicksort = function () {'
+ )
+
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [0, 17],
+ [0, 21]
+ ])
+
+ simulateTabKeyEvent()
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [1, 20],
+ [1, 20]
+ ])
+ })
+ })
+
+ describe('when snippet contains multi-caret tabstops with or without placeholder', () => {
+ it('should create two markers', () => {
+ editor.setCursorScreenPosition([0, 0])
+ editor.insertText('t9')
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe('with placeholder test')
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'without placeholder var quicksort = function () {'
+ )
+ editor.insertText('hello')
+ expect(editor.lineTextForBufferRow(0)).toBe('with placeholder hello')
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'without placeholder hellovar quicksort = function () {'
+ )
+ })
+
+ it('terminates the snippet when cursors are destroyed', () => {
+ editor.setCursorScreenPosition([0, 0])
+ editor.insertText('t9b')
+ simulateTabKeyEvent()
+ editor.getCursors()[0].destroy()
+ editor.getCursorBufferPosition()
+ simulateTabKeyEvent()
+
+ expect(editor.lineTextForBufferRow(1)).toEqual('without placeholder ')
+ })
+
+ it('terminates the snippet expansion if a new cursor moves outside the bounds of the tab stops', () => {
+ editor.setCursorScreenPosition([0, 0])
+ editor.insertText('t9b')
+ simulateTabKeyEvent()
+ editor.insertText('test')
+
+ editor.getCursors()[0].destroy()
+ editor.moveDown() // this should destroy the previous expansion
+ editor.moveToBeginningOfLine()
// this should insert whitespace instead of going through tabstops of the previous destroyed snippet
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(2).indexOf(" second")).toBe(0);
- });
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(2).indexOf(' second')).toBe(0)
+ })
- it("moves to the second tabstop after a multi-caret tabstop", () => {
- editor.setCursorScreenPosition([0, 0]);
- editor.insertText('t9b');
- simulateTabKeyEvent();
- editor.insertText('line 1');
+ it('moves to the second tabstop after a multi-caret tabstop', () => {
+ editor.setCursorScreenPosition([0, 0])
+ editor.insertText('t9b')
+ simulateTabKeyEvent()
+ editor.insertText('line 1')
- simulateTabKeyEvent();
- editor.insertText('line 2');
+ simulateTabKeyEvent()
+ editor.insertText('line 2')
- simulateTabKeyEvent();
- editor.insertText('line 3');
+ simulateTabKeyEvent()
+ editor.insertText('line 3')
- expect(editor.lineTextForBufferRow(2).indexOf("line 2 ")).toBe(-1);
- });
+ expect(editor.lineTextForBufferRow(2).indexOf('line 2 ')).toBe(-1)
+ })
it("mirrors input properly when a tabstop's placeholder refers to another tabstop", () => {
- editor.setText('t17');
- editor.setCursorScreenPosition([0, 3]);
- simulateTabKeyEvent();
- editor.insertText("foo");
- expect(editor.getText()).toBe("console.log('uh foo', foo);");
- simulateTabKeyEvent();
- editor.insertText("bar");
- expect(editor.getText()).toBe("console.log('bar', foo);");
- });
- });
-
- describe("when the snippet contains tab stops with transformations", () => {
- it("transforms the text typed into the first tab stop before setting it in the transformed tab stop", () => {
- editor.setText('t12');
- editor.setCursorScreenPosition([0, 3]);
- simulateTabKeyEvent();
- expect(editor.getText()).toBe("[b][/b]");
- editor.insertText('img src');
- expect(editor.getText()).toBe("[img src][/img]");
- });
-
- it("bundles the transform mutations along with the original manual mutation for the purposes of undo and redo", () => {
- editor.setText('t12');
- editor.setCursorScreenPosition([0, 3]);
- simulateTabKeyEvent();
- editor.insertText('i');
- expect(editor.getText()).toBe("[i][/i]");
-
- editor.insertText('mg src');
- expect(editor.getText()).toBe("[img src][/img]");
-
- editor.undo();
- expect(editor.getText()).toBe("[i][/i]");
-
- editor.redo();
- expect(editor.getText()).toBe("[img src][/img]");
- });
-
- it("can pick the right insertion to use as the primary even if a transformed insertion occurs first in the snippet", () => {
- editor.setText('t16');
- editor.setCursorScreenPosition([0, 3]);
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("& Q & q");
- expect(editor.getCursorBufferPosition()).toEqual([0, 7]);
-
- editor.insertText('rst');
- expect(editor.lineTextForBufferRow(0)).toBe("& RST & rst");
- });
-
- it("silently ignores a tab stop without a non-transformed insertion to use as the primary", () => {
- editor.setText('t15');
- editor.setCursorScreenPosition([0, 3]);
- simulateTabKeyEvent();
- editor.insertText('a');
- expect(editor.lineTextForBufferRow(0)).toBe(" & a");
- expect(editor.getCursorBufferPosition()).toEqual([0, 4]);
- });
- });
-
- describe("when the snippet contains mirrored tab stops and tab stops with transformations", () => {
- it("adds cursors for the mirrors but not the transformations", () => {
- editor.setText('t13');
- editor.setCursorScreenPosition([0, 3]);
- simulateTabKeyEvent();
- expect(editor.getCursors().length).toBe(2);
+ editor.setText('t17')
+ editor.setCursorScreenPosition([0, 3])
+ simulateTabKeyEvent()
+ editor.insertText('foo')
+ expect(editor.getText()).toBe("console.log('uh foo', foo);")
+ simulateTabKeyEvent()
+ editor.insertText('bar')
+ expect(editor.getText()).toBe("console.log('bar', foo);")
+ })
+ })
+
+ describe('when the snippet contains tab stops with transformations', () => {
+ it('transforms the text typed into the first tab stop before setting it in the transformed tab stop', () => {
+ editor.setText('t12')
+ editor.setCursorScreenPosition([0, 3])
+ simulateTabKeyEvent()
+ expect(editor.getText()).toBe('[b][/b]')
+ editor.insertText('img src')
+ expect(editor.getText()).toBe('[img src][/img]')
+ })
+
+ it('bundles the transform mutations along with the original manual mutation for the purposes of undo and redo', () => {
+ editor.setText('t12')
+ editor.setCursorScreenPosition([0, 3])
+ simulateTabKeyEvent()
+ editor.insertText('i')
+ expect(editor.getText()).toBe('[i][/i]')
+
+ editor.insertText('mg src')
+ expect(editor.getText()).toBe('[img src][/img]')
+
+ editor.undo()
+ expect(editor.getText()).toBe('[i][/i]')
+
+ editor.redo()
+ expect(editor.getText()).toBe('[img src][/img]')
+ })
+
+ it('can pick the right insertion to use as the primary even if a transformed insertion occurs first in the snippet', () => {
+ editor.setText('t16')
+ editor.setCursorScreenPosition([0, 3])
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe('& Q & q')
+ expect(editor.getCursorBufferPosition()).toEqual([0, 7])
+
+ editor.insertText('rst')
+ expect(editor.lineTextForBufferRow(0)).toBe('& RST & rst')
+ })
+
+ it('silently ignores a tab stop without a non-transformed insertion to use as the primary', () => {
+ editor.setText('t15')
+ editor.setCursorScreenPosition([0, 3])
+ simulateTabKeyEvent()
+ editor.insertText('a')
+ expect(editor.lineTextForBufferRow(0)).toBe(' & a')
+ expect(editor.getCursorBufferPosition()).toEqual([0, 4])
+ })
+ })
+
+ describe('when the snippet contains mirrored tab stops and tab stops with transformations', () => {
+ it('adds cursors for the mirrors but not the transformations', () => {
+ editor.setText('t13')
+ editor.setCursorScreenPosition([0, 3])
+ simulateTabKeyEvent()
+ expect(editor.getCursors().length).toBe(2)
expect(editor.getText()).toBe(`\
placeholder
PLACEHOLDER
\
-`
- );
+`)
- editor.insertText('foo');
+ editor.insertText('foo')
expect(editor.getText()).toBe(`\
foo
FOO
foo\
-`
- );
- });
- });
-
- describe("when the snippet contains multiple tab stops, some with transformations and some without", () => {
- it("does not get confused", () => {
- editor.setText('t14');
- editor.setCursorScreenPosition([0, 3]);
- simulateTabKeyEvent();
- expect(editor.getCursors().length).toBe(2);
- expect(editor.getText()).toBe("placeholder PLACEHOLDER ANOTHER another ");
- simulateTabKeyEvent();
- expect(editor.getCursors().length).toBe(2);
- editor.insertText('FOO');
- expect(editor.getText()).toBe("placeholder PLACEHOLDER FOO foo FOO");
- });
- });
-
- describe("when the snippet has a transformed tab stop such that it is possible to move the cursor between the ordinary tab stop and its transformed version without an intermediate step", () => {
- it("terminates the snippet upon such a cursor move", () => {
- editor.setText('t18');
- editor.setCursorScreenPosition([0, 3]);
- simulateTabKeyEvent();
- expect(editor.getText()).toBe("// \n// ");
- expect(editor.getCursorBufferPosition()).toEqual([0, 3]);
- editor.insertText('wat');
- expect(editor.getText()).toBe("// wat\n// ===");
+`)
+ })
+ })
+
+ describe('when the snippet contains multiple tab stops, some with transformations and some without', () => {
+ it('does not get confused', () => {
+ editor.setText('t14')
+ editor.setCursorScreenPosition([0, 3])
+ simulateTabKeyEvent()
+ expect(editor.getCursors().length).toBe(2)
+ expect(editor.getText()).toBe(
+ 'placeholder PLACEHOLDER ANOTHER another '
+ )
+ simulateTabKeyEvent()
+ expect(editor.getCursors().length).toBe(2)
+ editor.insertText('FOO')
+ expect(editor.getText()).toBe('placeholder PLACEHOLDER FOO foo FOO')
+ })
+ })
+
+ describe('when the snippet has a transformed tab stop such that it is possible to move the cursor between the ordinary tab stop and its transformed version without an intermediate step', () => {
+ it('terminates the snippet upon such a cursor move', () => {
+ editor.setText('t18')
+ editor.setCursorScreenPosition([0, 3])
+ simulateTabKeyEvent()
+ expect(editor.getText()).toBe('// \n// ')
+ expect(editor.getCursorBufferPosition()).toEqual([0, 3])
+ editor.insertText('wat')
+ expect(editor.getText()).toBe('// wat\n// ===')
// Move the cursor down one line, then up one line. This puts the cursor
// back in its previous position, but the snippet should no longer be
// active, so when we type more text, it should not be mirrored.
- editor.setCursorScreenPosition([1, 6]);
- editor.setCursorScreenPosition([0, 6]);
- editor.insertText('wat');
- expect(editor.getText()).toBe("// watwat\n// ===");
- });
- });
-
- describe("when the snippet contains tab stops with an index >= 10", () => {
- it("parses and orders the indices correctly", () => {
- editor.setText('t10');
- editor.setCursorScreenPosition([0, 3]);
- simulateTabKeyEvent();
- expect(editor.getText()).toBe("hello large indices");
- expect(editor.getCursorBufferPosition()).toEqual([0, 19]);
- simulateTabKeyEvent();
- expect(editor.getCursorBufferPosition()).toEqual([0, 5]);
- simulateTabKeyEvent();
- expect(editor.getSelectedBufferRange()).toEqual([[0, 6], [0, 11]]);
- });
- });
-
- describe("when there are multiple cursors", () => {
- describe("when the cursors share a common snippet prefix", () => {
- it("expands the snippet for all cursors and allows simultaneous editing", () => {
- editor.insertText('t9');
- editor.setCursorBufferPosition([12, 2]);
- editor.insertText(' t9');
- editor.addCursorAtBufferPosition([0, 2]);
- simulateTabKeyEvent();
-
- expect(editor.lineTextForBufferRow(0)).toBe("with placeholder test");
- expect(editor.lineTextForBufferRow(1)).toBe("without placeholder var quicksort = function () {");
- expect(editor.lineTextForBufferRow(13)).toBe("}; with placeholder test");
- expect(editor.lineTextForBufferRow(14)).toBe("without placeholder ");
-
- editor.insertText('hello');
- expect(editor.lineTextForBufferRow(0)).toBe("with placeholder hello");
- expect(editor.lineTextForBufferRow(1)).toBe("without placeholder hellovar quicksort = function () {");
- expect(editor.lineTextForBufferRow(13)).toBe("}; with placeholder hello");
- expect(editor.lineTextForBufferRow(14)).toBe("without placeholder hello");
- });
-
- it("applies transformations identically to single-expansion mode", () => {
- editor.setText('t14\nt14');
- editor.setCursorBufferPosition([1, 3]);
- editor.addCursorAtBufferPosition([0, 3]);
- simulateTabKeyEvent();
-
- expect(editor.lineTextForBufferRow(0)).toBe("placeholder PLACEHOLDER ANOTHER another ");
- expect(editor.lineTextForBufferRow(1)).toBe("placeholder PLACEHOLDER ANOTHER another ");
-
- editor.insertText("testing");
-
- expect(editor.lineTextForBufferRow(0)).toBe("testing TESTING testing ANOTHER another ");
- expect(editor.lineTextForBufferRow(1)).toBe("testing TESTING testing ANOTHER another ");
-
- simulateTabKeyEvent();
- editor.insertText("AGAIN");
-
- expect(editor.lineTextForBufferRow(0)).toBe("testing TESTING testing AGAIN again AGAIN");
- expect(editor.lineTextForBufferRow(1)).toBe("testing TESTING testing AGAIN again AGAIN");
- });
-
- it("bundles transform-induced mutations into a single history entry along with their triggering edit, even across multiple snippets", () => {
- editor.setText('t14\nt14');
- editor.setCursorBufferPosition([1, 3]);
- editor.addCursorAtBufferPosition([0, 3]);
- simulateTabKeyEvent();
-
- expect(editor.lineTextForBufferRow(0)).toBe("placeholder PLACEHOLDER ANOTHER another ");
- expect(editor.lineTextForBufferRow(1)).toBe("placeholder PLACEHOLDER ANOTHER another ");
-
- editor.insertText("testing");
-
- expect(editor.lineTextForBufferRow(0)).toBe("testing TESTING testing ANOTHER another ");
- expect(editor.lineTextForBufferRow(1)).toBe("testing TESTING testing ANOTHER another ");
-
- simulateTabKeyEvent();
- editor.insertText("AGAIN");
-
- expect(editor.lineTextForBufferRow(0)).toBe("testing TESTING testing AGAIN again AGAIN");
- expect(editor.lineTextForBufferRow(1)).toBe("testing TESTING testing AGAIN again AGAIN");
-
- editor.undo();
- expect(editor.lineTextForBufferRow(0)).toBe("testing TESTING testing ANOTHER another ");
- expect(editor.lineTextForBufferRow(1)).toBe("testing TESTING testing ANOTHER another ");
-
- editor.undo();
- expect(editor.lineTextForBufferRow(0)).toBe("placeholder PLACEHOLDER ANOTHER another ");
- expect(editor.lineTextForBufferRow(1)).toBe("placeholder PLACEHOLDER ANOTHER another ");
-
- editor.redo();
- expect(editor.lineTextForBufferRow(0)).toBe("testing TESTING testing ANOTHER another ");
- expect(editor.lineTextForBufferRow(1)).toBe("testing TESTING testing ANOTHER another ");
-
- editor.redo();
- expect(editor.lineTextForBufferRow(0)).toBe("testing TESTING testing AGAIN again AGAIN");
- expect(editor.lineTextForBufferRow(1)).toBe("testing TESTING testing AGAIN again AGAIN");
- });
-
- describe("when there are many tabstops", () => {
- it("moves the cursors between the tab stops for their corresponding snippet when tab and shift-tab are pressed", () => {
- editor.addCursorAtBufferPosition([7, 5]);
- editor.addCursorAtBufferPosition([12, 2]);
- editor.insertText('t11');
- simulateTabKeyEvent();
-
- const cursors = editor.getCursors();
- expect(cursors.length).toEqual(3);
-
- expect(cursors[0].getBufferPosition()).toEqual([0, 3]);
- expect(cursors[1].getBufferPosition()).toEqual([7, 8]);
- expect(cursors[2].getBufferPosition()).toEqual([12, 5]);
- expect(cursors[0].selection.isEmpty()).toBe(true);
- expect(cursors[1].selection.isEmpty()).toBe(true);
- expect(cursors[2].selection.isEmpty()).toBe(true);
-
- simulateTabKeyEvent();
- expect(cursors[0].getBufferPosition()).toEqual([0, 7]);
- expect(cursors[1].getBufferPosition()).toEqual([7, 12]);
- expect(cursors[2].getBufferPosition()).toEqual([12, 9]);
- expect(cursors[0].selection.isEmpty()).toBe(false);
- expect(cursors[1].selection.isEmpty()).toBe(false);
- expect(cursors[2].selection.isEmpty()).toBe(false);
- expect(cursors[0].selection.getText()).toEqual('two');
- expect(cursors[1].selection.getText()).toEqual('two');
- expect(cursors[2].selection.getText()).toEqual('two');
-
- simulateTabKeyEvent();
- expect(cursors[0].getBufferPosition()).toEqual([0, 13]);
- expect(cursors[1].getBufferPosition()).toEqual([7, 18]);
- expect(cursors[2].getBufferPosition()).toEqual([12, 15]);
- expect(cursors[0].selection.isEmpty()).toBe(true);
- expect(cursors[1].selection.isEmpty()).toBe(true);
- expect(cursors[2].selection.isEmpty()).toBe(true);
-
- simulateTabKeyEvent();
- expect(cursors[0].getBufferPosition()).toEqual([0, 0]);
- expect(cursors[1].getBufferPosition()).toEqual([7, 5]);
- expect(cursors[2].getBufferPosition()).toEqual([12, 2]);
- expect(cursors[0].selection.isEmpty()).toBe(true);
- expect(cursors[1].selection.isEmpty()).toBe(true);
- expect(cursors[2].selection.isEmpty()).toBe(true);
- });
- });
- });
-
- describe("when the cursors do not share common snippet prefixes", () => {
- it("inserts tabs as normal", () => {
- editor.insertText('t9');
- editor.setCursorBufferPosition([12, 2]);
- editor.insertText(' t8');
- editor.addCursorAtBufferPosition([0, 2]);
- simulateTabKeyEvent();
- expect(editor.lineTextForBufferRow(0)).toBe("t9 var quicksort = function () {");
- expect(editor.lineTextForBufferRow(12)).toBe("}; t8 ");
- });
- });
-
- describe("when a snippet is triggered within an existing snippet expansion", () => {
- it("ignores the snippet expansion and goes to the next tab stop", () => {
- editor.addCursorAtBufferPosition([7, 5]);
- editor.addCursorAtBufferPosition([12, 2]);
- editor.insertText('t11');
- simulateTabKeyEvent();
- simulateTabKeyEvent();
-
- editor.insertText('t1');
- simulateTabKeyEvent();
-
- const cursors = editor.getCursors();
- expect(cursors.length).toEqual(3);
-
- expect(cursors[0].getBufferPosition()).toEqual([0, 12]);
- expect(cursors[1].getBufferPosition()).toEqual([7, 17]);
- expect(cursors[2].getBufferPosition()).toEqual([12, 14]);
- expect(cursors[0].selection.isEmpty()).toBe(true);
- expect(cursors[1].selection.isEmpty()).toBe(true);
- expect(cursors[2].selection.isEmpty()).toBe(true);
- expect(editor.lineTextForBufferRow(0)).toBe("one t1 threevar quicksort = function () {");
- expect(editor.lineTextForBufferRow(7)).toBe(" }one t1 three");
- expect(editor.lineTextForBufferRow(12)).toBe("};one t1 three");
- });
- });
- });
-
- describe("when the editor is not a pane item (regression)", () => {
- it("handles tab stops correctly", () => {
- editor = new TextEditor();
- atom.grammars.assignLanguageMode(editor, 'source.js');
- editorElement = editor.getElement();
-
- editor.insertText('t2');
- simulateTabKeyEvent();
- editor.insertText('ABC');
- expect(editor.getText()).toContain('go here first:(ABC)');
-
- editor.undo();
- editor.undo();
- expect(editor.getText()).toBe('t2');
- simulateTabKeyEvent();
- editor.insertText('ABC');
- expect(editor.getText()).toContain('go here first:(ABC)');
- });
- });
- });
-
- describe("when atom://.atom/snippets is opened", () => {
- it("opens ~/.atom/snippets.cson", () => {
- jasmine.unspy(Snippets, 'getUserSnippetsPath');
- atom.workspace.destroyActivePaneItem();
- const configDirPath = temp.mkdirSync('atom-config-dir-');
- spyOn(atom, 'getConfigDirPath').andReturn(configDirPath);
- atom.workspace.open('atom://.atom/snippets');
-
- waitsFor(() => atom.workspace.getActiveTextEditor() != null);
+ editor.setCursorScreenPosition([1, 6])
+ editor.setCursorScreenPosition([0, 6])
+ editor.insertText('wat')
+ expect(editor.getText()).toBe('// watwat\n// ===')
+ })
+ })
+
+ describe('when the snippet contains tab stops with an index >= 10', () => {
+ it('parses and orders the indices correctly', () => {
+ editor.setText('t10')
+ editor.setCursorScreenPosition([0, 3])
+ simulateTabKeyEvent()
+ expect(editor.getText()).toBe('hello large indices')
+ expect(editor.getCursorBufferPosition()).toEqual([0, 19])
+ simulateTabKeyEvent()
+ expect(editor.getCursorBufferPosition()).toEqual([0, 5])
+ simulateTabKeyEvent()
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [0, 6],
+ [0, 11]
+ ])
+ })
+ })
+
+ describe('when there are multiple cursors', () => {
+ describe('when the cursors share a common snippet prefix', () => {
+ it('expands the snippet for all cursors and allows simultaneous editing', () => {
+ editor.insertText('t9')
+ editor.setCursorBufferPosition([12, 2])
+ editor.insertText(' t9')
+ editor.addCursorAtBufferPosition([0, 2])
+ simulateTabKeyEvent()
+
+ expect(editor.lineTextForBufferRow(0)).toBe('with placeholder test')
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'without placeholder var quicksort = function () {'
+ )
+ expect(editor.lineTextForBufferRow(13)).toBe(
+ '}; with placeholder test'
+ )
+ expect(editor.lineTextForBufferRow(14)).toBe('without placeholder ')
+
+ editor.insertText('hello')
+ expect(editor.lineTextForBufferRow(0)).toBe('with placeholder hello')
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'without placeholder hellovar quicksort = function () {'
+ )
+ expect(editor.lineTextForBufferRow(13)).toBe(
+ '}; with placeholder hello'
+ )
+ expect(editor.lineTextForBufferRow(14)).toBe(
+ 'without placeholder hello'
+ )
+ })
+
+ it('applies transformations identically to single-expansion mode', () => {
+ editor.setText('t14\nt14')
+ editor.setCursorBufferPosition([1, 3])
+ editor.addCursorAtBufferPosition([0, 3])
+ simulateTabKeyEvent()
+
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'placeholder PLACEHOLDER ANOTHER another '
+ )
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'placeholder PLACEHOLDER ANOTHER another '
+ )
+
+ editor.insertText('testing')
+
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'testing TESTING testing ANOTHER another '
+ )
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'testing TESTING testing ANOTHER another '
+ )
+
+ simulateTabKeyEvent()
+ editor.insertText('AGAIN')
+
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'testing TESTING testing AGAIN again AGAIN'
+ )
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'testing TESTING testing AGAIN again AGAIN'
+ )
+ })
+
+ it('bundles transform-induced mutations into a single history entry along with their triggering edit, even across multiple snippets', () => {
+ editor.setText('t14\nt14')
+ editor.setCursorBufferPosition([1, 3])
+ editor.addCursorAtBufferPosition([0, 3])
+ simulateTabKeyEvent()
+
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'placeholder PLACEHOLDER ANOTHER another '
+ )
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'placeholder PLACEHOLDER ANOTHER another '
+ )
+
+ editor.insertText('testing')
+
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'testing TESTING testing ANOTHER another '
+ )
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'testing TESTING testing ANOTHER another '
+ )
+
+ simulateTabKeyEvent()
+ editor.insertText('AGAIN')
+
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'testing TESTING testing AGAIN again AGAIN'
+ )
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'testing TESTING testing AGAIN again AGAIN'
+ )
+
+ editor.undo()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'testing TESTING testing ANOTHER another '
+ )
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'testing TESTING testing ANOTHER another '
+ )
+
+ editor.undo()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'placeholder PLACEHOLDER ANOTHER another '
+ )
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'placeholder PLACEHOLDER ANOTHER another '
+ )
+
+ editor.redo()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'testing TESTING testing ANOTHER another '
+ )
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'testing TESTING testing ANOTHER another '
+ )
+
+ editor.redo()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'testing TESTING testing AGAIN again AGAIN'
+ )
+ expect(editor.lineTextForBufferRow(1)).toBe(
+ 'testing TESTING testing AGAIN again AGAIN'
+ )
+ })
+
+ describe('when there are many tabstops', () => {
+ it('moves the cursors between the tab stops for their corresponding snippet when tab and shift-tab are pressed', () => {
+ editor.addCursorAtBufferPosition([7, 5])
+ editor.addCursorAtBufferPosition([12, 2])
+ editor.insertText('t11')
+ simulateTabKeyEvent()
+
+ const cursors = editor.getCursors()
+ expect(cursors.length).toEqual(3)
+
+ expect(cursors[0].getBufferPosition()).toEqual([0, 3])
+ expect(cursors[1].getBufferPosition()).toEqual([7, 8])
+ expect(cursors[2].getBufferPosition()).toEqual([12, 5])
+ expect(cursors[0].selection.isEmpty()).toBe(true)
+ expect(cursors[1].selection.isEmpty()).toBe(true)
+ expect(cursors[2].selection.isEmpty()).toBe(true)
+
+ simulateTabKeyEvent()
+ expect(cursors[0].getBufferPosition()).toEqual([0, 7])
+ expect(cursors[1].getBufferPosition()).toEqual([7, 12])
+ expect(cursors[2].getBufferPosition()).toEqual([12, 9])
+ expect(cursors[0].selection.isEmpty()).toBe(false)
+ expect(cursors[1].selection.isEmpty()).toBe(false)
+ expect(cursors[2].selection.isEmpty()).toBe(false)
+ expect(cursors[0].selection.getText()).toEqual('two')
+ expect(cursors[1].selection.getText()).toEqual('two')
+ expect(cursors[2].selection.getText()).toEqual('two')
+
+ simulateTabKeyEvent()
+ expect(cursors[0].getBufferPosition()).toEqual([0, 13])
+ expect(cursors[1].getBufferPosition()).toEqual([7, 18])
+ expect(cursors[2].getBufferPosition()).toEqual([12, 15])
+ expect(cursors[0].selection.isEmpty()).toBe(true)
+ expect(cursors[1].selection.isEmpty()).toBe(true)
+ expect(cursors[2].selection.isEmpty()).toBe(true)
+
+ simulateTabKeyEvent()
+ expect(cursors[0].getBufferPosition()).toEqual([0, 0])
+ expect(cursors[1].getBufferPosition()).toEqual([7, 5])
+ expect(cursors[2].getBufferPosition()).toEqual([12, 2])
+ expect(cursors[0].selection.isEmpty()).toBe(true)
+ expect(cursors[1].selection.isEmpty()).toBe(true)
+ expect(cursors[2].selection.isEmpty()).toBe(true)
+ })
+ })
+ })
+
+ describe('when the cursors do not share common snippet prefixes', () => {
+ it('inserts tabs as normal', () => {
+ editor.insertText('t9')
+ editor.setCursorBufferPosition([12, 2])
+ editor.insertText(' t8')
+ editor.addCursorAtBufferPosition([0, 2])
+ simulateTabKeyEvent()
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 't9 var quicksort = function () {'
+ )
+ expect(editor.lineTextForBufferRow(12)).toBe('}; t8 ')
+ })
+ })
+
+ describe('when a snippet is triggered within an existing snippet expansion', () => {
+ it('ignores the snippet expansion and goes to the next tab stop', () => {
+ editor.addCursorAtBufferPosition([7, 5])
+ editor.addCursorAtBufferPosition([12, 2])
+ editor.insertText('t11')
+ simulateTabKeyEvent()
+ simulateTabKeyEvent()
+
+ editor.insertText('t1')
+ simulateTabKeyEvent()
+
+ const cursors = editor.getCursors()
+ expect(cursors.length).toEqual(3)
+
+ expect(cursors[0].getBufferPosition()).toEqual([0, 12])
+ expect(cursors[1].getBufferPosition()).toEqual([7, 17])
+ expect(cursors[2].getBufferPosition()).toEqual([12, 14])
+ expect(cursors[0].selection.isEmpty()).toBe(true)
+ expect(cursors[1].selection.isEmpty()).toBe(true)
+ expect(cursors[2].selection.isEmpty()).toBe(true)
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'one t1 threevar quicksort = function () {'
+ )
+ expect(editor.lineTextForBufferRow(7)).toBe(' }one t1 three')
+ expect(editor.lineTextForBufferRow(12)).toBe('};one t1 three')
+ })
+ })
+ })
+
+ describe('when the editor is not a pane item (regression)', () => {
+ it('handles tab stops correctly', () => {
+ editor = new TextEditor()
+ atom.grammars.assignLanguageMode(editor, 'source.js')
+ editorElement = editor.getElement()
+
+ editor.insertText('t2')
+ simulateTabKeyEvent()
+ editor.insertText('ABC')
+ expect(editor.getText()).toContain('go here first:(ABC)')
+
+ editor.undo()
+ editor.undo()
+ expect(editor.getText()).toBe('t2')
+ simulateTabKeyEvent()
+ editor.insertText('ABC')
+ expect(editor.getText()).toContain('go here first:(ABC)')
+ })
+ })
+ })
+
+ describe('when atom://.atom/snippets is opened', () => {
+ it('opens ~/.atom/snippets.cson', () => {
+ jasmine.unspy(Snippets, 'getUserSnippetsPath')
+ atom.workspace.destroyActivePaneItem()
+ const configDirPath = temp.mkdirSync('atom-config-dir-')
+ spyOn(atom, 'getConfigDirPath').andReturn(configDirPath)
+ atom.workspace.open('atom://.atom/snippets')
+
+ waitsFor(() => atom.workspace.getActiveTextEditor() != null)
runs(() => {
- expect(atom.workspace.getActiveTextEditor().getURI()).toBe(path.join(configDirPath, 'snippets.cson'));
- });
- });
- });
-
- describe("snippet insertion API", () => {
- it("will automatically parse snippet definition and replace selection", () => {
- editor.setSelectedBufferRange([[0, 4], [0, 13]]);
- Snippets.insert("hello ${1:world}", editor);
-
- expect(editor.lineTextForBufferRow(0)).toBe("var hello world = function () {");
- expect(editor.getSelectedBufferRange()).toEqual([[0, 10], [0, 15]]);
- });
- });
+ expect(atom.workspace.getActiveTextEditor().getURI()).toBe(
+ path.join(configDirPath, 'snippets.cson')
+ )
+ })
+ })
+ })
+
+ describe('snippet insertion API', () => {
+ it('will automatically parse snippet definition and replace selection', () => {
+ editor.setSelectedBufferRange([
+ [0, 4],
+ [0, 13]
+ ])
+ Snippets.insert('hello ${1:world}', editor)
+
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'var hello world = function () {'
+ )
+ expect(editor.getSelectedBufferRange()).toEqual([
+ [0, 10],
+ [0, 15]
+ ])
+ })
+ })
describe("when the 'snippets:available' command is triggered", () => {
- let availableSnippetsView = null;
+ let availableSnippetsView = null
beforeEach(() => {
Snippets.add(__filename, {
- ".source.js": {
- "test": {
- prefix: "test",
- body: "${1:Test pass you will}, young "
+ '.source.js': {
+ test: {
+ prefix: 'test',
+ body: '${1:Test pass you will}, young '
},
- "challenge": {
- prefix: "chal",
- body: "$1: ${2:To pass this challenge}"
+ challenge: {
+ prefix: 'chal',
+ body: '$1: ${2:To pass this challenge}'
}
}
- }
- );
+ })
- delete Snippets.availableSnippetsView;
+ delete Snippets.availableSnippetsView
- atom.commands.dispatch(editorElement, "snippets:available");
+ atom.commands.dispatch(editorElement, 'snippets:available')
- waitsFor(() => atom.workspace.getModalPanels().length === 1);
+ waitsFor(() => atom.workspace.getModalPanels().length === 1)
runs(() => {
- availableSnippetsView = atom.workspace.getModalPanels()[0].getItem();
- });
- });
-
- it("renders a select list of all available snippets", () => {
- expect(availableSnippetsView.selectListView.getSelectedItem().prefix).toBe('test');
- expect(availableSnippetsView.selectListView.getSelectedItem().name).toBe('test');
- expect(availableSnippetsView.selectListView.getSelectedItem().bodyText).toBe('${1:Test pass you will}, young ');
-
- availableSnippetsView.selectListView.selectNext();
-
- expect(availableSnippetsView.selectListView.getSelectedItem().prefix).toBe('chal');
- expect(availableSnippetsView.selectListView.getSelectedItem().name).toBe('challenge');
- expect(availableSnippetsView.selectListView.getSelectedItem().bodyText).toBe('$1: ${2:To pass this challenge}');
- });
-
- it("writes the selected snippet to the editor as snippet", () => {
- availableSnippetsView.selectListView.confirmSelection();
-
- expect(editor.getCursorScreenPosition()).toEqual([0, 18]);
- expect(editor.getSelectedText()).toBe('Test pass you will');
- expect(editor.lineTextForBufferRow(0)).toBe('Test pass you will, young var quicksort = function () {');
- });
-
- it("closes the dialog when triggered again", () => {
- atom.commands.dispatch(availableSnippetsView.selectListView.refs.queryEditor.element, 'snippets:available');
- expect(atom.workspace.getModalPanels().length).toBe(0);
- });
- });
-});
+ availableSnippetsView = atom.workspace.getModalPanels()[0].getItem()
+ })
+ })
+
+ it('renders a select list of all available snippets', () => {
+ expect(
+ availableSnippetsView.selectListView.getSelectedItem().prefix
+ ).toBe('test')
+ expect(availableSnippetsView.selectListView.getSelectedItem().name).toBe(
+ 'test'
+ )
+ expect(
+ availableSnippetsView.selectListView.getSelectedItem().bodyText
+ ).toBe('${1:Test pass you will}, young ')
+
+ availableSnippetsView.selectListView.selectNext()
+
+ expect(
+ availableSnippetsView.selectListView.getSelectedItem().prefix
+ ).toBe('chal')
+ expect(availableSnippetsView.selectListView.getSelectedItem().name).toBe(
+ 'challenge'
+ )
+ expect(
+ availableSnippetsView.selectListView.getSelectedItem().bodyText
+ ).toBe('$1: ${2:To pass this challenge}')
+ })
+
+ it('writes the selected snippet to the editor as snippet', () => {
+ availableSnippetsView.selectListView.confirmSelection()
+
+ expect(editor.getCursorScreenPosition()).toEqual([0, 18])
+ expect(editor.getSelectedText()).toBe('Test pass you will')
+ expect(editor.lineTextForBufferRow(0)).toBe(
+ 'Test pass you will, young var quicksort = function () {'
+ )
+ })
+
+ it('closes the dialog when triggered again', () => {
+ atom.commands.dispatch(
+ availableSnippetsView.selectListView.refs.queryEditor.element,
+ 'snippets:available'
+ )
+ expect(atom.workspace.getModalPanels().length).toBe(0)
+ })
+ })
+})