javascriptregexvisual-studio-codevscode-snippets

How to create a comment block of //'s around text of different lengths


I'm curious, if there's a way to create these blocks automatically around a text? Currently working in VS / VSCode projects.

/////////////////////////////////////////////////////////
///////////////////// Demo Text /////////////////////////
/////////////////////////////////////////////////////////

Due to varying text length, this can be really annoying.

Thanks!


Solution

  • I decided to make an extension to handle a wide variety of comment block requests, Comment Blocks, which is simpler to use than the version I previously made below.

    With this keybinding (in your keybindings.json after installing the extension)

    {
      "key": "alt+b",                     // whatever you want
      "command": "comment-blocks.createBlock",
      "args": {
        "lineLength": 57,          // what you used in your example
        "startText": "${LINE_COMMENT}",
        "endText": "",
    
        // two padded lines with no text surrounding the selected text
        "subjects": ["", "${selectedText}", ""], 
      
        "padLines": "/",   // pad with the '/' character
        "gapLeft": 1,      // 1 space to left of text
        "gapRight": 1      // 1 space to right of text
      }
    }
    

    Demo:

    center text with padding

    You can also select multiple lines of text (with the same keybinding!):

    center a comment block with multiple selected lines


    Here is a vscode solution. You will need some macro extension to run several commands in a row. Here I am using multi-command for example. See https://marketplace.visualstudio.com/items?itemName=ryuta46.multi-command

    settings.json:

    {
      "command": "multiCommand.createTextBlock2",
      // "interval": 350,
      "sequence": [
        
        "cursorEnd",        
        "cursorHomeSelect",
        {
                     // pad with equal number of /'s before and after text
                     
          "command": "editor.action.insertSnippet",
          "args": {
            "snippet": "////////////////////////////// $TM_SELECTED_TEXT //////////////////////////////"
          }
        },
        
        "cursorHomeSelect",
        {
          "command": "editor.action.insertSnippet", 
          "args": {
            "name": "Create a Text Block",
          }
        },
        "cursorDown"
      ]
    },
    

    A snippet (in one of your snippets files):

    "Create a Text Block": {
      "prefix": "tb",
      "body": [
        
        "/////////////////////////////////////////////////////////", 
        "${TM_SELECTED_TEXT/(.*)(.{57})(\\1).*/$2/g}",
        "/////////////////////////////////////////////////////////",    
        
      ],
      "description": "create a text block"
    },
    

    And a keybinding (keybindings.json) to trigger the macro.

    {
      "key": "alt+b",
      "command": "extension.multiCommand.execute",
      "args": { "command": "multiCommand.createTextBlock" },
      "when": "editorTextFocus && !editorReadonly"
    },
    

    To explain the macro:

    You had 57 /'s on each line without any text, so that is what I used - chose some amount.

    Step 1 of the macro: The text is selected and padded at the start and end of the text with lots of /'s. Must be an equal number of /'s before and after the text for the regex to do its magic - I used about 30 or so.

    Step 2: The snippet is inserted.

    The interesting part. Keep the middle 57 characters of the line containing the text with the regex (.*)(.{57})(\\1).*. The \\1 is a backreference to whatever was captured in the first capture group - so capture groups 1 and 3 will be the same length.

    And capture group 2 will be our text surrounded by an equal number of /'s (if we added and equal number of /'s before the regex transform which we did). The .* at the very end of the regex is to handle the odd/even number of characters in the text.

    regex101 demo - middle 25 characters

    demo of create a text block

    And see How to pad out line to certain length using regex replace and snippets for a similar question about padding out different lines of text to equal lengths.