Recording a 'macro'? or a series of actions in Visual Studio Code?
Asked Answered
M

1

24

I would need something like this. Once I create a folder within a project. A React Project for example. I could select that folder and run some kind of macro or series of actions that would do this.

Provided that the name of the folder is Component for example, when the macro would be played it would do this:

Create a file with the name, Component.js that would have some kind of snippet default content. Create a file with the name, Component.styled.js which again would have in it some kind of snippet default content. Create a file with the name index.js that would have the Content: export { default } from './Component' where Component would actually be the name of the folder.

I have no idea where to actually start with this...I've looked into macros and I know how to use visual studio code user snippets, but not sure how this exact thing could be done.

Myrticemyrtie answered 20/9, 2020 at 15:20 Comment(1)
See #64249232 for a similar question (except for the default content).Peduncle
P
10

With a macro extension called macro-commander you could create a folder and included files (with some default content if you wish) fairly easily. But it looks a little complicated since it is essentially writing an extension in your settings.json but in operation it is smooth. This code goes into your settings.json after you install the extension:

"macros": {

  "createReactFolderAndFiles" : [
  
    { 
      "javascript": [

        "const newReactFolder = await window.showInputBox()",  // get the component's name

            // create a object to store various edits, including file creation, deletion and edits
        "const we = new vscode.WorkspaceEdit();",

            // get the workspace folder path + file:/// uri scheme
        "const thisWorkspace = vscode.workspace.workspaceFolders[0].uri.toString();",  // file:///c:/Users/Mark/OneDrive/Test Bed
            // append the new folder name
        "const uriBase = `${thisWorkspace}/${newReactFolder}`;",  // file:///c:/Users/Mark/OneDrive/Test Bed/Test

        // "await window.showInformationMessage(` ${uriBase}`)",  // just handy to check on progress

            // create uri's for the three files to be created
        "let newUri1 = vscode.Uri.parse(`${uriBase}/index.js`);",
        "let newUri2 = vscode.Uri.parse(`${uriBase}/${newReactFolder}.js`);",
        "let newUri3 = vscode.Uri.parse(`${uriBase}/${newReactFolder}.styled.js`);",

        "let newFiles = [ newUri1, newUri2, newUri3];",

        "for (const newFile of newFiles) { let document = await we.createFile(newFile, { ignoreIfExists: false, overwrite: true });};",

        "let styledContent = `first line flush left",   // how to use template literals in this macro
                             "second line will be flush left",
                             "   third line indented`;",

              //  insert text into the top of each file
        "await we.insert(newUri1, new vscode.Position(0, 0), `export { default } from './${newReactFolder}'`);",
        "await we.insert(newUri2, new vscode.Position(0, 0), `my ${newReactFolder}.js content`);",
        "await we.insert(newUri3, new vscode.Position(0, 0), styledContent);",
        
        "await vscode.workspace.applyEdit(we);",  // apply all the edits: file creation and adding text

        "for (const newFile of newFiles) { let document = await vscode.workspace.openTextDocument(newFile); await document.save(); };",
      ]
    }
  ]
},

It allows you to use the vscode extension api in a setting. To run this macro, set up a keybinding:

{
  "key": "alt+j",
  "command": "macros.createReactFolderAndFiles"
},

The first thing it will do is pop up an input box for the folder name. Enter one and hit Enter.

create a React folder with macro-commander extension


If you had default content that you wanted to repeatedly use you could store that and retrieve it for use in this macro. Say the default content is in the same workspace /templates/defaultComponent.txt.

This will get that content:

  "let defaultContent = await vscode.workspace.fs.readFile(vscode.Uri.parse(`${thisWorkspace}/templates/defaultComponent.txt`));",

and add it to one of your files:

"await we.insert(newUri3, new vscode.Position(0, 0), defaultContent.toString());",

As you can see in the demo, it always opens up a couple of the newly created files for some reason - I don't know how to prevent that.

Although the code is complicated-looking I think it is straightforward to modify it for different file names or content.

Peduncle answered 10/10, 2020 at 2:33 Comment(1)
Mark, thanks for you answer, I didnt try it out as I already solved my problem, but I believe it to be right as I trust you knowdlege and think it will help others.Myrticemyrtie

© 2022 - 2024 — McMap. All rights reserved.