I need to run VSCode through some XML that's at least 90% auto-generated. There are a few things the automatic generation can't determine on its own and needs manual intervention on-- hand-editing where a specific piece of text will be generated on each entry.
What I'm trying to do is to find a way (through extension or through built-in commands) to set up a keybinding that will move the cursor down to the next instance of a specific phrase of my choice (that I wouldn't be manually typing; it would be assigned as part of the keybind) in the current file when I press the binding for it.
For instance, press F17 to go to the next instance of "FIXME" in the current document.
I've been through at least a dozen extensions and haven't found anything that matches my need, and the built-in actions.find doesn't support parameters. actions.findWithSelection requires the text to be selected, so that won't work either.
Any ideas? Someone surely has had the same need for this at some point. I can't see this as a rare need at the very least.
I modified the other extension I mentioned, Find and Transform, to make this really easy. With this keybinding
{
"key": "alt+r",
"command": "findInCurrentFile",
"args": {
"find": "FIXME",
// "replace": "DONE",
"restrictFind": "nextMoveCursor"
}
}
or
{
"key": "alt+r",
"command": "findInCurrentFile",
"args": {
// "find": "FIXME", // no find necessary !!
// "replace": "DONE",
"restrictFind": "nextMoveCursor"
}
},
The first example uses a fixed find and will go to the next FIXME from wherever the cursor is - and it will wrap to the beginning of the file if there are no matches in the rest of the file.
The second example will use the word under the cursor, and thus requires that you start at the word FIXME for example.
First demo (with a find value):
Second demo (with no find, note using during words under cursor to search):
The extension can do a lot more. There are many examples at its link above.
{
"key": "alt+r",
"command": "findInCurrentFile",
"args": {
"find": "FIXME",
// "replace": "DONE",
"restrictFind": "nextSelect"
}
}
The nextSelect option will go to and select the matches in turn so you could modify some of the selections and then move to the next.
I think this extension (that I wrote) is what you are looking for: Jump and select.
Example keybinding (without optional selection of the phrase):
{
"key": "alt+r", // whatever keybinding you wish
"command": "jump-and-select.jumpForward",
"args": {
"text": "FIXME",
// "restrictSearch": "document",
}
},
[If you actually wanted to find all matches and optionally replace them with a pre-defined regex find/replace see Find and Transform.]
You are most probably looking for Move Last Selection To Next Find Match (editor.action.moveSelectionToNextFindMatch), by default bound to ctrl+k ctrl+d. Opposite direction (editor.action.moveSelectionToPreviousFindMatch) has no default binding.
Personally I use Ctrl+Shift+vertical arrows for this, and take my word I use them all the time. keybindings.json snippet:
{
"command": "editor.action.moveSelectionToPreviousFindMatch",
"key": "ctrl+shift+up",
"when": "editorFocus"
},
{
"command": "editor.action.moveSelectionToNextFindMatch",
"key": "ctrl+shift+down",
"when": "editorFocus"
},
Indeed, these command names are quite impossible to find in command palette, when you just want to "jump to next occurrence of word or selection under cursor". It is beyond comprehension how they got such convoluted names.
Congratulations for the first question, BTW!
Related
I've been using Visual Studio Code version 1.74.3 on Windows 10 to take all my math notes. So my txt file is mainly composed of the following structure:
[Theorem]
[Indentation] Proof:
[Indentation] [Indentation] [Proof per see]
Here is an example: https://imgur.com/a/2MD3EQq
I want to fold all the groups of lines that start with the word "Proof" (it occurs 3454 times as of now) because most of the time I don't need to see it, and they're usually quite lengthy. I want to collapse all the lines immediately below each Proof line that share the same indentation. It's also the case that every proof ends with the character "∎".
The problem is that the file is very long (75k lines) and subdivided into many different regions with different indentation levels, so I cannot just use the "Fold by level K" option, since not all proofs are at the same level.
Therefore, folding all the lines that start with the word "Proof" seems to be the way to go.
I've read the section https://code.visualstudio.com/docs/editor/codebasics#_folding for a way to fold all the lines that start with the word "Proof", but I couldn't find any.
Does anyone know how to do it, or have any other suggestion?
Thanks in advance! :-)
This can be done thanks to the command editor.createFoldingRangeFromSelection which will fold anything you can select. It looks like this find would select each of your proof-groups:
^[\t ]*Proof[\s\S\n]*?∎ // I didn't thoroughly test this
So you could (1) find those using the Find Widget, then
(2) Alt+Enter (the editor.action.selectAllMatches command will select each find match separately) and then
(3) Ctrl+k Ctrl+, to apply the editor.createFoldingRangeFromSelection command and it should fold each of those find matches.
To automate this a bit, you can use an extension I wrote, Find and Transform, and this keybinding (in your keybindings.json):
{
"key": "alt+c", // whatever keybinding you want
"command": "findInCurrentFile",
"args": {
"find": "^[\\t ]*Proof[\\s\\S\n]*?∎", // need double-escaping here
"isRegex": true,
"postCommands": [
"editor.action.selectAllMatches",
"editor.createFoldingRangeFromSelection"
]
},
"when": "editorTextFocus && !editorReadonly && editorLangId == plaintext"
}
It does the same find, separately selects each match and then folds it.
The command Remove Manual Folding Ranges will unfold any selected manually folded range. So if you wanted to unfold all your proof-ranges at once, this keybinding would work:
{
"key": "alt+d", // whatever keybinding you want
"command": "findInCurrentFile",
"args": {
"find": "^[\\t ]*Proof[\\s\\S\n]*?∎",
"isRegex": true,
"postCommands": [
"editor.action.selectAllMatches",
"editor.removeManualFoldingRanges"
]
},
"when": "editorTextFocus && !editorReadonly && editorLangId == plaintext"
}
I'm currently using VSCode for Q# programming. This sometimes entails including simple qubit expressions in the comments for clarity. It is of course possible to just settle with using regular angle brackets (such as |00> or <00|), but it looks nicer using the appropriate Unicode characters (such as |00⟩ or ⟨00|). Copying and pasting these characters whenever needed is a bit cumbersome, so it would be nice to have key bindings in VSCode just for this purpose. Actually, I'd like to be able to configure VSCode for quick access to any selection of characters I might be interested at the moment.
VSCode customization supports a type command which does exactly that - types in its argument. In order to create an entry for a keybinding, open the command prompt (Ctrl+Shift+P or ⌘+Shift+P on Mac) and type Preferences: Open Keyboard Shortcuts (JSON) and insert entries of the form:
{
"key": "<key-binding>",
"command": "type",
"args": {
"text": "<character>"
}
}
where <key-binding> is the usual description of the keybinding and <character> is the desired character literal. So, for the bra-ket case above, my customization looks like this:
[
{
"key": "ctrl+shift+.",
"command": "type",
"args": {
"text": "⟩"
}
},
{
"key": "ctrl+shift+,",
"command": "type",
"args": {
"text": "⟨"
}
}
]
I'm trying to replace a structure like this:
testVars.bread.componentFlour
testVars.bread.componentWater
to something like this:
testVars.dough.flour
testVars.dough.water
this happens with multiple variable names; I want to remove the component and have the first letter converted to lowercase to match CamelCase.
What I tried doing was matching testVars.bread.component(.) replacing it with testVars.dough.\l$1.
According to regex documentation, that should convert my match to lowercase. However, VSCode wants to insert \l as text.
How do I get VSCode to convert my match to lowercase?
EDIT: To clarify, this is strictly for VSCode's implementation, not a regex question itself. Matching this group in notepad++ and replacing with testVars.dough.\l\1 does exactly what I want it to do.
NEW ANSWER: !! Those case modifiers like \l and \u are being added to the find/replace functionality in vscode (both in find within one file and search across multiple files [v1.49] - see https://github.com/microsoft/vscode/pull/105101) (see https://github.com/microsoft/vscode-docs/blob/vnext/release-notes/v1_47.md#case-changing-in-regex-replace) - will be in v1.47 (find) and v1.49 (search across files).
So that your original thought to
Find : testVars.bread.component(.)
Replace : testVars.dough.\l$1
is now working.
For more on how the case modifiers work in vscode, see https://stackoverflow.com/a/62270300/836330
OLD ANSWER:
While you cannot replace with a lowercase identifier in vscode, you still have some of options.
Use a regex like (?<=testVars\.).*\.component(.*) so that testVars. is not captured - because you do not want to change its case.
Ctrl+Shift+L to select all your matches (same aseditor.action.selectHighlights).
Ctrl+Shift+P, type lowerand trigger that command (or make a keybinding for this unbound command).
Trigger your replaceAll
To speed that up you have two options. (1) Make a macro that would run steps 2, 3 and 4. Or (2) make a snippet that will transform your selections - effectively running steps 3 and 4 at once.
Snippet in your keybindings.json (not in a snippets file):
{
"key": "alt+m", // choose some keybinding
"command": "editor.action.insertSnippet",
"args": {
"snippet": "${TM_SELECTED_TEXT/.*\\.component(.*)/dough.${1:/downcase}/}"
},
},
and then Ctrl+Shift+L to select all, and alt+m to trigger the above insertSnippet.
Macro approach:
Using some macro extension, here multi-command, put this into your settings.json:
"multiCommand.commands": [
{
"command": "multiCommand.findReplaceLowercase",
"sequence": [
"editor.action.selectHighlights", {
"command": "editor.action.insertSnippet",
"args": {
"name": "replace and lowercase",
}
},
]
}
]
and a snippet, in one of your snippets files:
"replace and lowercase": { // this "label" is used in the macro
"prefix": "for",
"body": [
"${TM_SELECTED_TEXT/.*\\.component(.*)/dough.${1:/downcase}/}"
// "${TM_SELECTED_TEXT/(.*)/${1:/downcase}/}" // to downcase all selected text
],
"description": "replace selected text"
},
and a keybinding to trigger the macro:
{
"key": "alt+m", // choose some keybinding
"command": "extension.multiCommand.execute",
"args": { "command": "multiCommand.findReplaceLowercase" },
}
In the demo I copy the find regex into the find widget (or just write it there, it doesn't matter how it gets there or where focus is) and then hit alt+m (the macro keybinding) and that is it.
Obviously, this looks like a lot of work but you could keep reusing the macro and snippet, transforming to the replace result you would like the next time. And there you can use /downcase, /upcase, /capitalize and /pascalcase all you want which you can't use in the replace field of the find/search widgets.
from other text editors I'm used to adding Markdown links by
selecting the word I want to be linked,
pressing cmd-K on my Mac's / iPad Pro's keyboard, which puts square brackets around the marked word, appends a pair of normal parenthesis () and places the cursor right in beetween those two parenthesis so that I can
just paste the URL I have in my clipboard into the right place by pressing cmd-V.
So, select -> cmd-K -> cmd-V is a nice and short sequence for adding links in a Markdown document and cmd-K has become some kind of pseudo standard for adding links in several writing apps.
However, in VSCode that's not possible. But I'd love to make it possible. Any ideas? cmd-K is (hard-wired?) bound to listen for a next key press.
But it doesn't have to be cmd-K. I can learn another keystroke. But I need to be able to put additional text (square brackets and parenthesis) into the text and move the cursor to the right position. How's that done?
Thanks so much!
This extension Markdown All In One looks like it does what you want in one step.
Paste link on selected text
Just select your link and hit Ctrl+V and it creates the link and inserts the clipboard link.
If for some reason you don't want to use this extension, it would be pretty easy to create a snippet to do what you want.
Adding another answer that doesn't use the extension Markdown All In One I mentioned in the other answer and because a couple of commenters requested a different way. #MarcoLackovic
First Method: keybinding in keybindings.json, then manually paste
{
"key": "alt+w", // use whatever keybinding you wish
"command": "editor.action.insertSnippet",
"args": {
"snippet": "[${TM_SELECTED_TEXT}]($0)"
},
"when": "editorHasSelection && editorLangId == markdown "
}
Select the link text and, trigger your keybinding - the cursor will be placed where you want it and paste.
Second Method: use a macro to insert the snippet and paste in one step
You will need a macro extension like multi-command to run multiple commands in series. Then this keybinding:
{
"key": "alt+w",
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
{
"command": "editor.action.insertSnippet",
"args": {
"snippet": "[${TM_SELECTED_TEXT}]($0)"
}
},
"editor.action.clipboardPasteAction"
]
},
"when": "editorHasSelection && editorLangId == markdown "
}
Demo of second method:
I am a huge Sublime Text user, and learned ways to improve my productivity using customizations in Sublime text. But as VScode is becoming popular day by day, wanted to check if there is any way which I can bind the shortcut keys to the custom actions.
For example, I select a word ABC in any file in VSCode and hit CTRL+B, and it places my own defined values around it like it should become
<b>ABC</b>
I had created the following snippet in Sublime Text, which when I wrote in Visual Studio Code - keybindings.json nothing worked.
{
"keys": [
"ctrl+b"
],
"command": "insert_snippet",
"args": {
"contents": "<b>${0:$SELECTION}</b>"
}
}
This will work in your keybindings.json:
{
"key": "ctrl+b",
"command": "editor.action.insertSnippet",
"when": "resourceExtname == .html", // this is optional
"args": {
"snippet": "<b>${TM_SELECTED_TEXT}</b>"
}
},
The optional when clause is if you want to limit the snippet's operation to .html files.
More general though is to use the emmet command which is built-in: Emmet: Wrap with Abbreviation in the command palette. Select your text, open the command palette, find that command and trigger it - type b or whatever your element is and it will wrap the selected text with the opening and closing elements.
[Note that there is a command workbench.action.toggleSidebarVisibility already bound to Ctrl-B, but the snippet above version seems to take precedence - meaning you lose the toggleSidebarVisibility keybinding functionality - that may be acceptable to you?]