Search code examples
pythonsublimetext3sublimetextsublime-text-plugin

Custom AutoFormat in Sublime Text


Is there a way to format using Regex but tie up a handful of replace-all expressions on the current document for formating? I regularly use a hand full of regex expressions to clean up my SQL scripts, and I would like to not have to do it by hand every time. Is there a way to hotkey all of these to run at once?

This is not relevant but here are the SQL Regex scripts that I use where -- is a comment and the second line is the replace variables. You can use this as a reference or use it for your own script if you like.

-- Add a space between = or + or * or / phrases
([@\w\d'")\]])([+=*\/]|<>|<=|>=|>|<)(['"@\w\d(-\[])
$1 $2 $3

-- Remove unnessisary space at the end of a line
([-!$%^&*()_+|~=`{}\[\]:";'<>?,.\/\d\w])\h+$
$1

-- Add space between minus sign. Doesn't work after a letter because it could be mistaken with a hyphan.
([\d)\]])([-])([\w\d(\[])
$1 $2 $3

-- Add a space after a , that comes after a letter, ), ', or "
([)\w\d'")])([,])([\w\d'"(@])
$1$2 $3

-- Fix dates in comments that are messed up from adding spacing to /
\* *(Created on: )?(\d{1,2}) *\/ *(\d{1,2}) *\/ *(\d)
* $1$2/$3/$4

Solution

  • As Keith Hall pointed out, packagecontrol.io/packages/RegReplace, will do the job nicely.

    But, FYI, if you wanted to create such a custom command directly it would go like this:

    1. Pull down Preferences > Browse Packages... and then go into the User folder.

    2. Create a file called sql_cleanup.py and paste in the following:

    
    from sublime_plugin import TextCommand
    import re
    
    # Sublime automatically recognizes this class name as being the "sql_fixup" command
    class SqlFixupCommand(TextCommand):
        def run(self, edit):
            self._edit = edit
            self._process_text()
    
        def _get_file_content(self):
            return self.view.substr(sublime.Region(0, self.view.size()))
    
        def _update_file(self, doc):
            self.view.replace(self._edit, sublime.Region(0, self.view.size()), doc)
    
        def _process_text(self):
            txt = self._get_file_content()
    
            # Add a space between = or + or * or / phrases
            txt = re.sub(r"([@\w\d'\")\]])([+=*\/]|<>|<=|>=|>|<)(['\"@\w\d(-\[])", r"\1 \2 \3", txt)
    
            # Remove unnecessary space at the end of a line
            txt = re.sub(r"([-!$%^&*()_+|~=`{}\[\]:\";'<>?,.\/\d\w])\h+$", r"\1", txt)
    
            # Add space between minus sign. Doesn't work after a letter because it could be mistaken with a hyphen.
            txt = re.sub(r"([\d)\]])([-])([\w\d(\[])", r"\1 \2 \3", txt)
    
            # Add a space after a , that comes after a letter, ), ', or "
            txt = re.sub(r"([)\w\d'\")])([,])([\w\d'\"(@])", r"\1\2 \3", txt)
    
            # Fix dates in comments that are messed up from adding spacing to /
            txt = re.sub(r"\* *(Created on: )?(\d{1,2}) *\/ *(\d{1,2}) *\/ *(\d)", r"* \1\2/\3/\4", txt)
    
            self._update_file(txt)
    
    1. To optionally add your new command to the command palette, create a file called sql_cleanup.sublime-commands and paste in the following:
    [
      { "caption": "SQL: Fix Up Code","command": "sql_fixup" },
    ]
    
    
    1. To optionally add this command to Sublime's Tools menu (in a submenu called SQL), create a file called Main.sublime-menu with the following contents: (If there is already a submenu called SQL, then this will add it to whatever is already there.)
    [
      {
        "id": "tools",
        "children": [
          {
            "caption": "SQL",
            "id": "sql-tools",
            "mnemonic": "S",
            "children": [
              {
                "caption": "Fix Up Code",
                "command": "sql_fixup" },
            ]
          }
        ]
      },
    ]
    
    1. To optionally bind this command to a keystroke, create a file called Default (Windows).sublime-keymap (or whatever platform you are on) with something like the following contents: (This example binds it to holding down the CTRL key and typing UQ.)
    [
       { "keys": ["ctrl+u", "ctrl+q"], "command": "sql_fixup" },
    ]