Created
September 19, 2012 19:35
-
-
Save dsc/3751741 to your computer and use it in GitHub Desktop.
Fix Block Indentation TextMate Command
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# TextMate command to correct block indentation for languages with | |
# semantic whitespace (like Python or CoffeeScript). | |
# | |
# Command settings: | |
# input: Selected Text or Document | |
# output: Replace Selected Text | |
# activation: cmd+shift+R | |
# scope: source | |
from os import environ as ENV | |
import re | |
TM_SOFT_TABS = ENV.get('TM_SOFT_TABS', 'YES') == 'YES' | |
TM_TAB_SIZE = int(ENV.get('TM_TAB_SIZE', 4)) | |
TM_INDENT = (TM_TAB_SIZE * ' ') if TM_SOFT_TABS else '\t' | |
INDENT_PAT = re.compile(r'^([ \t]*)(.+?\n)(\n+)(?=([ \t]+))', re.MULTILINE) | |
FORCE_INDENT_PAT = re.compile(r'^([ \t]*)(.+?\n)[ \t]*(\n+)(?=([ \t]+))', re.MULTILINE) | |
INC_INDENT_PAT = re.compile(r'[\'"]{3} |((class|def|elif|else|except|finally|for|if|try|with|while)\b.*:\s*$)') | |
DEC_INDENT_PAT = re.compile(r'(elif|else|except|finally)\b.*:') | |
def indenter(m): | |
s = m.group(0) | |
gs = (i1, line, gap, i2) = m.groups() | |
# deal with indentation-change on preceeding line | |
if INC_INDENT_PAT.match(line): | |
i1 += TM_INDENT | |
elif DEC_INDENT_PAT.match(line): | |
i1 = il[0:-len(TM_INDENT)] | |
indent = min(i1, i2) | |
gap = gap.replace('\n', indent+'\n') | |
return '{1}{2}{gap}'.format(s, *m.groups(), **locals()) | |
def fix_block_indentation(txt, force_fix=False): | |
PAT = FORCE_INDENT_PAT if force_fix else INDENT_PAT | |
return PAT.subn(indenter, txt)[0] | |
if __name__ == '__main__': | |
import sys, codecs, locale | |
sys.stdin = codecs.open('/dev/stdin', 'rU', 'utf-8') | |
sys.stdout = codecs.open('/dev/stdout', 'w', 'utf-8') | |
force_fix = False | |
if len(sys.argv) > 1 and sys.argv[1] == '-f': | |
force_fix = True | |
txt = sys.stdin.read() | |
sys.stdout.write(fix_block_indentation(txt, force_fix=force_fix)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment