Skip to content

Instantly share code, notes, and snippets.

@dsc
Created September 19, 2012 19:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dsc/3751741 to your computer and use it in GitHub Desktop.
Save dsc/3751741 to your computer and use it in GitHub Desktop.
Fix Block Indentation TextMate Command
#!/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