3

I've made a mistake in making a lot of bold readings in restructured text (rst) files where I should've used a different heading style.

I need to replace:

**some heading**

with:

some heading
............

I'm wanting to do this with VS Code snippets, where I highlight the text in question, and then run the snippet to make the replacement.

To do this, I think I need to make two replacements:

  1. Take selected text, strip leading and trailing **
  2. Take the result of 1, and then essentially replace anything (.) with literal dot (.): s/././g

I cannot figure out how to make nested replacements in VS Code snippets -- is this even possible?

This is what I have right now:

 "BoldToSubHeading": {
 "prefix": ["boldtosubheading"],
 "body": [
 "${TM_SELECTED_TEXT/\\*\\*(.*)\\*\\*/${1}/}",
 "${TM_SELECTED_TEXT/././g}",
 ],
 "description": "Change bold text into subheading."
 }

If the input text is:

**foobar**

I get four too many dots -- because the asterisks are included in the last replacement.

foobar
..........

Textmate docs, which the Snippet code seems to be based on, indicates:

For nested replacements, use named captures as variables are inherited.

However, I've tried the "${TM_SELECTED_TEXT/(?<guts>.*)/${guts}/g}" with no luck.

Any suggestions to solve my replacement problem? Are nested replacements possible with snippets?

Requirements are:

  1. Highlighted text will contain double asterisk at front and back
  2. Text between the double asterisks (let's call it 'guts') can contain anything -- spaces, numbers, quotes, etc
  3. The result should be 'guts', plus a new line, plus a number of dots equal to length of guts.
asked Oct 22, 2020 at 17:36

1 Answer 1

3

I thought this would be easier with one snippet - perhaps with a conditional replacement - but I couldn't figure it out in a reasonable time. But it is pretty easy to do in steps.

Using a macro extension like multi-command, put this into your settings:

"multiCommand.commands": [
 {
 "command": "multiCommand.refactorHeadings",
 "interval": 250, // remove this line and will be instantaneous
 "sequence": [
 {
 "command": "editor.action.insertSnippet",
 "args": {
 "snippet": "${TM_SELECTED_TEXT/\\*\\*(.*)\\*\\*/1ドル/}",
 }
 },
 "editor.action.copyLinesDownAction",
 "cursorLineStartSelect",
 {
 "command": "editor.action.insertSnippet",
 "args": {
 "snippet": "${TM_SELECTED_TEXT/././g}",
 }
 } 
 ]
 }
],

and a keybinding (in keybindings.json) to trigger it:

{
 "key": "alt+c", // whatever keybinding you like
 "command": "extension.multiCommand.execute",
 "args": { "command": "multiCommand.refactorHeadings" },
 // replace markdown with your langId
 // "when": "editorTextFocus && editorHasSelection && editorLangId == markdown"
},

refactor headings with a macro

The demo shows selecting all such occurrences of your simple find regex,Ctrl+Shift+L will do that, and triggering the macro. It is showed slowed down just for demonstration purposes.

answered Oct 22, 2020 at 21:06
Sign up to request clarification or add additional context in comments.

1 Comment

Works like a charm, thanks @Mark! Although this isn't using a snippet I am marking this as the answer because it helped me get done what I needed to get done, and I learned about mult-command to boot.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.