Regex in VSCode: case conversion in replace, modifiers \l, \L, \U, \u not working - visual-studio-code

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.

Related

Visual Studio Code multiline select until a character

I would like to select all the words at once between the backtick. In MACOSX use alt+ shift and the cursor put a multi cursor at the beginning of the words but I can't stop the selection to the "`" character where the word ends.
`apples` int(200) NOT NULL,
`bananas` int(100) NOT NULL,
`mangos` int(100) NOT NULL,
`kiwi` int(100) NOT NULL,
`raspberry` int(100) NOT NULL,
Is there a way I can select until some character is found in the line where the cursor is placed?
In this case, the expected selection is:
`apples`
`bananas`
`mangos`
`kiwi`
`raspberry`
Press command+F to open the find widget.
Type `.*?` in regex mode (.* icon).
Press command+shift+L to select all occurrences.
Press esc to close the find widget.
If there is a dedicate way to select until a specific character, I am not aware of it.
However, you have a very regular "input" here (none of the fruit words have spaces in them). If that's representative of your real scenario, then to select apples, bananas, mangos, kiwi, raspberry, then put the caret right at the beginning of "`apple`", then hold alt+shift and click the beginning of "raspberry", then press ctrl+shift+right, then shift+right (Windows and Ubuntu. I think for MacOS it's option+shift+right then shift+right, but I'm not 100% sure).
This doesn't work if the fruit words have spaces in them. In that case, if you happen to be doing this because you want to do find and replace, you can use the regular expression mode of the find and replace feature. Something like find ^ `([^`]+)` and then replace withsome usage of $1.
You can use the extension Select By
Create a keybinding:
{
"key": "shift+alt+]", // or any other combo
"command": "selectby.regex",
"when": "editorTextFocus",
"args": {
"forward": "('''|\"\"\"|'|\"|`)",
"forwardNext": "{{1}}",
"forwardInclude": false,
"forwardNextInclude": false
}
}
Place multiple cursors before the strings you want to select, and press the key binding.
If you do this selection frequently you can make a keybinding for it using this extension: Find and Transform (which I wrote). Sample keybinding - in your keybindings.json:
{
"key": "alt+d", // whatever keybinding you want
"command": "findInCurrentFile",
"args": {
"find": "(?<=`)(.*)(?=`)",
"restrictFind": "selections",
"isRegex": true
},
}
For this you just need to select the lines you want changed - it can be one selection, see demo. Or you could use this option:
"restrictFind": "line",
and just put a cursor on any lines you want changed - the cursor can go anywhere on the line.
By "line":

Possible to move cursor to next instance of specific word?

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!

Setting character $ to wrap text as parentheses in vscode

Suppose following code exists.
sample text
When user double click text, then press { or (, it just wraps the text while keeping it.
sample {text}
sample (text)
But I don't know how to apply this rule to $ in VS Code Settings.
What I expect is
sample $text$
Which setting in VS Code is related to this feature?
Edit> Auto Surround
is the setting in vscode. But it only applies to quotes and brackets like (), {}, <> and [] (and possibly some other language-defined cases). You cannot change that setting to include another character like $ unfortunately.
Here is a keybinding you might try (in keybindings.json):
{
"key": "alt+4", // or whatever keybinding you wish
"command": "editor.action.insertSnippet",
"args": {
// "snippet": "\\$$TM_SELECTED_TEXT\\$"
// to have the text still selected after the $'s are inserted, use this
"snippet": "\\$${1:$TM_SELECTED_TEXT}\\$"
},
"when": "editorTextFocus && editorHasSelection"
},
So that any selected text will be wrapped by a $ when you select it and alt+4 (where the $ is on an English keyboard). If you do that operation a lot it might be worth it.
If you use this line instead in the snippet above:
"snippet": "$1$TM_SELECTED_TEXT$1" // or
"snippet": "$1${2:$TM_SELECTED_TEXT}$1"
then more generically select text to surround, trigger that keybinding and type whichever and how many characters you want to wrap the selection.

Emmet How To Wrap Usig Multiple Tags

I'm trying to wrap bunch of data with following tags.
For an example:
link1
link2
link3
link4
link5
I want each one of them to be wrapped with following tags.
<url>
<loc>link1</loc>
<lastmod>2020-01-16T22:59:45+00:00</lastmod>
<priority>0.80</priority>
</url>
<url>
<loc>link2</loc>
<lastmod>2020-01-16T22:59:45+00:00</lastmod>
<priority>0.80</priority>
</url>
....
I want to know if this is possible to do using Emmet code. Any help would be appreciated.
There are two things you should use from Emmet syntax:
Implicit repeater: mark element with * (without number) to Emmet to repeat element as many as lines you’re wrapping. For example, ul>li*
Output placeholder: tell Emmet where to put content you are wrapping with $#. You can use it in text (li{Put here: $#}) and/or in attributes (li[title=$#]).
So, in the end your wrapping abbreviation will look like this:
url*>loc{$#}+lastmod{2020-01-16T22:59:45+00:00}+priority{0.8}
Note that, for some reason, in VSCode you should use Emmet: Wrap Individual Lines with Abbreviation command to wrap multiple lines while in other editors the default Wrap With Abbreviation should work.
Read more about abbreviation syntax: https://docs.emmet.io/abbreviations/syntax/
In PHPStorm, I'd suggest defining a live template for that:
<url>
<loc>$SELECTION$</loc>
<lastmod>$date$</lastmod>
<priority>0.80</priority>
</url>
where $date$ has date("yyyy-MM-dd'T'HH:mm:ss.SSSZ") used as Expression:
Now enable column selection mode (Edit | Column Selection Mode), select the lines you'd like to surround with tags, choose Code > Surround With Live Template...
Another alternative is to use regular snippets. This is for vscode:
"link snippet": {
"prefix": "link",
"body": [
"<url>"
"<loc>$TM_SELECTED_TEXT</loc>",
"<lastmod>2020-01-16T22:59:45+00:00</lastmod>", // if date is fixed ahead of time
// use below if date is dynamic at creation time
"<lastmod>${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}T${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}+00:00</lastmod>"
"<priority>0.80</priority>",
"</url>",
""
],
"description": "Wrap link with url, etc."
},
Then, because you will need to chain 3 commands together to make this easy, use a macro extension like multi-command. Pu this into your settings.json:
"multiCommand.commands": [
{
"command": "multiCommand.expandLink",
"sequence": [
"editor.action.insertCursorAtEndOfEachLineSelected",
"cursorHomeSelect",
{
"command": "editor.action.insertSnippet",
"args": {
"name": "link snippet",
}
},
]
}
]
That will trigger the snippet after it selects each of your lines separately. To trigger the macro itself you need a keybinding (in keybindings.json):
{
"key": "shift+alt+l",
"command": "extension.multiCommand.execute",
"args": { "command": "multiCommand.expandLink" },
},
A fair amount of setup, but then it is just the one keybinding to trigger it all. Demo:

How to Create Custom Key Binded Snippets in VS Code

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?]