How to set hotkey to move cursor out of quotes/parenthesis? - visual-studio-code

In Sublime I could easily set a more complex hotkey that lets me exit quotes and parenthesis by pressing Enter. It is here below:
// Move out of single and double quotes with `Enter`
{
"keys": ["enter"],
"command": "move",
"args": {"by": "characters", "forward": true},
"context": [
{ "key": "following_text", "operator": "regex_match", "operand": "(?:\"|').*", "match_all": true },
{ "key": "preceding_text", "operator": "regex_contains", "operand": "(?:\"|')", "match_all": true }
]
},
In VS Code, is there any way to achieve this? This in keybindings.json moves the cursor, but it is active when I don't want too. Thanks.
{ "key": "enter", "command": "cursorRight",
"when": "editorTextFocus" }

Check out this extension which does what you want - https://marketplace.visualstudio.com/items?itemName=albert.TabOut
And you can find the implementation here - https://github.com/albertromkes/tabout

I found Ctrl+Shift+\ useful for moving out of quotes. Also, it could be remapped by searching jumpToBracket in Keyboard Shortcuts.
See full VSCode keyboard binding here.

In VS Code, you can type the closing quote (i.e. if using double quotes)
{shift+'}
while you are INSIDE the quotes to have it exit outside the closing quote. This also works for parenthesis and brackets, just type the closing one (i.e. ) or ]). You can also jump straight to a new line by pressing
{ctrl+enter}
which exits out of any brackets, parenthesis, quotes you are already in. These 2 methods here should be embedded in standard VS Code AFAIK.

Related

Make jump to bracket and select to bracket in VSCode stay within brackets (like Sublime)

I am trying to switch from Sublime Text to VSCode and two commands I'm quite dependent on are jumping and selecting between brackets which seem to differ between in VSCode compared to Sublime.
I've found an option in VSCode to do this, namely editor.action.jumpToBracket and editor.action.selectToBracket. The problem is that these differ to the ones in Sublime.
Jumping between brackets in Sublime stays within brackets and selecting does not include brackets, while in VSCode jumping moves outside of the brackets and selecting also includes brackets.
I would like to preserve the Sublime functionality. Is there a simple way to do that in VSCode?
For the selection you can use the extensions
multi-command
Select By
Add the following key binding
{
"key": "ctrl+i ctrl+s", // or any other combo
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
"editor.action.selectToBracket",
{ "command": "selectby.moveLastSelectionActive", "args": {"offset": -2} },
{ "command": "selectby.moveLastSelection", "args": {"offset": 1} }
]
}
}
It only works for a single selection.
I will add commands selectby.moveSelectionActive and selectby.moveSelection that will act on all selections.
The brackets is a bit more difficult because jump-to-bracket places the cursor before the bracket, but you have no idea if you jump to the open-bracket. If you have multiple brackets it is even harder: ((()()(())))
Edit
With v1.17.0 of Select By it operates on all selections.
Modify to:
{
"key": "ctrl+i ctrl+s", // or any other combo
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
"editor.action.selectToBracket",
{ "command": "selectby.moveSelections", "args": {"start": 1, "end": -1} }
]
}
}

How do I disable inserting a new empty line when I press Enter when the cursor is in brackets?

Steps to reproduce:
simple code:
if () {}
cursor is between {}
i press Enter
result:
if () {
}
expected result:
if () {
}
I want a empty line not to be inserted.
It may be that it works by default(adds a empty line), and when Alt+Enter it doesn't add a empty line.
I did not find settings in vscode. I didn't find anything on google.
I tried this:
{
"key": "alt+enter",
"command": "type",
"args": {
"text": "\n"
},
"when": "editorTextFocus"
}
Because Alt+Enter does nothing by default.
However, the onEnterRules function used with the editor.autoIndent option detects the addition of the \n character and adds an extra empty line anyway. :(
I want to use editor.autoIndent. But I want to turn off (do not turn on) using the shortcut Alt+Enter.
Worst option: look for an extension that does exactly the same as editor.autoIndent, but has the ability to create a shortcut Alt+Enter to work the way I want.
You can use the extension multi-command and construct a command that does what you want.
Add this to your settings.json (global or workspace)
"multiCommand.commands": {
"multiCommand.lineBreakNoEmptyline": {
"sequence": [
"lineBreakInsert",
"deleteWordRight",
"cursorRight",
"cursorHome"
]
}
}
Add this to your keybindings.json:
{
"key": "alt+enter",
"command": "multiCommand.lineBreakNoEmptyline",
"when": "editorTextFocus"
}
Or using the keybinding only method
{
"key": "alt+enter",
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
"lineBreakInsert",
"deleteWordRight",
"cursorRight",
"cursorHome"
]
},
"when": "editorTextFocus"
}
I'll show the info from my comment here so that it is clearer. This keybinding:
{
"key": "alt+enter", // whatever keybinding you want
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
// "lineBreakInsert",
{
"command": "type",
"args": {
"text": "\n"
}
},
"editor.action.clipboardCutAction"
]
},
}
The type command acts differently than a lineBreakInsert command so it is a little easier to then delete that extra line as the cursor is already there. It is just a small improvement, 2 less commands.
Demo:

Code scope depending "when" rules for keybindings?

i'm new in VSCode, but in Sublime Text it's possible to assign shortkeys with a code scope context, like:
{
"keys": ["tab"],
"command": "insert",
"args":
{
"characters": "\n"
},
"context": [
{
"key": "selector",
"operand": "source.css meta.rule.css meta.declaration-list.css",
"operator": "equal",
"match_all": true
}]
}
That means, when my cursor is at the scope source.css meta.rule.css meta.declaration-list.css and when I press tab key, I'll insert new line. Can I do like that in VSCode, because I try to search for the list of "when" rules, that's what I had found Visual Studio Code list of keyboard shortcuts options and there is nothing about code scope context, or comparing current line text, or something like that.

How to use conditions/context in ST3 macros?

I am trying to modify the Ctrl+Enter-macro so that it appends a semicolon to the end of the line before writing a newline, similar to this question.
The basic solution is pretty simple
[
{"command": "move_to", "args": {"to": "hardeol"}},
{"command": "insert", "args": {"characters": ";\n"}}
]
, however, it has two problems:
1) If there is already a semicolon at eol, it will be duplicated. Is there a way to include a condition of ( preceding_text == ";" ) similar to keybindings'
{ "key": "preceding_text", "operator": "regex_match", "operand": ";$" }
and have the macro run one of two different insert commands depending on that?
2) As it is, the plugin runs independent of language, also inserting semicolons, for example, in html. Again, is there a way to make inserting the semicolon optional depending on the scope?
I found a pretty good workaround. I still don't know, if it's possible to add this kind of condition in the macro itself, but it can be substituted by adding the conditions in the key-bindings.
First, create a second macro "Packages/User/Add Line Semicolon.sublime-macro" with
[
{"command": "move_to", "args": {"to": "hardeol"}},
{"command": "insert", "args": {"characters": ";\n"}}
]
In the user-keybindings add
{ "keys": ["ctrl+enter"], "command": "run_macro_file", "args": {"file": "res://Packages/User/Add Line Semicolon.sublime-macro"}, "context":
[
{ "key": "following_text", "operator": "not_regex_contains", "operand": ";$", "match_all": false },
{ "key": "selector", "operator": "equal", "operand": "(source.css, source.scss) - comment", "match_all": false },
]
},
This listens to the same keys as the normal ctrl+enter, but calls the new macro and only triggers if certain conditions are met.
First, the text after the cursor may not end with a semicolon. If there's already a semicolon at the end of line, this binding will not trigger and the shortcut will be passed through to the default binding instead. Note that, since it only checks the text after the caret, this will not work if your cursor is already at the end of the line.
Secondly, the position of the caret must have the appropriate scope. For this example, I just included css and scss files, and it only matches if you're not currently in a comment. Again, if the condition fails, the shortcut will be passed through to the default macro.

Sublime Text 2 - Auto-indent for brackets and HTML tags

(Note: In these examples, I will use the pipe symbol "|" to represent the cursor)
In Sublime Text 2, when I type a brace, it automatically adds a matching brace like this:
{|}
with the cursor in between the two braces. Then when I hit Enter, it automatically adds an extra new line and an indent, resulting in:
{
|
}
However, the same indent behavior does not happen with brackets and HTML elements. For example, if I type a bracket "[", it does automatically add the matching bracket like:
[|]
But when I hit Enter, the result is:
[
|]
It doesn't add an extra line or indent. Similarly, when I type "div.some-class", then Tab, I get:
<div class="some-class">|</div>
But when I hit Enter, I get
<div class="some-class">
|</div>
Not what I want. The only case that is working correctly is with the braces. But in all 3 cases (braces, brackets, html elements), I want an extra line and indent added. So they should all look like:
Braces:
{
|
}
Brackets:
[
|
]
HTML elements:
<div class="some-class">
|
</div>
How can I accomplish this?
Install EMMET Plugin, it will do that plus tons of extra great features especially for writing HTML and CSS. :)
If you haven't already install Package control (for easily installing new packages/plugins), install it using instructions here.
Then you can simply press CTRL+SHIFT+P and write Package Control : Instal Package and find EMMET and install it. Once done restart Sublime Text and it should work :)
Explanation
I've just figured out for myself how to do one of the things on your list.
I've modified the regex that runs when you press the "enter" key.
The old regex checked for this "operand": "\\{$" and this "operand": "^\\}"
I added or checks using the pipe | to also check for [ and ( in the same manner: "operand": "\\{$|\\[$|\\($" and "operand": "^\\}|^\\]|^\\)"
Directions
Navigate to Preferences>Key Bindings - User
Personally, I keep this file organized by putting short, simple bindings at the top, and larger, block bindings/concerns at the bottom. I consider the following to be a larger block.
Paste this new code in the file:
// Auto-insert line and indent on square bracket and bracket (parenthesis)
{ "keys": ["enter"], "command": "run_macro_file", "args": {"file": "res://Packages/Default/Add Line in Braces.sublime-macro"}, "context":
[
{ "key": "setting.auto_indent", "operator": "equal", "operand": true },
{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
{ "key": "preceding_text", "operator": "regex_contains", "operand": "\\{$|\\[$|\\($", "match_all": true },
{ "key": "following_text", "operator": "regex_contains", "operand": "^\\}|^\\]|^\\)", "match_all": true }
]
},
{ "keys": ["shift+enter"], "command": "run_macro_file", "args": {"file": "res://Packages/Default/Add Line in Braces.sublime-macro"}, "context":
[
{ "key": "setting.auto_indent", "operator": "equal", "operand": true },
{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
{ "key": "preceding_text", "operator": "regex_contains", "operand": "\\{$|\\[$|\\($", "match_all": true },
{ "key": "following_text", "operator": "regex_contains", "operand": "^\\}|^\\]|^\\)", "match_all": true }
]
},
A few notes:
My code does this for parenthesis as I said. (Sublime refers to parenthesis as "brackets", distinguished from "square brackets" and "braces".)
If you don't want this to work on parenthesis, change the first "operand" check to this: "operand": "\\{$|\\[$" and the "operand" check on the next line to this: "operand": "^\\}|^\\]"
Last, I'm guessing Sublime parses it correctly either way, but I have a comma , at the end of my closing brace, which would assume you've got some more key bindings that follow. If it's the last binding before the closing square bracket at the end of the file, you should remove the comma.
Also, in Sublime Text 3 at least, your questions about the <div> indent has been fixed.