Skip to content
This repository was archived by the owner on Jan 8, 2025. It is now read-only.

Add command property that registers a command name for a snippet #10

Merged
merged 11 commits into from
Feb 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.pegjs
13 changes: 13 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -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"]
}
}
18 changes: 12 additions & 6 deletions .github/workflows/pulsar_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,46 @@ 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'
```

The outermost keys are the selectors where these snippets should be active, prefixed with a period (`.`) (details below).

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 <kbd>tab</kbd> once a snippet has been triggered.
`$` followed by a number are the tabs stops which can be cycled between by pressing <kbd>Tab</kbd> 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");
```

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 <kbd>Tab</kbd>. In this example, typing `log` (as its own word) and then pressing <kbd>Tab</kbd> 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.
Expand Down
5 changes: 4 additions & 1 deletion lib/editor-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
6 changes: 3 additions & 3 deletions lib/snippet-expansion.js
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)
}
Expand Down
14 changes: 12 additions & 2 deletions lib/snippet.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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,
Expand Down
Loading