"""
Greedy_Backspace.py - A Jython Macro for jEdit that will
backspace to the previous tab column when using soft tabs.
For example, If you are on column 6 and have tabs size set
to 4 if you invoke this macro, it will backspace to column
4 (assuming 5 and 6 are both space characters). This macro 
can be used as a replacement for the built-in `Delete 
Previous Character` action, however you might want to bind
another key combination to `Delete Previous Character`, such
as ``CS+BACKSPACE`` for times when you do actually want to
delete a single whitespace character. This macro will behave
the same as `Delete Previous Character` when not using soft
tabs or when any text is selected.

Copyright (C) 2002 Ollie Rutherfurd <oliver@rutherfurd.net>

$Id: Greedy_Backspace.py 28 2003-03-25 22:40:28Z oliver $
"""

def greedyBackspace(textArea):
	buffer = textArea.buffer

	# don't bother getting fancy unless we're using soft tabs
	if str(buffer.getProperty('noTabs')) not in ('1','true'):
		textArea.backspace()
	# if any text is selected, use built-in backspace
	elif textArea.getSelectedText():
		textArea.backspace()
	else:
		tab_size = textArea.buffer.getProperty('tabSize')
		caret_pos = textArea.getCaretPosition()
		line = textArea.getLineOfOffset(caret_pos)
		line_start = textArea.getLineStartOffset(line)
		# if at the start of the line, nothing special
		# is needed, just backspace and return
		if caret_pos == line_start:
			textArea.backspace()
			return
		line_text = textArea.getLineText(line)
		# get portion of line before caret
		text = line_text[:(caret_pos-line_start)]

		text.expandtabs(tab_size)

		try:
			textArea.buffer.beginCompoundEdit()
			textArea.backspace()

			# check the character just backspaced -- if it wasn't
			# a space or tab, don't remove any more
			if not text[-1].isspace():
				return

			# remove character we just deleted
			text = text[:-1]

			# TODO: make this work with embedded tabs
			num_back = len(text) % tab_size
			#print 'num_back: %d' % (num_back,)

			for i in range(1, num_back+1):
				# if the current character to backspace over 
				# isn't whitespace don't backspace it.
				#print len(text), -i, `text[-i]`, `text`
	
				# only treating consecutive whitespace
				# as a 'tab', so stop when non-whitespace
				# is found
				if not text[-i].isspace():
					break
				textArea.backspace()

		finally:
			textArea.buffer.endCompoundEdit()


if __name__ in ('__main__','main'):
	greedyBackspace(init.textArea)



