diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 00000000..e868bcf3
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1 @@
+*.pegjs
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 00000000..13b430ef
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,13 @@
+{
+ "parserOptions": {
+ "sourceType": "module",
+ "ecmaVersion": 2022
+ },
+ "rules": {
+ "indent": ["error", 2],
+ "linebreak-style": ["error", "unix"],
+ "object-curly-spacing": ["error", "never"],
+ "space-before-function-paren": ["error", "always"],
+ "semi": ["error", "never"]
+ }
+}
diff --git a/.github/workflows/pulsar_test.yml b/.github/workflows/pulsar_test.yml
index deb2404b..d3aa6cf0 100644
--- a/.github/workflows/pulsar_test.yml
+++ b/.github/workflows/pulsar_test.yml
@@ -14,11 +14,17 @@ jobs:
- name: Checkout the Latest Package Code
uses: actions/checkout@v3
- name: Setup Pulsar Editor
- uses: pulsar-edit/action-pulsar-dependency@v2.1
- with:
- package-to-test: "snippets"
+ uses: pulsar-edit/action-pulsar-dependency@v3.2
+ - name: Install dependencies (Windows)
+ if: ${{ runner.os == 'Windows' }}
+ # Currently the Pulsar process starts, but unlike *nix doesn't wait for ppm to finish, probably because pulsar.cmd needs updated
+ # So we'll fallback to ppm (still named apm) instead
+ run: apm install
+ - name: Install dependencies (*nix)
+ if: ${{ runner.os != 'Windows' }}
+ run: pulsar --package install
- name: Run the headless Pulsar Tests
- uses: GabrielBB/xvfb-action@v1
+ uses: coactions/setup-xvfb@v1.0.1
with:
- run: yarn start --test spec
- working-directory: ./pulsar
+ run: pulsar --test spec
+ # working-directory: ./pulsar
diff --git a/README.md b/README.md
index 267f42cb..91836e7a 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,7 @@ Snippets files are stored in a package's `snippets/` folder and also loaded from
'.source.js':
'console.log':
'prefix': 'log'
+ 'command': 'insert-console-log'
'body': 'console.log(${1:"crash"});$2'
```
@@ -20,11 +21,11 @@ The outermost keys are the selectors where these snippets should be active, pref
The next level of keys are the snippet names.
-Under each snippet name is a `prefix` that should trigger the snippet and a `body` to insert when the snippet is triggered.
+Under each snippet name is a `body` to insert when the snippet is triggered.
-`$` followed by a number are the tabs stops which can be cycled between by pressing tab once a snippet has been triggered.
+`$` followed by a number are the tabs stops which can be cycled between by pressing Tab once a snippet has been triggered.
-The above example adds a `log` snippet to JavaScript files that would expand to.
+The above example adds a `console.log` snippet to JavaScript files that would expand to:
```js
console.log("crash");
@@ -32,7 +33,26 @@ console.log("crash");
The string `"crash"` would be initially selected and pressing tab again would place the cursor after the `;`
+A snippet must define **at least one** of the following keys:
+
+### The ‘prefix’ key
+
+If a `prefix` is defined, it specifies a string that can trigger the snippet: type the string in the editor and press Tab. In this example, typing `log` (as its own word) and then pressing Tab would replace `log` with the string `console.log("crash")` as described above.
+
+Prefix completions can be suggested if partially typed thanks to the `autocomplete-snippets` package.
+
+### The ‘command’ key
+
+If a `command` is defined, it specifies a command name that can trigger the snippet. That command can be invoked from the command palette or mapped to a keyboard shortcut via your `keymap.cson`.
+
+If you defined the `console.log` snippet described above in your own `snippets.cson`, it would be available in the command palette as “Snippets: Insert Console Log”, or could be referenced in a keymap file as `snippets:insert-console-log`.
+
+If a package called `some-package` had defined that snippet, it would be available in the keymap as `some-package:insert-console-log`, or in the command palette as “Some Package: Insert Console Log”.
+
+Invoking the command would insert the snippet at the cursor, replacing any text that may be selected.
+
### 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.
diff --git a/lib/editor-store.js b/lib/editor-store.js
index c57cb7ad..44678b78 100644
--- a/lib/editor-store.js
+++ b/lib/editor-store.js
@@ -27,7 +27,10 @@ class EditorStore {
}
observeHistory (delegates) {
- if (this.existingHistoryProvider == null) {
+ let isObservingHistory = this.existingHistoryProvider != null
+ if (isObservingHistory) {
+ return
+ } else {
this.existingHistoryProvider = this.buffer.historyProvider
}
diff --git a/lib/snippet-expansion.js b/lib/snippet-expansion.js
index a1545cd4..b962d803 100644
--- a/lib/snippet-expansion.js
+++ b/lib/snippet-expansion.js
@@ -1,7 +1,7 @@
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)
@@ -175,7 +175,7 @@ module.exports = class SnippetExpansion {
const marker = this.getMarkerLayer(this.editor).markBufferRange([
startPosition.traverse(start),
startPosition.traverse(end)
- ], { exclusive: !shouldBeInclusive })
+ ], {exclusive: !shouldBeInclusive})
// Now that we've created these markers, we need to store them in a
// data structure because they'll need to be deleted and re-created
// when their exclusivity changes.
@@ -364,7 +364,7 @@ module.exports = class SnippetExpansion {
this.getMarkerLayer(this.editor).clear()
this.insertionsByIndex = []
this.relatedInsertionsByIndex = new Map()
- this.markersForInsertions = new Map();
+ this.markersForInsertions = new Map()
this.snippets.stopObservingEditor(this.editor)
this.snippets.clearExpansions(this.editor)
}
diff --git a/lib/snippet.js b/lib/snippet.js
index d3b1767d..b432fe83 100644
--- a/lib/snippet.js
+++ b/lib/snippet.js
@@ -12,17 +12,23 @@ function tabStopsReferencedWithinTabStopContent (segment) {
}
module.exports = class Snippet {
- constructor({name, prefix, bodyText, description, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML, bodyTree}) {
+ constructor ({name, prefix, command, bodyText, description, packageName, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML, bodyTree, selector}) {
this.name = name
this.prefix = prefix
+ this.command = command
+ this.packageName = packageName
this.bodyText = bodyText
this.description = description
this.descriptionMoreURL = descriptionMoreURL
this.rightLabelHTML = rightLabelHTML
this.leftLabel = leftLabel
this.leftLabelHTML = leftLabelHTML
+ this.selector = selector
this.tabStopList = new TabStopList(this)
this.body = this.extractTabStops(bodyTree)
+ if (packageName && command) {
+ this.commandName = `${packageName}:${command}`
+ }
}
extractTabStops (bodyTree) {
@@ -35,10 +41,14 @@ module.exports = class Snippet {
for (const segment of bodyTree) {
if (segment.index != null) {
let {index, content, substitution} = segment
- if (index === 0) { index = Infinity; }
+ // Ensure tabstop `$0` is always last.
+ if (index === 0) { index = Infinity }
+
const start = [row, column]
extractTabStops(content)
+
const referencedTabStops = tabStopsReferencedWithinTabStopContent(content)
+
const range = new Range(start, [row, column])
const tabStop = this.tabStopList.findOrCreate({
index,
diff --git a/lib/snippets.js b/lib/snippets.js
index e544e720..b86427ec 100644
--- a/lib/snippets.js
+++ b/lib/snippets.js
@@ -11,6 +11,117 @@ const SnippetExpansion = require('./snippet-expansion')
const EditorStore = require('./editor-store')
const {getPackageRoot} = require('./helpers')
+// TODO: Not sure about validity of numbers in here, but might as well be
+// permissive.
+const COMMAND_NAME_PATTERN = /^[a-z\d][a-z\d\-]*[a-z\d]$/
+function isValidCommandName (commandName) {
+ return COMMAND_NAME_PATTERN.test(commandName)
+}
+
+function showCommandNameConflictNotification (name, commandName, packageName, snippetsPath) {
+ let remedy
+ if (packageName === 'builtin') {
+ // If somehow this happens with a builtin snippet, something crazy is
+ // happening. But we shouldn't show a notification because there's no
+ // action for the user to take. Just fail silently.
+ return
+ }
+ if (packageName === 'snippets') {
+ let extension = snippetsPath.substring(snippetsPath.length - 4)
+ remedy = `Edit your \`snippets.${extension}\` file to resolve this conflict.`
+ } else {
+ remedy = `Contact the maintainer of \`${packageName}\` so they can resolve this conflict.`
+ }
+ const message = `Cannot register command \`${commandName}\` for snippet “${name}” because that command name already exists.\n\n${remedy}`
+ atom.notifications.addError(
+ `Snippets conflict`,
+ {
+ description: message,
+ dismissable: true
+ }
+ )
+}
+
+function showInvalidCommandNameNotification (name, commandName) {
+ const message = `Cannot register \`${commandName}\` for snippet “${name}” because the command name isn’t valid. Command names must be all lowercase and use hyphens between words instead of spaces.`
+ atom.notifications.addError(
+ `Snippets error`,
+ {
+ description: message,
+ dismissable: true
+ }
+ )
+}
+
+// When we first run, checking `atom.commands.registeredCommands` is a good way
+// of checking whether a command of a certain name already exists. But if we
+// register a command and then unregister it (e.g., upon later disabling of a
+// package's snippets), the relevant key won't get deleted from
+// `registeredCommands`. So if the user re-enables the snippets, we'll
+// incorrectly think that the command already exists.
+//
+// Hence, after the first check, we have to keep track ourselves. At least this
+// gives us a place to keep track of individual command disposables.
+//
+const CommandMonitor = {
+ map: new Map,
+ disposables: new Map,
+ compositeDisposable: new CompositeDisposable,
+ exists (commandName) {
+ let {map} = this
+ if (!map.has(commandName)) {
+ // If it's missing altogether from the registry, we haven't asked yet.
+ let value = atom.commands.registeredCommands[commandName]
+ map.set(commandName, value)
+ return value
+ } else {
+ return map.get(commandName)
+ }
+ },
+
+ add (commandName, disposable) {
+ this.map.set(commandName, true)
+ this.disposables.set(commandName, disposable)
+ this.compositeDisposable.add(disposable)
+ },
+
+ remove (commandName) {
+ this.map.set(commandName, false)
+ let disposable = this.disposables.get(commandName)
+ if (disposable) { disposable.dispose() }
+ },
+
+ reset () {
+ this.map.clear()
+ this.disposables.clear()
+ this.compositeDisposable.dispose()
+ }
+}
+
+// When we load snippets from packages, we're given a bunch of package paths
+// instead of package names. This lets us match the former to the latter.
+const PackageNameResolver = {
+ pathsToNames: new Map,
+ setup () {
+ this.pathsToNames.clear()
+ let meta = atom.packages.getLoadedPackages() || []
+ for (let {name, path} of meta) {
+ this.pathsToNames.set(path, name)
+ }
+ if (!this._observing) {
+ atom.packages.onDidLoadPackage(() => this.setup())
+ atom.packages.onDidUnloadPackage(() => this.setup())
+ }
+ this._observing = true
+ },
+ find (filePath) {
+ for (let [packagePath, name] of this.pathsToNames.entries()) {
+ if (filePath.startsWith(packagePath)) return name
+ }
+ return null
+ }
+}
+
module.exports = {
activate () {
this.loaded = false
@@ -36,19 +147,26 @@ module.exports = {
}
}))
+ PackageNameResolver.setup()
+
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) {
+ 'snippets:expand' (event) {
const editor = this.getModel()
if (snippets.snippetToExpandUnderCursor(editor)) {
snippets.clearExpansions(editor)
@@ -58,20 +176,22 @@ module.exports = {
}
},
- 'snippets:next-tab-stop'(event) {
+ 'snippets:next-tab-stop' (event) {
const editor = this.getModel()
if (!snippets.goToNextTabStop(editor)) { event.abortKeyBinding() }
},
- 'snippets:previous-tab-stop'(event) {
+ 'snippets:previous-tab-stop' (event) {
const editor = this.getModel()
if (!snippets.goToPreviousTabStop(editor)) { event.abortKeyBinding() }
},
- 'snippets:available'(event) {
+ 'snippets:available' (event) {
const editor = this.getModel()
const SnippetsAvailable = require('./snippets-available')
- if (snippets.availableSnippetsView == null) { snippets.availableSnippetsView = new SnippetsAvailable(snippets) }
+ if (snippets.availableSnippetsView == null) {
+ snippets.availableSnippetsView = new SnippetsAvailable(snippets)
+ }
snippets.availableSnippetsView.toggle(editor)
}
}))
@@ -84,6 +204,7 @@ module.exports = {
this.emitter = null
this.editorSnippetExpansions = null
atom.config.transact(() => this.subscriptions.dispose())
+ CommandMonitor.reset()
},
getUserSnippetsPath () {
@@ -99,11 +220,15 @@ module.exports = {
this.loadPackageSnippets(packageSnippets => {
this.loadUserSnippets(userSnippets => {
atom.config.transact(() => {
- for (const snippetSet of [bundledSnippets, packageSnippets, userSnippets]) {
- for (const filepath in snippetSet) {
- const snippetsBySelector = snippetSet[filepath]
- this.add(filepath, snippetsBySelector)
- }
+ for (const [filepath, snippetsBySelector] of Object.entries(bundledSnippets)) {
+ this.add(filepath, snippetsBySelector, 'builtin')
+ }
+ for (const [filepath, snippetsBySelector] of Object.entries(packageSnippets)) {
+ let packageName = PackageNameResolver.find(filepath) || 'snippets'
+ this.add(filepath, snippetsBySelector, packageName)
+ }
+ for (const [filepath, snippetsBySelector] of Object.entries(userSnippets)) {
+ this.add(filepath, snippetsBySelector, 'snippets')
}
})
this.doneLoading()
@@ -168,11 +293,22 @@ module.exports = {
// Called when a user's snippets file is changed, deleted, or moved so that we
// can immediately re-process the snippets it contains.
handleUserSnippetsDidChange () {
+ // TODO: There appear to be scenarios where this method gets invoked more
+ // than once with each change to the user's `snippets.cson`. To prevent
+ // more than one concurrent rescan of the snippets file, we block any
+ // additional calls to this method while the first call is still operating.
const userSnippetsPath = this.getUserSnippetsPath()
+
+ if (this.isHandlingUserSnippetsChange) {
+ return
+ }
+
+ this.isHandlingUserSnippetsChange = true
atom.config.transact(() => {
this.clearSnippetsForPath(userSnippetsPath)
this.loadSnippetsFile(userSnippetsPath, result => {
- this.add(userSnippetsPath, result)
+ this.add(userSnippetsPath, result, 'snippets')
+ this.isHandlingUserSnippetsChange = false
})
})
},
@@ -200,7 +336,7 @@ module.exports = {
const snippetSet = this.snippetsByPackage.get(packageName)
for (const filePath in snippetSet) {
const snippetsBySelector = snippetSet[filePath]
- this.add(filePath, snippetsBySelector)
+ this.add(filePath, snippetsBySelector, packageName)
}
},
@@ -218,7 +354,7 @@ module.exports = {
loadPackageSnippets (callback) {
const disabledPackageNames = atom.config.get('core.packagesWithSnippetsDisabled') || []
const packages = atom.packages.getLoadedPackages().sort((pack, _) => {
- return /\/node_modules\//.test(pack.path) ? -1 : 1
+ return pack.path.includes(`${path.sep}node_modules${path.sep}`) ? -1 : 1
})
const snippetsDirPaths = []
@@ -274,7 +410,7 @@ module.exports = {
loadSnippetsDirectory (snippetsDirPath, callback) {
fs.stat(snippetsDirPath, (error, stat) => {
- if (error || !stat.isDirectory()) return callback(null, {});
+ if (error || !stat.isDirectory()) return callback(null, {})
fs.readdir(snippetsDirPath, (error, entries) => {
if (error) {
@@ -294,7 +430,8 @@ module.exports = {
snippetsByPath[filePath] = snippets
}
callback(null, snippetsByPath)
- })
+ }
+ )
})
})
},
@@ -310,30 +447,143 @@ module.exports = {
})
},
- add (filePath, snippetsBySelector, isDisabled = false) {
+ add (filePath, snippetsBySelector, packageName = null, isDisabled = false) {
+ packageName ??= 'snippets'
for (const selector in snippetsBySelector) {
const snippetsByName = snippetsBySelector[selector]
const unparsedSnippetsByPrefix = {}
for (const name in snippetsByName) {
const attributes = snippetsByName[name]
- const {prefix, body} = attributes
+ const {prefix, command, body} = attributes
+ if (!prefix && !command) {
+ // A snippet must define either `prefix` or `command`, or both.
+ // TODO: Worth showing notification?
+ console.error(`Skipping snippet ${name}: no "prefix" or "command" property present`)
+ continue
+ }
+ attributes.selector = selector
attributes.name = name
attributes.id = this.snippetIdCounter++
- if (typeof body === 'string') {
- unparsedSnippetsByPrefix[prefix] = attributes
- } else if (body == null) {
- unparsedSnippetsByPrefix[prefix] = null
+ attributes.packageName = packageName
+ // Snippets with "prefix"es will get indexed according to that prefix.
+ // Snippets without "prefix"es will be indexed by their ID below _if_
+ // they have a "command" property. Snippets without "prefix" or
+ // "command" have already been filtered out.
+ if (prefix) {
+ if (typeof body === 'string') {
+ unparsedSnippetsByPrefix[prefix] = attributes
+ } else if (body == null) {
+ unparsedSnippetsByPrefix[prefix] = null
+ }
+ }
+ if (command) {
+ if (!isValidCommandName(command)) {
+ showInvalidCommandNameNotification(name, command)
+ continue
+ }
+ if (!prefix) {
+ // We need a key for these snippets that will not clash with any
+ // prefix key. Since prefixes aren't allowed to have spaces, we'll
+ // put a space in this key.
+ //
+ // We'll use the snippet ID as part of the key. If a snippet's
+ // `command` property clashes with another command, we'll catch
+ // that later.
+ let unparsedSnippetsKey = `command ${attributes.id}`
+ if (typeof body === 'string') {
+ unparsedSnippetsByPrefix[unparsedSnippetsKey] = attributes
+ } else {
+ unparsedSnippetsByPrefix[unparsedSnippetsKey] = null
+ }
+ }
+ if (!isDisabled) {
+ this.addCommandForSnippet(attributes, packageName, selector)
+ }
}
}
- this.storeUnparsedSnippets(unparsedSnippetsByPrefix, filePath, selector, isDisabled)
+ this.storeUnparsedSnippets(unparsedSnippetsByPrefix, filePath, selector, packageName, isDisabled)
}
},
+ addCommandForSnippet (attributes, packageName, selector) {
+ packageName = packageName || 'snippets'
+ let {name, command} = attributes
+ let commandName = `${packageName}:${command}`
+ console.trace()
+ if (CommandMonitor.exists(commandName)) {
+ console.error(`Skipping ${commandName} because it's already been registered!`)
+ showCommandNameConflictNotification(
+ name,
+ commandName,
+ packageName,
+ this.getUserSnippetsPath()
+ )
+ // We won't remove the snippet because it might still be triggerable by
+ // prefix. But we will null out the `command` property to prevent any
+ // possible confusion.
+ attributes.command = null
+ return
+ }
+
+ let commandHandler = (event) => {
+ let editor = event.target.closest('atom-text-editor').getModel()
+
+ // We match the multi-cursor behavior that prefix-triggered snippets
+ // exhibit: only the last cursor determines which scoped set of snippets
+ // we pull, but we'll insert this snippet for each cursor, whether it
+ // happens to be valid for that cursor's scope or not. This could
+ // possibly be refined in the future.
+ let snippets = this.getSnippets(editor)
+
+ let targetSnippet = null
+ for (let snippet of Object.values(snippets)) {
+ if (snippet.command === command && snippet.packageName === packageName) {
+ targetSnippet = snippet
+ break
+ }
+ }
+
+ if (!targetSnippet) {
+ // We don't show an error notification here because it isn't
+ // necessarily a mistake. But we put a warning in the console just in
+ // case the user is confused.
+ console.warn(`Snippet “${name}” not invoked because its scope was not matched.`)
+
+ // Because its scope was not matched, we abort the key binding; this
+ // signals to the key binding resolver that it can pick the next
+ // candidate for a key shortcut, if one exists.
+ return event.abortKeyBinding()
+ }
+
+ this.getStore(editor).observeHistory({
+ undo: event => { this.onUndoOrRedo(editor, event, true) },
+ redo: event => { this.onUndoOrRedo(editor, event, false) }
+ })
+ this.findOrCreateMarkerLayer(editor)
+ editor.transact(() => {
+ const cursors = editor.getCursors()
+ for (const cursor of cursors) {
+ this.insert(targetSnippet, editor, cursor)
+ }
+ })
+ }
+
+ let disposable = atom.commands.add(
+ 'atom-text-editor',
+ commandName,
+ commandHandler
+ )
+
+ this.subscriptions.add(disposable)
+ CommandMonitor.add(commandName, disposable)
+ },
+
addSnippetsInDisabledPackage (bundle) {
for (const filePath in bundle) {
const snippetsBySelector = bundle[filePath]
- this.add(filePath, snippetsBySelector, true)
+ const packageName = PackageNameResolver.find(filePath)
+ this.add(filePath, snippetsBySelector, packageName, true)
}
},
@@ -348,7 +598,7 @@ module.exports = {
.join(' ')
},
- storeUnparsedSnippets (value, path, selector, isDisabled = false) {
+ storeUnparsedSnippets (value, path, selector, packageName, isDisabled = false) {
// The `isDisabled` flag determines which scoped property store we'll use.
// Active snippets get put into one and inactive snippets get put into
// another. Only the first one gets consulted when we look up a snippet
@@ -362,9 +612,15 @@ module.exports = {
clearSnippetsForPath (path) {
for (const scopeSelector in this.scopedPropertyStore.propertiesForSource(path)) {
- const object = this.scopedPropertyStore.propertiesForSourceAndSelector(path, scopeSelector)
+ let object = this.scopedPropertyStore.propertiesForSourceAndSelector(path, scopeSelector)
+ if (object.snippets) { object = object.snippets }
for (const prefix in object) {
const attributes = object[prefix]
+ if (!attributes) { continue }
+ let {command, packageName} = attributes
+ if (packageName && command) {
+ CommandMonitor.remove(`${packageName}:${command}`)
+ }
this.parsedSnippetsById.delete(attributes.id)
}
@@ -416,9 +672,9 @@ 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
+ let {id, prefix, command, name, body, bodyTree, description, packageName, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML, selector} = attributes
if (bodyTree == null) { bodyTree = this.getBodyParser().parse(body) }
- snippet = new Snippet({id, name, prefix, bodyTree, description, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML, bodyText: body})
+ snippet = new Snippet({id, name, prefix, command, bodyTree, description, packageName, descriptionMoreURL, rightLabelHTML, leftLabel, leftLabelHTML, selector, bodyText: body})
this.parsedSnippetsById.set(attributes.id, snippet)
}
return snippet
@@ -485,6 +741,10 @@ module.exports = {
let longestPrefixMatch = null
for (const snippetPrefix in snippets) {
+ // Any snippet without a prefix was keyed on its snippet ID, but with a
+ // space introduced to ensure it would never be a prefix match. But let's
+ // play it safe here anyway.
+ if (snippetPrefix.includes(' ')) { continue }
const snippet = snippets[snippetPrefix]
if (prefix.endsWith(snippetPrefix) && (wordPrefix.length <= snippetPrefix.length)) {
if ((longestPrefixMatch == null) || (snippetPrefix.length > longestPrefixMatch.prefix.length)) {
@@ -634,11 +894,11 @@ module.exports = {
const iterate = sets => {
for (const item of sets) {
const newItem = _.deepClone(item)
- // The atom-slick library has already parsed the `selector` property, so
- // it's an AST here instead of a string. The object has a `toString`
+ // The atom-slick library has already parsed the `selector` property,
+ // so it's an AST here instead of a string. The object has a `toString`
// method that turns it back into a string. That custom behavior won't
- // be preserved in the deep clone of the object, so we have to handle it
- // separately.
+ // be preserved in the deep clone of the object, so we have to handle
+ // it separately.
newItem.selectorString = item.selector.toString()
results.push(newItem)
}
@@ -659,7 +919,7 @@ module.exports = {
}
},
- onUndoOrRedo (editor, isUndo) {
+ onUndoOrRedo (editor, event, isUndo) {
const activeExpansions = this.getExpansions(editor)
activeExpansions.forEach(expansion => expansion.onUndoOrRedo(isUndo))
}
diff --git a/package-lock.json b/package-lock.json
index eaf0e7bc..d5bda9b6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,29 +19,203 @@
"underscore-plus": "^1.0.0"
},
"devDependencies": {
- "coffeelint": "^1.9.7"
+ "eslint": "^8.33.0"
},
"engines": {
"atom": "*"
}
},
+ "node_modules/@eslint/eslintrc": {
+ "version": "1.4.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.4.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/ignore": {
+ "version": "5.2.4",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+ "version": "3.1.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.11.8",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^1.2.1",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
+ "version": "3.1.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "1.2.1",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.8.2",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
"node_modules/ansi-regex": {
"version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "Python-2.0"
+ },
"node_modules/async": {
- "version": "0.2.10",
- "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
- "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E="
+ "version": "0.2.10"
},
"node_modules/atom-select-list": {
"version": "0.7.2",
- "resolved": "https://registry.npmjs.org/atom-select-list/-/atom-select-list-0.7.2.tgz",
- "integrity": "sha512-a707OB1DhLGjzqtFrtMQKH7BBxFuCh8UBoUWxgFOrLrSwVh3g+/TlVPVDOz12+U0mDu3mIrnYLqQyhywQOTxhw==",
+ "license": "MIT",
"dependencies": {
"etch": "^0.12.6",
"fuzzaldrin": "^2.1.0"
@@ -49,38 +223,56 @@
},
"node_modules/atom-slick": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/atom-slick/-/atom-slick-2.0.0.tgz",
- "integrity": "sha1-/w2+Fb4sTtomi50w124lF+C308o=",
+ "license": "MIT (http://mootools.net/license.txt)",
"engines": {
"node": "*"
}
},
"node_modules/balanced-match": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ "license": "MIT"
},
"node_modules/brace-expansion": {
"version": "1.1.8",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
- "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/camelcase": {
"version": "2.1.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
- "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
"node_modules/cliui": {
"version": "3.2.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
- "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "license": "ISC",
"dependencies": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1",
@@ -89,17 +281,14 @@
},
"node_modules/code-point-at": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
- "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/coffee-script": {
"version": "1.12.7",
- "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz",
- "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==",
- "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)",
+ "license": "MIT",
"bin": {
"cake": "bin/cake",
"coffee": "bin/coffee"
@@ -108,84 +297,94 @@
"node": ">=0.8.0"
}
},
- "node_modules/coffeelint": {
- "version": "1.16.0",
- "resolved": "https://registry.npmjs.org/coffeelint/-/coffeelint-1.16.0.tgz",
- "integrity": "sha1-g9jtHa/eOmd95E57ihi+YHdh5tg=",
+ "node_modules/color-convert": {
+ "version": "2.0.1",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "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"
- },
- "bin": {
- "coffeelint": "bin/coffeelint"
+ "color-name": "~1.1.4"
},
"engines": {
- "node": ">=0.8.0",
- "npm": ">=1.3.7"
+ "node": ">=7.0.0"
}
},
- "node_modules/coffeelint/node_modules/coffee-script": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.11.1.tgz",
- "integrity": "sha1-vxxHrWREOg2V0S3ysUfMCk2q1uk=",
- "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)",
+ "node_modules/color-name": {
+ "version": "1.1.4",
"dev": true,
- "bin": {
- "cake": "bin/cake",
- "coffee": "bin/coffee"
- },
- "engines": {
- "node": ">=0.8.0"
- }
+ "license": "MIT"
},
- "node_modules/coffeelint/node_modules/optimist": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
- "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "minimist": "~0.0.1",
- "wordwrap": "~0.0.2"
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
}
},
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
- },
"node_modules/cson-parser": {
"version": "1.3.5",
- "resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz",
- "integrity": "sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ=",
+ "license": "BSD-3-Clause",
"dependencies": {
"coffee-script": "^1.10.0"
}
},
"node_modules/d": {
"version": "0.1.1",
- "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz",
- "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=",
+ "license": "MIT",
"dependencies": {
"es5-ext": "~0.10.2"
}
},
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
"node_modules/decamelize": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/emissary": {
"version": "1.3.3",
- "resolved": "https://registry.npmjs.org/emissary/-/emissary-1.3.3.tgz",
- "integrity": "sha1-phjZLWgrIy0xER3DYlpd9mF5lgY=",
"dependencies": {
"es6-weak-map": "^0.1.2",
"mixto": "1.x",
@@ -195,8 +394,7 @@
},
"node_modules/es5-ext": {
"version": "0.10.30",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz",
- "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=",
+ "license": "MIT",
"dependencies": {
"es6-iterator": "2",
"es6-symbol": "~3.1"
@@ -204,16 +402,14 @@
},
"node_modules/es5-ext/node_modules/d": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
- "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+ "license": "MIT",
"dependencies": {
"es5-ext": "^0.10.9"
}
},
"node_modules/es5-ext/node_modules/es6-iterator": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
- "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=",
+ "license": "MIT",
"dependencies": {
"d": "1",
"es5-ext": "^0.10.14",
@@ -222,8 +418,7 @@
},
"node_modules/es5-ext/node_modules/es6-symbol": {
"version": "3.1.1",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
- "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+ "license": "MIT",
"dependencies": {
"d": "1",
"es5-ext": "~0.10.14"
@@ -231,8 +426,7 @@
},
"node_modules/es6-iterator": {
"version": "0.1.3",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-0.1.3.tgz",
- "integrity": "sha1-1vWLjE/EE8JJtLqhl2j45NfIlE4=",
+ "license": "MIT",
"dependencies": {
"d": "~0.1.1",
"es5-ext": "~0.10.5",
@@ -241,8 +435,7 @@
},
"node_modules/es6-symbol": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-2.0.1.tgz",
- "integrity": "sha1-dhtcZ8/U8dGK+yNPaR1nhoLLO/M=",
+ "license": "MIT",
"dependencies": {
"d": "~0.1.1",
"es5-ext": "~0.10.5"
@@ -250,8 +443,7 @@
},
"node_modules/es6-weak-map": {
"version": "0.1.4",
- "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-0.1.4.tgz",
- "integrity": "sha1-cGzvnpmqI2undmwjnIueKG6n0ig=",
+ "license": "MIT",
"dependencies": {
"d": "~0.1.1",
"es5-ext": "~0.10.6",
@@ -259,23 +451,343 @@
"es6-symbol": "~2.0.1"
}
},
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.33.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint/eslintrc": "^1.4.1",
+ "@humanwhocodes/config-array": "^0.11.8",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "ajv": "^6.10.0",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.1.1",
+ "eslint-utils": "^3.0.0",
+ "eslint-visitor-keys": "^3.3.0",
+ "espree": "^9.4.0",
+ "esquery": "^1.4.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "grapheme-splitter": "^1.0.4",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-sdsl": "^4.1.4",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.1",
+ "regexpp": "^3.2.0",
+ "strip-ansi": "^6.0.1",
+ "strip-json-comments": "^3.1.0",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.1.1",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/eslint-utils": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^2.0.0"
+ },
+ "engines": {
+ "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=5"
+ }
+ },
+ "node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.3.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/eslint/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint/node_modules/ignore": {
+ "version": "5.2.4",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/eslint/node_modules/minimatch": {
+ "version": "3.1.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/eslint/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint/node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.4.1",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.8.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.4.0",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/etch": {
"version": "0.12.8",
- "resolved": "https://registry.npmjs.org/etch/-/etch-0.12.8.tgz",
- "integrity": "sha512-dFLRe4wLroVtwzyy1vGlE3BSDZHiL0kZME5XgNGzZIULcYTvVno8vbiIleAesoKJmwWaxDTzG+4eppg2zk14JQ=="
+ "license": "MIT"
},
"node_modules/event-kit": {
"version": "1.5.0",
- "resolved": "https://registry.npmjs.org/event-kit/-/event-kit-1.5.0.tgz",
- "integrity": "sha1-Ek72qtgyjcsmtxxHWQtbjmPrxIc=",
"dependencies": {
"grim": "^1.2.1"
}
},
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.15.0",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.0.4",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.1.0",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flat-cache/node_modules/glob": {
+ "version": "7.2.3",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/flat-cache/node_modules/minimatch": {
+ "version": "3.1.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/flat-cache/node_modules/rimraf": {
+ "version": "3.0.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.2.7",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/fs-plus": {
"version": "3.0.1",
- "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.0.1.tgz",
- "integrity": "sha1-VMFpxA4ohKZtNSeA0Y3TH5HToQ0=",
+ "license": "MIT",
"dependencies": {
"async": "^1.5.2",
"mkdirp": "^0.5.1",
@@ -285,23 +797,18 @@
},
"node_modules/fs-plus/node_modules/async": {
"version": "1.5.2",
- "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
- "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+ "license": "MIT"
},
"node_modules/fs.realpath": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ "license": "ISC"
},
"node_modules/fuzzaldrin": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz",
- "integrity": "sha1-kCBMPi/appQbso0WZF1BgGOpDps="
+ "version": "2.1.0"
},
"node_modules/glob": {
"version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=",
+ "license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -314,24 +821,76 @@
"node": "*"
}
},
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "13.20.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/grapheme-splitter": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/grim": {
"version": "1.5.0",
- "resolved": "https://registry.npmjs.org/grim/-/grim-1.5.0.tgz",
- "integrity": "sha1-sysI71Z88YUvgXWe2caLDXE5ajI=",
"dependencies": {
"emissary": "^1.2.0"
}
},
- "node_modules/ignore": {
- "version": "3.3.5",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz",
- "integrity": "sha1-xOcVRV9gc6jX5drnLS/J1xZj26Y=",
- "dev": true
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
},
"node_modules/inflight": {
"version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "license": "ISC",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@@ -339,53 +898,138 @@
},
"node_modules/inherits": {
"version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ "license": "ISC"
},
"node_modules/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=",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "number-is-nan": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/js-sdsl": {
+ "version": "4.3.0",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/js-sdsl"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/key-path-helpers": {
+ "version": "0.1.0"
+ },
+ "node_modules/lcid": {
+ "version": "1.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "invert-kv": "^1.0.0"
+ },
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "number-is-nan": "^1.0.0"
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.8.0"
}
},
- "node_modules/key-path-helpers": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/key-path-helpers/-/key-path-helpers-0.1.0.tgz",
- "integrity": "sha1-zYFJULeZzHRaNGqlIfkilK9du6Q="
- },
- "node_modules/lcid": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
- "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "invert-kv": "^1.0.0"
+ "p-locate": "^5.0.0"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/loophole": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/loophole/-/loophole-1.1.0.tgz",
- "integrity": "sha1-N5Sf6kU7YlasxyXDIM4MWn9wor0="
+ "license": "MIT"
},
"node_modules/minimatch": {
"version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -395,19 +1039,14 @@
},
"node_modules/minimist": {
"version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ "license": "MIT"
},
"node_modules/mixto": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/mixto/-/mixto-1.0.0.tgz",
- "integrity": "sha1-wyDvYbUvKJj1IuF9i7xtUG2EJbY="
+ "version": "1.0.0"
},
"node_modules/mkdirp": {
"version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
- "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
+ "license": "MIT",
"dependencies": {
"minimist": "0.0.8"
},
@@ -415,26 +1054,49 @@
"mkdirp": "bin/cmd.js"
}
},
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/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=",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/once": {
"version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "license": "ISC",
"dependencies": {
"wrappy": "1"
}
},
+ "node_modules/optionator": {
+ "version": "0.9.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
"node_modules/os-locale": {
"version": "1.4.0",
- "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
- "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "license": "MIT",
"dependencies": {
"lcid": "^1.0.0"
},
@@ -444,24 +1106,75 @@
},
"node_modules/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=",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/path-is-absolute": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/pegjs": {
"version": "0.8.0",
- "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.8.0.tgz",
- "integrity": "sha1-l28GfaE+XFsVAcAXklZoolOBFWE=",
"bin": {
"pegjs": "bin/pegjs"
},
@@ -469,25 +1182,79 @@
"node": ">= 0.8"
}
},
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
"node_modules/property-accessors": {
"version": "1.1.3",
- "resolved": "https://registry.npmjs.org/property-accessors/-/property-accessors-1.1.3.tgz",
- "integrity": "sha1-Hd6EAkYxhlkJ7zBwM2VoDF+SixU=",
"dependencies": {
"es6-weak-map": "^0.1.2",
"mixto": "1.x"
}
},
- "node_modules/resolve": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-0.6.3.tgz",
- "integrity": "sha1-3ZV5gufnNt699TtYpN2RdUV13UY=",
- "dev": true
+ "node_modules/punycode": {
+ "version": "2.3.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/regexpp": {
+ "version": "3.2.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
},
"node_modules/rimraf": {
"version": "2.6.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
- "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=",
+ "license": "ISC",
"dependencies": {
"glob": "^7.0.5"
},
@@ -495,10 +1262,30 @@
"rimraf": "bin.js"
}
},
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
"node_modules/scoped-property-store": {
"version": "0.17.0",
- "resolved": "https://registry.npmjs.org/scoped-property-store/-/scoped-property-store-0.17.0.tgz",
- "integrity": "sha1-raAsANYC/SBQlh4nF92dArozGDE=",
"dependencies": {
"atom-slick": "^2",
"event-kit": "^1.0.0",
@@ -509,8 +1296,6 @@
},
"node_modules/season": {
"version": "6.0.2",
- "resolved": "https://registry.npmjs.org/season/-/season-6.0.2.tgz",
- "integrity": "sha1-naWPsd3SSCTXYhstxjpxI7UCF7Y=",
"dependencies": {
"cson-parser": "^1.3.0",
"fs-plus": "^3.0.0",
@@ -520,10 +1305,28 @@
"csonc": "bin/csonc"
}
},
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/string-width": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "license": "MIT",
"dependencies": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -535,8 +1338,7 @@
},
"node_modules/strip-ansi": {
"version": "3.0.1",
- "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "license": "MIT",
"dependencies": {
"ansi-regex": "^2.0.0"
},
@@ -544,25 +1346,23 @@
"node": ">=0.10.0"
}
},
- "node_modules/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=",
+ "node_modules/supports-color": {
+ "version": "7.2.0",
"dev": true,
- "bin": {
- "strip-json-comments": "cli.js"
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
},
"engines": {
- "node": ">=0.8.0"
+ "node": ">=8"
}
},
"node_modules/temp": {
"version": "0.8.3",
- "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
- "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=",
"engines": [
"node >=0.8.0"
],
+ "license": "MIT",
"dependencies": {
"os-tmpdir": "^1.0.0",
"rimraf": "~2.2.6"
@@ -570,29 +1370,72 @@
},
"node_modules/temp/node_modules/rimraf": {
"version": "2.2.8",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
- "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
+ "license": "MIT",
"bin": {
"rimraf": "bin.js"
}
},
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/underscore": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz",
- "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag="
+ "version": "1.6.0"
},
"node_modules/underscore-plus": {
"version": "1.6.6",
- "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.6.6.tgz",
- "integrity": "sha1-ZezeG9xEGjXYnmUP1w3PE65Dmn0=",
"dependencies": {
"underscore": "~1.6.0"
}
},
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/window-size": {
"version": "0.1.4",
- "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
- "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=",
+ "license": "MIT",
"bin": {
"window-size": "cli.js"
},
@@ -600,19 +1443,17 @@
"node": ">= 0.10.0"
}
},
- "node_modules/wordwrap": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
- "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+ "node_modules/word-wrap": {
+ "version": "1.2.3",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=0.4.0"
+ "node": ">=0.10.0"
}
},
"node_modules/wrap-ansi": {
"version": "2.1.0",
- "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
- "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "license": "MIT",
"dependencies": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1"
@@ -623,18 +1464,15 @@
},
"node_modules/wrappy": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ "license": "ISC"
},
"node_modules/y18n": {
"version": "3.2.1",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
- "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
+ "license": "ISC"
},
"node_modules/yargs": {
"version": "3.32.0",
- "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
- "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
+ "license": "MIT",
"dependencies": {
"camelcase": "^2.0.1",
"cliui": "^3.0.3",
@@ -644,56 +1482,171 @@
"window-size": "^0.1.4",
"y18n": "^3.2.0"
}
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
}
},
"dependencies": {
+ "@eslint/eslintrc": {
+ "version": "1.4.1",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.4.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "dependencies": {
+ "ignore": {
+ "version": "5.2.4",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "dev": true
+ }
+ }
+ },
+ "@humanwhocodes/config-array": {
+ "version": "0.11.8",
+ "dev": true,
+ "requires": {
+ "@humanwhocodes/object-schema": "^1.2.1",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.5"
+ },
+ "dependencies": {
+ "minimatch": {
+ "version": "3.1.2",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ }
+ }
+ },
+ "@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "dev": true
+ },
+ "@humanwhocodes/object-schema": {
+ "version": "1.2.1",
+ "dev": true
+ },
+ "@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "dev": true
+ },
+ "@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ }
+ },
+ "acorn": {
+ "version": "8.8.2",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "5.3.2",
+ "dev": true,
+ "requires": {}
+ },
+ "ajv": {
+ "version": "6.12.6",
+ "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"
+ }
+ },
"ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ "version": "2.1.1"
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "argparse": {
+ "version": "2.0.1",
+ "dev": true
},
"async": {
- "version": "0.2.10",
- "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
- "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E="
+ "version": "0.2.10"
},
"atom-select-list": {
"version": "0.7.2",
- "resolved": "https://registry.npmjs.org/atom-select-list/-/atom-select-list-0.7.2.tgz",
- "integrity": "sha512-a707OB1DhLGjzqtFrtMQKH7BBxFuCh8UBoUWxgFOrLrSwVh3g+/TlVPVDOz12+U0mDu3mIrnYLqQyhywQOTxhw==",
"requires": {
"etch": "^0.12.6",
"fuzzaldrin": "^2.1.0"
}
},
"atom-slick": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/atom-slick/-/atom-slick-2.0.0.tgz",
- "integrity": "sha1-/w2+Fb4sTtomi50w124lF+C308o="
+ "version": "2.0.0"
},
"balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ "version": "1.0.0"
},
"brace-expansion": {
"version": "1.1.8",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
- "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
+ "callsites": {
+ "version": "3.1.0",
+ "dev": true
+ },
"camelcase": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
- "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
+ "version": "2.1.1"
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
},
"cliui": {
"version": "3.2.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
- "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
"requires": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1",
@@ -701,77 +1654,69 @@
}
},
"code-point-at": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
- "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+ "version": "1.1.0"
},
"coffee-script": {
- "version": "1.12.7",
- "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz",
- "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw=="
+ "version": "1.12.7"
},
- "coffeelint": {
- "version": "1.16.0",
- "resolved": "https://registry.npmjs.org/coffeelint/-/coffeelint-1.16.0.tgz",
- "integrity": "sha1-g9jtHa/eOmd95E57ihi+YHdh5tg=",
+ "color-convert": {
+ "version": "2.0.1",
"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"
- },
- "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=",
- "dev": true,
- "requires": {
- "minimist": "~0.0.1",
- "wordwrap": "~0.0.2"
- }
- }
+ "color-name": "~1.1.4"
}
},
+ "color-name": {
+ "version": "1.1.4",
+ "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="
+ "version": "0.0.1"
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
},
"cson-parser": {
"version": "1.3.5",
- "resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz",
- "integrity": "sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ=",
"requires": {
"coffee-script": "^1.10.0"
}
},
"d": {
"version": "0.1.1",
- "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz",
- "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=",
"requires": {
"es5-ext": "~0.10.2"
}
},
+ "debug": {
+ "version": "4.3.4",
+ "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="
+ "version": "1.2.0"
+ },
+ "deep-is": {
+ "version": "0.1.4",
+ "dev": true
+ },
+ "doctrine": {
+ "version": "3.0.0",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
},
"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",
@@ -781,8 +1726,6 @@
},
"es5-ext": {
"version": "0.10.30",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz",
- "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=",
"requires": {
"es6-iterator": "2",
"es6-symbol": "~3.1"
@@ -790,16 +1733,12 @@
"dependencies": {
"d": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
- "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
"requires": {
"es5-ext": "^0.10.9"
}
},
"es6-iterator": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
- "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=",
"requires": {
"d": "1",
"es5-ext": "^0.10.14",
@@ -808,8 +1747,6 @@
},
"es6-symbol": {
"version": "3.1.1",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
- "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
"requires": {
"d": "1",
"es5-ext": "~0.10.14"
@@ -819,8 +1756,6 @@
},
"es6-iterator": {
"version": "0.1.3",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-0.1.3.tgz",
- "integrity": "sha1-1vWLjE/EE8JJtLqhl2j45NfIlE4=",
"requires": {
"d": "~0.1.1",
"es5-ext": "~0.10.5",
@@ -829,8 +1764,6 @@
},
"es6-symbol": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-2.0.1.tgz",
- "integrity": "sha1-dhtcZ8/U8dGK+yNPaR1nhoLLO/M=",
"requires": {
"d": "~0.1.1",
"es5-ext": "~0.10.5"
@@ -838,8 +1771,6 @@
},
"es6-weak-map": {
"version": "0.1.4",
- "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-0.1.4.tgz",
- "integrity": "sha1-cGzvnpmqI2undmwjnIueKG6n0ig=",
"requires": {
"d": "~0.1.1",
"es5-ext": "~0.10.6",
@@ -847,23 +1778,224 @@
"es6-symbol": "~2.0.1"
}
},
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "dev": true
+ },
+ "eslint": {
+ "version": "8.33.0",
+ "dev": true,
+ "requires": {
+ "@eslint/eslintrc": "^1.4.1",
+ "@humanwhocodes/config-array": "^0.11.8",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "ajv": "^6.10.0",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.1.1",
+ "eslint-utils": "^3.0.0",
+ "eslint-visitor-keys": "^3.3.0",
+ "espree": "^9.4.0",
+ "esquery": "^1.4.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "grapheme-splitter": "^1.0.4",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-sdsl": "^4.1.4",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.1",
+ "regexpp": "^3.2.0",
+ "strip-ansi": "^6.0.1",
+ "strip-json-comments": "^3.1.0",
+ "text-table": "^0.2.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "5.0.1",
+ "dev": true
+ },
+ "ignore": {
+ "version": "5.2.4",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "dev": true
+ }
+ }
+ },
+ "eslint-scope": {
+ "version": "7.1.1",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ }
+ },
+ "eslint-utils": {
+ "version": "3.0.0",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^2.0.0"
+ },
+ "dependencies": {
+ "eslint-visitor-keys": {
+ "version": "2.1.0",
+ "dev": true
+ }
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "3.3.0",
+ "dev": true
+ },
+ "espree": {
+ "version": "9.4.1",
+ "dev": true,
+ "requires": {
+ "acorn": "^8.8.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.3.0"
+ }
+ },
+ "esquery": {
+ "version": "1.4.0",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.1.0"
+ }
+ },
+ "esrecurse": {
+ "version": "4.3.0",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.2.0"
+ }
+ },
+ "estraverse": {
+ "version": "5.3.0",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "dev": true
+ },
"etch": {
- "version": "0.12.8",
- "resolved": "https://registry.npmjs.org/etch/-/etch-0.12.8.tgz",
- "integrity": "sha512-dFLRe4wLroVtwzyy1vGlE3BSDZHiL0kZME5XgNGzZIULcYTvVno8vbiIleAesoKJmwWaxDTzG+4eppg2zk14JQ=="
+ "version": "0.12.8"
},
"event-kit": {
"version": "1.5.0",
- "resolved": "https://registry.npmjs.org/event-kit/-/event-kit-1.5.0.tgz",
- "integrity": "sha1-Ek72qtgyjcsmtxxHWQtbjmPrxIc=",
"requires": {
"grim": "^1.2.1"
}
},
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "dev": true
+ },
+ "fastq": {
+ "version": "1.15.0",
+ "dev": true,
+ "requires": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "file-entry-cache": {
+ "version": "6.0.1",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^3.0.4"
+ }
+ },
+ "find-up": {
+ "version": "5.0.0",
+ "dev": true,
+ "requires": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "flat-cache": {
+ "version": "3.0.4",
+ "dev": true,
+ "requires": {
+ "flatted": "^3.1.0",
+ "rimraf": "^3.0.2"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.2.3",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "flatted": {
+ "version": "3.2.7",
+ "dev": true
+ },
"fs-plus": {
"version": "3.0.1",
- "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.0.1.tgz",
- "integrity": "sha1-VMFpxA4ohKZtNSeA0Y3TH5HToQ0=",
"requires": {
"async": "^1.5.2",
"mkdirp": "^0.5.1",
@@ -872,26 +2004,18 @@
},
"dependencies": {
"async": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
- "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+ "version": "1.5.2"
}
}
},
"fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ "version": "1.0.0"
},
"fuzzaldrin": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz",
- "integrity": "sha1-kCBMPi/appQbso0WZF1BgGOpDps="
+ "version": "2.1.0"
},
"glob": {
"version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -901,154 +2025,271 @@
"path-is-absolute": "^1.0.0"
}
},
+ "glob-parent": {
+ "version": "6.0.2",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.3"
+ }
+ },
+ "globals": {
+ "version": "13.20.0",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.20.2"
+ }
+ },
+ "grapheme-splitter": {
+ "version": "1.0.4",
+ "dev": true
+ },
"grim": {
"version": "1.5.0",
- "resolved": "https://registry.npmjs.org/grim/-/grim-1.5.0.tgz",
- "integrity": "sha1-sysI71Z88YUvgXWe2caLDXE5ajI=",
"requires": {
"emissary": "^1.2.0"
}
},
- "ignore": {
- "version": "3.3.5",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz",
- "integrity": "sha1-xOcVRV9gc6jX5drnLS/J1xZj26Y=",
+ "has-flag": {
+ "version": "4.0.0",
+ "dev": true
+ },
+ "import-fresh": {
+ "version": "3.3.0",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
"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": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ "version": "2.0.3"
},
"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="
+ "version": "1.0.0"
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "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",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"requires": {
"number-is-nan": "^1.0.0"
}
},
+ "is-glob": {
+ "version": "4.0.3",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-path-inside": {
+ "version": "3.0.3",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "dev": true
+ },
+ "js-sdsl": {
+ "version": "4.3.0",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "4.1.0",
+ "dev": true,
+ "requires": {
+ "argparse": "^2.0.1"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "dev": true
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "dev": true
+ },
"key-path-helpers": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/key-path-helpers/-/key-path-helpers-0.1.0.tgz",
- "integrity": "sha1-zYFJULeZzHRaNGqlIfkilK9du6Q="
+ "version": "0.1.0"
},
"lcid": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
- "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
"requires": {
"invert-kv": "^1.0.0"
}
},
+ "levn": {
+ "version": "0.4.1",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ }
+ },
+ "locate-path": {
+ "version": "6.0.0",
+ "dev": true,
+ "requires": {
+ "p-locate": "^5.0.0"
+ }
+ },
+ "lodash.merge": {
+ "version": "4.6.2",
+ "dev": true
+ },
"loophole": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/loophole/-/loophole-1.1.0.tgz",
- "integrity": "sha1-N5Sf6kU7YlasxyXDIM4MWn9wor0="
+ "version": "1.1.0"
},
"minimatch": {
"version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
"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="
+ "version": "0.0.8"
},
"mixto": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/mixto/-/mixto-1.0.0.tgz",
- "integrity": "sha1-wyDvYbUvKJj1IuF9i7xtUG2EJbY="
+ "version": "1.0.0"
},
"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"
}
},
+ "ms": {
+ "version": "2.1.2",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "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="
+ "version": "1.0.1"
},
"once": {
"version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
+ "optionator": {
+ "version": "0.9.1",
+ "dev": true,
+ "requires": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.3"
+ }
+ },
"os-locale": {
"version": "1.4.0",
- "resolved": "http://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="
+ "version": "1.0.2"
},
- "path-is-absolute": {
+ "p-limit": {
+ "version": "3.1.0",
+ "dev": true,
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "5.0.0",
+ "dev": true,
+ "requires": {
+ "p-limit": "^3.0.2"
+ }
+ },
+ "parent-module": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0"
+ }
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1"
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "dev": true
},
"pegjs": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.8.0.tgz",
- "integrity": "sha1-l28GfaE+XFsVAcAXklZoolOBFWE="
+ "version": "0.8.0"
+ },
+ "prelude-ls": {
+ "version": "1.2.1",
+ "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"
}
},
- "resolve": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-0.6.3.tgz",
- "integrity": "sha1-3ZV5gufnNt699TtYpN2RdUV13UY=",
+ "punycode": {
+ "version": "2.3.0",
+ "dev": true
+ },
+ "queue-microtask": {
+ "version": "1.2.3",
+ "dev": true
+ },
+ "regexpp": {
+ "version": "3.2.0",
+ "dev": true
+ },
+ "resolve-from": {
+ "version": "4.0.0",
+ "dev": true
+ },
+ "reusify": {
+ "version": "1.0.4",
"dev": true
},
"rimraf": {
"version": "2.6.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
- "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=",
"requires": {
"glob": "^7.0.5"
}
},
+ "run-parallel": {
+ "version": "1.2.0",
+ "dev": true,
+ "requires": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
"scoped-property-store": {
"version": "0.17.0",
- "resolved": "https://registry.npmjs.org/scoped-property-store/-/scoped-property-store-0.17.0.tgz",
- "integrity": "sha1-raAsANYC/SBQlh4nF92dArozGDE=",
"requires": {
"atom-slick": "^2",
"event-kit": "^1.0.0",
@@ -1059,18 +2300,25 @@
},
"season": {
"version": "6.0.2",
- "resolved": "https://registry.npmjs.org/season/-/season-6.0.2.tgz",
- "integrity": "sha1-naWPsd3SSCTXYhstxjpxI7UCF7Y=",
"requires": {
"cson-parser": "^1.3.0",
"fs-plus": "^3.0.0",
"yargs": "^3.23.0"
}
},
+ "shebang-command": {
+ "version": "2.0.0",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "dev": true
+ },
"string-width": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -1079,81 +2327,89 @@
},
"strip-ansi": {
"version": "3.0.1",
- "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "^2.0.0"
}
},
- "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=",
- "dev": true
+ "supports-color": {
+ "version": "7.2.0",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
},
"temp": {
"version": "0.8.3",
- "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
- "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=",
"requires": {
"os-tmpdir": "^1.0.0",
"rimraf": "~2.2.6"
},
"dependencies": {
"rimraf": {
- "version": "2.2.8",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
- "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI="
+ "version": "2.2.8"
}
}
},
+ "text-table": {
+ "version": "0.2.0",
+ "dev": true
+ },
+ "type-check": {
+ "version": "0.4.0",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "^1.2.1"
+ }
+ },
+ "type-fest": {
+ "version": "0.20.2",
+ "dev": true
+ },
"underscore": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz",
- "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag="
+ "version": "1.6.0"
},
"underscore-plus": {
"version": "1.6.6",
- "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.6.6.tgz",
- "integrity": "sha1-ZezeG9xEGjXYnmUP1w3PE65Dmn0=",
"requires": {
"underscore": "~1.6.0"
}
},
+ "uri-js": {
+ "version": "4.4.1",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
"window-size": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
- "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY="
+ "version": "0.1.4"
},
- "wordwrap": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
- "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+ "word-wrap": {
+ "version": "1.2.3",
"dev": true
},
"wrap-ansi": {
"version": "2.1.0",
- "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
- "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"requires": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1"
}
},
"wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ "version": "1.0.2"
},
"y18n": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
- "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
+ "version": "3.2.1"
},
"yargs": {
"version": "3.32.0",
- "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
- "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
"requires": {
"camelcase": "^2.0.1",
"cliui": "^3.0.3",
@@ -1163,6 +2419,10 @@
"window-size": "^0.1.4",
"y18n": "^3.2.0"
}
+ },
+ "yocto-queue": {
+ "version": "0.1.0",
+ "dev": true
}
}
}
diff --git a/package.json b/package.json
index d70b5c75..cbd9d429 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,6 @@
}
},
"devDependencies": {
- "coffeelint": "^1.9.7"
+ "eslint": "^8.33.0"
}
}
diff --git a/spec/.eslintrc b/spec/.eslintrc
new file mode 100644
index 00000000..65bf2aac
--- /dev/null
+++ b/spec/.eslintrc
@@ -0,0 +1,5 @@
+{
+ "rules": {
+ "semi": ["error", "always"]
+ }
+}
diff --git a/spec/fixtures/package-with-snippets/snippets/test.cson b/spec/fixtures/package-with-snippets/snippets/test.cson
index 1fe2e0ae..cb28534a 100644
--- a/spec/fixtures/package-with-snippets/snippets/test.cson
+++ b/spec/fixtures/package-with-snippets/snippets/test.cson
@@ -20,9 +20,12 @@
".package-with-snippets-unique-scope":
"Test Snippet":
prefix: "test"
- body: "testing 123"
+ body: "testing 123"
".source.js":
"Overrides a core package's snippet":
prefix: "log"
body: "from-a-community-package"
+ "Maps to a command":
+ body: 'lorem ipsum $0 dolor sit amet'
+ command: 'test-command-name'
diff --git a/spec/snippet-loading-spec.js b/spec/snippet-loading-spec.js
index 05544e94..c04d5358 100644
--- a/spec/snippet-loading-spec.js
+++ b/spec/snippet-loading-spec.js
@@ -81,6 +81,24 @@ describe("Snippet Loading", () => {
});
});
+ it("registers a command if a package snippet defines one", () => {
+ waitsForPromise(() => {
+ return atom.packages.activatePackage("snippets").then(
+ ({mainModule}) => {
+ return new Promise((resolve) => {
+ mainModule.onDidLoadSnippets(resolve);
+ });
+ }
+ );
+ });
+
+ runs(() => {
+ expect(
+ 'package-with-snippets:test-command-name' in atom.commands.registeredCommands
+ ).toBe(true);
+ });
+ });
+
it("logs a warning if package snippets files cannot be parsed", () => {
activateSnippetsPackage();
@@ -93,10 +111,10 @@ describe("Snippet Loading", () => {
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.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", () => {
@@ -126,7 +144,7 @@ describe("Snippet Loading", () => {
describe("when ~/.atom/snippets.json exists", () => {
beforeEach(() => {
- fs.mkdirSync(configDirPath, { recursive: true });
+ fs.mkdirSync(configDirPath, {recursive: true});
fs.writeFileSync(path.join(configDirPath, 'snippets.json'), `\
{
".foo": {
@@ -155,7 +173,7 @@ describe("Snippet Loading", () => {
describe("when that file changes", () => {
it("reloads the snippets", () => {
- fs.mkdirSync(configDirPath, { recursive: true });
+ fs.mkdirSync(configDirPath, {recursive: true});
fs.writeFileSync(path.join(configDirPath, 'snippets.json'), `\
{
".foo": {
@@ -174,7 +192,7 @@ describe("Snippet Loading", () => {
});
runs(() => {
- fs.mkdirSync(configDirPath, { recursive: true });
+ fs.mkdirSync(configDirPath, {recursive: true});
fs.writeFileSync(path.join(configDirPath, 'snippets.json'), "");
});
@@ -185,7 +203,7 @@ describe("Snippet Loading", () => {
describe("when ~/.atom/snippets.cson exists", () => {
beforeEach(() => {
- fs.mkdirSync(configDirPath, { recursive: true });
+ fs.mkdirSync(configDirPath, {recursive: true});
fs.writeFileSync(path.join(configDirPath, 'snippets.cson'), `\
".foo":
"foo snippet":
@@ -210,7 +228,7 @@ describe("Snippet Loading", () => {
describe("when that file changes", () => {
it("reloads the snippets", () => {
- fs.mkdirSync(configDirPath, { recursive: true });
+ fs.mkdirSync(configDirPath, {recursive: true});
fs.writeFileSync(path.join(configDirPath, 'snippets.cson'), `\
".foo":
"foo snippet":
@@ -225,7 +243,7 @@ describe("Snippet Loading", () => {
});
runs(() => {
- fs.mkdirSync(configDirPath, { recursive: true });
+ fs.mkdirSync(configDirPath, {recursive: true});
fs.writeFileSync(path.join(configDirPath, 'snippets.cson'), "");
});
diff --git a/spec/snippets-spec.js b/spec/snippets-spec.js
index ba9f8d32..d72f9af8 100644
--- a/spec/snippets-spec.js
+++ b/spec/snippets-spec.js
@@ -16,11 +16,13 @@ describe("Snippets extension", () => {
};
beforeEach(() => {
+ if (atom.notifications != null) { spyOn(atom.notifications, 'addError'); }
spyOn(Snippets, 'loadAll');
spyOn(Snippets, 'getUserSnippetsPath').andReturn('');
waitsForPromise(() => atom.workspace.open('sample.js'));
waitsForPromise(() => atom.packages.activatePackage('language-javascript'));
+ waitsForPromise(() => atom.packages.activatePackage('language-html'));
waitsForPromise(() => atom.packages.activatePackage('snippets'));
runs(() => {
@@ -1183,13 +1185,13 @@ foo\
});
});
- describe("when atom://.atom/snippets is opened", () => {
- it("opens ~/.atom/snippets.cson", () => {
+ describe("when atom://.pulsar/snippets is opened", () => {
+ it("opens ~/.pulsar/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');
+ atom.workspace.open('atom://.pulsar/snippets');
waitsFor(() => atom.workspace.getActiveTextEditor() != null);
@@ -1209,10 +1211,128 @@ foo\
});
});
+ describe("when a user snippet maps to a command", () => {
+ beforeEach(() => {
+ editor.setText('');
+ Snippets.add(
+ __filename, {
+ ".source.js": {
+ "some command snippet": {
+ body: "lorem ipsum dolor $1 sit ${2:amet}$0",
+ command: "some-command-snippet"
+ },
+ "another command snippet with a prefix": {
+ prefix: 'prfx',
+ command: 'command-with-prefix',
+ body: 'this had $0 a prefix'
+ },
+ "another snippet with neither command nor prefix": {
+ body: 'useless'
+ },
+ "another snippet with a malformed command name": {
+ command: 'i flout the RULES',
+ body: 'inconsiderate'
+ }
+ },
+ ".source.python": {
+ "some python command snippet": {
+ body: "consecuetur $0 adipiscing",
+ command: "some-python-command-snippet"
+ }
+ },
+ ".text.html": {
+ "wrap in tag": {
+ "command": "wrap-in-html-tag",
+ "body": "<${1:div}>$0${1/[ ]+.*$//}>"
+ }
+ }
+ },
+ 'snippets'
+ );
+ });
+
+ afterEach(() => {
+ Snippets.clearSnippetsForPath(__filename);
+ });
+
+ it("registers the command", () => {
+ expect(
+ "snippets:some-command-snippet" in atom.commands.registeredCommands
+ ).toBe(true);
+ });
+
+ it("complains about a malformed command name", () => {
+ const expectedMessage = `Cannot register \`i flout the RULES\` for snippet “another snippet with a malformed command name” because the command name isn’t valid. Command names must be all lowercase and use hyphens between words instead of spaces.`;
+ expect(atom.notifications.addError).toHaveBeenCalledWith(
+ `Snippets error`,
+ {
+ description: expectedMessage,
+ dismissable: true
+ }
+ );
+ });
+
+ describe("and the command is invoked", () => {
+ beforeEach(() => {
+ editor.setText('');
+ });
+
+ it("expands the snippet when the scope matches", () => {
+ atom.commands.dispatch(editor.element, 'snippets:some-command-snippet');
+ let cursor = editor.getLastCursor();
+ let pos = cursor.getBufferPosition();
+ expect(cursor.getBufferPosition()).toEqual([0, 18]);
+
+ expect(editor.getText()).toBe('lorem ipsum dolor sit amet');
+ editor.insertText("virus");
+ expect(editor.getText()).toBe('lorem ipsum dolor virus sit amet');
+
+ simulateTabKeyEvent();
+ expect(editor.getSelectedBufferRange()).toEqual([[0, 28], [0, 32]]);
+ });
+
+ it("expands the snippet even when a prefix is defined", () => {
+ atom.commands.dispatch(editor.element, 'snippets:command-with-prefix');
+ let cursor = editor.getLastCursor();
+ let pos = cursor.getBufferPosition();
+ expect(pos.toArray().join(',')).toBe('0,9');
+ expect(editor.getText()).toBe('this had a prefix');
+ });
+
+ it("does nothing when the scope does not match", () => {
+ atom.commands.dispatch(editor.element, 'snippets:some-python-command-snippet');
+ expect(editor.getText()).toBe("");
+ });
+
+ });
+
+ describe("and the command is invoked in an HTML document", () => {
+ beforeEach(() => {
+ atom.grammars.assignLanguageMode(editor, 'text.html.basic');
+ editor.setText('');
+ });
+
+ it("expands tab stops correctly", () => {
+ atom.commands.dispatch(editor.element, 'snippets:wrap-in-html-tag');
+ let cursor = editor.getLastCursor();
+ expect(cursor.getBufferPosition()).toEqual([0, 4]);
+ expect(editor.getSelectedText()).toEqual('div');
+
+ editor.insertText("aside class=\"wat\"");
+
+ expect(editor.getText()).toBe("");
+
+ simulateTabKeyEvent();
+ expect(cursor.getBufferPosition()).toEqual([0, 19]);
+ });
+ });
+ });
+
describe("when the 'snippets:available' command is triggered", () => {
let availableSnippetsView = null;
beforeEach(() => {
+ atom.grammars.assignLanguageMode(editor, 'source.js');
Snippets.add(__filename, {
".source.js": {
"test": {
@@ -1225,8 +1345,7 @@ foo\
body: "$1: ${2:To pass this challenge}"
}
}
- }
- );
+ });
delete Snippets.availableSnippetsView;