Sublime Forum

Making python indents uniform

#1

here’s a text command I wrote to make python indents uniform, so if you have python code that use 2 / 3 / 4 spaces or tabs for indents, it’ll make all the indents uniform

class TidyPythonIndentsCommand(sublimeplugin.TextCommand):
	"""Make .py indents uniform"""

	def run(self, view, args):

		# indentChar = ' ' * 4
		indentChar = '\t'
		buff = view.substr(sublime.Region(0,view.size())).split('\n')
		convertedLines = 0
		newBuff = ]
		nl = ''

		indents = [0]
		# list of indents, [0] means indent depth = 0
		# '""example:"""  [0]
		# ..def _____     [0,2]
		# ....if blah;    [0,2,4]
		# ......blah      [0,2,4,6]
		# ......if:       [0,2,4,6]
		# ........blah    [0,2,4,6,8]
		# ....else:       [0,2,4]
		#

		for line in buff:
			if line.startswith(' ') or line.startswith('\t'):
				spaces = 0
				saved  = None
				for ch in line:
					if ch == ' ' or ch == '\t': spaces += 1
					else:
						# if a comment, go ahead and process it like any line of code
						# but save indents to restore later b/c comments should not affect code indent
						if ch == '#': saved = indents
						break
				if spaces < len(line):
					if spaces > indents-1]:
						indents.append(spaces)
					elif spaces < indents-1]:
						while spaces < indents-1]:
							indents.pop()
					convertedLines += 1
					line = indentChar * (len(indents)-1)  + line[spaces:]
					if saved != None: indents = saved
				else:
					line = ''
			elif len(line)>0 and not line.startswith('#'):
				indents = [0]

			newBuff.append(nl+line)
			nl = '\n'

		if convertedLines > 0:
			view.replace(sublime.Region(0,view.size()), ''.join(newBuff))
			sublime.statusMessage(str(convertedLines)+' lines converted')

I just learned python like last week so this is just an exercise. Please tell me if I’m making some naive assumptions and this code will break given the right input. (Ran it on PowerUser.py and it seemed fine.)

0 Likes