Migrate SQLPrompt Snippets to VSCode

 I love snippets; love em. And I have a whole bunch in RedGate SQL Prompt. Now I want to be able to use those in VSCode as well, but boy do I dread having to retype all of them. Solution? Python!

First arg is the path where your SQLPrompt snippets are

Second arg is the directory where you want it to spit out a "sql.json" file with all your snippets.

"""
A script to translate sqlprompt snippet files to vscode formatted snippets
"""
import os
import json
import glob
import io
import argparse

class SQLPromptPlaceholder:
    """Represents the values of a SQLPrompt placeholder"""
    def __init__(self, name, default_value):
        self.name = name
        self.default_value = default_value

class SQLPromptSnippet:
    """Represents the content of a SQLPrompt snippet"""

    @staticmethod
    def from_file(filename):
        """Generates an instance from a filename (and the json found therein)"""
        with open(filename, 'r') as f:
            json_data = json.load(f)
            return(SQLPromptSnippet(json_data))
       
    def __init__(self, json_data):
        """Takes a dictionary of parsed JSON data and turns it into a class instance"""
        self.id = json_data['id']
        self.prefix = json_data['prefix']
        # Due to inconsistent line endings, we sometimes wind up with a trailing \n after the lines are split.
        self.body = [ line.replace('\n', '').replace('\r', '').replace('\t', '    ') for line in io.StringIO(json_data['body']).readlines() ]
        # Turn this into a list of placeholder class instances
        if 'placeholders' in json_data:
            self.placeholders = [ SQLPromptPlaceholder(d['name'], d['defaultValue']) for d in json_data['placeholders'] ]
        else:
            self.placeholders = []
        self.description = json_data['description']
   
    def to_vscode_snippet(self):
        body = []
        for line in self.body:
            for idx, placeholder in enumerate(self.placeholders):
                idx += 1
                slug = f'${{{idx}:{placeholder.default_value}}}' if placeholder.default_value else f"${{{idx}:{placeholder.name}}}"
                line = line.replace(f'${placeholder.name}$', slug)
            line.replace("$CURSOR$", "$0")
            body.append(line)

        return VSCodeSnippet(
            self.description,
            self.prefix,
            body,
            self.description
        )

    def __str__(self):
        return f"{self.id}\n\tPrefix: {self.prefix}\n\tDescription: {self.description}"

class VSCodeSnippet:
    """Represents the content of a VSCode snippet"""
    def __init__(self, name, prefix, body, description):
        self.name = name
        self.prefix = prefix
        self.body = body
        self.description = description

    def get_snippet_json(self):
        """Return the JSON text of the snippet for VSCode"""
        data = {}
        data[self.name] = {
            "prefix": self.prefix,
            "body": self.body,
            "description": self.description,
        }
        return json.dumps(data, indent=4)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-s',
        "--source_dir",
        default=r"C:\Users\GTower\AppData\Local\Red Gate\SQL Prompt 10\Snippets",
        dest="source_dir"
    )
    parser.add_argument(
        '-t',
        "--target_dir",
        default=os.getcwd(),
        dest="target_dir"
    )
    args = parser.parse_args()
    outfile = os.path.join(args.target_dir, "sql.json")
    print(f"Output File: {outfile}")
    print(f"Working Directory: {args.source_dir}")
    os.chdir(args.source_dir)
   
    all_snippets = {}
    for json_file in glob.glob("*.json"):
        filename = os.path.abspath(json_file)
        sqlprompt = SQLPromptSnippet.from_file(filename)
        vscode = sqlprompt.to_vscode_snippet()
        all_snippets[vscode.name] = {
            "prefix": vscode.prefix,
            "body": vscode.body,
            "description": vscode.description,
        }

    with open(outfile, 'w') as of:
        json.dump(all_snippets, of, indent=4)

Comments

Popular posts from this blog

Fixing Git "Unexpected Disconnect while reading sideband packet"

Left-Padding Zeroes