Reputation: 14074
I'd like to use Ctrl+Shift+C to paste a basic output syntax relevant to the type of file I'm in.
console.log('');
console.log();
for .vue
, .js
or .html
, and
writeDump();
abort;
for .cfc
(also I want this to happen on Ctrl+Shift+W).
Here's the code I have so far:
{ "keys": ["ctrl+shift+c"],
"command": "insert_snippet",
"args": {
"contents": "console.log(`${1:}$SELECTION`);\nconsole.log(${1:}$SELECTION);\n${0}"
}, "context":
[
{
"key": "selector",
"operator": "equal",
"operand": ["source.js","source.html"],
"match_all": true
}
]
},
{ "keys": ["ctrl+shift+c"],
"command": "insert_snippet",
"args": {
"contents": "console.log(`${1:}$SELECTION`);\nconsole.log(${1:}$SELECTION);\n${0}"
}, "context":
[
{
"key": "selector",
"operator": "equal",
"operand": "source.vue",
"match_all": true
}
]
},
{ "keys": ["ctrl+shift+w","ctrl+shift+c"],
"command": "insert_snippet",
"args": {
"contents": "writeDump(${1:}$SELECTION\"$2);\nabort;\n${0}"
}, "context":
[
{
"key": "selector",
"operator": "equal",
"operand": "source.cfc",
"match_all": true
}
]
},
However Ctrl+Shift+C always puts console.log
, regardless of the file type, and Ctrl+Shift+W closes the current sublime window - meaning it's not being overwritten at all.
Upvotes: 0
Views: 127
Reputation: 14074
@OdatNurd's amazing answer explained a lot of the inner-workings of key bindings, and put me on the right track, but I wanted to post my final solution without hijacking his post, and not in the comments because the code is too verbose to be readable there.
I have tested all of the functionality and this works as expected:
{
"keys": ["ctrl+shift+c"],
"command": "insert_snippet",
"args": {
"contents":
"console.log(`${1:}$SELECTION`);\nconsole.log(${1:}$SELECTION);\n${0}"
}
},
{
"keys": ["ctrl+shift+c"],
"command": "insert_snippet",
"args": {
"contents":
"console.log(`${1:}$SELECTION`);\nconsole.log(${1:}$SELECTION);\n${0}"
},
"context": [
{
"key": "selector",
"operator": "equal",
"operand": "text.html.vue",
"match_all": true
}
]
},
{
"keys": ["ctrl+shift+w"],
"command": "insert_snippet",
"args": {
"contents": "writeDump(${1:}$SELECTION\"$2);\nabort;\n${0}"
}
},
{
"keys": ["ctrl+shift+c"],
"command": "insert_snippet",
"args": {
"contents": "writeDump(${1:}$SELECTION\"$2);\nabort;\n${0}"
},
"context": [
{
"key": "selector",
"operator": "equal",
"operand": "embedding.cfml",
"match_all": true
}
]
},
Working backwards, the same way Sublime reads key bindings:
Ctrl+Shift+C for ColdFusion files
writeDump
appear rather than console.log
, but only if the file is related to ColdFusion. Unfortunately, I'm not using CFML files so I wasn't able to figure out a way to distinguish between .cfml and .cfc. The CFML Package for Sublime does not seem to differentiate between the two - at least at the top scope level. If someone figures this out, let us know.Ctrl+Shift+W
writeDump
be written - which is easily undone - than all the windows close - not so easy to undo.Ctrl+Shift+C for Vue files
operand
to match the Scope Name
(Ctrl+Alt+Shift+P), which was text.html.vue
Ctrl+Shift+C for everything else:
console.log
. Now, Ctrl+Shift+C will paste the console.log
snippet in any file that is not specifically defined in key-bindings. This is because Ctrl+Shift+C is not assigned to anything by default.Upvotes: 0
Reputation: 22791
The key bindings in your question are not fully correct in that some scopes are (potentially) invalid and at least the first one has a syntax issue in it that's causing Sublime to ignore the context
in it completely.
The scope for HTML files if you're using the built in syntax for HTML in Sublime is text.html
and not source.html
, which I've reflected in the bindings below. In addition the scopes for Vue and CFC files may also be incorrect. I don't use those languages and so I just installed the first package I found that supports syntax highlighting in those types of files, so you may be using something different than I picked.
To be sure, you can use Tools > Developer > Show Scope Name
from the main menu (or press the associated key) to see the scope at the cursor in any file in a popup. Generally the first line in the popup is the one you want to use to constrain your key bindings to a particular type of file.
Additionally, in each of the (corrected) bindings below, the contents of the snippet have been adjusted slightly so that we can verify that the right thing is inserted at the right time.
{ "keys": ["ctrl+shift+c"],
"command": "insert_snippet",
"args": {
"contents": "console.log(`${1:}$SELECTION`);\nconsole.log(${1:}$SELECTION);\n${0}"
}, "context":
[
{
"key": "selector",
"operator": "equal",
"operand": ["source.js","source.html"],
"match_all": true
}
]
},
This binding is not valid because the operand
in a context
needs to be a string and not a list of strings. As such Sublime thinks that the context is broken and silently ignores it, which makes Ctrl+Shift+C active in every type of file, which is the behaviour you're currently seeing.
It is possible to include multiple scopes in the operand, but you do it as a single string and not as a list. An example of that is the following:
{ "keys": ["ctrl+shift+c"],
"command": "insert_snippet",
"args": {
"contents": "/* js;html */ console.log(`${1:}$SELECTION`);\nconsole.log(${1:}$SELECTION);\n${0}"
}, "context":
[
{
"key": "selector",
"operator": "equal",
"operand": "source.js, text.html",
"match_all": true
}
]
},
Here the operand is two scopes separated by commas, which makes the binding active as long as the scope matches either one of them. Additionally, the scope for HTML has been corrected from source.html
to text.html
.
{ "keys": ["ctrl+shift+c"],
"command": "insert_snippet",
"args": {
"contents": "console.log(`${1:}$SELECTION`);\nconsole.log(${1:}$SELECTION);\n${0}"
}, "context":
[
{
"key": "selector",
"operator": "equal",
"operand": "source.vue",
"match_all": true
}
]
},
This binding is technically valid, but source.vue
may not be the correct scope for this, depending on what syntax definition you're using to provide syntax highlighting for Vue files.
{ "keys": ["ctrl+shift+c"],
"command": "insert_snippet",
"args": {
"contents": "/* vue */ console.log(`${1:}$SELECTION`);\nconsole.log(${1:}$SELECTION);\n${0}"
}, "context":
[
{
"key": "selector",
"operator": "equal",
"operand": "text.html.vue",
"match_all": true
}
]
},
For the Vue syntax highlighting package that I picked, the scope for Vue files is text.html.vue
, which I've reflected here; otherwise everything about this binding is correct.
Note that the scope for HTML is text.html
and the scope for Vue is text.html.vue
. Following the rules of how scopes are matched, text.html.vue
matches the scope text.html
, which has some implications on the bindings depending on what you want to have happen (and assuming that this scope matches the package that you're using).
If you want to inject the same code in Vue as you do in HTML files, you can exclude this binding completely and the one for HTML above will match it and do what you want directly.
On the other hand, if you want to do something specific for Vue, then it's important that this binding come after the HTML binding in your key bindings file. Sublime evaluates key bindings from the bottom of the file up and uses the first one that matches. Since text.html.vue
matches text.html
, you need to have a specific rule for Vue files lower in the file to make sure it gets found and used first.
{ "keys": ["ctrl+shift+w","ctrl+shift+c"],
"command": "insert_snippet",
"args": {
"contents": "writeDump(${1:}$SELECTION\"$2);\nabort;\n${0}"
}, "context":
[
{
"key": "selector",
"operator": "equal",
"operand": "source.cfc",
"match_all": true
}
]
},
Again, except for the scope in this binding being potentially wrong, there's nothing wrong with this binding except that based on your description above, it may not be doing what you expect.
{ "keys": ["ctrl+shift+w","ctrl+shift+c"],
"command": "insert_snippet",
"args": {
"contents": "writeDump(${1:}$SELECTION\"$2);\nabort;\n${0}"
}, "context":
[
{
"key": "selector",
"operator": "equal",
"operand": "embedding.cfml",
"match_all": true
}
]
},
The scope in the CFML package I selected to test with uses embedding.cfml
as the scope, which is reflected here.
Of more importance, using two keys as a list in the binding such as this turns the binding into a key chord. This means that in order to trigger this, you need to press Ctrl+Shift+W followed by Ctrl+Shift+c.
It sounds from the description in your question that you might want two distinct key bindings that both do the same thing. If that's the case then you need to duplicate the entire binding and change the key in the second one.
Upvotes: 1