How do I create a snippet that inserts \{\} using escape characters? - sublimetext3

I am trying to create a snippet in sublime text that when I press ctrl+shift+[ it inserts the snippet \{\}, but I am having trouble working out how to use escape characters to do it.
Here is what I have:
{
"keys": ["ctrl+shift+["],
"command": "insert_snippet",
"args": {
"contents": "\\{\\}"
}
}
but when I use the keyboard shortcut, it only inserts {} without the backslashes! It is strange because when I change it to just "\\" then the output is \, but when something comes after the two backslashes, it ignores the backslash.
I have found a work around of sorts using the ChainOfCommand package that inserts each character separately like this:
{
"keys": ["ctrl+shift+["],
"command": "chain",
"args": {
"commands": [
["insert_snippet", {"contents": "\\"}],
["insert_snippet", {"contents": "{"}],
["insert_snippet", {"contents": "\\"}],
["insert_snippet", {"contents": "}"}]
]
}
}
but the problem with that is that if I then do a ctrl-z undo, it will remove each character one at a time, instead of removing the whole snippet, which is annoying. Also, its just the principle of the thing, I should be able to do it in one snippet I am sure!
Does anyone have any idea how I can make it work?

As un-intuitive as it may seem, using the following keybinding will insert \{\}:
{
"keys": ["ctrl+shift+["],
"command": "insert_snippet",
"args": {
"contents": "\\\\{\\\\}"
}
},
The reason for this is explained at: https://github.com/SublimeTextIssues/Core/issues/1878#issuecomment-328133400:
Due to compatibility with TextMate snippets, the following characters must be escaped to be literal:
\, $, {, }
Any other \{CHAR} will be produced verbatim. This explains why a single backslash is fine, but two become a single.
In case it helps, you can also execute the following in the ST console to see the difference that the JSON extra-escaping makes (compared to, for example, the same content inside a .sublime-snippet file):
view.run_command('insert_snippet', { 'contents': r'\\{\\}' })

Related

Keybinding alt+up won't work in Sublime Text 3

I want to copy the Move Line Up/Down keyboard shortcut of VS Code to Sublime Text 3 which uses Ctrl+Up/Ctrl+Down key bindings, so I placed the following in the User-defined key-bindings file:
[
{
"keys": ["alt+up"], "command": "swap_line_up",
"keys": ["alt+down"], "command": "swap_line_down"
}
]
The swap_line_down works but the swap_line_up doesn't. I've already checked for conflicts within Default(Windows).sublime-keymap. I've tried to swap the commands to check if the problem is specific with alt+up
[
{
"keys": ["alt+up"], "command": "swap_line_down",
"keys": ["alt+down"], "command": "swap_line_up"
}
]
and, indeed, now swap_line_up works but swap_line_down doesn't. So it seems alt+up is the problem. What seems to be the issue here?
Your key bindings aren't specified correctly; each binding object should have a single keys and command (and optionally a single args and context key s well), but you have both specified in a single binding.
It should look more like this:
[
{
"keys": ["alt+up"], "command": "swap_line_up",
},
{
"keys": ["alt+down"], "command": "swap_line_down"
},
]

Convert - -(double dash) to -> automatically in SublimeText 3

During my work I use -> many times and on a hungarian keyboard there is no dedicated > button, so I have to use 3 keys to enter this and sometimes I also misstype.
Is there a way to convert -- (double dash) automatically a ->? Snippet is not so good because it requires a TAB to convert.
Thanks
It's possible to do this with a simple key binding such as the following:
{
"keys": ["-", "-"],
"command": "insert", "args": {
"characters": "->"
},
},
Now when you type -- as soon as you hit the second - it triggers and replaces the text with -> like you want.
Note however that this would apply to every usage of the text -- in every file. This could be constrained to some degree by using a context in the key binding that makes it apply only in certain files, such as this one that ensures that the binding is only valid in plain text files:
{
"keys": ["-", "-"],
"command": "insert", "args": {
"characters": "->"
},
"context": [
{
"key": "selector",
"operator": "equal",
"operand": "text.plain",
"match_all": true
},
],
},
This can be applied to any scope you want; use Tools > Developer > Show Scope Name... from the menu while editing a file to determine the scope that you need (generally you probably want only the first scope item).
Either way, this makes it impossible to type -- directly without including a deliberate long pause between the two - characters or doing a backspace. That may or may not be an issue.

Sublime text 3 keymap only runs last command defined

I'm trying to create two shortcuts to add these codes on sublime when I hit these keys, but only the second one works, like it overrides the first one.
Does someone have any idea on how to get this working?
I tried this:
[{
"keys": ["ctrl+."],
"command": "insert_snippet",
"args": {
"contents": "<pre><?print_r()?></pre>"
},
"keys": ["ctrl+alt+."],
"command": "insert_snippet",
"args": {
"contents": "?><pre><?print_r()?></pre><?"
},
}]
And this:
[{
"keys": ["ctrl+.", "ctrl+alt+."],
"command": "insert_snippet",
"args": {
"contents": "<pre><?print_r()?></pre>",
"contents": "?><pre><?print_r()?></pre><?"
}
}]
Each individual key binding needs to be it's own distinct JSON object (i.e. inside of {} characters), with keys to specify what key triggers it, command to specify what to execute and args to specify the command arguments.
Assuming it's not a copy/paste error of some sort, the reason your examples don't work the way you want them to is because although they contain valid JSON, they don't contain valid key bindings. So the structure of the file is valid, but the way that Sublime interprets it is different than you intended.
To visualize this, here's your first example with the [] characters removed:
{
"keys": ["ctrl+."],
"command": "insert_snippet",
"args": {
"contents": "<pre><?print_r()?></pre>"
},
"keys": ["ctrl+alt+."],
"command": "insert_snippet",
"args": {
"contents": "?><pre><?print_r()?></pre><?"
},
}
Now we can see that the very first { character is opening the first key binding, but there is no matching } character after the args of that command; instead we see another set of key binding object keys and the } on the last line is the end of the key binding.
In any JSON object (this is not Sublime Text specific), object keys need to be unique; so this is actually a single JSON object with each key duplicated. Sublime's reaction to this is to ignore the first three keys in favor of the second three.
This ends you up with a single key binding instead of two of them, and it's the second one, so ctrl+alt+. works, but ctrl+. doesn't because it was ignored.
In your second example, the duplicate object key is in the args key of the key binding; that means that when the key binding triggers, the insert_snippet command will execute, but the argument that it gets will be the contents of that second key.
In this case this binding works, but what you (perhaps inadvertently) did was define a key binding that requires you to press two keys in sequence in order to trigger it. That is, you would need to press ctrl+. followed by ctrl+alt+. in order for the key binding to trigger.
I think based on your examples you intended to have two distinct key bindings that each insert something different, and the first example is closest to that; you just need to insert }, after the first args and a { before the second keys:
[
{
"keys": ["ctrl+."],
"command": "insert_snippet",
"args": {
"contents": "<pre><?print_r()?></pre>"
},
},
{
"keys": ["ctrl+alt+."],
"command": "insert_snippet",
"args": {
"contents": "?><pre><?print_r()?></pre><?"
},
},
]
Here I've reformatted your second example with the additional fix in place to help clarify that it's the {} that are defining the individual key bindings, the [] characters are for wrapping the list of bindings in the file.

how to bind multiple key to a command in sublime

In sublime, for example,I want to bind both ctrl+1 and ctrl+2 to a command, is there any way to set this?
Thanks.
You can simply repeat the config. For example:
[
{ "keys": ["super+ctrl+f"], "command": "toggle_full_screen" },
{ "keys": ["super+alt+f"], "command": "toggle_full_screen" }
]
Will result in both super+ctrl+f and super+alt+f working.
Note the , at the end of the lines except the last line if you're getting syntax errors.
Don't confuse it with using a pair of shortcuts for a single command, which is done like this:
{ "keys": ["super+k", "super+b"], "command": "toggle_side_bar" },

Sublime Text 2 config - Let space save the file

Sublime Text 2 already supports normal Vim bindings. However, I'd like to have it support saving the current file when pressing space in command mode.
This key binding has become one of my number one features I love about vim.
However, when trying to write this key binding, Sublime Text 2 seems to ignore it:
{ "keys": ["space"], "command": "save",
"context":
[
{ "key": "setting.command_mode", "operand": true }
]
}
Sublime Text 2 seems to not recognize "space".
It much rather has to be like this:
{ "keys": [" "], "command": "save",
"context":
[
{ "key": "setting.command_mode" }
]
}

Resources