How can I more easily replace a selection of text with an equal number of space characters? - visual-studio-code

I'm doing a lot of text editing right now that involves replacing spans of text with spaces (same number of spaces as number of replaced characters). It would be easier and more efficient if I could somehow highlight/select the text to replace, and then replace it all with blank spaces instead of first deleting the text and then manually refilling the spaces, tabs or newlines, especially during moments where I want to be precise.
For example:
This is my example sentence.
I decide I want to select 'my example' and delete it, like this:
This is sentence.
Instead of having it go like this:
This is sentence.
Is there an easier way to do this?

This is also easy with this extension, Find and Transform (disclaimer: I wrote it). Here is a keybinding that would work (in your keybindings.json):
{
"key": "alt+q", // whatever keybinding you want
"command": "findInCurrentFile",
"args": {
"replace": [ "$${ return `$1`.replace(/./g, ' '); }$$" ],
"isRegex": true,
"restrictFind": "selections",
"postCommands": "cancelSelection" // if you had multiple selections and wanted to clear them
}
}
"restrictFind": "selections" will only work within selections, as many as you want. If you had repetitive text in the document, you could omit this argument and it will find the selected text wherever it occurs in the document and replace it.
The $1 referred to is the selected text.

What you can do is switch your editor find mode to regex, and put "[^\s]" in the find input, and then " " (space) in the replace input. Then select the text you want to replace with spaces and either click the "Find in Selection" button or use the keyboard shortcut (Ex. alt+l). Then click "Replace All" or use the keyboard shortcut (Ex. ctrl+alt+enter).
This will replace each instance of any non-whitespace character in the selection with a space character.
If you don't want to preserve the types of whitespace characters (Ex. keeping tab characters as tab characters), just put "." in the find input field instead of "[^\s]".

You can use the extension Regex Text Generator
Add this to your settings.json
"regexTextGen.predefined": {
"Replace with spaces": {
"originalTextRegex": "(?g)(.)",
"generatorRegex": " {S}"
}
}
Select the text you want to replace, multi cursor is supported.
Execute command: Generate text based on Regular Expression (regex)
Select the predefined: Replace with spaces
Press Enter 2 times.
You are able to preview the replacement and Escape if needed when you are allowed to edit the generator expression.
You can create a key binding for this if you need to do it a lot. See the extension page for an example.

Related

How can I turn VSCode's sub word navigation off?

In a snake_cased language, I would want to navigate variablewise and not word_wise and also exclude sigils like #, % or / from these stops.
Example:
|$here_she_goes_again; #the pipe marks my cursor position
With one Ctrl+Right, I want to land on the space before the semicolon,
$here_she_goes_again|; #the pipe marks my cursor position
then, with a Ctrl+Left, I want to return to the beginning of the line.
|$here_she_goes_again; #the pipe marks my cursor position
Somebody got this to work?
Put this into your settings.json:
"[javascript]": {
"editor.wordSeparators": "`~!##%^&*()-=+[{]}\|;:'",.<>/?"
}
Use whatever your language identifier is. I deleted the $ from the default separators to get your example to work for javascript. You can remove the other characters you indicated. The underscore was already not in the default for me. Just make sure those characters are not in the language-specific setting shown above.
You can use the extension Select By and the command moveby.regex
You are able to define a regex to search and bind this to Ctrl+Left and another to Ctrl+Right
In the key binding you can limit this to a particular languageID.

same Keybinds to opposite commands

I would love to set my 'tranformTOLowerCase' and 'tranformToUpperCase' to the same keybind, and use the when clause option that vs code has, but I can't find the right property to rely on,
I'v looked in the vsCode documentation under when contexts and didn't find a solution,
Does anyone know any different way?
I don't think there is any keybinding context key that will help to differentiate between text that is uppercase and text that is lowercase.
But you can use an extension that I wrote to do this: Find and Transform.
Create this keybinding in your keybindings.json:
{
"key": "alt+d", // whatever keybinding you want
"command": "findInCurrentFile",
"args": {
"find": "((([a-z])|([A-Z]))(.*))", // is the first letter upper of lowercase?
"replace": "${3:+${1:/upcase}}${4:+${1:/downcase}}",
"isRegex": true,
"matchCase": true, // this must be set to true to distinguish cases
"restrictFind": "selections", // works on your selection(s), one or many
}
}
As you can see, it tests the first letter. If it is lowercase a-z, then the selection is uppercased. And vice-versa, if the first letter is [A-Z], then the selection is lowercased.
If you can have digits, underscores or other non-alphabetic characters as the first character, this simple first-letter matching won't work and you would have to keep testing characters which would make for a messy regex, but could probably be done. [Let me know if you need that, I think I know how it can be done, although it is a different approach.]
The replacement:
"replace": ${3:+${1:/upcase}}${4:+${1:/downcase}}
is pretty interesting. The $n's refer to capture groups from the find regex. ${3:+${1:/upcase}} means if there is a capture group 3 (the first letter is [a-z], then upcase all of capture group 1.
And similarly if the first letter is [A-Z], so there is a capture group 4, then it and the rest of the selection, capture group 1, will be lowercased.
In a normal vscode snippet or keybinding you can not embed a capture group inside a conditional like ${3:+${1:/upcase}}. ${3:+text to add here if group 3} normally takes only text and cannot resolve variables or capture groups, much less transform their case like ${1:/upcase} inside the conditional - but the extension can.

How to place a cursor after every N characters in VS Code?

Say for example I have a very long line of text in a single line in VS Code (let's pretend that the example given below is very long).
0xffffffffeeeeeeee02020202aaaaaaaa
At first I placed my cursor after the characters 0x.
(the cursor is denoted by the | character in the example below)
0x|ffffffffeeeeeeee02020202aaaaaaaa
Then I want to add more cursors after every N characters from the current cursor. In this case N is equal to 8 and I want to do this twice to add two more cursor like in the example below.
0x|ffffffff|eeeeeeee|02020202aaaaaaaa
So that after I press the following sequence of keys in the keyboard, in this case those sequence of keys are ,(space)0x I should be able to get these final result.
0x, 0x|ffffffff, 0x|eeeeeeee, 0x|02020202aaaaaaaa
After I deselect the cursors I should be getting this
0x, 0xffffffff, 0xeeeeeeee, 0x02020202aaaaaaaa
Is this possible to do in VS code?
There is a straightforward regex that can do what you want:
Find: ^0x|(.{8})(?!$)
But you have to enable the Find in Selection option and trigger the Select All Matches command yourself after entering it.
Or use a macro extension like multi-command and this keybinding to automate it:
{
"key": "alt+p",
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
{
"command": "editor.actions.findWithArgs",
"args": {
"findInSelection": true,
"isRegex": true,
"searchString": "^0x|.{8}",
}
},
"editor.action.selectAllMatches",
"cursorRight"
]
},
}
You must select up to where you want the last cursor and then trigger the macro.
Because of a flaky implementation, you must start with the Find in Selection option disabled in the Find Widget. I haven't found a way around that.
The setting Editor > Find: Seed Search String From Selection must be set to never. Otherwise your selected text will over-ride the searchString from the macro above.
Here is the pure regex method with no extensions:
Enter ^0x|(.{8})(?!$) in your Find Widget with the regex option enabled.
^0x the first part of the string you ultimately want a cursor after.
(.{8})(?!$) select each 8-character block, but not the last - that is why there is a negative lookahead for the end of the line (?!$) - so the last 8 characters are not matched. Don't worry, there will be a cursor in front of those last 8 characters as you want. (.{8}) doesn't actually need to be in a capture group, it is just clearer to see.
Select all the text to match: 0xffffffffeeeeeeee. Stop the selection there - wherever you want the last cursor.
Enable the Find in Selection option in the Find Widget by Alt+L.
Alt+Enter to select all the find matches respecting the Find in Selection option: editor.action.selectHighlights.
Step (4) will select your matches - you should have 4 for the above string. But you don't want the matches selected you just want a cursor at the beginning of each, so do step (5):
Right arrow: this cancels each selection with a cursor at the right end of each.
Type.
You can use the extension Select By
It has a command to add a new cursor by keyboard
{
"key": "ctrl+i ctrl+alt+right", // or any other key combo
"when": "editorTextFocus",
"command": "selectby.addNewSelection",
"args": {"offset": 8}
}
Now the offset is hard coded but I will add an option to ask the user the offset.
The possibility of the context switch is already working. I have to update the README.

how to select real numbers by double clicking in VSCode?

because . is a word separator, a real number like 0.1 will be selected only 0 or 1.
but if I remove . from word separators, the whole method call such as a.b or a.b.c will be selected, rather than a, b or c selected.
furthermore, ' is also a possible separator between the digits, which can not be selected correctly as well.
so is there any extension that can solve this problem?
With the extension Select By v0.10.0 you can select the text surrounding the current selection described with a regular expression.
If you add the following to your settings
"selectby.regexes": {
"selectFloat": {
"surround": "[-+]?\\d+(\\.\\d+)?([eE][-+]?\\d+)?[fF]?"
}
}
Place the cursor somewhere inside the number and execute the command Select text range based on regex and select the option selectFloat from the QuickPick list.
You can add a keybinding if needed
{
"key": "ctrl+shift+f", // any key combo you like
"when": "editorTextFocus",
"command": "selectby.regex",
"args": ["selectFloat"]
}
This extension Quick and Simple Text Selection allows for selecting of everything within single quotes, double quotes, backticks, etc., although it requires keyboard shortcuts.

How to do search and replace involving fields in Microsoft Word?

I have a Word document with fields of the reference variety, which occur in the form "[field].[field]"--in other words, there's a period between the two fields. I want to globally replace this with a space.
Word offers the ^d special character to search for fields, but for some reason the query "^d.^d" does not find anything. However, ".^d" does. Now comes the problem, however--what do I specify as the replacement text in order to retain the field code? If using regular expressions, I could use a "Find What Expression" such as \1, but with regexp ("wild card") mode the ^d is not permitted.
I guess I could write a macro...
I would like to add to Bibadia's solution.
An example of an index entry field; we want to change a name we misspelled.
Make sure hidden formatting is displayed (toggle with SHIFT+CTRL+F8).
Make sure wildcards option is not selected. To search for fields, use the opening and closing field braces code (optionally use ^w for spaces, as Bibadia suggested):^19 XE "Deo, John" ^21
Replace won't recognize field braces character, but will allow to insert the clipboard's content. ;). To do that, insert in text the correct entry. CTRL+F9 to insert field and type:XE "Doe, John"
Select the field above and copy
Use ^c in the replace box
Hit Replace All
Ta-da!
It's usually better to go the macro route when finding fields because, as you say, the find algorithm that Word uses doesn't work the way you might hope with fields.
But if you know exactly what the fields contain, you can specify a search pattern that will probably work (however not in wildcard mode).
For example, if you want to look for figure number field pairs such as
{ STYLEREF 1 \s }.{ SEQ Figure \* ARABIC \s 1 }
(which would typically be the same set of fields everywhere in the document)
If you only really need to look for the following:
{ STYLEREF 1 \s }.<any field>
you could ensure that field codes are displayed and search for
^d STYLEREF 1 \s ^21.^d
or
^19 STYLEREF 1 \s ^21.^19
If you need to be more precise, you can spell out the second field as well.
"^d" only works for finding the field beginning, not the field end.
It's a shame that ^w wants to find at least 1 whitespace character because otherwise it would be more robust to look for
^19^wSTYLEREF^w1^w\s^w^21.^19
Perhaps someone else knows how to work around that without using wildcards?
Torzaburo,
I suggest that you do this using a macro. You can start by recording the macro, and later refining your processing steps within the macro.
First turn on the hidden characters by navigating to Home > Paragraph > toggle the show/hide Paragraph symbol. Also, select all and toggle the field codes on (right-click and select "Toggle Field Codes".
Open a new blank Word doc in addition to the one you have open. You will use this later. Start the macro recording and find the field using the "^d" (field code) as you said.
When the field is found, copy only the field text within the brackets, and not the full field reference. While the macro is still recording, ALT + TAB to the new blank document and paste the field code in as plain text.
At this point, do the necessary find & replace processing to the field codes. Highlight the processed field codes, copy, ALT + TAB back to the original document, and paste back between the { } brackets.
Stop the macro recording. Add any further custom processing to the macro VBA.
Select-All and re-toggle the field codes. Update the field codes.
You don't need a macro. Just toggle all field codes on by using Alt+F9. Then do a find and replace for what you want to change. Once the replacement is complete, use Alt+F9 again to toggle the field codes back off.
Disclaimer: I didn't originate this solution, but it's clean and elegant and I thought it should be included here:
(Adapted from Search & Replace Field Codes in Word):
Create or find a single instance of the field you want to convert text to
Toggle Field Codes visible (AltF9)
Copy the code for the field you want to use to the Clipboard (highlight and CtrlC)
Open the Replace dialog box (CtrlH), insert the text you want to replace in the Find What box and then enter ^c in the Replace With box.
This will replace your text with the contents of the Clipboard, turning it into the field code you copied in step 3. It also copies formatting information (font, color, etc.), to control how the field will appear when hidden. (Caveat: I've tested this with Word 2003 under Windows 7 only.)
Coming in late on this, probably way too late for Beth (sorry Beth). And this may not be quite what Beth was looking for. But for anyone interested ...
It sounds like Beth may have created captions throughout the document using INSERT CAPTION (hence the presence of field codes). This means these captions will have been (automatically) created in CAPTION style.
To globally replace the separator "." with " " (space) in such captions, take two steps:
[1] Go to REFERENCES | INSERT CAPTION, then click on NUMBERING and replace the SEPARATOR "." with "EM-DASH". This will replace all separators in captions for the selected label in the CAPTION Window. If you have other labels in use in the document (e.g. FIGURE), select the other labels one by one and repeat this process.
[2] Do a find/replace searching for special character "em-dash" (^+) in style CAPTION, replacing with " ". Click REPLACE ALL.
Voila!
NOTE: This presumes that em-dash does not appear in the caption text anywhere. If it does, then you'll need to do a pre- and post- "fiddle" to ensure these em-dashes are not touched by the global replace above.
The "pre-fiddle" is to do a global find/replace across captions, replacing the em-dash ("^+") with some other string (e.g. "EM-DASH") that doesn't ever occur in any caption's text. Then you do the separator change as described above. Finally, the "post-fiddle" is to restore the em-dashes that were in the captions, by doing a global replace of the string "EM-DASH" with the actual em-dash character "^+".